@agentskit/harness 0.3.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,82 @@
1
+ # ADR-0026: Kernel and adapter boundary for 0.4.0
2
+
3
+ ## Status
4
+
5
+ Accepted — approved by the owner on 2026-09-10.
6
+
7
+ ## Context
8
+
9
+ The Harness now contains deterministic SDLC controls, local execution
10
+ plumbing, and three provider-facing adapters. The 0.4.0 goal is a modular
11
+ engine that can plug in orchestrators, documentation, trackers, memory,
12
+ models, MCP, and event bridges without making the kernel provider-specific.
13
+ H-040 requires a baseline before changing behavior and must not infer
14
+ architecture decisions that belong to the owner.
15
+
16
+ ## Decision
17
+
18
+ Adopt the following boundary for review:
19
+
20
+ 1. **Kernel:** deterministic contracts and decisions: state machine, discovery,
21
+ WIP admission, delivery gates, eval scoring, cache/memory record contracts,
22
+ workflow scheduling, policy, preflight, coordination, resilience, status,
23
+ learning, model bindings, and metric projections. Kernel modules may use
24
+ Node standard library and other kernel contracts only.
25
+ 2. **Execution support:** local filesystem, Git/source snapshots, process or
26
+ Docker execution, event logs, evidence, run persistence, reconciliation,
27
+ and the CLI. It may depend on the kernel but does not define provider
28
+ semantics.
29
+ 3. **Adapters/plugins:** Doc Bridge, Orca, Linear/GitHub (or another tracker),
30
+ LLM providers, memory stores, MCP, and event bridges. They implement
31
+ generic contracts and own credentials/network side effects.
32
+ 4. **Composition:** `src/index.ts` and `src/cli.ts` compose the surfaces. A
33
+ consumer must not import private module paths as a supported API.
34
+ 5. **Fail-closed rule:** provider failure, missing evidence, stale source, or
35
+ ambiguous product decisions cannot be converted into a passing kernel
36
+ decision by an adapter.
37
+
38
+ ## Dependency constraints
39
+
40
+ ```text
41
+ consumer -> composition -> execution support -> kernel
42
+ consumer -> composition -> adapters -> kernel contracts
43
+ kernel -> kernel / Node stdlib only
44
+ ```
45
+
46
+ Type-only references between `context`, `plugins`, `events`, `runtime`, and
47
+ `types` are allowed. `bundle` may call run reconciliation because signed
48
+ evidence must be exported only from a reconciled terminal run. These are the
49
+ only baseline exceptions; a new runtime import direction requires an ADR.
50
+
51
+ ## Human decisions required
52
+
53
+ The following decisions are intentionally not inferred by this ADR:
54
+
55
+ - approve the module classifications in `docs/MODULE-BOUNDARIES.md`;
56
+ - approve `codex / gpt-5.6-luna / high` as the pilot's fixed provider/model
57
+ binding, or provide a replacement;
58
+ - approve the proposed eval thresholds and three repetitions, or provide
59
+ different values;
60
+ - provide or authorize a controlled no-Harness cohort and its task IDs;
61
+ - decide whether future MCP/event-bridge adapters belong in this package or a
62
+ separate integration package once their contracts are specified.
63
+
64
+ The architecture decision is accepted. H-040 still requires empirical baseline
65
+ collection and verification evidence before it can be reported complete.
66
+
67
+ ## Consequences
68
+
69
+ - Swapping Orca, a tracker, Doc Bridge, a model, or a memory backend does not
70
+ require changing kernel decisions.
71
+ - External side effects stay auditable and testable through adapter contracts.
72
+ - The kernel remains usable in a local process or Docker execution mode.
73
+ - Provider-specific integration tests and evals are required before an adapter
74
+ can be described as production-ready.
75
+
76
+ ## Alternatives considered
77
+
78
+ - **Provider logic in the kernel:** rejected; it couples decisions to vendors
79
+ and makes deterministic comparison impossible.
80
+ - **A new abstraction layer for every capability:** rejected for now; one-file
81
+ capabilities stay in the existing capability-first layout until a second
82
+ implementation or boundary test requires a directory.
@@ -0,0 +1,41 @@
1
+ # ADR-0027: Keep-pushing loop as composition over Orca
2
+
3
+ - Status: Accepted
4
+ - Date: 2026-09-11
5
+
6
+ ## Context
7
+
8
+ Teams want a coding-agent loop that drains one person's Linear queue around the clock: pick a ticket, freeze a
9
+ verifiable contract, run a worker in an isolated worktree, review, merge, repeat — while never exceeding the
10
+ machine, never guessing when acceptance criteria are missing, and surviving provider usage limits. The harness already
11
+ owns the deterministic pieces (dispatch ledger, machine pressure, delivery gates, evidence). Orca already owns
12
+ scheduling, worktrees, terminals, Linear access and the visibility surface. Nothing owned the composition.
13
+
14
+ ## Decision
15
+
16
+ 1. The loop lives in this package as **Adapter + Composition** (`src/adapters/{command,orca-cli,providers,linear-orca,
17
+ github-cli,code-review}.ts`, `src/loop/*`). The kernel is unchanged and never imports it (`pnpm test:boundaries`).
18
+ 2. Every project-specific value lives in `loop.config.yaml` (zod-validated). The code carries no repository, person,
19
+ path or model id. Env variable **names** may appear in config; values never do.
20
+ 3. External systems are reached only through argv-based, timeout-bounded process execution injected as a
21
+ `CommandRunner`. Adapters never spawn a shell; composition supplies the real runner; tests supply fakes.
22
+ 4. Orca is the single scheduler and visibility surface: two automations (`<prefix>-tick`, `<prefix>-deliver`), each
23
+ gated by a read-only `--precheck` that exits 0 only when work exists, run an agent prompt whose sole job is to
24
+ invoke `ak-harness loop <stage>`. No cron, launchd or daemon of our own.
25
+ 5. Model routing is tiered per role (`orchestrator`, `reviewer`, `builder`, `watcher`); within a tier the first
26
+ provider with usage available wins. Usage comes from `orca account list`; an auth/quota failure marks the provider
27
+ cooling down (exponential, never before the reset Orca reports) and the next candidate is tried.
28
+ 6. Autonomy envelope: the loop may claim tickets, freeze contracts, dispatch workers, nudge them, review, squash-merge on
29
+ a clean review plus green checks, move Linear states and clean worktrees. It must not merge PRs touching
30
+ `selfEditPaths`, must not force-push or bypass approvals, must not recover leases (human only, ADR-0021), and must
31
+ escalate with one deduplicated comment when a contract has no executable acceptance criterion or when fix rounds
32
+ are exhausted.
33
+
34
+ ## Consequences
35
+
36
+ - `yaml` and `zod` become runtime dependencies of the package.
37
+ - The loop is verifiable offline: every stage has fixture-driven tests and `--dry-run` prints the exact argv.
38
+ - Provider CLIs (`claude`, `codex`, `grok`, `opencode`) are configuration, not code; adding one is a YAML entry with a
39
+ TUI template, an optional headless template and an `agentskit-review` provider id.
40
+ - Windows is supported through Node's process model; WSL is detected and capped to one worker because host
41
+ antivirus load is invisible from the distro.
@@ -0,0 +1,18 @@
1
+ # Getting started
2
+
3
+ Install the package, then run the included consumer example:
4
+
5
+ ```bash
6
+ pnpm add -D @agentskit/harness
7
+ pnpm build
8
+ node examples/minimum-profile.mjs
9
+ ```
10
+
11
+ The example uses a fake profile in YOLO mode, a coding-agent adapter, a local
12
+ Doc Bridge index, adversarial code review, and a dry-run tracking adapter. It
13
+ prints a structured result and never performs a network mutation.
14
+
15
+ For a real project, keep phase decisions in the kernel, select a named profile,
16
+ and provide integrations through adapters. Start with `mode: "dry-run"`, inspect
17
+ the evidence, then move to `safe` or `yolo` only after the preflight contract is
18
+ current.
package/docs/LOOP.md ADDED
@@ -0,0 +1,195 @@
1
+ # Keep-pushing loop (`ak-harness loop`)
2
+
3
+ The loop drains one person's Linear queue through Orca worktrees, 24/7, with role-based model routing and
4
+ usage-aware fallback. The harness supplies the deterministic parts (claims, machine pressure, gates, evidence);
5
+ Orca supplies scheduling, worktrees, terminals, Linear access and visibility. Everything project-specific lives in
6
+ `loop.config.yaml` — switching project or person is a config change, never a code change.
7
+
8
+ Status: **complete (phases 1–5).** Config, doctor, adapters, the dispatch tick, the deliver stage and the Orca
9
+ automation installer are in place. See [ADR-0027](ADR-0027-keep-pushing-loop.md).
10
+
11
+ ## Commands
12
+
13
+ ```bash
14
+ ak-harness loop validate -f loop.config.yaml # schema check + effective config + hash
15
+ ak-harness loop doctor -f loop.config.yaml --json # readiness report (exit 1 when a blocking check fails)
16
+ ak-harness loop doctor --no-probe # skip provider probe commands
17
+ ak-harness loop precheck tick # exit 0 when a slot, a builder and a candidate exist (Orca --precheck)
18
+ ak-harness loop tick --dry-run --max 1 # plan the next dispatch, print the exact orca argv, write nothing
19
+ ak-harness loop tick # dispatch up to <free slots> workers
20
+ ak-harness loop contract ENG-123 [--refresh|--dry-run] # freeze or show the orchestrator contract for one issue
21
+ ak-harness loop precheck deliver # exit 0 when a dispatched issue is in flight
22
+ ak-harness loop deliver [--dry-run] [--issue ENG-123] # drive dispatched workers to merge
23
+ ak-harness loop install [--yes|--force|--skip-rehearsal|--skip-local-config|--dry-run|--plain] # guided: overlay → checks → rehearsal → confirm
24
+ ak-harness loop uninstall [--dry-run] # remove them
25
+ ak-harness loop status # what Orca knows: enabled, trigger, provider, latest run
26
+ ak-harness loop hook # one status line for a SessionStart hook; never mutates
27
+ ak-harness loop debrief [--issue ENG-123] [--since 24h] # human-facing: what is in flight, held, escalated
28
+ ak-harness loop watch [--issue ENG-123] [--once] [--interval 30] # poll delivery/PR; DONE|FAILED|ACTION_REQUIRED
29
+ ak-harness loop retro [--since 7d] [--json|--learnings] # weekly digest + calibration suggestions
30
+ ```
31
+
32
+ ### Debrief and watch
33
+
34
+ `loop debrief` is the human companion to the automations: a read-only Markdown (or `--json`) snapshot of
35
+ in-flight dispatches, delivery phase (waiting for PR / review / fix round / ready to merge), holds that need a
36
+ person, recent escalations and provider cooldowns. It does not call Orca or `gh` — only the loop state directory —
37
+ so it is safe to run from a SessionStart hook or a chat agent that needs context before acting.
38
+
39
+ `loop watch` polls `delivery.json` (and optionally the live PR via `gh`) and prints line-oriented events:
40
+
41
+ | Event | Meaning |
42
+ |---|---|
43
+ | `DONE` | Delivery finished as merged (or the PR is MERGED) |
44
+ | `FAILED` | stuck / abandoned / failed / PR closed without merge |
45
+ | `ACTION_REQUIRED` | held for a human, incomplete review twice, or fix-round findings |
46
+ | `PROGRESS` | still moving (waiting for PR, review pending, …) |
47
+
48
+ Use `--once` for a single snapshot; omit it to block until a terminal outcome (or `--timeout <seconds>`).
49
+
50
+ ## Running 24/7 with Orca
51
+
52
+ `loop install` is guided and rendered with Ink when stdin/stdout are terminals (plain lines otherwise). When no
53
+ `loop.config.local.yaml` exists next to the config it first offers to create one: it lists the Linear team members from
54
+ Orca, asks whose queue this machine drains and, optionally, how much RAM to keep free and the worker ceiling, then
55
+ writes the gitignored overlay and reloads. It then runs the doctor and the automation-environment checks (harness and review CLIs on
56
+ PATH, `gh auth status`, checkout registered in Orca, queue owner), stops on any failed check unless `--force`,
57
+ offers a dry-run tick rehearsal (one orchestrator call, nothing written), lists the exact automations it will
58
+ create, and asks for confirmation before touching Orca. `--yes` accepts every prompt for scripted setups; without
59
+ a TTY the command refuses unless `--yes` or `--dry-run` is given; `--plain` keeps the old check-free behaviour.
60
+
61
+ It creates two automations in the Orca runtime, each bound to the main checkout as an existing workspace
62
+ with session reuse:
63
+
64
+ | Automation | Trigger | Precheck (plain command, exit 0 = run) | Prompt |
65
+ |---|---|---|---|
66
+ | `<prefix>-tick` | `schedule.tick` | `<harnessCommand> loop stage tick -f <config>` (runs the tick, exits 1) | never reached under `runner: precheck` |
67
+ | `<prefix>-deliver` | `schedule.deliver` | `<harnessCommand> loop stage deliver -f <config>` (runs deliver, exits 1) | never reached under `runner: precheck` |
68
+
69
+ With the default `schedule.runner: precheck` the **precheck command is the stage itself** (`ak-harness loop stage
70
+ tick|deliver`): it runs the harness, prints the JSON report and always exits 1, so Orca records every run as
71
+ `skipped_precheck` with the report in `precheckResult.stdout` and never opens an agent session. This is deliberate:
72
+ Orca caps a precheck at 600 s, so `contract.timeoutMs` (default 300 s) plus dispatch must fit one run; an Orca-launched agent starts in bypass-permissions mode and waits for a human to accept the warning, which leaks one
73
+ stuck session per run. `schedule.runner: agent` keeps the legacy behaviour for providers that run unattended.
74
+ Runs and their output are visible in Orca's Automations view and via `loop status`.
75
+
76
+ `schedule.harnessCommand` must resolve inside Orca's environment: install the harness globally
77
+ (`npm i -g @agentskit/harness`) or set an absolute command. `loop install` warns when it cannot find it on this shell's PATH.
78
+
79
+ Optional SessionStart hook for Claude Code (`.claude/settings.json` of the target project):
80
+
81
+ ```json
82
+ { "hooks": { "SessionStart": [{ "hooks": [{ "type": "command", "command": "ak-harness loop hook -f loop.config.yaml", "timeout": 10 }] }] } }
83
+ ```
84
+
85
+ It prints `loop: installed (2/2, last run …)` or the install command; it never installs or changes anything.
86
+
87
+ ## Deliver
88
+
89
+ For every issue the loop dispatched (`<stateDir>/issues/<id>/dispatch.json`) and has not finished:
90
+
91
+ | Situation | Action |
92
+ |---|---|
93
+ | No PR, worker terminal alive and active | wait |
94
+ | No PR, idle ≥ `workerIdleTimeoutMin` | one check-in via `terminal send`; idle again after that → **stuck**: lease released, issue → `returnState` + `blocked`, worktree kept |
95
+ | No PR, terminal gone (> 5 min after dispatch) | **stuck** as above |
96
+ | PR touches `selfEditPaths` | **held**: one PR comment, no review, no merge |
97
+ | PR conflicting | rebase instruction to the worker, once per head (does not count as a fix round) |
98
+ | CI red | failing check names to the worker; counts as a fix round |
99
+ | CI pending / required check missing | wait |
100
+ | CI green, head not reviewed | `agentskit-review --pr … --block <minSeverity> --result … [--post]` with the first available reviewer candidate |
101
+ | Review findings ≥ floor | findings to the worker; counts as a fix round; same head is never re-reviewed |
102
+ | Fix rounds exhausted (`maxFixRounds`) | **blocked**: Linear comment + label + `returnState`, PR comment, lease released, worktree and PR kept |
103
+ | Review clean, `merge.auto` | `gh api PUT …/merge` with `sha=<reviewed head>` (GitHub refuses if the head moved) → Linear attach + comment + `doneState`, worktree removed when `cleanupWorktree` |
104
+ | PR merged outside the loop | same completion path |
105
+ | PR closed without merge | **abandoned**: lease released, issue → `returnState`, worktree kept |
106
+
107
+ State lives in `<stateDir>/issues/<id>/delivery.json` (reviews per head, fix rounds, nudges) and every decision is
108
+ appended to `<stateDir>/events.ndjson`. `--dry-run` reports the decision for each issue without touching anything.
109
+
110
+ ## One tick
111
+
112
+ 1. **Intake** — `orca linear list-issues` once per configured state, filtered and ordered locally; issues already
113
+ leased, linked to a live worktree or sitting on their branch are *busy* and skipped.
114
+ 2. **Admit** — `assessSlots` (machine) and the harness dispatch ledger (`<stateDir>/coordination`) decide how many
115
+ workers may start; a claim is atomic per issue/worktree/branch.
116
+ 3. **Contract** — the orchestrator (first available candidate across `models.orchestrator` tiers) reads the issue and
117
+ the repository read-only and returns a JSON contract between `<<<LOOP_CONTRACT … LOOP_CONTRACT>>>`. Issue text is
118
+ wrapped as untrusted data. An auth/quota failure on one candidate marks it cooling down and the next is tried.
119
+ Contracts are cached under `<stateDir>/issues/<id>/contract.json` while the issue is unchanged.
120
+ 4. **Dispatch or escalate** — a contract with at least one executable outcome and no blocking ambiguity becomes a
121
+ worker: `orca worktree create --linear-issue <url> --base-branch <base> --no-parent` (no `--agent`: Orca's agent
122
+ launcher runs Claude in bypass-permissions mode and waits for a human), then `orca terminal create --command
123
+ "<providers.<id>.tui>"`, `terminal wait --for tui-idle`, and the brief goes in through `terminal send`. The issue
124
+ moves to `In Progress` and one dedicated comment is posted. Otherwise the loop posts one
125
+ `needs-info` comment (deduped by contract digest), adds the label, and moves on without consuming a slot.
126
+
127
+ Every side effect is recorded in `<stateDir>/events.ndjson`; `dispatch.json` per issue links the worktree,
128
+ terminal handle, provider/model and lease for the deliver stage.
129
+
130
+ Start from [`loop.config.example.yaml`](../loop.config.example.yaml) at the package root.
131
+
132
+ ## What the doctor checks
133
+
134
+ | Check | Source | Blocking |
135
+ |---|---|---|
136
+ | `orca.version` / `orca.runtime` | `orca --version`, `orca status --json` | yes — the loop cannot run without a reachable Orca runtime at or above `orca.minVersion` |
137
+ | `provider.<id>` | PATH lookup, `orca account list` usage windows, `orca agent hooks status`, env key names, optional probe, cooldown store | no — reported per provider |
138
+ | `routing.<role>` | tiers from `models.<role>` filtered by provider availability | yes — a role with no available provider blocks |
139
+ | `machine.slots` | `sampleMachine` + `adaptiveConcurrency`, free RAM reserve, WSL cap, running worktrees | no — 0 free slots is a warning, not a failure |
140
+ | `linear.queue` | `orca linear list-issues` per configured state, filtered and ordered locally | yes — an unreachable Linear blocks |
141
+
142
+ ## Model routing
143
+
144
+ `models.<role>` is a list of tiers; each tier is a list of `provider/model`. Tiers are tried in order and, inside a
145
+ tier, providers in declaration order. The first provider that is **available** wins. A provider is available when
146
+ its binary is on PATH, its auth is not known to be missing, no Orca usage window is at or above
147
+ `cooldown.exhaustedPercent`, it is not cooling down, and its optional probe passed.
148
+
149
+ Providers authenticate through their own CLI login (`claude login`, `codex login`, `grok login`); only providers
150
+ declared `auth: api-key` need an environment variable, and the loop never reads its value. Orca has no per-run model flag; the chosen model is rendered into `providers.<id>.tui` (for example
151
+ `codex -m {model} --full-auto`) and launched in the worker terminal.
152
+
153
+ When a provider runs out of usage the loop records a cooldown in `<stateDir>/provider-cooldowns.json`:
154
+ `initialMin` doubling up to `maxMin`, never earlier than the reset instant Orca reported.
155
+
156
+ ## Machine slots
157
+
158
+ `maxAgents = max(floor, min(adaptiveConcurrency(ceiling), ramBound, wslCap?))` where `ceiling` defaults to
159
+ `cpus / 2`, `ramBound` fits `agentRssMb` agents into free RAM minus `minFreeRamGb`, and the WSL cap applies only
160
+ inside a WSL distro (host Defender load is invisible there). The loop never lowers a running worker; it only
161
+ decides whether to start another.
162
+
163
+ ## Boundaries
164
+
165
+ Adapters (`src/adapters/command.ts`, `orca-cli.ts`, `providers.ts`, `linear-orca.ts`) depend on kernel contracts
166
+ only and receive a `CommandRunner`; they never spawn a shell. Composition (`src/loop/*`) supplies the real
167
+ runner and wires adapters together. See `docs/MODULE-BOUNDARIES.md`.
168
+
169
+ ## Security notes
170
+
171
+ - `loop.config.yaml` holds env variable **names**, never values.
172
+ - Every external call is argv-based with a timeout; `ok: false` envelopes fail closed.
173
+ - Linear text is data. Later phases render it into worker briefs inside delimiters and never execute it.
174
+
175
+ ## Continuous improvement: `loop retro`
176
+
177
+ `ak-harness loop retro --since 7d` reads `<stateDir>/events.ndjson`, every `issues/<id>/{contract,dispatch,delivery}.json`,
178
+ `provider-cooldowns.json` and (unless `--no-orca`) the Orca run records of the two automations, and prints a Markdown
179
+ digest:
180
+
181
+ - **Numbers** — contracts frozen, escalation rate, dispatches by provider, merged/blocked/stuck/abandoned/in flight,
182
+ review outcomes, fix rounds, median dispatch→merge, cooldowns, Orca runs (idle/work/timed out, durations).
183
+ - **Problems** — escalation reasons grouped by shape, blocked/stuck/abandoned issues.
184
+ - **What worked** — merged issues with worker, lead time and fix rounds.
185
+ - **Adjustments — project** — rule-based suggestions about the target project, each with its evidence and the
186
+ `loop.config.yaml` knob to turn (`escalation-rate`, `review-floor`, `fix-rounds`, `stuck-workers`, `review-incomplete`,
187
+ `provider-cooldowns`, `idle-loop`, `lead-time`, or `steady`).
188
+ - **Adjustments — harness** — defects or limitations of the library itself, derived from events the loop only emits
189
+ when its own machinery misbehaved (`worker-relaunch`, `dispatch-failures`, `contract-failures`, `merge-refusals`,
190
+ `review-tool-errors`, `stage-timeout`), with a pointer to the harness issue tracker. `--target project|harness`
191
+ filters one side.
192
+
193
+ The headings follow the harness retro grammar, so `--learnings` prints `LearningRecord`s in `proposed` state; a human
194
+ promotes them with `promoteLearnings` (ADR-0019 keeps that decision human). The calibration loop is: read the digest →
195
+ change one knob in `loop.config.yaml` → next digest measures the effect.
@@ -0,0 +1,171 @@
1
+ # Module and boundary inventory (H-040)
2
+
3
+ This document is the reviewed starting point for the 0.4.0 work. It describes
4
+ the repository at revision `f4b2b092af97d528bd5fe5955ed38f101521b98d` (the
5
+ `main` baseline captured on 2026-09-10) and is intentionally descriptive: it
6
+ does not claim that the proposed 0.4.0 boundary has already been accepted.
7
+
8
+ ## Classification
9
+
10
+ | Class | Meaning | Dependency rule |
11
+ | --- | --- | --- |
12
+ | Kernel | Deterministic contracts, state transitions, policy and metric projections | May use Node standard library and other kernel modules; must not import adapters, provider SDKs, CLI composition, credentials, or UI libraries (`ink`/`react` are composition-only). |
13
+ | Execution support | Local process, filesystem, event, evidence, and run lifecycle plumbing | May depend on the kernel; must expose provenance and fail closed at trust boundaries. |
14
+ | Adapter | Provider-specific or external-system integration | May depend on kernel contracts; must not be imported by kernel modules. |
15
+ | Composition | Package and CLI entry points | May compose kernel, execution support, and adapters; consumers use `src/index.ts`. |
16
+
17
+ ## Complete source inventory
18
+
19
+ Every current TypeScript module is listed below. Relative imports are the
20
+ observed imports at the baseline revision; `stdlib` means Node's built-in
21
+ modules, not a provider dependency.
22
+
23
+ | Module | Class | Responsibility | Relative dependencies | External boundary |
24
+ | --- | --- | --- | --- | --- |
25
+ | `src/kernel/constants.ts` | Kernel | State, decision, and surface constants | `types` (type-only) | None |
26
+ | `src/kernel/errors.ts` | Kernel | Typed fail-closed errors | None | None |
27
+ | `src/kernel/hash.ts` | Kernel | SHA-256 and JSON digests | stdlib | None |
28
+ | `src/kernel/types.ts` | Kernel | Shared contract, run, evidence, and metric types | `context` (type-only) | None |
29
+ | `src/kernel/state-machine.ts` | Kernel | Legal lifecycle transitions and human decisions | `constants`, `types` | None |
30
+ | `src/kernel/discovery.ts` | Kernel | Discovery freshness, ambiguity, and decision packets | `errors`, `hash` | None |
31
+ | `src/kernel/wip.ts` | Kernel | WIP admission and capacity decisions | `errors` | None |
32
+ | `src/kernel/experiment.ts` | Kernel | Comparable runtime/provider selection | `errors` | None |
33
+ | `src/delivery/index.ts` | Delivery | G2–G5 delivery gates and deterministic PR projection | `errors`, `hash` | None |
34
+ | `src/delivery/review.ts` | Delivery | Bounded parallel adversarial review lenses and evidence verdicts | `errors`, `hash`, `workflow`, `delivery/index` (type-only) | Reviewer callback supplied by caller |
35
+ | `src/kernel/cycle.ts` | Kernel | Bounded improvement-cycle assessment | stdlib, `errors` | None |
36
+ | `src/kernel/eval.ts` | Kernel | Versioned eval manifest validation, deterministic battery runner, min/median/max aggregation, and fail-closed assessment | `errors`, `hash` | Grader callback supplied by caller |
37
+ | `src/kernel/compatibility.ts` | Kernel | Pinned AgentsKit component manifest and evidence-bound compatibility assessment | `errors`, `hash` | Upstream commands and reports supplied by caller |
38
+ | `src/kernel/cache.ts` | Kernel | Safe cache keys and in-memory LLM cache contract | `hash`, `errors` | Cache backend supplied by caller |
39
+ | `src/kernel/optimization.ts` | Kernel | Token, memory, cache, parallelism comparisons | `hash`, `errors` | None |
40
+ | `src/kernel/memory.ts` | Kernel | Memory record validation and memory adapter contract | `errors` | KV store supplied by caller |
41
+ | `src/kernel/policy.ts` | Kernel | Tool/action policy gate | `errors` | None |
42
+ | `src/kernel/preflight.ts` | Kernel | File-scoped checks and safe-command validation | stdlib, `errors` | Shell command is data, never executed here |
43
+ | `src/kernel/block.ts` | Kernel | Portable execution block manifest and dependency admission | `errors`, `hash` | None |
44
+ | `src/kernel/learning.ts` | Kernel | Retrospective parsing and human learning promotion | stdlib, `errors` | None |
45
+ | `src/kernel/status.ts` | Kernel | Deterministic status snapshot and digest | `errors`, `hash`, `block`, `types` (type-only) | None |
46
+ | `src/kernel/model-policy.ts` | Kernel | Role-to-model binding and validation | `errors`, `hash` | Provider is data, not an SDK |
47
+ | `src/execution/machine.ts` | Execution support | Machine sampling and adaptive concurrency | stdlib, `types`, `errors` | Host CPU/memory metrics |
48
+ | `src/execution/coordination.ts` | Execution support | Atomic issue/worktree claims and dispatch ledger | stdlib, `errors`, `hash` | Local state directory only |
49
+ | `src/kernel/resilience.ts` | Kernel | Failure classification and bounded retry/recovery policy | `errors` | Operation callback supplied by caller |
50
+ | `src/kernel/workflow.ts` | Kernel | Bounded workflow scheduling | `errors` | Node callbacks supplied by caller |
51
+ | `src/kernel/phase-executor.ts` | Kernel | Declarative phase routing, preflight, effect policy, and bounded decisions | `errors`, `workflow` | Phase handlers, gates, and Grill-me callback supplied by caller |
52
+ | `src/kernel/artifacts.ts` | Kernel support | Versioned provenance-bound artifacts, Markdown rendering, and idempotent phase resume projection | stdlib, `errors`, `hash`, `events`, `phase-executor` (type-only) | Local state directory only |
53
+ | `src/kernel/adapter-contract.ts` | Kernel | Shared assurance levels and bounded telemetry contract | `errors` | Provider measurements supplied by adapters |
54
+ | `src/kernel/quality.ts` | Kernel | Phase telemetry validation, 0–100 quality matrix, baseline deltas, and watchdog blockers | `errors`, `hash` | Metrics supplied by phases/adapters |
55
+ | `src/kernel/pilot.ts` | Kernel | Cohort freeze and pilot assessment | `errors`, `hash` | None |
56
+ | `src/kernel/plugins.ts` | Kernel | Generic slots, dependency checks, and lifecycle listeners | `errors`, `events` (type-only) | Plugin implementation supplied by caller |
57
+ | `src/context/index.ts` | Context | Context snapshot contract, hashing, and provider slot | stdlib, `plugins`, `hash`, `errors` | Provider implementation supplied by caller |
58
+ | `src/execution/metrics.ts` | Execution support | Benchmark manifest validation, run projection, and comparison | stdlib, `errors`, `files`, `types` | Reads local state only |
59
+ | `src/execution/config.ts` | Execution support | Contract loading, profile resolution, and config hashing | stdlib, `constants`, `profiles`, `errors`, `hash`, `files`, `types` | Local `.codex/verification.json` |
60
+ | `src/profiles/index.ts` | Profiles | Profile defaults and overrides | `errors` | None |
61
+ | `src/execution/files.ts` | Execution support | Run/config JSON and task-artifact filesystem helpers | stdlib, `errors`, `types` | Local filesystem |
62
+ | `src/execution/source.ts` | Execution support | Git/source snapshot and dirty-tree detection | stdlib, `hash`, `errors`, `types` | Git CLI |
63
+ | `src/execution/runs.ts` | Execution support | Run persistence and lifecycle event creation | `hash`, `files`, `events`, `context`, `types` | Local state directory |
64
+ | `src/execution/verification.ts` | Execution support | Plan/start/verify/reconcile/approval orchestration | stdlib, `runs`, `config`, `errors`, `evidence`, `state-machine`, `source`, `files`, `context`, `hash`, `types`, `events`, `machine` | Configured check commands and local processes |
65
+ | `src/kernel/events.ts` | Kernel support | Event contracts, append-only log, hash chain, and lock recovery | stdlib, `errors`, `hash`, `context` (type-only), `types` (type-only), `runtime` (type-only) | Local filesystem |
66
+ | `src/execution/evidence.ts` | Execution support | Structured evidence parsing and artifact validation | stdlib, `hash`, `files`, `types` | Check output and local artifacts |
67
+ | `src/execution/bundle.ts` | Execution support | Signed evidence bundle export and verification | stdlib, `errors`, `files`, `hash`, `verification`, `events`, `config`, `types` | Local keys and files |
68
+ | `src/execution/agent.ts` | Execution support | Agent session recorder, resume, and tool lifecycle | stdlib, `events`, `errors`, `policy`, `runtime`, `types` | Agent/runtime callbacks |
69
+ | `src/execution/runtime.ts` | Execution support | Process, Docker, and generic tool runtimes | stdlib, `hash`, `errors`, `types` | Child process and Docker CLI |
70
+ | `src/cli.ts` | Composition | `ak-harness` / `ak-verify` command surface | `index`, `metrics`, `errors`, `events`, stdlib, `commander` | Shell/CLI invocation |
71
+ | `src/index.ts` | Composition | Supported package entry point | All supported public modules | Consumer import boundary |
72
+ | `src/adapters/doc-bridge.ts` | Adapter | Deterministic Doc Bridge context provider | stdlib, `hash`, `context` | `.doc-bridge/index.json` |
73
+ | `src/adapters/agent.ts` | Adapter | Structured coding-agent execution with bounded timeout and failure classification | `errors`, `resilience`, `adapter-contract` | Agent/provider callback supplied by caller |
74
+ | `src/adapters/orca.ts` | Adapter | Safe, idempotent Orca dispatch plan | `errors`, `hash`, `preflight` | Orca CLI arguments; no execution |
75
+ | `src/adapters/tracking.ts` | Adapter | Idempotent provider-neutral tracking transition | `errors`, `hash` | User-supplied Linear/GitHub/etc. handler |
76
+ | `src/adapters/command.ts` | Adapter | Shell-free command runner seam, PATH executable lookup, Orca JSON envelope parsing | stdlib | Command runner supplied by composition or tests |
77
+ | `src/adapters/orca-cli.ts` | Adapter | Typed `orca … --json` calls: version/status/account/agent hooks, worktree ps/create/set/rm, terminal list/send/wait/read, automations list/create/edit/remove/run | `errors`, `command` | Orca CLI via the injected runner |
78
+ | `src/adapters/providers.ts` | Adapter | Coding-agent CLI availability: binary, auth, Orca usage windows, exhaustion, cooldown, optional probe | `command` | PATH, env var names, `orca account list` payload |
79
+ | `src/adapters/linear-orca.ts` | Adapter | Linear queue via `orca linear list-issues`, issue detail, status/comment/label/attach writes with deterministic `--write-id`, `TrackingAdapter` over Orca | `errors`, `hash`, `orca-cli`, `tracking`, `command` | Linear through the Orca CLI |
80
+ | `src/adapters/github-cli.ts` | Adapter | Pull request snapshots, check classification, self-edit path guard, optimistic squash-merge and comments via `gh` | `errors`, `command` | GitHub through the `gh` CLI |
81
+ | `src/adapters/code-review.ts` | Adapter | `agentskit-review` argv, `--result` parsing, severity floor, worker-facing findings | `command` (type-only) | AgentsKit code review CLI via runner |
82
+ | `src/loop/config.ts` | Composition | `loop.config.yaml` schema (zod), loading, model reference parsing | `errors`, `hash`, `model-policy`, `yaml`, `zod` | Project config file |
83
+ | `src/loop/process.ts` | Composition | Real shell-free `CommandRunner` with timeout and output caps | stdlib, `command` (type-only) | Child processes |
84
+ | `src/loop/slots.ts` | Composition | Machine slot assessment: adaptive concurrency, RAM reserve, WSL cap, floor | stdlib, `machine`, `config` | Host CPU/memory |
85
+ | `src/loop/routing.ts` | Composition | Tiered role → provider/model selection over provider availability | `model-policy`, `providers` (type-only), `config` | None |
86
+ | `src/loop/cooldown.ts` | Composition | Provider cooldown store with exponential backoff | stdlib, `providers` | `<stateDir>/provider-cooldowns.json` |
87
+ | `src/loop/doctor.ts` | Composition | Loop readiness report: Orca, providers, routing, slots, workers, queue | adapters, `config`, `cooldown`, `routing`, `slots` | Orca CLI via runner |
88
+ | `src/loop/contract.ts` | Composition | Task contract schema, orchestrator prompt (issue text as untrusted data), marked-JSON parsing, dispatchability assessment, candidate fallback with auth/quota classification, contract cache | `errors`, `hash`, `resilience`, `doc-bridge`, `config`, `routing` (type-only), `zod` | Headless coding-agent CLI via runner |
89
+ | `src/loop/brief.ts` | Composition | Worker prompt: frozen contract + repository rules + protected paths + done signal | `contract`, `config`, `linear-orca` (type-only) | None |
90
+ | `src/loop/tick.ts` | Composition | One keep-pushing tick: intake, admit (slots + dispatch ledger claim), contract, dispatch into an Orca worktree, Linear transition, escalation, precheck | adapters, `coordination`, `errors`, `hash`, `brief`, `config`, `contract`, `cooldown`, `doctor`, `routing`, `slots` | Orca CLI + Linear via runner; `<stateDir>` files |
91
+ | `src/loop/deliver.ts` | Composition | Deliver stage per dispatched issue: PR detection, self-edit hold, conflict/CI/review fix rounds via terminal, review at head, optimistic squash-merge, Linear Done, cleanup, stuck/abandoned escalation | adapters, `coordination`, `errors`, `config`, `cooldown`, `doctor`, `routing`, `tick` | Orca, Linear, GitHub, agentskit-review via runner; `<stateDir>` files |
92
+ | `src/loop/install.ts` | Composition | Orca automation specs (`<prefix>-tick`, `<prefix>-deliver`) with read-only prechecks, idempotent create/edit by name, uninstall, status and the SessionStart hook line | `command`, `orca-cli`, `providers`, `errors`, `config`, `cooldown`, `doctor`, `routing` | Orca automations via runner |
93
+ | `src/loop/guided-install.ts` | Composition | Interactive install: doctor + environment preflight, dry-run rehearsal, confirmation, install, status; readline IO injected | `command`, `orca-cli`, `config`, `doctor`, `install`, `tick`, stdlib readline | Terminal prompts; Orca via runner |
94
+ | `src/loop/local-config.ts` | Composition | Per-machine overlay wizard: Linear team members via Orca, queue owner and machine tuning answers, YAML rendering and reload | `orca-cli`, `config`, `yaml` | Orca via runner; writes `loop.config.local.yaml` |
95
+ | `src/loop/retro.ts` | Composition | Retro digest over `events.ndjson`, per-issue state, cooldowns and Orca runs; rule-based calibration suggestions; Markdown that `parseRetro` can lift into learnings | `orca-cli`, `hash`, `learning`, `config`, `contract`, `cooldown`, `deliver`, `install`, `tick` | Orca via runner (optional); `<stateDir>` files |
96
+ | `src/loop/debrief.ts` | Composition | Human-facing read-only snapshot of what the loop is working on (in-flight, holds, escalations, cooldowns) | `config`, `contract`, `cooldown`, `deliver`, `retro`, `tick` | `<stateDir>` files only |
97
+ | `src/loop/watch.ts` | Composition | Poll delivery (+ optional live PR) and emit DONE/FAILED/ACTION_REQUIRED/PROGRESS for agents or humans | `command`, `github-cli`, `config`, `deliver`, `tick` | optional `gh` via runner; `<stateDir>` files |
98
+ | `src/loop/ui/components.tsx` | Composition | Ink components: check rows, sections, banner, spinner, select/confirm/text prompts | `ink`, `react`, `doctor` (type-only) | Terminal |
99
+ | `src/loop/ui/terminal.tsx` | Composition | `createRichIO`: Ink-backed IO for TTYs with a plain-text fallback | `ink`, `react`, `components`, `guided-install` (type-only) | Terminal |
100
+
101
+ ## Allowed dependency directions and exceptions
102
+
103
+ ```text
104
+ consumer -> src/index.ts -> composition
105
+ -> execution support -> kernel
106
+ -> adapters -> kernel
107
+ kernel -----------------> kernel (or Node stdlib)
108
+ ```
109
+
110
+ The following are intentional exceptions and are type-only or composition
111
+ edges, not provider leakage:
112
+
113
+ 1. `context.ts` uses the generic plugin slot from `plugins.ts`; the provider
114
+ implementation remains outside the kernel.
115
+ 2. `plugins.ts` references event types and `events.ts` references context and
116
+ runtime types only. These are compile-time contracts, not runtime cycles.
117
+ 3. `cli.ts` imports from `index.ts` so the CLI exercises the supported public
118
+ surface rather than private implementation paths.
119
+ 4. `bundle.ts` calls reconciliation because a bundle is only exportable from a
120
+ reconciled terminal run; this is a local execution-support dependency.
121
+ 5. `runtime.ts` contains process/Docker mechanics because those are execution
122
+ providers. Kernel decisions receive runtime evidence as data and do not
123
+ import the runtime implementation.
124
+
125
+ Any new external provider (Linear, GitHub, Orca, Doc Bridge, MCP, event bridge,
126
+ LLM, or memory backend) must enter through an adapter or plugin slot. A new
127
+ provider import in a kernel module is a boundary violation and requires an ADR.
128
+
129
+ ## Public entry point inventory
130
+
131
+ `src/index.ts` is the only supported consumer entry point. Its named exports
132
+ are grouped below; the source file remains authoritative for exact signatures.
133
+
134
+ | Area | Named exports |
135
+ | --- | --- |
136
+ | Lifecycle/config | `STATES`, `LEGAL_TRANSITIONS`, `HarnessError`, `loadConfig`, `validateConfig`, `transition`, `assertHuman`, `approvedDecision`, `loadLatestRun`, `planRun`, `startRun`, `verifyRun`, `reconcileRun`, `approveRun`, `authorizeRun`, `retryRun`, `cancelRun`, `cleanTaskArtifacts` |
137
+ | Events/plugins/context | `EVENT_LOG_GENESIS`, `FileEventStore`, `HARNESS_EVENT_SCHEMA_VERSION`, `HARNESS_EVENT_TYPES`, `inspectEventLogLock`, `recoverEventLogLock`, `createPluginRegistry`, `createPluginSlot`, `HARNESS_PLUGIN_API_VERSION`, `CONTEXT_PROVIDER_SLOT`, `hashContextSnapshot`, `hashContextSnapshots`, `readContextSnapshots`, `validateContextSnapshot`, `validateContextSnapshots` |
138
+ | Discovery and delivery | `assessDiscovery`, `isDiscoveryCurrent`, `assessWip`, `WIP_STATES`, `selectRuntime`, `assessAcceptance`, `assessIntegration`, `assessPreflight`, `assessProduction`, `assessWorktreeCleanup`, `composePullRequest`, `assessPilot`, `IMPROVEMENT_CYCLE_STEPS`, `assessImprovementCycle` |
139
+ | Eval and optimization | `assessAgentEval`, `runAgentEval`, `createLlmCache`, `createLlmCacheKey`, `validateCacheableOperation`, `compareOptimization`, `validateOptimizationObservation`, `MEMORY_SCOPES`, `createInMemoryMemoryAdapter`, `createKvMemoryAdapter`, `validateMemoryRecord`, `runWorkflow`, `BENCHMARK_SCHEMA_VERSION`, `benchmarkRuns`, `loadBenchmarkManifest`, `recordBenchmarkObservation`, `validateBenchmarkManifest` |
140
+ | Agent/runtime controls | `createSessionRecorder`, `createCodingAgentAdapter`, `createPolicyGate`, `createConfiguredToolRuntime`, `createDockerToolRuntime`, `createProcessToolRuntime`, `createToolRuntime`, `adaptiveConcurrency`, `createMachineMonitor`, `sampleMachine`, `summarizeMachine`, `createDispatchLedger`, `classifyFailure`, `recoveryDelayMs`, `runWithRecovery`, `planFilePreflight`, `validateSafeCommand`, `BLOCK_STATUSES`, `assessBlock`, `validateBlockManifest`, `LEARNING_STATUSES`, `parseRetro`, `promoteLearnings`, `createStatusSnapshot`, `validateStatusSnapshot`, `MODEL_ROLES`, `createModelPolicy`, `modelFor`, `PHASE_MODES`, `createPhaseProfile`, `planPhaseProfile`, `executePhaseProfile`, `ARTIFACT_SCHEMA_VERSION`, `createArtifactEnvelope`, `FileArtifactStore`, `artifactIsFresh`, `resumeStateFromArtifacts`, `ASSURANCE_LEVELS`, `validateAdapterMetadata` |
141
+ | Integrations and evidence | `createDocBridgeContextProvider`, `createOrcaDispatchPlan`, `createTrackingAdapter`, `createTrackingTransition`, `EVIDENCE_BUNDLE_SCHEMA_VERSION`, `exportEvidenceBundle`, `readEvidenceTrustStore`, `verifyEvidenceBundle` |
142
+
143
+ The entry point also re-exports the public type surfaces from `types`,
144
+ `events`, `plugins`, `context`, `discovery`, `wip`, `experiment`, `delivery`,
145
+ `pilot`, `cycle`, `metrics`, `agent`, `policy`, `runtime`, `bundle`, and
146
+ `machine`, `phase-executor`, `artifacts`, plus explicit type exports for cache, optimization, memory,
147
+ coordination, resilience, preflight, block, learning, status, model policy,
148
+ Orca, and tracking. No adapter implementation is re-exported wholesale.
149
+
150
+ ## External integration inventory
151
+
152
+ | Integration | Current location | Side effects | 0.4.0 boundary |
153
+ | --- | --- | --- | --- |
154
+ | Doc Bridge | `src/adapters/doc-bridge.ts` | Reads a local index | Keep behind `ContextProvider`; measure context hit/quality separately. |
155
+ | Orca | `src/adapters/orca.ts` | None; produces argv and lifecycle projections only | Keep lease/worktree/issue-lock/SHA planning provider-neutral; execution belongs to the orchestrator. |
156
+ | Linear/GitHub/other tracker | `src/adapters/tracking.ts` callback | Caller-owned network mutation | Require idempotency key and explicit tracking authorization. |
157
+ | Orca CLI (loop) | `src/adapters/orca-cli.ts`, `src/adapters/linear-orca.ts` via `CommandRunner` | Read-only `--json` calls in the doctor; dispatch/mutation arrive in later loop phases | Argv only, never a shell string; every call bounded by a timeout; envelope `ok:false` fails closed. |
158
+ | Coding-agent CLIs | `src/adapters/providers.ts` | PATH lookup and optional probe command | Env keys are names only; usage comes from Orca, never from provider SDKs. |
159
+ | GitHub | `src/adapters/github-cli.ts` via `CommandRunner` | `gh pr view/list`, `gh api PUT …/merge` with `sha=<reviewed head>`, `gh pr comment` | Merge is refused by GitHub when the head moved; every call argv-based and bounded. |
160
+ | AgentsKit code review | `src/adapters/code-review.ts` via `CommandRunner` | `agentskit-review --pr … --result <file> [--post]` | Exit codes 0/1/2 plus the private result file decide clean/findings/incomplete; the floor is `--block`. |
161
+ | Process runtime | `src/execution/runtime.ts` | Starts child processes | Execution support; policy and evidence gates remain kernel decisions. |
162
+ | Docker runtime | `src/execution/runtime.ts` | Starts Docker containers | Optional sandbox selected by config, never a mandatory kernel dependency. |
163
+ | LLM provider/model | Caller/plugin | Provider call and token spend | Bind provider/model in experiment metadata; do not embed SDKs in kernel. |
164
+ | Memory backend | Caller/plugin; `memory.ts` contract | Backend reads/writes | Keep record validation in kernel; backend adapter owns persistence. |
165
+ | MCP/event bridge | Not implemented | Future network/event effects | Add as adapters only after a separate ADR and eval coverage. |
166
+
167
+ ## Review status
168
+
169
+ This inventory is evidence for H-040. ADR-0026 records the accepted boundary;
170
+ the remaining H-040 work is empirical baseline collection and verification
171
+ evidence, not an unresolved architecture choice.
@@ -9,10 +9,17 @@ the repository stays navigable without speculative layers.
9
9
  ├── src/
