Skip to content

epic #252: Gate the release tail on the invocation rewrite - #337

Merged
sameera merged 2 commits into
mainfrom
feat/252-publish-one-package
Aug 27, 2026
Merged

epic #252: Gate the release tail on the invocation rewrite#337
sameera merged 2 commits into
mainfrom
feat/252-publish-one-package

Conversation

@sameera

@sameera sameera commented Aug 27, 2026

Copy link
Copy Markdown
Owner

Closes out the conformance findings from the epic #252 analyze pass. PR #333 carried the package definition; this carries the release-tail gate and the loose ends the receipt named.

The invocation gate

pnpm nexus:release-gate scans the shipped component bodies and fails on any .claude/… path the payload itself does not carry. Decision record #334 invariant 15 forbids the tag and the public publish while a shipped body reaches a toolkit capability by an in-repository script path — those paths exist in no installed package, so a release cut today would put bodies on the registry that cannot work.

The rule is narrow: a path the payload carries resolves wherever the components are deployed, so it passes; a path it does not carry is a capability that moved into a toolkit and must be reached by the toolkit's name. It is red today on twelve references across nxs.epic.md, nxs.setup.md and nxs-epic-resolve/SKILL.md, and goes green by itself when #250 lands. docs/delivery/release-procedure.md runs it as step 4, ahead of tag and publish.

Also

  • delivery_config.py loses its second entry point, so the byte-code suppression has one place to hold (invariant 8), asserted in test_packaging.py.
  • release-notes checks the breaking wording an entry needs while the version is below 1.0, and the procedure records in writing that the suite checks the entry's language, not its coverage.
  • build-bundles.ts, pack-release.ts and vendor-bundle.ts use isDirectRun() rather than the string run-guard the record replaced.
  • bundle-fingerprint.json and payload-manifest.json re-pinned.

Story #312's AC1

AC1 required a release to have actually been cut, which invariant 15 forbids inside this epic. It is rescoped on #312 to the identity check (checkReleaseIdentity) that this story actually built, with the amendment recorded on the issue. Cutting the release — tag, registry publish, releases-page entry — is re-filed as #336, blocked by #250.

Verification

  • 524 portable-tools tests pass, 191 gh-toolkit tests pass, tsc --noEmit clean.
  • pnpm nexus:release-gate exits non-zero on the twelve known references, as intended.

🤖 Generated with Claude Code

https://claude.ai/code/session_0117PM8UzzRSpUvZuRekR6i6

sameera and others added 2 commits August 27, 2026 06:41
Adds an executable invariant-15 gate: a shipped component body may name a
path under the component tree only when the payload carries that file.
`pnpm nexus:release-gate` prints every offending body and exits non-zero,
and release-procedure.md step 4 stops the release there.

Also:
- delivery_config.py loses its second entry point, so the byte-code
  suppression has one place to hold (invariant 8), with the assertion in
  test_packaging.py.
- release-notes checks the breaking-change wording an entry needs while
  the version is below 1.0.
- build-bundles, pack-release and vendor-bundle use isDirectRun() rather
  than the string run-guard the record replaced.
- bundle-fingerprint.json and payload-manifest.json re-pinned.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0117PM8UzzRSpUvZuRekR6i6
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant