@awebai/oats 0.23.2 → 0.24.1

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 (172) hide show
  1. package/README.md +224 -391
  2. package/bin/oats-pi-sdk-host.mjs +17 -0
  3. package/bin/oats.mjs +470 -51
  4. package/capabilities/oats-okf/bin/oats-okf-binding.mjs +14 -0
  5. package/capabilities/oats-okf/bin/oats-okf.mjs +79 -11
  6. package/capabilities/oats-okf/lib/binding-wire.mjs +268 -0
  7. package/capabilities/oats-okf/lib/captured-worker.mjs +109 -0
  8. package/capabilities/oats-okf/lib/config.mjs +2 -1
  9. package/capabilities/oats-okf/lib/inspection.mjs +16 -1
  10. package/capabilities/oats-okf/lib/invocation-context.mjs +111 -0
  11. package/capabilities/oats-okf/lib/invocation-shape.mjs +135 -0
  12. package/capabilities/oats-okf/lib/io.mjs +1 -1
  13. package/capabilities/oats-okf/lib/portable-binding.mjs +199 -0
  14. package/capabilities/oats-okf/lib/source-contract.mjs +46 -0
  15. package/capabilities/oats-okf/lib/sources.mjs +123 -3
  16. package/capabilities/oats-okf/lib/stores.mjs +104 -25
  17. package/capabilities/oats-okf/lib/worker.mjs +69 -10
  18. package/capabilities/oats-okf/oats.json +35 -7
  19. package/capabilities/oats-okf/schemas/okf-portable-declaration.schema.json +87 -0
  20. package/capabilities/oats-okf/schemas/okf-portable-payload.schema.json +113 -0
  21. package/capabilities/oats-okf/skills/memory-harvest/SKILL.md +23 -5
  22. package/capabilities/oats-okf/skills/okf/SKILL.md +42 -1
  23. package/docs/artifact-approvals.schema.json +7 -0
  24. package/docs/capabilities.md +4 -0
  25. package/docs/capability-manifest.schema.json +37 -66
  26. package/docs/captured-invocation-context.schema.json +7 -0
  27. package/docs/captured-resolution.schema.json +7 -0
  28. package/docs/design/2026-09-14-artifact-retention-contract.md +190 -0
  29. package/docs/design/2026-09-14-portable-souls-and-git-workspaces.md +708 -0
  30. package/docs/design/2026-09-14-portable-souls-contract-amendments.md +85 -0
  31. package/docs/design/2026-09-14-portable-souls-explainer.md +750 -0
  32. package/docs/design/2026-09-15-captured-dispatch.md +127 -0
  33. package/docs/design/2026-09-15-captured-resolution-records.md +143 -0
  34. package/docs/design/2026-09-15-package-preparation.md +100 -0
  35. package/docs/design/2026-09-15-portable-data-contract.md +121 -0
  36. package/docs/design/2026-09-15-portable-declarations.md +189 -0
  37. package/docs/design/2026-09-15-portable-souls-handoff.md +150 -0
  38. package/docs/design/2026-09-15-portable-souls-implementation.md +417 -0
  39. package/docs/design/2026-09-15-selection-lock-and-approval.md +122 -0
  40. package/docs/design/2026-09-15-source-observation.md +119 -0
  41. package/docs/design/2026-09-16-captured-admission.md +77 -0
  42. package/docs/design/2026-09-16-captured-helper-dispatch.md +105 -0
  43. package/docs/design/2026-09-16-captured-launch-inputs.md +42 -0
  44. package/docs/design/2026-09-16-command-profile-preparation.md +86 -0
  45. package/docs/design/2026-09-16-fresh-install-first-rollout.md +47 -0
  46. package/docs/design/2026-09-16-fresh-operator-walkthrough.md +277 -0
  47. package/docs/design/2026-09-16-knowledge-capability-contract.md +61 -0
  48. package/docs/design/2026-09-16-messaging-capability-contract.md +59 -0
  49. package/docs/design/2026-09-16-portable-migration-evidence.md +156 -0
  50. package/docs/design/2026-09-16-portable-onboarding.md +177 -0
  51. package/docs/design/2026-09-16-prepare-request-transport.md +26 -0
  52. package/docs/design/2026-09-16-provider-binding-codecs.md +98 -0
  53. package/docs/design/2026-09-16-provider-binding-wire.md +247 -0
  54. package/docs/design/2026-09-17-capability-helper-input-contract.md +95 -0
  55. package/docs/design/2026-09-17-captured-backend-parity.md +53 -0
  56. package/docs/design/2026-09-17-captured-native-start.md +58 -0
  57. package/docs/design/2026-09-17-portable-boundary-hookup.md +19 -0
  58. package/docs/design/2026-09-17-portable-boundary-resources.md +52 -0
  59. package/docs/design/2026-09-17-public-captured-start.md +108 -0
  60. package/docs/design/2026-09-17-public-prepare-request.md +90 -0
  61. package/docs/design/2026-09-18-captured-pi-host.md +205 -0
  62. package/docs/design/2026-09-18-first-cut-release-checklist.md +131 -0
  63. package/docs/design/2026-09-18-herdr-protocol-compatibility.md +60 -0
  64. package/docs/design/2026-09-20-redesign-program-board.md +70 -0
  65. package/docs/design/2026-09-20-workspace-and-portable-adoption-plan.md +287 -0
  66. package/docs/design/2026-09-20-workspace-onboarding-public.md +124 -0
  67. package/docs/design/README.md +42 -0
  68. package/docs/desktop-cli-api.md +5 -2
  69. package/docs/execution-capsule.schema.json +108 -0
  70. package/docs/execution-targets.md +20 -7
  71. package/docs/first-team.md +1 -1
  72. package/docs/knowledge-theory.md +353 -111
  73. package/docs/knowledge.md +10 -1
  74. package/docs/layers.md +89 -354
  75. package/docs/oats-lock-v3.schema.json +7 -0
  76. package/docs/oats-member.schema.json +38 -0
  77. package/docs/oats-workspace.schema.json +68 -0
  78. package/docs/official-marketplace.md +79 -0
  79. package/docs/packages.md +4 -0
  80. package/docs/portable.schema.json +2512 -0
  81. package/docs/provider-check-input.schema.json +7 -0
  82. package/docs/release-notes/v0.24.0.md +104 -0
  83. package/docs/release-notes/v0.24.1.md +17 -0
  84. package/docs/schedules.md +126 -14
  85. package/docs/soul.schema.json +82 -0
  86. package/docs/souls-and-instances.md +20 -7
  87. package/docs/workspace-adoption.md +285 -0
  88. package/docs/workspaces.md +154 -0
  89. package/injects/oats-portable.md +16 -0
  90. package/injects/portable-instance-boundary.md +39 -0
  91. package/injects/portable-work-directory.md +29 -0
  92. package/lib/artifact-approvals.mjs +120 -0
  93. package/lib/artifact-tree.mjs +141 -0
  94. package/lib/capability-artifacts.mjs +179 -0
  95. package/lib/capability-execution.mjs +15 -0
  96. package/lib/capability-inputs.mjs +39 -0
  97. package/lib/capability-provenance.mjs +231 -0
  98. package/lib/captured-action-shape.mjs +21 -0
  99. package/lib/captured-admission-shape.mjs +20 -0
  100. package/lib/captured-binding-file.mjs +36 -0
  101. package/lib/captured-dispatch.mjs +66 -0
  102. package/lib/captured-instance-index.mjs +277 -0
  103. package/lib/captured-invocation-context.mjs +130 -0
  104. package/lib/captured-launch-request.mjs +46 -0
  105. package/lib/captured-operation-process.mjs +15 -0
  106. package/lib/captured-pi-custody.mjs +29 -0
  107. package/lib/captured-pi-host.mjs +167 -0
  108. package/lib/captured-pi-outcome.mjs +172 -0
  109. package/lib/captured-resolutions.mjs +275 -0
  110. package/lib/captured-scaffold.mjs +87 -0
  111. package/lib/captured-selector.mjs +28 -0
  112. package/lib/captured-session-backend.mjs +52 -0
  113. package/lib/captured-source-receipt-file.mjs +72 -0
  114. package/lib/config-data.mjs +104 -0
  115. package/lib/core.mjs +961 -566
  116. package/lib/errors.mjs +7 -0
  117. package/lib/helper-injection-policy.mjs +98 -0
  118. package/lib/herdr.mjs +18 -7
  119. package/lib/instruction-composition.mjs +31 -0
  120. package/lib/legacy-lock-codec.mjs +106 -0
  121. package/lib/manifest-settings.mjs +84 -0
  122. package/lib/package-closure.mjs +48 -0
  123. package/lib/package-materialization.mjs +83 -0
  124. package/lib/pi-sdk-host.mjs +229 -0
  125. package/lib/portable-artifacts.mjs +115 -0
  126. package/lib/portable-choices.mjs +82 -0
  127. package/lib/portable-composition.mjs +136 -0
  128. package/lib/portable-digest.mjs +105 -0
  129. package/lib/portable-files.mjs +26 -0
  130. package/lib/portable-identity.mjs +40 -0
  131. package/lib/portable-lock.mjs +117 -0
  132. package/lib/portable-migration-artifacts.mjs +135 -0
  133. package/lib/portable-migration-evidence.mjs +305 -0
  134. package/lib/portable-migration-store.mjs +199 -0
  135. package/lib/portable-migration.mjs +104 -0
  136. package/lib/portable-onboarding-acceptance.mjs +66 -0
  137. package/lib/portable-onboarding-request.mjs +49 -0
  138. package/lib/portable-onboarding.mjs +249 -0
  139. package/lib/portable-package-preparation.mjs +188 -0
  140. package/lib/portable-policy.mjs +44 -0
  141. package/lib/portable-shape.mjs +35 -0
  142. package/lib/portable-soul.mjs +38 -0
  143. package/lib/portable-state.mjs +80 -0
  144. package/lib/portable-values.mjs +181 -0
  145. package/lib/prepare-composition.mjs +151 -0
  146. package/lib/prepared-bindings.mjs +78 -0
  147. package/lib/prepared-resources.mjs +127 -0
  148. package/lib/provider-binding-broker.mjs +59 -0
  149. package/lib/provider-binding-wire.mjs +110 -0
  150. package/lib/provider-binding.mjs +22 -0
  151. package/lib/repository-observation.mjs +226 -0
  152. package/lib/resolution-shape.mjs +393 -0
  153. package/lib/schedule-capsule.mjs +206 -0
  154. package/lib/schedule.mjs +259 -38
  155. package/lib/servers.mjs +15 -0
  156. package/lib/soul-constraints.mjs +40 -0
  157. package/lib/source-projection.mjs +84 -0
  158. package/lib/source-spec.mjs +189 -0
  159. package/lib/workspace-definition.mjs +126 -0
  160. package/lib/workspace-discovery.mjs +146 -0
  161. package/package-catalog.json +2 -1
  162. package/package.json +3 -2
  163. package/packages/record/lib/capture-cc.mjs +14 -6
  164. package/packages/record/lib/formats.mjs +14 -3
  165. package/packages/record/lib/native-history.mjs +277 -7
  166. package/packages/record/lib/session-snapshot.mjs +25 -5
  167. package/packages/record/lib/sessions-for-home.mjs +30 -13
  168. package/skills/oats/SKILL.md +12 -7
  169. package/skills/oats-config/SKILL.md +11 -9
  170. package/skills/oats-packages/SKILL.md +12 -8
  171. package/skills/oats-portable/SKILL.md +115 -0
  172. package/skills/oats-portable-artifacts/SKILL.md +63 -0
