sortie-dogs 0.16.3 → 0.16.4

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.
@@ -3,6 +3,6 @@
3
3
  * installed project marker without importing every asset body.
4
4
  */
5
5
  export declare const RUNTIME_ASSET_VERSION = "0.3.89-completion-proof-v1";
6
- export declare const V010_RUNTIME_ASSET_VERSION = "0.16.3-strategy-admission-recovery-v1";
6
+ export declare const V010_RUNTIME_ASSET_VERSION = "0.16.4-compaction-model-view-v1";
7
7
  export declare const CODEX_SKILL_ASSET_VERSION = "0.14.6-codex-skill-v1";
8
8
  export type RuntimeAssetVersion = typeof RUNTIME_ASSET_VERSION | typeof V010_RUNTIME_ASSET_VERSION | typeof CODEX_SKILL_ASSET_VERSION;
@@ -3,5 +3,5 @@
3
3
  * installed project marker without importing every asset body.
4
4
  */
5
5
  export const RUNTIME_ASSET_VERSION = "0.3.89-completion-proof-v1";
6
- export const V010_RUNTIME_ASSET_VERSION = "0.16.3-strategy-admission-recovery-v1";
6
+ export const V010_RUNTIME_ASSET_VERSION = "0.16.4-compaction-model-view-v1";
7
7
  export const CODEX_SKILL_ASSET_VERSION = "0.14.6-codex-skill-v1";
