Skip to content

test(authorization): name the lifecycle bits a tombstone, and stop the guard passing vacuously - #1682

Merged
os-steve merged 1 commit into
mainfrom
claude/issue-1634-lifecycle-bits-guard-prose
Sep 6, 2026
Merged

test(authorization): name the lifecycle bits a tombstone, and stop the guard passing vacuously#1682
os-steve merged 1 commit into
mainfrom
claude/issue-1634-lifecycle-bits-guard-prose

Conversation

@claude

@claude claude Bot commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

Closes #1634

Description

The lifecycle-bits guard in test/authorization-coverage.test.ts scanned every permission grant for allowRestore: true / allowPurge: true under a comment that described those keys as "RBAC-gated" bits "whose operations do not exist yet" — live-but-unenforced. On the pinned @objectstack/spec 17.3.0 they are neither. This PR fixes the prose (ruled disposition 1 on the card) and adds the guard-the-guard assertion the grading asked for. The guard itself is kept and unchanged.

Type of Change

  • Documentation update (a test comment stating a platform fact that is no longer true)
  • New tests added (one guard-the-guard assertion, copied in shape from the adjacent allowTransfer test)

Related Issues

Closes #1634. Source card #1376. Upstream: objectstack#12497 (ADR-0049 retirement), objectstack#12840 (retired-default residue tolerance), objectstack#1883 (M2 lifecycle anchor, still open).

