instar 1.3.704 → 1.3.705

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.
Files changed (67) hide show
  1. package/dist/commands/server.d.ts.map +1 -1
  2. package/dist/commands/server.js +216 -17
  3. package/dist/commands/server.js.map +1 -1
  4. package/dist/core/DeliverMessageHandler.d.ts +16 -0
  5. package/dist/core/DeliverMessageHandler.d.ts.map +1 -1
  6. package/dist/core/DeliverMessageHandler.js +0 -0
  7. package/dist/core/DeliverMessageHandler.js.map +1 -1
  8. package/dist/core/PostUpdateMigrator.d.ts +15 -0
  9. package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
  10. package/dist/core/PostUpdateMigrator.js +108 -0
  11. package/dist/core/PostUpdateMigrator.js.map +1 -1
  12. package/dist/core/QueueDrainLoop.d.ts +6 -2
  13. package/dist/core/QueueDrainLoop.d.ts.map +1 -1
  14. package/dist/core/QueueDrainLoop.js +0 -0
  15. package/dist/core/QueueDrainLoop.js.map +1 -1
  16. package/dist/core/SessionRouter.d.ts +24 -4
  17. package/dist/core/SessionRouter.d.ts.map +1 -1
  18. package/dist/core/SessionRouter.js +25 -2
  19. package/dist/core/SessionRouter.js.map +1 -1
  20. package/dist/core/meshRejectionLog.d.ts +37 -0
  21. package/dist/core/meshRejectionLog.d.ts.map +1 -0
  22. package/dist/core/meshRejectionLog.js +73 -0
  23. package/dist/core/meshRejectionLog.js.map +1 -0
  24. package/dist/core/registryHighWater.d.ts +59 -0
  25. package/dist/core/registryHighWater.d.ts.map +1 -0
  26. package/dist/core/registryHighWater.js +120 -0
  27. package/dist/core/registryHighWater.js.map +1 -0
  28. package/dist/core/senderRejectionNotice.d.ts +89 -0
  29. package/dist/core/senderRejectionNotice.d.ts.map +1 -0
  30. package/dist/core/senderRejectionNotice.js +149 -0
  31. package/dist/core/senderRejectionNotice.js.map +1 -0
  32. package/dist/core/senderValidationGate.d.ts +80 -0
  33. package/dist/core/senderValidationGate.d.ts.map +1 -0
  34. package/dist/core/senderValidationGate.js +133 -0
  35. package/dist/core/senderValidationGate.js.map +1 -0
  36. package/dist/core/types.d.ts +12 -0
  37. package/dist/core/types.d.ts.map +1 -1
  38. package/dist/core/types.js.map +1 -1
  39. package/dist/messaging/MessageProcessingLedger.d.ts +33 -5
  40. package/dist/messaging/MessageProcessingLedger.d.ts.map +1 -1
  41. package/dist/messaging/MessageProcessingLedger.js +50 -7
  42. package/dist/messaging/MessageProcessingLedger.js.map +1 -1
  43. package/dist/messaging/ingressDedup.d.ts.map +1 -1
  44. package/dist/messaging/ingressDedup.js +9 -0
  45. package/dist/messaging/ingressDedup.js.map +1 -1
  46. package/dist/scaffold/templates.d.ts.map +1 -1
  47. package/dist/scaffold/templates.js +2 -1
  48. package/dist/scaffold/templates.js.map +1 -1
  49. package/dist/server/CapabilityIndex.d.ts.map +1 -1
  50. package/dist/server/CapabilityIndex.js +1 -0
  51. package/dist/server/CapabilityIndex.js.map +1 -1
  52. package/dist/server/routes.d.ts.map +1 -1
  53. package/dist/server/routes.js +36 -0
  54. package/dist/server/routes.js.map +1 -1
  55. package/dist/users/UserManager.d.ts +22 -1
  56. package/dist/users/UserManager.d.ts.map +1 -1
  57. package/dist/users/UserManager.js +87 -2
  58. package/dist/users/UserManager.js.map +1 -1
  59. package/dist/users/testIdentityMarkers.d.ts +94 -0
  60. package/dist/users/testIdentityMarkers.d.ts.map +1 -0
  61. package/dist/users/testIdentityMarkers.js +170 -0
  62. package/dist/users/testIdentityMarkers.js.map +1 -0
  63. package/package.json +1 -1
  64. package/src/data/builtin-manifest.json +63 -63
  65. package/src/scaffold/templates.ts +2 -1
  66. package/upgrades/1.3.705.md +79 -0
  67. package/upgrades/side-effects/silent-loss-refusal-conservation.md +124 -0
