Skip to content

spec: amend Phase 2 to three workflows; defer the fix loop - #142

Merged
yihanzhu merged 13 commits into
mainfrom
ystack/spec/v2-phase-2-amend
Aug 27, 2026
Merged

spec: amend Phase 2 to three workflows; defer the fix loop#142
yihanzhu merged 13 commits into
mainfrom
ystack/spec/v2-phase-2-amend

Conversation

@yihanzhu

Copy link
Copy Markdown
Owner

G2 — the spec amendment, on its own gate. Codex was right that folding this into #141 collapsed the gate: a spec change earns its own approval, separate from the plan that answers it.

What changes: R4 (bounded fix loop) deferred to its own intent; R5 scoped to three workflows and one open bot edge; the Design section stops building fix-on-review.yml and address-review; the exit test proves R1–R3.

Direction matters: this amendment reduces what the lane does — a delivery decision you ruled at the cap. The amendment this project refuses is the opposite one: widening a spec so an agent can have more power (which is exactly what the deferred fix stage would have needed).

Merge order: this first, then #141 — whose plan already records this spec's hash, so the chain reads fresh the moment this lands.

🤖 Generated with Claude Code

Records the operator's ruling at the review cap, in the artifact that is
supposed to carry it:
- R4 (bounded fix loop) is DEFERRED to its own intent. It needed a third
  claude[bot] trigger edge where R5 allows two, and it was the one job
  holding write credentials, running PR-authored code, and reading
  untrusted PR text at once — that earns a clean design, not patches.
- R5 is scoped to this phase's three workflows and its single open bot
  edge (review-of-agent-PRs).
- The Design section no longer builds fix-on-review.yml or the
  address-review skill, and the exit test proves R1-R3.

This amendment REDUCES what the lane does. Widening a spec so an agent
can have more power is the amendment this project refuses; recording less
delivery is the operator's call, taken at the cap.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Aug 27, 2026

Copy link
Copy Markdown

Deploying ystack with  Cloudflare Pages  Cloudflare Pages

Latest commit: aa2e856
Status: ✅  Deploy successful!
Preview URL: https://0d6c752c.fabrica-6yx.pages.dev
Branch Preview URL: https://ystack-spec-v2-phase-2-amend.fabrica-6yx.pages.dev

View logs

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 05a085599a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread work/v2-phase-2/spec.md Outdated
Comment on lines +8 to +10
From the accepted intent: the chain must advance without a live session — merged
intent → spec PR, merged spec → implementation PR, every PR reviewed with a bounded
fix loop; the operator's only actions are the gate merges.
intent → spec PR, merged spec → implementation PR, every PR reviewed; the operator's
only actions are the gate merges.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Reconcile the merge-only claim with manual review fixes

When any automated review produces findings, the amendment explicitly makes the operator address them in a live session (lines 17–18), so the operator's actions are no longer limited to gate merges as claimed here. The same contradiction appears in the R1–R3 exit criterion, allowing a clean smoke PR to pass without testing the manual handoff that now interrupts the autonomous lane; update the outcome and exit criterion to describe and verify the operator remediation step.

Useful? React with 👍 / 👎.

Comment thread work/v2-phase-2/spec.md Outdated
Comment on lines +14 to +16
recorded in `plan.md` under "Deferred: fix-on-review": the fix stage needed a third
`claude[bot]` trigger edge where R5 allows two, and it was the one job holding write
credentials, running PR-authored code, and reading untrusted PR text at once — it

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Point the deferral at an existing design record

In this commit, work/v2-phase-2/plan.md contains neither the referenced "Deferred: fix-on-review" section nor a credential-split design; it still instructs PR B to build fix-on-review and address-review. Consequently the amendment's rationale cannot be audited and its later instruction to start the next intent from that credential split points at nonexistent content, while the repository's ordering document continues to prescribe the unsafe scope being deferred. Include the plan amendment in the reviewed state or reference an artifact that already contains the design.

Useful? React with 👍 / 👎.

Comment thread work/v2-phase-2/spec.md
label before acting; at `round-3` it applies `needs-human`, posts the productive-cap
comment, and stops. That design is superseded — the next intent starts from the
credential split in `plan.md`, not from this text.
- **R5 — safety invariants (all three workflows in this phase).** One global `claude-quota`

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Remove the deferred fix-stage check from active R5

