@xingular/harness 2.1.1 → 3.0.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.
Files changed (152) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/NOTICE.md +22 -0
  3. package/README.md +70 -37
  4. package/dist/cli.js +6572 -6700
  5. package/dist/terminal-pi.js +51 -38
  6. package/docs/terminal-tui.md +50 -12
  7. package/package.json +2 -2
  8. package/src/accounts/accounts.ts +4 -3
  9. package/src/capabilities/api.ts +1 -1
  10. package/src/cli.ts +7 -3
  11. package/src/core/bus.test.ts +15 -1
  12. package/src/core/bus.ts +39 -0
  13. package/src/core/caller.ts +34 -0
  14. package/src/core/fs.ts +17 -1
  15. package/src/harness.ts +55 -66
  16. package/src/{memory → history}/recall.test.ts +1 -1
  17. package/src/{memory → history}/recall.ts +1 -1
  18. package/src/{memory → history}/trajectory.test.ts +4 -4
  19. package/src/{memory → history}/trajectory.ts +1 -1
  20. package/src/hub/hub.test.ts +4 -5
  21. package/src/hub/hub.ts +2 -2
  22. package/src/index.ts +28 -14
  23. package/src/mcp/connections.ts +1 -1
  24. package/src/mcp/service.ts +1 -1
  25. package/src/pi/proxy.test.ts +68 -0
  26. package/src/pi/runtime.test.ts +61 -0
  27. package/src/pi/runtime.ts +50 -0
  28. package/src/plugins/api.ts +11 -9
  29. package/src/plugins/builtin.ts +22 -40
  30. package/src/plugins/catalogue.test.ts +13 -41
  31. package/src/plugins/catalogue.ts +3 -32
  32. package/src/plugins/discover.ts +2 -1
  33. package/src/plugins/firstParty.test.ts +1 -1
  34. package/src/plugins/hooks.test.ts +21 -71
  35. package/src/plugins/hooks.ts +6 -7
  36. package/src/plugins/identity.ts +16 -2
  37. package/src/plugins/install.test.ts +1 -1
  38. package/src/plugins/install.ts +2 -1
  39. package/src/plugins/inventory.ts +19 -18
  40. package/src/plugins/plugins.ts +38 -2
  41. package/src/prompt/compile.test.ts +82 -193
  42. package/src/prompt/compile.ts +98 -363
  43. package/src/refine/cli.ts +114 -0
  44. package/src/refine/demo.ts +124 -0
  45. package/src/refine/evidence.ts +349 -0
  46. package/src/refine/host.ts +102 -0
  47. package/src/refine/ledger.ts +104 -0
  48. package/src/refine/library.ts +192 -0
  49. package/src/refine/pi.test.ts +90 -0
  50. package/src/refine/pi.ts +218 -0
  51. package/src/refine/prompts.ts +430 -0
  52. package/src/refine/recursion.ts +353 -0
  53. package/src/refine/refine.test.ts +140 -0
  54. package/src/refine/runner.ts +205 -0
  55. package/src/refine/selection.ts +291 -0
  56. package/src/refine/service.ts +194 -0
  57. package/src/refine/trajectory.ts +71 -0
  58. package/src/refine/types.ts +91 -0
  59. package/src/server/methods.ts +137 -123
  60. package/src/server/server.test.ts +37 -30
  61. package/src/sessions/contracts.ts +7 -2
  62. package/src/sessions/conversation.test.ts +2 -27
  63. package/src/sessions/planMode.test.ts +8 -1
  64. package/src/sessions/planMode.ts +17 -9
  65. package/src/sessions/policy.ts +1 -1
  66. package/src/sessions/pricing.ts +3 -1
  67. package/src/sessions/questionBatches.test.ts +15 -3
  68. package/src/sessions/registry.ts +13 -1
  69. package/src/sessions/runStore.ts +3 -1
  70. package/src/sessions/runner.ts +10 -5
  71. package/src/sessions/sessions.test.ts +60 -13
  72. package/src/sessions/sessions.ts +43 -18
  73. package/src/sessions/subagentService.test.ts +22 -1
  74. package/src/sessions/subagentService.ts +14 -1
  75. package/src/sessions/subagents.ts +2 -0
  76. package/src/terminal/cli.ts +24 -48
  77. package/src/terminal/logs.test.ts +26 -0
  78. package/src/terminal/logs.ts +67 -0
  79. package/src/terminal/piExtension.lifecycle.test.ts +1 -1
  80. package/src/terminal/piExtension.ts +3 -3
  81. package/src/terminal/pluginControl.test.ts +7 -8
  82. package/src/terminal/socket.ts +3 -3
  83. package/src/terminal/terminal.test.ts +41 -39
  84. package/src/terminal/terminals.ts +31 -13
  85. package/src/terminal/tui/application.test.ts +58 -0
  86. package/src/terminal/tui/application.ts +15 -4
  87. package/src/terminal/tui/clipboardFiles.test.ts +94 -0
  88. package/src/terminal/tui/clipboardFiles.ts +86 -0
  89. package/src/terminal/tui/commands.test.ts +13 -1
  90. package/src/terminal/tui/commands.ts +16 -0
  91. package/src/terminal/tui/logPanel.test.ts +61 -0
  92. package/src/terminal/tui/logPanel.ts +175 -0
  93. package/src/terminal/tui/piAdapter.ts +7 -4
  94. package/src/terminal/tui/questionPicker.ts +168 -0
  95. package/src/terminal/tui/questions.test.ts +86 -19
  96. package/src/terminal/tui/questions.ts +27 -22
  97. package/src/terminal/tui/runtime.ts +2 -0
  98. package/src/tools/askUser.test.ts +23 -2
  99. package/src/tools/askUser.ts +15 -5
  100. package/src/tools/definitions.ts +49 -132
  101. package/src/tools/dispatch.ts +78 -0
  102. package/src/tools/harnessTools.ts +23 -0
  103. package/src/tools/spawnSubagent.ts +3 -3
  104. package/src/tools/types.ts +3 -1
  105. package/src/tree/components.ts +221 -0
  106. package/src/tree/materialise.ts +122 -0
  107. package/src/tree/seed.ts +123 -0
  108. package/src/tree/store.ts +193 -0
  109. package/src/tree/surface.ts +135 -0
  110. package/src/tree/tree.test.ts +126 -0
  111. package/src/tree/tree.ts +346 -0
  112. package/src/tree/trust.ts +86 -0
  113. package/src/web/tools.ts +27 -5
  114. package/src/web/web.test.ts +26 -1
  115. package/src/wiki/notes.ts +313 -0
  116. package/src/memory/api.test.ts +0 -82
  117. package/src/memory/api.ts +0 -303
  118. package/src/memory/blocks.test.ts +0 -78
  119. package/src/memory/blocks.ts +0 -408
  120. package/src/memory/caller.ts +0 -69
  121. package/src/memory/curation.test.ts +0 -206
  122. package/src/memory/curation.ts +0 -64
  123. package/src/memory/dispatch.ts +0 -64
  124. package/src/memory/facts.test.ts +0 -41
  125. package/src/memory/facts.ts +0 -248
  126. package/src/memory/graph.ts +0 -103
  127. package/src/memory/health.test.ts +0 -130
  128. package/src/memory/health.ts +0 -74
  129. package/src/memory/maintainer.ts +0 -272
  130. package/src/memory/maintenance.test.ts +0 -192
  131. package/src/memory/maintenance.ts +0 -679
  132. package/src/memory/migrate.ts +0 -79
  133. package/src/memory/operations.ts +0 -150
  134. package/src/memory/proposals.test.ts +0 -168
  135. package/src/memory/proposals.ts +0 -584
  136. package/src/memory/references.ts +0 -77
  137. package/src/memory/runContext.ts +0 -93
  138. package/src/memory/store.test.ts +0 -66
  139. package/src/memory/store.ts +0 -385
  140. package/src/memory/wiki.test.ts +0 -47
  141. package/src/memory/wiki.ts +0 -423
  142. package/src/memory/wikiIndex.test.ts +0 -88
  143. package/src/memory/wikiIndex.ts +0 -117
  144. package/src/plugins/proposal.ts +0 -121
  145. package/src/skills/registry.test.ts +0 -104
  146. package/src/skills/registry.ts +0 -413
  147. package/src/tools/maintenance.ts +0 -29
  148. package/src/tools/memoryTools.ts +0 -22
  149. package/src/tools/pluginPropose.ts +0 -41
  150. package/src/tools/registryWrite.test.ts +0 -101
  151. package/src/tools/registryWrite.ts +0 -182
  152. /package/src/{memory → core}/secrets.ts +0 -0