@@ -27,9 +27,30 @@ export declare class UserManager {
27
27
  private users;
28
28
  private channelIndex;
29
29
  private usersFile;
30
+ private readonly stateDir;
31
+ /**
32
+ * silent-loss-refusal-conservation §2.D — the server-held HMAC key that
33
+ * verifies a signed `allowTestIdentity` marker on a legitimate fixture-collision
34
+ * profile. Loaded only by the server process (NOT authToken/dashboardPin).
35
+ * Absent (CLI / read-only probe / tests) → a fixture-collision profile is
36
+ * refused (write) / skipped (load) unless the double-keyed test escape is on —
37
+ * a marker can be neither minted nor verified without the key (safe direction).
38
+ */
39
+ private readonly testIdentityKey;
30
40
  /** WS2.6 user-record replication emitter (injected, dark by default). Absent ⇒ strict no-op. */
31
41
  private userReplication;
32
- constructor(stateDir: string, initialUsers?: UserProfile[]);
42
+ constructor(stateDir: string, initialUsers?: UserProfile[], opts?: {
43
+ testIdentityKey?: string;
44
+ });
45
+ /**
46
+ * silent-loss-refusal-conservation §2.D — is a fixture-identity write/load
47
+ * PERMITTED for this profile? A match is permitted only when (a) the
48
+ * double-keyed test escape is active (env + on-disk test-home marker) OR (b) the
49
+ * profile carries a signed `allowTestIdentity` marker that VERIFIES under the
50
+ * server key (a legitimate name-collision, dashboard-PIN-minted). Returns the
51
+ * matched marker string when the write/load must be REFUSED, or null when it is
52
+ * permitted (either no match, or an accepted override). */
53
+ private refusedTestIdentity;
33
54
  /**
34
55
  * Late-bind the WS2.6 user-record replication emitter (server.ts constructs the journal/clock
35
56
  * AFTER the manager). Idempotent; passing undefined/null detaches (back to single-machine
@@ -1 +1 @@
1
- {"version":3,"file":"UserManager.d.ts","sourceRoot":"","sources":["../../src/users/UserManager.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAG1E;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,sBAAsB;IACrC,kFAAkF;IAClF,OAAO,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI,CAAC;IACnC,gFAAgF;IAChF,UAAU,CAAC,QAAQ,EAAE,WAAW,EAAE,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9D;AAED,qBAAa,WAAW;IACtB,OAAO,CAAC,KAAK,CAAuC;IACpD,OAAO,CAAC,YAAY,CAAkC;IACtD,OAAO,CAAC,SAAS,CAAS;IAC1B,gGAAgG;IAChG,OAAO,CAAC,eAAe,CAAuC;gBAElD,QAAQ,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,WAAW,EAAE;IAK1D;;;;;OAKG;IACH,yBAAyB,CAAC,OAAO,EAAE,sBAAsB,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI;IAInF;;;OAGG;IACH,kBAAkB,CAAC,OAAO,EAAE,OAAO,GAAG,WAAW,GAAG,IAAI;IAIxD;;OAEG;IACH,kBAAkB,CAAC,OAAO,EAAE,WAAW,GAAG,WAAW,GAAG,IAAI;IAO5D;;;;;;;OAOG;IACH,yBAAyB,CAAC,cAAc,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI;IAQrE;;;;;;;OAOG;IACH,sBAAsB,CAAC,WAAW,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI;IAW/D;;OAEG;IACH,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI;IAI3C;;OAEG;IACH,SAAS,IAAI,WAAW,EAAE;IAI1B;;OAEG;IACH,UAAU,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI;IA6BtC;;OAEG;IACH,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IA4BnC;;OAEG;IACH,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO;IAM1D;;;OAGG;IACH,kBAAkB,CAAC,cAAc,EAAE,OAAO,CAAC,WAAW,CAAC,GAAG;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,WAAW;IAYpG;;;OAGG;IACH,qBAAqB,IAAI,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC;IAQpF;;OAEG;IACH,SAAS,IAAI,WAAW,EAAE;IAI1B,OAAO,CAAC,eAAe;IAYvB,OAAO,CAAC,SAAS;IAoCjB,OAAO,CAAC,YAAY;CA+BrB"}
1
+ {"version":3,"file":"UserManager.d.ts","sourceRoot":"","sources":["../../src/users/UserManager.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAU1E;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,sBAAsB;IACrC,kFAAkF;IAClF,OAAO,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI,CAAC;IACnC,gFAAgF;IAChF,UAAU,CAAC,QAAQ,EAAE,WAAW,EAAE,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9D;AAED,qBAAa,WAAW;IACtB,OAAO,CAAC,KAAK,CAAuC;IACpD,OAAO,CAAC,YAAY,CAAkC;IACtD,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC;;;;;;;OAOG;IACH,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAqB;IACrD,gGAAgG;IAChG,OAAO,CAAC,eAAe,CAAuC;gBAElD,QAAQ,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,WAAW,EAAE,EAAE,IAAI,CAAC,EAAE;QAAE,eAAe,CAAC,EAAE,MAAM,CAAA;KAAE;IAO/F;;;;;;;+DAO2D;IAC3D,OAAO,CAAC,mBAAmB;IAQ3B;;;;;OAKG;IACH,yBAAyB,CAAC,OAAO,EAAE,sBAAsB,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI;IAInF;;;OAGG;IACH,kBAAkB,CAAC,OAAO,EAAE,OAAO,GAAG,WAAW,GAAG,IAAI;IAIxD;;OAEG;IACH,kBAAkB,CAAC,OAAO,EAAE,WAAW,GAAG,WAAW,GAAG,IAAI;IAO5D;;;;;;;OAOG;IACH,yBAAyB,CAAC,cAAc,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI;IAQrE;;;;;;;OAOG;IACH,sBAAsB,CAAC,WAAW,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI;IAW/D;;OAEG;IACH,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI;IAI3C;;OAEG;IACH,SAAS,IAAI,WAAW,EAAE;IAI1B;;OAEG;IACH,UAAU,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI;IAmCtC;;OAEG;IACH,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IA4BnC;;OAEG;IACH,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO;IAM1D;;;OAGG;IACH,kBAAkB,CAAC,cAAc,EAAE,OAAO,CAAC,WAAW,CAAC,GAAG;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,WAAW;IAYpG;;;OAGG;IACH,qBAAqB,IAAI,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC;IAQpF;;OAEG;IACH,SAAS,IAAI,WAAW,EAAE;IAI1B,OAAO,CAAC,eAAe;IAsBvB,OAAO,CAAC,SAAS;IAsEjB,OAAO,CAAC,YAAY;CA+BrB"}
@@ -8,16 +8,48 @@ import fs from 'node:fs';
8
8
  import path from 'node:path';
9
9
  import { randomBytes } from 'node:crypto';
10
10
  import { SafeFsExecutor } from '../core/SafeFsExecutor.js';
11
+ import { matchTestIdentity, testIdentitiesAllowed, verifyAllowTestIdentity, TestIdentityRefusedError, } from './testIdentityMarkers.js';
12
+ import { setRegistryHighWater } from '../core/registryHighWater.js';
11
13
  export class UserManager {
12
14
  users = new Map();
13
15
  channelIndex = new Map(); // "type:identifier" -> userId
14
16
  usersFile;
17
+ stateDir;
18
+ /**
19
+ * silent-loss-refusal-conservation §2.D — the server-held HMAC key that
20
+ * verifies a signed `allowTestIdentity` marker on a legitimate fixture-collision
21
+ * profile. Loaded only by the server process (NOT authToken/dashboardPin).
22
+ * Absent (CLI / read-only probe / tests) → a fixture-collision profile is
23
+ * refused (write) / skipped (load) unless the double-keyed test escape is on —
24
+ * a marker can be neither minted nor verified without the key (safe direction).
25
+ */
26
+ testIdentityKey;
15
27
  /** WS2.6 user-record replication emitter (injected, dark by default). Absent ⇒ strict no-op. */
16
28
  userReplication = null;
17
- constructor(stateDir, initialUsers) {
29
+ constructor(stateDir, initialUsers, opts) {
18
30
  this.usersFile = path.join(stateDir, 'users.json');
31
+ this.stateDir = stateDir;
32
+ this.testIdentityKey = opts?.testIdentityKey;
19
33
  this.loadUsers(initialUsers);
20
34
  }
35
+ /**
36
+ * silent-loss-refusal-conservation §2.D — is a fixture-identity write/load
37
+ * PERMITTED for this profile? A match is permitted only when (a) the
38
+ * double-keyed test escape is active (env + on-disk test-home marker) OR (b) the
39
+ * profile carries a signed `allowTestIdentity` marker that VERIFIES under the
40
+ * server key (a legitimate name-collision, dashboard-PIN-minted). Returns the
41
+ * matched marker string when the write/load must be REFUSED, or null when it is
42
+ * permitted (either no match, or an accepted override). */
43
+ refusedTestIdentity(profile) {
44
+ const marker = matchTestIdentity(profile);
45
+ if (!marker)
46
+ return null;
47
+ if (testIdentitiesAllowed(this.stateDir))
48
+ return null;
49
+ if (verifyAllowTestIdentity(this.testIdentityKey, profile.id, marker, profile.allowTestIdentity))
50
+ return null;
51
+ return marker;
52
+ }
21
53
  /**
22
54
  * Late-bind the WS2.6 user-record replication emitter (server.ts constructs the journal/clock
23
55
  * AFTER the manager). Idempotent; passing undefined/null detaches (back to single-machine
@@ -120,6 +152,14 @@ export class UserManager {
120
152
  this.channelIndex.set(`${channel.type}:${channel.identifier}`, profile.id);
121
153
  }
122
154
  this.persistUsers();
155
+ // silent-loss-refusal-conservation §2.D set-point: a successful register/upsert
156
+ // of a (validated non-fixture) user means the authoritative local registry now
157
+ // holds a real user — set the monotonic high-water marker so a later emptying
158
+ // classifies POPULATED (emptied-by-deletion), not never-populated.
159
+ try {
160
+ setRegistryHighWater(this.stateDir, 'user-registered');
161
+ }
162
+ catch { /* best-effort */ }
123
163
  }
