From 7b87462207c70c7594fe5840a55afe3d4b76ea96 Mon Sep 17 00:00:00 2001 From: James3014 Date: Sun, 13 Sep 2026 18:06:13 +0800 Subject: [PATCH 1/7] feat(chat-swarm): add worker auto-compact planner --- src/chat-swarm-auto-compact.ts | 291 +++++++++++++++++++++++++++++++++ 1 file changed, 291 insertions(+) create mode 100644 src/chat-swarm-auto-compact.ts diff --git a/src/chat-swarm-auto-compact.ts b/src/chat-swarm-auto-compact.ts new file mode 100644 index 000000000..7bb7aa0ca --- /dev/null +++ b/src/chat-swarm-auto-compact.ts @@ -0,0 +1,291 @@ +import { + assertBounded, + canonicalize, + ChatSwarmError, + hashContent, + MAX_ID_BYTES, + MAX_JSON_BYTES, + type ChatSwarmWorker, +} from "./chat-swarm-contract.js"; + +export const WORKER_AUTO_COMPACT_CAPSULE_SCHEMA = "chat_swarm.worker_auto_compact_capsule.v1" as const; +export const WORKER_AUTO_COMPACT_CAPSULE_MAX_BYTES = 48 * 1024; + +const MAX_PROVENANCE_BYTES = 2 * 1024; +const MAX_ROLE_BYTES = 8 * 1024; +const MAX_SUMMARY_BYTES = 16 * 1024; +const MAX_CLAIM_CEILING_BYTES = 2 * 1024; +const MAX_REF_BYTES = 512; +const MAX_BLOCKER_BYTES = 2 * 1024; +const MAX_REFS_PER_KIND = 32; +const MAX_BLOCKERS = 16; +const MAX_TIMESTAMP_BYTES = 128; + +export type WorkerContextPressurePrecision = "ESTIMATED" | "EXACT"; +export type WorkerContextPressureSource = "DEVSPACE_ESTIMATE" | "CARRIER_ESTIMATE" | "HOST_NATIVE"; + +export interface WorkerContextPressureSignal { + precision: WorkerContextPressurePrecision; + source: WorkerContextPressureSource; + utilizationRatio: number; + provenance: string; + observedAt: string; +} + +export type WorkerAutoCompactDecisionState = + | "NOT_REQUIRED" + | "WAIT_SAFE_BOUNDARY" + | "BLOCKED_RECONCILIATION" + | "BLOCKED_CHECKPOINT" + | "BLOCKED_DISABLED" + | "PREPARE_REQUIRED"; + +export interface WorkerAutoCompactDecisionInput { + worker: Pick< + ChatSwarmWorker, + "id" | "swarmId" | "lifecycleState" | "currentTaskId" | "continuationEpoch" | "checkpoint" + >; + pressure: WorkerContextPressureSignal; + prepareAtRatio: number; + hasPendingContinuation?: boolean; + hasUnknownEffect?: boolean; +} + +export interface WorkerAutoCompactDecision { + state: WorkerAutoCompactDecisionState; + compactRequired: boolean; + safeToPrepare: boolean; + reason: string; + sourceEpoch: number; + checkpointHash?: string; +} + +export interface WorkerAutoCompactCapsule { + schema: typeof WORKER_AUTO_COMPACT_CAPSULE_SCHEMA; + swarmId: string; + workerId: string; + sourceEpoch: number; + checkpointHash: string; + pressure: WorkerContextPressureSignal; + roleInstructions: string; + contextSummary: string; + summaryAuthority: "CONTEXT_ONLY"; + taskRefs: string[]; + resultRefs: string[]; + evidenceRefs: string[]; + blockers: string[]; + claimCeiling: string; + createdAt: string; + capsuleHash: string; +} + +export interface WorkerAutoCompactPrepareInput extends WorkerAutoCompactDecisionInput { + roleInstructions: string; + contextSummary: string; + taskRefs?: string[]; + resultRefs?: string[]; + evidenceRefs?: string[]; + blockers?: string[]; + claimCeiling: string; + createdAt: string; +} + +export interface WorkerAutoCompactReplacementIntent { + kind: "REQUEST_REPLACEMENT_CARRIER"; + authority: "NON_AUTHORIZING"; + swarmId: string; + workerId: string; + sourceEpoch: number; + capsuleHash: string; +} + +export interface WorkerAutoCompactPlan { + decision: WorkerAutoCompactDecision; + capsule?: WorkerAutoCompactCapsule; + replacementIntent?: WorkerAutoCompactReplacementIntent; +} + +export function evaluateWorkerAutoCompact(input: WorkerAutoCompactDecisionInput): WorkerAutoCompactDecision { + validateWorkerIdentity(input.worker); + validatePressure(input.pressure); + validateThreshold(input.prepareAtRatio); + validateEpoch(input.worker.continuationEpoch); + + if (input.pressure.utilizationRatio < input.prepareAtRatio) { + return decision(input, "NOT_REQUIRED", false, false, "context pressure is below the configured prepare threshold"); + } + + if (input.hasUnknownEffect || input.hasPendingContinuation || input.worker.lifecycleState === "RECONCILE_REQUIRED") { + return decision( + input, + "BLOCKED_RECONCILIATION", + true, + false, + "worker has unresolved effect or continuation state and must reconcile before Auto Compact", + ); + } + + if (input.worker.lifecycleState === "DISABLED") { + return decision(input, "BLOCKED_DISABLED", true, false, "disabled worker cannot prepare Auto Compact"); + } + + if (input.worker.lifecycleState === "BUSY" || input.worker.currentTaskId) { + if (input.worker.currentTaskId) assertBounded(input.worker.currentTaskId, MAX_ID_BYTES, "currentTaskId"); + return decision(input, "WAIT_SAFE_BOUNDARY", true, false, "worker must reach an idle safe boundary before Auto Compact"); + } + + const checkpointHash = computeCheckpointHash(input.worker.checkpoint); + if (!checkpointHash) { + return decision(input, "BLOCKED_CHECKPOINT", true, false, "worker requires a bounded checkpoint before Auto Compact"); + } + + return { + state: "PREPARE_REQUIRED", + compactRequired: true, + safeToPrepare: true, + reason: "context pressure reached the configured threshold at a safe worker boundary", + sourceEpoch: input.worker.continuationEpoch, + checkpointHash, + }; +} + +export function prepareWorkerAutoCompact(input: WorkerAutoCompactPrepareInput): WorkerAutoCompactPlan { + const decisionResult = evaluateWorkerAutoCompact(input); + if (!decisionResult.safeToPrepare || decisionResult.state !== "PREPARE_REQUIRED" || !decisionResult.checkpointHash) { + return { decision: decisionResult }; + } + + assertBounded(input.roleInstructions, MAX_ROLE_BYTES, "roleInstructions"); + assertBounded(input.contextSummary, MAX_SUMMARY_BYTES, "contextSummary"); + assertBounded(input.claimCeiling, MAX_CLAIM_CEILING_BYTES, "claimCeiling"); + validateTimestamp(input.createdAt, "createdAt"); + + const taskRefs = validateRefs(input.taskRefs ?? [], "taskRefs"); + const resultRefs = validateRefs(input.resultRefs ?? [], "resultRefs"); + const evidenceRefs = validateRefs(input.evidenceRefs ?? [], "evidenceRefs"); + const blockers = validateBlockers(input.blockers ?? []); + + const payload = { + schema: WORKER_AUTO_COMPACT_CAPSULE_SCHEMA, + swarmId: input.worker.swarmId, + workerId: input.worker.id, + sourceEpoch: input.worker.continuationEpoch, + checkpointHash: decisionResult.checkpointHash, + pressure: input.pressure, + roleInstructions: input.roleInstructions, + contextSummary: input.contextSummary, + summaryAuthority: "CONTEXT_ONLY" as const, + taskRefs, + resultRefs, + evidenceRefs, + blockers, + claimCeiling: input.claimCeiling, + createdAt: input.createdAt, + }; + + const canonicalJson = JSON.stringify(canonicalize(payload)); + if (Buffer.byteLength(canonicalJson, "utf8") > WORKER_AUTO_COMPACT_CAPSULE_MAX_BYTES) { + throw new ChatSwarmError( + "INVALID_INPUT", + `Auto Compact capsule exceeds ${WORKER_AUTO_COMPACT_CAPSULE_MAX_BYTES} bytes`, + ); + } + + const capsule: WorkerAutoCompactCapsule = { + ...payload, + capsuleHash: hashContent(canonicalJson), + }; + + return { + decision: decisionResult, + capsule, + replacementIntent: { + kind: "REQUEST_REPLACEMENT_CARRIER", + authority: "NON_AUTHORIZING", + swarmId: input.worker.swarmId, + workerId: input.worker.id, + sourceEpoch: input.worker.continuationEpoch, + capsuleHash: capsule.capsuleHash, + }, + }; +} + +function decision( + input: WorkerAutoCompactDecisionInput, + state: WorkerAutoCompactDecisionState, + compactRequired: boolean, + safeToPrepare: boolean, + reason: string, +): WorkerAutoCompactDecision { + return { + state, + compactRequired, + safeToPrepare, + reason, + sourceEpoch: input.worker.continuationEpoch, + }; +} + +function validateWorkerIdentity(worker: WorkerAutoCompactDecisionInput["worker"]): void { + assertBounded(worker.id, MAX_ID_BYTES, "workerId"); + assertBounded(worker.swarmId, MAX_ID_BYTES, "swarmId"); +} + +function validatePressure(pressure: WorkerContextPressureSignal): void { + if (!Number.isFinite(pressure.utilizationRatio) || pressure.utilizationRatio < 0 || pressure.utilizationRatio > 1) { + throw new ChatSwarmError("INVALID_INPUT", "context utilizationRatio must be between 0 and 1"); + } + assertBounded(pressure.provenance, MAX_PROVENANCE_BYTES, "pressure provenance"); + validateTimestamp(pressure.observedAt, "pressure observedAt"); + if (pressure.precision === "EXACT" && pressure.source !== "HOST_NATIVE") { + throw new ChatSwarmError("INVALID_INPUT", "exact context pressure requires a host-native source"); + } +} + +function validateThreshold(value: number): void { + if (!Number.isFinite(value) || value <= 0 || value > 1) { + throw new ChatSwarmError("INVALID_INPUT", "prepareAtRatio must be greater than 0 and at most 1"); + } +} + +function validateEpoch(value: number): void { + if (!Number.isSafeInteger(value) || value < 0) { + throw new ChatSwarmError("INVALID_INPUT", "continuationEpoch must be a non-negative integer"); + } +} + +function computeCheckpointHash(checkpoint: Record | undefined): string | undefined { + if (!checkpoint || Array.isArray(checkpoint) || typeof checkpoint !== "object") return undefined; + const checkpointJson = JSON.stringify(canonicalize(checkpoint)); + if (Buffer.byteLength(checkpointJson, "utf8") > MAX_JSON_BYTES) { + throw new ChatSwarmError("INVALID_INPUT", `worker checkpoint exceeds ${MAX_JSON_BYTES} bytes`); + } + return hashContent(checkpointJson); +} + +function validateRefs(values: string[], label: string): string[] { + if (values.length > MAX_REFS_PER_KIND) { + throw new ChatSwarmError("INVALID_INPUT", `${label} exceeds ${MAX_REFS_PER_KIND} entries`); + } + return values.map((value, index) => { + assertBounded(value, MAX_REF_BYTES, `${label}[${index}]`); + return value; + }); +} + +function validateBlockers(values: string[]): string[] { + if (values.length > MAX_BLOCKERS) { + throw new ChatSwarmError("INVALID_INPUT", `blockers exceeds ${MAX_BLOCKERS} entries`); + } + return values.map((value, index) => { + assertBounded(value, MAX_BLOCKER_BYTES, `blockers[${index}]`); + return value; + }); +} + +function validateTimestamp(value: string, label: string): void { + assertBounded(value, MAX_TIMESTAMP_BYTES, label); + if (!Number.isFinite(Date.parse(value))) { + throw new ChatSwarmError("INVALID_INPUT", `${label} must be a valid timestamp`); + } +} From 20abf0c402a8fa8a167f84e519fecd8e649fde4d Mon Sep 17 00:00:00 2001 From: James3014 Date: Sun, 13 Sep 2026 18:06:38 +0800 Subject: [PATCH 2/7] test(chat-swarm): cover worker auto-compact planner --- src/chat-swarm-auto-compact.test.ts | 222 ++++++++++++++++++++++++++++ 1 file changed, 222 insertions(+) create mode 100644 src/chat-swarm-auto-compact.test.ts diff --git a/src/chat-swarm-auto-compact.test.ts b/src/chat-swarm-auto-compact.test.ts new file mode 100644 index 000000000..95d089606 --- /dev/null +++ b/src/chat-swarm-auto-compact.test.ts @@ -0,0 +1,222 @@ +import assert from "node:assert/strict"; +import test from "node:test"; +import { ChatSwarmError, type ChatSwarmWorker } from "./chat-swarm-contract.js"; +import { + WORKER_AUTO_COMPACT_CAPSULE_SCHEMA, + evaluateWorkerAutoCompact, + prepareWorkerAutoCompact, + type WorkerContextPressureSignal, +} from "./chat-swarm-auto-compact.js"; + +function worker(overrides: Partial = {}): ChatSwarmWorker { + return { + id: "worker-1", + swarmId: "swarm-1", + label: "Worker-01", + runtimeKind: "mcp_peer", + sessionIdentityFingerprint: "1".repeat(64), + carrierConversationFingerprint: "2".repeat(64), + lifecycleState: "AVAILABLE", + checkpoint: { summary: "safe checkpoint", lastTaskId: "task-9" }, + continuationEpoch: 4, + createdAt: "2026-09-13T09:00:00.000Z", + updatedAt: "2026-09-13T09:00:00.000Z", + ...overrides, + }; +} + +function pressure(overrides: Partial = {}): WorkerContextPressureSignal { + return { + precision: "ESTIMATED", + source: "DEVSPACE_ESTIMATE", + utilizationRatio: 0.85, + provenance: "bounded DevSpace context ledger estimate", + observedAt: "2026-09-13T09:30:00.000Z", + ...overrides, + }; +} + +function prepare(overrides: Partial[0]> = {}) { + return prepareWorkerAutoCompact({ + worker: worker(), + pressure: pressure(), + prepareAtRatio: 0.8, + roleInstructions: "Continue as the same logical worker under existing Swarm authority.", + contextSummary: "Completed the prior bounded task; next work should resume from durable task state.", + taskRefs: ["task-9"], + resultRefs: ["result:task-9"], + evidenceRefs: ["evidence:checkpoint-9"], + blockers: [], + claimCeiling: "WORKER_AUTO_COMPACT_PLANNER_SOURCE_ACCEPTED", + createdAt: "2026-09-13T09:31:00.000Z", + ...overrides, + }); +} + +test("pressure below threshold does not require Auto Compact", () => { + const result = evaluateWorkerAutoCompact({ + worker: worker(), + pressure: pressure({ utilizationRatio: 0.79 }), + prepareAtRatio: 0.8, + }); + assert.equal(result.state, "NOT_REQUIRED"); + assert.equal(result.compactRequired, false); + assert.equal(result.safeToPrepare, false); +}); + +test("estimated pressure remains explicitly estimated and prepares only at a safe boundary", () => { + const result = prepare(); + assert.equal(result.decision.state, "PREPARE_REQUIRED"); + assert.equal(result.decision.compactRequired, true); + assert.equal(result.decision.safeToPrepare, true); + assert.equal(result.capsule?.schema, WORKER_AUTO_COMPACT_CAPSULE_SCHEMA); + assert.equal(result.capsule?.pressure.precision, "ESTIMATED"); + assert.equal(result.capsule?.pressure.source, "DEVSPACE_ESTIMATE"); + assert.equal(result.capsule?.summaryAuthority, "CONTEXT_ONLY"); + assert.match(result.capsule?.checkpointHash ?? "", /^[0-9a-f]{64}$/); + assert.match(result.capsule?.capsuleHash ?? "", /^[0-9a-f]{64}$/); + assert.deepEqual(result.replacementIntent, { + kind: "REQUEST_REPLACEMENT_CARRIER", + authority: "NON_AUTHORIZING", + swarmId: "swarm-1", + workerId: "worker-1", + sourceEpoch: 4, + capsuleHash: result.capsule?.capsuleHash, + }); +}); + +test("non-host pressure cannot be labeled exact", () => { + assert.throws( + () => evaluateWorkerAutoCompact({ + worker: worker(), + pressure: pressure({ precision: "EXACT", source: "CARRIER_ESTIMATE" }), + prepareAtRatio: 0.8, + }), + (error: unknown) => error instanceof ChatSwarmError && error.code === "INVALID_INPUT", + ); + + assert.doesNotThrow(() => evaluateWorkerAutoCompact({ + worker: worker(), + pressure: pressure({ precision: "EXACT", source: "HOST_NATIVE" }), + prepareAtRatio: 0.8, + })); +}); + +test("busy worker waits for an idle boundary without producing a replacement intent", () => { + const result = prepare({ + worker: worker({ lifecycleState: "BUSY", currentTaskId: "task-live" }), + }); + assert.equal(result.decision.state, "WAIT_SAFE_BOUNDARY"); + assert.equal(result.decision.compactRequired, true); + assert.equal(result.decision.safeToPrepare, false); + assert.equal(result.capsule, undefined); + assert.equal(result.replacementIntent, undefined); +}); + +test("unknown effect, pending continuation, or reconciliation state blocks Auto Compact", () => { + for (const input of [ + { hasUnknownEffect: true }, + { hasPendingContinuation: true }, + { worker: worker({ lifecycleState: "RECONCILE_REQUIRED" }) }, + ]) { + const result = prepare(input); + assert.equal(result.decision.state, "BLOCKED_RECONCILIATION"); + assert.equal(result.decision.safeToPrepare, false); + assert.equal(result.capsule, undefined); + } +}); + +test("missing checkpoint and disabled worker fail closed", () => { + const missingCheckpoint = prepare({ worker: worker({ checkpoint: undefined }) }); + assert.equal(missingCheckpoint.decision.state, "BLOCKED_CHECKPOINT"); + assert.equal(missingCheckpoint.capsule, undefined); + + const disabled = prepare({ worker: worker({ lifecycleState: "DISABLED" }) }); + assert.equal(disabled.decision.state, "BLOCKED_DISABLED"); + assert.equal(disabled.capsule, undefined); +}); + +test("capsule hash is deterministic and material changes alter the hash", () => { + const first = prepare(); + const second = prepare(); + const changedSummary = prepare({ contextSummary: "different bounded context" }); + const changedPressure = prepare({ pressure: pressure({ utilizationRatio: 0.9 }) }); + const changedEpoch = prepare({ worker: worker({ continuationEpoch: 5 }) }); + + assert.equal(first.capsule?.capsuleHash, second.capsule?.capsuleHash); + assert.notEqual(first.capsule?.capsuleHash, changedSummary.capsule?.capsuleHash); + assert.notEqual(first.capsule?.capsuleHash, changedPressure.capsule?.capsuleHash); + assert.notEqual(first.capsule?.capsuleHash, changedEpoch.capsule?.capsuleHash); +}); + +test("capsule structurally excludes raw checkpoint, transcript, reasoning, tool history and credentials", () => { + const capsule = prepare().capsule! as unknown as Record; + for (const forbidden of [ + "checkpoint", + "transcript", + "chainOfThought", + "reasoning", + "toolHistory", + "rawToolOutput", + "credentials", + "token", + "cookie", + "sessionSecret", + ]) { + assert.equal(Object.prototype.hasOwnProperty.call(capsule, forbidden), false, forbidden); + } + assert.equal(typeof capsule.checkpointHash, "string"); +}); + +test("capsule and reference bounds fail closed", () => { + assert.throws( + () => prepare({ contextSummary: "x".repeat(16 * 1024 + 1) }), + (error: unknown) => error instanceof ChatSwarmError && error.code === "INVALID_INPUT", + ); + + assert.throws( + () => prepare({ taskRefs: Array.from({ length: 33 }, (_, index) => `task-${index}`) }), + (error: unknown) => error instanceof ChatSwarmError && error.code === "INVALID_INPUT", + ); + + assert.throws( + () => prepare({ blockers: Array.from({ length: 17 }, (_, index) => `blocker-${index}`) }), + (error: unknown) => error instanceof ChatSwarmError && error.code === "INVALID_INPUT", + ); +}); + +test("invalid threshold, ratio, timestamp and epoch fail closed", () => { + for (const prepareAtRatio of [0, -0.1, 1.01, Number.NaN]) { + assert.throws( + () => evaluateWorkerAutoCompact({ worker: worker(), pressure: pressure(), prepareAtRatio }), + (error: unknown) => error instanceof ChatSwarmError && error.code === "INVALID_INPUT", + ); + } + + assert.throws( + () => evaluateWorkerAutoCompact({ + worker: worker(), + pressure: pressure({ utilizationRatio: 1.1 }), + prepareAtRatio: 0.8, + }), + (error: unknown) => error instanceof ChatSwarmError && error.code === "INVALID_INPUT", + ); + + assert.throws( + () => evaluateWorkerAutoCompact({ + worker: worker(), + pressure: pressure({ observedAt: "not-a-time" }), + prepareAtRatio: 0.8, + }), + (error: unknown) => error instanceof ChatSwarmError && error.code === "INVALID_INPUT", + ); + + assert.throws( + () => evaluateWorkerAutoCompact({ + worker: worker({ continuationEpoch: -1 }), + pressure: pressure(), + prepareAtRatio: 0.8, + }), + (error: unknown) => error instanceof ChatSwarmError && error.code === "INVALID_INPUT", + ); +}); From 6446d869408e9704a492f4d2fbcf3665502a3b8b Mon Sep 17 00:00:00 2001 From: James3014 Date: Sun, 13 Sep 2026 18:07:22 +0800 Subject: [PATCH 3/7] test(chat-swarm): include auto-compact regressions --- src/chat-swarm-continuation-domain.test.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/chat-swarm-continuation-domain.test.ts b/src/chat-swarm-continuation-domain.test.ts index 0631b1ed8..673ba9433 100644 --- a/src/chat-swarm-continuation-domain.test.ts +++ b/src/chat-swarm-continuation-domain.test.ts @@ -1,5 +1,6 @@ import assert from "node:assert/strict"; import test from "node:test"; +import "./chat-swarm-auto-compact.test.js"; import "./chat-swarm-continuation-coordinator.test.js"; import "./chat-swarm-continuation-corruption-fence.test.js"; import "./chat-swarm-continuation-restart-fence.test.js"; @@ -120,4 +121,4 @@ test("commit guard rejects malformed target epoch and non-pending request", () = () => assertContinuationCommitAllowed(worker(), request({ status: "APPROVED" })), (error: unknown) => error instanceof ChatSwarmError && error.code === "INVALID_STATE", ); -}); +}); \ No newline at end of file From be472f90ba99261febf6ce76ccbfb158a1297887 Mon Sep 17 00:00:00 2001 From: James3014 Date: Sun, 13 Sep 2026 18:09:09 +0800 Subject: [PATCH 4/7] fix(chat-swarm): bind auto-compact trigger provenance --- src/chat-swarm-auto-compact.ts | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/chat-swarm-auto-compact.ts b/src/chat-swarm-auto-compact.ts index 7bb7aa0ca..62b140476 100644 --- a/src/chat-swarm-auto-compact.ts +++ b/src/chat-swarm-auto-compact.ts @@ -11,6 +11,8 @@ import { export const WORKER_AUTO_COMPACT_CAPSULE_SCHEMA = "chat_swarm.worker_auto_compact_capsule.v1" as const; export const WORKER_AUTO_COMPACT_CAPSULE_MAX_BYTES = 48 * 1024; +const PRESSURE_PRECISIONS = ["ESTIMATED", "EXACT"] as const; +const PRESSURE_SOURCES = ["DEVSPACE_ESTIMATE", "CARRIER_ESTIMATE", "HOST_NATIVE"] as const; const MAX_PROVENANCE_BYTES = 2 * 1024; const MAX_ROLE_BYTES = 8 * 1024; const MAX_SUMMARY_BYTES = 16 * 1024; @@ -21,8 +23,8 @@ const MAX_REFS_PER_KIND = 32; const MAX_BLOCKERS = 16; const MAX_TIMESTAMP_BYTES = 128; -export type WorkerContextPressurePrecision = "ESTIMATED" | "EXACT"; -export type WorkerContextPressureSource = "DEVSPACE_ESTIMATE" | "CARRIER_ESTIMATE" | "HOST_NATIVE"; +export type WorkerContextPressurePrecision = (typeof PRESSURE_PRECISIONS)[number]; +export type WorkerContextPressureSource = (typeof PRESSURE_SOURCES)[number]; export interface WorkerContextPressureSignal { precision: WorkerContextPressurePrecision; @@ -57,6 +59,7 @@ export interface WorkerAutoCompactDecision { safeToPrepare: boolean; reason: string; sourceEpoch: number; + prepareAtRatio: number; checkpointHash?: string; } @@ -67,6 +70,7 @@ export interface WorkerAutoCompactCapsule { sourceEpoch: number; checkpointHash: string; pressure: WorkerContextPressureSignal; + prepareAtRatio: number; roleInstructions: string; contextSummary: string; summaryAuthority: "CONTEXT_ONLY"; @@ -145,6 +149,7 @@ export function evaluateWorkerAutoCompact(input: WorkerAutoCompactDecisionInput) safeToPrepare: true, reason: "context pressure reached the configured threshold at a safe worker boundary", sourceEpoch: input.worker.continuationEpoch, + prepareAtRatio: input.prepareAtRatio, checkpointHash, }; } @@ -159,6 +164,9 @@ export function prepareWorkerAutoCompact(input: WorkerAutoCompactPrepareInput): assertBounded(input.contextSummary, MAX_SUMMARY_BYTES, "contextSummary"); assertBounded(input.claimCeiling, MAX_CLAIM_CEILING_BYTES, "claimCeiling"); validateTimestamp(input.createdAt, "createdAt"); + if (Date.parse(input.createdAt) < Date.parse(input.pressure.observedAt)) { + throw new ChatSwarmError("INVALID_INPUT", "createdAt cannot precede the pressure observation"); + } const taskRefs = validateRefs(input.taskRefs ?? [], "taskRefs"); const resultRefs = validateRefs(input.resultRefs ?? [], "resultRefs"); @@ -172,6 +180,7 @@ export function prepareWorkerAutoCompact(input: WorkerAutoCompactPrepareInput): sourceEpoch: input.worker.continuationEpoch, checkpointHash: decisionResult.checkpointHash, pressure: input.pressure, + prepareAtRatio: input.prepareAtRatio, roleInstructions: input.roleInstructions, contextSummary: input.contextSummary, summaryAuthority: "CONTEXT_ONLY" as const, @@ -223,6 +232,7 @@ function decision( safeToPrepare, reason, sourceEpoch: input.worker.continuationEpoch, + prepareAtRatio: input.prepareAtRatio, }; } @@ -232,6 +242,12 @@ function validateWorkerIdentity(worker: WorkerAutoCompactDecisionInput["worker"] } function validatePressure(pressure: WorkerContextPressureSignal): void { + if (!(PRESSURE_PRECISIONS as readonly string[]).includes(pressure.precision)) { + throw new ChatSwarmError("INVALID_INPUT", "unknown context pressure precision"); + } + if (!(PRESSURE_SOURCES as readonly string[]).includes(pressure.source)) { + throw new ChatSwarmError("INVALID_INPUT", "unknown context pressure source"); + } if (!Number.isFinite(pressure.utilizationRatio) || pressure.utilizationRatio < 0 || pressure.utilizationRatio > 1) { throw new ChatSwarmError("INVALID_INPUT", "context utilizationRatio must be between 0 and 1"); } From 66232e4451a7d5763807ee58415e572716a0f29a Mon Sep 17 00:00:00 2001 From: James3014 Date: Sun, 13 Sep 2026 18:09:43 +0800 Subject: [PATCH 5/7] test(chat-swarm): harden auto-compact trigger provenance --- src/chat-swarm-auto-compact.test.ts | 34 ++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/src/chat-swarm-auto-compact.test.ts b/src/chat-swarm-auto-compact.test.ts index 95d089606..c8025dc6b 100644 --- a/src/chat-swarm-auto-compact.test.ts +++ b/src/chat-swarm-auto-compact.test.ts @@ -62,6 +62,7 @@ test("pressure below threshold does not require Auto Compact", () => { assert.equal(result.state, "NOT_REQUIRED"); assert.equal(result.compactRequired, false); assert.equal(result.safeToPrepare, false); + assert.equal(result.prepareAtRatio, 0.8); }); test("estimated pressure remains explicitly estimated and prepares only at a safe boundary", () => { @@ -69,9 +70,11 @@ test("estimated pressure remains explicitly estimated and prepares only at a saf assert.equal(result.decision.state, "PREPARE_REQUIRED"); assert.equal(result.decision.compactRequired, true); assert.equal(result.decision.safeToPrepare, true); + assert.equal(result.decision.prepareAtRatio, 0.8); assert.equal(result.capsule?.schema, WORKER_AUTO_COMPACT_CAPSULE_SCHEMA); assert.equal(result.capsule?.pressure.precision, "ESTIMATED"); assert.equal(result.capsule?.pressure.source, "DEVSPACE_ESTIMATE"); + assert.equal(result.capsule?.prepareAtRatio, 0.8); assert.equal(result.capsule?.summaryAuthority, "CONTEXT_ONLY"); assert.match(result.capsule?.checkpointHash ?? "", /^[0-9a-f]{64}$/); assert.match(result.capsule?.capsuleHash ?? "", /^[0-9a-f]{64}$/); @@ -102,6 +105,26 @@ test("non-host pressure cannot be labeled exact", () => { })); }); +test("unknown pressure precision or source fails closed at runtime", () => { + assert.throws( + () => evaluateWorkerAutoCompact({ + worker: worker(), + pressure: { ...pressure(), precision: "MAGICAL" as WorkerContextPressureSignal["precision"] }, + prepareAtRatio: 0.8, + }), + (error: unknown) => error instanceof ChatSwarmError && error.code === "INVALID_INPUT", + ); + + assert.throws( + () => evaluateWorkerAutoCompact({ + worker: worker(), + pressure: { ...pressure(), source: "UNTRUSTED" as WorkerContextPressureSignal["source"] }, + prepareAtRatio: 0.8, + }), + (error: unknown) => error instanceof ChatSwarmError && error.code === "INVALID_INPUT", + ); +}); + test("busy worker waits for an idle boundary without producing a replacement intent", () => { const result = prepare({ worker: worker({ lifecycleState: "BUSY", currentTaskId: "task-live" }), @@ -141,11 +164,13 @@ test("capsule hash is deterministic and material changes alter the hash", () => const second = prepare(); const changedSummary = prepare({ contextSummary: "different bounded context" }); const changedPressure = prepare({ pressure: pressure({ utilizationRatio: 0.9 }) }); + const changedThreshold = prepare({ prepareAtRatio: 0.81 }); const changedEpoch = prepare({ worker: worker({ continuationEpoch: 5 }) }); assert.equal(first.capsule?.capsuleHash, second.capsule?.capsuleHash); assert.notEqual(first.capsule?.capsuleHash, changedSummary.capsule?.capsuleHash); assert.notEqual(first.capsule?.capsuleHash, changedPressure.capsule?.capsuleHash); + assert.notEqual(first.capsule?.capsuleHash, changedThreshold.capsule?.capsuleHash); assert.notEqual(first.capsule?.capsuleHash, changedEpoch.capsule?.capsuleHash); }); @@ -185,6 +210,13 @@ test("capsule and reference bounds fail closed", () => { ); }); +test("capsule creation cannot predate its pressure observation", () => { + assert.throws( + () => prepare({ createdAt: "2026-09-13T09:29:59.999Z" }), + (error: unknown) => error instanceof ChatSwarmError && error.code === "INVALID_INPUT", + ); +}); + test("invalid threshold, ratio, timestamp and epoch fail closed", () => { for (const prepareAtRatio of [0, -0.1, 1.01, Number.NaN]) { assert.throws( @@ -219,4 +251,4 @@ test("invalid threshold, ratio, timestamp and epoch fail closed", () => { }), (error: unknown) => error instanceof ChatSwarmError && error.code === "INVALID_INPUT", ); -}); +}); \ No newline at end of file From c7501437df277ed6ea99024620a5ce95549102f9 Mon Sep 17 00:00:00 2001 From: James3014 Date: Sun, 13 Sep 2026 18:11:03 +0800 Subject: [PATCH 6/7] feat(chat-swarm): verify worker auto-compact capsules --- src/chat-swarm-auto-compact.ts | 126 +++++++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) diff --git a/src/chat-swarm-auto-compact.ts b/src/chat-swarm-auto-compact.ts index 62b140476..9f3b8e2e5 100644 --- a/src/chat-swarm-auto-compact.ts +++ b/src/chat-swarm-auto-compact.ts @@ -13,6 +13,27 @@ export const WORKER_AUTO_COMPACT_CAPSULE_MAX_BYTES = 48 * 1024; const PRESSURE_PRECISIONS = ["ESTIMATED", "EXACT"] as const; const PRESSURE_SOURCES = ["DEVSPACE_ESTIMATE", "CARRIER_ESTIMATE", "HOST_NATIVE"] as const; +const CAPSULE_KEYS = [ + "schema", + "swarmId", + "workerId", + "sourceEpoch", + "checkpointHash", + "pressure", + "prepareAtRatio", + "roleInstructions", + "contextSummary", + "summaryAuthority", + "taskRefs", + "resultRefs", + "evidenceRefs", + "blockers", + "claimCeiling", + "createdAt", + "capsuleHash", +] as const; +const PRESSURE_KEYS = ["precision", "source", "utilizationRatio", "provenance", "observedAt"] as const; +const SHA256 = /^[0-9a-f]{64}$/; const MAX_PROVENANCE_BYTES = 2 * 1024; const MAX_ROLE_BYTES = 8 * 1024; const MAX_SUMMARY_BYTES = 16 * 1024; @@ -219,6 +240,79 @@ export function prepareWorkerAutoCompact(input: WorkerAutoCompactPrepareInput): }; } +export function verifyWorkerAutoCompactCapsule(value: unknown): WorkerAutoCompactCapsule { + const record = requireRecord(value, "capsule"); + assertExactKeys(record, CAPSULE_KEYS, "capsule"); + if (record.schema !== WORKER_AUTO_COMPACT_CAPSULE_SCHEMA) { + invalidCapsule("unsupported schema"); + } + + const pressureRecord = requireRecord(record.pressure, "pressure"); + assertExactKeys(pressureRecord, PRESSURE_KEYS, "pressure"); + const pressure: WorkerContextPressureSignal = { + precision: requireString(pressureRecord.precision, "pressure.precision") as WorkerContextPressurePrecision, + source: requireString(pressureRecord.source, "pressure.source") as WorkerContextPressureSource, + utilizationRatio: requireNumber(pressureRecord.utilizationRatio, "pressure.utilizationRatio"), + provenance: requireString(pressureRecord.provenance, "pressure.provenance"), + observedAt: requireString(pressureRecord.observedAt, "pressure.observedAt"), + }; + + const capsule: WorkerAutoCompactCapsule = { + schema: WORKER_AUTO_COMPACT_CAPSULE_SCHEMA, + swarmId: requireString(record.swarmId, "swarmId"), + workerId: requireString(record.workerId, "workerId"), + sourceEpoch: requireNumber(record.sourceEpoch, "sourceEpoch"), + checkpointHash: requireString(record.checkpointHash, "checkpointHash"), + pressure, + prepareAtRatio: requireNumber(record.prepareAtRatio, "prepareAtRatio"), + roleInstructions: requireString(record.roleInstructions, "roleInstructions"), + contextSummary: requireString(record.contextSummary, "contextSummary"), + summaryAuthority: requireString(record.summaryAuthority, "summaryAuthority") as "CONTEXT_ONLY", + taskRefs: requireStringArray(record.taskRefs, "taskRefs"), + resultRefs: requireStringArray(record.resultRefs, "resultRefs"), + evidenceRefs: requireStringArray(record.evidenceRefs, "evidenceRefs"), + blockers: requireStringArray(record.blockers, "blockers"), + claimCeiling: requireString(record.claimCeiling, "claimCeiling"), + createdAt: requireString(record.createdAt, "createdAt"), + capsuleHash: requireString(record.capsuleHash, "capsuleHash"), + }; + + try { + assertBounded(capsule.swarmId, MAX_ID_BYTES, "swarmId"); + assertBounded(capsule.workerId, MAX_ID_BYTES, "workerId"); + validateEpoch(capsule.sourceEpoch); + validatePressure(capsule.pressure); + validateThreshold(capsule.prepareAtRatio); + assertBounded(capsule.roleInstructions, MAX_ROLE_BYTES, "roleInstructions"); + assertBounded(capsule.contextSummary, MAX_SUMMARY_BYTES, "contextSummary"); + assertBounded(capsule.claimCeiling, MAX_CLAIM_CEILING_BYTES, "claimCeiling"); + validateTimestamp(capsule.createdAt, "createdAt"); + validateRefs(capsule.taskRefs, "taskRefs"); + validateRefs(capsule.resultRefs, "resultRefs"); + validateRefs(capsule.evidenceRefs, "evidenceRefs"); + validateBlockers(capsule.blockers); + } catch (error) { + if (error instanceof ChatSwarmError) invalidCapsule(error.message); + throw error; + } + + if (capsule.summaryAuthority !== "CONTEXT_ONLY") invalidCapsule("summaryAuthority must be CONTEXT_ONLY"); + if (!SHA256.test(capsule.checkpointHash)) invalidCapsule("checkpointHash must be a SHA-256 hash"); + if (!SHA256.test(capsule.capsuleHash)) invalidCapsule("capsuleHash must be a SHA-256 hash"); + if (Date.parse(capsule.createdAt) < Date.parse(capsule.pressure.observedAt)) { + invalidCapsule("createdAt precedes the pressure observation"); + } + + const { capsuleHash, ...payload } = capsule; + const canonicalJson = JSON.stringify(canonicalize(payload)); + if (Buffer.byteLength(canonicalJson, "utf8") > WORKER_AUTO_COMPACT_CAPSULE_MAX_BYTES) { + invalidCapsule(`capsule exceeds ${WORKER_AUTO_COMPACT_CAPSULE_MAX_BYTES} bytes`); + } + if (hashContent(canonicalJson) !== capsuleHash) invalidCapsule("capsule hash mismatch"); + + return capsule; +} + function decision( input: WorkerAutoCompactDecisionInput, state: WorkerAutoCompactDecisionState, @@ -305,3 +399,35 @@ function validateTimestamp(value: string, label: string): void { throw new ChatSwarmError("INVALID_INPUT", `${label} must be a valid timestamp`); } } + +function requireRecord(value: unknown, label: string): Record { + if (!value || Array.isArray(value) || typeof value !== "object") invalidCapsule(`${label} must be an object`); + return value as Record; +} + +function requireString(value: unknown, label: string): string { + if (typeof value !== "string") invalidCapsule(`${label} must be a string`); + return value; +} + +function requireNumber(value: unknown, label: string): number { + if (typeof value !== "number") invalidCapsule(`${label} must be a number`); + return value; +} + +function requireStringArray(value: unknown, label: string): string[] { + if (!Array.isArray(value) || value.some((item) => typeof item !== "string")) { + invalidCapsule(`${label} must be an array of strings`); + } + return [...value] as string[]; +} + +function assertExactKeys(record: Record, allowed: readonly string[], label: string): void { + const allowedSet = new Set(allowed); + const extras = Object.keys(record).filter((key) => !allowedSet.has(key)); + if (extras.length > 0) invalidCapsule(`${label} contains unsupported fields: ${extras.join(",")}`); +} + +function invalidCapsule(message: string): never { + throw new ChatSwarmError("INVALID_STATE", `invalid Auto Compact capsule: ${message}`); +} From 82e35e79df70d18028572f7362b33bd1b1bfc99e Mon Sep 17 00:00:00 2001 From: James3014 Date: Sun, 13 Sep 2026 18:11:35 +0800 Subject: [PATCH 7/7] test(chat-swarm): reject corrupt auto-compact capsules --- src/chat-swarm-auto-compact.test.ts | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/chat-swarm-auto-compact.test.ts b/src/chat-swarm-auto-compact.test.ts index c8025dc6b..d06515ce6 100644 --- a/src/chat-swarm-auto-compact.test.ts +++ b/src/chat-swarm-auto-compact.test.ts @@ -5,6 +5,7 @@ import { WORKER_AUTO_COMPACT_CAPSULE_SCHEMA, evaluateWorkerAutoCompact, prepareWorkerAutoCompact, + verifyWorkerAutoCompactCapsule, type WorkerContextPressureSignal, } from "./chat-swarm-auto-compact.js"; @@ -86,6 +87,7 @@ test("estimated pressure remains explicitly estimated and prepares only at a saf sourceEpoch: 4, capsuleHash: result.capsule?.capsuleHash, }); + assert.doesNotThrow(() => verifyWorkerAutoCompactCapsule(result.capsule)); }); test("non-host pressure cannot be labeled exact", () => { @@ -193,6 +195,21 @@ test("capsule structurally excludes raw checkpoint, transcript, reasoning, tool assert.equal(typeof capsule.checkpointHash, "string"); }); +test("capsule verifier rejects version mismatch, hash corruption, material tampering and unsupported fields", () => { + const capsule = prepare().capsule!; + for (const corrupted of [ + { ...capsule, schema: "chat_swarm.worker_auto_compact_capsule.v2" }, + { ...capsule, capsuleHash: "0".repeat(64) }, + { ...capsule, contextSummary: "tampered after hash" }, + { ...capsule, transcript: "must never be accepted" }, + ]) { + assert.throws( + () => verifyWorkerAutoCompactCapsule(corrupted), + (error: unknown) => error instanceof ChatSwarmError && error.code === "INVALID_STATE", + ); + } +}); + test("capsule and reference bounds fail closed", () => { assert.throws( () => prepare({ contextSummary: "x".repeat(16 * 1024 + 1) }),