# Current architecture and health budget

Status: authoritative current architecture through the `0.13.17` refactor closeout.

Historical opening snapshot: `main@0667537ac6efe116c5261fa33370a4190f2d2226`, package
`0.13.3`, measured 2026-09-15. The machine-readable baseline and budgets are
in [`config/architecture-health-budget.json`](../../config/architecture-health-budget.json).
Run `npm run architecture:dashboard` to validate the budgets and print the
current JSON dashboard. The `0.13.17` closeout below supersedes the earlier
ratchet values; the opening and P2 measurements remain historical evidence.

The stable [orchestration architecture index](./orchestration-refactor.md)
routes readers to this current document or the immutable
[Issue #126 historical ledger](./orchestration-refactor-history.md). That
ledger and the [Issue #126 closeout report](./issue-126-final-report.md) are
historical evidence; they do not describe current module sizes, protocols, or
the current health budget.

## Shape of the system

Production dependencies flow inward:

```text
CLI / OpenClaw / Host connectors
  -> typed command facades and composition
  -> dispatch / lifecycle / callback / monitor / watch application services
  -> pure authority, policy, and state-transition modules
  -> domain records and ports

tmux / Herdr / Codex / Claude / Store / Gateway adapters implement ports
and point back toward the application boundary.
```

`src/cli.ts` is the sole production importer of `src/cli-core.ts`. The core is
a compatibility command facade, not an owner of terminal, lifecycle, monitor,
Watch, callback, or persistence state machines. Every production module has one
domain owner in `config/production-module-ownership.json`; the compiler-AST
architecture gate rejects missing ownership, computed production imports,
dependency cycles, duplicated canonical status policies, and unapproved reverse
imports into `cli-core.ts`.

The canonical mutation lock order remains:

```text
terminal dispatch lock -> Store writer lease -> conversation state lock
```

Refactoring must preserve durable reservation before terminal input, exact
terminal/process/cwd authority, execution-time revalidation, reverse-order lock
release, and `uncertain + do_not_retry` after possible input with an unproven
postcondition.

## Issue #320 opening snapshot

| Metric | Snapshot | Gate |
| --- | ---: | --- |
| Production modules | 155 | observed |
| Production physical LOC | 144,726 | observed only |
| Production functions | 5,926 | observed |
| Production import edges | 1,004 | observed |
| Production import cycles | 0 | must remain 0 |
| Hard function violations (`>=500` LOC or `>=50` approximate complexity) | 0 | must remain 0 |
| Default function violations (`>=100` LOC or `>=20` approximate complexity) | 338 | must not increase |
| Production files over 2,000 LOC | 19 | must not increase |
| OpenClaw / Host Bridge semantic tools | 24 each | must stay synchronized |
| Pi / DSH catalog parity | Host Adapter capability handshake v1 | fail closed on catalog, registration, or Skill drift |
| Canonical / generated Pi / generated DSH Skill documents | byte-identical | generated by a hash-gated sync step |

Total production LOC is deliberately not a pass/fail budget. Typed safety
checks, compatibility profiles, and evidence may legitimately add source. It is
still reported with a delta from this snapshot so growth remains visible. The
gate instead targets concentration, complexity, cycles, and duplicated public
artifacts.

The `cli-core.ts` ceiling is 1,839 LOC and can move downward without editing a
manifest. Eight opening concentration paths have individual ratcheting budgets:

| Path | Maximum physical LOC |
| --- | ---: |
| `src/terminal-command-cli-adapter.ts` | 10,421 |
| `src/terminal-agent-bridge.ts` | 7,409 |
| `src/terminal-list-cli-adapter.ts` | 5,093 |
| `src/openclaw-plugin-command-adapter.ts` | 3,817 |
| `src/terminal-watch-cli-adapter.ts` | 3,683 |
| `src/claude-local-transcript-provider.ts` | 3,534 |
| `src/terminal-monitor-state-cli-adapter.ts` | 3,478 |
| `src/terminal-watch-store.ts` | 3,191 |

These are ceilings, not desired final sizes. Removing or splitting a hotspot is
allowed without changing its historical budget; the dashboard reports a removed
path as `retired: true` with zero current LOC. Reusing that same path later still
subjects it to its historical ceiling. Raising a baseline ceiling is rejected
by the validator rather than normalized away in a routine feature PR.

## P2 closeout ratchets

Measured on 2026-09-15 at `main@9b4b007` before the closeout-budget commit:

| Metric | P2 closeout | Opening delta |
| --- | ---: | ---: |
| Production modules | 212 | +57 responsibility-focused modules |
| Production physical LOC | 150,684 | +5,958 observed-only LOC |
| Production functions | 6,210 | +284 |
| Production import edges | 1,382 | +378 |
| Import cycles / hard function violations | 0 / 0 | unchanged |
| Default function violations | 332 | -6 |
| Production files over 2,000 LOC | 9 | -10 |
| Largest production file | 3,635 LOC | below the new 5,000-LOC gate |

The P2 closeout converted the achieved concentration reductions into executable
non-regression gates. At that milestone the budget permitted no more than nine
production files over 2,000 physical LOC, rejected every production file at
5,000 LOC or larger, and lowered each tracked hotspot ceiling to its
post-refactor size. The default function-violation ceiling was likewise lowered
from the opening 338 to the measured closeout value. The `0.13.17` milestone
tightens these ratchets again; it does not raise them to absorb feature growth.

The separate 90-day goal of at most 250 default-threshold violations is not a
claim about this P2 milestone. Reaching it requires function-level decomposition
across callback, Watch, identity, transcript, and terminal-input policies rather
than mechanical file movement. It remains visible follow-up work; the current
ratchet neither weakens the `>=100` LOC / `>=20` approximate-complexity
definition nor labels that longer-horizon target complete.

Two other 90-day measures are longitudinal rather than static source gates:
the typical production-file touch count for a new agent/version profile and
`test:fast` p50/p95. They require evidence across multiple future changes or
runs and are not inferred from a single P2 checkout.

## 0.13.17 refactor closeout

Measured on 2026-10-02 against the released `0.13.16` source at `d9e6b3f`.
This phase covers the published backend, its test support, and release
verification scripts. Uncommitted Control UI work from another checkout is
outside this comparison.

| Metric | 0.13.16 baseline | 0.13.17 closeout | Delta |
| --- | ---: | ---: | ---: |
| Production modules | 248 | 281 | +33 |
| Production physical LOC | 161,601 | 163,877 | +2,276 |
| Production functions | 6,922 | 6,965 | +43 |
| Production import edges | 1,590 | 1,821 | +231 |
| Import cycles / hard function violations | 0 / 0 | 0 / 0 | unchanged |
| Default function violations | 332 | 330 | -2 |
| Production files over 2,000 LOC | 9 | 4 | -5 |
| Largest production file | 3,631 LOC | 3,534 LOC | -97 LOC |

The decomposition gives Watch capture, fallback observation, interaction
authority, and response execution separate owners; Monitor reconciliation and
recovery likewise leave its CLI facade. Legacy Codex rollout file access,
record parsing, human-started task observation, interaction evidence, and bound
completion now have distinct modules. Native model-control execution and
surface/input handling, Codex inventory, and native inspection proof are also
separated from their existing public entry points.

| Existing production entry point | Before LOC | After LOC |
| --- | ---: | ---: |
| `src/terminal-watch-cli-adapter.ts` | 3,631 | 651 |
| `src/terminal-monitor-state-cli-adapter.ts` | 3,476 | 1,119 |
| `src/terminal-submission-acceptance.ts` | 3,414 | 771 |
| `src/native-thread-lifecycle-cli-adapter.ts` | 2,852 | 1,764 |
| `src/terminal-model-control.ts` | 2,658 | 1,151 |
| `src/codex-store-adapter.ts` | 1,795 | 744 |
| `src/terminal-native-inspection-bridge.ts` | 1,956 | 1,080 |

These are physical line counts, including comments and blank lines. Splitting
modules and wrapping long descriptions adds explicit imports, interfaces, and
lines: total production LOC increases about 1.4%. That growth is reported,
not presented as code removal. The improvement is reduced responsibility
concentration with unchanged dependency direction and public behavior.
Production lines over 160, 200, and 300 characters fall from 192/118/63 to
87/36/9 respectively; script lines over 160 characters fall from six to zero.
This is targeted readability work, not a repository-wide formatting rewrite.

Test and maintenance boundaries are preserved too. The 4,970-line Watch test
file becomes a 9-line registration entry over eight behavior groups and shared
fixtures; its 42 test definitions and 352 assertion calls are unchanged in
static AST comparison. The 3,080-line no-rollout support file becomes a
112-line export facade over 14 modules; all 62 functions and 86 assertions are
retained, including the deliberate subprocess and crash/exit cases. The
affected-test map records the new direct consumers without changing test-tier
entry points. The 1,744-line refactor-evidence script and 1,339-line OpenClaw
compatibility script become 50-line and 90-line entry points over domain
modules. The compatibility flow retains all 72 assertions and the same
Gateway cleanup boundary. Its full-host function now delegates lifecycle
stages rather than owning the entire scenario inline.

The bound-completion detector preserves acceptance and identity error
precedence, diagnostic fields, the same open descriptor for reads and stat
checks, and its `finally` close on every post-open return. Public facades retain
their exports. Compiled comparison against the immutable `0.13.16` package
confirms equal action-contract values, fresh nested contract objects, equal
schema exports, and the same complete 24-tool catalog. Extracted descriptions
and guidance retain their exact text; native approval and input checks are not
relaxed. Long captured ANSI fixture data remains intact.

The current executable ratchets now permit at most **330 default function
violations** and **four production files over 2,000 LOC**. Watch, Monitor, and
List hotspot ceilings are **651**, **1,119**, and **2,616** LOC respectively.
The other hotspot ceilings remain as recorded in the budget manifest. Import
cycles and hard function violations must remain zero, and the 4,999-LOC
production-file ceiling remains unchanged. These values replace the earlier
P2 allowances; the historical snapshot is not rewritten.

Four production files still exceed 2,000 physical lines:

| Remaining concentration | Physical LOC |
| --- | ---: |
| `src/claude-local-transcript-provider.ts` | 3,534 |
| `src/terminal-agent-bridge.ts` | 2,641 |
| `src/terminal-list-cli-adapter.ts` | 2,616 |
| `src/terminal-acceptance-cli-adapter.ts` | 2,272 |

Those files and the remaining 330 default-threshold function violations remain
follow-up work. This closeout does not claim that all complexity is eliminated
or that the longer-horizon 250-violation goal has been reached.

Validation completed for publication: `npm run test:fast` passed all 2,434
tests; `npm run test:release` passed all 2,949 full-suite tests, the isolated
OpenClaw 2026.9.1 install/callback/update/uninstall scenario, ClawHub runtime
inspection (zero breakages or warnings), and publication dry run. TypeScript
no-emit checking, JavaScript syntax/module-link checking, architecture and
refactor-evidence validators, static preservation review, and compiled
public-contract parity also passed. All 27 changed production modules retain
their previous runtime exports. No live terminal scenarios were executed;
fixture coverage and package comparisons do not substitute for live verification.

## Contract synchronization

The canonical semantic tool contract remains
`config/public-contract-witnesses.json`. Existing contract validation proves
the exact OpenClaw list and the Host Bridge count. Pi and DeepSeek Harness no
longer repeat that count or expose a source constant for the architecture gate
to scrape. At startup they verify Host Adapter capability handshake v1: the
contract version, ordered tool names and derived count, canonical catalog
SHA-256, bundled Skill SHA-256, and their completed registration names must all
agree. Missing, unknown, or drifted handshakes fail before AKK becomes ready.

The only editable Skill source is:

```text
templates/openclaw-skills/agent-knock-knock/SKILL.md
```

The Pi and DeepSeek Harness package copies are generated artifacts and must not
be edited directly. `npm run skill:sync` atomically regenerates both copies;
`npm run skill:check` fails on a missing or byte-different artifact and reports
the canonical SHA-256. Connector builds regenerate only their allowlisted copy,
and build/prepack checks keep the packaged Skill byte-identical. The dashboard
continues to report the canonical SHA-256 and every generated replica result.

The architecture dashboard therefore reports only its directly witnessed
OpenClaw/Host Bridge parity; connector parity is executable conformance rather
than a regex over connector source. Connector release policy also has one
engine. `npm run connectors:verify`
runs its deterministic offline mode for Pi and DeepSeek Harness independently;
the connector-local `release:check` wrappers add clean-main, upstream, unused
npm version/tag, and explicit publish-confirmation checks. Ordinary root
validation never queries published registry state.

Host connectors and the shared semantic runtime depend only on the neutral
`semantic-tool-*`, `semantic-private-authority-offers`, and
`host-monitor-reconciliation` modules. OpenClaw's command, schema, helper,
private-offer, and supervisor filenames are compatibility adapters over those
owners; no Host or semantic-core module imports an `openclaw-*` implementation.
This keeps the 24-tool schema/order/digest, owner-local offers, asynchronous
relay, and one Host-owned lifecycle byte-compatible while making dependency
direction executable in the fast contract tests and architecture evidence.

## Refactor boundaries

The Issue #320 sequence uses narrow strangler changes:

1. P0 makes model-control availability and execution consume one decision and
   makes managed Turn and Watch native-interaction responses consume one
   transaction kernel.
2. P1 decomposes the terminal command, List, and Bridge adapters along existing
   use-case boundaries while retaining their public facades and single input
   ledger boundary.
3. P2 extracts reusable callback/Store kernels, makes the Host tool and Skill
   catalogs single-source, and splits oversized tests and historical documents.

Monitor and Watch share terminal observation and native-interaction execution,
including blocking `questionnaire` and working-parallel Codex `async_question`
offers. An async response defaults to advertised `steer_current_turn` or explicitly
selects advertised `queue_next_turn`; a blocking questionnaire carries none. Both
public paths remain semantic-ID-only and never expose raw keys or menu indexes.
They do not share task-completion semantics or persistence ownership. Model
control ordinary, residual-continuation, and repair authorities remain separate
domains. Refactoring must not use file movement to collapse those distinctions.

## Updating the dashboard

Use the gate during each small refactor PR:

```bash
npm run test:fast
npm run typecheck
npm run build
npm run validate:architecture
npm run validate:refactor-evidence
git diff --check
```

The architecture command exits nonzero before printing a successful dashboard
when a budget or synchronization invariant fails. Normal P0/P1/P2 development
uses only the fast test tier. Full/release tests follow repository policy and
are not implied by updating this dashboard.

Snapshot observation values are historical and are not rewritten after every
feature. A hotspot or soft-complexity ceiling may be lowered after a completed
refactor milestone. It must not be raised to make a regression green. New
production modules still require an explicit owner and affected-test mapping.