@@ -0,0 +1,277 @@
1
+ # Fresh operator walkthrough: working preparation versus pending launch
2
+
3
+ ## Scope of this evidence
4
+
5
+ This is a **source-level integration walkthrough**, not a claim about an installed
6
+ release. The onboarding builder/acceptance boundary is from `3b8f6532`; the real
7
+ preparation consumer remains pinned to
8
+ `c5c6a3c9171e424a36a1bdbf3932b9319a3c6c72`. A separate producer/CLI case is pinned
9
+ to `257c4b96b67001fa2bcf38436e57106c44aa797b` and exercises actual public
10
+ `spawn --no-launch`, including incarnation and intent custody. Neither test implies
11
+ compatibility with an untested newer wire. Core owns preparation scratch,
12
+ artifact retention, binding execution, approval and incarnation/admission. Onboarding does not replace
13
+ those implementations.
14
+
15
+ The acceptance uses a small manifest-declared **fixture knowledge capability**.
16
+ It does not use OKF, access external services, exercise harvesting, or qualify
17
+ private messaging. Its provider program interprets only its own collection and
18
+ explicit destination data. The source carries an unreachable publisher-workspace
19
+ backlink; inspection/preparation never adopts or contacts that workspace.
20
+
21
+ ## Reproduce the pinned public consumer
22
+
23
+ From the framework worktree, with the existing locked root dependencies installed
24
+ and both exact core commits available in the local Git object database:
25
+
26
+ ```bash
27
+ node --test --test-timeout=60000 test/portable-onboarding-public.acceptance.mjs
28
+ ```
29
+
30
+ This explicit acceptance driver is separate from the default `*.test.mjs` suite:
31
+ a shallow checkout or source tarball need not contain a historical cross-branch
32
+ commit. An explicit run **fails** if the pin or matching dependency lock is absent;
33
+ it never silently skips, fetches a moving branch, substitutes current core or
34
+ strips unsupported request fields.
35
+
36
+ `test/helpers/portable-onboarding-consumer.mjs` archives committed core objects
37
+ into owned ignored `stage/onboarding-consumer-*` scratch and verifies the pin and
38
+ held-patch exclusion. It links only this worktree's dependencies after comparing
39
+ the complete npm lock. No working files from another agent are loaded and no Git
40
+ worktree/branch is added, reset or merged. Only the fixture's scratch is removed
41
+ on completion.
42
+
43
+ The test runs real native Git observations with isolated host configuration and
44
+ explicit local file transport mappings. Other transports are disabled. Public
45
+ preparation creates retained software/state **inside temporary fixture
46
+ deployments**; after explicit fixture-only artifact approval, its inert provider
47
+ normalize/bind/check commands run. The separate 257c4b96 case also executes the
48
+ fixture's declared spawn hook through the actual public CLI. It never hand-writes
49
+ permissive instance metadata: the producer mints and indexes each incarnation,
50
+ admits the hook intent, and settles the receipt. Guarded test executables detect
51
+ any attempted backend/model/client/host-timer invocation. No runtime, helper,
52
+ schedule, normal capability command or live provider is launched.
53
+
54
+ ## Exact operator sequence at this source checkpoint
55
+
56
+ ### 1. Choose independent inputs
57
+
58
+ Choose an explicit source export/revision/alias, deployment directory and work
59
+ target. Existing project files/Git repositories need not be empty. For organization
60
+ setup, choose an explicit workspace; consuming a public source does not make its
61
+ repository a member. Supply a member request only when reciprocal admission is
62
+ actually intended.
63
+
64
+ For standalone setup, supply an own `standaloneContextKey` field containing an
65
+ explicit opaque key, or explicit `null` for no private context. Never derive it
66
+ from a path, username, source alias or agent identity. Do not also supply a
67
+ workspace. The fixture prepares both keyed and explicit-null standalone requests,
68
+ with messaging disabled; neither case proves messaging enrollment/privacy.
69
+
70
+ Onboarding and pinned core both accept at most **256 UTF-8 bytes** for the key.
71
+ Oversized keys are refused, never truncated, dropped or derived from another input.
72
+ The earlier onboarding limit of 1,024 characters has been corrected: local ingress
73
+ rejects over-limit ASCII and non-ASCII keys before source access, and the real
74
+ pinned consumer retains an exact 256-byte non-ASCII key unchanged.
75
+
76
+ The key boundary is verified against pinned c5 preparation. Incarnation/admission
77
+ behavior is checked separately against exact 257c4b96, not inferred from c5.
78
+
79
+ ### 2. Inspect, without authorizing installation
80
+
81
+ Use `preflightFreshDeployment({deployment})` and then
82
+ `inspectPortableOnboarding(input, {repositories})`, where `repositories` is the
83
+ existing `createRepositoryTransaction` owned by the caller. Inspect explicit
84
+ workspace imports/exports and optional catalog descriptor witnesses. There is no
85
+ automatic topology scan or publisher-workspace adoption.
86
+
87
+ - `separate-deployment-required`: preserve everything at that deployment and
88
+ select another path. Do not delete its OATS state, knowledge, identity or history.
89
+ - `needs-configuration`: resolve the reported explicit input/membership issue.
90
+ - `ready-for-preparation`: advisory preflight/discovery passed; it is **not**
91
+ provider readiness, executable approval, installation or launch permission.
92
+
93
+ Close the inspection repository transaction when inspection ends. The issued
94
+ inspection may be used to build a public request without retaining its scratch.
95
+ The real consumer proves this by closing inspection scratch before preparation.
96
+
97
+ A missing deployment path can be inspected, but public preparation requires an
98
+ existing directory. Provision that explicit path separately without replacing an
99
+ existing entry; onboarding does not create it. **Re-inspect after provisioning**
100
+ before the first preparation call. The old absent-path inspection is not permission
101
+ to use a directory that appeared later. Replacement of the selected deployment,
102
+ its absent-path parent or the work-target directory also requires reinspection;
103
+ ordinary project-file edits do not.
104
+
105
+ ### 3. Supply explicit provider bindings and build the public request
106
+
107
+ ```js
108
+ const choices = { operator, mode: "directory", allowLocalPaths: false };
109
+ const handoff = buildFreshPreparationRequest(inspection, choices);
110
+ ```
111
+
112
+ `operator` uses the existing public operator envelope (`policy`, operator
113
+ `document`, optional `bindings`). A capability interprets its own binding payload;
114
+ there is no universal `writeDestination` schema or default destination in
115
+ onboarding. The fixture's `bindings.destination` is **fixture-provider syntax**,
116
+ not an OKF or generic kernel field.
117
+
118
+ Pass **all** of `handoff.preparation` unchanged. It contains deployment/source/
119
+ origin, explicit workspace or standalone key, operator/mode/local-input choices,
120
+ and an optional member request. It contains no `directory`: public
121
+ `prepareCapturedComposition` creates and cleans its own private scratch.
122
+ `handoff.workTarget` stays separate; this step does not perform actual work
123
+ placement.
124
+
125
+ ### 4. Explicitly perform the first preparation
126
+
127
+ Given `core` loaded from the intended compatible kernel and explicit native
128
+ `repositoryOptions`, the working API handoff is:
129
+
130
+ ```js
131
+ const first = prepareFreshOnboarding(inspection, choices, {
132
+ prepareCapturedComposition(request) {
133
+ return core.prepareCapturedComposition(request, { repositoryOptions });
134
+ },
135
+ });
136
+ ```
137
+
138
+ This is a **mutating command boundary**, unlike inspection/building. The driver
139
+ rechecks fresh state and its ephemeral selected directory witnesses immediately
140
+ before calling public core. If a legacy lock or other relevant managed state
141
+ appeared, it throws `fresh-deployment-required`; if an inspected directory was
142
+ replaced or a previously absent deployment was provisioned, it throws
143
+ `selection-changed` and requires a fresh inspection. Both refuse before calling
144
+ core. No project-content pin or new persistent custody registry is added; this
145
+ local recheck does not replace core's own concurrency and lifecycle guards.
146
+
147
+ An absent deployment returns `pending/fresh-deployment-provisioning-required`;
148
+ an absent callable adapter returns `pending/onboarding-integration-required`.
149
+ Both have `mutationAttempted:false`. An installed core that rejects a supplied
150
+ field remains a typed error, not a reason to strip the field and retry.
151
+
152
+ ### 5. Review an exact approval request, then explicitly continue
153
+
154
+ An executable binding codec must itself be approved before normalize/bind may
155
+ run. In the real fixture, the first result has `resolution:null`, an
156
+ `approval-required` problem and an exact `{capability, artifactSet, request}`
157
+ approval request. No provider phase ran before that approval.
158
+
159
+ After the operator has reviewed and chosen **that exact** artifact:
160
+
161
+ ```js
162
+ core.approveAvailableCapability(
163
+ handoff.preparation.deployment,
164
+ chosenApproval.artifactSet,
165
+ chosenApproval.capability,
166
+ explicitOperatorApprovalOrigin,
167
+ );
168
+ const prepared = core.prepareCapturedComposition(
169
+ handoff.preparation,
170
+ { repositoryOptions },
171
+ );
172
+ ```
173
+
174
+ These are two deliberate mutations, not an automatic approval loop. Never approve
175
+ all returned requests merely to obtain a green result. The capability may still
176
+ report incomplete/conflicting bindings afterward.
177
+
178
+ After the first preparation writes managed state, the deployment is **no longer
179
+ fresh**. Continue through ordinary explicit public preparation as above; rerunning
180
+ the fresh driver correctly refuses. Do not erase the newly retained state to
181
+ bypass that guard. The driver is not a full resumable onboarding orchestrator.
182
+
183
+ ### 6. Inspect the captured result, not a launch claim
184
+
185
+ When public preparation returns a resolution, use the existing public
186
+ `core.loadCapturedDispatch({deployment, resolution, action:{kind:"inspect"}})`.
187
+ The real test verifies the exact source commit/qualified identity, adopter-local
188
+ alias, explicit provider destination, workspace or standalone context, and
189
+ messaging-disabled choice from the retained record. Full-subject invocation data
190
+ also matches that record through the generic fixture check seam.
191
+
192
+ It verifies retained inspection again after removing **fixture-owned original
193
+ sources**, not after deleting real user repositories. This is preparation and
194
+ retention evidence—not actual running instance/job lifecycle acceptance.
195
+
196
+ ### 7. Explicit public spawn without runtime launch (257c4b96 only)
197
+
198
+ At the separately pinned producer, a reviewed prepared **directory-mode** record
199
+ can create a new home and run its approved spawn hooks:
200
+
201
+ ```bash
202
+ node "$PINNED_KERNEL/bin/oats.mjs" \
203
+ --deployment "$DEPLOYMENT" --resolution "$RESOLUTION" \
204
+ spawn "$RETAINED_SUBJECT_ALIAS" --home "$NEW_ABSOLUTE_HOME" --no-launch --json
205
+ ```
206
+
207
+ These variables must name the explicit pinned kernel, retained resolution and a
208
+ new home under a real existing parent; the alias must match the retained subject.
209
+ Do not point the command at an occupied home or substitute an old instance's
210
+ metadata. No additional work-target flag is supported by this captured spawn
211
+ form. Its `home/work` is a newly owned execution directory, not silent adoption
212
+ of the separately inspected project checkout.
213
+
214
+ The real consumer uses this exact CLI after removing its fixture source/workspace
215
+ repositories. It asserts producer-created `incarnationId`, exact execution binding,
216
+ retained source/context/provider binding, index schemaVersion 2, and the same
217
+ completed hook intent in index/metadata/opaque provider receipt. Two homes with the
218
+ same resolution receive distinct incarnation and execution IDs. It also proves
219
+ private invocation/binding snapshots are cleaned up after hooks.
220
+
221
+ Successful output is **still pending launch**:
222
+
223
+ ```text
224
+ ok:true
225
+ result.launched:false
226
+ result.launchPending:true
227
+ result.hooksPending:false
228
+ instance/index lifecycle: spawned-launch-pending
229
+ ```
230
+
231
+ `ok:true` confirms this no-launch operation, not that a runtime started or user work
232
+ completed. Repeating the call for the same home, or choosing an occupied user-data
233
+ directory, returns `E_INSTANCE_EXISTS` without changing existing metadata/index/
234
+ work or dispatching another hook. The operator must preserve the occupied path;
235
+ there is no force/cleanup shortcut in this flow. Actual runtime start/wake/retire
236
+ and production provider qualification remain separate lifecycle/acceptance gates.
237
+
238
+ ### Pending request-file router (lifecycle-owned)
239
+
240
+ The requested addition is `prepare --request <absolute-regular-json-file> [--json]`;
241
+ it is **not implemented in either pinned CLI**. The
242
+ [request transport helper](2026-09-17-public-prepare-request.md) is now implemented
243
+ as `readPortablePreparationRequest({file,inputFlags,explicitSelector})`; it takes
244
+ already-parsed transport forms, reads bounded strict JSON, and returns the whole
245
+ input unchanged to public core. The real preparation consumer exercises it.
246
+ The file is exactly `handoff.preparation`, never its wrapper or a captured
247
+ execution selector. The
248
+ lifecycle adapter must retain the existing source/workspace flag forms, make
249
+ request mode mutually exclusive with all source/deployment input overrides, and
250
+ use the existing bounded reader, strict JSON decoder and public core validator.
251
+ Explicit captured selectors must be refused for new preparation, including before
252
+ the command; stale inherited resolution/instance environment must not supply
253
+ new-work authority. The existing global selector parser owns this routing—there
254
+ is no onboarding-owned parallel parser. Until implemented/tested, use the working
255
+ public JavaScript handoff above, not invented request flags.
256
+
257
+ ## Working versus pending
258
+
259
+ | Boundary | Status at the pinned consumer |
260
+ |---|---|
261
+ | Explicit source/workspace inspection and exact public preparation handoff | Exercised with real native Git and unchanged request objects |
262
+ | String/null standalone context in the public JavaScript API | Exercised; core's 256-byte limit applies |
263
+ | Exact artifact approval before provider compilation, explicit adopter binding | Exercised with a declared fixture capability only |
264
+ | Fresh preflight refuses newly appeared legacy state | Exercised before the real adapter is invoked |
265
+ | Private `directory` in public request | Correctly refused before scratch/acquisition writes |
266
+ | Request-file helper feeding the existing public preparation API | Implemented and exercised with unchanged inputs; no installer/global parser |
267
+ | Onboarding CLI request mode and standalone-key/operator-binding flags | **Not implemented in pinned `prepareCmd`**; lifecycle-owned router still pending |
268
+ | Public `oats prepare` source/workspace forms | Present in pinned source, but cannot express this complete fresh-context/binding flow; not a substitute for the tested API request |
269
+ | Core-owned inspection of a retained resolution | Exercised without source/workspace availability |
270
+ | Actual public `spawn --no-launch` at exact 257c4b96 | Exercised producer-created incarnation/index/intent and fixture hooks; returns pending launch, refuses overwrite |
271
+ | Full actual captured launch/start/wake/retire, managed runtimes and non-directory work placement | **Not qualified by these tests**; lifecycle-owned work/gates remain |
272
+ | Real knowledge delivery and private messaging grants/reuse | **Not qualified**; provider-owned implementation and bounded live acceptance remain |
273
+ | Historical reconstruction/in-place migration | Deferred; not required or silently satisfied by fresh setup |
274
+
275
+ No migration CLI, alternate installer/config engine, registry, identity database or
276
+ provider backend is introduced here. Main integration/release remain coordinator
277
+ operations, not consequences of a passing local consumer test.
@@ -0,0 +1,61 @@
1
+ ---
2
+ type: Decision
3
+ status: accepted-boundary
4
+ title: Knowledge and harvesting capability contract boundary
5
+ description: OATS provides generic context, binding, lifecycle and execution contracts; capabilities implement knowledge and harvesting functionality.
6
+ timestamp: 2026-09-16
7
+ ---
8
+
9
+ # Knowledge and harvesting capability contract boundary
10
+
11
+ **OATS provides contracts; capabilities provide functionality.** Knowledge and
12
+ harvesting follow the same separation as the
13
+ [messaging capability contract](2026-09-16-messaging-capability-contract.md).
14
+ The reference knowledge theory remains optional authoring guidance, not a mandatory
15
+ runtime model or a kernel-owned harvester.
16
+
17
+ ## Responsibilities
18
+
19
+ | Kernel contract/support | Capability functionality |
20
+ |---|---|
21
+ | Selection, exact executable approval and the shared resolver | Interpret provider-owned declarations; validate and render its nonsecret bindings |
22
+ | Verified captured source/instance/context and bounded invocation data | Select/read the knowledge relevant to that context through its own model/tools |
23
+ | Generic lifecycle events, hook outcomes and cleanup custody | Initialize its memory protocol, capture/freeze inputs and perform its own retirement handoff |
24
+ | Generic native evidence APIs where applicable | Choose which evidence to collect, how to interpret it and its durable source/cursor format |
25
+ | Source-independent helper/job execution, exact artifact/record references and admission identity | Supply harvester helpers, prompts, runtime conventions, schedules and input/destination receipts |
26
+ | Truthful execution/uncertainty and declared operation result contracts | Judge promotion, validate, retry, publish and establish provider-specific acceptance |
27
+
28
+ Reuse ProviderBinding, captured invocation/lifecycle, declared operations and
29
+ execution capsules. Any missing generic field is reviewed/versioned once. Do not
30
+ introduce a second config parser, resolver, command registry or harvesting engine.
31
+ Capability-specific data remains opaque to the kernel.
32
+
33
+ ## Default OKF versus alternatives
34
+
35
+ `oats.okf` owns stores/nodes, reads/owns, immutable views, STATE/log/notes conventions,
36
+ durable source descriptors, harvester judgment and store-specific delivery. Its
37
+ existing promotion bar and PR-only Git knowledge publication remain in force.
38
+ Other capabilities may use different models, stores and harvesting machinery;
39
+ they are not required to imitate OKF's filesystem or workflow.
40
+
41
+ The knowledge-theory expert is an authoring aid, not a runtime dispatcher,
42
+ universal harvester or required approval service. Capability ownership does not
43
+ waive repository governance, work boundaries, secret exclusions, exact executable
44
+ approval or truthful lifecycle/custody reporting.
45
+
46
+ ## Integration checks
47
+
48
+ - Audit helper memory/injection suppression and source handoff projection for
49
+ accidental kernel-owned knowledge policy. Move new behavior behind neutral
50
+ contracts or capability declarations as appropriate; do not blindly enable
51
+ recursive harvesting or weaken existing fail-closed guards.
52
+ - A knowledge-specific source receipt may remain a compatibility input for a
53
+ provider, but must not become the mandatory shape for every alternative.
54
+ - Retirement must honor required capture/handoff outcomes before deleting their
55
+ source. The capability supplies the evidence and outcome; the kernel does not
56
+ implement the provider's memory/promotion algorithm.
57
+ - Independent work must retain everything it needs through the existing execution
58
+ and provider custody contracts, without a live source/config fallback.
59
+
60
+ This records the boundary and remaining audit, not a claim that every consumer is
61
+ already refactored or that a fresh deployment/live harvester is qualified.
@@ -0,0 +1,59 @@
1
+ ---
2
+ type: Decision
3
+ status: accepted-boundary
4
+ title: Messaging capability contract boundary
5
+ description: Define generic messaging inputs and outcomes in OATS, then implement their provider behavior in oats.aweb.
6
+ timestamp: 2026-09-16
7
+ ---
8
+
9
+ # Messaging capability contract boundary
10
+
11
+ OATS supplies the messaging contracts; the selected messaging capability consumes
12
+ them. `oats.aweb` owns the aweb implementation. This follows the accepted
13
+ [Portable Souls decisions](2026-09-15-portable-souls-handoff.md), not a new kernel
14
+ messaging backend or OATS-hosted identity/permissions system.
15
+
16
+ ## Existing shared contracts
17
+
18
+ Reuse [provider wire v1](2026-09-16-provider-binding-wire.md), ProviderBinding1,
19
+ MessagingChoice1, execution bindings and manifest-owned commands/hooks.
20
+
21
+ | Contract responsibility | Kernel supplies/enforces | Capability implements/reports |
22
+ |---|---|---|
23
+ | Selection | One selected provider, exact artifact approval, shared resolver choices | Provider-domain normalization/binding, no hidden precedence |
24
+ | Ownership/context | Responsible-human reference; qualified workspace or explicit standalone key; inherited owner for children/jobs | Native reference resolution and proof it addresses the intended human/context |
25
+ | Membership intent | Private floor plus explicit wider set; source/team declarations are not enrollment | Native private-team provision/reuse and wider membership reconciliation |
26
+ | Invocation | Exact execution binding, validated instance/subject and action/event, own binding and prior provider receipt | Native operation using only supplied authority and supported credential lookup |
27
+ | Outcomes | Typed readiness, action/result and cleanup custody; nonsecret retained receipts | Provider-specific identity/team/member references and actual evidence |
28
+ | Access | Four distinct expected grants, no privacy inferred from configuration | Verification through actual catalog/live/contact/history mechanisms |
29
+
30
+ The existing generic wire is implemented. The exact additional captured messaging
31
+ lifecycle projection, if required, must be reviewed/versioned before hookup. It
32
+ must derive from the captured record and invocation, not ambient team/configuration
33
+ or a knowledge-specific source declaration. This table does not invent a second
34
+ command table, resolver or readiness protocol.
35
+
36
+ ## Phase and effect boundary
37
+
38
+ - Normalize/bind compile supplied intent into nonsecret provider data and common
39
+ messaging choices. No identity/team enrollment occurs merely from acquisition.
40
+ - Check is read-only and action-specific. A setup action may be admissible when
41
+ authorized to provision; that is not proof membership already exists.
42
+ - Explicit capability setup/lifecycle actions perform permitted mutations, retain
43
+ receipts and handle retries/cleanup. Subsequent readiness reflects actual state.
44
+ - Unadapted captured actions refuse before using live legacy configuration. No
45
+ hidden fallback, arbitrary team creation or identity borrowing is acceptable.
46
+
47
+ ## Getting the aweb capability working
48
+
49
+ Investigate and use supported aweb identity, team, membership and transport
50
+ mechanisms inside the capability. A missing field in `whoami`, or absence of a
51
+ single human/context lookup command, is not sufficient to declare the design
52
+ blocked. Establish the native resolution/reuse mechanism and its authority; where
53
+ that truly cannot be implemented, report the precise missing backend contract.
54
+
55
+ The four grants intentionally need not share a native API. Compose their separate
56
+ mechanisms without treating contact as history access. Preserve the no-new-OATS-
57
+ control-plane constraint and validate cross-host identity/private-team reuse with
58
+ real provider evidence before claiming privacy. Fixtures and connectivity alone
59
+ remain insufficient. No credential values belong in captured contracts or logs.
@@ -0,0 +1,156 @@
1
+ # Portable migration evidence reader and planner
2
+
3
+ 16 September 2026. This is the first read-only implementation slice of the
4
+ Portable Souls consumer migration. The retention contract and the fifteen
5
+ binding decisions in `2026-09-15-portable-souls-handoff.md` remain authoritative.
6
+
7
+ ## Boundary
8
+
9
+ `lib/portable-migration-evidence.mjs` inventories an explicitly supplied bounded
10
+ set of deployment-local inputs:
11
+
12
+ - legacy/current lock files;
13
+ - instance homes (`instance.json` plus an optional rollback-incomplete cleanup
14
+ descriptor); and
15
+ - schedule scopes (`oats-schedules.json` plus schedule state).
16
+
17
+ The caller supplies the target list. The reader does not recursively discover a
18
+ workspace, infer an owner from an alias, consult current config, fetch source,
19
+ execute a provider, inspect a live process, or write any file. Targets must be
20
+ contained by one explicit canonical deployment and may not traverse symlinked
21
+ parents. Metadata is read through the shared descriptor-backed bounded reader.
22
+ Every present document is identified by `oats.bytes.v1` over its literal bytes,
23
+ including historical whitespace and old field spelling.
24
+
25
+ The inventory deliberately emits a bounded summary rather than copying arbitrary
26
+ legacy settings, commands, task text, credentials, or hook output into a new
27
+ record. A valid-shaped `executionBinding` or scheduled execution capsule is
28
+ preserved as a candidate reference, but shape validation is not retained-input,
29
+ approval, host, provider, or lifecycle verification.
30
+
31
+ `verifyPortableMigrationInventory` repeats the same bounded reads and compares the
32
+ complete deterministic projection. Byte drift, disappearance, appearance, or a
33
+ changed summary returns `selection-changed`. This is a precondition for a future
34
+ apply operation, not an apply operation itself.
35
+
36
+ ## Honest planning
37
+
38
+ `lib/portable-migration.mjs` is pure. `planPortableMigration(inventory)` emits only:
39
+
40
+ - `preserve`: retain an existing captured job authority while verifying it;
41
+ - `verify`: verify an existing captured reference and all separate readiness
42
+ gates; or
43
+ - `hold`: preserve literal evidence because reconstruction is not established.
44
+
45
+ Every target remains `partial` or `unknown`. This planner cannot emit
46
+ `reconstructed`, sets `readyToApply:false`, and declares that it performs no
47
+ writes, provider execution, session or schedule changes, or trust transfer.
48
+
49
+ ## Separate unselectable evidence store
50
+
51
+ `lib/portable-migration-store.mjs` validates `ResolutionEvidence1` and publishes
52
+ planned partial/unknown evidence under:
53
+
54
+ ```text
55
+ <deployment>/.agents/resolution-evidence/<oats.json.v1 id>.json
56
+ ```
57
+
58
+ The store is distinct from `.agents/resolutions/`; partial/unknown documents must
59
+ carry `resolution:null`. `listResolutionEvidence` provides bounded deterministic
60
+ diagnostics with incremental visited-entry, retained-record and aggregate-byte
61
+ limits. Managed metadata/staging consumes the visited-entry budget even though it
62
+ is not returned. An absent store is empty; every returned content address is
63
+ verified, and corruption or unexpected entries fail closed.
64
+ `commitPlannedResolutionEvidence` re-reads and compares
65
+ the complete inventory before it creates the evidence store, recomputes the
66
+ planner output rather than trusting caller-supplied status, and publishes canonical
67
+ private bytes by atomic no-replace hard link. Matching existing bytes are reused;
68
+ damaged existing evidence refuses without repair. Publication changes no source
69
+ lock, home, schedule, session or approval state.
70
+
71
+ `commitHistoricalHomeCapabilityEvidence` can publish the narrow verified
72
+ home-to-v2-artifact association as `partial`. It persists capability/package IDs,
73
+ paths and old/new digests, but deliberately omits unclassified legacy source,
74
+ settings and command text; the original byte-addressed documents remain the
75
+ witnesses. It still grants no selection, approval or retention authority.
76
+
77
+ The validator can read a future `reconstructed` evidence document only when it has
78
+ no unresolved inputs and names a shaped resolution reference. This slice exposes
79
+ no writer for that state. A later dedicated historical verifier must establish and
80
+ publish the complete reconstructed record before it can publish that evidence.
81
+
82
+ Old v1/v2 lock rows remain literal historical evidence. Their legacy digest and
83
+ trust fields are not reinterpreted as owner-execute identity or exact-artifact
84
+ approval. `lib/legacy-lock-codec.mjs` is the acyclic bytes-in structural decoder
85
+ for both historical formats. It preserves the existing v1 entry, retired-entry,
86
+ v2 row/graph/back-reference, state-free empty-v2 and transitional-v2 semantics,
87
+ while routing ingress through the common bounded strict JSON decoder. Duplicate
88
+ decoded keys, malformed UTF-8 and oversized inputs therefore refuse before any
89
+ row is exposed. Retired capability policy is an injected pure callback; the
90
+ codec imports no core/config/filesystem module.
91
+
92
+ The migration inventory accepts this codec as `legacyLockDecoder`. Successful
93
+ structural verification removes only that unresolved item from the plan.
94
+ `verifyHistoricalLockCandidate` then rechecks the complete inventory, rereads the
95
+ chosen explicit target and returns the strictly decoded v1/v2 rows with their
96
+ literal witness and `trustAuthority:"none"`. It does not retain artifacts or
97
+ associate the lock with a home/job. A deployment lock still cannot establish which
98
+ revision an individual home or job used. Home runtime rows, rendered hook paths,
99
+ copied skills and launch metadata can narrow investigation but do not establish
100
+ the full source, capability, helper and managed-runtime closure. A legacy or
101
+ unknown scheduled attempt is held exactly; it is never rebound to today's
102
+ definition or lock. The inventory distinguishes an existing legacy attempt from
103
+ an absent attempt even when no execution field exists. A captured current
104
+ definition cannot turn that old unresolved attempt into preserved captured
105
+ authority; the planner keeps the target `unknown` and `hold` pending owner
106
+ reconciliation.
107
+
108
+ `lib/portable-migration-artifacts.mjs` adds one narrower read-only proof for an
109
+ explicit materialized-v2 candidate. It requires the strict lock witness, verifies
110
+ the existing legacy artifact digest and exact `.oats-installation.json` provenance,
111
+ preflights `.oats-installation.json` through the bounded descriptor-backed
112
+ regular-file reader before the legacy tree hasher can allocate it, records the
113
+ exact provenance-byte digest, and then measures both old and new tree digests
114
+ twice. A final bounded provenance read must match the preflight witness. A
115
+ symlinked, oversized, replaced or drifting provenance file therefore cannot lend
116
+ external/pre-hash bytes to the candidate. The old digest implementation and its
117
+ historical mode limitations remain unchanged. The result labels modes
118
+ `observed-at-migration`, trust/selection authority `none`, and retention
119
+ `not-retained`.
120
+
121
+ V1 candidates require the existing literal legacy digest as an injected callback;
122
+ the migration module never imports core or substitutes the v2 algorithm. It
123
+ preflights and byte-witnesses bounded regular `oats.json`, requires its
124
+ capability/version to match the v1 row, brackets old/new digest measurements, and
125
+ still treats `trustedExecutables` only as evidence. V1 `package` and capability
126
+ `path` are persisted as `null`: unknown historical row keys do not become verified
127
+ artifact provenance. No legacy source, settings or other unknown row text is copied
128
+ into the new evidence document; only the independently verified artifact path is.
129
+
130
+ `verifyHistoricalHomeCapabilityCandidate` can additionally prove that one unchanged
131
+ home's `capabilityRuntime` names exactly one capability with the same old digest.
132
+ That is a narrow per-capability association only: the result remains `partial`,
133
+ retains the legacy trusted bit only as a claim, and leaves source revision, full
134
+ resources/helpers/runtime closure and new-format approval unresolved.
135
+
136
+ ## Required follow-on seams
137
+
138
+ 1. The acyclic strict legacy-lock byte decoder is implemented. Parent integration
139
+ must replace `core.parseLockFileStrict`'s duplicate body with a tiny file-read
140
+ wrapper around it and expose the bound bytes seam with the kernel's retired-ID
141
+ callback. Until that integration lands, core remains the live parser and the
142
+ migration inventory requires explicit decoder injection.
143
+ 2. Parent lifecycle integration must provide the authoritative bounded target
144
+ list, including quarantined/deferred homes and independent provider records.
145
+ This module does not infer deployment topology.
146
+ 3. Reconstructed publication needs a dedicated historical evidence verifier. It
147
+ must establish every managed input, recheck unchanged witnesses, retain exact
148
+ artifacts, require new-format executable approval, and use immutable guarded
149
+ publication. It must not weaken the existing prepared-only
150
+ `commitCapturedResolution` gate.
151
+ 4. Partial/unknown evidence now has its own immutable evidence store and never
152
+ enters `.agents/resolutions/` or becomes dispatch-selectable. A later lifecycle
153
+ adapter may index these references without changing that authority boundary.
154
+
155
+ No live migration, lock conversion, timer, provider, instance, or deployment
156
+ operation is performed by this slice.