switchroom 0.19.32 → 0.19.34

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.
@@ -4012,6 +4012,410 @@ var init_zod = __esm(() => {
4012
4012
  init_external();
4013
4013
  });
4014
4014
 
4015
+ // src/vault/broker/peercred-ffi.ts
4016
+ function getPeerCred(fd) {
4017
+ if (process.platform !== "linux")
4018
+ return null;
4019
+ try {
4020
+ const ffi = __require("bun:ffi");
4021
+ const { dlopen, FFIType, ptr } = ffi;
4022
+ const SOL_SOCKET = 1;
4023
+ const SO_PEERCRED = 17;
4024
+ const UCRED_SIZE = 12;
4025
+ const cache = getPeerCred;
4026
+ const lib = cache._lib ?? (() => {
4027
+ const candidates = ["libc.so.6", "libc.so"];
4028
+ const symbolSpec = {
4029
+ getsockopt: {
4030
+ args: [FFIType.i32, FFIType.i32, FFIType.i32, FFIType.ptr, FFIType.ptr],
4031
+ returns: FFIType.i32
4032
+ }
4033
+ };
4034
+ const errors2 = [];
4035
+ for (const name of candidates) {
4036
+ try {
4037
+ const opened = dlopen(name, symbolSpec);
4038
+ cache._lib = opened;
4039
+ return opened;
4040
+ } catch (e) {
4041
+ errors2.push(`${name}: ${e instanceof Error ? e.message : String(e)}`);
4042
+ }
4043
+ }
4044
+ process.stderr.write(`[vault-broker] peercred-ffi: dlopen failed for all libc candidates ` + `(${errors2.join("; ")}); falling back to ss-parsing.
4045
+ `);
4046
+ throw new Error("no libc candidate could be opened");
4047
+ })();
4048
+ const credBuf = new ArrayBuffer(UCRED_SIZE);
4049
+ const lenBuf = new Uint32Array(1);
4050
+ lenBuf[0] = UCRED_SIZE;
4051
+ const rc = lib.symbols.getsockopt(fd, SOL_SOCKET, SO_PEERCRED, ptr(credBuf), ptr(lenBuf.buffer));
4052
+ if (rc !== 0)
4053
+ return null;
4054
+ if (lenBuf[0] !== UCRED_SIZE)
4055
+ return null;
4056
+ const view = new DataView(credBuf);
4057
+ return {
4058
+ pid: view.getInt32(0, true),
4059
+ uid: view.getInt32(4, true),
4060
+ gid: view.getInt32(8, true)
4061
+ };
4062
+ } catch {
4063
+ return null;
4064
+ }
4065
+ }
4066
+ // src/vault/broker/peercred.ts
4067
+ function isReservedAgentName(name) {
4068
+ return RESERVED_AGENT_NAMES.has(name);
4069
+ }
4070
+ var RESERVED_AGENT_NAMES;
4071
+ var init_peercred = __esm(() => {
4072
+ RESERVED_AGENT_NAMES = new Set(["operator", "hostd"]);
4073
+ });
4074
+
4075
+ // src/vault/broker/protocol.ts
4076
+ function decodeRequest(line) {
4077
+ if (Buffer.byteLength(line, "utf8") > MAX_FRAME_BYTES) {
4078
+ throw new RangeError(`Request frame too large (${Buffer.byteLength(line, "utf8")} bytes; max ${MAX_FRAME_BYTES})`);
4079
+ }
4080
+ const obj = JSON.parse(line);
4081
+ return RequestSchema.parse(obj);
4082
+ }
4083
+ function encodeResponse(resp) {
4084
+ const json = JSON.stringify(resp);
4085
+ if (Buffer.byteLength(json, "utf8") > MAX_FRAME_BYTES) {
4086
+ throw new Error(`Response frame too large (${Buffer.byteLength(json, "utf8")} bytes; max ${MAX_FRAME_BYTES})`);
4087
+ }
4088
+ return json + `
4089
+ `;
4090
+ }
4091
+ function errorResponse(code, msg) {
4092
+ return { ok: false, code, msg };
4093
+ }
4094
+ var MAX_FRAME_BYTES, AgentNameSchema, GetRequestSchema, PutRequestSchema, ListRequestSchema, MintGrantRequestSchema, ListGrantsRequestSchema, RevokeGrantRequestSchema, StatusRequestSchema, LockRequestSchema, PreflightAccessRequestSchema, OkPreflightAccessResponseSchema, ApprovalRequestRequestSchema, ApprovalLookupRequestSchema, ApprovalLookupByRequestRequestSchema, ApprovalConsumeRequestSchema, ApprovalRevokeRequestSchema, ApprovalListRequestSchema, ApprovalDecisionModeSchema, ApprovalRecordRequestSchema, ApprovalConsumeRecordRequestSchema, RequestSchema, VaultEntrySchema, ErrorCode, OkEntryResponseSchema, OkKeysResponseSchema, BrokerStatus, OkStatusResponseSchema, OkLockResponseSchema, OkPutResponseSchema, OkMintGrantResponseSchema, GrantMetaSchema, OkListGrantsResponseSchema, OkRevokeGrantResponseSchema, OkApprovalRequestResponseSchema, ApprovalDecisionMetaSchema, OkApprovalLookupResponseSchema, OkApprovalConsumeResponseSchema, OkApprovalRevokeResponseSchema, OkApprovalListResponseSchema, OkApprovalRecordResponseSchema, OkApprovalConsumeRecordResponseSchema, ErrorResponseSchema, ResponseSchema;
4095
+ var init_protocol = __esm(() => {
4096
+ init_zod();
4097
+ init_peercred();
4098
+ MAX_FRAME_BYTES = 64 * 1024;
4099
+ AgentNameSchema = exports_external.string().min(1).max(64, "agent name max 64 chars").regex(/^[a-zA-Z0-9][a-zA-Z0-9_-]*$/, "agent name must be kebab-case ASCII (alnum + _- only, first char alnum)").refine((s) => !isReservedAgentName(s), {
4100
+ message: "agent name is reserved"
4101
+ });
4102
+ GetRequestSchema = exports_external.object({
4103
+ v: exports_external.literal(1),
4104
+ op: exports_external.literal("get"),
4105
+ key: exports_external.string().min(1),
4106
+ filename: exports_external.string().optional(),
4107
+ token: exports_external.string().optional()
4108
+ });
4109
+ PutRequestSchema = exports_external.object({
4110
+ v: exports_external.literal(1),
4111
+ op: exports_external.literal("put"),
4112
+ key: exports_external.string().min(1),
4113
+ entry: exports_external.union([
4114
+ exports_external.object({ kind: exports_external.literal("string"), value: exports_external.string() }),
4115
+ exports_external.object({ kind: exports_external.literal("binary"), value: exports_external.string() })
4116
+ ]),
4117
+ token: exports_external.string().optional(),
4118
+ passphrase: exports_external.string().optional(),
4119
+ attest_via_posture: exports_external.boolean().optional()
4120
+ });
4121
+ ListRequestSchema = exports_external.object({
4122
+ v: exports_external.literal(1),
4123
+ op: exports_external.literal("list"),
4124
+ token: exports_external.string().optional()
4125
+ });
4126
+ MintGrantRequestSchema = exports_external.object({
4127
+ v: exports_external.literal(1),
4128
+ op: exports_external.literal("mint_grant"),
4129
+ agent: AgentNameSchema,
4130
+ keys: exports_external.array(exports_external.string().min(1)),
4131
+ ttl_seconds: exports_external.number().int().positive().nullable(),
4132
+ description: exports_external.string().optional(),
4133
+ write_keys: exports_external.array(exports_external.string().min(1)).optional(),
4134
+ passphrase: exports_external.string().optional(),
4135
+ attest_via_posture: exports_external.boolean().optional(),
4136
+ decision_id: exports_external.string().optional()
4137
+ });
4138
+ ListGrantsRequestSchema = exports_external.object({
4139
+ v: exports_external.literal(1),
4140
+ op: exports_external.literal("list_grants"),
4141
+ agent: AgentNameSchema.optional(),
4142
+ passphrase: exports_external.string().optional(),
4143
+ attest_via_posture: exports_external.boolean().optional()
4144
+ });
4145
+ RevokeGrantRequestSchema = exports_external.object({
4146
+ v: exports_external.literal(1),
4147
+ op: exports_external.literal("revoke_grant"),
4148
+ id: exports_external.string().min(1)
4149
+ });
4150
+ StatusRequestSchema = exports_external.object({
4151
+ v: exports_external.literal(1),
4152
+ op: exports_external.literal("status")
4153
+ });
4154
+ LockRequestSchema = exports_external.object({
4155
+ v: exports_external.literal(1),
4156
+ op: exports_external.literal("lock")
4157
+ });
4158
+ PreflightAccessRequestSchema = exports_external.object({
4159
+ v: exports_external.literal(1),
4160
+ op: exports_external.literal("preflight_access"),
4161
+ agent: AgentNameSchema,
4162
+ keys: exports_external.array(exports_external.string().min(1)).min(1).max(128)
4163
+ });
4164
+ OkPreflightAccessResponseSchema = exports_external.object({
4165
+ ok: exports_external.literal(true),
4166
+ op: exports_external.literal("preflight_access"),
4167
+ results: exports_external.array(exports_external.object({
4168
+ key: exports_external.string(),
4169
+ exists: exports_external.boolean(),
4170
+ acl_ok: exports_external.boolean(),
4171
+ acl_reason: exports_external.string().optional(),
4172
+ scope_ok: exports_external.boolean(),
4173
+ scope_reason: exports_external.string().optional()
4174
+ }))
4175
+ });
4176
+ ApprovalRequestRequestSchema = exports_external.object({
4177
+ v: exports_external.literal(1),
4178
+ op: exports_external.literal("approval_request"),
4179
+ agent_unit: exports_external.string().min(1),
4180
+ scope: exports_external.string().min(1),
4181
+ action: exports_external.string().min(1),
4182
+ approver_set: exports_external.array(exports_external.string()),
4183
+ why: exports_external.string().optional(),
4184
+ ttl_ms: exports_external.number().int().positive().optional()
4185
+ });
4186
+ ApprovalLookupRequestSchema = exports_external.object({
4187
+ v: exports_external.literal(1),
4188
+ op: exports_external.literal("approval_lookup"),
4189
+ agent_unit: exports_external.string().min(1),
4190
+ scope: exports_external.string().min(1),
4191
+ action: exports_external.string().min(1),
4192
+ current_approver_set: exports_external.array(exports_external.string())
4193
+ });
4194
+ ApprovalLookupByRequestRequestSchema = exports_external.object({
4195
+ v: exports_external.literal(1),
4196
+ op: exports_external.literal("approval_lookup_by_request"),
4197
+ agent_unit: exports_external.string().min(1),
4198
+ request_id: exports_external.string().regex(/^[0-9a-f]{32}$/),
4199
+ current_approver_set: exports_external.array(exports_external.string())
4200
+ });
4201
+ ApprovalConsumeRequestSchema = exports_external.object({
4202
+ v: exports_external.literal(1),
4203
+ op: exports_external.literal("approval_consume"),
4204
+ request_id: exports_external.string().regex(/^[0-9a-f]{32}$/)
4205
+ });
4206
+ ApprovalRevokeRequestSchema = exports_external.object({
4207
+ v: exports_external.literal(1),
4208
+ op: exports_external.literal("approval_revoke"),
4209
+ decision_id: exports_external.string().min(1),
4210
+ actor: exports_external.string().min(1),
4211
+ reason: exports_external.string().optional()
4212
+ });
4213
+ ApprovalListRequestSchema = exports_external.object({
4214
+ v: exports_external.literal(1),
4215
+ op: exports_external.literal("approval_list"),
4216
+ agent_unit: exports_external.string().optional()
4217
+ });
4218
+ ApprovalDecisionModeSchema = exports_external.enum([
4219
+ "allow_once",
4220
+ "allow_always",
4221
+ "allow_ttl",
4222
+ "deny",
4223
+ "deny_perm"
4224
+ ]);
4225
+ ApprovalRecordRequestSchema = exports_external.object({
4226
+ v: exports_external.literal(1),
4227
+ op: exports_external.literal("approval_record"),
4228
+ request_id: exports_external.string().regex(/^[0-9a-f]{32}$/),
4229
+ decision: ApprovalDecisionModeSchema,
4230
+ approver_set: exports_external.array(exports_external.string()),
4231
+ granted_by_user_id: exports_external.number().int(),
4232
+ ttl_ms: exports_external.number().int().positive().nullable().optional()
4233
+ });
4234
+ ApprovalConsumeRecordRequestSchema = exports_external.object({
4235
+ v: exports_external.literal(1),
4236
+ op: exports_external.literal("approval_consume_record"),
4237
+ request_id: exports_external.string().regex(/^[0-9a-f]{32}$/),
4238
+ decision: ApprovalDecisionModeSchema,
4239
+ approver_set: exports_external.array(exports_external.string()),
4240
+ granted_by_user_id: exports_external.number().int(),
4241
+ ttl_ms: exports_external.number().int().positive().nullable().optional()
4242
+ });
4243
+ RequestSchema = exports_external.discriminatedUnion("op", [
4244
+ GetRequestSchema,
4245
+ PutRequestSchema,
4246
+ ListRequestSchema,
4247
+ StatusRequestSchema,
4248
+ LockRequestSchema,
4249
+ PreflightAccessRequestSchema,
4250
+ MintGrantRequestSchema,
4251
+ ListGrantsRequestSchema,
4252
+ RevokeGrantRequestSchema,
4253
+ ApprovalRequestRequestSchema,
4254
+ ApprovalLookupRequestSchema,
4255
+ ApprovalLookupByRequestRequestSchema,
4256
+ ApprovalConsumeRequestSchema,
4257
+ ApprovalRevokeRequestSchema,
4258
+ ApprovalListRequestSchema,
4259
+ ApprovalRecordRequestSchema,
4260
+ ApprovalConsumeRecordRequestSchema
4261
+ ]);
4262
+ VaultEntrySchema = exports_external.union([
4263
+ exports_external.object({ kind: exports_external.literal("string"), value: exports_external.string() }),
4264
+ exports_external.object({ kind: exports_external.literal("binary"), value: exports_external.string() }),
4265
+ exports_external.object({
4266
+ kind: exports_external.literal("files"),
4267
+ files: exports_external.record(exports_external.string(), exports_external.object({
4268
+ encoding: exports_external.enum(["utf8", "base64"]),
4269
+ value: exports_external.string()
4270
+ }))
4271
+ })
4272
+ ]);
4273
+ ErrorCode = exports_external.enum([
4274
+ "LOCKED",
4275
+ "DENIED",
4276
+ "UNKNOWN_KEY",
4277
+ "BAD_REQUEST",
4278
+ "INTERNAL",
4279
+ "AUDIT_UNAVAILABLE"
4280
+ ]);
4281
+ OkEntryResponseSchema = exports_external.object({
4282
+ ok: exports_external.literal(true),
4283
+ entry: VaultEntrySchema
4284
+ });
4285
+ OkKeysResponseSchema = exports_external.object({
4286
+ ok: exports_external.literal(true),
4287
+ keys: exports_external.array(exports_external.string())
4288
+ });
4289
+ BrokerStatus = exports_external.object({
4290
+ unlocked: exports_external.boolean(),
4291
+ keyCount: exports_external.number().int().nonnegative(),
4292
+ uptimeSec: exports_external.number().nonnegative()
4293
+ });
4294
+ OkStatusResponseSchema = exports_external.object({
4295
+ ok: exports_external.literal(true),
4296
+ status: BrokerStatus
4297
+ });
4298
+ OkLockResponseSchema = exports_external.object({
4299
+ ok: exports_external.literal(true),
4300
+ locked: exports_external.literal(true)
4301
+ });
4302
+ OkPutResponseSchema = exports_external.object({
4303
+ ok: exports_external.literal(true),
4304
+ put: exports_external.literal(true),
4305
+ key: exports_external.string()
4306
+ });
4307
+ OkMintGrantResponseSchema = exports_external.object({
4308
+ ok: exports_external.literal(true),
4309
+ token: exports_external.string(),
4310
+ id: exports_external.string(),
4311
+ expires_at: exports_external.number().nullable()
4312
+ });
4313
+ GrantMetaSchema = exports_external.object({
4314
+ id: exports_external.string(),
4315
+ agent_slug: exports_external.string(),
4316
+ key_allow: exports_external.array(exports_external.string()),
4317
+ write_allow: exports_external.array(exports_external.string()).default([]),
4318
+ expires_at: exports_external.number().nullable(),
4319
+ created_at: exports_external.number(),
4320
+ description: exports_external.string().nullable()
4321
+ });
4322
+ OkListGrantsResponseSchema = exports_external.object({
4323
+ ok: exports_external.literal(true),
4324
+ grants: exports_external.array(GrantMetaSchema)
4325
+ });
4326
+ OkRevokeGrantResponseSchema = exports_external.object({
4327
+ ok: exports_external.literal(true),
4328
+ revoked: exports_external.boolean()
4329
+ });
4330
+ OkApprovalRequestResponseSchema = exports_external.discriminatedUnion("state", [
4331
+ exports_external.object({
4332
+ ok: exports_external.literal(true),
4333
+ kind: exports_external.literal("approval_request"),
4334
+ state: exports_external.literal("pending"),
4335
+ request_id: exports_external.string(),
4336
+ expires_at: exports_external.number()
4337
+ }),
4338
+ exports_external.object({
4339
+ ok: exports_external.literal(true),
4340
+ kind: exports_external.literal("approval_request"),
4341
+ state: exports_external.literal("rate_limited"),
4342
+ retry_after_ms: exports_external.number()
4343
+ })
4344
+ ]);
4345
+ ApprovalDecisionMetaSchema = exports_external.object({
4346
+ id: exports_external.string(),
4347
+ agent_unit: exports_external.string(),
4348
+ scope: exports_external.string(),
4349
+ action: exports_external.string(),
4350
+ decision: ApprovalDecisionModeSchema,
4351
+ granted_at: exports_external.number(),
4352
+ granted_by_user_id: exports_external.number(),
4353
+ ttl_expires_at: exports_external.number().nullable(),
4354
+ last_used_at: exports_external.number().nullable(),
4355
+ revoked_at: exports_external.number().nullable(),
4356
+ revoke_reason: exports_external.string().nullable(),
4357
+ origin: exports_external.enum(["agent", "operator"]).optional()
4358
+ });
4359
+ OkApprovalLookupResponseSchema = exports_external.object({
4360
+ ok: exports_external.literal(true),
4361
+ state: exports_external.enum(["granted", "denied", "pending", "expired", "drift_revoked", "no_decision"]),
4362
+ decision: ApprovalDecisionMetaSchema.nullable().optional()
4363
+ });
4364
+ OkApprovalConsumeResponseSchema = exports_external.object({
4365
+ ok: exports_external.literal(true),
4366
+ consumed: exports_external.boolean(),
4367
+ agent_unit: exports_external.string().optional(),
4368
+ scope: exports_external.string().optional(),
4369
+ action: exports_external.string().optional(),
4370
+ why: exports_external.string().nullable().optional()
4371
+ });
4372
+ OkApprovalRevokeResponseSchema = exports_external.object({
4373
+ ok: exports_external.literal(true),
4374
+ revoked: exports_external.boolean()
4375
+ });
4376
+ OkApprovalListResponseSchema = exports_external.object({
4377
+ ok: exports_external.literal(true),
4378
+ decisions: exports_external.array(ApprovalDecisionMetaSchema)
4379
+ });
4380
+ OkApprovalRecordResponseSchema = exports_external.object({
4381
+ ok: exports_external.literal(true),
4382
+ decision_id: exports_external.string()
4383
+ });
4384
+ OkApprovalConsumeRecordResponseSchema = exports_external.object({
4385
+ ok: exports_external.literal(true),
4386
+ consumed: exports_external.boolean(),
4387
+ decision_id: exports_external.string().optional(),
4388
+ agent_unit: exports_external.string().optional(),
4389
+ scope: exports_external.string().optional(),
4390
+ action: exports_external.string().optional(),
4391
+ why: exports_external.string().nullable().optional()
4392
+ });
4393
+ ErrorResponseSchema = exports_external.object({
4394
+ ok: exports_external.literal(false),
4395
+ code: ErrorCode,
4396
+ msg: exports_external.string()
4397
+ });
4398
+ ResponseSchema = exports_external.union([
4399
+ OkEntryResponseSchema,
4400
+ OkKeysResponseSchema,
4401
+ OkStatusResponseSchema,
4402
+ OkLockResponseSchema,
4403
+ OkPreflightAccessResponseSchema,
4404
+ OkPutResponseSchema,
4405
+ OkMintGrantResponseSchema,
4406
+ OkListGrantsResponseSchema,
4407
+ OkRevokeGrantResponseSchema,
4408
+ OkApprovalRequestResponseSchema,
4409
+ OkApprovalLookupResponseSchema,
4410
+ OkApprovalConsumeResponseSchema,
4411
+ OkApprovalRevokeResponseSchema,
4412
+ OkApprovalListResponseSchema,
4413
+ OkApprovalRecordResponseSchema,
4414
+ OkApprovalConsumeRecordResponseSchema,
4415
+ ErrorResponseSchema
4416
+ ]);
4417
+ });
4418
+
4015
4419
  // src/memory/observation-scopes.ts