After redefining R5 as the safety requirements for the three workflows that remain, the same requirement still says that "the fix stage never pushes to a PR that already has an approval" (lines 52–54). Because this amendment explicitly removes that stage, the active requirement is impossible to exercise or verify and can lead an implementer to restore part of the deferred workflow merely to satisfy R5; move this condition into the deferred R4 history instead.

Useful? React with 👍 / 👎.

Codex on this PR, all three adopted:
- the opening claim said the operator's only actions are gate merges,
  while the amendment gives them review findings to answer; it now says
  both
- the deferral cited a plan section that lands in a later PR, so the
  rationale could not be audited from this branch alone. The reasons and
  the credential-split direction are stated here, in the spec
- R5 still required "the fix stage never pushes to an approved PR" — a
  rule about a stage this phase does not build

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
yihanzhu pushed a commit that referenced this pull request Aug 27, 2026
The spec amendment took three review findings, so its blob moved and the
plan's recorded hash went stale. Chain discipline: the plan names the
exact spec it answers, or the helpers report it stale and refuse to build
on it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: fac77d4d17

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread work/v2-phase-2/spec.md
Comment on lines +13 to +14
**Amended 2026-08-27 (operator ruling at the review cap).** This phase ships three
workflows, not four: the fix loop (R4) is deferred to its own intent. Two reasons,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Update R6 to reference the three in-scope workflows

Compliance: After this amendment reduces the lane to three workflows, R6 still requires the plumbing probe to run before “the four workflows are finalized” (line 63). Since the fourth workflow is now explicitly deferred, that prerequisite no longer describes a reachable phase milestone and leaves the implementation plan ambiguous about whether another workflow must exist before R6 can pass; change the remaining count to three.

Useful? React with 👍 / 👎.

Codex: the probe prerequisite still said 'before the four workflows are
finalized', describing a phase this amendment no longer reaches.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
yihanzhu pushed a commit that referenced this pull request Aug 27, 2026
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@yihanzhu

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: bbbd65e794

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread work/v2-phase-2/spec.md Outdated
Comment on lines +29 to +31
Each requirement is verifiable; R1–R3 are jointly proven by the phase exit test
(one real change flows through the lane with the operator only merging). R4 is
deferred with this phase's fix stage — see the amendment note above.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Exercise the manual review handoff in the exit test

When the review workflow reports a finding, the fresh amendment now explicitly requires the operator to resolve it in a live session, but this changed exit criterion still declares R1–R3 proven by a smoke run where the operator only merges. A clean smoke PR can therefore pass without exercising the newly introduced review-to-operator handoff; update the exit test to include a finding and its manual remediation.

Useful? React with 👍 / 👎.

Comment thread work/v2-phase-2/spec.md Outdated
Comment on lines +51 to +52
comment, and stops. That design is superseded — the next intent starts from the
credential split in `plan.md`, not from this text.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Stop directing the deferred design to the stale plan

The newly added sentence points the next intent at a credential split in plan.md, but the plan in this target tree still has the old spec-blob and directs PR B to build four workflows, including fix-on-review, plus address-review. Thus the supposedly superseded, unsafe fix design remains the referenced source of truth; either amend the plan or point this sentence to the credential split actually described in the amendment above.

Useful? React with 👍 / 👎.

Comment thread work/v2-phase-2/spec.md
Comment on lines +13 to +14
**Amended 2026-08-27 (operator ruling at the review cap).** This phase ships three
workflows, not four: the fix loop (R4) is deferred to its own intent. Two reasons,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Reconcile quota sizing with the three-job scope

After this amendment removes the fix workflow, the quota concern later in this same spec still says that “all four jobs” share the subscription window. That stale count makes the sizing question and the intended quota-preflight.sh default ambiguous—especially because the separate plumbing probe is a permanent diagnostic—so state whether the budget covers the three lane jobs or those jobs plus the probe.

Useful? React with 👍 / 👎.

Comment thread work/v2-phase-2/spec.md Outdated
Comment on lines +60 to +62
(mechanical enforcement arrives with Phase 3 hooks). (The "never push to an
approved PR" rule went with the deferred fix stage — it belongs to that intent,
which is the only thing that pushes to an open PR.)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Account for producer stages that update open PRs

