Commit Graph
3 Commits
Author SHA1 Message Date
amosblomqvist e8fe5da6b1 fix: honest activation + turn-scoped practice gates (the BKT stuck-slot incident)
The bkt-practice record showed ONE turn in which the model concluded
(clean ack) and then every pose died on 'a problem is already active'
until it gave up ('the problem slot is stuck — the conclude calls report
success'). Two flaws, both fixed:

1. GATES READ A FROZEN RECORD. problem/conclude gates re-read the stored
   record per execute — but the record freezes at the turn's write-ahead
   (persistTurn lands only at turn END), so a mid-turn conclude → pose
   pair could never see each other. practiceTools now builds ONE
   turn-scoped gate (createPracticeGate) seeded once from the record;
   the executes flip it. Fresh closure per turn (the agent is built per
   request) — no cross-turn leakage.

2. PHANTOM ACTIVATION. activeProblemOf ignored tool RESULTS, so the
   composer mounted from a pose the gate itself had refused (owner
   ruling: 'either it goes through or it doesn't'). Honest activation:
   a problem activates only on its clean ack; a conclude frees only on
   its clean ack; errored and dangling calls are skipped. Retroactively
   heals the BKT record (all its poses errored, all concludes clean →
   no active problem). pendingProblemDismissalOf follows the same law
   via the shared cleanToolCallIds helper.

Pinned: the mid-turn conclude→pose pair works in one toolset; the gate
re-arms after a successful pose; lone errored/dangling poses activate
nothing; a clean pose under a rejection stays active; an errored
conclude frees nothing.
2026-10-05 01:22:25 +03:00
amosblomqvist 9362baf36e practice polish: no phantom wake, Practice header tag, honest meta
- needsContinuation: a persisted problem-pose ack (terminate:true ended
  the turn deliberately) owes no continuation — reloads after a pose no
  longer wake a phantom turn; error results stay owed like any
  interrupted tool.
- Chat header: practice sessions swap the phase chip for a quiet
  Practice tag (no probe→teach arc applies) and hide the coverage ring
  (practice never extracts — an ever-filling ring would lie).
- ChatSummary gains pendingProblem (activeProblemOf at projection); the
  sidebar meta says 'Problem waiting' for a practice row with a posed
  problem. Kind threads through Chat/[id] page.
- Home picker chip gains Clear (picks were otherwise irremovable).
2026-10-04 22:06:22 +03:00
amosblomqvist eb7454900c practice record mechanics: active-problem fold, thinking channel, deferred conclude
The native shapes beneath the practice tools (owner design 2026-10-04):
- activeProblemOf — the conclude-before-next-problem gate's fold (a
  conclude call OR a dismissal marker deactivates; the pose-time ack
  never does — nudges keep the card up).
- The thinking input: {problemCallId, commit, text} → practice-thinking
  marker; the label (THINKING_HINT/COMMIT_LABEL, single-sourced in
  contracts) is the only register difference the model sees.
- Ask-style problem dismissal: silent route appends the UI-only marker;
  the user's NEXT input prepends the synthesized conclude pair (call
  outcome:'dismissed' + shared ack) so the agent reads the discard in
  its own vocabulary and the slot frees.
- toLlmMessages: dismissal marker filtered; pair passes natively.
2026-10-04 21:41:29 +03:00