Skip to main content
← Back to list
01Issue
BugClosedSwamp CLIPublic
Assigneesskunk-ape

Relationships

#2197 Verification workflow guards read a nonexistent .attributes key on @swamp/git diff output, blocking all PRs

Opened by skunk-ape · 9/16/2026

The verify-reviews and verify-skills workflows both abort with:

InvalidExpressionError: Invalid expression: No such key: attributes

data.latest('repo', 'diff').attributes.files.filter(...)
                            ^

This blocks verification for every PR in the repo. Because no attestation can be produced, no PR can legitimately open — the validate-attestation CI gate has nothing to validate.

Root cause

The guards read data.latest('repo', 'diff').attributes.files, but the @swamp/git diff result has no attributes wrapper. At the currently pulled version (2026.09.15.1), DiffResultSchema is:

export const DiffResultSchema = z.object({
  files: z.array(z.string()),
  raw: z.string(),
  count: z.number().int(),
  base: z.string(),
  head: z.string(),
});

So files is top-level and the correct expression is data.latest('repo', 'diff').files.

This is extension drift, not a regression in the workflows. The .attributes spelling has been present since at least 8ce6f91f (2026-09-07) and worked then; a later @swamp/git release dropped the wrapper.

Affected guards

  • verification/workflow-verify-reviews.yaml:126 (adversarial-review)
  • verification/workflow-verify-reviews.yaml:166 (ux-review)
  • verification/workflow-verify-reviews.yaml:206 (ci-security-review)
  • verification/workflow-verify-skills.yaml — both skill-path guards

Reproduction

SWAMP_WORKFLOWS_DIR=verification swamp workflow run verify-reviews \
  --input commit=<SHA> --input branch=<branch>

detect-changes succeeds; the first guarded step then throws. Note that code-review is unguarded, so it runs and passes before the failure — the workflow still reports failed overall.

Proposed fix

Replace .attributes.files with .files in all five guards.

Worth considering alongside: the guards silently depend on an external extension's payload shape, and a shape change surfaces only as a run-time expression error. A contract test over DiffResultSchema, or pinning the @swamp/git version used by verification, would turn this class of drift into a build-time failure instead.

Notes

Found while verifying the fix for swamp-club#2181, which is blocked on this.

02Bog Flow
OPENTRIAGEDIN PROGRESSCLOSED+ 1 MOREASSIGNED

Closed

9/16/2026, 6:34:02 PM

No activity in this phase yet.

03Sludge Pulse
skunk-ape assigned skunk-ape9/16/2026, 6:32:40 PM
Editable. Press Enter to edit.

skunk-ape commented 9/16/2026, 6:34:02 PM

Duplicate of swamp-club#2188, which is already shipped (PR #2471, commit 245276a1).

My root-cause analysis here was wrong. I concluded the guards' .attributes spelling was stale against @swamp/git's DiffResultSchema and should become .files. That is incorrect — .attributes is the data-record wrapper and the spelling is right. The actual cause, per #2188, is that data.latest() could not see ephemeral data once #2468 introduced the light expression context, so the lookup returned an empty map and any .attributes access threw.

No change to the verification workflows is needed. The fix is in the binary; upgrading past 20260916.163631.0-sha.34d98319 resolves it.

Sign in to post a ripple.