Files
jason.woltje 068d868a99 lead: commit rocko's untracked evidence (4471 files: queue-124 queue-129 queue-171 queue-178 queue-280 queue-31 queue-84 queue-85 queue-94)
Unclaimed files left in the canonical checkout. Inventory: canonical-cleanup-inventory.md (commit-as-evidence groups). detect-secrets scan clean on 2026-11-02: hits are sha256 pins, git object ids, test sentinels already in tracked tests and unit-file lines.
2026-11-02 15:05:15 -06:00

12 KiB
Raw Permalink Blame History

Row 124 / #1618 — token accounting per run

Base 9098c33f7, detached /mnt/storage/src/mosaic-stack-rocko-124. Claim rev 1718 after sage-0705 re-pinned the unchanged section at rev 1716. Brief: docs/plans/2026-10-14_prd-1.2-build.md, Token accounting per run. Requirements: REQ-LIMIT-2/3 counting foundation, REQ-LIMIT-4, REQ-PLUG-1 and REQ-WEB-1. Reviewer Dewey (decision 130). Source is not committed; Sage lands.

Implementation and acceptance mapping

  • transcript plug-in is interface 1's first usage source. It is reached only through the packages/plugins loader, never a named core import. Runtime injects the accountant into Broker, preserving its exact sandbox client import closure. Enabled/disabled source tests and real-runtime socket integration pin this; a copied fixture plug-in tree tests multiple sources, thrown failures and malformed readings.
  • The runner brackets actual harness invocations with private usage.begin/end protocol calls. The broker requires its held role and delivered message, binds the business/run/instance/harness/provider/model and rejects extra keys, paths and token counts. Launcher passes selected provider/model in its trusted bind record so a later settings change cannot relabel old runs. No harness tool or grant expands. Real runner ordering and socket tests cover this boundary; a read is scoped to the bound business.
  • Per-source begin snapshots and end outcomes are durable and append-only. The baseline excludes existing history on resumed threads. Retries consume no new reading; known records sum; pending turns, missing begins, rewritten history, failed/disabled sources, malformed readings and no new usage stay unknown. Multiple sources can contribute known counts while a failed source leaves that turn visibly unknown. Each unknown end logs its fixed safe code; no parser/source exception text or transcript content is logged.
  • Each kind is separate: input/output/cacheWrite/cacheRead. Per-turn values are safe nonnegative integers; an unrepresentable per-turn sum is unknown. Aggregates use BigInt internally and return exact decimal strings above JavaScript's safe integer range. These are representation/parser bounds, not a token-policy ceiling. Account is null until account tracking ships.
  • usage returns total and byRun/byInstance/byModel/byProvider/byAccount groups, each with unknownTurns counted distinctly by run+turn. CLI text shows it beside every total; --json retains the view. scripts/mosaic dispatches usage; the shared read adapter and strict read-only HTTP route are tested.
  • Settings adds only its own Token usage section. It shows all four kinds and unknown turns for every grouping, escapes labels, has no write controls and reports unavailable reads without inventing zeros. The actual browser test runs in the gate; its four mutants pin fields, unknowns, section and escaping. No row 155 Settings editor code is replaced.
  • The 3g→3h migration and current-schema copy test are described in MIGRATION.md. Every old evidence column/row/sequence is checked, including existing names. Ordered future migration chaining remains tested, now through fixture 3i.

The source follows no session symlink. Each root/project component is anchored with directory descriptors, O_DIRECTORY and O_NOFOLLOW; final opens add O_NOFOLLOW/O_NONBLOCK and require a regular single-link file. fstat size, actual stream bytes, line bytes, entry/record counts, stable file identity, UTF-8, complete JSONL, usage/id shape and safe nonnegative counters are checked. Each has a fixture and a named mutant. A session can edit its own transcript: counts are the stack's best reading, not proof. The resource bounds and exact source API are in packages/plugins/usage-source/transcript/README.md and DESIGN.md.

Gate, corrections and scope

