From 10077c6d08feb1f7469c096c9516e6a0fe74800b Mon Sep 17 00:00:00 2001 From: SteveBot <1153461+unbraind@users.noreply.github.com> Date: Thu, 10 Sep 2026 23:53:13 +0200 Subject: [PATCH 1/2] Certify pm CLI 2026.9.10 and take the auditor fixes the lockfile withheld MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CI runs the repo-pinned binaries, not whatever is installed globally, so the pins decide what the gates actually exercise. Advance `@unbrained/pm-cli` 2026.9.7 -> 2026.9.10 (npm latest) and `pm-ops` 2026.9.7 -> 2026.9.9. The pm-ops bump is the one that matters. This repository already launched the canonical publish-attestation auditor from `pm-ops/attestation` rather than vendoring it, and declared it as `^2026.9.7` — so it read as tracking canonical. It was not: `npm ci` installs the lockfile, and the lockfile pinned exactly 2026.9.7. Measured with the 38-case bypass corpus, this repository admitted seven fail-open constructions — nonliteral-overwrite, nonliteral-overwrite-cmdsub, quoted-metachar-value, single-quoted-metachar-value, multiword-unreadable-tail, quoted-paren-in-substitution and unterminated-substitution — all of them closed upstream two releases ago. After the bump the corpus reports clean, with scripts/verify-release-publish-attestation.ts unchanged. Validation: npm test passes 299/299. --- .agents/pm/chores/pm-github-drwr.toon | 29 +++++++++++++++++++++++++ .agents/pm/history/pm-github-drwr.jsonl | 5 +++++ CHANGELOG.md | 6 +++++ package-lock.json | 16 +++++++------- package.json | 4 ++-- 5 files changed, 50 insertions(+), 10 deletions(-) create mode 100644 .agents/pm/chores/pm-github-drwr.toon create mode 100644 .agents/pm/history/pm-github-drwr.jsonl diff --git a/.agents/pm/chores/pm-github-drwr.toon b/.agents/pm/chores/pm-github-drwr.toon new file mode 100644 index 0000000..c46df46 --- /dev/null +++ b/.agents/pm/chores/pm-github-drwr.toon @@ -0,0 +1,29 @@ +id: pm-github-drwr +title: Certify pm CLI 2026.9.10 and pick up the canonical auditor fixes the lockfile was holding back +description: "CI runs the repo-pinned binaries, so the pins decide what the gates exercise. Advance @unbrained/pm-cli from 2026.9.7 to 2026.9.10, the published npm latest, and pm-ops from 2026.9.7 to 2026.9.9. The pm-ops range already read as a caret, so this repository read as tracking the canonical publish-attestation auditor; it was not, because npm ci installs the lockfile and the lockfile pinned 2026.9.7. Measured with the 38-case bypass corpus, this repository admitted seven fail-open constructions at the locked version and is clean at 2026.9.9, with the launcher unchanged." +type: Chore +status: closed +priority: 2 +tags: [] +created_at: "2026-09-10T21:53:08.100Z" +updated_at: "2026-09-10T21:53:11.365Z" +closed_at: "2026-09-10T21:53:11.331Z" +completed_at: "2026-09-10T21:53:11.331Z" +claim_principal: claude-orchestrator +author: claude-orchestrator +files[2]{path,scope}: + package-lock.json,project + package.json,project +tests[1]: + - command: npm test + scope: project + timeout_seconds: 2400 + provenance: + author: claude-orchestrator + created_at: "2026-09-10T21:53:10.554Z" + source_kind: local_mutation + source_ref: chore/certify-pm-cli-2026-9-10 + assert_stdout_contains[1]: pass 299 + note: Full suite under CLI 2026.9.10 and pm-ops 2026.9.9; the count assertion fails if the suite shrinks +close_reason: "Pins advanced: @unbrained/pm-cli 2026.9.7 to 2026.9.10, pm-ops 2026.9.7 to 2026.9.9. npm test passes 299 of 299 with zero failures. The publish-attestation bypass corpus reports clean for this repository after the bump, against seven admitted cases before it, with scripts/verify-release-publish-attestation.ts unchanged." +body: "" diff --git a/.agents/pm/history/pm-github-drwr.jsonl b/.agents/pm/history/pm-github-drwr.jsonl new file mode 100644 index 0000000..a95e82d --- /dev/null +++ b/.agents/pm/history/pm-github-drwr.jsonl @@ -0,0 +1,5 @@ +{"ts":"2026-09-10T21:53:08.100Z","author":"claude-orchestrator","author_source":"asserted","agent_harness":"claude-code","agent_model":"claude-opus-5","agent_model_source":"probe","agent_instance":"3a51a1fe5204a56374236921","agent_provenance":{"model":{"value":"claude-opus-5","source":"probe"},"effort":{"value":"xhigh","source":"environment"},"role":{"value":"implementer","source":"argv"},"topic":null,"version":{"value":"2.1.268","source":"probe"}},"op":"create","patch":[{"op":"add","path":"/metadata/id","value":"pm-github-drwr"},{"op":"add","path":"/metadata/title","value":"Certify pm CLI 2026.9.10 and pick up the canonical auditor fixes the lockfile was holding back"},{"op":"add","path":"/metadata/description","value":"CI runs the repo-pinned binaries, so the pins decide what the gates exercise. Advance @unbrained/pm-cli from 2026.9.7 to 2026.9.10, the published npm latest, and pm-ops from 2026.9.7 to 2026.9.9. The pm-ops range already read as a caret, so this repository read as tracking the canonical publish-attestation auditor; it was not, because npm ci installs the lockfile and the lockfile pinned 2026.9.7. Measured with the 38-case bypass corpus, this repository admitted seven fail-open constructions at the locked version and is clean at 2026.9.9, with the launcher unchanged."},{"op":"add","path":"/metadata/type","value":"Chore"},{"op":"add","path":"/metadata/status","value":"open"},{"op":"add","path":"/metadata/priority","value":2},{"op":"add","path":"/metadata/tags","value":[]},{"op":"add","path":"/metadata/created_at","value":"2026-09-10T21:53:08.100Z"},{"op":"add","path":"/metadata/updated_at","value":"2026-09-10T21:53:08.100Z"},{"op":"add","path":"/metadata/author","value":"claude-orchestrator"}],"before_hash":"3cc22dff72be7b14824654a7a64ea62b04799939b2fee54c1b5f52ca60bf6df0","after_hash":"9c351753f800eb019871e3af0fc6b5944c3c1c495b47ac49a67468bec437f248","item_hash_version":3,"message":"","event_class":"substantive","record_hash_version":1,"record_hash":"0c58cc9fd47b8e8154149e561fa938938abecfa24fdb16114941d4176d0cda21"} +{"ts":"2026-09-10T21:53:09.033Z","author":"claude-orchestrator","author_source":"asserted","agent_harness":"claude-code","agent_model":"claude-opus-5","agent_model_source":"probe","agent_instance":"3a51a1fe5204a56374236921","agent_provenance":{"model":{"value":"claude-opus-5","source":"probe"},"effort":{"value":"xhigh","source":"environment"},"role":{"value":"implementer","source":"argv"},"topic":null,"version":{"value":"2.1.268","source":"probe"}},"op":"claim","patch":[{"op":"replace","path":"/metadata/updated_at","value":"2026-09-10T21:53:09.033Z"},{"op":"add","path":"/metadata/assignee","value":"claude-orchestrator"},{"op":"add","path":"/metadata/claim_principal","value":"claude-orchestrator"}],"before_hash":"9c351753f800eb019871e3af0fc6b5944c3c1c495b47ac49a67468bec437f248","after_hash":"9212d4ff317b70a692a38609f23b620b30cbd4474bdd27b21e70a3e479250906","item_hash_version":3,"event_class":"substantive","record_hash_version":1,"record_hash":"607336b02abca37dd8ba126bb148fb2dd1a8b0a5eca7811554d4b46144584c8f"} +{"ts":"2026-09-10T21:53:09.793Z","author":"claude-orchestrator","author_source":"asserted","agent_harness":"claude-code","agent_model":"claude-opus-5","agent_model_source":"probe","agent_instance":"3a51a1fe5204a56374236921","agent_provenance":{"model":{"value":"claude-opus-5","source":"probe"},"effort":{"value":"xhigh","source":"environment"},"role":null,"topic":null,"version":{"value":"2.1.268","source":"probe"}},"op":"files_add","patch":[{"op":"replace","path":"/metadata/updated_at","value":"2026-09-10T21:53:09.793Z"},{"op":"add","path":"/metadata/files","value":[{"path":"package-lock.json","scope":"project"},{"path":"package.json","scope":"project"}]}],"before_hash":"9212d4ff317b70a692a38609f23b620b30cbd4474bdd27b21e70a3e479250906","after_hash":"8ab3ef4439cc71fca90eda801d175b89eab6e4a4623a62b9bfc4d7ad8f6b6e83","item_hash_version":3,"event_class":"maintenance","record_hash_version":1,"record_hash":"d822964c8afc707a0ccbd43bad73d73ec866eda274149ef98b280ce3667305b6"} +{"ts":"2026-09-10T21:53:10.580Z","author":"claude-orchestrator","author_source":"asserted","agent_harness":"claude-code","agent_model":"claude-opus-5","agent_model_source":"probe","agent_instance":"3a51a1fe5204a56374236921","agent_provenance":{"model":{"value":"claude-opus-5","source":"probe"},"effort":{"value":"xhigh","source":"environment"},"role":null,"topic":null,"version":{"value":"2.1.268","source":"probe"}},"op":"tests_add","patch":[{"op":"replace","path":"/metadata/updated_at","value":"2026-09-10T21:53:10.580Z"},{"op":"add","path":"/metadata/tests","value":[{"command":"npm test","scope":"project","timeout_seconds":2400,"provenance":{"author":"claude-orchestrator","created_at":"2026-09-10T21:53:10.554Z","source_kind":"local_mutation","source_ref":"chore/certify-pm-cli-2026-9-10"},"assert_stdout_contains":["pass 299"],"note":"Full suite under CLI 2026.9.10 and pm-ops 2026.9.9; the count assertion fails if the suite shrinks"}]}],"before_hash":"8ab3ef4439cc71fca90eda801d175b89eab6e4a4623a62b9bfc4d7ad8f6b6e83","after_hash":"c40a6b4fd81e080f35241436f737cce8a44928793389ba02906c03514d1f299f","item_hash_version":3,"event_class":"maintenance","record_hash_version":1,"record_hash":"3ebeab1d32078cd40397c1488ae6edd710c0bfbfe5f0b9d05ef70e8669336d03"} +{"ts":"2026-09-10T21:53:11.365Z","author":"claude-orchestrator","author_source":"asserted","agent_harness":"claude-code","agent_model":"claude-opus-5","agent_model_source":"probe","agent_instance":"3a51a1fe5204a56374236921","agent_provenance":{"model":{"value":"claude-opus-5","source":"probe"},"effort":{"value":"xhigh","source":"environment"},"role":{"value":"implementer","source":"argv"},"topic":null,"version":{"value":"2.1.268","source":"probe"}},"op":"close","patch":[{"op":"remove","path":"/metadata/assignee"},{"op":"replace","path":"/metadata/updated_at","value":"2026-09-10T21:53:11.365Z"},{"op":"replace","path":"/metadata/status","value":"closed"},{"op":"add","path":"/metadata/closed_at","value":"2026-09-10T21:53:11.331Z"},{"op":"add","path":"/metadata/completed_at","value":"2026-09-10T21:53:11.331Z"},{"op":"add","path":"/metadata/close_reason","value":"Pins advanced: @unbrained/pm-cli 2026.9.7 to 2026.9.10, pm-ops 2026.9.7 to 2026.9.9. npm test passes 299 of 299 with zero failures. The publish-attestation bypass corpus reports clean for this repository after the bump, against seven admitted cases before it, with scripts/verify-release-publish-attestation.ts unchanged."}],"before_hash":"c40a6b4fd81e080f35241436f737cce8a44928793389ba02906c03514d1f299f","after_hash":"c7c543a62bd4517b640d7e16b8c71009bbb26d550347fc43afb585ca629de529","item_hash_version":3,"event_class":"substantive","record_hash_version":1,"record_hash":"e623811374e0d4bf274f50834f2254356f70372f60253d5cab8362ddd2f65f10"} diff --git a/CHANGELOG.md b/CHANGELOG.md index 69a584a..ffd1109 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## Unreleased + +### Other + +- Certify pm CLI 2026.9.10 and pick up the canonical auditor fixes the lockfile was holding back ([pm-github-drwr](https://github.com/unbraind/pm-github/blob/main/.agents/pm/chores/pm-github-drwr.toon)) + ## 2026.9.8 - 2026-09-08 ### Security diff --git a/package-lock.json b/package-lock.json index 38b8d1b..87fbeaa 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,9 +10,9 @@ "license": "MIT", "devDependencies": { "@types/node": "^26.1.1", - "@unbrained/pm-cli": "2026.9.7", + "@unbrained/pm-cli": "2026.9.10", "pm-changelog": "2026.9.6", - "pm-ops": "^2026.9.7", + "pm-ops": "^2026.9.9", "typescript": "^7.0.2" }, "engines": { @@ -669,9 +669,9 @@ } }, "node_modules/@unbrained/pm-cli": { - "version": "2026.9.7", - "resolved": "https://registry.npmjs.org/@unbrained/pm-cli/-/pm-cli-2026.9.7.tgz", - "integrity": "sha512-EbyrHyYVHqk2qyhRNPlu892npbSR7Sgd2C65rIacWKVdDuIdDLv6GqkTq9O23u4zoGwhgvK1mAYCvlpE8skSvw==", + "version": "2026.9.10", + "resolved": "https://registry.npmjs.org/@unbrained/pm-cli/-/pm-cli-2026.9.10.tgz", + "integrity": "sha512-MZQor/cbmacHsJ9mg5Roj6VHa8kz9aD9poi9zMyU/k3Y8k5fAgSGl/oupIoW4n5IWfNO4MLmIECaCcI5JWSgxg==", "dev": true, "license": "MIT", "dependencies": { @@ -998,9 +998,9 @@ } }, "node_modules/pm-ops": { - "version": "2026.9.7", - "resolved": "https://registry.npmjs.org/pm-ops/-/pm-ops-2026.9.7.tgz", - "integrity": "sha512-fU+j8c/r4zmo4WMJBrifeZQxEUwtQPoQe1jLCgh2/MXQog0eVJEChRFgCv4zwNWEcSVFBz7vr5AMUrv0jov7SA==", + "version": "2026.9.9", + "resolved": "https://registry.npmjs.org/pm-ops/-/pm-ops-2026.9.9.tgz", + "integrity": "sha512-OY6Ces3qRDCO5wGOsJgYo4Tqu5ykSMwwDfvBKUeJEJCp9QbDPzZxw5uHqERTidVLzHeYQTgzpJFKj694VuzcuQ==", "dev": true, "license": "MIT", "dependencies": { diff --git a/package.json b/package.json index 699e109..d1f2dae 100644 --- a/package.json +++ b/package.json @@ -45,9 +45,9 @@ }, "devDependencies": { "@types/node": "^26.1.1", - "@unbrained/pm-cli": "2026.9.7", + "@unbrained/pm-cli": "2026.9.10", "pm-changelog": "2026.9.6", - "pm-ops": "^2026.9.7", + "pm-ops": "^2026.9.9", "typescript": "^7.0.2" }, "keywords": [ From 92827ad015a7245ff91e2daf5e73443e9234476f Mon Sep 17 00:00:00 2001 From: SteveBot <1153461+unbraind@users.noreply.github.com> Date: Fri, 11 Sep 2026 00:28:35 +0200 Subject: [PATCH 2/2] Guard the seven bypasses at consumer level, not just by bumping past them Greptile and CodeRabbit both raised the same gap on the first push: the dependency bump closes seven fail-open cases, but nothing in this repository exercised them, and the item's clean-corpus claim had no structured test behind it. The corpus that measured them lives in the private companion, so nothing here failed while this repository was installing an auditor that accepted all seven, and nothing would fail again if a later lockfile change put one back. Add two tests to test/verify-release-publish-attestation.test.ts: - all seven constructions are run through `auditPublishAttestation` from the installed pm-ops and each must be refused. This asserts BEHAVIOUR, not a version: a floor would still accept a regressed release numbered above it. - a positive control: a readable `--provenance` binding must still pass. Without it the first test passes against an auditor that refuses everything, which would be just as broken and easier to ship. Revert-check: with pm-ops downgraded to 2026.9.7 the first test goes RED naming the nonliteral-overwrite construction, while the control stays green. Restoring 2026.9.9 returns the suite to 301/301. --- .agents/pm/chores/pm-github-drwr.toon | 23 ++++++--- .agents/pm/history/pm-github-drwr.jsonl | 4 ++ ...verify-release-publish-attestation.test.ts | 49 +++++++++++++++++++ 3 files changed, 70 insertions(+), 6 deletions(-) diff --git a/.agents/pm/chores/pm-github-drwr.toon b/.agents/pm/chores/pm-github-drwr.toon index c46df46..91b6915 100644 --- a/.agents/pm/chores/pm-github-drwr.toon +++ b/.agents/pm/chores/pm-github-drwr.toon @@ -6,15 +6,16 @@ status: closed priority: 2 tags: [] created_at: "2026-09-10T21:53:08.100Z" -updated_at: "2026-09-10T21:53:11.365Z" -closed_at: "2026-09-10T21:53:11.331Z" -completed_at: "2026-09-10T21:53:11.331Z" +updated_at: "2026-09-10T22:28:34.162Z" +closed_at: "2026-09-10T22:28:34.149Z" +completed_at: "2026-09-10T22:28:34.149Z" claim_principal: claude-orchestrator author: claude-orchestrator -files[2]{path,scope}: +files[3]{path,scope}: package-lock.json,project package.json,project -tests[1]: + test/verify-release-publish-attestation.test.ts,project +tests[2]: - command: npm test scope: project timeout_seconds: 2400 @@ -25,5 +26,15 @@ tests[1]: source_ref: chore/certify-pm-cli-2026-9-10 assert_stdout_contains[1]: pass 299 note: Full suite under CLI 2026.9.10 and pm-ops 2026.9.9; the count assertion fails if the suite shrinks -close_reason: "Pins advanced: @unbrained/pm-cli 2026.9.7 to 2026.9.10, pm-ops 2026.9.7 to 2026.9.9. npm test passes 299 of 299 with zero failures. The publish-attestation bypass corpus reports clean for this repository after the bump, against seven admitted cases before it, with scripts/verify-release-publish-attestation.ts unchanged." + - command: node --test test/verify-release-publish-attestation.test.ts + scope: project + timeout_seconds: 900 + provenance: + author: claude-orchestrator + created_at: "2026-09-10T22:28:33.156Z" + source_kind: local_mutation + source_ref: chore/certify-pm-cli-2026-9-10 + assert_stdout_contains[1]: the installed auditor refuses every known fail-open provenance handoff + note: "Consumer-level fail-open regression guard; verified RED against pm-ops 2026.9.7 and green at 2026.9.9, with the positive control green in both" +close_reason: "Pins advanced: @unbrained/pm-cli 2026.9.7 to 2026.9.10, pm-ops 2026.9.7 to 2026.9.9. Greptile and CodeRabbit both observed that the bump closed seven fail-open cases without leaving anything in this repository that would notice if they returned, and that the clean-corpus claim had no structured test behind it. Both are correct. Added two tests to test/verify-release-publish-attestation.test.ts: the seven constructions are run through auditPublishAttestation from the installed pm-ops and each must be refused, plus a positive control asserting a readable --provenance binding still passes. The guard asserts behaviour rather than a version number, so it also fails against a regressed release numbered above any floor. Revert-check: with pm-ops downgraded to 2026.9.7 the guard goes RED naming the nonliteral-overwrite construction while the control stays green; restoring 2026.9.9 returns the suite to 301 of 301. The 38-case corpus itself stays in the private companion because it is fleet infrastructure, so the linked test names the local guard, which is the part that is runnable here." body: "" diff --git a/.agents/pm/history/pm-github-drwr.jsonl b/.agents/pm/history/pm-github-drwr.jsonl index a95e82d..8a13df9 100644 --- a/.agents/pm/history/pm-github-drwr.jsonl +++ b/.agents/pm/history/pm-github-drwr.jsonl @@ -3,3 +3,7 @@ {"ts":"2026-09-10T21:53:09.793Z","author":"claude-orchestrator","author_source":"asserted","agent_harness":"claude-code","agent_model":"claude-opus-5","agent_model_source":"probe","agent_instance":"3a51a1fe5204a56374236921","agent_provenance":{"model":{"value":"claude-opus-5","source":"probe"},"effort":{"value":"xhigh","source":"environment"},"role":null,"topic":null,"version":{"value":"2.1.268","source":"probe"}},"op":"files_add","patch":[{"op":"replace","path":"/metadata/updated_at","value":"2026-09-10T21:53:09.793Z"},{"op":"add","path":"/metadata/files","value":[{"path":"package-lock.json","scope":"project"},{"path":"package.json","scope":"project"}]}],"before_hash":"9212d4ff317b70a692a38609f23b620b30cbd4474bdd27b21e70a3e479250906","after_hash":"8ab3ef4439cc71fca90eda801d175b89eab6e4a4623a62b9bfc4d7ad8f6b6e83","item_hash_version":3,"event_class":"maintenance","record_hash_version":1,"record_hash":"d822964c8afc707a0ccbd43bad73d73ec866eda274149ef98b280ce3667305b6"} {"ts":"2026-09-10T21:53:10.580Z","author":"claude-orchestrator","author_source":"asserted","agent_harness":"claude-code","agent_model":"claude-opus-5","agent_model_source":"probe","agent_instance":"3a51a1fe5204a56374236921","agent_provenance":{"model":{"value":"claude-opus-5","source":"probe"},"effort":{"value":"xhigh","source":"environment"},"role":null,"topic":null,"version":{"value":"2.1.268","source":"probe"}},"op":"tests_add","patch":[{"op":"replace","path":"/metadata/updated_at","value":"2026-09-10T21:53:10.580Z"},{"op":"add","path":"/metadata/tests","value":[{"command":"npm test","scope":"project","timeout_seconds":2400,"provenance":{"author":"claude-orchestrator","created_at":"2026-09-10T21:53:10.554Z","source_kind":"local_mutation","source_ref":"chore/certify-pm-cli-2026-9-10"},"assert_stdout_contains":["pass 299"],"note":"Full suite under CLI 2026.9.10 and pm-ops 2026.9.9; the count assertion fails if the suite shrinks"}]}],"before_hash":"8ab3ef4439cc71fca90eda801d175b89eab6e4a4623a62b9bfc4d7ad8f6b6e83","after_hash":"c40a6b4fd81e080f35241436f737cce8a44928793389ba02906c03514d1f299f","item_hash_version":3,"event_class":"maintenance","record_hash_version":1,"record_hash":"3ebeab1d32078cd40397c1488ae6edd710c0bfbfe5f0b9d05ef70e8669336d03"} {"ts":"2026-09-10T21:53:11.365Z","author":"claude-orchestrator","author_source":"asserted","agent_harness":"claude-code","agent_model":"claude-opus-5","agent_model_source":"probe","agent_instance":"3a51a1fe5204a56374236921","agent_provenance":{"model":{"value":"claude-opus-5","source":"probe"},"effort":{"value":"xhigh","source":"environment"},"role":{"value":"implementer","source":"argv"},"topic":null,"version":{"value":"2.1.268","source":"probe"}},"op":"close","patch":[{"op":"remove","path":"/metadata/assignee"},{"op":"replace","path":"/metadata/updated_at","value":"2026-09-10T21:53:11.365Z"},{"op":"replace","path":"/metadata/status","value":"closed"},{"op":"add","path":"/metadata/closed_at","value":"2026-09-10T21:53:11.331Z"},{"op":"add","path":"/metadata/completed_at","value":"2026-09-10T21:53:11.331Z"},{"op":"add","path":"/metadata/close_reason","value":"Pins advanced: @unbrained/pm-cli 2026.9.7 to 2026.9.10, pm-ops 2026.9.7 to 2026.9.9. npm test passes 299 of 299 with zero failures. The publish-attestation bypass corpus reports clean for this repository after the bump, against seven admitted cases before it, with scripts/verify-release-publish-attestation.ts unchanged."}],"before_hash":"c40a6b4fd81e080f35241436f737cce8a44928793389ba02906c03514d1f299f","after_hash":"c7c543a62bd4517b640d7e16b8c71009bbb26d550347fc43afb585ca629de529","item_hash_version":3,"event_class":"substantive","record_hash_version":1,"record_hash":"e623811374e0d4bf274f50834f2254356f70372f60253d5cab8362ddd2f65f10"} +{"ts":"2026-09-10T22:28:32.686Z","author":"claude-orchestrator","author_source":"asserted","agent_harness":"claude-code","agent_model":"claude-opus-5","agent_model_source":"probe","agent_instance":"3a51a1fe5204a56374236921","agent_provenance":{"model":{"value":"claude-opus-5","source":"probe"},"effort":{"value":"xhigh","source":"environment"},"role":null,"topic":null,"version":{"value":"2.1.268","source":"probe"}},"op":"reopen","patch":[{"op":"remove","path":"/metadata/close_reason"},{"op":"remove","path":"/metadata/completed_at"},{"op":"remove","path":"/metadata/closed_at"},{"op":"replace","path":"/metadata/updated_at","value":"2026-09-10T22:28:32.686Z"},{"op":"replace","path":"/metadata/status","value":"open"}],"before_hash":"c7c543a62bd4517b640d7e16b8c71009bbb26d550347fc43afb585ca629de529","after_hash":"e8062a1c86821b82191043c9ebe7c7dcc617d261e8033bd8a0e8b365dd35a77d","item_hash_version":3,"context":{"recurrence":{"reason":"Bot review found the bump shipped without a regression guard; reopening to add one before this lands.","from_status":"closed","to_status":"open","previous_terminal":{"close_reason":"Pins advanced: @unbrained/pm-cli 2026.9.7 to 2026.9.10, pm-ops 2026.9.7 to 2026.9.9. npm test passes 299 of 299 with zero failures. The publish-attestation bypass corpus reports clean for this repository after the bump, against seven admitted cases before it, with scripts/verify-release-publish-attestation.ts unchanged."}}},"event_class":"substantive","record_hash_version":1,"record_hash":"484c389e111faf794a6d2106477b9afccaffd550b89cf05387e49e325533bb8c"} +{"ts":"2026-09-10T22:28:33.181Z","author":"claude-orchestrator","author_source":"asserted","agent_harness":"claude-code","agent_model":"claude-opus-5","agent_model_source":"probe","agent_instance":"3a51a1fe5204a56374236921","agent_provenance":{"model":{"value":"claude-opus-5","source":"probe"},"effort":{"value":"xhigh","source":"environment"},"role":null,"topic":null,"version":{"value":"2.1.268","source":"probe"}},"op":"tests_add","patch":[{"op":"add","path":"/metadata/tests/1","value":{"command":"node --test test/verify-release-publish-attestation.test.ts","scope":"project","timeout_seconds":900,"provenance":{"author":"claude-orchestrator","created_at":"2026-09-10T22:28:33.156Z","source_kind":"local_mutation","source_ref":"chore/certify-pm-cli-2026-9-10"},"assert_stdout_contains":["the installed auditor refuses every known fail-open provenance handoff"],"note":"Consumer-level fail-open regression guard; verified RED against pm-ops 2026.9.7 and green at 2026.9.9, with the positive control green in both"}},{"op":"replace","path":"/metadata/updated_at","value":"2026-09-10T22:28:33.181Z"}],"before_hash":"e8062a1c86821b82191043c9ebe7c7dcc617d261e8033bd8a0e8b365dd35a77d","after_hash":"54a76130899fc5605585d0e4b6b020d45c246adf35de3f0b548344eff29f20d2","item_hash_version":3,"event_class":"maintenance","record_hash_version":1,"record_hash":"c5ab84b46cc243af269c50cb028e79c4d3f3a46ace7f148c8d9a175ed6d7e745"} +{"ts":"2026-09-10T22:28:33.664Z","author":"claude-orchestrator","author_source":"asserted","agent_harness":"claude-code","agent_model":"claude-opus-5","agent_model_source":"probe","agent_instance":"3a51a1fe5204a56374236921","agent_provenance":{"model":{"value":"claude-opus-5","source":"probe"},"effort":{"value":"xhigh","source":"environment"},"role":null,"topic":null,"version":{"value":"2.1.268","source":"probe"}},"op":"files_add","patch":[{"op":"add","path":"/metadata/files/2","value":{"path":"test/verify-release-publish-attestation.test.ts","scope":"project"}},{"op":"replace","path":"/metadata/updated_at","value":"2026-09-10T22:28:33.664Z"}],"before_hash":"54a76130899fc5605585d0e4b6b020d45c246adf35de3f0b548344eff29f20d2","after_hash":"06e1de515b4e4831dda1778bc7077b2e57a598751ff3623707b525b490f33856","item_hash_version":3,"event_class":"maintenance","record_hash_version":1,"record_hash":"ba4dce548095967e2cf11cbf6d18e02895bfe85c61a0ebce6d4f8467ce5e1c1d"} +{"ts":"2026-09-10T22:28:34.162Z","author":"claude-orchestrator","author_source":"asserted","agent_harness":"claude-code","agent_model":"claude-opus-5","agent_model_source":"probe","agent_instance":"3a51a1fe5204a56374236921","agent_provenance":{"model":{"value":"claude-opus-5","source":"probe"},"effort":{"value":"xhigh","source":"environment"},"role":{"value":"implementer","source":"argv"},"topic":null,"version":{"value":"2.1.268","source":"probe"}},"op":"close","patch":[{"op":"replace","path":"/metadata/updated_at","value":"2026-09-10T22:28:34.162Z"},{"op":"replace","path":"/metadata/status","value":"closed"},{"op":"add","path":"/metadata/closed_at","value":"2026-09-10T22:28:34.149Z"},{"op":"add","path":"/metadata/completed_at","value":"2026-09-10T22:28:34.149Z"},{"op":"add","path":"/metadata/close_reason","value":"Pins advanced: @unbrained/pm-cli 2026.9.7 to 2026.9.10, pm-ops 2026.9.7 to 2026.9.9. Greptile and CodeRabbit both observed that the bump closed seven fail-open cases without leaving anything in this repository that would notice if they returned, and that the clean-corpus claim had no structured test behind it. Both are correct. Added two tests to test/verify-release-publish-attestation.test.ts: the seven constructions are run through auditPublishAttestation from the installed pm-ops and each must be refused, plus a positive control asserting a readable --provenance binding still passes. The guard asserts behaviour rather than a version number, so it also fails against a regressed release numbered above any floor. Revert-check: with pm-ops downgraded to 2026.9.7 the guard goes RED naming the nonliteral-overwrite construction while the control stays green; restoring 2026.9.9 returns the suite to 301 of 301. The 38-case corpus itself stays in the private companion because it is fleet infrastructure, so the linked test names the local guard, which is the part that is runnable here."}],"before_hash":"06e1de515b4e4831dda1778bc7077b2e57a598751ff3623707b525b490f33856","after_hash":"f0fb1b082c1b9d300924aa3a403f683b5ad599d37440f18dae7e0bfcad6002e9","item_hash_version":3,"event_class":"substantive","record_hash_version":1,"record_hash":"5ff89de3912576fe6c4f91e23968d7c5fc1c4753ecc9f022675e0eeaae50b0af"} diff --git a/test/verify-release-publish-attestation.test.ts b/test/verify-release-publish-attestation.test.ts index 7582fc2..9068921 100644 --- a/test/verify-release-publish-attestation.test.ts +++ b/test/verify-release-publish-attestation.test.ts @@ -74,6 +74,55 @@ test("the resolved gate still refuses an unattested publish", () => { assert.deepEqual(attested.recognition, { kind: "recognized", count: 1 }); }); +/** + * Shell constructions that hand `npm publish` an unreadable `--provenance` + * binding, each of which a fail-open auditor accepts as attested. + * + * These seven were admitted by the canonical auditor at pm-ops 2026.9.7 — the + * version this repository's lockfile installed until 2026.9.9 — and are refused + * from 2026.9.9 on. They are reproduced here, at consumer level, because a + * dependency bump is not a guard: nothing in this repository failed while it was + * installing an auditor that accepted all seven, and nothing would fail again if + * a later lockfile change put one back. The property asserted is behavioural — + * *this* construction is refused by whichever auditor is installed — not a + * version comparison, which would still pass against a regressed release + * numbered above any floor. + */ +const FAIL_OPEN_CONSTRUCTIONS: ReadonlyArray<{ id: string; script: string }> = [ + { id: "nonliteral-overwrite", script: "FLAG=--provenance\nFLAG=$OTHER\nnpm publish $FLAG --access public\n" }, + { id: "nonliteral-overwrite-cmdsub", script: "FLAG=--provenance\nFLAG=$(cat /tmp/x)\nnpm publish $FLAG --access public\n" }, + { id: "quoted-metachar-value", script: "FLAG=\"--provenance;\"\nnpm publish $FLAG --access public\n" }, + { id: "single-quoted-metachar-value", script: "FLAG='--provenance;'\nnpm publish $FLAG --access public\n" }, + { id: "multiword-unreadable-tail", script: "FLAG=--provenance\nNOOP=x FLAG=$(true)\nnpm publish $FLAG --access public\n" }, + { id: "quoted-paren-in-substitution", script: "FLAG=--provenance\nFLAG=$(printf ') ' )\nnpm publish $FLAG --access public\n" }, + { id: "unterminated-substitution", script: "FLAG=--provenance\nFLAG=$(unterminated\nnpm publish $FLAG --access public\n" }, +]; + +test("the installed auditor refuses every known fail-open provenance handoff", () => { + for (const { id, script } of FAIL_OPEN_CONSTRUCTIONS) { + const audited = auditPublishAttestation([ + { file: `.github/case-${id}.sh`, text: `#!/usr/bin/env bash\n${script}` }, + ]); + assert.ok( + audited.failures.length > 0, + `the installed pm-ops auditor accepted the ${id} construction as attested; ` + + "an unattested publish would reach the registry", + ); + } +}); + +test("the fail-open guard still admits a genuinely attested publish", () => { + // Without this control the guard above passes against an auditor that refuses + // everything, which would be just as broken and far easier to ship. + const audited = auditPublishAttestation([ + { + file: ".github/case-control.sh", + text: "#!/usr/bin/env bash\nFLAG=--provenance\nnpm publish $FLAG --access public\n", + }, + ]); + assert.deepEqual(audited.failures, [], "a readable --provenance binding must still pass"); +}); + test("this repository's own workflows pass the gate", () => { // The gate pointed at this checkout, which is what CI runs. Reported through // captured streams rather than the process ones so a failure is readable.