Repository navigation
Description
Problem
/qa ends green on paths where nothing merged. The reported case: when verify-pr-base confirms
there is no open PR, it sets base_ok to "true", merge runs, and the run prints
complete — 0 item(s) resolved. ✓. The same shape holds wherever /qa does not merge: a failed
test, a red e2e or coverage-gate, a wrong base, a failed base query, and a merge node that
does not merge. Archon skips the node, nothing fails, and the run reads as a success.
After #439, a red /build opens no PR, so a
/qa on that branch meets the reported case on run 4's path.
This predates PR #650
(#505), which kept the behaviour and stated it
in the 0.30.0 changelog. The round 2 silent-failure review of that PR found it.
Rulings (grilled with the maintainer, 2026-10-27)
- Every
/qapath that does not merge endscancelled, never completed and neverfailed. This
matches bug(unic-archon-dlc): open-pr precedes its gate, and a config-value gate has no safe middle #439, where a red/buildis a result and endscancelled. - The cancel nodes follow the sibling idiom bug(unic-archon-dlc): open-pr precedes its gate, and a config-value gate has no safe middle #439 ruled: a
cancel:leaf whosewhenis the exact
negation of thewhenof the node it guards. - The PR's existence is a signal of its own,
pr_state, with five values:
open | merged | closed | none | unknown.base_okkeeps one meaning, "the open PR targets
$BASE_BRANCH", and is never set to stand for a missing PR. - The PR check runs right after
bootstrap, before any test, and again insideverify-pr-base,
because a PR can be merged or closed during UAT. - A red check still reaches
uat-gate. Its reject path is where a human files the failure as a
ticket, and AFK skips it at no cost. - A merge that landed but failed to write
resolvedon some items ends completed. It is not undone.
Acceptance criteria
-
Before any Box YAML changes, a probe on Archon 0.12.1 measures the behaviours the criteria
below rest on. It uses the probe shape of #439's
criterion 0: Archon run by path, an isolatedARCHON_HOME, a scratch repository outside every clone,
and a minimal workflow. It measures bug(unic-archon-dlc): open-pr precedes its gate, and a config-value gate has no safe middle #439's items 2, 3 and 4:- A
cancel:node whosewhenholds sets terminal statuscancelled, and a sibling with the
inversewhendoes not run, nor does any node that depends on that sibling. - On the other branch, the skipped
cancel:leaf does not stop the run from reachingcompleted. - A
cancel:message substitutes node-output references.
The loop runs the probe when it can, otherwise it is a HITL step for the maintainer before any YAML
changes. Stop rule, the same as bug(unic-archon-dlc): open-pr precedes its gate, and a config-value gate has no safe middle #439's: if any of the three does not hold, stop and report what
you measured. Do not adapt the design in the implementation. The PR records the probe's date, the
Archon version and each result, and states that bug(unic-archon-dlc): open-pr precedes its gate, and a config-value gate has no safe middle #439's criterion 0 may cite this probe for its
items 2, 3 and 4 instead of re-running them. - A
-
A
/qaon a branch whose PR state is notopenendscancelledbeforetestruns. Its last
message names the case and the next action:none: no PR was ever opened for the branch. Fix the build and re-run/build.merged: the PR is already merged. Nothing to do.closed: the PR was closed without merging. Reopen it, or abandon the work.unknown: the PR state could not be read. The message carries the cause. A failed query gives the
error as received and says to check access to the tracker and re-run/qa. A missing or unusable
tracker contract names the file and says to add it with/unic-archon-dlc:setup.
-
verify-pr-basereportspr_stateas well asbase_ok. It no longer setsbase_okto"true"
when no PR exists. A PR that is no longer open whenverify-pr-baseruns ends the runcancelled,
and the message carries the text for its case from criterion 1, joined as criterion 4 says. -
A
/qaon an open PR with the wrong base endscancelled, and its message says the PR targets
<actual>but<expected>was expected. It never says the PR is missing. -
When
testis notpass,e2eorcoverage-gateisfail, the base is wrong, or the base query
failed, the run endscancelledafterverify-pr-base. Its message names every cause that held,
not only the first. Atverify-pr-base, a PR that is not open and a wrong base are causes like the
others: the message joins the text from criterion 1 or 3 with every failed check, and no cause
replaces another. -
In HITL,
merge-gateasks for approval only whenmergewould run. Itswhenequals the
conditions ofmerge'swhen. -
mergereports as structured output whether it merged. When it runs and does not merge (the tracker
contract is missing, the tracker cannot merge, the branch policy refuses, or the merge call errors),
the run endscancelled. The message gives the reason, and the manual steps when the tracker cannot
merge. -
The line
merge: QA for "<slug>" complete … ✓is printed only after a merge that landed. If writing
resolvedfailed on some items, the line names them and does not count them as resolved. -
No path through
/qathat does not merge ends completed. -
docs/boxes/unic-dlc-qa.mddescribes the PR check, each cancel case and its message, and the
changedmerge-gatecondition. -
docs/architecture/20260925-unic-dlc-qa-pipeline.jsonshows the new nodes, and both PNGs are
exported again from it. -
CHANGELOG.mdrecords the change under### Breaking: runs that ended completed now end
cancelled. The release is aminorbump.
Activity
orioltf commentedon Oct 21, 2026
Triage notes. Found by the round 2 silent-failure review of PR #650, at head
bd943acd. I did not run/qa. I readverify-pr-base,merge-gateandmergeinunic-dlc-qa.yamlat that head.base_okis"true"for a confirmed "no open PR", andmergehas no branch for that case. Blocked by #505, because PR #650 rewritesverify-pr-baseand this ticket edits it again.orioltf commentedon Oct 26, 2026
Stale — do not follow. The criteria are approved and the fix is dispatched under
/afk-loop 498; the opener for the fix is the newer comment that starts with**Opener for #652**.Opener — How to start this session (written 2026-10-26 by
unic-sdlc-orchestrator-6, at dispatch)What this session produces
Triage and approved acceptance criteria in this ticket's body, then the label
ready-for-agent. Nothing else. The fix runs later under/afk-loop 498. This ticket now blocks #439, so/afk-loop 498reaches #439 only after this one merges.Start: the maintainer types
/wayfinder 498 #652. When the grilling starts, the maintainer types/grill-with-docs. Both carrydisable-model-invocation, so the session cannot invoke them itself.Do not close this ticket. This overrides
/wayfinderstep 4. This stream grills a ticket into its own criteria and implements it under the same number. Do not invoke/implement,/tddor/to-tickets. Replaceneeds-triagewith a state label when the maintainer approves.Read in this order
/buildrun opens no pull request. A/qaon that branch is the case this ticket fixes, so this ticket is now on run 4's path.apps/claude-code/unic-archon-dlc/.archon/workflows/unic-dlc-qa.yamlonorigin/develop:verify-pr-base,merge-gate,merge, andguard-not-readyfor the Box's own cancel idiom.docs/boxes/unic-dlc-qa.md, the part on the base check.The trap that costs an hour
Fixing it by setting
base_okto"false"when no PR exists.merge-gateandmergewould skip, the run would stop being green-with-nothing-merged, and the criteria would read satisfied. Butbase_okmeans "the PR targets the right base". Overloading it makes "no PR" and "wrong base" one value, and the operator reads a base mismatch where there is no PR at all. The no-PR case needs its own signal and its own message. Name that signal in the criteria.What this ticket does not decide yet
Each of these is a question for the maintainer. None is yours to settle with a plausible default.
mergereports that nothing merged and the run does not end with a success line. "Either is acceptable" is an open question. Pick one. bug(unic-archon-dlc): open-pr precedes its gate, and a config-value gate has no safe middle #439 ruled the sibling cancel idiom for/build, which argues for acancel:leaf here too./qare-run). Decide whether the message tells them apart, and what each tells the operator to do.verify-pr-baseruns after the tests and the UAT gate. A run with no PR spends both before it learns there is nothing to merge. Decide whether the no-PR check moves earlier, or say why it stays.cancel:node, it rests on behaviour bug(unic-archon-dlc): open-pr precedes its gate, and a config-value gate has no safe middle #439's criterion 0 probes on Archon 0.12.1, and this ticket lands first. Either measure it here, or say that it relies on the idiomguard-not-readyalready uses, measured on 0.10.1 only.Other traps
/qastalesapps/claude-code/unic-archon-dlc/docs/architecture/20260925-unic-dlc-qa-pipeline.json. If the criteria add one, they require its JSON updated and both PNGs exported again.CHANGELOG.mdentry goes under### Breakingif a run that ended green now endscancelled.The bar that proves it
Run the four reads from
docs/agents/dispatching-and-learning.md§ Before you post one on the criteria as a set. Then check:/qadispatched on a branch with no open PR cannot end with a success line, and its last message says no PR exists./qaon a PR with the wrong base still says the base is wrong, not that the PR is missing.A false pass is the overloaded
base_ok: every criterion reads satisfied, and the two failure cases print the same thing.On landing
unic-sdlc-orchestrator-7with the link. The orchestrator reads the criteria as one set and replies.needs-triagewithready-for-agent, set its priority if the maintainer moves it fromp2, and leave it unassigned for/afk-loop 498.Report back
Review and handover
There is no pull request. The maintainer approves the criteria in the session. The orchestrator reads them as one set before the label goes on. Implementation runs under
/afk-loop 498, which this seat records as unproven in the Consumer until a Consumer run reads it.Edited 2026-10-27 by
unic-sdlc-orchestrator-7: report-back address moved from orchestrator-6, which has handed off.[-]bug(unic-archon-dlc): `/qa` ends green without merging when no open PR exists[/-][+]bug(unic-archon-dlc): `/qa` ends green on paths where nothing merged[/+]orioltf commentedon Oct 27, 2026
Body rewritten with the criteria the maintainer approved in a grilling on 2026-10-27. What changed:
/qapath that does not merge: a failed check, a wrong base, a failed base query, and amergenode that does not merge. The maintainer chose this over a sibling ticket to avoid another round of delay. The title changed with it.cancelled, with a message per cause.pr_state(open | merged | closed | none | unknown), andbase_okkeeps its one meaning.verify-pr-base.cancel:leaf on Archon 0.12.1 once, before the YAML changes, because this ticket lands before bug(unic-archon-dlc): open-pr precedes its gate, and a config-value gate has no safe middle #439's own probe.p2top1.orioltf commentedon Oct 27, 2026
Criteria amended after the orchestrator read them as one set. The maintainer approved each change on 2026-10-27.
/qaon a branch with no PR. That needs a tracker a scratch repository cannot give, and the current Box has nocancel:leaf on that path to measure. The PR states that bug(unic-archon-dlc): open-pr precedes its gate, and a config-value gate has no safe middle #439's criterion 0 may cite this probe for its items 2, 3 and 4.verify-pr-base, a PR that is not open and a wrong base are causes like the failed checks. The message joins all of them, and no cause replaces another.mergereports whether it merged as structured output, and a missing tracker contract is one more non-merge cause.orioltf commentedon Oct 27, 2026
Opener for #652
Written 2026-10-28 by the
/afk-loop 498orchestrator, at dispatch. It supersedes the grilling opener above, whose job ended when the criteria were approved.What this session produces
First the probe of criterion 0, then, only if all three of its items hold, one pull request to
developthat changesapps/claude-code/unic-archon-dlc/.archon/workflows/unic-dlc-qa.yaml, its Box doc, its architecture diagram and the changelog, so that no/qapath that does not merge ends completed. The criteria in this ticket's body are the spec. Do not invoke/tddor/to-tickets: the Box is prose, and the bar is a run and a read (AGENTS.md§ Acceptance criteria are prose).Read in this order
gh release download v0.12.1 --repo coleam00/Archoninto a scratch directory, checksums checked, a wrapper that setsARCHON_HOMEto a scratch folder and runs that binary by its path, and a scratch repository outside every clone. This machine's ownarchonis v0.10.1. Leave it,~/.archonand~/.claudeuntouched.unic-dlc-qa.yamlonorigin/develop:bootstrap,guard-not-ready(the Box's owncancel:idiom),test,uat-gate,verify-pr-base,merge-gateandmerge, with the comments above each.apps/claude-code/unic-archon-dlc/docs/boxes/unic-dlc-qa.md, anddocs/architecture/20260925-unic-dlc-qa-pipeline.jsonwith thearchifyskill, which renders it.The trap that costs an hour
A path that reaches neither
mergenor acancel:leaf. The defect is a run where every node is skipped or green and nothing merged, so a fix is correct only if every path ends in a merge that landed or a cancel. Two things make a path easy to miss:verify-pr-baseandmergerun ontrigger_rule: all_done, andtest,e2eandcoverage-gatecan be skipped orunresolved. A cancel leaf'swhenmust be the exact negation of thewhenit guards, written against the same outputs, so the two cannot both be false.mergeitself can run and not merge (criterion 6). That needs its own leaf aftermerge, readingmerge's new structured output.Before you edit, list every path through the new graph on paper: the PR states, the check results, HITL and AFK, and the merge outcome. Put that list in the PR body, with the node each path ends in. Criterion 8 is that list.
What this ticket does not decide
bootstrap, or a change tobootstrap, both fit criterion 1.testmust then depend on that check, so that a cancel stops the run beforeteststarts. A sibling that depends onbootstrapalone can start in parallel with the cancel.pr_stateis read. The tracker contract governs it, as it does forverify-pr-basetoday. Name no tracker in the Box.Other traps
archifyskill. Print no PNG to your context.e2eandcoverage-gatecancel only onfail.unresolvedstill lets the merge through, as the comment abovemergeexplains. Criterion 4 keeps that.cd. The NDA hook refuses aghcommand that changes directory.The bar that proves it
The probe's three results, measured on 0.12.1 and written into the PR body with the date. Then the path list from the trap above, read against the YAML at your head: every path ends in a merge that landed or in a named cancel, and each cancel message carries the text criteria 1, 3, 4 and 6 give it.
A false pass is a run that reaches
completedwith nothing merged on one path the list left out. Another false pass is a cancel message that names only the first cause when several held (criterion 4).On landing
apps/claude-code/unic-archon-dlc/CHANGELOG.mdunder## [Unreleased],### Breaking, and commit it with the change.pnpm --filter unic-archon-dlc bump minor, and commit the result on its own aschore(unic-archon-dlc): release <version>.Closes #652, the probe results, the path list, and a line saying the change is unproven in the Consumer until a Consumer run reads it.Report back
Report in your final answer, as your worker prompt's step 7 says, and stop after the handover. If the probe's stop rule fires, your report is the probe comment's link and its three results. The orchestrator may continue you with fix rounds.
Review and handover
The orchestrator runs the review rounds, sends you the findings to fix, and merges when the gate holds. You do not merge, and you do not answer review threads.
/qareports failedresolvedwrites only on the console #664