10
10
  │ ├── index.ts # supported package API
11
11
  │ ├── cli.ts # ak-harness / ak-verify commands
12
- │ ├── adapters/ # optional integrations
13
- └── <capability>.ts # contract, evidence, delivery, runtime, metrics...
12
+ │ ├── kernel/ # deterministic contracts and decisions
13
+ ├── execution/ # filesystem, runtime, evidence, and run plumbing
14
+ │ ├── context/ # context contracts and provider slot
15
+ │ ├── delivery/ # delivery gates and PR projection
16
+ │ ├── profiles/ # configuration profiles
17
+ │ └── adapters/ # optional integrations
14
18
  ├── test/ # deterministic tests and fixtures
15
19
  ├── scripts/ # real CLI, packaging, and repository checks
20
+ ├── capabilities/ # generated public-surface capability manifest
21
+ ├── examples/ # runnable consumer examples
22
+ ├── compatibility/ # pinned ecosystem manifest and migration/rollback procedures
16
23
  ├── docs/ # ADRs and this organization contract
17
24
  ├── .codex/ # verification contract and local run state
18
25
  └── .github/ # CI and release workflows
@@ -22,8 +29,10 @@ the repository stays navigable without speculative layers.
22
29
 
23
30
  - Import internal modules with explicit relative paths; only `src/index.ts`
24
31
  is supported for consumers.
25
- - Add a directory when a capability has multiple cohesive modules. Do not add
26
- a layer for one file.
32
+ - Keep deterministic decisions in `kernel/`; execution mechanics and external
33
+ effects live behind the other capability boundaries.
34
+ - A single-file capability may use an `index.ts` boundary when it has a
35
+ distinct public contract; do not add speculative layers.
27
36
  - Adapters may depend on the kernel; the kernel must not depend on adapters or
28
37
  external providers.
29
38
  - Tests may use internal modules when exercising a boundary, but consumer