@awebai/oats 0.23.1 → 0.24.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 (159) hide show
  1. package/README.md +7 -4
  2. package/bin/oats-pi-sdk-host.mjs +17 -0
  3. package/bin/oats.mjs +442 -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 +101 -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/capability-manifest.schema.json +37 -66
  25. package/docs/captured-invocation-context.schema.json +7 -0
  26. package/docs/captured-resolution.schema.json +7 -0
  27. package/docs/design/2026-09-14-artifact-retention-contract.md +190 -0
  28. package/docs/design/2026-09-14-portable-souls-and-git-workspaces.md +708 -0
  29. package/docs/design/2026-09-14-portable-souls-contract-amendments.md +85 -0
  30. package/docs/design/2026-09-14-portable-souls-explainer.md +750 -0
  31. package/docs/design/2026-09-15-captured-dispatch.md +127 -0
  32. package/docs/design/2026-09-15-captured-resolution-records.md +143 -0
  33. package/docs/design/2026-09-15-package-preparation.md +100 -0
  34. package/docs/design/2026-09-15-portable-data-contract.md +121 -0
  35. package/docs/design/2026-09-15-portable-declarations.md +189 -0
  36. package/docs/design/2026-09-15-portable-souls-handoff.md +150 -0
  37. package/docs/design/2026-09-15-portable-souls-implementation.md +417 -0
  38. package/docs/design/2026-09-15-selection-lock-and-approval.md +122 -0
  39. package/docs/design/2026-09-15-source-observation.md +119 -0
  40. package/docs/design/2026-09-16-captured-admission.md +77 -0
  41. package/docs/design/2026-09-16-captured-helper-dispatch.md +105 -0
  42. package/docs/design/2026-09-16-captured-launch-inputs.md +42 -0
  43. package/docs/design/2026-09-16-command-profile-preparation.md +86 -0
  44. package/docs/design/2026-09-16-fresh-install-first-rollout.md +47 -0
  45. package/docs/design/2026-09-16-fresh-operator-walkthrough.md +277 -0
  46. package/docs/design/2026-09-16-knowledge-capability-contract.md +61 -0
  47. package/docs/design/2026-09-16-messaging-capability-contract.md +59 -0
  48. package/docs/design/2026-09-16-portable-migration-evidence.md +156 -0
  49. package/docs/design/2026-09-16-portable-onboarding.md +177 -0
  50. package/docs/design/2026-09-16-prepare-request-transport.md +26 -0
  51. package/docs/design/2026-09-16-provider-binding-codecs.md +98 -0
  52. package/docs/design/2026-09-16-provider-binding-wire.md +247 -0
  53. package/docs/design/2026-09-17-capability-helper-input-contract.md +95 -0
  54. package/docs/design/2026-09-17-captured-backend-parity.md +53 -0
  55. package/docs/design/2026-09-17-captured-native-start.md +58 -0
  56. package/docs/design/2026-09-17-portable-boundary-hookup.md +19 -0
  57. package/docs/design/2026-09-17-portable-boundary-resources.md +52 -0
  58. package/docs/design/2026-09-17-public-captured-start.md +108 -0
  59. package/docs/design/2026-09-17-public-prepare-request.md +90 -0
  60. package/docs/design/2026-09-18-captured-pi-host.md +205 -0
  61. package/docs/design/2026-09-18-first-cut-release-checklist.md +131 -0
  62. package/docs/design/2026-09-18-herdr-protocol-compatibility.md +60 -0
  63. package/docs/desktop-cli-api.md +5 -2
  64. package/docs/execution-capsule.schema.json +108 -0
  65. package/docs/execution-targets.md +20 -7
  66. package/docs/oats-lock-v3.schema.json +7 -0
  67. package/docs/oats-member.schema.json +38 -0
  68. package/docs/oats-workspace.schema.json +68 -0
  69. package/docs/portable.schema.json +2512 -0
  70. package/docs/provider-check-input.schema.json +7 -0
  71. package/docs/release-notes/v0.23.2.md +49 -0
  72. package/docs/release-notes/v0.24.0.md +104 -0
  73. package/docs/schedules.md +126 -14
  74. package/docs/soul.schema.json +82 -0
  75. package/injects/oats-portable.md +17 -0
  76. package/injects/portable-instance-boundary.md +39 -0
  77. package/injects/portable-work-directory.md +29 -0
  78. package/lib/artifact-approvals.mjs +120 -0
  79. package/lib/artifact-tree.mjs +141 -0
  80. package/lib/capability-artifacts.mjs +179 -0
  81. package/lib/capability-execution.mjs +15 -0
  82. package/lib/capability-inputs.mjs +39 -0
  83. package/lib/capability-provenance.mjs +231 -0
  84. package/lib/captured-action-shape.mjs +21 -0
  85. package/lib/captured-admission-shape.mjs +20 -0
  86. package/lib/captured-binding-file.mjs +36 -0
  87. package/lib/captured-dispatch.mjs +66 -0
  88. package/lib/captured-instance-index.mjs +277 -0
  89. package/lib/captured-invocation-context.mjs +130 -0
  90. package/lib/captured-launch-request.mjs +46 -0
  91. package/lib/captured-operation-process.mjs +15 -0
  92. package/lib/captured-pi-custody.mjs +29 -0
  93. package/lib/captured-pi-host.mjs +167 -0
  94. package/lib/captured-pi-outcome.mjs +172 -0
  95. package/lib/captured-resolutions.mjs +275 -0
  96. package/lib/captured-scaffold.mjs +87 -0
  97. package/lib/captured-selector.mjs +28 -0
  98. package/lib/captured-session-backend.mjs +52 -0
  99. package/lib/captured-source-receipt-file.mjs +72 -0
  100. package/lib/config-data.mjs +104 -0
  101. package/lib/core.mjs +918 -562
  102. package/lib/errors.mjs +7 -0
  103. package/lib/helper-injection-policy.mjs +98 -0
  104. package/lib/herdr.mjs +18 -7
  105. package/lib/instruction-composition.mjs +31 -0
  106. package/lib/legacy-lock-codec.mjs +106 -0
  107. package/lib/manifest-settings.mjs +84 -0
  108. package/lib/package-closure.mjs +48 -0
  109. package/lib/package-materialization.mjs +83 -0
  110. package/lib/pi-sdk-host.mjs +229 -0
  111. package/lib/portable-artifacts.mjs +115 -0
  112. package/lib/portable-choices.mjs +82 -0
  113. package/lib/portable-composition.mjs +136 -0
  114. package/lib/portable-digest.mjs +105 -0
  115. package/lib/portable-files.mjs +26 -0
  116. package/lib/portable-identity.mjs +40 -0
  117. package/lib/portable-lock.mjs +117 -0
  118. package/lib/portable-migration-artifacts.mjs +135 -0
  119. package/lib/portable-migration-evidence.mjs +305 -0
  120. package/lib/portable-migration-store.mjs +199 -0
  121. package/lib/portable-migration.mjs +104 -0
  122. package/lib/portable-onboarding-acceptance.mjs +66 -0
  123. package/lib/portable-onboarding-request.mjs +49 -0
  124. package/lib/portable-onboarding.mjs +230 -0
  125. package/lib/portable-package-preparation.mjs +188 -0
  126. package/lib/portable-policy.mjs +44 -0
  127. package/lib/portable-shape.mjs +35 -0
  128. package/lib/portable-soul.mjs +38 -0
  129. package/lib/portable-state.mjs +80 -0
  130. package/lib/portable-values.mjs +181 -0
  131. package/lib/prepare-composition.mjs +151 -0
  132. package/lib/prepared-bindings.mjs +78 -0
  133. package/lib/prepared-resources.mjs +127 -0
  134. package/lib/provider-binding-broker.mjs +59 -0
  135. package/lib/provider-binding-wire.mjs +110 -0
  136. package/lib/provider-binding.mjs +22 -0
  137. package/lib/repository-observation.mjs +226 -0
  138. package/lib/resolution-shape.mjs +393 -0
  139. package/lib/schedule-capsule.mjs +206 -0
  140. package/lib/schedule.mjs +259 -38
  141. package/lib/servers.mjs +15 -0
  142. package/lib/soul-constraints.mjs +40 -0
  143. package/lib/source-projection.mjs +84 -0
  144. package/lib/source-spec.mjs +189 -0
  145. package/lib/workspace-definition.mjs +126 -0
  146. package/lib/workspace-discovery.mjs +146 -0
  147. package/package-catalog.json +1 -1
  148. package/package.json +3 -2
  149. package/packages/record/lib/capture-cc.mjs +14 -6
  150. package/packages/record/lib/formats.mjs +14 -3
  151. package/packages/record/lib/native-history.mjs +277 -7
  152. package/packages/record/lib/session-snapshot.mjs +25 -5
  153. package/packages/record/lib/sessions-for-home.mjs +30 -13
  154. package/skills/oats/SKILL.md +12 -7
  155. package/skills/oats-config/SKILL.md +12 -9
  156. package/skills/oats-packages/SKILL.md +12 -8
  157. package/skills/oats-portable/SKILL.md +116 -0
  158. package/skills/oats-portable-artifacts/SKILL.md +63 -0
  159. package/skills/oats-portable-setup/SKILL.md +69 -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,49 @@