On a re-trigger with an existing spec or implementation PR, R1 explicitly requires the stage to open “or update” that PR, so the deferred fix stage is not the only component that pushes to an open PR. Removing the approval-safety discussion under this false premise leaves it unspecified whether a producer stage may rewrite an already approved PR; either apply the guard to every updating stage or document the distinct safety mechanism for producer updates.

Useful? React with 👍 / 👎.

Codex round 3 on this amendment:
- the exit test declared R1-R3 proven while the operator "only merges",
  but this amendment also makes them answer findings. The run now counts
  only if the review found something and the operator resolved it —
  otherwise the smoke test proves the happy path, not the handoff the
  phase depends on
- the deferral pointed the next intent at plan.md for its design, but any
  plan written for the four-workflow shape is exactly what was
  superseded; the direction lives in this spec
- quota sizing still counted four jobs
- I removed the "never push to an approved PR" rule claiming only the fix
  stage pushes to open PRs. False: R1 and R2 let a re-triggered producer
  stage update an existing PR. The rule is restored and now covers every
  stage — an approval means the operator read that diff

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
yihanzhu pushed a commit that referenced this pull request Aug 27, 2026
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@yihanzhu

Copy link
Copy Markdown
Owner Author

Round 3 — four folded, and one was a rule I cut on a false premise.

I removed "never push to a PR the operator already approved" on the grounds that only the deferred fix stage pushes to open PRs. That was wrong: R1 and R2 let a re-triggered producer stage update an existing PR. So the rule is restored and now covers every stage — an approval means the operator read that diff, and a later push silently moves what they approved. Deleting a safety rule because of a wrong assumption about who can trip it is a good way to lose one.

Also: the exit test declared R1–R3 proven while "the operator only merges", even though this amendment gives them findings to answer — so the run now counts only if the review found something and the operator resolved it; a smoke change clean enough to find nothing proves the happy path, not the handoff the phase now depends on. Plus: the deferral pointed the next intent at a plan written for the four-workflow shape (the very thing superseded), and quota sizing still counted four jobs.

This is round 3 for this PR — the cap. Whatever comes next is the operator's ruling, not another automatic fold.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 43a28a7add

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread work/v2-phase-2/spec.md Outdated
Comment on lines +64 to +68
(mechanical enforcement arrives with Phase 3 hooks). **No stage pushes to a PR
the operator has already approved** — R1 and R2 let a re-triggered producer
stage update an existing PR, so this is not only the deferred fix stage's
concern: an approval means the operator read that diff, and a later push would
silently move what they approved.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Define a path for updating an approved producer PR

When an existing spec or implementation PR has an approval and a later intent/spec merge makes that PR stale, R1/R2 require the deterministic PR to be updated, while this new invariant forbids the producer from pushing that update. Because the same slug cannot use a second PR, these requirements leave the chain unable to publish the fresh artifact unless an unstated manual step first removes the approval or closes the PR; specify that recovery behavior or permit a safe update that invalidates the old approval.

Useful? React with 👍 / 👎.

My restored rule created a deadlock: R1/R2 have a re-triggered producer
update an existing PR, while the new invariant forbids pushing to an
approved one. Resolution: the stage does not push. It labels the PR
stale, comments once, and stops — the operator merges, dismisses the
approval, or closes it. An approved PR belongs to the operator, so the
lane never edits one behind them.

Completing the previous fold rather than a new round: the deadlock was
introduced by that fold.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
yihanzhu pushed a commit that referenced this pull request Aug 27, 2026
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@yihanzhu

Copy link
Copy Markdown
Owner Author

Adopted — and this was a defect in my own fold, not a new round: restoring "never push to an approved PR" collided with R1/R2's "open or update" and deadlocked the case where the upstream artifact moves while a PR sits approved and unmerged. Resolved: the stage does not push — it labels the PR stale, says so once, and stops. You merge it, dismiss the approval, or close it; the stage rebuilds once the PR is yours again. An approved PR belongs to the operator, so the lane never edits one behind you.

@yihanzhu

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0b76d303fa

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread work/v2-phase-2/spec.md Outdated
Comment on lines +70 to +71
unmerged — it does not push. It labels the PR `stale`, says so in one comment,
and stops. The operator then merges it, dismisses the approval, or closes it;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Remove merging from stale-PR recovery

