You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
On 2026-04-11 I merged apexstack PR #10 after the CEO replied "go" to a 6-step plan whose step 1 was the merge. The CEO flagged this as overreach — they wanted to eyeball the merged PR on GitHub before it landed on main, and "go" was intended as plan-level authorization for the surrounding steps, not per-PR authorization for the merge itself.
Direct quote from the CEO: "u need explicit approval everytime, lets make sure this is recorded in apexstack".
The rule exists in .claude/rules/pr-workflow.md today as:
Before gh pr merge
[ ] Code Reviewer approved? NO → WAIT
[ ] Human approver approved? NO → WAIT
NO EXCEPTIONS. Not for "small fixes". Not for "just a typo".
…but that wording is ambiguous about what counts as human approval. The test-run failure was me treating a plan-level "go" as human approval, when the CEO meant it to be a per-PR, per-merge, explicit moment. The rule needs to be tightened so there's no room for that inference.
There is no mechanical enforcement for the human-approval side of the merge gate. block-unreviewed-merge.sh (shipped in PR #10) enforces the Rex (code-reviewer) side — it requires .claude/session/reviews/<pr>-rex.approved with a matching SHA — but the human side relies on prose discipline. That's the gap this ticket closes.
Acceptance Criteria
Prose fix (zero debate)
Update .claude/rules/pr-workflow.md "Before gh pr merge" section to state explicitly:
Plan-level authorization ("go", "continue", "ship it", "execute the plan", etc.) does NOT carry through to merge steps, even if the plan explicitly listed the merge.
Every gh pr merge requires its own per-PR, per-merge explicit approval that names the PR.
Treat gh pr merge the same as any other destructive / externally-visible action: stop and ask right before executing.
Add a concrete example showing a plan with a merge step, and what the correct "stop and ask" moment looks like, so there's zero ambiguity for future contributors.
Extend block-unreviewed-merge.sh to also require a CEO approval marker at .claude/session/reviews/<pr>-ceo.approved (in addition to the existing -rex.approved).
Add a new skill /approve-merge <pr> that writes the marker. The skill itself does not run gh pr merge — its only job is to record "the CEO explicitly approved merging PR X at HEAD Y." Design constraint: the skill should only write the marker when the user invokes it, never from Claude's own reasoning. (Yes, Claude can still technically forge this by running the skill unprompted — but the rule and the memory note make that a visible, auditable violation rather than an invisible inference.)
Update the hooks README and CLAUDE.md to document the CEO marker and the /approve-merge skill.
Scope notes
Do NOT try to mechanically enforce "the user must have typed this in the last message" — shell hooks can't see the chat buffer cleanly, and anything heuristic will have false positives/negatives.
Do NOT try to enforce via GitHub's review API (e.g. requiring an APPROVED review from a CODEOWNERS entry) — that's a separate branch-protection problem, belongs in a different ticket.
The /approve-merge skill should live in .claude/skills/approve-merge/SKILL.md and follow the same format as /start-ticket and /onboard.
Link to memory
Feedback memory captured at feedback_explicit_merge_approval.md in the CEO's local memory store. The in-repo rule in pr-workflow.md is the durable, portable version of the same rule for anyone using apexstack.
Context
On 2026-04-11 I merged apexstack PR #10 after the CEO replied "go" to a 6-step plan whose step 1 was the merge. The CEO flagged this as overreach — they wanted to eyeball the merged PR on GitHub before it landed on main, and "go" was intended as plan-level authorization for the surrounding steps, not per-PR authorization for the merge itself.
Direct quote from the CEO: "u need explicit approval everytime, lets make sure this is recorded in apexstack".
The rule exists in
.claude/rules/pr-workflow.mdtoday as:…but that wording is ambiguous about what counts as human approval. The test-run failure was me treating a plan-level "go" as human approval, when the CEO meant it to be a per-PR, per-merge, explicit moment. The rule needs to be tightened so there's no room for that inference.
There is no mechanical enforcement for the human-approval side of the merge gate.
block-unreviewed-merge.sh(shipped in PR #10) enforces the Rex (code-reviewer) side — it requires.claude/session/reviews/<pr>-rex.approvedwith a matching SHA — but the human side relies on prose discipline. That's the gap this ticket closes.Acceptance Criteria
Prose fix (zero debate)
.claude/rules/pr-workflow.md"Beforegh pr merge" section to state explicitly:gh pr mergerequires its own per-PR, per-merge explicit approval that names the PR.gh pr mergethe same as any other destructive / externally-visible action: stop and ask right before executing.CLAUDE.mdrule docs(#100): positioning rewrite — "where projects get forged" #4 ("2 REVIEWS | Code Reviewer agent + CEO approval") with a one-line clarification: CEO approval must be per-PR explicit, not inferred.Mechanical fix (needs decision)
block-unreviewed-merge.shto also require a CEO approval marker at.claude/session/reviews/<pr>-ceo.approved(in addition to the existing-rex.approved)./approve-merge <pr>that writes the marker. The skill itself does not rungh pr merge— its only job is to record "the CEO explicitly approved merging PR X at HEAD Y." Design constraint: the skill should only write the marker when the user invokes it, never from Claude's own reasoning. (Yes, Claude can still technically forge this by running the skill unprompted — but the rule and the memory note make that a visible, auditable violation rather than an invisible inference.)CLAUDE.mdto document the CEO marker and the/approve-mergeskill.Scope notes
APPROVEDreview from a CODEOWNERS entry) — that's a separate branch-protection problem, belongs in a different ticket./approve-mergeskill should live in.claude/skills/approve-merge/SKILL.mdand follow the same format as/start-ticketand/onboard.Link to memory
feedback_explicit_merge_approval.mdin the CEO's local memory store. The in-repo rule inpr-workflow.mdis the durable, portable version of the same rule for anyone using apexstack.c93cc52. Not reverted — the content was correct, only the authorization model was wrong.Non-goals
gh pr merge --autoflows. Those should be deferred to the ticket that handles branch protection / CI-gate merging.