@awebai/oats 0.29.4 → 0.30.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 (224) hide show
  1. package/README.md +12 -6
  2. package/bin/oats.mjs +194 -50
  3. package/capabilities/oats-aweb/bin/oats-aweb.mjs +538 -204
  4. package/capabilities/oats-aweb/injects/aweb.md +1 -1
  5. package/capabilities/oats-aweb/lib/binding-wire.mjs +31 -22
  6. package/capabilities/oats-aweb/oats.json +5 -12
  7. package/capabilities/oats-aweb/skills/VENDORED.md +4 -4
  8. package/capabilities/oats-aweb/skills/aweb-team-membership/SKILL.md +1 -1
  9. package/capabilities/oats-aweb/skills/oats-aweb/SKILL.md +83 -13
  10. package/capabilities/oats-code-review/injects/reviewer.md +26 -0
  11. package/capabilities/oats-code-review/oats.json +16 -0
  12. package/capabilities/oats-code-review/skills/adversarial-review/SKILL.md +66 -0
  13. package/capabilities/oats-code-review/skills/review-dev-docs/SKILL.md +30 -0
  14. package/capabilities/oats-code-review/skills/security-review/SKILL.md +56 -0
  15. package/capabilities/oats-code-review/skills/simplification-review/SKILL.md +34 -0
  16. package/capabilities/oats-developer/injects/developer.md +38 -0
  17. package/capabilities/oats-developer/oats.json +17 -0
  18. package/capabilities/oats-developer/skills/execution-strategy/SKILL.md +43 -0
  19. package/capabilities/oats-developer/skills/maintain-dev-docs/SKILL.md +47 -0
  20. package/capabilities/oats-developer/skills/run-the-review-loop/SKILL.md +65 -0
  21. package/capabilities/oats-developer/skills/understand-the-spec/SKILL.md +37 -0
  22. package/capabilities/oats-developer/skills/worktrees/SKILL.md +36 -0
  23. package/capabilities/oats-engineering-expert/injects/expert.md +37 -0
  24. package/capabilities/oats-engineering-expert/oats.json +17 -0
  25. package/capabilities/oats-engineering-expert/skills/coordinate-developers/SKILL.md +37 -0
  26. package/capabilities/oats-engineering-expert/skills/coordinate-experts/SKILL.md +52 -0
  27. package/capabilities/oats-engineering-expert/skills/land-your-prs/SKILL.md +50 -0
  28. package/capabilities/oats-engineering-expert/skills/plan-and-spec/SKILL.md +53 -0
  29. package/capabilities/oats-engineering-expert/skills/verify-developer-work/SKILL.md +49 -0
  30. package/capabilities/oats-okf/bin/oats-okf.mjs +8 -4
  31. package/capabilities/oats-okf/lib/binding-wire.mjs +47 -15
  32. package/capabilities/oats-okf/lib/inspection.mjs +26 -7
  33. package/capabilities/oats-okf/lib/sources.mjs +16 -2
  34. package/capabilities/oats-okf/lib/worker.mjs +5 -16
  35. package/capabilities/oats-okf/oats.json +6 -3
  36. package/capabilities/oats-okf-harvest/bin/okf-harvest.mjs +2 -2
  37. package/capabilities/oats-okf-harvest/oats.json +3 -3
  38. package/capabilities/oats-okf-harvest/skills/knowledge-harvest/SKILL.md +6 -6
  39. package/capabilities/oats-okf-maintenance/bin/okf-maintenance.mjs +2 -2
  40. package/capabilities/oats-okf-maintenance/injects/maintainer.md +1 -1
  41. package/capabilities/oats-okf-maintenance/oats.json +2 -2
  42. package/capabilities/oats-okf-maintenance/skills/knowledge-review/SKILL.md +1 -1
  43. package/capabilities/oats-okf-maintenance/skills/okf-trigger-setup/SKILL.md +11 -23
  44. package/capabilities/oats-workspace-experts/injects/oats-experts.md +26 -0
  45. package/capabilities/oats-workspace-experts/oats.json +9 -0
  46. package/docs/capabilities.md +160 -171
  47. package/docs/capability-manifest.schema.json +6 -11
  48. package/docs/configuration.md +213 -64
  49. package/docs/design/2026-09-16-knowledge-capability-contract.md +36 -50
  50. package/docs/design/2026-09-23-workspace-module-contracts.md +377 -544
  51. package/docs/design/2026-09-26-okf-knowledge-operations.md +132 -357
  52. package/docs/design/2026-09-27-team-model-v2.md +97 -117
  53. package/docs/design/2026-09-28-automations-trust.md +38 -0
  54. package/docs/design/2026-09-28-soul-launch-preference.md +63 -0
  55. package/docs/design/HISTORY.md +65 -0
  56. package/docs/design/README.md +23 -54
  57. package/docs/desktop-cli-api.md +1787 -1777
  58. package/docs/desktop.md +30 -91
  59. package/docs/execution-targets.md +146 -292
  60. package/docs/first-team.md +31 -17
  61. package/docs/implementation.md +76 -288
  62. package/docs/integrations.md +118 -320
  63. package/docs/knowledge-capability-authoring.md +25 -52
  64. package/docs/knowledge-reference/acceptance.md +3 -3
  65. package/docs/knowledge-reference/adoption.md +1 -1
  66. package/docs/knowledge-reference/harvester.md +2 -2
  67. package/docs/knowledge-reference/package-craft.md +3 -3
  68. package/docs/knowledge-reference/provider-mapping.md +3 -6
  69. package/docs/knowledge-reference/reader-capture.md +3 -3
  70. package/docs/knowledge-theory.md +62 -166
  71. package/docs/knowledge.md +225 -404
  72. package/docs/layers.md +42 -97
  73. package/docs/oats-local.schema.json +58 -5
  74. package/docs/oats-membership.schema.json +1 -8
  75. package/docs/oats-package.schema.json +5 -5
  76. package/docs/oats-workspace.schema.json +8 -22
  77. package/docs/official-catalog.md +25 -28
  78. package/docs/packages.md +45 -63
  79. package/docs/plans/0.30-close-out.md +61 -0
  80. package/docs/release-lane.md +77 -0
  81. package/docs/release-notes/oats-framework-v1.1.3.md +10 -8
  82. package/docs/release-notes/v0.19.0.md +48 -147
  83. package/docs/release-notes/v0.19.1.md +2 -3
  84. package/docs/release-notes/v0.19.3.md +2 -15
  85. package/docs/release-notes/v0.20.0.md +0 -15
  86. package/docs/release-notes/v0.22.0.md +71 -138
  87. package/docs/release-notes/v0.22.1.md +42 -90
  88. package/docs/release-notes/v0.22.10.md +1 -1
  89. package/docs/release-notes/v0.22.11.md +1 -47
  90. package/docs/release-notes/v0.22.12.md +4 -13
  91. package/docs/release-notes/v0.22.13.md +1 -42
  92. package/docs/release-notes/v0.22.14.md +3 -11
  93. package/docs/release-notes/v0.22.15.md +1 -46
  94. package/docs/release-notes/v0.22.16.md +6 -8
  95. package/docs/release-notes/v0.22.18.md +1 -99
  96. package/docs/release-notes/v0.22.19.md +3 -14
  97. package/docs/release-notes/v0.22.2.md +6 -15
  98. package/docs/release-notes/v0.22.3.md +0 -1
  99. package/docs/release-notes/v0.22.4.md +1 -14
  100. package/docs/release-notes/v0.22.5.md +2 -12
  101. package/docs/release-notes/v0.22.6.md +0 -3
  102. package/docs/release-notes/v0.23.0.md +9 -25
  103. package/docs/release-notes/v0.23.1.md +9 -25
  104. package/docs/release-notes/v0.23.2.md +2 -4
  105. package/docs/release-notes/v0.24.0.md +56 -97
  106. package/docs/release-notes/v0.24.1.md +7 -11
  107. package/docs/release-notes/v0.24.10.md +34 -45
  108. package/docs/release-notes/v0.24.11.md +12 -20
  109. package/docs/release-notes/v0.24.12.md +35 -48
  110. package/docs/release-notes/v0.24.13.md +34 -41
  111. package/docs/release-notes/v0.24.2.md +9 -13
  112. package/docs/release-notes/v0.24.3.md +7 -11
  113. package/docs/release-notes/v0.24.4.md +6 -6
  114. package/docs/release-notes/v0.24.5.md +6 -10
  115. package/docs/release-notes/v0.24.6.md +2 -5
  116. package/docs/release-notes/v0.24.7.md +46 -75
  117. package/docs/release-notes/v0.24.8.md +58 -96
  118. package/docs/release-notes/v0.24.9.md +38 -54
  119. package/docs/release-notes/v0.25.0.md +59 -76
  120. package/docs/release-notes/v0.25.1.md +57 -81
  121. package/docs/release-notes/v0.25.2.md +51 -70
  122. package/docs/release-notes/v0.25.3.md +11 -13
  123. package/docs/release-notes/v0.25.4.md +9 -13
  124. package/docs/release-notes/v0.25.5.md +3 -5
  125. package/docs/release-notes/v0.25.6.md +20 -29
  126. package/docs/release-notes/v0.25.7.md +5 -7
  127. package/docs/release-notes/v0.25.8.md +26 -39
  128. package/docs/release-notes/v0.26.0.md +175 -646
  129. package/docs/release-notes/v0.27.0.md +4 -5
  130. package/docs/release-notes/v0.27.1.md +4 -6
  131. package/docs/release-notes/v0.27.2.md +1 -1
  132. package/docs/release-notes/v0.28.0.md +57 -124
  133. package/docs/release-notes/v0.29.0.md +89 -208
  134. package/docs/release-notes/v0.29.1.md +1 -1
  135. package/docs/release-notes/v0.29.2.md +3 -4
  136. package/docs/release-notes/v0.30.0.md +205 -0
  137. package/docs/schedules.md +280 -363
  138. package/docs/servers.md +99 -117
  139. package/docs/soul.schema.json +2 -9
  140. package/docs/souls-and-instances.md +145 -158
  141. package/docs/workspaces.md +132 -215
  142. package/lib/automations.mjs +21 -6
  143. package/lib/core.mjs +226 -74
  144. package/lib/instance-events.mjs +1 -1
  145. package/lib/instance-inspect.mjs +109 -34
  146. package/lib/instance-lifecycle.mjs +14 -1
  147. package/lib/instance-resolution.mjs +26 -27
  148. package/lib/launch-preference.mjs +87 -0
  149. package/lib/materialize.mjs +3 -3
  150. package/lib/resolve.mjs +29 -87
  151. package/lib/schedule.mjs +1 -1
  152. package/lib/teams-verbs.mjs +195 -0
  153. package/lib/teams.mjs +190 -0
  154. package/lib/triggers.mjs +2 -2
  155. package/lib/workspace.mjs +54 -147
  156. package/package-catalog.json +9 -15
  157. package/package.json +1 -1
  158. package/skills/oats-getting-started/SKILL.md +25 -13
  159. package/capabilities/oats-review/injects/review.md +0 -69
  160. package/capabilities/oats-review/oats.json +0 -10
  161. package/capabilities/oats-review/skills/code-review/SKILL.md +0 -44
  162. package/capabilities/oats-review/skills/security-review/SKILL.md +0 -59
  163. package/docs/conventions.md +0 -90
  164. package/docs/design/2026-09-07-architecture-reassessment.md +0 -131
  165. package/docs/design/2026-09-07-desktop-souls-capabilities.md +0 -50
  166. package/docs/design/2026-09-07-mobile-agent-management-proposal.md +0 -228
  167. package/docs/design/2026-09-08-expert-assisted-deployment-proposal.md +0 -558
  168. package/docs/design/2026-09-13-knowledge-and-memory-direction.md +0 -744
  169. package/docs/design/2026-09-13-knowledge-implementation.md +0 -127
  170. package/docs/design/2026-09-13-knowledge-location-contract.md +0 -340
  171. package/docs/design/2026-09-14-artifact-retention-contract.md +0 -190
  172. package/docs/design/2026-09-14-portable-souls-and-git-workspaces.md +0 -708
  173. package/docs/design/2026-09-14-portable-souls-contract-amendments.md +0 -85
  174. package/docs/design/2026-09-14-portable-souls-explainer.md +0 -750
  175. package/docs/design/2026-09-15-captured-dispatch.md +0 -127
  176. package/docs/design/2026-09-15-captured-resolution-records.md +0 -143
  177. package/docs/design/2026-09-15-package-preparation.md +0 -100
  178. package/docs/design/2026-09-15-portable-data-contract.md +0 -121
  179. package/docs/design/2026-09-15-portable-declarations.md +0 -189
  180. package/docs/design/2026-09-15-portable-souls-handoff.md +0 -150
  181. package/docs/design/2026-09-15-portable-souls-implementation.md +0 -417
  182. package/docs/design/2026-09-15-selection-lock-and-approval.md +0 -122
  183. package/docs/design/2026-09-15-source-observation.md +0 -119
  184. package/docs/design/2026-09-16-captured-admission.md +0 -77
  185. package/docs/design/2026-09-16-captured-helper-dispatch.md +0 -105
  186. package/docs/design/2026-09-16-captured-launch-inputs.md +0 -42
  187. package/docs/design/2026-09-16-command-profile-preparation.md +0 -86
  188. package/docs/design/2026-09-16-fresh-install-first-rollout.md +0 -47
  189. package/docs/design/2026-09-16-fresh-operator-walkthrough.md +0 -282
  190. package/docs/design/2026-09-16-messaging-capability-contract.md +0 -59
  191. package/docs/design/2026-09-16-portable-migration-evidence.md +0 -158
  192. package/docs/design/2026-09-16-portable-onboarding.md +0 -179
  193. package/docs/design/2026-09-16-prepare-request-transport.md +0 -26
  194. package/docs/design/2026-09-16-provider-binding-codecs.md +0 -98
  195. package/docs/design/2026-09-16-provider-binding-wire.md +0 -274
  196. package/docs/design/2026-09-17-capability-helper-input-contract.md +0 -95
  197. package/docs/design/2026-09-17-captured-backend-parity.md +0 -53
  198. package/docs/design/2026-09-17-captured-native-start.md +0 -58
  199. package/docs/design/2026-09-17-portable-boundary-hookup.md +0 -19
  200. package/docs/design/2026-09-17-portable-boundary-resources.md +0 -52
  201. package/docs/design/2026-09-17-public-captured-start.md +0 -108
  202. package/docs/design/2026-09-17-public-prepare-request.md +0 -90
  203. package/docs/design/2026-09-18-captured-pi-host.md +0 -205
  204. package/docs/design/2026-09-18-first-cut-release-checklist.md +0 -131
  205. package/docs/design/2026-09-18-herdr-protocol-compatibility.md +0 -60
  206. package/docs/design/2026-09-20-redesign-program-board.md +0 -142
  207. package/docs/design/2026-09-20-workspace-and-portable-adoption-plan.md +0 -289
  208. package/docs/design/2026-09-20-workspace-onboarding-public.md +0 -207
  209. package/docs/design/2026-09-22-desktop-parity-seams.md +0 -58
  210. package/docs/design/2026-09-23-simplified-workspace-model.md +0 -711
  211. package/docs/design/2026-09-23-workspace-v2-implementation-plan.md +0 -65
  212. package/docs/design/2026-09-24-desktop-phase-f-boundary.md +0 -242
  213. package/docs/design/2026-09-24-phase-d-plan.md +0 -305
  214. package/docs/design/2026-09-25-teams-contract.md +0 -258
  215. package/docs/design/2026-09-26-desktop-design-brief-architecture.md +0 -241
  216. package/docs/design/desktop-ux-plan.md +0 -362
  217. package/docs/design/launch-configurations.md +0 -168
  218. package/docs/design/okf-mirror-provenance.md +0 -105
  219. package/docs/design/operations-contract.md +0 -141
  220. package/docs/oats-member.schema.json +0 -38
  221. package/skills/integration-authoring/SKILL.md +0 -84
  222. package/skills/oats-support/SKILL.md +0 -79
  223. package/skills/skill-craft/SKILL.md +0 -109
  224. package/skills/soul-craft/SKILL.md +0 -116
