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
Two deliberate rules in this repo contradict each other, and the contradiction makes the ordinary
owner-approval wait unrecordable.
.fabrika.jsonc sets "parkCause": {"uncaused": "refuse"}. causeForEvent in packages/fabrika-cli/src/lane/report.ts reads that as:
every BLOCKED with no --cause is Required, refused at exit 52 with the log unappended. AWAITING-CP-APPROVAL maps to BLOCKED in that same file. So the terminal ship hands back when
owner approval is genuinely absent cannot be recorded at all.
Verified at origin/main. The closed PARK_CAUSES set is worktree-holds-branch, head-behind-base, assembly-conflict, replay-conflict, campaign-paused, spawn-dead, no-preview-render, no-design-manifest, no-rendered-delta, base-conflicted, queue-ejected, head-ci-red, repair-budget-spent, replay-budget-spent. None names an owner-approval wait.
The conflict is by design on both sides, which is why no new token fixes it by itself. The human:cp-approval row in packages/fabrika-cli/src/recipe/parks.ts keys on cause: null on purpose, and its own comment says why: BLOCKED out of ship folds to human:cp-approval whatever the block was, so a row that ignored the cause would clear a park
recorded for something else by reading an approval nobody was waiting on. Adding an awaiting-cp-approval token therefore also means re-keying that row, and the row can only be
re-keyed if the shipper always passes the token.
STRUCTURAL_PARK_CAUSES is not the escape here. Main added it for exactly this class, a cause
nobody can type read off the leaf, but its own admission rule is "only a leaf a single transition
can produce". human:cp-approval is the catch-all fold out of ship, produced by many transitions,
so binding it there would stamp every ship-stage block as an approval wait.
Triage note: the direction is open, and the two answers point opposite ways. Either (a) the
shipper starts naming the wait with a new awaiting-cp-approval cause and the parks.ts row is
re-keyed off null, or (b) requireCause stops applying to a leaf some recipe row already covers
with cause: null, so the existing route survives untouched. (a) changes what every recorder must
type; (b) narrows a guard this repo deliberately flipped on. That is why this leaves triage for a
person rather than a builder.
Triage note: searched, left standalone. Queried the park-cause surface and today's queue. #9011 (no token for an unreadable CI verdict), #9106 (a spent machinery lap parks uncaused) and #8889 (no token for a refused spawn) are the same family, but each is a missing token: the park
lands and the unpark refuses. This one sits upstream of that, because the park never lands at all. #9186 is the nearest twin, an uncaused STOPPED the build skill says is legal, and is genuinely
separate: its leaf has no recipe row at all, so (b) above would not cover it and its own fix would
not cover this. No open epic owns the vocabulary, so this is minted standalone.
Triage note: not the branch-drift story. The same ship cp-approval read reported clean base
drift, and root chose ordinary queue integration for that clean head. This issue is only about the
remaining owner-approval wait.
Acceptance criteria
A ruling is recorded choosing between (a) a new awaiting-cp-approval cause token the shipper passes, with the parks.ts row re-keyed off cause: null, and (b) exempting from requireCause any park leaf a recipe row already covers with cause: null.
With parkCause.uncaused set to refuse, lane report <n> --task issue --token AWAITING-CP-APPROVAL records the terminal instead of refusing at exit 52.
After that record, recipe unpark still routes the lane to its existing human:cp-approval clearance rather than refusing or matching a different row.
A park recorded out of ship for a reason other than an approval wait still does not match the human:cp-approval clearance.
Original report
Summary
With requireCause enabled, lane report refuses AWAITING-CP-APPROVAL even when ship cp-approval has proven that owner approval is absent. The closed cause set has no owner-approval value.
What I was doing
Driving issue 8882 and PR #8915 through the reviewed, green head 52a8bad, then recording the actual wait for fresh owner approval.
What I observed
ship cp-approval returned stop awaiting-approval after reading four owners and two reviews. The following supported lane report returned exit 52 with the log unappended: lane report 8882 --task issue --token AWAITING-CP-APPROVAL --pr #8915. Its diagnostic required a cause from the closed list, which contains no owner-approval cause. The lane remains at ship, so the actual external wait cannot be recorded honestly through this route.
The same approval read also reported clean base drift. Root explicitly chose ordinary queue integration for that clean head under user authorization, preserving actual approval, review and CI gates. This observation concerns the remaining owner-approval wait, not inventing a branch defect as its substitute cause.
The inspected code maps AWAITING-CP-APPROVAL to BLOCKED. causeForEvent requires a supplied cause for every BLOCKED when requireCause is on. Yet routeForCause documents human:cp-approval as a known park keyed by its leaf without a cause. No config, code or lane history was changed to bypass the refusal.
Why it matters
A normal founder-owned wait cannot enter the ledger under a supported policy. The operator must leave the lane looking active or select a different cause that does not describe what it is waiting for.
Reproduce with requireCause enabled and preserve the real owner-approval clearing read. Determine the smallest consistent way to record the existing known wait without weakening required causes for unknown parks.
Filed by an agent · session 01a089df-d8ca-74c0-be4c-ae8630f14c95 · 2026-09-11T02:27:51Z
Original report (verbatim)
Summary
With requireCause enabled, lane report refuses AWAITING-CP-APPROVAL even when ship cp-approval has proven that owner approval is absent. The closed cause set has no owner-approval value.
What I was doing
Driving issue 8882 and PR #8915 through the reviewed, green head 52a8bad, then recording the actual wait for fresh owner approval.
What I observed
ship cp-approval returned stop awaiting-approval after reading four owners and two reviews. The following supported lane report returned exit 52 with the log unappended: lane report 8882 --task issue --token AWAITING-CP-APPROVAL --pr #8915. Its diagnostic required a cause from the closed list, which contains no owner-approval cause. The lane remains at ship, so the actual external wait cannot be recorded honestly through this route.
The same approval read also reported clean base drift. Root explicitly chose ordinary queue integration for that clean head under user authorization, preserving actual approval, review and CI gates. This observation concerns the remaining owner-approval wait, not inventing a branch defect as its substitute cause.
The inspected code maps AWAITING-CP-APPROVAL to BLOCKED. causeForEvent requires a supplied cause for every BLOCKED when requireCause is on. Yet routeForCause documents human:cp-approval as a known park keyed by its leaf without a cause. No config, code or lane history was changed to bypass the refusal.
Why it matters
A normal founder-owned wait cannot enter the ledger under a supported policy. The operator must leave the lane looking active or select a different cause that does not describe what it is waiting for.
Reproduce with requireCause enabled and preserve the real owner-approval clearing read. Determine the smallest consistent way to record the existing known wait without weakening required causes for unknown parks.
Filed by an agent · session 01a089df-d8ca-74c0-be4c-ae8630f14c95 · 2026-09-11T02:27:51Z
Two deliberate rules in this repo contradict each other, and the contradiction makes the ordinary
owner-approval wait unrecordable.
.fabrika.jsoncsets"parkCause": {"uncaused": "refuse"}.causeForEventinpackages/fabrika-cli/src/lane/report.tsreads that as:every
BLOCKEDwith no--causeisRequired, refused at exit 52 with the log unappended.AWAITING-CP-APPROVALmaps toBLOCKEDin that same file. So the terminalshiphands back whenowner approval is genuinely absent cannot be recorded at all.
Verified at
origin/main. The closedPARK_CAUSESset isworktree-holds-branch,head-behind-base,assembly-conflict,replay-conflict,campaign-paused,spawn-dead,no-preview-render,no-design-manifest,no-rendered-delta,base-conflicted,queue-ejected,head-ci-red,repair-budget-spent,replay-budget-spent. None names an owner-approval wait.The conflict is by design on both sides, which is why no new token fixes it by itself. The
human:cp-approvalrow inpackages/fabrika-cli/src/recipe/parks.tskeys oncause: nullon purpose, and its own comment says why:BLOCKEDout ofshipfolds tohuman:cp-approvalwhatever the block was, so a row that ignored the cause would clear a parkrecorded for something else by reading an approval nobody was waiting on. Adding an
awaiting-cp-approvaltoken therefore also means re-keying that row, and the row can only bere-keyed if the shipper always passes the token.
STRUCTURAL_PARK_CAUSESis not the escape here. Main added it for exactly this class, a causenobody can type read off the leaf, but its own admission rule is "only a leaf a single transition
can produce".
human:cp-approvalis the catch-all fold out ofship, produced by many transitions,so binding it there would stamp every ship-stage block as an approval wait.
Triage note: the direction is open, and the two answers point opposite ways. Either (a) the
shipper starts naming the wait with a new
awaiting-cp-approvalcause and theparks.tsrow isre-keyed off
null, or (b)requireCausestops applying to a leaf some recipe row already coverswith
cause: null, so the existing route survives untouched. (a) changes what every recorder musttype; (b) narrows a guard this repo deliberately flipped on. That is why this leaves triage for a
person rather than a builder.
Triage note: searched, left standalone. Queried the park-cause surface and today's queue.
#9011 (no token for an unreadable CI verdict), #9106 (a spent machinery lap parks uncaused) and
#8889 (no token for a refused spawn) are the same family, but each is a missing token: the park
lands and the unpark refuses. This one sits upstream of that, because the park never lands at all.
#9186 is the nearest twin, an uncaused
STOPPEDthebuildskill says is legal, and is genuinelyseparate: its leaf has no recipe row at all, so (b) above would not cover it and its own fix would
not cover this. No open epic owns the vocabulary, so this is minted standalone.
Triage note: not the branch-drift story. The same
ship cp-approvalread reported clean basedrift, and root chose ordinary queue integration for that clean head. This issue is only about the
remaining owner-approval wait.
Acceptance criteria
awaiting-cp-approvalcause token the shipper passes, with theparks.tsrow re-keyed offcause: null, and (b) exempting fromrequireCauseany park leaf a recipe row already covers withcause: null.parkCause.uncausedset torefuse,lane report <n> --task issue --token AWAITING-CP-APPROVALrecords the terminal instead of refusing at exit 52.recipe unparkstill routes the lane to its existinghuman:cp-approvalclearance rather than refusing or matching a different row.shipfor a reason other than an approval wait still does not match thehuman:cp-approvalclearance.Original report
Summary
With requireCause enabled, lane report refuses AWAITING-CP-APPROVAL even when ship cp-approval has proven that owner approval is absent. The closed cause set has no owner-approval value.
What I was doing
Driving issue 8882 and PR #8915 through the reviewed, green head 52a8bad, then recording the actual wait for fresh owner approval.
What I observed
ship cp-approval returned stop awaiting-approval after reading four owners and two reviews. The following supported lane report returned exit 52 with the log unappended: lane report 8882 --task issue --token AWAITING-CP-APPROVAL --pr #8915. Its diagnostic required a cause from the closed list, which contains no owner-approval cause. The lane remains at ship, so the actual external wait cannot be recorded honestly through this route.
The same approval read also reported clean base drift. Root explicitly chose ordinary queue integration for that clean head under user authorization, preserving actual approval, review and CI gates. This observation concerns the remaining owner-approval wait, not inventing a branch defect as its substitute cause.
The inspected code maps AWAITING-CP-APPROVAL to BLOCKED. causeForEvent requires a supplied cause for every BLOCKED when requireCause is on. Yet routeForCause documents human:cp-approval as a known park keyed by its leaf without a cause. No config, code or lane history was changed to bypass the refusal.
Why it matters
A normal founder-owned wait cannot enter the ledger under a supported policy. The operator must leave the lane looking active or select a different cause that does not describe what it is waiting for.
Pointers
Suggested next step (non-binding)
Reproduce with requireCause enabled and preserve the real owner-approval clearing read. Determine the smallest consistent way to record the existing known wait without weakening required causes for unknown parks.
Filed by an agent · session
01a089df-d8ca-74c0-be4c-ae8630f14c95· 2026-09-11T02:27:51ZOriginal report (verbatim)
Summary
With requireCause enabled, lane report refuses AWAITING-CP-APPROVAL even when ship cp-approval has proven that owner approval is absent. The closed cause set has no owner-approval value.
What I was doing
Driving issue 8882 and PR #8915 through the reviewed, green head 52a8bad, then recording the actual wait for fresh owner approval.
What I observed
ship cp-approval returned stop awaiting-approval after reading four owners and two reviews. The following supported lane report returned exit 52 with the log unappended: lane report 8882 --task issue --token AWAITING-CP-APPROVAL --pr #8915. Its diagnostic required a cause from the closed list, which contains no owner-approval cause. The lane remains at ship, so the actual external wait cannot be recorded honestly through this route.
The same approval read also reported clean base drift. Root explicitly chose ordinary queue integration for that clean head under user authorization, preserving actual approval, review and CI gates. This observation concerns the remaining owner-approval wait, not inventing a branch defect as its substitute cause.
The inspected code maps AWAITING-CP-APPROVAL to BLOCKED. causeForEvent requires a supplied cause for every BLOCKED when requireCause is on. Yet routeForCause documents human:cp-approval as a known park keyed by its leaf without a cause. No config, code or lane history was changed to bypass the refusal.
Why it matters
A normal founder-owned wait cannot enter the ledger under a supported policy. The operator must leave the lane looking active or select a different cause that does not describe what it is waiting for.
Pointers
Suggested next step (non-binding)
Reproduce with requireCause enabled and preserve the real owner-approval clearing read. Determine the smallest consistent way to record the existing known wait without weakening required causes for unknown parks.
Filed by an agent · session
01a089df-d8ca-74c0-be4c-ae8630f14c95· 2026-09-11T02:27:51Z