loki-mode 11.17.19 → 11.17.21

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.
Files changed (73) hide show
  1. package/SKILL.md +2 -2
  2. package/VERSION +1 -1
  3. package/autonomy/lib/functional-verify.py +141 -3
  4. package/autonomy/loki +2 -0
  5. package/dashboard/__init__.py +1 -1
  6. package/docs/CLI-REFERENCE.md +1 -1
  7. package/docs/INSTALLATION.md +1 -1
  8. package/docs/v10/BOARD.md +15 -15
  9. package/docs/v10/CLI-MODERN.md +1 -1
  10. package/docs/v10/FAILURE-CLASSES.md +7 -0
  11. package/docs/v10/PROGRESS.md +7 -0
  12. package/loki-ts/dist/loki.js +926 -922
  13. package/mcp/__init__.py +1 -1
  14. package/package.json +2 -2
  15. package/packages/control-plane/dist/server.js +393 -324
  16. package/plugins/loki-mode/.claude-plugin/plugin.json +1 -1
  17. package/web-app/dist/assets/{AdminPage-Dc62a8CS.js → AdminPage-DGg_5Yos.js} +1 -1
  18. package/web-app/dist/assets/{Avatar-3Z6DLFQZ.js → Avatar-BIDvM3U5.js} +1 -1
  19. package/web-app/dist/assets/{Badge-mkuAR2TD.js → Badge-AsUMPLOU.js} +1 -1
  20. package/web-app/dist/assets/{Button-EQyd4r_R.js → Button-DodbV8If.js} +1 -1
  21. package/web-app/dist/assets/{CockpitPage-BtlAhPdm.js → CockpitPage-BxL2zTsP.js} +1 -1
  22. package/web-app/dist/assets/{ComparePage-BbbQ5kC5.js → ComparePage-O1iC9fvU.js} +1 -1
  23. package/web-app/dist/assets/{ErrorBoundary-VIK-1yJA.js → ErrorBoundary-Cll1sP40.js} +1 -1
  24. package/web-app/dist/assets/{EvidenceReceiptPanel-B9EPySH2.js → EvidenceReceiptPanel-DXlOEyn9.js} +1 -1
  25. package/web-app/dist/assets/{GitHubIssuesPanel-DrxLIcV6.js → GitHubIssuesPanel-DbbqZGUy.js} +1 -1
  26. package/web-app/dist/assets/{GitHubPRsPanel-BNuKtoKu.js → GitHubPRsPanel-B6XhdcJp.js} +1 -1
  27. package/web-app/dist/assets/{HomePage-sZJBAvuK.js → HomePage-DenelbJm.js} +2 -2
  28. package/web-app/dist/assets/{LoginPage-BNe7doQt.js → LoginPage-MF65tKQb.js} +1 -1
  29. package/web-app/dist/assets/{MagicPage-Djh-aWoE.js → MagicPage-Caa_kRza.js} +1 -1
  30. package/web-app/dist/assets/{MetricsPage-B5RoFk1f.js → MetricsPage-BVSJe-I6.js} +1 -1
  31. package/web-app/dist/assets/{NotFoundPage-BiG9Qx-K.js → NotFoundPage-BPTMfi71.js} +1 -1
  32. package/web-app/dist/assets/{ProjectPage-rQZIHvO1.js → ProjectPage-BbnEno5f.js} +3 -3
  33. package/web-app/dist/assets/{ProjectsPage-Br37M7yx.js → ProjectsPage-CYL7Eh40.js} +1 -1
  34. package/web-app/dist/assets/{SettingsPage-DxEcGRRT.js → SettingsPage-D5rk0Q-i.js} +1 -1
  35. package/web-app/dist/assets/{ShowcasePage-BQ_cOsd8.js → ShowcasePage-Cgsx2N4V.js} +1 -1
  36. package/web-app/dist/assets/{SystemSettingsPage-CJuMeLfn.js → SystemSettingsPage-DKPw7kf7.js} +1 -1
  37. package/web-app/dist/assets/{TeamsPage-CxNvYxl0.js → TeamsPage-BOQyzfGG.js} +1 -1
  38. package/web-app/dist/assets/{TemplatesPage-CowBuPlo.js → TemplatesPage-C85kNfws.js} +1 -1
  39. package/web-app/dist/assets/{TerminalOutput-Bs0qzgnx.js → TerminalOutput-CaZ75acm.js} +1 -1
  40. package/web-app/dist/assets/{activity-BZBTb6gx.js → activity-_vZZ0q95.js} +1 -1
  41. package/web-app/dist/assets/{bell-DWQ-mGsX.js → bell-BepNateL.js} +1 -1
  42. package/web-app/dist/assets/{bot-Cp-aoJki.js → bot-CLPO5bfI.js} +1 -1
  43. package/web-app/dist/assets/{check-CyFL_qpg.js → check-Cw2ZY8Hd.js} +1 -1
  44. package/web-app/dist/assets/{chevron-left-CSpNuW_B.js → chevron-left-CNkV8_tB.js} +1 -1
  45. package/web-app/dist/assets/{circle-alert-BLXbl8kD.js → circle-alert-CBgwfRV4.js} +1 -1
  46. package/web-app/dist/assets/{clock-BBWu569k.js → clock-Kbd5g1Q4.js} +1 -1
  47. package/web-app/dist/assets/{cloud-Ce7Luvrn.js → cloud-BUHvBaGU.js} +1 -1
  48. package/web-app/dist/assets/{code-xml-C_ID1rox.js → code-xml-BFtb44h7.js} +1 -1
  49. package/web-app/dist/assets/{database-_ed-qaFL.js → database-BKTm6rSV.js} +1 -1
  50. package/web-app/dist/assets/{dollar-sign-CYnJuf7T.js → dollar-sign-CxSlnHdr.js} +1 -1
  51. package/web-app/dist/assets/{file-code-corner-jBR2MosN.js → file-code-corner-CzODg9ft.js} +1 -1
  52. package/web-app/dist/assets/{file-plus-DObnySLq.js → file-plus-DwR8w4_g.js} +1 -1
  53. package/web-app/dist/assets/{globe-CBYgMBCX.js → globe-BN26QQLG.js} +1 -1
  54. package/web-app/dist/assets/{hammer-Aopfj9DH.js → hammer-BMGuBFj7.js} +1 -1
  55. package/web-app/dist/assets/{index-Az6c4mLi.js → index-RYEDj5dp.js} +3 -3
  56. package/web-app/dist/assets/{layers-RU1n4mJF.js → layers-Bih4Qqbx.js} +1 -1
  57. package/web-app/dist/assets/{loader-circle-vkUFjVTs.js → loader-circle-DTh3fBtD.js} +1 -1
  58. package/web-app/dist/assets/{lock-DX7cm7nZ.js → lock-B77al7oQ.js} +1 -1
  59. package/web-app/dist/assets/{package-rQet8lbL.js → package-BMcYmquO.js} +1 -1
  60. package/web-app/dist/assets/{plus-B6lq3pKQ.js → plus-D40JVGe8.js} +1 -1
  61. package/web-app/dist/assets/{refresh-cw-C5pY6vxn.js → refresh-cw-BzmtMb8b.js} +1 -1
  62. package/web-app/dist/assets/{rotate-ccw-B_66hj0H.js → rotate-ccw-B0-EyBz6.js} +1 -1
  63. package/web-app/dist/assets/{scroll-text-DoY2VPSX.js → scroll-text-BQNWKEf4.js} +1 -1
  64. package/web-app/dist/assets/{server-Cur2b1Py.js → server-DrTKOH08.js} +1 -1
  65. package/web-app/dist/assets/{shield-alert-ZxlmrPzT.js → shield-alert-bacDs6zS.js} +1 -1
  66. package/web-app/dist/assets/{thumbs-up-CO6PAF2d.js → thumbs-up-CKbEwA0r.js} +1 -1
  67. package/web-app/dist/assets/{trash-2-KkO1Q-C7.js → trash-2-BeWrrpHd.js} +1 -1
  68. package/web-app/dist/assets/{trending-down-eak_OVU-.js → trending-down-UfhUQ_MW.js} +1 -1
  69. package/web-app/dist/assets/{trending-up-X0avjdBr.js → trending-up-CLkxjmYM.js} +1 -1
  70. package/web-app/dist/assets/{upload-CMNuZ7nb.js → upload-DdaprL3w.js} +1 -1
  71. package/web-app/dist/assets/{usePolling-BOF9VJY_.js → usePolling-Btjcs4pC.js} +1 -1
  72. package/web-app/dist/assets/{user-CemBNbFR.js → user-DhyL9aMl.js} +1 -1
  73. package/web-app/dist/index.html +1 -1
package/SKILL.md CHANGED
@@ -3,7 +3,7 @@ name: loki-mode
3
3
  description: An autonomous software factory that knows what it is supposed to deliver, and proves it did. Use when the user says Loki Mode or asks to build, fix or verify software autonomously.
4
4
  ---
5
5
 
6
- # Loki Mode v11.17.19
6
+ # Loki Mode v11.17.21
7
7
 
8
8
  **Current entry points (Loki 10 engine):** `loki "<task>"`, `loki owner/repo#N` and `loki quick "<task>"` run the Loki 10 engine and end with a signed receipt (`loki verify`). `loki backlog owner/repo --all` runs many issues in parallel. Guide: `docs/v10/GUIDE.md`. The skill instructions below, and `loki start`, describe the previous bash loop. PRD-file starts (`loki start ./prd.md`) and the opencode provider still run on it until FC38-SWEEP ports them; the legacy-engine command and the LOKI_ENGINE switch remain removed. Prefer `loki owner/repo#N` for issues.
9
9
 
@@ -483,4 +483,4 @@ See `CHANGELOG.md` entries [7.5.7], [7.5.8], [7.5.13] for the per-fix list and r
483
483
 
484
484
  ---
485
485
 
486
- **v11.17.19 | [Autonomi](https://www.autonomi.dev/) flagship product | core skill**
486
+ **v11.17.21 | [Autonomi](https://www.autonomi.dev/) flagship product | core skill**
package/VERSION CHANGED
@@ -1 +1 @@
1
- 11.17.19
1
+ 11.17.21
@@ -27,6 +27,7 @@ import json
27
27
  import re
28
28
  import sys
29
29
  import urllib.error
30
+ import urllib.parse
30
31
  import urllib.request
31
32
 
32
33
 
@@ -66,6 +67,80 @@ def derive_endpoint_assertions(spec_text: str) -> list[dict]:
66
67
  return out
67
68
 
68
69
 
70
+ # Wording that marks an endpoint as protected. Matched on the endpoint's own line
71
+ # or on the nearest enclosing markdown heading (its section).
72
+ _PROTECTED_RE = re.compile(
73
+ r'\b(requires?\s+(auth\w*|login|a\s+login|credentials|a\s+(bearer\s+|valid\s+)?token)'
74
+ r'|(must|needs?\s+to)\s+be\s+(logged[ -]in|authenticated)'
75
+ r'|login\s+required|auth(entication)?\s+required'
76
+ r'|authenticated(\s+users?)?(\s+only)?|admin[ -]only|admins?\s+only'
77
+ r'|protected\s+(endpoint|route|resource|api|path|page)s?|is\s+protected'
78
+ r'|(without|no|missing)\s+(\w+\s+)?(auth\w*|credentials|token)\b(?:(?!\b(?:never|not)\b)[^.;,])*?\b40[13])\b',
79
+ re.IGNORECASE)
80
+ _NEGATION_WORDS = {"no", "not", "never", "without",
81
+ "isn't", "doesn't", "don't", "cannot", "can't",
82
+ "aren't", "won't", "shouldn't", "needn't", "wasn't"}
83
+ _NEGATION_AUX = {"does", "do", "is", "are", "need", "needs", "would", "will",
84
+ "should", "must", "longer", "even", "actually", "really",
85
+ "necessarily", "always", "ever", "also", "currently",
86
+ "a", "an", "the"}
87
+
88
+
89
+ def _is_negated(words: list[str]) -> bool:
90
+ """True when a negator sits right before a protected match, with at most two
91
+ intervening auxiliary or adverb words ("no longer", "does not even"). Any
92
+ other intervening word (e.g. "public") blocks it, so "not public requires
93
+ auth" stays protected. A negator that is itself preceded by not/no/never
94
+ does not count."""
95
+ for back in (1, 2, 3):
96
+ if len(words) < back:
97
+ return False
98
+ i = len(words) - back
99
+ if words[i] in _NEGATION_WORDS:
100
+ if i > 0 and words[i - 1] in ("not", "no", "never"):
101
+ return False
102
+ return True
103
+ if words[i] not in _NEGATION_AUX:
104
+ return False
105
+ return False
106
+
107
+
108
+ def _is_protected_text(text: str) -> bool:
109
+ """True when a protected-wording match is not directly negated. Negation
110
+ cancels only the match it modifies, inside the same clause (no ; , . : between;
111
+ and/but need no split because they are not aux words, so _is_negated's window
112
+ already stops at them). Words like "public" are not negators: "not public" means protected."""
113
+ for m in _PROTECTED_RE.finditer(text or ""):
114
+ clause = re.split(r'[;,.:]', text[:m.start()])[-1]
115
+ clause = clause.replace("\u2018", "'").replace("\u2019", "'")
116
+ if not _is_negated(re.findall(r"[\w']+", clause.lower())):
117
+ return True
118
+ return False
119
+
120
+
121
+ def derive_auth_assertions(spec_text: str) -> list[dict]:
122
+ """Endpoints the spec marks protected (same line or enclosing heading).
123
+ Returns [{method, path}], deduped, order-preserved."""
124
+ seen = set()
125
+ out = []
126
+ heading = ""
127
+ for line in (spec_text or "").splitlines():
128
+ if re.match(r'\s*#{1,6}\s', line):
129
+ heading = line
130
+ eps = list(_ENDPOINT_RE.finditer(line))
131
+ if not eps:
132
+ continue
133
+ if not (_is_protected_text(line) or _is_protected_text(heading)):
134
+ continue
135
+ for m in eps:
136
+ key = (m.group(1).upper(), _clean_path(m.group(2)))
137
+ if key in seen:
138
+ continue
139
+ seen.add(key)
140
+ out.append({"method": key[0], "path": key[1]})
141
+ return out
142
+
143
+
69
144
  # --- run assertions against the live app ------------------------------------
70
145
 
71
146
  def _req(base_url: str, method: str, path: str, body=None, timeout=8):
@@ -197,6 +272,68 @@ def verify_crud_lifecycle(base_url: str, assertions: list[dict]) -> list[dict]:
197
272
  return results
198
273
 
199
274
 
275
+ class _NoRedirect(urllib.request.HTTPRedirectHandler):
276
+ def redirect_request(self, *a, **k):
277
+ return None
278
+
279
+
280
+ def _probe_unauth(base_url: str, method: str, path: str, timeout=8):
281
+ """One credential-free call, redirects not followed.
282
+ Returns (status, body_nonempty, location_or_error)."""
283
+ probe = re.sub(r'(:[A-Za-z_]\w*|\{[^}]*\})', 'loki-auth-probe', path)
284
+ url = base_url.rstrip("/") + probe
285
+ data = b"{}" if method in ("POST", "PUT", "PATCH") else None
286
+ headers = {"Content-Type": "application/json"} if data else {}
287
+ req = urllib.request.Request(url, data=data, method=method, headers=headers)
288
+ opener = urllib.request.build_opener(_NoRedirect)
289
+ try:
290
+ with opener.open(req, timeout=timeout) as resp:
291
+ return resp.status, bool(resp.read().strip()), ""
292
+ except urllib.error.HTTPError as e:
293
+ return e.code, False, e.headers.get("Location", "") or ""
294
+ except (urllib.error.URLError, OSError) as e:
295
+ return None, False, str(e)
296
+
297
+
298
+ def _is_login_redirect(location: str, probe_path: str, base_url: str = "") -> bool:
299
+ """True when Location points at a login page: the auth segment is the LAST
300
+ path segment (optional extension, optional trailing slash). A redirect to
301
+ the request path (base_url path prefix included) differing only by a trailing
302
+ slash, case-insensitively, is a canonical-slash redirect, never a login page."""
303
+ probe = re.sub(r'(:[A-Za-z_]\w*|\{[^}]*\})', 'loki-auth-probe', probe_path)
304
+ req_url = base_url.rstrip("/") + probe
305
+ req_path = urllib.parse.urlsplit(req_url).path
306
+ # Resolve relative Location values (auth/, ./auth/, ../api/auth/) against the request URL.
307
+ loc_path = urllib.parse.urlsplit(urllib.parse.urljoin(req_url, location)).path
308
+ if loc_path.rstrip("/").lower() == req_path.rstrip("/").lower():
309
+ return False
310
+ return bool(re.search(
311
+ r'(^|/)(login|signin|sign-in|auth|oauth)(?:\.(?:html?|php|aspx?|jsp))?/?$',
312
+ loc_path, re.IGNORECASE))
313
+
314
+
315
+ def verify_auth_behaviors(base_url: str, auth_assertions: list[dict]) -> list[dict]:
316
+ """Probe each spec-protected endpoint unauthenticated.
317
+ 401/403 -> passed; 2xx served -> failed; anything else -> inconclusive."""
318
+ results = []
319
+ for a in auth_assertions:
320
+ method, path = a["method"], a["path"]
321
+ name = f"auth: {method} {path} rejects unauthenticated requests"
322
+ code, has_body, extra = _probe_unauth(base_url, method, path)
323
+ if code in (401, 403):
324
+ st, detail = "passed", f"HTTP {code} without credentials"
325
+ elif code is not None and 200 <= code < 300 and (has_body or method != "GET"):
326
+ st, detail = "failed", f"served without credentials (HTTP {code})"
327
+ elif code is not None and 300 <= code < 400 and _is_login_redirect(extra, path, base_url):
328
+ st, detail = "passed", f"HTTP {code} redirect to {extra}"
329
+ elif code is None:
330
+ st, detail = "inconclusive", f"unreachable: {extra}"
331
+ else:
332
+ st, detail = "inconclusive", f"HTTP {code}; cannot tell if protected"
333
+ results.append({"behavior": name, "status": st, "detail": detail})
334
+ return results
335
+
336
+
200
337
  def summarize(results: list[dict]) -> dict:
201
338
  passed = sum(1 for r in results if r["status"] == "passed")
202
339
  failed = sum(1 for r in results if r["status"] == "failed")
@@ -217,14 +354,15 @@ def summarize(results: list[dict]) -> dict:
217
354
 
218
355
  def run(spec_text: str, base_url: str) -> dict:
219
356
  assertions = derive_endpoint_assertions(spec_text)
357
+ auth = verify_auth_behaviors(base_url, derive_auth_assertions(spec_text))
220
358
  if not assertions:
221
359
  return {"spec_behaviors": [], "summary": {"passed": 0, "failed": 0,
222
360
  "inconclusive": 0, "functional_status": "inconclusive"},
223
- "note": "no HTTP endpoint behaviors derivable from the spec"}
361
+ "auth_behaviors": [], "note": "no HTTP endpoint behaviors derivable from the spec"}
224
362
  results = verify_crud_lifecycle(base_url, assertions)
225
- summ = summarize(results)
363
+ summ = summarize(results + auth)
226
364
  return {"assertions_derived": assertions, "spec_behaviors": results,
227
- "summary": summ, "functional_status": summ["functional_status"]}
365
+ "auth_behaviors": auth, "summary": summ, "functional_status": summ["functional_status"]}
228
366
 
