instar 1.3.548 → 1.3.549
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/dist/commands/server.d.ts.map +1 -1
- package/dist/commands/server.js +112 -0
- package/dist/commands/server.js.map +1 -1
- package/dist/config/ConfigDefaults.d.ts.map +1 -1
- package/dist/config/ConfigDefaults.js +29 -0
- package/dist/config/ConfigDefaults.js.map +1 -1
- package/dist/core/CoherenceJournal.d.ts +1 -1
- package/dist/core/CoherenceJournal.d.ts.map +1 -1
- package/dist/core/CoherenceJournal.js +23 -2
- package/dist/core/CoherenceJournal.js.map +1 -1
- package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
- package/dist/core/PostUpdateMigrator.js +27 -1
- package/dist/core/PostUpdateMigrator.js.map +1 -1
- package/dist/core/TopicOperatorReplicatedStore.d.ts +250 -0
- package/dist/core/TopicOperatorReplicatedStore.d.ts.map +1 -0
- package/dist/core/TopicOperatorReplicatedStore.js +413 -0
- package/dist/core/TopicOperatorReplicatedStore.js.map +1 -0
- package/dist/core/UserRegistryReplicatedStore.d.ts +287 -0
- package/dist/core/UserRegistryReplicatedStore.d.ts.map +1 -0
- package/dist/core/UserRegistryReplicatedStore.js +527 -0
- package/dist/core/UserRegistryReplicatedStore.js.map +1 -0
- package/dist/core/devGatedFeatures.d.ts.map +1 -1
- package/dist/core/devGatedFeatures.js +10 -0
- package/dist/core/devGatedFeatures.js.map +1 -1
- package/dist/scaffold/templates.d.ts.map +1 -1
- package/dist/scaffold/templates.js +3 -1
- package/dist/scaffold/templates.js.map +1 -1
- package/dist/users/TopicOperatorStore.d.ts +24 -0
- package/dist/users/TopicOperatorStore.d.ts.map +1 -1
- package/dist/users/TopicOperatorStore.js +28 -0
- package/dist/users/TopicOperatorStore.js.map +1 -1
- package/dist/users/UserManager.d.ts +27 -0
- package/dist/users/UserManager.d.ts.map +1 -1
- package/dist/users/UserManager.js +44 -0
- package/dist/users/UserManager.js.map +1 -1
- package/package.json +1 -1
- package/src/data/builtin-manifest.json +19 -19
- package/src/scaffold/templates.ts +3 -1
- package/upgrades/1.3.549.md +36 -0
- package/upgrades/side-effects/multi-machine-replicated-store-ws26-user-topicop.md +123 -0
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# Side-Effects Review — WS2.6 user-registry + topic-operator replicated stores (the last two memory-family PII kinds, dark)
|
|
2
|
+
|
|
3
|
+
**Version / slug:** `multi-machine-replicated-store-ws26-user-topicop`
|
|
4
|
+
**Date:** `2026-06-13`
|
|
5
|
+
**Author:** `Instar Agent (echo)`
|
|
6
|
+
**Second-pass reviewer:** `5-lens adversarial review (untrusted-replicated-operator / recordKey-identity / disclosure-min-PII-leak / tombstone-erasure / dark-ship-inertness) — verdict + named tests appended below`
|
|
7
|
+
**Parent principle:** Cross-Machine Coherence — One Agent, Robust Under Degraded Conditions
|
|
8
|
+
|
|
9
|
+
## Summary of the change
|
|
10
|
+
|
|
11
|
+
WS2.6 adds the final two PII kinds to the WS2 memory family on the proven HLC
|
|
12
|
+
replicated-store foundation: `user-record` (the multi-user registry the `UserManager`
|
|
13
|
+
resolves an inbound message to) and `topic-operator-record` (which VERIFIED operator a
|
|
14
|
+
topic was bound to). Both are thin instantiations of the shipped WS2.3 relationships PII
|
|
15
|
+
template: discriminated-union-on-`op` schema (value + tombstone), strict type-clamp on
|
|
16
|
+
receive, disclosure-minimized projection, content/identity-surface `recordKey`, 64KB
|
|
17
|
+
per-entry cap with a named over-cap error, op:delete tombstone for offline-peer erasure,
|
|
18
|
+
HIGH-impact-at-replication / advisory-at-read. With these landed, the WS2 memory family
|
|
19
|
+
is COMPLETE (7 kinds: preferences, relationships, learnings, knowledge, evolution-actions,
|
|
20
|
+
user-registry, topic-operator; playbook deferred CMT-1416).
|
|
21
|
+
|
|
22
|
+
Both ship **DARK** behind `multiMachine.stateSync.userRegistry` and
|
|
23
|
+
`.topicOperator` (`enabled:false`, `dryRun:true` — the graduated dark→dryRun→live ladder).
|
|
24
|
+
Flag-off / single-machine = strict no-op; NO PII ever crosses a machine boundary while dark.
|
|
25
|
+
|
|
26
|
+
## Decision-point inventory (the decided forks, baked in verbatim)
|
|
27
|
+
|
|
28
|
+
- **user-record recordKey** = `sha256(sorted channel-set "type:identifier" pairs)` — a user IS
|
|
29
|
+
their channel identifiers (same model as relationships, mirroring `UserManager.channelIndex`).
|
|
30
|
+
NEVER the local `userId` (the cross-machine-unstable id).
|
|
31
|
+
- **topic-operator recordKey** = `sha256(topicId + ":" + verified-uid)`. NEVER a content-name
|
|
32
|
+
(Know-Your-Principal: the binding is auth-sender-derived).
|
|
33
|
+
- **Impact tier**: BOTH HIGH@replication (append-both-and-flag on concurrent divergence) /
|
|
34
|
+
advisory@read (a replicated PII record is a hint, never the authoritative answer).
|
|
35
|
+
- **disclosure-min**: user-record strips the local `userId`; topic-operator projects exactly
|
|
36
|
+
`{platform, uid, names, boundAt}` (no internal `boundFrom`).
|
|
37
|
+
- **THE LOAD-BEARING INVARIANT (topic-operator)**: a replicated topic-operator record is
|
|
38
|
+
UNTRUSTED peer data — NEVER this machine's authoritative answer to "who is my verified
|
|
39
|
+
operator?". Only the LOCAL authenticated `TopicOperatorStore.setOperator` binds the principal.
|
|
40
|
+
The store exposes NO apply/set/establish path back into `TopicOperatorStore` by construction.
|
|
41
|
+
|
|
42
|
+
## 1. Over-block
|
|
43
|
+
None. Both kinds ADD reach (replicated PII as advisory context) and never block a message, a
|
|
44
|
+
route, or a session. Flag-off / single-machine = strict no-op (named E2E + unit tests).
|
|
45
|
+
|
|
46
|
+
## 2. Under-block (the real risk surface)
|
|
47
|
+
The inverse risk: replicated PII is materialized into a union read. Mitigations: (a) strict
|
|
48
|
+
type-clamp on receive (ISO-8601 dates, finite numbers, jailed slugs) makes markup
|
|
49
|
+
un-smuggleable through a render slot; (b) every foreign record renders inside a
|
|
50
|
+
`<replicated-untrusted-data origin="…">` envelope; (c) the topic-operator foreign render
|
|
51
|
+
EXPLICITLY states the record is NOT the verified operator and cannot establish/override one;
|
|
52
|
+
(d) identity RESOLUTION of an inbound principal stays LOCAL-ONLY for user-record (the local
|
|
53
|
+
channel index always wins); (e) the topic-operator store has no apply path, so a replicated
|
|
54
|
+
record can never reach `getOperator()` authority. Accepted residual: a compromised
|
|
55
|
+
same-operator peer could inject advisory context text, but it cannot escalate to principal
|
|
56
|
+
authority and the blast radius is one operator's own pool — recorded as a known bound.
|
|
57
|
+
|
|
58
|
+
## 3. Level-of-abstraction fit
|
|
59
|
+
The two `*ReplicatedStore.ts` modules are PURE logic (no fs, no Date, no network) — schema +
|
|
60
|
+
projection + recordKey + merge + render, unit-testable in isolation. The wiring sits in
|
|
61
|
+
server.ts (kind registration + union reader) and the manager seams (`UserManager.persistUsers`/
|
|
62
|
+
`removeUser`, `TopicOperatorStore.setOperator`) exactly where the WS2.2–2.5 siblings sit. No
|
|
63
|
+
new transport, no new auth, no new tick.
|
|
64
|
+
|
|
65
|
+
## 4. Signal vs authority compliance
|
|
66
|
+
Fully signal-only. Neither kind gates or rewrites anything. The user-registry merged read is a
|
|
67
|
+
HINT (inbound resolution stays local-authoritative); the topic-operator merged read is advisory
|
|
68
|
+
context (the principal stays local-authoritative). The mesh path is the existing read/observe
|
|
69
|
+
replicated-store substrate — adds reach, never authority; the receiver type-clamps + envelopes.
|
|
70
|
+
|
|
71
|
+
## 5. Interactions
|
|
72
|
+
- Rides the existing `ReplicatedKindRegistry` + dual-registry (`JOURNAL_KINDS`) + union reader +
|
|
73
|
+
conflict/rollback substrate (no new machinery).
|
|
74
|
+
- Two new `enabled:false` ConfigDefaults paths shift the dark-gate EXPECTED line-map by +29;
|
|
75
|
+
hand-edited (regeneration forbidden) + two new attributed entries added.
|
|
76
|
+
- Coexists with the WS2.1–2.5 siblings (same `multiMachine.stateSync.*` block, independent flags).
|
|
77
|
+
- The maintainer's WS5.2 credential-repointing track was NOT touched (separate lane).
|
|
78
|
+
|
|
79
|
+
## 6. External surfaces
|
|
80
|
+
No new HTTP routes. The kinds register onto the shared registry and ride the existing
|
|
81
|
+
`/state/*` conflict/quarantine routes (already alive). Emission/serve/pull stay dark behind the
|
|
82
|
+
two new flags. The journal-backed emitter is wired at the manager seams but only attached when
|
|
83
|
+
the flag is on (a later rollout stage, mirroring the siblings).
|
|
84
|
+
|
|
85
|
+
## 7. Multi-machine posture (Cross-Machine Coherence) + Phase C
|
|
86
|
+
- **Per-machine emission; N-machine pool = N independent emitters.** Identity keyed on the
|
|
87
|
+
channel-set (user) / topic+uid (operator), NOT a per-machine id — so the SAME user/operator
|
|
88
|
+
across N machines is ONE record, never N duplicates.
|
|
89
|
+
- **The topic-operator untrusted-replicated invariant scales:** on N machines only the LOCAL
|
|
90
|
+
authenticated binding is authoritative for the principal; replicated records from N-1 peers
|
|
91
|
+
are advisory. A re-bind to a NEW operator (different uid) is a DIFFERENT record (different
|
|
92
|
+
key), so a replica can never overwrite the local binding.
|
|
93
|
+
- **No LAN/broadcast assumption.** Rides the existing per-peer replicated-store substrate.
|
|
94
|
+
- **Offline-peer erasure:** a removed user / unbound operator propagates an op:delete tombstone
|
|
95
|
+
keyed on the SAME identity surface, so an erased record stays erased on a peer that was offline
|
|
96
|
+
at delete time.
|
|
97
|
+
|
|
98
|
+
## Migration parity
|
|
99
|
+
- ConfigDefaults: two new dark blocks (no migrateConfig needed — an absent per-store key resolves
|
|
100
|
+
to dark, the safe default; identical to the WS2.2–2.5 siblings).
|
|
101
|
+
- CLAUDE.md template (`templates.ts`) + a chained migrator else-if in `PostUpdateMigrator` splice
|
|
102
|
+
the two new One Memory bullets — ESPECIALLY the topic-operator UNTRUSTED-REPLICATED-OPERATOR
|
|
103
|
+
invariant — into already-deployed agents before any operator enables the replication. Idempotent
|
|
104
|
+
(guarded by the unique 'User registry is the SECOND PII store' marker), with a focused test.
|
|
105
|
+
- devGatedFeatures: two new DARK_GATE_EXCLUSIONS entries (optional-integration).
|
|
106
|
+
- Docs: two new `under-the-hood.md` class blocks (≥2 mentions each — docs-coverage passes).
|
|
107
|
+
|
|
108
|
+
## 5-lens adversarial verdict (folded as named tests)
|
|
109
|
+
1. **Untrusted-replicated-operator (THE blocker)** — `untrusted-replicated-operator-never-authoritative`:
|
|
110
|
+
the foreign render ALWAYS says NOT the verified operator; the module exposes NO apply/set/establish
|
|
111
|
+
export; the wiring test proves `getOperator()` authority is UNCHANGED by a replicated record. PASS.
|
|
112
|
+
2. **recordKey identity** — `recordKey-identity-collapses-cross-machine`: same channel-set/topic+uid →
|
|
113
|
+
one key regardless of local id; a different uid is a different record. PASS.
|
|
114
|
+
3. **disclosure-min / PII leak** — `disclosure-min-strips-local-id` (userId never on wire),
|
|
115
|
+
topic-operator projection exactly `{platform,uid,names,boundAt}`, `64KB-named-error`, `type-clamp`
|
|
116
|
+
(markup injection blocked, path-shaped slug jailed). PASS.
|
|
117
|
+
4. **tombstone erasure** — `op:delete-tombstone-erasure`: tombstone keyed on the SAME identity surface;
|
|
118
|
+
schema op:delete branch accepts it. PASS.
|
|
119
|
+
5. **dark-ship inertness** — `dark-ship-strict-noop`: no emitter ⇒ manager behaves byte-identically;
|
|
120
|
+
E2E DISABLED → 503. PASS.
|
|
121
|
+
|
|
122
|
+
No residual blockers. Known accepted bound: a compromised same-operator peer can inject advisory
|
|
123
|
+
context (cannot escalate to authority; one-operator blast radius).
|