sage-0714 granted five package suites (plugins, bus, harness, cli, webui), the Settings browser test, test-land-work.sh, test-config.sh and mutants. Busy check exited 0/CLEAR at 2026-10-18T15:12:55Z. Every step is gated on its exit code with pipefail. TMPDIR=/mnt/storage/scratch/rocko-124/tmp throughout the gate/mutants; DOCKER_HOST=unix:///nonexistent.sock. No Docker, live store/file/unit action, push or activation. No task/queue shell suite; Sage owns those and the full landing gate. Public landing waits for Mos's go (decision 123).

Shell-reader search over changed packages and scripts/mosaic identified scripts/test-land-work.sh, test-config.sh, test-task.sh and test-queue.sh. land-work directly imports the Store schema exports; config exercises command configuration. Task reads the unchanged mosaic-task CLI; queue exercises the unchanged queue branch and shell dispatcher syntax. Sage approved the first two here and retains the others for landing, sage-0714.

The first bus suite found stale schema expectations, not a runtime defect: chief-of-staff.test builds a pinned 3c engine by replacing the current version literal, and schema.test pins table/trigger counts. Updated 3g→3h references and counts 15→16 tables, 67→70 triggers, preserving all authority assertions. One remaining current-version assertion in chief was fixed on its focused rerun. Original bus failure logs are retained. These are not known flakes. Other historical migration tests change only their current target, copy the additional step when needed, and keep their pinned source DDL unchanged.

After the gate passed, added nonblocking-open/name and multiple-source/precision fixtures, then reran the two owning packages; the final counts below include them. No product change was needed after these additional tests.

Mutants are exact-once edits, isolated process groups, source restored in finally and group/descendant kill on timeout. No runner timeout or import/syntax fault counts as a kill. Case 44 originally caused JSON.parse in the JSON-output test to fail as intended, but the classifier falsely labelled any SyntaxError as invalid. Corrected classification uses node --check / bash -n for mutated source syntax, retained the first classifier log and resumed at case 44 on the same unchanged source. A second classifier-only correction selects node --check for public .js too, rather than bash -n; its browser test already failed on the intended 0-versus-7 assertion. Final results combine 01–43, resumed 44–46 and resumed 47–64.

Final verification, counts, kill table and packet digests follow below.

The first focused target for case 63 survived because the runtime fixture's provider is literally other-provider, the mutant's constant. The exact same fault is killed by usage.test.mjs, which asserts the other fixture provider (fixture). Retargeted case 63 to that existing owning-file check; retained the original runtime survivor log. No source or assertion change was needed.

Final verification

Observed completion: 2026-10-18T15:26:07Z.

Suite Passed Failed Skipped
plugins 52 0 0
bus 362 0 0
harness 110 0 0
cli 244 0 0
webui 146 0 0

Total 914 package tests passed; no cancelled/skipped cases. land-work: 86 passed, 0 failed. config: 24 passed, 0 failed.

No #258/#261/#262/#263 recurrence. Final gate script passed at 15:19:26Z; final owning-package reruns include the added guard tests.

