Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions .agents/pm/chores/pm-github-u5qc.toon
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
id: pm-github-u5qc
title: Consume the canonical attestation gate instead of carrying a copy of it
description: "This repository carried its own 837-line shell scanner and 426-line verifier, duplicated from the same origin as every other package in the fleet. That gate decides whether an artefact may reach the registry, so a false pass is the failure that matters. The canonical implementation (pm-ops/attestation and pm-ops/shell-scan) has had fifteen fail-open constructions closed in it; the vendored copy is frozen and still admits constructions closed after that. BEFORE check.sh: 11 wrong. AFTER target: nonliteral-overwrite,nonliteral-overwrite-cmdsub only (plus any new corpus cases open in canonical)."
type: Chore
status: closed
priority: 1
tags[2]: attestation,security
created_at: "2026-09-07T10:05:34.490Z"
updated_at: "2026-09-07T10:31:52.885Z"
closed_at: "2026-09-07T10:16:57.788Z"
completed_at: "2026-09-07T10:16:57.788Z"
claim_principal: pi-agent
author: pi-agent
acceptance_criteria: Delete scripts/shell-command-scan.ts; Rewrite scripts/verify-release-publish-attestation.ts as thin launcher over pm-ops/attestation; Replace test suite to assert consumption not re-test shell model
comments[3]{created_at,author,text}:
"2026-09-07T10:16:40.082Z",pi-agent,"AFTER check.sh: nonliteral-overwrite,nonliteral-overwrite-cmdsub,quoted-metachar-value,single-quoted-metachar-value (4 wrong). Also fixed scripts/verify-release-changelog-date.sh: replaced $bin variable in command position with a run_changelog function, because the canonical auditor flags unresolved variables in command position as potential publish paths (by design - fail closed). BEFORE: 11 wrong. AFTER: 4 wrong, all 4 open in canonical pm-ops@2026.9.7."
"2026-09-07T10:28:17.727Z",claude,"Greptile found that the convergence guard did not actually guard. The test asserted that the symbols imported from pm-ops/attestation are functions, and its own comment claimed they were the launcher's functions by reference - but it never compared the two. A launcher that imports the package and then re-exports a local wrapper would have passed, which is exactly the re-fork the test exists to catch.\n\nThe test now imports the launcher's own bindings and asserts reference equality against the package's. Proven not vacuous: replacing the re-export with a local arrow wrapper that still calls through to the package makes the test fail, and restoring it makes it pass."
"2026-09-07T10:31:52.885Z",claude,"Greptile's rule about unreproduced behaviour claims caught a claim that was not merely unreproduced but WRONG. The launcher docstring said the auditor 'treats any file whose first two bytes are a shebang as executable shell'. Reproduced against the real auditor, that is false: a shebang says a file executes, not that it executes AS shell, and only a shebang naming a shell interpreter makes the body shell input.\n\nMeasured by writing this file into a throwaway git repository under four shebangs and calling verify():\n #!/bin/bash -> the file is reported by name (scanned as shell)\n #!/usr/bin/env sh -> reported by name\n #!/usr/bin/env node -> NOT reported (not shell input)\n no shebang -> NOT reported, which is why this file has none\n\nThe same wrong sentence is present in all seven repositories carrying this launcher, which is what propagating a fleet change by copying a reference file produces: the error travels with the text. Corrected here and in the five sibling convergence branches; pm-csv already has it on main and needs the same correction separately.\n\nThe claim is now reproduced in the suite rather than asserted."
close_reason: "Convergence complete. Deleted scripts/shell-command-scan.ts (837 lines), rewrote verify-release-publish-attestation.ts as thin launcher over pm-ops/attestation (426 to 57 lines), replaced test suite to assert consumption. Also fixed verify-release-changelog-date.sh to use a function instead of a variable in command position. BEFORE: 11 wrong. AFTER: 4 wrong (all 4 open in canonical pm-ops@2026.9.7). All gates pass: check, docstring, coverage, verify:release-publish-attestation, test (298 pass)."
body: ""
7 changes: 7 additions & 0 deletions .agents/pm/history/pm-github-u5qc.jsonl
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{"ts":"2026-09-07T10:05:34.490Z","author":"pi-agent","author_source":"asserted","agent_harness":"pi","agent_model":"glm-5.2:cloud","agent_model_source":"environment","agent_instance":"d306d30b6b3e7d89e0e68250","agent_provenance":{"model":{"value":"glm-5.2:cloud","source":"environment"},"effort":null,"role":{"value":"implementer","source":"argv"},"topic":null},"op":"create","patch":[{"op":"add","path":"/metadata/id","value":"pm-github-u5qc"},{"op":"add","path":"/metadata/title","value":"Consume the canonical attestation gate instead of carrying a copy of it"},{"op":"add","path":"/metadata/description","value":"This repository carried its own 837-line shell scanner and 426-line verifier, duplicated from the same origin as every other package in the fleet. That gate decides whether an artefact may reach the registry, so a false pass is the failure that matters. The canonical implementation (pm-ops/attestation and pm-ops/shell-scan) has had fifteen fail-open constructions closed in it; the vendored copy is frozen and still admits constructions closed after that. BEFORE check.sh: 11 wrong. AFTER target: nonliteral-overwrite,nonliteral-overwrite-cmdsub only (plus any new corpus cases open in canonical)."},{"op":"add","path":"/metadata/type","value":"Chore"},{"op":"add","path":"/metadata/status","value":"open"},{"op":"add","path":"/metadata/priority","value":1},{"op":"add","path":"/metadata/tags","value":["attestation","security"]},{"op":"add","path":"/metadata/created_at","value":"2026-09-07T10:05:34.490Z"},{"op":"add","path":"/metadata/updated_at","value":"2026-09-07T10:05:34.490Z"},{"op":"add","path":"/metadata/author","value":"pi-agent"},{"op":"add","path":"/metadata/acceptance_criteria","value":"Delete scripts/shell-command-scan.ts; Rewrite scripts/verify-release-publish-attestation.ts as thin launcher over pm-ops/attestation; Replace test suite to assert consumption not re-test shell model"}],"before_hash":"3cc22dff72be7b14824654a7a64ea62b04799939b2fee54c1b5f52ca60bf6df0","after_hash":"f382ed69201a76e63eacd2f3b1e39417c05a1515fd4b24ac81557cf76e088980","item_hash_version":3,"message":"","event_class":"substantive","record_hash_version":1,"record_hash":"3a0fc37fa19d84480df28a9978c0790e49c175ead4bde5bf8d76e303d96ccd7b"}
{"ts":"2026-09-07T10:05:41.772Z","author":"pi-agent","author_source":"asserted","agent_harness":"pi","agent_model":"glm-5.2:cloud","agent_model_source":"environment","agent_instance":"d306d30b6b3e7d89e0e68250","agent_provenance":{"model":{"value":"glm-5.2:cloud","source":"environment"},"effort":null,"role":null,"topic":null},"op":"claim","patch":[{"op":"replace","path":"/metadata/updated_at","value":"2026-09-07T10:05:41.772Z"},{"op":"add","path":"/metadata/assignee","value":"pi-agent"},{"op":"add","path":"/metadata/claim_principal","value":"pi-agent"}],"before_hash":"f382ed69201a76e63eacd2f3b1e39417c05a1515fd4b24ac81557cf76e088980","after_hash":"4cfe822bbf65e10c1064dc780ab18cd1d71720a178a685dc95cc1471587afab5","item_hash_version":3,"message":"Starting convergence: delete vendored scanner, rewrite attestation gate as thin launcher over pm-ops/attestation","event_class":"substantive","record_hash_version":1,"record_hash":"4e58a9e766385e57a985bf00bc8b32725ef3571d205ed98b757929dcdd5643bd"}
{"ts":"2026-09-07T10:05:41.813Z","author":"pi-agent","author_source":"asserted","agent_harness":"pi","agent_model":"glm-5.2:cloud","agent_model_source":"environment","agent_instance":"d306d30b6b3e7d89e0e68250","agent_provenance":{"model":{"value":"glm-5.2:cloud","source":"environment"},"effort":null,"role":null,"topic":null},"op":"update","patch":[{"op":"replace","path":"/metadata/updated_at","value":"2026-09-07T10:05:41.813Z"},{"op":"replace","path":"/metadata/status","value":"in_progress"}],"before_hash":"4cfe822bbf65e10c1064dc780ab18cd1d71720a178a685dc95cc1471587afab5","after_hash":"64e9836a075318fa7c25073d8915b2f50967d13d8000abc19b1d86666c19bd1c","item_hash_version":3,"message":"Starting convergence: delete vendored scanner, rewrite attestation gate as thin launcher over pm-ops/attestation","event_class":"substantive","record_hash_version":1,"record_hash":"59049802ce12a9804f5eaa7e647df73710d19fb2b7925d77f826a46456716bd1"}
{"ts":"2026-09-07T10:16:40.082Z","author":"pi-agent","author_source":"asserted","agent_harness":"pi","agent_model":"glm-5.2:cloud","agent_model_source":"environment","agent_instance":"d306d30b6b3e7d89e0e68250","agent_provenance":{"model":{"value":"glm-5.2:cloud","source":"environment"},"effort":null,"role":null,"topic":null},"op":"comment_add","patch":[{"op":"replace","path":"/metadata/updated_at","value":"2026-09-07T10:16:40.082Z"},{"op":"add","path":"/metadata/comments","value":[{"created_at":"2026-09-07T10:16:40.082Z","author":"pi-agent","text":"AFTER check.sh: nonliteral-overwrite,nonliteral-overwrite-cmdsub,quoted-metachar-value,single-quoted-metachar-value (4 wrong). Also fixed scripts/verify-release-changelog-date.sh: replaced $bin variable in command position with a run_changelog function, because the canonical auditor flags unresolved variables in command position as potential publish paths (by design - fail closed). BEFORE: 11 wrong. AFTER: 4 wrong, all 4 open in canonical pm-ops@2026.9.7."}]}],"before_hash":"64e9836a075318fa7c25073d8915b2f50967d13d8000abc19b1d86666c19bd1c","after_hash":"9d690d77f9fc77cad343bc2a1369d7e47a9ef876f4d5f492e0d7767f17965ebe","item_hash_version":3,"event_class":"substantive","record_hash_version":1,"record_hash":"0039443765892326b26a2c4029353a156534676a7bc9e2f130166a27c3dd84f7"}
{"ts":"2026-09-07T10:16:57.814Z","author":"pi-agent","author_source":"asserted","agent_harness":"pi","agent_model":"glm-5.2:cloud","agent_model_source":"environment","agent_instance":"d306d30b6b3e7d89e0e68250","agent_provenance":{"model":{"value":"glm-5.2:cloud","source":"environment"},"effort":null,"role":{"value":"implementer","source":"argv"},"topic":null},"op":"close","patch":[{"op":"remove","path":"/metadata/assignee"},{"op":"replace","path":"/metadata/updated_at","value":"2026-09-07T10:16:57.814Z"},{"op":"replace","path":"/metadata/status","value":"closed"},{"op":"add","path":"/metadata/closed_at","value":"2026-09-07T10:16:57.788Z"},{"op":"add","path":"/metadata/completed_at","value":"2026-09-07T10:16:57.788Z"},{"op":"add","path":"/metadata/close_reason","value":"Convergence complete. Deleted scripts/shell-command-scan.ts (837 lines), rewrote verify-release-publish-attestation.ts as thin launcher over pm-ops/attestation (426 to 57 lines), replaced test suite to assert consumption. Also fixed verify-release-changelog-date.sh to use a function instead of a variable in command position. BEFORE: 11 wrong. AFTER: 4 wrong (all 4 open in canonical pm-ops@2026.9.7). All gates pass: check, docstring, coverage, verify:release-publish-attestation, test (298 pass)."}],"before_hash":"9d690d77f9fc77cad343bc2a1369d7e47a9ef876f4d5f492e0d7767f17965ebe","after_hash":"4313a0e2d515a7bfaa440432d5e5ecb3246ff5c676e63b64e673db85134e20ca","item_hash_version":3,"message":"Convergence complete. Deleted scripts/shell-command-scan.ts (837 lines), rewrote verify-release-publish-attestation.ts as thin launcher over pm-ops/attestation (426 to 57 lines), replaced test suite to assert consumption. Also fixed verify-release-changelog-date.sh to use a function instead of a variable in command position. BEFORE: 11 wrong. AFTER: 4 wrong (all 4 open in canonical pm-ops@2026.9.7). All gates pass: check, docstring, coverage, verify:release-publish-attestation, test (298 pass).","event_class":"substantive","record_hash_version":1,"record_hash":"532eaf60807c289d1ad69e934ebccc45fdfc86b481271d6a68c9d090f1186d53"}
{"ts":"2026-09-07T10:28:17.727Z","author":"claude","author_source":"asserted","agent_harness":"claude-code","agent_model":"claude-opus-5","agent_model_source":"probe","agent_instance":"ac5fbc41d1fa70d2dee4261b","agent_provenance":{"model":{"value":"claude-opus-5","source":"probe"},"effort":{"value":"xhigh","source":"environment"},"role":null,"topic":null,"version":{"value":"2.1.263","source":"probe"}},"op":"comment_add","patch":[{"op":"add","path":"/metadata/comments/1","value":{"created_at":"2026-09-07T10:28:17.727Z","author":"claude","text":"Greptile found that the convergence guard did not actually guard. The test asserted that the symbols imported from pm-ops/attestation are functions, and its own comment claimed they were the launcher's functions by reference - but it never compared the two. A launcher that imports the package and then re-exports a local wrapper would have passed, which is exactly the re-fork the test exists to catch.\n\nThe test now imports the launcher's own bindings and asserts reference equality against the package's. Proven not vacuous: replacing the re-export with a local arrow wrapper that still calls through to the package makes the test fail, and restoring it makes it pass."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-09-07T10:28:17.727Z"}],"before_hash":"4313a0e2d515a7bfaa440432d5e5ecb3246ff5c676e63b64e673db85134e20ca","after_hash":"5500c1a301563b8e24b01a594f9fc588c8aab42b25b1273002afbe13d7cfcda6","item_hash_version":3,"message":"review round: the convergence guard did not guard","event_class":"substantive","record_hash_version":1,"record_hash":"3bd53e5f71444b344e4a03a8d55f26df2e26a6c36aa502aca88baddf0dab9f8b"}
{"ts":"2026-09-07T10:31:52.885Z","author":"claude","author_source":"asserted","agent_harness":"claude-code","agent_model":"claude-opus-5","agent_model_source":"probe","agent_instance":"ac5fbc41d1fa70d2dee4261b","agent_provenance":{"model":{"value":"claude-opus-5","source":"probe"},"effort":{"value":"xhigh","source":"environment"},"role":null,"topic":null,"version":{"value":"2.1.263","source":"probe"}},"op":"comment_add","patch":[{"op":"add","path":"/metadata/comments/2","value":{"created_at":"2026-09-07T10:31:52.885Z","author":"claude","text":"Greptile's rule about unreproduced behaviour claims caught a claim that was not merely unreproduced but WRONG. The launcher docstring said the auditor 'treats any file whose first two bytes are a shebang as executable shell'. Reproduced against the real auditor, that is false: a shebang says a file executes, not that it executes AS shell, and only a shebang naming a shell interpreter makes the body shell input.\n\nMeasured by writing this file into a throwaway git repository under four shebangs and calling verify():\n #!/bin/bash -> the file is reported by name (scanned as shell)\n #!/usr/bin/env sh -> reported by name\n #!/usr/bin/env node -> NOT reported (not shell input)\n no shebang -> NOT reported, which is why this file has none\n\nThe same wrong sentence is present in all seven repositories carrying this launcher, which is what propagating a fleet change by copying a reference file produces: the error travels with the text. Corrected here and in the five sibling convergence branches; pm-csv already has it on main and needs the same correction separately.\n\nThe claim is now reproduced in the suite rather than asserted."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-09-07T10:31:52.885Z"}],"before_hash":"5500c1a301563b8e24b01a594f9fc588c8aab42b25b1273002afbe13d7cfcda6","after_hash":"5ee745cb7cf27a05deab1f8cfed0a72f3d6a9d360e529c2afdf55bcf74b14aca","item_hash_version":3,"message":"correct a wrong shebang claim, reproduced","event_class":"substantive","record_hash_version":1,"record_hash":"331d5d45621c58dd7a2dc2075416ed74d81877473f039bafabd01ad83365b882"}
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changelog

## Unreleased

### Security

- Consume the canonical attestation gate instead of carrying a copy of it ([pm-github-u5qc](https://github.com/unbraind/pm-github/blob/main/.agents/pm/chores/pm-github-u5qc.toon))

## 2026.9.6 - 2026-09-06

### Fixed
Expand Down
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
"@types/node": "^26.1.1",
"@unbrained/pm-cli": "2026.9.5",
"pm-changelog": "2026.9.2",
"pm-ops": "^2026.9.5",
"pm-ops": "^2026.9.7",
"typescript": "^7.0.2"
},
"keywords": [
Expand Down
Loading