loki-mode 11.74.2 → 11.75.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/SKILL.md +2 -3
- package/VERSION +1 -1
- package/autonomy/completion-council.sh +10 -10
- package/autonomy/council-v2.sh +4 -4
- package/autonomy/grill.sh +1 -1
- package/autonomy/lib/ablation.py +22 -2
- package/autonomy/lib/browser-open.sh +1 -1
- package/autonomy/lib/chat.sh +1 -1
- package/autonomy/lib/cockpit-render.sh +1 -1
- package/autonomy/lib/done-recognition.sh +4 -4
- package/autonomy/lib/efficiency_cost.py +1 -1
- package/autonomy/lib/engine10-push.sh +2 -2
- package/autonomy/lib/prd-enrich.sh +1 -1
- package/autonomy/lib/proof-check.sh +1 -1
- package/autonomy/lib/proof-generator.py +3 -3
- package/autonomy/lib/proof-pr.sh +1 -1
- package/autonomy/lib/skill-link-heal.sh +1 -1
- package/autonomy/lib/voter-agents.sh +1 -1
- package/autonomy/loki +26 -37
- package/autonomy/prd-checklist.sh +1 -1
- package/autonomy/receipt_jwt.py +1 -1
- package/autonomy/run.sh +28 -28
- package/autonomy/trigger-schedule.py +6 -414
- package/autonomy/tui.sh +1 -1
- package/autonomy/verify.sh +4 -4
- package/completions/loki.bash +0 -5
- package/dashboard/__init__.py +1 -1
- package/docs/ARCHITECTURE.md +1 -2
- package/docs/CLI-REFERENCE.md +1 -1
- package/docs/COMPONENTS.md +1 -1
- package/docs/INSTALLATION.md +1 -1
- package/docs/ROUTING-EVIDENCE.md +1 -2
- package/docs/V10-RESEARCH.md +1 -1
- package/docs/dev/architecture-reference.md +3 -7
- package/docs/dev/project-structure.md +1 -4
- package/docs/dev/release-checklist.md +13 -31
- package/docs/research-2026-07/OBSERVABILITY-TOOL-SPEC.md +1 -1
- package/docs/v11/MARKET-SLICES.md +1 -1
- package/docs/v11/REGISTRIES.md +1 -1
- package/docs/v11/ROUTER-1.md +2 -2
- package/loki-ts/dist/loki.js +2 -2
- package/mcp/__init__.py +1 -1
- package/package.json +2 -2
- package/plugins/loki-mode/.claude-plugin/plugin.json +1 -1
- package/skills/extending.md +2 -3
- package/skills/factory-operations.md +11 -18
- package/skills/release-cadence.md +2 -2
- package/web-app/dist/assets/{AdminPage-jkjilfbl.js → AdminPage-CTwi8SUX.js} +1 -1
- package/web-app/dist/assets/{Avatar-bd5JWkSJ.js → Avatar-DVtGtLkJ.js} +1 -1
- package/web-app/dist/assets/{Badge-DVRit2Xw.js → Badge-rwKzz0Pe.js} +1 -1
- package/web-app/dist/assets/{Button-BNAB-pVZ.js → Button-nIsPDfsQ.js} +1 -1
- package/web-app/dist/assets/{CockpitPage-DpG29h_w.js → CockpitPage-BCeDpoWa.js} +1 -1
- package/web-app/dist/assets/{ComparePage-Dasg5V41.js → ComparePage-CYIYanVq.js} +1 -1
- package/web-app/dist/assets/{ErrorBoundary-DJojse6b.js → ErrorBoundary-Bkz6HqWp.js} +1 -1
- package/web-app/dist/assets/{EvidenceReceiptPanel-Blxw7_u1.js → EvidenceReceiptPanel-DZT2Np4F.js} +1 -1
- package/web-app/dist/assets/{GitHubIssuesPanel-BBvSFj80.js → GitHubIssuesPanel-Bzla91Lu.js} +1 -1
- package/web-app/dist/assets/{GitHubPRsPanel-BCIKeSBg.js → GitHubPRsPanel-FjT-Xn5t.js} +1 -1
- package/web-app/dist/assets/{HomePage-C7d__oNG.js → HomePage-pXgmRGLt.js} +2 -2
- package/web-app/dist/assets/{LoginPage-BXljL3yY.js → LoginPage-CnmpE28B.js} +1 -1
- package/web-app/dist/assets/{MagicPage-Xjkts_yE.js → MagicPage-CuSeGsLq.js} +1 -1
- package/web-app/dist/assets/{MetricsPage-kQvVp-j2.js → MetricsPage-Bg3PkBOU.js} +1 -1
- package/web-app/dist/assets/{NotFoundPage-D-4ZlEaO.js → NotFoundPage-uzBtZNV-.js} +1 -1
- package/web-app/dist/assets/{ProjectPage-DfzR5RXP.js → ProjectPage-Dacki8Xr.js} +3 -3
- package/web-app/dist/assets/{ProjectsPage-DFDsWzkV.js → ProjectsPage-BRGjksXG.js} +1 -1
- package/web-app/dist/assets/{SettingsPage-CLPIoYT3.js → SettingsPage-BbNf3fEJ.js} +1 -1
- package/web-app/dist/assets/{ShowcasePage-PZKkyGeY.js → ShowcasePage-XX4830sX.js} +1 -1
- package/web-app/dist/assets/{SystemSettingsPage-BsBlcnzo.js → SystemSettingsPage-DOhQeXa6.js} +1 -1
- package/web-app/dist/assets/{TeamsPage-BSjgNhoU.js → TeamsPage-2reIRUp_.js} +1 -1
- package/web-app/dist/assets/{TemplatesPage-W2KeAzbg.js → TemplatesPage-BUsLEWHW.js} +1 -1
- package/web-app/dist/assets/{TerminalOutput-BjroTiCC.js → TerminalOutput-BrBDcgzC.js} +1 -1
- package/web-app/dist/assets/{activity-BXZ5YYes.js → activity-B6AZpgmb.js} +1 -1
- package/web-app/dist/assets/{bell-D1urp5pa.js → bell-CB792A7S.js} +1 -1
- package/web-app/dist/assets/{bot-Chedf2bF.js → bot-uQZwOFAn.js} +1 -1
- package/web-app/dist/assets/{check-DhaCuOCV.js → check-DrtG0lIZ.js} +1 -1
- package/web-app/dist/assets/{chevron-left-D7BpQyA6.js → chevron-left-CrsJSAqQ.js} +1 -1
- package/web-app/dist/assets/{circle-alert-DnGvQ_AQ.js → circle-alert-BUCly4p3.js} +1 -1
- package/web-app/dist/assets/{clock-CqfxWhHM.js → clock-B2IT9SnE.js} +1 -1
- package/web-app/dist/assets/{cloud-BKxp5AWB.js → cloud-CN6Ux7Q7.js} +1 -1
- package/web-app/dist/assets/{code-xml-BDQ6GBtt.js → code-xml-BEm8PWnK.js} +1 -1
- package/web-app/dist/assets/{database-BmpEx1y_.js → database-cHe5Fgu8.js} +1 -1
- package/web-app/dist/assets/{dollar-sign-DYNY9R_C.js → dollar-sign-BVmP4YrE.js} +1 -1
- package/web-app/dist/assets/{file-code-corner-BJi0IBFd.js → file-code-corner-D-m-NrwO.js} +1 -1
- package/web-app/dist/assets/{file-plus-Dqyb2bcQ.js → file-plus-6mCjIzAB.js} +1 -1
- package/web-app/dist/assets/{globe-DPh4RWfM.js → globe-vcWOujwU.js} +1 -1
- package/web-app/dist/assets/{hammer-B3xnuoA1.js → hammer-D4nZFpO2.js} +1 -1
- package/web-app/dist/assets/{index-BpX8DcTr.js → index-u8toJ43r.js} +3 -3
- package/web-app/dist/assets/{layers-BRCmyCW8.js → layers-CNhYLop8.js} +1 -1
- package/web-app/dist/assets/{loader-circle-n07Pky0M.js → loader-circle-Vl7XIMV6.js} +1 -1
- package/web-app/dist/assets/{lock-BWqOuQmS.js → lock-SW_KwAvf.js} +1 -1
- package/web-app/dist/assets/{package-BJlB_Z-Z.js → package-QPK-7Ej1.js} +1 -1
- package/web-app/dist/assets/{plus-oH17BZu2.js → plus-DUgAlgCB.js} +1 -1
- package/web-app/dist/assets/{refresh-cw-CPQ476LL.js → refresh-cw-LfUksPHq.js} +1 -1
- package/web-app/dist/assets/{rotate-ccw-7hLvOcnS.js → rotate-ccw-CMbuouVq.js} +1 -1
- package/web-app/dist/assets/{scroll-text-BCmLauQn.js → scroll-text-C_FxBmNQ.js} +1 -1
- package/web-app/dist/assets/{server-DfTfvW84.js → server-7UJe9Jqt.js} +1 -1
- package/web-app/dist/assets/{shield-alert-CaeGRq19.js → shield-alert-BMuu6fYB.js} +1 -1
- package/web-app/dist/assets/{thumbs-up-Dz-l2GPC.js → thumbs-up-Bhs0d2Gp.js} +1 -1
- package/web-app/dist/assets/{trash-2-B-OsDmSo.js → trash-2-BZKxv49w.js} +1 -1
- package/web-app/dist/assets/{trending-down-CXTFOxzq.js → trending-down-DKeCMZek.js} +1 -1
- package/web-app/dist/assets/{trending-up-FQEdqr3v.js → trending-up-43_9fShg.js} +1 -1
- package/web-app/dist/assets/{upload-CacWSNTg.js → upload-pV3irPEW.js} +1 -1
- package/web-app/dist/assets/{usePolling-cIjZ9qd2.js → usePolling-CoZQM-WL.js} +1 -1
- package/web-app/dist/assets/{user-DAouWFHi.js → user-CMl7dXvC.js} +1 -1
- package/web-app/dist/index.html +1 -1
- package/autonomy/company-seats.json +0 -82
- package/docs/COMPETITIVE-INTEL-2026-09.md +0 -444
- package/docs/FOUNDER-DECISIONS-TRUST-SEMANTICS-2026-08-01.md +0 -145
- package/docs/FOUNDER-STATUS-AND-DECISIONS-2026-07-01.md +0 -132
- package/docs/LOKI-10-BUILD-PROMPT.md +0 -350
- package/docs/STRATEGY-2026-2028.md +0 -124
- package/docs/V10-VISION.md +0 -161
- package/docs/v10/ADOPTION-PLAN.md +0 -375
- package/docs/v10/ARCHITECT-CUTS.md +0 -744
- package/docs/v10/BACKLOG.md +0 -231
- package/docs/v10/BOARD.md +0 -1403
- package/docs/v10/CONTROL-PLANE.md +0 -120
- package/docs/v10/CONTROL.md +0 -36
- package/docs/v10/CP-ASK-PLAN.md +0 -85
- package/docs/v10/CP-ENTERPRISE-UI.md +0 -537
- package/docs/v10/D51-PHASE-B.md +0 -120
- package/docs/v10/D61-SPEED.md +0 -105
- package/docs/v10/D63-CARDS.md +0 -354
- package/docs/v10/DECISIONS.md +0 -915
- package/docs/v10/E2E-D65.md +0 -123
- package/docs/v10/ENGINE-LAWS.md +0 -163
- package/docs/v10/ENGINE-MEASURE.md +0 -69
- package/docs/v10/ENGINE.md +0 -743
- package/docs/v10/FAILURE-CLASSES.md +0 -2026
- package/docs/v10/FC21B-FC22-PLAN.md +0 -107
- package/docs/v10/FIRST-RUN-GATE.md +0 -39
- package/docs/v10/FOUNDER-QUEUE.md +0 -29
- package/docs/v10/GAP-RESEARCH-1003.md +0 -32
- package/docs/v10/GUARDS.md +0 -883
- package/docs/v10/L0-WAVE1.md +0 -81
- package/docs/v10/LEGACY-REMOVAL.md +0 -408
- package/docs/v10/MEDIUM-ANALYSIS.md +0 -346
- package/docs/v10/METRICS.md +0 -645
- package/docs/v10/MODERNIZE.md +0 -437
- package/docs/v10/OPENCODE-PARITY-PLAN.md +0 -84
- package/docs/v10/OPERATING-MODEL.md +0 -60
- package/docs/v10/PLAN-V12.md +0 -896
- package/docs/v10/PROGRESS.md +0 -2735
- package/docs/v10/RELEASE-11.md +0 -77
- package/docs/v10/RETRO-2026.md +0 -650
- package/docs/v10/ROADMAP-D63.md +0 -35
- package/docs/v10/SCALE.md +0 -140
- package/docs/v10/SCORECARD-PLAN.md +0 -250
- package/docs/v10/SWARM-PROMPT.md +0 -98
- package/docs/v10/SWARM.md +0 -293
- package/docs/v10/cp-redesign/PARITY.md +0 -188
- package/docs/v10/cp-redesign/legacy/INDEX.md +0 -1167
- package/docs/v10/roadmap-10/01-measurement.md +0 -113
- package/docs/v10/roadmap-10/02-cost.md +0 -75
- package/docs/v10/roadmap-10/03-speed.md +0 -65
- package/docs/v10/roadmap-10/04-first-run.md +0 -61
- package/docs/v10/roadmap-10/05-deploy.md +0 -61
- package/docs/v10/roadmap-10/06-stability.md +0 -64
- package/docs/v10/roadmap-10/07-quality.md +0 -57
- package/docs/v10/roadmap-10/08-proof.md +0 -48
- package/docs/v10/roadmap-10/09-safety.md +0 -74
- package/docs/v10/roadmap-10/README.md +0 -1464
- package/skills/sdlc-fleet.md +0 -170
- package/tools/cockpit/SPEC.md +0 -275
- package/tools/cockpit/index.html +0 -146
- package/tools/cockpit/roi-basis.json +0 -33
- package/tools/cockpit/server.py +0 -946
package/docs/v10/MODERNIZE.md
DELETED
|
@@ -1,437 +0,0 @@
|
|
|
1
|
-
# Loki 10 Part 2: `loki modernize` design
|
|
2
|
-
|
|
3
|
-
Source: the D30 directive as dispatched on 2026-09-28 (PROGRESS.md 01:51Z entry). D30 has no row in DECISIONS.md yet. The moat order holds: nothing here weakens the Seal, the Wall, Rule of Two or honest verdicts. I read main at 677f88dd. Every file:line cited below comes from that tree.
|
|
4
|
-
|
|
5
|
-
## 1. Goals and non-goals
|
|
6
|
-
|
|
7
|
-
**Goals**
|
|
8
|
-
- One command, `loki modernize <repo> --to "<target>"`, converts a codebase with no human steps and survives restarts.
|
|
9
|
-
- Every converted unit has a Wall made of behavior captured from the OLD code before any change.
|
|
10
|
-
- Claims stop exactly where equivalence data stops. Units without proof are listed as NOT PROVEN, with a reason.
|
|
11
|
-
- Cost, wall time and risk are printed before any model spend. `--budget` is a hard stop.
|
|
12
|
-
- First targets: Python 2 to 3, then Java 8 to 21. COBOL to Java and AngularJS to React come after the eval gates pass on the first two (section 6).
|
|
13
|
-
|
|
14
|
-
**Non-goals**
|
|
15
|
-
- No change to the legacy `loki migrate` (`autonomy/loki:17489`, `dashboard/migration_engine.py`). It is legacy engine code, `autonomy/loki` is on the no-edit list, and its phase gates are agent-judged rather than behavior-captured. It stays as it is.
|
|
16
|
-
- No model-judged equivalence. Equivalence is a deterministic diff over captured cases.
|
|
17
|
-
- No claim of "complete" for a codebase unless every unit is proven equivalent.
|
|
18
|
-
- No new always-on prompt text outside the cache-stable prefix.
|
|
19
|
-
- No flip of the engine default. `loki modernize` reaches engine10 whatever the default is (section 2).
|
|
20
|
-
|
|
21
|
-
## 2. CLI and flags
|
|
22
|
-
|
|
23
|
-
```
|
|
24
|
-
loki modernize <repo> --to "<target>" [--budget USD] [--workers N] [--remote URL]
|
|
25
|
-
[--resume <mid>] [--dry-run] [--provider P] [--no-pr]
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
| Flag | Meaning |
|
|
29
|
-
|---|---|
|
|
30
|
-
| `--to` | Required. Resolves to a target module: `python3`, `java21`. Later: `java` from COBOL, `react`. An unknown target exits 2 and lists the supported ones. |
|
|
31
|
-
| `--budget` | USD hard cap for the whole modernization. Dispatch stops when spent plus the in-flight estimate would exceed it. |
|
|
32
|
-
| `--workers` | Concurrent unit workers. Default 4, max 32 locally. With `--remote`, the cap comes from the cluster. |
|
|
33
|
-
| `--resume <mid>` | Resumes from the modernization event log at unit level (section 5). |
|
|
34
|
-
| `--dry-run` | Runs Inventory only. Prints the unit count, wave plan and estimate, then exits 0 with zero model spend. |
|
|
35
|
-
| `--remote URL` | Dispatches units to POST /jobs on a cluster (section 3.4). |
|
|
36
|
-
|
|
37
|
-
**Routing**
|
|
38
|
-
- `bin/loki` gets one `modernize)` arm ahead of the `LOKI_ENGINE` block that execs `bun "$BUN_CLI" engine10 modernize "$@"`, so the legacy default tonight does not block it.
|
|
39
|
-
- The engine10 `cli.ts` TABLE gets `modernize: { module: "modernize/cli.ts", fn: "main" }`.
|
|
40
|
-
- Without bun, the command exits 1 with a one-line hint. It never falls back to `loki migrate`.
|
|
41
|
-
|
|
42
|
-
**Modernization id:** `mod-<utc>-<short>`. All state lives under `<repo>/.loki/modernize/<mid>/`.
|
|
43
|
-
|
|
44
|
-
## 3. The pipeline
|
|
45
|
-
|
|
46
|
-
**Event log**
|
|
47
|
-
- Each modernization has one append-only log at `.loki/modernize/<mid>/events.jsonl`.
|
|
48
|
-
- It reuses `events.ts` (`EventLog`, `fold`, `tail`) and the supervisor's running-sha256 single-writer pattern (`supervisor.ts:84 SupervisorLog`).
|
|
49
|
-
- `validateEnvelope` (`events.ts:13`) accepts any non-empty type string, so the modernize event types live in `modernize/types.ts` and `engine10/types.ts` stays unedited.
|
|
50
|
-
- Each unit is an ordinary v10 run under `.loki/runs/<run-id>/`. The modernize log references it by run id.
|
|
51
|
-
|
|
52
|
-
### 3.1 Inventory (deterministic, no model spend)
|
|
53
|
-
|
|
54
|
-
**Inputs:** the repo path and the target.
|
|
55
|
-
|
|
56
|
-
**Work**
|
|
57
|
-
- **Files:** `repomap.listRepoFiles` (`repomap.ts:29`, `git ls-files`), with no file cap in this mode.
|
|
58
|
-
- **Languages and build system:** detected by extension and marker files (`setup.py`, `pyproject.toml`, `tox.ini`, `pom.xml`, `build.gradle`).
|
|
59
|
-
- **Entry points:** console scripts, `__main__`, `main(String[])`, servlet or web.xml.
|
|
60
|
-
- **Existing tests:** `testmap.buildTestMap` (`testmap.ts:174`).
|
|
61
|
-
- **Dependency graph**
|
|
62
|
-
- Python: import extraction with the stdlib `tokenize`, which lexes Python 2 source (print statements included) where py3 `ast` cannot parse it.
|
|
63
|
-
- Java: `jdeps -verbose:class` over compiled classes, since jdeps ships with the JDK. If the build fails, fall back to scanning `import` lines and record the fallback in the inventory.
|
|
64
|
-
- **Clustering:** Tarjan SCC condensation, packing of nodes into units under the sizing rule (section 4), and topological layers of the unit DAG, which become the waves.
|
|
65
|
-
- **Risk score per unit:** size, fan-in, test coverage of the existing suite, and a legacy score (density of removed APIs: py2 `print`, `unicode`, `iteritems`; Java JAXB, `sun.*`, finalizers, `SecurityManager`).
|
|
66
|
-
|
|
67
|
-
**Prior art examined and not reused**
|
|
68
|
-
- `project_graph.ts` discovers cross-project app members, not a code dependency graph.
|
|
69
|
-
- `loki_graph_query` (`mcp/server.py:2531`) needs an external graphify build. When `graphify-out/` exists, Inventory reads its edges as a cross-check only and never depends on them.
|
|
70
|
-
|
|
71
|
-
**Outputs:** `inventory.json` (files, languages, build, entry points, tests, graph edges, units, waves) and `estimate.json`.
|
|
72
|
-
|
|
73
|
-
**Estimate**
|
|
74
|
-
- Cost: units x per-unit cost prior. The prior comes from the cache (`eta.ts` history, `cost.ts` records), else from the Legacy-Bench pilot median.
|
|
75
|
-
- Wall time: critical path of waves x p50 unit time / workers.
|
|
76
|
-
- Risk: each unit's risk class.
|
|
77
|
-
- The estimate prints before any spend. A missing prior prints "not measured", never $0.
|
|
78
|
-
|
|
79
|
-
**Events:** `modernize.started`, `inventory.completed`, `estimate.printed`.
|
|
80
|
-
|
|
81
|
-
**Failure handling:** an unparseable file becomes its own unit with a risk flag. It is not dropped. An undetectable build system stops the run with exit 2 before any spend.
|
|
82
|
-
|
|
83
|
-
### 3.2 Oracle capture (before any change)
|
|
84
|
-
|
|
85
|
-
**Inputs:** the units, plus the OLD runtime (python2.7, or a JDK 8 toolchain).
|
|
86
|
-
|
|
87
|
-
**Old runtime:** its location is taken from `LOKI_MOD_OLD_RUNTIME`, or from PATH discovery. If it is missing, capture fails and every unit is NOT PROVEN "old runtime unavailable". Capture is never skipped.
|
|
88
|
-
|
|
89
|
-
**Work**
|
|
90
|
-
- Run the existing suite under the old runtime with branch coverage: coverage.py branch mode on 2.7, or the JaCoCo agent.
|
|
91
|
-
- Record I/O at unit boundaries (section 7).
|
|
92
|
-
- Run a coverage-guided input search. A read-only provider session sees the old unit's source and the uncovered branches, and proposes inputs. The harness executes them and keeps only the inputs that add branches. It stops at a plateau (two rounds with no gain) or at the unit's capture budget. This follows the witness-search result: 91.9% branch coverage with every generated case at parity (V10-RESEARCH section 7).
|
|
93
|
-
- Replay every case twice on the old runtime. A field that differs between the replays is marked nondeterministic.
|
|
94
|
-
|
|
95
|
-
**Seal**
|
|
96
|
-
- Each case file gets a sha256 and a sealed copy under `.loki/modernize/<mid>/oracle/<unit>/`, the same pattern as `wall.sealed`.
|
|
97
|
-
- About 20% of cases per unit are held out. The implementer never sees them, and they are checked only at verify (V10-RESEARCH section 1: visible oracles get inlined).
|
|
98
|
-
|
|
99
|
-
**Coverage floor**
|
|
100
|
-
- A unit whose captured branch coverage is below 80% gets one more capture round.
|
|
101
|
-
- If it is still below 80%, it is flagged `NOT PROVEN: coverage <x>% below 80%` in the up-front report and still converted. Its verdict can never exceed PARTIAL.
|
|
102
|
-
|
|
103
|
-
**Outputs:** `oracle/<unit>/cases.jsonl`, `oracle/<unit>/coverage.json`, `oracle/<unit>/sealed.json` (the hashes).
|
|
104
|
-
|
|
105
|
-
**Events:** `oracle.captured` (per unit: cases, held_out, branch_pct), `oracle.flagged`.
|
|
106
|
-
|
|
107
|
-
**Honest-verdict rule:** a boundary whose text or bytes type is undeclared, or a field that is nondeterministic with no declared normalizer, is NOT PROVEN for that field. It is never auto-masked.
|
|
108
|
-
|
|
109
|
-
### 3.3 Plan in waves
|
|
110
|
-
|
|
111
|
-
**Inputs:** `inventory.json` and the oracle results.
|
|
112
|
-
|
|
113
|
-
**Work**
|
|
114
|
-
- Waves are topological layers, leaves first. A dependency cycle is one unit. It is never split across waves.
|
|
115
|
-
- Each unit card holds: unit id, files, entry symbols, target, dependencies, oracle path, risk, model route and caps.
|
|
116
|
-
- The target module adds the strangler adapter (section 8), so old and new coexist and every wave builds, runs and ships alone.
|
|
117
|
-
|
|
118
|
-
**Output:** `plan.json` plus `units/<unit>.md`, the brief each unit run receives. **Event:** `unit.planned`.
|
|
119
|
-
|
|
120
|
-
**Failure handling:** a wave that cannot build alone is merged into the next wave and the merge is recorded. The plan never ships a wave that needs a later one.
|
|
121
|
-
|
|
122
|
-
### 3.4 Execute in parallel
|
|
123
|
-
|
|
124
|
-
**Unit runs**
|
|
125
|
-
- Each unit is one v10 engine run (`runSupervisor`, `supervisor.ts:174`) in its own git worktree. That keeps a single writer per unit (V10-RESEARCH section 4).
|
|
126
|
-
- The brief is the unit card. The Wall is the sealed oracle plus the target-conformance check (section 7).
|
|
127
|
-
- Deterministic codemods run first when installed: `python-modernize` or futurize for py2 to 3, OpenRewrite `UpgradeToJava21` for Java. The model fixes only what the codemods miss. A missing tool emits `codemod.skipped`, and the model does the whole unit.
|
|
128
|
-
|
|
129
|
-
**Model cascade**
|
|
130
|
-
- Sonnet first. Opus only on a failed Wall or failed test. Escalation is triggered by a failed check, never by self-assessment (V10-RESEARCH section 3).
|
|
131
|
-
- Units in the top legacy-risk class go straight to opus.
|
|
132
|
-
- A unit that fails once gets best-of-2: two fresh sessions from the same base. The first variant that is equivalent on all cases, held-out cases included, wins.
|
|
133
|
-
|
|
134
|
-
**Workers**
|
|
135
|
-
- Local mode: N workers under a coordinator in `modernize/scheduler.ts`. The coordinator is the modernize log's single writer.
|
|
136
|
-
- Remote mode:
|
|
137
|
-
- Units go to POST /jobs (`autonomy/trigger-server.py:13`) as `{"kind":"unit","card":...,"base":<sha>}`, bearer-token authenticated.
|
|
138
|
-
- The Helm `job-worker.yaml` gains a `worker.engine: v10` value, because today it runs `loki start`, which is the legacy engine.
|
|
139
|
-
- Workers return a patch plus a receipt through GET /jobs/<id>/proof and hold no push credential.
|
|
140
|
-
- The coordinator re-runs the equivalence check locally on every returned patch before accepting it. A remote receipt alone is never trusted (Rule of Two).
|
|
141
|
-
|
|
142
|
-
**Caps**
|
|
143
|
-
- Per-unit hard cap: the engine cap plus a cost cap from `estimate.json` x 3.
|
|
144
|
-
- On `--budget`, the coordinator stops dispatching, finishes in-flight units, and writes the report.
|
|
145
|
-
|
|
146
|
-
**Events:** `wave.started`, `unit.started` (run_id, model, worker), `unit.variant`, `budget.hit`.
|
|
147
|
-
|
|
148
|
-
### 3.5 Verify
|
|
149
|
-
|
|
150
|
-
**Per unit**
|
|
151
|
-
- Differential equivalence: old against new on every captured case, held-out cases included (section 7).
|
|
152
|
-
- Target conformance.
|
|
153
|
-
- The no-op ablation from V10-RESEARCH section 1: replace the new unit with stubs, and the checker must go red. A checker that stays green marks the unit NOT PROVEN "oracle does not constrain unit".
|
|
154
|
-
- A captured-literal scan: new source that contains any held-out expected output verbatim is refused.
|
|
155
|
-
|
|
156
|
-
**Per wave:** full build and integration tests under the target runtime, plus the original suite.
|
|
157
|
-
|
|
158
|
-
**Fix and re-slice**
|
|
159
|
-
- A unit that is not equivalent after its fix rounds (`MAX_FIX_ROUNDS`) and best-of-2 is re-sliced smaller: the unit is re-clustered at function granularity, to a depth of 2.
|
|
160
|
-
- After that it is NOT PROVEN with the failing case ids. It is never force-passed.
|
|
161
|
-
|
|
162
|
-
**Events:** `unit.equivalence` (pass, fail, rate, branch_pct), `unit.resliced`, `unit.completed`, `unit.not_proven`, `wave.verified`.
|
|
163
|
-
|
|
164
|
-
### 3.6 Ship
|
|
165
|
-
|
|
166
|
-
**PRs**
|
|
167
|
-
- One PR per wave through the existing credentialed push path (`stages/pr.ts`, `autonomy/lib/engine10-push.sh`), run only in the supervisor-side process.
|
|
168
|
-
- The PR body lists each unit: equivalence rate, coverage, NOT PROVEN reasons, run id and receipt sha256. Deep verify then runs on the PR as it does today.
|
|
169
|
-
- A wave PR is a draft unless every unit in it is proven.
|
|
170
|
-
|
|
171
|
-
**Routing and reversibility**
|
|
172
|
-
- Routing flags in `routes.json` switch traffic module by module (section 8).
|
|
173
|
-
- A wave stays reversible, with the old path kept, until all its units are proven equivalent. Only then does a later wave remove the old path.
|
|
174
|
-
|
|
175
|
-
**Events:** `wave.shipped` (pr url, draft), `route.switched`.
|
|
176
|
-
|
|
177
|
-
### 3.7 Durable and observable
|
|
178
|
-
|
|
179
|
-
- **Resume:** `--resume <mid>` folds the log.
|
|
180
|
-
- Units with `unit.completed` or `unit.not_proven` are skipped.
|
|
181
|
-
- In-flight units resume through the existing `loki --resume <run-id>` (E-39).
|
|
182
|
-
- Units that never started are dispatched again.
|
|
183
|
-
- **Tamper:** a sha mismatch on the modernize log refuses every ship (`TAMPER_NOT_PROVEN`, `supervisor.ts:20`).
|
|
184
|
-
- **Budgets:** the global budget plus the per-unit hard caps.
|
|
185
|
-
- **Dashboard:** a new view on the engine10 dashboard (section 10).
|
|
186
|
-
|
|
187
|
-
### 3.8 Final report
|
|
188
|
-
|
|
189
|
-
**Files:** `report.json` and `report.md` under `.loki/modernize/<mid>/`.
|
|
190
|
-
|
|
191
|
-
**Contents**
|
|
192
|
-
- Units converted.
|
|
193
|
-
- Proven equivalent, with coverage.
|
|
194
|
-
- NOT PROVEN, each with its exact reason.
|
|
195
|
-
- Total cost (null prints "not measured") and wall time.
|
|
196
|
-
- Human touches: a count of operator-input events. The target is 0.
|
|
197
|
-
|
|
198
|
-
**Verdict**
|
|
199
|
-
- COMPLETE only when every unit is proven.
|
|
200
|
-
- Otherwise PARTIAL, with the counts.
|
|
201
|
-
- FAILED when no wave shipped.
|
|
202
|
-
|
|
203
|
-
The report never states more than the equivalence data proves. It is sealed and signed through `stages/seal.ts` (`receipt_jwt.py`). UNSIGNED is stated when there is no key. **Event:** `modernize.completed`.
|
|
204
|
-
|
|
205
|
-
## 4. Unit sizing rule
|
|
206
|
-
|
|
207
|
-
- **The horizon.** METR's 50% time horizon is about 320 minutes (Opus 4.5), and the 80% horizon is much shorter (V10-RESEARCH section 4).
|
|
208
|
-
- **The rule.** A unit must be convertible in well under the 80% horizon. The design sets the target at one quarter of the 50% horizon: 80 human-equivalent minutes per unit.
|
|
209
|
-
- **The deterministic proxy.** Inventory cannot measure minutes, so it uses a line cap. The starting value is 1,500 non-blank source lines per unit, with at most 40 files.
|
|
210
|
-
- This number is a starting heuristic, not a research result.
|
|
211
|
-
- The Legacy-Bench pilot (M-27) calibrates it: raise it while first-pass equivalence stays at 90% or higher, lower it when it does not.
|
|
212
|
-
- **Cycles and re-slicing.** An SCC larger than the cap stays one unit, flagged high risk, and routed to opus. Re-slicing (3.5) is the release valve.
|
|
213
|
-
- **Why parallel works here.** Parallelism gains only on decomposable work (+81%) and loses 39-70% on sequential work. Units in the same wave are independent by construction, and the waves themselves run in sequence.
|
|
214
|
-
|
|
215
|
-
## 5. Durability and resume
|
|
216
|
-
|
|
217
|
-
- **State:** everything is on disk under `.loki/modernize/<mid>/`: `events.jsonl`, `inventory.json`, `plan.json`, `oracle/`, `units/`, `routes.json`, `report.*`.
|
|
218
|
-
- **Writes:** atomic (a temp file, then rename), the same as `writeEngineMarker` (`supervisor.ts:65`).
|
|
219
|
-
- **Recovery:** a crash at any point is recovered by folding the log. No step depends on in-memory state that is not in the log.
|
|
220
|
-
- **Worktrees:** unit worktrees live under `.loki/modernize/<mid>/wt/<unit>`. Resume reattaches a worktree when its HEAD matches the recorded base, and otherwise recreates it from the recorded base.
|
|
221
|
-
- **The resume test** (M-22) kills the coordinator mid-wave. It asserts that no unit runs twice to completion and that seq keeps increasing.
|
|
222
|
-
|
|
223
|
-
## 6. Why Python 2 to 3 and Java 8 to 21 first, and COBOL later
|
|
224
|
-
|
|
225
|
-
**Python 2 to 3**
|
|
226
|
-
- Both interpreters run locally.
|
|
227
|
-
- coverage.py supports branch mode on 2.7.
|
|
228
|
-
- The 2/3-compatible intermediate form lets old and new coexist in one tree.
|
|
229
|
-
- Codemods exist.
|
|
230
|
-
|
|
231
|
-
**Java 8 to 21**
|
|
232
|
-
- JDK 21 runs Java 8 bytecode, so modules at different levels coexist in one JVM.
|
|
233
|
-
- JaCoCo, jdeps, jdeprscan and OpenRewrite are mature open source.
|
|
234
|
-
- Randoop generates regression tests, which feed the input search.
|
|
235
|
-
|
|
236
|
-
**COBOL to Java**
|
|
237
|
-
- It needs a GnuCOBOL or mainframe runtime and file or copybook I/O capture. It also has no in-process boundary, and Legacy-Bench scores run 16.9-42.5% (V10-RESEARCH section 7).
|
|
238
|
-
- The research gives a method (witness search, symbolic execution plus delta debugging) but no tooling we have.
|
|
239
|
-
- It starts after the first two targets meet the gates in section 12.
|
|
240
|
-
|
|
241
|
-
**AngularJS to React** follows COBOL. It needs browser-level capture (Playwright traces) as the oracle.
|
|
242
|
-
|
|
243
|
-
## 7. Oracle capture per language family, and the equivalence checker contract
|
|
244
|
-
|
|
245
|
-
**Python 2 to 3 capture** (`autonomy/lib/modernize/py_capture.py`, runs on 2.7 and 3.x)
|
|
246
|
-
- A tracer wraps each unit's public entry symbols and records arguments, return value, raised exception type and message, stdout, and file writes under a temp root.
|
|
247
|
-
- **Serialization is type-tagged canonical JSON, never pickle.** A py2 `str` crossing into py3 is ambiguous, and pickle makes cases falsely equal or falsely different. Tags: `{"t":"bytes","v":<base64>}`, `{"t":"text","v":...}`, `{"t":"int"}`, `{"t":"float","v":...}`, `list`, `dict` (sorted keys), `none`, `exc`.
|
|
248
|
-
- **Boundary declaration.** Each unit declares text or bytes per boundary in its card. Inventory proposes a declaration from literal and codec usage. An undeclared boundary is NOT PROVEN.
|
|
249
|
-
|
|
250
|
-
**Java 8 to 21 capture** (`autonomy/lib/modernize/java_capture.sh` plus `modernize/oracle/java.ts`)
|
|
251
|
-
- Run the existing JUnit suite under JDK 8 with the JaCoCo agent. Add Randoop-generated regression tests per unit class, filtered to deterministic ones by the double replay.
|
|
252
|
-
- Cases record the method, serialized arguments (JSON through reflection, primitives, strings and collections only), the return value, the exception class and stdout.
|
|
253
|
-
- A unit whose boundary types are not serializable is NOT PROVEN "boundary not capturable". The run does not guess.
|
|
254
|
-
|
|
255
|
-
**Equivalence checker contract** (`modernize/equiv.ts`)
|
|
256
|
-
|
|
257
|
-
| Part | Detail |
|
|
258
|
-
|---|---|
|
|
259
|
-
| Input | The unit id, the sealed `cases.jsonl` (sha-verified before use), the new tree, and the target runner. |
|
|
260
|
-
| Normalizers | Declared per unit in the card and sealed with the oracle: float tolerance, set ordering, and named nondeterministic fields. Nothing is implicit. |
|
|
261
|
-
| Output | `{unit, cases, pass, fail, held_out_pass, held_out_fail, rate, branch_pct, failures:[{case, field, old, new}] (max 20), not_proven:[...]}` |
|
|
262
|
-
| Proven equivalent | rate = 100%, held-out rate = 100%, branch_pct of 80% or higher, the no-op ablation goes red, and conformance passes (runner_reported, FC-24: not proof against unit code that subverts the test runner in-process). |
|
|
263
|
-
| Otherwise | PARTIAL with the numbers, or FAILED when rate < 100% after re-slice. |
|
|
264
|
-
|
|
265
|
-
**Target conformance**
|
|
266
|
-
- The captured oracle passes on the OLD code by construction. The Wall therefore also carries a check that the old code fails:
|
|
267
|
-
- py3: the unit imports and runs its cases under python3;
|
|
268
|
-
- java21: it compiles with `--release 21` and `jdeprscan --for-removal --release 21` is clean.
|
|
269
|
-
- The Wall runs under the target runtime. A Wall that is green before any change is a design error reported as `oracle.flagged`. It is never ALREADY_SATISFIED.
|
|
270
|
-
- `stages/wall.ts` gains a pre-sealed mode (M-14) that takes these files instead of running the author session.
|
|
271
|
-
- Conformance is runner_reported (FC-24): UnitRunResult.conformance and the unit.conformance_passed event carry trust "runner_reported", limit "FC-24". It stops accidental and low-effort false passes, not unit code that subverts pytest inside its own process.
|
|
272
|
-
|
|
273
|
-
## 8. Strangler adapters and routing flags per target
|
|
274
|
-
|
|
275
|
-
| Target | Coexistence pattern | Routing flag |
|
|
276
|
-
|---|---|---|
|
|
277
|
-
| Python 2 to 3 | Waves convert units to 2/3-compatible form (`__future__`, `six`), so the tree runs on both interpreters. The final wave drops 2.7 compatibility. | `routes.json` unit -> `py2`, `dual` or `py3`. The generated `tox.ini` envs run the suite on each interpreter a unit claims. |
|
|
278
|
-
| Java 8 to 21 | Each Maven or Gradle module moves its `release` level independently. JDK 21 loads the modules still at 8. Removed-API shims (JAXB and so on) come in as explicit dependencies. | `routes.json` module -> `8` or `21`. The target module writes the per-module compiler release into the build file. |
|
|
279
|
-
| COBOL to Java (later) | A CALL-boundary adapter: a batch step switch or program alias, so old and new programs share files. | The step-level switch in the job definition. |
|
|
280
|
-
| AngularJS to React (later) | `react2angular` wrappers per component, with route-level cutover. | Per-route flag. |
|
|
281
|
-
|
|
282
|
-
- Every switch emits `route.switched`.
|
|
283
|
-
- Switching back is always allowed until the wave is fully proven.
|
|
284
|
-
|
|
285
|
-
## 9. Wave shipping
|
|
286
|
-
|
|
287
|
-
1. Wave verify passes.
|
|
288
|
-
2. One PR is opened, with a table of unit receipts.
|
|
289
|
-
3. Deep verify runs.
|
|
290
|
-
4. Routes switch for the proven units only.
|
|
291
|
-
5. The next wave starts from the merged tree.
|
|
292
|
-
|
|
293
|
-
- Waves ship even when some units are NOT PROVEN. Those units keep the old route, and the PR is a draft that names them.
|
|
294
|
-
- `--no-pr` keeps everything local for evals.
|
|
295
|
-
|
|
296
|
-
## 10. Dashboard view
|
|
297
|
-
|
|
298
|
-
- A `/modernize/<mid>` page on the existing 127.0.0.1-only engine10 dashboard (`dashboard/server.ts`), folded from the modernize log with `fold`/`tail`.
|
|
299
|
-
- It shows:
|
|
300
|
-
- units done/total;
|
|
301
|
-
- equivalence % (proven / converted);
|
|
302
|
-
- coverage % (the median branch_pct and the count below 80%);
|
|
303
|
-
- cost so far ("not measured" when null);
|
|
304
|
-
- ETA (`eta.ts`);
|
|
305
|
-
- current failures by cause, grouped as runtime missing, coverage low, not equivalent, conformance, cap, and budget.
|
|
306
|
-
- It never opens a browser.
|
|
307
|
-
|
|
308
|
-
## 11. Risks
|
|
309
|
-
|
|
310
|
-
| Risk | Mitigation |
|
|
311
|
-
|---|---|
|
|
312
|
-
| The implementer inlines captured outputs | Held-out cases, read-only sealed oracle, no-op ablation, captured-literal scan (3.5). |
|
|
313
|
-
| The oracle under-constrains behavior | 80% branch floor, NOT PROVEN below it, witness search. The report never rounds up. |
|
|
314
|
-
| Text and bytes confusion in py2 to 3 | Type-tagged JSON and per-boundary declarations (section 7). |
|
|
315
|
-
| Nondeterministic legacy code | Double replay and declared normalizers only. Unexplained drift is NOT PROVEN. |
|
|
316
|
-
| The line-cap proxy is wrong | Calibrated on the pilot, plus re-slicing. |
|
|
317
|
-
| Remote worker compromise | Workers hold no push token, and the coordinator re-verifies every patch locally. |
|
|
318
|
-
| Cost blowup at 1M lines | Estimate before spend, `--budget`, per-unit caps, sonnet first. |
|
|
319
|
-
| The old runtime is unavailable (2.7 is end of life) | The unit is NOT PROVEN, never skipped. Documented container images supply python2.7 and JDK 8. |
|
|
320
|
-
| File contention with in-flight engine rows | Dependencies on E-31, E-54 and E-39 (section 13). |
|
|
321
|
-
|
|
322
|
-
## 12. Eval plan (publish everything, failures included)
|
|
323
|
-
|
|
324
|
-
**Metrics, per run:** equivalence rate, NOT PROVEN share, human touches, cost per 1K source lines, wall time, units re-sliced.
|
|
325
|
-
|
|
326
|
-
**1. Legacy-Bench pilot (M-27)**
|
|
327
|
-
- V10-RESEARCH cites Legacy-Bench only through a vendor report.
|
|
328
|
-
- The slice first confirms that a public task set exists and records its URL and license. If none exists, the pilot uses 10 public py2 and Java 8 repos under 20K lines, each with a suite, and says so.
|
|
329
|
-
- Gate: the equivalence rate on the pilot is published, and the sizing cap is calibrated from it.
|
|
330
|
-
- Calibration factors (eval/modernize/pilot-manifest.json): raise x1.25 at 90% or higher, lower x0.75 below, clamp 300-6000 lines, round to 50; hold when any run failed or was skipped.
|
|
331
|
-
|
|
332
|
-
**2. 200K-line scale test (M-28)**
|
|
333
|
-
- Chosen candidate: Mercurial at its last Python 2 only release, 4.x (py2 to 3).
|
|
334
|
-
- Criteria:
|
|
335
|
-
- at least 200K source lines excluding vendored code;
|
|
336
|
-
- a suite that runs headless in bounded time on the old runtime;
|
|
337
|
-
- an upstream human port exists as a reference to diff against;
|
|
338
|
-
- the license (GPL) allows running it.
|
|
339
|
-
- Why: it is a real Python 2 codebase with a large suite of its own (`run-tests.py`), and upstream later completed the Python 3 port, so a human reference exists.
|
|
340
|
-
- The line count is UNVERIFIED offline. M-28 measures it first with `--dry-run` inventory and `cloc`. If the count is under 200K or the suite is unbounded, the named fallback is Calibre before its Python 3 port, and the choice is recorded again.
|
|
341
|
-
- Operator notes (`eval/modernize/scale.py`, M-28; extends pilot.py, no separate SCALE.md):
|
|
342
|
-
- `python3 eval/modernize/scale.py --target hg --dry-run-first [--source PATH] [--fallback-source PATH]` is the default and spends nothing. It resolves the source (a local `--source` is read in place and copied for the estimate; otherwise it clones Mercurial 4.9.1 with `hg` or Calibre v3.48.0 with the Git CLI; both refs UNVERIFIED offline), counts lines per language excluding vendored directories, runs `loki modernize --to python3 --dry-run`, and prints JSON: planned units, waves, estimated cost, the unit line cap (pilot manifest `cap.start_lines`), the spend cap (null until `--budget-usd`), and a suggested budget of 1.5x the estimate.
|
|
343
|
-
- Selection: hg unavailable (no `hg`, clone failure, bad `--source`) or under `--min-lines` (default 200000) falls back to Calibre. Each step is logged to stderr and to `selection_log`. If no candidate meets the floor the run exits 2.
|
|
344
|
-
- The paid run needs `--execute` AND `--budget-usd` greater than 0, else exit 2 before any clone or spend. It runs through `pilot.execute_repo`, so cost, status and calibration follow the M-27b rules (cost is a lower bound; unmeasured spend is charged at the full budget). Results: `eval/modernize/results/pilot-scale-<ts>.json`.
|
|
345
|
-
- Known limit: `source_lines` in the paid result comes from pilot's counter and includes vendored code, so cost per 1K lines is understated against the measured plan figure.
|
|
346
|
-
|
|
347
|
-
**3. 1M lines (M-29)**
|
|
348
|
-
- Chosen candidate: Apache Hadoop 2.x (Java 8 to 21). It is Java 8, multi-module, and has an extensive JUnit suite.
|
|
349
|
-
- The line count is UNVERIFIED. It is measured the same way, with its suite run per module under the wave plan.
|
|
350
|
-
|
|
351
|
-
**Publishing:** results go to `eval/modernize/results/` and a summary to `docs/v10/METRICS.md` through the EV owner. That includes every NOT PROVEN unit and every failure.
|
|
352
|
-
|
|
353
|
-
## 13. Slice plan (M-01..M-30)
|
|
354
|
-
|
|
355
|
-
**Paths**
|
|
356
|
-
- `mod/` means `loki-ts/src/engine10/modernize/`.
|
|
357
|
-
- `T/` means `loki-ts/tests/engine10/modernize/`.
|
|
358
|
-
- `Wb` means `cd loki-ts && bun test`.
|
|
359
|
-
|
|
360
|
-
**Merge-time exception.** New shell tests register in `tests/run-all-tests.sh` and `tests/shard-durations.tsv`, and new modules register in `engine10/registry.ts`. The Release Manager adds those one-line registrations at merge, as with the E-32 registry lines, so no slice owns those three files.
|
|
361
|
-
|
|
362
|
-
**Shared-file dependencies**
|
|
363
|
-
- M-07 and M-08 touch `engine10/cli.ts` and `bin/loki`. E-31 owns both (approved, held until 03:00Z), so M-07 and M-08 depend on E-31 merging or parking. They never depend on the flip itself.
|
|
364
|
-
- M-14 touches `stages/wall.ts` and depends on E-54 (building).
|
|
365
|
-
|
|
366
|
-
| ID | Goal | Files | Tier | Wall check | Deps |
|
|
367
|
-
|---|---|---|---|---|---|
|
|
368
|
-
| M-01 | Modernize event types, log wrapper and state paths | mod/types.ts, mod/log.ts, T/log.test.ts | MEDIUM | Wb T/log.test.ts | none |
|
|
369
|
-
| M-02 | Inventory core: files, languages, build, entry points, tests | mod/inventory.ts, T/inventory.test.ts, T/fixtures/inv/ | MEDIUM | Wb T/inventory.test.ts | M-01 |
|
|
370
|
-
| M-03 | Python import graph via tokenize (lexes py2 source) | mod/lang/python.ts, autonomy/lib/modernize/py_imports.py, T/python_graph.test.ts | MEDIUM | Wb T/python_graph.test.ts | M-02 |
|
|
371
|
-
| M-04 | Java graph via jdeps, import-scan fallback recorded | mod/lang/java.ts, T/java_graph.test.ts, T/fixtures/java8/ | MEDIUM | Wb T/java_graph.test.ts | M-02 |
|
|
372
|
-
| M-05 | SCC clustering, 1,500-line unit cap, topological waves | mod/cluster.ts, T/cluster.test.ts | MEDIUM | Wb T/cluster.test.ts | M-02 |
|
|
373
|
-
| M-06 | Up-front estimate (cost, time, risk), --budget math, --dry-run print | mod/estimate.ts, T/estimate.test.ts | LOW | Wb T/estimate.test.ts | M-05 |
|
|
374
|
-
| M-07 | modernize CLI and flag parsing; TABLE route in engine10 cli | mod/cli.ts, loki-ts/src/engine10/cli.ts (TABLE and USAGE line only), T/cli.test.ts | MEDIUM | Wb T/cli.test.ts | M-06, E-31 merged or parked |
|
|
375
|
-
| M-08 | bin/loki modernize arm to engine10 regardless of default | bin/loki (modernize arm only), tests/test-modernize-dispatch.sh | MEDIUM | bash tests/test-modernize-dispatch.sh | M-07 |
|
|
376
|
-
| M-09 | py2/3 capture tracer with type-tagged JSON and branch coverage | autonomy/lib/modernize/py_capture.py, tests/test-modernize-py-capture.sh, tests/fixtures/modernize/py2/ | HIGH | bash tests/test-modernize-py-capture.sh | M-01 |
|
|
377
|
-
| M-10 | Coverage-guided input search (read-only session, plateau stop) | mod/oracle/search.ts, T/search.test.ts | HIGH | Wb T/search.test.ts | M-09 |
|
|
378
|
-
| M-11 | Java capture: JUnit under JDK 8 with JaCoCo plus Randoop | autonomy/lib/modernize/java_capture.sh, mod/oracle/java.ts, T/java_capture.test.ts | HIGH | Wb T/java_capture.test.ts | M-04 |
|
|
379
|
-
| M-12 | Oracle seal, held-out split, 80% floor, up-front NOT PROVEN | mod/oracle/seal.ts, T/oracle_seal.test.ts | HIGH | Wb T/oracle_seal.test.ts | M-09 |
|
|
380
|
-
| M-13 | Equivalence checker with sealed normalizers and contract output | mod/equiv.ts, T/equiv.test.ts, T/fixtures/equiv/ | HIGH | Wb T/equiv.test.ts | M-12 |
|
|
381
|
-
| M-14 | Wall pre-sealed mode: oracle plus conformance, green base is an error | loki-ts/src/engine10/stages/wall.ts (pre-sealed branch only), T/wall_presealed.test.ts | HIGH | Wb T/wall_presealed.test.ts | M-12, E-54 |
|
|
382
|
-
| M-15 | Unit runner: card to v10 run with oracle Wall and equiv check | mod/unit.ts, T/unit.test.ts | HIGH | Wb T/unit.test.ts | M-13, M-14 |
|
|
383
|
-
| M-16 | Deterministic codemods first (futurize, OpenRewrite) or skipped | mod/codemod.ts, T/codemod.test.ts | MEDIUM | Wb T/codemod.test.ts | M-02 |
|
|
384
|
-
| M-17 | Scheduler: N workers, worktrees, cascade, best-of-2, budget stop | mod/scheduler.ts, T/scheduler.test.ts | HIGH | Wb T/scheduler.test.ts | M-15 |
|
|
385
|
-
| M-18 | Re-slice non-equivalent units to depth 2, then NOT PROVEN | mod/reslice.ts, T/reslice.test.ts | MEDIUM | Wb T/reslice.test.ts | M-05, M-13 |
|
|
386
|
-
| M-19 | Strangler targets and routes.json (py2/dual/py3, per-module release) | mod/routes.ts, mod/targets/python3.ts, mod/targets/java21.ts, T/routes.test.ts | MEDIUM | Wb T/routes.test.ts | M-05 |
|
|
387
|
-
| M-20 | Wave verify: full build, integration and original suite | mod/wave.ts, T/wave.test.ts | MEDIUM | Wb T/wave.test.ts | M-17, M-19 |
|
|
388
|
-
| M-21 | Wave ship: one PR per wave with unit receipts, draft unless all proven | mod/ship.ts, T/ship.test.ts | HIGH | Wb T/ship.test.ts | M-20 |
|
|
389
|
-
| M-22 | Unit-level resume after coordinator crash | mod/resume.ts, T/resume.test.ts | MEDIUM | Wb T/resume.test.ts | M-17, E-39 |
|
|
390
|
-
| M-23 | Remote units via POST /jobs kind unit, Helm worker.engine v10, local re-verify | autonomy/trigger-server.py (unit job kind only), deploy/helm/autonomi/templates/job-worker.yaml, deploy/helm/autonomi/values.yaml, loki-ts/src/util/modernize_unit.ts, T/remote.test.ts, tests/test-trigger-server-unit-jobs.py | HIGH | python3 tests/test-trigger-server-unit-jobs.py && Wb T/remote.test.ts | M-17 |
|
|
391
|
-
| M-24 | Dashboard /modernize view | loki-ts/src/engine10/dashboard/modernize.ts, loki-ts/src/engine10/dashboard/server.ts (one route), T/dashboard.test.ts | LOW | Wb T/dashboard.test.ts | M-01 |
|
|
392
|
-
| M-25 | Final report and verdict (COMPLETE only if all proven), sealed | mod/report.ts, T/report.test.ts | HIGH | Wb T/report.test.ts | M-13, M-21 |
|
|
393
|
-
| M-26 | End-to-end: py2 fixture repo modernized with stub provider | T/e2e.test.ts, T/fixtures/e2e_py2/ | MEDIUM | Wb T/e2e.test.ts | M-08, M-22, M-25 |
|
|
394
|
-
| M-27 | Legacy-Bench pilot harness; confirm public set; calibrate cap | eval/modernize/pilot.py, eval/modernize/test-pilot.sh | HIGH | bash eval/modernize/test-pilot.sh | M-26 |
|
|
395
|
-
| M-28 | 200K scale run (Mercurial 4.x, measured first, fallback Calibre) | eval/modernize/scale.py (notes in section 12) | HIGH | python3 eval/modernize/scale.py --target hg --dry-run-first | M-27 |
|
|
396
|
-
| M-29 | 1M scale run (Hadoop 2.x Java 8 to 21, measured first) | eval/modernize/scale_1m.py, eval/modernize/SCALE-1M.md | HIGH | python3 eval/modernize/scale_1m.py --dry-run-first | M-28, M-11 |
|
|
397
|
-
| M-30 | User docs for loki modernize, no dashes, commands match USAGE | docs/v10/GUIDE-MODERNIZE.md, tests/test-modernize-docs.sh | LOW | bash tests/test-modernize-docs.sh | M-07 |
|
|
398
|
-
|
|
399
|
-
**Critical path:** M-01 -> M-02 -> M-05 -> M-09 -> M-12 -> M-13 -> M-14 -> M-15 -> M-17 -> M-20 -> M-21 -> M-25 -> M-26 -> M-27 -> M-28.
|
|
400
|
-
|
|
401
|
-
**Parallel from the start:** M-03, M-04, M-06, M-16, M-19 and M-24 run alongside it.
|
|
402
|
-
|
|
403
|
-
**Red and green for every slice**
|
|
404
|
-
- Red: the test file is missing or asserts the absent behavior.
|
|
405
|
-
- Green: every assertion named in the goal holds.
|
|
406
|
-
- Each HIGH slice needs a unanimous opus review (D12).
|
|
407
|
-
|
|
408
|
-
## 14. Fan-out alignment: G-04 cloud dispatch and the M-23 unit job (G-05)
|
|
409
|
-
|
|
410
|
-
Both fan-outs hand one independent piece of work to a remote worker and accept the result only after the coordinator checks it. They share one shape so a single dispatcher can drive either.
|
|
411
|
-
|
|
412
|
-
**M-23 unit job schema** (POST /jobs, same bearer token as every job kind; the schema is closed and any other field is rejected with 400):
|
|
413
|
-
|
|
414
|
-
| Field | Bound | Required |
|
|
415
|
-
|---|---|---|
|
|
416
|
-
| `kind` | the literal `unit` | yes |
|
|
417
|
-
| `repo` | `owner/name`, at most 140 chars, no leading dash, no `.` or `..` segment | yes |
|
|
418
|
-
| `ref` | git ref, at most 200 chars, no `..`, no leading dash | yes |
|
|
419
|
-
| `unit` | unit id, `[A-Za-z0-9][A-Za-z0-9_.-]{0,127}`, never contains `~` | yes |
|
|
420
|
-
| `mid` | `mod-<utc>-<6 hex>` | no |
|
|
421
|
-
| `target` | `python3` or `java21` | no |
|
|
422
|
-
|
|
423
|
-
The worker runs `loki modernize unit --repo <repo> --ref <ref> --unit <unit>` (plus `--mid` and `--target` when given). It fetches repo@ref into a run-owned temp directory with the safe_git helpers, runs the unit there through the same unit runner as a local run, and removes the directory afterwards. A checkout failure, a runner failure or any verdict other than PROVEN exits nonzero with the reason on stderr; exit 2 means bad arguments or runners that are not wired yet.
|
|
424
|
-
|
|
425
|
-
**G-04 dispatch fields mapped onto it** (scripts/cloud-dispatch.sh, docs/v10/SWARM.md "Cloud dispatch"):
|
|
426
|
-
|
|
427
|
-
| G-04 field | M-23 field | Rule |
|
|
428
|
-
|---|---|---|
|
|
429
|
-
| slice id (`SLICE-ID`) | `unit` | Same unit-id charset; the id is the unit of fan-out and of overlap checks. |
|
|
430
|
-
| branch `cloud/<slice-id>` | `ref` | The worker works on this ref (G-04 also returns it); the coordinator never merges a ref it did not name. |
|
|
431
|
-
| repository of the checkout | `repo` | Always `owner/name`; no URL, no userinfo. |
|
|
432
|
-
| file set (overlap check) | the unit's own files | Resolved coordinator-side from plan.json before dispatch; never sent in the job. Overlap with in-flight work refuses the dispatch in both. |
|
|
433
|
-
| tier and governor max | scheduler `--workers` | Concurrency is the governor cap, not a job field. |
|
|
434
|
-
| cloud session id (BOARD note) | server job `id` | Recorded by the coordinator against the unit (events.jsonl for M-23, the BOARD row for G-04). |
|
|
435
|
-
| PR and check conclusion | local re-verify | The PR check result and the remote "passed" are claims. The coordinator re-verifies locally (equivalence check for a unit, required checks for a slice) and merges only if both agree. |
|
|
436
|
-
|
|
437
|
-
Shared rules: credentials are never in the payload (the token is an Authorization header for POST /jobs, and the cloud session uses its own login); an unobserved or unknown remote outcome is not a pass; a remote pass with a failing local re-verify never merges; dispatch refuses rather than guesses when the schema, the overlap check or the cap cannot be evaluated.
|
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
# v11.4.0 plan: beat opencode by 1-2 points in every category
|
|
2
|
-
|
|
3
|
-
Founder directive (2026-10-15): close every gap an outside assessment found
|
|
4
|
-
against opencode. Keep Loki autonomous. Keep the harness and internals
|
|
5
|
-
(RARV-C, receipts, Seal, council) as they are, and keep Claude Code as the
|
|
6
|
-
primary provider. Ship all of it as one MINOR release, v11.4.0, built in
|
|
7
|
-
parallel. Under the founder's standing waiver nothing is tested.
|
|
8
|
-
|
|
9
|
-
Founder clarification (2026-10-15): `loki start` is always the primary
|
|
10
|
-
path. `loki chat` is an alternative surface. Every improvement in this
|
|
11
|
-
release (model routes, local models, providers, agents, routing, exit codes,
|
|
12
|
-
run summary, onboarding) must work through `loki start` first. Chat must hand
|
|
13
|
-
off to and from `loki start` without friction: `/run` in chat starts the same
|
|
14
|
-
run with the same model, provider and agents, and chat can attach to a
|
|
15
|
-
running or finished `loki start` session (status, steer, diff, verify).
|
|
16
|
-
|
|
17
|
-
## Scorecard target
|
|
18
|
-
|
|
19
|
-
| Category | Was (Loki / opencode) | Target | Slices |
|
|
20
|
-
|---|---|---|---|
|
|
21
|
-
| Everyday user experience | 6 / 8 | 10 | OC-CHAT, OC-OUTPUT |
|
|
22
|
-
| Installation and onboarding | 6 / 8 | 10 | OC-ONBOARD, OC-DOCS |
|
|
23
|
-
| Learning curve | 5 / 8 | 10 | OC-ROUTE, OC-HELP |
|
|
24
|
-
| Interactive coding and exploration | 6 / 9 | 10 | OC-CHAT |
|
|
25
|
-
| Small, targeted changes | 7 / 8 | 10 | OC-EDIT |
|
|
26
|
-
| Model/provider flexibility | 5 / 9 | 10 | OC-MODELS, OC-OPENCODE-E10 |
|
|
27
|
-
| Local-model setup | 5 / 8 | 10 | OC-MODELS |
|
|
28
|
-
| Multi-agent workflow design | 7 / 8 | 10 | OC-AGENTS |
|
|
29
|
-
| Documentation consistency | 4 / 7 | 10 | OC-DOCS |
|
|
30
|
-
| Predictability across commands/upgrades | 5 / 6 | 10 | OC-ROUTE, OC-EXIT, OC-PARITY-COST, OC-PARITY-ENFORCE |
|
|
31
|
-
|
|
32
|
-
## Todo (one slice each, parallel, own branch `slice-OC-<KEY>`)
|
|
33
|
-
|
|
34
|
-
- [x] OC-CHAT: `loki chat` opens an interactive session (the first cut
|
|
35
|
-
also opened it from bare `loki` on a TTY; that was reverted, and bare `loki`
|
|
36
|
-
stays unchanged). Plan mode is read-only and Build mode edits; `/plan`
|
|
37
|
-
and `/build` switch between them. Slash commands: /run, /quick, /edit,
|
|
38
|
-
/verify, /receipt, /model, /provider, /cost, /diff, /undo, /help, /exit.
|
|
39
|
-
`loki chat --tui` launches Claude Code's own TUI.
|
|
40
|
-
- [x] OC-ROUTE: one predictable execution path. Flag-first calls, PRD files
|
|
41
|
-
and one-word starts reach the same engine as the positional form. The
|
|
42
|
-
legacy engine runs only on an explicit `--engine legacy` or
|
|
43
|
-
`LOKI_ENGINE=legacy`. `loki route <args>` prints the engine and why.
|
|
44
|
-
- [x] OC-EXIT: close the three `loki verify` exit-code gaps and use one
|
|
45
|
-
exit-code contract for verify, run, quick and edit. Update
|
|
46
|
-
docs/exit-codes.md and remove the KNOWN-ISSUES entry.
|
|
47
|
-
- [x] OC-MODELS: model routes over the Claude harness, so every Tier-1
|
|
48
|
-
control still works. Routes: `--model openrouter/<id>`, `ollama/<id>`,
|
|
49
|
-
`lmstudio/<id>`, `llamacpp/<id>`, `vllm/<id>`, and any
|
|
50
|
-
Anthropic-compatible base URL. `loki models` lists routes;
|
|
51
|
-
`loki models --local` discovers local runtimes.
|
|
52
|
-
- [x] OC-PARITY-COST: engine10 measures cost for Codex, Cline and Aider.
|
|
53
|
-
- [x] OC-PARITY-ENFORCE: engine10 enforces the budget kill, a post-iteration
|
|
54
|
-
guard scan and native sandbox flags for Codex, Cline, Aider and opencode.
|
|
55
|
-
Receipts still list `kill blocking not enforced` because the scan is post-hoc.
|
|
56
|
-
- [x] OC-OPENCODE-E10: opencode becomes a supported engine10 provider.
|
|
57
|
-
- [x] OC-AGENTS: configurable child agents in `.loki/agents/*.md` (model,
|
|
58
|
-
provider, tools, permissions, prompt), managed with
|
|
59
|
-
`loki agents list|new|show`. Councils and reviewers use them when present,
|
|
60
|
-
and they export to Claude Code subagents.
|
|
61
|
-
- [x] OC-EDIT: `loki edit "<change>"` makes a fast single-pass edit with no
|
|
62
|
-
PR, plan or council. It shows the diff; `--verify` and `--receipt` are
|
|
63
|
-
opt-in.
|
|
64
|
-
- [x] OC-ONBOARD: `loki setup` wizard and `loki doctor --fix`. Claude Code
|
|
65
|
-
first, with required and optional prerequisites stated plainly.
|
|
66
|
-
- [x] OC-HELP: `loki help` shows the core verbs, `loki help all` shows the
|
|
67
|
-
full surface, and `loki help <topic>` covers topics. Mistyped commands get
|
|
68
|
-
"did you mean" suggestions, and `--json` works the same everywhere.
|
|
69
|
-
- [x] OC-OUTPUT: one run summary across engines (result, cost, time,
|
|
70
|
-
receipt, next step), with `--quiet` and NO_COLOR honored.
|
|
71
|
-
- [ ] OC-START-INTEGRATION (after merge): wire every feature above into
|
|
72
|
-
`loki start` (`--model <route>`, `--provider`, configured agents, unified
|
|
73
|
-
summary, exit codes, explain-route). Bare `loki` keeps its current
|
|
74
|
-
behavior and does not open chat. Seamless chat handoff: `/run` reuses the
|
|
75
|
-
chat's model, provider and agents; `loki chat --attach` joins the current
|
|
76
|
-
or last `loki start` session; the run summary's next step names
|
|
77
|
-
`loki chat --attach`.
|
|
78
|
-
- [x] OC-DOCS (after merge; README, INSTALLATION, GUIDE, QUICKSTART and
|
|
79
|
-
COMPARE-OPENCODE written): README, INSTALLATION, GUIDE and a new QUICKSTART
|
|
80
|
-
agree with the code on prerequisites, the spend cap, routing and providers.
|
|
81
|
-
Add docs/COMPARE-OPENCODE.md.
|
|
82
|
-
- [ ] Release: merge onto train-v11.4.0, rebuild loki-ts dist, write a full
|
|
83
|
-
CHANGELOG v11.4.0 section, run `scripts/release.sh minor --bump-only`,
|
|
84
|
-
push main, and confirm the release run.
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
# Loki company operating model (always loaded; never exceed 90 lines)
|
|
2
|
-
|
|
3
|
-
The CEO is Lokesh Mure (Loki), the founder. Everyone else is an agent. The company ships Loki Mode v10 per docs/V10-VISION.md. Order when goals conflict: moat > Seal accuracy > delivered accuracy > cost > speed. Velocity target: 30-60 releases per day.
|
|
4
|
-
|
|
5
|
-
## Roles and models (pin every agent's model explicitly, D13)
|
|
6
|
-
Ten standing seats. Each file holds the seat's mandate, metrics, decision rights, inputs, outputs, escalation rule and the RETRO-2026.md root causes it owns. Each seat writes .loki/company/status/<slug>.json every turn; the cockpit (tools/cockpit/SPEC.md) reads them.
|
|
7
|
-
- chief-of-staff (opus, the main session; .claude/agents/chief-of-staff.md): operating rhythm, BOARD.md dispatch, CEO digest, founder queue, ROI ledger; holds the PM duty; escalates only to Loki; never writes product code. RC6, RC9, RC1.
|
|
8
|
-
- cto (opus; .claude/agents/cto.md): architecture and quality calls; approves any change to the moat, gates or release policy; acts as Architect for large tasks (designs the slices, never implements them); rules review round 3. RC4, RC7, RC3.
|
|
9
|
-
- release-reliability-lead (sonnet, exactly one; .claude/agents/release-reliability-lead.md): the Release Manager, the only role that pushes main, bumps VERSION, tags or publishes; owns channel truth and the post-publish first-run gate. RC5, RC7, RC4.
|
|
10
|
-
- verification-scientist (opus; .claude/agents/verification-scientist.md): claims registry, Seal and verdict accuracy, guard mutation; veto on uncited claims. RC2, RC1, RC3.
|
|
11
|
-
- research-outcomes-scientist (opus; .claude/agents/research-outcomes-scientist.md): nightly Loki versus raw claude -p scoreboard, the only source for outcome claims. RC1, RC9, RC5.
|
|
12
|
-
- research-harness-scientist (opus; .claude/agents/research-harness-scientist.md): ablation, model-tier pinning, SDK freshness, frontier scan. RC9, RC1, RC10.
|
|
13
|
-
- product-growth-lead (sonnet; .claude/agents/product-growth-lead.md): the Product Owner; strategy page, backlog ranking, slice cards (60 lines max), funnel, competitor matrix. RC10, RC4, RC1.
|
|
14
|
-
- developer-experience-lead (sonnet; .claude/agents/developer-experience-lead.md): install, loki start, preview, dashboard, docs from code, platforms. RC5, RC10, RC2.
|
|
15
|
-
- security-lead (sonnet; .claude/agents/security-lead.md): secrets, deny-by-default env, auth boundaries; dispatches the HIGH security reviewers. RC3, RC5, RC8.
|
|
16
|
-
- platform-lead (sonnet; .claude/agents/platform-lead.md): process safety, guards as mechanisms, CI speed, structured stores, the cockpit build. RC8, RC3, RC7.
|
|
17
|
-
Spawned per slice, not standing seats:
|
|
18
|
-
- Software Engineers (sonnet): one slice each, worktree isolation, single writer, red-then-green tests.
|
|
19
|
-
- Tech Leads (sonnet): LOW and MEDIUM reviews, unanimous (D12).
|
|
20
|
-
- Reviewers for HIGH-tier work (opus): moat, verifier, Seal, auth, security. Unanimous; a reproduced blocking finding always blocks (D12).
|
|
21
|
-
|
|
22
|
-
## Leadership lock (one company per repo)
|
|
23
|
-
- The leader holds .loki/v10-leader (PID and start time). A session becomes leader only if that file is missing or its PID is dead (kill -0 fails).
|
|
24
|
-
- Non-leader sessions act as extra engineers or reviewers on BOARD.md slices, or answer Loki. They never push, bump VERSION, release or rewrite BOARD.md.
|
|
25
|
-
|
|
26
|
-
## Nobody sits idle
|
|
27
|
-
- Ready queue >= 30 specced slices (features, enhancements, fixes evenly; D91). Seat cap 20 (D103: founder ruled cost irrelevant on the Max plan; load and memory are the limit).
|
|
28
|
-
- The Chief of Staff keeps 8-16 engineers busy whenever ready slices exist. When anyone finishes, the next slice is assigned in the same turn.
|
|
29
|
-
- The ready queue never drops below 2x the number of engineers; the chief-of-staff and the product-growth-lead refill it.
|
|
30
|
-
- Idle seats while work exists, or an empty ready queue, is a P0 violation.
|
|
31
|
-
|
|
32
|
-
## Time limits (anything slower gets redesigned, not waited on)
|
|
33
|
-
- Budgets: trivial ops use scripts, never agents (target under 10s). LOW engineer 15 min, MEDIUM 30 min. Reviewers 30 min, HIGH adversarial reviewer 60 min.
|
|
34
|
-
- Any shell command: timeout 10 min max; target under 2 min.
|
|
35
|
-
- An agent or command over budget is stopped, recorded in METRICS.md, and re-sliced smaller.
|
|
36
|
-
|
|
37
|
-
## Release pipeline
|
|
38
|
-
- Tier A fast gate on every change (target 60-120s): syntax checks, changed-file shellcheck, diff-selected tests, moat suite split per property. It is feedback, not release authority.
|
|
39
|
-
- Tier B: every main commit has a full Tier B verdict on its exact tree, run on main or on the train that produced it (D55); never cancelled on main.
|
|
40
|
-
- Every approved slice is a release (D96, D102): merge-gate merges to main, and a VERSION push publishes to npm under `latest` AND `next` within seconds, depending only on pack-npm. No CI, nightly, backstop or smoke result delays npm. No trains, no batching. Target 3-10 releases per hour.
|
|
41
|
-
- Tests, Security Audit, nightly and the backstop run in parallel as fix-forward signals. If one fails on main, a P0 fix-forward slice opens within the hour. Never unpublish; npm deprecate is allowed.
|
|
42
|
-
|
|
43
|
-
## Large tasks (for example "rebuild the dashboard")
|
|
44
|
-
- The Architect splits the task into 10-40 slices behind a feature flag.
|
|
45
|
-
- Engineers build them in parallel; each merges and releases behind the flag as soon as it is green.
|
|
46
|
-
- The flag flips when the Wall checks for the whole feature pass.
|
|
47
|
-
- Releases never pause for a big task.
|
|
48
|
-
|
|
49
|
-
## Discipline
|
|
50
|
-
- Evidence or it did not happen: every claim cites a command plus its exit code or output line.
|
|
51
|
-
- Engine Laws (D86): docs/v10/ENGINE-LAWS.md binds every stage. No bug becomes a fix slice until its row is in docs/v10/FAILURE-CLASSES.md (user-visible vs raw, law broken, sibling sweep, one shared mechanism, regression fixture); reviewers reject stage-only patches when siblings exist.
|
|
52
|
-
- Every incident becomes a guard with a test (docs/v10/GUARDS.md, D26).
|
|
53
|
-
- The pulse block (scripts/v10-pulse.sh) is injected every turn. Act on the top VIOLATION first.
|
|
54
|
-
- Never kill by name or pattern, force-push, git add -A, or bypass branch protection.
|
|
55
|
-
|
|
56
|
-
## Always-on seats (headless)
|
|
57
|
-
- `loki trigger install` seeds one `seat <name>` schedule per .claude/agents/*.md (autonomy/company-seats.json) and installs the LaunchAgent dev.autonomi.loki-company, which runs `loki trigger daemon --loop`. `loki trigger uninstall` removes it. Linux prints a systemd user unit.
|
|
58
|
-
- A tick is `claude -p --agent <name> --dangerously-skip-permissions --output-format json` in the repo root, 20 min cap (LOKI_SEAT_TIMEOUT_SECS). The seat writes .loki/company/<name>/last.json and log.jsonl.
|
|
59
|
-
- Skips: .loki/company/PAUSE, 1-min load above 28, usage governor max engineers 0, a live PID in .loki/v10-leader (chief-of-staff and release-reliability-lead only), or a live per-seat lock. Only the tick's own process group is ever stopped.
|
|
60
|
-
- `loki trigger uninstall` does not stop ticks already running; `touch .loki/company/PAUSE` stops all seats.
|