Skip to content

fix(C0-2): pin sovereign-ci.yml by sha; CB-2100 reachability finding filed (#3029) — PMAT-976 - #3031

Open
noahgift wants to merge 5 commits into
mainfrom
agent/C0-2
Open

fix(C0-2): pin sovereign-ci.yml by sha; CB-2100 reachability finding filed (#3029) — PMAT-976#3031
noahgift wants to merge 5 commits into
mainfrom
agent/C0-2

Conversation

@noahgift

@noahgift noahgift commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

Ticket

PMAT-976 · DAG row C0-2 · epic #2873 · issue #2891 · pp-066 inst:C C0-2

Claim

Pins .github/workflows/ci.yml's sovereign-ci.yml reference to a commit sha
(real, independent supply-chain-provenance value) and wires a guard proving it
stays pinned. Does not close CB-2100 — filed as #3029 with the full finding
(pinning does not change pmat's gate-effect reachability verdict; closing it for
real needs either six new ratchet-baseline rows for untracked comply debt, or
cross-repo manifest tooling in paiml/.github + pmat, neither in scope here).
Receipt is status: partial.

RED test (sha)

f46824526scripts/check_ci_reusable_workflow_pinned.sh added standalone
(ci.yml still @main); live check fails naming @main as "not a full 40-char
commit sha".

Acceptance (accept.sh output — re-run at HEAD)

A_i command result
A1 pmat comply check | grep CB-2100 shows ✓ NOT MET — still ✗, "whose steps this repository cannot read" (unchanged by the pin; see #3029)
A2 ci.yml references …sovereign-ci.yml@<sha>, not @main MET@4453399ee3794714800ff8db316ea7e1d3705a00
$ bash scripts/check_ci_reusable_workflow_pinned.sh --self-test
=== case table: check_ci_reusable_workflow_pinned.sh ===
  ok   ref: 40-char lowercase hex sha                 rc=0
  ok   ref: all-zero but valid 40-hex sha             rc=0
  ok   ref: @main (the registered mutation)           rc=1
  ok   ref: @master                                   rc=1
  ok   ref: a tag                                     rc=1
  ok   ref: a short (abbreviated) sha                 rc=1
  ok   ref: 40 chars but non-hex tail                 rc=1
  ok   ref: empty                                     rc=1
  ok   find_uses_ref: locates the pinned line         rc=0
  ok   find_uses_ref: extracts the exact sha          rc=0
  ok   find_uses_ref: locates the @main line too      rc=0
  ok   find_uses_ref: extracts "main" verbatim        rc=0
  ok   find_uses_ref: unrelated callee is not a match rc=1
  ok   find_uses_ref: missing file is not clean       rc=2
PASS: all cases behave as declared.

$ bash scripts/check_ci_reusable_workflow_pinned.sh
PASS: .github/workflows/ci.yml references paiml/.github/.github/workflows/sovereign-ci.yml@4453399ee3794714800ff8db316ea7e1d3705a00 (a pinned commit sha).

Reproduced against the real pre-fix tree directly (not only synthetic fixtures):
git show origin/main:.github/workflows/ci.yml swapped in → guard FAILs naming
@main; restored → PASSes.

Mutation (RED → GREEN)

Commit-level: f46824526 (guard only, ci.yml unpinned) is RED;
2e6a3805b (pin + wiring) is GREEN. CI-level: mutant commit a642a6077
(reverted the pin to @main) → guard-runner-labels job
101535304151
RED, step "ci.yml must pin sovereign-ci.yml by commit sha, not @main" failed
naming @main. Reverted at d06b21dc5guard-runner-labels job
101548517884
GREEN, both new steps passed.

Contract

contracts/apr-required-checks-v1.yaml (the DAG's named contract for this row)
— extended, not replaced: equation c0_2_reusable_workflow_pinned_by_sha,
proof obligation RC-OB-008, falsification test RC-F-008 bound to
check_ci_reusable_workflow_pinned.sh --self-test.

$ bash -c 'source scripts/pv_bin.sh; "$PV" validate contracts/apr-required-checks-v1.yaml'
0 error(s), 0 warning(s)
Contract is valid.

$ bash -c 'source scripts/pv_bin.sh; "$PV" lint contracts/ --diff origin/main'
Diff-aware: 1 contracts changed since origin/main
  apr-required-checks-v1
...
  Gate 4: verify               ✓  (26 refs, 26 found, 0 missing)
...
Summary: 0 errors, 1082 warnings, 0 suppressed
Result: PASS

$ bash scripts/check_contract_test_binding.sh
ok    ratchet  scripts/contract_test_binding_baseline.txt did not grow (0 removed) vs 3792afa3d
Resolved 530 test references; 27 dangling across 13 contract(s).
PASS: no contract cites more nonexistent tests than its baseline allows.

Quorum (teamwork, per DAG)

paiml-agy-delegate, lane=teamwork width=1, two runs (primary + mechanism-check
retry): both PROCEED/PASS, no dissent, on the plan (pin now, file the CB-2100
finding, receipt partial, continue to C0-4). The delegate's own receipt flags
this as a weak quorum — agy 1.1.27 headless -p mode did not engage true
/teamwork-preview fan-out (2 turns, ~27s each, zero child agents, every
finding grounding=asserted). Load-bearing evidence in this PR is the
orchestrator's own direct pmat-source reading and empirical reproduction (RED
against origin/main's real ci.yml, GREEN against the fix), not the quorum
lane. Recorded as a lesson in the delegate's agent-memory
(feedback_teamwork_lane_does_not_fan_out.md) for future sessions.

Receipt

docs/audits/impl-PMAT-976-receipt.mdstatus: partial. A2 met, A1 not;
follow-up tracked in #3029.

Writes

  • .github/workflows/ci.yml (sha pin + guard wiring)
  • contracts/apr-required-checks-v1.yaml (extended)
  • scripts/check_ci_reusable_workflow_pinned.sh (new)
  • docs/audits/impl-PMAT-976-receipt.md (new)

No shared file touched (check_row_pr_write_set.sh PASS): not
docs/specifications/pp-066-dag.yaml, not docs/roadmaps/roadmap.yaml, not
docs/specifications/PP-066-release-spec.md, no README count line.

Follow-up

#3029 — CB-2100 remedy (ratchet-baseline 6 untracked comply debts, or cross-repo
manifest tooling). Linked from #2891.

…s sovereign-ci.yml reference is not pinned

Guard is added standalone, before the fix, so its self-test case table and
its live check both run against the current (unpinned) ci.yml: the live
check fails, naming `@main` as "not a full 40-char commit sha". Fixed in the
next commit.

Pmat-Ticket: PMAT-976
…ire the guard into CI (PMAT-976, #2891)

.github/workflows/ci.yml's `ci` job now calls
paiml/.github@4453399
instead of @main — content-identical to @main at pin time (diffed), so this
is a pure provenance change: a mutable ref no longer re-resolves on every
push with no diff in this repository to review.

check_ci_reusable_workflow_pinned.sh (added RED in the prior commit) is now
wired into the guard-runner-labels job, self-test then live-check, following
the existing convention (e.g. check_test_fixture_paths.sh immediately
above). contracts/apr-required-checks-v1.yaml (the contract the DAG names
for C0-2) gains equation c0_2_reusable_workflow_pinned_by_sha, proof
obligation RC-OB-008, and falsification test RC-F-008 bound to the guard's
--self-test.

What this does NOT do: close CB-2100. Read directly from pmat 3.39.0 source
(services/gate_effect/resolve.rs::local_reusable_path), an external `uses:`
reference is `Resolution::Opaque` regardless of ref shape — branch, tag, or
sha. Confirmed empirically too: pinning left `pmat comply check`'s CB-2100
line byte-for-byte unchanged. The only mechanism CB-2100 currently
recognizes is a required, local job invoking `pmat comply check`/`comply
status` unsuppressed, and wiring that in today would red `ci / gate` /
`workspace-test` for every PR on six untracked pre-existing failures
(CB-040, CB-081, CB-400, CB-1305, CB-1308, CB-1650) that own no ticket in the
PP-066 DAG — see the header comment above `uses:` in ci.yml and #2891 (filed
alongside this PR) for the full finding and the follow-up it blocks on.

Pmat-Ticket: PMAT-976
@noahgift noahgift added pp-066 PP-066 (0.66) DAG row inst:C PP-066 instance claim (I14): inst:C C0-2 PP-066 DAG row C0-2 labels Sep 6, 2026
… turns CI RED

Registered mutation (RC-F-008 in contracts/apr-required-checks-v1.yaml).
Reverted in the next commit once CI is observed RED.

Pmat-Ticket: PMAT-976
@github-actions

github-actions Bot commented Sep 6, 2026

Copy link
Copy Markdown

§13.11 rung 1 — quorum shadow verdict

S13-SHADOW pr=3031 head=d06b21dc53c3e819177d5b823d725ebefe5eeb2a verdict=REFUSE class=Q1 arm_rc=1

Shadow mode: this records a verdict and merges nothing. A refusal
to arm is not a block (§13 adds zero rows to §7) — the pull request is
exactly as green as it was.

@noahgift
noahgift enabled auto-merge September 6, 2026 21:30
@noahgift

noahgift commented Sep 6, 2026

Copy link
Copy Markdown
Contributor Author

Auto-merge armed. Currently BLOCKED in the merge queue on two unrelated, already-tracked fleet issues (not this PR's diff): (1) #3028/PR #3030 — main's roadmap.yaml carries 12 legacy duplicate ids that pmat 3.39.0 rejects, redding ci / security on every PR; (2) a fleet-wide gap where scripts/pmat_bin.sh's pinned pmat 3.37.0 analyser is missing on at least two runner hosts (paiml/infra#468 comment). Will merge automatically via the queue once both clear.

@noahgift
noahgift disabled auto-merge September 7, 2026 11:53
noahgift added a commit that referenced this pull request Sep 8, 2026
…dogfood

`pmat work add` was not used, for the two reasons this ticket exists:

1. It allocates from the roadmap it can see. Max across origin/main and every
   open pp-066 head is PMAT-1079, and three instances are minting concurrently,
   so an auto-mint races. 1090 leaves 1080-1089 as headroom. A gap is opaque; a
   collision is data loss (and 12 duplicate ids on stale heads is what turned
   `ci / security` red on #3031 and #3001).

2. It re-serialises the whole file — the defect this ticket fixes.

The new `--staged` mode judged its own commit, which is the point:

    $ bash scripts/check_roadmap_diff_additive.sh --staged
    === roadmap.yaml STAGED diff is additive: base=c04eda87d (merge-base(origin/main, HEAD))
        head=8e4ceee37 (index tree) ===
    roadmap-diff: base=818 head=819 added=1 lifecycle=0 reserialised=0 deleted=0
    PASS

    $ git diff --cached --stat
    docs/roadmaps/roadmap.yaml | 19 +++++++++++++++++++

added=1, reserialised=0, 0 deletions. That is the diff the rule asks for, and
`pmat work add` cannot produce it — which is why the remedy script exists and
why nothing calling it made the rule unenforceable in practice.

Refs #3047, PMAT-1090.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EeUX4ymyt8XhjXbtTuNH8L
@noahgift noahgift added this to the 0.68.0 milestone Sep 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

C0-2 PP-066 DAG row C0-2 inst:C PP-066 instance claim (I14): inst:C pp-066 PP-066 (0.66) DAG row

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant