Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions docs/logs/INDEX.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,18 @@

- 2026-08-03 — Issue #1124 deterministic retry-wait callback fixture evidence
is recorded in the engineering, observational, and system logs.
- 2026-08-03 — Issue #1136 records immutable submission timeout capability,
one-shot dispatch, and reset/load all-stream detachment separately from #1133.

- 2026-08-03 — Issue #1133 corrects the prior displaced-result wording:
displacement revokes controls but does not end A outcome observation.

- 2026-08-03 — Issue #1130 submission-local outcome ownership, deterministic
barriers, and ToolWalk timeout ordering are recorded in all durable logs.

- 2026-08-03 — Issue #1128 native submitted-run ownership evidence is recorded
in the engineering, observational, system, and long-term logs.

- 2026-08-03 — Issue #1125 native Stop/steer/ToolWalk ownership evidence is
recorded in the engineering, observational, system, and long-term logs.

Expand Down
82 changes: 82 additions & 0 deletions docs/logs/engineering-log.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,88 @@
normal/race passed in 13.200s/14.719s. Isolated foreground
`./scripts/test-regression.sh` then passed normal/race plus 85.5% total
coverage and zero uncovered functions in 2m26s.
## 2026-08-03 (Issue #1136 immutable timeout authority)

- Replaced the provisional public handle cancel with a package-visible opaque
`TimedOutSubmissionTicket`. Its initializer is fileprivate to `Runner`; the
only mint point is `waitForTerminal`'s final deadline-edge lifecycle check.
Ticket consumption retains the private `RunSubmission` owner-token/generation
recheck and is transport-only. Terminal, failure, reset, and load revoke it.
- `RunSession` now tracks every submission stream by handle. Reset/load cancels
both displaced A and selected C rather than only the most recent stream.
- TDD red: removing the old API produced nine expected focused compile errors
at former direct call sites. Gated proof now requires no ticket/action before
deadline, B -> C -> A exact-one dispatch, duplicate refusal, and post-ticket
terminal/failure/reset revocation. Remaining full-gate evidence is recorded
by this corrected PR rather than inherited from the superseded implementation.
- Review correction: the first ticket implementation left a package-scoped raw
transport method callable before deadline. The ticket, constructor, and
transport closure now live in GoCodeUI; ToolWalk binds the immutable duration
at submission and `submissionTimeoutGate(for:)` alone verifies the derived
deadline and mints once. The #1146 CI-flake repair introduces an internal
`RunSession` monotonic-now seam shared by `RunSubmission.markStarted` and
`SubmissionTimeoutGate`; tests freeze/advance it at epsilon and exact
deadline instead of sleeping. `Runner.waitForTerminal` now accepts only its
poll interval so a caller cannot silently pass a conflicting timeout after
submission. A direct
gate regression plus a source-surface drift test prevents that bypass.

## 2026-08-03 (Issue #1133 passive displaced-submission outcome)

- Corrected the #1130 wait-policy gap: displacement is now a permanent action
fence, not a terminal ToolWalk result. Runner waits for its immutable A
handle's terminal/failure through deadline and never auto-answers/approves a
mismatched or displaced selected B.
- `cancelTimedOutSubmission` retains exact locally owned A transport authority
after B selection, but its displaced path is transport-only: it cannot alter
B selection, transcript, pending UI, or cancellation state.
- Test-first evidence: four URLSession-gated `RunSession.submit()` + Runner
tests were red before the repair (terminal/EOF/timeout returned displaced;
delayed ACK returned without A identity). The resulting #1133 tests prove
passive terminal, EOF failure, delayed acknowledgement, and B-safe timeout
policy. The stronger B -> C authority and revocation proof is tracked in
the separate #1136 entry above.
- Verification: final combined focused `PassiveSubmissionOutcomeIntegrationTests`
passes 10/10 (not the earlier intermediate 4/4 or 8/8 counts); strict format
(0/7 touched Swift files require formatting) and
full `swift test --package-path macapp` (244 tests / 46 suites) pass. Full
regression, independent review, and hosted checks remain.

## 2026-08-03 (Issue #1130 submission-local outcomes)

