agents-handoff 0.0.0-stage → 2.0.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.
Files changed (54) hide show
  1. package/CHANGELOG.md +150 -0
  2. package/LICENSE +21 -0
  3. package/README.md +110 -2
  4. package/SKILL.md +147 -0
  5. package/capability-registry.json +27 -0
  6. package/docs/ARCHITECTURE.md +164 -0
  7. package/docs/CHANGELOG.md +151 -0
  8. package/docs/CLI.md +196 -0
  9. package/docs/COMPATIBILITY.md +124 -0
  10. package/docs/CONTRIBUTING.md +134 -0
  11. package/docs/FORMAT.md +157 -0
  12. package/docs/INSTALL.md +179 -0
  13. package/docs/INTEGRATION.md +188 -0
  14. package/docs/LEVEL4.md +202 -0
  15. package/docs/LEVEL5.md +96 -0
  16. package/docs/PERMISSIONS.md +145 -0
  17. package/docs/PROVENANCE.md +83 -0
  18. package/docs/SECURITY.md +93 -0
  19. package/docs/SESSIONS.md +66 -0
  20. package/docs/TROUBLESHOOTING.md +158 -0
  21. package/docs/UNINSTALL.md +122 -0
  22. package/docs/UPGRADE.md +139 -0
  23. package/docs/_config.yml +16 -0
  24. package/docs/_data/nav.yml +36 -0
  25. package/docs/_layouts/default.html +31 -0
  26. package/docs/assets/style.css +88 -0
  27. package/docs/index.md +83 -0
  28. package/handoff.config.example.json +35 -0
  29. package/handoff.config.schema.json +117 -0
  30. package/install/CHANGELOG.md +48 -0
  31. package/install/README.md +76 -0
  32. package/install/install.mjs +856 -0
  33. package/install/package.json +39 -0
  34. package/package.json +66 -4
  35. package/permission-policy.json +33 -0
  36. package/refs/ADAPTERS.md +33 -0
  37. package/refs/bootstrap.md +59 -0
  38. package/refs/brief-checklist.md +79 -0
  39. package/refs/handbook.md +58 -0
  40. package/refs/protocol.md +117 -0
  41. package/refs/roles.md +75 -0
  42. package/refs/validator.md +73 -0
  43. package/schemas/handoff.schema.json +275 -0
  44. package/skill.json +147 -0
  45. package/templates/HANDOFF.llm.schema.json +144 -0
  46. package/templates/HANDOFF.template.md +40 -0
  47. package/tests/acceptance/acceptance.yaml +209 -0
  48. package/tests/fixtures/minimal-transcript.jsonl +2 -0
  49. package/tools/agent-handoff.mjs +410 -0
  50. package/tools/capability-registry.mjs +120 -0
  51. package/tools/handoff.mjs +398 -0
  52. package/tools/handoff.test.mjs +465 -0
  53. package/tools/lib/handoff-root.mjs +161 -0
  54. package/tools/runtime-engine.mjs +330 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,150 @@