package/CHANGELOG.md CHANGED
@@ -2,6 +2,24 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 3.0.0 - 2026-10-19
6
+
7
+ Rebuilt on recursive harnessing (Harness², Apache-2.0, Google LLC). Breaking.
8
+
9
+ - Add harness trees (`src/tree/`): each caller scope has a versioned tree of eight components — system prompt, guardrails, memory, tool guidance, subagents, skills, scripts and plugins — that is validated, content-addressed, and pinned for a whole run. `SessionRunInput.harness` and `TerminalPrepareInput.harness` choose one; run records carry `harnessScope` and `harnessVersion`. Plugin code in a tree loads only after it is trusted (`TreeTrust`).
10
+ - Add refinement (`src/refine/`): Propose–Probe–Compose in parallel and sequential modes with the R=4k/P=3k budget identity, blind answer-free selection, reflection into a per-scope experience library, and adoption of the chosen tree. Executions and improver sessions are ordinary recorded runs, marked by the `probe` and `improver` triggers. `harness.refine`, `refine.*` and `library.*` RPC methods, and `xingular-harness refine demo|run`.
11
+ - Add the seventh extension point, `RefineHost`: where an execution works, as whom, with which tools, and what it produced.
12
+ - `spawn_subagent` takes `agent`, naming one of the tree's subagents; that child works from its own definition.
13
+ - Replace the Wiki with project notes (`src/wiki/`): linked Markdown under `wiki/`, versions, search, and `wiki_search`, `wiki_read`, `wiki_list` and a switchable `wiki_write`. An earlier Wiki's memory blocks, facts, revisions and Inbox are moved once to `legacy/wiki-<time>/`; nothing is deleted.
14
+ - Remove memory blocks, facts, proposals and the evidence gate, maintenance and the maintainer, curation, context profiles, the skills/rules/prompts registry as a source of prompt text, `registry_write`, `plugin_write` and `plugin_propose`. `harnesses.seed` builds a caller's first tree from what shaped it before (instructions, its rules, its memory blocks, its skills). `registry/` stays as a component library the Hub installs into and a tree can take items from.
15
+ - Hook events are `wiki.page.saved` and `history.run.ended`.
16
+
17
+ ## 2.1.2 - 2026-10-19
18
+
19
+ - Add `/log`, a full-screen snapshot of redacted Harness diagnostics and current-conversation run events.
20
+ - Allow argument-specific, provider-classified research calls during plan-mode runs while refusing other tools before approvals.
21
+ - Mark recommended options in batched questions and provide a picker for staged multi-select and free-text answers.
22
+
5
23
  ## 2.1.1 - 2026-10-19
