switchroom 0.19.32 → 0.19.33
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/auth-broker/index.js +112 -6
- package/dist/cli/switchroom.js +177 -34
- package/dist/host-control/main.js +289 -27
- package/dist/vault/approvals/kernel-server.js +112 -6
- package/dist/vault/broker/server.js +112 -6
- package/package.json +1 -1
- package/telegram-plugin/dist/gateway/gateway.js +209 -61
- package/telegram-plugin/gateway/stale-pin-sweep-store.ts +14 -8
- package/telegram-plugin/gateway/stale-pin-sweep.test.ts +106 -1
- package/telegram-plugin/gateway/stale-pin-sweep.ts +156 -47
- package/telegram-plugin/gateway/status-pin-store.ts +44 -11
- package/telegram-plugin/tests/status-pin-store.test.ts +62 -6
- package/vendor/hindsight-memory/scripts/subagent_retain.py +30 -7
- package/vendor/hindsight-memory/scripts/tests/test_subagent_retain.py +100 -2
- package/vendor/hindsight-memory/settings.json +1 -1
|
@@ -21210,7 +21210,7 @@ function allocateAgentUid(name) {
|
|
|
21210
21210
|
}
|
|
21211
21211
|
|
|
21212
21212
|
// src/build-info.ts
|
|
21213
|
-
var VERSION = "0.19.
|
|
21213
|
+
var VERSION = "0.19.33";
|
|
21214
21214
|
|
|
21215
21215
|
// src/setup/hindsight-recall-tunables.ts
|
|
21216
21216
|
var RECALL_DEADLINE_HEADROOM_SECONDS = 2;
|
|
@@ -21310,12 +21310,12 @@ function assertPositive(value, label) {
|
|
|
21310
21310
|
var _warnedReads = new Set;
|
|
21311
21311
|
|
|
21312
21312
|
// src/setup/hindsight-pg-defaults.ts
|
|
21313
|
-
var HINDSIGHT_PG_MEM_LIMIT_MIB_FOR_DERIVATION =
|
|
21313
|
+
var HINDSIGHT_PG_MEM_LIMIT_MIB_FOR_DERIVATION = 16 * 1024;
|
|
21314
21314
|
var HINDSIGHT_PG_APP_ANON_MIB = 2560;
|
|
21315
21315
|
var HINDSIGHT_PG_PAGE_CACHE_FLOOR_MIB = 2048;
|
|
21316
21316
|
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;
|
|
21317
|
-
var HINDSIGHT_PG_DEFAULT_SHARED_BUFFERS_MIB =
|
|
21318
|
-
var HINDSIGHT_PG_DEFAULT_EFFECTIVE_CACHE_SIZE_MIB =
|
|
21317
|
+
var HINDSIGHT_PG_DEFAULT_SHARED_BUFFERS_MIB = 3072;
|
|
21318
|
+
var HINDSIGHT_PG_DEFAULT_EFFECTIVE_CACHE_SIZE_MIB = 7168;
|
|
21319
21319
|
function pgMib(mib) {
|
|
21320
21320
|
return `${mib}MB`;
|
|
21321
21321
|
}
|
|
@@ -21490,7 +21490,17 @@ var HINDSIGHT_HEALTHCHECK_CMD = `python3 -c '${HINDSIGHT_HEALTHCHECK_PY}'`;
|
|
|
21490
21490
|
var DOCKER_PROBE_TIMEOUT_MS = 60 * 1000;
|
|
21491
21491
|
|
|
21492
21492
|
// src/memory/hindsight.ts
|
|
21493
|
-
var DEFAULT_RETAIN_MISSION = `Extract durable facts that will still be true and useful weeks from now
|
|
21493
|
+
var DEFAULT_RETAIN_MISSION = `Extract durable facts that will still be true and useful weeks from now, once this session is forgotten.
|
|
21494
|
+
` + `
|
|
21495
|
+
` + `DURABILITY GATE. Emit a candidate ONLY if it is one of these five classes:
|
|
21496
|
+
` + `- PREFERENCE — what the user likes, wants, or always does; a standing rule or correction.
|
|
21497
|
+
` + `- 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.
|
|
21498
|
+
` + `- FINDING — a root cause, a measurement, or verified behaviour of a system. Include the number.
|
|
21499
|
+
` + `- OUTCOME — a completed result that changed the world: what shipped, what a thing turned out to be. Not the act of shipping it.
|
|
21500
|
+
` + `- RELATIONSHIP — who a person is, what a project or tool is, and how they connect.
|
|
21501
|
+
` + `If a candidate fits none of the five, it is not a memory. Drop it; do not reword it into one.
|
|
21502
|
+
` + `
|
|
21503
|
+
` + `A preference revealed by a request is durable — record the preference (what the user likes, wants, or always does), not the request itself.
|
|
21494
21504
|
` + `
|
|
21495
21505
|
` + `A TOOL RESULT IS NOT A FACT. Before extracting, ask: is the subject of this
|
|
21496
21506
|
` + `candidate a file path, a command/process/agent/session id, a temp directory, or
|
|
@@ -21507,6 +21517,9 @@ var DEFAULT_RETAIN_MISSION = `Extract durable facts that will still be true and
|
|
|
21507
21517
|
` + `- Anything mentioning a path under /tmp, a scratchpad directory, or a .tmp file.
|
|
21508
21518
|
` + `- Agent tool-use traces or narration of what the assistant did (e.g. "the
|
|
21509
21519
|
` + ` assistant used X to query Y", "ran a search", "sent the message").
|
|
21520
|
+
` + `- The act of delegating, dispatching, spawning, launching, steering or merging
|
|
21521
|
+
` + ` work — including when it succeeded. "X was dispatched and completed" is the
|
|
21522
|
+
` + ` session describing itself. Record only what the work LEARNED or CHANGED.
|
|
21510
21523
|
` + `- In-flight workflow/process narration (a sub-task started, paused, or is still
|
|
21511
21524
|
` + ` running) — retain the outcome only once the task completes or a decision is made.
|
|
21512
21525
|
` + `- Operation, request, batch, agent, command or session IDs, UUIDs, hashes, or error codes.
|
|
@@ -21529,8 +21542,12 @@ var DEFAULT_RETAIN_MISSION = `Extract durable facts that will still be true and
|
|
|
21529
21542
|
` + ` the fact is explicitly dated, in which case record it as a dated observation.
|
|
21530
21543
|
` + `- Greetings, acknowledgements, and routine operational chatter.
|
|
21531
21544
|
` + `
|
|
21545
|
+
` + `Write each fact so it stands alone: name the thing, the number, and the date. A
|
|
21546
|
+
` + `sentence that only makes sense while reading this transcript is not durable.
|
|
21547
|
+
` + `
|
|
21532
21548
|
` + `If a candidate fact matches an exclusion, drop it rather than rewording it. If
|
|
21533
|
-
` +
|
|
21549
|
+
` + `nothing durable remains, return an empty facts list.
|
|
21550
|
+
`;
|
|
21534
21551
|
var SUPERSEDED_RETAIN_MISSIONS = [
|
|
21535
21552
|
"Extract technical decisions, architectural choices, user preferences, project context, and people/tool relationships. Ignore routine greetings and transient operational details.",
|
|
21536
21553
|
"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.",
|
|
@@ -21577,7 +21594,96 @@ var SUPERSEDED_RETAIN_MISSIONS = [
|
|
|
21577
21594
|
` + `- Greetings, acknowledgements, and routine operational chatter.
|
|
21578
21595
|
` + `
|
|
21579
21596
|
` + `If a candidate fact matches an exclusion, drop it rather than rewording it. If
|
|
21580
|
-
` + "nothing durable remains, return an empty facts list."
|
|
21597
|
+
` + "nothing durable remains, return an empty facts list.",
|
|
21598
|
+
`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.
|
|
21599
|
+
` + `
|
|
21600
|
+
` + `A TOOL RESULT IS NOT A FACT. Before extracting, ask: is the subject of this
|
|
21601
|
+
` + `candidate a file path, a command/process/agent/session id, a temp directory, or
|
|
21602
|
+
` + `the location where some output was written? If yes, drop it — it is transcript
|
|
21603
|
+
` + `exhaust, not memory.
|
|
21604
|
+
` + `
|
|
21605
|
+
` + `NEVER extract:
|
|
21606
|
+
` + `- Tool results verbatim or paraphrased. Concretely, never produce a fact whose
|
|
21607
|
+
` + ` text resembles any of these: "File created successfully at /path/to/file",
|
|
21608
|
+
` + ` "A background command with ID bctz4yskm is running, and its output will be
|
|
21609
|
+
` + ` written to /tmp/...", "Async agent a745598ba84e71df1 was launched successfully
|
|
21610
|
+
` + ` and is running in the background", "User executed a Bash command to sleep for
|
|
21611
|
+
` + ` 200 seconds", "The assistant used grep to locate 'truncateSync' in src/foo.ts".
|
|
21612
|
+
` + `- Anything mentioning a path under /tmp, a scratchpad directory, or a .tmp file.
|
|
21613
|
+
` + `- Agent tool-use traces or narration of what the assistant did (e.g. "the
|
|
21614
|
+
` + ` assistant used X to query Y", "ran a search", "sent the message").
|
|
21615
|
+
` + `- In-flight workflow/process narration (a sub-task started, paused, or is still
|
|
21616
|
+
` + ` running) — retain the outcome only once the task completes or a decision is made.
|
|
21617
|
+
` + `- Operation, request, batch, agent, command or session IDs, UUIDs, hashes, or error codes.
|
|
21618
|
+
` + `- Slash commands the user typed and their effects (e.g. "User issued /clear to
|
|
21619
|
+
` + ` reset assistant state").
|
|
21620
|
+
` + `- Hindsight's own errors, retries, backlogs, or internal state — the memory
|
|
21621
|
+
` + ` system's self-reports are not memories.
|
|
21622
|
+
` + `- Restatements of the user's current request or the task in progress.
|
|
21623
|
+
` + `- Volatile state written as a timeless assertion. A version, count, size,
|
|
21624
|
+
` + ` backlog, status, or any "X is running Y" / "X is at Y" / "X is currently Y"
|
|
21625
|
+
` + ` claim is true only at the instant it was said. Concretely, never produce a
|
|
21626
|
+
` + ` fact whose text resembles any of these: "Switchroom fleet is running image
|
|
21627
|
+
` + ` version v0.18.19", "The switchroom repo is at /path/to/fleet, version
|
|
21628
|
+
` + ` v0.19.5", "Bank overlord has 43155 pending consolidations", "The build is
|
|
21629
|
+
` + ` currently green". If the claim is worth keeping, put the date INSIDE the
|
|
21630
|
+
` + ` fact text ("As of 2026-07-19 the fleet was running v0.18.19"); if you
|
|
21631
|
+
` + ` cannot date it, drop it. An undated one is recalled forever as though it
|
|
21632
|
+
` + ` were still true, which is worse than not remembering it at all.
|
|
21633
|
+
` + `- Transient state (unread counts, build status, what is running right now) unless
|
|
21634
|
+
` + ` the fact is explicitly dated, in which case record it as a dated observation.
|
|
21635
|
+
` + `- Greetings, acknowledgements, and routine operational chatter.
|
|
21636
|
+
` + `
|
|
21637
|
+
` + `If a candidate fact matches an exclusion, drop it rather than rewording it. If
|
|
21638
|
+
` + "nothing durable remains, return an empty facts list.",
|
|
21639
|
+
`Extract durable facts that will still be true and useful weeks from now, once this session is forgotten.
|
|
21640
|
+
` + `
|
|
21641
|
+
` + `DURABILITY GATE. Emit a candidate ONLY if it is one of these five classes:
|
|
21642
|
+
` + `- PREFERENCE — what the user likes, wants, or always does; a standing rule or correction.
|
|
21643
|
+
` + `- 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.
|
|
21644
|
+
` + `- FINDING — a root cause, a measurement, or verified behaviour of a system. Include the number.
|
|
21645
|
+
` + `- OUTCOME — a completed result that changed the world: what shipped, what a thing turned out to be. Not the act of shipping it.
|
|
21646
|
+
` + `- RELATIONSHIP — who a person is, what a project or tool is, and how they connect.
|
|
21647
|
+
` + `If a candidate fits none of the five, it is not a memory. Drop it; do not reword it into one.
|
|
21648
|
+
` + `
|
|
21649
|
+
` + `A preference revealed by a request is durable — record the preference (what the user likes, wants, or always does), not the request itself.
|
|
21650
|
+
` + `
|
|
21651
|
+
` + `A TOOL RESULT IS NOT A FACT. Before extracting, ask: is the subject of this
|
|
21652
|
+
` + `candidate a file path, a command/process/agent/session id, a temp directory, or
|
|
21653
|
+
` + `the location where some output was written? If yes, drop it — it is transcript
|
|
21654
|
+
` + `exhaust, not memory.
|
|
21655
|
+
` + `
|
|
21656
|
+
` + `NEVER extract:
|
|
21657
|
+
` + `- Tool results verbatim or paraphrased. Concretely, never produce a fact whose
|
|
21658
|
+
` + ` text resembles any of these: "File created successfully at /path/to/file",
|
|
21659
|
+
` + ` "A background command with ID bctz4yskm is running, and its output will be
|
|
21660
|
+
` + ` written to /tmp/...", "Async agent a745598ba84e71df1 was launched successfully
|
|
21661
|
+
` + ` and is running in the background", "User executed a Bash command to sleep for
|
|
21662
|
+
` + ` 200 seconds", "The assistant used grep to locate 'truncateSync' in src/foo.ts".
|
|
21663
|
+
` + `- Anything mentioning a path under /tmp, a scratchpad directory, or a .tmp file.
|
|
21664
|
+
` + `- Agent tool-use traces or narration of what the assistant did (e.g. "the
|
|
21665
|
+
` + ` assistant used X to query Y", "ran a search", "sent the message").
|
|
21666
|
+
` + `- The act of delegating, dispatching, spawning, launching, steering or merging
|
|
21667
|
+
` + ` work — including when it succeeded. "X was dispatched and completed" is the
|
|
21668
|
+
` + ` session describing itself. Record only what the work LEARNED or CHANGED.
|
|
21669
|
+
` + `- In-flight workflow/process narration (a sub-task started, paused, or is still
|
|
21670
|
+
` + ` running) — retain the outcome only once the task completes or a decision is made.
|
|
21671
|
+
` + `- Operation, request, batch, agent, command or session IDs, UUIDs, hashes, or error codes.
|
|
21672
|
+
` + `- Slash commands the user typed and their effects (e.g. "User issued /clear to
|
|
21673
|
+
` + ` reset assistant state").
|
|
21674
|
+
` + `- Hindsight's own errors, retries, backlogs, or internal state — the memory
|
|
21675
|
+
` + ` system's self-reports are not memories.
|
|
21676
|
+
` + `- Restatements of the user's current request or the task in progress.
|
|
21677
|
+
` + `- Transient state (unread counts, build status, what is running right now) unless
|
|
21678
|
+
` + ` the fact is explicitly dated, in which case record it as a dated observation.
|
|
21679
|
+
` + `- Greetings, acknowledgements, and routine operational chatter.
|
|
21680
|
+
` + `
|
|
21681
|
+
` + `Write each fact so it stands alone: name the thing, the number, and the date. A
|
|
21682
|
+
` + `sentence that only makes sense while reading this transcript is not durable.
|
|
21683
|
+
` + `
|
|
21684
|
+
` + `If a candidate fact matches an exclusion, drop it rather than rewording it. If
|
|
21685
|
+
` + `nothing durable remains, return an empty facts list.
|
|
21686
|
+
`
|
|
21581
21687
|
];
|
|
21582
21688
|
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.
|
|
21583
21689
|
` + `
|
|
@@ -21764,7 +21870,7 @@ var BIND_MOUNT_EXACT_SOURCE_DENY = new Set(["/var/run/docker.sock"]);
|
|
|
21764
21870
|
|
|
21765
21871
|
// src/host-control/server.ts
|
|
21766
21872
|
import { createServer } from "node:net";
|
|
21767
|
-
import { spawn as spawn2, spawnSync as
|
|
21873
|
+
import { spawn as spawn2, spawnSync as spawnSync4 } from "node:child_process";
|
|
21768
21874
|
import { mkdir as mkdir2, chmod, chown, unlink, appendFile } from "node:fs/promises";
|
|
21769
21875
|
import {
|
|
21770
21876
|
readdirSync as readdirSync6,
|
|
@@ -27924,6 +28030,12 @@ function parseAuditLine(line) {
|
|
|
27924
28030
|
entry.m = o.m;
|
|
27925
28031
|
if (typeof o.prior_pin === "string")
|
|
27926
28032
|
entry.prior_pin = o.prior_pin;
|
|
28033
|
+
if (Array.isArray(o.prior_pin_observed) && o.prior_pin_observed.every((v) => typeof v === "string")) {
|
|
28034
|
+
entry.prior_pin_observed = o.prior_pin_observed;
|
|
28035
|
+
}
|
|
28036
|
+
if (typeof o.prior_pin_source === "string") {
|
|
28037
|
+
entry.prior_pin_source = o.prior_pin_source;
|
|
28038
|
+
}
|
|
27927
28039
|
return entry;
|
|
27928
28040
|
}
|
|
27929
28041
|
function latestRolloutRowForRequest(raw, requestId) {
|
|
@@ -27946,11 +28058,96 @@ function latestRolloutRowForRequest(raw, requestId) {
|
|
|
27946
28058
|
// src/cli/deploy-version-guard.ts
|
|
27947
28059
|
var DOCKER_INSPECT_TIMEOUT_MS = 60 * 1000;
|
|
27948
28060
|
|
|
28061
|
+
// src/cli/component-versions.ts
|
|
28062
|
+
var SEMVER_TAG_RE = /^v\d+\.\d+\.\d+$/;
|
|
28063
|
+
function versionFromImageRef(ref) {
|
|
28064
|
+
const at = ref.indexOf("@");
|
|
28065
|
+
const withoutDigest = at >= 0 ? ref.slice(0, at) : ref;
|
|
28066
|
+
const slash = withoutDigest.lastIndexOf("/");
|
|
28067
|
+
const colon = withoutDigest.indexOf(":", slash + 1);
|
|
28068
|
+
if (colon < 0) {
|
|
28069
|
+
return { version: null, detail: `image ref has no tag (${ref})` };
|
|
28070
|
+
}
|
|
28071
|
+
const tag = withoutDigest.slice(colon + 1);
|
|
28072
|
+
if (SEMVER_TAG_RE.test(tag))
|
|
28073
|
+
return { version: tag };
|
|
28074
|
+
return { version: null, detail: `non-semver tag "${tag}"` };
|
|
28075
|
+
}
|
|
28076
|
+
function isSwitchroomReleaseImage(_name, imageRef) {
|
|
28077
|
+
return /\/switchroom-[a-z0-9-]+(:|@|$)/.test(imageRef);
|
|
28078
|
+
}
|
|
28079
|
+
function collectContainerComponents(exec) {
|
|
28080
|
+
const r = exec("docker", [
|
|
28081
|
+
"ps",
|
|
28082
|
+
"--filter",
|
|
28083
|
+
"name=switchroom-",
|
|
28084
|
+
"--format",
|
|
28085
|
+
"{{.Names}}\t{{.Image}}"
|
|
28086
|
+
]);
|
|
28087
|
+
if (r.status !== 0)
|
|
28088
|
+
return [];
|
|
28089
|
+
const out = [];
|
|
28090
|
+
for (const line of r.stdout.split(`
|
|
28091
|
+
`)) {
|
|
28092
|
+
const [name, imageRef] = line.trim().split("\t");
|
|
28093
|
+
if (!name || !imageRef)
|
|
28094
|
+
continue;
|
|
28095
|
+
if (!isSwitchroomReleaseImage(name, imageRef))
|
|
28096
|
+
continue;
|
|
28097
|
+
const { version: version2, detail } = versionFromImageRef(imageRef);
|
|
28098
|
+
out.push({
|
|
28099
|
+
name,
|
|
28100
|
+
kind: "container",
|
|
28101
|
+
version: version2,
|
|
28102
|
+
imageRef,
|
|
28103
|
+
...detail ? { detail } : {}
|
|
28104
|
+
});
|
|
28105
|
+
}
|
|
28106
|
+
return out.sort((a, b) => a.name.localeCompare(b.name));
|
|
28107
|
+
}
|
|
28108
|
+
function normalizeSemverTag(v) {
|
|
28109
|
+
if (!v)
|
|
28110
|
+
return null;
|
|
28111
|
+
const tag = `v${v.trim().replace(/^v/, "")}`;
|
|
28112
|
+
return SEMVER_TAG_RE.test(tag) ? tag : null;
|
|
28113
|
+
}
|
|
28114
|
+
|
|
28115
|
+
// src/cli/component-scope.ts
|
|
28116
|
+
function imageRepoName(imageRef) {
|
|
28117
|
+
if (!imageRef)
|
|
28118
|
+
return null;
|
|
28119
|
+
const at = imageRef.indexOf("@");
|
|
28120
|
+
const withoutDigest = at >= 0 ? imageRef.slice(0, at) : imageRef;
|
|
28121
|
+
const slash = withoutDigest.lastIndexOf("/");
|
|
28122
|
+
if (slash < 0)
|
|
28123
|
+
return null;
|
|
28124
|
+
const afterSlash = withoutDigest.slice(slash + 1);
|
|
28125
|
+
const colon = afterSlash.indexOf(":");
|
|
28126
|
+
const repo = colon >= 0 ? afterSlash.slice(0, colon) : afterSlash;
|
|
28127
|
+
return /^switchroom-[a-z0-9-]+$/.test(repo) ? repo : null;
|
|
28128
|
+
}
|
|
28129
|
+
function classifyComponent(c) {
|
|
28130
|
+
if (c.kind === "cli")
|
|
28131
|
+
return { kind: "cli" };
|
|
28132
|
+
const repo = imageRepoName(c.imageRef);
|
|
28133
|
+
switch (repo) {
|
|
28134
|
+
case "switchroom-web":
|
|
28135
|
+
return { kind: "web" };
|
|
28136
|
+
case "switchroom-hostd":
|
|
28137
|
+
return { kind: "hostd" };
|
|
28138
|
+
case "switchroom-hindsight":
|
|
28139
|
+
return { kind: "hindsight" };
|
|
28140
|
+
case "switchroom-agent": {
|
|
28141
|
+
const agent = c.name.startsWith("switchroom-") ? c.name.slice("switchroom-".length) : c.name;
|
|
28142
|
+
return agent ? { kind: "fleet", agent } : { kind: "fleet" };
|
|
28143
|
+
}
|
|
28144
|
+
default:
|
|
28145
|
+
return { kind: "fleet" };
|
|
28146
|
+
}
|
|
28147
|
+
}
|
|
28148
|
+
|
|
27949
28149
|
// src/cli/rollout.ts
|
|
27950
28150
|
var VERIFY_COMPONENTS_STEP = "verify-components";
|
|
27951
|
-
function isVersionAssertable(target) {
|
|
27952
|
-
return /^v?\d+\.\d+\.\d+$/.test(target.trim());
|
|
27953
|
-
}
|
|
27954
28151
|
var ROLLOUT_PHASE_SENTINEL = "SWITCHROOM_ROLLOUT_PHASE:";
|
|
27955
28152
|
function parseRolloutPhaseLine(line) {
|
|
27956
28153
|
const trimmed = line.trim();
|
|
@@ -28238,12 +28435,74 @@ function parseUpdateResultLine(stdout) {
|
|
|
28238
28435
|
}
|
|
28239
28436
|
}
|
|
28240
28437
|
|
|
28438
|
+
// src/host-control/prior-pin.ts
|
|
28439
|
+
import { spawnSync as spawnSync2 } from "node:child_process";
|
|
28440
|
+
function dockerFleetComponents(dockerBin) {
|
|
28441
|
+
const bin = dockerBin ?? "docker";
|
|
28442
|
+
try {
|
|
28443
|
+
return collectContainerComponents((cmd, args) => {
|
|
28444
|
+
const r = spawnSync2(cmd === "docker" ? bin : cmd, args, {
|
|
28445
|
+
encoding: "utf-8",
|
|
28446
|
+
timeout: 5000
|
|
28447
|
+
});
|
|
28448
|
+
return { status: r.status ?? 1, stdout: r.stdout ?? "" };
|
|
28449
|
+
});
|
|
28450
|
+
} catch {
|
|
28451
|
+
return [];
|
|
28452
|
+
}
|
|
28453
|
+
}
|
|
28454
|
+
function byVersionDesc(a, b) {
|
|
28455
|
+
const cmp = compareReleaseTags(a, b);
|
|
28456
|
+
if (cmp !== null && cmp !== 0)
|
|
28457
|
+
return -cmp;
|
|
28458
|
+
return b.localeCompare(a);
|
|
28459
|
+
}
|
|
28460
|
+
function resolvePriorPinFromFleet(components, target, scope) {
|
|
28461
|
+
const normalizedTarget = normalizeSemverTag(target);
|
|
28462
|
+
const scoped = new Set(scope ?? []);
|
|
28463
|
+
const seen = new Set;
|
|
28464
|
+
for (const c of components) {
|
|
28465
|
+
if (c.kind !== "container")
|
|
28466
|
+
continue;
|
|
28467
|
+
const owner = classifyComponent(c);
|
|
28468
|
+
if (owner.kind !== "fleet" || !owner.agent)
|
|
28469
|
+
continue;
|
|
28470
|
+
if (scoped.size > 0 && !scoped.has(owner.agent))
|
|
28471
|
+
continue;
|
|
28472
|
+
const v = normalizeSemverTag(c.version ?? undefined);
|
|
28473
|
+
if (v)
|
|
28474
|
+
seen.add(v);
|
|
28475
|
+
}
|
|
28476
|
+
const observed = [...seen].sort(byVersionDesc);
|
|
28477
|
+
if (observed.length === 0)
|
|
28478
|
+
return { prior_pin_source: "unobserved" };
|
|
28479
|
+
const candidates = normalizedTarget ? observed.filter((v) => v !== normalizedTarget) : [...observed];
|
|
28480
|
+
if (candidates.length === 0) {
|
|
28481
|
+
return { prior_pin_source: "all-on-target", prior_pin_observed: observed };
|
|
28482
|
+
}
|
|
28483
|
+
if (candidates.length === 1 && observed.length === 1) {
|
|
28484
|
+
return { prior_pin: candidates[0], prior_pin_source: "running-fleet" };
|
|
28485
|
+
}
|
|
28486
|
+
if (candidates.length === 1) {
|
|
28487
|
+
return {
|
|
28488
|
+
prior_pin: candidates[0],
|
|
28489
|
+
prior_pin_source: "running-fleet",
|
|
28490
|
+
prior_pin_observed: observed
|
|
28491
|
+
};
|
|
28492
|
+
}
|
|
28493
|
+
return {
|
|
28494
|
+
prior_pin: candidates[candidates.length - 1],
|
|
28495
|
+
prior_pin_source: "running-fleet-mixed",
|
|
28496
|
+
prior_pin_observed: observed
|
|
28497
|
+
};
|
|
28498
|
+
}
|
|
28499
|
+
|
|
28241
28500
|
// src/host-control/config-edit-validator.ts
|
|
28242
28501
|
var import_yaml5 = __toESM(require_dist(), 1);
|
|
28243
28502
|
import { mkdtempSync, writeFileSync as writeFileSync5, rmSync as rmSync2, existsSync as existsSync14, readFileSync as readFileSync10 } from "node:fs";
|
|
28244
28503
|
import { tmpdir } from "node:os";
|
|
28245
28504
|
import { join as join12, isAbsolute as isAbsolute3, normalize, basename as basename4 } from "node:path";
|
|
28246
|
-
import { spawnSync as
|
|
28505
|
+
import { spawnSync as spawnSync3 } from "node:child_process";
|
|
28247
28506
|
import { isDeepStrictEqual } from "node:util";
|
|
28248
28507
|
var MAX_PATCH_BYTES = 1024 * 1024;
|
|
28249
28508
|
var UNLOCK_CARD_YAML_ALLOWLIST = new Set([
|
|
@@ -28404,10 +28663,10 @@ function applyPatch(unifiedDiff, configPath, gitBin) {
|
|
|
28404
28663
|
"--whitespace=nowarn",
|
|
28405
28664
|
"--recount"
|
|
28406
28665
|
];
|
|
28407
|
-
const checkP1 =
|
|
28666
|
+
const checkP1 = spawnSync3(bin, [...baseArgs.slice(0, 1), "--check", ...baseArgs.slice(1), "-p1", patchFile], { cwd: scratchDir, encoding: "utf8", timeout: 1e4 });
|
|
28408
28667
|
let pStrip = "-p1";
|
|
28409
28668
|
if (checkP1.status !== 0) {
|
|
28410
|
-
const checkP0 =
|
|
28669
|
+
const checkP0 = spawnSync3(bin, [...baseArgs.slice(0, 1), "--check", ...baseArgs.slice(1), "-p0", patchFile], { cwd: scratchDir, encoding: "utf8", timeout: 1e4 });
|
|
28411
28670
|
if (checkP0.status !== 0) {
|
|
28412
28671
|
const stderr = (checkP1.stderr || "") + (checkP0.stderr || "");
|
|
28413
28672
|
return {
|
|
@@ -28418,7 +28677,7 @@ function applyPatch(unifiedDiff, configPath, gitBin) {
|
|
|
28418
28677
|
}
|
|
28419
28678
|
pStrip = "-p0";
|
|
28420
28679
|
}
|
|
28421
|
-
const real =
|
|
28680
|
+
const real = spawnSync3(bin, [...baseArgs, pStrip, patchFile], { cwd: scratchDir, encoding: "utf8", timeout: 1e4 });
|
|
28422
28681
|
if (real.status !== 0) {
|
|
28423
28682
|
return {
|
|
28424
28683
|
ok: false,
|
|
@@ -29123,7 +29382,7 @@ function resolveDigests(imageRefs) {
|
|
|
29123
29382
|
const out = new Map;
|
|
29124
29383
|
for (const ref of imageRefs) {
|
|
29125
29384
|
try {
|
|
29126
|
-
const r =
|
|
29385
|
+
const r = spawnSync4("docker", ["inspect", "--format={{index .RepoDigests 0}}", ref], { encoding: "utf-8", timeout: 5000 });
|
|
29127
29386
|
if (r.status !== 0)
|
|
29128
29387
|
continue;
|
|
29129
29388
|
const trimmed = (r.stdout ?? "").trim();
|
|
@@ -30049,14 +30308,7 @@ class HostdServer {
|
|
|
30049
30308
|
if (args.allow_downgrade)
|
|
30050
30309
|
argv.push("--allow-downgrade");
|
|
30051
30310
|
const installCtx = readCachedInstallType(this.opts.bindRoot ?? this.opts.homeDir);
|
|
30052
|
-
|
|
30053
|
-
try {
|
|
30054
|
-
const cfg = loadConfig(this.opts.configPath);
|
|
30055
|
-
const cfgPin = cfg.release?.pin;
|
|
30056
|
-
if (cfgPin && isVersionAssertable(cfgPin)) {
|
|
30057
|
-
priorPin = cfgPin.startsWith("v") ? cfgPin : `v${cfgPin}`;
|
|
30058
|
-
}
|
|
30059
|
-
} catch {}
|
|
30311
|
+
const priorPin = resolvePriorPinFromFleet(this.fleetComponents(), args.pin, args.agents);
|
|
30060
30312
|
const entry = {
|
|
30061
30313
|
request_id,
|
|
30062
30314
|
caller,
|
|
@@ -30072,7 +30324,9 @@ class HostdServer {
|
|
|
30072
30324
|
install_type: installCtx.install_type,
|
|
30073
30325
|
detected_at: installCtx.detected_at
|
|
30074
30326
|
},
|
|
30075
|
-
...priorPin ? { prior_pin: priorPin } : {}
|
|
30327
|
+
...priorPin.prior_pin ? { prior_pin: priorPin.prior_pin } : {},
|
|
30328
|
+
...priorPin.prior_pin_observed ? { prior_pin_observed: priorPin.prior_pin_observed } : {},
|
|
30329
|
+
prior_pin_source: priorPin.prior_pin_source
|
|
30076
30330
|
};
|
|
30077
30331
|
this.recordStatus(entry);
|
|
30078
30332
|
this.fleetMutationInFlight = {
|
|
@@ -30800,6 +31054,9 @@ ${output.recovery.stderr}` : "";
|
|
|
30800
31054
|
child.on("close", (code) => resolve10({ exit_code: code ?? -1, stdout, stderr }));
|
|
30801
31055
|
});
|
|
30802
31056
|
}
|
|
31057
|
+
fleetComponents() {
|
|
31058
|
+
return this.opts.fleetComponents ? this.opts.fleetComponents() : [];
|
|
31059
|
+
}
|
|
30803
31060
|
imageRefsForDigestCapture() {
|
|
30804
31061
|
if (this.opts.imageRefsForDigests)
|
|
30805
31062
|
return this.opts.imageRefsForDigests();
|
|
@@ -30807,7 +31064,7 @@ ${output.recovery.stderr}` : "";
|
|
|
30807
31064
|
const composePath = join13(this.opts.bindRoot ?? this.opts.homeDir, ".switchroom", "compose", "docker-compose.yml");
|
|
30808
31065
|
if (!existsSync15(composePath))
|
|
30809
31066
|
return [];
|
|
30810
|
-
const r =
|
|
31067
|
+
const r = spawnSync4("docker", [
|
|
30811
31068
|
"compose",
|
|
30812
31069
|
"-p",
|
|
30813
31070
|
"switchroom",
|
|
@@ -30890,6 +31147,8 @@ ${output.recovery.stderr}` : "";
|
|
|
30890
31147
|
}
|
|
30891
31148
|
if (entry.result !== "completed") {
|
|
30892
31149
|
delete entry.prior_pin;
|
|
31150
|
+
delete entry.prior_pin_observed;
|
|
31151
|
+
delete entry.prior_pin_source;
|
|
30893
31152
|
}
|
|
30894
31153
|
}).catch((err2) => {
|
|
30895
31154
|
entry.result = "error";
|
|
@@ -30897,6 +31156,8 @@ ${output.recovery.stderr}` : "";
|
|
|
30897
31156
|
entry.finished_at = Date.now();
|
|
30898
31157
|
entry.error = err2.message;
|
|
30899
31158
|
delete entry.prior_pin;
|
|
31159
|
+
delete entry.prior_pin_observed;
|
|
31160
|
+
delete entry.prior_pin_source;
|
|
30900
31161
|
}).finally(() => {
|
|
30901
31162
|
const pinNote = sentinelProvenOk ? this.clearProvenRolloutPinJournal(`rollout terminal ${entry.request_id}`, entry.started_at) : this.recoverRolloutPinJournal(`rollout terminal ${entry.request_id}`);
|
|
30902
31163
|
if (pinNote)
|
|
@@ -30970,7 +31231,7 @@ ${pinNote}`.trim();
|
|
|
30970
31231
|
return notes;
|
|
30971
31232
|
}
|
|
30972
31233
|
if (!priorPin) {
|
|
30973
|
-
notes.push(`No automatic rollback: no prior version
|
|
31234
|
+
notes.push(`No automatic rollback: no prior version could be read off the running ` + `fleet when this roll started (every agent was already on the target, ` + `or no agent container reported a semver tag), so there is no restore ` + `target to name. Verify compose host-side (\`switchroom apply\`).`);
|
|
30974
31235
|
return notes;
|
|
30975
31236
|
}
|
|
30976
31237
|
const applyRes = await this.runSwitchroom(["apply", "--pin", priorPin, "--compose-only", "--non-interactive"], { SWITCHROOM_HOSTD_CONTEXT: "1" });
|
|
@@ -32662,6 +32923,7 @@ async function main() {
|
|
|
32662
32923
|
const server = new HostdServer({
|
|
32663
32924
|
homeDir: homedir8(),
|
|
32664
32925
|
agentUids,
|
|
32926
|
+
fleetComponents: () => dockerFleetComponents(),
|
|
32665
32927
|
config: {
|
|
32666
32928
|
agents: Object.fromEntries(Object.entries(config.agents).map(([n, a]) => [
|
|
32667
32929
|
n,
|
|
@@ -19287,12 +19287,12 @@ init_paths();
|
|
|
19287
19287
|
var _warnedReads = new Set;
|
|
19288
19288
|
|
|
19289
19289
|
// src/setup/hindsight-pg-defaults.ts
|
|
19290
|
-
var HINDSIGHT_PG_MEM_LIMIT_MIB_FOR_DERIVATION =
|
|
19290
|
+
var HINDSIGHT_PG_MEM_LIMIT_MIB_FOR_DERIVATION = 16 * 1024;
|
|
19291
19291
|
var HINDSIGHT_PG_APP_ANON_MIB = 2560;
|
|
19292
19292
|
var HINDSIGHT_PG_PAGE_CACHE_FLOOR_MIB = 2048;
|
|
19293
19293
|
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 =
|
|
19295
|
-
var HINDSIGHT_PG_DEFAULT_EFFECTIVE_CACHE_SIZE_MIB =
|
|
19294
|
+
var HINDSIGHT_PG_DEFAULT_SHARED_BUFFERS_MIB = 3072;
|
|
19295
|
+
var HINDSIGHT_PG_DEFAULT_EFFECTIVE_CACHE_SIZE_MIB = 7168;
|
|
19296
19296
|
function pgMib(mib) {
|
|
19297
19297
|
return `${mib}MB`;
|
|
19298
19298
|
}
|
|
@@ -19467,7 +19467,17 @@ var HINDSIGHT_HEALTHCHECK_CMD = `python3 -c '${HINDSIGHT_HEALTHCHECK_PY}'`;
|
|
|
19467
19467
|
var DOCKER_PROBE_TIMEOUT_MS = 60 * 1000;
|
|
19468
19468
|
|
|
19469
19469
|
// src/memory/hindsight.ts
|
|
19470
|
-
var DEFAULT_RETAIN_MISSION = `Extract durable facts that will still be true and useful weeks from now
|
|
19470
|
+
var DEFAULT_RETAIN_MISSION = `Extract durable facts that will still be true and useful weeks from now, once this session is forgotten.
|
|
19471
|
+
` + `
|
|
19472
|
+
` + `DURABILITY GATE. Emit a candidate ONLY if it is one of these five classes:
|
|
19473
|
+
` + `- PREFERENCE — what the user likes, wants, or always does; a standing rule or correction.
|
|
19474
|
+
` + `- 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.
|
|
19475
|
+
` + `- FINDING — a root cause, a measurement, or verified behaviour of a system. Include the number.
|
|
19476
|
+
` + `- OUTCOME — a completed result that changed the world: what shipped, what a thing turned out to be. Not the act of shipping it.
|
|
19477
|
+
` + `- RELATIONSHIP — who a person is, what a project or tool is, and how they connect.
|
|
19478
|
+
` + `If a candidate fits none of the five, it is not a memory. Drop it; do not reword it into one.
|
|
19479
|
+
` + `
|
|
19480
|
+
` + `A preference revealed by a request is durable — record the preference (what the user likes, wants, or always does), not the request itself.
|
|
19471
19481
|
` + `
|
|
19472
19482
|
` + `A TOOL RESULT IS NOT A FACT. Before extracting, ask: is the subject of this
|
|
19473
19483
|
` + `candidate a file path, a command/process/agent/session id, a temp directory, or
|
|
@@ -19484,6 +19494,9 @@ var DEFAULT_RETAIN_MISSION = `Extract durable facts that will still be true and
|
|
|
19484
19494
|
` + `- Anything mentioning a path under /tmp, a scratchpad directory, or a .tmp file.
|
|
19485
19495
|
` + `- Agent tool-use traces or narration of what the assistant did (e.g. "the
|
|
19486
19496
|
` + ` assistant used X to query Y", "ran a search", "sent the message").
|
|
19497
|
+
` + `- The act of delegating, dispatching, spawning, launching, steering or merging
|
|
19498
|
+
` + ` work — including when it succeeded. "X was dispatched and completed" is the
|
|
19499
|
+
` + ` session describing itself. Record only what the work LEARNED or CHANGED.
|
|
19487
19500
|
` + `- In-flight workflow/process narration (a sub-task started, paused, or is still
|
|
19488
19501
|
` + ` running) — retain the outcome only once the task completes or a decision is made.
|
|
19489
19502
|
` + `- Operation, request, batch, agent, command or session IDs, UUIDs, hashes, or error codes.
|
|
@@ -19506,8 +19519,12 @@ var DEFAULT_RETAIN_MISSION = `Extract durable facts that will still be true and
|
|
|
19506
19519
|
` + ` the fact is explicitly dated, in which case record it as a dated observation.
|
|
19507
19520
|
` + `- Greetings, acknowledgements, and routine operational chatter.
|
|
19508
19521
|
` + `
|
|
19522
|
+
` + `Write each fact so it stands alone: name the thing, the number, and the date. A
|
|
19523
|
+
` + `sentence that only makes sense while reading this transcript is not durable.
|
|
19524
|
+
` + `
|
|
19509
19525
|
` + `If a candidate fact matches an exclusion, drop it rather than rewording it. If
|
|
19510
|
-
` +
|
|
19526
|
+
` + `nothing durable remains, return an empty facts list.
|
|
19527
|
+
`;
|
|
19511
19528
|
var SUPERSEDED_RETAIN_MISSIONS = [
|
|
19512
19529
|
"Extract technical decisions, architectural choices, user preferences, project context, and people/tool relationships. Ignore routine greetings and transient operational details.",
|
|
19513
19530
|
"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 +19571,96 @@ var SUPERSEDED_RETAIN_MISSIONS = [
|
|
|
19554
19571
|
` + `- Greetings, acknowledgements, and routine operational chatter.
|
|
19555
19572
|
` + `
|
|
19556
19573
|
` + `If a candidate fact matches an exclusion, drop it rather than rewording it. If
|
|
19557
|
-
` + "nothing durable remains, return an empty facts list."
|
|
19574
|
+
` + "nothing durable remains, return an empty facts list.",
|
|
19575
|
+
`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.
|
|
19576
|
+
` + `
|
|
19577
|
+
` + `A TOOL RESULT IS NOT A FACT. Before extracting, ask: is the subject of this
|
|
19578
|
+
` + `candidate a file path, a command/process/agent/session id, a temp directory, or
|
|
19579
|
+
` + `the location where some output was written? If yes, drop it — it is transcript
|
|
19580
|
+
` + `exhaust, not memory.
|
|
19581
|
+
` + `
|
|
19582
|
+
` + `NEVER extract:
|
|
19583
|
+
` + `- Tool results verbatim or paraphrased. Concretely, never produce a fact whose
|
|
19584
|
+
` + ` text resembles any of these: "File created successfully at /path/to/file",
|
|
19585
|
+
` + ` "A background command with ID bctz4yskm is running, and its output will be
|
|
19586
|
+
` + ` written to /tmp/...", "Async agent a745598ba84e71df1 was launched successfully
|
|
19587
|
+
` + ` and is running in the background", "User executed a Bash command to sleep for
|
|
19588
|
+
` + ` 200 seconds", "The assistant used grep to locate 'truncateSync' in src/foo.ts".
|
|
19589
|
+
` + `- Anything mentioning a path under /tmp, a scratchpad directory, or a .tmp file.
|
|
19590
|
+
` + `- Agent tool-use traces or narration of what the assistant did (e.g. "the
|
|
19591
|
+
` + ` assistant used X to query Y", "ran a search", "sent the message").
|
|
19592
|
+
` + `- In-flight workflow/process narration (a sub-task started, paused, or is still
|
|
19593
|
+
` + ` running) — retain the outcome only once the task completes or a decision is made.
|
|
19594
|
+
` + `- Operation, request, batch, agent, command or session IDs, UUIDs, hashes, or error codes.
|
|
19595
|
+
` + `- Slash commands the user typed and their effects (e.g. "User issued /clear to
|
|
19596
|
+
` + ` reset assistant state").
|
|
19597
|
+
` + `- Hindsight's own errors, retries, backlogs, or internal state — the memory
|
|
19598
|
+
` + ` system's self-reports are not memories.
|
|
19599
|
+
` + `- Restatements of the user's current request or the task in progress.
|
|
19600
|
+
` + `- Volatile state written as a timeless assertion. A version, count, size,
|
|
19601
|
+
` + ` backlog, status, or any "X is running Y" / "X is at Y" / "X is currently Y"
|
|
19602
|
+
` + ` claim is true only at the instant it was said. Concretely, never produce a
|
|
19603
|
+
` + ` fact whose text resembles any of these: "Switchroom fleet is running image
|
|
19604
|
+
` + ` version v0.18.19", "The switchroom repo is at /path/to/fleet, version
|
|
19605
|
+
` + ` v0.19.5", "Bank overlord has 43155 pending consolidations", "The build is
|
|
19606
|
+
` + ` currently green". If the claim is worth keeping, put the date INSIDE the
|
|
19607
|
+
` + ` fact text ("As of 2026-07-19 the fleet was running v0.18.19"); if you
|
|
19608
|
+
` + ` cannot date it, drop it. An undated one is recalled forever as though it
|
|
19609
|
+
` + ` were still true, which is worse than not remembering it at all.
|
|
19610
|
+
` + `- Transient state (unread counts, build status, what is running right now) unless
|
|
19611
|
+
` + ` the fact is explicitly dated, in which case record it as a dated observation.
|
|
19612
|
+
` + `- Greetings, acknowledgements, and routine operational chatter.
|
|
19613
|
+
` + `
|
|
19614
|
+
` + `If a candidate fact matches an exclusion, drop it rather than rewording it. If
|
|
19615
|
+
` + "nothing durable remains, return an empty facts list.",
|
|
19616
|
+
`Extract durable facts that will still be true and useful weeks from now, once this session is forgotten.
|
|
19617
|
+
` + `
|
|
19618
|
+
` + `DURABILITY GATE. Emit a candidate ONLY if it is one of these five classes:
|
|
19619
|
+
` + `- PREFERENCE — what the user likes, wants, or always does; a standing rule or correction.
|
|
19620
|
+
` + `- 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.
|
|
19621
|
+
` + `- FINDING — a root cause, a measurement, or verified behaviour of a system. Include the number.
|
|
19622
|
+
` + `- OUTCOME — a completed result that changed the world: what shipped, what a thing turned out to be. Not the act of shipping it.
|
|
19623
|
+
` + `- RELATIONSHIP — who a person is, what a project or tool is, and how they connect.
|
|
19624
|
+
` + `If a candidate fits none of the five, it is not a memory. Drop it; do not reword it into one.
|
|
19625
|
+
` + `
|
|
19626
|
+
` + `A preference revealed by a request is durable — record the preference (what the user likes, wants, or always does), not the request itself.
|
|
19627
|
+
` + `
|
|
19628
|
+
` + `A TOOL RESULT IS NOT A FACT. Before extracting, ask: is the subject of this
|
|
19629
|
+
` + `candidate a file path, a command/process/agent/session id, a temp directory, or
|
|
19630
|
+
` + `the location where some output was written? If yes, drop it — it is transcript
|
|
19631
|
+
` + `exhaust, not memory.
|
|
19632
|
+
` + `
|
|
19633
|
+
` + `NEVER extract:
|
|
19634
|
+
` + `- Tool results verbatim or paraphrased. Concretely, never produce a fact whose
|
|
19635
|
+
` + ` text resembles any of these: "File created successfully at /path/to/file",
|
|
19636
|
+
` + ` "A background command with ID bctz4yskm is running, and its output will be
|
|
19637
|
+
` + ` written to /tmp/...", "Async agent a745598ba84e71df1 was launched successfully
|
|
19638
|
+
` + ` and is running in the background", "User executed a Bash command to sleep for
|
|
19639
|
+
` + ` 200 seconds", "The assistant used grep to locate 'truncateSync' in src/foo.ts".
|
|
19640
|
+
` + `- Anything mentioning a path under /tmp, a scratchpad directory, or a .tmp file.
|
|
19641
|
+
` + `- Agent tool-use traces or narration of what the assistant did (e.g. "the
|
|
19642
|
+
` + ` assistant used X to query Y", "ran a search", "sent the message").
|
|
19643
|
+
` + `- The act of delegating, dispatching, spawning, launching, steering or merging
|
|
19644
|
+
` + ` work — including when it succeeded. "X was dispatched and completed" is the
|
|
19645
|
+
` + ` session describing itself. Record only what the work LEARNED or CHANGED.
|
|
19646
|
+
` + `- In-flight workflow/process narration (a sub-task started, paused, or is still
|
|
19647
|
+
` + ` running) — retain the outcome only once the task completes or a decision is made.
|
|
19648
|
+
` + `- Operation, request, batch, agent, command or session IDs, UUIDs, hashes, or error codes.
|
|
19649
|
+
` + `- Slash commands the user typed and their effects (e.g. "User issued /clear to
|
|
19650
|
+
` + ` reset assistant state").
|
|
19651
|
+
` + `- Hindsight's own errors, retries, backlogs, or internal state — the memory
|
|
19652
|
+
` + ` system's self-reports are not memories.
|
|
19653
|
+
` + `- Restatements of the user's current request or the task in progress.
|
|
19654
|
+
` + `- Transient state (unread counts, build status, what is running right now) unless
|
|
19655
|
+
` + ` the fact is explicitly dated, in which case record it as a dated observation.
|
|
19656
|
+
` + `- Greetings, acknowledgements, and routine operational chatter.
|
|
19657
|
+
` + `
|
|
19658
|
+
` + `Write each fact so it stands alone: name the thing, the number, and the date. A
|
|
19659
|
+
` + `sentence that only makes sense while reading this transcript is not durable.
|
|
19660
|
+
` + `
|
|
19661
|
+
` + `If a candidate fact matches an exclusion, drop it rather than rewording it. If
|
|
19662
|
+
` + `nothing durable remains, return an empty facts list.
|
|
19663
|
+
`
|
|
19558
19664
|
];
|
|
19559
19665
|
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
19666
|
` + `
|