229
367
 
230
368
  def main(argv):
package/autonomy/loki CHANGED
@@ -37563,6 +37563,8 @@ cmd_proof() {
37563
37563
  echo " md <id> Paste-able Markdown for a PR comment or Slack"
37564
37564
  echo " open <id> Open .loki/proofs/<id>/index.html in a browser"
37565
37565
  echo " share <id> Publish the proof page as a GitHub Gist (opt-in)"
37566
+ echo " bundle <run-id> Write a portable receipt bundle for offline verification"
37567
+ echo " [--out <dir>] (default ./loki-bundle-<run-id>; Bun route)"
37566
37568
  echo ""
37567
37569
  echo "Options for 'share':"
37568
37570
  echo " --yes Skip the redaction-preview confirmation prompt"
@@ -7,6 +7,6 @@ Modules:
7
7
  control: Session control helpers (status, atomic writes, origin check)
8
8
  """
9
9
 
10
- __version__ = "11.17.19"
10
+ __version__ = "11.17.21"
11
11
 
12
12
  __all__ = ["__version__"]
@@ -1,6 +1,6 @@
1
1
  # CLI reference
2
2
 
3
- Generated from `loki-ts/src/cli/registry.ts` by `scripts/generate-stale-zero.sh` for v11.17.19. Do not edit by hand.
3
+ Generated from `loki-ts/src/cli/registry.ts` by `scripts/generate-stale-zero.sh` for v11.17.21. Do not edit by hand.
4
4
  Hidden and legacy-only commands are omitted; see `docs/v10/CLI-MODERN.md` for the full inventory.
5
5
 
6
6
  | Command | Description |
@@ -2,7 +2,7 @@
2
2
 
3
3
  Loki Mode, by [Autonomi](https://www.autonomi.dev/), turns a spec or an issue into a verified pull request with a receipt you can check. This page covers installing it, a first run, and the options around it.
4
4
 
5
- **Version:** v11.17.19
5
+ **Version:** v11.17.21
6
6
 
7
7
  **Engine note:** `loki start` is the primary command. `loki start`, `loki "<task>"`, `loki owner/repo#N` and `loki quick` all run the Loki 10 engine, whatever the flag order or input form (PRD file, issue ref, task or one-word brief). The previous loop runs only on `--engine legacy`, `LOKI_ENGINE=legacy`, or for one call when a flag Loki 10 cannot honor is present. See the [user guide](v10/GUIDE.md) and the [5-minute quickstart](QUICKSTART.md).
8
8
 
package/docs/v10/BOARD.md CHANGED
@@ -1005,9 +1005,9 @@ Source: ~/git/autonomi-dev/research/2026-09-30-adoption/SWARM-PROMPT-ADOPTION.md
1005
1005
  | FC-22 | FC-22: (a) impacted-test selection is scoped by the Project Model, touched packages plus their real dependents (manifest or import edges), never every package; (b) a selected package with no installed deps gets the Project Model's own install command run once before verify, recorded as a check with its cwd, opt-out by config | loki-ts/src/e10ext/select.ts, project_model resolve and gather, engine10 verify pre-step, plus tests | HIGH | a backend-only change in the monorepo-fc01 fixture selects no frontend test; a selected package without node_modules gets one recorded install check; no guessed command; e10ext under 1500 | released@2026-10-16T00:49Z | Plan docs/v10/FC21B-FC22-PLAN.md (S1 then S2 selection and S3 install). FireLater#17 gate on 10.10.5 (run e10-20261003T233414Z-30ca) PARTIAL only from 4 over-selected frontend tests (steering 23:47Z). HIGH because selection feeds verify proof. Architect plan first; e10ext is 1 line under its cap. Next train with FC-21b and FC-23. | 00:33Z: S1 merged 88e9e43fb (review-s1 APPROVE). S2 e9e04fe1d in opus review-s2; S3 cb6486550 in opus review-s3. 01:08Z: S3 merged 736f4d436 (review-s3 APPROVE on d2e61c2ff, 3627/0, tsc 0; discard.ts L2 tension to CTO). S2 merged b4022e6fb (review-s2 APPROVE on a62aba7b2, 3624/0, tsc 0) behind LOKI_E10_SCOPE default off. Before the flag flips: F1 root-owned keep test with a non-relative import, F2 verify test.scoped_out event test. The install library is wired by S4.
1006
1006
  | FC-23 | FC-23: the Wall writes tests matching the package's module system and test conventions from the Project Model; a lint or type error inside a Wall file is harness-owned, the Wall file is regenerated once or discarded with a NOT PROVEN note, and no fix round is spent on it | loki-ts/src/engine10/stages/wall.ts, the fix-round target filter, project_model conventions, plus tests | MEDIUM | a CommonJS package gets a Wall test with no import.meta; a forced type error in a Wall file yields regenerate-or-discard and zero fix rounds | released@2026-10-04T00:51Z | released@2026-10-04T00:51Z | Merged c0a1c43c2 (38c782386, review-fc23 sonnet APPROVE; nits: duplicate NOT PROVEN line for a discarded file, merged comment in verify.ts).
1007
1007
  | TEN-DEPLOY-01 | Capture the deployed public URL on every --execute path and probe it by default | autonomy/loki (_deploy_try_execute non-canary exec block and the _deploy_record arg list and JSON fields only), tests/test-deploy-receipt-gate.sh (new section after the existing 14-18 block), CHANGELOG.md | MEDIUM | see Wall in note | released@2026-10-17T02:57Z | merge 60a9bb709; TL APPROVE b14d908a4 (deploy-receipt-gate 56/0, test-deploy 6/6, shellcheck 91=91 vs main). wave 1; depends: none. Goal: After a deploy that exits 0, take the last https URL the provider CLI printed (the canary grep -Eo already does this; reuse that, do not add a second parser). Store it as deployed_url in loki.deploy/1. When no --health-url is given, probe deployed_url with _deploy_probe_health and record health_url_source=captured/flag. No URL printed: deployed_url is empty, health stays 'unchecked', and Loki never invents a URL. Print 'Live at: <url>' only when one was captured. Wall: RED: a new section stubs vercel to print 'https://app-x.vercel.app' and exit 0, and stubs curl to 200. The record lacks deployed_url, health_status is 'unchecked', and the test fails on main. GREEN: deployed_url equals the stub URL, health_status=healthy, health_url_source=captured. A second stub prints no URL: deployed_url is empty, health is 'unchecked', exit 0. A third case passes --health-url: health_url_source=flag. MUTATION: hardcode deployed_url to a constant and the no-URL case goes red. Gate: bash -n autonomy/loki && shellcheck -S warning autonomy/loki && bash tests/test-deploy-receipt-gate.sh && bash tests/test-deploy.sh Rules: FAILURE-CLASSES row first for any bug fix (D86); no CHANGELOG edits (Release Manager writes notes); DECISIONS numbers assigned by the Chief of Staff; reuse util/secure_scan.ts, the shared badge helper, keys_cmd export and the TS claude login probe instead of new copies; new CLI flags update autonomy/completions and the help-drift guard. v11.17.13 npm next 11.17.13 |
1008
- | TEN-DEPLOY-02 | Signed live provenance doc (loki.provenance/1) and loki verify --url | loki-ts/src/util/receipt_signer.ts, loki-ts/tests/engine10/verify_cmd.test.ts (provenance cases; existing deploy-record tests live here), docs/SIGNED-RECEIPTS.md (one section), CHANGELOG.md. Engine10 core is not edited: verify_cmd.ts:164 already routes through deployAttestCmd, and a one-token --url passthrough there needs the budget test to stay green. | HIGH | see Wall in note | ready@2026-10-17T01:40Z | SPLIT per CTO critic into (a) signProvenance plus --sign-provenance, (b) verify --url fetch and verdicts; build as two commits or two agents. wave 2; depends: none. Goal: Extend receipt_signer.ts, the owner of signed deploy attestations, with: signProvenance(head_sha, tree_sha, receipt_sha256, run_id, built_at), which signs with the same Ed25519 key as signDeployRecord; a `--sign-provenance FILE` dispatch in deployAttestCmd; and `loki verify --url https://host` plus a pubkey. The --url check fetches <url>/.well-known/loki-provenance.json with a timeout and size cap, checks the signature, and requires a 200 with JSON. The verdict is VERIFIED only when the signature verifies against the local JWKS or --pubkey AND the cited receipt (when present locally or via --receipt) is VERIFIED. The doc alone with an unknown kid is UNCHECKED rc 2. An edited doc is TAMPERED rc 1. A fetch failure is UNCHECKED and never VERIFIED. Optional --expect-sha SHA must equal head_sha. Wall: RED: tests serve a signed provenance doc from Bun.serve on 127.0.0.1. On main, `verify --url` is an unknown arg and exits 2, so the tests fail. GREEN: genuine doc with --pubkey gives VERIFIED rc 0. One edited byte of head_sha gives TAMPERED rc 1. An unknown kid gives UNCHECKED rc 2. A 404, a non-JSON body or a doc over 64KB gives UNCHECKED rc 2. A wrong --expect-sha gives TAMPERED rc 1. MUTATION: skip the signature verify and the edited-byte case goes red. Gate: cd loki-ts && bun test tests/engine10/verify_cmd.test.ts && bun test tests/engine10/ && bunx tsc --noEmit (the full engine10 suite runs the budget and spawn-env guards) Rules: FAILURE-CLASSES row first for any bug fix (D86); no CHANGELOG edits (Release Manager writes notes); DECISIONS numbers assigned by the Chief of Staff; reuse util/secure_scan.ts, the shared badge helper, keys_cmd export and the TS claude login probe instead of new copies; new CLI flags update autonomy/completions and the help-drift guard. |
1008
+ | TEN-DEPLOY-02 | Signed live provenance doc (loki.provenance/1) and loki verify --url | loki-ts/src/util/receipt_signer.ts, loki-ts/tests/engine10/verify_cmd.test.ts (provenance cases; existing deploy-record tests live here), docs/SIGNED-RECEIPTS.md (one section), CHANGELOG.md. Engine10 core is not edited: verify_cmd.ts:164 already routes through deployAttestCmd, and a one-token --url passthrough there needs the budget test to stay green. | HIGH | see Wall in note | building@2026-10-17T04:38Z | SPLIT per CTO critic into (a) signProvenance plus --sign-provenance, (b) verify --url fetch and verdicts; build as two commits or two agents. wave 2; depends: none. Goal: Extend receipt_signer.ts, the owner of signed deploy attestations, with: signProvenance(head_sha, tree_sha, receipt_sha256, run_id, built_at), which signs with the same Ed25519 key as signDeployRecord; a `--sign-provenance FILE` dispatch in deployAttestCmd; and `loki verify --url https://host` plus a pubkey. The --url check fetches <url>/.well-known/loki-provenance.json with a timeout and size cap, checks the signature, and requires a 200 with JSON. The verdict is VERIFIED only when the signature verifies against the local JWKS or --pubkey AND the cited receipt (when present locally or via --receipt) is VERIFIED. The doc alone with an unknown kid is UNCHECKED rc 2. An edited doc is TAMPERED rc 1. A fetch failure is UNCHECKED and never VERIFIED. Optional --expect-sha SHA must equal head_sha. Wall: RED: tests serve a signed provenance doc from Bun.serve on 127.0.0.1. On main, `verify --url` is an unknown arg and exits 2, so the tests fail. GREEN: genuine doc with --pubkey gives VERIFIED rc 0. One edited byte of head_sha gives TAMPERED rc 1. An unknown kid gives UNCHECKED rc 2. A 404, a non-JSON body or a doc over 64KB gives UNCHECKED rc 2. A wrong --expect-sha gives TAMPERED rc 1. MUTATION: skip the signature verify and the edited-byte case goes red. Gate: cd loki-ts && bun test tests/engine10/verify_cmd.test.ts && bun test tests/engine10/ && bunx tsc --noEmit (the full engine10 suite runs the budget and spawn-env guards) Rules: FAILURE-CLASSES row first for any bug fix (D86); no CHANGELOG edits (Release Manager writes notes); DECISIONS numbers assigned by the Chief of Staff; reuse util/secure_scan.ts, the shared badge helper, keys_cmd export and the TS claude login probe instead of new copies; new CLI flags update autonomy/completions and the help-drift guard. |
1009
1009
  | TEN-DEPLOY-03 | Ship the provenance doc with the build and prove the live URL serves the verified SHA | autonomy/loki (_deploy_try_execute pre-exec and post-health blocks, _deploy_record live_binding field only), tests/test-deploy-receipt-gate.sh (new section), docs/WORKSPACES.md, CHANGELOG.md | HIGH | see Wall in note | ready@2026-10-17T01:40Z | SPLIT per CTO critic into (a) provenance file into deploy root per project type, (b) post-deploy live-binding probe; build as two commits or two agents. wave 3; depends: TEN-DEPLOY-01, TEN-DEPLOY-02. Goal: In _deploy_try_execute, after the gate passes and before the provider runs, write a signed .well-known/loki-provenance.json into the deploy root via `verify --sign-provenance`. The deploy root is public/ for nextjs and vite, the detected dist/ or build/ for static, and is refused with a reason for docker/python where no static root exists. Write it as an untracked build artifact so the dirty-tree gate is evaluated before it. After the deploy, probe <deployed_url>/.well-known/loki-provenance.json. Set live_binding=VERIFIED only when its head_sha equals the anchor. A mismatch gives FAILED_HEALTH exit 4 (stale or wrong build served). Update docs/WORKSPACES.md and replace 'deployed-SHA binding is not implemented' with what is now bound and what is not. Wall: RED: a stubbed vercel copies dist/ into a served dir and a python http.server serves it. On main, no provenance file exists and the record has no live_binding. GREEN: the file exists in dist/.well-known, live_binding=VERIFIED, and its head_sha equals git rev-parse HEAD. A stub that serves an older provenance gives FAILED_HEALTH exit 4. A docker project prints the refusal reason and records live_binding=unsupported, never VERIFIED. The dirty-tree gate still refuses a dirty tree before the file is written. MUTATION: compare against a constant instead of the anchor and the stale-serve case goes red. Gate: bash -n autonomy/loki && shellcheck -S warning autonomy/loki && bash tests/test-deploy-receipt-gate.sh && (cd loki-ts && bun test tests/engine10/verify_cmd.test.ts) Rules: FAILURE-CLASSES row first for any bug fix (D86); no CHANGELOG edits (Release Manager writes notes); DECISIONS numbers assigned by the Chief of Staff; reuse util/secure_scan.ts, the shared badge helper, keys_cmd export and the TS claude login probe instead of new copies; new CLI flags update autonomy/completions and the help-drift guard. |
1010
- | TEN-DEPLOY-04 | Verified deploy badge from loki status --badge | loki-ts/src/commands/status.ts (renderLastDeploy plus --badge flag parse only), loki-ts/tests/commands/status.test.ts, CHANGELOG.md | MEDIUM | see Wall in note | ready@2026-10-17T01:40Z | wave 4; depends: TEN-DEPLOY-01 (deployed_url field); live_binding from TEN-DEPLOY-03 is read if present, and its absence omits the badge. Goal: `loki status --badge` reads the newest loki.deploy/1 record (renderLastDeploy already loads it) and verifies it through the existing verify path. It prints a markdown shields badge linking to <deployed_url>/.well-known/loki-provenance.json. The message is 'deployed: verified' (brightgreen) ONLY when the record verifies and live_binding=VERIFIED. 'deployed: unverified' (red) is printed for TAMPERED or a failed health check. In all other cases the badge is omitted with a one-line reason. It never prints green from an unchecked field. The color mapping matches the share badge (autonomy/loki:38291), and no new vocabulary is added. Wall: RED: status.test.ts fixture with a signed healthy record, live_binding=VERIFIED and deployed_url. On main, --badge is unknown and no badge line is printed. GREEN: the badge line contains 'brightgreen' and deployed_url. A record with health FAILED_HEALTH gives a red badge. An unsigned record or a missing live_binding omits the badge and prints the reason. A record with no deployed_url omits the badge. MUTATION: drop the verify call and the unsigned case goes green, so the test goes red. Gate: cd loki-ts && bun test tests/commands/status.test.ts && bunx tsc --noEmit && bash tests/test-status-surface-agrees.sh Rules: FAILURE-CLASSES row first for any bug fix (D86); no CHANGELOG edits (Release Manager writes notes); DECISIONS numbers assigned by the Chief of Staff; reuse util/secure_scan.ts, the shared badge helper, keys_cmd export and the TS claude login probe instead of new copies; new CLI flags update autonomy/completions and the help-drift guard. |
1010
+ | TEN-DEPLOY-04 | Verified deploy badge from loki status --badge | loki-ts/src/commands/status.ts (renderLastDeploy plus --badge flag parse only), loki-ts/tests/commands/status.test.ts, CHANGELOG.md | MEDIUM | see Wall in note | building@2026-10-17T04:38Z | wave 4; depends: TEN-DEPLOY-01 (deployed_url field); live_binding from TEN-DEPLOY-03 is read if present, and its absence omits the badge. Goal: `loki status --badge` reads the newest loki.deploy/1 record (renderLastDeploy already loads it) and verifies it through the existing verify path. It prints a markdown shields badge linking to <deployed_url>/.well-known/loki-provenance.json. The message is 'deployed: verified' (brightgreen) ONLY when the record verifies and live_binding=VERIFIED. 'deployed: unverified' (red) is printed for TAMPERED or a failed health check. In all other cases the badge is omitted with a one-line reason. It never prints green from an unchecked field. The color mapping matches the share badge (autonomy/loki:38291), and no new vocabulary is added. Wall: RED: status.test.ts fixture with a signed healthy record, live_binding=VERIFIED and deployed_url. On main, --badge is unknown and no badge line is printed. GREEN: the badge line contains 'brightgreen' and deployed_url. A record with health FAILED_HEALTH gives a red badge. An unsigned record or a missing live_binding omits the badge and prints the reason. A record with no deployed_url omits the badge. MUTATION: drop the verify call and the unsigned case goes green, so the test goes red. Gate: cd loki-ts && bun test tests/commands/status.test.ts && bunx tsc --noEmit && bash tests/test-status-surface-agrees.sh Rules: FAILURE-CLASSES row first for any bug fix (D86); no CHANGELOG edits (Release Manager writes notes); DECISIONS numbers assigned by the Chief of Staff; reuse util/secure_scan.ts, the shared badge helper, keys_cmd export and the TS claude login probe instead of new copies; new CLI flags update autonomy/completions and the help-drift guard. |
1011
1011
  | TEN-DEPLOY-05 | loki deploy --env-file: push env to the provider with names-only records | autonomy/loki (cmd_deploy arg parse for --env-file, _deploy_try_execute env step, _deploy_record env_keys field only), tests/test-deploy-receipt-gate.sh (new section), autonomy/completions (loki deploy flag list only), CHANGELOG.md | HIGH | see Wall in note | ready@2026-10-17T01:40Z | SPLIT per CTO critic into (a) env-file parser, .env.example check, masking, env_keys record, (b) four provider verbs; build as two commits or two agents. wave 4; depends: TEN-DEPLOY-03 (same function, serialized to avoid conflicts). Goal: `--env-file FILE` (with --execute only) parses KEY=VALUE with no shell eval. It refuses when a key in .env.example is missing from FILE, naming the keys. Env is applied through documented verbs only: Vercel `vercel --prod -e K=V` per key (args built as an array, never through the shell); Fly `fly secrets set --stage K=V ...` before `fly deploy`; Netlify `netlify env:import FILE`; Cloudflare `wrangler secret bulk FILE`. An unsupported provider refuses with nothing run. The record stores env_keys (names, sorted) and env_source; it NEVER stores values. Values never appear in stdout, the record or the printed 'Running:' line, where they are masked as K=***. Wall: RED: a recording vercel stub logs argv. On main, --env-file is ignored and no -e args appear. GREEN: argv has `-e API_URL=x -e TOKEN=s3cr3t`. Grepping stdout, stderr and the record for s3cr3t finds nothing; env_keys=[API_URL,TOKEN]. When .env.example lists DB_URL and the env file lacks it, the command refuses with rc 1, no stub calls and DB_URL named. A value with $(touch pwned) leaves no file named pwned. MUTATION: write values into the record and the secret-grep goes red. Gate: bash -n autonomy/loki && shellcheck -S warning autonomy/loki && bash tests/test-deploy-receipt-gate.sh && bash tests/test-completion-drift.sh (or whichever completion drift test the CHANGELOG cites) Rules: FAILURE-CLASSES row first for any bug fix (D86); no CHANGELOG edits (Release Manager writes notes); DECISIONS numbers assigned by the Chief of Staff; reuse util/secure_scan.ts, the shared badge helper, keys_cmd export and the TS claude login probe instead of new copies; new CLI flags update autonomy/completions and the help-drift guard. |
1012
1012
  | TEN-DEPLOY-06 | loki deploy --domain: attach a custom domain and prove TLS | autonomy/loki (cmd_deploy --domain parse and a post-health domain block in _deploy_try_execute, _deploy_record domain/tls fields only), tests/test-deploy-receipt-gate.sh (new section), CHANGELOG.md | MEDIUM | see Wall in note | ready@2026-10-17T01:40Z | wave 5; depends: TEN-DEPLOY-05 (same function, serialized). Goal: `--domain example.com` (with --execute) runs documented verbs after a healthy deploy: Vercel `vercel alias set <deployed_url> <domain>`; Fly `fly certs add <domain>`. Netlify and Cloudflare print the manual dashboard step and set domain_status=manual. Then a TLS proof runs: `openssl s_client -servername <domain> -connect <domain>:443` plus `openssl x509 -noout -enddate -checkend 604800`. It records domain, tls_status (valid/expiring/invalid/unchecked) and tls_not_after, and re-probes https://<domain>/.well-known/loki-provenance.json for the same head_sha. DNS not yet pointed gives tls_status=invalid and exit 6, with the DNS record the provider needs printed. It never claims valid without the openssl check. Wall: RED: vercel, openssl and curl are stubbed. On main, --domain is ignored. GREEN: the alias set argv is recorded, tls_status=valid and tls_not_after is set. An openssl stub that fails -checkend gives expiring. An openssl handshake failure gives invalid and exit 6. A netlify project gives domain_status=manual, no alias call, and tls still checked. No openssl on PATH gives unchecked, never valid. MUTATION: default tls_status to valid and the missing-openssl case goes red. Gate: bash -n autonomy/loki && shellcheck -S warning autonomy/loki && bash tests/test-deploy-receipt-gate.sh Rules: FAILURE-CLASSES row first for any bug fix (D86); no CHANGELOG edits (Release Manager writes notes); DECISIONS numbers assigned by the Chief of Staff; reuse util/secure_scan.ts, the shared badge helper, keys_cmd export and the TS claude login probe instead of new copies; new CLI flags update autonomy/completions and the help-drift guard. |
1013
1013
  | TEN-DEPLOY-07 | loki github publish: receipt-stamped GitHub export from the CLI | autonomy/loki (cmd_github publish arm and its help line only), tests/test-github-publish.sh (new: no existing test owns cmd_github repo creation; test-proven-pr-check.sh covers PR checks only) plus its run-all-tests.sh registration and shard row, CHANGELOG.md | MEDIUM | see Wall in note | released@2026-10-17T03:50Z | merged efa201ffd (TL APPROVE 81346df2a) Shipped in npm 11.17.15 (latest+next) or 11.17.16 (Release run success on e3d445460). |
@@ -1029,27 +1029,27 @@ Source: ~/git/autonomi-dev/research/2026-09-30-adoption/SWARM-PROMPT-ADOPTION.md
1029
1029
  | TEN-COST-06 | xreview claude judge: lean flags and child-ledger line | loki-ts/src/engine10/stages/xreview.ts, loki-ts/tests/engine10/xreview.test.ts | MEDIUM | see Wall in note | released@2026-10-17T03:50Z | TL APPROVE 2e40a4be8, merged for v11.17.14 Shipped in npm 11.17.15 (latest+next) or 11.17.16 (Release run success on e3d445460). |
1030
1030
  | TEN-COST-07 | Project-model discovery on the fast tier, retry on the run model | loki-ts/src/project_model/discover.ts, loki-ts/tests/project_model/project_model.test.ts | MEDIUM | see Wall in note | released@2026-10-17T03:50Z | TL APPROVE e01e37c5e. wave 1; depends: none. Goal: Discovery attempt 1 runs on fastTierModel(env) (runner/model_downgrades.ts:8). It is sonnet unless LOKI_ALLOW_HAIKU, so it never drops below sonnet without opt-in, and it is never weaker than an explicit LOKI_MODEL_OVERRIDE. The existing validation-error retry (attempt 2) runs on the run model, so a weak answer escalates, never ships. The model used is recorded on the project_model result. The schema validation and the owner=provider fallback are unchanged. Wall: Red first, with a stub SessionRunner: - Attempt 1 opts.model equals fastTierModel. - After an invalid answer, attempt 2 opts.model is undefined (run model). - With LOKI_MODEL_OVERRIDE set, both attempts use the override. Mutation: pin attempt 2 to the fast tier; the escalation test goes red. Gate: cd loki-ts && bun test tests/project_model && bunx tsc --noEmit Rules: FAILURE-CLASSES row first for any bug fix (D86); no CHANGELOG edits (Release Manager writes notes); DECISIONS numbers assigned by the Chief of Staff; reuse util/secure_scan.ts, the shared badge helper, keys_cmd export and the TS claude login probe instead of new copies; new CLI flags update autonomy/completions and the help-drift guard. Shipped in npm 11.17.15 (latest+next) or 11.17.16 (Release run success on e3d445460). |
1031
1031
  | TEN-COST-08 | Documented reproducible cost proof run | docs/v10/METRICS.md, docs/EVALUATING.md | LOW | see Wall in note | ready@2026-10-17T01:40Z | wave 4; depends: TEN-COST-04. Goal: docs/v10/METRICS.md gains a 'Cost proof (C-F1)' section that states: - the exact command (attribution.py --execute, arms raw-configured, raw-lean, raw-bare, loki, loki-lean, n=3, pinned model, --max-spend-usd); - the verdict rule from TEN-COST-03; - that results are reported against all three floors, never only the favorable one; - that a run is valid only when the recorded loki version equals VERSION. docs/EVALUATING.md links to it. This is an extension of existing docs, not a new doc. Wall: Red first: grep -n 'Cost proof (C-F1)' docs/v10/METRICS.md exits 1 before the edit. Green: - The documented dry-run command, copied verbatim, exits 0. - grep -n 'raw-lean' docs/EVALUATING.md prints a line. - No em or en dashes: grep -nP '[\x{2013}\x{2014}]' on both files exits 1. Gate: python3 -I benchmarks/bench/attribution.py --dry-run --arms raw-configured,raw-lean,raw-bare,loki,loki-lean && bash tests/test-help-changelog-drift.sh Rules: FAILURE-CLASSES row first for any bug fix (D86); no CHANGELOG edits (Release Manager writes notes); DECISIONS numbers assigned by the Chief of Staff; reuse util/secure_scan.ts, the shared badge helper, keys_cmd export and the TS claude login probe instead of new copies; new CLI flags update autonomy/completions and the help-drift guard. |
1032
- | TEN-QUALITY-01 | Fix brief carries a bounded failure excerpt (assertion, traceback, expected/received) | loki-ts/src/util/check_result.ts (failureExcerpt), loki-ts/src/engine10/stages/verify.ts (runCheck keeps the fail output excerpt; line 315 sample; at most 3 core lines), loki-ts/tests/engine10/check_result.test.ts, loki-ts/tests/engine10/fix.test.ts, loki-ts/tests/engine10/wall_holdout.test.ts | HIGH | see Wall in note | building@2026-10-17T04:27Z | SPLIT per CTO critic into (a) pure failureExcerpt plus fixtures, (b) verify.ts wiring plus holdout test; build as two commits or two agents. wave 2; depends: none. Goal: Each failing non-holdout check's output reaches the fix session as a redacted excerpt of at most 1500 bytes, with at most 6 KB across all groups. The group format is `<rerun cmd>\n<excerpt>`. failureExcerpt() in util/check_result.ts finds the decisive block: pytest `E ` lines plus the last frame, jest/vitest Expected/Received, node AssertionError, go `--- FAIL` with the next lines, and tsc/ruff diagnostic lines. It strips ANSI, makes absolute paths repo-relative and runs util/redact.ts. The signature stays byte-identical, so stall detection at machine.ts:232 and escalation in fix.ts are unchanged. The excerpt lives in a stage-local map inside verify.ts. It is never added to VerifyCheck, never emitted in test.result, and never computed for holdout checks. Wall: Red first: fix.test.ts drives verify then fix on a fixture with a failing pytest `assert add(2,2) == 5`. Today the brief lacks `E assert 4 == 5`, so the test fails. check_result.test.ts covers one fixture each for pytest, jest, node:test, go and tsc. It also asserts the size cap and that an AKIA-style token is redacted. wall_holdout.test.ts asserts that a failing holdout's output text appears in neither failures_grouped, events.jsonl nor the fix brief. Mutations: failureExcerpt returning '' must turn fix.test red; removing the isHold filter at verify.ts:314 must turn wall_holdout red; adding the excerpt to the signature must turn the existing stall test in machine.test.ts red. Gate: cd /Users/lokesh/git/lokimode-anthropic/loki-ts && bun test tests/engine10/check_result.test.ts tests/engine10/fix.test.ts tests/engine10/wall_holdout.test.ts && bun test && npx tsc --noEmit && bun test tests/engine10/budget.test.ts; then bash scripts/local-ci.sh Rules: FAILURE-CLASSES row first for any bug fix (D86); no CHANGELOG edits (Release Manager writes notes); DECISIONS numbers assigned by the Chief of Staff; reuse util/secure_scan.ts, the shared badge helper, keys_cmd export and the TS claude login probe instead of new copies; new CLI flags update autonomy/completions and the help-drift guard. |
1032
+ | TEN-QUALITY-01 | Fix brief carries a bounded failure excerpt (assertion, traceback, expected/received) | loki-ts/src/util/check_result.ts (failureExcerpt), loki-ts/src/engine10/stages/verify.ts (runCheck keeps the fail output excerpt; line 315 sample; at most 3 core lines), loki-ts/tests/engine10/check_result.test.ts, loki-ts/tests/engine10/fix.test.ts, loki-ts/tests/engine10/wall_holdout.test.ts | HIGH | see Wall in note | released@2026-10-17T04:35Z | SPLIT per CTO critic into (a) pure failureExcerpt plus fixtures, (b) verify.ts wiring plus holdout test; build as two commits or two agents. wave 2; depends: none. Goal: Each failing non-holdout check's output reaches the fix session as a redacted excerpt of at most 1500 bytes, with at most 6 KB across all groups. The group format is `<rerun cmd>\n<excerpt>`. failureExcerpt() in util/check_result.ts finds the decisive block: pytest `E ` lines plus the last frame, jest/vitest Expected/Received, node AssertionError, go `--- FAIL` with the next lines, and tsc/ruff diagnostic lines. It strips ANSI, makes absolute paths repo-relative and runs util/redact.ts. The signature stays byte-identical, so stall detection at machine.ts:232 and escalation in fix.ts are unchanged. The excerpt lives in a stage-local map inside verify.ts. It is never added to VerifyCheck, never emitted in test.result, and never computed for holdout checks. Wall: Red first: fix.test.ts drives verify then fix on a fixture with a failing pytest `assert add(2,2) == 5`. Today the brief lacks `E assert 4 == 5`, so the test fails. check_result.test.ts covers one fixture each for pytest, jest, node:test, go and tsc. It also asserts the size cap and that an AKIA-style token is redacted. wall_holdout.test.ts asserts that a failing holdout's output text appears in neither failures_grouped, events.jsonl nor the fix brief. Mutations: failureExcerpt returning '' must turn fix.test red; removing the isHold filter at verify.ts:314 must turn wall_holdout red; adding the excerpt to the signature must turn the existing stall test in machine.test.ts red. Gate: cd /Users/lokesh/git/lokimode-anthropic/loki-ts && bun test tests/engine10/check_result.test.ts tests/engine10/fix.test.ts tests/engine10/wall_holdout.test.ts && bun test && npx tsc --noEmit && bun test tests/engine10/budget.test.ts; then bash scripts/local-ci.sh Rules: FAILURE-CLASSES row first for any bug fix (D86); no CHANGELOG edits (Release Manager writes notes); DECISIONS numbers assigned by the Chief of Staff; reuse util/secure_scan.ts, the shared badge helper, keys_cmd export and the TS claude login probe instead of new copies; new CLI flags update autonomy/completions and the help-drift guard. |
1033
1033
  | TEN-QUALITY-02 | Pure static-diagnostic baseline attribution (new vs pre-existing lint) | loki-ts/src/runner/repo_profile.ts, loki-ts/tests/runner/harness_intelligence.test.ts (extends its existing repo_profile describe blocks) | HIGH | see Wall in note | released@2026-10-17T03:50Z | merged 43deeafe9 (HIGH r2 APPROVE 05cafda44) Shipped in npm 11.17.15 (latest+next) or 11.17.16 (Release run success on e3d445460). |
1034
1034
  | TEN-QUALITY-03 | Wire static attribution into verify so pre-existing lint never drives fix rounds | loki-ts/src/engine10/stages/verify.ts (runLintChecks only; at most 4 core lines, helper calls live in repo_profile.ts), loki-ts/tests/engine10/verify_lint.test.ts | HIGH | see Wall in note | released@2026-10-17T04:08Z | v11.17.17; TL APPROVE batch J workflow w9sw9xytw |
1035
1035
  | TEN-QUALITY-04 | Repo map indexes methods and whole large files; cache key versioned | loki-ts/src/engine10/repomap.ts, loki-ts/src/engine10/cache.ts (one-token key rename; net core growth at most 5 lines), loki-ts/tests/engine10/repomap.test.ts, loki-ts/tests/engine10/cache.test.ts | MEDIUM | see Wall in note | released@2026-10-17T03:50Z | TL APPROVE cc1c1b67d. wave 1; depends: none. Goal: repomap.ts records indented Python def and async def under the most recent top-level class as `Class.method`. It raises the symbol-scan cap from 20 KB to 256 KB per file and caps symbols at 300 per file. cache.ts renames the cache file to repomap2-${tree}.json, so a map cached before methods existed is never read. The RepoMap shape is unchanged (symbols are still strings), so isRepoMap and every caller keep working. Wall: Red first: repomap.test.ts writes a 60 KB Python file with `class QuerySet:` and `def bulk_create(self, objs):` past byte 20,000, and asserts the map has `QuerySet.bulk_create`. A file with 1000 defs yields at most 300 symbols. cache.test.ts: a stale repomap-<tree>.json written in the old format is ignored, so a fresh build happens. Mutations: restore the 20 KB cap and the test goes red; restore the old cache filename and the stale test goes red. Gate: cd /Users/lokesh/git/lokimode-anthropic/loki-ts && bun test tests/engine10/repomap.test.ts tests/engine10/cache.test.ts tests/engine10/intake.test.ts tests/engine10/sizing.test.ts && bun test && npx tsc --noEmit && bun test tests/engine10/budget.test.ts; then bash scripts/local-ci.sh Rules: FAILURE-CLASSES row first for any bug fix (D86); no CHANGELOG edits (Release Manager writes notes); DECISIONS numbers assigned by the Chief of Staff; reuse util/secure_scan.ts, the shared badge helper, keys_cmd export and the TS claude login probe instead of new copies; new CLI flags update autonomy/completions and the help-drift guard. Shipped in npm 11.17.15 (latest+next) or 11.17.16 (Release run success on e3d445460). |
1036
- | TEN-QUALITY-05 | Identifier-aware relevance ranking (traceback paths, exact identifier tokens, stopwords) | loki-ts/src/engine10/relevant_files.ts, loki-ts/src/util/relevance.ts (new; justified above), loki-ts/tests/engine10/plan.test.ts | MEDIUM | see Wall in note | ready@2026-10-17T01:40Z | wave 2; depends: none (gains compound with TEN-QUALITY-04 Class.method symbols). Goal: selectRelevantFiles and selectRelevantFilesWithReason keep their signatures, but rank by these rules: (a) A repo path named in the task or in a traceback frame ranks first. This covers `File "a/b.py", line N`, `a/b.ts:12:3` and dotted modules `pkg.mod.Name` resolved to a mapped path. (b) Exact token matches only. Tokens come from splitting camelCase, snake_case, dots and slashes; substring matches no longer count. (c) Weights: basename stem 3, symbol 2, path segment 1. (d) A fixed stopword list. (e) Ties keep repo-map order. Reasons still name the matched tokens. New file util/relevance.ts: relevant_files.ts sits in engine10 core at 4964 of 5000 lines, so the scoring moves out and relevant_files.ts becomes a thin delegate with net negative core lines. Wall: Red first, in plan.test.ts: - The task 'add a retry flag' must not select address.py. - A task containing a pytest traceback `File "src/pkg/query.py", line 88` ranks src/pkg/query.py first, ahead of 7 keyword-noise files. - `bulk_create` selects the file whose symbol is QuerySet.bulk_create. - `parseConfig` matches the symbol parse_config. Existing callers stay green: decompose.test.ts, warm.test.ts, already_done_cleanup.test.ts and the e10ext brief tests. Mutation: restore `hay.includes(w)` and the address case goes red; drop the traceback rule and the traceback case goes red. Gate: cd /Users/lokesh/git/lokimode-anthropic/loki-ts && bun test tests/engine10/plan.test.ts tests/engine10/decompose.test.ts tests/features/warm.test.ts && bun test && npx tsc --noEmit && bun test tests/engine10/budget.test.ts; then bash scripts/local-ci.sh Rules: FAILURE-CLASSES row first for any bug fix (D86); no CHANGELOG edits (Release Manager writes notes); DECISIONS numbers assigned by the Chief of Staff; reuse util/secure_scan.ts, the shared badge helper, keys_cmd export and the TS claude login probe instead of new copies; new CLI flags update autonomy/completions and the help-drift guard. |
1036
+ | TEN-QUALITY-05 | Identifier-aware relevance ranking (traceback paths, exact identifier tokens, stopwords) | loki-ts/src/engine10/relevant_files.ts, loki-ts/src/util/relevance.ts (new; justified above), loki-ts/tests/engine10/plan.test.ts | MEDIUM | see Wall in note | building@2026-10-17T04:38Z | wave 2; depends: none (gains compound with TEN-QUALITY-04 Class.method symbols). Goal: selectRelevantFiles and selectRelevantFilesWithReason keep their signatures, but rank by these rules: (a) A repo path named in the task or in a traceback frame ranks first. This covers `File "a/b.py", line N`, `a/b.ts:12:3` and dotted modules `pkg.mod.Name` resolved to a mapped path. (b) Exact token matches only. Tokens come from splitting camelCase, snake_case, dots and slashes; substring matches no longer count. (c) Weights: basename stem 3, symbol 2, path segment 1. (d) A fixed stopword list. (e) Ties keep repo-map order. Reasons still name the matched tokens. New file util/relevance.ts: relevant_files.ts sits in engine10 core at 4964 of 5000 lines, so the scoring moves out and relevant_files.ts becomes a thin delegate with net negative core lines. Wall: Red first, in plan.test.ts: - The task 'add a retry flag' must not select address.py. - A task containing a pytest traceback `File "src/pkg/query.py", line 88` ranks src/pkg/query.py first, ahead of 7 keyword-noise files. - `bulk_create` selects the file whose symbol is QuerySet.bulk_create. - `parseConfig` matches the symbol parse_config. Existing callers stay green: decompose.test.ts, warm.test.ts, already_done_cleanup.test.ts and the e10ext brief tests. Mutation: restore `hay.includes(w)` and the address case goes red; drop the traceback rule and the traceback case goes red. Gate: cd /Users/lokesh/git/lokimode-anthropic/loki-ts && bun test tests/engine10/plan.test.ts tests/engine10/decompose.test.ts tests/features/warm.test.ts && bun test && npx tsc --noEmit && bun test tests/engine10/budget.test.ts; then bash scripts/local-ci.sh Rules: FAILURE-CLASSES row first for any bug fix (D86); no CHANGELOG edits (Release Manager writes notes); DECISIONS numbers assigned by the Chief of Staff; reuse util/secure_scan.ts, the shared badge helper, keys_cmd export and the TS claude login probe instead of new copies; new CLI flags update autonomy/completions and the help-drift guard. |
1037
1037
  | TEN-QUALITY-06 | Signature digest of top relevant files in the implement/fix brief | loki-ts/src/util/ts_signatures.ts, loki-ts/src/e10ext/context.ts (at most 5 lines, e10ext stays under 1500), loki-ts/tests/e10ext/full_job_brief.test.ts | MEDIUM | see Wall in note | released@2026-10-17T03:50Z | TL APPROVE d7a7eecb9. wave 1; depends: none. Goal: util/ts_signatures.ts gains signatureDigest(repoDir, files, maxBytes=4000): - TS/JS through the existing lexer. - Python def and class headers up to the colon, with methods indented under their class. - Deterministic order: the order of the files argument. - Unreadable files are skipped. briefContext (e10ext/context.ts) appends a 'Key signatures (read the files for bodies):' block for the first 5 relevant files after the Relevant files block. The block is off with LOKI_E10_SIGS=0. The unit-brief path (unitBrief) is unchanged. Placement is after FIXED_RULES and the task, so the cache-stable prefix keeps its bytes. Wall: Red first: the brief for a fixture repo with models.py `def bulk_create(self, objs, batch_size=None):` under class QuerySet contains that header under `class QuerySet`. A TS fixture shows `export function add(a: number, b: number): number`. Two calls give byte-identical output, and the 4000-byte cap holds with 40 large files. LOKI_E10_SIGS=0 gives a brief byte-identical to today's golden. The FIXED_RULES prefix is unchanged. Mutation: drop the cap and the cap test goes red; reverse the file order and the stability/order test goes red. Gate: cd /Users/lokesh/git/lokimode-anthropic/loki-ts && bun test tests/e10ext/full_job_brief.test.ts tests/e10ext/unit_mode.test.ts tests/features/wall_manifest*.test.ts && bun test && npx tsc --noEmit && bun test tests/engine10/budget.test.ts; then bash scripts/local-ci.sh Rules: FAILURE-CLASSES row first for any bug fix (D86); no CHANGELOG edits (Release Manager writes notes); DECISIONS numbers assigned by the Chief of Staff; reuse util/secure_scan.ts, the shared badge helper, keys_cmd export and the TS claude login probe instead of new copies; new CLI flags update autonomy/completions and the help-drift guard. Shipped in npm 11.17.15 (latest+next) or 11.17.16 (Release run success on e3d445460). |
1038
1038
  | TEN-QUALITY-07 | Fix rounds see the current diff (fix the dead diff_stat reader) | loki-ts/src/runner/session_resume.ts, loki-ts/src/engine10/stages/fix.ts (replace the dead read; at most 2 core lines), loki-ts/tests/engine10/fix.test.ts, loki-ts/tests/engine10/fix_resume.test.ts | MEDIUM | see Wall in note | released@2026-10-17T03:50Z | TL APPROVE 8f6092d77, merged for v11.17.14 Shipped in npm 11.17.15 (latest+next) or 11.17.16 (Release run success on e3d445460). |
1039
1039
  | TEN-QUALITY-08 | Lean-path reproduce-first instruction (flagged until measured) | loki-ts/src/engine10/stages/implement.ts (one line), loki-ts/tests/engine10/implement.test.ts | MEDIUM | see Wall in note | ready@2026-10-17T01:40Z | wave 3; depends: none (flag flip gated on TEN-QUALITY-09 results). Goal: Only when LOKI_E10_REPRO=1 is set, buildImplementBrief's no-plan line (implement.ts:39, the lean path with no Wall) adds a fixed, task-independent sentence: 'If the task reports a bug, first add a new test function that reproduces it, run it and see it fail, then fix the code and run that test again.' This matches how Claude Code works on SWE-bench-style issues. It stays default-off: the prompt-ablation program showed that added prompt text can hurt. TEN-QUALITY-09's A/B decides the flip. If it is flipped on, the sentence moves into FIXED_RULES (the cache-stable prefix) under the harness invariant. Wall: Red first: with LOKI_E10_REPRO=1 the lean brief contains the sentence. With the flag unset, the brief is byte-identical to a golden captured before the change. A plan-present brief never contains it. Mutation: an inverted flag check turns both cases red. Gate: cd /Users/lokesh/git/lokimode-anthropic/loki-ts && bun test tests/engine10/implement.test.ts tests/engine10/lean_session.test.ts && bun test && npx tsc --noEmit && bun test tests/engine10/budget.test.ts; then bash scripts/local-ci.sh Rules: FAILURE-CLASSES row first for any bug fix (D86); no CHANGELOG edits (Release Manager writes notes); DECISIONS numbers assigned by the Chief of Staff; reuse util/secure_scan.ts, the shared badge helper, keys_cmd export and the TS claude login probe instead of new copies; new CLI flags update autonomy/completions and the help-drift guard. |
1040
1040
  | TEN-QUALITY-09 | Offline localization-recall eval on the pinned SWE-bench subset | benchmarks/swebench/loader.py, benchmarks/bench/tests/ (extend the existing loader test file there; grep for its current name before adding) | LOW | see Wall in note | released@2026-10-17T03:50Z | TL APPROVE db3196348. wave 1; depends: none. Goal: benchmarks/swebench/loader.py gains gold_files(patch), which parses the paths in the gold patch's diff headers, and a `localization` subcommand. For each pinned instance with a checkout at $LOKI_SWEBENCH_REPOS/<repo>@<base_commit>, it runs `bun -e` importing buildRepoMap and selectRelevantFiles from loki-ts/src. It writes recall@8 and recall@20 JSON with per-instance hits. An instance without a checkout is listed as skipped with its reason, never scored 0. Offline only, with no network. This gives TEN-QUALITY-04/05 a before/after number versus E-98d's 4/7, and gives TEN-QUALITY-08's paid A/B a pre-registered harness to run through the existing claude_code and loki adapters. Wall: Red first: gold_files on a recorded 2-file patch returns both paths and ignores /dev/null. The localization command on a temp git repo fixture plus a stub instance gives recall@8 = 1.0 when the gold file is named in the problem statement. A missing checkout appears as skipped with recall None, never 0. Mutation: count skipped as 0 and the skip test goes red. Gate: cd /Users/lokesh/git/lokimode-anthropic && python3 -I -m pytest benchmarks/bench/tests -q && bash scripts/local-ci.sh Rules: FAILURE-CLASSES row first for any bug fix (D86); no CHANGELOG edits (Release Manager writes notes); DECISIONS numbers assigned by the Chief of Staff; reuse util/secure_scan.ts, the shared badge helper, keys_cmd export and the TS claude login probe instead of new copies; new CLI flags update autonomy/completions and the help-drift guard. Shipped in npm 11.17.15 (latest+next) or 11.17.16 (Release run success on e3d445460). |
1041
- | TEN-UX-01 | Empty-folder first run: loki start "<brief>" sets up a repo and checks Claude login before any spend | loki-ts/src/util/first_run_repo.ts (new; justification: no existing module owns setting up an empty folder as a repo, and core has about 36 lines left so the logic cannot live in preflight.ts); loki-ts/src/engine10/preflight.ts (call the helper and the login check, net +3 lines max); loki-ts/src/commands/doctor.ts (export claudeAuthStatusLoggedIn only, and let it take an argv/env so preflight reuses it; no second parser); loki-ts/tests/engine10/preflight.test.ts; docs/v10/FAILURE-CLASSES.md (row first) | MEDIUM | see Wall in note | ready@2026-10-17T01:40Z | SPLIT per CTO critic into (a) empty folder becomes a repo, (b) Claude login check in preflight plus doctor export; build as two commits or two agents. wave 2; depends: none. Goal: In an empty folder with no git repo, `loki start "<brief>"` runs git init -q, sets the default branch to main and makes an empty initial commit, then continues. It prints one line: `initialized a new git repository in <dir> (LOKI_AUTO_GIT_INIT=0 to refuse)`. A folder that is not empty and has no repo is never initialised automatically: it stays fatal, and the message gives the exact commands (git init && git add . && git commit -m init). A missing git identity stays fatal with the exact git config command; the identity is never set automatically. When the provider is claude and no ANTHROPIC_API_KEY or CLAUDE_CODE_OAUTH_TOKEN is set, preflight runs `claude auth status` (5s timeout, using the run env's PATH and LOKI_CLAUDE_CLI). A clear loggedIn:false is fatal and names the fix `claude login (or set ANTHROPIC_API_KEY)`. An unknown or empty answer is a warning only, never fatal, so a stub CLI still works. Wall: Red first: preflight.test.ts gains cases that fail on main today: (a) empty temp folder, no repo: checkPreflight returns fatal null, the folder now has .git and HEAD resolves; (b) folder holding one file, no repo: fatal contains `git init && git add . && git commit -m init`, and no .git is created; (c) LOKI_AUTO_GIT_INIT=0 on an empty folder: still fatal, no .git; (d) a fake claude on PATH printing {"loggedIn":false} gives a fatal containing `claude login`; (e) fake printing {} or exiting 1 gives fatal null plus one warning; (f) ANTHROPIC_API_KEY set: the fake claude is never called (it writes a marker file; assert the file is absent). Mutations: (1) drop the emptiness check, so case (b) must go red; (2) treat the unknown login answer as fatal, so case (e) must go red; (3) delete the export in doctor.ts, so the build/typecheck must go red. Gate: cd loki-ts && bun test tests/engine10/preflight.test.ts tests/engine10/budget.test.ts tests/commands/doctor.test.ts && bun test && bunx tsc --noEmit; then bash scripts/local-ci.sh Rules: FAILURE-CLASSES row first for any bug fix (D86); no CHANGELOG edits (Release Manager writes notes); DECISIONS numbers assigned by the Chief of Staff; reuse util/secure_scan.ts, the shared badge helper, keys_cmd export and the TS claude login probe instead of new copies; new CLI flags update autonomy/completions and the help-drift guard. |
1041
+ | TEN-UX-01 | Empty-folder first run: loki start "<brief>" sets up a repo and checks Claude login before any spend | loki-ts/src/util/first_run_repo.ts (new; justification: no existing module owns setting up an empty folder as a repo, and core has about 36 lines left so the logic cannot live in preflight.ts); loki-ts/src/engine10/preflight.ts (call the helper and the login check, net +3 lines max); loki-ts/src/commands/doctor.ts (export claudeAuthStatusLoggedIn only, and let it take an argv/env so preflight reuses it; no second parser); loki-ts/tests/engine10/preflight.test.ts; docs/v10/FAILURE-CLASSES.md (row first) | MEDIUM | see Wall in note | building@2026-10-17T04:38Z | SPLIT per CTO critic into (a) empty folder becomes a repo, (b) Claude login check in preflight plus doctor export; build as two commits or two agents. wave 2; depends: none. Goal: In an empty folder with no git repo, `loki start "<brief>"` runs git init -q, sets the default branch to main and makes an empty initial commit, then continues. It prints one line: `initialized a new git repository in <dir> (LOKI_AUTO_GIT_INIT=0 to refuse)`. A folder that is not empty and has no repo is never initialised automatically: it stays fatal, and the message gives the exact commands (git init && git add . && git commit -m init). A missing git identity stays fatal with the exact git config command; the identity is never set automatically. When the provider is claude and no ANTHROPIC_API_KEY or CLAUDE_CODE_OAUTH_TOKEN is set, preflight runs `claude auth status` (5s timeout, using the run env's PATH and LOKI_CLAUDE_CLI). A clear loggedIn:false is fatal and names the fix `claude login (or set ANTHROPIC_API_KEY)`. An unknown or empty answer is a warning only, never fatal, so a stub CLI still works. Wall: Red first: preflight.test.ts gains cases that fail on main today: (a) empty temp folder, no repo: checkPreflight returns fatal null, the folder now has .git and HEAD resolves; (b) folder holding one file, no repo: fatal contains `git init && git add . && git commit -m init`, and no .git is created; (c) LOKI_AUTO_GIT_INIT=0 on an empty folder: still fatal, no .git; (d) a fake claude on PATH printing {"loggedIn":false} gives a fatal containing `claude login`; (e) fake printing {} or exiting 1 gives fatal null plus one warning; (f) ANTHROPIC_API_KEY set: the fake claude is never called (it writes a marker file; assert the file is absent). Mutations: (1) drop the emptiness check, so case (b) must go red; (2) treat the unknown login answer as fatal, so case (e) must go red; (3) delete the export in doctor.ts, so the build/typecheck must go red. Gate: cd loki-ts && bun test tests/engine10/preflight.test.ts tests/engine10/budget.test.ts tests/commands/doctor.test.ts && bun test && bunx tsc --noEmit; then bash scripts/local-ci.sh Rules: FAILURE-CLASSES row first for any bug fix (D86); no CHANGELOG edits (Release Manager writes notes); DECISIONS numbers assigned by the Chief of Staff; reuse util/secure_scan.ts, the shared badge helper, keys_cmd export and the TS claude login probe instead of new copies; new CLI flags update autonomy/completions and the help-drift guard. |
1042
1042
  | TEN-UX-02 | Failure-specific Next line: every failed start names the exact fix | loki-ts/src/util/run_summary.ts (nextOf only); loki-ts/src/engine10/supervisor.ts (line 393 argument only; rebase after Q18-07 if it lands first); loki-ts/tests/util/run_summary.test.ts | LOW | see Wall in note | released@2026-10-17T02:57Z | merge 63cdd70ec, dist bd6348d77; TL APPROVE f450cf65f (94 pass, 2 mutations red); post-merge tsc 0 errors, 130 pass. wave 1; depends: none (rebase onto Q18-07 if supervisor.ts:313 moved). Goal: nextOf takes the run's reason and outcome and returns one concrete command per failure class: provider authentication failed -> `claude login` (or that provider's fix line from setup-requirements.json via requirementFix); provider credit exhausted -> `loki start ... --provider <other>` or check billing; '<check> failed: ...' -> `loki chat --attach` (ask why) plus `loki undo` when files changed; spec conflict (BLOCKED) -> `loki answer --text "..."`; STALLED -> `loki chat --attach`; engine ended before sealing a receipt -> `loki doctor`. The existing verified, done-unverified and budget branches stay byte-identical. The supervisor call site passes res.reason on the same line, with zero net core lines. Wall: Red first: run_summary.test.ts adds one table row per reason string that output.ts:74 reasonOf really produces (copy the literals, do not paraphrase), each asserting the exact Next command. These fail today because nextOf returns loki doctor/loki undo. A pin asserts the old outputs for verified, done-unverified, stopped and failed-without-reason, so default output does not drift. A source-scan test asserts every literal reason produced at output.ts:74 has a nextOf mapping (catches new reasons with no mapping). Mutation: make nextOf ignore the reason argument, so every new row must go red; remove the supervisor argument, so a contract test in tests/features/contract.test.ts that runs the summary with fatal:auth must go red. Gate: cd loki-ts && bun test tests/util/run_summary.test.ts tests/features/contract.test.ts tests/engine10/budget.test.ts && bun test && bunx tsc --noEmit Rules: FAILURE-CLASSES row first for any bug fix (D86); no CHANGELOG edits (Release Manager writes notes); DECISIONS numbers assigned by the Chief of Staff; reuse util/secure_scan.ts, the shared badge helper, keys_cmd export and the TS claude login probe instead of new copies; new CLI flags update autonomy/completions and the help-drift guard. v11.17.13 npm next 11.17.13 |
1043
1043
  | TEN-UX-03 | Funnel on the default engine10 route: first_run_blocked at preflight and build_verified at seal | loki-ts/src/util/funnel.ts (new; justification: telemetry.sh is the owner and this file is the only TS bridge to it, replacing the private copy in doctor.ts); loki-ts/src/commands/doctor.ts (emitFirstRunBlocked becomes a call to the helper; remove the spawn code); loki-ts/src/engine10/cli.ts (one call after main, at most +2 lines); autonomy/telemetry.sh (_loki_known_blocker keys and a loki_emit_build_verified_enum function); tests/test-first-run-funnel-coverage.sh | MEDIUM | see Wall in note | ready@2026-10-17T01:40Z | wave 3; depends: TEN-UX-01 (shares doctor.ts; also needs the not_a_repo fatal text to exist). Goal: Move the detached, opt-out-respecting telemetry.sh spawn from doctor.ts:1047-1069 into one TS helper (emitFunnel(kind, key)), and delete the copy in doctor.ts in the same change. Call it from engine10/cli.ts after the supervisor returns: preflight exit 2 sends first_run_blocked with a bounded key; a VERIFIED or ALREADY_SATISFIED exit sends build_verified carrying only headline=VERIFIED and route=engine10. No other field is sent. Add keys not_a_repo and git_identity to _loki_known_blocker (telemetry.sh:204), and add an allowlisted build_verified variant that takes enum args instead of a proof.json path. All existing opt-outs still apply because everything goes through _loki_analytics_enabled. Wall: Red first: test-first-run-funnel-coverage.sh gains (a) a wiring assertion that engine10/cli.ts reaches emitFunnel on a preflight exit 2 and on a VERIFIED exit, and (b) a run with a stub telemetry.sh in a throwaway HOME, analytics forced on, with no network: loki_telemetry is replaced by a recorder function. Assert that one first_run_blocked blocker=not_a_repo line is recorded for a start in a non-empty folder with no repo, and that a second identical run records nothing (once-per-install marker). Assert DO_NOT_TRACK=1 and LOKI_TELEMETRY_DISABLED=1 each record zero lines. Assert the recorded payload contains no path, home dir or brief text (grep the recorder file for the temp folder path and the brief: must be absent). Mutations: emit a raw blocker string instead of the enum, so the no-path assertion must go red; drop the marker write, so the second-run assertion must go red; leave doctor's old spawn copy in place, so a grep guard counting `telemetry.sh` spawns in loki-ts/src (exactly 1) must go red. Gate: bash tests/test-first-run-funnel-coverage.sh && bash tests/test-first-run-blocked-signal.sh && cd loki-ts && bun test tests/engine10/budget.test.ts tests/commands/doctor.test.ts && bun test; then bash scripts/local-ci.sh Rules: FAILURE-CLASSES row first for any bug fix (D86); no CHANGELOG edits (Release Manager writes notes); DECISIONS numbers assigned by the Chief of Staff; reuse util/secure_scan.ts, the shared badge helper, keys_cmd export and the TS claude login probe instead of new copies; new CLI flags update autonomy/completions and the help-drift guard. |
1044
1044
  | TEN-UX-04 | loki doctor --fix: consent-gated installs and Claude login, plus its first tests | loki-ts/src/commands/doctor_fix.ts; loki-ts/src/commands/doctor.ts (pass --yes through to runDoctorFix only; rebase after TEN-UX-01/03 if they touch the same hunk); loki-ts/tests/commands/doctor.test.ts (extend; no doctor_fix test exists today) | MEDIUM | see Wall in note | ready@2026-10-17T01:40Z | wave 4; depends: TEN-UX-03 (doctor.ts edit order only). Goal: On a TTY, `loki doctor --fix` offers each missing default-provider install as a y/N question before running it: `npm install -g @anthropic-ai/claude-code`, then `claude login` when evaluateClaudeLogin returns fail. `--fix --yes` runs the same steps without asking, for scripted onboarding. Without a TTY and without --yes, it prints the commands only, exactly as today. System package managers and sudo are never run. Every step that runs reports `fixed:` or `failed: <first stderr line>`, and the command exits non-zero when a required step still fails. Command execution is behind an injectable runner, so tests never install anything. Wall: Red first: doctor.test.ts gains applyDoctorFixes/runDoctorFix cases with an injected has() and runner: (a) claude missing, tty=false, no --yes: the runner is never called and the npm command is printed; (b) claude missing, --yes: the runner gets exactly [npm, install, -g, @anthropic-ai/claude-code]; (c) runner fails: output has `failed:` and the exit code is non-zero; (d) jq missing with --yes: the runner is never called for jq (system package, print only); (e) claude present and logged out with --yes: the runner gets [claude, login]. These fail today because doctor_fix has no runner, no --yes and no exit code. Mutations: drop the tty/--yes gate, so (a) must go red; let system packages through the runner, so (d) must go red. Gate: cd loki-ts && bun test tests/commands/doctor.test.ts tests/commands/doctor_router.test.ts && bun test && bunx tsc --noEmit; bash tests/test-doctor-ux.sh; bash tests/test-doctor-single-impl.sh Rules: FAILURE-CLASSES row first for any bug fix (D86); no CHANGELOG edits (Release Manager writes notes); DECISIONS numbers assigned by the Chief of Staff; reuse util/secure_scan.ts, the shared badge helper, keys_cmd export and the TS claude login probe instead of new copies; new CLI flags update autonomy/completions and the help-drift guard. |
1045
- | TEN-UX-05 | loki chat startup readiness check and slash-command suggestions | autonomy/lib/chat.sh; tests/test-doctor-ux.sh (already owns the chat assertions, P12-16) | LOW | see Wall in note | ready@2026-10-17T01:40Z | wave 3; depends: none (the folder message text refers to TEN-UX-01 behaviour; write it to whichever behaviour is on main). Goal: When cmd_chat starts (after the TTY check), print at most 3 readiness lines, once, using existing helpers only. (1) The provider CLI for _CHAT_PROVIDER is missing (any provider, not only claude): print `_loki_req_fix_line <provider>` and a hint to try `/provider claude`. (2) claude is logged out: print `claude login (or set ANTHROPIC_API_KEY)`. (3) The folder is not a git repo: say that `/run` will set up an empty folder (TEN-UX-01) or needs `git init` for a non-empty one. When everything is ready, print nothing extra, so a working setup sees no new text. An unknown slash command prints `unknown command: /stat (did you mean /status?)` by unique-prefix or single-edit match against the _chat_help list. The hint for a missing non-Claude provider replaces the bare 'cannot load provider X' at chat.sh:259/:271 with the fix line. Wall: Red first: test-doctor-ux.sh adds cases that drive cmd_chat through `script`/a pty helper already used there (or calls the new _chat_readiness function directly). With PATH holding no codex and LOKI_PROVIDER=codex, the output contains the codex fix string from setup-requirements.json. With a fake claude printing {"loggedIn":false}, the output contains `claude login`. In a non-git temp folder, the output mentions git. With every check passing (fake claude logged in, inside a repo), the readiness output is empty. `/stat` suggests `/status`; `/zzzz` prints no suggestion. Mutations: print readiness lines unconditionally, so the all-ready empty assertion must go red; hardcode the claude fix for every provider, so the codex fix assertion must go red. bash -n and shellcheck on chat.sh. Gate: bash tests/test-doctor-ux.sh && bash tests/test-loki-steer.sh && bash tests/test-first-run-bash32.sh && shellcheck autonomy/lib/chat.sh; then bash scripts/local-ci.sh Rules: FAILURE-CLASSES row first for any bug fix (D86); no CHANGELOG edits (Release Manager writes notes); DECISIONS numbers assigned by the Chief of Staff; reuse util/secure_scan.ts, the shared badge helper, keys_cmd export and the TS claude login probe instead of new copies; new CLI flags update autonomy/completions and the help-drift guard. |
1045
+ | TEN-UX-05 | loki chat startup readiness check and slash-command suggestions | autonomy/lib/chat.sh; tests/test-doctor-ux.sh (already owns the chat assertions, P12-16) | LOW | see Wall in note | building@2026-10-17T04:43Z | wave 3; depends: none (the folder message text refers to TEN-UX-01 behaviour; write it to whichever behaviour is on main). Goal: When cmd_chat starts (after the TTY check), print at most 3 readiness lines, once, using existing helpers only. (1) The provider CLI for _CHAT_PROVIDER is missing (any provider, not only claude): print `_loki_req_fix_line <provider>` and a hint to try `/provider claude`. (2) claude is logged out: print `claude login (or set ANTHROPIC_API_KEY)`. (3) The folder is not a git repo: say that `/run` will set up an empty folder (TEN-UX-01) or needs `git init` for a non-empty one. When everything is ready, print nothing extra, so a working setup sees no new text. An unknown slash command prints `unknown command: /stat (did you mean /status?)` by unique-prefix or single-edit match against the _chat_help list. The hint for a missing non-Claude provider replaces the bare 'cannot load provider X' at chat.sh:259/:271 with the fix line. Wall: Red first: test-doctor-ux.sh adds cases that drive cmd_chat through `script`/a pty helper already used there (or calls the new _chat_readiness function directly). With PATH holding no codex and LOKI_PROVIDER=codex, the output contains the codex fix string from setup-requirements.json. With a fake claude printing {"loggedIn":false}, the output contains `claude login`. In a non-git temp folder, the output mentions git. With every check passing (fake claude logged in, inside a repo), the readiness output is empty. `/stat` suggests `/status`; `/zzzz` prints no suggestion. Mutations: print readiness lines unconditionally, so the all-ready empty assertion must go red; hardcode the claude fix for every provider, so the codex fix assertion must go red. bash -n and shellcheck on chat.sh. Gate: bash tests/test-doctor-ux.sh && bash tests/test-loki-steer.sh && bash tests/test-first-run-bash32.sh && shellcheck autonomy/lib/chat.sh; then bash scripts/local-ci.sh Rules: FAILURE-CLASSES row first for any bug fix (D86); no CHANGELOG edits (Release Manager writes notes); DECISIONS numbers assigned by the Chief of Staff; reuse util/secure_scan.ts, the shared badge helper, keys_cmd export and the TS claude login probe instead of new copies; new CLI flags update autonomy/completions and the help-drift guard. |
1046
1046
  | TEN-UX-06 | Dashboard page: empty state, auto-select of the live run, stage progress strip, readable timeline, theme and narrow-screen layout | loki-ts/src/util/dashboard_page.ts; loki-ts/tests/engine10/dashboard_entry.test.ts (extend; it already serves the real page from a fixture events.jsonl) | LOW | see Wall in note | released@2026-10-17T03:50Z | merged 0a45be416 (TL APPROVE d933581dc; follow-up: test that a later click survives the next poll) Shipped in npm 11.17.15 (latest+next) or 11.17.16 (Release run success on e3d445460). |
1047
1047
  | TEN-UX-07 | Dashboard server panels: Reason, Next step and current stage elapsed | loki-ts/src/runner/engine10_dashboard.ts (formatPanels and summarizeRun only); loki-ts/tests/engine10/dashboard.test.ts | LOW | see Wall in note | released@2026-10-17T04:08Z | v11.17.17; TL APPROVE batch J workflow w9sw9xytw |
1048
1048
  | TEN-UX-08 | First-run gate: empty-folder loki start scenario and the install-to-first-success time budget | scripts/first-run-gate.sh; tests/test-first-run-gate.sh; docs/v10/METRICS.md (row 14 text only, written by --real runs, not by the engineer) | MEDIUM | see Wall in note | ready@2026-10-17T01:40Z | wave 4; depends: TEN-UX-01 (empty-folder start must work), TEN-UX-02 (Next wording). Goal: Add `--entry start-empty` to scripts/first-run-gate.sh. It installs (with --installed) or uses the tree, creates an empty folder under the run-owned temp directory, sets git identity through GIT_* env vars only, and runs `loki doctor` then `loki start "<brief>"` with the existing stub claude. It asserts: the folder was set up as a repo, Outcome is VERIFIED, a receipt is sealed, Next is present, and install+doctor+start wall time on the stub is <= 120s, recorded as `install_to_first_success_s`. The stub run measures harness overhead only. With --real, it appends the measured time-to-first-sealed-result row to docs/v10/METRICS.md, replacing the 'not measured' row at METRICS.md:14 with a dated measurement and its command. In stub mode it never writes METRICS. Wall: Red first: test-first-run-gate.sh adds fake-loki modes for the new entry: (a) a fake that leaves the folder without a repo: FAIL repo-init; (b) a fake that sleeps past an injected budget FRG_BUDGET_S=1: FAIL first-success-budget; (c) a fake with no Next line: FAIL next-line; (d) a well-behaved fake: all PASS and the report has `install_to_first_success_s=<int>`. The new entry does not exist today, so these fail. Mutations: drop the budget comparison, so (b) must go red; parse the time field as a string compare, so a budget of 9 vs a measured 10 must go red. Tests use loki_run_tmp_create/cleanup only, never /tmp globs. Gate: bash tests/test-first-run-gate.sh && bash scripts/first-run-gate.sh --stub --entry start-empty; then bash scripts/local-ci.sh Rules: FAILURE-CLASSES row first for any bug fix (D86); no CHANGELOG edits (Release Manager writes notes); DECISIONS numbers assigned by the Chief of Staff; reuse util/secure_scan.ts, the shared badge helper, keys_cmd export and the TS claude login probe instead of new copies; new CLI flags update autonomy/completions and the help-drift guard. |
1049
1049
  | TEN-GATES-01 | FC row plus pure check-provenance classifier in check_result.ts | loki-ts/src/util/check_result.ts, loki-ts/tests/engine10/check_result.test.ts, docs/v10/FAILURE-CLASSES.md | HIGH | see Wall in note | released@2026-10-17T03:50Z | merged 0970d5887 (HIGH r2 APPROVE 10be1a1bd; FAILURE-CLASSES append conflict kept both sections) Shipped in npm 11.17.15 (latest+next) or 11.17.16 (Release run success on e3d445460). |
1050
1050
  | TEN-GATES-02 | Seal: receipt checks carry provenance; VERIFIED requires agent-independent proof | loki-ts/src/engine10/stages/seal.ts, loki-ts/src/engine10/types.ts, loki-ts/tests/engine10/seal.test.ts, docs/v10/DECISIONS.md | HIGH | see Wall in note | ready@2026-10-17T01:40Z | wave 3; depends: TEN-GATES-01, Q18-05b (seal.ts in flight). Goal: In seal.ts replace hasExecutedProof at seal.ts:190 with hasExogenousProof (wallGreenOnBase still counts); when only agent_authored/llm_judge checks passed, verdict caps at PARTIAL and not_proven gains 'only agent-authored tests executed (no agent-independent proof)'. Each receipt check gains additive optional provenance (types.ts ReceiptCheck provenance?: ...; omitted key keeps older receipts byte-stable for verification). renderReceiptMd splits '### Agent-independent checks' and '### Agent-authored / advisory checks'. Opt-out LOKI_EXOGENOUS_PROOF=0 (record the default-on decision in DECISIONS.md under the D99 grant). Net-zero line change in engine10 core (fold into existing lines or move helpers to util). Wall: Red first in seal.test.ts: fake verify outputs with one passing check on a test file ADDED in the diff and no Wall -> expect PARTIAL plus the not_proven line (today VERIFIED); same check on a pre-existing file -> VERIFIED; receipt.json checks carry provenance; receipt.md has both sections. Mutation: revert to hasExecutedProof -> red. LOKI_EXOGENOUS_PROOF=0 restores old verdict. Gate: cd loki-ts && bun test tests/engine10/seal.test.ts tests/engine10/seal_verify_roundtrip.test.ts tests/engine10/budget.test.ts && bun test && bunx tsc --noEmit Rules: FAILURE-CLASSES row first for any bug fix (D86); no CHANGELOG edits (Release Manager writes notes); DECISIONS numbers assigned by the Chief of Staff; reuse util/secure_scan.ts, the shared badge helper, keys_cmd export and the TS claude login probe instead of new copies; new CLI flags update autonomy/completions and the help-drift guard. |
1051
1051
  | TEN-GATES-03 | loki verify reports agent-independent evidence and adds --require-exogenous | loki-ts/src/engine10/verify_cmd.ts, loki-ts/tests/engine10/verify_cmd.test.ts | HIGH | see Wall in note | released@2026-10-17T04:08Z | v11.17.17; TL APPROVE batch J workflow w9sw9xytw |
1052
- | TEN-GATES-04 | TS-callable app boot and HTTP health probe over app-runner.sh | loki-ts/src/util/app_probe.ts (new), loki-ts/tests/util/app_probe.test.ts (new) | MEDIUM | see Wall in note | ready@2026-10-17T01:40Z | SPLIT per CTO critic into (a) app boot and health, (b) functional-verify run and artifact write; build as two commits or two agents. wave 2; depends: none. Goal: New loki-ts/src/util/app_probe.ts (justification: no TS module owns app boot; app-runner.sh is bash-only and deep.ts:121-122 names this missing surface). appProbe(repoDir, lokiDir, {specText?, timeoutMs}) sources autonomy/app-runner.sh in a bash child (token-free env via plainTestEnv), runs app_runner_init, app_runner_start, app_runner_health_check, reads .loki/app-runner/health.json, then (when specText given) runs autonomy/lib/functional-verify.py against the URL and writes .loki/quality/functional-results.json in the shape proof-generator.py:841-870 reads. ALWAYS calls app_runner_stop in finally (stops only the PID app-runner recorded). Returns ReceiptCheck-shaped results: 'app boot' and 'http probe' with result pass/fail/not_run and reason; missing runtime or no app detected = not_run, never fail. Wall: Red first: fixture repo with a static index.html (app-runner static-site path, as tests/test-app-runner-static-site.sh) -> app boot pass + health.json ok; fixture whose start command exits 1 -> fail; empty repo -> not_run. Assert no process left on the recorded PID after return. Mutation: drop the stop call -> leftover-PID assertion red. Gate: cd loki-ts && bun test tests/util/app_probe.test.ts && bun test && bunx tsc --noEmit; register the new test file per the structural guards (select-tests.sh --guards-only rows, shard registration) Rules: FAILURE-CLASSES row first for any bug fix (D86); no CHANGELOG edits (Release Manager writes notes); DECISIONS numbers assigned by the Chief of Staff; reuse util/secure_scan.ts, the shared badge helper, keys_cmd export and the TS claude login probe instead of new copies; new CLI flags update autonomy/completions and the help-drift guard. |
1052
+ | TEN-GATES-04 | TS-callable app boot and HTTP health probe over app-runner.sh | loki-ts/src/util/app_probe.ts (new), loki-ts/tests/util/app_probe.test.ts (new) | MEDIUM | see Wall in note | building@2026-10-17T04:38Z | SPLIT per CTO critic into (a) app boot and health, (b) functional-verify run and artifact write; build as two commits or two agents. wave 2; depends: none. Goal: New loki-ts/src/util/app_probe.ts (justification: no TS module owns app boot; app-runner.sh is bash-only and deep.ts:121-122 names this missing surface). appProbe(repoDir, lokiDir, {specText?, timeoutMs}) sources autonomy/app-runner.sh in a bash child (token-free env via plainTestEnv), runs app_runner_init, app_runner_start, app_runner_health_check, reads .loki/app-runner/health.json, then (when specText given) runs autonomy/lib/functional-verify.py against the URL and writes .loki/quality/functional-results.json in the shape proof-generator.py:841-870 reads. ALWAYS calls app_runner_stop in finally (stops only the PID app-runner recorded). Returns ReceiptCheck-shaped results: 'app boot' and 'http probe' with result pass/fail/not_run and reason; missing runtime or no app detected = not_run, never fail. Wall: Red first: fixture repo with a static index.html (app-runner static-site path, as tests/test-app-runner-static-site.sh) -> app boot pass + health.json ok; fixture whose start command exits 1 -> fail; empty repo -> not_run. Assert no process left on the recorded PID after return. Mutation: drop the stop call -> leftover-PID assertion red. Gate: cd loki-ts && bun test tests/util/app_probe.test.ts && bun test && bunx tsc --noEmit; register the new test file per the structural guards (select-tests.sh --guards-only rows, shard registration) Rules: FAILURE-CLASSES row first for any bug fix (D86); no CHANGELOG edits (Release Manager writes notes); DECISIONS numbers assigned by the Chief of Staff; reuse util/secure_scan.ts, the shared badge helper, keys_cmd export and the TS claude login probe instead of new copies; new CLI flags update autonomy/completions and the help-drift guard. |
1053
1053
  | TEN-GATES-05 | Spec-derived API auth probe in functional-verify.py | autonomy/lib/functional-verify.py, tests/test_functional_verify.py | HIGH | see Wall in note | parked@2026-10-17T03:30Z | HIGH r1 BLOCK; re-sliced as TEN-GATES-05b |
1054
1054
  | TEN-GATES-06 | Deep verify: real app boot and secure-scan rules on engine10 | loki-ts/src/engine10/stages/deep.ts, loki-ts/tests/engine10/deep.test.ts | HIGH | see Wall in note | ready@2026-10-17T01:40Z | wave 3; depends: TEN-GATES-04, Q18-04 (deep.ts in flight). Goal: Replace runAppBoot's hard-coded not_run (deep.ts:105-130) with a call to util/app_probe.ts, pushing its 'app boot' and 'http probe' checks; extend the existing 'security scan' check to also run autonomy/lib/secure-scan.py over changed files (HIGH active finding = fail, scanner absent = not_run). DEEP_NOT_PROVEN entries clear only for checks that actually ran. Net-zero lines in engine10 core (app boot body shrinks to the call). Wall: Red first in deep.test.ts: injected appProbe fake returning pass -> 'app boot' check result pass (today always not_run); a changed file with a committed PEM private key -> security scan fail with secure-scan rule id; secure-scan missing -> not_run. Mutation: ignore secure-scan exit -> red. Gate: cd loki-ts && bun test tests/engine10/deep.test.ts tests/engine10/deep_wiring.test.ts tests/engine10/budget.test.ts && bun test && bunx tsc --noEmit Rules: FAILURE-CLASSES row first for any bug fix (D86); no CHANGELOG edits (Release Manager writes notes); DECISIONS numbers assigned by the Chief of Staff; reuse util/secure_scan.ts, the shared badge helper, keys_cmd export and the TS claude login probe instead of new copies; new CLI flags update autonomy/completions and the help-drift guard. |
1055
1055
  | TEN-GATES-07 | loki start route: collect app health and functional facts before the proof | loki-ts/src/runner/proof.ts, loki-ts/tests/runner/proof.test.ts | MEDIUM | see Wall in note | ready@2026-10-17T01:40Z | wave 3; depends: TEN-GATES-04. Goal: In runner/proof.ts, before spawning proof-generator.py, call util/app_probe.ts with the run's PRD text (LOKI_PROOF_APP_PROBE=0 opts out) so .loki/app-runner/health.json and .loki/quality/functional-results.json exist on the primary route; the proof's healthcheck and functional facts stop being permanently not_run. Still never throws; probe failure leaves the facts absent (not_run), never fabricated. Wall: Red first in proof.test.ts: inject a fake probe that writes both artifacts -> generator facts.healthcheck/functional ran=true; probe throwing -> generator still invoked, facts not_run. Mutation: skip probe -> red. Gate: cd loki-ts && bun test tests/runner/proof.test.ts tests/runner/proof_run_id_pointer.test.ts && bun test && bunx tsc --noEmit Rules: FAILURE-CLASSES row first for any bug fix (D86); no CHANGELOG edits (Release Manager writes notes); DECISIONS numbers assigned by the Chief of Staff; reuse util/secure_scan.ts, the shared badge helper, keys_cmd export and the TS claude login probe instead of new copies; new CLI flags update autonomy/completions and the help-drift guard. |
@@ -1062,7 +1062,7 @@ Source: ~/git/autonomi-dev/research/2026-09-30-adoption/SWARM-PROMPT-ADOPTION.md
1062
1062
  | TEN-STABILITY-04 | global-guards.tsv covers every repo-wide guard that reached main red | scripts/global-guards.tsv; tests/test-select-tests.sh | LOW | see Wall in note | released@2026-10-17T02:57Z | merge 3e542a7fc; TL APPROVE 07aa41ad1 (select-tests 117/0, fast-gate 25/0, shard-coverage 19/0). wave 1; depends: none. Goal: Add as R8 rows the repo-wide guards that turned main red on 2026-10-16 even though no slice diff selected them: - tests/cli/test-completions-coverage.sh - loki-ts/tests/engine10/budget.test.ts - loki-ts/tests/engine10/l2_destructive_registry.test.ts - loki-ts/tests/engine10/pr_body_golden.test.ts - loki-ts/tests/commands/cli_help_routes.test.ts - tests/test-select-tests.sh (FC-89 walker markers) Also add a meta-assertion to test-select-tests.sh: every loki-ts test file that carries '// select: walk-all-src' is either an R8 row or selected by R-rules for any loki-ts/src diff. A new repo-wide guard then cannot silently stay out of R8. Wall: RED: a new test-select-tests.sh case asserts that --guards-only lists each of the 6 targets. It fails today because they are absent from the 17 rows. GREEN after adding the rows. MUTATION: delete one row and its case goes red. Add a fixture walker test without an R8 row and the meta-assertion goes red. GATE: bash tests/test-select-tests.sh && bash tests/test-fast-gate.sh && bash tests/test-shard-coverage.sh. Then time bash scripts/impacted-gate.sh --guards-only and record the added seconds in tests/shard-durations.tsv only if a row is new there. The fast-gate plan for a docs-only diff must stay under 60s per shard. Rules: FAILURE-CLASSES row first for any bug fix (D86); no CHANGELOG edits (Release Manager writes notes); DECISIONS numbers assigned by the Chief of Staff; reuse util/secure_scan.ts, the shared badge helper, keys_cmd export and the TS claude login probe instead of new copies; new CLI flags update autonomy/completions and the help-drift guard. v11.17.13 npm next 11.17.13 |
1063
1063
  | TEN-STABILITY-05 | WC-01b wall_concurrent stops racing the 5s bun timeout | loki-ts/tests/engine10/wall_concurrent.test.ts | LOW | see Wall in note | released@2026-10-17T02:57Z | merge 516e4a4f1; TL APPROVE 5fa97f2d5 (13/0 x3, 13/0 under 12x load at --timeout 1500). wave 1; depends: none. Goal: Make the WC-01b suite hermetic and fast. Build the git fixture once in beforeAll: copy a template repo per test instead of running git init, add and commit per test (wall_concurrent.test.ts:15-20). Give the concurrency case an explicit timeout sized from measured CI duration, and keep every assertion unchanged. Cause measured in nightly 38938949858: 5004.82ms against the 5000ms default. Wall: RED: cd loki-ts && bun test --timeout 1500 tests/engine10/wall_concurrent.test.ts fails today on this machine under 'yes > /dev/null' x4 CPU load (record the measured ms). GREEN: the same command passes after the fixture change, and plain bun test passes 20/20 in a loop: for i in $(seq 20); do bun test tests/engine10/wall_concurrent.test.ts // break; done. MUTATION: swap the expected order of implement:start and author:end and the test still fails, so the assertion is intact. GATE: cd loki-ts && bun run typecheck && bun test (full). Rules: FAILURE-CLASSES row first for any bug fix (D86); no CHANGELOG edits (Release Manager writes notes); DECISIONS numbers assigned by the Chief of Staff; reuse util/secure_scan.ts, the shared badge helper, keys_cmd export and the TS claude login probe instead of new copies; new CLI flags update autonomy/completions and the help-drift guard. v11.17.13 npm next 11.17.13 |
1064
1064
  | TEN-STABILITY-06 | pulse PROMOTION_LAG violation with the blocking reason | scripts/v10-pulse.sh; tests/test-v10-pulse.sh | MEDIUM | see Wall in note | released@2026-10-17T03:50Z | TL APPROVE ce461a4d1. wave 1; depends: none. Goal: In the npm section of v10-pulse.sh (near :830-863), emit 'VIOLATION PROMOTION_LAG' when next != latest and latest's publish time is more than 6h older than next's (threshold set by LOKI_PULSE_PROMOTION_LAG_H). Include the first PROMOTE-BLOCK or FATAL line from the newest non-skipped Promote run (gh run list -w Promote, then gh run view --log-failed). Also include the failing step names of the newest measured Nightly. The CoS acts on the top violation each turn, so a red bench is triaged within one turn instead of 13h. Fail soft: an API error prints UNKNOWN and never crashes the pulse. Wall: RED: test-v10-pulse.sh gains a fixture with stubbed npm and gh: latest 11.10.1 published 2026-10-15T00:00Z, next 11.17.6 published 2026-10-16T23:40Z, and Promote log containing 'PROMOTE-BLOCK: the newest nightly at the promoted SHA ... is failure'. Expect a PROMOTION_LAG line carrying that reason; today none is printed. GREEN cases: next==latest gives no violation; lag under the threshold gives none; gh failure gives UNKNOWN with rc 0. MUTATION: invert the threshold comparison and both lag cases go red. GATE: bash tests/test-v10-pulse.sh && shellcheck scripts/v10-pulse.sh && bash scripts/v10-pulse.sh on the real repo prints the violation today (latest 11.10.1 vs next 11.17.6). Rules: FAILURE-CLASSES row first for any bug fix (D86); no CHANGELOG edits (Release Manager writes notes); DECISIONS numbers assigned by the Chief of Staff; reuse util/secure_scan.ts, the shared badge helper, keys_cmd export and the TS claude login probe instead of new copies; new CLI flags update autonomy/completions and the help-drift guard. Shipped in npm 11.17.15 (latest+next) or 11.17.16 (Release run success on e3d445460). |
1065
- | TEN-STABILITY-07 | nightly classifies flips vs stable reds across same-SHA legs | .github/workflows/nightly.yml (new flake-classify job only); scripts/nightly-flake-tracker.sh (--gh-run mode); tests/test-nightly-flake-tracker.sh | MEDIUM | see Wall in note | ready@2026-10-17T01:40Z | wave 2; depends: none (TEN-STABILITY-01 only matters for a green run). Goal: Add one nightly.yml job, flake-classify (needs all test jobs, if: always(), never sets the run conclusion). It downloads the bun-test job logs of this run via gh api. The 3-4 bun legs run identical loki-ts tests at one SHA. It feeds the logs to scripts/nightly-flake-tracker.sh and writes FLIP and STABLE-FAIL lines plus the BOARD: slice lines to the step summary. Extend the tracker with a '--gh-run RUN_ID' fetch mode so the workflow holds no parsing logic. Experimental bun=latest legs are labelled so a flip there is reported as drift. Wall: RED: test-nightly-flake-tracker.sh gains a --gh-run case with a stub gh serving two job logs at one SHA. In one log WC-01b is (pass), in the other it is (fail) [5004.82ms]. Expect 'FLIP <sha7> WC-01b'. Today --gh-run is a usage error (exit 2). GREEN: FLIP printed, exit 1; with both logs failing, STABLE-FAIL is printed. MUTATION: make the tracker ignore the [ms] suffix strip, and the FLIP case goes red. GATE: bash tests/test-nightly-flake-tracker.sh && bash tests/test-workflow-no-masked-failures.sh && python3 -m pytest -q tests/test_release_next_tag.py (nightly structure cases) && actionlint .github/workflows/nightly.yml if installed. The new job name must not start with 'Full suite (backstop)' (promote.yml:185 counts that prefix). Rules: FAILURE-CLASSES row first for any bug fix (D86); no CHANGELOG edits (Release Manager writes notes); DECISIONS numbers assigned by the Chief of Staff; reuse util/secure_scan.ts, the shared badge helper, keys_cmd export and the TS claude login probe instead of new copies; new CLI flags update autonomy/completions and the help-drift guard. |
1065
+ | TEN-STABILITY-07 | nightly classifies flips vs stable reds across same-SHA legs | .github/workflows/nightly.yml (new flake-classify job only); scripts/nightly-flake-tracker.sh (--gh-run mode); tests/test-nightly-flake-tracker.sh | MEDIUM | see Wall in note | building@2026-10-17T04:38Z | wave 2; depends: none (TEN-STABILITY-01 only matters for a green run). Goal: Add one nightly.yml job, flake-classify (needs all test jobs, if: always(), never sets the run conclusion). It downloads the bun-test job logs of this run via gh api. The 3-4 bun legs run identical loki-ts tests at one SHA. It feeds the logs to scripts/nightly-flake-tracker.sh and writes FLIP and STABLE-FAIL lines plus the BOARD: slice lines to the step summary. Extend the tracker with a '--gh-run RUN_ID' fetch mode so the workflow holds no parsing logic. Experimental bun=latest legs are labelled so a flip there is reported as drift. Wall: RED: test-nightly-flake-tracker.sh gains a --gh-run case with a stub gh serving two job logs at one SHA. In one log WC-01b is (pass), in the other it is (fail) [5004.82ms]. Expect 'FLIP <sha7> WC-01b'. Today --gh-run is a usage error (exit 2). GREEN: FLIP printed, exit 1; with both logs failing, STABLE-FAIL is printed. MUTATION: make the tracker ignore the [ms] suffix strip, and the FLIP case goes red. GATE: bash tests/test-nightly-flake-tracker.sh && bash tests/test-workflow-no-masked-failures.sh && python3 -m pytest -q tests/test_release_next_tag.py (nightly structure cases) && actionlint .github/workflows/nightly.yml if installed. The new job name must not start with 'Full suite (backstop)' (promote.yml:185 counts that prefix). Rules: FAILURE-CLASSES row first for any bug fix (D86); no CHANGELOG edits (Release Manager writes notes); DECISIONS numbers assigned by the Chief of Staff; reuse util/secure_scan.ts, the shared badge helper, keys_cmd export and the TS claude login probe instead of new copies; new CLI flags update autonomy/completions and the help-drift guard. |
1066
1066
  | TEN-FC-ROWS | FAILURE-CLASSES rows for every TEN bug-fix slice lacking one (QUALITY-01/02/03/07, COST-06, DEPLOY-08, STABILITY-01/05, UX-02) | docs/v10/FAILURE-CLASSES.md | LOW | bash tests/test-structural-checks.sh | released@2026-10-17T02:57Z | merge 8cdb33633, dist bd6348d77; TL APPROVE 7e6f47482 (structural 25/0); post-merge tsc 0 errors, 130 pass. wave 1; CTO critic MISSING item. One row per class with user-visible vs raw, law broken, siblings, mechanism, fixture. Rules: FAILURE-CLASSES row first for any bug fix (D86); no CHANGELOG edits (Release Manager writes notes); DECISIONS numbers assigned by the Chief of Staff; reuse util/secure_scan.ts, the shared badge helper, keys_cmd export and the TS claude login probe instead of new copies; new CLI flags update autonomy/completions and the help-drift guard. v11.17.13 npm next 11.17.13 |
1067
1067
  | TEN-CORE-TRIM | Free engine10 core headroom (4964 of 5000) by moving pure helpers out of engine10 into src/util with no behavior change | loki-ts/src/engine10/*, loki-ts/src/util/* | MEDIUM | cd loki-ts && bun test tests/engine10/ tests/runner/spawn_env_guard.test.ts && bunx tsc --noEmit | released@2026-10-17T02:57Z | merge 096174f2a, dist bd6348d77; TL APPROVE f0f82a4e8 (core 4931/5000, 143 pass); post-merge tsc 0 errors, 130 pass. wave 1; CTO critic MISSING item. Target at least 60 lines freed; budget guard must stay green; no logic change. Rules: FAILURE-CLASSES row first for any bug fix (D86); no CHANGELOG edits (Release Manager writes notes); DECISIONS numbers assigned by the Chief of Staff; reuse util/secure_scan.ts, the shared badge helper, keys_cmd export and the TS claude login probe instead of new copies; new CLI flags update autonomy/completions and the help-drift guard. v11.17.13 npm next 11.17.13 |
1068
1068
  | TEN-SECURE-SCAN-UTIL | One util/secure_scan.ts wrapper over secure-scan.py shared by TEN-GATES-06 and TEN-GATES-08 | loki-ts/src/util/secure_scan.ts (new: no TS owner of secure-scan.py exists), loki-ts/tests/util/secure_scan.test.ts | MEDIUM | cd loki-ts && bun test tests/util/secure_scan.test.ts && bunx tsc --noEmit | released@2026-10-17T02:57Z | merge 47a9e4aae, dist none; TL APPROVE 3c1ce036d (9 pass, tsc rc=0). wave 1; CTO critic MISSING item. Removes the duplicate wrappers the CTO critic found. Rules: FAILURE-CLASSES row first for any bug fix (D86); no CHANGELOG edits (Release Manager writes notes); DECISIONS numbers assigned by the Chief of Staff; reuse util/secure_scan.ts, the shared badge helper, keys_cmd export and the TS claude login probe instead of new copies; new CLI flags update autonomy/completions and the help-drift guard. v11.17.13 npm next 11.17.13 |
@@ -1075,22 +1075,22 @@ Source: ~/git/autonomi-dev/research/2026-09-30-adoption/SWARM-PROMPT-ADOPTION.md
1075
1075
  | TEN-COST-20 | C-F1 seeds ship tests | benchmarks C-F1 seeds | LOW | see note | released@2026-10-17T03:50Z | TL APPROVE 0d1a37eed Shipped in npm 11.17.15 (latest+next) or 11.17.16 (Release run success on e3d445460). |
1076
1076
  | TEN-COST-17 | Raw token classes in the Claude Code ledger | C-F1 harness ledger, test_model_pin.py | HIGH | pytest test_model_pin.py | released@2026-10-17T03:50Z | HIGH r2 APPROVE 232f1fbec Shipped in npm 11.17.15 (latest+next) or 11.17.16 (Release run success on e3d445460). |
1077
1077
  | TEN-RELEASE-INSTANT | Every release publishes npm latest and next immediately (D102) | .github/workflows/release.yml, promote.yml removed | HIGH | see note | released@2026-10-17T03:50Z | HIGH r3 APPROVE 7e0e38c77; D98 round-limit exception recorded under D99 Shipped in npm 11.17.15 (latest+next) or 11.17.16 (Release run success on e3d445460). |
1078
- | TEN-GATES-05b | Spec-derived auth probe: negation window fixes | autonomy/lib/functional-verify.py, tests/test_functional_verify.py | HIGH | pytest tests/test_functional_verify.py | building@2026-10-17T04:31Z | HIGH r2 BLOCK aaf27e569: trailing-slash redirect false green, curly apostrophe and article negation false reds; r3 under D99 |
1078
+ | TEN-GATES-05b | Spec-derived auth probe: negation window fixes | autonomy/lib/functional-verify.py, tests/test_functional_verify.py | HIGH | pytest tests/test_functional_verify.py | released@2026-10-17T04:48Z | HIGH r2 BLOCK aaf27e569: trailing-slash redirect false green, curly apostrophe and article negation false reds; r3 under D99 |
1079
1079
  | TEN-RELEASE-INSTANT-F1 | Empty CUR from a failed npm view fails closed; rename the stale publish step | .github/workflows/release.yml | LOW | see note | released@2026-10-17T03:50Z | TL APPROVE 29ca496f1, ships v11.17.16 Shipped in npm 11.17.15 (latest+next) or 11.17.16 (Release run success on e3d445460). |
1080
1080
  | TEN-COST-18-F1 | cost_claim: a non-object JSON row is skipped, not an AttributeError | C-F1 harness cost_claim | LOW | see note | released@2026-10-17T03:50Z | TL APPROVE 924cec1c8, ships v11.17.16 Shipped in npm 11.17.15 (latest+next) or 11.17.16 (Release run success on e3d445460). |
1081
1081
  | TEN-GROUP-AUTH-F1 | kpis iteration_count does not count group cost records | loki-ts kpis | LOW | see note | released@2026-10-17T04:31Z | r1 BLOCK 1c59103ad (writer kind unasserted); r2 adds writer-reader test and stats.ts sibling |
1082
- | TEN-COST-09 | Skip a Wall that cannot run | engine10 wall stage | HIGH | see note | review@2026-10-17T04:31Z | architect cost plan |
1083
- | TEN-COST-10 | Plan on haiku for small and normal tasks | engine10 plan stage | MEDIUM | see note | building@2026-10-17T04:31Z | architect cost plan |
1084
- | TEN-COST-11 | Wall on haiku, re-authored on sonnet on failure | engine10 wall stage | HIGH | see note | ready@2026-10-17T03:30Z | architect cost plan |
1085
- | TEN-COST-12 | 5-minute cache TTL by default | runner cache settings | MEDIUM | see note | building@2026-10-17T04:31Z | architect cost plan |
1082
+ | TEN-COST-09 | Skip a Wall that cannot run | engine10 wall stage | HIGH | see note | released@2026-10-17T04:48Z | architect cost plan |
1083
+ | TEN-COST-10 | Plan on haiku for small and normal tasks | engine10 plan stage | MEDIUM | see note | rejected@2026-10-17T04:35Z | D99: FC-35 pins the router-on plan to opus and router-off must stay byte-identical, so the haiku plan pin was dead code (HIGH BLOCK bc80a88b6); quality outranks cost. architect cost plan |
1084
+ | TEN-COST-11 | Wall on haiku, re-authored on sonnet on failure | engine10 wall stage | HIGH | see note | building@2026-10-17T04:43Z | architect cost plan |
1085
+ | TEN-COST-12 | 5-minute cache TTL by default | runner cache settings | MEDIUM | see note | released@2026-10-17T04:35Z | architect cost plan |
1086
1086
  | TEN-COST-13 | Lean prefix by default | runner prompt prefix | MEDIUM | see note | released@2026-10-17T04:31Z | architect cost plan |
1087
1087
  | TEN-COST-14 | Wall brief output budget | engine10 wall brief | LOW | see note | released@2026-10-17T04:24Z | architect cost plan |
1088
- | TEN-COST-15 | Plan output trim | engine10 plan stage | LOW | see note | ready@2026-10-17T03:30Z | architect cost plan |
1088
+ | TEN-COST-15 | Plan output trim | engine10 plan stage | LOW | see note | parked@2026-10-17T04:35Z | parked with TEN-COST-10 (rejected). architect cost plan |
1089
1089
  | TEN-COST-16 | Implement on haiku first (opt-in) | engine10 implement stage | HIGH | see note | building@2026-10-17T04:15Z | architect cost plan |
1090
1090
  | TEN-COST-19 | Group cost in loki rows of C-F1 | C-F1 harness | LOW | see note | ready@2026-10-17T03:30Z | after COST-04 |
1091
1091
  | TEN-COST-21 | C-F1 .venv and keep_evidence | C-F1 harness | LOW | see note | ready@2026-10-17T03:30Z | after COST-04 and COST-20 |
1092
1092
  | TEN-COST-22 | Cache read pricing correction | model-pricing.json | LOW | see note | rejected@2026-10-17T03:30Z | premise false: Sonnet 5.5 cache read is $0.10 (0.05x) already |
1093
- | TEN-COST-23 | Investigate multi-unit launcher exit 1 | features/speed launcher | HIGH | see note | building@2026-10-17T04:31Z | architect cost plan |
1093
+ | TEN-COST-23 | Investigate multi-unit launcher exit 1 | features/speed launcher | HIGH | see note | released@2026-10-17T04:35Z | architect cost plan |
1094
1094
  | TEN-COST-24 | Opt-in Batch API path for single-shot judge calls under an API key | judge call sites | MEDIUM | see note | building@2026-10-17T04:15Z | never used in loki start; subscription runs gain nothing from batch |
1095
1095
  | TEN-GATES-03-F1 | verify --require-exogenous fails closed with --allow-unsigned and ignores zero-test checks | loki-ts/src/engine10/verify_cmd.ts; loki-ts/tests/engine10/verify_cmd.test.ts | HIGH | an UNSIGNED agent-only receipt with --require-exogenous --allow-unsigned exits 4; an exogenous pass with n=0 does not count toward k | building@2026-10-17T04:15Z | from GATES-03 HIGH review non-blocking findings 1 and 2; batch O |
1096
1096
  | TEN-ADOPTION-03-F1 | proof share scan catches tokens (ghp_, AKIA, sk-ant) and proof registry lists badge, md, bundle | autonomy/lib/secure-scan.py or loki-ts/src/util/secure_scan.ts; loki-ts/src/commands/proof.ts; loki-ts/src/cli/registry.ts; tests | MEDIUM | a bundle with a ghp_ token in events.jsonl shows a finding in the share preview; registry proof subcommands include badge, md, bundle | building@2026-10-17T04:15Z | from ADOPTION-03 TL review notes 1 and 2; batch O |
@@ -172,7 +172,7 @@ Classes: KEEP-MODERN (v10-native or engine-neutral), UPDATE (live but needs mode
172
172
  - enterprise: 2
173
173
  - explain: 5
174
174
  - export: 6
175
- - github: 5
175
+ - github: 6
176
176
  - import: 1
177
177
  - init: 21
178
178
  - issue: 2
@@ -997,3 +997,10 @@ L0 review rule (ENGINE-LAWS.md L0): a fix that adds an `if` or a regex about the
997
997
  - Siblings: deep.ts was the only engine10 stage importing runner/quality_gates.ts (git grep); xreview.ts already imports providers/claude_flags.ts. pack-npm also lacked a loki-ts install, fixed in 386e73f32.
998
998
  - Mechanism: REVIEW_GUARD_DENYLIST moves to providers/claude_flags.ts; quality_gates.ts re-exports it; deep.ts imports the leaf.
999
999
  - Fixture: tests/test-control-plane.sh builds serve.ts with a metafile and fails if runner/sdk_invoker appears (red with the old import: 3 hits; green: 0).
1000
+
1001
+ ## FC-TEN-COST-23 Decomposer emits a unit with an empty write set and unit mode refuses it (EMPTY-WRITESET-UNIT)
1002
+ - User-visible vs raw: every multi-unit run of coord-1-api-web exited 1 with "unit launcher exit 1; 2 unit(s) did not pass" after about 50s, the spurious unit having failed with exit 2 in 1s and $0; the raw reason ("unit mode was requested but its spec file is invalid") never reached the user.
1003
+ - Law broken: a decomposer output must be runnable by the stage that consumes it; unit_mode.ts parseText rejects writeSet.length === 0 and the engine refuses an unfenced run, so a file-less prose bullet ("`limit` must be an int ...") became a unit that could never start.
1004
+ - Siblings: decompose.ts items with no matching file (also shared-file-only items); fix_units.ts units (always carry a write set); the u1 PARTIAL exit 1 in the same evidence is the separate no-test-runner seed cause (TEN-COST-20, TEN-COST-21), not this class.
1005
+ - Mechanism: decompose() folds every item that names no write-set file into the first unit that owns files; if no item names a file all items form one unit and route.ts falls back to the sequential run (fewer than 2 units).
1006
+ - Fixture: tests/engine10/decompose.test.ts "no unit has an empty write set" and "a spec where no item names a file collapses to one unit"; repro: LOKI_UNIT_SPEC with writeSet [] and bin/loki start gives rc=2 "spec file is invalid".
@@ -2427,3 +2427,10 @@ The swarm is stopped: .loki/V10-STOP exists, the loop has no wake-ups, and the c
2427
2427
 
2428
2428
  ## 2026-10-17T04:31Z (CoS) v11.17.19: COST-13 and GROUP-AUTH-F1
2429
2429
  - v11.17.17 publish-npm success (Release run on 1fa2b21cc; npm-visible job pending on propagation). v11.17.18 (COST-14) held behind that run, now pushed together with v11.17.19. TEN-COST-13 TL APPROVE 0b15dc2ba (session 225 pass, runner 1293 pass, 2 mutations caught). TEN-GROUP-AUTH-F1 r2 TL APPROVE 367b4e042 (writer, stats and shared predicate mutations each fail a test). Batch L blocks: GATES-05b r3 BLOCK 7eef05bcb (base_url prefix false green, regex tail unguarded); COST-12 BLOCK b96ffb5f9 (call-site wiring untested); COST-10 BLOCK a0bd42473 (router-off goldens red); COST-09 reviewer returned no verdict; COST-23 build failed on the fixed USER/LOGNAME env drop. r2 rounds dispatched. TEN-QUALITY-01 building; TEN-STABILITY-03 parked under D102.
2430
+
2431
+ ## 2026-10-17T04:35Z (CoS) v11.17.20: P0 CI fix, QUALITY-01, COST-12, COST-23
2432
+ - v11.17.19 Release run success (npm next 11.17.19, latest 11.17.17 propagating). P0-CI-RED TL APPROVE ec63f4398 (6 mutations each caught). TEN-QUALITY-01 r2 HIGH APPROVE 80dd9af12 (total cap byte-exact 6144 on CJK, signature stable, holdout and redaction mutations caught). TEN-COST-12 r2 TL APPROVE e177b6cd2 (both call sites pinned). TEN-COST-23 TL APPROVE 8c0bbaaf8. Decisions under D99: TEN-COST-10 rejected (router-on plan stays pinned to opus by FC-35, router-off stays byte-identical, so the haiku plan pin was dead code; quality outranks cost); TEN-COST-15 parked with it. TEN-COST-09 r2: skip the Wall only when holdout is off (r1 HIGH BLOCK: skipping discarded the holdout run). TEN-GATES-05b r5: resolve relative Location headers before comparing.
2433
+
2434
+ ## 2026-10-17T04:48Z (CoS) v11.17.21
2435
+
2436
+ v11.17.20 published (Release run success on e2b6b77d2; npm latest 11.17.20, next 11.17.20). Security Audit red on e2b6b77d2: gitleaks found 2 leaks because the merge-commit fingerprints in .gitleaksignore were mangled by the zsh :l modifier; fixed, local gitleaks over 10eb771d8..HEAD rc=0 "no leaks found". Ships TEN-COST-09 r2 (HIGH APPROVE 660256752), TEN-GATES-05b r5 (HIGH APPROVE 8dda21a8d), TEN-COST-09-F1 (TL APPROVE 5a1a3d36c). Batch O (6), batch P (DEPLOY-02, DEPLOY-04, QUALITY-05, UX-01, GATES-04, STABILITY-07) and batch Q (UX-05, COST-11) building.