6
24
 
7
25
  - Change terminal `/plan` to run one isolated, read-only planning request; queue later messages until it settles and apply plan instructions only for that run.
package/NOTICE.md CHANGED
@@ -1,5 +1,27 @@
1
1
  # Third-party notices
2
2
 
3
+ ## Harness²
4
+
5
+ The harness tree (`src/tree/`) and refinement (`src/refine/`) port the method of Harness²:
6
+ Recursive Agent Harnessing for an Open World (Xu, Chen, CuiZhu, Dalvi Mishra, Ming, Yu, Han,
7
+ Lee, Pfister; arXiv:2610.14224). The component surface and its validation, Propose–Probe–Compose
8
+ in parallel and sequential modes with its budget identity, blind answer-free selection, the
9
+ reflection record and the experience library, and the improver, selector and reflector prompts
10
+ are adapted from its reference implementation (`harness2/core`, `harness2/substrate`) for Pi.
11
+
12
+ Upstream: https://github.com/google-research/harness2 (Copyright 2026 Google LLC)
13
+
14
+ Licensed under the Apache License, Version 2.0 (the "License"); you may not use these files
15
+ except in compliance with the License. You may obtain a copy of the License at
16
+ https://www.apache.org/licenses/LICENSE-2.0. Unless required by applicable law or agreed to in
17
+ writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
18
+ WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Changes from upstream: ported
19
+ from Python to TypeScript; the OpenCode and Codex surfaces replaced by one Pi surface; executors
20
+ and improvers run as recorded harness sessions; benchmark adapters replaced by a host-supplied
21
+ `RefineHost`; prompt text that named a framework rewritten for Pi.
22
+
23
+ ## Oh My Pi
24
+
3
25
  The Harness terminal presentation adapts the titanium color palette, five-row Pi logo,