@@ -355,7 +355,47 @@ export class OperatorRuntime {
355
355
  // Display metadata must not turn an otherwise valid execution state into a refusal.
356
356
  if (Buffer.byteLength(source) > OPERATOR_LIMITS.planBytes * 4) {
357
357
  const { workQuantity: _display, ...execution } = parsed;
358
- if (Buffer.byteLength(JSON.stringify(execution)) > OPERATOR_LIMITS.planBytes * 4)
358
+ // Formal snapshot recipes are generated by the host and can legitimately contain
359
+ // many paths. Exclude those arrays only from this size check; retain the exact
360
+ // saved evidence and its freshness inputs in the state used by validation.
361
+ const sizedBinding = (binding) => {
362
+ if (!record(binding))
363
+ return binding;
364
+ const result = { ...binding };
365
+ for (const key of ["source_paths", "candidate_paths"])
366
+ if (Array.isArray(result[key]))
367
+ delete result[key];
368
+ if (record(result.freshness)) {
369
+ const freshness = { ...result.freshness };
370
+ for (const key of ["protected_paths", "scratch_paths", "incidental_control_paths"]) {
371
+ if (Array.isArray(freshness[key]))
372
+ delete freshness[key];
373
+ }
374
+ result.freshness = freshness;
375
+ }
376
+ return result;
377
+ };
378
+ const sizedChecks = (holder) => {
379
+ if (!record(holder) || !Array.isArray(holder.checks))
380
+ return holder;
381
+ return { ...holder, checks: holder.checks.map(check => record(check) && record(check.binding)
382
+ ? { ...check, binding: sizedBinding(check.binding) } : check) };
383
+ };
384
+ const sized = { ...execution, units: Array.isArray(execution.units) ? execution.units.map(unit => {
385
+ if (!record(unit) || !Array.isArray(unit.evidence))
386
+ return unit;
387
+ return { ...unit, evidence: unit.evidence.map(item => {
388
+ if (!record(item) || !record(item.protected_binding))
389
+ return item;
390
+ return { ...item, protected_binding: sizedBinding(item.protected_binding) };
391
+ }),
392
+ ...(unit.directExecution ? { directExecution: sizedChecks(unit.directExecution) } : {}),
393
+ ...(unit.reviewerCorrection ? { reviewerCorrection: sizedChecks(unit.reviewerCorrection) } : {}),
394
+ ...(unit.validationRegistration ? { validationRegistration: sizedChecks(unit.validationRegistration) } : {}),
395
+ ...(Array.isArray(unit.directHandoffs) ? { directHandoffs: unit.directHandoffs.map(sizedChecks) } : {}),
396
+ };
397
+ }) : execution.units };
398
+ if (Buffer.byteLength(JSON.stringify(sized)) > OPERATOR_LIMITS.planBytes * 4)
359
399
  throw new Error("operator-state-too-large");
360
400
  }
361
401
  const repairGeneration = parsed.repairGeneration === undefined ? 0 : parsed.repairGeneration;
@@ -1,8 +1,52 @@
1
1
  import { type OperatorState } from "../core/operator-runtime.js";
2
+ import type { GoalEvidence } from "../core/goal-bound.js";
2
3
  import { type MissionEvidenceExcerpt, type MissionReviewScope, type OperatorMission } from "../core/operator-mission.js";
3
4
  import { type RuntimeProfile } from "../core/runtime-profile.js";
4
5
  import type { DirectHandoffValidationCheck, ReviewerCorrectionCheck } from "./runtime-bridge.js";
5
6
  export declare const validationDirectoryMatches: (commands: readonly string[], actual: string | undefined, directory?: string, directories?: Readonly<Record<string, string>>) => boolean;
7
+ /** Project measured evidence without copying the host's protected snapshot recipe. */
8
+ export declare function missionEvidenceView(items: readonly GoalEvidence[]): {
9
+ protected_binding_ref?: {
10
+ docker_workspace?: {
11
+ readonly container_id: string;
12
+ readonly cwd: string;
13
+ readonly actual_cwd?: string;
14
+ readonly repository_root: string;
15
+ readonly source: string;
16
+ readonly candidate: string;
17
+ } | undefined;
18
+ manifest_path: string;
19
+ manifest_hash: string;
20
+ source_policy: "project-files-v1" | "declared-paths-v1" | undefined;
21
+ } | undefined;
22
+ evidence_id: string;
23
+ goal_id: string;
24
+ goal_revision: number;
25
+ scope_epoch: number;
26
+ acceptance_fingerprint: string;
27
+ measurement: {
28
+ readonly criterion_ids: readonly string[];
29
+ readonly target: string;
30
+ readonly entrypoint: string;
31
+ readonly workload: string;
32
+ readonly oracle_coverage: readonly string[];
33
+ readonly build_boundary: "included" | "excluded" | "not-applicable";
34
+ };
35
+ identity: {
36
+ readonly source: string;
37
+ readonly candidate: string;
38
+ readonly fixture: string;
39
+ };
40
+ execution: {
41
+ readonly command: readonly string[];
42
+ readonly exit_code: number | null;
43
+ readonly outcome: "pass" | "fail" | "skip" | "cancel";
44
+ readonly started_at: string;
45
+ readonly ended_at: string;
46
+ readonly units: readonly string[];
47
+ };
48
+ proof_scope: "requested-full" | "supporting-proxy" | "document-deliverable" | "expected-negative";
49
+ }[];
6
50
  /** Reviewer-facing evidence preserves execution/coverage; the host retains the full snapshot recipe. */
7
51
  export declare function missionReviewValidation(run: OperatorState, statePath: string): {
8
52
  details_ref: {
@@ -36,6 +36,18 @@ async function currentGitDiff(git, paths) {
36
36
  }
37
37
  const record = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
38
38
  export const validationDirectoryMatches = (commands, actual, directory, directories) => directory === undefined || commands.every(command => resolve(directory, directories?.[normalizeCommand(command)] ?? ".") === resolve(directory, actual ?? "."));
39
+ /** Project measured evidence without copying the host's protected snapshot recipe. */
40
+ export function missionEvidenceView(items) {
41
+ return items.map(({ protected_binding, ...evidence }) => ({
42
+ ...evidence,
43
+ ...(protected_binding ? { protected_binding_ref: {
44
+ manifest_path: protected_binding.manifest_path,
45
+ manifest_hash: protected_binding.manifest_hash,
46
+ source_policy: protected_binding.source_policy,
47
+ ...(protected_binding.docker_workspace ? { docker_workspace: protected_binding.docker_workspace } : {}),
48
+ } } : {}),
49
+ }));
50
+ }
39
51
  /** Reviewer-facing evidence preserves execution/coverage; the host retains the full snapshot recipe. */
40
52
  export function missionReviewValidation(run, statePath) {
41
53
  return run.units.map(unit => ({
@@ -44,15 +56,7 @@ export function missionReviewValidation(run, statePath) {
44
56
  ...(unitValidationCwd(unit) ? {
45
57
  validation_cwd: unitValidationCwd(unit),
46
58
  } : {}),
47
- evidence: unit.evidence.map(({ protected_binding, ...evidence }) => ({
48
- ...evidence,
49
- ...(protected_binding ? { protected_binding_ref: {
50
- manifest_path: protected_binding.manifest_path,
51
- manifest_hash: protected_binding.manifest_hash,
52
- source_policy: protected_binding.source_policy,
53
- ...(protected_binding.docker_workspace ? { docker_workspace: protected_binding.docker_workspace } : {}),
54
- } } : {}),
55
- })),
59
+ evidence: missionEvidenceView(unit.evidence),
56
60
  ...(unit.reviewerCorrection ? { correction_checks: (unit.reviewerCorrection.checks ?? []).map(check => ({
57
61
  call_id: check.callID, dispatch_call_id: check.dispatchCallID, child_session_id: check.childSessionID,
58
62
  command: check.command, directory: check.directory, exit_code: check.exitCode, started_at: check.startedAt, ended_at: check.endedAt,
@@ -1,6 +1,34 @@
1
+ import { missionEvidenceView } from "./mission-review.js";
1
2
  const object = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
2
3
  const values = (value) => (Array.isArray(value) ? value : object(value) && Array.isArray(value.data) ? value.data : []).filter(object);
3
4
  const key = (parent) => `v2-background-dispatches:${parent}`;
5
+ /** Project the captured Coordinator result, not today's potentially different run or evidence. */
6
+ function modelResult(dispatch, result) {
7
+ if (!object(dispatch.owner) || !object(dispatch.owner.profile) || dispatch.owner.profile.mission !== true)
8
+ return result;
9
+ let packet;
10
+ try {
11
+ packet = JSON.parse(result);
12
+ }
13
+ catch {
14
+ return result;
15
+ }
16
+ if (!object(packet) || typeof packet.mission_id !== "string" || typeof packet.run_id !== "string" || !Array.isArray(packet.units))
17
+ return result;
18
+ let changed = false;
19
+ const units = packet.units.map(unit => {
20
+ if (!object(unit) || typeof unit.id !== "string" || !Array.isArray(unit.evidence) ||
21
+ !unit.evidence.every((item) => object(item) && (item.protected_binding === undefined || object(item.protected_binding))) ||
22
+ !unit.evidence.some((item) => object(item.protected_binding)))
23
+ return unit;
24
+ changed = true;
25
+ return { ...unit, evidence: missionEvidenceView(unit.evidence),
26
+ evidence_details_ref: { storage: "sortie-dogs.v010", key: key(dispatch.parent), call_id: dispatch.callID,
27
+ run_id: packet.run_id, unit_id: unit.id, field: "result.units[].evidence",
28
+ omitted: "captured host snapshot recipe; the original result remains in this native background dispatch" } };
29
+ });
30
+ return changed ? JSON.stringify({ ...packet, units }) : result;
31
+ }
4
32
  /** Lifecycle transport for native Jobs, not a scheduler. The host owns execution and wakeup. */
5
33
  export class NativeBackgroundLifecycle {
6
34
  context;
@@ -135,7 +163,7 @@ export class NativeBackgroundLifecycle {
135
163
  }
136
164
  }
137
165
  if (dispatch.result !== undefined)
138
- additions.set(text, { callID: dispatch.callID, text: dispatch.result });
166
+ additions.set(text, { callID: dispatch.callID, text: modelResult(dispatch, dispatch.result) });
139
167
  }
140
168
  if (changed)
141
169
  await this.write(parent, dispatches);
@@ -642,7 +642,7 @@ export function createProfiledPlugin(profile, assetVersion) {
642
642
  // not by resetting the goal budget. This checkpoint grants no dispatch itself.
643
643
  if (mission && (!["completed", "cancelled"].includes(mission.phase) ||
644
644
  (mission.phase === "cancelled" && run))) {
645
- return JSON.stringify(missionPacket(mission, run, false));
645
+ return JSON.stringify(compactMissionEvidence(missionPacket(mission, run, false), run, root));
646
646
  }
647
647
  return await operators.continuationCheckpoint(root) ?? await proposals.continuationCheckpoint(root);
648
648
  },
@@ -5071,7 +5071,8 @@ export function createProfiledPlugin(profile, assetVersion) {
5071
5071
  if ((await identity(request.sessionID)).role === "dog-operator") {
5072
5072
  const mission = await missions.read(root);
5073
5073
  if (mission?.coordinator === request.sessionID) {
5074
- (output.context ??= []).push(`Mission continuation: ${JSON.stringify(missionPacket(mission, await operators.read(root), false))}. ` +
5074
+ const run = await operators.read(root);
5075
+ (output.context ??= []).push(`Mission continuation: ${JSON.stringify(compactMissionEvidence(missionPacket(mission, run, false), run, root))}. ` +
5075
5076
  `Continue in this same Coordinator. Use ${status} or ${next}; retain original requirements and cumulative budget. No proposal/approval phase.`);
5076
5077
  return;
5077
5078
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sortie-dogs",
3
- "version": "0.16.3",
3
+ "version": "0.16.4",
4
4
  "description": "Adaptive execution harness for OpenCode and Codex: goal retention, validation, review, and evidence-backed handoff",
5
5
  "keywords": [
6
6
  "opencode",