sortie-dogs 0.15.2 → 0.15.3

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/README.md CHANGED
@@ -19,8 +19,8 @@ evidence-backed result, not more agents for their own sake.
19
19
  [![Node.js](https://img.shields.io/node/v/sortie-dogs)](https://www.npmjs.com/package/sortie-dogs)
20
20
  [![MIT License](https://img.shields.io/npm/l/sortie-dogs)](LICENSE)
21
21
 
22
- **Current release: [v0.15.2](https://github.com/zufall-upon/Sortie-dogs/releases/tag/v0.15.2)**
23
- · [Release notes](docs/release-v0.15.2.md)
22
+ **Current release: [v0.15.3](https://github.com/zufall-upon/Sortie-dogs/releases/tag/v0.15.3)**
23
+ · [Release notes](docs/release-v0.15.3.md)
24
24
  · [Execution vision](docs/v0.14.0-execution-vision.md)
25
25
 
26
26
  [When to use](#when-to-use-sortie-dogs) · [Quick start](#quick-start) · [Workflow](#mission-workflow) · [Models](#default-models) ·
@@ -78,7 +78,7 @@ Use an existing Codex CLI signed in with **ChatGPT**. On Windows, PowerShell **7
78
78
  available; POSIX uses bash. Sortie does not install Codex, start login or use a metered API fallback.
79
79
 
80
80
  ```sh
81
- npm install --save-dev sortie-dogs@0.15.2
81
+ npm install --save-dev sortie-dogs@0.15.3
82
82
  npx --no-install sortie-dogs codex init .
83
83
  ```
84
84
 
@@ -107,7 +107,7 @@ bridge. [Codex guide: SDK, permissions, progress, resume and manifest route](doc
107
107
  Use **OpenCode V2**. In the target project:
108
108
 
109
109
  ```sh
110
- npm install --save-dev sortie-dogs@0.15.2
110
+ npm install --save-dev sortie-dogs@0.15.3
111
111
  npx --no-install sortie-dogs init .
112
112
  ```
113
113
 
@@ -127,7 +127,7 @@ v0.10 is installed. [OpenCode setup and configuration](docs/configuration.md) ·
127
127
 
128
128
  ### Project Memory (OpenCode v010, opt-in)
129
129
 
130
- With v0.15.2 installed, run `sortie-dogs memory on .` once and reload
130
+ With v0.15.3 installed, run `sortie-dogs memory on .` once and reload
131
131
  the project plugin. Ordinary public turns then become pending sources; the existing
132
132
  Operator records semantic additions, corrections, withdrawals and decisions without
133
133
  another save request or a dedicated model call per turn. New sessions recall the
@@ -284,7 +284,7 @@ Install the desired package version and rerun **your host's** initializer:
284
284
 
285
285
  An OpenCode config-local bridge may resolve a separate package; npm-global update alone does not
286
286
  update it. [Global/update instructions](docs/configuration.md#global-availability).
287
- The current Mission asset marker is `0.15.2-tactical-return-v1`; the Codex skill marker is
287
+ The current Mission asset marker is `0.15.3-external-review-links-v1`; the Codex skill marker is
288
288
  `0.14.6-codex-skill-v1`. Installed markers alone do not prove a running host reloaded the new version.
289
289
 
290
290
  There is no supported uninstall command. Remove the dependency and only known Sortie-owned paths;
@@ -300,6 +300,7 @@ follow the [manual removal guide](docs/uninstall.md), never delete the entire `.
300
300
  [SWE-bench history](docs/benchmarks/swebench-lite-history.md) · [Historical local case study](docs/benchmark-reference.md).
301
301
  - **Development:** [Testing](docs/testing.md) · [CLI testing](docs/cli-testing.md) ·
302
302
  [Windows tests](docs/windows-tests.md) · [Release routine](docs/release-batch.md).
303
+ - **Current release:** [v0.15.3](docs/release-v0.15.3.md).
303
304
  - **Releases:** [v0.15.2](docs/release-v0.15.2.md) · [v0.15.1](docs/v0.15.1-migration.md) · [v0.15.0](docs/release-v0.15.0.md) · [v0.14.9](docs/release-v0.14.9.md) · [v0.14.8](docs/release-v0.14.8.md) · [v0.14.7](docs/release-v0.14.7.md) · [v0.14.6](docs/release-v0.14.6.md) · [v0.14.5](docs/release-v0.14.5.md) · [v0.14.4](docs/release-v0.14.4.md) · [v0.14.3](docs/release-v0.14.3.md) · [v0.14.2](docs/release-v0.14.2.md) · [v0.14.1](docs/release-v0.14.1.md) · [v0.14.0](docs/release-v0.14.0.md) · [v0.13.22](docs/release-v0.13.22.md) · [v0.13.21](docs/release-v0.13.21.md) · [v0.13.20](docs/release-v0.13.20.md) · [v0.13.19](docs/release-v0.13.19.md) · [v0.13.18](docs/release-v0.13.18.md) · [v0.13.17](docs/release-v0.13.17.md) · [v0.13.16](docs/release-v0.13.16.md) · [v0.13.15](docs/release-v0.13.15.md) · [v0.13.14](docs/release-v0.13.14.md) · [v0.13.13](docs/release-v0.13.13.md) · [v0.13.12](docs/release-v0.13.12.md) · [v0.13.11](docs/release-v0.13.11.md) · [v0.13.10](docs/release-v0.13.10.md) ·
304
305
  [v0.13.9](docs/release-v0.13.9.md) · [All GitHub releases](https://github.com/zufall-upon/Sortie-dogs/releases).
305
306
 
@@ -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.15.2-tactical-return-v1";
6
+ export declare const V010_RUNTIME_ASSET_VERSION = "0.15.3-external-review-links-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.15.2-tactical-return-v1";
6
+ export const V010_RUNTIME_ASSET_VERSION = "0.15.3-external-review-links-v1";
7
7
  export const CODEX_SKILL_ASSET_VERSION = "0.14.6-codex-skill-v1";
@@ -3,6 +3,7 @@
3
3
  */
4
4
  export declare function declaredArtifacts(paths: readonly string[], previewLimit?: number, options?: {
5
5
  reportUnreadableDirectories?: boolean;
6
+ reportOutsideLinks?: boolean;
6
7
  }): Promise<{
7
8
  entries: (readonly [string, string, (string | undefined)?])[];
8
9
  excerpt: string;
@@ -62,8 +62,22 @@ export async function declaredArtifacts(paths, previewLimit = 0, options = {}) {
62
62
  return;
63
63
  }
64
64
  entries.push([label, `symlink:${target}`, canonical]);
65
- if (!physical.some(root => within(root, canonical)))
66
- throw new Error("declared-artifact-link-outside-scope");
65
+ if (!physical.some(root => within(root, canonical))) {
66
+ if (!options.reportOutsideLinks)
67
+ throw new Error("declared-artifact-link-outside-scope");
68
+ // Review records the link entry, not authority to inspect its target. Keep the
69
+ // strict default for validation snapshots and never recurse beyond declared roots.
70
+ entries.push([label, "target-not-inspected:outside-scope", canonical]);
71
+ const notice = Buffer.from(`\n--- external symlink: ${label} ---\n${target}\n[target not inspected: outside declared scope]\n`);
72
+ const bounded = notice.subarray(0, remaining);
73
+ if (bounded.length) {
74
+ excerpts.push(bounded.toString("utf8"));
75
+ remaining -= bounded.length;
76
+ }
77
+ if (bounded.length < notice.length)
78
+ truncated = true;
79
+ return;
80
+ }
67
81
  if (ancestors.has(canonical))
68
82
  return; // The link identity is recorded; do not traverse cycles.
69
83
  await visit(canonical, ancestors);
@@ -761,6 +761,7 @@ export async function missionReviewSource(directory, run, evidence = [], baselin
761
761
  untracked.add(path);
762
762
  const omitted = [];
763
763
  const unreadable = [];
764
+ const outsideLinks = [];
764
765
  let diff = scopedDiff;
765
766
  if (repository && local.length && displayBaseline) {
766
767
  // HEAD-only diffs are empty once the author commits. Display the original mission delta
@@ -881,19 +882,25 @@ export async function missionReviewSource(directory, run, evidence = [], baselin
881
882
  // A declared write scope can also be a host-managed runtime directory (e.g. Docker's data root).
882
883
  // Do not make review depend on listing it; record the missing coverage instead. Protected
883
884
  // validation still requires readable outputs and does not use this review-only option.
884
- const artifacts = await declaredArtifacts(external, Math.max(1, 24_000 - Buffer.byteLength(excerpt)), { reportUnreadableDirectories: true });
885
+ const artifacts = await declaredArtifacts(external, Math.max(1, 24_000 - Buffer.byteLength(excerpt)), { reportUnreadableDirectories: true, reportOutsideLinks: true });
885
886
  sourceUpdate(JSON.stringify(artifacts.entries));
886
887
  excerpt += artifacts.excerpt;
887
888
  if (artifacts.truncated)
888
889
  omitted.push("external artifacts");
889
890
  unreadable.push(...artifacts.unreadable);
891
+ outsideLinks.push(...artifacts.entries.filter(([, kind]) => kind === "target-not-inspected:outside-scope").map(([path]) => path));
890
892
  }
891
893
  const bytes = Buffer.from(excerpt);
892
894
  const truncatedSource = [...new Set(omitted)];
893
895
  if (bytes.length > 24_000 && truncatedSource.length === 0)
894
896
  truncatedSource.push("(source diff exceeds excerpt budget)");
897
+ // Missing coverage is not a clipped source preview: disclose it even after that
898
+ // budget is exhausted. Full link identities remain in the fingerprint above.
899
+ const outsideNotice = outsideLinks.length ? `\n[UNINSPECTED EXTERNAL LINK TARGETS: ${outsideLinks.length} link(s); outside declared artifact roots; ` +
900
+ `target contents not inspected or fingerprinted through these links. Link entries (first 20, clipped preview): ` +
901
+ `${Buffer.from(JSON.stringify(outsideLinks.slice(0, 20))).subarray(0, 2_000).toString("utf8")}]` : "";
895
902
  return { fingerprint: `sha256:${hash.digest("hex")}`, candidateFingerprint: `sha256:${candidateHash.digest("hex")}`, excerpt: (bytes.length > 24_000 ? bytes.subarray(0, 24_000).toString("utf8") : excerpt) +
896
903
  (truncatedSource.length ? `\n[EXCERPT TRUNCATED: ${truncatedSource.slice(0, 20).join(", ")}; Reviewer can read/search the relevant source directly]` : "") +
897
- (unreadable.length ? `\n[UNINSPECTED EXTERNAL DIRECTORIES: ${unreadable.slice(0, 20).join(", ")}; select specific result files as review evidence]` : ""),
904
+ (unreadable.length ? `\n[UNINSPECTED EXTERNAL DIRECTORIES: ${unreadable.slice(0, 20).join(", ")}; select specific result files as review evidence]` : "") + outsideNotice,
898
905
  truncatedEvidence, truncatedSource };
899
906
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sortie-dogs",
3
- "version": "0.15.2",
3
+ "version": "0.15.3",
4
4
  "description": "Adaptive execution harness for OpenCode and Codex: goal retention, validation, review, and evidence-backed handoff",
5
5
  "keywords": [
6
6
  "opencode",