@skill-harness/core 0.6.0 → 0.8.0

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.
Files changed (44) hide show
  1. package/dist/adapters/types.d.ts +37 -0
  2. package/dist/adjudication.d.ts +210 -0
  3. package/dist/adjudication.js +392 -0
  4. package/dist/affected.d.ts +88 -0
  5. package/dist/affected.js +222 -0
  6. package/dist/capture-trace-types.d.ts +228 -0
  7. package/dist/capture-trace-types.js +23 -0
  8. package/dist/capture.d.ts +193 -0
  9. package/dist/capture.js +344 -0
  10. package/dist/execution-trace.d.ts +61 -0
  11. package/dist/execution-trace.js +299 -0
  12. package/dist/index.d.ts +9 -0
  13. package/dist/index.js +9 -0
  14. package/dist/instruction-coverage.d.ts +106 -0
  15. package/dist/instruction-coverage.js +253 -0
  16. package/dist/journal.d.ts +17 -0
  17. package/dist/lint.d.ts +8 -1
  18. package/dist/lint.js +31 -2
  19. package/dist/regate.js +80 -17
  20. package/dist/regrade.js +17 -3
  21. package/dist/report.d.ts +24 -0
  22. package/dist/report.js +24 -0
  23. package/dist/reps.d.ts +14 -1
  24. package/dist/reps.js +28 -2
  25. package/dist/rescore.js +11 -2
  26. package/dist/restamp.d.ts +68 -0
  27. package/dist/restamp.js +194 -0
  28. package/dist/results.d.ts +128 -6
  29. package/dist/results.js +155 -6
  30. package/dist/run.js +114 -8
  31. package/dist/seeded.d.ts +11 -0
  32. package/dist/seeded.js +31 -7
  33. package/dist/sources.d.ts +50 -0
  34. package/dist/sources.js +215 -7
  35. package/dist/spec-write.d.ts +62 -0
  36. package/dist/spec-write.js +106 -0
  37. package/dist/spec.d.ts +29 -0
  38. package/dist/spec.js +55 -0
  39. package/dist/stability.js +26 -4
  40. package/dist/trace-gates.d.ts +133 -0
  41. package/dist/trace-gates.js +519 -0
  42. package/dist/workspace.d.ts +36 -0
  43. package/dist/workspace.js +61 -0
  44. package/package.json +1 -1
@@ -47,3 +47,39 @@ export declare function createWorkspace(kind: WorkspaceKind, opts: {
47
47
  specDir: string;
48
48
  remote?: boolean;
49
49
  }): Workspace;
50
+ /**
51
+ * A content snapshot of every file in a workspace: relative path → sha256.
52
+ *
53
+ * Taken immediately before the model runs, and compared after. Three reasons it
54
+ * is a content walk rather than the obvious `git diff`:
55
+ *
56
+ * 1. **`git add -A` honours `.gitignore`.** The canonical assertion this feature
57
+ * exists for is `unchanged_paths: [".env"]`, and `.env` is the canonical
58
+ * gitignored file. Overwriting it produced an empty diff, which read as
59
+ * "observed, nothing changed" — a safety gate reporting green on precisely
60
+ * the file class that motivated it. It also covers `TOOL_ARTIFACTS`, which
61
+ * the harness itself writes into `.git/info/exclude`.
62
+ * 2. **The baseline commit is not the pre-run state.** `createWorkspace` applies
63
+ * a fixture's `_staged/` and `_uncommitted/` trees AFTER `gitBaseline`, so
64
+ * those files are already dirty before the model does anything. Diffing
65
+ * against the baseline blamed the model for the fixture's own contents.
66
+ * 3. **The harness writes to the workspace too** — `runSeeded` copies the
67
+ * post-test in. A snapshot taken after setup contains it, so it cancels out
68
+ * instead of being attributed to the model.
69
+ */
70
+ export type PathSnapshot = Map<string, string>;
71
+ /** Snapshot a workspace, or null when there is no workspace to look at. */
72
+ export declare function snapshotPaths(cwd: string | undefined, kind: WorkspaceKind): PathSnapshot | null;
73
+ /**
74
+ * Paths whose content changed between two snapshots — added, removed, modified.
75
+ *
76
+ * The ONLY evidence `assert.trace.unchanged_paths` can honestly rest on. A tool
77
+ * trace proves which tool was called with which arguments; it cannot prove what
78
+ * that tool then did to the filesystem, so a path policy has to be checked
79
+ * against the filesystem.
80
+ *
81
+ * Returns null when either snapshot is missing — the caller must treat that as
82
+ * MISSING EVIDENCE, never as "nothing changed". An empty array means
83
+ * observed-and-nothing-changed; null means we could not look.
84
+ */
85
+ export declare function diffSnapshots(before: PathSnapshot | null, after: PathSnapshot | null): string[] | null;
package/dist/workspace.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import { appendFileSync, cpSync, existsSync, mkdtempSync, readFileSync, readdirSync, rmSync } from "node:fs";
2
2
  import { execFileSync } from "node:child_process";