Mutant Owning test Result
01-dir-no-follow packages/plugins/tests/transcript.test.mjs KILLED
02-file-no-follow packages/plugins/tests/transcript.test.mjs KILLED
03-regular-single-link packages/plugins/tests/transcript.test.mjs KILLED
04-stat-size-before-read packages/plugins/tests/transcript.test.mjs KILLED
05-stream-size-bound packages/plugins/tests/transcript.test.mjs KILLED
06-snapshot-stability packages/plugins/tests/transcript.test.mjs KILLED
07-fatal-utf8 packages/plugins/tests/transcript.test.mjs KILLED
08-cut-line packages/plugins/tests/transcript.test.mjs KILLED
09-line-byte-bound packages/plugins/tests/transcript.test.mjs KILLED
10-record-bound packages/plugins/tests/transcript.test.mjs KILLED
11-directory-entry-bound packages/plugins/tests/transcript.test.mjs KILLED
12-root-confinement packages/plugins/tests/transcript.test.mjs KILLED
13-harness-validation packages/plugins/tests/transcript.test.mjs KILLED
14-json-object packages/plugins/tests/transcript.test.mjs KILLED
15-assistant-id packages/plugins/tests/transcript.test.mjs KILLED
16-usage-object packages/plugins/tests/transcript.test.mjs KILLED
17-nonnegative-safe-integers packages/plugins/tests/transcript.test.mjs KILLED
18-conflicting-duplicates packages/plugins/tests/transcript.test.mjs KILLED
19-claude-kinds packages/plugins/tests/transcript.test.mjs KILLED
20-pi-kinds packages/plugins/tests/transcript.test.mjs KILLED
21-dedup-identical packages/plugins/tests/transcript.test.mjs KILLED
22-baseline-required packages/bus/tests/usage.test.mjs KILLED
23-rewritten-history packages/bus/tests/usage.test.mjs KILLED
24-no-new-usage-unknown packages/bus/tests/usage.test.mjs KILLED
25-turn-idempotence packages/bus/tests/usage.test.mjs KILLED
26-unknowns-beside-totals packages/bus/tests/usage.test.mjs KILLED
27-log-unknown packages/bus/tests/usage.test.mjs KILLED
28-safe-parse-code packages/bus/tests/usage.test.mjs KILLED
29-business-scoped-view packages/bus/tests/usage.test.mjs KILLED
30-loader-only-source packages/bus/tests/usage.test.mjs KILLED
31-run-grouping packages/bus/tests/usage.test.mjs KILLED
32-thread-transcript-root packages/bus/tests/usage.test.mjs KILLED
33-exact-large-totals packages/bus/tests/usage.test.mjs KILLED
34-runner-role-check packages/bus/tests/usage-broker.test.mjs KILLED
35-bound-delivered-turn packages/bus/tests/usage-broker.test.mjs KILLED
36-no-path-in-request packages/bus/tests/usage-broker.test.mjs KILLED
37-reader-usage-allowed packages/bus/tests/usage-broker.test.mjs KILLED
38-view-bound-business packages/bus/tests/usage-broker.test.mjs KILLED
39-runtime-injection packages/bus/tests/usage-runtime.test.mjs KILLED
40-await-usage packages/bus/tests/usage-runtime.test.mjs KILLED
41-runner-begin packages/harness/tests/runner.test.mjs KILLED
42-runner-end packages/harness/tests/runner.test.mjs KILLED
43-cli-unknown packages/cli/tests/usage.test.mjs KILLED
44-cli-json packages/cli/tests/usage.test.mjs KILLED
45-dispatch packages/cli/tests/usage.test.mjs KILLED
46-read-adapter packages/cli/tests/usage.test.mjs KILLED
47-settings-unknown packages/webui/tests/usage-browser.test.mjs KILLED
48-settings-four-kinds packages/webui/tests/usage-browser.test.mjs KILLED
49-settings-section packages/webui/tests/usage-browser.test.mjs KILLED
50-settings-safe-labels packages/webui/tests/usage-browser.test.mjs KILLED
51-http-arguments packages/webui/tests/usage.test.mjs KILLED
52-http-shape packages/webui/tests/usage.test.mjs KILLED
53-migration-step packages/bus/tests/usage-migration.test.mjs KILLED
54-migration-chain packages/bus/tests/comment-migration.test.mjs KILLED
55-nonblocking-open packages/plugins/tests/transcript.test.mjs KILLED
56-entry-name-validation packages/plugins/tests/transcript.test.mjs KILLED
57-source-output-validation packages/bus/tests/usage.test.mjs KILLED
58-turn-sum-precision packages/bus/tests/usage.test.mjs KILLED
59-source-failure-is-unknown packages/bus/tests/usage.test.mjs KILLED
60-all-enabled-sources packages/bus/tests/usage.test.mjs KILLED
61-instance-group packages/bus/tests/usage.test.mjs KILLED
62-model-group packages/bus/tests/usage.test.mjs KILLED
63-provider-group packages/bus/tests/usage.test.mjs KILLED
64-account-unassigned packages/bus/tests/usage.test.mjs KILLED

64/64 final kills, no runner timeout or invalid syntax/module failure. All 37 candidate file hashes and staged blobs restored. Node/chromium/Git/ bwrap/Python cwd-and-argv sweep under the worktree and scratch found none; every runner exited. No Docker network was created. No live files/units touched.

Candidate manifest SHA-256: b7139ea3909c49449436daee2eb45f542bca0ffce2515870e1f49ba27e918016.