When the upstream intent moves while an approved spec PR is open, the newly specified recovery explicitly permits merging that stale PR. This lands a spec.md whose intent-blob mismatches main; the spec workflow will not rerun because the merge changes the spec rather than the intent, while pending-impl.sh rejects the mismatch, so the chain remains stranded. Require dismissal followed by a producer rerun/rebuild (or another mechanism that restores freshness) rather than presenting merge as a valid recovery.

Useful? React with 👍 / 👎.

Comment thread work/v2-phase-2/spec.md Outdated
Comment on lines +15 to +16
stated here so this spec stands on its own: the fix stage needed a third
`claude[bot]` trigger edge where R5 allows two, and it was the one job holding write

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Reconcile the bot-trigger edge count

The amendment says the deferred fix stage would require a third claude[bot] trigger edge, but R5 later says this phase opens one edge and that the second allowed edge served that same fix stage. In the described chain, fix-on-review-comment is the second edge and a fix push reuses review-on-agent-PRs; no third distinct actor-gate edge is identified. This makes a stated security reason for the deferral internally unauditable, so either identify the third workflow transition or correct the count and rationale.

Useful? React with 👍 / 👎.

Codex on the current head, both adopted:
- my stale-PR recovery offered merging as a way out. That lands an
  artifact whose recorded upstream hash no longer matches main, and no
  stage rebuilds it — merging changes the artifact, not the upstream that
  moved. The way out is to close it, or dismiss the approval and let the
  stage rebuild from current upstream.
- the amendment said the fix stage needed a third edge while R5 said the
  second allowed edge already served it. Both are true and the text now
  says so: R5 allows two, the fix stage needed both plus a third (the
  dispatch re-running review after a push-back that changes no code) —
  which is precisely why it was deferred.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
yihanzhu pushed a commit that referenced this pull request Aug 27, 2026
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
yihanzhu pushed a commit that referenced this pull request Aug 27, 2026
Splitting the amendment into #142 left an older copy of it committed
here. Merging this after #142 would have quietly reverted the four
rounds of fixes #142 has taken since — a stale artifact reintroduced by
merge order, which is exactly what the chain's hashes exist to prevent
and exactly what a file-level revert sneaks past them.

This PR now carries no spec change at all: the plan, the rules, the docs
sweep and the hook fix. The spec is #142's alone.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@yihanzhu

Copy link
Copy Markdown
Owner Author

Both findings folded: a stale PR is rebuilt, never merged (merging it would land an artifact whose recorded upstream hash no longer matches main, and no stage would rebuild it — the merge changes the artifact, not the upstream that moved), and the edge count now reads honestly (R5 allows two; the fix stage needed both plus a third for the push-back re-review, which is precisely why it was deferred).

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f89e9240ad

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread work/v2-phase-2/spec.md Outdated
Comment on lines +77 to +78
upstream that moved. The operator closes the stale PR (or dismisses the approval
and lets the stage rebuild it from the current upstream). An approved PR belongs

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Add a trigger to stale-PR recovery

In the stale-approved-PR scenario, neither recovery action schedules the producer again: the Design gives the spec and implementation workflows only push-to-main path triggers (lines 101–103), while dismissing an approval or closing a PR emits no such event. Because the upstream merge that found the stale PR has already been consumed and the stage explicitly stopped, the artifact remains stale or closed until an unrelated merge or manual rerun; require an explicit rerun/dispatch after either operator action so the promised rebuild occurs. This is fresh evidence from the newly added recovery path, rather than the earlier merge-versus-rebuild concern.

Useful? React with 👍 / 👎.

Codex: closing a stale PR or dismissing an approval fires no event, so
push-triggered stages never wake and the slug sits stranded — my recovery
told the operator to do something the lane could not act on. Both stage
workflows now carry workflow_dispatch beside their push trigger, gated to
the operator, and the recovery says to use it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
yihanzhu pushed a commit that referenced this pull request Aug 27, 2026
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@yihanzhu

Copy link
Copy Markdown
Owner Author

Adopted. Closing a stale PR or dismissing an approval fires no event, so the push-triggered stages would never wake — my recovery told you to do something the lane could not act on. Both stage workflows now carry workflow_dispatch beside their push trigger, operator-gated, and the recovery says to use it.

