Skip to content

test(spec-tooling): restore the liveness author-lint's array fan-out assertion (#7079) - #7689

Merged
os-help merged 1 commit into
mainfrom
claude/issue-7079-liveness-fanout-assertion
Aug 11, 2026
Merged

test(spec-tooling): restore the liveness author-lint's array fan-out assertion (#7079)#7689
os-help merged 1 commit into
mainfrom
claude/issue-7079-liveness-fanout-assertion

Conversation

@os-help

@os-help os-help commented Aug 11, 2026

Copy link
Copy Markdown
Collaborator

Fixes #7079

What was lost, and what pays it back

getNested (packages/lint/src/lint-liveness-properties.ts:146) resolves a dotted warn-map path by fanning it out over an array container levelnavigation.runAction must check every navigation entry, not just navigation[0]. That reach is the half a walk can lose silently: a getNested that stopped at index 0 still warns on every single-entry fixture, on every top-level warned key, and on the first item of every real app, so nothing else in the suite goes red.

It had exactly one subject, dashboard.widgets.colorVariant, and #6774 flipped that row to live. The assertion — "fans out over EVERY widget, not just the first" — was removed with a tombstone comment rather than downgraded into a silence check that would pass on a broken fan-out. #7079 recorded the loss.

app.props.navigation.children.runAction is now a dotted warned path under an array container: #4848's spec half, planned + authorWarn (the declared deep-link auto-run slot is validated at authoring, but no shipped shell reads it yet), and navigation is an array in all three authored apps. The assertion is rebuilt against it in the deleted test's construction — the warned key on navigation[1], nowhere on navigation[0].

The evidence is the mutation, not the green suite

A test that merely passes today would be the exact non-test this card was filed to avoid. So getNested was temporarily broken to take only c[0] at an array level:

 ❯ src/lint-liveness-properties.test.ts (32 tests | 1 failed) 120ms
       × fans out over EVERY navigation entry, not just the first 12ms

AssertionError: expected [] to have a length of 1 but got +0
 ❯ src/lint-liveness-properties.test.ts:572:23

 Test Files  1 failed | 69 passed (70)
      Tests  1 failed | 1883 passed (1884)

The new assertion is the only failure in the entire package — the red is attributable to the broken walk, not to collateral damage. Mutation reverted, getNested byte-identical to main:

 Test Files  70 passed (70)
      Tests  1884 passed (1884)

Also in the block

  • a control pinning that index 0 is not a blind spot either, so a red on the main assertion reads "the fan-out is broken", not "the walk moved";
  • the checkItem one-finding-per-(item, path) contract the toHaveLength(1) rests on, so that number is pinned rather than accidental;
  • a silence pin for navigation entries authoring no warned key;
  • the tombstone comment at :448 replaced by a pointer to this resolution.

Because the discriminating assertion is a positive warning, it cannot pass vacuously: lintLivenessProperties returns [] both when the ledgers fail to load and when the walk is broken, and this block fails in either case.

Option 1 (export getNested) — declined, deliberately

The card offered a ledger-independent unit test via an exported getNested or an @internal seam, and named its cost: a second contract on a function whose entire design is "ledger-driven, coverage grows by marking entries". Declined, because the mutation above shows the ledger-driven test already delivers the one fact the card asks for — it distinguishes a working walk from one that never looks past [0]. A seam would add public surface to @objectstack/lint for no additional discriminating power, and would cost the property this test has and a unit test would not: it holds the real shipped ledger to its authorWarn on that row, the contract this file's header docblock describes.

Scope

Entirely packages/lint/src/lint-liveness-properties.test.ts (+99 / −9, one file). No ledger row was added or flipped — the subject already existed. lint-liveness-properties.ts, packages/spec/liveness/*.json, packages/spec/src/**/*.zod.ts and content/docs/releases/** are untouched.

Gates

Gate Invocation Result
tests pnpm --filter @objectstack/lint run test 1884 passed (70 files)
typecheck pnpm --filter @objectstack/lint run typecheck clean

skip-changeset: test-only, nothing published changes — packages/lint's files ships dist, README.md, CHANGELOG.md, and vitest sources are in none of them. AGENTS.md:1018 requires a changeset for feature work; the label's own description is "PR has no user-facing published change; bypasses the changeset gate". Precedent: #7579 (test(drivers): remove redundant object: key from mongodb/sql query test literals), merged test-only with the label.


Generated by Claude Code

…assertion (#7079)

`getNested` fans a dotted warn-map path out over an ARRAY container level, so
`navigation.runAction` must check EVERY navigation entry, not just index 0.
That reach lost its only test subject when #6774 flipped
`dashboard.widgets.colorVariant` to `live`: the assertion "fans out over EVERY
widget, not just the first" had nowhere left to stand, and was removed with a
tombstone comment rather than downgraded into a silence check that would pass
on a walk which never looks past `widgets[0]`.

`app.props.navigation.children.runAction` (#4848's spec half — `planned` +
`authorWarn`, because the declared deep-link auto-run slot is validated at
authoring but no shipped shell reads it yet) is now a dotted warned path under
an array container: `navigation` is an array in every authored app. Rebuild the
assertion against it in the deleted test's construction — the warned key on
`navigation[1]` and nowhere on `navigation[0]`, so a walk that stops at the
first element finds `undefined`, emits nothing, and goes red.

Verified by mutation, not by a green suite: with `getNested` temporarily taking
only `c[0]` at an array level, this assertion is the ONLY failure across the
package (1883 passed / 1 failed), so the red is attributable to the broken walk
rather than to collateral damage. Reverting the mutation returns 1884 passed.

Alongside it: a control pinning that index 0 is not a blind spot either, the
`checkItem` one-finding-per-(item, path) contract the length assertion rests
on, and a clean-navigation silence pin. The tombstone comment is replaced by a
pointer to this resolution.

Test-only; `getNested` and the lint's behaviour are untouched.

Fixes #7079

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DveDnLVD1syPGfXryonczk
@vercel

vercel Bot commented Aug 11, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
objectstack Ignored Ignored Aug 11, 2026 10:17am

Request Review

@os-help os-help added tests skip-changeset PR has no user-facing published change; bypasses the changeset gate domain:spec-tooling labels Aug 11, 2026 — with Claude
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

No hand-written docs reference the 0 changed package(s). ✅

@os-help
os-help marked this pull request as ready for review August 11, 2026 10:48
@os-help
os-help added this pull request to the merge queue Aug 11, 2026
Merged via the queue into main with commit 06b43cc Aug 11, 2026
35 checks passed
@os-help
os-help deleted the claude/issue-7079-liveness-fanout-assertion branch August 11, 2026 11:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

domain:spec-tooling size/m skip-changeset PR has no user-facing published change; bypasses the changeset gate tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

finding: the liveness author-lint's array fan-out (getNested) has no warned subject left, so it is now untested

2 participants