@@ -1,362 +0,0 @@
1
- # OATS Desktop — UX plan (phase 1)
2
-
3
- Author: ux-designer-desktop-ux · Branch: `ux-designer/desktop-app`
4
- Scope: design language + UX for `packages/desktop/` (Electron shell,
5
- xterm.js terminal, brain viewer, markdown viewer, diff viewer, panel port).
6
- This is a **decision document**: each section states the chosen option and why.
7
- It is written against the binding contract in
8
- `briefs/desktop-app-CONTRACT.md` (view modules `mount(el, ctx)` / `unmount()`;
9
- data from the oats-web HTTP API; tmux-attach terminals).
10
-
11
- ---
12
-
13
- ## 1. Design research — what we take from VS Code and opencode
14
-
15
- ### VS Code shell anatomy (what applies)
16
-
17
- VS Code's shell is: **activity bar → sidebar → editor group (tabs) → panel →
18
- status bar**, all keyboard-addressable through a **command palette**, all
19
- colored through **semantic theme tokens** (`editor.background`,
20
- `sideBar.foreground`, …) rather than raw hex in components.
21
-
22
- Principles we adopt:
23
-
24
- 1. **One persistent shell, swappable content.** Chrome (sidebar, tabs, status
25
- bar) never remounts; only the active view does. This maps 1:1 onto the
26
- `mount(el, ctx)` contract — the shell owns chrome, views own their `el`.
27
- 2. **Semantic color tokens.** Components reference roles (`--surface`,
28
- `--accent`, `--term-bg`), never palette values. Themes are token maps.
29
- The existing panel (`capabilities/oats-web/ui/panel.html`) already does
30
- this correctly — we extend its token set, we don't replace it (§4).
31
- 3. **Command palette as the universal escape hatch.** Every action reachable
32
- by mouse is reachable by `⌘K` (see §5). This is the cheapest way to be
33
- keyboard-first without designing a shortcut for everything.
34
- 4. **Tabs are documents; the sidebar is the world.** Tabs hold *open work*
35
- (a terminal, a diff, a markdown file); the sidebar holds *everything that
36
- exists* (the roster). Closing a tab never destroys the underlying thing —
37
- which matches the contract exactly (detach pty, never kill tmux).
38
- 5. **Status bar for ambient truth**: connection to the oats-web server,
39
- active workspace, running-instance count, theme toggle.
40
-
41
- What we deliberately **do not** clone:
42
-
43
- - **No activity bar.** VS Code's activity bar exists because it has many
44
- coequal top-level domains (explorer, SCM, debug, extensions). OATS desktop
45
- has *one* primary domain — agents — so a vertical icon rail would be
46
- ceremony. The sidebar gets a small segmented header instead
47
- (Agents | Hierarchy) — two modes, not five domains.
48
- - **No multi-root editor-group splitting (phase 2).** The panel's proven
49
- ≤3-pane terminal split is enough initially; generalized grid splitting is
50
- a later enhancement, not a launch requirement.
51
-
52
- ### opencode (what applies)
53
-
54
- opencode is a TUI-first agent client: session list on the left, one live
55
- session dominating the screen, minimal chrome, everything driven by keys and
56
- a fuzzy switcher. Principles we adopt:
57
-
58
- 1. **The session is the hero.** When you open an instance, its live terminal
59
- fills the stage immediately — no dashboard detour, no click-through.
60
- 2. **Fast session switching** (fuzzy, recency-ordered) matters more than
61
- deep navigation trees. Our palette's default mode is "jump to instance".
62
- 3. **State is legible at a glance**: running/idle/busy is shown as a colored
63
- dot next to every session name, everywhere the name appears (roster,
64
- tabs, hierarchy graph, palette). One vocabulary of status dots (§5).
65
- 4. **Terminal fidelity over widgetry.** Don't wrap the agent session in
66
- chat-bubble reconstructions; show the real terminal. The contract's
67
- direct tmux-attach already commits us to this — the UX embraces it.
68
-
69
- ---
70
-
71
- ## 2. Information architecture — agents at the heart
72
-
73
- **Decision: the primary object is the agent *instance*.** Files, diffs,
74
- terminals and brains are *facets of an instance*, not siblings of it. The IA
75
- is instance-centric, not file-centric — this is the single biggest departure
76
- from VS Code, and the reason the app exists.
77
-
78
- ### Shell layout
79
-
80
- ```
81
- ┌──────────────────────────────────────────────────────────────┐
82
- │ titlebar: ● oats [workspace ▾] filter/⌘K ◐ theme │
83
- ├───────────────┬──────────────────────────────────────────────┤
84
- │ SIDEBAR │ TAB STRIP [dev-1 ⬤][dev-1: diff][README.md] │
85
- │ ┌───────────┐ ├──────────────────────────────────────────────┤
86
- │ │Agents|Tree│ │ │
87
- │ └───────────┘ │ ACTIVE VIEW │
88
- │ roster: │ (terminal / brain / markdown / diff / │
89
- │ ws → repo → │ hierarchy / home) │
90
- │ instances │ │
91
- │ (children │ │
92
- │ indented) │ │
93
- │ ── souls ── │ │
94
- │ spawnable │ │
95
- ├───────────────┴──────────────────────────────────────────────┤
96
- │ status bar: ⬤ server · ws:oats · 4 running · branch · theme │
97
- └──────────────────────────────────────────────────────────────┘
98
- ```
99
-
100
- - **Sidebar (left, collapsible ⌘B)** — the roster, ported from the panel:
101
- workspace → repo → instances, with spawn-children indented under parents
102
- (the panel's `parentInstance` walk is kept verbatim). Below it, spawnable
103
- souls with a Spawn action. A segmented control at the top switches the
104
- sidebar between **Agents** (list) and **Hierarchy** (mini-tree; the full
105
- graph opens as a view, §3).
106
- - **Tab strip** — open facets. Tab title = `instance` (terminal),
107
- `instance: diff`, `instance: brain`, or file name (markdown). Terminal
108
- tabs carry the status dot. Middle-click / `⌘W` closes (detach only).
109
- - **Status bar** — server reachability, workspace, running count. Clicking
110
- the server segment reveals host/port; clicking the count filters to
111
- running.
112
-
113
- ### The home surface
114
-
115
- **Decision: home = the hierarchy view with an overview header**, not an
116
- empty state and not a dashboard of widgets. On launch (no tabs open) the
117
- stage shows the agent hierarchy graph (§3) topped by a one-line summary
118
- ("*oats workspace — 4 running, 2 idle, 1 retired today*") and a spawn button.
119
- Rationale: it makes the app's thesis — *you are orchestrating a team* —
120
- visible in the first second, and every node is one click from its terminal.
121
-
122
- ### Per-instance facet model
123
-
124
- Selecting an instance (sidebar click, palette, or graph node) opens its
125
- **terminal tab** — the hero facet. From the terminal tab's header (and the
126
- context menu / palette) the sibling facets are one action away:
127
-
128
- | Facet | Source | Opens as |
129
- |----------|-------------------------------|-----------------------|
130
- | Terminal | tmux attach via pty IPC | tab (default) |
131
- | Brain | `GET /api/brain/<agent>` | tab `instance: brain` |
132
- | Diff | `GET /api/diff/<instance>` | tab `instance: diff` |
133
- | Files | `GET /api/file?path=…` | tab per file (markdown viewer) |
134
-
135
- Cross-facet links use the contract's `ctx` verbs: brain view lists skills /
136
- knowledge / STATE.md → `ctx.openFile(path)`; any view can
137
- `ctx.openTerminal(instance)`. The hierarchy view is itself a view module and
138
- uses the same two verbs — no new contract surface needed.
139
-
140
- **Decision: tabs are per-facet, not per-instance-with-inner-tabs.** Inner
141
- tab bars (an instance tab containing terminal/brain/diff sub-tabs) were
142
- considered and rejected: they double the chrome, break `⌘W`/`⌘1..9`
143
- uniformity, and fight the `mount(el, ctx)` contract, which is flat. Facet
144
- association is expressed by tab naming + grouping tabs of the same instance
145
- adjacently.
146
-
147
- ---
148
-
149
- ## 3. Agent hierarchy visualization
150
-
151
- **Decision: an interactive tree-of-trees (layered DAG), not a force-directed
152
- graph.** Spawn parentage (`parentInstance` in the roster) is a forest —
153
- force layouts add jitter and non-determinism for zero benefit on tree data.
154
- Layout: **top-down tidy tree per workspace** (d3-hierarchy-style tidy layout;
155
- implementable in ~150 lines without a dependency, or with `d3-hierarchy`
156
- since desktop deps are allowed), workspaces side by side, SVG-rendered,
157
- pan/zoom.
158
-
159
- ### Two relationship kinds, two visual languages
160
-
161
- 1. **Spawn parentage** (who spawned whom): solid edges, the tree structure
162
- itself. Source: roster `parentInstance`.
163
- 2. **Coordination** (who works with whom): dashed accent edges *overlaid*
164
- on the tree, shown on hover/selection (always-on is noisy). Source:
165
- shared workspace/repo membership + aweb team metadata as exposed by
166
- `/api/panel`; degrade gracefully if absent — the view must not depend on
167
- a new endpoint (if richer comms data is wanted later, that is a phase-2
168
- request to the coordinator, not an assumption).
169
-
170
- ### Node design
171
-
172
- A compact card, not a bare circle — names and states must be readable
173
- without hover:
174
-
175
- ```
176
- ┌──────────────────────────┐
177
- │ ⬤ webpanel-dev-brain │ ⬤ status dot (see states)
178
- │ webpanel-dev · repo:oats │ agent · repo, muted
179
- └──────────────────────────┘
180
- ```
181
-
182
- - **States** (same vocabulary app-wide): **running** = green dot +
183
- full-opacity card; **idle** = hollow/gray dot, card at ~65% opacity
184
- (matching the panel's `.inst.idle`); **retired** = dashed border,
185
- faint text, only shown when the "show retired" toggle is on (retired
186
- instances known from roster history if available; otherwise omitted).
187
- - **Busy pulse** (phase-2 nice-to-have): subtle dot pulse when the session
188
- produced output in the last N seconds — cheap liveness signal.
189
-
190
- ### Interactions
191
-
192
- - **Click node → focus + detail popover** (task line, branch, dirty chip,
193
- buttons: *Open terminal · Brain · Diff*). **Double-click / Enter → open
194
- terminal tab** directly.
195
- - **Hover → highlight lineage** (ancestors + descendants) and show
196
- coordination edges for that node.
197
- - Pan (drag), zoom (pinch/`⌘±`), `f` to fit. Keyboard: arrows walk the tree,
198
- Enter opens.
199
- - Search-as-you-type filters/highlights nodes (reuses the sidebar filter
200
- semantics).
201
-
202
- The hierarchy is both a **full view** (home surface / `⌘⇧H`) and a
203
- **sidebar mini-mode** (same data, vertical indented tree — effectively the
204
- roster's existing child-indentation, promoted).
205
-
206
- ---
207
-
208
- ## 4. Theming
209
-
210
- **Decision: extend the panel's existing token system — it is already
211
- semantic, already dual-theme, already AA-audited.** The panel's `:root` /
212
- `[data-theme]` token blocks become `packages/desktop/renderer/theme.css`,
213
- the single source of truth. Views consume tokens only; a view containing a
214
- hex literal fails review.
215
-
216
- ### Token architecture
217
-
218
- Three tiers, one file:
219
-
220
- 1. **Core surface/text/interactive tokens** (exist today): `--bg`,
221
- `--surface`, `--surface-2`, `--border`, `--fg`, `--muted`, `--faint`,
222
- `--accent`, `--accent-fg`, `--ok`, `--warn`, `--danger`, `--chip-*`,
223
- `--sel`, `--shadow`.
224
- 2. **Terminal tokens**: `--term-bg`, `--term-fg`, `--term-sel` (exist) plus
225
- a **16-slot ANSI set** `--ansi-black … --ansi-bright-white` (new —
226
- xterm.js takes a theme object; we generate it from these tokens so the
227
- embedded terminal matches the app theme, including the solarized remap
228
- the panel already ships for light mode).
229
- 3. **New component tokens** (thin aliases over tier 1, so themes rarely
230
- need to override them): `--tab-active-bg`, `--tab-inactive-fg`,
231
- `--statusbar-bg`, `--graph-edge`, `--graph-edge-coord`,
232
- `--diff-add-bg`, `--diff-del-bg`, `--md-code-bg`.
233
-
234
- ### Themes
235
-
236
- - **Dark** (default when OS is dark): the panel's GitHub-dark-adjacent
237
- palette, unchanged.
238
- - **Light**: the panel's **solarized-light** palette, unchanged —
239
- compatibility with the web panel is a requirement and the palette already
240
- passes AA (`--fg` 9.9:1, `--muted` 4.9:1 on surface).
241
- - Theme = OS-follow by default, manual override persisted
242
- (`localStorage`, same keys as the panel: `oatsweb.theme`) so panel and
243
- desktop feel like one product. Room for future themes = adding one
244
- `[data-theme="x"]` block; no component changes.
245
-
246
- ### Accessibility commitments (both themes, verified in phase 2)
247
-
248
- - Body & secondary text ≥ 4.5:1 on their actual surfaces; UI glyphs/borders
249
- ≥ 3:1; status conveyed by **dot shape + label**, never color alone
250
- (idle = hollow dot, retired = dashed border — already specified in §3).
251
- - Visible `:focus-visible` ring (`--accent`, 2px) on every interactive
252
- element; full keyboard reachability (tabs, sidebar, graph, palette).
253
- - Diff colors get text labels (`+`/`−` gutters) in addition to
254
- `--diff-add/del-bg`; ANSI light remap keeps terminal output ≥ 4.5:1 as
255
- the panel already does.
256
- - `prefers-reduced-motion`: disable graph pan-inertia, dot pulse, spinner
257
- fades.
258
-
259
- ---
260
-
261
- ## 5. Component inventory + interaction details
262
-
263
- **Type & space.** UI font: system stack (as panel). Mono:
264
- `"SF Mono", ui-monospace, Menlo` (as panel). Type scale (px):
265
- 11 (chips/status) · 12 (secondary) · 13 (body/controls) · 14 (view titles) —
266
- matching the panel's proven density. Spacing scale: **4-px base**
267
- (4/8/12/16/24/32); radii: 6 (small controls) / 8 (cards, inputs) / 999
268
- (chips). Shadows: `--shadow` only.
269
-
270
- **Components** (shell-owned unless noted):
271
-
272
- - **Tabs**: 32px strip; active tab `--tab-active-bg` + 2px top accent
273
- (mirrors the panel's focused-pane inset accent); dirty/status dot on
274
- terminal tabs; overflow scrolls; drag-reorder phase-2. `⌘1..9` jump,
275
- `⌘W` close, `⌃Tab` MRU cycle.
276
- - **Sidebar**: as panel roster (filter input, collapsible groups, chips for
277
- branch/dirty/runtime) + segmented Agents/Hierarchy header. `⌘B` toggle.
278
- - **Command palette** (`⌘K`): single input, mode prefixes —
279
- default = jump to instance (fuzzy, MRU-boosted); `>` commands
280
- (spawn, toggle theme, open diff/brain of current instance, fit graph);
281
- `#` open file within current instance's home. Esc closes; results show
282
- status dots and repo chips.
283
- - **Toasts**: bottom-right, `--surface` card + colored left border
284
- (`--ok/--warn/--danger`), auto-dismiss 5s (errors sticky with a Close
285
- button), max 3 stacked, `aria-live="polite"`. Used for: spawn result,
286
- server lost/regained, pty exit.
287
- - **Loading states**: reuse panel's `.spinner` + `.loading-block`; skeleton
288
- rows (pulse animation) for roster and brain tree; terminals show
289
- "attaching to `<session>` …" with spinner until first pty bytes.
290
- - **Empty states**: reuse panel's `.empty` pattern (big glyph, one sentence,
291
- one action). E.g. diff view with clean tree: "No changes on
292
- `<branch>` — the work tree is clean."
293
- - **Dialogs**: only for destructive/parameterized actions (spawn with task
294
- text). Everything else is inline or palette.
295
- - **Markdown viewer** (view module): panel typography, `--md-code-bg` code
296
- blocks with syntax highlight, heading anchor links, relative links to
297
- files resolved through `ctx.openFile`.
298
- - **Diff viewer** (view module): file list (status/+/− counts) left or top,
299
- unified diff with `--diff-*` tokens, per-file collapse, staged toggle.
300
- - **Brain viewer** (view module): two columns — soul (AGENTS.md, skills,
301
- knowledge tree) and instances (state/task/notes) — every leaf is an
302
- `openFile` link; skills show their descriptions inline.
303
-
304
- **Keyboard-first rules**: `⌘K` palette · `⌘B` sidebar · `⌘T` spawn ·
305
- `⌘⇧H` hierarchy · `⌘W`/`⌘1..9`/`⌃Tab` tabs · `⌘F` filter. **Ctrl-B is never
306
- bound** — it is the tmux prefix and always flows to the focused terminal
307
- (the panel already enforces this rule; we keep it as law).
308
-
309
- ---
310
-
311
- ## 6. Phase-2 implementation plan (incremental, contract-compatible)
312
-
313
- Each step lands independently on the integrated app; none changes the view
314
- contract or the API contract. Order chosen so every step is visible value.
315
-
316
- 1. **Token foundation** — extract/extend `renderer/theme.css` (tiers 1–3,
317
- ANSI variables), wire `data-theme` + OS-follow + persistence; generate
318
- the xterm.js theme object from tokens; contrast-check both themes
319
- (automated check script if feasible).
320
- 2. **Shell chrome polish** — tab strip (status dots, accents, keyboard
321
- map), status bar, sidebar restyle to spec (segmented header, chips,
322
- focus rings), toasts, loading/empty components as shared renderer
323
- helpers views can import.
324
- 3. **Command palette** — jump/command/file modes as above; registered
325
- commands provided by the shell; instance jump from roster data.
326
- 4. **Hierarchy view** — new view module `views/hierarchy.js` using only
327
- roster data + `ctx.openTerminal`/`ctx.openFile`; tidy-tree layout,
328
- node cards, states, lineage highlight, popover, keyboard nav; wire as
329
- home surface and `⌘⇧H`.
330
- 5. **View polish pass** — apply tokens/typography/empty-loading patterns to
331
- the four developer-built views (terminal header, brain, markdown, diff),
332
- coordinating any needed hooks through dev-coordinator-1.
333
- 6. **Accessibility + reduced-motion audit** — keyboard walk of every
334
- surface, focus-visible sweep, contrast verification, `prefers-reduced-
335
- motion` guards; fix list executed before calling phase 2 done.
336
-
337
- ### Addendum — human directives (received via coordinator before phase-2
338
- go-ahead; to be re-confirmed in the go-ahead mail)
339
-
340
- Binding design directives that supersede anything conflicting above:
341
-
342
- 1. **Diff viewer surface removed** — no nav entry, no diff tabs. `/api/diff`
343
- and `diff.mjs` stay in the tree, dormant; removing dead UI wiring is in my
344
- scope. (Step 5 no longer polishes a diff view; `--diff-*` tokens remain
345
- defined for a possible return.)
346
- 2. **Markdown reader is the flagship viewer** — `openFile → markdown` gets
347
- the depth budget: typography, highlighting, anchors, relative-link
348
- resolution via `ctx.openFile`, strong loading/empty states.
349
- 3. **Jira surface hidden entirely** — no nav entry or inline cards; code
350
- stays unwired. Verify no remnants during the polish pass.
351
- 4. **Three first-class surfaces**: (a) hierarchy view = home + primary
352
- navigation (extra investment beyond step 4); (b) a proper **souls
353
- browser** stage view (descriptions + spawn affordances, palette-reachable)
354
- — promoted from the sidebar-list sketch in §2; (c) a nice way into agent
355
- brains.
356
- 5. Everything else (themes, tokens, palette, a11y) stands as written.
357
-
358
- Dependencies/risks flagged to the coordinator up front: (a) step 5 touches
359
- other developers' view code — I will work on the *integrated* branch only,
360
- after their merges; (b) coordination-edge data for §3 uses whatever
361
- `/api/panel` already exposes — if we want explicit aweb-team edges, that is
362
- a small additive API request, not a blocker.
@@ -1,168 +0,0 @@
1
- # Launch configurations and launch recipes
2
-
3
- A **launch configuration** is a named way to start a harness, declared by
4
- the host under `launch-configs:` in the deployment's `oats-local.yaml` (see
5
- docs/configuration.md; 0.26.0, lead decision 2 — earlier kernels read it
6
- from a scope's `oats-config.yaml`): runtime, an executable, literal
7
- arguments, environment (literals or `{fromEnv}` references), model, yolo.
8
- It is independent of any soul, and a spawn, start or restart selects one by
9
- name (`--launch-config`, or the Desktop's per-launch choice). A launch
10
- configuration is a spawn-time host choice, never a soul field: `launch-config:`
11
- is not a field of a workspace-model soul.yaml (docs/soul.schema.json; discovery
12
- refuses it), so a v2 soul cannot name one, not even as a default. (A classic
13
- 0.25 soul.yaml could name a preferred entry; 0.26.0 reads no such field.)
14
-
15
- A **launch recipe** is what a start is made of, recorded in the instance's
16
- `instance.json` under `launch` beside the rendered `command`:
17
-
18
- ```json
19
- {
20
- "version": 1,
21
- "runtime": "claude",
22
- "launchConfig": "personal", "launchConfigSource": "/deployment",
23
- "executable": "/deployment/tools/claude-wrapper.sh",
24
- "executableDeclared": "./tools/claude-wrapper.sh", "executableResolvedFrom": "relative to /deployment",
25
- "args": ["--settings", "/abs/settings.json"],
26
- "env": { "KEY": { "fromEnv": "SRC" }, "LIT": "plain" },
27
- "model": "claude-opus-5", "yolo": true,
28
- "hooks": {
29
- "launch": { "claude": "--dangerously-load-development-channels plugin:aweb-channel@awebai-marketplace" },
30
- "env": { "AWEB_DELIVERY": "session" },
31
- "contributions": [{ "capability": "oats.aweb", "layer": "messaging", "level": "/scope", "settings": { "delivery": "session" }, "trust": { "trusted": true, "integrity": "sha256-..." }, "launch": { "claude": "..." }, "env": ["AWEB_DELIVERY"] }]
32
- },
33
- "prompt": { "kind": "task-file", "file": "TASK.md" }
34
- }
35
- ```
36
-
37
- The rendered `command` is produced by one renderer from the recipe. With no
38
- configuration it is byte-identical to what spawn rendered before recipes
39
- existed, so an older kernel starts such a home unchanged, and the golden
40
- matrix freezes that. Configuration `args` go after the runtime's own
41
- options and before capability launch arguments (for claude and codex the
42
- `--` separator keeps them from consuming the task; for pi they follow the
43
- task, like capability arguments). Every argument and literal value is
44
- single-quoted: spaces, quotes and metacharacters are literal.
45
-
46
- ## Environment references
47
-
48
- `{fromEnv: SRC}` renders as `NAME="$SRC"` in the command: the persisted
49
- command, the pending receipt and every answer carry the reference, never a
50
- value. At start the execution host checks each source variable is set
51
- (`E_LAUNCH_ENV_MISSING` before anything is created or stopped) and hands the
52
- source variables to the pane only (tmux `-e`; a Herdr launch exports them in
53
- the launched shell). Literal values are non-secret by contract but no answer
54
- shows them: `list` and `preview` redact every environment value.
55
-
56
- ## Selection rules
57
-
58
- - A named configuration is a unit. `--launch-config NAME` with a `--runtime`
59
- that disagrees with the configuration's runtime is refused
60
- (`E_LAUNCH_CONFIG_MISMATCH`) before anything happens; the same runtime may
61
- be repeated; `--model` and `--yolo` override the configuration's fields.
62
- - Without `--launch-config`: a spawn uses no configuration (the runtime's
63
- defaults; a soul names none); an existing home keeps its recorded configuration, except that
64
- `--runtime` alone deliberately leaves it behind and renders the new
65
- runtime's defaults (no old executable or args are carried).
66
- - Model: explicit, else the configuration's, else on an existing home the
67
- recorded model when the runtime is unchanged, else the runtime's native
68
- default; a spawn without either uses the runtime's native default (a
69
- workspace-model soul declares no model). A model never crosses runtimes.
70
- - Executable: the configuration's (bare name on PATH; a path resolved against
71
- the deployment directory when relative) or the runtime's default (claude through
72
- `oats-claude-config`). It must be a regular executable file; it is never
73
- run to probe it. Capability runtime-package requirements are checked with
74
- the runtime's default binary, as at spawn.
75
-
76
- ## Capability boundary
77
-
78
- Spawn hooks contribute `launch` arguments keyed by runtime and `env` values.
79
- Launch arguments are runtime-specific by construction; environment is
80
- runtime-neutral by contract. The recipe records both with per-capability
81
- provenance (settings and trust at spawn). A later start on the same runtime
82
- reuses them. A runtime switch reuses the environment and needs the new
83
- runtime's launch arguments from the same capabilities: a capability that
84
- answered arguments for the old runtime and none for the new one refuses the
85
- switch (`E_LAUNCH_PREPARATION`) with the remedy (change that capability's
86
- setting, or the provider declares a `launch` hook). Spawn hooks are never
87
- re-run by a start or restart.
88
-
89
- ## `oats launch-config preview`
90
-
91
- Read-only; nothing is locked or started. `--home ABS` describes an existing
92
- home under a selection (`selection.source`: `frozen` when nothing was
93
- selected, `config` when re-resolved, `frozen-command` for a home that
94
- predates recipes, where a selection answers `E_LAUNCH_LEGACY`: re-spawn it);
95
- `--soul NAME [--dir SCOPE] [--agents-root ABS]` describes a new instance.
96
- Answer: `{context, selected, selection:{source, launchConfig, runtime,
97
- model, yolo}, runtime, model, modelSource, yolo, launchConfig,
98
- launchConfigSource, executable:{path, declared, resolvedFrom}, argv,
99
- environment:[{name, redacted|fromEnv}], command (redacted rendering),
100
- prompt:{kind:"task-file", file:"TASK.md"}, hooks (redacted),
101
- preflight:[{check: executable|environment|model|capabilities, ok, detail}],
102
- ok}`. The TASK body is never included.
103
-
104
- ## Starting and restarting an existing home
105
-
106
- `oats session start --home ABS` runs the recorded recipe as it is (a
107
- `--model` re-renders the model in place and the recipe follows). With
108
- `--launch-config`, `--runtime` or `--yolo` the recipe is re-resolved by the
109
- same planner preview uses, against the home's recorded context, and every
110
- check runs before anything is observed: the recipe's shape, the executable
111
- (regular file, executable), the references (set on this host), the
112
- capabilities' contributions (below), the runtime packages. A recorded
113
- reference is re-checked on every start path, model-only starts included,
114
- and the pane receives the source's value under the kernel alias.
115
-
116
- `oats session restart --home ABS [same flags] [--stop-grace SECONDS]` stops
117
- the running harness and starts again in place under the one per-home lock:
118
-
119
- 1. Every preflight above, first. A refusal leaves the harness running.
120
- 2. The stop: SIGTERM to every process under the pane's launcher (a wrapper
121
- that does not exec, the harness, their children), then a bounded wait
122
- (default 20 s) for the signalled processes to be gone and the session to
123
- read as a bare shell or stopped. Nothing is escalated: a harness still
124
- there when the wait ends is reported (`E_SESSION_STOP_FAILED`, with the
125
- processes still running) and nothing is launched. Elapsed time is never
126
- taken as exit; a turn interruption is never taken as exit.
127
- 3. The in-place start, with the pending receipt carrying the new recipe,
128
- runtime and yolo, exactly as a start does; `.oats-restart.json` keeps the
129
- stop's facts (what was signalled, when, whether exit was observed).
130
-
131
- What the harnesses do on SIGTERM, from their installed sources and
132
- documentation as read by the operating lead on 2026-09-07 (no live process
133
- signalled): pi (@earendil-works/pi-coding-agent 0.84.2) registers
134
- SIGTERM/SIGHUP handlers that end tracked children, dispose extensions and
135
- exit; Claude Code's documentation makes Ctrl-C state-dependent (interrupt,
136
- clear, double-press exit) and does not establish that an external SIGTERM
137
- runs its SessionEnd hook; Codex's documentation establishes no SIGTERM
138
- cleanup guarantee. So the contract is the request and the observation, not
139
- a promise that a harness flushes its latest conversation: OATS preserves
140
- the home, work, identity and notes; an old native conversation's unsaved
141
- state is the harness's own. Wrappers should exec the harness or forward
142
- signals. A longer `--stop-grace` can accommodate hook cleanup.
143
-
144
- ## Homes that predate recipes
145
-
146
- A home with a recorded `command` and no `launch` is converted narrowly when
147
- a start selects something: only the kernel's own generated shapes are
148
- recognized (identity environment, the binary, the runtime's template
149
- arguments, `--model`, yolo, the task prompt). Other environment is kept and
150
- attributed to the capability whose recorded declaration (`environment`,
151
- `environmentNamespaces` in `capabilityRuntime`) owns it, so a session-delivery
152
- home switches runtime with its `AWEB_DELIVERY` intact; spawn hooks are never
153
- re-run. Any other argument is unclassified: the start is refused, naming the
154
- arguments, unless an active trusted capability declares a `launch` hook that
155
- prepares the launch anew (then its answer replaces them). The conversion is
156
- recorded (`launch.legacy`) by the start that uses it.
157
-
158
- ## The `launch` hook
159
-
160
- A capability may declare `hooks.launch`. It runs on a start or restart of an
161
- existing home (never at spawn, never spawn's identity work), side-effect-free
162
- by contract, with `OATS_RUNTIME` set to the target runtime and
163
- `OATS_PREVIOUS_RUNTIME` to the recorded one, and answers `{launch:{<runtime>:
164
- args}, env:{...}}` for that runtime; its answer replaces the capability's
165
- recorded contribution. Without it, a capability that contributed
166
- runtime-specific arguments at spawn cannot follow a runtime change
167
- (`E_LAUNCH_PREPARATION`), and a capability the scope no longer trusts has its
168
- recorded arguments withheld the same way.
@@ -1,105 +0,0 @@
1
- # Internal: finalizing the OKF mirror's source provenance
2
-
3
- The standalone `oats.okf` distribution is authoritative. The framework's
4
- `capabilities/oats-okf/` and `scripts/okf-source-inventory.json` are generated
5
- mirrors, not authoring surfaces. This procedure does not publish the source,
6
- accept a PR, update the catalog, commit, fetch, or change branches.
7
-
8
- ## Development versus publication
9
-
10
- - `node scripts/check-okf-mirror.mjs --generate --source <standalone-repository>`
11
- captures current exported working bytes, including dirty/untracked files.
12
- It always records `release.status: pending`, null final refs and
13
- `published: false`, even when HEAD happens to have a published tag.
14
- - `node scripts/check-okf-mirror.mjs --verify` uses only the checked-in inventory
15
- and mirror. No Git, clone, credentials or network is needed for either a
16
- pending or finalized inventory. It checks exact file sets (including empty
17
- directories), file bytes, portable Git executable modes, literal symlink
18
- targets, wrapper hashes, and consistent release metadata.
19
- - `--verify-source --source <standalone-repository>` verifies pending snapshots
20
- against their exact recorded working state, including branch/dirty metadata.
21
- For published inventories it rechecks the immutable commit, payload, origin
22
- tag object and peeled commit, ignoring the recorded local branch name. The
23
- checkout must still be clean at the recorded accepted commit; renamed
24
- branches and detached HEAD are supported. This published-source check needs
25
- origin access. It does not depend on cached remote-tracking refs.
26
-
27
- Offline verification is an integrity check of a reviewed checked-in inventory,
28
- not independent proof that a remote still advertises a tag. The explicit source
29
- check supplies that evidence. No boolean flag is a publication attestation.
30
-
31
- ## Post-publication command
32
-
33
- Only after source review/merge and actual publication of `v2.0.0`:
34
-
35
- 1. Obtain the **accepted full merged commit ID** from the source review/release
36
- record. Do not substitute a mutable branch name, abbreviated hash, or whatever
37
- HEAD happens to resolve to. The legacy inventory field `finalMergedCommit`
38
- records this caller-supplied acceptance; Git cannot prove human PR approval.
39
- 2. Have a clean standalone checkout at that commit, with the published tag
40
- available locally and `origin` pointing to `awebai/oats-okf`. Fetch/check out
41
- deliberately through the parent release procedure; the checker never does it.
42
- 3. From the framework checkout, run:
43
-
44
- ```bash
45
- node scripts/check-okf-mirror.mjs --finalize \
46
- --source .agents/knowledge-rework/repos/okf \
47
- --final-tag v2.0.0 \
48
- --final-commit "${OKF_V2_ACCEPTED_COMMIT:?set the reviewed full merged source commit ID}" &&
49
- node scripts/check-okf-mirror.mjs --verify-source \
50
- --source .agents/knowledge-rework/repos/okf &&
51
- node --test test/okf-mirror-parity.test.mjs
52
- ```
53
-
54
- The relative source path above is the existing ignored work-view convention;
55
- substitute an explicitly resolved standalone repository path in other work
56
- views. The command must not be run while source acceptance is still changing.
57
-
58
- 4. Review the resulting payload/inventory diff, run the remaining release gates,
59
- then advance the catalog through the parent integration process. Finalization
60
- itself never touches the catalog.
61
-
62
- `--finalize` requires both `--final-tag` and a full SHA-1/SHA-256 `--final-commit`.
63
- It replaces only the mirrored capability and inventory, just like `--generate`,
64
- but stamps `release.status: published` only after all checks succeed:
65
-
66
- - The version tag is exactly `v<distribution version>`; HEAD is the explicitly
67
- accepted commit and Git reports a clean source tree. Masked index entries
68
- (`assume-unchanged`/`skip-worktree`) are not accepted.
69
- - Actual exported files and wrappers match raw objects at that commit, not just
70
- Git status or filtered checkout content. Ignored exported extras, untracked
71
- empty directories, CRLF/filter changes, hidden byte changes, mode drift with
72
- `core.filemode=false`, and literal symlink-target differences fail closed.
73
- Git replacement objects are disabled. Published inventories also record and
74
- hash wrapper file modes; materialization preserves those modes and bytes.
75
- - Exactly one effective origin fetch URL identifies the official source. The
76
- usual official GitHub HTTPS/SSH spellings are equivalent. URL rewrites to an
77
- unrelated repository are rejected. The remote query uses canonical public
78
- HTTPS with source-local Git configuration disabled, so local upload-pack/SSH
79
- overrides cannot fabricate its response. Prompts/helpers are disabled and
80
- Git commands have a bounded timeout.
81
- - The local tag resolves to the accepted commit. A fresh `ls-remote` query must
82
- advertise the same tag object and the same peeled commit (or direct commit
83
- for a lightweight tag). Both annotated and lightweight tags are supported.
84
- Missing/unreachable origin, unpublished tags or mismatched refs fail closed.
85
- - The source is checked again after staging the copy, before replacing the
86
- mirror or inventory. Failed acceptance checks leave both untouched. Ordinary
87
- filesystem failures during replacement are not a multi-file transaction.
88
-
89
- The published record retains `source.head`, clean-state metadata, the branch
90
- observed at generation (informational during immutable verification), the
91
- accepted final tag/commit, `remote: origin`, and the exact `tagObject`. Thus
92
- changing an annotated tag object without changing its commit still invalidates
93
- `--verify-source`. Remote checks attest what was advertised when queried; they
94
- cannot prevent an upstream tag from being moved later. Do not move released
95
- tags, and re-run source verification at the release gate.
96
-
97
- ## Isolated regression coverage
98
-
99
- `test/okf-mirror-parity.test.mjs` uses temporary source repositories and local bare
100
- origins only, including tag creation/deletion/movement solely inside fixtures.
101
- The JavaScript `finalizeOkfMirror`/`verifyOkfSource` APIs accept an explicit
102
- `repository` expectation for these fixtures and record their real source
103
- identity; the CLI cannot override the official repository. No tests publish to
104
- GitHub. Checked-in mirror tests accept consistent pending **or** published
105
- provenance, so finalizing the source does not require weakening those tests.