Skip to content

chore(workflows): drop direction/scope gate from maintainer-review-pr#1675

Merged
Wirasm merged 1 commit into
devfrom
workflow/maintainer-review-drop-gate
May 14, 2026
Merged

chore(workflows): drop direction/scope gate from maintainer-review-pr#1675
Wirasm merged 1 commit into
devfrom
workflow/maintainer-review-drop-gate

Conversation

@Wirasm

@Wirasm Wirasm commented May 14, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Problem: The gate node in maintainer-review-pr was the workflow's most fragile point. Pi/Minimax intermittently wrapped the verdict JSON in a markdown fence or prefixed reasoning prose, which broke the condition-evaluator's field extraction. When that happened the DAG silently skipped every downstream aspect and the workflow exited 0 — a "successful" run that posted no review and surfaced no error (the silent-failure cascade tracked separately in Workflow exits success when condition_json_parse_failed cascades to silent node skips #1673).
  • Why it matters: Hand-picked PRs from the morning standup brief never benefited from the gate. Across ~13 production runs over two days the gate returned verdict: review every single time; the decline / needs_split / unclear branches were never exercised. So the gate added all of the failure mode and none of the signal.
  • What changed: Removed the gate path entirely (gate, approve-decline, post-decline, approve-unclear, plus the read-context node that only fed the gate). Rewired review-classify to depend directly on [fetch-pr, fetch-diff]. Updated the synthesize and report commands and deleted the now-orphan gate command. record-review hard-codes gate_verdict: 'review' for back-compat with the standup brief's reviewed/declined/triaged marker logic.
  • What did not change (scope boundary): No engine code touched. No @archon/workflows changes. Bundled defaults untouched (bun run check:bundled clean). The standup workflow and its persist script are unchanged — those handle their own (unrelated) Pi-format quirks. The decline/needs_split workflow path is gone for now; if/when automated PR triage is introduced, the gate (with a hardened parser or Claude provider) can be added back in a separate workflow.

UX Journey

Before

User                              Archon
────                              ──────
runs maintainer-review-pr 1554 ▶  extract-pr  →  fetch-pr + fetch-diff + read-context
                                              ▼
                                  gate (Pi, ~1m) → JSON verdict
                                              ▼
                          ┌───────────────────┼──────────────────────────┐
                  [verdict=review]   [verdict=decline]            [verdict=unclear]
                          ▼                   ▼                          ▼
                  review-classify       approve-decline (human)    approve-unclear (human)
                          ▼                   ▼
                  5 aspects (parallel)  post-decline
                          ▼                   ▼
                  synthesize           record-review
                          ▼                   ▼
                  post-review          report
                          ▼                   ▼
sees draft + posted comment    (or)    sees decline outcome

Failure mode (observed twice yesterday):

                                  gate emits ```json\n{verdict: review,...}\n```
                                              ▼
                  condition-evaluator: parse fails (warn log only)
                  $gate.output.verdict missing → all when: clauses falsy
                  [X] every aspect node Skipped (when_condition)
                  workflow exits 0
sees "Workflow completed successfully" — but no review was actually run.

After

User                              Archon
────                              ──────
runs maintainer-review-pr 1554 ▶  extract-pr  →  fetch-pr → fetch-diff
                                                                 ▼
                                                          review-classify (Pi)
                                                                 ▼
                                                          5 aspects (parallel, gated by classifier)
                                                                 ▼
                                                          synthesize
                                                                 ▼
                                                          [+] post-review
                                                                 ▼
                                                          record-review
                                                                 ▼
                                                          report
sees draft + posted comment

Architecture Diagram

Before

+----------------------+        +----------------------+        +----------------------+
| extract-pr-number    | -----> | fetch-pr             | -----> | gate (Pi command)    |
+----------------------+        | fetch-diff           |        +----------------------+
                                | read-context (script)|             |   |   |
                                +----------------------+             v   v   v
                                                      review-classify  decline  unclear
                                                              |          |        |
                                                              v          v        v
                                                       5 aspects    post-decline  (manual)
                                                              \         /
                                                               v       v
                                                              record-review
                                                                   v
                                                                  report

After

+----------------------+        +----------------------+
| extract-pr-number    | -----> | fetch-pr             |
+----------------------+        | fetch-diff           |
                                +----------------------+
                                          v
                                review-classify
                                          v
                                5 aspects (parallel)
                                          v
                                synthesize-review
                                          v
                                post-review
                                          v
                                record-review
                                          v
                                report

Connection inventory:

From To Status Notes
fetch-pr / fetch-diff gate removed gate node deleted
extract-pr-number read-context removed read-context deleted (only consumer was gate)
gate review-classify / approve-decline / approve-unclear removed all three downstream deps gone
fetch-pr / fetch-diff review-classify new direct dep replacing gate
post-review / post-decline / approve-unclear record-review modified now only post-review; no trigger_rule: one_success

Label Snapshot

  • Risk: risk: low
  • Size: size: M (-426 net lines; mostly deletions)
  • Scope: workflows
  • Module: workflows:maintainer-review

Change Metadata

  • Change type: chore (workflow simplification; no engine code touched)
  • Primary scope: workflows

Linked Issue

Validation Evidence (required)

$ bun run validate
# All six steps passed (check:bundled, check:bundled-skill, type-check, lint, format:check, test)

$ bun run cli validate workflows
# Results: 36 valid, 0 with errors

$ bun run cli workflow run maintainer-review-pr "1554"
# End-to-end smoke test on this branch:
#   extract-pr-number  15.3s
#   fetch-pr           838ms      (parallel with fetch-diff)
#   fetch-diff         525ms
#   review-classify    58s
#   code-review        6m51s      (only aspect classifier picked for this PR)
#   synthesize         1m43s
#   post-review        1.3s       (posted to PR #1554)
#   record-review      35ms
#   report             35.8s
# Total ~12 min, exit 0, 0 condition_json_parse_failed events.

Security Impact (required)

  • New permissions/capabilities? No
  • New external network calls? No (same gh pr view / gh pr diff / gh pr comment calls as before)
  • Secrets/tokens handling changed? No
  • File system access scope changed? No

Compatibility / Migration

  • Backward compatible? Yes for the standup brief's reviewed-prs.json reader. Old entries with gate_verdict: 'decline' | 'needs_split' | 'unclear' are still read correctly. New entries are always gate_verdict: 'review', which the standup synth treats as "reviewed Nd ago" — the natural behavior we want.
  • Config/env changes? No
  • Database migration needed? No

Human Verification (required)

  • Verified scenarios:
    • Smoke ran maintainer-review-pr "1554" end-to-end on this branch and confirmed the posted comment on the PR.
    • Confirmed reviewed-prs.json got the new entry with gate_verdict: 'review'.
    • Inspected reviewed-prs.json to confirm existing entries with gate_verdict: 'decline' | 'needs_split' | 'unclear' still parse fine (no schema change).
    • Ran bun run cli validate workflows to confirm all 36 workflows still load.
  • Edge cases checked:
    • Workflow with interactive: false (was true) runs fine on CLI; foreground execution on Web is not required without approval gates.
    • Synthesize command no longer reads $ARTIFACTS_DIR/gate-decision.md; smoke confirmed no spurious "Gate-decision notes" section in the synthesis output.
  • What was not verified: did not run any of the other 35 workflows (none depend on the deleted gate command).

Side Effects / Blast Radius (required)

  • Affected subsystems/workflows: maintainer-review-pr only.
  • Potential unintended effects: the standup brief's "Replies waiting" / "✓ reviewed" markers depend on gate_verdict in reviewed-prs.json. With every new entry being 'review', the standup synth's declined / triaged (unclear) branches will only ever match older entries — which is the intended outcome.
  • Guardrails/monitoring for early detection: run the workflow on a fresh PR; if anything regresses we'll see it in the standup's next-day brief (the PR will be missing the ✓ reviewed Nd ago marker).

Rollback Plan (required)

  • Fast rollback command/path: revert the merge commit; the prior workflow file is restored verbatim. There is no engine state to migrate back.
  • Feature flags or config toggles (if any): none — this is a project workflow file.
  • Observable failure symptoms: review-classify or any aspect node fails with a missing-context error. (Unlikely — review-classify already had access to fetch-pr / fetch-diff content via gate upstream, which is what we wire directly now.)

Risks and Mitigations

  • Risk: A future PR contributed by someone unfamiliar with Archon's direction is reviewed deeply when a polite decline would have been the right answer.
    • Mitigation: the maintainer is the one running this workflow on PRs they've already chosen from the standup brief. The standup brief's P4 "Polite-decline candidates" section already surfaces those PRs separately; this workflow is for PRs the maintainer has decided to review. If automated PR triage is ever wired up, reintroduce the gate (with a hardened parser or Claude provider on that specific node) in a separate workflow rather than this one.
  • Risk: Project-local workflow file edits drift away from bundled defaults over time.
    • Mitigation: bun run check:bundled and bun run check:bundled-skill still pass (this workflow is not in defaults/).

Summary by CodeRabbit

Refactor

  • Streamlined the maintainer review workflow by removing intermediate gating decision phases, enabling reviews to proceed directly from classification through synthesis to automated comment posting
  • Simplified review output templates to focus on core findings and outcomes
  • Updated internal state tracking to align with the new streamlined review process

The gate node was the most fragile part of the workflow. It used Pi/Minimax
to return a structured JSON verdict that the DAG branched on, but Pi
intermittently wrapped the JSON in markdown fences or prefixed reasoning
prose, breaking the condition-evaluator's field extraction. When that
happened, every downstream review aspect was silently skipped and the
workflow exited 0 with no review posted — indistinguishable from a
successful run where the gate legitimately declined.

In practice the gate added no signal for hand-picked PRs from the morning
standup brief: across two full days of usage (~13 runs) the gate returned
"review" every single time. The decline/needs_split/unclear branches were
never exercised. Removing the gate eliminates the failure mode without
losing any verdict the workflow has actually produced.

Changes:
- Remove gate, approve-decline, post-decline, approve-unclear nodes from
  maintainer-review-pr.yaml.
- Rewire review-classify to depend on [fetch-pr, fetch-diff].
- Drop read-context (only the gate command consumed it).
- Simplify record-review: hardcode gate_verdict to "review" for back-compat
  with the standup brief's marker logic; drop the one_success join.
- Drop interactive: true (no more approval gate).
- Update synthesize and report commands to remove gate-decision references.
- Delete the now-orphan maintainer-review-gate.md command.

If we later wire up automated review on every open PR (where the
direction/scope decline would matter), reintroduce the gate then — and
this time with a hardened parser or Claude provider on the gate node.
@Wirasm Wirasm merged commit 7aafcfd into dev May 14, 2026
3 of 4 checks passed
@Wirasm Wirasm deleted the workflow/maintainer-review-drop-gate branch May 14, 2026 07:15
@coderabbitai

coderabbitai Bot commented May 14, 2026

Copy link
Copy Markdown

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 312c8163-be83-47dd-bda1-c4c1b22ddd52

📥 Commits

Reviewing files that changed from the base of the PR and between 19573df and f0e3932.

📒 Files selected for processing (4)
  • .archon/commands/maintainer-review-gate.md
  • .archon/commands/maintainer-review-report.md
  • .archon/commands/maintainer-review-synthesize.md
  • .archon/workflows/maintainer/maintainer-review-pr.yaml

📝 Walkthrough

Walkthrough

This PR removes the gating/approval mechanism from the maintainer review workflow, converting it from a multi-branch process (review/decline/needs-split/unclear) into a streamlined deep-review-only path for PRs already selected by maintainers. The gate command is deleted, and the workflow, synthesizer, and reporter are restructured to omit gate-dependent logic while recording results for standup integration.

Changes

Maintainer Review Workflow Gate Removal & Deep-Review Restructuring

Layer / File(s) Summary
Gate mechanism removal
.archon/commands/maintainer-review-gate.md
Entire gating workflow deleted, including decision matrix, verdict logic, and decline-comment templating that previously decided whether a PR qualified for review or should be declined.
Workflow redesign to deep-review-only path
.archon/workflows/maintainer/maintainer-review-pr.yaml
Workflow restructured from multi-branch gated process to a single deep-review path. Gate phase removed, diff-fetching failure handling made explicit, review aspects classified and run in parallel, and decline/unclear branching eliminated. Auto-posting of synthesized review comment now follows classification directly without approval gating.
Synthesizer and reporter refactoring
.archon/commands/maintainer-review-synthesize.md, .archon/commands/maintainer-review-report.md
Synthesizer no longer reads or references gate-decision.md or includes gate notes in synthesis output. Reporter template refactored from branch-driven outcome (branch taken/gate decision/decline/unclear sections) to a unified outcome block driven solely by synthesized verdict and findings, with simplified "Next steps" and fixed action=posted-review-comment return.
Shared state recording for standup integration
.archon/workflows/maintainer/maintainer-review-pr.yaml
New Phase 5 records reviewed PRs to .archon/maintainer-standup/reviewed-prs.json after post-review succeeds, with hardcoded gate_verdict: 'review' for backward-compatibility with standup brief expectations and includes run_id for traceability.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • coleam00/Archon#1458: Introduces the shared state mechanism in .archon/maintainer-standup/reviewed-prs.json and standup backfill logic that this PR's new recording phase now feeds into.
  • coleam00/Archon#1430: Modifies the same gate mechanism in opposite direction; while this PR removes gating entirely, #1430 refines gate routing and configuration.
  • coleam00/Archon#1432: Tightens gate/deadline logic and error handling in the same command templates; this PR removes that complexity by eliminating the gate flow.

Poem

🐰 A gated garden simplified,
No branching paths to pick and decide—
Just deep review for PRs just right,
One workflow shining, clean and bright!
✨ The gate is gone, the path is clear.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch workflow/maintainer-review-drop-gate

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@coleam00 coleam00 mentioned this pull request May 14, 2026
cropse pushed a commit to cropse/Archon that referenced this pull request May 19, 2026
…coleam00#1675)

The gate node was the most fragile part of the workflow. It used Pi/Minimax
to return a structured JSON verdict that the DAG branched on, but Pi
intermittently wrapped the JSON in markdown fences or prefixed reasoning
prose, breaking the condition-evaluator's field extraction. When that
happened, every downstream review aspect was silently skipped and the
workflow exited 0 with no review posted — indistinguishable from a
successful run where the gate legitimately declined.

In practice the gate added no signal for hand-picked PRs from the morning
standup brief: across two full days of usage (~13 runs) the gate returned
"review" every single time. The decline/needs_split/unclear branches were
never exercised. Removing the gate eliminates the failure mode without
losing any verdict the workflow has actually produced.

Changes:
- Remove gate, approve-decline, post-decline, approve-unclear nodes from
  maintainer-review-pr.yaml.
- Rewire review-classify to depend on [fetch-pr, fetch-diff].
- Drop read-context (only the gate command consumed it).
- Simplify record-review: hardcode gate_verdict to "review" for back-compat
  with the standup brief's marker logic; drop the one_success join.
- Drop interactive: true (no more approval gate).
- Update synthesize and report commands to remove gate-decision references.
- Delete the now-orphan maintainer-review-gate.md command.

If we later wire up automated review on every open PR (where the
direction/scope decline would matter), reintroduce the gate then — and
this time with a hardened parser or Claude provider on the gate node.
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