- Split `RunSubmission` into independent A-local `Lifecycle` and displacement
facts. A terminal or failure therefore remains available to the initiating
caller after scheduled B selection instead of becoming a false timeout.
- A delayed `startRun` acknowledgement now binds A's handle first, but only an
exact, undisplaced active handle may select/activate/account it. Stream EOF
and start/transport errors always settle A locally; they fail visible state
only while that same A still owns it. `finishRunIfCurrent` clears by object
identity rather than a reusable run-id lookup.
- ToolWalk now uses typed wait outcomes. Terminal/failure precede displacement,
and only `.timedOut` reaches guarded A cancellation. New deterministic gate
tests cover late acknowledgement, late start/EOF failure, reset/load
detachment, and zero B mutation; outcome tests cover ordering and cancellation.
- Verification: strict Swift formatting, focused submission/ToolWalk suites
(13 tests/2 suites), full `swift test` (238 tests/45 suites), and the
retained-pane `./scripts/test-regression.sh` pass (normal, race, 85.5% total
coverage, zero uncovered functions).

## 2026-08-03 (Issue #1128 submitted-run ownership)

- Added `RunSubmission`, returned by both native submit layers. It records A's
`startRun` identity, per-run transcript, terminal result, failure, and
displacement independently from the conversation's selected run.
- ToolWalk now waits, auto-controls, times out, and judges the handle. A
selected B produces an explicit displaced result before any B endpoint call.
A local lifecycle timestamp is retained so later authoritative B selection
works without weakening provisional stale-replay protection.
- Composer captures `.submit` or `.steer(A)` once; the pure execution seam
proves stale steering cannot fall through to a new submission.
- Verification: strict Swift format; focused submission/external/ToolWalk
suite (37 tests/5 suites); full Swift package (230 tests/44 suites); exact
repository normal/race regression; coverage 85.5% with zero uncovered
functions.

## 2026-08-03 (Issue #1125 native action-owner fence)

- Added expected-run cancel/steer boundaries. Chat Stop, Composer, and ToolWalk
Expand Down
45 changes: 45 additions & 0 deletions docs/logs/long-term-thinking-log.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,51 @@
later same-run admission; normal/race/package/full gates are green.
- Guardrails: no product source, API, SQLite schema, config, client, UI, or
lifecycle change; no sleep/timeout increase or synthetic production defect.
## 2026-08-03 (Issue #1136 immutable timeout authority)

- Command intent: make a timed-out submitted A independently and exactly
cancellable after B/C selection without allowing the timeout path to affect
B or C.
- Success: only a Runner deadline-minted opaque ticket can consume A's
started-only capability once; terminal, failure, reset, and load revoke it;
reset/load physically stop every A/C submission stream. Direct deterministic
proof complements #1133 policy waits.
- Non-goal: reintroducing run-ID lookup, changing server cancellation, or
mutating selected-run UI from timeout transport.

## 2026-08-03 (Issue #1133 intent correction)

- Command intent: a callback/cron continuation must visibly continue B while
the initiating tool walk truthfully observes its own submitted A outcome.
- Success: B displacement is sticky for control authority; A terminal/failure
after B is a valid A verdict; an A deadline cancels only A and produces no B
action or visible-state mutation.
- Non-goal: making B a hidden fallback, treating displacement as success, or
using shared `currentRunID` to judge/control A.

## 2026-08-03 (Issue #1130 submission-local outcomes)

- Command intent: repair the #1128 review findings without weakening the
native external-run ownership fences.
- User intent: an initiating A turn must receive its real terminal/failure
outcome, while a visible callback/cron B remains correct and controllable.
- Success: barrier-proven A terminal/failure survives B selection; late A work
cannot change B; ToolWalk cancels only a genuine A timeout; reset/load/EOF
are deterministic ownership boundaries.
- Guardrails: stacked native/ToolWalk-only change; preserve #1122/#1125
expected-run guards and #1128 A-only transcript/displacement behavior.

## 2026-08-03 (Issue #1128 submitted-run ownership)

- Command intent: close the remaining native composer/ToolWalk A-to-B ownership
gaps identified by Sol review after #1125.
- User intent: an agent-walk or user click must continue/control the submitted
conversation turn, never a later cron/callback continuation that happens to
be visually selected.
- Success: immutable composer action selection plus an A-only handle whose
identity comes only from `startRun`, with deterministic zero-B-action proof,
retained A terminal verdict, and safe failure/reset behavior.

## 2026-08-03 (Issue #1125 native action-owner fence)

- Command intent: repair the remaining stale native action paths identified in
Expand Down
47 changes: 47 additions & 0 deletions docs/logs/observational-log.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,53 @@
- The pre-deadline checkpoint includes retry state, exact due time, reserved
run ID, attempt one, and empty token/lease; checking all of them prevents a
no-call assertion from masking an accidental claim or fence leak.
## 2026-08-03 (Issue #1136 timeout capability proof)

