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
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