instar 1.3.1254 → 1.3.1255

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.
@@ -31,6 +31,16 @@ import { type Secrets } from './SecretStore.js';
31
31
  * the same credential/channel it is meant to survive.
32
32
  */
33
33
  export declare const LOCAL_ONLY_SECRET_PREFIXES: readonly ["machineIdentityRecovery"];
34
+ /**
35
+ * Prototype agent-held Google passkeys (spec agent-held-google-passkey §6, Increment 1).
36
+ * These were minted on one machine and must never be copied to another, but they are a
37
+ * single top-level vault key (e.g. `google_passkey_echo_studio`), not a dotted namespace,
38
+ * so the dot-segment rule above cannot match them. A separate first-segment prefix
39
+ * matcher handles them.
40
+ */
41
+ export declare const LEGACY_PASSKEY_KEY_PREFIX = "google_passkey_";
42
+ /** True when the key path's FIRST segment is a prototype passkey key. */
43
+ export declare function isLegacyPasskeyPath(keyPath: string): boolean;
34
44
  /** Return a deep, non-mutating copy with every machine-local namespace removed. */
35
45
  export declare function filterSecretsForSync(secrets: Secrets, prefix?: string): Secrets;
36
46
  /** The `secret-share` mesh command payload (mirrors the MeshCommand variant). */
@@ -129,9 +139,13 @@ export declare class SecretShareHandler {
129
139
  };
130
140
  log?: (msg: string) => void;
131
141
  });
132
- /** Decrypt + store. Returns the keyPaths stored. Throws only on a malformed/foreign payload. */
142
+ /**
143
+ * Decrypt + store. Returns the keyPaths stored and any prototype passkey keys dropped.
144
+ * Throws only on a malformed/foreign payload or a machine-local recovery namespace.
145
+ */
133
146
  handle(command: SecretShareCommand, sender: string): {
134
147
  stored: string[];
148
+ dropped: string[];
135
149
  };
136
150
  }
137
151
  //# sourceMappingURL=SecretSync.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"SecretSync.d.ts","sourceRoot":"","sources":["../../src/core/SecretSync.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"SecretSync.d.ts","sourceRoot":"","sources":["../../src/core/SecretSync.ts"],"names":[],"mappings":"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"}
@@ -12,6 +12,19 @@ function isLocalOnlySecretPath(keyPath) {
12
12
  || keyPath.endsWith(`.${prefix}`)
13
13
  || keyPath.includes(`.${prefix}.`)));
14
14
  }
15
+ /**
16
+ * Prototype agent-held Google passkeys (spec agent-held-google-passkey §6, Increment 1).
17
+ * These were minted on one machine and must never be copied to another, but they are a
18
+ * single top-level vault key (e.g. `google_passkey_echo_studio`), not a dotted namespace,
19
+ * so the dot-segment rule above cannot match them. A separate first-segment prefix
20
+ * matcher handles them.
21
+ */
22
+ export const LEGACY_PASSKEY_KEY_PREFIX = 'google_passkey_';
23
+ /** True when the key path's FIRST segment is a prototype passkey key. */
24
+ export function isLegacyPasskeyPath(keyPath) {
25
+ const first = keyPath.split('.')[0] ?? '';
26
+ return first.startsWith(LEGACY_PASSKEY_KEY_PREFIX);
27
+ }
15
28
  /** Return a deep, non-mutating copy with every machine-local namespace removed. */
