@awebai/oats 0.24.7 → 0.24.9
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.
- package/bin/oats.mjs +233 -20
- package/capabilities/oats-okf/bin/oats-okf.mjs +3 -3
- package/capabilities/oats-okf/lib/binding-wire.mjs +35 -8
- package/capabilities/oats-okf/lib/config.mjs +1 -0
- package/capabilities/oats-okf/lib/sources.mjs +27 -2
- package/capabilities/oats-okf/lib/worker.mjs +5 -2
- package/capabilities/oats-okf/oats.json +29 -6
- package/docs/design/2026-09-20-redesign-program-board.md +2 -2
- package/docs/design/2026-09-22-desktop-parity-seams.md +4 -4
- package/docs/desktop-cli-api.md +392 -3
- package/docs/release-notes/v0.24.7.md +2 -2
- package/docs/release-notes/v0.24.8.md +107 -0
- package/docs/release-notes/v0.24.9.md +67 -0
- package/docs/workspace-adoption.md +4 -1
- package/docs/workspaces.md +1 -1
- package/lib/core.mjs +263 -21
- package/lib/instance-events.mjs +76 -0
- package/lib/instance-git.mjs +21 -0
- package/lib/instance-lifecycle.mjs +181 -0
- package/lib/portable-soul.mjs +5 -1
- package/lib/process-group.mjs +12 -0
- package/lib/readiness.mjs +225 -0
- package/lib/schedule.mjs +22 -3
- package/package-catalog.json +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# OATS v0.24.8 — lifecycle plans, readiness, spawn preview, instance events, and guarded Stop/Remove in the Desktop
|
|
2
|
+
|
|
3
|
+
Kernel/Pi/Desktop **0.24.8**. Tag `v0.24.8` → the commit carrying these notes
|
|
4
|
+
(the last code change is `508fda04`, PR #69). The npm tarball's `gitHead` is
|
|
5
|
+
the tagged commit; the version-bump commit lands after the tag. All new
|
|
6
|
+
contracts are **advertised**: consumers gate on `oats version --json`
|
|
7
|
+
`features[]` names and the API integers below — never on the version number,
|
|
8
|
+
never by optimistic invocation.
|
|
9
|
+
|
|
10
|
+
## Kernel — the remaining Desktop-parity seams (K3, K5, K6, K7, K8)
|
|
11
|
+
|
|
12
|
+
- **Lifecycle plans** (K3, `lifecycleApi: 1`, feature `lifecycle-plans`):
|
|
13
|
+
`oats instance stop <i> --plan|--apply` and `oats retire <i> --plan`, then the
|
|
14
|
+
**guarded apply** `oats retire <i> --plan-revision <rev> --idempotency-key <key>
|
|
15
|
+
[--discard-worktree] [--delete-branch]`. A plan states producer facts (ordered
|
|
16
|
+
targets deepest-first, session/work facts, recorded children, `midTask:
|
|
17
|
+
"unknown"` never inferred) under a 24-hex `planRevision`; apply re-reads and
|
|
18
|
+
refuses `E_PLAN_STALE` (fresh plan attached) when facts moved. Keys replay
|
|
19
|
+
their own receipt instead of acting twice — stop receipts are stored **per
|
|
20
|
+
key**, retire receipts survive the home's removal.
|
|
21
|
+
- **Retention by default** (feature `retire-retention`): a plain retire
|
|
22
|
+
re-homes the worktree to `<workspace>/.agents/worktrees/<repo>/<branch>`
|
|
23
|
+
instead of deleting it; `--discard-worktree` removes; `--delete-branch`
|
|
24
|
+
deletes the branch the tree is **verified** to be on and implies discard.
|
|
25
|
+
Receipt `retention {worktree: retained|removed|absent, movedTo, branch,
|
|
26
|
+
recordedBranch, branchDeleted?, branchDeletionSkipped?}`; a failed move is
|
|
27
|
+
`E_WORK_PRESERVATION_FAILED` with the home kept.
|
|
28
|
+
- **Children first, kernel-owned.** A guarded retire stops the plan's recorded
|
|
29
|
+
children (bounded SIGTERM, never escalated) and retains them; a child still
|
|
30
|
+
running refuses the whole retirement — `E_CHILDREN_RUNNING`, nothing retired.
|
|
31
|
+
- **Branch deletion is bound to the confirmed branch**: re-verified at deletion,
|
|
32
|
+
after hooks (which may mutate the tree); a mismatch deletes nothing and
|
|
33
|
+
reports `branchDeletionSkipped {expected, actual, reason}`.
|
|
34
|
+
- **Ambiguous parentage is reported, never acted on**: parent edges are bare
|
|
35
|
+
names; one that resolves to several homes appears under `ambiguous[]`
|
|
36
|
+
(`plan.ambiguous` on stop, `plan.facts.ambiguous` on retire).
|
|
37
|
+
- A pre-plan CLI does not understand `--plan` and would retire on it; that is
|
|
38
|
+
exactly why the feature is advertised — consumers must gate.
|
|
39
|
+
- **Readiness** (K5, `readinessApi: 1`): `oats readiness [--soul] [--home]
|
|
40
|
+
[--verify-signatures] [--policy] --json` — the quartet
|
|
41
|
+
installed · trusted · configured · enrolled, each `pass|fail|unknown|not-applicable`
|
|
42
|
+
with items `{subject, required, reason, producer, evidence, remedy}`;
|
|
43
|
+
`summary.ready` is never vacuous. Signatures are `unknown` unless
|
|
44
|
+
`--verify-signatures` (an explicit one-commit fetch; `verified|unsigned|invalid`
|
|
45
|
+
with the signer named). Enrolled = workspace-member admission.
|
|
46
|
+
- **Enforced child policy** (K5): soul `children: {spawn: bool}`, spawn
|
|
47
|
+
`--allow-child-spawns|--no-child-spawns`, recorded as `instance.json`
|
|
48
|
+
`policy.childSpawns {allowed, origin}`; a spawn with `--parent` under an off
|
|
49
|
+
policy refuses `E_CHILD_SPAWNS_DISABLED`. `inspect --json` souls carry
|
|
50
|
+
`declarations.children`; capability rows carry `commit`.
|
|
51
|
+
- **Spawn preview** (K6, `spawnPreviewApi: 1`): `oats spawn … --preview --json`
|
|
52
|
+
states the decision — instance name, home, worktree, branch, base `{ref, oid}`,
|
|
53
|
+
runtime/model/launch config, work mode, composition sources, policy — without
|
|
54
|
+
creating anything. `--base <ref>` picks the base; `@native-default` names the
|
|
55
|
+
runtime's own default explicitly.
|
|
56
|
+
- **Instance events** (K7, `eventsApi: 1`, feature `instance-events`):
|
|
57
|
+
`oats instance events <i> [--limit] [--since] --json` — typed, producer-
|
|
58
|
+
attributed lifecycle events (spawned, launched, restarted, stopped,
|
|
59
|
+
stop-refused, retire-planned, retired, worktree-retained, branch-deleted,
|
|
60
|
+
child-spawn-refused, recomposed) from the home's log and the workspace's
|
|
61
|
+
retained copy; truncation and unreadable lines are visible, never smoothed.
|
|
62
|
+
- **Schedule run history** (K8, `scheduleApi: 2`, feature `schedule-history`):
|
|
63
|
+
schedules report `recentRuns` — settled runs only, producer order, ≤ 50.
|
|
64
|
+
- **Instruction refresh** (feature `session-recompose`): `oats session recompose
|
|
65
|
+
--home <abs> [--dry-run] --json` recomposes a **live** home's `AGENTS.md`
|
|
66
|
+
from its current soul with the same composer spawn used; previous text is
|
|
67
|
+
retained beside it, `instance.json` and a `recomposed` event record it,
|
|
68
|
+
nothing is restarted. An operator action for when a role changes and a
|
|
69
|
+
respawn is not possible or wanted.
|
|
70
|
+
- Remote workspaces: `oats instance git|diff` reach a remote instance through
|
|
71
|
+
the negotiated route (K1 remote), refusing rather than guessing where no
|
|
72
|
+
route exists.
|
|
73
|
+
|
|
74
|
+
## Desktop (parity slices 2b and 2c)
|
|
75
|
+
|
|
76
|
+
- **2b — Connections.** Settings → Connections with an inline "Connect
|
|
77
|
+
GitHub" (device flow through `gh`, credential custody stays with `gh`; the
|
|
78
|
+
auth pane is a closed key set with redaction). The Git & GitHub panel gains an
|
|
79
|
+
observation-bound PR card: informational, correlated to the exact K1
|
|
80
|
+
revision/branch/remote, never authority. Forge connections are an **ADE
|
|
81
|
+
integration**, not a capability.
|
|
82
|
+
- **2c — Stop and Remove.** The instance menu offers *Stop…* and *Remove
|
|
83
|
+
instance…*; both open a plan-backed confirmation showing the kernel's exact
|
|
84
|
+
targets, skipped/ambiguous children, session and work facts, the real branch
|
|
85
|
+
(recorded-branch drift noted separately) and retained-by-default choices.
|
|
86
|
+
One guarded local route; the plan is read from the CLI, each confirmation
|
|
87
|
+
gets an opaque reference, the idempotency key is minted on the first
|
|
88
|
+
confirmation and kept for that intent's retries, one apply at a time; lost
|
|
89
|
+
responses are shown as **unknown outcome**, never "no effect". Stale plans
|
|
90
|
+
require a new confirmation; a refused child stop names the child. The old
|
|
91
|
+
unguarded retire route now answers `E_PLAN_REQUIRED`.
|
|
92
|
+
- Everything above is **unavailable** (not hidden, not guessed) when the
|
|
93
|
+
installed CLI does not advertise the corresponding feature.
|
|
94
|
+
|
|
95
|
+
## Also
|
|
96
|
+
|
|
97
|
+
- Lessons recorded: consumers gate on advertised features, never on
|
|
98
|
+
optimistic invocation; a declaration that suppresses a default must be
|
|
99
|
+
enforced; read-only Git observation is a security boundary.
|
|
100
|
+
- Verification budget: one full gate per change is PR CI; locally only the
|
|
101
|
+
affected suites. Desktop-only changes run the Desktop suites plus the
|
|
102
|
+
focused suite.
|
|
103
|
+
|
|
104
|
+
## Upgrade
|
|
105
|
+
|
|
106
|
+
`npm i -g @awebai/oats@0.24.8`, then `oats doctor`. Desktops pinned to an
|
|
107
|
+
older CLI keep working; new controls appear as the CLI's advertised features do.
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# OATS v0.24.9 — readiness pins, side-effect-free spawn preview (API 2), process-group safety, Desktop Readiness view
|
|
2
|
+
|
|
3
|
+
Kernel/Pi/Desktop **0.24.9**. Tag `v0.24.9` → the commit carrying these notes;
|
|
4
|
+
the version-bump commit lands after the tag. Consumers gate on `oats version
|
|
5
|
+
--json` `features[]` names and API integers — never on the version.
|
|
6
|
+
|
|
7
|
+
## Kernel
|
|
8
|
+
|
|
9
|
+
- **Spawn preview API 2** (feature `spawn-preview-2`, `spawnPreviewApi: 2`).
|
|
10
|
+
API 1 previews **wrote before they returned** — a refused child spawn appended
|
|
11
|
+
an event to the parent, a Herdr backend could be started, an unknown soul
|
|
12
|
+
could be imported from an importable def — and nothing bound a later spawn to
|
|
13
|
+
the previewed decision. API 2: a preview touches nothing, success or refusal
|
|
14
|
+
(proven by a byte-identical deployment tree); `spawn --agents-root <abs>`
|
|
15
|
+
binds the exact root with no fallback and the preview echoes `subject` as
|
|
16
|
+
given; `decision {instance, home, branch, base, revision}` + `spawn
|
|
17
|
+
--expect-decision <rev>` refuses **`E_DECISION_STALE`** with the fresh
|
|
18
|
+
decision on any drift (no auto-suffix, no silent re-base, nothing created);
|
|
19
|
+
every native probe shares one bounded preflight budget and is process-group
|
|
20
|
+
killed on timeout (`preflight {status, budgetMs, elapsedMs}`). **Gate on API
|
|
21
|
+
2 — API 1 is the pre-fix marker.**
|
|
22
|
+
- **Readiness pins** (`oats readiness`): `configured` is *effective* activation
|
|
23
|
+
(a capability declared for the soul but disabled is a fail that says so);
|
|
24
|
+
data-only capabilities (skills/inject, no commands/hooks/env) report trust
|
|
25
|
+
**not-applicable** — the inspect row carries `health.executableSurface`;
|
|
26
|
+
every item is typed (`capability {id, level, scope}`, `origin {kind,
|
|
27
|
+
target}`) and `summary.byCapability[]` regroups the same items with
|
|
28
|
+
`ownReady` vs `ready` (never ready under a `summary.subjectBlockers[]` item
|
|
29
|
+
such as unknown membership); `subject.selector` echoes the arguments as given,
|
|
30
|
+
byte-exact; an unreadable member document is `unknown`, not not-applicable;
|
|
31
|
+
`readiness --home <captured>` refuses `E_UNSUPPORTED_MODE`; `--agents-root`
|
|
32
|
+
documented. **Signature verification** (feature `readiness-verify`) is
|
|
33
|
+
bounded custody: one budget per read, process-group kill, cleanup on
|
|
34
|
+
SIGINT/SIGTERM/SIGHUP, `GIT_CONFIG_GLOBAL=/dev/null`, https/ssh only, a closed
|
|
35
|
+
`signature.failure.code` — never stderr.
|
|
36
|
+
- **Process-group safety (high).** Bounded-custody code killed a child's
|
|
37
|
+
process group on timeout with `process.kill(-child.pid)`; a **failed** spawn
|
|
38
|
+
(binary missing → `ENOENT`) reports `pid: 0`, and `kill(-0)` signals the
|
|
39
|
+
caller's own process group — `oats readiness --verify-signatures` without
|
|
40
|
+
`git` would have SIGKILLed the operator's shell/tmux/Desktop backend. One
|
|
41
|
+
guarded helper now refuses non-positive PIDs at every kill site.
|
|
42
|
+
- **OKF 2.1.3** mirrored and pinned in the official catalog: per-cause `check`
|
|
43
|
+
reasons, a named remedy when a soul has no `okf.json` (was a raw ENOENT from
|
|
44
|
+
the required spawn hook), retired drained sources switch their `okf-<id>` job
|
|
45
|
+
off.
|
|
46
|
+
|
|
47
|
+
## Desktop
|
|
48
|
+
|
|
49
|
+
- **Readiness** (frame 09/04): Workspace header entry and first-run
|
|
50
|
+
invitation; the quartet from `oats readiness` with items, remedies (display
|
|
51
|
+
only), *View policy*, *Skip for now* (presentation only). Verify signatures
|
|
52
|
+
and Enrol are shown unavailable with the exact reason until their contracts
|
|
53
|
+
land. Effective-readiness section per scope on the Capabilities view.
|
|
54
|
+
- **Normalized route classification**: one classifier decides every specialized
|
|
55
|
+
IPC route from the normalized pathname — dot-segment, percent-encoded,
|
|
56
|
+
backslash, tab and CRLF aliases can no longer skip a route's frame/epoch
|
|
57
|
+
guard.
|
|
58
|
+
- Spawn modal: kernel **preview** (API 2) for the instance name, home, worktree,
|
|
59
|
+
branch and resolved base — *Suggest* asks the kernel for its default
|
|
60
|
+
candidate; preview-only choices block legacy submission rather than being
|
|
61
|
+
dropped. Apply companion, attach-knowledge, auto-PR and branch enumeration are
|
|
62
|
+
named follow-ups, not parity-done.
|
|
63
|
+
|
|
64
|
+
## Upgrade
|
|
65
|
+
|
|
66
|
+
`npm i -g @awebai/oats@0.24.9`, then `oats doctor`. Desktops on an older CLI
|
|
67
|
+
show the new controls as unavailable until the CLI advertises them.
|
|
@@ -107,7 +107,10 @@ onboarding and legacy roster/knowledge cutover remain separate.
|
|
|
107
107
|
production store or grants are supplied. An acceptance fixture is parent-owned
|
|
108
108
|
and cannot be counted as production knowledge adoption.
|
|
109
109
|
- Current authored expert editions require knowledge **oats.okf@2.1.2** and
|
|
110
|
-
messaging **oats.aweb@1.11.2** (both OATS >=0.24.4), not optional defaults.
|
|
110
|
+
messaging **oats.aweb@1.11.2** (both OATS >=0.24.4), not optional defaults.
|
|
111
|
+
The official catalog now offers **oats.okf 2.1.3** (per-cause `check` reasons,
|
|
112
|
+
a named remedy for a soul without `okf.json`, retired sources switch their
|
|
113
|
+
job off); editions move to it when their owner re-reviews them. These published revisions
|
|
111
114
|
are **not proof that their combined bindings/runtime profile is ready**. The provider
|
|
112
115
|
owner supplies that evidence and any subsequently reviewed compatible revision.
|
|
113
116
|
Do not replace either requirement with none or erase a read edge to launch.
|
package/docs/workspaces.md
CHANGED
|
@@ -71,7 +71,7 @@ name: domain-expert
|
|
|
71
71
|
requires:
|
|
72
72
|
knowledge:
|
|
73
73
|
capability: oats.okf
|
|
74
|
-
source: git:github.com/awebai/oats-okf@v2.1.
|
|
74
|
+
source: git:github.com/awebai/oats-okf@v2.1.3#oats-package
|
|
75
75
|
```
|
|
76
76
|
|
|
77
77
|
This illustrates software selection, not complete OKF provisioning: the chosen capability also needs its own valid knowledge declaration, bindings and accepted base.
|