124
164
  /**
125
165
  * Remove a user.
@@ -201,6 +241,16 @@ export class UserManager {
201
241
  if (!Array.isArray(profile.permissions)) {
202
242
  throw new Error(`UserProfile(${profile.id}).permissions must be an array`);
203
243
  }
244
+ // silent-loss-refusal-conservation §2.D — fixture refusal at the WRITE path
245
+ // (API/CLI/registration). "Test Identity Never Enters Production State": a
246
+ // typed throw so a fixture id can never be persisted into the production
247
+ // registry (the 2026-07-01 clobber's write side). A legitimate name-collision
248
+ // supplies a dashboard-PIN-minted signed `allowTestIdentity`; an isolated test
249
+ // home sets the double-keyed escape.
250
+ const refused = this.refusedTestIdentity(profile);
251
+ if (refused) {
252
+ throw new TestIdentityRefusedError(profile.id, refused);
253
+ }
204
254
  }
205
255
  loadUsers(initialUsers) {
206
256
  // Load from file if exists
@@ -213,6 +263,19 @@ export class UserManager {
213
263
  console.warn(`[UserManager] Skipping malformed user entry: ${JSON.stringify(user).slice(0, 100)}`);
214
264
  continue;
215
265
  }
266
+ // silent-loss-refusal-conservation §2.D — fixture refusal at the LOAD
267
+ // path. Refuse-and-skip-with-loud-alert (NEVER throw — a constructor
268
+ // throw fails boot). A fixture row that slipped into an already-polluted
269
+ // store is dropped from the in-memory registry so it can never resolve
270
+ // as a real sender; the §4 boot migration quarantines it off disk.
271
+ const refused = this.refusedTestIdentity(user);
272
+ if (refused) {
273
+ console.error(`[UserManager] REFUSING to load fixture/test identity "${user.id}" (matched marker "${refused}") from the user registry ` +
274
+ `— "Test Identity Never Enters Production State" (silent-loss-refusal-conservation §2.D). ` +
275
+ `The row is skipped in-memory; the boot migration quarantines it off disk. ` +
276
+ `If this is a legitimate user, register them via the dashboard-PIN-authed allow-identity override.`);
277
+ continue;
278
+ }
216
279
  this.users.set(user.id, user);
217
280
  for (const channel of user.channels) {
218
281
  if (channel.type && channel.identifier) {
@@ -235,10 +298,32 @@ export class UserManager {
235
298
  if (initialUsers) {
236
299
  for (const user of initialUsers) {
237
300
  if (!this.users.has(user.id)) {
238
- this.upsertUser(user);
301
+ // upsertUser → validateProfile refuses a fixture initialUsers entry
302
+ // (typed throw). Guard so a fixture in config.users can't fail boot;
303
+ // a real initialUsers merge below sets the high-water marker.
304
+ try {
305
+ this.upsertUser(user);
306
+ }
307
+ catch (err) {
308
+ if (err instanceof TestIdentityRefusedError) {
309
+ console.error(`[UserManager] Skipped fixture identity from initialUsers: ${err.message}`);
310
+ continue;
311
+ }
312
+ throw err;
313
+ }
239
314
  }
240
315
  }
241
316
  }
317
+ // silent-loss-refusal-conservation §2.D set-point: if the authoritative local
318
+ // registry holds ≥1 resolvable real user, this machine has "held a real user"
319
+ // — set the monotonic high-water marker so a LATER emptying classifies as
320
+ // POPULATED (emptied-by-deletion → keep rejecting), not never-populated.
321
+ if (this.users.size > 0) {
322
+ try {
323
+ setRegistryHighWater(this.stateDir, 'load-observed-real-user');
324
+ }
325
+ catch { /* best-effort */ }
326
+ }
242
327
  }