3
+ import { createHash } from "node:crypto";
3
4
  import { tmpdir } from "node:os";
4
5
  import { isAbsolute, join, resolve } from "node:path";
5
6
  const GIT_TIMEOUT_MS = 30_000;
@@ -189,4 +190,64 @@ export function createWorkspace(kind, opts) {
189
190
  }
190
191
  return { cwd, cleanup };
191
192
  }
193
+ /** Never the model's work, and never worth hashing. */
194
+ const SNAPSHOT_SKIP = new Set([".git", "node_modules", "coverage", ".vitest"]);
195
+ /** Snapshot a workspace, or null when there is no workspace to look at. */
196
+ export function snapshotPaths(cwd, kind) {
197
+ if (kind === "none" || !cwd || !existsSync(cwd))
198
+ return null;
199
+ const out = new Map();
200
+ const walk = (dir, prefix) => {
201
+ let entries;
202
+ try {
203
+ entries = readdirSync(dir, { withFileTypes: true });
204
+ }
205
+ catch {
206
+ return; // an unreadable subtree is not evidence about the model
207
+ }
208
+ for (const e of entries) {
209
+ if (SNAPSHOT_SKIP.has(e.name))
210
+ continue;
211
+ const rel = prefix ? `${prefix}/${e.name}` : e.name;
212
+ const abs = join(dir, e.name);
213
+ if (e.isDirectory()) {
214
+ walk(abs, rel);
215
+ }
216
+ else if (e.isFile()) {
217
+ try {
218
+ out.set(rel, createHash("sha256").update(readFileSync(abs)).digest("hex"));
219
+ }
220
+ catch {
221
+ out.set(rel, "<unreadable>");
222
+ }
223
+ }
224
+ }
225
+ };
226
+ walk(cwd, "");
227
+ return out;
228
+ }
229
+ /**
230
+ * Paths whose content changed between two snapshots — added, removed, modified.
231
+ *
232
+ * The ONLY evidence `assert.trace.unchanged_paths` can honestly rest on. A tool
233
+ * trace proves which tool was called with which arguments; it cannot prove what
234
+ * that tool then did to the filesystem, so a path policy has to be checked
235
+ * against the filesystem.
236
+ *
237
+ * Returns null when either snapshot is missing — the caller must treat that as
238
+ * MISSING EVIDENCE, never as "nothing changed". An empty array means
239
+ * observed-and-nothing-changed; null means we could not look.
240
+ */
241
+ export function diffSnapshots(before, after) {
242
+ if (!before || !after)
243
+ return null;
244
+ const changed = new Set();
245
+ for (const [path, hash] of after)
246
+ if (before.get(path) !== hash)
247
+ changed.add(path);
248
+ for (const path of before.keys())
249
+ if (!after.has(path))
250
+ changed.add(path);
251
+ return [...changed].sort();
252
+ }
192
253
  //# sourceMappingURL=workspace.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@skill-harness/core",
3
- "version": "0.6.0",
3
+ "version": "0.8.0",
4
4
  "description": "skill-harness engine — spec, discover, run, LLM-judge grade, score, results (internal API)",
5
5
  "type": "module",
6
6
  "license": "MIT",