That is three consequences-of-a-fix in a row on this one rule: the rule, the deadlock it created, and now the dead end its resolution left. Each was real, and the chain is shorter each time — worth watching for the point where a finding is no longer a consequence of the last fix, which is what settling looks like.

@codex review

@yihanzhu

Copy link
Copy Markdown
Owner Author

@codex review

Codex [Security]: adding workflow_dispatch to the stage workflows
re-opened the rerun hole the probe already taught us — github.actor stays
the ORIGINAL dispatcher on a re-run, so any write-capable collaborator
can re-run an operator's dispatch and spend their subscription. R5 now
requires github.triggering_actor to match too, as plumbing-test.yml
already does.

The lesson existed in the plan and in a live workflow; the spec never
carried it, so a new dispatch path inherited the old hole. Rules learned
in one artifact have to reach the artifact that governs.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@yihanzhu

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b6563156f3

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread work/v2-phase-2/spec.md
Comment on lines +53 to +57
- **R4 — bounded fix loop. DEFERRED** to its own intent (see the amendment note
above). It described: review findings trigger a fix pass that bumps the `round-N`
label before acting; at `round-3` it applies `needs-human`, posts the productive-cap
comment, and stops. That design is superseded — the next intent starts from the
credential split stated in the amendment note above, not from this text and not

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Remove the fix-loop helper from the active design

After deferring the entire bounded fix loop, the active Helpers section still prescribes scripts/v2/round-cap.sh and a hermetic test for it (lines 119–123), even though none of the three remaining workflows consumes round labels and address-review was removed. This leaves fix-loop-only machinery in the phase scope despite the amendment saying that design is superseded; move the helper and its test into the deferred intent or document a remaining in-scope consumer.

Useful? React with 👍 / 👎.

@yihanzhu yihanzhu added the needs-human Escalation: round cap hit, ambiguous spec, oversized PR, or failure label Aug 27, 2026
Codex: the Helpers section still prescribed round-cap.sh and its test
while nothing in the three workflows consumes round labels — fix-loop
machinery left in an active design reads as work to do. It is already
merged, so the spec now says it stays and sleeps until the deferred
intent wakes it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
yihanzhu pushed a commit that referenced this pull request Aug 27, 2026
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@yihanzhu

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 44966e34a4

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread work/v2-phase-2/spec.md
Comment on lines +109 to +110
the two stage jobs **plus `workflow_dispatch` on each, so the operator can
restart a stage after clearing a stale PR** (see the approved-PR rule in R5),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Exclude skipped dispatches from the quota count

When a non-operator collaborator manually dispatches either producer workflow, the actor gate skips the agent job, but the workflow run is still recorded. scripts/v2/quota-preflight.sh lines 15–22 explicitly assumes these workflows can never have skipped runs, while lines 66–74 count every run for each workflow without filtering by event, status, or triggering user; gh run list --help confirms that --event, --status, and --user are the available filters. Adding workflow_dispatch here therefore lets 20 cost-free dispatches trip the backstop and block legitimate lane work for the five-hour window, so the quota helper or recovery trigger design must be adjusted.

Useful? React with 👍 / 👎.

Codex: adding workflow_dispatch to the producer stages broke the
invariant quota-preflight.sh depends on — that a counted workflow's runs
always mean the agent ran. A dispatch that fails the actor gate still
records a skipped run, so a collaborator could spam dispatches until the
brake trips and starves the lane. Counting --event push restores the
invariant: the ruleset means only an operator merge causes those.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@yihanzhu

Copy link
Copy Markdown
Owner Author

@codex review

@yihanzhu yihanzhu removed the needs-human Escalation: round cap hit, ambiguous spec, oversized PR, or failure label Aug 27, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 98e7b6ce57

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread work/v2-phase-2/spec.md Outdated
Comment on lines +65 to +68
this reason — or `allowed_bots: claude[bot]` only on deliberately
opened bot edges — this phase opens exactly one, review-of-agent-PRs. R5's second
allowed edge, the fix-on-review comment, went with the deferred stage, and the
third edge that stage would also have needed is precisely why it was deferred);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Gate bot-originated reruns by the triggering actor

