instar 1.3.198 → 1.3.200

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 (45) hide show
  1. package/dist/core/ApprenticeshipProgram.d.ts +211 -0
  2. package/dist/core/ApprenticeshipProgram.d.ts.map +1 -0
  3. package/dist/core/ApprenticeshipProgram.js +433 -0
  4. package/dist/core/ApprenticeshipProgram.js.map +1 -0
  5. package/dist/core/AutonomousSessions.d.ts +2 -0
  6. package/dist/core/AutonomousSessions.d.ts.map +1 -1
  7. package/dist/core/AutonomousSessions.js +2 -0
  8. package/dist/core/AutonomousSessions.js.map +1 -1
  9. package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
  10. package/dist/core/PostUpdateMigrator.js +35 -0
  11. package/dist/core/PostUpdateMigrator.js.map +1 -1
  12. package/dist/core/SessionClock.d.ts +57 -0
  13. package/dist/core/SessionClock.d.ts.map +1 -0
  14. package/dist/core/SessionClock.js +128 -0
  15. package/dist/core/SessionClock.js.map +1 -0
  16. package/dist/core/SessionClockReader.d.ts +18 -0
  17. package/dist/core/SessionClockReader.d.ts.map +1 -0
  18. package/dist/core/SessionClockReader.js +35 -0
  19. package/dist/core/SessionClockReader.js.map +1 -0
  20. package/dist/core/retroHarvestValidator.d.ts +79 -0
  21. package/dist/core/retroHarvestValidator.d.ts.map +1 -0
  22. package/dist/core/retroHarvestValidator.js +256 -0
  23. package/dist/core/retroHarvestValidator.js.map +1 -0
  24. package/dist/scaffold/templates.d.ts.map +1 -1
  25. package/dist/scaffold/templates.js +12 -0
  26. package/dist/scaffold/templates.js.map +1 -1
  27. package/dist/server/AgentServer.d.ts +1 -0
  28. package/dist/server/AgentServer.d.ts.map +1 -1
  29. package/dist/server/AgentServer.js +48 -0
  30. package/dist/server/AgentServer.js.map +1 -1
  31. package/dist/server/CapabilityIndex.d.ts.map +1 -1
  32. package/dist/server/CapabilityIndex.js +16 -0
  33. package/dist/server/CapabilityIndex.js.map +1 -1
  34. package/dist/server/routes.d.ts +5 -0
  35. package/dist/server/routes.d.ts.map +1 -1
  36. package/dist/server/routes.js +118 -0
  37. package/dist/server/routes.js.map +1 -1
  38. package/package.json +1 -1
  39. package/scripts/validate-retro-harvest.mjs +31 -237
  40. package/src/data/builtin-manifest.json +63 -63
  41. package/src/scaffold/templates.ts +12 -0
  42. package/upgrades/1.3.199.md +24 -0
  43. package/upgrades/1.3.200.md +25 -0
  44. package/upgrades/side-effects/APPRENTICESHIP-STEP1-PROGRAM-SCAFFOLD-SPEC.md +82 -0
  45. package/upgrades/side-effects/session-clock-step1.md +52 -0
