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
{{ message }}
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
Repository navigation
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
Triage (maintainer-authorized one-off pass, 2026-08-09, registered on objectstack#6015): promoted finding → pm:queue. Reading a ref during render is a React correctness defect with a named user-visible consequence (a ?runAction=create_environment auto-trigger silently swallowed by an unrelated re-render) — timing-dependent bugs of this class only get more expensive to diagnose later. Small fix: move the consume into an effect.
Claim: PM loop round 5 (rolling slot refill)
Session: session_017Qqyix2QcnpUC9XeYVDzx3 · Branch: claude/issue-3803-autorun-create-ref · Worktree: objectui-issue-3803
File surface: packages/app-shell/src/environment/EnvironmentListToolbar.tsx (useAutoRunCreate) + tests. Serial constraints: disjoint from #3810 (app-shell AUTH pages), #3788/#4111/#4114 in flight.
Container & model: S, mode:subagent, model: opus
Sequencing note from the card, binding: FIRST write the failing test (the intermediate unrelated re-render between the effect consuming the flag and the runner consuming autoTrigger — the card names three real triggers: parent onUpgrade state, list refresh, entitlements re-resolve), THEN pick between the card's two fix shapes based on what the test shows about the runner's consumption timing. If the failure genuinely cannot be reproduced (the card admits it never was), the honest outcome is a report saying so with the render-purity fix still applied ONLY if it can be pinned by StrictMode/concurrent-semantics tests — not a speculative rewrite.
Investigation result (session session_017Qqyix2QcnpUC9XeYVDzx3, branch claude/issue-3803-autorun-create-ref, verified at origin/main sha bfdf3d419): the premise does not survive measurement. No PR.
The card correctly conditions its claim on the runner's consumption timing ("于是取决于 action:bar runner 消费 autoTrigger 的时机"). I measured that timing first, as the claim requires.
1. The runner consumes BEFORE the flag flips, in the same commit
action:button's auto-trigger is a useEffect guarded by its own ref (autoTriggered). React flushes passive effects in fiber-completion order, child before parent, so the button's effect runs strictly before useAutoRunCreate's effect in the same commit. Instrumented with the real action:bar + action:button (spying on history.replaceState for the parent's consume-and-strip, and on the runner's execute):
The runner has already consumed autoTrigger by the time consumed.current becomes true. The window the card hypothesises is therefore closed at its source, and no later re-render can reach into it.
2. All three named triggers fail to reproduce
Real renderer, real runner, deep-linked URL, asserting execute call count:
A null-to-resolved (entitlements resolve): execute=1
B unrelated re-render immediately after resolve: execute=1
C entitlements re-resolution (refreshKey path): execute=1
D StrictMode double-invoke: execute=1
B is the card's scenario driven as hard as the test environment allows (parent state churn, the onUpgrade path included) and it stays green.
3. The StrictMode/concurrent divergence is not constructible either
Render double-invocation happens back-to-back with no effect flush in between, so both invocations read the same consumed.current; there is no discarded-vs-kept divergence to pin. D above confirms it empirically. Per the dispatch's step 3 this is the "not pinnable" case, so no speculative rewrite was made.
4. Neither proposed fix shape would have fixed the hypothesised bug
Worth recording, because it is the most useful thing the investigation turned up. Both shapes the card proposes — (a) consumed as state, (b) deriving requested from the URL each render — leave autoTrigger disappearing on the next render exactly as today: in (a) setConsumed(true) re-renders to shouldRun === false, and in (b) the URL has just been stripped so requested is false. Only a sticky arm would keep autoTrigger stable until consumption, and that is a regression risk in the other direction: the runner's once-guard is a ref, so a later remount of the bar (list refresh) would re-fire the create dialog. The current un-arming is load-bearing, not an oversight.
Scope note
The eslint react-hooks/refs warning at the return shouldRun; line is real and still present (warning, not error — the lint gate is not red on it). It is a genuine render-purity smell with, as far as this investigation can show, no reachable behavioural consequence. Left untouched deliberately rather than suppressed.
One genuinely reachable defect was found next door and is filed separately as #4123: the hook arms on toolbarActions.length > 0 rather than on the create action's presence, so a toolbar without a create_environment action strips the deep-link param and triggers nothing — measured urlParam=null execute=0, and unrecoverable on reload.
Suggest closing this card as not-a-defect (or re-scoping it to the render-purity cleanup alone, which is cosmetic), with #4123 carrying the real behaviour question.
CLOSE — premise disproven by measurement, no code change (objectui seat PM, session session_017Qqyix2QcnpUC9XeYVDzx3; review of the dispatched dev's evidence, recorded in the comment above).
The card's defect claim was explicitly conditional on the runner's consumption timing, and the measurement answers it: with the REAL SchemaRenderer + action:bar + action:button (the existing tests stub the renderer, which is why they couldn't see this), React flushes passive effects child-before-parent — instrumented order ["runner:execute","parent:consumed+strip"] — so autoTrigger is consumed strictly before consumed.current flips. All three of the card's named re-render triggers plus StrictMode measured green (execute=1 each); the StrictMode double-invocation divergence is not constructible (back-to-back renders, no effect flush between). The deeper finding: NEITHER fix shape the card sketched would have fixed the hypothesized bug (state-based consumed re-renders to false; URL-derived requested is false post-strip — both drop autoTrigger on the next render exactly as today), and a sticky arm would regress the other way (re-firing the dialog on bar remount). The current un-arming is load-bearing design, not an oversight.
The one real edge found on the way is filed as #4123 (arming keys on toolbarActions.length rather than the create action's presence — a toolbar with actions but no create_environment strips the deep link unrecoverably; reachability via the ADR-0066 D4 capability-gate filter is the open triage question). That card stands on its own; this one closes.
The residual react-hooks/refs eslint warning is cosmetic (render purity with no constructible divergence) — not worth a card; it dies naturally whenever this hook is next touched for a real reason.
Activity
os-project-manager commentedon Aug 9, 2026
Triage (maintainer-authorized one-off pass, 2026-08-09, registered on objectstack#6015): promoted
finding→pm:queue. Reading a ref during render is a React correctness defect with a named user-visible consequence (a?runAction=create_environmentauto-trigger silently swallowed by an unrelated re-render) — timing-dependent bugs of this class only get more expensive to diagnose later. Small fix: move the consume into an effect.Generated by Claude Code
yinlianghui commentedon Aug 10, 2026
Claim: PM loop round 5 (rolling slot refill)
Session:
session_017Qqyix2QcnpUC9XeYVDzx3· Branch:claude/issue-3803-autorun-create-ref· Worktree:objectui-issue-3803File surface:
packages/app-shell/src/environment/EnvironmentListToolbar.tsx(useAutoRunCreate) + tests. Serial constraints: disjoint from #3810 (app-shell AUTH pages), #3788/#4111/#4114 in flight.Container & model: S,
mode:subagent,model: opusSequencing note from the card, binding: FIRST write the failing test (the intermediate unrelated re-render between the effect consuming the flag and the runner consuming
autoTrigger— the card names three real triggers: parentonUpgradestate, list refresh, entitlements re-resolve), THEN pick between the card's two fix shapes based on what the test shows about the runner's consumption timing. If the failure genuinely cannot be reproduced (the card admits it never was), the honest outcome is a report saying so with the render-purity fix still applied ONLY if it can be pinned by StrictMode/concurrent-semantics tests — not a speculative rewrite.Generated by Claude Code
yinlianghui commentedon Aug 10, 2026
Investigation result (session
session_017Qqyix2QcnpUC9XeYVDzx3, branchclaude/issue-3803-autorun-create-ref, verified atorigin/mainshabfdf3d419): the premise does not survive measurement. No PR.The card correctly conditions its claim on the runner's consumption timing ("于是取决于
action:barrunner 消费autoTrigger的时机"). I measured that timing first, as the claim requires.1. The runner consumes BEFORE the flag flips, in the same commit
action:button's auto-trigger is auseEffectguarded by its own ref (autoTriggered). React flushes passive effects in fiber-completion order, child before parent, so the button's effect runs strictly beforeuseAutoRunCreate's effect in the same commit. Instrumented with the realaction:bar+action:button(spying onhistory.replaceStatefor the parent's consume-and-strip, and on the runner'sexecute):The runner has already consumed
autoTriggerby the timeconsumed.currentbecomes true. The window the card hypothesises is therefore closed at its source, and no later re-render can reach into it.2. All three named triggers fail to reproduce
Real renderer, real runner, deep-linked URL, asserting
executecall count:B is the card's scenario driven as hard as the test environment allows (parent state churn, the
onUpgradepath included) and it stays green.3. The StrictMode/concurrent divergence is not constructible either
Render double-invocation happens back-to-back with no effect flush in between, so both invocations read the same
consumed.current; there is no discarded-vs-kept divergence to pin.Dabove confirms it empirically. Per the dispatch's step 3 this is the "not pinnable" case, so no speculative rewrite was made.4. Neither proposed fix shape would have fixed the hypothesised bug
Worth recording, because it is the most useful thing the investigation turned up. Both shapes the card proposes — (a)
consumedas state, (b) derivingrequestedfrom the URL each render — leaveautoTriggerdisappearing on the next render exactly as today: in (a)setConsumed(true)re-renders toshouldRun === false, and in (b) the URL has just been stripped sorequestedis false. Only a sticky arm would keepautoTriggerstable until consumption, and that is a regression risk in the other direction: the runner's once-guard is a ref, so a later remount of the bar (list refresh) would re-fire the create dialog. The current un-arming is load-bearing, not an oversight.Scope note
The eslint
react-hooks/refswarning at thereturn shouldRun;line is real and still present (warning, not error — the lint gate is not red on it). It is a genuine render-purity smell with, as far as this investigation can show, no reachable behavioural consequence. Left untouched deliberately rather than suppressed.One genuinely reachable defect was found next door and is filed separately as #4123: the hook arms on
toolbarActions.length > 0rather than on the create action's presence, so a toolbar without acreate_environmentaction strips the deep-link param and triggers nothing — measuredurlParam=null execute=0, and unrecoverable on reload.Suggest closing this card as not-a-defect (or re-scoping it to the render-purity cleanup alone, which is cosmetic), with #4123 carrying the real behaviour question.
Generated by Claude Code
Generated by Claude Code
yinlianghui commentedon Aug 10, 2026
CLOSE — premise disproven by measurement, no code change (objectui seat PM, session
session_017Qqyix2QcnpUC9XeYVDzx3; review of the dispatched dev's evidence, recorded in the comment above).The card's defect claim was explicitly conditional on the runner's consumption timing, and the measurement answers it: with the REAL SchemaRenderer + action:bar + action:button (the existing tests stub the renderer, which is why they couldn't see this), React flushes passive effects child-before-parent — instrumented order
["runner:execute","parent:consumed+strip"]— soautoTriggeris consumed strictly beforeconsumed.currentflips. All three of the card's named re-render triggers plus StrictMode measured green (execute=1 each); the StrictMode double-invocation divergence is not constructible (back-to-back renders, no effect flush between). The deeper finding: NEITHER fix shape the card sketched would have fixed the hypothesized bug (state-basedconsumedre-renders to false; URL-derivedrequestedis false post-strip — both dropautoTriggeron the next render exactly as today), and a sticky arm would regress the other way (re-firing the dialog on bar remount). The current un-arming is load-bearing design, not an oversight.The one real edge found on the way is filed as #4123 (arming keys on
toolbarActions.lengthrather than the create action's presence — a toolbar with actions but nocreate_environmentstrips the deep link unrecoverably; reachability via the ADR-0066 D4 capability-gate filter is the open triage question). That card stands on its own; this one closes.The residual
react-hooks/refseslint warning is cosmetic (render purity with no constructible divergence) — not worth a card; it dies naturally whenever this hook is next touched for a real reason.Generated by Claude Code
fix(app-shell): arm the create deep link on the create action, not on…