instar 1.3.590 → 1.3.591

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.
@@ -51,7 +51,14 @@ export interface OwnershipApplierDeps {
51
51
  /** The SAME durable store the SessionOwnershipRegistry reads — so a materialized
52
52
  * record is immediately visible to owner-resolution / routing. */
53
53
  store: SessionOwnershipStore;
54
- selfMachineId: string;
54
+ /**
55
+ * This machine's mesh id — used ONLY for the SELF-vs-peer log label, never for
56
+ * materialization (every placement is adopted regardless of owner). Accepts a
57
+ * **late-bound getter** so a caller can wire the applier before `_meshSelfId` is
58
+ * resolved without capturing a stale `null` (the boot-ordering hazard this fix closes);
59
+ * a plain string still works for callers/tests that already have the id.
60
+ */
61
+ selfMachineId: string | (() => string | null | undefined);
55
62
  /** Max placement entries to scan per tick (bounded cost). Default 1000. */
56
63
  scanLimit?: number;
57
64
  logger?: (msg: string) => void;
@@ -68,6 +75,8 @@ export declare class OwnershipApplier {
68
75
  constructor(deps: OwnershipApplierDeps);
69
76
  private now;
70
77
  private log;
78
+ /** Resolve the (possibly late-bound) self machine id at tick time, for the log label only. */
79
+ private resolveSelf;
71
80
  /**
72
81
  * One pass: adopt the highest-epoch placement per topic into the local store.
73
82
  * Returns counts for observability. Never throws — a read/parse failure degrades
@@ -1 +1 @@
1
- {"version":3,"file":"OwnershipApplier.d.ts","sourceRoot":"","sources":["../../src/core/OwnershipApplier.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAGH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AAE3E,uFAAuF;AACvF,MAAM,WAAW,eAAe;IAC9B,KAAK,CAAC,IAAI,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG;QAC9D,OAAO,EAAE,KAAK,CAAC;YAAE,KAAK,CAAC,EAAE,MAAM,CAAC;YAAC,OAAO,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YAAC,MAAM,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;KACrG,CAAC;CACH;AAED,MAAM,WAAW,oBAAoB;IACnC,yEAAyE;IACzE,MAAM,EAAE,eAAe,CAAC;IACxB;uEACmE;IACnE,KAAK,EAAE,qBAAqB,CAAC;IAC7B,aAAa,EAAE,MAAM,CAAC;IACtB,2EAA2E;IAC3E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,oBAAoB;IACnC,4DAA4D;IAC5D,QAAQ,EAAE,MAAM,CAAC;IACjB,iFAAiF;IACjF,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAuB;gBAE7B,IAAI,EAAE,oBAAoB;IAItC,OAAO,CAAC,GAAG;IAIX,OAAO,CAAC,GAAG;IAIX;;;;OAIG;IACH,IAAI,IAAI,oBAAoB;CAkD7B"}
1
+ {"version":3,"file":"OwnershipApplier.d.ts","sourceRoot":"","sources":["../../src/core/OwnershipApplier.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAGH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AAE3E,uFAAuF;AACvF,MAAM,WAAW,eAAe;IAC9B,KAAK,CAAC,IAAI,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG;QAC9D,OAAO,EAAE,KAAK,CAAC;YAAE,KAAK,CAAC,EAAE,MAAM,CAAC;YAAC,OAAO,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YAAC,MAAM,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;KACrG,CAAC;CACH;AAED,MAAM,WAAW,oBAAoB;IACnC,yEAAyE;IACzE,MAAM,EAAE,eAAe,CAAC;IACxB;uEACmE;IACnE,KAAK,EAAE,qBAAqB,CAAC;IAC7B;;;;;;OAMG;IACH,aAAa,EAAE,MAAM,GAAG,CAAC,MAAM,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;IAC1D,2EAA2E;IAC3E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,oBAAoB;IACnC,4DAA4D;IAC5D,QAAQ,EAAE,MAAM,CAAC;IACjB,iFAAiF;IACjF,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAuB;gBAE7B,IAAI,EAAE,oBAAoB;IAItC,OAAO,CAAC,GAAG;IAIX,OAAO,CAAC,GAAG;IAIX,8FAA8F;IAC9F,OAAO,CAAC,WAAW;IAKnB;;;;OAIG;IACH,IAAI,IAAI,oBAAoB;CAuD7B"}
@@ -40,6 +40,11 @@ export class OwnershipApplier {
40
40
  log(m) {
41
41
  this.d.logger?.(`[ownership-applier] ${m}`);
42
42
  }
43
+ /** Resolve the (possibly late-bound) self machine id at tick time, for the log label only. */
44
+ resolveSelf() {
45
+ const s = this.d.selfMachineId;
46
+ return typeof s === 'function' ? s() : s;
47
+ }
43
48
  /**
44
49
  * One pass: adopt the highest-epoch placement per topic into the local store.
45
50
  * Returns counts for observability. Never throws — a read/parse failure degrades
@@ -85,8 +90,13 @@ export class OwnershipApplier {
85
90
  const r = this.d.store.casWrite(rec);
86
91
  if (r.ok) {
87
92
  materialized++;
93
+ const self = this.resolveSelf();
88
94
  this.log(`materialized topic ${sessionKey} → owner ${best.owner} @epoch ${best.epoch}` +
89
- (best.owner === this.d.selfMachineId ? ' (SELF — this machine now serves it)' : ' (peer — route forwards there)'));
95
+ (self && best.owner === self
96
+ ? ' (SELF — this machine now serves it)'
97
+ : self
98
+ ? ' (peer — route forwards there)'
99
+ : ''));
90
100
  }
91
101
  }
92
102
  }
@@ -1 +1 @@
1
- {"version":3,"file":"OwnershipApplier.js","sourceRoot":"","sources":["../../src/core/OwnershipApplier.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"OwnershipApplier.js","sourceRoot":"","sources":["../../src/core/OwnershipApplier.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * ownershipApplierWiring — the testable construction factory for the transfer-fix §7.2
3
+ * OwnershipApplier (spec: docs/specs/ownership-applier-meshself-ordering-fix.md).
4
+ *
5
+ * Why this exists: the applier's construction CONDITION used to live inline in
6
+ * `server.ts` as `if (durableOwnershipStore && _meshSelfId)`. That guard read
7
+ * `_meshSelfId` ~650 lines BEFORE the boot sequence assigns it, so it was always
8
+ * `null` at the check → the applier was never constructed or ticked, on either machine,
9
+ * and a transferred seat never materialized on the destination. The inline condition was
10
+ * also untestable, which is precisely how the ordering bug shipped.
11
+ *
12
+ * The fix (Structure > Willpower): gate construction on the durable store ALONE — the
13
+ * genuinely relevant condition (applying replicated placements is a durable-store concern;
14
+ * the in-memory store has no cross-machine replication to apply) — and pass `selfMachineId`
15
+ * as a LATE-BOUND getter so the (label-only) self id resolves at tick time instead of being
16
+ * captured as a stale `null` at construction. This makes the wiring order-independent and
17
+ * unit-testable without booting the whole server.
18
+ */
19
+ import type { PlacementReader } from './OwnershipApplier.js';
20
+ import { OwnershipApplier } from './OwnershipApplier.js';
21
+ import type { SessionOwnershipStore } from './SessionOwnershipRegistry.js';
22
+ export interface OwnershipApplierWiringDeps {
23
+ /** The durable per-session store, or null when the in-memory store is in use. */
24
+ durableOwnershipStore: SessionOwnershipStore | null;
25
+ /** Reads replicated + own placement entries (CoherenceJournalReader). */
26
+ reader: PlacementReader;
27
+ /**
28
+ * Late-bound resolver for this machine's mesh id. May legitimately return null/undefined
29
+ * at construction time (before the boot sequence assigns it); it is used ONLY for the
30
+ * SELF-vs-peer log label, never for materialization.
31
+ */
32
+ getSelfMachineId: () => string | null | undefined;
33
+ scanLimit?: number;
34
+ logger?: (msg: string) => void;
35
+ now?: () => number;
36
+ }
37
+ /**
38
+ * Build the OwnershipApplier when (and only when) the durable ownership store is active.
39
+ * Returns `null` for the in-memory store (nothing to apply). NEVER gates on the self id —
40
+ * that was the boot-ordering bug. The caller schedules the boot tick + interval on a
41
+ * non-null result.
42
+ */
43
+ export declare function wireOwnershipApplier(deps: OwnershipApplierWiringDeps): OwnershipApplier | null;
44
+ //# sourceMappingURL=ownershipApplierWiring.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ownershipApplierWiring.d.ts","sourceRoot":"","sources":["../../src/core/ownershipApplierWiring.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AAE3E,MAAM,WAAW,0BAA0B;IACzC,iFAAiF;IACjF,qBAAqB,EAAE,qBAAqB,GAAG,IAAI,CAAC;IACpD,yEAAyE;IACzE,MAAM,EAAE,eAAe,CAAC;IACxB;;;;OAIG;IACH,gBAAgB,EAAE,MAAM,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAClD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACpB;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,0BAA0B,GAAG,gBAAgB,GAAG,IAAI,CAU9F"}
@@ -0,0 +1,20 @@
1
+ import { OwnershipApplier } from './OwnershipApplier.js';
2
+ /**
3
+ * Build the OwnershipApplier when (and only when) the durable ownership store is active.
4
+ * Returns `null` for the in-memory store (nothing to apply). NEVER gates on the self id —
5
+ * that was the boot-ordering bug. The caller schedules the boot tick + interval on a
6
+ * non-null result.
7
+ */
8
+ export function wireOwnershipApplier(deps) {
9
+ if (!deps.durableOwnershipStore)
10
+ return null;
11
+ return new OwnershipApplier({
12
+ reader: deps.reader,
13
+ store: deps.durableOwnershipStore,
14
+ selfMachineId: deps.getSelfMachineId, // getter — resolved per-tick, never captured stale
15
+ scanLimit: deps.scanLimit,
16
+ logger: deps.logger,
17
+ now: deps.now,
18
+ });
19
+ }
20
+ //# sourceMappingURL=ownershipApplierWiring.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ownershipApplierWiring.js","sourceRoot":"","sources":["../../src/core/ownershipApplierWiring.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAmBzD;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB,CAAC,IAAgC;IACnE,IAAI,CAAC,IAAI,CAAC,qBAAqB;QAAE,OAAO,IAAI,CAAC;IAC7C,OAAO,IAAI,gBAAgB,CAAC;QAC1B,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,KAAK,EAAE,IAAI,CAAC,qBAAqB;QACjC,aAAa,EAAE,IAAI,CAAC,gBAAgB,EAAE,mDAAmD;QACzF,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,GAAG,EAAE,IAAI,CAAC,GAAG;KACd,CAAC,CAAC;AACL,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "instar",
3
- "version": "1.3.590",
3
+ "version": "1.3.591",
4
4
  "description": "Coherence infrastructure for self-evolving AI agents — on the Claude Code or Codex subscription you already have.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "$schema": "./builtin-manifest.schema.json",
3
3
  "schemaVersion": 1,
4
- "generatedAt": "2026-06-16T06:03:16.573Z",
5
- "instarVersion": "1.3.590",
4
+ "generatedAt": "2026-06-16T06:55:01.483Z",
5
+ "instarVersion": "1.3.591",
6
6
  "entryCount": 201,
7
7
  "entries": {
8
8
  "hook:session-start": {
@@ -0,0 +1,34 @@
1
+ # Upgrade Guide — vNEXT
2
+
3
+ <!-- assembled-by: assemble-next-md -->
4
+ <!-- bump: patch -->
5
+
6
+ ## What Changed
7
+
8
+ Fixed a boot-ordering bug that left the cross-machine `OwnershipApplier` permanently
9
+ un-wired: a topic moved between machines was reported moved but the destination never took
10
+ ownership, so the conversation went silent on arrival. The applier's on-switch now depends on
11
+ the durable ownership store alone (extracted into a testable `wireOwnershipApplier` factory),
12
+ and the machine id it uses for logging is late-bound, so the wiring can't be broken by code
13
+ reordering. Caught by applying the Live-User-Channel Proof gold standard to a real
14
+ Laptop→Mini transfer (the second, deeper bug after the dev-gate-darkness fix in v1.3.590).
15
+
16
+ ## What to Tell Your User
17
+
18
+ If you move a conversation between your machines, the destination now genuinely takes over and
19
+ answers there. Before this, a moved conversation could report success but then go quiet on the
20
+ new machine, because the new machine never realized it owned the conversation. Single-machine
21
+ setups are unaffected.
22
+
23
+ ## Summary of New Capabilities
24
+
25
+ | Capability | How to Use |
26
+ |-----------|-----------|
27
+ | Moving a conversation between machines actually lands it on the destination | Move a topic to another machine as usual; the destination now takes ownership and serves it |
28
+
29
+ ## Evidence
30
+
31
+ - 6 new unit/wiring tests (`tests/unit/ownershipApplierWiring.test.ts`) + 7 existing applier
32
+ tests stay green; tsc clean.
33
+ - Release gate: a live two-machine re-run asserts the destination materializes the seat and a
34
+ reply serves from it (Telegram + Slack).
@@ -0,0 +1,52 @@
1
+ # Side-Effects Review — OwnershipApplier mesh-self ordering fix
2
+
3
+ **Slug:** ownership-applier-meshself-ordering-fix
4
+ **Spec:** docs/specs/ownership-applier-meshself-ordering-fix.md
5
+ **Parent principle:** Wiring Integrity — a dependency-injected component must actually run, not be a silently-skipped no-op.
6
+
7
+ ## What changed
8
+
9
+ A boot-ordering bug in `src/commands/server.ts` meant the transfer-fix §7.2 `OwnershipApplier`
10
+ was never constructed or ticked at runtime (its guard read `_meshSelfId` ~650 lines before
11
+ the boot sequence assigns it, so the guard was always false). Result: a topic transferred
12
+ between machines was recorded on the SOURCE and replicated to the DESTINATION's journal, but
13
+ the destination never materialized ownership → it never knew it owned the session → the seat
14
+ died on arrival. Caught by applying the Live-User-Channel Proof gold standard to a real
15
+ Laptop→Mini transfer.
16
+
17
+ Fix (order-independent — Structure > Willpower):
18
+ - `src/core/OwnershipApplier.ts` — `selfMachineId` accepts a late-bound getter (label-only;
19
+ materialization never needs it); resolved per-tick instead of captured stale at construction.
20
+ - `src/core/ownershipApplierWiring.ts` (new) — `wireOwnershipApplier()` factory gates
21
+ construction on the durable store ALONE (the correct condition), extracted so the invariant
22
+ is unit-testable (the inline condition was untestable, which is how the bug shipped).
23
+ - `src/commands/server.ts` — calls the factory in place of the inline guard.
24
+
25
+ ## Blast radius
26
+
27
+ - **Multi-machine destinations (the target):** a transferred seat now materializes durable
28
+ ownership on the destination and is served there. This was BROKEN before — net improvement.
29
+ - **Single machine:** the durable store may be active but there are no peer placements; the
30
+ applier ticks and finds nothing — a harmless no-op. No behavior change.
31
+ - **Transfer SOURCE:** unchanged (it writes ownership directly via the tclaim path).
32
+ - **No new route, config flag, state schema, URL, or migration.** Pure internal wiring +
33
+ one new internal module (no agent-facing surface → no CLAUDE.md template change required).
34
+ - **Backward compatibility:** `OwnershipApplier`'s `selfMachineId` still accepts a plain
35
+ string; all existing callers/tests are unaffected (7 existing applier tests stay green).
36
+
37
+ ## Reversibility
38
+
39
+ No flag (it only activates the durable-ownership path that already ships pool-consistent for
40
+ replication-on pools / dark for single-machine). Revertable by reverting the three-file diff;
41
+ no durable state is written that would outlive a revert (ownership records are re-derived from
42
+ the replicated journal on the next tick).
43
+
44
+ ## Risk / monitoring
45
+
46
+ Low. The applier is off the hot path (boot tick + 15s interval), never throws (degrades to
47
+ "materialized fewer this tick"), and fast-forward-CAS guards against clobbering a fresher
48
+ local decision. Observable via `[ownership-applier] materialized …` / `[OwnershipApplier]
49
+ materialized N/M …` in `logs/server.log` — their appearance is itself the proof the wiring is
50
+ now alive (the bug's signature was their total absence). Release gate: the live two-machine
51
+ re-run (deploy both → transfer → assert destination materializes + a reply serves from the
52
+ destination).