- A real deadline is suitable for #1133 wait-policy coverage but is not enough
if any caller can turn a submission handle into authority. The opaque ticket
is absent before deadline and can be constructed only at Runner's deadline
boundary; deterministic consumption makes B -> C -> A exact-one dispatch
and terminal/failure/reset non-dispatch observable.
- A single mutable stream task would leave displaced A running when C starts.
The handle-keyed task registry permits reset/load to stop both streams.

## 2026-08-03 (Issue #1133 passive outcome observation)

- The #1130 handle correctly retained A lifecycle after B selection, but the
consumer stopped polling it on `.displaced`; durable A evidence was therefore
present but unobserved. A control authority and outcome observation are
separate concerns.
- Gated integration runs show B can precede A terminal, A stream EOF, A timeout,
or A start acknowledgement. Each retains B as the selected scheduled run;
only the deadline scenario emits an A cancel request.
- B can itself terminal before A while a user submits C. This proved timeout
authorization must follow A's stream lifetime, not `activeSubmission` or the
one current local-stream pointer. The final contract uses an immutable A
handle owner token plus reset/load generation and cancels every live local
submission stream when detaching a session.

## 2026-08-03 (Issue #1130 submission-outcome observation)

- The original single `State` made displacement overwrite terminal/failure
evidence. ToolWalk then saw only a nonterminal displaced handle and could
report an A timeout even when A had completed.
- A late `startRun` response is not a stale response to discard: its run ID is
needed for A-local diagnostics and outcome handling. It is stale only for
shared selection, accounting, streams, and visible error state.
- EOF is an ownership-sensitive failure: the visible A must stop spinning, but
the same EOF after B selection must not make B look failed.

## 2026-08-03 (Issue #1128 submission observation)

- A rendered run ID is insufficient when the action type is re-derived at
click time. Both the mode and owner must be captured together. Likewise,
shared session state is a presentation authority, not proof of which run a
ToolWalk submission started.
- The red regression additionally showed that a local run must record its own
first timestamped lifecycle frame. Otherwise it remains permanently
provisional and a genuinely newer scheduled continuation cannot become the
selected owner.

## 2026-08-03 (Issue #1125 action-owner observation)

- Stop and steer are authority-bearing UI actions: retaining a SwiftUI closure
Expand Down
56 changes: 56 additions & 0 deletions docs/logs/system-log.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,62 @@
complete tools normal/race (13.200s/14.719s) pass on the final source tree;
isolated repository regression also passes normal/race, 85.5% coverage, and
zero uncovered functions.
## 2026-08-03 (Issue #1136 immutable timeout capability)

- `RunSubmission` privately binds owner token, generation, lifecycle, and a
consumed bit. ToolWalk alone binds its configured duration at submission,
`markStarted` derives the absolute deadline, and `Runner.waitForTerminal`
mints a package-visible ticket with a fileprivate constructor only through
`RunSession.submissionTimeoutGate(for:)` after its exact deadline check. The
ticket captures a fileprivate transport closure;
no raw package or public `RunSubmission` handle-cancel API remains. A
handle-keyed task registry lets reset/load cancel all local streams.
- Deterministic native timing: production uses `ContinuousClock.now`; the
internal-only RunSession initializer injects the same monotonic closure into
`markStarted` deadline creation and gate expiry checks, so tests advance
epsilon/exact-deadline state without scheduler-dependent sleeps.
- Wait API boundary: `Runner.waitForTerminal` accepts only a polling interval.
The timeout is immutable submission configuration, not a second wait-phase
parameter that can conflict with the stored deadline.

## 2026-08-03 (Issue #1133 passive A outcome after B selection)

- Flow: ToolWalk captures `RunSubmission(A)` -> conversation stream selects B
and marks A displaced -> Runner disables all automatic controls yet continues
reading A-local lifecycle -> A terminal/failure is judged, or deadline sends
the existing A cancel endpoint through a local-ownership fence.
- The selected-run reducer remains the only B UI authority. The displaced A
timeout path intentionally performs no shared-state transition, so it cannot
clear B pending controls, selection, transcript, or acknowledgement state.
- `RunSubmission` carries a session-owner token and reset/load generation plus
a one-shot started-only timeout capability. It preserves A-only authority
through B -> C replacement without reconstructing it from an ID/set; terminal
or failure consume no capability, and reset/load cancels all live submission
tasks while invalidating old handles.

## 2026-08-03 (Issue #1130 submission-local outcome flow)