1
+ # OATS v0.23.2 — Desktop Workspace redesign
2
+
3
+ This release refreshes OATS Desktop around souls, instances and reported
4
+ capabilities, while keeping lifecycle operations behind the installed OATS CLI.
5
+ It builds on the released 0.23.1 kernel and knowledge contracts; it does not
6
+ implement the proposed Portable Souls architecture.
7
+
8
+ ## Workspace and visual polish
9
+
10
+ - A cleaner sidebar, aligned toolbar and soul cards, with a side inspector for
11
+ explicit Launch, Files and Schedule actions.
12
+ - Workspace sections for **Souls**, **Capabilities** and **Sources**. Capability
13
+ health, installation, trust and activation are reported facts; Sources shows
14
+ provenance, not a new remote discovery or repository-admission feature.
15
+ - **White** is the default theme, alongside explicit **Solarized** and **Dark**
16
+ choices. Existing valid theme preferences are retained.
17
+ - Orange accents distinct from errors, quieter split controls, roomier instance
18
+ selection, darker navigation and colored marks for reported runtimes.
19
+ - Stable muted soul marks. Optional local `soul.yaml` display metadata accepts
20
+ `color: sand`, `sage`, `slate`, `mauve`, `clay` or `olive`. Unknown values use a
21
+ deterministic identity-based fallback. Current remote CLI rosters do not report
22
+ this metadata; colors are decorative, never identity or status authority.
23
+
24
+ ## Working with instances and files
25
+
26
+ - Workspace switches retain session-local tabs, selected panels and split sizes.
27
+ - Closing a tab preserves its empty panel. Selecting that panel and reopening an
28
+ instance uses the selected destination; reusing an open terminal does not create
29
+ another attachment. Close split remains an explicit layout action.
30
+ - **File: open read-only…** / **Mod+O** opens a native file chooser for sanitized
31
+ Markdown, highlighted code or plain text, alongside ordinary workspace tabs.
32
+ Files are read-only with a 2 MiB limit; no absolute-path guessing, sibling-file
33
+ access, editing or save workflow is introduced.
34
+ - Soul Spawn no longer presents launch-configuration controls; the CLI's inherited
35
+ defaults remain authoritative. Quick Open inspects; Launch is always explicit.
36
+ - Improved picker/shortcut focus handoffs and stale-selection protection across
37
+ workspace changes, roster refreshes and delayed operations.
38
+
39
+ ## Compatibility and boundaries
40
+
41
+ Desktop supports the reviewed OATS 0.22.x and 0.23.x CLI contracts. Without a
42
+ compatible installation it remains observation-only, with persistent recovery
43
+ controls across Workspace sections. The root npm package still contains no
44
+ Electron dependencies; Desktop remains a private, separately packaged app.
45
+
46
+ New Knowledge/Tasks views, portable-soul membership/discovery and an agent-facing
47
+ file-open CLI command are not part of this release. Workspace layout memory is
48
+ session-local, not restart persistence. macOS assets retain the existing ad-hoc
49
+ signing model; this release does not introduce Developer ID notarization.
@@ -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.
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
+ }
@@ -0,0 +1,17 @@
1
+ ## You run on a captured OATS composition
2
+
3
+ You are an instance of a retained soul/helper composition selected by
4
+ `instance.json.executionBinding`. Managed instructions, skills, capabilities,
5
+ settings, provider bindings, and executable resources come from that exact
6
+ `deployment` + `resolution`; do not replace them with a current checkout,
7
+ configuration cascade, package lock, similarly named capability, or source path.
8
+
9
+ Load **oats-portable** before invoking or reasoning about captured OATS commands.
10
+ Load **oats-portable-setup** for fresh by-reference preparation and explicit
11
+ source/workspace/deployment/work/team choices. Load **oats-portable-artifacts**
12
+ for exact retained inspection and approval. Do not load the legacy **oats**,
13
+ **oats-config**, or **oats-packages** procedures to fill a captured input.
14
+
15
+ Captured start/restart/wake/retire, managed launch/runtime and non-directory work
16
+ are not yet public. If a command is unsupported or retained authority is missing,
17
+ stop and report it; never remove selectors or fall back to ambient configuration.
@@ -0,0 +1,39 @@
1
+ ## Captured instance: home, source and work
2
+
3
+ **Your instance home** is the specific OATS instance directory supplied as
4
+ `OATS_INSTANCE_HOME`, not your user home, source repository or work target.
5
+ `instance.json.executionBinding` names the explicit captured **deployment and
6
+ resolution**. Home-bound actions must also match this owned home's incarnation
7
+ and recorded custody. Do not invent, copy or rewrite those identifiers to make
8
+ another home or composition appear authorized.
9
+
10
+ - **Home holds composed instructions and instance state.** `AGENTS.md` is the
11
+ canonical composed instruction file; `CLAUDE.md -> AGENTS.md` is its relative
12
+ compatibility alias, not a second instruction source. Preserve the generated
13
+ instructions, aliases and metadata; do not hand-edit them to change authority.
14
+ Task material and provider-managed state belong where their owning contract
15
+ specifies. The selected capabilities define any knowledge or memory protocol.
16
+ - **`./soul` is a read-only retained source link, not your edit surface.** Reading
17
+ it must not depend on the publisher's current checkout. Never write through it
18
+ or modify retained artifacts. If a task authorizes source changes, use its
19
+ explicitly authorized tracked work surface and review path instead.
20
+ - **`./work` is the task's work surface.** The work-mode instructions determine
21
+ whether it is an owned directory or another permitted repository view. Make
22
+ task edits only on that authorized surface, not in deployment stores or a
23
+ convenient source checkout. Reading an external input is not permission to
24
+ modify it or its owner.
25
+
26
+ For supported captured commands, keep the explicit `--deployment` and
27
+ `--resolution` pair from the recorded binding; supply the exact owned home when
28
+ an action requires one. Running from home preserves the invocation's working
29
+ location, but **cwd and a recorded `repo` path never select configuration or
30
+ execution authority**. Source location, deployment, work target and team
31
+ membership are separate facts. Do not fill missing inputs from a config cascade,
32
+ a current lock, an alias match or another instance's environment.
33
+
34
+ Load **oats-portable** for the running kernel's supported captured operations.
35
+ A no-launch scaffold or `launchPending` receipt is not a running agent. Where
36
+ captured launch, start/restart/wake/retire or recovery is unsupported, stop and
37
+ report the limitation; do not strip selectors or use a legacy command as a
38
+ workaround. Preserve work, knowledge, native history, identities and outstanding
39
+ cleanup receipts. Missing authority is a hold, never permission to erase state.
@@ -0,0 +1,29 @@
1
+ ## Portable work mode: owned directory
2
+
3
+ Your `./work` is an **instance-owned execution directory**, not a Git worktree,
4
+ a checkout, or a link to the source, deployment or another instance. No Git
5
+ repository or branch is created by this mode. Do not initialize a fake repository
6
+ to satisfy a workflow; a containing Git repository does not grant authority over
7
+ its contents.
8
+
9
+ - Do task work inside `./work`. External inputs and delivery destinations require
10
+ explicit task/capability authorization. Neither a source link nor a recorded
11
+ `repo` or work-target path grants permission to edit that external directory.
12
+ - Execution uses the explicit captured deployment/resolution and, for home-bound
13
+ actions, the matching owned home/incarnation binding. Cwd does not resolve
14
+ configuration or select a provider; do not rebind from a current checkout,
15
+ config cascade, package lock or another instance.
16
+ - Preserve home/work separation and canonical instruction aliases:
17
+ `AGENTS.md` in home, `CLAUDE.md -> AGENTS.md`, and the generated skill aliases.
18
+ The home's `./soul` link and retained software are read-only, not edit surfaces.
19
+ - Deliver results using the task and selected capability's supported protocol.
20
+ This mode imposes no knowledge layout, harvester, storage backend or publication
21
+ policy. A recovery copy, if independently verified, is not publication or
22
+ accepted delivery.
23
+
24
+ Keep nonempty work and its custody evidence intact. This mode does not promise
25
+ implemented captured launch, start/restart/wake/retire or automatic recovery.
26
+ Before any supported, explicitly authorized teardown, require verified
27
+ preservation of outstanding work and receipts; if that capability is unavailable,
28
+ hold and report rather than deleting or moving the home/work yourself. A
29
+ `launchPending` result means runtime launch remains pending.