Security: When a write-capable collaborator reruns a review run originally triggered by claude[bot], GitHub preserves the bot as github.actor and records the collaborator only in github.triggering_actor—the behavior already documented in .github/workflows/plumbing-test.yml lines 30–33. The operator alternative now checks both identities, but the allowed_bots: claude[bot] alternative places no restriction on triggering_actor, so such a rerun can still pass the bot edge and spend the subscription or post duplicate reviews. Require an authorized triggering actor on the bot alternative as well.

Useful? React with 👍 / 👎.

@yihanzhu yihanzhu added the needs-human Escalation: round cap hit, ambiguous spec, oversized PR, or failure label Aug 27, 2026
Codex found the actor/triggering_actor hole for the third time, at a
third location: a collaborator can re-run a bot-triggered review, and
github.actor stays claude[bot] while only triggering_actor names them.

Patching a third edge would have invited a fourth. R5 now states it as
one invariant covering every job in the lane — operator gates, dispatches,
and the bot edge alike — instead of a note attached to whichever gate was
last found wanting.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@yihanzhu

Copy link
Copy Markdown
Owner Author

@codex review

@yihanzhu yihanzhu removed the needs-human Escalation: round cap hit, ambiguous spec, oversized PR, or failure label Aug 27, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e5e0916c81

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread work/v2-phase-2/spec.md Outdated
Comment on lines +68 to +69
requires the triggering actor to be the operator (or, on the bot edge, the bot
itself), alongside whatever `github.actor` or `allowed_bots` allows. The probe

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Allow the operator to rerun bot-originated reviews

When a claude[bot]-originated review run fails transiently and the operator clicks re-run, github.actor remains the bot while github.triggering_actor becomes the operator (the behavior documented in .github/workflows/plumbing-test.yml lines 30–33). Requiring the triggering actor to be the bot itself makes both the bot alternative and the operator alternative fail, so no authorized human can rerun that review and R3 may remain unsatisfied without manufacturing another PR event. Allow the operator as an authorized triggering actor on the bot edge while continuing to reject other collaborators.

Useful? React with 👍 / 👎.

@yihanzhu yihanzhu added the needs-human Escalation: round cap hit, ambiguous spec, oversized PR, or failure label Aug 27, 2026
My own both-actors rule was written tightly enough to lock the operator
out of re-running a review that failed transiently — the triggering actor
on such a re-run is the operator, not the bot. The rule now names the two
acceptable triggering actors explicitly: the operator, or the bot itself.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@yihanzhu

Copy link
Copy Markdown
Owner Author

@codex review

@yihanzhu yihanzhu removed the needs-human Escalation: round cap hit, ambiguous spec, oversized PR, or failure label Aug 27, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 22f1d3307e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread work/v2-phase-2/spec.md
Comment on lines +92 to +93
upstream that moved. The operator closes the stale PR, then **re-runs the stage
by dispatch** — closing a PR or dismissing an approval fires no event, so the

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve the single-PR invariant during stale recovery

The fresh close-and-dispatch recovery still has no compliant outcome when the stale PR was already approved: reusing and reopening that PR requires pushing new content to a PR the operator approved, while opening a replacement violates the repository's rule in work/README.md lines 18–20 that reruns update the existing PR and never open a second one for the slug. Thus an upstream change can still strand an approved spec or implementation PR; specify a recovery that clears the approval and safely reuses the PR, or explicitly revise the single-PR invariant.

Useful? React with 👍 / 👎.

@yihanzhu yihanzhu added the needs-human Escalation: round cap hit, ambiguous spec, oversized PR, or failure label Aug 27, 2026
Codex: closing a stale PR and re-dispatching leaves no legal move if the
one-PR-per-slug rule counts closed PRs — reopening means pushing into an
approval, and a new PR looks like a second one. The rule is about
concurrency: one OPEN PR per slug. A closed PR is history.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@yihanzhu yihanzhu removed the needs-human Escalation: round cap hit, ambiguous spec, oversized PR, or failure label Aug 27, 2026
yihanzhu pushed a commit that referenced this pull request Aug 27, 2026
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@yihanzhu
yihanzhu merged commit b151caf into main Aug 27, 2026
2 checks passed
@yihanzhu
yihanzhu deleted the ystack/spec/v2-phase-2-amend branch August 27, 2026 21:20
yihanzhu added a commit that referenced this pull request Aug 27, 2026
* plan: record the probe verdict and the rules it cost us