4
26
  diagonal gradient and related terminal presentation conventions from Oh My Pi 18.11.3,
5
27
  particularly `@oh-my-pi/pi-tui/src/theme/defaults/titanium.json` and
package/README.md CHANGED
@@ -1,22 +1,38 @@
1
1
  # Xingular Harness
2
2
 
3
- A Pi agent harness, as one TypeScript package (`@xingular/harness`). It is everything a model
4
- needs to work for someone over time, and nothing about any particular application:
3
+ A Pi agent harness built on **recursive harnessing** ([Harness²](https://arxiv.org/abs/2610.14224),
4
+ Apache-2.0, Google LLC), as one TypeScript package (`@xingular/harness`). The harness — what a
5
+ model is told and can do — is the object that improves, with model weights fixed:
6
+
7
+ - **A harness is a tree of eight components** (c1–c8): system prompt, guardrails, memory and tool
8
+ guidance (always in the prompt, capped), subagents, skills and scripts (on demand), and plugins
9
+ (in the tool loop). Each caller scope has versioned, validated trees; a run pins one version.
10
+ - **Task-level recursion** refines a tree on one task through *Propose–Probe–Compose*: k base
11
+ executions, improvers that edit the tree from the evidence (INV: how the agent works; DOM: what a
12
+ practitioner knows), a probe execution of each candidate, and compositions built from the
13
+ behavioural contrasts. Parallel mode explores wider; sequential mode refines deeper. Each costs
14
+ 4k executions and 3k improver sessions.
15
+ - **Blind, answer-free selection** picks one final output from anonymised candidates; no rubric,
16
+ score or reviewer verdict ever reaches an improver.
17
+ - **Harnessing-level recursion** keeps an experience library per scope: each adopted tree with
18
+ what each edit did and one evidence-backed lesson, read by the next task's improvers.
5
19
 
6
20
  | Part | Folder | What it does |
7
21
  |---|---|---|
22
+ | Harness trees | `src/tree/` | The eight-component surface, validation and repair, content-addressed versions and lineage, materialising a tree for Pi, plugin-code trust, seeding a first tree, the component library. |
23
+ | Refinement | `src/refine/` | Evidence folders, the prompt pack, parallel and sequential recursion, the budget ledger, selection, reflection, the experience library, Pi-backed executor and improver, and the `refine` service. |
8
24
  | Accounts | `src/accounts/` | Several isolated Pi accounts and pools, sign-in, model lists, health and limits. A session keeps the account it started with. |
9
- | Sessions | `src/sessions/` | Pi SDK turns, run records and `events.jsonl`, interrupt, approvals, questions, recovery after a crash. |
10
- | Prompt | `src/prompt/` | The system prompt compiled from sections with budgets and profiles; a stable prefix, and changing state delivered as updates in native history. |
11
- | Memory | `src/memory/` | The Wiki: pages, facts, memory blocks, revisions, proposals with an evidence gate, undo, an Inbox, history recall, run trajectory inspection, and sleep-time consolidation. |
12
- | Skills | `src/skills/` | Skills, prompts, and rules: a person's own in the data root, and built-in ones shipped with the harness or the application. |
25
+ | Sessions | `src/sessions/` | Pi SDK turns on a pinned harness tree, run records and `events.jsonl`, interrupt, approvals, questions, subagents (named by a tree's c5), recovery after a crash. |
26
+ | Prompt | `src/prompt/` | The system prompt compiled from the tree's sections and the application's, with budgets; a stable prefix, and changing state delivered as updates in native history. |
27
+ | Wiki | `src/wiki/` | Project notes: linked Markdown, versions, search. Reference material, not instructions. |
28
+ | History | `src/history/` | Recall over earlier runs and bounded trajectory reads. |
13
29
  | Plugins | `src/plugins/` | What a Pi session loads, chosen by the harness and never by Pi's own discovery; trust for a working folder's code; the list of every plugin and what reaches one caller. |
14
- | Tools | `src/tools/` | Tool definitions, the memory tools, `ask_user`; a gate that asks the application's policy, then standing approvals, then the person. |
30
+ | Tools | `src/tools/` | Tool definitions, History/Wiki/skill tools, `ask_user`; a gate that asks the application's policy, then standing approvals, then the person. |
15
31
  | Connected apps | `src/mcp/` | MCP connections, OAuth, per-session grants, redaction, a trace of what each call returned. |
16
- | Terminal | `src/terminal/` | A Harness-owned terminal frontend over persistent Pi sessions, isolated accounts, compiled instructions, the tool gate and telemetry bridge, native history, plugin UI, `/plugins`, `/hub`, `/accounts`, and the existing session socket. |
32
+ | Terminal | `src/terminal/` | A Harness-owned terminal frontend over persistent Pi sessions on a harness tree. |
17
33
  | Server | `src/server/` | The same API over newline-delimited JSON, for a host that is not a Node program. |
18
34
 
19
- It was split out of Xingular Agent, which is now an application built on it.
35
+ Try refinement with no model and no credentials: `npm run build && node dist/cli.js refine demo --k 2`.
20
36
  The [documentation index](docs/README.md) links current terminal architecture and decisions.
21
37
 
22
38
  ### Session options for applications
@@ -26,8 +42,9 @@ The [documentation index](docs/README.md) links current terminal architecture an
26
42
  - The model's `spawn_subagent` returns immediately by default; `wait: true` returns an inline result. `wait_subagents` joins selected children. The SDK and standalone terminal share this execution service. Terminal calls use its private control channel, including when connected apps are disabled.
27
43
  - Parents receive results at native turn boundaries and join outstanding children before completing. Typed native-history receipts prevent duplicate automatic delivery; explicit waits can reread results. Ownership is recorded before startup so an explicit resume can recover even a lost spawn return. Startup reservations without a run become interrupted outcomes. A restarted Harness never restarts model work automatically. Recovery requires the same recorded account, caller, working folder, and selected history branch. Session IDs are opaque; consumers follow `parentRunId` and `relation`.
28
44
  - `providers: false` runs a session with the harness's own tools only.
29
- - On the caller, `vaultAccess: 'propose'` writes no memory directly, and `recallExcludeAgents` hides those agents' conversations from history and trajectory tools.
30
- - `maintenanceRunTrigger: false` (a harness option) leaves memory to explicit proposals and scheduled merges.
45
+ - `harness: { scope }` runs the session on that scope's head tree (or `{ scope, version }`, or `{ dir }` for a tree on disk). The version is pinned for the run and recorded on it.
46
+ - On the caller, `recallExcludeAgents` hides those agents' conversations from history and trajectory tools.
47
+ - `harnessTools: false` runs a session without the History, Wiki and skill tools.
31
48
 
32
49
  Every session also gets `trajectory_search` and `trajectory_read` from the built-in History plugin.
33
50
  Search lists runs in the current data root, including active runs, with filters and a continuation
@@ -44,16 +61,19 @@ They report recorded evidence without scoring runs, and do not backfill older re
44
61
  import { createHarness } from '@xingular/harness'
45
62
 
46
63
  const harness = createHarness({
47
- dataRoot: '/path/to/data', // knowledge and history: wiki/, registry/, runs/, index.sqlite
64
+ dataRoot: '/path/to/data', // harnesses/, library/, refine/, wiki/, registry/, runs/, index.sqlite
48
65
  stateDir: '/path/to/state', // device-local: accounts, approvals, connections, sockets
49
66
  productName: 'My App', // how the harness names itself to a model (default 'Xingular Harness')
50
67
  secrets, // SecretStore; defaults to an owner-only file in stateDir
51
68
  policy, // ToolPolicy: what a run may do, and what needs a person
52
69
  directory, // names for the ids the application uses
53
70
  builtins: ['/path/to/builtin'], // folders of built-in skills, prompts, and rules
54
- plugins: [myPlugin] // the application's own parts, described as plugins
71
+ plugins: [myPlugin], // the application's own parts, described as plugins
72
+ refineHost // where refinement executions work, as whom, with which tools
55
73
  })
56
74
 
75
+ harness.refine.start({ task: { id, scope: 'agent-1', prompt }, k: 1, mode: 'parallel' })
76
+
57
77
  harness.sessions.provide((session) => myTools(session)) // the application's own tools
58
78
  harness.runs.listen((event, run) => show(event)) // every run event, after it is saved
59
79
 
@@ -61,6 +81,7 @@ await harness.sessions.run({
61
81
  run: { id, sessionId },
62
82
  cwd, sessionDir, text,
63
83
  caller: { agentId, agentName, actor: 'Chat' },
84
+ harness: { scope: 'agent-1' },
64
85
  launch: { sections: [{ id: 'identity', title: 'Identity', body, budget: 2000, order: 10 }] },
65
86
  tools: { allow: ['read', 'bash', 'my_tool'], gated: ['bash'] }
66
87
  })
@@ -68,14 +89,14 @@ await harness.sessions.run({
68
89
 
69
90
  ## How an application extends it
70
91
 
71
- The harness knows a caller (an opaque id that owns memory), never an agent, a group, or a task.
72
- An application adds what it knows through six points:
92
+ The harness knows a caller and a harness scope (opaque ids), never an agent, a group, or a task.
93
+ An application adds what it knows through seven points:
73
94
 
74
95
  1. **Prompt sections** (`Launch.sections`, `Launch.toolGroups`, `Launch.references`). Each
75
- section has an `order` and may be `dynamic`. The harness adds its own (`blocks` 30, `rules` 40,
76
- `references` 50, `skills` 60, `knowledge` 80, `tools` 90), applies budgets and the caller's
77
- context profile, keeps stable sections in the system prompt, and sends dynamic ones as
78
- updates.
96
+ section has an `order` and may be `dynamic`. The harness adds its own (`system` 25,
97
+ `guardrails` 40, `memory` 45, `references` 50, `subagents` 64, `scripts` 66, `wiki` 80,
98
+ `tools` 90), applies budgets, keeps stable sections in the system prompt, and sends dynamic
99
+ ones as updates.
79
100
  2. **Tool providers** (`harness.sessions.provide`). A provider returns `ToolSpec`s for a session;
80
101
  only the names in the session's `allow` list are registered, in that order.
81
102
  A tool may return `attachments` as `{ id, name, mimeType }` references. The harness records
@@ -84,9 +105,6 @@ An application adds what it knows through six points:
84
105
  The harness provides the web tools itself: `webTools({ secrets })` gives `web_search` (Brave Search,
85
106
  key read from the secret store) and `web_fetch` (checked reads of public pages). An application
86
107
  passes it to `harness.sessions.provide` and switches the names on for each agent.
87
- `registryTools({ harness })` gives `registry_write` (a skill, rule, or prompt) and `plugin_write`
88
- (a plugin). Each writes for the calling agent only: the item is on for that agent, and a plugin's
89
- code is trusted once written. An item others already use goes to the Inbox instead.
90
108
  3. **`ToolPolicy`**. `scope` says whether a call is inside what the run may do (or needs one
91
109
  approval). A decision with `humanOnly` is for a person alone: the always-approve switch and
92
110
  remembered answers do not apply to it. `authorize` says whether the tool is still switched on;
@@ -99,6 +117,11 @@ An application adds what it knows through six points:
99
117
  the application and says which tools, prompt sections and tool groups it provides. It is data:
100
118
  it changes what `plugins.list` and `plugins.inventory` report, never what runs. `WEB_PLUGIN`
101
119
  describes the web tools. A host that is not a Node program sends them with `plugins.describe`.
120
+ 7. **`RefineHost`** (`HarnessOptions.refineHost`). Where a refinement execution works
121
+ (`prepareWorkspace`: an isolated folder, such as a git worktree), as whom and with which tools
122
+ (`session`), and what it produced (`deliverable`). Executions run as unattended runs with
123
+ trigger `probe`, so a `ToolPolicy` can refuse anything with effects outside that folder;
124
+ improver sessions run with trigger `improver`, file tools only, on a copy of the evidence.
102
125
 
103
126
  `apps.expose(...)` additionally offers the application's tools through the connected-apps
104
127
  broker (`mcp_list_tools`, `mcp_call_tool`), which is how a terminal session reaches them.
@@ -107,7 +130,7 @@ broker (`mcp_list_tools`, `mcp_call_tool`), which is how a terminal session reac
107
130
 
108
131
  A plugin is a bundle with a title, a description and contributions: instructions, skills,
109
132
  commands, tools, connections, code (a Pi extension) and themes. A Pi package is a plugin as it
110
- is; so are the harness's own parts (Memory, Wiki, History, Ask the user, Connected apps, Pi), the
133
+ is; so are the harness's own parts (Harness, Wiki, History, Subagents, Ask the user, Connected apps, Pi), the
111
134
  application's, a person's registry ("Yours"), the folder every account shares, and what a
112
135
  working folder brings.
113
136
 
@@ -141,11 +164,10 @@ working folder brings.
141
164
  input does so before the gate sees it. Every resource reload revalidates the parent's original
142
165
  trusted selection; changed or revoked code requires review and a fresh terminal.
143
166
  - **A required part can be extended.** A package names the part it adds to and, optionally, a
144
- hooks file: `"harness": { "extends": ["memory"], "hooks": "./hooks.mjs" }`. The harness runs
145
- hooks itself (`src/plugins/hooks.ts`), in its own process, because most memory is written while
146
- no session is open. `export default function (harness) { harness.on('memory.saved', async
147
- (event, ctx) => …) }`; the events are `memory.saved`, `memory.block.changed`,
148
- `wiki.page.saved` and `history.run.ended`. A hook is told after the write and cannot stop it,
167
+ hooks file: `"harness": { "extends": ["wiki"], "hooks": "./hooks.mjs" }`. The harness runs
168
+ hooks itself (`src/plugins/hooks.ts`), in its own process, because notes are often written while
169
+ no session is open. `export default function (harness) { harness.on('wiki.page.saved', async
170
+ (event, ctx) => …) }`; the events are `wiki.page.saved` and `history.run.ended`. A hook is told after the write and cannot stop it,
149
171
  has 30 seconds, and what it throws is kept in `plugin-hooks.json` and shown on its plugin. It
150
172
  runs only while its plugin is switched on for everyone and trusted; what is loaded is checked
151
173
  against that before each delivery. `ctx.call(connection, tool, args)` reaches a connected app
@@ -172,7 +194,8 @@ working folder brings.
172
194
  Outside a session, `xingular-harness plugins list | show | install | remove | update | attach |
173
195
  detach | trust | untrust` acts directly, as the person who typed it; `trust` shows the files
174
196
  and wants a typed yes or `--yes`. It does not open the data root, so it settles no run.
175
- - **Unattended runs and memory maintenance load no extension**, as before.
197
+ - **Unattended runs load no extension found on disk.** A harness tree's own trusted plugins still
198
+ load, so a refinement probe runs the plugin it is testing.
176
199
  - **A person switches things on and off for a scope.** `plugins.attach` and `plugins.detach`
177
200
  take a plugin's or a contribution's `id` and a `scope` (`{}` for everywhere, `{ agentId }`, or
178
201
  `{ projectId }`). The narrowest scope that says something wins: an agent, then a project, then
@@ -216,7 +239,8 @@ table. With the `--host-*` flags the harness calls the host for `secrets.get|set
216
239
  `policy.scope|authorize|approval|connections`, and `tools.call`; the host registers its tools
217
240
  with `tools.register` and its names with `directory.set`.
218
241
 
219
- `skills.import` accepts complete user-owned skill folders:
242
+ `harnesses.importComponents` adds complete skill folders, or single-file rules and prompts, to the
243
+ component library:
220
244
 
221
245
  ```ts
222
246
  { skills: [{ name, files: [{ path, content, encoding }] }] }
@@ -227,7 +251,8 @@ It validates bounded relative paths and file encodings, requires a root
227
251
  has no knowledge of the application feature that may call it.
228
252
 
229
253
  `npm run prove` starts that server on a throwaway data root, with no application present, and
230
- exercises accounts, memory, skills, the prompt, connected apps, and a recorded session.
254
+ exercises accounts, harness trees, the Wiki, the prompt, connected apps, a recorded session, a
255
+ plugin hook, and the refinement demo end to end.
231
256
 
232
257
  ## Run it as a standalone Harness terminal
233
258
 
@@ -281,7 +306,9 @@ changing or reloading a session. Full OMP visual parity is not established by th
281
306
  verification. `/permissions` reviews device-local Pi terminal grants and the Full Permission switch;
282
307
  tool grants apply across terminal sessions sharing this Harness state, and Full Permission requires
283
308
  confirmation. `/trajectory` opens recorded runs for the current native conversation, with event
284
- navigation and a detail inspector. See [terminal architecture and evidence](docs/terminal-tui.md),
309
+ navigation and a detail inspector. `/log` shows a static, redacted snapshot of Harness diagnostics
310
+ and run events for the current conversation; press Escape to close. See
311
+ [terminal architecture and evidence](docs/terminal-tui.md),
285
312
  [the decision](docs/decisions/ADR-0001-owned-terminal.md), and [third-party notices](NOTICE.md).
286
313
 
287
314
  ### `/accounts` in the terminal
@@ -307,19 +334,25 @@ command. The explicit `terminal` command is an alias for the default launch. Use
307
334
 
308
335
  ```
309
336
  <data root>/
310
- wiki/ home.md, library/, projects/<slug>/, facts/, blocks/, revisions, inbox, log
311
- registry/ skills/, prompts/, rules/ (a person's own; never copied)
337
+ harnesses/<scope>/ versions/<fingerprint>/tree/, head.json, lineage.jsonl (the eight components)
338
+ refine/<id>/ summary.json, task.json, harnesses/<label>/, rollouts/, context/, selection/, reflection/, improver/
339
+ library/<scope>/<area>/ INDEX.md, harnesses/<task>/{harness/, EXPERIENCE.md} (the experience library)
340
+ wiki/ home.md, library/, projects/<slug>/ (project notes)
341
+ wiki-history/ earlier versions of notes
342
+ legacy/ what an earlier Wiki kept (memory blocks, facts, revisions, Inbox), moved once
343
+ registry/ skills/, prompts/, rules/ (the component library; the Hub installs here)
312
344
  plugins/<name>/ packages kept with a person's data; each is found as an installed plugin
313
345
  runs/<id>/ run.json, events.jsonl, context.json, caller.json, subagents.json (reserved child IDs)
314
- config/ context profiles, what is switched on for whom (plugin-attachments.json),
346
+ config/ what is switched on for whom (plugin-attachments.json),
315
347
  settings the harness reads
316
- index.sqlite a rebuildable index of Wiki entries and runs (FTS5)
348
+ index.sqlite a rebuildable index of runs for recall (FTS5)
317
349
  projects.json read only: the application owns it
318
350
 
319
351
  <state dir>/
320
352
  accounts/ registry, per-account Pi agent folders, audit log
321
353
  approvals.json standing approvals
322
354
  plugin-trust.json the code a person trusted, by hash, and whether earlier packages were taken over
355
+ tree-plugin-trust.json harness-tree plugin code a person trusted, and scopes whose probes may run improver code
323
356
  plugin-registered.json what each extension registered the last time a session loaded it
324
357
  plugin-hooks.json what each hooks file listens for and how its last run went
325
358
  connections.json connected apps (secrets are in the SecretStore)
@@ -341,7 +374,7 @@ Node 22.19 or newer.
341
374
 
342
375
  ## Images
343
376
 
344
- `SessionRunInput.requiresImageInput` optionally requires a vision-capable resolved Pi model before a prompt is delivered. The check includes direct `images` input, and the generic tool wrapper rejects image results on text-only models. Direct prompt images use Pi's `{ type: 'image', data, mimeType }` content shape. Applications own file formats, attachment selection, extraction and image preparation; the Harness only transports typed image content and validates model capability.
377
+ `SessionRunInput.requiresImageInput` optionally requires a vision-capable resolved Pi model before a prompt is delivered. The check includes direct `images` input, and the generic tool wrapper rejects image results on text-only models. Direct prompt images use Pi's `{ type: 'image', data, mimeType }` content shape. Applications own attachment selection, extraction and image preparation; the Harness transports typed image content and validates model capability. In the standalone terminal, pasting Finder-copied HEIC/HEIF files on macOS converts them to temporary PNGs so Pi can read their pixels. See [the terminal guide](docs/terminal-tui.md#clipboard-image-paste).
345
378
 
346
379
  ## Curated Hub
347
380