Changes Made

  • The comment now names a tombstone. ADR-0049 enforce-or-remove retired both keys (objectstack#12497). Measured against the installed package, ObjectPermissionSchema.safeParse({ allowRead: true, allowRestore: true }) is refused at parse time, and the verbatim prescription is quoted in the comment:

    objects.OBJECT.allowRestore was removed in @objectstack/spec 17 (ADR-0049) — the restore ObjectQL operation it claimed to gate has never shipped (roadmap M2), so granting the bit delivered nothing. Delete the key — a dispatched restore stays denied fail-closed by the permission evaluator's destructive-operation backstop, and the bit returns with the M2 lifecycle initiative alongside the operation it gates. Run os migrate meta --from 17 to list the mechanical edits for existing sources; apply them by hand.

    (OBJECT stands for the angle-bracket placeholder the real message prints.)

  • Only true is refused. The false that the pre-retirement schema defaulted into every artifact the published 17.x toolchain built parses as inert residue and is stripped (objectstack#12840). Measured both ways here. That is why the scan tests === true, and the comment now says so.

  • The comment says why the guard stays. validate and build both reject such a source earlier in pnpm verify, but pnpm typecheck does not: src/profiles/*.profile.ts are untyped object literals and this suite reads the raw objectstack.config rather than a schema-parsed object, so nothing gives the literal a contextual type and a bare pnpm test still trips here. objectstack#1883 stays open as the M2 anchor.

  • Guard-the-guard. The steady state of this scan is an empty result, in which a real pass and a collapsed input are indistinguishable. It now asserts the scanned population is non-empty, the same shape the adjacent allowTransfer test has carried all along. No new check surface — the sibling pattern applied to the assertion already in the file (AGENTS.md "do not grow a gate farm" respected).

  • One changeset (patch).

Version references — re-measured, and one card reading corrected

The card and its grading said the retirement "actually landed in 17.2". That does not hold on the pin:

  • @objectstack/spec's own CHANGELOG.md lists the retirement changeset (8af88dd, "retire the allowRestore / allowPurge object-permission bits … (#12497, ADR-0049)") under ## 17.3.0 → Minor Changes. The ## 17.2.0 section mentions neither key nor #12497.
  • The sentence the grading attributed to @objectstack/metadata ("spec 17.1 to 17.2 retired the allowRestore/allowPurge permission bits") appears nowhere in any installed @objectstack/* package. What metadata's CHANGELOG does carry, inside its own 17.3.0 section, is a prose aside — "spec 17.2.0's retiredKey tombstone refused the boot" — which conflicts with spec's own version placement.

So the comment cites the major, exactly as the platform's own prescription does ("removed in @objectstack/spec 17"), and says out loud not to "correct" that to an earlier minor. The other two readings held: @objectstack/spec is 17.3.0, and the freshly built dist/objectstack.json carries 75 object-permission entries with 0 carrying either key.

Testing

  • pnpm verify fully green — validatetypechecklintlint:i18n-gatehygienehygiene:tokensbuildtest.

    • ✓ Validation passed, ✓ source hygiene clean, ✓ source token ratchet clean (comment-stripped and src/-scoped, so a test comment does not move it), ✓ Build complete.
    • Test Files 161 passed (161) · Tests 3402 passed | 1 skipped (3403).
  • The new assertion was proved able to go red, not merely observed green. The grants set was emptied at its source (permissionSetspermissionSets.slice(0, 0)), the mutation was proved on disk by blob hash and by grepping both the removed and the injected anchor text, and the run failed on exactly the new line:

    AssertionError: no permission grants resolved at all — this scan proves nothing: expected 0 to be greater than 0
    

    The first assertion passed under that mutation — which is precisely the vacuity this closes. Restored with git checkout HEAD -- PATH, and the restore was proved by state rather than by an editor exit code: the on-disk blob hash returned to 529dd9483b71ee220bb5f90e9ca5717a79776f17 and git diff HEAD printed nothing. Re-run green.

Additional Notes

Scope fence honoured: the diff touches only the lifecycle-bits it() block, its comment, and the one new assertion. test/authorization-coverage.test.ts is listed in epic #1579 family F5 (#1586) as group A only, i.e. a mixed file — and the lifecycle-bits guard matches none of F5's nine named security-* / rls-predicate-* rules, so it is group B and stays. Nothing touched under src/profiles/, and no assertion or prose relating to those nine rules was touched. The new assertion is also what the epic's own gate 1 (non-vacuous) requires of this block.


Generated by Claude Code

…e guard passing vacuously

`test/authorization-coverage.test.ts` scans every permission grant for
`allowRestore: true` / `allowPurge: true`. Its comment described those keys as
"RBAC-gated" bits "whose operations do not exist yet" — live-but-unenforced. On
the pinned `@objectstack/spec` 17.3.0 they are neither: ADR-0049 enforce-or-remove
retired both (objectstack#12497) and the schema refuses them at parse time with a
prescription, measured verbatim against the installed package and quoted in the
comment.

Only `true` is refused; the `false` that the pre-retirement schema defaulted into
every artifact the published 17.x toolchain built parses as inert residue and is
stripped (objectstack#12840), so `=== true` is both what the scan tests and the
only value worth testing for.

The guard stays, and the comment now says why: `validate` and `build` reject such
a source earlier in `pnpm verify`, but `pnpm typecheck` does not — the profile
files are untyped object literals and this suite reads the raw
`objectstack.config` rather than a schema-parsed object, so a bare `pnpm test`
still trips here. objectstack#1883 stays open as the M2 lifecycle anchor.

The steady state of this scan is an empty result, which a real pass and a
collapsed input look identical in, so it now carries the same guard-the-guard
assertion the adjacent `allowTransfer` test has carried all along: the population
being scanned must be non-empty. Same file, existing pattern, no new check
surface.

Co-authored-by: Claude
@vercel

vercel Bot commented Sep 6, 2026

Copy link
Copy Markdown

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

1 Skipped Deployment
Project Deployment Actions Updated
hotcrm Ignored Ignored Sep 6, 2026 10:08am UTC

Request Review

@github-actions github-actions Bot added the ci/cd CI plumbing and the verification pipeline label Sep 6, 2026
@os-steve
os-steve marked this pull request as ready for review September 6, 2026 10:13
@os-steve
os-steve added this pull request to the merge queue Sep 6, 2026
Merged via the queue into main with commit c256885 Sep 6, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci/cd CI plumbing and the verification pipeline

Projects

None yet

Development

Successfully merging this pull request may close these issues.

test/authorization-coverage.test.ts: the lifecycle-bits guard now describes a platform state two minors stale

2 participants