R6 answered — app events cascade, so the lane uses the direct path.
The five probe rules and the three reviewer-loop rules are now written
into the plan, so an implementer who never saw the conversation gets
them: allowlist by command prefix, writes behind a deterministic
wrapper, assert side effects, verify secrets via API, dispatch only
from the default branch; fence verdicts to the head, let them settle,
bump the round label before acting.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* AGENTS.md: the repo's rules, in the file other agents read

Codex reads AGENTS.md, not CLAUDE.md — so pointing it at this folder
meant it never saw the conventions, the review policy, or the chain.
Thin bridge that points at the real sources instead of duplicating them
(a copy would drift), plus the handful of rules that bite.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* AGENTS.md: the repo's rules, in the file other agents read

Codex reads AGENTS.md, not CLAUDE.md — so pointing it at this folder
meant it never saw the conventions, the review policy, or the chain.
Thin bridge that points at the real sources instead of duplicating them
(a copy would drift), plus the handful of rules that bite. Registered in
the manifest.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* One rules file: AGENTS.md canonical, CLAUDE.md imports it

Two files describing how to work here would drift — the same class of
bug this repo keeps catching. AGENTS.md is now the single source (the
vendor-neutral name Codex and most tools read); CLAUDE.md is an import
so Claude Code loads the same text with no copy. Pointers in REVIEW.md
and the stage skills follow.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* AGENTS.md: drop the framing the merge duplicated

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* plan: fold six review findings — including three of my own rules

Codex on the brief, all adopted:
- assert the side effect THIS stage should have; "a PR exists" is
  vacuous for review and fix jobs, which run on an existing PR
- bind verdicts to the reviewed head SHA, not a timestamp: a review of
  head A can land after head B is pushed and pass a time fence
- wait for a completion marker, not a fixed settle window — a slow
  review wakes the fix job early, a late comment starts a duplicate
- load write wrappers from the default branch: a same-repo PR can edit
  its own wrapper and the job would run the PR's version
- corrected my dispatch rule: --ref works once a workflow exists on the
  default branch; my earlier claim was inferred from a run that had
  actually failed on the allowlist
- marked PR A and the probe done and retired the fallback in the steps
  and risks, which still told the implementer to do obsolete work

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Fold five more findings: guard the rules file, retire a stale permission

Codex round 2 on the brief, all adopted:
- SECURITY: AGENTS.md became the canonical rules file but no constitution
  list protected it — an unattended PR could have rewritten the safety
  rails directly. Added to REVIEW.md, proposals/README.md, and its own
  stage rule.
- The old permission for the manager to auto-merge low-risk PRs survived
  into the canonical file, contradicting "no agent may merge" three lines
  below. Retired explicitly: merging is the operator's, always.
- PR B cannot review itself — a pull_request workflow only fires when its
  file is already on the default branch — so its proof is the existing
  harness plus the operator's read; the smoke test proves the lane fires.
