@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,7 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "$id": "https://oats.dev/schemas/provider-check-input-v1.json",
4
+ "title": "Provider check input v1",
5
+ "description": "New private wire boundary; public consumer activation requires the explicit preparation/migration integration. See portable-v1.json for semantic verification requirements.",
6
+ "$ref": "https://oats.dev/schemas/portable-v1.json#/$defs/ProviderCheckInput"
7
+ }
@@ -0,0 +1,104 @@
1
+ # OATS v0.24.0 — retained execution first cut
2
+
3
+ This kernel/Pi/Desktop **0.24.0** cut covers the qualified retained-execution slice
4
+ below. Source review, native acceptance, packaged-artifact validation, publication
5
+ and deployment remain distinct facts; this note is not proof of any user's rollout.
6
+
7
+ ## Published official OKF pairing
8
+
9
+ This cut pins **oats.okf 2.1.0**, requiring **OATS >=0.24.0**, at the existing
10
+ `oats-package` source path. Published tag `v2.1.0` resolves to reviewed commit
11
+ `f20f8e57a22bdffb48b34dee9bcbc03a9e0704db`. The existing finalizer verified the actual
12
+ origin tag object, committed payload bytes/modes/alias and wrapper files; the mirror
13
+ inventory now records that publication. Do not use an installed0.23.x kernel with
14
+ this newer provider floor. Kernel versions are stamped by the existing tag lane;
15
+ no compatibility check is bypassed.
16
+
17
+ Before kernel publication, real retained primary and operation-created SOURCE workers
18
+ completed on both tmux and Herdr, with qualified process/SDK outcomes, protected
19
+ captured turns and independent directory-knowledge delivery. A separate real probe
20
+ passed exact replay and distinct restart for all four homes, observing the supplied
21
+ instruction heading and selected skill read without a controlled unrelated ancestor
22
+ canary. The release-stamped kernel/adapter tarballs with this provider also passed
23
+ actual installation and smoke outside the checkout. These results do not extend the
24
+ explicit feature limits below or substitute for installed published-artifact checks.
25
+
26
+ ## Source-complete preparation and retained execution
27
+
28
+ - Public `prepare --request` accepts one bounded nonsecret JSON input through the
29
+ shared strict reader and preparation validator. Source, deployment, work target
30
+ and workspace/standalone context remain distinct; no inherited current config
31
+ fills missing source authority. Exact executable approvals remain explicit.
32
+ - Fresh onboarding detects existing managed state without deleting it. Inspected
33
+ deployment/work-directory replacement or later provisioning requires reinspection;
34
+ ordinary project edits remain allowed. This is a point-in-time check, not a lock
35
+ against concurrent writers or a general migration engine.
36
+ - Captured instructions/resources, source identity and provider bindings remain
37
+ usable from retained bytes after the source is removed. Portable home/work
38
+ boundaries preserve canonical aliases and immutable source custody.
39
+ - Captured primary/helper public start and restart use retained selections and
40
+ indexed incarnation/intent custody. A helper is launched through its exact
41
+ **SOURCE helper edge**, not by treating a dedicated helper ID as a persistent
42
+ source. Same-ID uncertainty is held rather than redispatched; failure receipts,
43
+ pending allocation, native history and cleanup obligations are preserved.
44
+ - Provider execution keeps generic invocation, same-owner binding and explicitly
45
+ opted-in source-receipt inputs separate. Missing/invalid current transport does
46
+ not silently become legacy authority. Source-owned completion is not transferred
47
+ to a helper or invented instance.
48
+
49
+ ## Backends and first-cut Pi profile
50
+
51
+ The shared native path supports the existing tmux and Herdr adapters. Herdr adapter
52
+ selection understands exact protocols20 and22; it does not negotiate an unknown
53
+ protocol, relabel a retained target or fall back to tmux. Public caller/schema support
54
+ and the actual explicit server endpoint must match the selected protocol. API2
55
+ availability/readiness-not-checked is not server, model or provider health.
56
+
57
+ The first-cut Pi host target is explicit print-mode retained execution, not unrestricted
58
+ interactive/plugin parity. Its packaged entrypoint, parser/native services, selected
59
+ curriculum eligibility and external session-directory identity witness must be complete
60
+ before that selected profile is usable. An absent/incomplete witness or required
61
+ runtime/bridge/plugin contribution remains a refusal, never a dummy success or a
62
+ silently dropped requirement.
63
+
64
+ The user's already-authenticated harness retains its normal native profile,
65
+ auth/helpers/OAuth/model configuration. This cut does not introduce an auth-file
66
+ selector, credential inspection/copy, provider/key allowlist, empty production store
67
+ or substitute profile. Strict selected curriculum and controlled native history are
68
+ separate from that authentication boundary.
69
+
70
+ ## Desktop CLI compatibility
71
+
72
+ Desktop's released-CLI band extends to `>=0.22.0 <0.25.0`, including0.24.x. Desktop
73
+ CLI API remains **v1**; prereleases, wrong probe/API versions and failed probes still
74
+ refuse. Optional execution/remote capabilities are advertised separately—version
75
+ acceptance grants none of them. Observation-only degradation remains available when
76
+ no compatible CLI is verified.
77
+
78
+ This version-band update is not complete captured UI, Herdr0.9 terminal attachment,
79
+ plugin, scheduling, retirement/recovery or all-platform Desktop parity. The existing
80
+ release lane aligns kernel, Pi and Desktop manifests/locks together, retains package
81
+ and installed-artifact checks, and keeps Desktop artifact gates before tag-workflow
82
+ publication. Ad-hoc signing is not Developer ID notarization.
83
+
84
+ ## Explicit limits and safe adoption
85
+
86
+ - No automatic reconstruction/in-place migration, old-state deletion, role-library
87
+ adoption or new operator-root/bootstrap-helper grammar is introduced.
88
+ - Selected unsupported managed/plugin/bridge or interactive profiles stay held.
89
+ Default-OKF worker/capture/learning claims require the actual selected launcher,
90
+ real turn, captured result and accepted fresh-reader evidence—not seeded transcripts
91
+ or a successful scaffold. Git knowledge delivery remains PR-only.
92
+ - Public captured retirement, wake and recovery remain separately bounded work;
93
+ do not strip selectors, use a legacy/private fallback, or delete an uncertain home
94
+ to simulate completion. Preserve old sessions, identities, work and receipts.
95
+ - No private-aweb human/admin/privacy qualification follows from backend/model
96
+ success. External authority evidence cannot be fabricated by the framework.
97
+ - Provider versions, catalog refs and compatibility floors must identify real
98
+ reviewed/published artifacts. This note does not finalize or repin them.
99
+
100
+ Use a new explicit deployment/source request and the actual installed public contract.
101
+ Do not assume parked source candidates or optional helper packages are published.
102
+ Final release evidence must distinguish package installation, native dispatch, actual
103
+ model/task completion, provider-worker behavior and learning; a narrow first-cut pass
104
+ must not be presented as full parity.
@@ -0,0 +1,17 @@
1
+ # OATS v0.24.1 — workspace adoption, public inspection, captured custody on the home route
2
+
3
+ Kernel/Pi/Desktop **0.24.1**. Publication is not deployment; every operator still installs, approves and qualifies locally.
4
+
5
+ ## What changed
6
+
7
+ - **Framework repository joins the Git workspace model.** `oats-workspace.yaml` (workspace `oats-development`, seven intended members) and `oats.yaml` (exports: transitional `souls/oats-expert` edition, `oats-package`, `capabilities/oats-authoring`) are published at the repository root. Member indexes are on `main` in oats-okf, oats-aweb, oats-authoring and oats-jira. Membership is discovery, not activation; `imports` stay empty until sources are pinned at reviewed revisions.
8
+ - **`oats inspect --request <absolute-json> [--json]`** — read-only inspection of a source/workspace/member through the existing onboarding facade. Metadata only: provider payloads and adoption values are omitted, no deployment state or approval is touched, captured selectors are refused.
9
+ - **Captured custody on the home-only session route.** `oats session inspect|input --home H` now applies the existing captured incarnation/custody checks for captured homes and refuses before any transport when the home was replaced (integrity drift). Non-captured homes are unchanged. This is the route the aweb broker uses.
10
+ - **OKF 2.1.1 pairing.** The mirror, `package-catalog.json` ref and the transitional soul's source pin `oats.okf@v2.1.1`: ordinary Claude/Codex helpers with a complete approved capability closure are accepted by the OKF consumer; strict Pi still requires an explicit model and the sole-OKF profile.
11
+ - **Official marketplace policy** — `docs/official-marketplace.md`: the reviewed `package-catalog.json` list *is* the official marketplace; listing is by maintainer-reviewed PR; discoverable ≠ installed ≠ approved.
12
+ - **Kernel setup skill removed.** `skills/oats-portable-setup` is deleted on the human's instruction; setup guidance moves to the planned `oats.setup` capability (see the [decision](https://github.com/awebai/oats/blob/main/agents/oats-expert/soul/knowledge/decisions/official-capabilities-oats-core-setup-and-marketplace.md)).
13
+ - Docs: `docs/workspaces.md`, `docs/workspace-adoption.md`, condensed `docs/layers.md`, `docs/design/README.md` navigation, program board.
14
+
15
+ ## Not in this cut
16
+
17
+ `oats.core` / `oats.setup` capabilities, explicit default `oats.core` on soul creation, `oats-setup-expert` onboarding, the five expert soul editions, the aweb portable adapter (aweb 1.10.3 still has no binding interface) and Desktop marketplace views are in progress — see the [program board](../design/2026-09-20-redesign-program-board.md).
package/docs/schedules.md CHANGED
@@ -18,8 +18,16 @@ and no queue.
18
18
 