16
29
  export function filterSecretsForSync(secrets, prefix = '') {
17
30
  const filtered = {};
@@ -19,6 +32,8 @@ export function filterSecretsForSync(secrets, prefix = '') {
19
32
  const keyPath = prefix ? `${prefix}.${key}` : key;
20
33
  if (isLocalOnlySecretPath(keyPath))
21
34
  continue;
35
+ if (isLegacyPasskeyPath(keyPath))
36
+ continue;
22
37
  if (value && typeof value === 'object' && !Array.isArray(value)) {
23
38
  const child = filterSecretsForSync(value, keyPath);
24
39
  if (Object.keys(child).length > 0)
@@ -97,7 +112,10 @@ export class SecretShareHandler {
97
112
  constructor(deps) {
98
113
  this.deps = deps;
99
114
  }
100
- /** Decrypt + store. Returns the keyPaths stored. Throws only on a malformed/foreign payload. */
115
+ /**
116
+ * Decrypt + store. Returns the keyPaths stored and any prototype passkey keys dropped.
117
+ * Throws only on a malformed/foreign payload or a machine-local recovery namespace.
118
+ */
101
119
  handle(command, sender) {
102
120
  // The legacy permissive path must be structurally unreachable for credential-class data
103
121
  // (WS5.2 R3a / §6.5): a credential rides the distinct `account-credential-share` verb +
@@ -112,12 +130,24 @@ export class SecretShareHandler {
112
130
  throw new Error(`SecretShareHandler refuses machine-local secret namespace: ${forbidden}`);
113
131
  }
114
132
  const stored = [];
133
+ // Prototype passkey keys from an older-build sender are dropped and audited, never
134
+ // stored — and the rest of the batch is still stored (spec §6 Increment 1: a
135
+ // mixed-version fleet must not halt ALL secret sync). A copy this machine already
136
+ // holds is left untouched: a receive refusal never deletes anything.
137
+ const dropped = [];
115
138
  for (const [keyPath, value] of Object.entries(secrets)) {
139
+ if (isLegacyPasskeyPath(keyPath)) {
140
+ dropped.push(keyPath);
141
+ continue;
142
+ }
116
143
  this.deps.store.set(keyPath, value);
117
144
  stored.push(keyPath);
118
145
  }
146
+ if (dropped.length > 0) {
147
+ this.deps.log?.(`[secret-sync] dropped ${dropped.length} prototype passkey key(s) from ${sender} (machine-local; names: ${dropped.join(', ')})`);
148
+ }
119
149
  this.deps.log?.(`[secret-sync] stored ${stored.length} secret(s) from ${sender}`);
120
- return { stored };
150
+ return { stored, dropped };
121
151
  }
122
152
  }
123
153
  //# sourceMappingURL=SecretSync.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"SecretSync.js","sourceRoot":"","sources":["../../src/core/SecretSync.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"SecretSync.js","sourceRoot":"","sources":["../../src/core/SecretSync.ts"],"names":[],"mappings":"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"}
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
3
  "generatedFrom": "source-tree",
4
- "registrySha256": "c2114fbb049a01ae580ff0b4489af22dca9c4e3c0e4790501a33d229cef56108",
5
- "packageVersion": "1.3.1254",
4
+ "registrySha256": "c55d201d822f8706b0dc50ce21b0b8298b4ac470543cfe46d8988da03b0d34b9",
5
+ "packageVersion": "1.3.1255",
6
6
  "guards": [
7
7
  {
8
8
  "ref": "docs/audits/phase-b/f10-triage.md",
@@ -1,5 +1,5 @@
1
1
  {
2
- "sha256": "75a3d5b58d5df5a9b162ab0ed97cf042467b861ebb350f7d032e87422922d067",
3
- "registrySha256": "c2114fbb049a01ae580ff0b4489af22dca9c4e3c0e4790501a33d229cef56108",
4
- "packageVersion": "1.3.1254"
2
+ "sha256": "ee84c0659d64a84485d8879ebc68cc08eba6e40720bfde88f08abb91fbc3c8ed",
3
+ "registrySha256": "c55d201d822f8706b0dc50ce21b0b8298b4ac470543cfe46d8988da03b0d34b9",
4
+ "packageVersion": "1.3.1255"
5
5
  }
@@ -230,7 +230,7 @@ The Root says *enforce behavior in structure, not willpower.* This family is **w
230
230
  **Tree placement.** **CHILD** — this is **a tree node under *Deferral = Deletion***, declared 2026-08-22 at ratification. That parent holds that an insight not captured NOW is gone, because the successor instance lacks the context that made it worth capturing. This article is the same conservation one step later in time: an insight that WAS captured is equally gone if the store holding it evicts it. Same loss, same reason — no successor can reconstruct it — different mechanism: omission versus eviction. A CHILD rather than a sibling because the parent states the conservation principle and this extends its reach past the capture boundary. It is deliberately NOT filed under *An Instar Agent Is Always a Multi-Machine Entity*: its subject holds on a single machine with no peers at all — a store that rotates history away violates it whether or not the agent is multi-machine — and filing it there would bind a general obligation to a condition it does not depend on.
231
231
  **Fails.** If a store cannot demonstrate that its growth-bounding path preserves rather than evicts, fail closed on ADOPTING that store for agent memory: the work may proceed on a store that can, but memory may not be entrusted to a mechanism that forgets. A PERMITTED deletion — operator-requested or lawful-erasure-required — is never this failure; it is the permitted case, and the wording says "permitted deletion" rather than "operator-requested" because an external lens caught the narrower phrasing quietly re-closing the carve-out the Rule had just widened (round 3). **Erasure must PROPAGATE, and this is the condition that makes the duplication rule safe.** When a permitted deletion runs, it must reach every copy the duplication rule created — the memory store, any bounded operational copy still holding it, derived summaries, and search indexes. A duplication requirement that did not carry a propagation requirement would let this article preserve exactly the content an erasure obligation required destroyed, which is the reverse of the compliance problem it claims to help with.
232
232
  **In practice.** **Distinct from *Observable Intelligence*.** That article's **Balanced by — Responsible Resource** clause requires audit trails to age out — bounded retention, never forever — and calls an unbounded observability store its own incoherence. Worded generally, "archiving may never delete" contradicts it head-on, and a reader could cite the registry for either position. The boundary is therefore part of this Rule rather than commentary beneath it: memory is conserved, telemetry is bounded, and the test between them is continuity rather than usefulness. Without that line stated in the Rule the two articles are each citable against the other, which is the both-sides-citable defect the registry's residual section exists to prevent. **Why this is affordable, measured rather than assumed.** The obvious objection is that "every machine holds everything" plus "nothing is ever deleted" is unbounded growth on every machine forever. Compression resolves it and the margin is not close. Measured on the originating machine 2026-08-21: 2,490 messages over 3 days, 3.0 MB raw, **0.4 MB gzipped — 7.5x, lossless.** At that rate a year of history is roughly 50 MB compressed and a decade under half a gigabyte. **The honest scope of that measurement (narrowed at ratification after an external lens called the extrapolation improper):** it covers MESSAGE TEXT on one machine over three working days. It does NOT cover attachments, search indexes, encryption overhead, the other memory kinds, or growth rates unlike those three days, and "affordable on any hardware" is therefore a claim about conversation text specifically, not a proof for all memory. What the number establishes is narrower than it first reads, and is stated at its real strength (round 3, external lens): for THIS sample — message text, this machine, three heavy working days — the size objection does not hold, by a margin large enough that a modest change in growth rate would not reverse it. It does NOT establish a bound for other growth rates, other memory kinds, or constrained hardware, and this article claims no unconditional bound. The obligation to keep memory does not rest on the measurement; the measurement only removes the reflex that the obligation is obviously unaffordable. **A claim that stood in the proposal was withdrawn before ratification and the withdrawal is recorded here rather than edited away:** the proposal argued the real cost was the container — that the coherence journal rotates-and-deletes and that its per-kind byte budgets were too small. Reading the rotation code shows both halves wrong: the byte figure is a rotation THRESHOLD with no total ceiling behind it, and a rotate-but-never-delete setting already ships on one kind today. A peer that falls past the tail window re-joins by snapshot-then-tail rather than losing anything. The container was never the obstacle. **Why the operator carve-out is load-bearing rather than decorative.** The stores that hold agent memory deliberately DO expire their transport logs, and the reason written into that code is erasure compliance: a never-deleting log would retain a person's details after they had asked to be erased. That is a genuine legal constraint and an unqualified "never delete" would collide with it. The carve-out is what lets both hold at once — the system never forgets on its own, and the principal may still ask for a deletion. So this article is compatible with the compliance requirement rather than in conflict with it — but it does not by itself DELIVER compliance, and the earlier draft claiming it did was over-claiming (round 3, external lens). Actual compliance depends on the propagation condition in **Fails.** above holding across every duplicate, summary, index and replica, which is engineering work this article requires and does not perform.
233
- **Documented-only until.** `2026-09-22` — tracked as `STD-COUNTDOWN-archiving-never-deletes`. No guard decides whether a store deletes agent memory, and none is claimed. This lands as a `/spec-converge` cross-machine and integration reviewer question — "does any store here delete agent memory, and is what it deletes memory or telemetry?" — which is semantic authority, weaker than a lint and stronger than prose. A deterministic version is conceivable (enumerate the stores holding memory kinds, assert each declares a non-evicting retention posture) and is not built. **Sub-obligation countdown.** `2026-09-22` — tracked as `STD-SUBCOUNTDOWN-archiving-never-deletes`. This is a COUNTDOWN, not a resting state: the article is ratified and binding from 2026-08-22, and the label records that its enforcement is owed rather than built.
233
+ **Documented-only until.** `2026-12-21` — tracked as `STD-COUNTDOWN-archiving-never-deletes`. No guard decides whether a store deletes agent memory, and none is claimed. This lands as a `/spec-converge` cross-machine and integration reviewer question — "does any store here delete agent memory, and is what it deletes memory or telemetry?" — which is semantic authority, weaker than a lint and stronger than prose. A deterministic version is conceivable (enumerate the stores holding memory kinds, assert each declares a non-evicting retention posture) and is not built. **Sub-obligation countdown.** `2026-12-21` — tracked as `STD-SUBCOUNTDOWN-archiving-never-deletes`. This is a COUNTDOWN, not a resting state: the article is ratified and binding from 2026-08-22, and the label records that its enforcement is owed rather than built.
234
234
  **Earned from.** 2026-08-21 (topic 52222), operator directive, ratified 2026-08-22: "archiving CANNOT mean deleting. We must be able to access message history at all costs." Raised while designing cross-machine conversation coherence, where the mechanism proposed for replicating history was one built to bound itself by eviction — the agent was about to entrust its memory to a container designed to forget, and the design passed six convergence rounds without anyone naming that.
235
235
  **Traces to the goal.** The founding promise is one coherent, persistent agent. The registry's own Root section already supplies the reason this line falls where it does: destroying an agent's accumulated record is "an injury to a self," not a data incident. *Deferral = Deletion* protects the record at the moment of capture; this protects it for the rest of its life. An agent whose memory is bounded by eviction is not persisting through time — it is a sliding window that believes it is a self.
236
236
 
@@ -474,7 +474,7 @@ The Root says *enforce behavior in structure, not willpower.* This family is **w
474
474
  **In practice.** This is **THE SINGLE GOVERNING ARTICLE for the cross-machine posture declaration** (declared 2026-08-08, fourth pass, after the review found both this article and *Cross-Machine Coherence* owning it: "both still own the declaration/review obligation"). It governs here because it STRENGTHENS the permitted answers — the enumerated postures below — while the other article owns the broader robustness rule that a posture serves. Every new state surface asserts its cross-machine posture — `unified` (rides the One Memory / stateSync machinery), `proxied-on-read` (a named remote read — **OPERATIONAL state ONLY; invalid for memory-bearing state**, see the survivability clause in the Rule), or `machine-local + justification` (the reason jailed to the closed taxonomy stated above: physical-credential-locality [narrowed 2026-08-22], hardware-bound-resource, operator-ratified-exception, or migrating-to-unified [added 2026-08-22]). Absence defaults to `unified`-required. A bare "machine-local BY DESIGN" with no justification fails review — the default is *asserted*, never *assumed*. **THE CLOSED TAXONOMY, amended 2026-08-22 (operator directive, topic 52222 — Amendments 3 and 5).** A `machine-local` posture jails its reason to this closed set, and widening the set remains a constitution-bound operator decision, never an author's convenience. **`physical-credential-locality` — NARROWED (Amendment 3).** It covers only a credential whose relocation is PROHIBITED or technically impossible: a vendor's terms of service, a hardware-bound key, a legal residency constraint. It does NOT cover a credential that merely HAPPENS to be stored on one disk. Where a vault (Bitwarden and equivalents) can hold it, the locality is a storage choice and this key does not apply. A claim under this key must NAME its basis — the prohibiting authority (`prohibited-by`) or, where the barrier is technical rather than forbidding, what makes relocation impossible (`impossible-because`). Both are accepted, because "technically impossible" often has no authority to cite and demanding one was an inconsistent evidentiary bar (external adversarial lens, 2026-08-22). The claim must also declare whether the barrier is expected to be PERMANENT or TEMPORARY, and **a TEMPORARY declaration must record its exit** (`exit=<ref>`), **a re-review date** (`expires=YYYY-MM-DD`, at most 180 days out), **and the date it was first declared** (`since=YYYY-MM-DD`, with the same 360-day TOTAL-LIFETIME cap) — the full contract `migrating-to-unified` carries, for the same reason and closed in the same place (round 4: giving this key a deadline without a lifetime cap re-created, one key over, exactly the renew-every-180-days loophole round 3 had just closed for the other; a fix that reintroduces the defect it was patterned on is not a fix). At the cap the barrier is re-argued in front of the operator, who may of course rule it PERMANENT — which is the honest outcome for a barrier that has held for a year: a barrier declared temporary with no tracked way out is a permanent barrier wearing a temporary label, and one with an exit but no deadline is the same thing with paperwork (the deadline was added in round 3 after an external lens observed the exit ref alone let a TEMPORARY barrier outlive the horizon imposed on the newer key — a rule that binds a new key more tightly than an old one for no stated reason is an inconsistency, not a conservative default). The one genuine current instance is Anthropic's prohibition on relocating a Claude login between machines (why WS5.2 re-mints per machine rather than copying a token); under this amendment it still passes, and must be declared TEMPORARY with the planned exit recorded — API-key doorways once per-machine login becomes untenable at scale (operator, same directive). **`hardware-bound-resource`** — unchanged. **`operator-ratified-exception`** — unchanged; still requires a machine-verifiable, existence-checkable ref. **`migrating-to-unified` — NEW (Amendment 5).** Permitted ONLY when the marker also cites (a) the ratified decision establishing `unified` as the destination and (b) a resolvable tracking ref for the work that delivers it, AND carries an expiry date, and that date may be **at most 180 days out** — a bound added at ratification after an external adversarial lens showed the key was RENEWABLE rather than self-terminating (an author could set a distant expiry, deliver nothing, and never be asked again; the first draft's own test fixture used the year 2099 and passed). On expiry the surface either declares `unified` or the exception is re-argued in front of the operator; it may never lapse silently into a permanent posture. **And because a per-declaration horizon alone is merely RENEWABLE (round 3, external lens: "renewal forever remains possible; assigning that loophole to semantic review does not close it"), the marker also carries `since=YYYY-MM-DD` — the date the posture was FIRST declared for that surface — and the posture's TOTAL LIFETIME (`expires` − `since`) may not exceed 360 days.** A renewal must carry the original `since` forward, so re-dating the expiry no longer buys unbounded time: the second renewal is the last one the parser will accept. **What remains open, stated rather than claimed closed:** a `since` that is simply rewritten is FALSIFICATION, not a loophole in the letter — the parser cannot detect it, and nothing here pretends otherwise. The difference matters: an author must now lie to keep the posture, where before they only had to pick a distant date. **Why a fourth key was ratified despite the hatch being deliberately narrow.** Amendment 1 GUARANTEES arrivals at this wall: making survivability the test converts a population of currently-passing `machine-local` surfaces into surfaces whose correct posture is `unified` and whose mechanism is unbuilt. With only three keys the honest posture is unavailable — the conversation-history spec keyed nine surfaces `operator-ratified-exception (PENDING)` for a ratification the operator then DENIED, leaving markers citing a refused approval. Adopting 1 without 5 therefore MANUFACTURES the false-claim class the taxonomy exists to reduce. This key is the only one of the four whose use is self-terminating — it requires a date and a tracked delivery, so it cannot become a resting place — and unlike Amendments 1, 2 and 4 its contract is deterministically CHECKABLE on arrival, because its citation requirements reduce to the same existence-check the marker lint already performs. **The honest scope of that check:** the parser verifies the marker's SHAPE — that an authority is named, that refs are ref-shaped, that a date is present and unexpired and inside the maximum horizon. It cannot verify that the named authority actually prohibits the relocation, that the tracked work will deliver unification, or that an expiry triggers real re-argument. Those remain the `/spec-converge` reviewer's semantic authority, exactly as before; "checkable" here never means "proven true".
475
475
  **Earned from.** 2026-07-03 (topic 29723), operator-ratified: the tiered-intelligence-delegation spec defaulted its consult memory to machine-local, conflicting with the single-unified-agent goal — and it survived SEVEN convergence rounds before the operator caught it on read. That it took the operator's read, not the review machinery, is the tell: the always-multi-machine expectation lived in prose and reviewer habit, not in structure. Justin named the meta-point — "the fact that I had to point out the misalignment means we have a gap in our standards or how we enforce them; it should be fundamental in our constitution that an Instar agent is always supported as a multi-machine entity."
476
476
  **Traces to the goal.** The founding promise is one coherent, persistent agent. An agent whose memory, budgets, or state fragment per-machine is not one agent — it is N confused copies of it. *Structure beats Willpower*: don't rely on the agent or a reviewer *remembering* that the agent is multi-machine; make the unified default the path of least resistance and machine-local the posture that must argue for itself.
477
- **Applied through.** The deterministic marker floor `scripts/lint-machine-local-justification.js` — a no-LLM static parser that grades the PRESENCE + well-formedness of the `machine-local-justification: <taxonomy-key>` marker a spec must carry per machine-local surface: an undefended machine-local posture fails, and — bidirectionally — a spurious/out-of-taxonomy marker or an `operator-ratified-exception` citing no machine-verifiable ref fails too (self-tested with positive, undefended, and spurious-marker fixtures). This is the cheap deterministic SIGNAL; the `/spec-converge` integration reviewer holds the semantic AUTHORITY (is the justification actually TRUE?) the parser cannot make. The lint ships REPORT-FIRST (a non-blocking signal; `--strict` is the FAIL capability) per the honesty / hard-sequencing clause of `docs/specs/three-standards-enforcement.md` (§197-202, §563-573) and the dark-first Maturation convention. The `/spec-converge` cross-machine check is also STRENGTHENED to REJECT "machine-local" unless the spec carries an explicit `machine-local-justification` (a bare "machine-local BY DESIGN" fails); the side-effects review §7 posture field gains the same justification requirement; and existing features are swept for undefended machine-local surfaces (folds into the feature-maturation audit, topic 30668). This registry entry + its **P21** twin in `docs/INSTAR-DESIGN-PRINCIPLES-AND-LESSONS.md` fire the `/spec-converge` lessons-aware reviewer on every future spec. **UNENFORCED SUB-OBLIGATION, named (2026-08-22).** Amendments 1 and 2 have NO deterministic guard and are not claimed to have one: no parser can decide whether a design survives the loss of every peer, nor whether a stated outcome is genuinely met. They land as `/spec-converge` cross-machine reviewer questions — "does this survive every peer disappearing?" — which is semantic authority, weaker than a lint and stronger than prose. Amendments 3 and 5 carry deterministically CHECKABLE MARKER CONTRACTS, enforced in `scripts/lint-machine-local-justification.js`. What is enforced is the marker's SHAPE — a basis is named, refs are ref-shaped, dates are present, unexpired, and inside their caps. The SEMANTIC facts those markers assert — that the named authority really prohibits relocation, that the impossibility is real, that the tracked work delivers unification — are NOT checked by anything deterministic and remain the reviewer's (re-narrowed 2026-08-22 round 3, after an external lens read the flat word "enforced" as covering the semantics). Naming this asymmetry rather than citing a guard for the unguarded clauses is deliberate: *Cross-Store Coherence* records that naming a guard in prose made an article classify as ENFORCED by a guard measuring something else, and reproducing that inside the article being amended to be more honest would be the worst available outcome. **Sub-obligation countdown.** `2026-09-22` — tracked as `STD-SUBCOUNTDOWN-multi-machine-survivability`.
477
+ **Applied through.** The deterministic marker floor `scripts/lint-machine-local-justification.js` — a no-LLM static parser that grades the PRESENCE + well-formedness of the `machine-local-justification: <taxonomy-key>` marker a spec must carry per machine-local surface: an undefended machine-local posture fails, and — bidirectionally — a spurious/out-of-taxonomy marker or an `operator-ratified-exception` citing no machine-verifiable ref fails too (self-tested with positive, undefended, and spurious-marker fixtures). This is the cheap deterministic SIGNAL; the `/spec-converge` integration reviewer holds the semantic AUTHORITY (is the justification actually TRUE?) the parser cannot make. The lint ships REPORT-FIRST (a non-blocking signal; `--strict` is the FAIL capability) per the honesty / hard-sequencing clause of `docs/specs/three-standards-enforcement.md` (§197-202, §563-573) and the dark-first Maturation convention. The `/spec-converge` cross-machine check is also STRENGTHENED to REJECT "machine-local" unless the spec carries an explicit `machine-local-justification` (a bare "machine-local BY DESIGN" fails); the side-effects review §7 posture field gains the same justification requirement; and existing features are swept for undefended machine-local surfaces (folds into the feature-maturation audit, topic 30668). This registry entry + its **P21** twin in `docs/INSTAR-DESIGN-PRINCIPLES-AND-LESSONS.md` fire the `/spec-converge` lessons-aware reviewer on every future spec. **UNENFORCED SUB-OBLIGATION, named (2026-08-22).** Amendments 1 and 2 have NO deterministic guard and are not claimed to have one: no parser can decide whether a design survives the loss of every peer, nor whether a stated outcome is genuinely met. They land as `/spec-converge` cross-machine reviewer questions — "does this survive every peer disappearing?" — which is semantic authority, weaker than a lint and stronger than prose. Amendments 3 and 5 carry deterministically CHECKABLE MARKER CONTRACTS, enforced in `scripts/lint-machine-local-justification.js`. What is enforced is the marker's SHAPE — a basis is named, refs are ref-shaped, dates are present, unexpired, and inside their caps. The SEMANTIC facts those markers assert — that the named authority really prohibits relocation, that the impossibility is real, that the tracked work delivers unification — are NOT checked by anything deterministic and remain the reviewer's (re-narrowed 2026-08-22 round 3, after an external lens read the flat word "enforced" as covering the semantics). Naming this asymmetry rather than citing a guard for the unguarded clauses is deliberate: *Cross-Store Coherence* records that naming a guard in prose made an article classify as ENFORCED by a guard measuring something else, and reproducing that inside the article being amended to be more honest would be the worst available outcome. **Sub-obligation countdown.** `2026-12-21` — tracked as `STD-SUBCOUNTDOWN-multi-machine-survivability`.
478
478
 
479
479
  ### Cross-Store Coherence Is an Invariant
480
480
  **Rule.** Any two stores that answer the same question — about identity, authority, machine liveness, or configuration — must have a **declared agreement invariant**, and that invariant must be **checked on a cadence by machinery**. A pair of authoritative stores with no coherence check is a contradiction waiting for a code path to read the wrong one. When a NEW store is introduced that answers a question an existing store already answers, declaring the invariant is part of introducing it.
@@ -1,6 +1,6 @@
1
1
  {
2
- "sha256": "c2114fbb049a01ae580ff0b4489af22dca9c4e3c0e4790501a33d229cef56108",
2
+ "sha256": "c55d201d822f8706b0dc50ce21b0b8298b4ac470543cfe46d8988da03b0d34b9",
3
3
  "articleCount": 91,
4
4
  "generatedFrom": "docs/STANDARDS-REGISTRY.md",
5
- "packageVersion": "1.3.1254"
5
+ "packageVersion": "1.3.1255"
6
6
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "instar",
3
- "version": "1.3.1254",
3
+ "version": "1.3.1255",
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",
@@ -137,7 +137,7 @@
137
137
  },
138
138
  {
139
139
  "path": "src/templates/scripts/secret-get.mjs",
140
- "sha256": "2b206fc53579a824cc07da769338bb822a1a455532b3f73c7e0ab1dabccfa424",
140
+ "sha256": "c6acba715f339c63d53a889bcea35b5e7de4b46a51de375093631189668447c4",
141
141
  "reason": "boundary case: retrieval failure containment (emits zero secret bytes), not a policy block"
142
142
  }
143
143
  ]
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "$schema": "./builtin-manifest.schema.json",
3
3
  "schemaVersion": 1,
4
- "generatedAt": "2026-09-22T23:12:44.922Z",
5
- "instarVersion": "1.3.1254",
4
+ "generatedAt": "2026-09-23T06:25:25.847Z",
5
+ "instarVersion": "1.3.1255",
6
6
  "entryCount": 203,
7
7
  "entries": {
8
8
  "hook:session-start": {
@@ -1219,7 +1219,7 @@
1219
1219
  "type": "template",
1220
1220
  "domain": "operations",
1221
1221
  "sourcePath": "src/templates/scripts/secret-get.mjs",
1222
- "contentHash": "2b206fc53579a824cc07da769338bb822a1a455532b3f73c7e0ab1dabccfa424",
1222
+ "contentHash": "c6acba715f339c63d53a889bcea35b5e7de4b46a51de375093631189668447c4",
1223
1223
  "since": "2025-01-01"
1224
1224
  },
1225
1225
  "template:serendipity-capture.sh": {
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
3
  "generatedFrom": "source-tree",
4
- "registrySha256": "c2114fbb049a01ae580ff0b4489af22dca9c4e3c0e4790501a33d229cef56108",
5
- "packageVersion": "1.3.1254",
4
+ "registrySha256": "c55d201d822f8706b0dc50ce21b0b8298b4ac470543cfe46d8988da03b0d34b9",
5
+ "packageVersion": "1.3.1255",
6
6
  "guards": [
7
7
  {
8
8
  "ref": "docs/audits/phase-b/f10-triage.md",
@@ -1,5 +1,5 @@
1
1
  {
2
- "sha256": "75a3d5b58d5df5a9b162ab0ed97cf042467b861ebb350f7d032e87422922d067",
3
- "registrySha256": "c2114fbb049a01ae580ff0b4489af22dca9c4e3c0e4790501a33d229cef56108",
4
- "packageVersion": "1.3.1254"
2
+ "sha256": "ee84c0659d64a84485d8879ebc68cc08eba6e40720bfde88f08abb91fbc3c8ed",
3
+ "registrySha256": "c55d201d822f8706b0dc50ce21b0b8298b4ac470543cfe46d8988da03b0d34b9",
4
+ "packageVersion": "1.3.1255"
5
5
  }
@@ -230,7 +230,7 @@ The Root says *enforce behavior in structure, not willpower.* This family is **w
230
230
  **Tree placement.** **CHILD** — this is **a tree node under *Deferral = Deletion***, declared 2026-08-22 at ratification. That parent holds that an insight not captured NOW is gone, because the successor instance lacks the context that made it worth capturing. This article is the same conservation one step later in time: an insight that WAS captured is equally gone if the store holding it evicts it. Same loss, same reason — no successor can reconstruct it — different mechanism: omission versus eviction. A CHILD rather than a sibling because the parent states the conservation principle and this extends its reach past the capture boundary. It is deliberately NOT filed under *An Instar Agent Is Always a Multi-Machine Entity*: its subject holds on a single machine with no peers at all — a store that rotates history away violates it whether or not the agent is multi-machine — and filing it there would bind a general obligation to a condition it does not depend on.
231
231
  **Fails.** If a store cannot demonstrate that its growth-bounding path preserves rather than evicts, fail closed on ADOPTING that store for agent memory: the work may proceed on a store that can, but memory may not be entrusted to a mechanism that forgets. A PERMITTED deletion — operator-requested or lawful-erasure-required — is never this failure; it is the permitted case, and the wording says "permitted deletion" rather than "operator-requested" because an external lens caught the narrower phrasing quietly re-closing the carve-out the Rule had just widened (round 3). **Erasure must PROPAGATE, and this is the condition that makes the duplication rule safe.** When a permitted deletion runs, it must reach every copy the duplication rule created — the memory store, any bounded operational copy still holding it, derived summaries, and search indexes. A duplication requirement that did not carry a propagation requirement would let this article preserve exactly the content an erasure obligation required destroyed, which is the reverse of the compliance problem it claims to help with.
232
232
  **In practice.** **Distinct from *Observable Intelligence*.** That article's **Balanced by — Responsible Resource** clause requires audit trails to age out — bounded retention, never forever — and calls an unbounded observability store its own incoherence. Worded generally, "archiving may never delete" contradicts it head-on, and a reader could cite the registry for either position. The boundary is therefore part of this Rule rather than commentary beneath it: memory is conserved, telemetry is bounded, and the test between them is continuity rather than usefulness. Without that line stated in the Rule the two articles are each citable against the other, which is the both-sides-citable defect the registry's residual section exists to prevent. **Why this is affordable, measured rather than assumed.** The obvious objection is that "every machine holds everything" plus "nothing is ever deleted" is unbounded growth on every machine forever. Compression resolves it and the margin is not close. Measured on the originating machine 2026-08-21: 2,490 messages over 3 days, 3.0 MB raw, **0.4 MB gzipped — 7.5x, lossless.** At that rate a year of history is roughly 50 MB compressed and a decade under half a gigabyte. **The honest scope of that measurement (narrowed at ratification after an external lens called the extrapolation improper):** it covers MESSAGE TEXT on one machine over three working days. It does NOT cover attachments, search indexes, encryption overhead, the other memory kinds, or growth rates unlike those three days, and "affordable on any hardware" is therefore a claim about conversation text specifically, not a proof for all memory. What the number establishes is narrower than it first reads, and is stated at its real strength (round 3, external lens): for THIS sample — message text, this machine, three heavy working days — the size objection does not hold, by a margin large enough that a modest change in growth rate would not reverse it. It does NOT establish a bound for other growth rates, other memory kinds, or constrained hardware, and this article claims no unconditional bound. The obligation to keep memory does not rest on the measurement; the measurement only removes the reflex that the obligation is obviously unaffordable. **A claim that stood in the proposal was withdrawn before ratification and the withdrawal is recorded here rather than edited away:** the proposal argued the real cost was the container — that the coherence journal rotates-and-deletes and that its per-kind byte budgets were too small. Reading the rotation code shows both halves wrong: the byte figure is a rotation THRESHOLD with no total ceiling behind it, and a rotate-but-never-delete setting already ships on one kind today. A peer that falls past the tail window re-joins by snapshot-then-tail rather than losing anything. The container was never the obstacle. **Why the operator carve-out is load-bearing rather than decorative.** The stores that hold agent memory deliberately DO expire their transport logs, and the reason written into that code is erasure compliance: a never-deleting log would retain a person's details after they had asked to be erased. That is a genuine legal constraint and an unqualified "never delete" would collide with it. The carve-out is what lets both hold at once — the system never forgets on its own, and the principal may still ask for a deletion. So this article is compatible with the compliance requirement rather than in conflict with it — but it does not by itself DELIVER compliance, and the earlier draft claiming it did was over-claiming (round 3, external lens). Actual compliance depends on the propagation condition in **Fails.** above holding across every duplicate, summary, index and replica, which is engineering work this article requires and does not perform.
233
- **Documented-only until.** `2026-09-22` — tracked as `STD-COUNTDOWN-archiving-never-deletes`. No guard decides whether a store deletes agent memory, and none is claimed. This lands as a `/spec-converge` cross-machine and integration reviewer question — "does any store here delete agent memory, and is what it deletes memory or telemetry?" — which is semantic authority, weaker than a lint and stronger than prose. A deterministic version is conceivable (enumerate the stores holding memory kinds, assert each declares a non-evicting retention posture) and is not built. **Sub-obligation countdown.** `2026-09-22` — tracked as `STD-SUBCOUNTDOWN-archiving-never-deletes`. This is a COUNTDOWN, not a resting state: the article is ratified and binding from 2026-08-22, and the label records that its enforcement is owed rather than built.
233
+ **Documented-only until.** `2026-12-21` — tracked as `STD-COUNTDOWN-archiving-never-deletes`. No guard decides whether a store deletes agent memory, and none is claimed. This lands as a `/spec-converge` cross-machine and integration reviewer question — "does any store here delete agent memory, and is what it deletes memory or telemetry?" — which is semantic authority, weaker than a lint and stronger than prose. A deterministic version is conceivable (enumerate the stores holding memory kinds, assert each declares a non-evicting retention posture) and is not built. **Sub-obligation countdown.** `2026-12-21` — tracked as `STD-SUBCOUNTDOWN-archiving-never-deletes`. This is a COUNTDOWN, not a resting state: the article is ratified and binding from 2026-08-22, and the label records that its enforcement is owed rather than built.
234
234
  **Earned from.** 2026-08-21 (topic 52222), operator directive, ratified 2026-08-22: "archiving CANNOT mean deleting. We must be able to access message history at all costs." Raised while designing cross-machine conversation coherence, where the mechanism proposed for replicating history was one built to bound itself by eviction — the agent was about to entrust its memory to a container designed to forget, and the design passed six convergence rounds without anyone naming that.
235
235
  **Traces to the goal.** The founding promise is one coherent, persistent agent. The registry's own Root section already supplies the reason this line falls where it does: destroying an agent's accumulated record is "an injury to a self," not a data incident. *Deferral = Deletion* protects the record at the moment of capture; this protects it for the rest of its life. An agent whose memory is bounded by eviction is not persisting through time — it is a sliding window that believes it is a self.
236
236
 
@@ -474,7 +474,7 @@ The Root says *enforce behavior in structure, not willpower.* This family is **w
474
474
  **In practice.** This is **THE SINGLE GOVERNING ARTICLE for the cross-machine posture declaration** (declared 2026-08-08, fourth pass, after the review found both this article and *Cross-Machine Coherence* owning it: "both still own the declaration/review obligation"). It governs here because it STRENGTHENS the permitted answers — the enumerated postures below — while the other article owns the broader robustness rule that a posture serves. Every new state surface asserts its cross-machine posture — `unified` (rides the One Memory / stateSync machinery), `proxied-on-read` (a named remote read — **OPERATIONAL state ONLY; invalid for memory-bearing state**, see the survivability clause in the Rule), or `machine-local + justification` (the reason jailed to the closed taxonomy stated above: physical-credential-locality [narrowed 2026-08-22], hardware-bound-resource, operator-ratified-exception, or migrating-to-unified [added 2026-08-22]). Absence defaults to `unified`-required. A bare "machine-local BY DESIGN" with no justification fails review — the default is *asserted*, never *assumed*. **THE CLOSED TAXONOMY, amended 2026-08-22 (operator directive, topic 52222 — Amendments 3 and 5).** A `machine-local` posture jails its reason to this closed set, and widening the set remains a constitution-bound operator decision, never an author's convenience. **`physical-credential-locality` — NARROWED (Amendment 3).** It covers only a credential whose relocation is PROHIBITED or technically impossible: a vendor's terms of service, a hardware-bound key, a legal residency constraint. It does NOT cover a credential that merely HAPPENS to be stored on one disk. Where a vault (Bitwarden and equivalents) can hold it, the locality is a storage choice and this key does not apply. A claim under this key must NAME its basis — the prohibiting authority (`prohibited-by`) or, where the barrier is technical rather than forbidding, what makes relocation impossible (`impossible-because`). Both are accepted, because "technically impossible" often has no authority to cite and demanding one was an inconsistent evidentiary bar (external adversarial lens, 2026-08-22). The claim must also declare whether the barrier is expected to be PERMANENT or TEMPORARY, and **a TEMPORARY declaration must record its exit** (`exit=<ref>`), **a re-review date** (`expires=YYYY-MM-DD`, at most 180 days out), **and the date it was first declared** (`since=YYYY-MM-DD`, with the same 360-day TOTAL-LIFETIME cap) — the full contract `migrating-to-unified` carries, for the same reason and closed in the same place (round 4: giving this key a deadline without a lifetime cap re-created, one key over, exactly the renew-every-180-days loophole round 3 had just closed for the other; a fix that reintroduces the defect it was patterned on is not a fix). At the cap the barrier is re-argued in front of the operator, who may of course rule it PERMANENT — which is the honest outcome for a barrier that has held for a year: a barrier declared temporary with no tracked way out is a permanent barrier wearing a temporary label, and one with an exit but no deadline is the same thing with paperwork (the deadline was added in round 3 after an external lens observed the exit ref alone let a TEMPORARY barrier outlive the horizon imposed on the newer key — a rule that binds a new key more tightly than an old one for no stated reason is an inconsistency, not a conservative default). The one genuine current instance is Anthropic's prohibition on relocating a Claude login between machines (why WS5.2 re-mints per machine rather than copying a token); under this amendment it still passes, and must be declared TEMPORARY with the planned exit recorded — API-key doorways once per-machine login becomes untenable at scale (operator, same directive). **`hardware-bound-resource`** — unchanged. **`operator-ratified-exception`** — unchanged; still requires a machine-verifiable, existence-checkable ref. **`migrating-to-unified` — NEW (Amendment 5).** Permitted ONLY when the marker also cites (a) the ratified decision establishing `unified` as the destination and (b) a resolvable tracking ref for the work that delivers it, AND carries an expiry date, and that date may be **at most 180 days out** — a bound added at ratification after an external adversarial lens showed the key was RENEWABLE rather than self-terminating (an author could set a distant expiry, deliver nothing, and never be asked again; the first draft's own test fixture used the year 2099 and passed). On expiry the surface either declares `unified` or the exception is re-argued in front of the operator; it may never lapse silently into a permanent posture. **And because a per-declaration horizon alone is merely RENEWABLE (round 3, external lens: "renewal forever remains possible; assigning that loophole to semantic review does not close it"), the marker also carries `since=YYYY-MM-DD` — the date the posture was FIRST declared for that surface — and the posture's TOTAL LIFETIME (`expires` − `since`) may not exceed 360 days.** A renewal must carry the original `since` forward, so re-dating the expiry no longer buys unbounded time: the second renewal is the last one the parser will accept. **What remains open, stated rather than claimed closed:** a `since` that is simply rewritten is FALSIFICATION, not a loophole in the letter — the parser cannot detect it, and nothing here pretends otherwise. The difference matters: an author must now lie to keep the posture, where before they only had to pick a distant date. **Why a fourth key was ratified despite the hatch being deliberately narrow.** Amendment 1 GUARANTEES arrivals at this wall: making survivability the test converts a population of currently-passing `machine-local` surfaces into surfaces whose correct posture is `unified` and whose mechanism is unbuilt. With only three keys the honest posture is unavailable — the conversation-history spec keyed nine surfaces `operator-ratified-exception (PENDING)` for a ratification the operator then DENIED, leaving markers citing a refused approval. Adopting 1 without 5 therefore MANUFACTURES the false-claim class the taxonomy exists to reduce. This key is the only one of the four whose use is self-terminating — it requires a date and a tracked delivery, so it cannot become a resting place — and unlike Amendments 1, 2 and 4 its contract is deterministically CHECKABLE on arrival, because its citation requirements reduce to the same existence-check the marker lint already performs. **The honest scope of that check:** the parser verifies the marker's SHAPE — that an authority is named, that refs are ref-shaped, that a date is present and unexpired and inside the maximum horizon. It cannot verify that the named authority actually prohibits the relocation, that the tracked work will deliver unification, or that an expiry triggers real re-argument. Those remain the `/spec-converge` reviewer's semantic authority, exactly as before; "checkable" here never means "proven true".
475
475
  **Earned from.** 2026-07-03 (topic 29723), operator-ratified: the tiered-intelligence-delegation spec defaulted its consult memory to machine-local, conflicting with the single-unified-agent goal — and it survived SEVEN convergence rounds before the operator caught it on read. That it took the operator's read, not the review machinery, is the tell: the always-multi-machine expectation lived in prose and reviewer habit, not in structure. Justin named the meta-point — "the fact that I had to point out the misalignment means we have a gap in our standards or how we enforce them; it should be fundamental in our constitution that an Instar agent is always supported as a multi-machine entity."
476
476
  **Traces to the goal.** The founding promise is one coherent, persistent agent. An agent whose memory, budgets, or state fragment per-machine is not one agent — it is N confused copies of it. *Structure beats Willpower*: don't rely on the agent or a reviewer *remembering* that the agent is multi-machine; make the unified default the path of least resistance and machine-local the posture that must argue for itself.
477
- **Applied through.** The deterministic marker floor `scripts/lint-machine-local-justification.js` — a no-LLM static parser that grades the PRESENCE + well-formedness of the `machine-local-justification: <taxonomy-key>` marker a spec must carry per machine-local surface: an undefended machine-local posture fails, and — bidirectionally — a spurious/out-of-taxonomy marker or an `operator-ratified-exception` citing no machine-verifiable ref fails too (self-tested with positive, undefended, and spurious-marker fixtures). This is the cheap deterministic SIGNAL; the `/spec-converge` integration reviewer holds the semantic AUTHORITY (is the justification actually TRUE?) the parser cannot make. The lint ships REPORT-FIRST (a non-blocking signal; `--strict` is the FAIL capability) per the honesty / hard-sequencing clause of `docs/specs/three-standards-enforcement.md` (§197-202, §563-573) and the dark-first Maturation convention. The `/spec-converge` cross-machine check is also STRENGTHENED to REJECT "machine-local" unless the spec carries an explicit `machine-local-justification` (a bare "machine-local BY DESIGN" fails); the side-effects review §7 posture field gains the same justification requirement; and existing features are swept for undefended machine-local surfaces (folds into the feature-maturation audit, topic 30668). This registry entry + its **P21** twin in `docs/INSTAR-DESIGN-PRINCIPLES-AND-LESSONS.md` fire the `/spec-converge` lessons-aware reviewer on every future spec. **UNENFORCED SUB-OBLIGATION, named (2026-08-22).** Amendments 1 and 2 have NO deterministic guard and are not claimed to have one: no parser can decide whether a design survives the loss of every peer, nor whether a stated outcome is genuinely met. They land as `/spec-converge` cross-machine reviewer questions — "does this survive every peer disappearing?" — which is semantic authority, weaker than a lint and stronger than prose. Amendments 3 and 5 carry deterministically CHECKABLE MARKER CONTRACTS, enforced in `scripts/lint-machine-local-justification.js`. What is enforced is the marker's SHAPE — a basis is named, refs are ref-shaped, dates are present, unexpired, and inside their caps. The SEMANTIC facts those markers assert — that the named authority really prohibits relocation, that the impossibility is real, that the tracked work delivers unification — are NOT checked by anything deterministic and remain the reviewer's (re-narrowed 2026-08-22 round 3, after an external lens read the flat word "enforced" as covering the semantics). Naming this asymmetry rather than citing a guard for the unguarded clauses is deliberate: *Cross-Store Coherence* records that naming a guard in prose made an article classify as ENFORCED by a guard measuring something else, and reproducing that inside the article being amended to be more honest would be the worst available outcome. **Sub-obligation countdown.** `2026-09-22` — tracked as `STD-SUBCOUNTDOWN-multi-machine-survivability`.
477
+ **Applied through.** The deterministic marker floor `scripts/lint-machine-local-justification.js` — a no-LLM static parser that grades the PRESENCE + well-formedness of the `machine-local-justification: <taxonomy-key>` marker a spec must carry per machine-local surface: an undefended machine-local posture fails, and — bidirectionally — a spurious/out-of-taxonomy marker or an `operator-ratified-exception` citing no machine-verifiable ref fails too (self-tested with positive, undefended, and spurious-marker fixtures). This is the cheap deterministic SIGNAL; the `/spec-converge` integration reviewer holds the semantic AUTHORITY (is the justification actually TRUE?) the parser cannot make. The lint ships REPORT-FIRST (a non-blocking signal; `--strict` is the FAIL capability) per the honesty / hard-sequencing clause of `docs/specs/three-standards-enforcement.md` (§197-202, §563-573) and the dark-first Maturation convention. The `/spec-converge` cross-machine check is also STRENGTHENED to REJECT "machine-local" unless the spec carries an explicit `machine-local-justification` (a bare "machine-local BY DESIGN" fails); the side-effects review §7 posture field gains the same justification requirement; and existing features are swept for undefended machine-local surfaces (folds into the feature-maturation audit, topic 30668). This registry entry + its **P21** twin in `docs/INSTAR-DESIGN-PRINCIPLES-AND-LESSONS.md` fire the `/spec-converge` lessons-aware reviewer on every future spec. **UNENFORCED SUB-OBLIGATION, named (2026-08-22).** Amendments 1 and 2 have NO deterministic guard and are not claimed to have one: no parser can decide whether a design survives the loss of every peer, nor whether a stated outcome is genuinely met. They land as `/spec-converge` cross-machine reviewer questions — "does this survive every peer disappearing?" — which is semantic authority, weaker than a lint and stronger than prose. Amendments 3 and 5 carry deterministically CHECKABLE MARKER CONTRACTS, enforced in `scripts/lint-machine-local-justification.js`. What is enforced is the marker's SHAPE — a basis is named, refs are ref-shaped, dates are present, unexpired, and inside their caps. The SEMANTIC facts those markers assert — that the named authority really prohibits relocation, that the impossibility is real, that the tracked work delivers unification — are NOT checked by anything deterministic and remain the reviewer's (re-narrowed 2026-08-22 round 3, after an external lens read the flat word "enforced" as covering the semantics). Naming this asymmetry rather than citing a guard for the unguarded clauses is deliberate: *Cross-Store Coherence* records that naming a guard in prose made an article classify as ENFORCED by a guard measuring something else, and reproducing that inside the article being amended to be more honest would be the worst available outcome. **Sub-obligation countdown.** `2026-12-21` — tracked as `STD-SUBCOUNTDOWN-multi-machine-survivability`.
478
478
 
479
479
  ### Cross-Store Coherence Is an Invariant
480
480
  **Rule.** Any two stores that answer the same question — about identity, authority, machine liveness, or configuration — must have a **declared agreement invariant**, and that invariant must be **checked on a cadence by machinery**. A pair of authoritative stores with no coherence check is a contradiction waiting for a code path to read the wrong one. When a NEW store is introduced that answers a question an existing store already answers, declaring the invariant is part of introducing it.
@@ -1,6 +1,6 @@
1
1
  {
2
- "sha256": "c2114fbb049a01ae580ff0b4489af22dca9c4e3c0e4790501a33d229cef56108",
2
+ "sha256": "c55d201d822f8706b0dc50ce21b0b8298b4ac470543cfe46d8988da03b0d34b9",
3
3
  "articleCount": 91,
4
4
  "generatedFrom": "docs/STANDARDS-REGISTRY.md",
5
- "packageVersion": "1.3.1254"
5
+ "packageVersion": "1.3.1255"
6
6
  }
@@ -134,6 +134,23 @@ if (!hit) {
134
134
  }
135
135
  const value = typeof hit[1] === 'string' ? hit[1] : JSON.stringify(hit[1]);
136
136
 
137
+ // Prototype agent-held Google passkeys (spec agent-held-google-passkey §6,
138
+ // Increment 1): reads stay allowed so the operator-run prototype scripts keep
139
+ // working, but every read is recorded — key name and time only, never the value
140
+ // — until the operator adopts or deletes that key.
141
+ if (keyPath.split('.')[0].startsWith('google_passkey_')) {
142
+ try {
143
+ const logDir = path.join(stateDir, 'logs');
144
+ fs.mkdirSync(logDir, { recursive: true });
145
+ fs.appendFileSync(
146
+ path.join(logDir, 'passkey-legacy-reads.jsonl'),
147
+ JSON.stringify({ ts: new Date().toISOString(), key: keyPath, pid: process.pid, mode: runCmd ? 'run' : 'stdout' }) + '\n',
148
+ );
149
+ } catch {
150
+ // Audit is best-effort: a logging failure must never block or leak the read.
151
+ }
152
+ }
153
+
137
154
  if (runCmd) {
138
155
  const r = spawnSync(runCmd[0], runCmd.slice(1), { input: value, stdio: ['pipe', 'inherit', 'inherit'] });
139
156
  process.exit(r.status ?? 1);
@@ -0,0 +1,37 @@
1
+ # Upgrade Guide — vNEXT
2
+
3
+ <!-- assembled-by: assemble-next-md -->
4
+ <!-- bump: patch -->
5
+
6
+ ## What Changed
7
+
8
+ First increment of the approved agent-held Google passkeys spec
9
+ (`docs/specs/agent-held-google-passkey.md` §6). Prototype passkeys are stored in the vault as
10
+ top-level keys named `google_passkey_*`. Secret sync no longer copies them between machines: the
11
+ sending side leaves them out, and a receiving machine that is sent them by an older build drops them
12
+ and records that it did, while still storing the rest of the batch. A copy a machine already holds is
13
+ never deleted. Reading one of these keys through the vault read script still works, so the existing
14
+ sign-in scripts keep running, but each read is now recorded (key name and time only) in
15
+ `.instar/logs/passkey-legacy-reads.jsonl`.
16
+
17
+ ## What to Tell Your User
18
+
19
+ The sign-in keys your agent keeps for your Google accounts are no longer copied from one of your
20
+ machines to the others. Nothing you use today changes — sign-ins keep working exactly as before.
21
+
22
+ ## Summary of New Capabilities
23
+
24
+ - Machine-bound sign-in keys stay on the machine that made them.
25
+ - A machine on an older version can't cause the rest of secret sync to fail.
26
+ - Every use of these keys is recorded, so it's visible which tools still depend on them.
27
+
28
+ ## Evidence
29
+
30
+ - Unit tests: `tests/unit/secret-sync-legacy-passkey.test.ts` covers the key matcher, the sending-side
31
+ filter, the payload the provisioner actually encrypts, an old-build sender pushing to a new-build
32
+ receiver (keys dropped, the rest stored, logs carry names only), a receiver's existing copy left
33
+ untouched, and the recovery namespace still rejecting the whole batch.
34
+ - `tests/unit/secret-get-legacy-passkey-read-log.test.ts` runs the real script against a real
35
+ encrypted vault: the value is returned, one audit line is written without the value, and ordinary
36
+ keys are not logged.
37
+ - The existing secret-sync unit tests pass unchanged.
@@ -0,0 +1,135 @@
1
+ # Side-Effects Review — Stop prototype Google passkeys spreading between machines (Increment 1)
2
+
3
+ **Version / slug:** `passkey-inc1-sync-filter`
4
+ **Date:** `2026-09-22`
5
+ **Author:** `echo`
6
+ **Second-pass reviewer:** `independent subagent (secret-sync is a credential-flow gate)`
7
+
8
+ ## Summary of the change
9
+
10
+ Increment 1 of the approved spec `docs/specs/agent-held-google-passkey.md` (§6). Prototype agent-held
11
+ Google passkeys live in the shared vault as single top-level keys named `google_passkey_*`, and until
12
+ now secret sync copied them to every peer machine. `src/core/SecretSync.ts` gains a first-segment
13
+ matcher (`isLegacyPasskeyPath`). The SENDER (`filterSecretsForSync`, used by `SecretProvisioner`) now
14
+ omits these keys. The RECEIVER (`SecretShareHandler.handle`) drops and audits any that an older-build
15
+ sender still pushes, and stores the rest of the batch; it returns `{stored, dropped}`. The existing
16
+ `machineIdentityRecovery` rule (reject the whole batch) is unchanged. The vault read script template
17
+ `src/templates/scripts/secret-get.mjs` (always overwritten on update by PostUpdateMigrator) keeps
18
+ allowing reads of these keys, so the operator-run prototype scripts keep working, and appends one line
19
+ per read (key name, time, pid, mode; never the value) to `.instar/logs/passkey-legacy-reads.jsonl`.
20
+
21
+ ## Decision-point inventory
22
+
23
+ - `filterSecretsForSync` (sender filter) — modify — also excludes `google_passkey_*` keys.
24
+ - `SecretShareHandler.handle` (receiver acceptance) — modify — drops `google_passkey_*` keys instead of storing them; the rest of the batch is stored.
25
+ - `secret-get.mjs` read path — pass-through with audit — no refusal; an audit line only.
26
+
27
+ ---
28
+
29
+ ## 1. Over-block
30
+
31
+ A vault key whose first segment happens to start with `google_passkey_` but is not a passkey would
32
+ stop syncing. No such key exists today, and the prefix is specific to the prototype naming. A user who
33
+ WANTS to share a prototype passkey to another machine can no longer do so through sync. That is the
34
+ intended behaviour (spec FD2: per-machine keys), and the spec's per-key adoption flow replaces it.
35
+
36
+ ## 2. Under-block
37
+
38
+ - Copies that already reached the Mini and Laptop stay there. This change deliberately never deletes
39
+ (spec §6); the per-key adopt/delete choice in a later increment handles them.
40
+ - The prefix match is case-sensitive: a key named in another case or style would still sync. All
41
+ seven known keys use the exact lowercase prefix.
42
+ - Only reads through `secret-get.mjs` are logged; a direct in-process `SecretStore` read (a script or
43
+ route importing the store) is not. Accepted for this increment; the separate passkey store in a
44
+ later increment removes these keys from the shared vault altogether.
45
+ - A prototype key stored under a different naming scheme would still sync. All seven known keys match
46
+ the prefix (verified from the vault's key names).
47
+ - Any session can still read these keys through `secret-get.mjs`. Now each read is logged. Refusing
48
+ reads is deferred by the spec until the operator's per-key choice, so today's working repairs are
49
+ not broken. <!-- tracked: CMT-544 -->
50
+
51
+ ## 3. Level-of-abstraction fit
52
+
53
+ Correct layer. `SecretSync.ts` already owns the local-only namespace policy
54
+ (`LOCAL_ONLY_SECRET_PREFIXES`) at exactly these two chokepoints. The new rule sits beside it. It is
55
+ kept separate because the existing rule matches dot-segments and cannot express a top-level name
56
+ prefix.
57
+
58
+ ## 4. Signal vs authority compliance
59
+
60
+ The receiver drop is a deterministic data-policy rule on a closed, named key family, not a brittle
61
+ detector judging content. It can only withhold a copy; it never deletes or blocks anything else. That
62
+ is the same shape as the existing `machineIdentityRecovery` rule. The read-log is signal only.
63
+
64
+ ## 4b. Judgment-point check (Judgment Within Floors standard)
65
+
66
+ Invariant, not a judgment point: the rule is a fixed key-name policy with no competing signals
67
+ (spec §10, "Machine-scope guard" family).
68
+
69
+ ## 5. Interactions
70
+
71
+ - `SecretProvisioner.provisionAll`: when every secret is a prototype passkey, it now sends nothing
72
+ (the existing empty-set early return). This is tested.
73
+ - The mesh `secret-share` handler returns the handler result as the response. The new `dropped` field
74
+ is additive and senders ignore unknown fields; it carries key NAMES back to the sender, never values
75
+ (the sender already knew those names, since it sent them).
76
+ - The receiver's drop is recorded in the server log (durable, `logs/server.log`), not a separate audit
77
+ file. That is accepted as the audit for this increment.
78
+ - `AccountCredentialShare` is unaffected; it uses its own verb.
79
+ - `/secrets/sync-status` lists local key paths only and is unchanged.
80
+
81
+ ## 6. External surfaces
82
+
83
+ Other machines receive fewer secrets: the seven prototype keys stop arriving. No user-visible
84
+ message. The new log file is local and holds no secret values.
85
+
86
+ ## 6b. Operator-surface quality (Operator-Surface Quality standard)
87
+
88
+ No operator-facing surface in this increment. The dashboard per-key choice comes in a later increment.
89
+
90
+ ## 7. Multi-machine posture (Cross-Machine Coherence)
91
+
92
+ This change exists to make prototype passkeys machine-local, per the operator-ratified exception in
93
+ the spec (§12, FD2). Mixed versions are covered in both directions:
94
+ - An old sender pushing to a new receiver: the keys are dropped, the rest is stored (tested).
95
+ - A new sender pushing to an old receiver: the old receiver simply stops receiving prototype keys.
96
+
97
+ `passkey-legacy-reads.jsonl` is a per-machine audit log by design.
98
+
99
+ ## 8. Rollback cost
100
+
101
+ Pure code change. Reverting restores the old copy-everything behaviour; there is no persistent state
102
+ to migrate. The audit log can be left in place or deleted.
103
+
104
+ ---
105
+
106
+ ## Conclusion
107
+
108
+ A small, restrictive-only first step that stops the spread of machine-bound credentials without
109
+ breaking the prototype scripts. Clear to ship after the second-pass review.
110
+
111
+ ---
112
+
113
+ ## Second-pass review (if required)
114
+
115
+ **Reviewer:** independent second-pass subagent
116
+ **Independent read of the artifact: concur**
117
+
118
+ Concurred after checking the diff and running the 21 tests. The four minor points it raised
119
+ (case-sensitivity, log-only audit for drops, direct SecretStore reads not logged, dropped names in
120
+ the mesh response) are now stated above.
121
+
122
+ ---
123
+
124
+ ## Evidence pointers
125
+
126
+ - `tests/unit/secret-sync-legacy-passkey.test.ts` (8 tests: matcher, sender filter, provisioner payload, mixed-version receiver, never-delete, recovery-namespace still rejected).
127
+ - `tests/unit/secret-get-legacy-passkey-read-log.test.ts` (read allowed + audit line with no value; ordinary keys not logged).
128
+ - Existing `tests/unit/secret-sync.test.ts` and `secret-sync-key-policy-wiring.test.ts` pass unchanged.
129
+
130
+ ---
131
+
132
+ ## Class-Closure Declaration (display-only mirror)
133
+
134
+ No agent-authored-artifact defect — not applicable. This is new policy from an approved spec, not a
135
+ fix to a prompt, hook, config, skill or standards text, and it adds no self-triggered controller.