- The reviewed-head marker has to come from THIS phase's reviewer, which
  is Claude: the review skill emits `reviewed-head: <sha>` and the fix job
  parses it (the same parser reads Codex's body later).
- Human docs pointed at a stub GitHub does not expand; they now point at
  AGENTS.md, and the stub carries a real link.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Retire the agent merge path everywhere it was still promised

Codex round 3 found the live persona still telling yshifu to run
merge-pr.sh — a permission the branch ruleset retired hours earlier.
Chasing it turned up the same stale promise across the product: README's
team table, loop diagram, design decisions and rollout; QUICKSTART's
adopter walkthrough; the routines; both reviewer runbooks; the repo-setup
template; and RESTORE, the disaster-recovery runbook — the worst place to
carry a rail that no longer exists.

Now, in one voice: yshifu labels a reviewed-clean head merge-ready and
hands the PR to the operator, who merges. merge-pr.sh stays for the
operator's own use. The deferred "unattended auto-merge" promise is gone
with it — there is no agent merge path, present or planned.

Also folded (same review round): constitution list completed with
CLAUDE.md and REVIEW.md; review and fix jobs load stage SKILLS as well as
wrappers from the trusted default branch; the reviewed-head marker is
stamped by a deterministic step after the review step, never written by
the model (an injected diff could otherwise forge a verdict); the marker
carries the verdict so a clean review no longer burns a fix round; and a
push-back re-triggers review so a standoff can still reach its cap.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Fix two regressions the post-cap review found in live files

Both are mine, from removing merge authority earlier:
- RESTORE's branch-protection checklist still said merges go through
  "yshifu or the human" — opposite instructions in the same runbook
- rewriting the merge-ready rule kept only the head check; the retired
  harness compared reviewed head AND base, and when main advances the
  head SHA is unchanged while the reviewed diff is gone. The label now
  goes void on either.

The brief-level findings from this round go to the operator: the cap
holds.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* plan: the lane ships three workflows; fix-on-review is deferred

Operator's ruling at the cap. The fix stage is cut from this phase and
comes back as its own intent with its own spec.

Two reasons, both recorded in the plan: the fix stage needed a third
claude[bot] trigger edge while the approved spec allows two, and a plan
that reaches past its spec gets shrunk rather than the spec amended; and
every security finding of the last two review rounds landed on that one
job, the only one that holds write credentials, runs PR-authored code,
and reads untrusted PR text at once. That earns a clean design, not four
patches.

Cut with it: the stamped verdict marker, marker polling, the push-back
re-review path, and the round-label brake — all of them existed to serve
the fix job. What review-on-pr still needs is kept and now scoped to it:
PR text is data, the review skill loads from the trusted default branch,
the skill posts nothing and a plain step posts its file, so the job needs
no write access at all.

Until the fix stage exists, review findings are the operator's to handle
in a session — as they were while this phase was built.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Amend the spec to match the ruling, and fix the label it still promised

Codex, from the other direction: a plan may not exceed its spec, and it
may not silently drop one either. The deferral left R4 in the approved
spec with nothing building it, so the spec now records the scope
reduction the operator ruled: R4 deferred to its own intent, R5 scoped to
this phase's three workflows and its one open bot edge, exit test proving
R1-R3. The plan's spec-blob is rebaselined to the amended spec, so the
chain reads fresh.

Note the direction of this amendment: it REDUCES what the lane does. The
earlier refusal was to amend a spec so an agent could have a third
trigger edge — widening power to fit a plan. Recording less delivery is
the operator's call; widening rails is not.

Also live: setup-target-repo.sh still installed a merge-ready label
saying low-risk PRs are "auto-merged in-session", and it force-updates
labels on every run — so every target repo kept getting the retired
promise. Now: "waiting on YOUR merge (no agent merges; void once new
commits land)", and this repo's live label is reconciled.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Close the merge-helper bypass; point the plan at the amended spec

Codex [Security]: the guard hook explicitly exempted scripts/merge-pr.sh.
That exemption was written when the manager could still merge in-session;
once that permission was retired the exemption became a live bypass — in
a clone with no ruleset, or under an account that can merge, an agent
could merge through the helper, making this repo's "no agent has a merge
path" claim false. The hook now blocks it: the helper is the operator's
tool, run by a human.

The spec amendment moves to its own PR (Codex [Compliance]: a spec change
earns its own G2 gate, not a ride along with the plan that answers it).
This branch keeps the plan, whose spec-blob points at that amended spec —
so the chain reads fresh once the spec PR lands, and stale before it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* plan: rebaseline onto the folded spec (#142)

The spec amendment took three review findings, so its blob moved and the
plan's recorded hash went stale. Chain discipline: the plan names the
exact spec it answers, or the helpers report it stale and refuse to build
on it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* plan: rebaseline onto the spec's R6 fix (#142)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* plan: rebaseline onto the spec's round-3 fold (#142)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* plan: rebaseline (#142 deadlock fix)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* plan: rebaseline onto the spec's stale-PR and edge-count fixes (#142)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* plan PR: drop the stale spec copy it was still carrying

Splitting the amendment into #142 left an older copy of it committed
here. Merging this after #142 would have quietly reverted the four
rounds of fixes #142 has taken since — a stale artifact reintroduced by
merge order, which is exactly what the chain's hashes exist to prevent
and exactly what a file-level revert sneaks past them.

This PR now carries no spec change at all: the plan, the rules, the docs
sweep and the hook fix. The spec is #142's alone.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* plan: rebaseline onto the spec's dispatch fix (#142)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* plan: rebaseline onto the current spec (#142)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* plan: rebaseline onto the settled spec (#142)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: ci <ci@example.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
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