19
19
  ## Files
20
20
 
21
- - `<workspace>/oats-schedules.json` — the definitions (`{version: 1, jobs:
22
- {<id>: ...}}`). Commit it if you want the schedule shared with the team.
21
+ - `<workspace>/oats-schedules.json` — the definitions (`{version: 1|2, jobs:
22
+ {<id>: ...}}`). Version 1 is the legacy format. Adding the first explicit
23
+ version-2 execution upgrades the whole document to version 2 so an older
24
+ scheduler refuses it instead of ignoring capture policy. Existing legacy
25
+ entries may remain visibly unmigrated; new entries in a v2 file must declare
26
+ their policy. Commit the file if you want the schedule shared with the team.
27
+ Automatic wake creation uses this same document-version gate. Remote captured
28
+ mutations require advertised numeric schedule API 2 before forwarding; the old
29
+ feature-only gate is insufficient. Unclassifiable remote spec files also require
30
+ API 2. Legacy inline specs/read operations remain compatible with older hosts.
23
31
  - `<workspace>/.agents/schedules/state.json` — last attempted minute and
24
32
  last run per job (gitignored), plus one lock directory per running job.
25
33
  - `~/.oats/schedules/registry.json` — the host registry: which scopes the
@@ -29,6 +37,10 @@ and no queue.
29
37
  with the directory to remove, and the holder removes its own lock on exit
