Skip to content

[v0.8 Release 1/3] bind artifacts to immutable source commits - #1176

Draft
sethkarten wants to merge 5 commits into
mainfrom
v080/release
Draft

[v0.8 Release 1/3] bind artifacts to immutable source commits#1176
sethkarten wants to merge 5 commits into
mainfrom
v080/release

Conversation

@sethkarten

@sethkarten sethkarten commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Phase 1 / 3 — immutable release provenance

Exact approved head: c41df11ff38405e2352da306a5367fed0dc9cd27
Branch: v080/releasemain

Narrow scope

REL01 exact provenance: bind release artifacts to the immutable source commit. The production workflow cleans and verifies the checked-out source before dependencies/build, permits only fixed generated dist overlays for packing, and packages non-generated inputs from a git archive of the asserted commit.

Validation and review evidence

  • Independently approved phase-1 head was asserted locally and on origin at the exact SHA above.
  • Clean worktree confirmed before publication.
  • git diff --check origin/main...HEAD passes.
  • Focused release-contract coverage at the approved head exercises rejection of untracked/ignored package inputs, permitted generated overlays with immutable tracked content, and the workflow clean boundary.

Dependencies

Standalone REL01 provenance foundation; no unmerged implementation dependency is introduced by this draft.

Deferred / explicitly excluded

This draft has no work from #1158#1165 and contains no ignored deferred work. It does not include later release phases beyond REL01.

Draft only: no reviewer requests and not ready for review yet.

Note

Bind release artifacts to immutable source commits for the v0.8 release pipeline

  • The build pipeline now resolves an immutable source_sha (peeled tag/commit) from package.json version validation before any build or publish step runs.
  • The build job checks out exactly that SHA, verifies a clean tracked state, sources non-dist content from a git archive snapshot, and passes --commit to the packer so artifacts carry the authoritative commit.
  • The publish job creates production tags exactly once via the GitHub refs API (no force), peels and re-validates the tag at multiple checkpoints, and verifies artifacts against source_sha before uploading.
  • New scripts — verify-prime-agent-release.mjs, pack-prime-agent-release.mjs, and prime-agent-release-components.mjs — enforce a fixed four-component inventory, SHA-256 checks, and commit binding across pack and verify steps.
  • Risk: any mismatch between the checked-out commit, the package.json version, and the production tag will now hard-fail the workflow rather than proceeding with a potentially inconsistent build.
📊 Macroscope summarized c41df11. 7 files reviewed, 0 issues evaluated, 0 issues filtered, 0 comments posted

🗂️ Filtered Issues

No issues evaluated.

Comment on lines +36 to +40
function authoritativeSourceCommit() {
const result = spawnSync("git", ["rev-parse", "HEAD"], { cwd: resolve(new URL("..", import.meta.url).pathname), encoding: "utf8" });
if (result.status !== 0) throw new Error(`Unable to resolve authoritative source HEAD: ${result.stderr.trim()}`);
return result.stdout.trim();
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟠 High scripts/verify-prime-agent-release.mjs:36

authoritativeSourceCommit uses new URL("..", import.meta.url).pathname as cwd for git rev-parse, which produces a percent-encoded path (e.g. /repo%20name/... for spaces, or /C:/... on Windows) instead of a valid filesystem path. When the checkout path contains spaces or non-ASCII characters, git rejects the cwd and the verifier fails; on Windows the drive-letter form also breaks. Use fileURLToPath from node:url to convert the URL to a real filesystem path before passing it to spawnSync.

Suggested change
function authoritativeSourceCommit() {
const result = spawnSync("git", ["rev-parse", "HEAD"], { cwd: resolve(new URL("..", import.meta.url).pathname), encoding: "utf8" });
if (result.status !== 0) throw new Error(`Unable to resolve authoritative source HEAD: ${result.stderr.trim()}`);
return result.stdout.trim();
}
function authoritativeSourceCommit() {
const result = spawnSync("git", ["rev-parse", "HEAD"], { cwd: fileURLToPath(new URL("..", import.meta.url)), encoding: "utf8" });
🚀 Reply "fix it for me" or copy this AI Prompt for your agent:
In file @scripts/verify-prime-agent-release.mjs around lines 36-40:

`authoritativeSourceCommit` uses `new URL("..", import.meta.url).pathname` as `cwd` for `git rev-parse`, which produces a percent-encoded path (e.g. `/repo%20name/...` for spaces, or `/C:/...` on Windows) instead of a valid filesystem path. When the checkout path contains spaces or non-ASCII characters, `git` rejects the `cwd` and the verifier fails; on Windows the drive-letter form also breaks. Use `fileURLToPath` from `node:url` to convert the URL to a real filesystem path before passing it to `spawnSync`.

const parsed = { artifactDir: undefined, channel: undefined, commit: undefined, dryRun: false, version: undefined };
for (let i = 0; i < args.length; i += 1) {
switch (args[i]) {
case "--artifact-dir": parsed.artifactDir = resolve(args[++i] || ""); break;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Medium scripts/verify-prime-agent-release.mjs:22

Passing --artifact-dir without a value at the end of the command makes resolve("") resolve to the current working directory, so parsed.artifactDir is set and the required-argument check passes. The verifier then silently validates artifacts in the invocation directory instead of rejecting the malformed command, and can report success for the wrong directory if it happens to contain a valid artifact set. Consider checking that args[i] is present and not another option before consuming it.

-			case "--artifact-dir": parsed.artifactDir = resolve(args[++i] || ""); break;
+			case "--artifact-dir": {
+				const dir = args[++i];
+				if (!dir || dir.startsWith("-")) throw new Error("--artifact-dir requires a value");
+				parsed.artifactDir = resolve(dir);
+				break;
+			}
🚀 Reply "fix it for me" or copy this AI Prompt for your agent:
In file @scripts/verify-prime-agent-release.mjs around line 22:

Passing `--artifact-dir` without a value at the end of the command makes `resolve("")` resolve to the current working directory, so `parsed.artifactDir` is set and the required-argument check passes. The verifier then silently validates artifacts in the invocation directory instead of rejecting the malformed command, and can report success for the wrong directory if it happens to contain a valid artifact set. Consider checking that `args[i]` is present and not another option before consuming it.

@sethkarten

Copy link
Copy Markdown
Contributor Author

v0.8 stack checkpoint — 2026-08-11 15:50 UTC

This draft PR remains the GitHub Release stack surface and will be kept current.

  • Latest source-approved local release candidate: 1062ef800918d38bdff149403b83c935a87edbee.
  • It passes 29/29 release contracts and implements separate immutable plan/receipt evidence, canonical pointer resolution, object readback/hash verification, and final-pointer-last publication.
  • It will be reconstructed onto the final parent-first Core/MCP/Prompts/ACP stack and then advanced here append-only/non-force.
  • Publication remains HOLD: final paired repository SHAs, clean-room builds, immutable evidence, rollback record, and human review are missing. Remote workflow-file publication also requires approved GitHub workflow scope.

No tag, version bump, release, or live publication has occurred.

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