@aperant/framework 0.16.0 → 0.19.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.
- package/CHANGELOG.md +185 -1
- package/dist/cli/commands/ci-watch.mjs +49 -2
- package/dist/cli/commands/ci-watch.mjs.map +1 -1
- package/dist/cli/commands/commit.mjs +3 -3
- package/dist/cli/commands/commit.mjs.map +1 -1
- package/dist/cli/commands/event.mjs +16 -16
- package/dist/cli/commands/event.mjs.map +1 -1
- package/dist/cli/commands/merge-integrate.mjs +3 -3
- package/dist/cli/commands/merge-integrate.mjs.map +1 -1
- package/dist/cli/commands/produce.d.mts +9 -0
- package/dist/cli/commands/produce.d.mts.map +1 -0
- package/dist/cli/commands/produce.mjs +1345 -0
- package/dist/cli/commands/produce.mjs.map +1 -0
- package/dist/cli/commands/spar-resolve-partner.d.mts +9 -0
- package/dist/cli/commands/spar-resolve-partner.d.mts.map +1 -0
- package/dist/cli/commands/spar-resolve-partner.mjs +82 -0
- package/dist/cli/commands/spar-resolve-partner.mjs.map +1 -0
- package/dist/cli/commands/task.d.mts +16 -1
- package/dist/cli/commands/task.d.mts.map +1 -1
- package/dist/cli/commands/task.mjs +434 -266
- package/dist/cli/commands/task.mjs.map +1 -1
- package/dist/cli/config/gitignore-drift.d.mts.map +1 -1
- package/dist/cli/config/gitignore-drift.mjs +1 -0
- package/dist/cli/config/gitignore-drift.mjs.map +1 -1
- package/dist/cli/config/post-merge-sweep.d.mts.map +1 -1
- package/dist/cli/config/post-merge-sweep.mjs +1 -0
- package/dist/cli/config/post-merge-sweep.mjs.map +1 -1
- package/dist/cli/coordination/auto-emit-artifact-ready.mjs +5 -5
- package/dist/cli/coordination/auto-emit-artifact-ready.mjs.map +1 -1
- package/dist/cli/coordination/event-schema.d.mts +5 -3
- package/dist/cli/coordination/event-schema.d.mts.map +1 -1
- package/dist/cli/coordination/event-schema.mjs +245 -21
- package/dist/cli/coordination/event-schema.mjs.map +1 -1
- package/dist/cli/coordination/store.d.mts +2 -2
- package/dist/cli/coordination/store.mjs +4 -4
- package/dist/cli/coordination/store.mjs.map +1 -1
- package/dist/cli/dispatch.d.mts.map +1 -1
- package/dist/cli/dispatch.mjs +4 -0
- package/dist/cli/dispatch.mjs.map +1 -1
- package/dist/cli/help.d.mts.map +1 -1
- package/dist/cli/help.mjs +31 -0
- package/dist/cli/help.mjs.map +1 -1
- package/dist/cli/host/codex-config.d.mts +78 -0
- package/dist/cli/host/codex-config.d.mts.map +1 -0
- package/dist/cli/host/codex-config.mjs +169 -0
- package/dist/cli/host/codex-config.mjs.map +1 -0
- package/dist/cli/install/legacy-paths.d.mts.map +1 -1
- package/dist/cli/install/legacy-paths.mjs +2 -0
- package/dist/cli/install/legacy-paths.mjs.map +1 -1
- package/dist/cli/produce/blind-probe.d.mts +85 -0
- package/dist/cli/produce/blind-probe.d.mts.map +1 -0
- package/dist/cli/produce/blind-probe.mjs +217 -0
- package/dist/cli/produce/blind-probe.mjs.map +1 -0
- package/dist/cli/produce/claim.d.mts +188 -0
- package/dist/cli/produce/claim.d.mts.map +1 -0
- package/dist/cli/produce/claim.mjs +518 -0
- package/dist/cli/produce/claim.mjs.map +1 -0
- package/dist/cli/produce/done-gate.d.mts +87 -0
- package/dist/cli/produce/done-gate.d.mts.map +1 -0
- package/dist/cli/produce/done-gate.mjs +200 -0
- package/dist/cli/produce/done-gate.mjs.map +1 -0
- package/dist/cli/produce/events.d.mts +77 -0
- package/dist/cli/produce/events.d.mts.map +1 -0
- package/dist/cli/produce/events.mjs +126 -0
- package/dist/cli/produce/events.mjs.map +1 -0
- package/dist/cli/produce/evidence-oracle.d.mts +63 -0
- package/dist/cli/produce/evidence-oracle.d.mts.map +1 -0
- package/dist/cli/produce/evidence-oracle.mjs +122 -0
- package/dist/cli/produce/evidence-oracle.mjs.map +1 -0
- package/dist/cli/produce/ledger.d.mts +140 -0
- package/dist/cli/produce/ledger.d.mts.map +1 -0
- package/dist/cli/produce/ledger.mjs +272 -0
- package/dist/cli/produce/ledger.mjs.map +1 -0
- package/dist/cli/produce/probe-family.d.mts +53 -0
- package/dist/cli/produce/probe-family.d.mts.map +1 -0
- package/dist/cli/produce/probe-family.mjs +160 -0
- package/dist/cli/produce/probe-family.mjs.map +1 -0
- package/dist/cli/produce/projection.d.mts +55 -0
- package/dist/cli/produce/projection.d.mts.map +1 -0
- package/dist/cli/produce/projection.mjs +97 -0
- package/dist/cli/produce/projection.mjs.map +1 -0
- package/dist/cli/produce/run-id.d.mts +42 -0
- package/dist/cli/produce/run-id.d.mts.map +1 -0
- package/dist/cli/produce/run-id.mjs +79 -0
- package/dist/cli/produce/run-id.mjs.map +1 -0
- package/dist/cli/produce/saga.d.mts +180 -0
- package/dist/cli/produce/saga.d.mts.map +1 -0
- package/dist/cli/produce/saga.mjs +290 -0
- package/dist/cli/produce/saga.mjs.map +1 -0
- package/dist/cli/produce/scheduler.d.mts +165 -0
- package/dist/cli/produce/scheduler.d.mts.map +1 -0
- package/dist/cli/produce/scheduler.mjs +399 -0
- package/dist/cli/produce/scheduler.mjs.map +1 -0
- package/dist/cli/produce/setpoint.d.mts +52 -0
- package/dist/cli/produce/setpoint.d.mts.map +1 -0
- package/dist/cli/produce/setpoint.mjs +113 -0
- package/dist/cli/produce/setpoint.mjs.map +1 -0
- package/dist/cli/produce/verification-ttl.d.mts +75 -0
- package/dist/cli/produce/verification-ttl.d.mts.map +1 -0
- package/dist/cli/produce/verification-ttl.mjs +169 -0
- package/dist/cli/produce/verification-ttl.mjs.map +1 -0
- package/dist/cli/roadmap/{conductor-view.d.mts → showrunner-view.d.mts} +3 -3
- package/dist/cli/roadmap/showrunner-view.d.mts.map +1 -0
- package/dist/cli/roadmap/{conductor-view.mjs → showrunner-view.mjs} +7 -7
- package/dist/cli/roadmap/showrunner-view.mjs.map +1 -0
- package/dist/cli/wfrun/run.d.mts.map +1 -1
- package/dist/cli/wfrun/run.mjs +1 -0
- package/dist/cli/wfrun/run.mjs.map +1 -1
- package/dist/plugin/.claude-plugin/plugin.json +2 -1
- package/dist/plugin/skills/apt/SKILL.md +112 -38
- package/dist/plugin/skills/apt-debug/SKILL.md +14 -24
- package/dist/plugin/skills/apt-fan-out/SKILL.md +4 -4
- package/dist/plugin/skills/apt-handoff/SKILL.md +1 -1
- package/dist/plugin/skills/apt-plan/SKILL.md +5 -5
- package/dist/plugin/skills/apt-plan/adapters/{conductor.md → showrunner.md} +16 -16
- package/dist/plugin/skills/apt-produce/SKILL.md +606 -0
- package/dist/plugin/skills/apt-quick/SKILL.md +14 -22
- package/dist/plugin/skills/apt-run/SKILL.md +126 -3
- package/dist/plugin/skills/apt-ship/SKILL.md +2 -0
- package/dist/plugin/skills/apt-spar/SKILL.md +19 -9
- package/dist/plugin/skills/apt-watch-ci/SKILL.md +4 -4
- package/package.json +4 -4
- package/prompts/{conductor-framework-context.md → showrunner-framework-context.md} +1 -1
- package/prompts/{conductor-status-check.md → showrunner-status-check.md} +1 -1
- package/prompts/{conductor-sub-agent.md → showrunner-sub-agent.md} +6 -6
- package/prompts/{conductor-system.md → showrunner-system.md} +8 -8
- package/skills/apt/SKILL.md +112 -38
- package/skills/apt-debug/SKILL.md +14 -24
- package/skills/apt-fan-out/SKILL.md +4 -4
- package/skills/apt-handoff/SKILL.md +1 -1
- package/skills/apt-plan/SKILL.md +5 -5
- package/skills/apt-plan/adapters/{conductor.md → showrunner.md} +16 -16
- package/skills/apt-produce/SKILL.md +606 -0
- package/skills/apt-quick/SKILL.md +14 -22
- package/skills/apt-run/SKILL.md +126 -3
- package/skills/apt-ship/SKILL.md +2 -0
- package/skills/apt-spar/SKILL.md +19 -9
- package/skills/apt-watch-ci/SKILL.md +4 -4
- package/src/cli/commands/ci-watch.mjs +51 -2
- package/src/cli/commands/commit.mjs +3 -3
- package/src/cli/commands/event.mjs +16 -16
- package/src/cli/commands/merge-integrate.mjs +3 -3
- package/src/cli/commands/produce.mjs +1466 -0
- package/src/cli/commands/spar-resolve-partner.mjs +85 -0
- package/src/cli/commands/task.mjs +482 -285
- package/src/cli/config/gitignore-drift.mjs +1 -0
- package/src/cli/config/post-merge-sweep.mjs +1 -0
- package/src/cli/coordination/auto-emit-artifact-ready.mjs +5 -5
- package/src/cli/coordination/event-schema.d.ts +4 -2
- package/src/cli/coordination/event-schema.mjs +276 -21
- package/src/cli/coordination/store.mjs +4 -4
- package/src/cli/dispatch.mjs +4 -0
- package/src/cli/help.mjs +31 -0
- package/src/cli/host/codex-config.mjs +165 -0
- package/src/cli/install/legacy-paths.mjs +2 -0
- package/src/cli/produce/blind-probe.mjs +245 -0
- package/src/cli/produce/claim.mjs +543 -0
- package/src/cli/produce/done-gate.mjs +238 -0
- package/src/cli/produce/events.mjs +131 -0
- package/src/cli/produce/evidence-oracle.mjs +133 -0
- package/src/cli/produce/ledger.mjs +284 -0
- package/src/cli/produce/probe-family.mjs +168 -0
- package/src/cli/produce/projection.mjs +105 -0
- package/src/cli/produce/run-id.mjs +84 -0
- package/src/cli/produce/saga.mjs +303 -0
- package/src/cli/produce/scheduler.mjs +423 -0
- package/src/cli/produce/setpoint.mjs +122 -0
- package/src/cli/produce/verification-ttl.mjs +191 -0
- package/src/cli/roadmap/showrunner-view.d.ts +10 -0
- package/src/cli/roadmap/{conductor-view.mjs → showrunner-view.mjs} +6 -6
- package/src/cli/wfrun/run.mjs +1 -0
- package/dist/cli/roadmap/conductor-view.d.mts.map +0 -1
- package/dist/cli/roadmap/conductor-view.mjs.map +0 -1
- package/src/cli/roadmap/conductor-view.d.ts +0 -10
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @internal
|
|
3
|
+
* produce/blind-probe.mjs — the held-out cross-family blind-probe set (M2, AC4-6).
|
|
4
|
+
*
|
|
5
|
+
* A fixed 10–20 behavioral probe set the implementer/Showrunner NEVER sees
|
|
6
|
+
* (probe-blindness, US-4 / ID-06), authored + run by a provider family DISJOINT
|
|
7
|
+
* from the implementer's, re-run on a rotating sample of already-done milestones
|
|
8
|
+
* against HEAD (US-6).
|
|
9
|
+
*
|
|
10
|
+
* The probe SET is a frozen immutable artifact at
|
|
11
|
+
* `.aperant/produce/<run-id>/probes/<milestone>.json`, written ONCE via
|
|
12
|
+
* `openSync(path, 'wx')` exclusive-create — a second freeze throws EEXIST and
|
|
13
|
+
* returns the byte-identical stored set (mirrors setpoint.mjs::freezeSetpoint).
|
|
14
|
+
* Its CONTENT never enters the event log or the roadmap projection the
|
|
15
|
+
* Showrunner re-reads each tick (structural probe-blindness, ID-M2-03): the
|
|
16
|
+
* `produce.probe.frozen` event carries ONLY `{probe_set_hash, author_family}`
|
|
17
|
+
* and `produce.probe.run` carries ONLY `{result, probe_family, head_sha}`.
|
|
18
|
+
*/
|
|
19
|
+
import { createHash } from 'node:crypto';
|
|
20
|
+
import { closeSync, existsSync, fsyncSync, mkdirSync, openSync, readFileSync, writeSync, } from 'node:fs';
|
|
21
|
+
import { join } from 'node:path';
|
|
22
|
+
import { appendProduceEvent, readImplementerFamily, readProduceRunEventsMatching, } from './events.mjs';
|
|
23
|
+
import { normalizeFamily } from './probe-family.mjs';
|
|
24
|
+
import { projectRoadmap } from './projection.mjs';
|
|
25
|
+
import { resolveRunDir } from './run-id.mjs';
|
|
26
|
+
/** sha256 of the canonical JSON of the probe content (the immutable hash stamp). */
|
|
27
|
+
function computeProbeSetHash(content) {
|
|
28
|
+
return createHash('sha256').update(JSON.stringify(content)).digest('hex');
|
|
29
|
+
}
|
|
30
|
+
/** The probes/<milestone>.json path for a run + milestone. */
|
|
31
|
+
export function probeSetPathFor(projectDir, runId, milestoneId) {
|
|
32
|
+
return join(resolveRunDir(projectDir, runId), 'probes', `${milestoneId}.json`);
|
|
33
|
+
}
|
|
34
|
+
/** Read + parse a frozen probe set. Returns null when absent or malformed. */
|
|
35
|
+
export function readProbeSet(projectDir, runId, milestoneId) {
|
|
36
|
+
const p = probeSetPathFor(projectDir, runId, milestoneId);
|
|
37
|
+
if (!existsSync(p))
|
|
38
|
+
return null;
|
|
39
|
+
try {
|
|
40
|
+
return JSON.parse(readFileSync(p, 'utf-8'));
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Exclusive-create write of the frozen probe set on the FINAL path (NOT
|
|
48
|
+
* tmp+rename), so a SECOND write throws EEXIST — the set is immutable.
|
|
49
|
+
*/
|
|
50
|
+
function writeProbeSetExclusive(probePath, probeSet) {
|
|
51
|
+
mkdirSync(join(probePath, '..'), { recursive: true });
|
|
52
|
+
const payload = `${JSON.stringify(probeSet, null, 2)}\n`;
|
|
53
|
+
const fd = openSync(probePath, 'wx'); // throws EEXIST when already frozen
|
|
54
|
+
try {
|
|
55
|
+
writeSync(fd, payload, 0, 'utf-8');
|
|
56
|
+
fsyncSync(fd);
|
|
57
|
+
}
|
|
58
|
+
finally {
|
|
59
|
+
closeSync(fd);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Freeze a blind-probe set for a milestone, idempotently. REFUSES fail-closed
|
|
64
|
+
* when the author family equals the implementer family (a held-out probe an
|
|
65
|
+
* implementer authored is not held out — ID-06) or when no implementer family
|
|
66
|
+
* is recorded (ID-M2-02). On a FRESH freeze appends `produce.probe.frozen`
|
|
67
|
+
* carrying ONLY the hash + author family (never the content). A second freeze
|
|
68
|
+
* returns the byte-identical stored set (`reused: true`) and never re-logs.
|
|
69
|
+
*
|
|
70
|
+
* @param {string} projectDir
|
|
71
|
+
* @param {string} runId
|
|
72
|
+
* @param {string} milestoneId
|
|
73
|
+
* @param {{ content: unknown, authorFamily: string, implementerFamily: string }} args
|
|
74
|
+
* @param {Date} [now]
|
|
75
|
+
* @returns {{ ok: true, reused: boolean, probe_set_hash: string, author_family: string }
|
|
76
|
+
* | { ok: false, reason: string }}
|
|
77
|
+
*/
|
|
78
|
+
export function freezeProbeSet(projectDir, runId, milestoneId, { content, authorFamily, implementerFamily }, now = new Date()) {
|
|
79
|
+
if (!authorFamily)
|
|
80
|
+
return { ok: false, reason: 'no_author_family' };
|
|
81
|
+
if (!implementerFamily)
|
|
82
|
+
return { ok: false, reason: 'no_implementer_family' };
|
|
83
|
+
// Cross-family enforcement (normalized so claude-code === claude).
|
|
84
|
+
if (normalizeFamily(authorFamily) === normalizeFamily(implementerFamily))
|
|
85
|
+
return { ok: false, reason: 'same_family_author' };
|
|
86
|
+
const probePath = probeSetPathFor(projectDir, runId, milestoneId);
|
|
87
|
+
const existing = readProbeSet(projectDir, runId, milestoneId);
|
|
88
|
+
if (existing)
|
|
89
|
+
return {
|
|
90
|
+
ok: true,
|
|
91
|
+
reused: true,
|
|
92
|
+
probe_set_hash: existing.probe_set_hash,
|
|
93
|
+
author_family: existing.author_family,
|
|
94
|
+
};
|
|
95
|
+
const probeSetHash = computeProbeSetHash(content ?? null);
|
|
96
|
+
const probeSet = {
|
|
97
|
+
run_id: runId,
|
|
98
|
+
milestone_id: milestoneId,
|
|
99
|
+
author_family: authorFamily,
|
|
100
|
+
frozen_at: now.toISOString(),
|
|
101
|
+
probe_set_hash: probeSetHash,
|
|
102
|
+
// The probe CONTENT lives in the frozen file (blind to the projection) —
|
|
103
|
+
// it NEVER enters the event log.
|
|
104
|
+
probes: content ?? null,
|
|
105
|
+
};
|
|
106
|
+
try {
|
|
107
|
+
writeProbeSetExclusive(probePath, probeSet);
|
|
108
|
+
}
|
|
109
|
+
catch (e) {
|
|
110
|
+
// Lost a concurrent race — the winner's file is authoritative; re-read it
|
|
111
|
+
// byte-identically rather than overwriting (mirrors freezeSetpoint).
|
|
112
|
+
if (e && e.code === 'EEXIST') {
|
|
113
|
+
const winner = readProbeSet(projectDir, runId, milestoneId);
|
|
114
|
+
if (winner)
|
|
115
|
+
return {
|
|
116
|
+
ok: true,
|
|
117
|
+
reused: true,
|
|
118
|
+
probe_set_hash: winner.probe_set_hash,
|
|
119
|
+
author_family: winner.author_family,
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
throw e;
|
|
123
|
+
}
|
|
124
|
+
// Announce by hash + author family ONLY — never the content (ID-M2-03).
|
|
125
|
+
appendProduceEvent(projectDir, 'produce.probe.frozen', {
|
|
126
|
+
run_id: runId,
|
|
127
|
+
milestone_id: milestoneId,
|
|
128
|
+
probe_set_hash: probeSetHash,
|
|
129
|
+
author_family: authorFamily,
|
|
130
|
+
});
|
|
131
|
+
return { ok: true, reused: false, probe_set_hash: probeSetHash, author_family: authorFamily };
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Record a blind-probe RUN result. REFUSES fail-closed when the probe family
|
|
135
|
+
* equals the implementer family (a probe run BY the implementer family is not
|
|
136
|
+
* cross-family — ID-08) or when no implementer family is recorded. On
|
|
137
|
+
* acceptance appends `produce.probe.run {run_id, milestone_id, result,
|
|
138
|
+
* probe_family, head_sha}` — result/family/head_sha only, never content.
|
|
139
|
+
*
|
|
140
|
+
* @param {string} projectDir
|
|
141
|
+
* @param {{ runId: string, milestoneId: string, result: string, probeFamily: string, headSha: string }} args
|
|
142
|
+
* @returns {{ ok: true, result: string, probe_family: string, head_sha: string }
|
|
143
|
+
* | { ok: false, reason: string }}
|
|
144
|
+
*/
|
|
145
|
+
export function recordProbeRun(projectDir, { runId, milestoneId, result, probeFamily, headSha }) {
|
|
146
|
+
if (result !== 'pass' && result !== 'fail')
|
|
147
|
+
return { ok: false, reason: 'invalid_result' };
|
|
148
|
+
if (!probeFamily)
|
|
149
|
+
return { ok: false, reason: 'no_probe_family' };
|
|
150
|
+
if (!headSha)
|
|
151
|
+
return { ok: false, reason: 'no_head_sha' };
|
|
152
|
+
const implementerFamily = readImplementerFamily(projectDir, runId, milestoneId);
|
|
153
|
+
if (!implementerFamily)
|
|
154
|
+
return { ok: false, reason: 'no_recorded_implementer' };
|
|
155
|
+
if (normalizeFamily(probeFamily) === normalizeFamily(implementerFamily))
|
|
156
|
+
return { ok: false, reason: 'same_family_probe' };
|
|
157
|
+
appendProduceEvent(projectDir, 'produce.probe.run', {
|
|
158
|
+
run_id: runId,
|
|
159
|
+
milestone_id: milestoneId,
|
|
160
|
+
result,
|
|
161
|
+
probe_family: probeFamily,
|
|
162
|
+
head_sha: headSha,
|
|
163
|
+
});
|
|
164
|
+
return { ok: true, result, probe_family: probeFamily, head_sha: headSha };
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Select a DETERMINISTIC rotating sample of already-`done` milestones for blind
|
|
168
|
+
* re-probing against HEAD (US-6). Rotates by fewest prior probe runs first,
|
|
169
|
+
* then oldest last-probe-run first (a never-probed done milestone sorts first),
|
|
170
|
+
* then first-seen roadmap order — so two folds of the same log select the same
|
|
171
|
+
* sample.
|
|
172
|
+
*
|
|
173
|
+
* @param {string} projectDir
|
|
174
|
+
* @param {string} runId
|
|
175
|
+
* @param {{ sample?: number }} [opts]
|
|
176
|
+
* @returns {{ run_id: string, sample_size: number, selected: Array<{ milestone_id: string, title: string, probe_run_count: number, last_probe_run_at: string | null }> }}
|
|
177
|
+
*/
|
|
178
|
+
export function selectSweepSample(projectDir, runId, { sample = 1 } = {}) {
|
|
179
|
+
const roadmap = projectRoadmap(projectDir, runId);
|
|
180
|
+
const done = roadmap.milestones.filter((m) => m.status === 'done');
|
|
181
|
+
const runEvents = readProduceRunEventsMatching(projectDir, runId, (op) => op === 'produce.probe.run');
|
|
182
|
+
const stats = new Map();
|
|
183
|
+
for (const e of runEvents) {
|
|
184
|
+
const id = e.data && typeof e.data.milestone_id === 'string' ? e.data.milestone_id : null;
|
|
185
|
+
if (!id)
|
|
186
|
+
continue;
|
|
187
|
+
const s = stats.get(id) || { count: 0, last: null };
|
|
188
|
+
s.count += 1;
|
|
189
|
+
if (typeof e.t === 'string' && (s.last === null || e.t > s.last))
|
|
190
|
+
s.last = e.t;
|
|
191
|
+
stats.set(id, s);
|
|
192
|
+
}
|
|
193
|
+
const withOrder = done.map((m, idx) => {
|
|
194
|
+
const s = stats.get(m.id) || { count: 0, last: null };
|
|
195
|
+
return { milestone: m, order: idx, count: s.count, last: s.last };
|
|
196
|
+
});
|
|
197
|
+
withOrder.sort((a, b) => {
|
|
198
|
+
if (a.count !== b.count)
|
|
199
|
+
return a.count - b.count; // fewest probe runs first
|
|
200
|
+
// oldest last-probe-run first — a never-probed done milestone (null) sorts
|
|
201
|
+
// ahead of any dated one.
|
|
202
|
+
const al = a.last ?? '';
|
|
203
|
+
const bl = b.last ?? '';
|
|
204
|
+
if (al !== bl)
|
|
205
|
+
return al < bl ? -1 : 1;
|
|
206
|
+
return a.order - b.order; // first-seen roadmap order (stable tiebreak)
|
|
207
|
+
});
|
|
208
|
+
const n = Number.isFinite(sample) && sample > 0 ? Math.floor(sample) : 1;
|
|
209
|
+
const selected = withOrder.slice(0, n).map((w) => ({
|
|
210
|
+
milestone_id: w.milestone.id,
|
|
211
|
+
title: w.milestone.title,
|
|
212
|
+
probe_run_count: w.count,
|
|
213
|
+
last_probe_run_at: w.last,
|
|
214
|
+
}));
|
|
215
|
+
return { run_id: runId, sample_size: selected.length, selected };
|
|
216
|
+
}
|
|
217
|
+
//# sourceMappingURL=blind-probe.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"blind-probe.mjs","sourceRoot":"","sources":["../../../src/cli/produce/blind-probe.mjs"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validate a Claim Envelope by dispatching on `envelope.profile` through the
|
|
3
|
+
* REGISTRY (never a hardcoded profile branch — ID-M6-02). An unknown/absent
|
|
4
|
+
* profile fails closed (`{ ok:false, reason:'unknown_profile' }`). Never throws.
|
|
5
|
+
*
|
|
6
|
+
* @param {Record<string, unknown>} envelope
|
|
7
|
+
* @param {{ profiles?: Record<string, { validate: (env: Record<string, unknown>) => { ok: boolean, reason?: string } }> }} [opts]
|
|
8
|
+
* @returns {{ ok: true } | { ok: false, reason: string }}
|
|
9
|
+
*/
|
|
10
|
+
export function validateClaimEnvelope(envelope: Record<string, unknown>, { profiles }?: {
|
|
11
|
+
profiles?: Record<string, {
|
|
12
|
+
validate: (env: Record<string, unknown>) => {
|
|
13
|
+
ok: boolean;
|
|
14
|
+
reason?: string;
|
|
15
|
+
};
|
|
16
|
+
}>;
|
|
17
|
+
}): {
|
|
18
|
+
ok: true;
|
|
19
|
+
} | {
|
|
20
|
+
ok: false;
|
|
21
|
+
reason: string;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Mint a claim id: `<slug-of-text>-<rand>`. Reuses `slugFromOutcome` + a short
|
|
25
|
+
* random suffix (mirrors ledger.mjs::mintCriterionId) so two claims minted from
|
|
26
|
+
* the same text never collide. Falls back to the profile when text is empty.
|
|
27
|
+
*
|
|
28
|
+
* @param {string} profile
|
|
29
|
+
* @param {string} text
|
|
30
|
+
* @returns {string}
|
|
31
|
+
*/
|
|
32
|
+
export function mintClaimId(profile: string, text: string): string;
|
|
33
|
+
/** The claims/<claim-id>.json path for a run + claim. */
|
|
34
|
+
export function claimPathFor(projectDir: any, runId: any, claimId: any): string;
|
|
35
|
+
/** Read + parse a frozen claim record. Returns null when absent or malformed. */
|
|
36
|
+
export function readClaim(projectDir: any, runId: any, claimId: any): any;
|
|
37
|
+
/**
|
|
38
|
+
* Freeze a Claim Envelope, idempotently. VALIDATES first (refuses to freeze an
|
|
39
|
+
* invalid envelope — fail-closed), computes `content_hash = sha256(envelope)`,
|
|
40
|
+
* writes `claims/<claim-id>.json` exclusive-create, and on a FRESH freeze appends
|
|
41
|
+
* `produce.claim.declared {run_id, profile, claim_id, content_hash}` (content_hash
|
|
42
|
+
* only — the full envelope lives in the frozen file, ID-M6-07). A second freeze
|
|
43
|
+
* of the same claim id returns the byte-identical stored record (`reused: true`)
|
|
44
|
+
* and never re-logs. The resolved `profile` (explicit arg or `envelope.profile`)
|
|
45
|
+
* is authoritative for validation dispatch + the stored/logged profile.
|
|
46
|
+
*
|
|
47
|
+
* @param {string} projectDir
|
|
48
|
+
* @param {string} runId
|
|
49
|
+
* @param {{ profile?: string, envelope: Record<string, unknown>, claimId?: string }} args
|
|
50
|
+
* @param {{ profiles?: object, now?: Date }} [opts]
|
|
51
|
+
* @returns {{ ok: true, reused: boolean, claim_id: string, profile: string | null, content_hash: string }
|
|
52
|
+
* | { ok: false, reason: string }}
|
|
53
|
+
*/
|
|
54
|
+
export function freezeClaim(projectDir: string, runId: string, { profile, envelope, claimId }?: {
|
|
55
|
+
profile?: string;
|
|
56
|
+
envelope: Record<string, unknown>;
|
|
57
|
+
claimId?: string;
|
|
58
|
+
}, { profiles, now }?: {
|
|
59
|
+
profiles?: object;
|
|
60
|
+
now?: Date;
|
|
61
|
+
}): {
|
|
62
|
+
ok: true;
|
|
63
|
+
reused: boolean;
|
|
64
|
+
claim_id: string;
|
|
65
|
+
profile: string | null;
|
|
66
|
+
content_hash: string;
|
|
67
|
+
} | {
|
|
68
|
+
ok: false;
|
|
69
|
+
reason: string;
|
|
70
|
+
};
|
|
71
|
+
/**
|
|
72
|
+
* Fold the run's claim ledger from the append-only log — a SEPARATE fold parallel
|
|
73
|
+
* to `ledger.mjs::projectLedger` / `saga.mjs::projectSaga` (the roadmap projection
|
|
74
|
+
* still folds `produce.roadmap.*` ONLY, so claim ops never enter the roadmap the
|
|
75
|
+
* Showrunner re-reads). A `produce.claim.declared` seeds an ACTIVE claim (in
|
|
76
|
+
* first-seen order); a `produce.claim.expired` advances it to `expired`;
|
|
77
|
+
* `produce.claim.consumed` is a forensic-only event that does NOT change status.
|
|
78
|
+
* Deterministic — two folds of the same log yield the identical ledger.
|
|
79
|
+
*
|
|
80
|
+
* @param {string} projectDir
|
|
81
|
+
* @param {string} runId
|
|
82
|
+
* @returns {{
|
|
83
|
+
* run_id: string,
|
|
84
|
+
* claims: Array<{ claim_id: string, profile: string | null, content_hash: string | null, status: 'active' | 'expired' }>,
|
|
85
|
+
* active_count: number,
|
|
86
|
+
* expired_count: number,
|
|
87
|
+
* updated_at: string | null,
|
|
88
|
+
* }}
|
|
89
|
+
*/
|
|
90
|
+
export function projectClaims(projectDir: string, runId: string): {
|
|
91
|
+
run_id: string;
|
|
92
|
+
claims: Array<{
|
|
93
|
+
claim_id: string;
|
|
94
|
+
profile: string | null;
|
|
95
|
+
content_hash: string | null;
|
|
96
|
+
status: "active" | "expired";
|
|
97
|
+
}>;
|
|
98
|
+
active_count: number;
|
|
99
|
+
expired_count: number;
|
|
100
|
+
updated_at: string | null;
|
|
101
|
+
};
|
|
102
|
+
/**
|
|
103
|
+
* Decide whether a claim may be consumed against a ctx (ID-M6-04, anti-corrosion).
|
|
104
|
+
* DETERMINISTIC (no LLM). SKIPS with a reason when: the claim is time-expired
|
|
105
|
+
* (`now() > expiry.expires_at` → `expired`); the claim's `revalidate_against_head`
|
|
106
|
+
* check no longer matches HEAD (`headCheck(check) === false` → `head_invalidated`);
|
|
107
|
+
* or the preconditions don't match ctx (`precondition_unmatched`). Otherwise
|
|
108
|
+
* `{ consume: true }`. `now` + `headCheck` are INJECTED (default now = new Date,
|
|
109
|
+
* default headCheck = the working-tree path-exists/grep).
|
|
110
|
+
*
|
|
111
|
+
* @param {Record<string, unknown>} claim — the claim ENVELOPE (carries expiry + preconditions).
|
|
112
|
+
* @param {Record<string, unknown>} [ctx]
|
|
113
|
+
* @param {{ now?: () => Date, headCheck?: (check: unknown) => boolean }} [deps]
|
|
114
|
+
* @returns {{ consume: true } | { consume: false, reason: string }}
|
|
115
|
+
*/
|
|
116
|
+
export function evaluateClaimForConsumption(claim: Record<string, unknown>, ctx?: Record<string, unknown>, deps?: {
|
|
117
|
+
now?: () => Date;
|
|
118
|
+
headCheck?: (check: unknown) => boolean;
|
|
119
|
+
}): {
|
|
120
|
+
consume: true;
|
|
121
|
+
} | {
|
|
122
|
+
consume: false;
|
|
123
|
+
reason: string;
|
|
124
|
+
};
|
|
125
|
+
/**
|
|
126
|
+
* Consume the run's ACTIVE claims against a ctx (ID-M6-06 — THE M6 invariant).
|
|
127
|
+
* For each active claim, evaluate it; a consumable claim emits ONE bounded delta
|
|
128
|
+
* `{ claim_id, profile, targets: [{ kind, requirement, ref? }] }` where every
|
|
129
|
+
* `targets[].kind ∈ CLAIM_TARGET_KINDS` and `requirement` is derived FROM
|
|
130
|
+
* `resolution_verifier` — a projection DOWN. The output MUST NOT carry the claim's
|
|
131
|
+
* `provenance` / `negative_evidence` / `preconditions` / body (never a context
|
|
132
|
+
* paste). Skipped claims (expired / head_invalidated / precondition_unmatched /
|
|
133
|
+
* unreadable) surface under `skipped[]` with a reason. PURE — appends no event
|
|
134
|
+
* (the CLI records `produce.claim.consumed` per target for the forensic trail).
|
|
135
|
+
*
|
|
136
|
+
* @param {string} projectDir
|
|
137
|
+
* @param {string} runId
|
|
138
|
+
* @param {Record<string, unknown>} [ctx]
|
|
139
|
+
* @param {{ now?: () => Date, headCheck?: (check: unknown) => boolean }} [deps]
|
|
140
|
+
* @returns {{
|
|
141
|
+
* consumed: Array<{ claim_id: string, profile: string | null, targets: Array<{ kind: string, requirement: string, ref?: string }> }>,
|
|
142
|
+
* skipped: Array<{ claim_id: string, reason: string }>,
|
|
143
|
+
* }}
|
|
144
|
+
*/
|
|
145
|
+
export function consumeClaims(projectDir: string, runId: string, ctx?: Record<string, unknown>, deps?: {
|
|
146
|
+
now?: () => Date;
|
|
147
|
+
headCheck?: (check: unknown) => boolean;
|
|
148
|
+
}): {
|
|
149
|
+
consumed: Array<{
|
|
150
|
+
claim_id: string;
|
|
151
|
+
profile: string | null;
|
|
152
|
+
targets: Array<{
|
|
153
|
+
kind: string;
|
|
154
|
+
requirement: string;
|
|
155
|
+
ref?: string;
|
|
156
|
+
}>;
|
|
157
|
+
}>;
|
|
158
|
+
skipped: Array<{
|
|
159
|
+
claim_id: string;
|
|
160
|
+
reason: string;
|
|
161
|
+
}>;
|
|
162
|
+
};
|
|
163
|
+
export namespace CLAIM_PROFILES {
|
|
164
|
+
namespace lesson {
|
|
165
|
+
export let requiredFields: string[];
|
|
166
|
+
export { validateLessonEnvelope as validate };
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
/** The closed set of consumption-delta target kinds (mirrors ALLOWED_CLAIM_TARGET_KINDS). */
|
|
170
|
+
export const CLAIM_TARGET_KINDS: string[];
|
|
171
|
+
/**
|
|
172
|
+
* The `lesson` profile validator (ID-M6-03). REQUIRES all 6 AC15 fields and
|
|
173
|
+
* REJECTS fail-closed (never throws): missing provenance; empty preconditions
|
|
174
|
+
* (unconditional rule — bounded-critic clamp); global/unbounded scope
|
|
175
|
+
* (anti-windup); missing expiry (anti-corrosion); missing negative_evidence
|
|
176
|
+
* field; empty resolution_verifier. Returns `{ ok:false, reason }`.
|
|
177
|
+
*
|
|
178
|
+
* @param {Record<string, unknown>} env
|
|
179
|
+
* @returns {{ ok: true } | { ok: false, reason: string }}
|
|
180
|
+
*/
|
|
181
|
+
declare function validateLessonEnvelope(env: Record<string, unknown>): {
|
|
182
|
+
ok: true;
|
|
183
|
+
} | {
|
|
184
|
+
ok: false;
|
|
185
|
+
reason: string;
|
|
186
|
+
};
|
|
187
|
+
export {};
|
|
188
|
+
//# sourceMappingURL=claim.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claim.d.mts","sourceRoot":"","sources":["../../../src/cli/produce/claim.mjs"],"names":[],"mappings":"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"}
|