1
+ # Changelog
2
+
3
+ All notable changes to agent-handoff are recorded here.
4
+
5
+ The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project
6
+ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). Releases before 2.0.0
7
+ were development builds and were never published, so they are not listed.
8
+
9
+ The version in [package.json](https://github.com/Alot1z/agent-handoff/blob/main/package.json)
10
+ and [skill.json](https://github.com/Alot1z/agent-handoff/blob/main/skill.json) is the release
11
+ version, and it is the version published to npm: the repository root is the
12
+ [`agents-handoff`](https://www.npmjs.com/package/agents-handoff) package.
13
+
14
+ ## [Unreleased]
15
+
16
+ Add entries under the matching heading as changes land.
17
+
18
+ ## [2.0.2] - 2026-10-09
19
+
20
+ ### Added
21
+
22
+ - **[Session index](https://alot1z.github.io/agent-handoff/SESSIONS.html)** (`docs/SESSIONS.md`):
23
+ a page rendered from a real handoff store, listing the captured sessions in
24
+ `examples/sessions/` with their project, harness, turn count, revision, manifest hash and
25
+ integrity verdict, plus the commands that reproduce each check. The sample store is built by
26
+ the engine from the two transcripts this repository ships, and
27
+ `.github/scripts/build-sessions-index.mjs --check` fails the build when the page and the store
28
+ disagree.
29
+ - The skill is published to npm as
30
+ [`agents-handoff`](https://www.npmjs.com/package/agents-handoff), from the repository root,
31
+ and the release workflow publishes it on a tag: it skips a version npm already has, and
32
+ reports — without failing the release — when `NPM_TOKEN` is not configured. The package
33
+ carries the skill tree, so `npx agents-handoff` installs with no download.
34
+ - `npm test`, `npm run check:docs` and `npm run check:session-index` are wired into
35
+ `prepublishOnly`, so a tree whose suite, links or session index are stale cannot be published.
36
+
37
+ ### Changed
38
+
39
+ - `npx agents-handoff` now installs the skill as documented. It previously looked for the skill
40
+ files beside itself, found none, and reported success while installing nothing; a bare copy of
41
+ `install/` still falls back to downloading the archive for the requested version.
42
+ - The clean-checkout suite builds its fixture from the shipped projection rather than the
43
+ development tree, which is what let the installer's broken source paths pass every local test.
44
+
45
+ ### Fixed
46
+
47
+ - The installer lost fourteen files whenever it ran outside the development tree: `README.md`,
48
+ `LICENSE` and the twelve guides were addressed under `repo-upstream/<path>`, a directory only
49
+ the development tree has. Sources are written in the shipped tree's terms and resolved against
50
+ both layouts, and an install that cannot resolve a source now fails with the missing paths
51
+ instead of warning and continuing.
52
+ - CI failed on every run: the runtime-layer smoke test ran `agent-handoff.mjs list`, which is not
53
+ a verb of that tool (it exits 2). The step builds a handoff into a scratch store and runs
54
+ `index`, a verb that exists.
55
+ - The shipped version disagreed across files: `SKILL.md` said 2.0.0 while `skill.json` and
56
+ `package.json` said 2.0.1, and the installer carried its own 2.0.0 constant, so every install
57
+ reported the previous version. `SKILL.md` is now the single source of truth, the installer
58
+ reads it, and the suite asserts the two agree.
59
+ - `install/package.json` pointed `repository` at a different repository from the one serving the
60
+ package; it now names this repository, with `homepage` and `bugs`.
61
+ - `handoff.config.schema.json` declared its `$id` under a path that does not serve the schema.
62
+ - `examples/demo/example-usage.md` addressed the engine as `../../../tools/handoff.mjs`, one
63
+ directory above the repository root, so every command in it failed when pasted.
64
+ - `tests/acceptance/acceptance.yaml` described the development tree: it listed documents that
65
+ are not published, scanned a directory that is not published, and asserted two behaviours the
66
+ shipped CLI does not have (`--help` exiting 0, `list` succeeding on an empty store). Every
67
+ entry was re-run against a clean checkout and now states what was observed.
68
+ - Documentation stopped describing files that are not published: `src/` was listed as part of an
69
+ installation in `INSTALL.md`, `UNINSTALL.md` and `UPGRADE.md`, and documented as a repository
70
+ directory in `CONTRIBUTING.md`.
71
+ - `ARCHITECTURE.md` claimed nothing in the repository makes a network call, which stopped being
72
+ true once the installer fetched archives.
73
+
74
+ ## [2.0.1] — 2026-10-09
75
+
76
+ Documentation release. No behaviour changed; no public interface changed.
77
+
78
+ ### Added
79
+
80
+ - **[Command reference](https://github.com/Alot1z/agent-handoff/blob/main/docs/CLI.md)**
81
+ (`docs/CLI.md`): every executable, verb, flag, exit code, environment variable and file
82
+ written, in one place.
83
+ - **[Architecture](https://github.com/Alot1z/agent-handoff/blob/main/docs/ARCHITECTURE.md)**
84
+ (`docs/ARCHITECTURE.md`): the five layers, the data flow, store-root resolution, the
85
+ write-safety discipline, and the boundaries the tool does not cross.
86
+ - **[Troubleshooting](https://github.com/Alot1z/agent-handoff/blob/main/docs/TROUBLESHOOTING.md)**
87
+ (`docs/TROUBLESHOOTING.md`): symptom, cause and fix, keyed to the real exit codes.
88
+ - This changelog, and a Changelog page on the site rendered from it, so the repository file
89
+ and the published page cannot drift apart.
90
+ - A docs-consistency check (`.github/scripts/check-docs.mjs`) run in CI: every page under
91
+ `docs/` must appear in the navigation, and every relative link must resolve where it is
92
+ read.
93
+
94
+ ### Changed
95
+
96
+ - README now links the published [installation guide](https://alot1z.github.io/agent-handoff/INSTALL.html)
97
+ and the [documentation site](https://alot1z.github.io/agent-handoff/) at the top, and its
98
+ documentation table covers every page.
99
+ - Links in `docs/` that pointed outside the published site are absolute URLs, so they resolve
100
+ for a reader of the documentation instead of returning 404.
101
+ - `package.json` homepage points at the documentation site.
102
+
103
+ ## [2.0.0] — 2026-10-08
104
+
105
+ The first public release: a capture engine, a runtime layer over it, an installer, and the
106
+ documentation site.
107
+
108
+ ### Added
109
+
110
+ - **Capture engine** (`tools/handoff.mjs`, published as the `agent-handoff` bin). `build`
111
+ reads a JSONL or plain-text transcript and writes a handoff directory:
112
+ `HANDOFF.md`, `HANDOFF.summary.json`, `HANDOFF.llm.json`, `timeline.jsonl`, `TOOLS.md`,
113
+ `manifest.json`. Also `list`, `show`, `verify`, `rename`, `retitle` and `config`.
114
+ - **Incremental builds.** Each build appends only the turns above the recorded `watermark`
115
+ and leaves `timeline.jsonl` untouched, so re-running over a longer transcript extends the
116
+ handoff instead of duplicating it. A rebuild with no new turns and an unchanged source hash
117
+ prints `handoff: up-to-date` and writes nothing.
118
+ - **sha256 provenance.** `manifest.json` carries `raw_sha256` over the source bytes and a
119
+ self-hash `manifest_sha256` over itself. `verify` recomputes the self-hash, checks the
120
+ `timeline.jsonl` line count against `turn_count`, and parses `HANDOFF.llm.json`.
121
+ - **Store-root resolution** (`tools/lib/handoff-root.mjs`): `HANDOFFS_ROOT`, then
122
+ `handoff.config.json` found by walking up, then a `handoffs/` directory on the same walk,
123
+ then the skill directory. Reported by `handoff.mjs config`.
124
+ - **Runtime layer** (`tools/agent-handoff.mjs`): `auto`, `verify-gate`, `promote`, `merge`,
125
+ `federated-merge`, `self-improve`, `index`. Every mutating command takes a lock, backs up
126
+ before writing, verifies after applying, and rolls back on failure.
127
+ - **Bounded execution** (`tools/runtime-engine.mjs`): risk classes `R0`–`R4` evaluated against
128
+ `permission-policy.json` before any operation runs, resumable jobs with sealed checkpoints,
129
+ and a per-decision record in the state directory.
130
+ - **Capability probes** (`tools/capability-registry.mjs`): `file-exists`, `dir-writable` and
131
+ `command` probes that report `healthy` / `unhealthy` / `unknown` with the evidence behind
132
+ each verdict.
133
+ - **Installer** (`install/`, package `agents-handoff`): `install`, `update`, `remove`,
134
+ `verify`, `list`, `where`, targeting a resolved global root, `./local/skills/agent-handoff`,
135
+ or `./skills/agent-handoff`.
136
+ - **Documentation site** at <https://alot1z.github.io/agent-handoff/>, built by GitHub Pages
137
+ from `docs/`.
138
+ - **CI** (`.github/workflows/ci.yml`): the test suite on Node 18, 20 and 22, a runtime-layer
139
+ smoke test, installer help, and a required-file and JSON-validity check.
140
+
141
+ ### Security
142
+
143
+ - The engine reads transcripts and writes handoff files. It makes no network calls, and it
144
+ never writes secrets. The limits of what the provenance chain proves are stated in
145
+ [docs/PROVENANCE.md](https://github.com/Alot1z/agent-handoff/blob/main/docs/PROVENANCE.md),
146
+ not implied.
147
+
148
+ [Unreleased]: https://github.com/Alot1z/agent-handoff/compare/v2.0.1...main
149
+ [2.0.1]: https://github.com/Alot1z/agent-handoff/compare/v2.0.0...v2.0.1
150
+ [2.0.0]: https://github.com/Alot1z/agent-handoff/tree/v2.0.0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Alot1z
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,111 @@
1
- # Temporary Holding Version
1
+ # agent-handoff
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ **[Installation guide →](https://alot1z.github.io/agent-handoff/INSTALL.html)** · **[Documentation →](https://alot1z.github.io/agent-handoff/)** · **[Changelog](CHANGELOG.md)**
4
+
5
+ [![CI](https://github.com/Alot1z/agent-handoff/actions/workflows/ci.yml/badge.svg)](https://github.com/Alot1z/agent-handoff/actions/workflows/ci.yml)
6
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
7
+ [![Node](https://img.shields.io/badge/node-%3E%3D18-brightgreen.svg)](#requirements)
8
+
9
+ One handoff format for every AI coding harness. A working session — messages, tool calls,
10
+ reasoning, and the provenance to prove where each byte came from — is captured as a folder
11
+ that a fresh agent can continue from with zero shared memory.
12
+
13
+ - Zero runtime dependencies; Node.js 18 or newer.
14
+ - Reads any JSONL or plain-text transcript, whatever produced it.
15
+ - Every artifact carries a sha256 provenance chain, and `verify` recomputes it.
16
+ - Writes are backed up, verified and rolled back on failure.
17
+
18
+ ## Install
19
+
20
+ ```bash
21
+ npx agents-handoff
22
+ npx agents-handoff where # show the resolved install root, and why it was chosen
23
+ ```
24
+
25
+ The installer resolves the global root instead of hard-coding one. The resolution order,
26
+ the location targets and the requirements are in the
27
+ **[installation guide](https://alot1z.github.io/agent-handoff/INSTALL.html)** and
28
+ [docs/INSTALL.md](docs/INSTALL.md).
29
+
30
+ ## Quick start
31
+
32
+ ```bash
33
+ # Capture a session
34
+ node tools/handoff.mjs build --source session.jsonl --harness claude-code --project my-project
35
+
36
+ # List, inspect and verify what you captured
37
+ node tools/handoff.mjs list
38
+ node tools/handoff.mjs show <id-prefix>
39
+ node tools/handoff.mjs verify <id-prefix>
40
+ ```
41
+
42
+ `build` is incremental: re-running it over a longer transcript merges past the recorded
43
+ watermark instead of creating a second handoff. `verify` exits non-zero when the manifest
44
+ hash, the timeline line count or the LLM payload no longer match what was written.
45
+
46
+ ## What a handoff folder contains
47
+
48
+ | File | Contents |
49
+ |---|---|
50
+ | `HANDOFF.md` | The brief a reader picks up cold: objective, current state, open loops, recent timeline |
51
+ | `HANDOFF.summary.json` | The same brief as structured fields |
52
+ | `HANDOFF.llm.json` | Payload shaped for a model to consume |
53
+ | `timeline.jsonl` | Every turn, one per line, appended and never paraphrased |
54
+ | `TOOLS.md` | The full tool-call log |
55
+ | `manifest.json` | Counts, classes, source paths, and the sha256 provenance chain |
56
+
57
+ The field-by-field contract is in [docs/FORMAT.md](docs/FORMAT.md).
58
+
59
+ ## Documentation
60
+
61
+ Full documentation is published at **<https://alot1z.github.io/agent-handoff/>**.
62
+
63
+ | Document | Covers |
64
+ |---|---|
65
+ | [docs/index.md](docs/index.md) | Start here: what the tool does and how the docs fit together |
66
+ | [docs/INSTALL.md](docs/INSTALL.md) · [site](https://alot1z.github.io/agent-handoff/INSTALL.html) | Install, locations, install options, troubleshooting |
67
+ | [docs/UPGRADE.md](docs/UPGRADE.md) | Updating an install, and what an update leaves alone |
68
+ | [docs/UNINSTALL.md](docs/UNINSTALL.md) | Removing an install, and what is kept |
69
+ | [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) | How the layers fit together, the data flow, and the boundaries |
70
+ | [docs/CLI.md](docs/CLI.md) | Every executable, verb, flag, exit code and state file |
71
+ | [docs/FORMAT.md](docs/FORMAT.md) | Handoff folder layout, manifest fields, provenance chain |
72
+ | [docs/SESSIONS.md](docs/SESSIONS.md) · [site](https://alot1z.github.io/agent-handoff/SESSIONS.html) | Session index: a sample store, its sessions, and the commands that verify them |
73
+ | [docs/INTEGRATION.md](docs/INTEGRATION.md) | Feeding a transcript in from another program or a CI job |
74
+ | [docs/LEVEL4.md](docs/LEVEL4.md) | The runtime layer: verbs, the evidence gate, bounded execution |
75
+ | [docs/LEVEL5.md](docs/LEVEL5.md) | Dispatching a verified handoff to a worker |
76
+ | [docs/PERMISSIONS.md](docs/PERMISSIONS.md) | Permission levels, risk classes, and what is enforced |
77
+ | [docs/SECURITY.md](docs/SECURITY.md) | What is read and written, and the guarantees that are not made |
78
+ | [docs/COMPATIBILITY.md](docs/COMPATIBILITY.md) | Platforms, Node versions, transcript formats |
79
+ | [docs/PROVENANCE.md](docs/PROVENANCE.md) | The hash chain, what it detects, what it cannot |
80
+ | [docs/TROUBLESHOOTING.md](docs/TROUBLESHOOTING.md) | Symptom, cause and fix, keyed to the real exit codes |
81
+ | [docs/CONTRIBUTING.md](docs/CONTRIBUTING.md) | Running the tests and adding an adapter |
82
+ | [CHANGELOG.md](CHANGELOG.md) | What changed in each release |
83
+ | [refs/ADAPTERS.md](refs/ADAPTERS.md) | The canonical input shape and how each store maps onto it |
84
+
85
+ ## Repository layout
86
+
87
+ ```
88
+ tools/handoff.mjs capture engine (the CLI above)
89
+ tools/agent-handoff.mjs runtime layer: auto, verify-gate, promote, merge, self-improve, index, dispatch
90
+ tools/runtime-engine.mjs bounded execution and the permission gate
91
+ tools/capability-registry.mjs capability health probes
92
+ tools/lib/ shared store-root resolution
93
+ docs/ refs/ templates/ documentation, reference material, output templates
94
+ schemas/ handoff payload and configuration schemas
95
+ install/ the npx installer package
96
+ tests/ acceptance fixture and a minimal transcript
97
+ ```
98
+
99
+ ## Requirements
100
+
101
+ Node.js 18 or newer. No dependencies, no build step, no network access at runtime. See
102
+ [docs/COMPATIBILITY.md](docs/COMPATIBILITY.md).
103
+
104
+ ## Contributing
105
+
106
+ Run the suite with `node tools/handoff.test.mjs`. It is hermetic — it writes to a scratch
107
+ directory and needs no network. See [docs/CONTRIBUTING.md](docs/CONTRIBUTING.md).
108
+
109
+ ## License
110
+
111
+ MIT — see [LICENSE](LICENSE).
package/SKILL.md ADDED
@@ -0,0 +1,147 @@
1
+ ---
2
+ name: agent-handoff
3
+ description: >-
4
+ Write, verify, and hand off complete AI working sessions across any harness
5
+ (Claude Code, Codex, DeepSeek Harness, plain JSONL or text logs). Captures a
6
+ session as a portable, sha256-proven handoff folder a fresh agent can continue
7
+ from with zero shared memory, with versioned contracts, an evidence gate, and
8
+ backup/verify/rollback on every write. Zero runtime dependencies, no network.
9
+ version: 2.0.2
10
+ domain: orchestration
11
+ tokens: 900
12
+ allowed-tools: Bash(node:*), Read, Edit, Write
13
+ ---
14
+
15
+ # Agent Handoff v2 — cross-harness session capture + verified continuation
16
+
17
+ ONE handoff system for every harness, every project, every model — backed by versioned
18
+ contracts, an evidence gate, and backup/verify/rollback on every write. Pick up any
19
+ conversation anywhere, with provenance for every artifact.
20
+
21
+ ## Level map (progressive disclosure)
22
+
23
+ | Level | When loaded | Token cost | Content |
24
+ |-------|-------------|-----------|---------|
25
+ | **L1 Metadata** | Always (frontmatter above) | ~100 | name + description |
26
+ | **L2 Instructions** | This file, when triggered | <5k | core workflow + commands below |
27
+ | **L3 Resources** | As needed | none until read | `docs/`, `templates/`, `refs/`, `tools/handoff.mjs` |
28
+ | **L4 Dynamic** | When you need runtime/self-adapting | none until run | `tools/agent-handoff.mjs`: auto, verify-gate, promote, merge, self-improve |
29
+ | **L5 Collaborative** | Verified handoff dispatches a worker | none until run | `tools/agent-handoff.mjs` dispatch + `docs/LEVEL5.md` |
30
+
31
+ ## What this skill is (capabilities + contracts)
32
+
33
+ 1. **Capture engine** (`tools/handoff.mjs`, zero deps) — builds
34
+ `projects/<project>/<session>/{HANDOFF.md, HANDOFF.summary.json, HANDOFF.llm.json,
35
+ timeline.jsonl, TOOLS.md, manifest.json}` with sha256 watermark-provenance; update-not-recreate.
36
+ 2. **Brief discipline** — lossless operational compression (10k-30k token briefs,
37
+ TASK / USER SPECIFICATION / CURRENT STATE / DONE / IN PROGRESS / PLANNED / FAILED / FILES /
38
+ VERIFICATION / ENVIRONMENT / NEXT / DO NOT), with length floors and a bootstrap text.
39
+ 3. **Evidence contract** — every handoff states RESULT/WHAT_CHANGED/VALIDATION/
40
+ EVIDENCE/BLOCKERS/RISKS/FOLLOW_UP; no evidence = no verified transition.
41
+ 4. **Write safety** — trigger on staleness, lock-guard, backup before write,
42
+ verify after write, rollback on failure, idempotent re-run.
43
+ 5. **Pipeline principles**:
44
+ - **Lossless raw**: rawInput/objective is verbatim, never replaced or paraphrased
45
+ (PromptIR rule). Matches handoff "objectives verbatim".
46
+ - **Versioned contracts**: every handoff artifact is a contract (schema v1, sha256);
47
+ re-run merges past watermark. No unversioned writes.
48
+ - **DecisionTrace**: record route/selection stages + provenance on every handoff
49
+ (stages: capture → brief → verify.gate → promote → dispatch).
50
+ - **Evidence-gated completion (ORC-1)**: state transitions only on evidence;
51
+ a worker-DONE is never a verified transition. verify.gate runs before promote/dispatch.
52
+ - **ContextPlan buckets (CTX-1)**: in the brief, classify context as required |
53
+ historical | authoritative | retrievable | sensitive | deferred with budget caps.
54
+ - **EVIDENCE_LEVELS ladder (KNOW-1)**: VERIFIED > OBSERVED > DERIVED > PREDICTED > UNKNOWN;
55
+ never silently upgrade; supersede rather than stack.
56
+ - **Autonomy ladder (CTL-1)**: observe → suggest → request-approval → constrained-execute →
57
+ workflow-execute → autonomous-within-policy. Handoff writes default to constrained-execute;
58
+ dispatch default dry-run.
59
+ - **Honesty rule (FINAL-1)**: oracle registry + success-criteria evaluator; RESULT is
60
+ DONE|PARTIAL|BLOCKED|FAILED — never fabricated.
61
+
62
+ ## Doctrine (unchanged + corpus-backed)
63
+
64
+ 1. Prompts are advisory; validators are authoritative. Fail closed on ambiguity (BLOCKED).
65
+ 2. Portability over compression: fidelity lives verbatim in the fileset (TOOLS.md, timeline.jsonl,
66
+ HANDOFF.llm.json); briefs reference by pointer.
67
+ 3. Downgrade unverified claims to their true evidence level — never upgrade.
68
+ 4. Handoff is prior knowledge, not ground truth: re-verify against the cheapest available
69
+ oracle, and keep instructions self-contained so a fresh agent can act cold.
70
+ 5. Max-local: every engine here runs with zero network deps; harness adapters are
71
+ probe-absent-safe (Claude Code, Codex, DeepSeek Harness, plain JSONL, plain text).
72
+
73
+ ## Core workflow
74
+
75
+ ### A. Capture (any harness)
76
+ ```bash
77
+ cd <handoffs-store> # or set HANDOFFS_ROOT
78
+ node tools/handoff.mjs build --source <transcript.jsonl|.txt|.md> \
79
+ --session <id> --harness claude-code|codex|dsh|generic \
80
+ --model <name> --project <project> [--objective "text"]
81
+ ```
82
+ Re-run merges past watermark. `verify <id-prefix>` checks manifest sha + turn-count + JSON parse.
83
+
84
+ ### B. Write the lossless brief (COS rules + CTX buckets)
85
+ Headings TASK / USER SPECIFICATION / CURRENT STATE / DONE / IN PROGRESS / PLANNED-DECIDED /
86
+ FAILED-UNRESOLVED / FILES / VERIFICATION / ENVIRONMENT / NEXT / DO NOT. Enforce floors
87
+ (>=200 chars any session; >=1000 chars for >=20k recorded tokens). Preserve exact
88
+ paths/ids/commands/error text. Mark context provenance: required | sensitive | deferred.
89
+
90
+ ### C. Gate with evidence (orchestrator + ORC-1)
91
+ ```
92
+ RESULT: DONE | PARTIAL | BLOCKED | FAILED
93
+ WHAT_CHANGED:
94
+ VALIDATION:
95
+ EVIDENCE: # artifact + sha; must match pending dispatch (phaseId + dispatchId)
96
+ BLOCKERS:
97
+ RISKS:
98
+ FOLLOW_UP:
99
+ ```
100
+
101
+ ### D. Level 4 runtime + L5 dispatch
102
+ ```bash
103
+ HANDOFFS_ROOT=<store> node tools/agent-handoff.mjs auto --source <file> --session <id> --harness <h> --project <p>
104
+ HANDOFFS_ROOT=<store> node tools/agent-handoff.mjs verify-gate <id-prefix>
105
+ HANDOFFS_ROOT=<store> node tools/agent-handoff.mjs promote <id-prefix>
106
+ HANDOFFS_ROOT=<store> node tools/agent-handoff.mjs merge <a> <b>
107
+ HANDOFFS_ROOT=<store> node tools/agent-handoff.mjs self-improve
108
+ HANDOFFS_ROOT=<store> node tools/agent-handoff.mjs index
109
+ HANDOFFS_ROOT=<store> node tools/agent-handoff.mjs dispatch <id-prefix> --task "<objective>" [--broker <orchestrator-root> --live]
110
+ ```
111
+ Dispatch re-runs the evidence gate first; carries manifest sha256; dry-run by default
112
+ (autonomy ladder: workflow-execute requires explicit --live).
113
+
114
+ ## Rules
115
+
116
+ 1. Never dump the whole corpus — load only what the task needs.
117
+ 2. Preserve provenance — every artifact carries raw + manifest sha256.
118
+ 3. Verbatim objectives (PromptIR lossless).
119
+ 4. Evidence gates — RESULT without EVIDENCE never becomes VERIFIED.
120
+ 5. Update, never duplicate (watermark merge).
121
+ 6. No secrets.
122
+ 7. Safety on writes (backup → apply → verify → rollback).
123
+ 8. User messages are the highest authority in any brief.
124
+ 9. Raw is never altered — handoffs render from canonical data.
125
+ 10. Self-improve — a refused/truncated brief is a knowledge candidate.
126
+ 11. Max-local: zero external-dependency engines; adapters absent-safe.
127
+ 12. Versioned contracts — every artifact has a schema version, a sha256 and a decided autonomy level.
128
+
129
+ ## Level map (L3 resources — read on demand)
130
+
131
+ | Need | File |
132
+ |------|------|
133
+ | Live dispatch protocol | `refs/protocol.md` |
134
+ | Role ladder | `refs/roles.md` |
135
+ | Validator gate (12-point) | `refs/validator.md` |
136
+ | Shared operating rules | `refs/handbook.md` |
137
+ | Fresh-session bootstrap | `refs/bootstrap.md` |
138
+ | Brief discipline | `refs/brief-checklist.md` |
139
+ | Engine source | `tools/handoff.mjs` |
140
+ | L4 runtime | `tools/agent-handoff.mjs` |
141
+ | L4/L5 design | `docs/LEVEL4.md`, `docs/LEVEL5.md` |
142
+ | Cross-harness adapters | `refs/ADAPTERS.md` |
143
+ | Handoff format + schema | `docs/FORMAT.md`, `templates/` |
144
+ | Installation | `docs/INSTALL.md` |
145
+
146
+ **Version**: 2.0.0
147
+ **Last Updated**: 2026-10-08
@@ -0,0 +1,27 @@
1
+ {
2
+ "schema_version": "1.0-capability-registry",
3
+ "capabilities": [
4
+ {
5
+ "id": "filesystem.read",
6
+ "kind": "file-exists",
7
+ "target": "tests/fixtures/minimal-transcript.jsonl",
8
+ "required": true,
9
+ "purpose": "read transcript sources for handoff builds"
10
+ },
11
+ {
12
+ "id": "filesystem.write",
13
+ "kind": "dir-writable",
14
+ "target": ".agent-handoff",
15
+ "required": true,
16
+ "purpose": "persist runtime state and checkpoints"
17
+ },
18
+ {
19
+ "id": "process.execute",
20
+ "kind": "command",
21
+ "command": "<node>",
22
+ "args": ["-e", "process.exit(0)"],
23
+ "required": true,
24
+ "purpose": "execute bounded engine subcommands"
25
+ }
26
+ ]
27
+ }
@@ -0,0 +1,164 @@
1
+ ---
2
+ title: Architecture
3
+ ---
4
+
5
+ # Architecture
6
+
7
+ ## The problem the shape solves
8
+
9
+ A working session lives inside whatever client recorded it. Continuing that session
10
+ elsewhere means either pasting the chat back in, or starting from memory. Both lose the part
11
+ that matters: the exact turns, the tool calls, and the ability to prove which source bytes
12
+ produced the brief you are reading.
13
+
14
+ agent-handoff turns the session into files instead. A directory of plain text and JSON, a
15
+ hash chain over it, and a fixed folder layout. Anything that can read a file can continue
16
+ from one, with no shared memory between the two sessions.
17
+
18
+ ## Layers
19
+
20
+ Five layers, each with one job, and each usable without the ones above it.
21
+
22
+ | Layer | File | Job |
23
+ |---|---|---|
24
+ | Capture engine | `tools/handoff.mjs` | Turns one transcript into one handoff folder. Passive: something has to invoke it. |
25
+ | Runtime layer | `tools/agent-handoff.mjs` | Acts on the state of the store: staleness, gates, composition, imports, index. |
26
+ | Bounded execution | `tools/runtime-engine.mjs` | Decides whether an operation may run, before running it. |
27
+ | Capability probes | `tools/capability-registry.mjs` | Reports what a declared capability actually does on this machine. |
28
+ | Distribution | `install/install.mjs` | Puts the skill where a client will look for it. |
29
+
30
+ The capture engine has no opinion about installation, and the runtime layer has no opinion
31
+ about transcripts — it shells out to the engine for builds and verification. That split is
32
+ what lets a store be inspected with one file, `manifest.json`, without loading anything else.
33
+
34
+ ## Data flow
35
+
36
+ ```
37
+ transcript ─────────────► build ─────────────► <root>/projects/<project>/<session>/
38
+ (.jsonl or .txt) │ HANDOFF.md
39
+ │ HANDOFF.summary.json
40
+ │ HANDOFF.llm.json
41
+ │ timeline.jsonl (append-only)
42
+ │ TOOLS.md
43
+ │ manifest.json (hash chain)
44
+ │
45
+ verify ◄──────────────────┘ recompute manifest_sha256
46
+ count timeline.jsonl lines
47
+ parse HANDOFF.llm.json
48
+
49
+ INDEX.json ◄──── index / build one row per session
50
+ links/*.md ◄──── merge cross-project relation notes
51
+ ```
52
+
53
+ A second build over a longer transcript appends only the turns above the watermark. Nothing
54
+ already written to `timeline.jsonl` is rewritten, so a brief can be regenerated without
55
+ invalidating what a consumer already read.
56
+
57
+ ## Where the store lives
58
+
59
+ `tools/lib/handoff-root.mjs` is the single implementation of the resolution order, so the
60
+ engine and the runtime layer can never disagree about which store they are operating on.
61
+ First match wins:
62
+
63
+ 1. `HANDOFFS_ROOT`, the environment override.
64
+ 2. `handoff.config.json`, found by walking up from the current directory, at most 10 levels.
65
+ `storage.path` beats `handoff_dir`; a relative `handoff_dir` resolves against the
66
+ directory holding the config.
67
+ 3. A `handoffs/` directory, checked at each level of the same upward walk.
68
+ 4. The skill directory, as the last resort.
69
+
70
+ A config file that is present but invalid stops the run with exit 2 instead of falling
71
+ through to rule 3. Falling back would write the session to a different store than the one
72
+ that was configured, which is worse than refusing.
73
+
74
+ `handoff.mjs config` prints the resolved root and the rule that chose it (`env`, `config`,
75
+ `discover`, `default`).
76
+
77
+ ## The provenance chain
78
+
79
+ Two hashes, and one of them covers the other.
80
+
81
+ | Value | Definition |
82
+ |---|---|
83
+ | `raw_sha256` | SHA-256 of the exact source bytes read at the last build. |
84
+ | `manifest_sha256` | SHA-256 of the manifest JSON with `manifest_sha256` removed. |
85
+
86
+ `verify` recomputes the self-hash, requires `timeline.jsonl`, compares its line count with
87
+ `turn_count`, and parses `HANDOFF.llm.json`. It prints `PASS` or `FAIL` and exits 0 or 1.
88
+
89
+ What the chain detects: a manifest edited by hand, a truncated or extended timeline, a
90
+ payload that no longer parses. What it does not do is prove that the source was authentic —
91
+ read [PROVENANCE.md](PROVENANCE.md) for the precise boundary.
92
+
93
+ ## Concurrency and write safety
94
+
95
+ Every mutating runtime command takes a lock before touching the store. Locks live in
96
+ `<root>/.locks/` and are named after a hash of the operation target, so two runs on
97
+ different sessions do not block each other while two runs on the same session do. A held
98
+ lock exits 3.
99
+
100
+ The discipline for a mutation is the same everywhere: take the lock, back up what is about
101
+ to change, apply, verify the result, and roll back on failure. `federated-merge` backs up a
102
+ local manifest to `manifest.json.bak-federated` before copying over it, and verifies every
103
+ imported session with the engine afterwards. `promote` backs a manifest up to
104
+ `manifest.json.bak` before stamping it.
105
+
106
+ ## Bounded execution
107
+
108
+ `runtime-engine.mjs` separates the decision from the act. `evaluate` classifies a target and
109
+ returns a verdict without running anything; `run` evaluates first and only then acts, and a
110
+ denied operation is recorded but never executed. Targets are classified in a fixed order —
111
+ an explicit denial, then the engine's own state directory, then approved workspaces, then
112
+ the broad personal-data roots, then system read-only roots, otherwise external — so a
113
+ personal-data or denied path is refused at any risk class.
114
+
115
+ Every decision is written to `<state>/executions/<id>.json` with
116
+ `enforced_before_execution: true`. Levels, risk classes and grants are in
117
+ [PERMISSIONS.md](PERMISSIONS.md).
118
+
119
+ ## Honest verdicts
120
+
121
+ The capability registry reports `healthy`, `unhealthy` or `unknown`, each with the evidence
122
+ that produced it. A probe kind with no implementation returns `unknown` rather than
123
+ `healthy`. `check` exits non-zero when a required capability is `unknown`, because an
124
+ unanswered question is not a pass.
125
+
126
+ The same rule applies to the evidence gate. `verify-gate` returns `REJECTED` in its JSON
127
+ when a check fails, and exits 0 either way, so the verdict has to be read rather than
128
+ inferred from a status code. `promote` prints the gate result without enforcing it, which is
129
+ stated in the command reference rather than left for a caller to discover.
130
+
131
+ ## Boundaries
132
+
133
+ - The engine makes no network calls, and neither does the runtime layer. The one component
134
+ that reaches the network is the installer, and only when it runs as the published package:
135
+ it downloads the archive for the version being installed. See
136
+ [COMPATIBILITY.md](COMPATIBILITY.md) and [INSTALL.md](INSTALL.md).
137
+ - The source transcript is read and never written.
138
+ - No secrets are stored. The code reads no credential files.
139
+ - No model is called. The `.llm.json` payload is shaped for a model to read, not produced by
140
+ one.
141
+ - `spawn` runs only the local node binary, with a 15000 ms timeout and its output captured
142
+ and hashed rather than streamed.
143
+
144
+ ## Repository layout
145
+
146
+ ```
147
+ tools/handoff.mjs capture engine
148
+ tools/agent-handoff.mjs runtime layer
149
+ tools/runtime-engine.mjs bounded execution
150
+ tools/capability-registry.mjs capability probes
151
+ tools/lib/handoff-root.mjs store-root resolution (single owner)
152
+ tools/handoff.test.mjs the hermetic test suite
153
+ docs/ this documentation and the Pages site
154
+ refs/ reference material: adapters, protocol, roles, brief checklist
155
+ templates/ handoff templates and the LLM payload schema
156
+ schemas/ the portable handoff payload schema
157
+ install/ the npx installer package
158
+ tests/ acceptance fixture and a minimal transcript
159
+ ```
160
+
161
+ The documentation site at <https://alot1z.github.io/agent-handoff/> is built by GitHub Pages
162
+ directly from `docs/`. `docs/_data/nav.yml` is the navigation, `docs/_config.yml` is the
163
+ Jekyll configuration, and `.github/scripts/check-docs.mjs` fails CI when a page is missing
164
+ from the navigation or a relative link does not resolve.