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 }}
Repository navigation
Commit 109e77b
Browse filesBrowse the repository at this point in the historyBrowse files
Sean Smith
authored and
Sean Smith
committed
fix(task): gate answer filing on return eligibility and project terminal truth
B-1 and B-3 land as one slice under CP-032 R-11: enabling the async Scope.result consumer without status-faithful finalization would make a cancelled child return an earlier turn retained fallback as degraded evidence.
B-3, in attachObservation: the lifetime waiter read waitHandle and then discarded it, calling finalizeOwnerScope(Exit.void). It now maps the authoritative BackgroundJob terminal onto the owner scope Exit -- cancelled to Exit.failCause(Cause.interrupt()), error to Exit.fail, otherwise Exit.void. The Exit is the carrier because AttachmentCoordinator.finalizeScope already maps interrupt to claimCancellation, failure to degrade, and success to close, so no new coordinator entry point is added and the projection cannot drift from the mapping every other finalization site obeys. The other nine finalizeOwnerScope callsites are deliberately unchanged: Exit.void is not neutral, it claims nothing and degrades nothing, so closeNow marks an unresolved scope degraded -- the truthful no-authoritative-terminal disposition.
B-1, in detect and executeSupplement: a new eligible() gate is the single path both run shapes take. With no scope, or a scope that already resolved, it returns immediately eligible evidence. Otherwise it announces the sequence, awaits invocation.result(), and derives filing identity from the controlling selected Assistant. A cancelled resolution returns undefined so nothing files. detect calls eligible AFTER its owner Assistant-error and failed-ToolPart checks, so those exits announce nothing; executeSupplement reaches it without them. That asymmetry is preserved, not copied.
A-1: renderAnswer now renders the retained selected record directly instead of rebuilding {fallback, degraded:false}, which had made candidate, observed and degraded selection unreachable on every observer route. controllingAssistant is exported from task-return.ts and reuses the private select rather than restating its precedence. The synchronous return consumes Info.output and the obsolete second ownerScopeHolder.scope.result call is deleted -- it would have latched a non-message as the retained fallback.
AttachmentContract.Current gains a readonly resolved flag. The eligibility gate is one-shot, but R-23 keeps an opened scope live through descendants, so a second sequential run on the same session inherited a resolution computed for a different turn, filed at the earlier position, and had its answer swallowed by the filing guard. Four parentPrompts assertions in task-attachment.test.ts caught it. eligible() now pre-checks current().resolved and takes immediate eligibility on its own turn.
T-032-3 adds the K14 oracle in attachment-coordinator.test.ts: a scope holding an earlier distinctive answer as its retained fallback returns cancellation with that text absent, while the control arm finalizing the same fixture as Exit.void reproduces the defect by replaying it as degraded evidence. T-032-1 in task-attachment-scope-lifetime.test.ts is re-framed from asserting the incident as correct to proving a yield files nothing until eligible.
Ref: CP-ocp-032 R-01, R-02, R-03, R-04, R-11, R-12, C2, C3
0 commit comments