243
328
  persistUsers() {
244
329
  const dir = path.dirname(this.usersFile);
@@ -1 +1 @@
1
- {"version":3,"file":"UserManager.js","sourceRoot":"","sources":["../../src/users/UserManager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"UserManager.js","sourceRoot":"","sources":["../../src/users/UserManager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,94 @@
1
+ /**
2
+ * Test-Identity Refusal (silent-loss-refusal-conservation §2.D — "Test Identity
3
+ * Never Enters Production State"). The 2026-07-01 silent-loss incident began 19
4
+ * days earlier when a live-test / harness run clobbered a machine's `users.json`
5
+ * with FIXTURE identities. A registry populated with only fixtures rejects every
6
+ * real sender (including the operator) once sender re-validation arms.
7
+ *
8
+ * This module is the single source of truth for WHICH identities are fixtures
9
+ * and HOW a legitimate name-collision is overridden. It is pure + dependency-free
10
+ * so both the write-path guard (UserManager.validateProfile — typed throw) and the
11
+ * load-path guard (UserManager.loadUsers — refuse-and-skip, never throw) and the
12
+ * §4 boot remediation share ONE matcher and can never drift.
13
+ *
14
+ * MATCH RULE (round-2 adversarial #10): exact match on the known fixture platform
15
+ * IDS + reserved-token anchored prefixes on ids — DISPLAY NAME IS NEVER A MATCH
16
+ * CRITERION (a real user named "Olivia" registers fine). See §2.D / decision 3.
17
+ */
18
+ import type { UserProfile } from '../core/types.js';
19
+ /**
20
+ * The closed fixture-identity set. IDS + reserved tokens only — never a
21
+ * display-name. Exact-match on the known platform ids; anchored-prefix match on
22
+ * the reserved `livetest`/`g3test` tokens.
23
+ *
24
+ * - `slackIds` — the demo Slack workspace user ids used by the live-test harness.
25
+ * - `harnessIds` — the `u-*` / `U_*` fixture user ids the integration harness writes.
26
+ * - `reservedTokenPrefixes` — anchored id/username prefixes the isolated test-home
27
+ * scaffold uses (`livetest…`, `g3test…`).
28
+ */
29
+ export declare const TEST_IDENTITY_MARKERS: {
30
+ readonly slackIds: readonly ["U0BA7QGPBQS", "U0BA5NW9QA2", "U0B9SFJ7QAK", "U0B9SFV2BAT", "U0BA4L8RMFF"];
31
+ readonly harnessIds: readonly ["u-olivia", "u-adam", "u-mia", "u-cory", "u-oscar", "U_OLIVIA", "U_ADAM", "U_MIA", "U_CORY", "U_OSCAR"];
32
+ readonly reservedTokenPrefixes: readonly ["livetest", "g3test"];
33
+ };
34
+ /**
35
+ * Does a single string token match a fixture marker? Exact match against the
36
+ * known-id set, OR an anchored (^) reserved-token prefix. Case-sensitive on the
37
+ * exact set (platform ids are case-significant); the reserved-token prefix is
38
+ * matched case-INsensitively (a `LiveTest…` id is still a fixture).
39
+ */
40
+ export declare function matchesTestIdentityToken(token: string | undefined | null): string | null;
41
+ /**
42
+ * Classify a profile against the fixture-identity set. Checks the id, the Slack
43
+ * user id, and slack-typed channel identifiers — NEVER the display name.
44
+ * Returns the matched marker string (for the audit + the allow-marker) or null.
45
+ */
46
+ export declare function matchTestIdentity(profile: Pick<UserProfile, 'id' | 'slackUserId' | 'channels'>): string | null;
47
+ /** Typed error thrown by the WRITE path (validateProfile) when a fixture identity
48
+ * is written without a verifying allow-marker + the double-keyed test escape. */
49
+ export declare class TestIdentityRefusedError extends Error {
50
+ readonly marker: string;
51
+ constructor(profileId: string, marker: string);
52
+ }
53
+ /** The on-disk marker a test home's scaffold writes to opt that home into
54
+ * fixture-identity writes. Its PRESENCE is the second key; contents are ignored. */
55
+ export declare const TEST_HOME_MARKER_FILENAME = ".instar-test-home";
56
+ /**
57
+ * The narrow escape is double-keyed (§2.D / decision 11): the env var
58
+ * `INSTAR_ALLOW_TEST_IDENTITIES=1` is honored ONLY when an on-disk test-home
59
+ * marker is ALSO present under the state dir. Env-set-but-marker-absent → refuse
60
+ * (a stray env var on a production box can never open the door).
61
+ */
62
+ export declare function testIdentitiesAllowed(stateDir: string, env?: NodeJS.ProcessEnv): boolean;
63
+ /**
64
+ * A profile that legitimately collides with a fixture marker carries a signed
65
+ * allow-marker `{ marker, sig }`. The PIN gates MINTING (the route); the LOAD
66
+ * path VERIFIES the HMAC with no PIN. `sig = HMAC-SHA256(serverKey, userId + ":" + marker)`
67
+ * where `serverKey` is a server-held vault secret loaded only by the server
68
+ * process — NOT the authToken/dashboardPin, NOT a state-dir file a plain
69
+ * users.json writer reads (§2.D / decision 23, honest threat model).
70
+ */
71
+ export interface AllowTestIdentityMarker {
72
+ marker: string;
73
+ sig: string;
74
+ }
75
+ /**
76
+ * Derive the server-held allow-marker HMAC key from the machine SIGNING key PEM
77
+ * — a server-held secret loaded only by the server process, NOT the
78
+ * authToken/dashboardPin and NOT users.json (§2.D / decision 23, honest scope:
79
+ * a fully-FS-privileged process is out of scope). Returns undefined when no
80
+ * signing key exists (a single-machine non-mesh install) — then a fixture
81
+ * override can be neither minted nor verified (the safe direction). The raw PEM
82
+ * is never used directly; the key is a domain-separated hash of it.
83
+ */
84
+ export declare function loadTestIdentityKey(stateDir: string): string | undefined;
85
+ /** Mint the HMAC signature for a legitimate fixture-collision override. */
86
+ export declare function signAllowTestIdentity(serverKey: string, userId: string, marker: string): string;
87
+ /**
88
+ * Verify a profile's signed allow-marker on the LOAD path (no PIN present).
89
+ * Constant-time compare. Returns true iff the profile carries an
90
+ * `allowTestIdentity` whose `marker` equals the matched marker AND whose `sig`
91
+ * recomputes under the server key. A missing/bogus sig → false → quarantine.
92
+ */
93
+ export declare function verifyAllowTestIdentity(serverKey: string | undefined | null, userId: string, matchedMarker: string, allow: AllowTestIdentityMarker | undefined | null): boolean;
94
+ //# sourceMappingURL=testIdentityMarkers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"testIdentityMarkers.d.ts","sourceRoot":"","sources":["../../src/users/testIdentityMarkers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAKH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAEpD;;;;;;;;;GASG;AACH,eAAO,MAAM,qBAAqB;;;;CAOxB,CAAC;AAOX;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,CAQxF;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,IAAI,CAAC,WAAW,EAAE,IAAI,GAAG,aAAa,GAAG,UAAU,CAAC,GAAG,MAAM,GAAG,IAAI,CAc9G;AAED;kFACkF;AAClF,qBAAa,wBAAyB,SAAQ,KAAK;IACjD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;gBACZ,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;CAU9C;AAID;qFACqF;AACrF,eAAO,MAAM,yBAAyB,sBAAsB,CAAC;AAE7D;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,OAAO,CAOrG;AAID;;;;;;;GAOG;AACH,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;CACb;AAMD;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAUxE;AAED,2EAA2E;AAC3E,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAE/F;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,EACpC,MAAM,EAAE,MAAM,EACd,aAAa,EAAE,MAAM,EACrB,KAAK,EAAE,uBAAuB,GAAG,SAAS,GAAG,IAAI,GAChD,OAAO,CAaT"}
@@ -0,0 +1,170 @@
1
+ /**
2
+ * Test-Identity Refusal (silent-loss-refusal-conservation §2.D — "Test Identity
3
+ * Never Enters Production State"). The 2026-07-01 silent-loss incident began 19
4
+ * days earlier when a live-test / harness run clobbered a machine's `users.json`
5
+ * with FIXTURE identities. A registry populated with only fixtures rejects every
6
+ * real sender (including the operator) once sender re-validation arms.
7
+ *
8
+ * This module is the single source of truth for WHICH identities are fixtures
9
+ * and HOW a legitimate name-collision is overridden. It is pure + dependency-free
10
+ * so both the write-path guard (UserManager.validateProfile — typed throw) and the
11
+ * load-path guard (UserManager.loadUsers — refuse-and-skip, never throw) and the
12
+ * §4 boot remediation share ONE matcher and can never drift.
13
+ *
14
+ * MATCH RULE (round-2 adversarial #10): exact match on the known fixture platform
15
+ * IDS + reserved-token anchored prefixes on ids — DISPLAY NAME IS NEVER A MATCH
16
+ * CRITERION (a real user named "Olivia" registers fine). See §2.D / decision 3.
17
+ */
18
+ import crypto from 'node:crypto';
19
+ import fs from 'node:fs';
20
+ import path from 'node:path';
21
+ /**
22
+ * The closed fixture-identity set. IDS + reserved tokens only — never a
23
+ * display-name. Exact-match on the known platform ids; anchored-prefix match on
24
+ * the reserved `livetest`/`g3test` tokens.
25
+ *
26
+ * - `slackIds` — the demo Slack workspace user ids used by the live-test harness.
27
+ * - `harnessIds` — the `u-*` / `U_*` fixture user ids the integration harness writes.
28
+ * - `reservedTokenPrefixes` — anchored id/username prefixes the isolated test-home
29
+ * scaffold uses (`livetest…`, `g3test…`).
30
+ */
31
+ export const TEST_IDENTITY_MARKERS = {
32
+ slackIds: ['U0BA7QGPBQS', 'U0BA5NW9QA2', 'U0B9SFJ7QAK', 'U0B9SFV2BAT', 'U0BA4L8RMFF'],
33
+ harnessIds: [
34
+ 'u-olivia', 'u-adam', 'u-mia', 'u-cory', 'u-oscar',
35
+ 'U_OLIVIA', 'U_ADAM', 'U_MIA', 'U_CORY', 'U_OSCAR',
36
+ ],
37
+ reservedTokenPrefixes: ['livetest', 'g3test'],
38
+ };
39
+ const EXACT_IDS = new Set([
40
+ ...TEST_IDENTITY_MARKERS.slackIds,
41
+ ...TEST_IDENTITY_MARKERS.harnessIds,
42
+ ]);
43
+ /**
44
+ * Does a single string token match a fixture marker? Exact match against the
45
+ * known-id set, OR an anchored (^) reserved-token prefix. Case-sensitive on the
46
+ * exact set (platform ids are case-significant); the reserved-token prefix is
47
+ * matched case-INsensitively (a `LiveTest…` id is still a fixture).
48
+ */
49
+ export function matchesTestIdentityToken(token) {
50
+ if (typeof token !== 'string' || !token)
51
+ return null;
52
+ if (EXACT_IDS.has(token))
53
+ return token;
54
+ const lower = token.toLowerCase();
55
+ for (const prefix of TEST_IDENTITY_MARKERS.reservedTokenPrefixes) {
56
+ if (lower.startsWith(prefix))
57
+ return token;
58
+ }
59
+ return null;
60
+ }
61
+ /**
62
+ * Classify a profile against the fixture-identity set. Checks the id, the Slack
63
+ * user id, and slack-typed channel identifiers — NEVER the display name.
64
+ * Returns the matched marker string (for the audit + the allow-marker) or null.
65
+ */
66
+ export function matchTestIdentity(profile) {
67
+ const idMatch = matchesTestIdentityToken(profile.id);
68
+ if (idMatch)
69
+ return idMatch;
70
+ const slackMatch = matchesTestIdentityToken(profile.slackUserId ?? null);
71
+ if (slackMatch)
72
+ return slackMatch;
73
+ if (Array.isArray(profile.channels)) {
74
+ for (const ch of profile.channels) {
75
+ if (ch && ch.type === 'slack') {
76
+ const chMatch = matchesTestIdentityToken(ch.identifier);
77
+ if (chMatch)
78
+ return chMatch;
79
+ }
80
+ }
81
+ }
82
+ return null;
83
+ }
84
+ /** Typed error thrown by the WRITE path (validateProfile) when a fixture identity
85
+ * is written without a verifying allow-marker + the double-keyed test escape. */
86
+ export class TestIdentityRefusedError extends Error {
87
+ marker;
88
+ constructor(profileId, marker) {
89
+ super(`Refusing to persist test/fixture identity "${profileId}" (matched marker "${marker}") into the production user registry ` +
90
+ `— "Test Identity Never Enters Production State" (silent-loss-refusal-conservation §2.D). ` +
91
+ `A legitimate name-collision uses the dashboard-PIN-authed X-Instar-Allow-Identity override; ` +
92
+ `an isolated test home sets INSTAR_ALLOW_TEST_IDENTITIES=1 plus the on-disk test-home marker.`);
93
+ this.name = 'TestIdentityRefusedError';
94
+ this.marker = marker;
95
+ }
96
+ }
97
+ // ── Double-keyed test escape (env + on-disk test-home marker) ────────────────
98
+ /** The on-disk marker a test home's scaffold writes to opt that home into
99
+ * fixture-identity writes. Its PRESENCE is the second key; contents are ignored. */
100
+ export const TEST_HOME_MARKER_FILENAME = '.instar-test-home';
101
+ /**
102
+ * The narrow escape is double-keyed (§2.D / decision 11): the env var
103
+ * `INSTAR_ALLOW_TEST_IDENTITIES=1` is honored ONLY when an on-disk test-home
104
+ * marker is ALSO present under the state dir. Env-set-but-marker-absent → refuse
105
+ * (a stray env var on a production box can never open the door).
106
+ */
107
+ export function testIdentitiesAllowed(stateDir, env = process.env) {
108
+ if (env.INSTAR_ALLOW_TEST_IDENTITIES !== '1')
109
+ return false;
110
+ try {
111
+ return fs.existsSync(path.join(stateDir, TEST_HOME_MARKER_FILENAME));
112
+ }
113
+ catch {
114
+ return false;
115
+ }
116
+ }
117
+ function allowMarkerMessage(userId, marker) {
118
+ return `${userId}:${marker}`;
119
+ }
120
+ /**
121
+ * Derive the server-held allow-marker HMAC key from the machine SIGNING key PEM
122
+ * — a server-held secret loaded only by the server process, NOT the
123
+ * authToken/dashboardPin and NOT users.json (§2.D / decision 23, honest scope:
124
+ * a fully-FS-privileged process is out of scope). Returns undefined when no
125
+ * signing key exists (a single-machine non-mesh install) — then a fixture
126
+ * override can be neither minted nor verified (the safe direction). The raw PEM
127
+ * is never used directly; the key is a domain-separated hash of it.
128
+ */
129
+ export function loadTestIdentityKey(stateDir) {
130
+ for (const name of ['signing-key.pem', 'signing-private.pem']) {
131
+ try {
132
+ const pem = fs.readFileSync(path.join(stateDir, 'machine', name), 'utf-8');
133
+ if (pem && pem.trim()) {
134
+ return crypto.createHash('sha256').update(`instar-test-identity-allow:${pem}`).digest('hex');
135
+ }
136
+ }
137
+ catch { /* try next / none */ }
138
+ }
139
+ return undefined;
140
+ }
141
+ /** Mint the HMAC signature for a legitimate fixture-collision override. */
142
+ export function signAllowTestIdentity(serverKey, userId, marker) {
143
+ return crypto.createHmac('sha256', serverKey).update(allowMarkerMessage(userId, marker)).digest('hex');
144
+ }
145
+ /**
146
+ * Verify a profile's signed allow-marker on the LOAD path (no PIN present).
147
+ * Constant-time compare. Returns true iff the profile carries an
148
+ * `allowTestIdentity` whose `marker` equals the matched marker AND whose `sig`
149
+ * recomputes under the server key. A missing/bogus sig → false → quarantine.
150
+ */
151
+ export function verifyAllowTestIdentity(serverKey, userId, matchedMarker, allow) {
152
+ if (!serverKey)
153
+ return false;
154
+ if (!allow || typeof allow.marker !== 'string' || typeof allow.sig !== 'string')
155
+ return false;
156
+ if (allow.marker !== matchedMarker)
157
+ return false;
158
+ const expected = signAllowTestIdentity(serverKey, userId, matchedMarker);
159
+ try {
160
+ const a = Buffer.from(expected, 'hex');
161
+ const b = Buffer.from(allow.sig, 'hex');
162
+ if (a.length !== b.length || a.length === 0)
163
+ return false;
164
+ return crypto.timingSafeEqual(a, b);
165
+ }
166
+ catch {
167
+ return false;
168
+ }
169
+ }
170
+ //# sourceMappingURL=testIdentityMarkers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"testIdentityMarkers.js","sourceRoot":"","sources":["../../src/users/testIdentityMarkers.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "instar",
3
- "version": "1.3.704",
3
+ "version": "1.3.705",
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",