30
38
  and on SIGINT/SIGTERM. Definition edits take a short per-scope lock.
31
39
 
40
+ The existing Desktop adapter can inspect/manage supported API-2 schedules, but its
41
+ legacy editor refuses captured policy fields rather than dropping them. Full captured
42
+ editing UI remains later Desktop work; use the explicit CLI for those definitions.
43
+
32
44
  ## Kinds
33
45
 
34
46
  - **spawn** `{id, enabled, cron, tz, kind: "spawn", agent, agentsRoot?,
@@ -48,6 +60,8 @@ and no queue.
48
60
  from durable context; the job follows that worker until its home is gone.
49
61
  Command return is not task completion. Avoid binding durable work to a
50
62
  disposable source-home cwd; see [OKF v2 source jobs](#okf-v2-source-jobs).
63
+ New exact-record command definitions use the fields described in
64
+ [Captured execution and recurrence](#captured-execution-and-recurrence).
51
65
  - **wake** `{id, enabled, cron, tz, kind: "wake", home, message}` — every
52
66
  due minute inspects the instance at `home` through its session receipts.
53
67
  Running: `message` is delivered once with `session input`. Not running
@@ -77,6 +91,88 @@ required IANA zone; both are evaluated by the croner library. `--wake-every
77
91
  N` at spawn time means `*/N * * * *`: every 7 fires at :00, :07, ... :56 and
78
92
  then :00 again, so 1, 5, 10, 15 and 30 give an even cadence.
79
93
 
94
+ ## Captured execution and recurrence
95
+
96
+ A new captured command definition is explicitly versioned and chooses its
97
+ recurrence policy. Its containing schedule document is version 2:
98
+
99
+ ```json
100
+ {
101
+ "id": "retained-job",
102
+ "definitionVersion": 2,
103
+ "recurrencePolicy": "capture",
104
+ "kind": "command",
105
+ "cwd": "/absolute/workspace",
106
+ "argv": [
107
+ "oats", "example-action", "run",
108
+ "--deployment", "/absolute/deployment",
109
+ "--resolution", "sha256-...",
110
+ "--", "--provider-argument", "--json"
111
+ ],
112
+ "responsibleHuman": null,
113
+ "cron": "0 * * * *",
114
+ "tz": "UTC"
115
+ }
116
+ ```
117
+
118
+ The admitted-attempt wire is published as
119
+ [`execution-capsule.schema.json`](execution-capsule.schema.json). Runtime
120
+ validation checks selector/target agreement. A canonical `oats.json.v1` digest
121
+ of all fields except `executionId` is the separate content witness;
122
+ `executionId` itself is opaque admission identity.
123
+
124
+ `capture` requires the explicit deployment/resolution selector pair and
125
+ `--json` in the **saved argv**. The scheduler never appends an unrecorded
126
+ protocol argument to a captured target. Adding or updating the definition
127
+ derives an immutable `execution` template containing that exact target,
128
+ resolution, input references and explicitly supplied responsible-human value.
129
+ It contains no execution ID; `executionStatus.contentIntegrity` exposes its
130
+ canonical content witness. At each due tick the
131
+ scheduler verifies the retained action first, then mints a fresh opaque
132
+ `executionId`, writes the resulting capsule into the attempt before reserving a
133
+ slot, and only then invokes the CLI. Thus two attempts with identical content
134
+ have the same capsule digest but remain different intents. Definition edits
135
+ affect later admissions only; an unknown attempt, `run`, or reconciliation never
136
+ replaces its capsule with the edited definition or today's config/lock. Captured
137
+ attempts carry their own `schemaVersion:1`; their launch-slot lock names the same
138
+ `executionId`. A mismatching lock or malformed/unknown attempt version stays
139
+ unresolved and cannot dispatch. Scheduler launch also scrubs ambient
140
+ `OATS_DEPLOYMENT` and `OATS_RESOLUTION`; only the saved argv is authority.
141
+
142
+ `prepare-on-tick` is a distinct explicit policy for a genuinely new command
143
+ tick. Its `preparation` object maps directly to the generic
144
+ `prepareCapturedComposition({deployment,source,workspace?,member?,operator?,mode?})`
145
+ input; scheduler code does not parse source/workspace policy itself. Production
146
+ uses the core adapter and tests may inject the same contract. Direct-source and
147
+ workspace-alias requests are supported; `mode` is a work-mode string, not a nested
148
+ launch object. A complete result must preserve the requested deployment and
149
+ returned resolution, and contain `executionBinding` and an explicit
150
+ `responsibleHuman` (`null` means messaging was actually disabled). The scheduler
151
+ then inserts the exact selector pair before `--`, verifies the captured action,
152
+ mints and persists the attempt, and dispatches. Missing adapters and incomplete
153
+ results return typed `migration-required`/`needs-configuration` with no attempt.
154
+ A dry run never invokes preparation or mints intent. There is no current-context
155
+ fallback. Captured spawn and
156
+ operation definitions remain unavailable until their public captured consumer
157
+ adapters exist. A captured wake definition is accepted only when its target
158
+ `instance.json` has an exact `executionBinding`; the binding is copied into the
159
+ execution template and checked again at admission without consulting source or
160
+ configuration. Actual captured wake delivery/start remains blocked with
161
+ `migration-required` until the parent-owned lifecycle consumer lands. Legacy
162
+ wakes continue through the old lifecycle boundary in this release.
163
+
164
+ Definitions without `definitionVersion`/`recurrencePolicy` are legacy v1
165
+ definitions. They retain the old release behavior during migration and are not
166
+ reported as captured execution. `list`/`show` report their `executionStatus` as
167
+ `{kind:"legacy",capture:"unknown",migrationRequired:true}`. A captured definition
168
+ reports only `capture:"recorded"` until action admission verifies the retained
169
+ record and current exact approval; it does not claim launch readiness. While an
170
+ attempt is unresolved or its confirmed launched work still holds a slot,
171
+ `executionStatus.intent` separately reports captured, legacy-unknown or invalid
172
+ authority, so editing a future definition cannot hide an older admitted capsule.
173
+ Partial, malformed or unsupported versioned
174
+ definitions/attempts are invalid or blocked, never reinterpreted as legacy.
175
+
80
176
  ## Commands
81
177
 
82
178
  ```sh