4016
4420
  var OBSERVATION_SCOPES;
4017
4421
  var init_observation_scopes = __esm(() => {
@@ -4432,6 +4836,7 @@ var init_schema = __esm(() => {
4432
4836
  }).describe("Per-operation LLM override. Every field optional; an unset field (or " + "an omitted op block) inherits the global `hindsight.llm.*`, which is " + "already the engine's fallback — switchroom emits only the vars set.");
4433
4837
  HindsightConfigSchema = exports_external.object({
4434
4838
  gpu: exports_external.boolean().optional().describe("Force GPU passthrough for the hindsight container on (`true`) or off " + "(`false`), overriding host autodetection in BOTH directions. Absent " + "(the default) → autodetect from the persisted host-capabilities " + "verdict (`~/.switchroom/host-capabilities.json`), which enables " + "`--gpus all` only when that file proves BOTH a GPU and the nvidia " + "container toolkit. Set `true` when that verdict is wrong or unreadable " + "and you know the host has a working toolkit — switchroom cannot verify " + "it for you, and `docker run --gpus all` hard-fails container create on " + "a host without one. Set `false` to pin the container to CPU on a GPU " + "host. This is also the declarative opt-out for the recreate-time GPU " + "drop guard (`switchroom memory setup --recreate` refuses to silently " + "turn a GPU container into a CPU one). `--gpu`/`--no-gpu` on `memory " + "setup` override this for a single run."),
4839
+ cp_access_key: exports_external.string().min(1).optional().describe("Access key for the hindsight control-plane DASHBOARD (upstream " + "`HINDSIGHT_CP_ACCESS_KEY`, port 9999). Literal or — strongly preferred " + "— a `vault:` reference such as `vault:hindsight_cp_access_key`, read " + "through the broker at container-launch time. This is the ONLY thing " + "that arms the dashboard's login: upstream's middleware short-circuits " + "to `next()` when the var is unset, so an unset key means the dashboard " + "has no authentication at all, not weak authentication. Because of that, " + "leaving it unset is FAIL-CLOSED: switchroom pins " + "`HINDSIGHT_CP_HOSTNAME=127.0.0.1` so the loginless dashboard is " + "reachable only from the host, and warns. Set this to serve the " + "dashboard on the LAN/tailnet."),
4435
4840
  llm: exports_external.object({
4436
4841
  provider: exports_external.string().min(1).optional().describe("Hindsight LLM provider (upstream `HINDSIGHT_API_LLM_PROVIDER`). " + "Defaults to `claude-code` (subscription-honest, broker-fed OAuth). " + "Any litellm-routable provider the upstream image supports is valid. " + "Serves as the GLOBAL default for every op absent a per-op override."),
4437
4842
  model: exports_external.string().min(1).optional().describe("Hindsight LLM model (upstream `HINDSIGHT_API_LLM_MODEL`). Defaults " + "to HINDSIGHT_DEFAULT_MODEL. Any model your LiteLLM proxy can route " + "is valid, e.g. `openrouter/z-ai/glm-5.2` when routing through the " + "fleet proxy. With provider=claude-code this value is ALSO exported " + "as `ANTHROPIC_MODEL` to the claude subprocess. Serves as the GLOBAL " + "default for every op absent a per-op override."),
@@ -18310,412 +18715,49 @@ var require_lib = __commonJS((exports, module) => {
18310
18715
  }
18311
18716
  });
18312
18717
 
18718
+ // src/vault/flock.ts
18719
+ var init_flock = () => {};
18720
+
18721
+ // src/vault/vault.ts
18722
+ var KNOWN_VAULT_ARTIFACT_NAMES, SCRYPT_MAXMEM;
18723
+ var init_vault = __esm(() => {
18724
+ init_flock();
18725
+ KNOWN_VAULT_ARTIFACT_NAMES = new Set([
18726
+ "vault.enc",
18727
+ "vault.enc.bak",
18728
+ "vault.enc.tmp",
18729
+ "vault.enc.lock",
18730
+ ".vault.enc.symlink-tmp"
18731
+ ]);
18732
+ SCRYPT_MAXMEM = 128 * 1024 * 1024;
18733
+ });
18734
+ // src/vault/broker/client.ts
18735
+ import { homedir as homedir3 } from "node:os";
18736
+ import { join as join3 } from "node:path";
18737
+ var LEGACY_SOCKET_PATH, OPERATOR_SOCKET_PATH;
18738
+ var init_client = __esm(() => {
18739
+ init_protocol();
18740
+ init_peercred();
18741
+ LEGACY_SOCKET_PATH = join3(homedir3(), ".switchroom", "vault-broker.sock");
18742
+ OPERATOR_SOCKET_PATH = join3(homedir3(), ".switchroom", "broker-operator", "sock");
18743
+ });
18744
+
18745
+ // src/vault/resolver.ts
18746
+ var materializedDirs;
18747
+ var init_resolver = __esm(() => {
18748
+ init_vault();
18749
+ init_loader();
18750
+ init_client();
18751
+ materializedDirs = new Set;
18752
+ });
18753
+
18313
18754
  // src/vault/approvals/kernel-server.ts
18755
+ init_protocol();
18314
18756
  import * as net from "node:net";
18315
18757
  import { mkdirSync as mkdirSync2, chmodSync, chownSync, existsSync as existsSync5, unlinkSync, readdirSync as readdirSync3, statSync as statSync3 } from "node:fs";
18316
18758
  import { dirname as dirname2, resolve as resolve6, basename as basename2 } from "node:path";
18317
18759
  import { Database } from "bun:sqlite";
18318
18760
 
18319
- // src/vault/broker/protocol.ts
18320
- init_zod();
18321
-
18322
- // src/vault/broker/peercred-ffi.ts
18323
- function getPeerCred(fd) {
18324
- if (process.platform !== "linux")
18325
- return null;
18326
- try {
18327
- const ffi = __require("bun:ffi");
18328
- const { dlopen, FFIType, ptr } = ffi;
18329
- const SOL_SOCKET = 1;
18330
- const SO_PEERCRED = 17;
18331
- const UCRED_SIZE = 12;
18332
- const cache = getPeerCred;
18333
- const lib = cache._lib ?? (() => {
18334
- const candidates = ["libc.so.6", "libc.so"];
18335
- const symbolSpec = {
18336
- getsockopt: {
18337
- args: [FFIType.i32, FFIType.i32, FFIType.i32, FFIType.ptr, FFIType.ptr],
18338
- returns: FFIType.i32
18339
- }
18340
- };
18341
- const errors2 = [];
18342
- for (const name of candidates) {
18343
- try {
18344
- const opened = dlopen(name, symbolSpec);
18345
- cache._lib = opened;
18346
- return opened;
18347
- } catch (e) {
18348
- errors2.push(`${name}: ${e instanceof Error ? e.message : String(e)}`);
18349
- }
18350
- }
18351
- process.stderr.write(`[vault-broker] peercred-ffi: dlopen failed for all libc candidates ` + `(${errors2.join("; ")}); falling back to ss-parsing.
18352
- `);
18353
- throw new Error("no libc candidate could be opened");
18354
- })();
18355
- const credBuf = new ArrayBuffer(UCRED_SIZE);
18356
- const lenBuf = new Uint32Array(1);
18357
- lenBuf[0] = UCRED_SIZE;
18358
- const rc = lib.symbols.getsockopt(fd, SOL_SOCKET, SO_PEERCRED, ptr(credBuf), ptr(lenBuf.buffer));
18359
- if (rc !== 0)
18360
- return null;
18361
- if (lenBuf[0] !== UCRED_SIZE)
18362
- return null;
18363
- const view = new DataView(credBuf);
18364
- return {
18365
- pid: view.getInt32(0, true),
18366
- uid: view.getInt32(4, true),
18367
- gid: view.getInt32(8, true)
18368
- };
18369
- } catch {
18370
- return null;
18371
- }
18372
- }
18373
-
18374
- // src/vault/broker/peercred.ts
18375
- var RESERVED_AGENT_NAMES = new Set(["operator", "hostd"]);
18376
- function isReservedAgentName(name) {
18377
- return RESERVED_AGENT_NAMES.has(name);
18378
- }
18379
-
18380
- // src/vault/broker/protocol.ts
18381
- var MAX_FRAME_BYTES = 64 * 1024;
18382
- var AgentNameSchema = exports_external.string().min(1).max(64, "agent name max 64 chars").regex(/^[a-zA-Z0-9][a-zA-Z0-9_-]*$/, "agent name must be kebab-case ASCII (alnum + _- only, first char alnum)").refine((s) => !isReservedAgentName(s), {
18383
- message: "agent name is reserved"
18384
- });
18385
- var GetRequestSchema = exports_external.object({
18386
- v: exports_external.literal(1),
18387
- op: exports_external.literal("get"),
18388
- key: exports_external.string().min(1),
18389
- filename: exports_external.string().optional(),
18390
- token: exports_external.string().optional()
18391
- });
18392
- var PutRequestSchema = exports_external.object({
18393
- v: exports_external.literal(1),
18394
- op: exports_external.literal("put"),
18395
- key: exports_external.string().min(1),
18396
- entry: exports_external.union([
18397
- exports_external.object({ kind: exports_external.literal("string"), value: exports_external.string() }),
18398
- exports_external.object({ kind: exports_external.literal("binary"), value: exports_external.string() })
18399
- ]),
18400
- token: exports_external.string().optional(),
18401
- passphrase: exports_external.string().optional(),
18402
- attest_via_posture: exports_external.boolean().optional()
18403
- });
18404
- var ListRequestSchema = exports_external.object({
18405
- v: exports_external.literal(1),
18406
- op: exports_external.literal("list"),
18407
- token: exports_external.string().optional()
18408
- });
18409
- var MintGrantRequestSchema = exports_external.object({
18410
- v: exports_external.literal(1),
18411
- op: exports_external.literal("mint_grant"),
18412
- agent: AgentNameSchema,
18413
- keys: exports_external.array(exports_external.string().min(1)),
18414
- ttl_seconds: exports_external.number().int().positive().nullable(),
18415
- description: exports_external.string().optional(),
18416
- write_keys: exports_external.array(exports_external.string().min(1)).optional(),
18417
- passphrase: exports_external.string().optional(),
18418
- attest_via_posture: exports_external.boolean().optional(),
18419
- decision_id: exports_external.string().optional()
18420
- });
18421
- var ListGrantsRequestSchema = exports_external.object({
18422
- v: exports_external.literal(1),
18423
- op: exports_external.literal("list_grants"),
18424
- agent: AgentNameSchema.optional(),
18425
- passphrase: exports_external.string().optional(),
18426
- attest_via_posture: exports_external.boolean().optional()
18427
- });
18428
- var RevokeGrantRequestSchema = exports_external.object({
18429
- v: exports_external.literal(1),
18430
- op: exports_external.literal("revoke_grant"),
18431
- id: exports_external.string().min(1)
18432
- });
18433
- var StatusRequestSchema = exports_external.object({
18434
- v: exports_external.literal(1),
18435
- op: exports_external.literal("status")
18436
- });
18437
- var LockRequestSchema = exports_external.object({
18438
- v: exports_external.literal(1),
18439
- op: exports_external.literal("lock")
18440
- });
18441
- var PreflightAccessRequestSchema = exports_external.object({
18442
- v: exports_external.literal(1),
18443
- op: exports_external.literal("preflight_access"),
18444
- agent: AgentNameSchema,
18445
- keys: exports_external.array(exports_external.string().min(1)).min(1).max(128)
18446
- });
18447
- var OkPreflightAccessResponseSchema = exports_external.object({
18448
- ok: exports_external.literal(true),
18449
- op: exports_external.literal("preflight_access"),
18450
- results: exports_external.array(exports_external.object({
18451
- key: exports_external.string(),
18452
- exists: exports_external.boolean(),
18453
- acl_ok: exports_external.boolean(),
18454
- acl_reason: exports_external.string().optional(),
18455
- scope_ok: exports_external.boolean(),
18456
- scope_reason: exports_external.string().optional()
18457
- }))
18458
- });
18459
- var ApprovalRequestRequestSchema = exports_external.object({
18460
- v: exports_external.literal(1),
18461
- op: exports_external.literal("approval_request"),
18462
- agent_unit: exports_external.string().min(1),
18463
- scope: exports_external.string().min(1),
18464
- action: exports_external.string().min(1),
18465
- approver_set: exports_external.array(exports_external.string()),
18466
- why: exports_external.string().optional(),
18467
- ttl_ms: exports_external.number().int().positive().optional()
18468
- });
18469
- var ApprovalLookupRequestSchema = exports_external.object({
18470
- v: exports_external.literal(1),
18471
- op: exports_external.literal("approval_lookup"),
18472
- agent_unit: exports_external.string().min(1),
18473
- scope: exports_external.string().min(1),
18474
- action: exports_external.string().min(1),
18475
- current_approver_set: exports_external.array(exports_external.string())
18476
- });
18477
- var ApprovalLookupByRequestRequestSchema = exports_external.object({
18478
- v: exports_external.literal(1),
18479
- op: exports_external.literal("approval_lookup_by_request"),
18480
- agent_unit: exports_external.string().min(1),
18481
- request_id: exports_external.string().regex(/^[0-9a-f]{32}$/),
18482
- current_approver_set: exports_external.array(exports_external.string())
18483
- });
18484
- var ApprovalConsumeRequestSchema = exports_external.object({
18485
- v: exports_external.literal(1),
18486
- op: exports_external.literal("approval_consume"),
18487
- request_id: exports_external.string().regex(/^[0-9a-f]{32}$/)
18488
- });
18489
- var ApprovalRevokeRequestSchema = exports_external.object({
18490
- v: exports_external.literal(1),
18491
- op: exports_external.literal("approval_revoke"),
18492
- decision_id: exports_external.string().min(1),
18493
- actor: exports_external.string().min(1),
18494
- reason: exports_external.string().optional()
18495
- });
18496
- var ApprovalListRequestSchema = exports_external.object({
18497
- v: exports_external.literal(1),
18498
- op: exports_external.literal("approval_list"),
18499
- agent_unit: exports_external.string().optional()
18500
- });
18501
- var ApprovalDecisionModeSchema = exports_external.enum([
18502
- "allow_once",
18503
- "allow_always",
18504
- "allow_ttl",
18505
- "deny",
18506
- "deny_perm"
18507
- ]);
18508
- var ApprovalRecordRequestSchema = exports_external.object({
18509
- v: exports_external.literal(1),
18510
- op: exports_external.literal("approval_record"),
18511
- request_id: exports_external.string().regex(/^[0-9a-f]{32}$/),
18512
- decision: ApprovalDecisionModeSchema,
18513
- approver_set: exports_external.array(exports_external.string()),
18514
- granted_by_user_id: exports_external.number().int(),
18515
- ttl_ms: exports_external.number().int().positive().nullable().optional()
18516
- });
18517
- var ApprovalConsumeRecordRequestSchema = exports_external.object({
18518
- v: exports_external.literal(1),
18519
- op: exports_external.literal("approval_consume_record"),
18520
- request_id: exports_external.string().regex(/^[0-9a-f]{32}$/),
18521
- decision: ApprovalDecisionModeSchema,
18522
- approver_set: exports_external.array(exports_external.string()),
18523
- granted_by_user_id: exports_external.number().int(),
18524
- ttl_ms: exports_external.number().int().positive().nullable().optional()
18525
- });
18526
- var RequestSchema = exports_external.discriminatedUnion("op", [
18527
- GetRequestSchema,
18528
- PutRequestSchema,
18529
- ListRequestSchema,
18530
- StatusRequestSchema,
18531
- LockRequestSchema,
18532
- PreflightAccessRequestSchema,
18533
- MintGrantRequestSchema,
18534
- ListGrantsRequestSchema,
18535
- RevokeGrantRequestSchema,
18536
- ApprovalRequestRequestSchema,
18537
- ApprovalLookupRequestSchema,
18538
- ApprovalLookupByRequestRequestSchema,
18539
- ApprovalConsumeRequestSchema,
18540
- ApprovalRevokeRequestSchema,
18541
- ApprovalListRequestSchema,
18542
- ApprovalRecordRequestSchema,
18543
- ApprovalConsumeRecordRequestSchema
18544
- ]);
18545
- var VaultEntrySchema = exports_external.union([
18546
- exports_external.object({ kind: exports_external.literal("string"), value: exports_external.string() }),
18547
- exports_external.object({ kind: exports_external.literal("binary"), value: exports_external.string() }),
18548
- exports_external.object({
18549
- kind: exports_external.literal("files"),
18550
- files: exports_external.record(exports_external.string(), exports_external.object({
18551
- encoding: exports_external.enum(["utf8", "base64"]),
18552
- value: exports_external.string()
18553
- }))
18554
- })
18555
- ]);
18556
- var ErrorCode = exports_external.enum([
18557
- "LOCKED",
18558
- "DENIED",
18559
- "UNKNOWN_KEY",
18560
- "BAD_REQUEST",
18561
- "INTERNAL",
18562
- "AUDIT_UNAVAILABLE"
18563
- ]);
18564
- var OkEntryResponseSchema = exports_external.object({
18565
- ok: exports_external.literal(true),
18566
- entry: VaultEntrySchema
18567
- });
18568
- var OkKeysResponseSchema = exports_external.object({
18569
- ok: exports_external.literal(true),
18570
- keys: exports_external.array(exports_external.string())
18571
- });
18572
- var BrokerStatus = exports_external.object({
18573
- unlocked: exports_external.boolean(),
18574
- keyCount: exports_external.number().int().nonnegative(),
18575
- uptimeSec: exports_external.number().nonnegative()
18576
- });
18577
- var OkStatusResponseSchema = exports_external.object({
18578
- ok: exports_external.literal(true),
18579
- status: BrokerStatus
18580
- });
18581
- var OkLockResponseSchema = exports_external.object({
18582
- ok: exports_external.literal(true),
18583
- locked: exports_external.literal(true)
18584
- });
18585
- var OkPutResponseSchema = exports_external.object({
18586
- ok: exports_external.literal(true),
18587
- put: exports_external.literal(true),
18588
- key: exports_external.string()
18589
- });
18590
- var OkMintGrantResponseSchema = exports_external.object({
18591
- ok: exports_external.literal(true),
18592
- token: exports_external.string(),
18593
- id: exports_external.string(),
18594
- expires_at: exports_external.number().nullable()
18595
- });
18596
- var GrantMetaSchema = exports_external.object({
18597
- id: exports_external.string(),
18598
- agent_slug: exports_external.string(),
18599
- key_allow: exports_external.array(exports_external.string()),
18600
- write_allow: exports_external.array(exports_external.string()).default([]),
18601
- expires_at: exports_external.number().nullable(),
18602
- created_at: exports_external.number(),
18603
- description: exports_external.string().nullable()
18604
- });
18605
- var OkListGrantsResponseSchema = exports_external.object({
18606
- ok: exports_external.literal(true),
18607
- grants: exports_external.array(GrantMetaSchema)
18608
- });
18609
- var OkRevokeGrantResponseSchema = exports_external.object({
18610
- ok: exports_external.literal(true),
18611
- revoked: exports_external.boolean()
18612
- });
18613
- var OkApprovalRequestResponseSchema = exports_external.discriminatedUnion("state", [
18614
- exports_external.object({
18615
- ok: exports_external.literal(true),
18616
- kind: exports_external.literal("approval_request"),
18617
- state: exports_external.literal("pending"),
18618
- request_id: exports_external.string(),
18619
- expires_at: exports_external.number()
18620
- }),
18621
- exports_external.object({
18622
- ok: exports_external.literal(true),
18623
- kind: exports_external.literal("approval_request"),
18624
- state: exports_external.literal("rate_limited"),
18625
- retry_after_ms: exports_external.number()
18626
- })
18627
- ]);
18628
- var ApprovalDecisionMetaSchema = exports_external.object({
18629
- id: exports_external.string(),
18630
- agent_unit: exports_external.string(),
18631
- scope: exports_external.string(),
18632
- action: exports_external.string(),
18633
- decision: ApprovalDecisionModeSchema,
18634
- granted_at: exports_external.number(),
18635
- granted_by_user_id: exports_external.number(),
18636
- ttl_expires_at: exports_external.number().nullable(),
18637
- last_used_at: exports_external.number().nullable(),
18638
- revoked_at: exports_external.number().nullable(),
18639
- revoke_reason: exports_external.string().nullable(),
18640
- origin: exports_external.enum(["agent", "operator"]).optional()
18641
- });
18642
- var OkApprovalLookupResponseSchema = exports_external.object({
18643
- ok: exports_external.literal(true),
18644
- state: exports_external.enum(["granted", "denied", "pending", "expired", "drift_revoked", "no_decision"]),
18645
- decision: ApprovalDecisionMetaSchema.nullable().optional()
18646
- });
18647
- var OkApprovalConsumeResponseSchema = exports_external.object({
18648
- ok: exports_external.literal(true),
18649
- consumed: exports_external.boolean(),
18650
- agent_unit: exports_external.string().optional(),
18651
- scope: exports_external.string().optional(),
18652
- action: exports_external.string().optional(),
18653
- why: exports_external.string().nullable().optional()
18654
- });
18655
- var OkApprovalRevokeResponseSchema = exports_external.object({
18656
- ok: exports_external.literal(true),
18657
- revoked: exports_external.boolean()
18658
- });
18659
- var OkApprovalListResponseSchema = exports_external.object({
18660
- ok: exports_external.literal(true),
18661
- decisions: exports_external.array(ApprovalDecisionMetaSchema)
18662
- });
18663
- var OkApprovalRecordResponseSchema = exports_external.object({
18664
- ok: exports_external.literal(true),
18665
- decision_id: exports_external.string()
18666
- });
18667
- var OkApprovalConsumeRecordResponseSchema = exports_external.object({
18668
- ok: exports_external.literal(true),
18669
- consumed: exports_external.boolean(),
18670
- decision_id: exports_external.string().optional(),
18671
- agent_unit: exports_external.string().optional(),
18672
- scope: exports_external.string().optional(),
18673
- action: exports_external.string().optional(),
18674
- why: exports_external.string().nullable().optional()
18675
- });
18676
- var ErrorResponseSchema = exports_external.object({
18677
- ok: exports_external.literal(false),
18678
- code: ErrorCode,
18679
- msg: exports_external.string()
18680
- });
18681
- var ResponseSchema = exports_external.union([
18682
- OkEntryResponseSchema,
18683
- OkKeysResponseSchema,
18684
- OkStatusResponseSchema,
18685
- OkLockResponseSchema,
18686
- OkPreflightAccessResponseSchema,
18687
- OkPutResponseSchema,
18688
- OkMintGrantResponseSchema,
18689
- OkListGrantsResponseSchema,
18690
- OkRevokeGrantResponseSchema,
18691
- OkApprovalRequestResponseSchema,
18692
- OkApprovalLookupResponseSchema,
18693
- OkApprovalConsumeResponseSchema,
18694
- OkApprovalRevokeResponseSchema,
18695
- OkApprovalListResponseSchema,
18696
- OkApprovalRecordResponseSchema,
18697
- OkApprovalConsumeRecordResponseSchema,
18698
- ErrorResponseSchema
18699
- ]);
18700
- function decodeRequest(line) {
18701
- if (Buffer.byteLength(line, "utf8") > MAX_FRAME_BYTES) {
18702
- throw new RangeError(`Request frame too large (${Buffer.byteLength(line, "utf8")} bytes; max ${MAX_FRAME_BYTES})`);
18703
- }
18704
- const obj = JSON.parse(line);
18705
- return RequestSchema.parse(obj);
18706
- }
18707
- function encodeResponse(resp) {
18708
- const json = JSON.stringify(resp);
18709
- if (Buffer.byteLength(json, "utf8") > MAX_FRAME_BYTES) {
18710
- throw new Error(`Response frame too large (${Buffer.byteLength(json, "utf8")} bytes; max ${MAX_FRAME_BYTES})`);
18711
- }
18712
- return json + `
18713
- `;
18714
- }
18715
- function errorResponse(code, msg) {
18716
- return { ok: false, code, msg };
18717
- }
18718
-
18719
18761
  // src/vault/approvals/kernel.ts
18720
18762
  import { randomBytes, randomUUID } from "node:crypto";
18721
18763
 
@@ -19154,6 +19196,7 @@ import { dirname, isAbsolute, join as join4, relative, resolve as resolve5 } fro
19154
19196
  init_atomic();
19155
19197
 
19156
19198
  // src/agents/agent-uid.ts
19199
+ init_peercred();
19157
19200
  import { createHash } from "node:crypto";
19158
19201
  var AGENT_UID_MIN = 10001;
19159
19202
  var AGENT_UID_MAX = 10999;
@@ -19287,12 +19330,12 @@ init_paths();
19287
19330
  var _warnedReads = new Set;
19288
19331
 
19289
19332
  // src/setup/hindsight-pg-defaults.ts
19290
- var HINDSIGHT_PG_MEM_LIMIT_MIB_FOR_DERIVATION = 8 * 1024;
19333
+ var HINDSIGHT_PG_MEM_LIMIT_MIB_FOR_DERIVATION = 16 * 1024;
19291
19334
  var HINDSIGHT_PG_APP_ANON_MIB = 2560;
19292
19335
  var HINDSIGHT_PG_PAGE_CACHE_FLOOR_MIB = 2048;
19293
19336
  var HINDSIGHT_PG_SHARED_BUFFERS_BUDGET_MIB = HINDSIGHT_PG_MEM_LIMIT_MIB_FOR_DERIVATION - HINDSIGHT_PG_APP_ANON_MIB - HINDSIGHT_PG_PAGE_CACHE_FLOOR_MIB;
19294
- var HINDSIGHT_PG_DEFAULT_SHARED_BUFFERS_MIB = 1536;
19295
- var HINDSIGHT_PG_DEFAULT_EFFECTIVE_CACHE_SIZE_MIB = 4096;
19337
+ var HINDSIGHT_PG_DEFAULT_SHARED_BUFFERS_MIB = 3072;
19338
+ var HINDSIGHT_PG_DEFAULT_EFFECTIVE_CACHE_SIZE_MIB = 7168;
19296
19339
  function pgMib(mib) {
19297
19340
  return `${mib}MB`;
19298
19341
  }
@@ -19465,9 +19508,21 @@ var HINDSIGHT_RETAIN_CLIENT_DEADLINE_S = hindsightRetainClientTimeoutSeconds() +
19465
19508
  var HINDSIGHT_HEALTHCHECK_PY = 'import urllib.request,sys; sys.exit(0 if urllib.request.urlopen("http://localhost:8888/health",timeout=4).getcode()==200 else 1)';
19466
19509
  var HINDSIGHT_HEALTHCHECK_CMD = `python3 -c '${HINDSIGHT_HEALTHCHECK_PY}'`;
19467
19510
  var DOCKER_PROBE_TIMEOUT_MS = 60 * 1000;
19511
+ var HINDSIGHT_CP_UNAUTHENTICATED_BIND_ADDR = "127.0.0.1";
19512
+ var HINDSIGHT_CP_NO_ACCESS_KEY_WARNING = "hindsight: no `hindsight.cp_access_key` configured — the control-plane " + "dashboard has NO login (the access-key middleware is inert when " + "HINDSIGHT_CP_ACCESS_KEY is unset), so it is pinned to " + `${HINDSIGHT_CP_UNAUTHENTICATED_BIND_ADDR} and will NOT be reachable from ` + "the LAN or tailnet. Set `hindsight.cp_access_key: vault:<key>` in " + "switchroom.yaml to arm the login and open it up.";
19468
19513
 
19469
19514
  // src/memory/hindsight.ts
19470
- var DEFAULT_RETAIN_MISSION = `Extract durable facts that will still be true and useful weeks from now: user preferences and standing rules, ongoing projects and recurring commitments, technical and architectural decisions with their rationale, and people/tool relationships. A preference revealed by a request is durable — record the preference (what the user likes, wants, or always does), not the request itself.
19515
+ var DEFAULT_RETAIN_MISSION = `Extract durable facts that will still be true and useful weeks from now, once this session is forgotten.
19516
+ ` + `
19517
+ ` + `DURABILITY GATE. Emit a candidate ONLY if it is one of these five classes:
19518
+ ` + `- PREFERENCE — what the user likes, wants, or always does; a standing rule or correction.
19519
+ ` + `- DECISION — a settled choice that changes how future work is done, including a choice NOT to do something. A decision about the mechanics of the CURRENT task (which worker to dispatch, which branch to rebase, which PR to merge now, what to do next) is process narration, not a durable decision — drop it unless it establishes a standing rule or permanently changes a system.
19520
+ ` + `- FINDING — a root cause, a measurement, or verified behaviour of a system. Include the number.
19521
+ ` + `- OUTCOME — a completed result that changed the world: what shipped, what a thing turned out to be. Not the act of shipping it.
19522
+ ` + `- RELATIONSHIP — who a person is, what a project or tool is, and how they connect.
19523
+ ` + `If a candidate fits none of the five, it is not a memory. Drop it; do not reword it into one.
19524
+ ` + `
19525
+ ` + `A preference revealed by a request is durable — record the preference (what the user likes, wants, or always does), not the request itself.
19471
19526
  ` + `
19472
19527
  ` + `A TOOL RESULT IS NOT A FACT. Before extracting, ask: is the subject of this
19473
19528
  ` + `candidate a file path, a command/process/agent/session id, a temp directory, or
@@ -19484,6 +19539,9 @@ var DEFAULT_RETAIN_MISSION = `Extract durable facts that will still be true and
19484
19539
  ` + `- Anything mentioning a path under /tmp, a scratchpad directory, or a .tmp file.
19485
19540
  ` + `- Agent tool-use traces or narration of what the assistant did (e.g. "the
19486
19541
  ` + ` assistant used X to query Y", "ran a search", "sent the message").
19542
+ ` + `- The act of delegating, dispatching, spawning, launching, steering or merging
19543
+ ` + ` work — including when it succeeded. "X was dispatched and completed" is the
19544
+ ` + ` session describing itself. Record only what the work LEARNED or CHANGED.
19487
19545
  ` + `- In-flight workflow/process narration (a sub-task started, paused, or is still
19488
19546
  ` + ` running) — retain the outcome only once the task completes or a decision is made.
19489
19547
  ` + `- Operation, request, batch, agent, command or session IDs, UUIDs, hashes, or error codes.
@@ -19506,8 +19564,12 @@ var DEFAULT_RETAIN_MISSION = `Extract durable facts that will still be true and
19506
19564
  ` + ` the fact is explicitly dated, in which case record it as a dated observation.
19507
19565
  ` + `- Greetings, acknowledgements, and routine operational chatter.
19508
19566
  ` + `
19567
+ ` + `Write each fact so it stands alone: name the thing, the number, and the date. A
19568
+ ` + `sentence that only makes sense while reading this transcript is not durable.
19569
+ ` + `
19509
19570
  ` + `If a candidate fact matches an exclusion, drop it rather than rewording it. If
19510
- ` + "nothing durable remains, return an empty facts list.";
19571
+ ` + `nothing durable remains, return an empty facts list.
19572
+ `;
19511
19573
  var SUPERSEDED_RETAIN_MISSIONS = [
19512
19574
  "Extract technical decisions, architectural choices, user preferences, project context, and people/tool relationships. Ignore routine greetings and transient operational details.",
19513
19575
  "Extract user preferences, ongoing projects, recurring commitments, " + "important context, and durable facts that should help across future " + "conversations. Skip one-off chatter and temporary task noise.",
@@ -19554,7 +19616,96 @@ var SUPERSEDED_RETAIN_MISSIONS = [
19554
19616
  ` + `- Greetings, acknowledgements, and routine operational chatter.
19555
19617
  ` + `
19556
19618
  ` + `If a candidate fact matches an exclusion, drop it rather than rewording it. If
19557
- ` + "nothing durable remains, return an empty facts list."
19619
+ ` + "nothing durable remains, return an empty facts list.",
19620
+ `Extract durable facts that will still be true and useful weeks from now: user preferences and standing rules, ongoing projects and recurring commitments, technical and architectural decisions with their rationale, and people/tool relationships. A preference revealed by a request is durable — record the preference (what the user likes, wants, or always does), not the request itself.
19621
+ ` + `
19622
+ ` + `A TOOL RESULT IS NOT A FACT. Before extracting, ask: is the subject of this
19623
+ ` + `candidate a file path, a command/process/agent/session id, a temp directory, or
19624
+ ` + `the location where some output was written? If yes, drop it — it is transcript
19625
+ ` + `exhaust, not memory.
19626
+ ` + `
19627
+ ` + `NEVER extract:
19628
+ ` + `- Tool results verbatim or paraphrased. Concretely, never produce a fact whose
19629
+ ` + ` text resembles any of these: "File created successfully at /path/to/file",
19630
+ ` + ` "A background command with ID bctz4yskm is running, and its output will be
19631
+ ` + ` written to /tmp/...", "Async agent a745598ba84e71df1 was launched successfully
19632
+ ` + ` and is running in the background", "User executed a Bash command to sleep for
19633
+ ` + ` 200 seconds", "The assistant used grep to locate 'truncateSync' in src/foo.ts".
19634
+ ` + `- Anything mentioning a path under /tmp, a scratchpad directory, or a .tmp file.
19635
+ ` + `- Agent tool-use traces or narration of what the assistant did (e.g. "the
19636
+ ` + ` assistant used X to query Y", "ran a search", "sent the message").
19637
+ ` + `- In-flight workflow/process narration (a sub-task started, paused, or is still
19638
+ ` + ` running) — retain the outcome only once the task completes or a decision is made.
19639
+ ` + `- Operation, request, batch, agent, command or session IDs, UUIDs, hashes, or error codes.
19640
+ ` + `- Slash commands the user typed and their effects (e.g. "User issued /clear to
19641
+ ` + ` reset assistant state").
19642
+ ` + `- Hindsight's own errors, retries, backlogs, or internal state — the memory
19643
+ ` + ` system's self-reports are not memories.
19644
+ ` + `- Restatements of the user's current request or the task in progress.
19645
+ ` + `- Volatile state written as a timeless assertion. A version, count, size,
19646
+ ` + ` backlog, status, or any "X is running Y" / "X is at Y" / "X is currently Y"
19647
+ ` + ` claim is true only at the instant it was said. Concretely, never produce a
19648
+ ` + ` fact whose text resembles any of these: "Switchroom fleet is running image
19649
+ ` + ` version v0.18.19", "The switchroom repo is at /path/to/fleet, version
19650
+ ` + ` v0.19.5", "Bank overlord has 43155 pending consolidations", "The build is
19651
+ ` + ` currently green". If the claim is worth keeping, put the date INSIDE the
19652
+ ` + ` fact text ("As of 2026-07-19 the fleet was running v0.18.19"); if you
19653
+ ` + ` cannot date it, drop it. An undated one is recalled forever as though it
19654
+ ` + ` were still true, which is worse than not remembering it at all.
19655
+ ` + `- Transient state (unread counts, build status, what is running right now) unless
19656
+ ` + ` the fact is explicitly dated, in which case record it as a dated observation.
19657
+ ` + `- Greetings, acknowledgements, and routine operational chatter.
19658
+ ` + `
19659
+ ` + `If a candidate fact matches an exclusion, drop it rather than rewording it. If
19660
+ ` + "nothing durable remains, return an empty facts list.",
19661
+ `Extract durable facts that will still be true and useful weeks from now, once this session is forgotten.
19662
+ ` + `
19663
+ ` + `DURABILITY GATE. Emit a candidate ONLY if it is one of these five classes:
19664
+ ` + `- PREFERENCE — what the user likes, wants, or always does; a standing rule or correction.
19665
+ ` + `- DECISION — a settled choice that changes how future work is done, including a choice NOT to do something. A decision about the mechanics of the CURRENT task (which worker to dispatch, which branch to rebase, which PR to merge now, what to do next) is process narration, not a durable decision — drop it unless it establishes a standing rule or permanently changes a system.
19666
+ ` + `- FINDING — a root cause, a measurement, or verified behaviour of a system. Include the number.
19667
+ ` + `- OUTCOME — a completed result that changed the world: what shipped, what a thing turned out to be. Not the act of shipping it.
19668
+ ` + `- RELATIONSHIP — who a person is, what a project or tool is, and how they connect.
19669
+ ` + `If a candidate fits none of the five, it is not a memory. Drop it; do not reword it into one.
19670
+ ` + `
19671
+ ` + `A preference revealed by a request is durable — record the preference (what the user likes, wants, or always does), not the request itself.
19672
+ ` + `
19673
+ ` + `A TOOL RESULT IS NOT A FACT. Before extracting, ask: is the subject of this
19674
+ ` + `candidate a file path, a command/process/agent/session id, a temp directory, or
19675
+ ` + `the location where some output was written? If yes, drop it — it is transcript
19676
+ ` + `exhaust, not memory.
19677
+ ` + `
19678
+ ` + `NEVER extract:
19679
+ ` + `- Tool results verbatim or paraphrased. Concretely, never produce a fact whose
19680
+ ` + ` text resembles any of these: "File created successfully at /path/to/file",
19681
+ ` + ` "A background command with ID bctz4yskm is running, and its output will be
19682
+ ` + ` written to /tmp/...", "Async agent a745598ba84e71df1 was launched successfully
19683
+ ` + ` and is running in the background", "User executed a Bash command to sleep for
19684
+ ` + ` 200 seconds", "The assistant used grep to locate 'truncateSync' in src/foo.ts".
19685
+ ` + `- Anything mentioning a path under /tmp, a scratchpad directory, or a .tmp file.
19686
+ ` + `- Agent tool-use traces or narration of what the assistant did (e.g. "the
19687
+ ` + ` assistant used X to query Y", "ran a search", "sent the message").
19688
+ ` + `- The act of delegating, dispatching, spawning, launching, steering or merging
19689
+ ` + ` work — including when it succeeded. "X was dispatched and completed" is the
19690
+ ` + ` session describing itself. Record only what the work LEARNED or CHANGED.
19691
+ ` + `- In-flight workflow/process narration (a sub-task started, paused, or is still
19692
+ ` + ` running) — retain the outcome only once the task completes or a decision is made.
19693
+ ` + `- Operation, request, batch, agent, command or session IDs, UUIDs, hashes, or error codes.
19694
+ ` + `- Slash commands the user typed and their effects (e.g. "User issued /clear to
19695
+ ` + ` reset assistant state").
19696
+ ` + `- Hindsight's own errors, retries, backlogs, or internal state — the memory
19697
+ ` + ` system's self-reports are not memories.
19698
+ ` + `- Restatements of the user's current request or the task in progress.
19699
+ ` + `- Transient state (unread counts, build status, what is running right now) unless
19700
+ ` + ` the fact is explicitly dated, in which case record it as a dated observation.
19701
+ ` + `- Greetings, acknowledgements, and routine operational chatter.
19702
+ ` + `
19703
+ ` + `Write each fact so it stands alone: name the thing, the number, and the date. A
19704
+ ` + `sentence that only makes sense while reading this transcript is not durable.
19705
+ ` + `
19706
+ ` + `If a candidate fact matches an exclusion, drop it rather than rewording it. If
19707
+ ` + `nothing durable remains, return an empty facts list.
19708
+ `
19558
19709
  ];
19559
19710
  var DEFAULT_OBSERVATIONS_MISSION = `Synthesise durable, standing knowledge about the people, projects, and systems this agent works with: preferences and standing rules, roles and relationships, skills and recurring patterns, technical and operational decisions with their rationale, and the state of long-running work once it lands.
19560
19711
  ` + `
@@ -19637,28 +19788,8 @@ init_paths();
19637
19788
  // src/agents/scaffold.ts
19638
19789
  init_paths();
19639
19790
  init_loader();
19640
-
19641
- // src/vault/vault.ts
19642
- var KNOWN_VAULT_ARTIFACT_NAMES = new Set([
19643
- "vault.enc",
19644
- "vault.enc.bak",
19645
- "vault.enc.tmp",
19646
- "vault.enc.lock",
19647
- ".vault.enc.symlink-tmp"
19648
- ]);
19649
- var SCRYPT_MAXMEM = 128 * 1024 * 1024;
19650
-
19651
- // src/vault/resolver.ts
19652
- init_loader();
19653
-
19654
- // src/vault/broker/client.ts
19655
- import { homedir as homedir3 } from "node:os";
19656
- import { join as join3 } from "node:path";
19657
- var LEGACY_SOCKET_PATH = join3(homedir3(), ".switchroom", "vault-broker.sock");
19658
- var OPERATOR_SOCKET_PATH = join3(homedir3(), ".switchroom", "broker-operator", "sock");
19659
-
19660
- // src/vault/resolver.ts
19661
- var materializedDirs = new Set;
19791
+ init_resolver();
19792
+ init_vault();
19662
19793
 
19663
19794
  // src/setup/onboarding.ts
19664
19795
  init_paths();