fix(release-kit): repair confirmed quality findings in the payload - #20
Closed
John-David Dalton (jdalton) wants to merge 11 commits into
Closed
fix(release-kit): repair confirmed quality findings in the payload#20John-David Dalton (jdalton) wants to merge 11 commits into
John-David Dalton (jdalton) wants to merge 11 commits into
Conversation
… examples The copy-in release engine (scripts/socket-release/): the ported fleet publish stack (npm staged publishing, cargo, web-auth router, browser session law), a NEW eight-step bootstrap (preflight, placeholder with hard --reserve consent, npm-access-permissive, github-env, staged-config, trusted-publisher, npm-access-staged-only, verify), the NEW brew tier (checksums-authority formula bumps, direct tap commits), github-release.mts (the registry-gated tag-gap healer), env-mapped SHA-pinned workflow templates, and the publishing-access permissive-then-staged-only machinery. Plus the sauce-side kit tooling: kit-manifest.json generator (--check), the channel-mapped installer (plan default, --apply, --force, --verify byte-parity, --json), three consumer examples with expected-install goldens, and the kit README (deferrals, contract-drift posture, first-publish/first-brew procedures with factory-rendered gates). shipped-surfaces classifies the new tree with a narrow marker allowlist for the shared browser-profile literal.
Four auto-discovered repo checks: release-kit-is-coherent (manifest freshness, fleet-marker leaks, no shipped tests, pure-module import discipline), release-kit-launches-are-sanctioned (the wheelhouse text scan over the payload plus the law self-check), release-kit-workflows-are-env-mapped (no expressions in run bodies, SHA-pinned dated uses, permissions + concurrency), and release-kit-types-resolve (the payload tsc program, release tier). The payload tree joins the repo-owned oxlint ignore tail: its bytes are the shipped product — kit-manifest.json pins them and every consumer byte-verifies them — so lint autofixes must never rewrite them; the kit's own gates lint it instead.
Five skills under skills/socket-release/: the user-invoked installer skill (clone sauce, install channels, pin deps, bootstrap through the gates, playwright law verbatim) and four agent skills that operate the shipped flows end to end — npm-publish (bootstrap with the publishing-access permissive/staged-only steps, staged dispatch, soak, --approve promote, backfill, deprecate-as-rollback), gh-release (ORDER RULE, immutable three-step cut, checksums.txt, tag-gap healing), crates-publish (staged model, trusted publishing, index-propagation wait, yank-as-rollback), and brew-tap (tap layout, formula bump, sha256 verification against the release's own manifest). Every command each skill names resolves to a shipped script; every human moment is a fleet gate. Marketplace + generated tables updated via generate.
Unit suites over the payload's pure core: plan DAG/resume/receipts, state round-trip + contextKey invalidation, render + the hand-rolled validateRunJson (accepts every committed run golden, rejects mutated documents), the eight-factory gate mirror, kit config accept/reject, preflight's ten check arms, placeholder consent + fail-closed classification, env probes with exact gh api argv fixes, staged-config byte-parity + conflict refusal + surgical package.json edit, trusted-publisher fail-closed trust reads + revoke-then-create argv, verify aggregation with the staged-only terminal assertion, the publishing-access parser over the three golden pages + unknown-shape refusal, brew formula round-trips + the four tap refusals with zero commits, install manifest/planner, and the checksum-writer grammar round-trip. Integration: the installer against real temp dirs per example (expected-install parity, idempotent second apply, --verify), and full in-process bootstrap runs on fully fake seams pinned to four run goldens with exit codes 0/2/3/4. All fixtures synthetic, authority-annotated; no test opens a socket or launches a browser.
Correctness (payload behavior): - staged/direct/workspace publishes resolve npm access (kit config -> publishConfig.access -> scoped/unscoped default) instead of hard-coding --access public, so a restricted package is no longer shipped public. - npm.distTag is now consumed: the staged --tag falls back to the kit config value, not a hard-coded 'latest'. - reject unknown flags across the registry-writing CLIs: npm-publish, cargo-publish, create-release diff parsed keys (camelCase-alias aware) and exit 2; github-release/brew-publish parse errors now exit 2, not 1. - npm-publish mode/backfill conflicts exit 2 (usage error), matching the bootstrap contract; --help names the real invocation, not `pnpm publish`. Stale references / duplication: - drop the phantom `publish-pipeline` mentions (npm-publish --help, approve, npm/shared); the healer is github-release.mts. - extract packumentUrl() + NPM_AUTH_TOKEN_KEY into constants/npm-registry.mts (8 inline copies + 3 hard-coded token keys collapsed); remove the unused NPM_REGISTRY export. - trusted-publisher-plan derives its CANONICAL_* from the single trustedPublisherLaw() so the browser plan and the registry sweep can never assert different desired shapes. - trim dangling check/doc citations and wheelhouse provenance from headers. - create-release: point the missing-config refusal at the real interface. Tests (was: zero release-time coverage): - publish-helpers: resolveNpmAccess (access-public regression guard), stageAction, readStagedShasum, packumentUrl, unknownFlags, extractChangelogSection. - trust-sweep: conformsToLaw pinned per law field (kills the surviving environment-comparison mutation). - registry-liveness-gate: runGate driven live/404/unreachable with an injected fetch, plus the pure decision functions. - typecheck the two release-kit test files that failed strict tsc.
- rename install/effects.mts -> install/seams.mts (Law 3: an injectable effect module is seams.mts); update all 7 referencing sites (installer, gen-manifest, 3 sauce checks, install test). - reclassify lib/commit-via-github-api.mts common -> brew in channelsForPath (its only importer is publish-infra/brew/tap.mts); regen kit-manifest.json; update npm-lib+rust-crate expected-install.json and manifest.test.mts. No runtime behavior change: the de-listed bytes were unreachable for npm/crates-only consumers. - README: add ARCHITECTURE (the npm thread walked file-by-file) + the naming law (10 rules), stating which are machine-enforced. - release-kit-is-coherent.mts: enforce naming law 1 (root-entry allowlist) and law 6 (suffix/.d.mts sidecar) mechanically. Skipped (documented): behavior-changing rows (soak backport, access-lifecycle forward-port, cli-flags content-adoption, create-release deletion, github-release registry hardcode) and fleet-canonical/cascade-owned rows (trust-sweep/trusted-publisher renames, check/script-paths-resolve move, skill renames).
…e to >=95%
Add fast-check (catalog 4.9.0) property suites for every fuzzable boundary in
the kit and back them with deterministic branch tests so coverage is stable:
- brew formula rewrite: arbitrary formula text + version/sha inputs yield a
valid rewritten formula or a loud refusal, never silent corruption
- npm access-state / trusted-publisher / staged-tarball page parsers, driven
by arbitrary HTML and single-byte mutations of the golden fixtures
- the pnpm-workspace catalog editor: splice/remove round-trips + idempotence
- installer manifest path handling: no traversal or clobbering outside target
- the drift / byte-parity checker: any single-byte mutation of a payload copy
is detected as a conflict
Fuzzing surfaced two real defects, fixed here:
- parseStagedPayload threw a TypeError on a valid-JSON null/primitive body; it
now degrades to an empty envelope (payload change, kit-manifest regenerated)
- the installer accepted manifest paths with ".." or an absolute/drive root; a
new isSafePayloadPath guard makes parseKitManifest refuse them loudly
Every pure module now clears >=95% lines and branches (parsers, plan, gates,
config at 100%; formula 96.8% branch; workspace-yaml 98.7%; render 98.3%).
Wire .config/repo/coverage.json so the coverage tooling measures the kit, and
retire the stale fuzz-tier exemption reason now that Tier-1 fast-check suites
cover the release-kit parsers.
- npm-publish.mts: disable yargs boolean-negation so --no-reconcile/--no-release/--no-scan bind their declared keys instead of writing phantom reconcile/release/scan keys that the unknown-flag guard rejected (exit 2); expose parsePublishArgs for regression coverage.
- release.mts extractChangelogSection: match the version at a heading boundary (end / space / ]) so 1.2.30 no longer answers for 1.2.3, nor 2.0.0-rc.1 for 2.0.0.
- registry-liveness-gate.mjs: resolve fs.globSync lazily via createRequire so the gate loads on the runner's system Node <22 (globSync is Node 22+); only the crates workspace-glob path needs it.
- brew-publish.mts + README: point the missing-checksums fix at github-release.mts --tag <tag> --release, not the dead create-release.mts.
- README naming law: add bootstrap.mts to the machine-enforced root allowlist, add release-kit-types-resolve to the sauce-side gates, fix install/{...,seams}.mts.
- SKILL.md backfill: add the mandatory non-latest --tag/dist-tag.
- Move every publish-infra/** and bootstrap/steps/** test to mirror its payload path (naming law rule 8) and add a structural enforcement test.
- Regenerate kit-manifest.json for the edited payload bytes.
…defects - npm-publish.mts: reject stray positionals (exit 2) via a new unexpectedPositionalsMessage so a dash-less mode typo (e.g. `approve` for `--approve`) no longer falls through to the default --staged path. - publish-infra/npm/staged.mts: gate runDirect's already-published heal on !dryRun so `--direct --dry-run` on a live version performs no tag/GH-release writes; emit a dry-run preview. runDirect gains root + release test seams. - bootstrap/seams.mts + publish-infra/shared.mts: resolve a sentinel non-zero code (127) on spawn ENOENT instead of rejecting, so a missing gh/git/pnpm degrades to preflight's designed red-check rather than an unhandled crash. - templates/.../mint-app-installation-token.mjs: drop the dangling scripts/socket-release/check/app-tokens-are-scoped.mts pointer (the real check is fleet-internal and unshipped) — name a fleet CI check, no path. - skills/socket-release/gh-release/SKILL.md: route "Cutting a release with assets" to github-release.mts (create-release.mts is the dead second entry, absent from real consumers). - kit-manifest.json regenerated; regression tests added for each code fix.
…release-subject redirect - README naming law rule 5 + npm-publish/SKILL.md: drop the "soak" phase from the two-phase-verb doctrine. The byte-authority payload ships no soak (no lib/soak.mts, no --soak/--skip-soak, no approve-time refusal), so npm/cargo promotion is `stage → approve`. Note crates.io has no dist-tags and no unpublish (its promote is a permanent one-way approve), and brew is a plan → apply formula bump tied to an already-published release. - test/repo/unit/release-kit/_shared/release-subject.test.mts: cover the publishConfig.directory redirect path end to end — the plain shape, the redirect shape, the repository fallback, and all four safety throws (empty/non-string directory, a directory escaping the repo root, a missing subject manifest, a subject manifest with no name/version). The escape guard had no test in the byte-authority; a mutation disabling it now fails.
John-David Dalton (jdalton)
force-pushed
the
main
branch
from
August 1, 2026 11:51
6e3b9d1 to
7f949ae
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follow-up to the merged #19. Repairs the CONFIRMED quality findings that reproduce in the sauce release-kit payload (the byte-authority). Verified against the adversarial findings set; findings that were jdm-aot-only or already-correct in sauce are documented rather than changed.
Correctness (payload behavior)
--accessno longer hard-coded public.runStaged/runDirect/runWorkspacePublishresolve access (kit config →publishConfig.access→ scoped/unscoped default) via a newresolveReleaseAccess, so a restricted package is no longer shipped public. Proven by a realbootstrap --dry-run:publish @acme/widget@0.0.0 --access restricted.npm.distTagis now consumed — staged--tagfalls back to the config value, not a hard-codedlatest.@socketsecurity/libparseArgs does not throw on unknown flags even understrict; npm-publish / cargo-publish / create-release now diff parsed keys (camelCase-alias aware) and exit 2. github-release / brew-publish parse errors exit 2 (were 1). Bootstrap already exits 2 (node:util strict).--helpnamesnode scripts/socket-release/npm-publish.mts, not the deadpnpm publish.Stale references / duplication
publish-pipelinementions (the healer isgithub-release.mts).packumentUrl()+NPM_AUTH_TOKEN_KEYintoconstants/npm-registry.mts(8 inline copies + 3 hard-coded token keys); removed the unusedNPM_REGISTRYexport.trusted-publisher-planderivesCANONICAL_*from the singletrustedPublisherLaw()— one law source.check//docs/citations and wheelhouse provenance from headers; fixed create-release's missing-config pointer.Tests (was: zero release-time coverage)
publish-helpers:resolveNpmAccess(access-public regression guard),stageAction,readStagedShasum,packumentUrl,unknownFlags,extractChangelogSection.trust-sweep:conformsToLawpinned per law field — kills the surviving environment-comparison mutation.registry-liveness-gate:runGatedriven live/404/unreachable with an injected fetch, plus the pure decision functions.Not changed (documented, with evidence)
playwright-law.mtsand the trusted-publisher browser quartet are live/intentional in sauce (imported by therelease-kit-launches-are-sanctionedcheck and allowlisted inrelease-kit-is-coherent), not dead as in jdm-aot.Gates
232 release-kit tests pass;
release-kit-is-coherent+release-kit-launches-are-sanctionedgreen; actionlint clean on all 4 workflow templates; payload + tests typecheck clean;bootstrap --help/--dry-runverified.