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
1 change: 1 addition & 0 deletions .abcd/work/DECISIONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -385,3 +385,4 @@
- 2026-09-21 — **Some models keep no transcript even while recording is on is built, reviewed and merged on one branch (`feat/2609091715` merged onto `integrate/2609091715`; itd-2609091715089488 shipped, spc-2609201007367486 closed with `--impact additive`), by the outer loop as a script (pilot 3) — and merged WITHOUT a release, because the lane was built before its parent.** Two fresh implementer sessions in sequence (the spec is over the split line), two Sonnet reviews, the fixes by resuming the second implementer, the spec closed in the same change, one planted merge conflict as the run's stop-and-resume test. The 2026-09-20 ordering line says transcript recording (itd-2609091707499248) lands before this intent; the maintainer's pilot-3 prompt chose this intent regardless, the loop ran it, and the ruthless review's one high finding is exactly the consequence: without the parent's switch `gateway.Options.TranscriptOn` is never set, so every models-list entry carries `recording: false` and every card and picker row reads "keeps no transcript" — which is true on a tree where nothing is recorded, but leaves criteria 9 and 10 (a visible difference between an excepted and a recorded model) unmet until the parent lands. The fix session captured it rather than changed the value rule: iss-2609211218478273, major, which refuses the release cut while open; the maintainer chose (at the pr step, 2026-09-21) to merge and not release: v0.9.3 follows the parent. Departures are rendered on the closed spec from the reports (the seam `Options.TranscriptOn` nil-is-off; `Control.TranscriptExcepted` removed in favour of `Config.NoTranscript` read per request; `docs/transcript.md` created rather than gained as a section; the form posts every per-model box explicitly because the merged save reads an absent key as "keep"). What holds each criterion: the field and its folded fail-closed reader, `TestNoTranscriptIsReadFoldedAndFailsClosed`; the field-by-field merge of the per-model map, `TestAPerModelFieldThePanelDidNotRenderSurvivesASave` (table-driven over every field) and `TestTheMergedPerModelMapHoldsExactlyTheKeysTheBodyNames`; the untouched save stays accepted, `TestASaveOfAnUneditedFormIsAccepted`; the form posts every box it draws, `TestSettingsFormPostsTheTranscriptBox` and `TestSettingsFormPostsThePerModelMapWhole`; settable before download, `TestTheExceptionIsSettableOnAModelNotYetDownloaded`; the debug arm refused, `TestAnExceptedModelRefusesTheDebugArm` and `TestExceptingAModelInSettingsRefusesItsNextDebugArm`, with both sentences in the markup, `TestBothPanelsSayHowTheExceptionMeetsDebugLogging`; `recording` in the base entry to every client, the two pinned-field-set tests and `TestModelsListReferenceDocumentsEveryFieldServed`; the icon in the client and the card, `TestChatClientPickerShowsTheTranscriptStateWithWords`, `TestChatClientTranscriptStateRule` (the Swift unit tier, 7 checks) and `TestTheCardDrawsTheTranscriptPillWithItsWords`; the bridge, `TestTheModelCommandOmitsAnExceptedModel`, `TestTheModelCommandRefusesAnExceptedModel` and `TestAChannelExceptedAfterItChoseIsRefusedAtTheNextMessage`. Not held on this tree: criteria 6 and 8's gateway tests (a mixed message array recorded whole; the first served request of an excepted model writing nothing) need the parent's store and are owed to its integration, where `Gateway.recorded` is called on the completions path. Reviews: ruthless FIX_FIRST with the one high finding above; security APPROVE, 0 findings (the merge cannot smuggle two spellings of one model past `validateModels`; the debug-arm read is per request, closing a stale-cache window the old seam had; the bridge has no path to an excepted model; `recording` renders only a fixed two-word vocabulary). Adjudication skipped on the count rule (1 < 3); docs currency CURRENT over `docs/transcript.md`, `docs/models-list.md` and `docs/discord-bridge.md`. Hand checks on the scratch root (integration build `v0.9.2-14-g17cfcc2c`, port 11999, loopback): row 10 of the debug-logging spec, owed since pilot 2 — arming succeeds before the exception (200), and once the model is excepted it is refused 409 with the reason, under the folded spelling too; through the real panel, two clicks on Debug logging post the 409 and the panel shows the reason; the panel's Transcript box posts `no_transcript: true` and every other box of the row as an explicit zero, and clearing it posts `false`; a stale form (its snapshot taken before `served_context` and `pinned` were hand-planted in `config.json` and the server restarted) saving only `no_transcript` leaves both planted fields on disk; both sentences are served (the debug control's "A model that keeps no transcript refuses this.", the transcript control's naming the bridge and the refusal); the card's icon carries the label "keeps no transcript" — before and after the exception alike, the finding made visible; pilot 2's owed DOM half of its row 4 (iss-2609210922572240): two clicks arm debug logging from the card (200, `DEBUG ARMED` pill, "Stop debug logging"), two more disarm it. Not checked by hand: the chat client's picker against a live server (the client compiles; its archtest and unit tier hold the words), and the Discord bridge (no bridge on the scratch root; the three bridge tests hold each arm). Not stood in for: the parent's landing, and the Fable design review the big run's plan asks for.
- 2026-09-21 — **The stuck context probe is three bug fixes, and pre-emption stays a draft** (branch `fix/stuck-probe`; iss-2609211334563318, iss-2609211334570516 and iss-2609211334576018 resolved; itd-2609211335097114 untouched). The live server (v0.9.1) refused every chat request 503 for six hours because the probe queued `mlx-community/GLM-OCR-bf16` — an image-to-text model, `chat: false` — and loaded it thirty-two times: the child raised `ValueError: Model type glm_ocr not supported` in its generate thread on the first request while its httpd answered `/health`, so the pool waited its ten-minute readiness timeout each time, and while loading the model was charged the whole budget (its default served window is worked out to fill what the budget has, so a 2.2 GB model with no served-window setting is charged ≈ the budget from the moment its entry exists — a property of the charge, not of loading, and not changed here). (1) The probe considers only models the server offers to chat: `Candidates()` and `MeasureNow` read `registry.Model.CanChat` with the rule in force. (2) A load the child has given up on fails in seconds: the pool watches the per-model child log while it waits for readiness (`LoadLogger`, which the real launcher's process satisfies) and ends the wait on a traceback whose terminal line is a ValueError, ModuleNotFoundError or ImportError, the line bounded and stripped of anything path-shaped; BrokenPipeError and the like are not in the set because the child survives them. A load that never became ready is recorded on the model (`registry.LoadFailure`: reason and provenance — runtime, budget, concurrency, served window); while it stands the probe and the self-test skip the model, a queued probe of it is dropped, and a request for it is refused at once as a NotReadyError carrying the reason; it is lifted by a moved provenance (through `RefreshStaleness`), a re-download, Load or Measure now. The pool tells the observer whether a failure was the model's own or interrupted (the entry taken out of the pool meanwhile), and only the former is recorded. The probe's ten-minute step floor is deliberately left: it is the gateway's own prefill base, which the probe's timer must not undercut or a slow step is filed as the deadline's, and a step's request includes the cold load the pool allows ten minutes for. (3) The refusal names the holder to an entitled client only: the gateway is handed the idle loop's status (which gains `since`), and a no-room refusal to a loopback or key-admitted client — the same clients the models list tells what is resident — names the model the job holds, the job, for how long, and that Unload releases it; the pool's own refusal still names no model and unentitled clients still get the generic sentence. The card's pill says "loading", "loading for the context probe", "held by the self-test". What would show these wrong: a chat model the probe now skips; a genuine load — a slow cold load — that a traceback line in the set fails early; a load failure that survives a runtime change; a keyless network client that reads a model id in a 503. Pre-emption — a real request taking the memory idle work holds — is itd-2609211335097114, a draft with no acceptance criteria, and is not implemented or approximated here.
- 2026-09-21 — **Corrections to the stuck-probe line above, from its two adversarial reviews** (an append-only ledger corrects by superseding; both lines stand and this one governs where they differ). (1) A load failure that is the pool's own bound — the readiness timeout, an exit by signal — is recorded as `transient`: it stands for this process (idle work skips the model, a client is told why at once) and is dropped at the next start, because a slow load on a busy Mac says nothing about the next one; the child's own traceback and a non-signal exit status stand until the provenance moves or a person retries, as the line above says. (2) The refusal's promise that Unload releases a model an idle job holds was false while the job's own request was in flight (the pool refused it as busy — the maintainer's two 409s on the live box): the idle loop now exposes `Runner.Interrupt(model)`, the run yields as it does for a client, and the panel's Unload asks for that first and waits, bounded, for the model to go (`TestUnloadFromThePanelTakesTheModelBackFromTheProbe`, watched red on the 409). (3) The child-log reader takes a terminal line only straight after a traceback's frames and only from whole lines; its open refuses a link and a FIFO; the sanitiser drops control characters and blanks a path with spaces as one path. (4) A failure reported after a hand retry has started a fresh load is not written over it; a Measure now arriving between Due's candidate snapshot and its pruning is not pruned. Accepted without change: a local process that can reach the child's loopback port can write a line the reader takes (the same trust class that can already plant registry.json; no new privilege); the provenance is read when the failure is recorded rather than when the load began.
- 2026-09-21 — **The 0.9.3 cut, codename Prellerhaus**, by hand on the 0.9.2 precedent (PR 140), on the maintainer's decision of 2026-09-21. The cut ships the stuck-probe fixes (iss-2609211334563318, iss-2609211334570516, iss-2609211334576018; PR 144, `impact: fix`) and the no-transcript models intent already on `main` without a release (itd-2609091715089488, PR 141, `impact: additive`), so the version is a patch; `build/CODENAME` is unchanged. Three open majors are deferred out loud with `deferred_after: "v0.9.3"`: iss-2609211218478273, because the no-transcript server half is live and every model truthfully reads "keeps no transcript" until the parent (itd-2609091707499248) lands, which is the next lane; iss-2609200815308397 and iss-2609190242198542 re-deferred with their existing reasons, because the maintainer tests by hand against this release and neither is of this cut's class. `abcd launch ship` refused the cut twice — the surface guard has no baseline in v0.9.2's tree (seeded after it; the clean-cutover manual roll is what puts one into a tag), and the unfixed-finding gate reads a deferral as `deferred_after: <base>` where this repository's records write the cut version — so the roll is manual, as the precedent's was; both are tooling findings for abcd, not this ledger. Retention after verification deletes the v0.9.2 release and keeps its tag.
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ found_during: "fidelity audit of itd-2609180959397172"
origin: researcher-authored
production_mode: hand-written
found_at: ".abcd/work/DECISIONS.md"
deferred_after: "v0.9.2"
deferral_reason: "Re-deferred at the 0.9.2 cut: the six live Discord checks need the maintainer's hand and a real Discord server; the maintainer tests by hand against this release; recorded here rather than stepped over."
deferred_after: "v0.9.3"
deferral_reason: "Re-deferred at the 0.9.3 cut: the six live Discord checks need the maintainer's hand and a real Discord server; the maintainer tests by hand against this release; recorded here rather than stepped over."
---

The six live checks the Discord bridge needs against real Discord are owed and none has been done: a real bot with a real token connecting at all; a mention in a real channel answered; a long answer cut and continued as Discord renders it; a resume across the Mac actually sleeping and waking; the slash commands appearing in Discord's own UI; and the edit cadence holding against Discord's real rate limits rather than a fake's headers. The shipping decision line at .abcd/work/DECISIONS.md:301 names all six as OWED and never claims them done, which is honest, but nothing in the issue ledger tracks them, so the intent is shipped with six of its acceptance criteria resting on a fake gateway. Six of the eleven criteria are MET_WITH_CONCERNS in the fidelity verdict rcp-91c0608082bd for exactly this reason. Until they are done, no user-facing prose should say the bridge is verified against Discord.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ found_during: "maintainer manual test of the chat client, 2026-09-20"
origin: researcher-authored
production_mode: hand-written
found_at: "client/DessauChat/DessauChat.swift"
deferred_after: "v0.9.2"
deferral_reason: "Re-deferred at the 0.9.2 cut: a client appearance defect (System to Dark to System leaves Settings dark) found in the maintainer's manual test; the maintainer tests by hand against this release, and the fix is next up in the client lanes; recorded here rather than stepped over."
deferred_after: "v0.9.3"
deferral_reason: "Re-deferred at the 0.9.3 cut: a client appearance defect (System to Dark to System leaves Settings dark) found in the maintainer's manual test; the maintainer tests by hand against this release, and the fix is next up in the client lanes; recorded here rather than stepped over."
---

Switching Appearance from System to Dark and back to System leaves the Settings window dark and blanks the main window's chat content: the main window turns light but shows no messages until the Settings window is closed, at which point the conversation reappears. Seen on macOS with the Settings window open beside the main window; the Appearance picker reads System while the Settings window is still rendered dark. Every window applies preferredColorScheme from the same AppStorage value, so a nil scheme (System) after an explicit one is not re-evaluated the same way in each scene.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ found_during: "ruthless review of the integration diff of itd-2609091715089488"
origin: researcher-authored
production_mode: hand-written
found_at: "cmd/dessau/main.go"
deferred_after: "v0.9.3"
deferral_reason: "the no-transcript server half is live and every model truthfully reads 'keeps no transcript' until the parent (itd-2609091707499248) lands, which is the next lane"
---

feat/2609091715 (itd-2609091715089488, no-transcript models) is built on a base without its parent, itd-2609091707499248: config.Config has no transcript switch, cmd/dessau/main.go wires nothing into gateway.Options.TranscriptOn, and app.js's transcriptState reads a config.transcript key the snapshot does not carry. Until the parent lands, /v1/models publishes recording:false for every model, the panel's cards and Dessau Chat's picker read 'keeps no transcript' for every model, and the switch sentences on docs/transcript.md, docs/models-list.md, the panel's Transcript hint and the changelog entry describe a control that is not in the tree. That is the truth of this tree — nothing is recorded — but it is not the feature the record describes, and it is the wrong landing order: the 2026-09-20 decision has the parent land first. Resolved when the parent's integration wires cfg.Transcript into TranscriptOn and the panel snapshot carries it, and the docs-currency reviewer reads the four pages against that tree. Open, this record holds the release cut.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ GitHub release notes.

## [Unreleased]

## [0.9.3] - 2026-09-21

### Added

- **Some models keep no transcript, even while recording is on.**
Expand Down
Loading