@aperant/framework 0.17.0 → 0.20.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 +261 -0
- package/agents/apt-executor.md +6 -0
- package/agents/apt-planner.md +3 -2
- package/bin/features-reconcile-check.mjs +77 -0
- package/dist/cli/artifacts/self-stage.d.mts.map +1 -1
- package/dist/cli/artifacts/self-stage.mjs +2 -1
- package/dist/cli/artifacts/self-stage.mjs.map +1 -1
- package/dist/cli/cli-wrappers/features-reconcile.d.mts +2 -0
- package/dist/cli/cli-wrappers/features-reconcile.d.mts.map +1 -0
- package/dist/cli/cli-wrappers/features-reconcile.mjs +9 -0
- package/dist/cli/cli-wrappers/features-reconcile.mjs.map +1 -0
- 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/features-reconcile.d.mts +2 -0
- package/dist/cli/commands/features-reconcile.d.mts.map +1 -0
- package/dist/cli/commands/features-reconcile.mjs +143 -0
- package/dist/cli/commands/features-reconcile.mjs.map +1 -0
- package/dist/cli/commands/health-check.d.mts +2 -2
- package/dist/cli/commands/health-check.mjs +2 -2
- 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/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/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 -2
- package/dist/cli/dispatch.mjs.map +1 -1
- package/dist/cli/features/area-shape.d.mts +11 -0
- package/dist/cli/features/area-shape.d.mts.map +1 -0
- package/dist/cli/features/area-shape.mjs +141 -0
- package/dist/cli/features/area-shape.mjs.map +1 -0
- package/dist/cli/features/delta.d.mts +78 -0
- package/dist/cli/features/delta.d.mts.map +1 -0
- package/dist/cli/features/delta.mjs +591 -0
- package/dist/cli/features/delta.mjs.map +1 -0
- package/dist/cli/features/reconcile.d.mts +236 -0
- package/dist/cli/features/reconcile.d.mts.map +1 -0
- package/dist/cli/features/reconcile.mjs +1126 -0
- package/dist/cli/features/reconcile.mjs.map +1 -0
- package/dist/cli/features/surface-map.d.mts +63 -0
- package/dist/cli/features/surface-map.d.mts.map +1 -0
- package/dist/cli/features/surface-map.mjs +191 -0
- package/dist/cli/features/surface-map.mjs.map +1 -0
- package/dist/cli/{commands/features-audit.d.mts → features/write-root.d.mts} +4 -3
- package/dist/cli/features/write-root.d.mts.map +1 -0
- package/dist/cli/features/write-root.mjs +137 -0
- package/dist/cli/features/write-root.mjs.map +1 -0
- package/dist/cli/gate/gates/features-reconciled.d.mts +36 -0
- package/dist/cli/gate/gates/features-reconciled.d.mts.map +1 -0
- package/dist/cli/gate/gates/features-reconciled.mjs +67 -0
- package/dist/cli/gate/gates/features-reconciled.mjs.map +1 -0
- package/dist/cli/gate/gates/index.mjs +1 -0
- package/dist/cli/gate/gates/index.mjs.map +1 -1
- package/dist/cli/help.d.mts.map +1 -1
- package/dist/cli/help.mjs +31 -1
- package/dist/cli/help.mjs.map +1 -1
- 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/release-notes/ship-autodraft.mjs +2 -2
- 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/variant/gallery.d.mts.map +1 -1
- package/dist/cli/variant/gallery.mjs +7 -3
- package/dist/cli/variant/gallery.mjs.map +1 -1
- package/dist/plugin/.claude-plugin/plugin.json +2 -1
- package/dist/plugin/agents/apt-executor.md +6 -0
- package/dist/plugin/agents/apt-planner.md +3 -2
- package/dist/plugin/skills/apt/SKILL.md +112 -38
- package/dist/plugin/skills/apt-close-task/SKILL.md +2 -2
- package/dist/plugin/skills/apt-debug/SKILL.md +22 -24
- package/dist/plugin/skills/apt-execute/SKILL.md +35 -26
- 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-mockup/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 +27 -33
- package/dist/plugin/skills/apt-review/SKILL.md +14 -11
- package/dist/plugin/skills/apt-run/SKILL.md +132 -3
- package/dist/plugin/skills/apt-ship/SKILL.md +29 -5
- package/dist/plugin/skills/apt-spar/SKILL.md +5 -3
- package/dist/plugin/skills/apt-watch-ci/SKILL.md +6 -4
- package/dist/schemas/feature-registry.d.ts.map +1 -1
- package/dist/schemas/feature-registry.js +34 -3
- package/dist/schemas/feature-registry.js.map +1 -1
- package/dist/types/config.d.ts +8 -5
- package/dist/types/config.d.ts.map +1 -1
- 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-close-task/SKILL.md +2 -2
- package/skills/apt-debug/SKILL.md +22 -24
- package/skills/apt-execute/SKILL.md +35 -26
- package/skills/apt-fan-out/SKILL.md +4 -4
- package/skills/apt-handoff/SKILL.md +1 -1
- package/skills/apt-mockup/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 +27 -33
- package/skills/apt-review/SKILL.md +14 -11
- package/skills/apt-run/SKILL.md +132 -3
- package/skills/apt-ship/SKILL.md +29 -5
- package/skills/apt-spar/SKILL.md +5 -3
- package/skills/apt-watch-ci/SKILL.md +6 -4
- package/src/cli/artifacts/self-stage.mjs +2 -1
- package/src/cli/cli-wrappers/features-reconcile.mjs +9 -0
- 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/features-reconcile.mjs +157 -0
- package/src/cli/commands/health-check.mjs +2 -2
- package/src/cli/commands/merge-integrate.mjs +3 -3
- package/src/cli/commands/produce.mjs +1466 -0
- package/src/cli/commands/task.mjs +482 -285
- 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 -2
- package/src/cli/features/area-shape.mjs +140 -0
- package/src/cli/features/delta.mjs +625 -0
- package/src/cli/features/reconcile.mjs +1169 -0
- package/src/cli/features/surface-map.mjs +192 -0
- package/src/cli/features/write-root.mjs +140 -0
- package/src/cli/gate/gates/features-reconciled.mjs +70 -0
- package/src/cli/gate/gates/index.mjs +1 -0
- package/src/cli/help.mjs +31 -1
- 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/release-notes/ship-autodraft.mjs +2 -2
- 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/variant/gallery.mjs +7 -3
- package/templates/aperant-claude-md-appendix.md +2 -2
- package/workflows/scan-features.md +17 -11
- package/dist/cli/cli-wrappers/features-audit.d.mts +0 -2
- package/dist/cli/cli-wrappers/features-audit.d.mts.map +0 -1
- package/dist/cli/cli-wrappers/features-audit.mjs +0 -8
- package/dist/cli/cli-wrappers/features-audit.mjs.map +0 -1
- package/dist/cli/commands/features-audit.d.mts.map +0 -1
- package/dist/cli/commands/features-audit.mjs +0 -293
- package/dist/cli/commands/features-audit.mjs.map +0 -1
- package/dist/cli/features/registry-audit.d.mts +0 -56
- package/dist/cli/features/registry-audit.d.mts.map +0 -1
- package/dist/cli/features/registry-audit.mjs +0 -264
- package/dist/cli/features/registry-audit.mjs.map +0 -1
- package/dist/cli/roadmap/conductor-view.d.mts.map +0 -1
- package/dist/cli/roadmap/conductor-view.mjs.map +0 -1
- package/src/cli/cli-wrappers/features-audit.mjs +0 -8
- package/src/cli/commands/features-audit.mjs +0 -302
- package/src/cli/features/registry-audit.mjs +0 -254
- package/src/cli/roadmap/conductor-view.d.ts +0 -10
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fold the run's acceptance-criteria ledger from the append-only log. A
|
|
3
|
+
* `produce.criteria.declared` seeds an OPEN criterion (in first-seen order); a
|
|
4
|
+
* `produce.criteria.closed` advances it to `closed`; `produce.scope.changed` is
|
|
5
|
+
* recorded on the scope-change trail. Deterministic — two folds of the same log
|
|
6
|
+
* yield the identical ledger; `updated_at` is the last folded event's timestamp.
|
|
7
|
+
*
|
|
8
|
+
* @param {string} projectDir
|
|
9
|
+
* @param {string} runId
|
|
10
|
+
* @returns {{
|
|
11
|
+
* run_id: string,
|
|
12
|
+
* criteria: Array<{ criterion_id: string, milestone_id: string | null, text: string, status: 'open' | 'closed' }>,
|
|
13
|
+
* open_count: number,
|
|
14
|
+
* closed_count: number,
|
|
15
|
+
* scope_changes: Array<{ reason: string, milestone_id: string | null, t: string | null }>,
|
|
16
|
+
* updated_at: string | null,
|
|
17
|
+
* }}
|
|
18
|
+
*/
|
|
19
|
+
export function projectLedger(projectDir: string, runId: string): {
|
|
20
|
+
run_id: string;
|
|
21
|
+
criteria: Array<{
|
|
22
|
+
criterion_id: string;
|
|
23
|
+
milestone_id: string | null;
|
|
24
|
+
text: string;
|
|
25
|
+
status: "open" | "closed";
|
|
26
|
+
}>;
|
|
27
|
+
open_count: number;
|
|
28
|
+
closed_count: number;
|
|
29
|
+
scope_changes: Array<{
|
|
30
|
+
reason: string;
|
|
31
|
+
milestone_id: string | null;
|
|
32
|
+
t: string | null;
|
|
33
|
+
}>;
|
|
34
|
+
updated_at: string | null;
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* V = open acceptance criteria = declared − closed, folded from the log.
|
|
38
|
+
*
|
|
39
|
+
* @param {string} projectDir
|
|
40
|
+
* @param {string} runId
|
|
41
|
+
* @returns {number}
|
|
42
|
+
*/
|
|
43
|
+
export function computeOpenCriteria(projectDir: string, runId: string): number;
|
|
44
|
+
/**
|
|
45
|
+
* The write-time anti-windup guard (ID-M3-03). `declare-criteria` raises V; it is
|
|
46
|
+
* REJECTED when the run is IN DESCENT (≥1 `produce.criteria.closed` already
|
|
47
|
+
* logged) AND no scope-change is supplied. Before descent, declaration is FREE
|
|
48
|
+
* (the baseline scope-definition window). This is the ONLY hard Lyapunov
|
|
49
|
+
* enforcement and it is fail-closed.
|
|
50
|
+
*
|
|
51
|
+
* @param {string} projectDir
|
|
52
|
+
* @param {string} runId
|
|
53
|
+
* @param {{ hasScopeChange?: boolean }} [opts]
|
|
54
|
+
* @returns {{ allowed: boolean, reason: string, in_descent: boolean }}
|
|
55
|
+
*/
|
|
56
|
+
export function evaluateDeclareGuard(projectDir: string, runId: string, { hasScopeChange }?: {
|
|
57
|
+
hasScopeChange?: boolean;
|
|
58
|
+
}): {
|
|
59
|
+
allowed: boolean;
|
|
60
|
+
reason: string;
|
|
61
|
+
in_descent: boolean;
|
|
62
|
+
};
|
|
63
|
+
/**
|
|
64
|
+
* Compute the monotone-progress report (ID-M3-02 / AC6). Folds ALL of
|
|
65
|
+
* `produce.criteria.*` + `produce.scope.changed` +
|
|
66
|
+
* `produce.roadmap.milestone_status_changed` in append order, maintaining the
|
|
67
|
+
* running V. Every `milestone_status_changed{status:'done'}` is a checkpoint: it
|
|
68
|
+
* captures `v_before`, then consumes the contiguous run of `criteria.closed`
|
|
69
|
+
* events that ship triggered (appended immediately after the done event) to
|
|
70
|
+
* capture `v_after`. `delta = v_after − v_before` (≤ 0). The series is STRICTLY
|
|
71
|
+
* DECREASING iff every ship checkpoint had `delta < 0`; a flat ship (delta === 0)
|
|
72
|
+
* is a soft STALL, not a hard violation.
|
|
73
|
+
*
|
|
74
|
+
* Read-time defense (ID-M3-03): a `produce.criteria.declared` that raised V
|
|
75
|
+
* AFTER descent WITHOUT an accompanying (immediately-preceding)
|
|
76
|
+
* `produce.scope.changed` is a HARD `lyapunov_violation`. `progress` FLAGS — it
|
|
77
|
+
* never rejects (the rejection is the write-time guard).
|
|
78
|
+
*
|
|
79
|
+
* @param {string} projectDir
|
|
80
|
+
* @param {string} runId
|
|
81
|
+
* @returns {{
|
|
82
|
+
* run_id: string,
|
|
83
|
+
* v_open_now: number,
|
|
84
|
+
* v_series: Array<{ milestone_id: string | null, v_before: number, v_after: number, delta: number, decreased: boolean }>,
|
|
85
|
+
* strictly_decreasing: boolean,
|
|
86
|
+
* lyapunov_ok: boolean,
|
|
87
|
+
* lyapunov_violations: Array<{ criterion_id: string | null, milestone_id: string | null, reason: string, t: string | null }>,
|
|
88
|
+
* scope_changes: Array<{ reason: string, milestone_id: string | null, t: string | null }>,
|
|
89
|
+
* }}
|
|
90
|
+
*/
|
|
91
|
+
export function computeProgress(projectDir: string, runId: string): {
|
|
92
|
+
run_id: string;
|
|
93
|
+
v_open_now: number;
|
|
94
|
+
v_series: Array<{
|
|
95
|
+
milestone_id: string | null;
|
|
96
|
+
v_before: number;
|
|
97
|
+
v_after: number;
|
|
98
|
+
delta: number;
|
|
99
|
+
decreased: boolean;
|
|
100
|
+
}>;
|
|
101
|
+
strictly_decreasing: boolean;
|
|
102
|
+
lyapunov_ok: boolean;
|
|
103
|
+
lyapunov_violations: Array<{
|
|
104
|
+
criterion_id: string | null;
|
|
105
|
+
milestone_id: string | null;
|
|
106
|
+
reason: string;
|
|
107
|
+
t: string | null;
|
|
108
|
+
}>;
|
|
109
|
+
scope_changes: Array<{
|
|
110
|
+
reason: string;
|
|
111
|
+
milestone_id: string | null;
|
|
112
|
+
t: string | null;
|
|
113
|
+
}>;
|
|
114
|
+
};
|
|
115
|
+
/**
|
|
116
|
+
* Close a shipped milestone's still-open acceptance criteria — the CONSEQUENCE
|
|
117
|
+
* of a milestone flipping to `done` (ID-M3-05, wired additively in
|
|
118
|
+
* `cmdSetMilestoneDone`). Folds the ledger, finds the milestone's OPEN criteria,
|
|
119
|
+
* and appends one `produce.criteria.closed` per criterion so V strictly
|
|
120
|
+
* decreases. Idempotent — an already-closed (or criteria-less) milestone appends
|
|
121
|
+
* nothing (`closed_count: 0`), so a criteria-less ship is byte-identical to M2.
|
|
122
|
+
*
|
|
123
|
+
* @param {string} projectDir
|
|
124
|
+
* @param {string} runId
|
|
125
|
+
* @param {string} milestoneId
|
|
126
|
+
* @returns {{ closed_count: number, criterion_ids: string[] }}
|
|
127
|
+
*/
|
|
128
|
+
export function closeCriteriaForShippedMilestone(projectDir: string, runId: string, milestoneId: string): {
|
|
129
|
+
closed_count: number;
|
|
130
|
+
criterion_ids: string[];
|
|
131
|
+
};
|
|
132
|
+
/**
|
|
133
|
+
* Mint a criterion id: `<slug-of-text>-<rand>`. Reuses `slugFromOutcome` and a
|
|
134
|
+
* short random suffix so two criteria minted from the same text never collide.
|
|
135
|
+
*
|
|
136
|
+
* @param {string} text
|
|
137
|
+
* @returns {string}
|
|
138
|
+
*/
|
|
139
|
+
export function mintCriterionId(text: string): string;
|
|
140
|
+
//# sourceMappingURL=ledger.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ledger.d.mts","sourceRoot":"","sources":["../../../src/cli/produce/ledger.mjs"],"names":[],"mappings":"AAyBA;;;;;;;;;;;;;;;;;GAiBG;AACH,0CAXW,MAAM,SACN,MAAM,GACJ;IACR,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,KAAK,CAAC;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,GAAG,QAAQ,CAAA;KAAE,CAAC,CAAC;IAChH,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,KAAK,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC,CAAC;IACxF,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B,CA4CH;AAED;;;;;;GAMG;AACH,gDAJW,MAAM,SACN,MAAM,GACJ,MAAM,CAIlB;AAED;;;;;;;;;;;GAWG;AACH,iDALW,MAAM,SACN,MAAM,uBACN;IAAE,cAAc,CAAC,EAAE,OAAO,CAAA;CAAE,GAC1B;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,OAAO,CAAA;CAAE,CAerE;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,4CAZW,MAAM,SACN,MAAM,GACJ;IACR,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,KAAK,CAAC;QAAE,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IACvH,mBAAmB,EAAE,OAAO,CAAC;IAC7B,WAAW,EAAE,OAAO,CAAC;IACrB,mBAAmB,EAAE,KAAK,CAAC;QAAE,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC,CAAC;IAC3H,aAAa,EAAE,KAAK,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC,CAAC;CACzF,CA6FH;AAED;;;;;;;;;;;;GAYG;AACH,6DALW,MAAM,SACN,MAAM,eACN,MAAM,GACJ;IAAE,YAAY,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,EAAE,CAAA;CAAE,CAe7D;AAED;;;;;;GAMG;AACH,sCAHW,MAAM,GACJ,MAAM,CAIlB"}
|
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @internal
|
|
3
|
+
* produce/ledger.mjs — the acceptance-criteria ledger + Lyapunov math (M3).
|
|
4
|
+
*
|
|
5
|
+
* V (the Lyapunov function) = open acceptance criteria = declared − closed,
|
|
6
|
+
* folded from the append-only log on every read (ID-M3-01 / ID-M3-02). Each
|
|
7
|
+
* criterion is a `produce.criteria.declared` event bound to a milestone; it
|
|
8
|
+
* closes via `produce.criteria.closed`. `produce.scope.changed` is the ONLY
|
|
9
|
+
* sanctioned way V may rise after the run has begun closing criteria (ID-M3-04).
|
|
10
|
+
*
|
|
11
|
+
* This module is a SEPARATE fold parallel to `projection.mjs` — the roadmap
|
|
12
|
+
* projection still folds `produce.roadmap.*` ONLY, so criteria/scope events
|
|
13
|
+
* never enter the roadmap the Showrunner re-reads (the M1/M2 blindness invariant
|
|
14
|
+
* is preserved). It reads ONLY the event log through `events.mjs` (no `node:`
|
|
15
|
+
* beyond what events.mjs already uses) and holds NO model id (it is pure math).
|
|
16
|
+
*/
|
|
17
|
+
import { appendProduceEvent, readProduceRunEventsMatching } from './events.mjs';
|
|
18
|
+
import { slugFromOutcome } from './run-id.mjs';
|
|
19
|
+
/** The op-match for the criteria + scope ledger fold (never `produce.roadmap.*`). */
|
|
20
|
+
function isLedgerOp(op) {
|
|
21
|
+
return op.startsWith('produce.criteria.') || op === 'produce.scope.changed';
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Fold the run's acceptance-criteria ledger from the append-only log. A
|
|
25
|
+
* `produce.criteria.declared` seeds an OPEN criterion (in first-seen order); a
|
|
26
|
+
* `produce.criteria.closed` advances it to `closed`; `produce.scope.changed` is
|
|
27
|
+
* recorded on the scope-change trail. Deterministic — two folds of the same log
|
|
28
|
+
* yield the identical ledger; `updated_at` is the last folded event's timestamp.
|
|
29
|
+
*
|
|
30
|
+
* @param {string} projectDir
|
|
31
|
+
* @param {string} runId
|
|
32
|
+
* @returns {{
|
|
33
|
+
* run_id: string,
|
|
34
|
+
* criteria: Array<{ criterion_id: string, milestone_id: string | null, text: string, status: 'open' | 'closed' }>,
|
|
35
|
+
* open_count: number,
|
|
36
|
+
* closed_count: number,
|
|
37
|
+
* scope_changes: Array<{ reason: string, milestone_id: string | null, t: string | null }>,
|
|
38
|
+
* updated_at: string | null,
|
|
39
|
+
* }}
|
|
40
|
+
*/
|
|
41
|
+
export function projectLedger(projectDir, runId) {
|
|
42
|
+
const events = readProduceRunEventsMatching(projectDir, runId, isLedgerOp);
|
|
43
|
+
const byId = new Map();
|
|
44
|
+
const order = [];
|
|
45
|
+
const scopeChanges = [];
|
|
46
|
+
let updatedAt = null;
|
|
47
|
+
for (const e of events) {
|
|
48
|
+
const d = e.data || {};
|
|
49
|
+
if (e.op === 'produce.criteria.declared') {
|
|
50
|
+
const cid = typeof d.criterion_id === 'string' ? d.criterion_id : null;
|
|
51
|
+
if (cid && !byId.has(cid)) {
|
|
52
|
+
byId.set(cid, {
|
|
53
|
+
criterion_id: cid,
|
|
54
|
+
milestone_id: typeof d.milestone_id === 'string' ? d.milestone_id : null,
|
|
55
|
+
text: typeof d.text === 'string' ? d.text : '',
|
|
56
|
+
status: 'open',
|
|
57
|
+
});
|
|
58
|
+
order.push(cid);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
else if (e.op === 'produce.criteria.closed') {
|
|
62
|
+
const cid = typeof d.criterion_id === 'string' ? d.criterion_id : null;
|
|
63
|
+
if (cid && byId.has(cid))
|
|
64
|
+
byId.get(cid).status = 'closed';
|
|
65
|
+
}
|
|
66
|
+
else if (e.op === 'produce.scope.changed') {
|
|
67
|
+
scopeChanges.push({
|
|
68
|
+
reason: typeof d.reason === 'string' ? d.reason : '',
|
|
69
|
+
milestone_id: typeof d.milestone_id === 'string' ? d.milestone_id : null,
|
|
70
|
+
t: typeof e.t === 'string' ? e.t : null,
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
if (typeof e.t === 'string')
|
|
74
|
+
updatedAt = e.t;
|
|
75
|
+
}
|
|
76
|
+
const criteria = order.map((cid) => byId.get(cid));
|
|
77
|
+
return {
|
|
78
|
+
run_id: runId,
|
|
79
|
+
criteria,
|
|
80
|
+
open_count: criteria.filter((c) => c.status === 'open').length,
|
|
81
|
+
closed_count: criteria.filter((c) => c.status === 'closed').length,
|
|
82
|
+
scope_changes: scopeChanges,
|
|
83
|
+
updated_at: updatedAt,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* V = open acceptance criteria = declared − closed, folded from the log.
|
|
88
|
+
*
|
|
89
|
+
* @param {string} projectDir
|
|
90
|
+
* @param {string} runId
|
|
91
|
+
* @returns {number}
|
|
92
|
+
*/
|
|
93
|
+
export function computeOpenCriteria(projectDir, runId) {
|
|
94
|
+
return projectLedger(projectDir, runId).open_count;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* The write-time anti-windup guard (ID-M3-03). `declare-criteria` raises V; it is
|
|
98
|
+
* REJECTED when the run is IN DESCENT (≥1 `produce.criteria.closed` already
|
|
99
|
+
* logged) AND no scope-change is supplied. Before descent, declaration is FREE
|
|
100
|
+
* (the baseline scope-definition window). This is the ONLY hard Lyapunov
|
|
101
|
+
* enforcement and it is fail-closed.
|
|
102
|
+
*
|
|
103
|
+
* @param {string} projectDir
|
|
104
|
+
* @param {string} runId
|
|
105
|
+
* @param {{ hasScopeChange?: boolean }} [opts]
|
|
106
|
+
* @returns {{ allowed: boolean, reason: string, in_descent: boolean }}
|
|
107
|
+
*/
|
|
108
|
+
export function evaluateDeclareGuard(projectDir, runId, { hasScopeChange = false } = {}) {
|
|
109
|
+
const closes = readProduceRunEventsMatching(projectDir, runId, (op) => op === 'produce.criteria.closed');
|
|
110
|
+
const inDescent = closes.length > 0;
|
|
111
|
+
const allowed = !inDescent || !!hasScopeChange;
|
|
112
|
+
let reason;
|
|
113
|
+
if (!allowed)
|
|
114
|
+
reason = 'in_descent_no_scope_change';
|
|
115
|
+
else if (!inDescent)
|
|
116
|
+
reason = 'baseline_window';
|
|
117
|
+
else
|
|
118
|
+
reason = 'scope_change';
|
|
119
|
+
return { allowed, reason, in_descent: inDescent };
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Compute the monotone-progress report (ID-M3-02 / AC6). Folds ALL of
|
|
123
|
+
* `produce.criteria.*` + `produce.scope.changed` +
|
|
124
|
+
* `produce.roadmap.milestone_status_changed` in append order, maintaining the
|
|
125
|
+
* running V. Every `milestone_status_changed{status:'done'}` is a checkpoint: it
|
|
126
|
+
* captures `v_before`, then consumes the contiguous run of `criteria.closed`
|
|
127
|
+
* events that ship triggered (appended immediately after the done event) to
|
|
128
|
+
* capture `v_after`. `delta = v_after − v_before` (≤ 0). The series is STRICTLY
|
|
129
|
+
* DECREASING iff every ship checkpoint had `delta < 0`; a flat ship (delta === 0)
|
|
130
|
+
* is a soft STALL, not a hard violation.
|
|
131
|
+
*
|
|
132
|
+
* Read-time defense (ID-M3-03): a `produce.criteria.declared` that raised V
|
|
133
|
+
* AFTER descent WITHOUT an accompanying (immediately-preceding)
|
|
134
|
+
* `produce.scope.changed` is a HARD `lyapunov_violation`. `progress` FLAGS — it
|
|
135
|
+
* never rejects (the rejection is the write-time guard).
|
|
136
|
+
*
|
|
137
|
+
* @param {string} projectDir
|
|
138
|
+
* @param {string} runId
|
|
139
|
+
* @returns {{
|
|
140
|
+
* run_id: string,
|
|
141
|
+
* v_open_now: number,
|
|
142
|
+
* v_series: Array<{ milestone_id: string | null, v_before: number, v_after: number, delta: number, decreased: boolean }>,
|
|
143
|
+
* strictly_decreasing: boolean,
|
|
144
|
+
* lyapunov_ok: boolean,
|
|
145
|
+
* lyapunov_violations: Array<{ criterion_id: string | null, milestone_id: string | null, reason: string, t: string | null }>,
|
|
146
|
+
* scope_changes: Array<{ reason: string, milestone_id: string | null, t: string | null }>,
|
|
147
|
+
* }}
|
|
148
|
+
*/
|
|
149
|
+
export function computeProgress(projectDir, runId) {
|
|
150
|
+
const events = readProduceRunEventsMatching(projectDir, runId, (op) => op.startsWith('produce.criteria.') ||
|
|
151
|
+
op === 'produce.scope.changed' ||
|
|
152
|
+
op === 'produce.roadmap.milestone_status_changed');
|
|
153
|
+
const status = new Map();
|
|
154
|
+
let v = 0;
|
|
155
|
+
let inDescent = false;
|
|
156
|
+
const vSeries = [];
|
|
157
|
+
const violations = [];
|
|
158
|
+
const scopeChanges = [];
|
|
159
|
+
/** Apply a `criteria.closed` payload to V (idempotent; sets inDescent). */
|
|
160
|
+
const applyClose = (d) => {
|
|
161
|
+
const cid = typeof d.criterion_id === 'string' ? d.criterion_id : null;
|
|
162
|
+
if (cid && status.get(cid) === 'open') {
|
|
163
|
+
status.set(cid, 'closed');
|
|
164
|
+
v -= 1;
|
|
165
|
+
}
|
|
166
|
+
else if (cid && !status.has(cid)) {
|
|
167
|
+
// Close of a never-declared criterion — record the state, no V change.
|
|
168
|
+
status.set(cid, 'closed');
|
|
169
|
+
}
|
|
170
|
+
inDescent = true;
|
|
171
|
+
};
|
|
172
|
+
for (let i = 0; i < events.length; i++) {
|
|
173
|
+
const e = events[i];
|
|
174
|
+
const d = e.data || {};
|
|
175
|
+
if (e.op === 'produce.criteria.declared') {
|
|
176
|
+
if (inDescent) {
|
|
177
|
+
const prev = i > 0 ? events[i - 1] : null;
|
|
178
|
+
const accompanied = !!prev && prev.op === 'produce.scope.changed';
|
|
179
|
+
if (!accompanied) {
|
|
180
|
+
violations.push({
|
|
181
|
+
criterion_id: typeof d.criterion_id === 'string' ? d.criterion_id : null,
|
|
182
|
+
milestone_id: typeof d.milestone_id === 'string' ? d.milestone_id : null,
|
|
183
|
+
reason: 'declared_after_descent_without_scope_change',
|
|
184
|
+
t: typeof e.t === 'string' ? e.t : null,
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
const cid = typeof d.criterion_id === 'string' ? d.criterion_id : null;
|
|
189
|
+
if (cid && !status.has(cid)) {
|
|
190
|
+
status.set(cid, 'open');
|
|
191
|
+
v += 1;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
else if (e.op === 'produce.criteria.closed') {
|
|
195
|
+
applyClose(d);
|
|
196
|
+
}
|
|
197
|
+
else if (e.op === 'produce.scope.changed') {
|
|
198
|
+
scopeChanges.push({
|
|
199
|
+
reason: typeof d.reason === 'string' ? d.reason : '',
|
|
200
|
+
milestone_id: typeof d.milestone_id === 'string' ? d.milestone_id : null,
|
|
201
|
+
t: typeof e.t === 'string' ? e.t : null,
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
else if (e.op === 'produce.roadmap.milestone_status_changed' && d.status === 'done') {
|
|
205
|
+
const vBefore = v;
|
|
206
|
+
// Consume the contiguous run of criteria.closed this ship triggered
|
|
207
|
+
// (the real flow appends them immediately after the done event).
|
|
208
|
+
let j = i + 1;
|
|
209
|
+
while (j < events.length && events[j].op === 'produce.criteria.closed') {
|
|
210
|
+
applyClose(events[j].data || {});
|
|
211
|
+
j++;
|
|
212
|
+
}
|
|
213
|
+
i = j - 1;
|
|
214
|
+
const vAfter = v;
|
|
215
|
+
const delta = vAfter - vBefore;
|
|
216
|
+
vSeries.push({
|
|
217
|
+
milestone_id: typeof d.milestone_id === 'string' ? d.milestone_id : null,
|
|
218
|
+
v_before: vBefore,
|
|
219
|
+
v_after: vAfter,
|
|
220
|
+
delta,
|
|
221
|
+
decreased: delta < 0,
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
return {
|
|
226
|
+
run_id: runId,
|
|
227
|
+
v_open_now: v,
|
|
228
|
+
v_series: vSeries,
|
|
229
|
+
strictly_decreasing: vSeries.every((s) => s.delta < 0),
|
|
230
|
+
lyapunov_ok: violations.length === 0,
|
|
231
|
+
lyapunov_violations: violations,
|
|
232
|
+
scope_changes: scopeChanges,
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Close a shipped milestone's still-open acceptance criteria — the CONSEQUENCE
|
|
237
|
+
* of a milestone flipping to `done` (ID-M3-05, wired additively in
|
|
238
|
+
* `cmdSetMilestoneDone`). Folds the ledger, finds the milestone's OPEN criteria,
|
|
239
|
+
* and appends one `produce.criteria.closed` per criterion so V strictly
|
|
240
|
+
* decreases. Idempotent — an already-closed (or criteria-less) milestone appends
|
|
241
|
+
* nothing (`closed_count: 0`), so a criteria-less ship is byte-identical to M2.
|
|
242
|
+
*
|
|
243
|
+
* @param {string} projectDir
|
|
244
|
+
* @param {string} runId
|
|
245
|
+
* @param {string} milestoneId
|
|
246
|
+
* @returns {{ closed_count: number, criterion_ids: string[] }}
|
|
247
|
+
*/
|
|
248
|
+
export function closeCriteriaForShippedMilestone(projectDir, runId, milestoneId) {
|
|
249
|
+
const ledger = projectLedger(projectDir, runId);
|
|
250
|
+
const open = ledger.criteria.filter((c) => c.milestone_id === milestoneId && c.status === 'open');
|
|
251
|
+
const criterionIds = [];
|
|
252
|
+
for (const c of open) {
|
|
253
|
+
appendProduceEvent(projectDir, 'produce.criteria.closed', {
|
|
254
|
+
run_id: runId,
|
|
255
|
+
milestone_id: milestoneId,
|
|
256
|
+
criterion_id: c.criterion_id,
|
|
257
|
+
});
|
|
258
|
+
criterionIds.push(c.criterion_id);
|
|
259
|
+
}
|
|
260
|
+
return { closed_count: criterionIds.length, criterion_ids: criterionIds };
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Mint a criterion id: `<slug-of-text>-<rand>`. Reuses `slugFromOutcome` and a
|
|
264
|
+
* short random suffix so two criteria minted from the same text never collide.
|
|
265
|
+
*
|
|
266
|
+
* @param {string} text
|
|
267
|
+
* @returns {string}
|
|
268
|
+
*/
|
|
269
|
+
export function mintCriterionId(text) {
|
|
270
|
+
return `${slugFromOutcome(text)}-${Math.random().toString(36).slice(2, 8)}`;
|
|
271
|
+
}
|
|
272
|
+
//# sourceMappingURL=ledger.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ledger.mjs","sourceRoot":"","sources":["../../../src/cli/produce/ledger.mjs"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Normalize a provider/CLI family alias to one of KNOWN_FAMILIES. Returns null
|
|
3
|
+
* for an unrecognized family so it is excluded from selection (fail-closed).
|
|
4
|
+
*
|
|
5
|
+
* @param {unknown} family
|
|
6
|
+
* @returns {string | null}
|
|
7
|
+
*/
|
|
8
|
+
export function normalizeFamily(family: unknown): string | null;
|
|
9
|
+
/**
|
|
10
|
+
* Resolve the probe/oracle family + LIVE model for a produce run.
|
|
11
|
+
*
|
|
12
|
+
* @param {{
|
|
13
|
+
* implementerFamily: string,
|
|
14
|
+
* hostFamily?: string | null,
|
|
15
|
+
* availableFamilies?: string[],
|
|
16
|
+
* codexDeps?: { home: string, existsSync: (p: string) => boolean, readFileSync: (p: string, enc: string) => string },
|
|
17
|
+
* }} args
|
|
18
|
+
* @returns {{
|
|
19
|
+
* available: boolean,
|
|
20
|
+
* probe_family: string | null,
|
|
21
|
+
* transport_hint: { prefer_self_resolving: boolean, recommended_walk: string[] } | null,
|
|
22
|
+
* model: string | null,
|
|
23
|
+
* source: string | null,
|
|
24
|
+
* reason: string | null,
|
|
25
|
+
* }}
|
|
26
|
+
*/
|
|
27
|
+
export function resolveProbeFamily({ implementerFamily, hostFamily, availableFamilies, codexDeps, }?: {
|
|
28
|
+
implementerFamily: string;
|
|
29
|
+
hostFamily?: string | null;
|
|
30
|
+
availableFamilies?: string[];
|
|
31
|
+
codexDeps?: {
|
|
32
|
+
home: string;
|
|
33
|
+
existsSync: (p: string) => boolean;
|
|
34
|
+
readFileSync: (p: string, enc: string) => string;
|
|
35
|
+
};
|
|
36
|
+
}): {
|
|
37
|
+
available: boolean;
|
|
38
|
+
probe_family: string | null;
|
|
39
|
+
transport_hint: {
|
|
40
|
+
prefer_self_resolving: boolean;
|
|
41
|
+
recommended_walk: string[];
|
|
42
|
+
} | null;
|
|
43
|
+
model: string | null;
|
|
44
|
+
source: string | null;
|
|
45
|
+
reason: string | null;
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* The provider families M2 selects across — the same three apt:spar supports.
|
|
49
|
+
* Ordered for a deterministic tiebreak when the partner-map default is not in
|
|
50
|
+
* the available pool.
|
|
51
|
+
*/
|
|
52
|
+
export const KNOWN_FAMILIES: string[];
|
|
53
|
+
//# sourceMappingURL=probe-family.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"probe-family.d.mts","sourceRoot":"","sources":["../../../src/cli/produce/probe-family.mjs"],"names":[],"mappings":"AA6CA;;;;;;GAMG;AACH,wCAHW,OAAO,GACL,MAAM,GAAG,IAAI,CASzB;AA8BD;;;;;;;;;;;;;;;;;GAiBG;AACH,sGAfW;IACN,iBAAiB,EAAE,MAAM,CAAC;IAC1B,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC7B,SAAS,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC;QAAC,YAAY,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,MAAM,CAAA;KAAE,CAAC;CACpH,GACS;IACR,SAAS,EAAE,OAAO,CAAC;IACnB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,cAAc,EAAE;QAAE,qBAAqB,EAAE,OAAO,CAAC;QAAC,gBAAgB,EAAE,MAAM,EAAE,CAAA;KAAE,GAAG,IAAI,CAAC;IACtF,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB,CA8DH;AA5ID;;;;GAIG;AACH,sCAA2D"}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @internal
|
|
3
|
+
* produce/probe-family.mjs — resolve a probe/oracle provider family DISJOINT
|
|
4
|
+
* from the implementer's, reusing the apt-spar cross-family mechanism (M2,
|
|
5
|
+
* ID-M2-01).
|
|
6
|
+
*
|
|
7
|
+
* The framework already selects + dispatches a different provider family in
|
|
8
|
+
* `apt:spar`: `host-detect` returns the current family, a partner-map picks a
|
|
9
|
+
* different one, and `spar-resolve-partner` resolves the partner's model LIVE
|
|
10
|
+
* from the user's own CLI config with ZERO baked default. M2 does NOT invent a
|
|
11
|
+
* second cross-family path — this module consumes the SAME `resolveCodexSparModel`
|
|
12
|
+
* primitive + the same partner-map shape and adds exactly ONE new rule: the
|
|
13
|
+
* resolved probe/oracle family must be DISJOINT from the *implementer* family
|
|
14
|
+
* (not merely "≠ host").
|
|
15
|
+
*
|
|
16
|
+
* Provider is an OUTPUT of selection; Aperant NEVER holds a model id (CLAUDE.md
|
|
17
|
+
* resolver rule / ID-M2-07). For codex the live model comes from
|
|
18
|
+
* `~/.codex/config.toml`; claude / gemini self-resolve (`model: null`). A
|
|
19
|
+
* setup where no disjoint family exists (host = implementer = only CLI) returns
|
|
20
|
+
* `available: false` fail-closed — a single-family setup cannot satisfy the
|
|
21
|
+
* cross-family rule by design.
|
|
22
|
+
*/
|
|
23
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
24
|
+
import { homedir } from 'node:os';
|
|
25
|
+
import { resolveCodexSparModel } from '../host/codex-config.mjs';
|
|
26
|
+
/**
|
|
27
|
+
* The provider families M2 selects across — the same three apt:spar supports.
|
|
28
|
+
* Ordered for a deterministic tiebreak when the partner-map default is not in
|
|
29
|
+
* the available pool.
|
|
30
|
+
*/
|
|
31
|
+
export const KNOWN_FAMILIES = ['claude', 'codex', 'gemini'];
|
|
32
|
+
/**
|
|
33
|
+
* The apt-spar §3 partner-map shape: each family's natural cross-family partner.
|
|
34
|
+
* Consulted as a PREFERENCE only — the disjoint + available + non-host rules
|
|
35
|
+
* decide the final pick; this just orders ties the way spar does.
|
|
36
|
+
*/
|
|
37
|
+
const PARTNER_MAP = {
|
|
38
|
+
claude: 'codex',
|
|
39
|
+
codex: 'claude',
|
|
40
|
+
gemini: 'codex',
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* Normalize a provider/CLI family alias to one of KNOWN_FAMILIES. Returns null
|
|
44
|
+
* for an unrecognized family so it is excluded from selection (fail-closed).
|
|
45
|
+
*
|
|
46
|
+
* @param {unknown} family
|
|
47
|
+
* @returns {string | null}
|
|
48
|
+
*/
|
|
49
|
+
export function normalizeFamily(family) {
|
|
50
|
+
if (typeof family !== 'string')
|
|
51
|
+
return null;
|
|
52
|
+
const f = family.trim().toLowerCase();
|
|
53
|
+
if (f === 'claude' || f === 'claude-code' || f === 'anthropic')
|
|
54
|
+
return 'claude';
|
|
55
|
+
if (f === 'codex' || f === 'openai' || f === 'gpt')
|
|
56
|
+
return 'codex';
|
|
57
|
+
if (f === 'gemini' || f === 'google')
|
|
58
|
+
return 'gemini';
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Pick the probe/oracle family: disjoint from the implementer (the ONE new
|
|
63
|
+
* rule), preferring a family that is ALSO not the host (a genuine third party),
|
|
64
|
+
* then honoring the apt-spar partner-map default, then a deterministic order.
|
|
65
|
+
*
|
|
66
|
+
* @param {string} implementerFamily — normalized implementer family.
|
|
67
|
+
* @param {string | null} hostFamily — normalized host family (or null).
|
|
68
|
+
* @param {string[]} normalizedAvailable — normalized available families.
|
|
69
|
+
* @returns {{ family: string | null, reason: string | null }}
|
|
70
|
+
*/
|
|
71
|
+
function pickProbeFamily(implementerFamily, hostFamily, normalizedAvailable) {
|
|
72
|
+
// The ONE new constraint over apt-spar: DISJOINT from the implementer.
|
|
73
|
+
const disjoint = normalizedAvailable.filter((f) => f !== implementerFamily);
|
|
74
|
+
if (disjoint.length === 0)
|
|
75
|
+
return { family: null, reason: 'no_disjoint_family' };
|
|
76
|
+
// Prefer a disjoint family that is ALSO not the host — a genuine third-party
|
|
77
|
+
// reviewer. Fall back to a disjoint-but-host family only if that is all
|
|
78
|
+
// that's available (still satisfies the cross-family rule, which is about the
|
|
79
|
+
// implementer, not the host).
|
|
80
|
+
const nonHost = disjoint.filter((f) => f !== hostFamily);
|
|
81
|
+
const pool = nonHost.length > 0 ? nonHost : disjoint;
|
|
82
|
+
// Honor the partner-map default when it is in the pool (apt-spar §3 shape).
|
|
83
|
+
const preferred = PARTNER_MAP[implementerFamily];
|
|
84
|
+
if (preferred && pool.includes(preferred))
|
|
85
|
+
return { family: preferred, reason: null };
|
|
86
|
+
// Deterministic tiebreak: first in KNOWN_FAMILIES order present in the pool.
|
|
87
|
+
const ordered = KNOWN_FAMILIES.filter((f) => pool.includes(f));
|
|
88
|
+
return { family: ordered[0] ?? pool[0], reason: null };
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Resolve the probe/oracle family + LIVE model for a produce run.
|
|
92
|
+
*
|
|
93
|
+
* @param {{
|
|
94
|
+
* implementerFamily: string,
|
|
95
|
+
* hostFamily?: string | null,
|
|
96
|
+
* availableFamilies?: string[],
|
|
97
|
+
* codexDeps?: { home: string, existsSync: (p: string) => boolean, readFileSync: (p: string, enc: string) => string },
|
|
98
|
+
* }} args
|
|
99
|
+
* @returns {{
|
|
100
|
+
* available: boolean,
|
|
101
|
+
* probe_family: string | null,
|
|
102
|
+
* transport_hint: { prefer_self_resolving: boolean, recommended_walk: string[] } | null,
|
|
103
|
+
* model: string | null,
|
|
104
|
+
* source: string | null,
|
|
105
|
+
* reason: string | null,
|
|
106
|
+
* }}
|
|
107
|
+
*/
|
|
108
|
+
export function resolveProbeFamily({ implementerFamily, hostFamily = null, availableFamilies = KNOWN_FAMILIES, codexDeps, } = {}) {
|
|
109
|
+
const implementer = normalizeFamily(implementerFamily);
|
|
110
|
+
if (!implementer) {
|
|
111
|
+
return {
|
|
112
|
+
available: false,
|
|
113
|
+
probe_family: null,
|
|
114
|
+
transport_hint: null,
|
|
115
|
+
model: null,
|
|
116
|
+
source: null,
|
|
117
|
+
reason: 'unknown_implementer_family',
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
const host = normalizeFamily(hostFamily);
|
|
121
|
+
const normalizedAvailable = [...new Set(availableFamilies.map(normalizeFamily).filter(Boolean))];
|
|
122
|
+
const { family, reason } = pickProbeFamily(implementer, host, normalizedAvailable);
|
|
123
|
+
if (!family) {
|
|
124
|
+
return {
|
|
125
|
+
available: false,
|
|
126
|
+
probe_family: null,
|
|
127
|
+
transport_hint: null,
|
|
128
|
+
model: null,
|
|
129
|
+
source: null,
|
|
130
|
+
reason: reason ?? 'no_disjoint_family',
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
// Resolve the model LIVE via the reused spar primitive (provider-is-output,
|
|
134
|
+
// zero baked id). codex reads ~/.codex/config.toml; claude/gemini self-resolve.
|
|
135
|
+
if (family === 'codex') {
|
|
136
|
+
const deps = codexDeps ?? { home: homedir(), existsSync, readFileSync };
|
|
137
|
+
const res = resolveCodexSparModel(deps);
|
|
138
|
+
return {
|
|
139
|
+
available: true,
|
|
140
|
+
probe_family: 'codex',
|
|
141
|
+
transport_hint: { prefer_self_resolving: true, recommended_walk: ['plugin', 'cli', 'mcp'] },
|
|
142
|
+
model: res.model,
|
|
143
|
+
source: res.source,
|
|
144
|
+
// A codex model that fails to resolve from config does NOT make the
|
|
145
|
+
// probe family unavailable — the self-resolving plugin/CLI rungs still
|
|
146
|
+
// run without a named model. Surface the model-resolution reason.
|
|
147
|
+
reason: res.reason,
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
// claude / gemini MCP rungs take only {prompt} — no model, no staleness vector.
|
|
151
|
+
return {
|
|
152
|
+
available: true,
|
|
153
|
+
probe_family: family,
|
|
154
|
+
transport_hint: { prefer_self_resolving: false, recommended_walk: ['mcp', 'plugin', 'cli'] },
|
|
155
|
+
model: null,
|
|
156
|
+
source: null,
|
|
157
|
+
reason: 'self_resolving',
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
//# sourceMappingURL=probe-family.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"probe-family.mjs","sourceRoot":"","sources":["../../../src/cli/produce/probe-family.mjs"],"names":[],"mappings":"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"}
|