@awebai/oats 0.25.3 → 0.25.4

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.
@@ -2,7 +2,7 @@
2
2
 
3
3
  **Purpose:** the one accurate view of every work stream in the redesign, what is on main, what is in flight, who owns it, and what blocks it. Lead: `oats-expert` (redesign lead). Updated whenever anything merges, is returned, or reality changes. Older per-lane boards are superseded by this file.
4
4
 
5
- **Last update:** 2026-09-23 20:00Z · **0.25.0 + 0.25.1 + 0.25.2 PUBLISHED** (workspace model A–C + team-review fixes + operator-rebuild round) · Phase D plan next · **Desktop engineer paused by the human** (10B-0 uncommitted foundation preserved; resume is the human's call; 0.24.14 to be cut from a maintenance branch off `e5cdaf95` when its PR lands) · parity pipeline ⏸.
5
+ **Last update:** 2026-09-23 20:00Z · **0.25.0–0.25.3 PUBLISHED** (workspace model A–C; team-review fixes; operator-rebuild round; OATS_SOUL_ID) · **OKF 2.1.4 pending human GO** (owner pin by id, clone/timeout, retire-schedule seam; Antares writes the PRs) · Phase D plan next · **Desktop engineer paused by the human** (10B-0 uncommitted foundation preserved; resume is the human's call; 0.24.14 to be cut from a maintenance branch off `e5cdaf95` when its PR lands) · parity pipeline ⏸.
6
6
 
7
7
  Legend: ✅ on main/published · 🔄 in flight (PR/branch) · 🟡 preserved, not adopted · ⬜ not started · ⛔ blocked
8
8
 
@@ -337,6 +337,13 @@ type a digest. An `--approve` that names an id or version the resolution does
337
337
  not contain is an error, not a silent skip; an entry the flags do not cover
338
338
  stays unapproved (exit `2`, as above).
339
339
 
340
+ `<version>` is the value `sync --json` reports as `approvalNeeded[].version`,
341
+ which is what the lock records as the package's `version`. For a **catalog**
342
+ package that is the published version (`oats.okf@2.1.4`). For a **git** source
343
+ pinned by commit (`git:github.com/awebai/oats-okf@<oid>`) it is the **full
344
+ commit OID**, not the `git:` reference and not a tag name — copy it from the
345
+ `approvalNeeded` line rather than from your workspace file.
346
+
340
347
  ## 7b. OKF 2: start a FRESH `state-dir` — do not re-point the old one
341
348
 
342
349
  OKF 2 pins each knowledge **owner** to a soul by path: at source registration
@@ -0,0 +1,21 @@
1
+ # OATS 0.25.4
2
+
3
+ Patch release: one kernel fix found by an operator rehearsal on 0.25.3.
4
+
5
+ ## Fixed
6
+
7
+ - **Quarantine retry never re-ran the owed retire hook on a workspace-mode
8
+ home.** When a required spawn hook fails and its compensation is incomplete,
9
+ the kernel retains the home with a cleanup descriptor
10
+ (`.oats-rollback-incomplete.json`). Module materialization had already
11
+ written a pre-hook `instance.json` stub (`{ modules, providers,
12
+ resolutionRevision }`), and `oats retire` trusted that stub over the
13
+ descriptor — so `meta.repo` was undefined, the retry reported *"retire hook
14
+ <cap>: did not run on this retry"* and *"cleanup descriptor lost its context
15
+ repo"* on every attempt, and only `--force` could remove the home (leaving
16
+ the provider's external state to be cleaned by hand). The retry now reads
17
+ the cleanup descriptor whenever the live record is not a complete spawn
18
+ record; the owed hook runs, the home stays while it fails, and is removed
19
+ once it succeeds. Regression test in `test/spawn-workspace.test.mjs`.
20
+
21
+ No contract changes. `oats version --json` is unchanged apart from the version.
package/lib/core.mjs CHANGED
@@ -9301,7 +9301,17 @@ export function retireInstance(root, name, o = {}) {
9301
9301
  } catch { markerUnusable = true; }
9302
9302
  }
9303
9303
  const liveMeta = existsSync(metaPath) ? JSON.parse(readFileSync(metaPath, "utf8")) : undefined;
9304
- const meta = liveMeta || quarantine?.cleanup || {};
9304
+ // A quarantined home may carry an instance.json that is NOT the spawn record:
9305
+ // module materialization writes a pre-hook stub ({ modules, providers,
9306
+ // resolutionRevision }) before the spawn hooks run, and a required-hook
9307
+ // failure retains the home with that stub in place. Trusting it over the
9308
+ // cleanup descriptor left meta.repo undefined, so the retry never re-ran the
9309
+ // owed retire hook and reported "cleanup descriptor lost its context repo"
9310
+ // on every attempt — only --force could clear the home (found by an operator
9311
+ // rehearsal on 0.25.3). The descriptor is written FOR this retry; a live
9312
+ // record only wins when it is a complete spawn record (repo + work present).
9313
+ const liveIsSpawnRecord = !!liveMeta && nonEmptyString(liveMeta.repo) && WORK_MODES.includes(liveMeta.work);
9314
+ const meta = liveIsSpawnRecord || !quarantine ? (liveMeta || quarantine?.cleanup || {}) : { ...liveMeta, ...quarantine.cleanup };
9305
9315
  // Compensation metadata is the SPAWN's, from whichever record survived — never
9306
9316
  // a failed retry's report, which says nothing about what still needs undoing.
9307
9317
  if (!liveMeta?.capabilityMeta && quarantine?.cleanup?.capabilityMeta) meta.capabilityMeta = quarantine.cleanup.capabilityMeta;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@awebai/oats",
3
- "version": "0.25.3",
3
+ "version": "0.25.4",
4
4
  "description": "OATS (Open Agent Team Specification) — durable souls, disposable instances, targetable capability packages, and the runtime-neutral oats CLI/kernel.",
5
5
  "keywords": [
6
6
  "agents",