- Flow: local composer/ToolWalk A -> `RunSubmission.lifecycle` plus
`isDisplaced`; conversation SSE can select scheduled B without rewriting A.
A start/stream tasks settle the handle, while `RunSession` shared transcript,
accounting, and controls require exact active-handle identity and selected A.
- ToolWalk order is terminal -> failure -> displaced -> timeout. The first two
are judged from A's transcript, displacement performs no automatic control,
and only timeout calls existing expected-run cancellation for A.
- Reset/load synchronously displace and detach active A. A late response cannot
select the replacement conversation; a cancelled detached task is not
reported as a transport failure.

## 2026-08-03 (Issue #1128 submission lifecycle)

- Flow: Composer/ToolWalk -> `ProjectSession.submit` -> `RunSession.submit` ->
`RunSubmission` -> `startRun` response assigns A -> A-only per-run SSE
reduces the handle -> terminal/failure/displacement is observed by ToolWalk.
- A selected B synchronously marks a started A handle displaced. ToolWalk then
performs no automatic input/approval/timeout action against B. Reset/load
displaces unresolved submissions; a late server response exits before it can
reactivate the reset session.

## 2026-08-03 (Issue #1125 native action owner)

- Ownership path: rendered Stop/Composer or ToolWalk timeout -> expected run ID
Expand Down
33 changes: 33 additions & 0 deletions docs/plans/2026-08-03-issue-1128-submission-handle-impact-map.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Cross-Surface Impact Map: Issue #1128

## Ownership and Data Flow

- Composer captures `ComposerAction` once: either `.submit` or `.steer(A)`.
- `ProjectSession.submit` returns `RunSession.submit`'s `RunSubmission`; only
the successful `startRun` response writes its A identity. The per-run stream
alone reduces the handle transcript and terminal state.
- ToolWalk polls, auto-answers, auto-approves, times out, and judges this
handle. It returns a displaced result rather than resolving B from shared UI
state.

## API, Persistence, Compatibility

- No API, wire, schema, or persistence changes. Existing run-specific control
endpoints remain unchanged.
- Existing callers may discard the newly returned submission value; visible
Composer and ToolWalk use the ownership-aware path. Rollback is native-only.

## Lifecycle, Clients, and Operations

- A local run records its first timestamped lifecycle frame, allowing a later
authoritative scheduled continuation to displace it while retaining the
provisional-replay protection from #1007.
- Reset/load marks an unresolved handle displaced, so a late `startRun`
response cannot resurrect a torn-down conversation. TUI, harness, providers,
deployment, cron, and callbacks are unaffected by source search.

## Tests

- Deterministic stubs prove B before response cannot become A; later B causes
A displacement and zero B cancel; A transcript/terminal excludes B; failure
and reset do not resurrect A; captured steer never calls submit.
41 changes: 41 additions & 0 deletions docs/plans/2026-08-03-issue-1128-submission-handle-plan.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Plan: Issue #1128 submitted-run ownership

## Context and Scope

- Governing issue: #1128, stacked on #1127 head `d2cd29cf`.
- A composer closure captured only its rendered run ID but chose steer versus
submit using live state. ToolWalk similarly re-read global run/transcript
state after submitting, allowing a scheduled B to replace local A.
- In scope: immutable composer action selection, one A-only `RunSubmission`
handle returned by both native submit layers, ToolWalk lifecycle ownership,
and deterministic native regressions.
- Out of scope: harness API/persistence, callback or cron execution, TUI, and
scheduled-run selection policy beyond recording an existing local run's
first lifecycle timestamp.

## TDD and Verification

- Red: B selected before A's response can be mistaken for A; after A capture,
B can receive A's timeout action; a stale steer can fall through to submit.
- Green: the handle resolves only from `startRun`, retains A-only events and
terminal evidence, becomes displaced on selected B, and ToolWalk exits with
no B action. A real terminal A still receives its normal verdict.
- Gates: strict format, focused submission/external-control/ToolWalk tests,
full Swift package, repository normal/race/coverage gate, then independent
cheap review and hosted checks.

## Impact Map

- `2026-08-03-issue-1128-submission-handle-impact-map.md`.

## Checklist

- [x] Verify #1128 acceptance criteria and stacked #1127 base.
- [x] Add immutable composer action and A-only `RunSubmission` evidence.
- [x] Add deterministic B-before-response, B-after-capture, A-terminal, and
start-failure/reset regressions.
- [x] Run strict format and complete Swift package.
- [x] Run repository regression: normal/race passed; coverage passed at 85.5%
with zero uncovered functions.
- [ ] Publish stacked draft `Closes #1128` and obtain independent cheap review
plus hosted checks.
Loading
Loading