loki-mode 9.73.0 → 9.74.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/SKILL.md +2 -2
- package/VERSION +1 -1
- package/autonomy/lib/proof-generator.py +7 -0
- package/autonomy/loki +18 -7
- package/autonomy/run.sh +14 -1
- package/dashboard/__init__.py +1 -1
- package/dashboard/server.py +22 -13
- package/dashboard/static/index.html +5 -5
- package/docs/INSTALLATION.md +1 -1
- package/docs/v10/ARCHITECT-CUTS.md +257 -314
- package/docs/v10/BOARD.md +25 -5
- package/loki-ts/dist/loki.js +251 -250
- package/mcp/__init__.py +1 -1
- package/package.json +1 -1
- package/plugins/loki-mode/.claude-plugin/plugin.json +1 -1
- package/web-app/dist/assets/{AdminPage-B11jqriL.js → AdminPage-DaeYgQSE.js} +1 -1
- package/web-app/dist/assets/{Avatar-vmIEiL2U.js → Avatar-CgwQi58_.js} +1 -1
- package/web-app/dist/assets/{Badge-DxtrDGcl.js → Badge-Bwq-lpRh.js} +1 -1
- package/web-app/dist/assets/{Button-BiPlRkkg.js → Button-BEf4Nher.js} +1 -1
- package/web-app/dist/assets/{CockpitPage-DXKAc0jc.js → CockpitPage-Bj41Xtg9.js} +1 -1
- package/web-app/dist/assets/{ComparePage-B4ddvt9J.js → ComparePage-tFbdo90G.js} +1 -1
- package/web-app/dist/assets/{ErrorBoundary-BIJy59N_.js → ErrorBoundary-Brewvgm9.js} +1 -1
- package/web-app/dist/assets/{EvidenceReceiptPanel-C4-Phh1f.js → EvidenceReceiptPanel-h_82QBVa.js} +1 -1
- package/web-app/dist/assets/GitHubIssuesPanel-Dcg5xDMm.js +7 -0
- package/web-app/dist/assets/{GitHubPRsPanel-B_VHTB-t.js → GitHubPRsPanel-DFKzVyA1.js} +1 -1
- package/web-app/dist/assets/{HomePage-cxONjTSm.js → HomePage-D21cM1Je.js} +2 -2
- package/web-app/dist/assets/{LoginPage-D49p6aVy.js → LoginPage-DJ9yqMn4.js} +1 -1
- package/web-app/dist/assets/{MagicPage-C5GUEIuM.js → MagicPage-mwkjJhBy.js} +1 -1
- package/web-app/dist/assets/{MetricsPage-I-OXi9kG.js → MetricsPage-D2q-PD-s.js} +1 -1
- package/web-app/dist/assets/{NotFoundPage-Do19cbOP.js → NotFoundPage-BtusJvgS.js} +1 -1
- package/web-app/dist/assets/{ProjectPage-TRyzTIFH.js → ProjectPage-CRPALtO8.js} +63 -63
- package/web-app/dist/assets/{ProjectsPage-BLSDhtVb.js → ProjectsPage-DuzABpfc.js} +1 -1
- package/web-app/dist/assets/{SettingsPage-BvixtAw7.js → SettingsPage-DhJPX-Rf.js} +1 -1
- package/web-app/dist/assets/{ShowcasePage-By96BMJz.js → ShowcasePage-CvgS47nu.js} +1 -1
- package/web-app/dist/assets/{SystemSettingsPage-AvVujpIo.js → SystemSettingsPage-l3Cv9YjY.js} +1 -1
- package/web-app/dist/assets/{TeamsPage-BiT3N4px.js → TeamsPage-DridGcnR.js} +1 -1
- package/web-app/dist/assets/{TemplatesPage-Y_m-dzfd.js → TemplatesPage-CTNsfp03.js} +1 -1
- package/web-app/dist/assets/{TerminalOutput-oPTCcEGy.js → TerminalOutput-BuyksqLh.js} +1 -1
- package/web-app/dist/assets/{activity-DCa9Pi7k.js → activity-DM2TKaBi.js} +1 -1
- package/web-app/dist/assets/{bell-Br7Xsjam.js → bell-D2PMLbbX.js} +1 -1
- package/web-app/dist/assets/{bot-BsQKlSP5.js → bot-BnN32Jxp.js} +1 -1
- package/web-app/dist/assets/{check-Cb49hCzQ.js → check-CU128nw_.js} +1 -1
- package/web-app/dist/assets/{chevron-left-Cs63FOmY.js → chevron-left-ehNW1Do7.js} +1 -1
- package/web-app/dist/assets/{circle-alert-C8A636Wl.js → circle-alert-Cpw2gtOC.js} +1 -1
- package/web-app/dist/assets/{clock-DhlnHjQI.js → clock-BOZHdPVS.js} +1 -1
- package/web-app/dist/assets/{cloud-uOYQxGRY.js → cloud-BZ2L9Fzi.js} +1 -1
- package/web-app/dist/assets/{code-xml-9O9XlVo9.js → code-xml-sSo522gu.js} +1 -1
- package/web-app/dist/assets/{database-D9Oek2JS.js → database-DrR1xHzS.js} +1 -1
- package/web-app/dist/assets/{dollar-sign-CHetUBPR.js → dollar-sign-CHE3T_rh.js} +1 -1
- package/web-app/dist/assets/{file-code-corner-oTJV_ce4.js → file-code-corner-CgcssyRQ.js} +1 -1
- package/web-app/dist/assets/{file-plus-vuloOqQB.js → file-plus-DtwfrxYH.js} +1 -1
- package/web-app/dist/assets/{globe-DMVdf8bk.js → globe-Dzla77iL.js} +1 -1
- package/web-app/dist/assets/{hammer-15WRQJ1o.js → hammer-BAMdG66t.js} +1 -1
- package/web-app/dist/assets/{index-SRKz3Imw.js → index-mQOnSYoW.js} +2 -2
- package/web-app/dist/assets/{layers-C-QQQP9K.js → layers-DhuyLqmc.js} +1 -1
- package/web-app/dist/assets/{loader-circle-DqoJevCK.js → loader-circle-DclFyQ3B.js} +1 -1
- package/web-app/dist/assets/{lock-B68yfqau.js → lock-C8v_bXNl.js} +1 -1
- package/web-app/dist/assets/{package-DAxTtm-S.js → package-B4AnjM5D.js} +1 -1
- package/web-app/dist/assets/{plus-BSbdI5QI.js → plus-DM95CmZI.js} +1 -1
- package/web-app/dist/assets/{refresh-cw-DlvFuI3J.js → refresh-cw-CWaauzqX.js} +1 -1
- package/web-app/dist/assets/{rotate-ccw-BF03pKE0.js → rotate-ccw-DxcvylpJ.js} +1 -1
- package/web-app/dist/assets/{scroll-text-QFZ1JdTD.js → scroll-text-Dx-V_BpP.js} +1 -1
- package/web-app/dist/assets/{server-tyIvmSke.js → server-Cj2EfoGN.js} +1 -1
- package/web-app/dist/assets/{shield-alert-DHeqbtBK.js → shield-alert-OlmWv7sU.js} +1 -1
- package/web-app/dist/assets/{thumbs-up-CRag1Tn5.js → thumbs-up-CIpJhyTd.js} +1 -1
- package/web-app/dist/assets/{trash-2-B0n4x-Ds.js → trash-2-BIkoZkY6.js} +1 -1
- package/web-app/dist/assets/{trending-down-DC4Aqzso.js → trending-down-CI-OcCGt.js} +1 -1
- package/web-app/dist/assets/{trending-up-DFG157ke.js → trending-up-B0dpgKi-.js} +1 -1
- package/web-app/dist/assets/{upload-BdWQ4cWx.js → upload-NhOBAjKA.js} +1 -1
- package/web-app/dist/assets/{usePolling-DMgD-dJ5.js → usePolling-_QRF6f7x.js} +1 -1
- package/web-app/dist/assets/{user-DXaZeAe4.js → user-kRNvOpun.js} +1 -1
- package/web-app/dist/index.html +1 -1
- package/web-app/dist/assets/GitHubIssuesPanel-CVIG0uwi.js +0 -7
|
@@ -1,334 +1,277 @@
|
|
|
1
|
-
# Architect slice cuts (2026-09-27)
|
|
2
1
|
|
|
3
|
-
Verbatim final reports from the two Architect agents, kept so BOARD rows S-112..S-151 can cite a durable source.
|
|
4
2
|
|
|
5
|
-
##
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
Notes:
|
|
33
|
-
1. The task premise is stale: tests/moat/pending.txt holds 13 entries, not 38. Two of them I did not slice, because they need a CEO decision (both are breaking changes deferred to v10.0.0): P2.fast-verify-inconclusive-not-zero, which is also dispatched through autonomy/loki and so collides with S-123, and P2.verify-exit-contract. P1.verification-metadata-signed is Seal work bigger than 30 minutes.
|
|
34
|
-
2. Risky: S-112 rewrites the user's working tree in place. S-112 to S-115 would promote P3 and P8 as present but not wired (BACKLOG 34 says do not promote until a stub-provider run.sh session records facts.ablation and invokes check-author), so a wiring slice on run.sh has to follow S-124.
|
|
35
|
-
3. CEO decisions: whether to spend 6 slices on the corpus (S-117 to S-122, which prove only P4.seeded-defect-corpus-present, not the floor-vs-top measurement), and S-131's warn-never-pause default. GUARDS 11 and 13 were not cut because they collide with S-99 (v10-guard.sh) and the pulse script. GUARDS 12 (gitconfig-write lint) is the next alternate.
|
|
36
|
-
|
|
37
|
-
## 18:05Z cut: S-132..S-151
|
|
38
|
-
|
|
39
|
-
I've cut 20 slices, S-132 to S-151, and checked each one against the current tree. Every row below names something still open in the code or in CI, and no two rows edit the same file. None of them edits a file or block the in-flight reworks own (S-30/S-50, S-96, S-99, S-100, S-123, S-124, S-125, S-126).
|
|
40
|
-
|
|
41
|
-
Candidates I dropped because they are already fixed or would not help:
|
|
42
|
-
- **BACKLOG 13:** no Docker pin is left.
|
|
43
|
-
- **BACKLOG 35:** `tests/test-moat-runner.sh:653` already has the 0-byte case.
|
|
44
|
-
- **BACKLOG 37 and 60:** already fixed in `quality_gates.ts`.
|
|
45
|
-
- **BACKLOG 53 and 54:** those files already use `-E` everywhere.
|
|
46
|
-
- **Pinning pytest-xdist:** every entry in `requirements-test.txt` is unpinned, so pinning one would break the file's convention.
|
|
47
|
-
|
|
48
|
-
| S-132 | Velocity: skip the full Tests workflow on a version-bump-only commit whose parent's Tests run succeeded; run it in full otherwise (source 4) | .github/workflows/test.yml (new first gate job, `actions: read`, `needs`/`if` on the heavy jobs), scripts/ci/version-bump-only.sh (new), tests/test-version-bump-only.sh (new) | HIGH | red: on a bump-only fixture commit, test.yml runs every job; a fixture whose `loki-ts/dist` differs by more than the version string is judged eligible by nothing yet. green: bump-only plus parent Tests success skips the heavy jobs; parent pending or red runs the full suite (never waits); any non-allowlisted file runs the full suite; a parity test pulls release.yml's STEP 1 out by its content markers and gets the same eligibility verdict as the new script on at least 6 fixture diffs; mutating the script's allowlist turns the parity test red | ready@2026-09-27T18:05Z | Why HIGH: a Tests run whose jobs are all skipped concludes success, and required-ci rule (a) accepts success at the release SHA without looking at the parent. So the gate job itself must confirm the parent's Tests run succeeded, and its eligibility must be no looser than release.yml STEP 1. Never skip the version-bump consistency step (test.yml:81). Do not edit release.yml; deduplicating STEP 1 is a later slice. What it buys: runner capacity, plus no flaky failure at the release SHA (rule (b)) can block a release whose parent is green. The Captain registers the new test. |
|
|
49
|
-
| S-133 | Velocity: make the Release workflow's required-ci poll faster (source 4), and fix the stale publish-npm comment S-85's review flagged as non-blocking (source 1) | .github/workflows/release.yml (the `sleep 30` in the STEP 2 poll loop, and that one comment in publish-npm) | LOW | red: `grep -n 'sleep 30' release.yml` matches inside the required-ci loop, and the publish-npm comment names publish-docker for the dist assert. green: poll interval is 10s or less, the 2400s deadline is unchanged, the comment names publish-docker-build, actionlint is clean | ready@2026-09-27T18:05Z | Token budget: 2 API calls per iteration at 10s is 12 a minute, at most 480 across the 40-minute deadline, against GITHUB_TOKEN's shared 1000 an hour per repo. Keep it at 10s or more. Edit STEP 2 only; S-132's parity test reads STEP 1 by content markers. Ships alone, since it touches release.yml (D22). |
|
|
50
|
-
| S-134 | Velocity: shorten the slowest Tests shard by re-measuring shard-durations.tsv (it is from run 36319020918, now stale), plus the duration-table drift detector S-81's review listed as a follow-up (sources 4 and 1) | tests/shard-durations.tsv, tests/test-shard-durations-drift.sh (new) | LOW | red: Tests run 36338540948 shows shard 2/8 at 325s against shard 7/8 at 124s; the drift test fails today on any registered suite missing from the table, or any table row naming no registered suite. green: the table is rebuilt from the `END: <name> (Ns)` lines of all 8 shard logs of a recent green run, the drift test passes, and the next real Tests run's max shard is under 250s | ready@2026-09-27T18:05Z | Measure the whole workflow's wall clock, not just the max shard: once rebalanced, the 195s Moat suite likely becomes the floor. The floor for any single shard is ShellCheck at 140s. The Captain registers the drift test. |
|
|
51
|
-
| S-135 | Velocity: run tests/test-trust-core-tests-detect.sh's 90 probe_case mutations in parallel (130s in shard 1, the second-slowest suite) (source 4) | tests/test-trust-core-tests-detect.sh | MEDIUM | red: 130s on CI and one probe at a time. green: bounded parallel probes under 50s locally; the case count stays exactly 90 and every case still executes; a deliberately removed guard still turns its case red; 5 runs under 4-way CPU load with 0 flakes | ready@2026-09-27T18:05Z | First confirm probe_case mutates a private copy. If it edits the shared tree in place, parallel runs corrupt each other and the slice changes shape. Its anchors point into completion-council.sh (line 196 loops council_checklist_gate/council_heldout_gate) and probably into the run.sh failure-count awk, so rebase after S-141 and S-140 if they land first. |
|
|
52
|
-
| S-136 | Velocity: tests/test-select-tests.sh hit the 60s D27 cap (rc=124) on S-49's and S-91's train 4 checks (source 1) | tests/test-select-tests.sh | MEDIUM | red: `timeout 60 bash tests/test-select-tests.sh` returns rc=124. green: it finishes in under 30s with rc=0, still 38/38 cases, and a mutation of scripts/select-tests.sh (drop one rule) still turns it red | ready@2026-09-27T18:05Z | Coverage must not drop: assert the case count, not just the time. Do not touch scripts/select-tests.sh or tier-a.yml (S-96). |
|
|
53
|
-
| S-137 | S-81 review follow-up: shard-coverage check T4 recomputes a static count instead of running the real runner (source 1) | tests/test-shard-coverage.sh | LOW | red: a mutation that makes run-all-tests.sh's LPT assignment drop one suite from shard 0 leaves T4 green. green: T4 enumerates every shard of the real runner at n=4 and n=8 through a dry-run/list path, the union equals the registration list, and the same mutation turns it red | ready@2026-09-27T18:05Z | If run-all-tests.sh has no list mode, stop and report. Adding one would touch a Captain-owned hot file. |
|
|
54
|
-
| S-138 | GUARDS 12 (no guard yet): a lint so test fixtures never write the operator's real ~/.gitconfig (source 3) | tests/test-no-ambient-gitconfig-writes.sh (new) | LOW | red: a planted fixture with `git config --global url.x.insteadOf y` and no `HOME=`/`GIT_CONFIG_GLOBAL=` isolation before it is flagged, rc=1. green: the lint passes on the current 5 files that do global writes (test-trusted-push-agent-config, -acceptance-resume-idempotence, -enterprise-resilience, -branch-lifecycle, plus the moat p6/p9 scripts) only if each isolates first; any real offender is named, not allowlisted in silence | ready@2026-09-27T18:05Z | If a current file really does write the ambient config, report it; do not fix it inside this slice. The Captain registers the lint and updates GUARDS 12. |
|
|
55
|
-
| S-139 | GUARDS 13 (pending) plus BACKLOG 136: pulse flags a `released@` row stamped after npm's newest publish time (RELEASED_AHEAD_OF_NPM), and reports UNKNOWN when the local release tag disagrees with npm's latest version (sources 3 and 2) | scripts/v10-pulse.sh, tests/test-v10-pulse.sh | MEDIUM | red: a fixture BOARD with a row stamped `released@15:54Z` while the PULSE_NPM_CMD fixture's latest publish is 15:00Z raises no violation; a local tag v9.54.2 against npm latest 9.55.0 prints a confident "N commits since". green: both fixtures give the new violation and an UNKNOWN respectively, existing pulse tests stay green, runtime stays under 5s | ready@2026-09-27T18:05Z | Reuse the existing `npm view loki-mode time --json` result and its cache. No new network call, to stay inside S-104's 5s budget. Chosen over a board-row-status precondition because the pulse runs on every prompt, while nothing shows the Captain writes `released` through v10-ops.sh. |
|
|
56
|
-
| S-140 | BACKLOG 103: jest "Test Suites: 1 failed" alongside "Tests: 2 passed", and vitest "Test Files 1 failed", still record as passed (source 2) | autonomy/run.sh (the BACKLOG 73/111 failure-count awk near line 14240 only), plus the existing S-45 summary-parser test | MEDIUM | red: fixture output with "Test Suites: 1 failed, 1 total" and "Tests: 2 passed" records failed_count 0 and pass true; same for vitest "Test Files 1 failed \| 2 passed". green: both count at least 1 failed and the gate fails; a pure-green jest/vitest summary is still a measured 0; the trust-core suite still passes | ready@2026-09-27T18:05Z | Far from S-100's region (on_run_complete ~6012, trusted push) and S-124's (iteration 0, load_state ~21470). Run the trust-core suite in the wall and fix any anchor this breaks. |
|
|
57
|
-
| S-141 | S-49 follow-up: council verdict readers outside the 3 fixed functions still run bare `python3 -E` (~1425, ~1564 gate results; ~4232 aggregate_result) (source 1) | autonomy/completion-council.sh (those 3 call sites only), tests/test-council-gate-readers-pth.sh (new) | HIGH | red: a user-site `.pth` planted under a scratch HOME flips each of the 3 readers' verdicts (as S-49 reproduced). green: all 3 go through the resolved `-I -S` interpreter helper, fail closed when no interpreter is found, the `.pth` has no effect, and a mutation reverting one site turns the test red; the trust-core suite passes | ready@2026-09-27T18:05Z | A standalone suite, not a moat case, because tests/moat/cases.txt is a hot file. The Captain registers the suite. Line numbers drift, so find the sites by grep. |
|
|
58
|
-
| S-142 | S-48 follow-up: convergence-floor NEGATIVE-B passes even without the `runner!='none'` guard (source 1) | tests/test-council-convergence-floor.sh | LOW | red: removing the runner guard from the fast-path check (a scratch-copy mutation) leaves every case green. green: a new NEGATIVE-C writes the legacy shape `runner:"none", pass:true`, returns 1, and turns red under that mutation | ready@2026-09-27T18:05Z | Test-only. Confirm the guard still exists before writing; if it was removed on purpose, report that instead. |
|
|
59
|
-
| S-143 | BACKLOG 117 remainder / S-51 follow-ups: Gemini, Railway, stale gate counts and "Q2 2026 Current" copy (source 2) | web-app/src/components/Roadmap.tsx, DocsSidebar.tsx, ContextualHelp.tsx, ProductTour.tsx, CostEstimator.tsx, web-app/src/pages/SystemSettingsPage.tsx | LOW | red: `grep -il -E 'gemini\|railway\|9 (automated )?quality gates\|10 quality gates\|Q2 2026'` matches all 6 files. green: 0 matches in them; gate count is 8; deploy targets are Vercel, Netlify and GitHub Pages only | ready@2026-09-27T18:05Z | Copy only. If CostEstimator's Gemini entry is pricing logic, remove the option and note it. ProjectWorkspace.tsx is out of scope. The Captain rebuilds web-app/dist. |
|
|
60
|
-
| S-144 | S-51 follow-up: Footer.tsx shows v9.55.0 against VERSION 9.66.0 and is not in the bump list (source 1) | scripts/release.sh, tests/test-release-sh.sh, web-app/src/components/Footer.tsx | LOW | red: Footer.tsx holds v9.55.0 while VERSION is 9.66.0, and a `--bump-only` fixture run leaves Footer unchanged. green: `--bump-only` rewrites the Footer version slot, and the test asserts it for that file by name | ready@2026-09-27T18:05Z | WhatsNew.tsx is deliberately excluded. Its modal opens when `lastSeen !== CURRENT_VERSION`, so bumping it automatically would pop the same stale modal for every user at every release (3-5 an hour). Keying it to its own content version is a separate question (see the end list). |
|
|
61
|
-
| S-145 | BACKLOG 118: GET /api/checklist/waivers answers 200 `{waivers: []}` when waivers.json is corrupt, so a read error looks like "no waivers" (source 2) | dashboard/server.py (get_checklist_waivers only), tests/dashboard/test_checklist_waivers_read_error.py (new) | LOW | red: a corrupt waivers.json returns 200 with an empty list. green: it returns 500 with an error body, matching the POST sibling at ~10431; a missing file still returns 200 with an empty list | ready@2026-09-27T18:05Z | Survey the consumers first (dashboard-ui checklist viewer, standalone): each must show "Could not load" on 500, not an empty state. Note which consumers were checked in the wall. |
|
|
62
|
-
| S-146 | BACKLOG 118: the dashboard shell has two elements with `id="budget-banner"` (source 2) | dashboard-ui/scripts/build-standalone.js | LOW | red: `grep -c 'id="budget-banner"'` returns 2. green: returns 1, and the banner script still finds and updates the remaining element (a node or DOM check in the builder's evidence) | ready@2026-09-27T18:05Z | While in the file, check the other two 118 items (the "Newest first" reversal at ~2510); fix only if trivial, otherwise report. The Captain rebuilds dashboard/static/index.html. |
|
|
63
|
-
| S-147 | BACKLOG 118: `loki metrics --json` sends `tokens.total` 0 and `total_iterations` 0 when nothing was recorded, and invents `time_saved_hours = iterations*15/60` (source 2) | autonomy/loki (cmd_metrics only), tests/test-metrics-json-unmeasured.sh (new) | MEDIUM | red: on an empty .loki, `loki metrics --json` prints total 0, iterations 0 and a numeric time_saved_hours. green: null (unknown) for unrecorded values, time_saved_hours removed or null, real recorded values unchanged | ready@2026-09-27T18:05Z | cmd_metrics (~28481) is far from S-123's attestation region (~956); rebase if S-123 lands first. Survey consumers of the JSON (dashboard, docs) before changing 0 to null. The Captain registers the test. |
|
|
64
|
-
| S-148 | BACKLOG 118: trust.html says "Stable: no significant change" when every axis lacks the 2+ runs of history needed (source 2) | dashboard/static/trust.html | LOW | red: an API fixture where every axis has `insufficient: true` renders the "Stable" headline. green: it renders "Not enough history yet"; a fixture with real flat axes still says "Stable" (pull the headline into a named function and check it with a small node assertion) | ready@2026-09-27T18:05Z | Hand-written page, not a generated bundle. The `delta: 0.0` on an insufficient axis in trust_trajectory.py is out of scope; note it for later. |
|
|
65
|
-
| S-149 | BACKLOG 118: prompt_optimizer.get_current_version returns never-ran zeros (version 0, based_on_sessions 0), and a corrupt latest file is folded into the same default (source 2) | dashboard/prompt_optimizer.py, tests/dashboard/test_prompt_optimizer_sentinels.py (new) | LOW | red: a corrupt latest file and a missing one return the identical zero dict. green: missing returns an explicit never-ran marker (nulls); corrupt returns an error marker distinct from never-ran | ready@2026-09-27T18:05Z | Survey the endpoint and panel consumers first so the new fields render as unknown, not crash. |
|
|
66
|
-
| S-150 | BACKLOG 118: migration_engine.get_progress reports 0/0 features and steps when the features or plan file is corrupt or missing (source 2) | dashboard/migration_engine.py (get_progress only), tests/dashboard/test_migration_progress_unknown.py (new) | LOW | red: a corrupt plan.json gives `steps_total 0, steps_completed 0`, identical to a real empty plan. green: corrupt or missing gives null counts plus a reason; a real empty plan still gives 0 | ready@2026-09-27T18:05Z | Survey consumers (loki-migration-dashboard.js, server endpoint) to make sure null renders as unknown. |
|
|
67
|
-
| S-151 | BACKLOG 118: loki-analytics heatmap counts days before the returned activity window as 0 activities (source 2) | dashboard-ui/components/loki-analytics.js (_computeHeatmap and the cell render only) | LOW | red: a fixture with activity starting 10 days ago renders the previous ~355 days as "0 activities". green: days before the earliest returned entry (or the API's window start) render as "no data", while days inside the window with no activity stay 0 | ready@2026-09-27T18:05Z | The Captain rebuilds dashboard/static/index.html. Different file from S-146. |
|
|
68
|
-
|
|
69
|
-
**Risks**
|
|
70
|
-
- **Registration is on the Captain.** 8 rows add a new test file (S-132, S-134, S-138, S-141, S-145, S-147, S-149, S-150). Each needs the Captain to register it in `tests/run-all-tests.sh`, or it never runs in CI.
|
|
71
|
-
- **Rebuilds are on the Captain.** S-143 needs web-app/dist rebuilt; S-146 and S-151 need dashboard/static rebuilt.
|
|
72
|
-
- **Test anchors, not files, couple S-135, S-140 and S-141.** Trust-core probes anchor into completion-council.sh and probably into the run.sh failure-count awk. Merge S-140 and S-141 first, and each of them must run the trust-core suite in its wall. S-135's first step is confirming probes use a private copy.
|
|
73
|
-
- **Two rows touch the release gate.** S-132 is the highest-risk slice: an all-skipped Tests run reads as success at the release SHA. It needs a HIGH review focused on the parent-green check and on eligibility never being looser than release.yml STEP 1. S-133 also touches release.yml, so under D22 it ships in its own train.
|
|
74
|
-
- **Same-file neighbours.** S-140 (run.sh) and S-147 (autonomy/loki) share a file with in-flight S-100/S-124 and S-123, in regions far from theirs. Expect rebases, not conflicts.
|
|
75
|
-
- **S-134's gain only shows on a real CI run.** The first Tests run after merge is the evidence; the Moat suite (195s) may become the new floor.
|
|
76
|
-
- **Changing zeros to null or 200 to 500 changes response shapes.** S-145, S-147, S-149 and S-150 must name the consumers they checked, or a panel can crash where it used to show a false zero.
|
|
77
|
-
|
|
78
|
-
**Held for a CEO decision or waiting on another slice (not in the 20)**
|
|
79
|
-
- S-112 and S-117 to S-122 (P4 corpus and ablation producer): already held.
|
|
80
|
-
- BACKLOG 4: breaking exit-code renumber for `loki verify` (v10.0.0).
|
|
81
|
-
- BACKLOG 18: Caveman bootstrap and its global `~/.claude` hook default-on; changing the default is a product decision.
|
|
82
|
-
- BACKLOG 121: browser-only settings (plain-text API keys in localStorage, unwired "Budget limit" and "Auto-deploy"): remove or wire is a product decision.
|
|
83
|
-
- BACKLOG 77: whether Bun should write its own test-results freshness marker.
|
|
84
|
-
- BACKLOG 123: `audit.py verify` reporting valid on nothing checked; the cross-chain verifier reads it, so it needs its own review.
|
|
85
|
-
- WhatsNew.tsx version: stays stale until someone decides what should trigger the modal.
|
|
86
|
-
- GUARDS 11 (scratchpad glob `rm`): a helper nobody is forced to call blocks nothing. The real rule belongs in `scripts/v10-guard.sh`, so cut it after S-99 lands.
|
|
87
|
-
- Waiting on a slice in this set: BACKLOG 127 remainder (`run.sh` auto_capture_episode, `cd "$PROJECT_DIR"` with no unset guard, ~21361) after S-140; BACKLOG 38 after S-141; BACKLOG 133 after S-139.
|
|
88
|
-
|
|
89
|
-
I edited no files. The only temp file was a log saved under `$TMPDIR` and deleted in the same command. I started no background processes.
|
|
90
|
-
|
|
91
|
-
## 19:10Z cut (S-154..S-173)
|
|
92
|
-
|
|
93
|
-
I edited no files and started no background processes. Each red condition below comes from reading or grepping the current tree at e952e1ae. Two numbers were measured on this host (load average about 9):
|
|
94
|
-
- `python3 tests/lib/scan-unreachable-shipped.py` ran in 47s, rc 0.
|
|
95
|
-
- `EVENT_NAME=push SHA=8d17be2b bash scripts/ci/version-bump-only.sh check` printed `normalizer: not on the allowlist: web-app/src/components/Footer.tsx`, rc 1.
|
|
96
|
-
|
|
97
|
-
`tests/test-sentrux-init-rules.sh` ran once for timing. It removed its own mktemp dir through its EXIT trap: `ls -d /tmp/loki-test-sentrux-init-*` found 0 entries. The working tree shows only the Chief of Staff's uncommitted BOARD.md and TODO.md edits.
|
|
98
|
-
|
|
99
|
-
Rules that apply to every row:
|
|
100
|
-
- No file set includes a hot file.
|
|
101
|
-
- Any new test file is registered in `tests/run-all-tests.sh` by the Captain.
|
|
102
|
-
- Dashboard-ui rows need the Captain to rebuild `dashboard/static/index.html`. Web-app rows need a `web-app/dist` rebuild.
|
|
103
|
-
- UI walls follow the pattern already in the repo. Web-app rows pull the copy decision into a named pure function tested with `node --test`, like `web-app/src/cockpit/useCockpitState.derive-view.test.mjs`. Dashboard-ui rows drive the real component class against a DOM stub, like `dashboard-ui/tests/loki-empty-vs-error.node.test.mjs`.
|
|
104
|
-
- Each UI wall includes a negative assertion: the error render must not contain the empty-state sentence. A grep for the absence of a string is not accepted as a wall.
|
|
105
|
-
|
|
106
|
-
### S-154: prune-worktrees.sh treats a cherry-picked branch as merged (GUARDS 5, TODO item 8)
|
|
107
|
-
- Files: scripts/prune-worktrees.sh, tests/test-prune-worktrees.sh (new)
|
|
108
|
-
- Tier: MEDIUM (it removes worktrees)
|
|
109
|
-
- Red: the script counts a worktree as merged only through `git merge-base --is-ancestor`. The Chief of Staff lands slices by cherry-pick, so no slice branch is ever an ancestor of main, and the dry run lists 0 of them. That is why pruning is still manual (TODO item 8: "count now 7 of 15"). No test file for the script exists (`ls tests | grep -i prune` shows only checkpoint tests).
|
|
110
|
-
- Green, on a fixture repo:
|
|
111
|
-
- A branch whose commits are all patch-equivalent on main (`git cherry main <branch>` shows no `+` lines) is listed as removable.
|
|
112
|
-
- A branch with one `+` commit is kept.
|
|
113
|
-
- A locked worktree is kept, and so is a dirty one.
|
|
114
|
-
- `--apply` removes only through `git worktree remove`.
|
|
115
|
-
- The test also greps the script and fails on any `stat`, `mtime`, `-mmin` or `-newer` token, so GUARDS 5 finally has a checked-in test.
|
|
116
|
-
- Wall: `bash tests/test-prune-worktrees.sh` exits 0 with every case PASS. A mutation that drops the `git cherry` branch makes the cherry-picked fixture case FAIL.
|
|
117
|
-
|
|
118
|
-
### S-155: shipped-module reachability scan under 10s, same verdicts (velocity)
|
|
119
|
-
- Files: tests/lib/scan-unreachable-shipped.py (referenced_from_runtime and its caller only)
|
|
120
|
-
- Tier: LOW
|
|
121
|
-
- Red: the scan takes 47s locally and 95s on CI (`tests/shard-durations.tsv`: "shipped modules have a recorded reachability verdict 95"). It is the 4th slowest suite. Every module runs one large alternation regex over every corpus file, including a `(node|bun)\s+[^\n]*` arm, and nothing filters the files first.
|
|
122
|
-
- Green:
|
|
123
|
-
- The builder first measures where the time goes (regex or I/O) and puts the numbers in the commit.
|
|
124
|
-
- Then add a substring prefilter: skip any corpus file that does not contain the module's stem. This is sound because every pattern alternative contains the stem literally. Also compile the regex once per module.
|
|
125
|
-
- stdout and rc are byte-identical to a capture taken before the change.
|
|
126
|
-
- Wall: the scan runs in under 10s wall time. `bash tests/test-no-unreachable-shipped.sh` shows 4 passed, 0 failed. A mutation that removes one real require of a listed module still gets reported (rc 1).
|
|
127
|
-
|
|
128
|
-
### S-156: auto-capture shadow_write runs the agent repo's memory package when PROJECT_DIR is unset, and splices importance into python source (BACKLOG 127 remainder)
|
|
129
|
-
- Files: autonomy/run.sh (the managed-memory auto-capture block, found by grepping `shadow_write`, about line 21380-21396 only), tests/test-autocapture-shadow-write-guard.sh (new)
|
|
130
|
-
- Tier: HIGH (code execution on a verdict-adjacent path)
|
|
131
|
-
- Red: `cd "$PROJECT_DIR" 2>/dev/null && ... python3 -m memory.managed_memory.shadow_write` has no `-n PROJECT_DIR` guard. On bash 3.2, `cd ""` succeeds silently and the cwd stays inside the agent repo. Also, `python3 -c "print('yes' if float('$_ep_imp') >= 0.6 else 'no')"` interpolates an episode-file value straight into the python source.
|
|
3
|
+
## 19:57Z cut (S-174..S-193)
|
|
4
|
+
|
|
5
|
+
**Checked before cutting.**
|
|
6
|
+
- **P2.verify-exit-contract and P2.fast-verify-inconclusive-not-zero.** Both are already listed in `tests/moat/pending.txt` with milestone v10.0.0. `tests/moat/run.sh` accepts them as FAIL, so they are not a regression on main.
|
|
7
|
+
- The fix is the breaking renumber of verify exit codes (BACKLOG 4). The 19:10Z cut held that for the CEO, and this cut does not undo that.
|
|
8
|
+
- When the renumber lands, the Captain promotes each case by deleting its pending.txt line.
|
|
9
|
+
- S-182 does the part that breaks nothing: it documents the current codes, so users stop reading exit 0 from `--fast` as a pass.
|
|
10
|
+
- **The run-all-tests missing-argument gap is real.** Probe: `bash -c 'set -euo pipefail; f(){ local a="$1"; local b="$2"; }; f x; echo after'` printed `$2: unbound variable` and exited 1 without printing `after`.
|
|
11
|
+
- The missing-script branch's `return 1` also stops the whole runner under `set -e`. That is the same "later suites silently skipped" problem.
|
|
12
|
+
- **Already handled, so dropped:**
|
|
13
|
+
- BACKLOG 35 (0-byte baseline test in tests/test-moat-runner.sh).
|
|
14
|
+
- BACKLOG 60 wording.
|
|
15
|
+
- BACKLOG 91 (stage status not_run).
|
|
16
|
+
- BACKLOG 116 Close button.
|
|
17
|
+
- Standalone VERIFIED WITH GAPS colour and receipt ordering.
|
|
18
|
+
- memory-browser null handling.
|
|
19
|
+
- learning-dashboard signals.
|
|
20
|
+
- GUARDS 13, whose mechanical check is S-139 (released). The PENDING text in GUARDS.md is out of date.
|
|
21
|
+
- **A `.catch(() => null)` lint was considered and dropped.** 16 sites match, and most of them already render "Could not load". It would pin nothing.
|
|
22
|
+
|
|
23
|
+
### S-174: run_test with a missing or empty argument stops run-all-tests.sh with no summary
|
|
24
|
+
- Files: tests/run-all-tests.sh (the run_test guard and the missing-script return only), tests/test-run-all-missing-arg.sh (new)
|
|
25
|
+
- Tier: MEDIUM. **Captain-built**, because tests/run-all-tests.sh is a hot file. The Captain also registers the new test.
|
|
26
|
+
- Red:
|
|
27
|
+
- `run_test "X"` stops the runner with `$2: unbound variable`. There is no summary and every later suite is skipped.
|
|
28
|
+
- `run_test "X" ""` passes today: `bash -c ""` exits 0.
|
|
29
|
+
- A missing script returns 1, and under `set -e` that stops the run.
|
|
132
30
|
- Green:
|
|
133
|
-
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
-
|
|
138
|
-
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
-
|
|
142
|
-
-
|
|
143
|
-
|
|
144
|
-
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
-
|
|
152
|
-
-
|
|
153
|
-
-
|
|
31
|
+
- Guard on `$# -lt 2` or an empty `$2`.
|
|
32
|
+
- Place it after `_shard_index` increments and before the shard skip, so LPT slots do not shift and every shard reports the fault.
|
|
33
|
+
- Print the name and the line number from `${BASH_LINENO[0]}` to stderr. The line must contain the word FAILED, so the LOKI_TEST_LIST output stays clean and the local-ci scraper still matches.
|
|
34
|
+
- Increment TOTAL_FAILED and return 0.
|
|
35
|
+
- Change the missing-script branch to count the failure and return 0.
|
|
36
|
+
- The test pulls the real run_test out of run-all-tests.sh with sed; it does not copy it. It drives three legs: one argument, an empty argument, and a missing script. A stub registered after each bad line must still run.
|
|
37
|
+
- Wall: `bash tests/test-run-all-missing-arg.sh` exits 0.
|
|
38
|
+
- Each leg prints Failed: 1, and the stub's PASSED line appears after the bad line.
|
|
39
|
+
- A scratch copy with the guard removed exits 1.
|
|
40
|
+
- `bash tests/test-run-all-dispatch.sh` and `LOKI_TEST_LIST=1 bash tests/test-shard-coverage.sh` both exit 0.
|
|
41
|
+
|
|
42
|
+
### S-175: a LOKI_MONOREPO_TEST_CMD rejected by the whitelist records pass true (BACKLOG 62)
|
|
43
|
+
- Files: autonomy/run.sh (the enforce_test_coverage `monorepo-custom-rejected` branch, ~13877, only), tests/test-monorepo-rejected-cmd-inconclusive.sh (new)
|
|
44
|
+
- Tier: HIGH
|
|
45
|
+
- Red: the rejected branch sets `test_runner=monorepo-custom-rejected` but leaves `test_passed=true`. It skips the `none` path at ~14140, so the record reads pass true and unit-tests.pass is touched.
|
|
46
|
+
- **Gate:** the builder must first reproduce pass true plus unit-tests.pass. If that does not reproduce, close the slice as already handled.
|
|
47
|
+
- Green: route the rejected command through the same no-runner record as the `none` path.
|
|
48
|
+
- `pass:"inconclusive"`, `status:"not_run"`, no unit-tests.pass, `.test-results.iter` stamped, and `_LOKI_TEST_SUITE_STATUS=not_run`.
|
|
49
|
+
- Wall: `bash tests/test-monorepo-rejected-cmd-inconclusive.sh` exits 0.
|
|
50
|
+
- Fixture: a workspaces monorepo with `LOKI_MONOREPO_TEST_CMD='npm test; true'`.
|
|
51
|
+
- Reverting the branch exits 1.
|
|
52
|
+
- `bash tests/test-trust-core-tests-detect.sh` exits 0.
|
|
53
|
+
- This is the only run.sh row in this cut.
|
|
54
|
+
|
|
55
|
+
### S-176: the proof headline reads a stale test-results.json (BACKLOG 98, headline half)
|
|
56
|
+
- Files: autonomy/lib/proof-generator.py (`_collect_tests` only), tests/test_proof_tests_freshness.py (new)
|
|
57
|
+
- Tier: HIGH
|
|
58
|
+
- Red: `_test_results_fresh` (322) gates only `_collect_quality_gates` (381). `_collect_tests` (893) feeds facts.tests and the headline, and has no freshness check.
|
|
59
|
+
- Green: when the file is stale, `_collect_tests` returns status not_run. `ITERATION_COUNT` unset keeps the existing reading, matching the helper's ponytail note.
|
|
60
|
+
- Wall: `python3 -m pytest -q tests/test_proof_tests_freshness.py` passes.
|
|
61
|
+
- ITERATION_COUNT=5 with marker 4: facts.tests.status is not_run, and honesty.headline differs from what the fresh case produces.
|
|
62
|
+
- Marker 5 keeps status verified.
|
|
63
|
+
- Removing the check fails the stale case.
|
|
64
|
+
|
|
65
|
+
### S-177: the Bun npm fallback reads an exit-0 run that prints failures as passed (BACKLOG 98, Bun half)
|
|
66
|
+
- Files: loki-ts/src/runner/quality_gates.ts (the `runTestCoverage` npm fallback, ~561-576, only), loki-ts/tests/runner/npm_fallback_summary_failures.test.ts (new)
|
|
67
|
+
- Tier: HIGH
|
|
68
|
+
- Red: `npm test` exits 0 while printing "Tests: 1 failed, 2 passed", and the fallback returns `passed: true`.
|
|
69
|
+
- Green: mirror the bash summary parser (run.sh `_tr_failed_n` awk, ~14268): jest Tests and Test Suites lines, the vitest Test Files line, pytest failed plus errors, mocha failing, and node TAP. Any count above 0 returns passed false.
|
|
70
|
+
- Wall: `cd loki-ts && bun test tests/runner/npm_fallback_summary_failures.test.ts` exits 0.
|
|
71
|
+
- The three failure shapes (jest, vitest, pytest "1 passed, 1 error") return passed false.
|
|
72
|
+
- "Tests: 3 passed" returns passed true.
|
|
73
|
+
- Removing the parse fails the three failure legs.
|
|
74
|
+
- The Captain rebuilds loki-ts/dist/loki.js.
|
|
75
|
+
|
|
76
|
+
### S-178: `/api/cost` treats context-tracker tokens without a USD figure as a measured $0 (BACKLOG 112)
|
|
77
|
+
- Files: dashboard/server.py (the get_cost context-tracker fallback, ~7925-7950, only), tests/dashboard/test_cost_tracker_fallback_unmeasured.py (new)
|
|
78
|
+
- Tier: MEDIUM
|
|
79
|
+
- Red: tokens greater than 0 set `cost_recorded = True` and `estimated_cost = totals.get("total_cost_usd", 0.0)`. The model defaults to "sonnet" when the provider is absent.
|
|
154
80
|
- Green:
|
|
155
|
-
-
|
|
156
|
-
-
|
|
157
|
-
|
|
158
|
-
-
|
|
159
|
-
-
|
|
160
|
-
|
|
161
|
-
### S-
|
|
162
|
-
- Files:
|
|
163
|
-
- Tier:
|
|
164
|
-
- Red:
|
|
81
|
+
- Tokens count as measured, and cost is null unless total_cost_usd is a number. A recorded 0.0 stays 0.0.
|
|
82
|
+
- The model is `unknown` when there is no provider.
|
|
83
|
+
- Wall: `python3 -m pytest -q tests/dashboard/test_cost_tracker_fallback_unmeasured.py` passes, and reverting fails the first case.
|
|
84
|
+
- `bash tests/moat/p7-no-fabricated-data.sh` prints `CASE P7.unmeasured-cost-never-zero PASS`.
|
|
85
|
+
- This is the only dashboard/server.py row.
|
|
86
|
+
|
|
87
|
+
### S-179: `loki cost` puts 0.0 in place of unknown spend (BACKLOG 106, bash half)
|
|
88
|
+
- Files: autonomy/loki (`cmd_cost`, 28196, only), tests/test-loki-cost-unmeasured.sh (new)
|
|
89
|
+
- Tier: MEDIUM
|
|
90
|
+
- Red:
|
|
91
|
+
- `else: budget_used = 0.0` (~28452) contradicts its own comment.
|
|
92
|
+
- budget.json always carries `budget_used`, because run.sh check_budget_limit writes it, so a recorded 0 carries no "measured" signal.
|
|
93
|
+
- Green: used and percent are null, and the text reads "not recorded", when no efficiency record is measured. Mirror the dashboard's `_record_is_measured` (server.py 7768) or S-131's Bun rule; the builder names which.
|
|
94
|
+
- Wall: `bash tests/test-loki-cost-unmeasured.sh` exits 0.
|
|
95
|
+
- A cap of 10 with no measured records: `--json` budget used null, percent null.
|
|
96
|
+
- Measured 2.50: 2.5 and 25.0.
|
|
97
|
+
- Reverting fails the first leg.
|
|
98
|
+
- This is the only autonomy/loki row.
|
|
99
|
+
|
|
100
|
+
### S-180: the P7 helper-return arm misses class methods (BACKLOG 144)
|
|
101
|
+
- Files: tests/moat/p7-no-fabricated-data.sh (the helper-return arm only)
|
|
102
|
+
- Tier: HIGH (moat)
|
|
103
|
+
- Red: `_getRows() { return [{id:1,user:'Admin'}]; } ... this._rows = this._getRows();` is caught by no rule.
|
|
104
|
+
- **Branch:** run the widened arm against main first.
|
|
105
|
+
- On any live hit in dashboard-ui or web-app, the slice becomes report-only. List the hits and let the Captain decide. Never add an allowlist to make it pass.
|
|
106
|
+
- cases.txt stays unchanged: no new case ID.
|
|
107
|
+
- Wall: `bash tests/moat/p7-no-fabricated-data.sh` prints PASS for every P7 case.
|
|
108
|
+
- An in-script planted class-method fixture is flagged.
|
|
109
|
+
- Removing the method-head pattern lets that fixture through.
|
|
110
|
+
|
|
111
|
+
### S-181: GUARDS 11, glob rm in a shared root
|
|
112
|
+
- Files: scripts/v10-guard.sh (the Rule 4 region only), tests/test-v10-guard.sh, docs/v10/GUARDS.md (section 11 guard and test lines only)
|
|
113
|
+
- Tier: MEDIUM
|
|
114
|
+
- Red: Rule 4 checks only recursive plus force rm. `rm -f /tmp/*.log` and an `rm -f` glob in the scratchpad root both go through.
|
|
165
115
|
- Green:
|
|
166
|
-
-
|
|
167
|
-
-
|
|
168
|
-
-
|
|
169
|
-
- Wall: `
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
116
|
+
- Block any rm with a glob target whose literal parent is exactly /tmp, /private/tmp, $TMPDIR, or a directory named `scratchpad`.
|
|
117
|
+
- Allow globs one level below such a root.
|
|
118
|
+
- Where the parent is an unexpanded variable, allow it, and leave a ponytail comment that names this limit.
|
|
119
|
+
- Wall: `bash tests/test-v10-guard.sh` exits 0.
|
|
120
|
+
- New cases: `rm -f /tmp/*.log` blocked, `rm -f <scratchpad>/*` blocked, `rm -f /tmp/run-1/*.log` allowed.
|
|
121
|
+
- Dropping the new rule fails the blocked cases.
|
|
122
|
+
|
|
123
|
+
### S-182: docs/exit-codes.md does not mention the verify codes that are pending
|
|
124
|
+
- Files: docs/exit-codes.md (the `loki verify` section only)
|
|
173
125
|
- Tier: LOW
|
|
174
|
-
- Red:
|
|
175
|
-
-
|
|
176
|
-
-
|
|
177
|
-
|
|
178
|
-
### S-161: ProjectsPage ignores the poll error and says "No projects yet" (BACKLOG 114)
|
|
179
|
-
- Files: web-app/src/pages/ProjectsPage.tsx, web-app/src/pages/ProjectsPage.state.test.mjs (new)
|
|
180
|
-
- Tier: LOW
|
|
181
|
-
- Red: `usePolling` returns `error` (web-app/src/hooks/usePolling.ts:7), but ProjectsPage destructures only `data` and `refresh` (~65). A failed history fetch renders "No projects yet. Start building." (~168).
|
|
126
|
+
- Red:
|
|
127
|
+
- The section says code 3 "never silently passes".
|
|
128
|
+
- `loki verify --fast` (autonomy/loki 18513, which calls fast_verify.py) exits 0 on INCONCLUSIVE and ignores unknown flags.
|
|
129
|
+
- Both cases are pending at v10.0.0.
|
|
182
130
|
- Green:
|
|
183
|
-
-
|
|
184
|
-
-
|
|
185
|
-
|
|
186
|
-
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
-
|
|
131
|
+
- Add a "Known gaps until v10.0.0" note. It gives the codes the builder measures on this checkout for four inputs: an empty diff, a non-git directory, an unknown flag, and `--fast` with nothing scanned.
|
|
132
|
+
- It names both pending case IDs, and tells users to check stdout for INCONCLUSIVE under `--fast`.
|
|
133
|
+
- Wall: `bash tests/test-exit-codes-documented.sh` exits 0.
|
|
134
|
+
- `grep -n 'P2.fast-verify-inconclusive-not-zero' docs/exit-codes.md` prints one line.
|
|
135
|
+
- The four measured codes are in the builder's report, each with its command.
|
|
136
|
+
|
|
137
|
+
### S-183: the migration dashboard renders a failed load as "No migration data available" (BACKLOG 114)
|
|
138
|
+
- Files: dashboard-ui/components/loki-migration-dashboard.js (the error render branch, ~599-610, only), dashboard-ui/tests/loki-migration-dashboard-fetch-error.node.test.mjs (new)
|
|
190
139
|
- Tier: LOW
|
|
191
|
-
-
|
|
192
|
-
-
|
|
193
|
-
-
|
|
140
|
+
- Wall: `node --test dashboard-ui/tests/loki-migration-dashboard-fetch-error.node.test.mjs` passes.
|
|
141
|
+
- A rejected fetch renders "Could not load migrations" plus the message, and not the empty-state sentence.
|
|
142
|
+
- A real empty list still renders "No migrations found".
|
|
143
|
+
- The Captain rebuilds dashboard/static/index.html.
|
|
194
144
|
|
|
195
|
-
### S-
|
|
196
|
-
- Files:
|
|
145
|
+
### S-184: the managed memory panel ignores a 200 response carrying an error (BACKLOG 114)
|
|
146
|
+
- Files: dashboard-ui/components/loki-managed-memory-panel.js (the events load only), dashboard-ui/tests/loki-managed-memory-events-error.node.test.mjs (new)
|
|
197
147
|
- Tier: LOW
|
|
198
|
-
- Red:
|
|
199
|
-
-
|
|
200
|
-
-
|
|
201
|
-
- `
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
- Files: web-app/src/components/AIChatPanel.tsx (the two `|| 'Done.'` fallbacks at ~543 and ~622 only), web-app/src/components/AIChatPanel.result.test.mjs (new)
|
|
148
|
+
- Red: server.py ~12145 returns `{"events": [], "count": 0, "error": ...}`, and the panel renders "No managed memory events recorded yet."
|
|
149
|
+
- Wall: `node --test dashboard-ui/tests/loki-managed-memory-events-error.node.test.mjs` passes.
|
|
150
|
+
- The error payload renders the error line, and not the empty sentence.
|
|
151
|
+
- `{events:[],count:0}` still renders the empty sentence.
|
|
152
|
+
- The Captain rebuilds dashboard/static/index.html.
|
|
153
|
+
|
|
154
|
+
### S-185: DeployConnections shows "Not connected" rows under its own load error (BACKLOG 114, rendering only)
|
|
155
|
+
- Files: web-app/src/components/DeployConnections.tsx (the row status render only), web-app/src/components/DeployConnections.state.test.mjs (new)
|
|
207
156
|
- Tier: LOW
|
|
208
|
-
-
|
|
209
|
-
-
|
|
210
|
-
- Wall: `node --test web-app/src/components/
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
-
|
|
157
|
+
- Scope: after a failed fetch, the rows read unknown instead of "Not connected", the same shape as S-170.
|
|
158
|
+
- The upward onStatusChange push of the defaults is BACKLOG 121 and stays held.
|
|
159
|
+
- Wall: `node --test web-app/src/components/DeployConnections.state.test.mjs` passes.
|
|
160
|
+
- After a failed fetch, no row reads "Not connected".
|
|
161
|
+
- A real `{connected:false}` still does.
|
|
162
|
+
- `cd web-app && npx tsc -b` exits 0.
|
|
163
|
+
- The Captain rebuilds web-app/dist.
|
|
164
|
+
|
|
165
|
+
### S-186: the issue list's comment count never shows (BACKLOG 116)
|
|
166
|
+
- Files: web-app/src/components/GitHubIssuesPanel.tsx (the list comment badge only), web-app/src/types/api.ts (GitHubIssue.comments only), web-app/src/components/GitHubIssuesPanel.comments.test.mjs (new)
|
|
214
167
|
- Tier: LOW
|
|
215
|
-
- Red:
|
|
216
|
-
-
|
|
217
|
-
-
|
|
218
|
-
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
- Files: dashboard-ui/components/loki-checkpoint-viewer.js (the load at ~95-110 only), dashboard-ui/tests/loki-checkpoint-viewer-fetch-error.node.test.mjs (new)
|
|
168
|
+
- Red: web-app/server.py 7297 asks gh for `comments`, which gh returns as an array. `issue.comments > 0` is then always false.
|
|
169
|
+
- Wall: `node --test web-app/src/components/GitHubIssuesPanel.comments.test.mjs` passes.
|
|
170
|
+
- An array of 2 renders 2, and a number 3 renders 3.
|
|
171
|
+
- `cd web-app && npx tsc -b` exits 0.
|
|
172
|
+
- The Captain rebuilds web-app/dist.
|
|
173
|
+
|
|
174
|
+
### S-187: CostEstimator uses the whole iteration cap as its estimate (BACKLOG 118)
|
|
175
|
+
- Files: web-app/src/components/ProjectWorkspace.tsx (the CostEstimator props, ~2482, only), web-app/src/components/CostEstimator.tsx (export estimateCosts only if needed), web-app/src/components/CostEstimator.estimate.test.mjs (new)
|
|
224
176
|
- Tier: LOW
|
|
225
|
-
- Red: `
|
|
226
|
-
-
|
|
227
|
-
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
-
|
|
177
|
+
- Red: `estimatedIterations={buildStatus.maxIterations ?? 0}`, so a cap of 1000 is priced as 1000 iterations.
|
|
178
|
+
- Wall: `node --test web-app/src/components/CostEstimator.estimate.test.mjs` passes.
|
|
179
|
+
- A cap of 1000 does not change the estimate from the complexity default.
|
|
180
|
+
- `grep -n 'estimatedIterations={buildStatus.maxIterations' web-app/src/components/ProjectWorkspace.tsx` exits 1.
|
|
181
|
+
- `cd web-app && npx tsc -b` exits 0.
|
|
182
|
+
- The Captain rebuilds web-app/dist.
|
|
183
|
+
|
|
184
|
+
### S-188: no test of its own covers the overview proof card's verdict wording (BACKLOG 123, tests only)
|
|
185
|
+
- Files: dashboard-ui/tests/loki-overview-proof-card.node.test.mjs (new)
|
|
231
186
|
- Tier: LOW
|
|
232
|
-
-
|
|
233
|
-
-
|
|
234
|
-
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
-
|
|
238
|
-
|
|
239
|
-
-
|
|
240
|
-
-
|
|
241
|
-
- Wall: `node --test dashboard-ui/tests/loki-task-board-fetch-error.node.test.mjs` passes. `node --test dashboard-ui/tests/loki-task-board-modal-guard.node.test.mjs` still passes.
|
|
242
|
-
|
|
243
|
-
### S-169: log stream swallows API failures silently (BACKLOG 114)
|
|
244
|
-
- Files: dashboard-ui/components/loki-log-stream.js (the API poll catch at ~179 and the empty render only), dashboard-ui/tests/loki-log-stream-fetch-error.node.test.mjs (new)
|
|
187
|
+
- Pins loki-overview.js 486-489:
|
|
188
|
+
- With no proof, the card reads "Not evaluated".
|
|
189
|
+
- With a headline, the meta starts with "Recorded, not re-verified here;".
|
|
190
|
+
- gaps null reads "uncertainty not measured".
|
|
191
|
+
- Wall: `node --test dashboard-ui/tests/loki-overview-proof-card.node.test.mjs` passes.
|
|
192
|
+
- Deleting the recorded-copy prefix in a scratch copy fails it.
|
|
193
|
+
|
|
194
|
+
### S-189: the learning dashboard renders failed metrics and trends reads as no data (BACKLOG 114)
|
|
195
|
+
- Files: dashboard-ui/components/loki-learning-dashboard.js (the metrics and trends load plus `_renderSummaryCards` and `_renderTrendChart` empty branches only), dashboard-ui/tests/loki-learning-dashboard-fetch-error.node.test.mjs (new)
|
|
245
196
|
- Tier: LOW
|
|
246
|
-
- Red:
|
|
247
|
-
-
|
|
248
|
-
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
-
|
|
197
|
+
- Red: `.catch(() => null)` at 132 and 133 feeds "No metrics available" and "No trend data available".
|
|
198
|
+
- Wall: `node --test dashboard-ui/tests/loki-learning-dashboard-fetch-error.node.test.mjs` passes.
|
|
199
|
+
- Rejected metrics and trends render "Could not load".
|
|
200
|
+
- A real empty trends response still renders "No trend data available".
|
|
201
|
+
- `loki-learning-dashboard.test.js` is unaffected.
|
|
202
|
+
- The Captain rebuilds dashboard/static/index.html.
|
|
203
|
+
|
|
204
|
+
### S-190: the R3 design doc describes project_total_usd as a plain sum (BACKLOG 112 remainder)
|
|
205
|
+
- Files: docs/R3-COST-OBSERVABILITY-DESIGN.md
|
|
252
206
|
- Tier: LOW
|
|
253
|
-
-
|
|
254
|
-
-
|
|
255
|
-
-
|
|
207
|
+
- Wall: `grep -n 'sum of per-run proof costs' docs/R3-COST-OBSERVABILITY-DESIGN.md` exits 1.
|
|
208
|
+
- `grep -n 'project_total_partial' docs/R3-COST-OBSERVABILITY-DESIGN.md` prints at least one line.
|
|
209
|
+
- The doc states null when no run is measured, citing dashboard/server.py 8384-8385.
|
|
256
210
|
|
|
257
|
-
### S-
|
|
258
|
-
- Files: tests/test-
|
|
211
|
+
### S-191: speed up test-review-assurance-tail.sh (116s in shard-durations.tsv)
|
|
212
|
+
- Files: tests/test-review-assurance-tail.sh
|
|
259
213
|
- Tier: MEDIUM
|
|
260
|
-
-
|
|
261
|
-
-
|
|
262
|
-
-
|
|
263
|
-
|
|
264
|
-
-
|
|
265
|
-
-
|
|
266
|
-
|
|
214
|
+
- The builder captures the pre-change wall time and pass count under `LOKI_TEST_SHARD=0/8` first.
|
|
215
|
+
- Then run independent cases concurrently, each in its own TMPROOT subdirectory.
|
|
216
|
+
- Review budgets and timeout values stay unchanged.
|
|
217
|
+
- Wall: `time LOKI_TEST_SHARD=0/8 bash tests/test-review-assurance-tail.sh` exits 0 with real time under 60s.
|
|
218
|
+
- The pass-count line matches the pre-change capture.
|
|
219
|
+
- The builder reports both timings.
|
|
220
|
+
|
|
221
|
+
### S-192: no test drives the web-app WebSocket status push payload (BACKLOG 112)
|
|
222
|
+
- Files: web-app/tests/test_status_push_unmeasured.py (new), web-app/server.py (lift the nested status reader, ~6360-6425, to module level only if TestClient cannot drive it)
|
|
223
|
+
- Tier: MEDIUM
|
|
224
|
+
- Wall: `python3 -m pytest -q web-app/tests/test_status_push_unmeasured.py` passes.
|
|
225
|
+
- dashboard-state.json with no tokens: the push has cost null and max_iterations null.
|
|
226
|
+
- Priced tokens: cost is a number.
|
|
227
|
+
- Forcing the reader to 0.0 in a scratch copy fails the first case.
|
|
267
228
|
|
|
268
|
-
### S-
|
|
269
|
-
- Files: tests/test-
|
|
229
|
+
### S-193: let a batch know its worktree budget before dispatch (TODO item 8)
|
|
230
|
+
- Files: scripts/v10-ops.sh (a new worktree-budget subcommand), tests/test-v10-ops.sh
|
|
270
231
|
- Tier: LOW
|
|
271
|
-
-
|
|
272
|
-
-
|
|
273
|
-
-
|
|
274
|
-
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
-
|
|
279
|
-
-
|
|
280
|
-
-
|
|
281
|
-
-
|
|
282
|
-
-
|
|
283
|
-
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
**
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
| S-
|
|
316
|
-
| S-
|
|
317
|
-
| S-156 | BACKLOG 127 remainder: auto-capture shadow_write runs with PROJECT_DIR unset, and float() splices episode importance into python source | autonomy/run.sh (shadow_write auto-capture block about 21380-21396 only), tests/test-autocapture-shadow-write-guard.sh (new) | HIGH | bash tests/test-autocapture-shadow-write-guard.sh exits 0 under /bin/bash and bash 5; no marker from a planted cwd memory package; no file from an injected importance; trust-core suite passes | ready@2026-09-27T19:10Z | Builder names who writes episode_path_file. Only run.sh row in this cut. Source: 19:10Z cut. |
|
|
318
|
-
| S-157 | BACKLOG 98/89: council member vote and _council_convergence_evidence_green read pass:true as green whatever failed_count says | autonomy/completion-council.sh (those 2 parsers only), tests/test-council-failed-count-honesty.sh (new) | HIGH | pass:true with failed_count 2 is not green at both sites; failed_count 0 stays green; trust-core and convergence-floor suites pass; reverting either site fails its case | ready@2026-09-27T19:10Z | Mirrors the evidence gate rule (~2014). Only completion-council.sh row in this cut. Source: 19:10Z cut. |
|
|
319
|
-
| S-158 | BACKLOG 118: per-run cost_partial dropped by /api/cost/timeline runs[] and /api/proofs; pages show a lower bound as a total | dashboard/server.py (runs.append in _compute_cost_timeline and the /api/proofs row only), dashboard/static/cost.html, dashboard/static/proofs.html, tests/dashboard/test_cost_partial_surfaced.py (new) | MEDIUM | pytest test_cost_partial_surfaced.py passes; fixture cost_partial true surfaces in both endpoints and renders as at least $X; dropping the key fails | ready@2026-09-27T19:10Z | Builder names the consumers checked. Source: 19:10Z cut. |
|
|
320
|
-
| S-159 | BACKLOG 114: NLSearch renders No results found when the search request failed | web-app/src/components/NLSearch.tsx, web-app/src/components/NLSearch.state.test.mjs (new) | LOW | node --test NLSearch.state.test.mjs passes incl. the negative assertion; npx tsc -b exits 0 | ready@2026-09-27T19:10Z | Captain rebuilds web-app/dist. Source: 19:10Z cut. |
|
|
321
|
-
| S-160 | BACKLOG 114: CommandPalette file-search failure reads as No results found | web-app/src/components/CommandPalette.tsx, web-app/src/components/CommandPalette.state.test.mjs (new) | LOW | node --test CommandPalette.state.test.mjs passes; npx tsc -b exits 0 | ready@2026-09-27T19:10Z | Captain rebuilds web-app/dist. Source: 19:10Z cut. |
|
|
322
|
-
| S-161 | BACKLOG 114: ProjectsPage ignores usePolling error and says No projects yet on a failed fetch | web-app/src/pages/ProjectsPage.tsx, web-app/src/pages/ProjectsPage.state.test.mjs (new) | LOW | node --test ProjectsPage.state.test.mjs passes (error, stale-data and real-empty cases); npx tsc -b exits 0 | ready@2026-09-27T19:10Z | Captain rebuilds web-app/dist. Source: 19:10Z cut. |
|
|
323
|
-
| S-162 | BACKLOG 114: SecretsPanel and DocsPanel swallow fetch errors into No secrets / No documentation empty states | web-app/src/components/ProjectWorkspace.tsx (SecretsPanel and DocsPanel fetch and empty branches only), web-app/src/components/ProjectWorkspace.panels.test.mjs (new) | LOW | node --test ProjectWorkspace.panels.test.mjs passes; npx tsc -b exits 0 | ready@2026-09-27T19:10Z | Captain rebuilds web-app/dist. Source: 19:10Z cut. |
|
|
324
|
-
| S-163 | BACKLOG 114: CICDPanel maps neutral/action_required/stale/null conclusions to Failed and unknown statuses to running | web-app/src/components/CICDPanel.tsx (3 normalizers and status map only), web-app/src/components/CICDPanel.status.test.mjs (new) | LOW | node --test CICDPanel.status.test.mjs passes for every conclusion; npx tsc -b exits 0 | ready@2026-09-27T19:10Z | Captain rebuilds web-app/dist. Source: 19:10Z cut. |
|
|
325
|
-
| S-164 | BACKLOG 114: AIChatPanel prints Done. for a non-zero exit with no output | web-app/src/components/AIChatPanel.tsx (the two Done. fallbacks only), web-app/src/components/AIChatPanel.result.test.mjs (new) | LOW | node --test AIChatPanel.result.test.mjs passes; npx tsc -b exits 0 | ready@2026-09-27T19:10Z | Captain rebuilds web-app/dist. Source: 19:10Z cut. |
|
|
326
|
-
| S-165 | BACKLOG 117 remainder: TrustedBy asserts Trusted by developers; ChangelogWidget shows March 2026 v6.x as Recent Changes | web-app/src/components/TrustedBy.tsx, web-app/src/components/ChangelogWidget.tsx | LOW | grep for Trusted by developers and 6.71.1 in those files returns rc 1; npx tsc -b exits 0 | ready@2026-09-27T19:10Z | Copy only. Captain rebuilds web-app/dist. Source: 19:10Z cut. |
|
|
327
|
-
| S-166 | BACKLOG 114: checkpoint viewer ignores a rejected allSettled fetch and clears the error | dashboard-ui/components/loki-checkpoint-viewer.js (load block only), dashboard-ui/tests/loki-checkpoint-viewer-fetch-error.node.test.mjs (new) | LOW | node --test the new file passes incl. the negative assertion | ready@2026-09-27T19:10Z | Captain rebuilds dashboard/static/index.html. Source: 19:10Z cut. |
|
|
328
|
-
| S-167 | BACKLOG 114: council transcripts render a failed hook-events read as zero events | dashboard-ui/components/loki-council-transcripts.js (hook events load only), dashboard-ui/tests/loki-council-transcripts-fetch-error.node.test.mjs (new) | LOW | node --test the new file passes | ready@2026-09-27T19:10Z | Captain rebuilds dashboard/static/index.html. Source: 19:10Z cut. |
|
|
329
|
-
| S-168 | BACKLOG 114: task board hides a server load error whenever local tasks exist | dashboard-ui/components/loki-task-board.js (catch and error render only), dashboard-ui/tests/loki-task-board-fetch-error.node.test.mjs (new) | LOW | node --test the new file passes; loki-task-board-modal-guard test still passes | ready@2026-09-27T19:10Z | Captain rebuilds dashboard/static/index.html. Source: 19:10Z cut. |
|
|
330
|
-
| S-169 | BACKLOG 114: log stream swallows API failures with an empty catch | dashboard-ui/components/loki-log-stream.js (API poll catch and empty render only), dashboard-ui/tests/loki-log-stream-fetch-error.node.test.mjs (new) | LOW | node --test the new file passes; loki-poll-registry test still passes | ready@2026-09-27T19:10Z | Captain rebuilds dashboard/static/index.html. Source: 19:10Z cut. |
|
|
331
|
-
| S-170 | BACKLOG 114: API keys panel renders No API keys configured under its own load-error banner | dashboard-ui/components/loki-api-keys.js (table branch only), dashboard-ui/tests/loki-api-keys-fetch-error.node.test.mjs (new) | LOW | node --test the new file passes; error render lacks the empty-state sentence | ready@2026-09-27T19:10Z | Captain rebuilds dashboard/static/index.html. Source: 19:10Z cut. |
|
|
332
|
-
| S-171 | BACKLOG 124: lint for response fields interpolated into innerHTML without the escape helper | tests/test-no-unescaped-innerhtml.sh (new), tests/lib/scan-unescaped-innerhtml.py (new) | MEDIUM | passes on main with a reasoned in-file allowlist; planted fixture exits 1; empty-reason entry fails; at least 20 files scanned | ready@2026-09-27T19:10Z | Real XSS found is reported, not fixed here. Captain registers. Source: 19:10Z cut. |
|
|
333
|
-
| S-172 | BACKLOG 132: shadow-write mutant check is green on bash 5.3 and red on /bin/bash 3.2 | tests/test-council-shadow-write-project-dir.sh | LOW | bash tests/test-council-shadow-write-project-dir.sh exits 0; mutant leg red under both /bin/bash and PATH bash, both versions printed | ready@2026-09-27T19:10Z | Test-only. Source: 19:10Z cut. |
|
|
334
|
-
| S-173 | BACKLOG 135: P2.council-readers-not-shadowed does not drive council_managed_should_stop (cwd-shadow class only) | tests/moat/p2-honest-verdict.sh (that case only) | HIGH | p2-honest-verdict.sh prints CASE P2.council-readers-not-shadowed PASS; removing the sys.path filter in a scratch copy prints FAIL | ready@2026-09-27T19:10Z | No .pth leg: that reader is still python3 -E, so a .pth leg would redden a proven case; follows alternate A2. Source: 19:10Z cut. |
|
|
232
|
+
- Wall: `bash tests/test-v10-ops.sh` exits 0.
|
|
233
|
+
- `scripts/v10-ops.sh worktree-budget 15` prints 15 minus the count of `.claude/worktrees` entries in `git worktree list --porcelain`.
|
|
234
|
+
- At or over the cap it prints 0 and exits 1.
|
|
235
|
+
- Fixtures use a scratch repo only.
|
|
236
|
+
|
|
237
|
+
**Registration and rebuilds (Captain).**
|
|
238
|
+
- New tests to register:
|
|
239
|
+
- S-175, S-176, S-178, S-179, S-183 to S-189, S-192.
|
|
240
|
+
- S-174 is registered by the Captain as part of building it.
|
|
241
|
+
- Bundle rebuilds:
|
|
242
|
+
- S-177: loki-ts/dist.
|
|
243
|
+
- S-183, S-184, S-189: dashboard/static/index.html.
|
|
244
|
+
- S-185 to S-187: web-app/dist.
|
|
245
|
+
|
|
246
|
+
**Held, not in the 20 (alternates):**
|
|
247
|
+
- **A1: BACKLOG 108**, HIGH. `create_session_pr` never reads agent-committed-user-files.z before a LOKI_AUTO_PR push. Its only reference is the writer at run.sh 10914. Cut it the moment S-175 merges, since it is also a run.sh change.
|
|
248
|
+
- **A2: BACKLOG 17**, the `/api/focus` POST that fires with LOKI_DASHBOARD=false (run.sh 24481). After S-175.
|
|
249
|
+
- **A3: council_managed_should_stop** `-I -S` plus the PROJECT_DIR guard, followed by S-173's `.pth` leg. After S-157.
|
|
250
|
+
- **A4: BACKLOG 51**, the NOT CHECKED message should name PYTHONPATH and PYTHONUSERBASE (autonomy/loki ~1270). After S-179.
|
|
251
|
+
- **A5: BACKLOG 145 and 147**, P7 arms. After S-180.
|
|
252
|
+
- **Too large or held:**
|
|
253
|
+
- P1.verification-metadata-signed (a seal.v1 format change).
|
|
254
|
+
- The P2 verify renumber (CEO, v10.0.0).
|
|
255
|
+
- BACKLOG 18, 52, 121, 123 (audit.py half).
|
|
256
|
+
- S-112, S-114, S-115, S-117 to S-122.
|
|
257
|
+
|
|
258
|
+
| S-174 | Guard: run_test with a missing or empty argument stops run-all-tests.sh with no summary and skips later suites | tests/run-all-tests.sh (run_test guard and missing-script return only), tests/test-run-all-missing-arg.sh (new) | MEDIUM | bash tests/test-run-all-missing-arg.sh exits 0 with Failed: 1 per leg (one-arg, empty-arg, missing-script) and the later stub's PASSED line printed; guard removed in a scratch copy exits 1; bash tests/test-run-all-dispatch.sh and LOKI_TEST_LIST=1 bash tests/test-shard-coverage.sh exit 0 | ready@2026-09-27T19:57Z | Source: 19:57Z cut. |
|
|
259
|
+
| S-175 | BACKLOG 62: a whitelist-rejected LOKI_MONOREPO_TEST_CMD records pass true and touches unit-tests.pass | autonomy/run.sh (enforce_test_coverage monorepo-custom-rejected branch only), tests/test-monorepo-rejected-cmd-inconclusive.sh (new) | HIGH | bash tests/test-monorepo-rejected-cmd-inconclusive.sh exits 0: pass is "inconclusive", status not_run, no unit-tests.pass; reverting the branch exits 1; bash tests/test-trust-core-tests-detect.sh exits 0 | ready@2026-09-27T19:57Z | Source: 19:57Z cut. |
|
|
260
|
+
| S-176 | BACKLOG 98: proof headline reads a stale test-results.json (_collect_tests has no .test-results.iter check) | autonomy/lib/proof-generator.py (_collect_tests only), tests/test_proof_tests_freshness.py (new) | HIGH | python3 -m pytest -q tests/test_proof_tests_freshness.py passes: ITERATION_COUNT=5 with marker 4 gives facts.tests.status not_run and a headline unlike the fresh case; marker 5 keeps the prior status; removing the check fails the stale case | ready@2026-09-27T19:57Z | Source: 19:57Z cut. |
|
|
261
|
+
| S-177 | BACKLOG 98: Bun npm-test fallback reads an exit-0 run that prints failures as passed | loki-ts/src/runner/quality_gates.ts (runTestCoverage npm fallback only), loki-ts/tests/runner/npm_fallback_summary_failures.test.ts (new) | HIGH | cd loki-ts && bun test tests/runner/npm_fallback_summary_failures.test.ts exits 0: jest Tests 1 failed, vitest Test Files 1 failed and pytest 1 passed 1 error all return passed false; Tests 3 passed returns passed true; removing the parse fails the first three | ready@2026-09-27T19:57Z | Source: 19:57Z cut. |
|
|
262
|
+
| S-178 | BACKLOG 112: /api/cost reads tracker tokens without a USD total as a measured $0 and labels the model sonnet | dashboard/server.py (get_cost context-tracker fallback only), tests/dashboard/test_cost_tracker_fallback_unmeasured.py (new) | MEDIUM | python3 -m pytest -q tests/dashboard/test_cost_tracker_fallback_unmeasured.py passes (tokens without total_cost_usd give cost null; recorded 0.0 stays 0.0; no provider gives model unknown); reverting fails case 1; bash tests/moat/p7-no-fabricated-data.sh prints CASE P7.unmeasured-cost-never-zero PASS | ready@2026-09-27T19:57Z | Source: 19:57Z cut. |
|
|
263
|
+
| S-179 | BACKLOG 106: loki cost puts 0.0 in place of unknown spend | autonomy/loki (cmd_cost only), tests/test-loki-cost-unmeasured.sh (new) | MEDIUM | bash tests/test-loki-cost-unmeasured.sh exits 0: cap 10 with no measured records gives --json used null and percent null; measured 2.50 gives 2.5 and 25.0; reverting fails the first leg | ready@2026-09-27T19:57Z | Source: 19:57Z cut. |
|
|
264
|
+
| S-180 | BACKLOG 144: P7 helper-return arm misses class-method helpers | tests/moat/p7-no-fabricated-data.sh (helper-return arm only) | HIGH | bash tests/moat/p7-no-fabricated-data.sh prints PASS for every P7 case and flags the in-script class-method fixture; removing the method-head pattern lets the fixture through; tests/moat/cases.txt unchanged | ready@2026-09-27T19:57Z | Source: 19:57Z cut. |
|
|
265
|
+
| S-181 | GUARDS 11: v10-guard blocks a glob rm whose parent is a shared root (/tmp, TMPDIR, scratchpad) | scripts/v10-guard.sh (Rule 4 region only), tests/test-v10-guard.sh, docs/v10/GUARDS.md (section 11 only) | MEDIUM | bash tests/test-v10-guard.sh exits 0 with rm -f /tmp/*.log and rm -f scratchpad/* blocked and rm -f /tmp/run-1/*.log allowed; dropping the new rule fails the blocked cases | ready@2026-09-27T19:57Z | Source: 19:57Z cut. |
|
|
266
|
+
| S-182 | docs/exit-codes.md omits the pending loki verify codes (verify --fast exits 0 on INCONCLUSIVE until v10.0.0) | docs/exit-codes.md (loki verify section only) | LOW | bash tests/test-exit-codes-documented.sh exits 0; grep -n P2.fast-verify-inconclusive-not-zero docs/exit-codes.md prints one line; the four measured codes appear in the report with their commands | ready@2026-09-27T19:57Z | Source: 19:57Z cut. |
|
|
267
|
+
| S-183 | BACKLOG 114: migration dashboard renders a failed load as No migration data available | dashboard-ui/components/loki-migration-dashboard.js (error render branch only), dashboard-ui/tests/loki-migration-dashboard-fetch-error.node.test.mjs (new) | LOW | node --test dashboard-ui/tests/loki-migration-dashboard-fetch-error.node.test.mjs passes: a rejected fetch renders Could not load and lacks the empty-state sentence; an empty list still renders No migrations found | ready@2026-09-27T19:57Z | Source: 19:57Z cut. |
|
|
268
|
+
| S-184 | BACKLOG 114: managed memory panel ignores a 200 events payload carrying error | dashboard-ui/components/loki-managed-memory-panel.js (events load only), dashboard-ui/tests/loki-managed-memory-events-error.node.test.mjs (new) | LOW | node --test dashboard-ui/tests/loki-managed-memory-events-error.node.test.mjs passes: the error payload renders the error line and not the empty sentence; events [] with no error still renders the empty sentence | ready@2026-09-27T19:57Z | Source: 19:57Z cut. |
|
|
269
|
+
| S-185 | BACKLOG 114: DeployConnections rows read Not connected under their own load error | web-app/src/components/DeployConnections.tsx (row status render only), web-app/src/components/DeployConnections.state.test.mjs (new) | LOW | node --test web-app/src/components/DeployConnections.state.test.mjs passes: no row reads Not connected after a failed fetch; a real connected false still does; cd web-app && npx tsc -b exits 0 | ready@2026-09-27T19:57Z | Source: 19:57Z cut. |
|
|
270
|
+
| S-186 | BACKLOG 116: issue list comment count never shows (gh sends comments as an array) | web-app/src/components/GitHubIssuesPanel.tsx (list comment badge only), web-app/src/types/api.ts (GitHubIssue.comments only), web-app/src/components/GitHubIssuesPanel.comments.test.mjs (new) | LOW | node --test web-app/src/components/GitHubIssuesPanel.comments.test.mjs passes: array of 2 renders 2, number 3 renders 3; cd web-app && npx tsc -b exits 0 | ready@2026-09-27T19:57Z | Source: 19:57Z cut. |
|
|
271
|
+
| S-187 | BACKLOG 118: CostEstimator prices the whole iteration cap as the estimate | web-app/src/components/ProjectWorkspace.tsx (CostEstimator props only), web-app/src/components/CostEstimator.tsx (export only if needed), web-app/src/components/CostEstimator.estimate.test.mjs (new) | LOW | node --test web-app/src/components/CostEstimator.estimate.test.mjs passes; grep -n 'estimatedIterations={buildStatus.maxIterations' web-app/src/components/ProjectWorkspace.tsx exits 1; cd web-app && npx tsc -b exits 0 | ready@2026-09-27T19:57Z | Source: 19:57Z cut. |
|
|
272
|
+
| S-188 | BACKLOG 123: overview proof card wording has no test of its own | dashboard-ui/tests/loki-overview-proof-card.node.test.mjs (new) | LOW | node --test dashboard-ui/tests/loki-overview-proof-card.node.test.mjs passes: no proof reads Not evaluated, a headline carries the recorded-copy prefix, gaps null reads uncertainty not measured; deleting the prefix in a scratch copy fails it | ready@2026-09-27T19:57Z | Source: 19:57Z cut. |
|
|
273
|
+
| S-189 | BACKLOG 114: learning dashboard renders failed metrics and trends reads as no data | dashboard-ui/components/loki-learning-dashboard.js (metrics and trends load plus their two empty branches only), dashboard-ui/tests/loki-learning-dashboard-fetch-error.node.test.mjs (new) | LOW | node --test dashboard-ui/tests/loki-learning-dashboard-fetch-error.node.test.mjs passes: rejected metrics and trends render Could not load; an empty trends response still renders No trend data available | ready@2026-09-27T19:57Z | Source: 19:57Z cut. |
|
|
274
|
+
| S-190 | BACKLOG 112: R3 design doc describes project_total_usd as a plain sum | docs/R3-COST-OBSERVABILITY-DESIGN.md | LOW | grep -n 'sum of per-run proof costs' docs/R3-COST-OBSERVABILITY-DESIGN.md exits 1; grep -n project_total_partial docs/R3-COST-OBSERVABILITY-DESIGN.md prints at least one line | ready@2026-09-27T19:57Z | Source: 19:57Z cut. |
|
|
275
|
+
| S-191 | Velocity: test-review-assurance-tail.sh (116s) under 60s by running independent cases concurrently, budgets unchanged | tests/test-review-assurance-tail.sh | MEDIUM | time LOKI_TEST_SHARD=0/8 bash tests/test-review-assurance-tail.sh exits 0 with real under 60s and the same pass-count line as the pre-change capture; both timings reported | ready@2026-09-27T19:57Z | Source: 19:57Z cut. |
|
|
276
|
+
| S-192 | BACKLOG 112: no test drives the web-app WebSocket status push payload for unmeasured cost | web-app/tests/test_status_push_unmeasured.py (new), web-app/server.py (lift the nested status reader only if needed) | MEDIUM | python3 -m pytest -q web-app/tests/test_status_push_unmeasured.py passes: no tokens gives cost null and max_iterations null, priced tokens give a number; forcing 0.0 in a scratch copy fails case 1 | ready@2026-09-27T19:57Z | Source: 19:57Z cut. |
|
|
277
|
+
| S-193 | Velocity: v10-ops worktree-budget prints how many worktrees a batch may open before dispatch | scripts/v10-ops.sh (new worktree-budget subcommand), tests/test-v10-ops.sh | LOW | bash tests/test-v10-ops.sh exits 0; scripts/v10-ops.sh worktree-budget 15 prints 15 minus the .claude/worktrees entries in git worktree list --porcelain, and at or over the cap prints 0 and exits 1 | ready@2026-09-27T19:57Z | Source: 19:57Z cut. |
|