@@ -0,0 +1,57 @@
1
+ /**
2
+ * SessionClock — pure, deterministic computation of a time-boxed session's
3
+ * elapsed / remaining clock. Tier0 (no LLM, no I/O): given the canonical record
4
+ * fields and a `now`, it returns the numbers the rest of the time-awareness
5
+ * system injects and serves.
6
+ *
7
+ * Spec: docs/specs/ROBUST-SESSION-TIME-AWARENESS-SPEC.md (Component 0 label
8
+ * derivation, Component 1 compute). Built for the 2026-06-02 time-blindness fix:
9
+ * an agent must never compute or guess elapsed/remaining — this module is the
10
+ * single source of that math (the bash hooks only render what this produces).
11
+ */
12
+ export type SessionKind = 'autonomous' | 'loop' | 'commitment';
13
+ export type SessionClockStatus = 'active' | 'expired' | 'not-started' | 'unbounded' | 'unparseable';
14
+ export interface SessionClockInput {
15
+ /** Short human label for the session. DERIVE it via deriveLabel(goal). */
16
+ label: string;
17
+ kind: SessionKind;
18
+ /** ISO-8601 timestamp (e.g. "2026-06-02T05:42:40Z"). */
19
+ startedAt: string;
20
+ /** Seconds the box is meant to run, or null/undefined for an unbounded run. */
21
+ durationSeconds: number | null;
22
+ }
23
+ export interface SessionClock {
24
+ label: string;
25
+ kind: SessionKind;
26
+ startedAt: string;
27
+ durationSeconds: number | null;
28
+ /** Derived ISO end (startedAt + durationSeconds), or null when unbounded/unparseable. */
29
+ endsAt: string | null;
30
+ elapsedSeconds: number;
31
+ /** null when unbounded or unparseable. */
32
+ remainingSeconds: number | null;
33
+ elapsedHuman: string;
34
+ remainingHuman: string | null;
35
+ /** 0-100, or null when unbounded/unparseable. */
36
+ percentElapsed: number | null;
37
+ status: SessionClockStatus;
38
+ }
39
+ /** Max chars for an injected/served label (matches the stop-hook goal_snippet cap). */
40
+ export declare const LABEL_MAX = 80;
41
+ /**
42
+ * Derive a safe, bounded label from a free-text `goal`. The ONLY task-descriptor
43
+ * text that may ever enter a prompt or the /session/clock response. Strips all
44
+ * control characters and newlines (so a multi-line fake-directive cannot survive)
45
+ * and angle brackets (so a <promise>-style tag cannot be reconstructed), collapses
46
+ * whitespace, and caps length.
47
+ */
48
+ export declare function deriveLabel(goal: string | null | undefined): string;
49
+ /** Format a non-negative duration in seconds as "Xh Ym" / "Ym" / "Xs". */
50
+ export declare function humanizeDuration(totalSeconds: number): string;
51
+ /**
52
+ * Compute the clock for a session record against `nowMs` (epoch ms).
53
+ * Pure + total: every malformed input maps to a defined, clamped result —
54
+ * never a negative, NaN, or throwing path.
55
+ */
56
+ export declare function computeSessionClock(input: SessionClockInput, nowMs: number): SessionClock;
57
+ //# sourceMappingURL=SessionClock.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SessionClock.d.ts","sourceRoot":"","sources":["../../src/core/SessionClock.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,MAAM,MAAM,WAAW,GAAG,YAAY,GAAG,MAAM,GAAG,YAAY,CAAC;AAE/D,MAAM,MAAM,kBAAkB,GAC1B,QAAQ,GACR,SAAS,GACT,aAAa,GACb,WAAW,GACX,aAAa,CAAC;AAElB,MAAM,WAAW,iBAAiB;IAChC,0EAA0E;IAC1E,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,WAAW,CAAC;IAClB,wDAAwD;IACxD,SAAS,EAAE,MAAM,CAAC;IAClB,+EAA+E;IAC/E,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,WAAW,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,yFAAyF;IACzF,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,0CAA0C;IAC1C,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,iDAAiD;IACjD,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,MAAM,EAAE,kBAAkB,CAAC;CAC5B;AAED,uFAAuF;AACvF,eAAO,MAAM,SAAS,KAAK,CAAC;AAO5B;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAQnE;AAED,0EAA0E;AAC1E,wBAAgB,gBAAgB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAO7D;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,iBAAiB,EAAE,KAAK,EAAE,MAAM,GAAG,YAAY,CAqFzF"}
@@ -0,0 +1,128 @@
1
+ /**
2
+ * SessionClock — pure, deterministic computation of a time-boxed session's
3
+ * elapsed / remaining clock. Tier0 (no LLM, no I/O): given the canonical record
4
+ * fields and a `now`, it returns the numbers the rest of the time-awareness
5
+ * system injects and serves.
6
+ *
7
+ * Spec: docs/specs/ROBUST-SESSION-TIME-AWARENESS-SPEC.md (Component 0 label
8
+ * derivation, Component 1 compute). Built for the 2026-06-02 time-blindness fix:
9
+ * an agent must never compute or guess elapsed/remaining — this module is the
10
+ * single source of that math (the bash hooks only render what this produces).
11
+ */
12
+ /** Max chars for an injected/served label (matches the stop-hook goal_snippet cap). */
13
+ export const LABEL_MAX = 80;
14
+ // Control characters (C0 range + DEL) that must never reach an injected prompt.
15
+ // Built via RegExp(string) with escaped unicode so the SOURCE carries no literal
16
+ // control bytes.
17
+ const CONTROL_CHARS = new RegExp('[\\u0000-\\u001F\\u007F]+', 'g');
18
+ /**
19
+ * Derive a safe, bounded label from a free-text `goal`. The ONLY task-descriptor
20
+ * text that may ever enter a prompt or the /session/clock response. Strips all
21
+ * control characters and newlines (so a multi-line fake-directive cannot survive)
22
+ * and angle brackets (so a <promise>-style tag cannot be reconstructed), collapses
23
+ * whitespace, and caps length.
24
+ */
25
+ export function deriveLabel(goal) {
26
+ if (!goal)
27
+ return '';
28
+ const stripped = String(goal)
29
+ .replace(CONTROL_CHARS, ' ')
30
+ .replace(/[<>]/g, ' ')
31
+ .replace(/\s+/g, ' ')
32
+ .trim();
33
+ return stripped.length > LABEL_MAX ? stripped.slice(0, LABEL_MAX).trimEnd() : stripped;
34
+ }
35
+ /** Format a non-negative duration in seconds as "Xh Ym" / "Ym" / "Xs". */
36
+ export function humanizeDuration(totalSeconds) {
37
+ const s = Math.max(0, Math.floor(totalSeconds));
38
+ const h = Math.floor(s / 3600);
39
+ const m = Math.floor((s % 3600) / 60);
40
+ if (h > 0)
41
+ return `${h}h ${m}m`;
42
+ if (m > 0)
43
+ return `${m}m`;
44
+ return `${s}s`;
45
+ }
46
+ /**
47
+ * Compute the clock for a session record against `nowMs` (epoch ms).
48
+ * Pure + total: every malformed input maps to a defined, clamped result —
49
+ * never a negative, NaN, or throwing path.
50
+ */
51
+ export function computeSessionClock(input, nowMs) {
52
+ const { kind, durationSeconds } = input;
53
+ const label = input.label ?? '';
54
+ const startMs = Date.parse(input.startedAt);
55
+ // Unparseable startedAt -> fail open. Caller renders absolute-time-only.
56
+ if (!Number.isFinite(startMs)) {
57
+ return {
58
+ label,
59
+ kind,
60
+ startedAt: input.startedAt,
61
+ durationSeconds: durationSeconds ?? null,
62
+ endsAt: null,
63
+ elapsedSeconds: 0,
64
+ remainingSeconds: null,
65
+ elapsedHuman: '0s',
66
+ remainingHuman: null,
67
+ percentElapsed: null,
68
+ status: 'unparseable',
69
+ };
70
+ }
71
+ const hasDuration = typeof durationSeconds === 'number' && Number.isFinite(durationSeconds) && durationSeconds > 0;
72
+ const endMs = hasDuration ? startMs + durationSeconds * 1000 : null;
73
+ const endsAt = endMs !== null ? new Date(endMs).toISOString() : null;
74
+ const rawElapsed = Math.floor((nowMs - startMs) / 1000);
75
+ // Future startedAt (clock skew / a state file synced from another machine):
76
+ // clamp to not-started rather than emit a negative elapsed.
77
+ if (rawElapsed < 0) {
78
+ return {
79
+ label,
80
+ kind,
81
+ startedAt: input.startedAt,
82
+ durationSeconds: hasDuration ? durationSeconds : null,
83
+ endsAt,
84
+ elapsedSeconds: 0,
85
+ remainingSeconds: hasDuration ? durationSeconds : null,
86
+ elapsedHuman: '0s',
87
+ remainingHuman: hasDuration ? humanizeDuration(durationSeconds) : null,
88
+ percentElapsed: hasDuration ? 0 : null,
89
+ status: 'not-started',
90
+ };
91
+ }
92
+ const elapsedSeconds = rawElapsed;
93
+ const elapsedHuman = humanizeDuration(elapsedSeconds);
94
+ if (!hasDuration) {
95
+ return {
96
+ label,
97
+ kind,
98
+ startedAt: input.startedAt,
99
+ durationSeconds: null,
100
+ endsAt: null,
101
+ elapsedSeconds,
102
+ remainingSeconds: null,
103
+ elapsedHuman,
104
+ remainingHuman: null,
105
+ percentElapsed: null,
106
+ status: 'unbounded',
107
+ };
108
+ }
109
+ const dur = durationSeconds;
110
+ const remainingRaw = dur - elapsedSeconds;
111
+ const remainingSeconds = Math.max(0, remainingRaw);
112
+ const percentElapsed = Math.min(100, Math.max(0, Math.round((elapsedSeconds / dur) * 100)));
113
+ const status = remainingRaw <= 0 ? 'expired' : 'active';
114
+ return {
115
+ label,
116
+ kind,
117
+ startedAt: input.startedAt,
118
+ durationSeconds: dur,
119
+ endsAt,
120
+ elapsedSeconds,
121
+ remainingSeconds,
122
+ elapsedHuman,
123
+ remainingHuman: humanizeDuration(remainingSeconds),
124
+ percentElapsed,
125
+ status,
126
+ };
127
+ }
128
+ //# sourceMappingURL=SessionClock.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SessionClock.js","sourceRoot":"","sources":["../../src/core/SessionClock.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * SessionClockReader — the I/O layer that turns active autonomous-state records
3
+ * into computed SessionClocks. Read-only; never mutates a record. Keeps
4
+ * SessionClock.ts pure (no fs). Spec: docs/specs/ROBUST-SESSION-TIME-AWARENESS-SPEC.md
5
+ * (Component 3 query surface; the autonomous-state record is the substrate).
6
+ */
7
+ import { type SessionClock } from './SessionClock.js';
8
+ /**
9
+ * Read the computed clock for each ACTIVE autonomous-state record under `stateDir`.
10
+ * Only records with a parseable `started_at` are returned. The emitted `label` is
11
+ * DERIVED + sanitized from the record's `goal` (never the raw goal).
12
+ *
13
+ * @param topicFilter when set, return only the record bound to that topic
14
+ * (multi-session binding); a legacy single-file job (topic null) matches any
15
+ * filter only when there is no per-topic record for that topic.
16
+ */
17
+ export declare function readSessionClocks(stateDir: string, nowMs: number, topicFilter?: string | null): SessionClock[];
18
+ //# sourceMappingURL=SessionClockReader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SessionClockReader.d.ts","sourceRoot":"","sources":["../../src/core/SessionClockReader.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAoC,KAAK,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAExF;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,YAAY,EAAE,CAmB9G"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * SessionClockReader — the I/O layer that turns active autonomous-state records
3
+ * into computed SessionClocks. Read-only; never mutates a record. Keeps
4
+ * SessionClock.ts pure (no fs). Spec: docs/specs/ROBUST-SESSION-TIME-AWARENESS-SPEC.md
5
+ * (Component 3 query surface; the autonomous-state record is the substrate).
6
+ */
7
+ import { activeAutonomousJobs } from './AutonomousSessions.js';
8
+ import { computeSessionClock, deriveLabel } from './SessionClock.js';
9
+ /**
10
+ * Read the computed clock for each ACTIVE autonomous-state record under `stateDir`.
11
+ * Only records with a parseable `started_at` are returned. The emitted `label` is
12
+ * DERIVED + sanitized from the record's `goal` (never the raw goal).
13
+ *
14
+ * @param topicFilter when set, return only the record bound to that topic
15
+ * (multi-session binding); a legacy single-file job (topic null) matches any
16
+ * filter only when there is no per-topic record for that topic.
17
+ */
18
+ export function readSessionClocks(stateDir, nowMs, topicFilter) {
19
+ const jobs = activeAutonomousJobs(stateDir);
20
+ const clocks = [];
21
+ for (const job of jobs) {
22
+ if (!job.startedAt)
23
+ continue; // no clock to compute without a start
24
+ if (topicFilter != null && job.topic != null && job.topic !== topicFilter)
25
+ continue;
26
+ clocks.push(computeSessionClock({
27
+ label: deriveLabel(job.goal),
28
+ kind: 'autonomous',
29
+ startedAt: job.startedAt,
30
+ durationSeconds: job.durationSeconds,
31
+ }, nowMs));
32
+ }
33
+ return clocks;
34
+ }
35
+ //# sourceMappingURL=SessionClockReader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SessionClockReader.js","sourceRoot":"","sources":["../../src/core/SessionClockReader.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAC/D,OAAO,EAAE,mBAAmB,EAAE,WAAW,EAAqB,MAAM,mBAAmB,CAAC;AAExF;;;;;;;;GAQG;AACH,MAAM,UAAU,iBAAiB,CAAC,QAAgB,EAAE,KAAa,EAAE,WAA2B;IAC5F,MAAM,IAAI,GAAG,oBAAoB,CAAC,QAAQ,CAAC,CAAC;IAC5C,MAAM,MAAM,GAAmB,EAAE,CAAC;IAClC,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,IAAI,CAAC,GAAG,CAAC,SAAS;YAAE,SAAS,CAAC,sCAAsC;QACpE,IAAI,WAAW,IAAI,IAAI,IAAI,GAAG,CAAC,KAAK,IAAI,IAAI,IAAI,GAAG,CAAC,KAAK,KAAK,WAAW;YAAE,SAAS;QACpF,MAAM,CAAC,IAAI,CACT,mBAAmB,CACjB;YACE,KAAK,EAAE,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC;YAC5B,IAAI,EAAE,YAAY;YAClB,SAAS,EAAE,GAAG,CAAC,SAAS;YACxB,eAAe,EAAE,GAAG,CAAC,eAAe;SACrC,EACD,KAAK,CACN,CACF,CAAC;IACJ,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,79 @@
1
+ /**
2
+ * retroHarvestValidator — the schema validator for Apprenticeship Step 0
3
+ * retro-harvest artifacts (`apprenticeship-retro-harvest/v1`).
4
+ *
5
+ * This is the SOURCE OF TRUTH for the validator (Apprenticeship Step 1 §3.2
6
+ * relocation). The pure logic lives here in TypeScript so it is type-checked
7
+ * and importable in-process by `ApprenticeshipProgram`; the thin CLI
8
+ * `scripts/validate-retro-harvest.mjs` re-exports from
9
+ * `dist/core/retroHarvestValidator.js` (the BackfillCore precedent).
10
+ *
11
+ * Per APPRENTICESHIP-STEP0-RETRO-HARVEST-SPEC.md §9, this is the structural
12
+ * SIGNAL — not the authority. It checks the artifact's SHAPE deterministically;
13
+ * the LLM fidelity review (recorded in frontmatter) is the AUTHORITY for whether
14
+ * the harvest is faithful. (Signal vs Authority / The Body and the Mind.)
15
+ *
16
+ * Two layers:
17
+ * - validateRetroHarvest(text, opts) — PURE, offline, unit-tested. Structure,
18
+ * reconciliation, redaction backstop, path safety, completeness, scope rules.
19
+ * - checkLiveLedger(frontmatter, fetchImpl) — OPTIONAL live cross-check that
20
+ * seeded ids resolve in the running ledger. Network; run by the integration
21
+ * test / `--check-live`, never by the pure unit path.
22
+ */
23
+ export declare const SCHEMA_ID = "apprenticeship-retro-harvest/v1";
24
+ export declare const INSTANCE_TYPES: readonly ["mentorship", "apprenticeship"];
25
+ export declare const SCOPE_MODES: readonly ["full", "incremental"];
26
+ export declare const COMPLETENESS: readonly ["complete", "partial-accepted"];
27
+ export declare const FIDELITY_VERDICTS: readonly ["faithful", "partial", "rejected"];
28
+ export declare const HARVEST_DIR = "docs/apprenticeship/retro-harvests";
29
+ /** Scrubbers Step 0 trusts. A missing/unknown/failed scrub refuses the artifact (§7). */
30
+ export declare const APPROVED_SCRUBBERS: readonly ["correction-scrub", "instar-pii-scrub"];
31
+ /** Evidence-pointer URI schemes (§6). */
32
+ export declare const POINTER_PATTERNS: Record<string, RegExp>;
33
+ /** Parsed frontmatter — the harvest carries arbitrary keys, so this is open. */
34
+ export type HarvestFrontmatter = Record<string, unknown>;
35
+ export interface ParsedArtifact {
36
+ frontmatter: HarvestFrontmatter;
37
+ body: string;
38
+ }
39
+ export interface ValidateResult {
40
+ valid: boolean;
41
+ errors: string[];
42
+ }
43
+ export interface ValidateOptions {
44
+ priorHarvestExists?: boolean;
45
+ }
46
+ /** Resolution shape for an injected live-ledger fetch (one seeded id). */
47
+ export interface LedgerResolution {
48
+ found: boolean;
49
+ playbookStatus?: string;
50
+ }
51
+ export type LedgerFetchImpl = (id: string) => Promise<LedgerResolution> | LedgerResolution;
52
+ export interface LiveLedgerResult {
53
+ ok: boolean;
54
+ errors: string[];
55
+ }
56
+ /**
57
+ * Split a markdown doc into { frontmatter (parsed), body (string) }.
58
+ * Throws if there is no `---`-delimited YAML frontmatter.
59
+ */
60
+ export declare function parseArtifact(text: string): ParsedArtifact;
61
+ /** Count top-level `- ` bullet items directly under a `## <heading>` section. */
62
+ export declare function countSectionItems(body: string, heading: string): number;
63
+ /** True when the body contains a secret-shaped string (returns the matched pattern name or null). */
64
+ export declare function findSecret(body: string): string | null;
65
+ /**
66
+ * Resolve + confine an artifact path to HARVEST_DIR. Returns the safe relative
67
+ * path or throws on traversal / bad component (§6 security).
68
+ */
69
+ export declare function safeArtifactPath(from: string, to: string, instanceType: string): string;
70
+ /**
71
+ * PURE structural validation of a retro-harvest artifact.
72
+ */
73
+ export declare function validateRetroHarvest(text: string, opts?: ValidateOptions): ValidateResult;
74
+ /**
75
+ * OPTIONAL live cross-check: every seededToPlaybook id resolves at candidate+ in
76
+ * the running ledger. Network — never part of the pure unit path. Inject fetch.
77
+ */
78
+ export declare function checkLiveLedger(frontmatter: HarvestFrontmatter, fetchImpl: LedgerFetchImpl): Promise<LiveLedgerResult>;
79
+ //# sourceMappingURL=retroHarvestValidator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retroHarvestValidator.d.ts","sourceRoot":"","sources":["../../src/core/retroHarvestValidator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAKH,eAAO,MAAM,SAAS,oCAAoC,CAAC;AAC3D,eAAO,MAAM,cAAc,2CAA4C,CAAC;AACxE,eAAO,MAAM,WAAW,kCAAmC,CAAC;AAC5D,eAAO,MAAM,YAAY,2CAA4C,CAAC;AACtE,eAAO,MAAM,iBAAiB,8CAA+C,CAAC;AAC9E,eAAO,MAAM,WAAW,uCAAuC,CAAC;AAEhE,yFAAyF;AACzF,eAAO,MAAM,kBAAkB,mDAAoD,CAAC;AAEpF,yCAAyC;AACzC,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAKnD,CAAC;AAaF,gFAAgF;AAChF,MAAM,MAAM,kBAAkB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEzD,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,kBAAkB,CAAC;IAChC,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,MAAM,WAAW,eAAe;IAC9B,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED,0EAA0E;AAC1E,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,OAAO,CAAC;IACf,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,MAAM,eAAe,GAAG,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,gBAAgB,CAAC,GAAG,gBAAgB,CAAC;AAE3F,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,CAK1D;AAED,iFAAiF;AACjF,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAUvE;AAED,qGAAqG;AACrG,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAKtD;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAevF;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,eAAoB,GAAG,cAAc,CA2I7F;AAED;;;GAGG;AACH,wBAAsB,eAAe,CACnC,WAAW,EAAE,kBAAkB,EAC/B,SAAS,EAAE,eAAe,GACzB,OAAO,CAAC,gBAAgB,CAAC,CAoB3B"}
@@ -0,0 +1,256 @@
1
+ /**
2
+ * retroHarvestValidator — the schema validator for Apprenticeship Step 0
3
+ * retro-harvest artifacts (`apprenticeship-retro-harvest/v1`).
4
+ *
5
+ * This is the SOURCE OF TRUTH for the validator (Apprenticeship Step 1 §3.2
6
+ * relocation). The pure logic lives here in TypeScript so it is type-checked
7
+ * and importable in-process by `ApprenticeshipProgram`; the thin CLI
8
+ * `scripts/validate-retro-harvest.mjs` re-exports from
9
+ * `dist/core/retroHarvestValidator.js` (the BackfillCore precedent).
10
+ *
11
+ * Per APPRENTICESHIP-STEP0-RETRO-HARVEST-SPEC.md §9, this is the structural
12
+ * SIGNAL — not the authority. It checks the artifact's SHAPE deterministically;
13
+ * the LLM fidelity review (recorded in frontmatter) is the AUTHORITY for whether
14
+ * the harvest is faithful. (Signal vs Authority / The Body and the Mind.)
15
+ *
16
+ * Two layers:
17
+ * - validateRetroHarvest(text, opts) — PURE, offline, unit-tested. Structure,
18
+ * reconciliation, redaction backstop, path safety, completeness, scope rules.
19
+ * - checkLiveLedger(frontmatter, fetchImpl) — OPTIONAL live cross-check that
20
+ * seeded ids resolve in the running ledger. Network; run by the integration
21
+ * test / `--check-live`, never by the pure unit path.
22
+ */
23
+ import path from 'node:path';
24
+ import yaml from 'js-yaml';
25
+ export const SCHEMA_ID = 'apprenticeship-retro-harvest/v1';
26
+ export const INSTANCE_TYPES = ['mentorship', 'apprenticeship'];
27
+ export const SCOPE_MODES = ['full', 'incremental'];
28
+ export const COMPLETENESS = ['complete', 'partial-accepted'];
29
+ export const FIDELITY_VERDICTS = ['faithful', 'partial', 'rejected'];
30
+ export const HARVEST_DIR = 'docs/apprenticeship/retro-harvests';
31
+ /** Scrubbers Step 0 trusts. A missing/unknown/failed scrub refuses the artifact (§7). */
32
+ export const APPROVED_SCRUBBERS = ['correction-scrub', 'instar-pii-scrub'];
33
+ /** Evidence-pointer URI schemes (§6). */
34
+ export const POINTER_PATTERNS = {
35
+ ledger: /^ledger:[0-9a-f-]{6,}$/i, // validator-resolvable
36
+ pr: /^pr:\d+$/, // validator-resolvable
37
+ thread: /^thread:\d+#[\w.-]+$/, // immutable msg locator; fidelity-review-only
38
+ memory: /^memory:[a-z0-9_-]+@[0-9a-f]{6,}#[\w.-]+$/i, // slug@hash#anchor; fidelity-review-only
39
+ };
40
+ /** Secret-shaped strings the backstop rejects (§7). A LIMITED backstop, not a scrub. */
41
+ const SECRET_PATTERNS = [
42
+ { name: 'bearer-token', re: /\bBearer\s+[A-Za-z0-9._-]{8,}/ },
43
+ { name: 'tunnel-sig', re: /[?&]sig=[0-9a-f]{16,}/i },
44
+ { name: 'long-hex-blob', re: /\b[0-9a-f]{40,}\b/i },
45
+ { name: 'long-base64-blob', re: /\b[A-Za-z0-9+/]{50,}={0,2}\b/ },
46
+ { name: 'email', re: /\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b/ },
47
+ ];
48
+ /**
49
+ * Split a markdown doc into { frontmatter (parsed), body (string) }.
50
+ * Throws if there is no `---`-delimited YAML frontmatter.
51
+ */
52
+ export function parseArtifact(text) {
53
+ const m = /^---\n([\s\S]*?)\n---\n?([\s\S]*)$/.exec(text);
54
+ if (!m)
55
+ throw new Error('no YAML frontmatter (--- … ---) found');
56
+ const frontmatter = yaml.load(m[1]) || {};
57
+ return { frontmatter, body: m[2] || '' };
58
+ }
59
+ /** Count top-level `- ` bullet items directly under a `## <heading>` section. */
60
+ export function countSectionItems(body, heading) {
61
+ const lines = body.split('\n');
62
+ let inSection = false;
63
+ let count = 0;
64
+ const headingRe = new RegExp('^##\\s+' + heading.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'i');
65
+ for (const line of lines) {
66
+ if (/^##\s+/.test(line))
67
+ inSection = headingRe.test(line);
68
+ else if (inSection && /^-\s+\S/.test(line))
69
+ count++;
70
+ }
71
+ return count;
72
+ }
73
+ /** True when the body contains a secret-shaped string (returns the matched pattern name or null). */
74
+ export function findSecret(body) {
75
+ for (const { name, re } of SECRET_PATTERNS) {
76
+ if (re.test(body))
77
+ return name;
78
+ }
79
+ return null;
80
+ }
81
+ /**
82
+ * Resolve + confine an artifact path to HARVEST_DIR. Returns the safe relative
83
+ * path or throws on traversal / bad component (§6 security).
84
+ */
85
+ export function safeArtifactPath(from, to, instanceType) {
86
+ for (const [k, v] of Object.entries({ from, to, instanceType })) {
87
+ if (typeof v !== 'string' || !/^[a-z0-9-]+$/.test(v)) {
88
+ throw new Error(`unsafe path component ${k}="${v}" (must match ^[a-z0-9-]+$)`);
89
+ }
90
+ }
91
+ const rel = `${HARVEST_DIR}/${from}-to-${to}-${instanceType}.md`;
92
+ const resolved = path.normalize(rel);
93
+ if (resolved.includes('..') ||
94
+ (!resolved.startsWith(HARVEST_DIR + path.sep) && !resolved.startsWith(HARVEST_DIR + '/'))) {
95
+ throw new Error(`path escapes ${HARVEST_DIR}: ${resolved}`);
96
+ }
97
+ return rel;
98
+ }
99
+ /**
100
+ * PURE structural validation of a retro-harvest artifact.
101
+ */
102
+ export function validateRetroHarvest(text, opts = {}) {
103
+ const errors = [];
104
+ const priorHarvestExists = !!opts.priorHarvestExists;
105
+ let parsed;
106
+ try {
107
+ parsed = parseArtifact(text);
108
+ }
109
+ catch (e) {
110
+ return { valid: false, errors: [`parse: ${e.message}`] };
111
+ }
112
+ const { frontmatter: fm, body } = parsed;
113
+ const fmStr = (k) => {
114
+ const v = fm[k];
115
+ return typeof v === 'string' ? v : undefined;
116
+ };
117
+ // --- schema id
118
+ if (fm.schema !== SCHEMA_ID)
119
+ errors.push(`schema must be "${SCHEMA_ID}" (got "${String(fm.schema)}")`);
120
+ // --- required scalar fields
121
+ for (const f of ['instanceType', 'from', 'to', 'framework', 'harvestedAt', 'scopeMode', 'completeness']) {
122
+ if (fm[f] == null || fm[f] === '')
123
+ errors.push(`missing required field: ${f}`);
124
+ }
125
+ const instanceType = fmStr('instanceType');
126
+ const scopeMode = fmStr('scopeMode');
127
+ const completeness = fmStr('completeness');
128
+ if (instanceType && !INSTANCE_TYPES.includes(instanceType))
129
+ errors.push(`instanceType must be one of ${INSTANCE_TYPES.join('|')}`);
130
+ if (scopeMode && !SCOPE_MODES.includes(scopeMode))
131
+ errors.push(`scopeMode must be one of ${SCOPE_MODES.join('|')}`);
132
+ if (completeness && !COMPLETENESS.includes(completeness))
133
+ errors.push(`completeness must be one of ${COMPLETENESS.join('|')}`);
134
+ // --- path safety on the identity components
135
+ const from = fmStr('from');
136
+ const to = fmStr('to');
137
+ if (from && to && instanceType) {
138
+ try {
139
+ safeArtifactPath(from, to, instanceType);
140
+ }
141
+ catch (e) {
142
+ errors.push(`path: ${e.message}`);
143
+ }
144
+ }
145
+ // --- scope rule: first harvest (no prior baseline) MUST be full (§8)
146
+ if (scopeMode === 'incremental' && !priorHarvestExists)
147
+ errors.push('scopeMode "incremental" requires a prior harvest baseline; the first harvest must be "full"');
148
+ // --- sourcesCovered: coverage EXTENT, not bare booleans (§8)
149
+ const sc = fm.sourcesCovered;
150
+ if (!sc || typeof sc !== 'object') {
151
+ errors.push('missing sourcesCovered');
152
+ }
153
+ else {
154
+ if (!sc.ledger || typeof sc.ledger.issueCount !== 'number')
155
+ errors.push('sourcesCovered.ledger must carry { read, issueCount }');
156
+ if (!sc.playbook || typeof sc.playbook.entryCount !== 'number')
157
+ errors.push('sourcesCovered.playbook must carry { read, entryCount }');
158
+ if (!Array.isArray(sc.threads))
159
+ errors.push('sourcesCovered.threads must be an array of { id, messagesRead, truncated }');
160
+ else
161
+ for (const t of sc.threads) {
162
+ if (typeof t.messagesRead !== 'number' || typeof t.truncated !== 'boolean')
163
+ errors.push(`sourcesCovered.threads[${t && t.id}] needs numeric messagesRead + boolean truncated (coverage extent, not presence)`);
164
+ }
165
+ }
166
+ // --- completeness vs truncation (§8): complete ⇒ nothing truncated
167
+ if (completeness === 'complete' && sc && Array.isArray(sc.threads)) {
168
+ if (sc.threads.some((t) => t.truncated === true))
169
+ errors.push('completeness "complete" is invalid when a source is truncated; use "partial-accepted" with named gaps');
170
+ }
171
+ // --- counts reconcile with body (§9)
172
+ const counts = fm.counts || {};
173
+ const bodyLessons = countSectionItems(body, 'Lessons');
174
+ const bodyMeta = countSectionItems(body, 'Meta-lessons');
175
+ const bodyProc = countSectionItems(body, 'Process-insights');
176
+ const bodyNeeds = countSectionItems(body, 'What the program needs');
177
+ if (counts.lessons !== bodyLessons)
178
+ errors.push(`counts.lessons=${counts.lessons} but body has ${bodyLessons} "## Lessons" items`);
179
+ if (counts.metaLessons !== bodyMeta)
180
+ errors.push(`counts.metaLessons=${counts.metaLessons} but body has ${bodyMeta} "## Meta-lessons" items`);
181
+ if (counts.processInsights !== bodyProc)
182
+ errors.push(`counts.processInsights=${counts.processInsights} but body has ${bodyProc} "## Process-insights" items`);
183
+ if (fm.programNeeds !== bodyNeeds)
184
+ errors.push(`programNeeds=${fm.programNeeds} but body has ${bodyNeeds} "## What the program needs" items`);
185
+ // --- redaction: approved scrubber, not failed (§7)
186
+ const r = fm.redaction;
187
+ if (!r || typeof r !== 'object') {
188
+ errors.push('missing redaction { scrubber, findingsRemoved, scrubbedAt }');
189
+ }
190
+ else {
191
+ const scrubberName = String(r.scrubber || '').split('@')[0];
192
+ if (!APPROVED_SCRUBBERS.includes(scrubberName))
193
+ errors.push(`redaction.scrubber "${String(r.scrubber)}" not in approved list (${APPROVED_SCRUBBERS.join(', ')})`);
194
+ if (r.status === 'failed')
195
+ errors.push('redaction.status is "failed" — scrub must succeed before write');
196
+ if (typeof r.findingsRemoved !== 'number')
197
+ errors.push('redaction.findingsRemoved must be a number');
198
+ }
199
+ // --- fidelity review: the authority's stamp (§9)
200
+ const fr = fm.fidelityReview;
201
+ if (!fr || typeof fr !== 'object') {
202
+ errors.push('missing fidelityReview { reviewer, verdict, at }');
203
+ }
204
+ else {
205
+ if (!FIDELITY_VERDICTS.includes(String(fr.verdict)))
206
+ errors.push(`fidelityReview.verdict must be one of ${FIDELITY_VERDICTS.join('|')}`);
207
+ if (fr.verdict === 'rejected')
208
+ errors.push('fidelityReview.verdict is "rejected" — harvest is not faithful');
209
+ if (fr.verdict === 'partial' && !fr.gaps && !(fr.audit && fr.audit.gaps))
210
+ errors.push('fidelityReview "partial" must name the gaps (fidelityReview.gaps)');
211
+ if (!fr.reviewer)
212
+ errors.push('fidelityReview.reviewer required (must be independent of the harvesting pass)');
213
+ }
214
+ // --- evidence pointers well-formed (§6). Strip trailing sentence punctuation
215
+ // so a pointer at a clause boundary ("ledger:abc123, priority…") still validates.
216
+ const pointerTokens = (body.match(/\b(?:ledger|pr|thread|memory):[^\s)\]]+/g) || []).map((t) => t.replace(/[.,;:]+$/, ''));
217
+ for (const tok of pointerTokens) {
218
+ const scheme = tok.split(':')[0];
219
+ const re = POINTER_PATTERNS[scheme];
220
+ if (re && !re.test(tok))
221
+ errors.push(`malformed evidence pointer: ${tok}`);
222
+ }
223
+ // --- secret backstop (§7)
224
+ const secret = findSecret(body);
225
+ if (secret)
226
+ errors.push(`secret-shaped string in body (${secret}) — pointers-not-payloads (§7)`);
227
+ return { valid: errors.length === 0, errors };
228
+ }
229
+ /**
230
+ * OPTIONAL live cross-check: every seededToPlaybook id resolves at candidate+ in
231
+ * the running ledger. Network — never part of the pure unit path. Inject fetch.
232
+ */
233
+ export async function checkLiveLedger(frontmatter, fetchImpl) {
234
+ const errors = [];
235
+ const seededRaw = frontmatter.seededToPlaybook;
236
+ const seeded = Array.isArray(seededRaw) ? seededRaw : [];
237
+ for (const s of seeded) {
238
+ const id = s && s.id;
239
+ if (!id) {
240
+ errors.push('seededToPlaybook entry without id');
241
+ continue;
242
+ }
243
+ try {
244
+ const res = await fetchImpl(id);
245
+ if (!res || !res.found)
246
+ errors.push(`seeded id ${id} not found in live ledger`);
247
+ else if (!['candidate', 'extracted'].includes(String(res.playbookStatus)))
248
+ errors.push(`seeded id ${id} is "${res.playbookStatus}", expected candidate+`);
249
+ }
250
+ catch (e) {
251
+ errors.push(`live check for ${id} failed: ${e.message}`);
252
+ }
253
+ }
254
+ return { ok: errors.length === 0, errors };
255
+ }
256
+ //# sourceMappingURL=retroHarvestValidator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retroHarvestValidator.js","sourceRoot":"","sources":["../../src/core/retroHarvestValidator.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../../src/scaffold/templates.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,aAAa,GAAG,MAAM,CAgG/D;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CA2E/F;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAiBvD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CA2B1D;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,OAAO,EACpB,WAAW,GAAE,OAAe,EAC5B,WAAW,GAAE,OAAe,GAC3B,MAAM,CAotCR;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,OAAO,EACpB,WAAW,GAAE,OAAe,GAC3B,MAAM,CAuSR"}
1
+ {"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../../src/scaffold/templates.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,aAAa,GAAG,MAAM,CAgG/D;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CA2E/F;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAiBvD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CA2B1D;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,OAAO,EACpB,WAAW,GAAE,OAAe,EAC5B,WAAW,GAAE,OAAe,GAC3B,MAAM,CAguCR;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,OAAO,EACpB,WAAW,GAAE,OAAe,GAC3B,MAAM,CAuSR"}