Skip to content

feat(ci): review-swarm GHA + hand-recovered from run 45b1974c coredump stall (replaces #74) - #75

Closed
kjgbot wants to merge 3 commits into
mainfrom
fix/gha-review-swarm-hand-recover
Closed

feat(ci): review-swarm GHA + hand-recovered from run 45b1974c coredump stall (replaces #74)#75
kjgbot wants to merge 3 commits into
mainfrom
fix/gha-review-swarm-hand-recover

Conversation

@kjgbot

@kjgbot kjgbot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Summary

Recovers the GHA review-swarm work from cloud run 45b1974c, which `DELIVER_FAIL_SYNC`'d because the sandbox left a coredump at `testdata/preflight/core` that `git apply` can't handle without a full index line. Stripped the coredump hunk from the patch, kept the GHA scaffold, dropped the ops churn, then hand-fixed the swarm's real findings from #74 before opening.

Diff

Just three files:

  • `.github/workflows/review-swarm.yml` (+82) — trigger on `kjgbot`/`miyaontherelay` PR events, launch `workflows/review-swarm.yaml` in cloud, poll status, hand off to `swarm-post.sh`
  • `.github/workflows/scripts/swarm-post.sh` (+79) — sync run, extract per-lens verdicts, post transcripts + one sticky aggregate marker
  • `README.md` (+2) — doc line for the required `RELAY_WORKSPACE_KEY` repo secret

Swarm findings from #74 addressed here

Maintainability blockers:

  • Poll loop only exited on `completed` — now handles `failed`/`errored`/`cancelled` explicitly, so a real failure doesn't masquerade as a 65-min timeout
  • Poll deadline 45m < swarm timeoutMs 60m — now 65m with a comment pinning the invariant

History blockers:

  • Aggregate verdict was `grep -q SWARM_PASSED` anywhere in the log — now takes the LAST `SWARM_` token (same fix commit `f59d9cd` made elsewhere)
  • Lens transcripts sorted by mtime, which is uniform on fresh checkouts — now sorted by FILENAME (`YYYYMMDD-HHMM` prefix), same fix commit `b2535aa` made elsewhere
  • Verdict was `grep -q REVIEW_FAILED` anywhere — now takes the last non-empty line's token so a passing review that quotes the token in prose doesn't misclassify

Additional hardening (concerns from #74):

  • Missing/unclear lens degrades aggregate to FAILED (not silent partial signal)
  • Marker uses hidden HTML comment and edits in place across re-runs — N pushes get 1 marker, not N
  • Kept the hidden-marker+edit-in-place pattern separate from the marker text so the greppable string doesn't change

Prerequisites (also flagged in #74's assessor NEEDS_HUMAN)

  • `RELAY_WORKSPACE_KEY` must exist as a GitHub Actions secret on `AgentWorkforce/flows`. Workspace key is on the laptop at `~/.agentworkforce/relay/cloud-auth.json`. `gh secret list --repo AgentWorkforce/flows` will tell you if it's already there.

Test plan

  • `yaml.safe_load` on `review-swarm.yml` — parses
  • `bash -n swarm-post.sh` — parses
  • Swarm review (this PR)
  • First real fire on a subsequent PR after merge

Recovered from cloud run 45b1974c (drive) after DELIVER_FAIL_SYNC —
the sandbox left a coredump at testdata/preflight/core that git apply
couldn't handle. Stripped the coredump hunk from the patch, kept the
GHA scaffold, then hand-fixed the swarm findings on the prior attempt
(#74) before opening.

Files:
- .github/workflows/review-swarm.yml — trigger on kjgbot/miyaontherelay PR
  events, launch workflows/review-swarm.yaml in cloud, poll status, hand
  off to swarm-post.sh
- .github/workflows/scripts/swarm-post.sh — sync run, extract per-lens
  verdicts, post transcripts + one sticky aggregate marker
- README.md — one-line doc for the required RELAY_WORKSPACE_KEY secret

Addresses swarm findings on #74:
- Poll loop now exits on ALL terminal states (failed/errored/cancelled),
  not just completed — a real failure won't masquerade as a 65-min
  timeout
- Poll deadline is 65m (was 45m) so it always ≥ the swarm's own 60m
  timeoutMs plus buffer, with a comment pinning the invariant
- Aggregate verdict is LAST SWARM_ token (not substring anywhere) —
  same pattern commit f59d9cd fixed elsewhere
- Lens verdicts sort by FILENAME (YYYYMMDD-HHMM prefix), not mtime —
  same pattern commit b2535aa fixed elsewhere
- Verdict is last non-empty line's token, not whole-file grep — a
  passing review that quotes REVIEW_FAILED won't misclassify
- Missing/unclear lens degrades aggregate to FAILED
- Marker uses hidden HTML comment and edits in place across re-runs —
  a PR with N pushes gets 1 marker, not N
@coderabbitai

coderabbitai Bot commented Aug 31, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

Next included review available in 22 minutes.

View limit details

Limit details: You’ve used the included review currently available.

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Free

Run ID: 91bdaef6-e573-49d1-85c3-c3a5fa882f6f

📥 Commits

Reviewing files that changed from the base of the PR and between 21af08e and 68b5e28.

📒 Files selected for processing (2)
  • .github/workflows/review-swarm.yml
  • .github/workflows/scripts/swarm-post.sh
ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Free

Run ID: 746a6379-c03d-443c-a701-9ddbca0f234b

📥 Commits

Reviewing files that changed from the base of the PR and between 7331e12 and 21af08e.

📒 Files selected for processing (3)
  • .github/workflows/review-swarm.yml
  • .github/workflows/scripts/swarm-post.sh
  • README.md

Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

The pull-request workflow now launches and monitors an Agent Relay Cloud review swarm for approved authors. A reporting script synchronizes results, posts transcripts, and maintains a sticky status comment. The README documents the required workspace secret.

Changes

Review swarm automation

Layer / File(s) Summary
Workflow setup and swarm launch
.github/workflows/review-swarm.yml
The workflow filters pull-request authors, checks out the merge commit, installs agent-relay@11.8.7, and launches the cloud review swarm.
Swarm monitoring and handoff
.github/workflows/review-swarm.yml
The workflow polls swarm status, handles terminal states, enforces a 65-minute deadline, and invokes the reporting script.
Result synchronization and pull-request reporting
.github/workflows/scripts/swarm-post.sh, README.md
The script validates inputs, extracts aggregate and lens verdicts, posts transcripts, updates or creates a sticky marker comment, and documents the required RELAY_WORKSPACE_KEY secret.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Merge Risk: ⚪ Minimal · up to 21af0

This change adds the review-swarm workflow, result posting script, and required-secret documentation; no actionable merge-blocking risk remains after normal checks and review.

Sequence Diagram(s)

sequenceDiagram
  participant PullRequest
  participant GitHubActions
  participant AgentRelayCloud
  participant SwarmPost
  PullRequest->>GitHubActions: eligible pull request event
  GitHubActions->>AgentRelayCloud: launch review swarm
  AgentRelayCloud-->>GitHubActions: swarm run identifier
  GitHubActions->>AgentRelayCloud: poll swarm status
  AgentRelayCloud-->>GitHubActions: terminal status
  GitHubActions->>SwarmPost: pass run identifier and pull request number
  SwarmPost->>AgentRelayCloud: synchronize run and retrieve logs
  AgentRelayCloud-->>SwarmPost: verdicts and transcripts
  SwarmPost->>PullRequest: post review comments and update marker
Loading

Poem

A rabbit checks the swarm at dawn
Cloud verdicts hop from dusk till morn
Lens transcripts line up neat
Sticky markers stamp the beat
Pull requests bloom with review notes
And carrots guard the workflow gates


Note

🎁 Summarized by CodeRabbit Free

Your organization is on the Free plan. CodeRabbit will generate a high-level summary and a walkthrough for each pull request. For a comprehensive line-by-line review, please upgrade your subscription to CodeRabbit Pro by visiting https://app.coderabbit.ai/settings/billing.

Comment @coderabbitai help to get the list of available commands.

@kjgbot

kjgbot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor Author

maintainability lens — PASS

Maintainability review — PR #75

Read AGENTS.md and workflows/review-swarm.yaml for context. The diff wires a GHA-triggered cloud review swarm plus a comment-poster script. Overall the diff is well-commented; the top of swarm-post.sh cites the two prior bug commits (b2535aa, f59d9cd) that motivated its parsing rules, which is exactly the "why" a six-month-later reader needs. That's the bar. My concerns are about implicit contracts and fail-closed discipline (AGENTS.md §4).

Concerns

  1. Verdict case-order violates fail-closed.github/workflows/scripts/swarm-post.sh:55-59. The case statement tests *REVIEW_PASSED* before *REVIEW_FAILED*. If a reviewer's last non-empty line ever contains both tokens (e.g., inline markdown quoting a prior verdict), PASSED wins. AGENTS.md §4 says "fail closed." Swap the arms so FAILED wins ties; contradicts the whole point of the swarm.

  2. Orphaned cloud runs on concurrency cancel.github/workflows/review-swarm.yml:12-13. cancel-in-progress: true kills the GHA job but the cloud swarm was launched via agent-relay cloud run and keeps executing. No agent-relay cloud cancel on trap. Silent budget/token drain over time.

  3. Transcript comments accumulate; only the aggregate is stickyswarm-post.sh:61 posts every lens transcript as a fresh comment on every synchronize push. The marker/edit-in-place pattern (lines 74-83) applies only to the summary. Three lens transcripts × N pushes = noise. Either sticky them too (per-lens marker) or state in the header comment why they aren't.

  4. No test pins the two "load-bearing" extraction rules — the file's docblock names them load-bearing and cites specific commits, but nothing gates a regression. A tiny fixture-based bats/shell test over swarm-post.sh (mtime-vs-filename ordering; PASSED prose in a FAILED review) would keep the rules alive. Absent that, the next refactor undoes them silently.

  5. Author allowlist is an undocumented implicit contractreview-swarm.yml:20-22. Hard-coded to kjgbot and miyaontherelay; a new bot silently gets no review, and there is no README/AGENTS note pointing here. Move the list to one commented place, or at minimum add a comment naming the invariant ("bot PRs only; humans use /code-review").

  6. Fragile response-shape fallbacksreview-swarm.yml:43 (.runId // .id // .run.id) and :62 (.status // .run.status) accept three/two shapes each. That's a smell that the cloud contract isn't pinned; if upstream changes again, the fallback masks the drift. A single expected shape with an explicit "unknown shape" error would fail loudly.

Notes

  • README addition (line 15) tells you the secret exists but not where it's provisioned, rotated, or who owns it. One more sentence would help ops.
  • Terminal-state list in the poll loop (line 63) is closed; a new cloud state (timeout, aborted) would fall through to the 65-min ceiling. The comment acknowledges the ceiling but not the enum coupling.

Nothing rises to a blocker for shipping the review swarm — the diff is a net win over the prior state and the failure modes it introduces are recoverable — but item 1 is a straight contradiction of AGENTS.md §4 and should be fixed before this is trusted as a gate.

REVIEW_PASSED

@kjgbot

kjgbot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor Author

history lens — FAIL

Blockers

  1. The timeout fix is ineffective, and the commit message is materially false. The job is capped at 50 minutes (.github/workflows/review-swarm.yml:20), while the poller claims a 65-minute deadline to accommodate the swarm’s 60-minute timeout (:49-65). GitHub Actions will kill the job before either deadline. This repeats drive: cloud run 4d577b53 #74’s timeout-ordering mistake despite the commit claiming it is fixed. Raise the outer job timeout above 65 minutes.

  2. A rejecting swarm never posts its evidence. The existing workflows/review-swarm.yaml:135-153 deliberately exits nonzero when any lens rejects. The new wait step converts cloud failed into immediate job failure (.github/workflows/review-swarm.yml:56-62), so GitHub skips “Sync and post review comments” (:69-74). That loses the rejection transcripts and aggregate marker—the exact evidence-loss class repeatedly recorded in ops/DRIVE-LOG.md. The commit’s claim that the script posts transcripts and a marker is therefore untrue on the most important path. Posting must run after review failure, while the job ultimately remains failed.

  3. The author filter contradicts the constitution. .github/workflows/review-swarm.yml:15-17 reviews only kjgbot and miyaontherelay. RFC-0001 §2 rule 7 and charter/LEAD.md require every PR to be met by the swarm. A deliberately narrower implementation may be documented as a temporary rollout, but it cannot satisfy the settled rule as presented.

Notes

The filename ordering and final-verdict parsing in swarm-post.sh:34-60 correctly preserve the deliberate fixes from b2535aa and f59d9cd; those mistakes are not reintroduced. The README’s workspace-secret wording is scoped to Actions and does not contradict RFC settled decision 7 that the workspace is only a projection.

REVIEW_FAILED

@kjgbot

kjgbot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor Author

structure lens — FAIL

→ Read docs/RFC-0001-everything-is-a-relayflow.md
→ Read AGENTS.md

Structure lens review — PR #75

This PR adds CI glue (one GitHub Actions workflow, one bash script, one README line). No kernel code, no primitives, no completionReason surface — so the RFC-specific structure rules don't bite here. File sizes are healthy (review-swarm.yml 78 lines, swarm-post.sh 83 lines), and the fail-closed discipline is genuinely present: missing/unclear transcripts degrade the aggregate to FAILED, and the poll loop exits 1 on non-completed terminal states rather than masquerading as timeout. That aligns with covenant 2 / fail-closed.

Blocker

  • .github/workflows/review-swarm.yml:19-21 — the if: whitelist restricts the swarm to exactly two actor usernames (kjgbot, miyaontherelay). This contradicts RFC §2 rule 7 ("Every PR is met by a review swarm") taken literally, but more structurally it hardcodes product/identity logic into a CI boundary: the gate is coupled to enumerated account handles rather than a principled rule. When any other contributor opens a PR, the swarm silently does not fire — the exact silent-zero failure shape RFC warns about (§3 gate 2, "a flow that is never triggered reports nothing"). Per AGENTS.md, contradicting the RFC is definitionally wrong. The boundary needs to be "review bot-authored PRs" expressed as a rule, not a hardcoded denylist of usernames — or the whitelist's rationale documented and the RFC rule amended (a human decision).

Concerns

  • swarm-post.sh enumerates the lens set twice (for lens in maintainability history structure at lines ~52 and ~66), and the workflow's sibling workflows/review-swarm.yaml (referenced, not in this diff) presumably declares it a third time. Three coupled copies of the same boundary list; rename a lens in one place and the others break or silently produce MISSING.
  • .github/workflows/review-swarm.yml:59-63 — magic-number coupling: poll deadline 3900 (seconds) must exceed the YAML's timeoutMs: 3600000 stated in a different file. Documented, but the invariant lives in prose across two files, not in code.
  • swarm-post.sh and the YAML both reach into agent-relay's JSON shape via fallback chains ('.runId // .id // .run.id', '.status // .run.status'. This is loose coupling to an unstable external contract rather than a closed, typed boundary.
  • swarm-post.sh:49 hardcodes the transcript path convention ops/reviews/*-pr"$pr_number"-"$lens".md — an implicit cross-file naming contract with review-swarm.yaml.

Notes — the two "hard-won extraction rules" comments (sort by filename not mtime; verdict = last non-empty line) are exactly the kind of lived-in reasoning AGENTS.md's "evidence is captured" section wants preserved.

REVIEW_FAILED

…RFC filter

History + structure lens on #75 identified three blockers, all real:

1. `timeout-minutes: 50` was less than the poll deadline of 65 minutes,
   so GHA would kill the job before the poll could time out. Raised job
   cap to 75 (65 + 10 headroom for checkout/install/post steps).

2. Wait step exiting nonzero on cloud `failed` made GHA skip the post
   step — so a rejecting swarm's transcripts never reached the PR. That
   is exactly the evidence-loss class ops/DRIVE-LOG.md warns about.
   Restructured: wait step records terminal status as an output and
   ALWAYS exits 0. Post step runs with `if: always()`. New final step
   fails the job iff swarm wasn't `completed`. Transcripts and marker
   land on the PR before the CI check goes red.

3. Author filter `kjgbot`/`miyaontherelay` contradicts RFC-0001 §2 rule 7
   "Every PR is met by a review swarm". Dropped the filter — human PRs
   get reviewed too, per the constitution. Comment records the intent.
@kjgbot

kjgbot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor Author

maintainability lens — PASS

I have enough context. Writing the review now.

Maintainability review — PR #75 (review-swarm CI wiring)

Blockers: none.

Concerns:

  1. Cross-file extraction rules disagree, silently. .github/workflows/scripts/swarm-post.sh:19-26 documents two "hard-won" rules — sort by filename, verdict = last non-empty line — and cites commits b2535aa and f59d9cd. But workflows/review-swarm.yaml:141,145 (pre-existing, not in this diff) still uses ls -t and grep -q "REVIEW_FAILED". This PR introduces the correct logic in one place while leaving the wrong logic in the place that actually decides swarm exit code. A stranger will read the two files, notice the contradiction, and have no way to know which is authoritative. Either fix the workflow's aggregate in the same PR, or add a one-liner in swarm-post.sh explaining that the two paths intentionally diverge (and why).

  2. swarm-post.sh degradation only handles MISSING/UNCLEAR (lines 68-73), not FAILED. The comment says "a partial signal must not read as PASSED", but a FAILED lens verdict does not degrade overall. This relies on the swarm aggregate having already set SWARM_FAILED in the log — a load-bearing invariant tied to point (1) above. If the two extraction paths ever drift further, the marker will show absurdities like PASSED (M:FAILED H:PASSED S:PASSED). Add FAILED to the degrade set, or comment why relying on last_swarm is safe.

  3. Pagination in sticky-comment lookup. swarm-post.sh:78 calls gh api .../comments with no --paginate; default page is 30. A long-lived PR with many comments before the swarm's first marker will fail to find the existing marker and post duplicates on every push — exactly the "N pushes accumulate N marker comments" failure the sticky comment was designed to prevent. Add --paginate.

  4. Implicit contract: RELAY_WORKSPACE_KEY. Declared in the job env (.github/workflows/review-swarm.yml:26) but never referenced by any visible script. It is consumed by the agent-relay CLI. The README addition names the secret but doesn't tell a maintainer how the CLI finds it (env var name, config file, etc.). One sentence about the CLI's env contract would prevent a future maintainer from deleting the "unused" env line.

  5. Implicit contract: .review-target crosses the local→cloud boundary. The CI writes .review-target locally (review-swarm.yml:37); the cloud workflow's fetch step reads it. Whether agent-relay cloud run uploads working-directory files is not stated. A stranger changing this path or renaming the file has no way to know what breaks. A comment on the Set review target step would fix it.

  6. agent-relay@11.8.7 pinned with no rationale. Bumping this version is safe today; in six months the reader will wonder whether the pin is load-bearing.

Notes:

  • The if: always() && steps.launch.outputs.run_id != '' guard on the post step is exactly right — evidence must reach the PR even when the swarm rejects.
  • The two large comment blocks citing prior commits (b2535aa, f59d9cd) and prior incidents (PR WP-4 — flows check preflight (covenant 2) #8 vendor bots) are the kind of institutional memory this repo needs more of. Keep this style.
  • Timeout budget (65 min poll + 75 min job cap) is clearly explained.

REVIEW_PASSED

@kjgbot

kjgbot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor Author

history lens — FAIL

Blockers

  • B1 — The reviewed PR controls its own judge. .github/workflows/review-swarm.yml:30-47 checks out the PR merge tree and launches that tree’s workflows/review-swarm.yaml; lines 79-87 also execute the PR-controlled posting script. This directly repeats the PR WP-4 — flows check preflight (covenant 2) #8 failure recorded in ops/DRIVE-LOG.md: the judge must be the immutable main version. It contradicts RFC-0001 settled decision regressions: relaycast workspace-key repair answers an untyped 500 #6 and exposes the job-wide workspace secret and write-capable token (review-swarm.yml:25-28) to code from the reviewed branch. Pin/export the gate and helper from the base revision.

  • B2 — A rejecting lens can still produce a PASSED marker. swarm-post.sh:34-37 derives overall from logs, but lines 63-68 downgrade only MISSING|UNCLEAR, not FAILED. Therefore line 72 can publish PASSED (M:PASSED H:FAILED S:PASSED) if transcript selection and cloud logs disagree. History repeatedly established that one rejecting lens must fail closed; include FAILED and reject any aggregate/transcript inconsistency.

Concern

  • The PR provides no test that pins either historical invariant. Its test plan claims syntax parsing without literal captured output and leaves the required real-cloud dry run unchecked, repeating the repository’s “evidence narrated, not captured” problem.

Notes

  • Filename sorting and terminal-token parsing in swarm-post.sh:41-58 correctly carry forward fixes b2535aa and f59d9cd.
  • The latest commit message truthfully describes the final correction. The PR body is stale: it still says the workflow is author-filtered, while review-swarm.yml:17-20 deliberately removes that filter. The final behavior aligns with RFC-0001’s “Every PR” rule despite contradicting the older operational brief.

REVIEW_FAILED

@kjgbot

kjgbot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor Author

structure lens — PASS

→ Read docs/RFC-0001-everything-is-a-relayflow.md
→ Read AGENTS.md

Structure lens — PR #75 review

Scope: all changes are CI/CD glue (.github/workflows/, a helper script, and a README line). Nothing touches kernel/. No new primitives are added; no provider SDK or tenant-awareness enters the kernel. File sizes are healthy: review-swarm.yml (~95 lines) and swarm-post.sh (~83 lines) are far under the 500-line smell threshold. On the three hard structure checks — product logic in kernel, primitive-over-helper, file past purpose — this PR is clean.

Concerns

Verdict logic reimplemented in shell, duplicating the relayflow's own judgment (swarm-post.sh:37-66). The RFC-0001 §2 rule 7 model is that the review swarm is itself a relayflow (workflows/review-swarm.yaml). That relayflow already emits an aggregate SWARM_PASSED|SWARM_FAILED token (consumed at swarm-post.sh:44-47). But the script then re-derives the verdict from per-lens transcript contents (swarm-post.sh:50-66) and re-inspects "last non-empty line" tokens. This creates two sources of truth for "did the swarm pass": the relayflow's own aggregate token and the CI shell's reconstruction. If the two ever disagree, there is no canonical answer. Structurally, aggregation belongs in the flow (which owns the lenses); the shell should post, not re-judge.

Cross-file timeout coupling by comment, not by artifact (review-swarm.yml:32-33,39-41 vs workflows/review-swarm.yaml timeoutMs 3600000). The job cap (75min) and poll deadline (3900s) are correct only because they track a third file's timeout via prose comments. Three independent numbers must agree, enforced only by comments — the same failure class AGENTS.md warns about ("stale MUST"). A single shared config or a typed handoff would remove the trap.

swarm-post.sh spans four jobs (swarm-post.sh:37-79): extract aggregate, extract per-lens verdicts, post transcripts, reconcile sticky marker. It is the only place the parsing rules (filename-sort, last-line-token) are encoded, and those rules carry "hard-won repo history" comments — reimplementation sites are a maintenance hazard, not a defect.

Notes

  • swarm-post.sh:19-28 validation (regex-guarded run_id/pr_number) and set -euo pipefail throughout are good fail-closed discipline.
  • Pinned agent-relay@11.8.7 (review-swarm.yml:22) is correct; unpinned global install would be a reproducibility defect.
  • The sticky-marker comment mechanism (swarm-post.sh:71-79) is a reasonable idempotency device, but it is the second comment channel alongside gh pr comment — mild concern about ordering/consistency on concurrent PRs.
  • README change (README.md:15) is accurate and minimal.

No blockers.

REVIEW_PASSED

@kjgbot kjgbot mentioned this pull request Aug 31, 2026
History lens on #75 caught: prior aggregate logic only degraded on
MISSING/UNCLEAR, not FAILED. So a log-derived PASSED (from the cloud
run's own aggregate step) could survive even when a lens transcript
said REVIEW_FAILED. That posted a PASSED marker while a lens rejected
— exactly the "single honest refusal must block merge" rule broken.

Now: aggregate = ALL lenses PASSED, else FAILED. Log-derived overall
is discarded — transcripts are the load-bearing evidence per the
review-swarm.yaml aggregate step's own rule.
@kjgbot

kjgbot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor Author

maintainability lens — FAIL

Looking through the maintainability lens on PR #75.

Blockers

B1. Dead code with self-justifying comment — swarm-post.sh:24-29 vs 60-66.
The script computes overall from cloud logs (lines 26-29) and then unconditionally overwrites it from lens transcripts (lines 60-66). The comment at 47-59 concedes this ("logs-derived overall above is a first pass") — but a value that's overwritten before any read is not a first pass, it is dead code. A stranger will spend real time trying to understand what the log grep contributes. Either delete lines 26-29 (and the initial overall=FAILED) or genuinely use the log-derived value as a cross-check that logs a warning when they disagree. As written, the comment asserts something the code does not do.

B2. Transcript comments accumulate on every push — swarm-post.sh:55.
The gh pr comment "$pr_number" --body-file "$transcript" inside the loop posts three fresh comments per re-run. The marker is sticky (edit-in-place) precisely to avoid the "N pushes → N comments" spam pattern the header comment brags about solving — but transcripts have no such protection. A PR that sees five pushes will accumulate 15 transcript comments plus one marker. The stated invariant (no accumulation) is only half-enforced; the code contradicts what the top-of-file comment implies. Either sticky the transcripts too (per-lens marker) or state explicitly that transcripts do accumulate and the marker is the summary.

Concerns

C1. Load-bearing invariant only expressed as a comment — review-swarm.yml:14-18, 47-50.
The chain workflows/review-swarm.yaml timeoutMs (3600000ms) ≤ wait deadline (3900s) ≤ job timeout-minutes (75) is enforced only by prose in two separate files. Change review-swarm.yaml's timeoutMs in six months and nothing in review-swarm.yml breaks loudly. Consider extracting to a single source (env, generated constant) or adding a preflight assertion that reads the yaml and checks the relationship.

C2. Silent CI/marker divergence — review-swarm.yml:91-95.
The merge gate keys on steps.wait.outputs.swarm_status, which is the cloud run status. But swarm-post.sh recomputes verdict from transcripts and can produce marker=FAILED while cloud=completed (missing transcript on the runner, sync race). In that case the sticky comment says FAILED but the CI check is green. Either fail the job from the post step's transcript-derived verdict, or delete the transcript-derived override in swarm-post.sh and trust the cloud aggregate.

C3. Implicit runId shape contract — review-swarm.yml:41.
jq -er '.runId // .id // .run.id' silently accepts three CLI shapes with no note on which agent-relay versions produce which. Pin to one shape or document the fallback rationale.

Notes

**N1. README addition (line 15) says the secret is required but not what workspace it points to or how a maintainer obtains one — a fork or new clone can't act on this hint.

**N2. No test would fail if swarm-post.sh's verdict parser regressed (e.g., someone reintroduces the whole-file grep the top comment warns against). The historical bug commits (b2535aa, f59d9cd) are cited but not pinned by a fixture. Consider a bats-style smoke test with fixture transcripts.

REVIEW_FAILED

@kjgbot

kjgbot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor Author

history lens — FAIL

Blockers

  • .github/workflows/review-swarm.yml:89-95 gates only on cloud status equaling completed; it never consumes the transcript-derived overall from swarm-post.sh:63-82. Therefore the discrepancy explicitly anticipated at lines 63-68—cloud completion while a transcript says REVIEW_FAILED—posts a failed marker but leaves the merge check green. This repeats the repository’s fail-open evidence mistake and contradicts RFC-0001 §2 rule 7’s “single honest refusal blocks” intent. The final script must exit nonzero or expose an output when overall=FAILED, and the job must gate on that result.

  • swarm-post.sh:39-58 selects transcripts only by PR number, lens, and lexicographic timestamp. It never binds them to this run_id or the reviewed head SHA. If a run produces no fresh transcript but its synced checkout contains an older one, the older verdict is accepted as current. Commit b2535aa fixed one stale-selection mechanism, but the DRIVE-LOG later records that final-head provenance is load-bearing. Require all three transcripts to identify the current head/run.

  • Authentication is not operational or fail-fast. review-swarm.yml:25-28,42-50 blindly launches with the required secret. At the current PR head, gh run view 33364011379 --log-failed captured:

    RELAY_WORKSPACE_KEY:
    Device login expired before it was approved.
    

    That is the RFC covenant-2 failure class: missing auth discovered through a ten-minute interactive fallback. Validate the secret before launch and ensure it is configured before calling this complete.

Concern

  • “Every PR” at review-swarm.yml:17-20 remains untrue for fork PRs, where repository secrets and write-capable tokens are withheld.

Note

The first two commit descriptions accurately describe their individual diffs. The latest commit overstates “fixes #75 B2”: it fixes the posted marker, not the merge-blocking check.

REVIEW_FAILED

@kjgbot

kjgbot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor Author

structure lens — FAIL

→ Read AGENTS.md
→ Read docs/RFC-0001-everything-is-a-relayflow.md

$ ls -la /Users/khaliqgant/AgentWorkforce/flows-ops && echo "---GITHUB---" && ls -la /Users/khaliqgant/AgentWorkforce/flows-ops/.github/workflows/ 2>/dev/null && echo "---SCRIPTS---" && ls -la /Users/khaliqgant/AgentWorkforce/flows-ops/.github/workflows/scripts/ 2>/dev/null
total 32
drwxr-xr-x@ 17 khaliqgant staff 544 Aug 30 05:11 .
drwxr-xr-x@ 12 khaliqgant staff 384 Aug 31 08:01 ..
drwxr-xr-x@ 3 khaliqgant staff 96 Aug 30 05:11 .claude
-rw-r--r--@ 1 khaliqgant staff 295 Aug 30 05:11 .env.example
drwxr-xr-x@ 17 khaliqgant staff 544 Aug 31 08:33 .git
-rw-r--r--@ 1 khaliqgant staff 416 Aug 30 05:11 .gitignore
-rw-r--r--@ 1 khaliqgant staff 3900 Aug 30 05:11 AGENTS.md
-rw-r--r--@ 1 khaliqgant staff 1410 Aug 30 05:11 README.md
drwxr-xr-x@ 3 khaliqgant staff 96 Aug 30 05:11 charter
drwxr-xr-x@ 5 khaliqgant staff 160 Aug 30 05:11 docs
drwxr-xr-x@ 10 khaliqgant staff 320 Aug 30 16:25 kernel
drwxr-xr-x@ 21 khaliqgant staff 672 Aug 30 20:14 ops
drwxr-xr-x@ 17 khaliqgant staff 544 Aug 30 05:11 regressions
drwxr-xr-x@ 3 khaliqgant staff 96 Aug 30 05:11 scripts
drwxr-xr-x@ 11 khaliqgant staff 352 Aug 31 00:40 sdk
drwxr-xr-x@ 23 khaliqgant staff 736 Aug 30 05:11 testdata
drwxr-xr-x@ 8 khaliqgant staff 256 Aug 30 05:11 workflows
---GITHUB---

$ cd /Users/khaliqgant/AgentWorkforce/flows-ops && echo "===workflows===" && ls -la workflows/ && echo "===ops===" && ls -la ops/ && echo "===kernel===" && ls -la kernel/ && echo "===scripts===" && ls -la scripts/
===workflows===
total 160
drwxr-xr-x@ 8 khaliqgant staff 256 Aug 30 05:11 .
drwxr-xr-x@ 17 khaliqgant staff 544 Aug 30 05:11 ..
-rw-r--r--@ 1 khaliqgant staff 7071 Aug 30 05:11 bootstrap-gate1.yaml
-rw-r--r--@ 1 khaliqgant staff 25565 Aug 30 05:11 drive-cloud.yaml
-rw-r--r--@ 1 khaliqgant staff 32297 Aug 30 05:11 drive.yaml
drwxr-xr-x@ 4 khaliqgant staff 128 Aug 30 05:11 probes
-rw-r--r--@ 1 khaliqgant staff 6681 Aug 30 05:11 review-swarm.yaml
-rw-r--r--@ 1 khaliqgant staff 1071 Aug 30 05:11 watchdog.yaml
===ops===
total 640
drwxr-xr-x@ 21 khaliqgant staff 672 Aug 30 20:14 .
drwxr-xr-x@ 17 khaliqgant staff 544 Aug 30 05:11 ..
-rw-r--r--@ 1 khaliqgant staff 5367 Aug 30 20:14 AUTODRIVE_BRIEF.md
-rw-r--r--@ 1 khaliqgant staff 1944 Aug 30 05:11 AUTONOMY.md
-rw-r--r--@ 1 khaliqgant staff 44135 Aug 30 05:11 BACKLOG.md
-rw-r--r--@ 1 khaliqgant staff 224 Aug 30 05:11 DIRECTIVES.md
-rw-r--r--@ 1 khaliqgant staff 170324 Aug 30 05:11 DRIVE-LOG.md
-rw-r--r--@ 1 khaliqgant staff 1061 Aug 30 05:11 FORBIDDEN_PATHS
-rw-r--r--@ 1 khaliqgant staff 5415 Aug 30 05:11 HANDOFF-2026-08-28.md
-rw-r--r--@ 1 khaliqgant staff 1296 Aug 30 05:11 IMMUTABLE_PATHS
-rw-r--r--@ 1 khaliqgant staff 3703 Aug 30 16:25 NEXT.md
-rw-r--r--@ 1 khaliqgant staff 4652 Aug 30 05:11 RUN-CONTRACT.md
-rw-r--r--@ 1 khaliqgant staff 2501 Aug 30 05:11 SCOREBOARD.md
-rw-r--r--@ 1 khaliqgant staff 11057 Aug 30 05:11 STATE.md
-rw-r--r--@ 1 khaliqgant staff 6000 Aug 30 05:11 autodrive.sh
-rwxr-xr-x@ 1 khaliqgant staff 6604 Aug 30 05:11 cargo.sh
-rwxr-xr-x@ 1 khaliqgant staff 10649 Aug 30 05:11 deliver-run.sh
-rw-r--r--@ 1 khaliqgant staff 6541 Aug 30 05:11 gen-drive-cloud.py
-rwxr-xr-x@ 1 khaliqgant staff 3446 Aug 30 05:11 launch-gate.sh
-rw-r--r--@ 1 khaliqgant staff 4885 Aug 30 05:11 open-pr.mjs
drwxr-xr-x@ 80 khaliqgant staff 2560 Aug 30 05:11 reviews
===kernel===
total 144
drwxr-xr-x@ 10 khaliqgant staff 320 Aug 30 16:25 .
drwxr-xr-x@ 17 khaliqgant staff 544 Aug 30 05:11 ..
-rw-r--r--@ 1 khaliqgant staff 35791 Aug 30 05:11 Cargo.lock
-rw-r--r--@ 1 khaliqgant staff 575 Aug 30 05:11 Cargo.toml
-rw-r--r--@ 1 khaliqgant staff 22547 Aug 30 05:11 DESIGN.md
-rw-r--r--@ 1 khaliqgant staff 522 Aug 30 05:11 README.md
-rw-r--r--@ 1 khaliqgant staff 85 Aug 30 16:25 package-lock.json
drwxr-xr-x@ 5 khaliqgant staff 160 Aug 30 05:11 relayflowd
drwxr-xr-x@ 5 khaliqgant staff 160 Aug 30 05:11 relayflowd-core
drwxr-xr-x@ 4 khaliqgant staff 128 Aug 30 05:11 relayflowd-journal
===scripts===
total 8
drwxr-xr-x@ 3 khaliqgant staff 96 Aug 30 05:11 .
drwxr-xr-x@ 17 khaliqgant staff 544 Aug 30 05:11 ..
-rwxr-xr-x@ 1 khaliqgant staff 612 Aug 30 05:11 run-workflow.sh

$ cd /Users/khaliqgant/AgentWorkforce/flows-ops && echo "===review-swarm.yaml?===" && find . -name 'review-swarm.yaml' -not -path './node_modules/*' 2>/dev/null && echo "===ops/reviews?===" && ls -la ops/reviews/ 2>/dev/null && echo "===git status===" && git log --oneline -5
===review-swarm.yaml?===
./workflows/review-swarm.yaml
===ops/reviews?===
total 2280
drwxr-xr-x@ 80 khaliqgant staff 2560 Aug 30 05:11 .
drwxr-xr-x@ 21 khaliqgant staff 672 Aug 30 20:14 ..
-rw-r--r--@ 1 khaliqgant staff 9293 Aug 30 05:11 20260827-1334-pr4-fixes.md
-rw-r--r--@ 1 khaliqgant staff 15588 Aug 30 05:11 20260827-1415-review.md
-rw-r--r--@ 1 khaliqgant staff 15429 Aug 30 05:11 20260827-1452-review.md
-rw-r--r--@ 1 khaliqgant staff 16790 Aug 30 05:11 20260827-1531-pr7-fixes.md
-rw-r--r--@ 1 khaliqgant staff 15033 Aug 30 05:11 20260827-1611-review.md
-rw-r--r--@ 1 khaliqgant staff 12726 Aug 30 05:11 20260827-1620-wp4-fixes.md
-rw-r--r--@ 1 khaliqgant staff 11275 Aug 30 05:11 20260827-1627-review.md
-rw-r--r--@ 1 khaliqgant staff 5498 Aug 30 05:11 20260827-1714-review.md
-rw-r--r--@ 1 khaliqgant staff 19252 Aug 30 05:11 20260827-1726-review.md
-rw-r--r--@ 1 khaliqgant staff 16792 Aug 30 05:11 20260827-1810-pr8-maintainability.md
-rw-r--r--@ 1 khaliqgant staff 7081 Aug 30 05:11 20260827-1815-pr8-history.md
-rw-r--r--@ 1 khaliqgant staff 9806 Aug 30 05:11 20260827-1819-pr8-structure.md
-rw-r--r--@ 1 khaliqgant staff 9142 Aug 30 05:11 20260827-1825-pr8-structure.md
-rw-r--r--@ 1 khaliqgant staff 8291 Aug 30 05:11 20260827-1826-pr8-history.md
-rw-r--r--@ 1 khaliqgant staff 22625 Aug 30 05:11 20260827-1829-pr8-maintainability.md
-rw-r--r--@ 1 khaliqgant staff 10576 Aug 30 05:11 20260827-1836-pr8-structure.md
-rw-r--r--@ 1 khaliqgant staff 7669 Aug 30 05:11 20260827-1838-pr8-history.md
-rw-r--r--@ 1 khaliqgant staff 26029 Aug 30 05:11 20260827-1842-pr8-maintainability.md
-rw-r--r--@ 1 khaliqgant staff 13780 Aug 30 05:11 20260827-1852-pr8-structure.md
-rw-r--r--@ 1 khaliqgant staff 8329 Aug 30 05:11 20260827-1853-pr8-history.md
-rw-r--r--@ 1 khaliqgant staff 25880 Aug 30 05:11 20260827-1857-pr8-maintainability.md
-rw-r--r--@ 1 khaliqgant staff 11284 Aug 30 05:11 20260827-1908-pr8-structure.md
-rw-r--r--@ 1 khaliqgant staff 7876 Aug 30 05:11 20260827-1909-pr8-history.md
-rw-r--r--@ 1 khaliqgant staff 22210 Aug 30 05:11 20260827-1914-pr8-maintainability.md
-rw-r--r--@ 1 khaliqgant staff 7511 Aug 30 05:11 20260827-1921-pr8-history.md
-rw-r--r--@ 1 khaliqgant staff 13160 Aug 30 05:11 20260827-1921-pr8-structure.md
-rw-r--r--@ 1 khaliqgant staff 16360 Aug 30 05:11 20260827-1924-pr8-maintainability.md
-rw-r--r--@ 1 khaliqgant staff 7831 Aug 30 05:11 20260827-1938-pr8-history.md
-rw-r--r--@ 1 khaliqgant staff 7980 Aug 30 05:11 20260827-1939-pr8-structure.md
-rw-r--r--@ 1 khaliqgant staff 15458 Aug 30 05:11 20260827-1942-pr8-maintainability.md
-rw-r--r--@ 1 khaliqgant staff 15650 Aug 30 05:11 20260827-1948-pr8-structure.md
-rw-r--r--@ 1 khaliqgant staff 7175 Aug 30 05:11 20260827-1949-pr8-history.md
-rw-r--r--@ 1 khaliqgant staff 19939 Aug 30 05:11 20260827-1952-pr8-maintainability.md
-rw-r--r--@ 1 khaliqgant staff 9306 Aug 30 05:11 20260827-1958-pr8-history.md
-rw-r--r--@ 1 khaliqgant staff 10866 Aug 30 05:11 20260827-1958-pr8-structure.md
-rw-r--r--@ 1 khaliqgant staff 18968 Aug 30 05:11 20260827-2002-pr8-maintainability.md
-rw-r--r--@ 1 khaliqgant staff 13914 Aug 30 05:11 20260827-2011-review.md
-rw-r--r--@ 1 khaliqgant staff 12519 Aug 30 05:11 20260827-2027-pr8-structure.md
-rw-r--r--@ 1 khaliqgant staff 8624 Aug 30 05:11 20260827-2031-pr8-history.md
-rw-r--r--@ 1 khaliqgant staff 22893 Aug 30 05:11 20260827-2032-pr8-maintainability.md
-rw-r--r--@ 1 khaliqgant staff 21873 Aug 30 05:11 20260827-2045-review.md
-rw-r--r--@ 1 khaliqgant staff 11793 Aug 30 05:11 20260827-2108-pr8-structure.md
-rw-r--r--@ 1 khaliqgant staff 9896 Aug 30 05:11 20260827-2110-pr8-history.md
-rw-r--r--@ 1 khaliqgant staff 19636 Aug 30 05:11 20260827-2115-pr8-maintainability.md
-rw-r--r--@ 1 khaliqgant staff 8983 Aug 30 05:11 20260827-2125-pr8-structure.md
-rw-r--r--@ 1 khaliqgant staff 7823 Aug 30 05:11 20260827-2127-pr8-history.md
-rw-r--r--@ 1 khaliqgant staff 19959 Aug 30 05:11 20260827-2131-pr8-maintainability.md
-rw-r--r--@ 1 khaliqgant staff 15689 Aug 30 05:11 20260827-2227-pr8-maintainability.md
-rw-r--r--@ 1 khaliqgant staff 9816 Aug 30 05:11 20260827-2228-pr8-structure.md
-rw-r--r--@ 1 khaliqgant staff 12208 Aug 30 05:11 20260827-2230-pr8-history.md
-rw-r--r--@ 1 khaliqgant staff 20465 Aug 30 05:11 20260827-2238-pr8-maintainability.md
-rw-r--r--@ 1 khaliqgant staff 9421 Aug 30 05:11 20260827-2238-pr8-structure.md
-rw-r--r--@ 1 khaliqgant staff 10652 Aug 30 05:11 20260827-2239-pr8-history.md
-rw-r--r--@ 1 khaliqgant staff 18350 Aug 30 05:11 20260827-2244-pr8-maintainability.md
-rw-r--r--@ 1 khaliqgant staff 12130 Aug 30 05:11 20260827-2244-pr8-structure.md
-rw-r--r--@ 1 khaliqgant staff 14055 Aug 30 05:11 20260827-2246-pr8-history.md
-rw-r--r--@ 1 khaliqgant staff 11754 Aug 30 05:11 20260827-2253-pr8-structure.md
-rw-r--r--@ 1 khaliqgant staff 9664 Aug 30 05:11 20260827-2254-pr8-history.md
-rw-r--r--@ 1 khaliqgant staff 17558 Aug 30 05:11 20260827-2254-pr8-maintainability.md
-rw-r--r--@ 1 khaliqgant staff 15442 Aug 30 05:11 20260827-2305-pr8-maintainability.md
-rw-r--r--@ 1 khaliqgant staff 8453 Aug 30 05:11 20260827-2306-pr8-structure.md
-rw-r--r--@ 1 khaliqgant staff 7484 Aug 30 05:11 20260827-2310-pr8-history.md
-rw-r--r--@ 1 khaliqgant staff 19208 Aug 30 05:11 20260827-2317-pr8-maintainability.md
-rw-r--r--@ 1 khaliqgant staff 9819 Aug 30 05:11 20260827-2318-pr8-structure.md
-rw-r--r--@ 1 khaliqgant staff 9193 Aug 30 05:11 20260827-2319-pr8-history.md
-rw-r--r--@ 1 khaliqgant staff 21092 Aug 30 05:11 20260827-2323-pr8-maintainability.md
-rw-r--r--@ 1 khaliqgant staff 10214 Aug 30 05:11 20260827-2324-pr8-history.md
-rw-r--r--@ 1 khaliqgant staff 12410 Aug 30 05:11 20260827-2324-pr8-structure.md
-rw-r--r--@ 1 khaliqgant staff 11132 Aug 30 05:11 20260827-2328-pr8-structure.md
-rw-r--r--@ 1 khaliqgant staff 11369 Aug 30 05:11 20260827-2331-pr8-history.md
-rw-r--r--@ 1 khaliqgant staff 21803 Aug 30 05:11 20260827-2331-pr8-maintainability.md
-rw-r--r--@ 1 khaliqgant staff 12245 Aug 30 05:11 20260828-0127-cloud-execution.md
-rw-r--r--@ 1 khaliqgant staff 3411 Aug 30 05:11 20260828-0244-pr9-adversarial.md
-rw-r--r--@ 1 khaliqgant staff 16142 Aug 30 05:11 20260828-0258-review.md
-rw-r--r--@ 1 khaliqgant staff 4476 Aug 30 05:11 20260828-0349-wp12-adversarial.md
-rw-r--r--@ 1 khaliqgant staff 1753 Aug 30 05:11 20260828-0512-review.md
-rw-r--r--@ 1 khaliqgant staff 12393 Aug 30 05:11 20260828-0605-review.md
-rw-r--r--@ 1 khaliqgant staff 15818 Aug 30 05:11 20260828-2050-review.md
===git status===
7331e12 fix(sdk): build kernel + restore fixture +x before npm test (unblocks drive loop, replaces #64/#65/#68) (#69)
7369f55 brief: retarget drive loop from SDK worker (shipped in #53) to GHA + cloud review-swarm
9681f11 drive: cloud run 88aaba35 (#53)
018c281 docs(state): correct the handoff — a lead IS live on sf-mini
3d7cdb4 docs(backlog): Khaliq answered — the agent worker belongs in this repo

→ Read workflows/review-swarm.yaml

Structure review — PR #75 (review-swarm CI GHA + post-back script)

This PR adds .github/workflows/review-swarm.yml, .github/workflows/scripts/swarm-post.sh, and a one-line README note. It touches no kernel, no product code, and no SDK — so the core RFC-0001 boundary concern (closed kernel vocabulary, product logic leaking into kernel/, adding a primitive instead of a helper) is clean. Good: the language boundary is respected by construction here, and both new files are far under the 500-line smell threshold.

The structural problems are all in how the verdict is computed and where it lives.

Blocker — the merge verdict now has two disagreeing sources of truth. swarm-post.sh:34-77 derives each lens verdict (last non-empty line's token) and the aggregate (all lenses PASSED else FAILED). But the authoritative signal — the cloud run status that review-swarm.yml:84-91 ("Fail the job when swarm rejected") gates on — is produced by workflows/review-swarm.yaml's aggregate step (lines 140-151), which still uses whole-file grep -q "REVIEW_FAILED" and ls -t mtime-sort. The script's own header (lines 5-11) names those exact two bug classes and cites f59d9cd/b2535aa as fixes — but the fix landed in the shell while the YAML that actually drives the gate kept the buggy version. A passing review that quotes REVIEW_FAILED in prose still flips the cloud run to failed, blocking merge, while swarm-post.sh says PASSED. One judgment, two implementations, no shared helper.

Concern — dead code. swarm-post.sh:28-32 computes overall/last_swarm from the log, then overall is unconditionally overwritten at line 72 and last_swarm is never read again. This is exactly AGENTS.md rule 6 ("no dead code") and the discarded first-pass is left in place solely to carry an explanatory comment.

Concern — the lens list is triplicated as an unowned contract. maintainability history structure appears in review-swarm.yaml (agents + aggregate loop) and again hardcoded in swarm-post.sh:34. Adding a lens means editing three files in lockstep with no single source of truth. The transcript filename glob (ops/reviews/*-pr…-{lens}.md) re-derives a format owned by the lens task steps in review-swarm.yaml.

Note — gate-editing-itself boundary. The workflow checks out refs/pull/$n/merge, so workflows/review-swarm.yaml executes from the PR's own merge commit: a PR can modify the very gate that judges it. This is more history/security than structure, but it's the boundary RFC-0001 §2 rule 6 ("no gate editable by the agents it judges") is built to forbid.

REVIEW_FAILED

@kjgbot

kjgbot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor Author

🎯 review-swarm: FAILED (M:fail H:fail S:fail)

Lens transcripts posted as sibling comments above.

@kjgbot

kjgbot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor Author

Pivoting: swarm iterated 4x on real architectural findings (gate-editing-itself, two disagreeing verdict sources across shell+yaml, transcript-verdict binding, sticky-transcript missing). Local review-swarm-loop.sh on the laptop is sufficient signal for now. Cloud GHA can be revisited when the deeper unification (workflows/review-swarm.yaml aggregate + .github/workflows/scripts/swarm-post.sh sharing verdict-extraction) is scoped as its own workstream.

@kjgbot kjgbot closed this Aug 31, 2026
@kjgbot
kjgbot deleted the fix/gha-review-swarm-hand-recover branch August 31, 2026 09:49
kjgbot pushed a commit that referenced this pull request Aug 31, 2026
Every real finding accumulated across walked-away PRs #75 (5 iterations)
and #77 baked in as non-negotiable requirements:
  1. Immutable gate — checkout main separately, PR doesn't judge itself
  2. Unified verdict logic (single source of truth across yaml + shell)
  3. Auth secret fail-fast preflight
  4. Sticky marker + transcripts (edit-in-place)
  5. Every PR reviewed — no author whitelist (RFC-0001 §2 rule 7)
  6. Fetch on launching host (cloud sandbox has no gh auth)
  7. Job timeout > poll deadline > swarm timeoutMs (invariant)
  8. Wait step records status; post runs on always()
  9. Transcript-to-run-id binding (mtime-freshness proxy)

Territory: .github/ + workflows/. No overlap with Track A (sdk/).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This was referenced Aug 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant