Skip to main content
← Back to list
01Issue
FeatureClosedSwamp CLIPublic
AssigneesNone

Relationships

#3064 verify-reviews: whole-extension rubric review for changed hand-written extensions, carried in the attestation and read by publish (design: Lab #3023)

Opened by skunk-ape · 10/6/2026

Problem

Every CI publish carries the medium warning "No adversarial review recorded for the current code" because swamp's push gate wants a per-extension, content-hash-keyed report with a verdict on every applicable rubric dimension, and nothing in this repository produces one. The repo's adversarial-review step judges the pull request diff and records one verdict; that cannot honestly fill whole-extension dimension verdicts. Design and decisions are recorded on Lab #3023.

Change

  1. detect-changes prints a marker listing changed hand-written extension directories: each changed path whose nearest manifest.yaml is outside model/. Generated extensions never get this step (their review is the adversarial-review step on codegen/ plus verify-build's idempotency check).
  2. A new step extension-review in the reviews job of verification/workflow-verify-reviews.yaml, guarded on that marker, with the allowlist shape scripts/verification_harness_test.ts pins (Read, Glob, Grep, one Edit on the record file, one Bash on the submit command), prompt at verification/review-prompts/extension-review.md (the swamp skill's adversarial-review reference: mechanical checks, universal and type-specific dimensions, output format, plus the harness security note; no dimension ids in the prompt, they come from the skeleton). The Edit rule must expand to an absolute path (double leading slash), as the existing steps' Edit(/$RECORD_FILE) already does.
  3. Per changed extension the step copies the extension directory to a scratch location, runs swamp repo init there (hash convention: repo dir = extension dir, the layout publish.yml produces), sets SWAMP_EXTENSION_REVIEW_DIR to an empty directory, runs swamp extension push manifest.yaml --dry-run --json --yes, parses the adversarial-review-report finding (multi-document JSON stream, skeleton is a JSON string, hash only in the finding's file name) and writes the skeleton into the reviewer's record file. The verified worktree is never modified.
  4. extensions/models/review_record.ts: ReviewSubmissionSchema gains an optional extensions array of {name, version, contentHash, hashConvention, reviewedAt, dimensions: [{id, verdict pass|issue|na, note (capped)}]}. submit rejects a pending verdict and an issue verdict with no finding; decide treats an issue verdict backed by a critical or high finding as fail. After decide passes, the step verifies each entry's name, version and contentHash against the dry-run values it computed itself and fails on a mismatch, then prints the validated record on one marker line.
  5. scripts/build_attestation.ts projects the marker line from the step's persisted stdout (the run record keeps each step's stdout) into an optional attestation block extensionReviews keyed by extension name with version, contentHash, hashConvention, reviewedAt, model and dimensions. extensions/models/_lib/schemas.ts and scripts/validate_attestation.ts accept the block. verification/attestation.yaml pins the new prompt and names the step.
  6. .forgejo/workflows/publish.yml, before each push: resolve the commit to its merged pull request head through the Forgejo API (repos/{owner}/{repo}/commits/{sha}/pull), fetch GET api/v1/admin/attestations?commit= from swamp-club, require gate.allPassed, and for the extension being pushed write the extensionReviews entry as a report at SWAMP_EXTENSION_REVIEW_DIR/swamp-extension-review/-.json in swamp's report shape plus a provenance object {kind: attestation, commit, attestationId} (stripped by today's binary, read by the gate change in the swamp issue). Set SWAMP_EXTENSION_REVIEW_DIR in the push step's environment. A missing attestation or a hash mismatch leaves the warning in place; this is expected when another change to the same extension landed between attestation and merge.
  7. Docs: agent-constraints/verification-conventions.md review table and Attestation section; scripts/verification_harness_test.ts covers the new step; the ci-security-review and CI review-integrity gates fire on these paths and are expected.

Acceptance

  • A branch changing vault/aws-sm produces an attestation whose extensionReviews entry for @swamp/aws-sm has 12 non-pending verdicts and a contentHash equal to the hash a dry-run in publish.yml's layout computes for the same commit.
  • A branch changing only model/ or codegen/ skips extension-review by guard and the attestation records the guard skip.
  • A record whose name, version or contentHash differs from the step's dry-run values fails the step.
  • A merged change to a hand-written extension publishes without the adversarial-review-report warning; the acceptedWarnings record no longer lists it.
  • An intervening change to the same extension between attestation and merge leaves the warning in place, and the publish log says why.
  • scripts/verification_harness_test.ts passes with the new step and pins its allowlist.

Lab #3017 (dry-run JSON is several documents; the step parses a stream until it ships), #3018 (sub-directory extensions dry-run only from inside their directory; the scratch copy handles it), #3020 (generated declaration, not needed for this step), the swamp issue drafted beside this one for the gate change. Design: Lab #3023.

Out of scope

Any swamp or swamp-club change; per-model report granularity; reviewing generated extensions one by one.

02Bog Flow
✓OPEN○TRIAGED○IN PROGRESS◉CLOSED

Closed

10/6/2026, 2:10:53 PM

No activity in this phase yet.

03Sludge Pulse
Editable. Press Enter to edit.

stack72 commented 10/6/2026, 2:10:49 PM

@skunk-ape going to close this out - I have this in a swamp workflow for when we cut these across to swamp serve doing the work for us - we don't need to worry too much about this right now

Sign in to post a ripple.