@@ -100,20 +196,29 @@ running}], scheduler: {installed, active, lastTick, maxConcurrent, ...}}`.
100
196
 
101
197
  ## What a run reports
102
198
 
103
- `launched` (spawn or command returned), `active` (the instance is running;
199
+ `launched` (spawn or command returned), `blocked` (versioned execution
200
+ admission refused before a launch slot or child process), `active` (the instance is running;
104
201
  a home whose retirement is pending still counts, its runtime may be alive),
105
202
  `ended` (its home is gone), `stopped` (home present, nothing running: needs
106
203
  attention, never removed for you), `launch-failed`, `unknown`, and for wake
107
204
  jobs `delivered`, `started` or `skipped`. The kernel never claims a task
108
205
  succeeded.
109
206
 
207
+ `blocked` includes an unavailable exact record/approval or incomplete new-work
208
+ preparation, including not-yet-qualified provider bindings. The result preserves the typed
209
+ `errorCode`; no attempt capsule or launch lock is created.
210
+
110
211
  `unknown` means the launch's side effects are unconfirmed: a command timed
111
212
  out or answered no envelope, an envelope named an instance the roster
112
213
  cannot place, or an attempt was never recorded. The job keeps its slot and
113
214
  is skipped until `oats schedule reconcile <id>`. Reconcile adopts only an
114
- attributable receipt: a spawn job's instance is named deterministically for
115
- its minute, a command job's only by the instance its answer named. Nothing
116
- is inferred from file times. A command whose answer named nothing stays
215
+ attributable receipt: a legacy spawn job's instance is named deterministically
216
+ for its minute. A captured command requires the SAME admitted execution ID and
217
+ content witness, plus its explicitly recorded home and matching instance metadata;
218
+ current-config roster lookup or a previous attempt's name cannot establish it.
219
+ Nothing is inferred from file times. Observation validates custody before releasing
220
+ slots, and unresolved attempts remain held even in the crash gap before a lock
221
+ exists. Ordinary removal refuses those attempts; force-forget remains explicit. A command whose answer named nothing stays
117
222
  unknown; check the roster and the host by hand, then
118
223
  `oats schedule reconcile <id> --clear` records launch-failed and frees the
119
224
  slot (or `remove --force` forgets the job).
@@ -132,13 +237,14 @@ or malformed definition is reported on that job and the rest of the tick
132
237
  continues.
133
238
 
134
239
  `disable` never stops anything. `update` never touches a running instance,
135
- and while a job holds a slot or has an unresolved attempt what its run is
136
- tracked or reconciled by (kind, agent, agentsRoot, repo, purpose, home, cwd,
137
- argv) cannot change; cron, tz, task, message, runtime, model and enabled
138
- can. A cold wake persists its slot before the session start runs and keeps
139
- it on any start exception, whatever its code (the kernel can refuse while
140
- recording, after the session exists); the next observation releases it once
141
- the runtime is proven stopped or absent, one tick at worst.
240
+ and while a job holds a slot or has an unresolved attempt its complete
241
+ execution identity (including a versioned capsule), kind and target cannot
242
+ change; cron, tz and enabled can. Legacy definitions retain their narrower
243
+ compatibility behavior until migrated. A cold wake persists its slot before
244
+ the session start runs and keeps it on any start exception, whatever its code
245
+ (the kernel can refuse while recording, after the session exists); the next
246
+ observation releases it once the runtime is proven stopped or absent, one tick
247
+ at worst.
142
248
  `remove` refuses while the job's instance is still tracked (`--force`
143
249
  forgets the job without stopping anything). Retiring an instance removes the
144
250
  wake jobs bound to its home; a wake whose home is gone otherwise stays
@@ -150,7 +256,13 @@ listed with its skipped reason.
150
256
  saves a wake job `wake-<instance>` bound to the new home after the spawn
151
257
  succeeded. If the spawn succeeds but the save fails, the spawn result still
152
258
  carries the full instance receipt, plus `wakeScheduleError` and a warning;
153
- the instance is neither hidden nor spawned again.
259
+ the instance is neither hidden nor spawned again. When the spawning consumer
260
+ supplies both the returned `executionBinding` and `responsibleHuman`,
261
+ `saveWakeForHome` creates a version-2 captured wake from the matching binding in
262
+ the new home. Supplying only one, or a result binding that differs from the
263
+ home, refuses. The current parent-owned spawn caller still needs to pass these
264
+ fields when its captured lifecycle path lands; omission retains explicit legacy
265
+ behavior rather than inventing a binding.
154
266
 
155
267
  ## OKF v2 source jobs
156
268
 
@@ -0,0 +1,82 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "$id": "https://oats.dev/schemas/soul-v1.json",
4
+ "title": "Portable soul declaration v1",
5
+ "description": "Authored shape only. The shared source codec, provider codec and preparation transaction enforce source semantics, containment, requirements and readiness.",
6
+ "type": "object",
7
+ "required": ["schemaVersion", "name"],
8
+ "additionalProperties": false,
9
+ "properties": {
10
+ "schemaVersion": { "const": 1 },
11
+ "name": { "type": "string", "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$" },
12
+ "description": { "type": "string" },
13
+ "requires": { "$ref": "#/$defs/requirements" },
14
+ "defaults": { "$ref": "#/$defs/defaults" },
15
+ "knowledge": {
16
+ "type": "object",
17
+ "required": ["contract", "version", "payload"],
18
+ "additionalProperties": false,
19
+ "properties": {
20
+ "contract": { "type": "string", "pattern": "^[a-zA-Z0-9][a-zA-Z0-9._-]*$" },
21
+ "version": { "type": "integer", "minimum": 1, "maximum": 9007199254740991 },
22
+ "payload": {}
23
+ }
24
+ },
25
+ "teams": {
26
+ "type": "array", "uniqueItems": true,
27
+ "items": { "type": "string", "pattern": "^[a-zA-Z0-9][a-zA-Z0-9._-]*$" }
28
+ },
29
+ "resources": {
30
+ "type": "array", "uniqueItems": true,
31
+ "items": { "type": "string", "pattern": "^(?:\\.|(?![A-Za-z]:)(?!.*(?:^|/)\\.{1,2}(?:/|$))[^/\\\\\u0000]+(?:/[^/\\\\\u0000]+)*)$" }
32
+ },
33
+ "work": { "enum": ["worktree", "checkout", "attached", "workspace", "directory"] },
34
+ "runtime": { "enum": ["pi", "claude", "codex"] },
35
+ "model": { "type": "string", "minLength": 1 },
36
+ "launch-config": { "type": "string", "pattern": "^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$" },
37
+ "backend": { "enum": ["tmux", "herdr"] },
38
+ "yolo": { "type": "boolean" }
39
+ },
40
+ "$defs": {
41
+ "source": { "type": "string", "pattern": "^(git|repo|path):.+$" },
42
+ "capability": { "type": "string", "pattern": "^[a-z0-9][a-z0-9._-]*$" },
43
+ "selection": {
44
+ "type": "object", "required": ["source"], "additionalProperties": false,
45
+ "properties": { "source": { "$ref": "#/$defs/source" }, "settings": { "type": "object" } }
46
+ },
47
+ "provider": {
48
+ "type": "object", "required": ["capability", "source"], "additionalProperties": false,
49
+ "properties": {
50
+ "capability": { "$ref": "#/$defs/capability" },
51
+ "source": { "$ref": "#/$defs/source" },
52
+ "settings": { "type": "object" }
53
+ }
54
+ },
55
+ "requiredProvider": { "anyOf": [{ "const": "any" }, { "$ref": "#/$defs/provider" }] },
56
+ "defaultProvider": { "anyOf": [{ "const": "none" }, { "$ref": "#/$defs/provider" }] },
57
+ "requirements": {
58
+ "type": "object", "additionalProperties": false,
59
+ "properties": {
60
+ "capabilities": {
61
+ "type": "object", "additionalProperties": false,
62
+ "patternProperties": { "^[a-z0-9][a-z0-9._-]*$": { "$ref": "#/$defs/selection" } }
63
+ },
64
+ "knowledge": { "$ref": "#/$defs/requiredProvider" },
65
+ "messaging": { "$ref": "#/$defs/requiredProvider" },
66
+ "tasks": { "$ref": "#/$defs/requiredProvider" }
67
+ }
68
+ },
69
+ "defaults": {
70
+ "type": "object", "additionalProperties": false,
71
+ "properties": {
72
+ "capabilities": {
73
+ "type": "object", "additionalProperties": false,
74
+ "patternProperties": { "^[a-z0-9][a-z0-9._-]*$": { "anyOf": [{ "$ref": "#/$defs/selection" }, { "const": false }] } }
75
+ },
76
+ "knowledge": { "$ref": "#/$defs/defaultProvider" },
77
+ "messaging": { "$ref": "#/$defs/defaultProvider" },
78
+ "tasks": { "$ref": "#/$defs/defaultProvider" }
79
+ }
80
+ }
81
+ }
82
+ }
@@ -1,8 +1,19 @@
1
1
  # Souls and instances
2
2
 
3
- Souls and instances are the two layers the OATS kernel owns. A soul is the
4
- expert. An instance is a named incarnation of that expert, with its own ID,
5
- home, worktree, and lifecycle. It is not the same thing as one chat session.
3
+ Souls and instances are the two layers the OATS kernel owns. A soul defines a
4
+ reusable specialisation. An instance is a named working incarnation, with its own
5
+ ID, home, work view and lifecycle—not necessarily one task or chat session.
6
+
7
+ An instance may be ephemeral, such as a developer or reviewer doing bounded work,
8
+ or long-running, carrying planning, investigation and domain understanding across
9
+ many tasks. Lifetime does not itself change the soul's identity. See the
10
+ [canonical knowledge and specialisation model](knowledge-theory.md) for how skills,
11
+ shared knowledge, working context and state differ.
12
+
13
+ This operational guide includes the configuration-based soul and lifecycle forms.
14
+ Portable source definitions and captured lifecycle have their own versioned scope;
15
+ see the [0.24 release notes](release-notes/v0.24.0.md) rather than assuming every
16
+ legacy example below applies to a captured instance.
6
17
 
7
18
  ## Soul anatomy
8
19
 
@@ -45,10 +56,12 @@ runtime-specific guidance, while keeping `AGENTS.md` canonical.
45
56
 
46
57
  ## Instance anatomy
47
58
 
48
- An instance is transient, but it is not a single chat session. It is the
49
- identity of one instantiated soul while that work is alive. Several sessions,
50
- compactions, restarts, or model switches can happen inside the same instance
51
- before it is retired.
59
+ An instance has a lifecycle, but need not be short-lived. It is the identity of
60
+ one instantiated soul while its assignment is alive. Supported session continuations,
61
+ compactions and restarts can preserve that continuity. Model or harness changes must
62
+ follow the selected execution profile; they are not permission to reinterpret a
63
+ captured recipe. Retirement should account for valuable context and unfinished work,
64
+ not assume an experienced instance is cheap to replace.
52
65
 
53
66
  An instance has a home directory, a task, and a worktree when the work mode
54
67
  needs one. Its runtime setup is composed from the canonical soul plus