@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
|
@@ -6,7 +6,7 @@ import { appendFileSync, mkdirSync, readdirSync, readFileSync, writeFileSync } f
|
|
|
6
6
|
import { hostname } from 'node:os'
|
|
7
7
|
import { join, resolve } from 'node:path'
|
|
8
8
|
import { readLifecycleEventsForDay } from '../coordination/event-log.mjs'
|
|
9
|
-
import {
|
|
9
|
+
import { validateShowrunnerEvent } from '../coordination/event-schema.mjs'
|
|
10
10
|
import { createCoordinationStore } from '../coordination/store.mjs'
|
|
11
11
|
import { parseFlags } from '../util/args.mjs'
|
|
12
12
|
import { err, ok } from '../util/result.mjs'
|
|
@@ -28,8 +28,8 @@ const VALID_EVENT_TYPES = [
|
|
|
28
28
|
'ci-watch.tick',
|
|
29
29
|
'ci-watch.fix-pushed',
|
|
30
30
|
'ci-watch.stopped',
|
|
31
|
-
// Phase 2.5 —
|
|
32
|
-
//
|
|
31
|
+
// Phase 2.5 — Showrunner-readable ops emitted by APT skills so the
|
|
32
|
+
// Showrunner's readEventLog tool can drive its observe loop. These
|
|
33
33
|
// events route to JSONL (like ci-watch.*) and carry terminal_id
|
|
34
34
|
// auto-stamped from APERANT_TERMINAL_ID when present.
|
|
35
35
|
'phase.changed',
|
|
@@ -40,9 +40,9 @@ const VALID_EVENT_TYPES = [
|
|
|
40
40
|
'budget.exceeded',
|
|
41
41
|
'terminal.enrolled',
|
|
42
42
|
'terminal.unenrolled',
|
|
43
|
-
'
|
|
44
|
-
'
|
|
45
|
-
'
|
|
43
|
+
'showrunner.intent',
|
|
44
|
+
'showrunner.cross_check',
|
|
45
|
+
'showrunner.realignment',
|
|
46
46
|
]
|
|
47
47
|
|
|
48
48
|
const CI_WATCH_EVENT_TYPES = new Set([
|
|
@@ -52,7 +52,7 @@ const CI_WATCH_EVENT_TYPES = new Set([
|
|
|
52
52
|
'ci-watch.stopped',
|
|
53
53
|
])
|
|
54
54
|
|
|
55
|
-
const
|
|
55
|
+
const SHOWRUNNER_EVENT_TYPES = new Set([
|
|
56
56
|
'phase.changed',
|
|
57
57
|
'artifact.ready',
|
|
58
58
|
'awaiting-input',
|
|
@@ -61,9 +61,9 @@ const CONDUCTOR_EVENT_TYPES = new Set([
|
|
|
61
61
|
'budget.exceeded',
|
|
62
62
|
'terminal.enrolled',
|
|
63
63
|
'terminal.unenrolled',
|
|
64
|
-
'
|
|
65
|
-
'
|
|
66
|
-
'
|
|
64
|
+
'showrunner.intent',
|
|
65
|
+
'showrunner.cross_check',
|
|
66
|
+
'showrunner.realignment',
|
|
67
67
|
])
|
|
68
68
|
|
|
69
69
|
/**
|
|
@@ -142,22 +142,22 @@ export function cmdEvent(subcommand, projectDir, extraArgs) {
|
|
|
142
142
|
return ok({ status: 'ok', command: 'event-append', event_file: jsonlFile, event })
|
|
143
143
|
}
|
|
144
144
|
|
|
145
|
-
// Phase 2.5 —
|
|
146
|
-
// path with the canonical envelope the
|
|
145
|
+
// Phase 2.5 — Showrunner-readable events route to the per-day JSONL
|
|
146
|
+
// path with the canonical envelope the Showrunner's readEventLog
|
|
147
147
|
// expects: { t, agent, pid, hostname, incarnation, op, task, data }.
|
|
148
148
|
// terminal_id is auto-stamped from APERANT_TERMINAL_ID env when set,
|
|
149
|
-
// so APT skills running in a
|
|
149
|
+
// so APT skills running in a Showrunner-spawned PTY automatically
|
|
150
150
|
// tag their events with the originating terminal.
|
|
151
|
-
if (
|
|
151
|
+
if (SHOWRUNNER_EVENT_TYPES.has(type)) {
|
|
152
152
|
const terminalId = process.env.APERANT_TERMINAL_ID
|
|
153
153
|
if (terminalId && data && typeof data === 'object' && !data.terminal_id) {
|
|
154
154
|
data.terminal_id = terminalId
|
|
155
155
|
}
|
|
156
156
|
// Step 1 — schema gate: reject payloads that violate the per-op
|
|
157
157
|
// contract before the line lands on disk. The same validator
|
|
158
|
-
// runs at the framework store seam and the core
|
|
158
|
+
// runs at the framework store seam and the core showrunner
|
|
159
159
|
// writer; gating here catches CLI emitters (APT skills).
|
|
160
|
-
const validation =
|
|
160
|
+
const validation = validateShowrunnerEvent(type, data)
|
|
161
161
|
if (!validation.ok) {
|
|
162
162
|
return err(`Schema violation for ${type}: ${validation.error}`)
|
|
163
163
|
}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* commands/features-reconcile.mjs — CLI entry point for the feature-registry
|
|
3
|
+
* delta ledger (replaces the retired append-only registry-audit writer).
|
|
4
|
+
*
|
|
5
|
+
* Exactly ONE verb per invocation:
|
|
6
|
+
* --draft — scaffold/refresh a per-writer delta from `git diff
|
|
7
|
+
* --name-status <base>..HEAD` (renames preserved; deletions
|
|
8
|
+
* pre-filled `remove`; modifications marked needs-disposition).
|
|
9
|
+
* --write — the single ordered idempotent materializer (7 steps, ID-03):
|
|
10
|
+
* deltas → post-images → validate → atomic area replace →
|
|
11
|
+
* receipt → delete consumed deltas → regenerate REGISTRY.md.
|
|
12
|
+
* --check — read-only 4-clause verifier (ID-05): base..HEAD coverage with
|
|
13
|
+
* blob fingerprints, area schema validity, per-area latest-
|
|
14
|
+
* receipt integrity, no orphan consumed deltas.
|
|
15
|
+
* --gc — prune receipts present on origin/main AND older than
|
|
16
|
+
* --max-age-days (default 30). Fetch failure → warned no-op.
|
|
17
|
+
*
|
|
18
|
+
* Flags: --task-id, --subtask-id (draft), --base <ref> (draft/check; an
|
|
19
|
+
* explicit ref is normalized via `merge-base HEAD <ref>` — see resolveBase;
|
|
20
|
+
* default merge-base HEAD origin/main), --dry-run (draft), --warn-only
|
|
21
|
+
* (check), --max-age-days (gc), --no-worktree-redirect.
|
|
22
|
+
*
|
|
23
|
+
* BUG-025b: the mutating verbs (--draft/--write) resolve their write root via
|
|
24
|
+
* features/write-root.mjs so registry writes land in the active task's
|
|
25
|
+
* worktree, never leak onto main. --write self-stages its committable writes
|
|
26
|
+
* (self-stage.mjs contract) so the caller's next commit picks them up.
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
import { resolve } from 'node:path'
|
|
30
|
+
import { selfStageCommittableWrites } from '../artifacts/self-stage.mjs'
|
|
31
|
+
import { checkReconciled, draftDelta, gcReceipts, materialize } from '../features/reconcile.mjs'
|
|
32
|
+
import { resolveWriteRoot } from '../features/write-root.mjs'
|
|
33
|
+
import { parseFlags } from '../util/args.mjs'
|
|
34
|
+
import { err, exitWith, ok } from '../util/result.mjs'
|
|
35
|
+
|
|
36
|
+
const VERBS = ['draft', 'write', 'check', 'gc']
|
|
37
|
+
|
|
38
|
+
export function cmdFeaturesReconcile(projectDir, extraArgs) {
|
|
39
|
+
if (!projectDir) {
|
|
40
|
+
return err(
|
|
41
|
+
'Usage: apt-tools features-reconcile <project-dir> (--draft|--write|--check|--gc) [flags]',
|
|
42
|
+
)
|
|
43
|
+
}
|
|
44
|
+
const root = resolve(projectDir)
|
|
45
|
+
const flags = parseFlags(extraArgs)
|
|
46
|
+
const verbs = VERBS.filter((v) => flags.has(v))
|
|
47
|
+
if (verbs.length !== 1) {
|
|
48
|
+
return err('features-reconcile requires exactly ONE of --draft | --write | --check | --gc', 1, {
|
|
49
|
+
command: 'features-reconcile',
|
|
50
|
+
})
|
|
51
|
+
}
|
|
52
|
+
const verb = verbs[0]
|
|
53
|
+
|
|
54
|
+
const taskIdFlag = flags.get('task-id')
|
|
55
|
+
const taskId = typeof taskIdFlag === 'string' && taskIdFlag.trim() ? taskIdFlag.trim() : null
|
|
56
|
+
const subtaskIdFlag = flags.get('subtask-id')
|
|
57
|
+
const subtaskId =
|
|
58
|
+
typeof subtaskIdFlag === 'string' && subtaskIdFlag.trim() ? subtaskIdFlag.trim() : null
|
|
59
|
+
const baseFlag = flags.get('base')
|
|
60
|
+
const base = typeof baseFlag === 'string' && baseFlag.trim() ? baseFlag.trim() : null
|
|
61
|
+
const noRedirect = flags.get('no-worktree-redirect') === true
|
|
62
|
+
|
|
63
|
+
// BUG-025b: only the MUTATING verbs redirect writes into the task worktree.
|
|
64
|
+
let writeRoot = root
|
|
65
|
+
let redirectNotice = null
|
|
66
|
+
if (verb === 'draft' || verb === 'write') {
|
|
67
|
+
const resolved = resolveWriteRoot({ projectDir: root, taskId, noRedirect })
|
|
68
|
+
if (resolved.error) {
|
|
69
|
+
return err(resolved.error.message, 1, {
|
|
70
|
+
command: 'features-reconcile',
|
|
71
|
+
kind: resolved.error.kind,
|
|
72
|
+
active_worktree_tasks: resolved.error.active_worktree_tasks,
|
|
73
|
+
})
|
|
74
|
+
}
|
|
75
|
+
writeRoot = resolved.writeRoot
|
|
76
|
+
redirectNotice = resolved.redirect_notice
|
|
77
|
+
if (redirectNotice) {
|
|
78
|
+
// Surface the redirect once on stderr so the executor's log carries
|
|
79
|
+
// the audit trail without polluting stdout JSON.
|
|
80
|
+
process.stderr.write(`[features-reconcile] ${redirectNotice}\n`)
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
const common = {
|
|
84
|
+
status: 'ok',
|
|
85
|
+
command: 'features-reconcile',
|
|
86
|
+
verb,
|
|
87
|
+
write_root: writeRoot,
|
|
88
|
+
...(redirectNotice ? { redirect_notice: redirectNotice } : {}),
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (verb === 'draft') {
|
|
92
|
+
if (!taskId) {
|
|
93
|
+
return err(
|
|
94
|
+
'features-reconcile --draft requires --task-id <id> (the delta path is per-writer)',
|
|
95
|
+
1,
|
|
96
|
+
{
|
|
97
|
+
command: 'features-reconcile',
|
|
98
|
+
},
|
|
99
|
+
)
|
|
100
|
+
}
|
|
101
|
+
const res = draftDelta({
|
|
102
|
+
root: writeRoot,
|
|
103
|
+
base,
|
|
104
|
+
taskId,
|
|
105
|
+
subtaskId,
|
|
106
|
+
dryRun: flags.get('dry-run') === true,
|
|
107
|
+
})
|
|
108
|
+
if (!res.ok) return err(res.error, 1, { command: 'features-reconcile', verb })
|
|
109
|
+
return ok({
|
|
110
|
+
...common,
|
|
111
|
+
delta_path: res.deltaPath,
|
|
112
|
+
wrote: res.wrote,
|
|
113
|
+
qualifying: res.qualifying,
|
|
114
|
+
base: res.base,
|
|
115
|
+
delta: res.delta,
|
|
116
|
+
})
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
if (verb === 'write') {
|
|
120
|
+
const res = materialize({ root: writeRoot, taskId })
|
|
121
|
+
if (res.status === 'error') {
|
|
122
|
+
return exitWith({ ...res, command: 'features-reconcile', verb, write_root: writeRoot }, 1)
|
|
123
|
+
}
|
|
124
|
+
let self_stage = null
|
|
125
|
+
if (res.status === 'ok' && Array.isArray(res.changed_paths) && res.changed_paths.length > 0) {
|
|
126
|
+
// Finally wiring the self-stage.mjs header contract: the write's
|
|
127
|
+
// committable outputs (areas + receipt + REGISTRY.md + deleted-delta
|
|
128
|
+
// paths) are staged so the ship-step commit picks them up.
|
|
129
|
+
self_stage = selfStageCommittableWrites(writeRoot, res.changed_paths)
|
|
130
|
+
}
|
|
131
|
+
return ok({
|
|
132
|
+
...common,
|
|
133
|
+
...res,
|
|
134
|
+
status: res.status,
|
|
135
|
+
...(self_stage ? { self_stage } : {}),
|
|
136
|
+
})
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
if (verb === 'check') {
|
|
140
|
+
const res = checkReconciled({
|
|
141
|
+
root,
|
|
142
|
+
base,
|
|
143
|
+
warnOnly: flags.get('warn-only') === true,
|
|
144
|
+
taskId,
|
|
145
|
+
})
|
|
146
|
+
const envelope = { ...common, ...res, status: res.status }
|
|
147
|
+
if (res.status === 'fail') return exitWith(envelope, 1)
|
|
148
|
+
return ok(envelope)
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// verb === 'gc'
|
|
152
|
+
const maxAgeFlag = flags.get('max-age-days')
|
|
153
|
+
const maxAgeDays =
|
|
154
|
+
typeof maxAgeFlag === 'string' && /^\d+$/.test(maxAgeFlag) ? Number(maxAgeFlag) : 30
|
|
155
|
+
const res = gcReceipts({ root, maxAgeDays })
|
|
156
|
+
return ok({ ...common, ...res, status: res.status, max_age_days: maxAgeDays })
|
|
157
|
+
}
|
|
@@ -16,8 +16,8 @@ const __dirname = dirname(__filename)
|
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
18
|
* SECURITY: validate a component path string from `.aperant/features/*.json`
|
|
19
|
-
* before passing it to git. The registry is on-disk JSON
|
|
20
|
-
* features-
|
|
19
|
+
* before passing it to git. The registry is on-disk JSON written by the
|
|
20
|
+
* features-reconcile materializer; pre-fix the orphan walker spliced this string into a
|
|
21
21
|
* shell command (`execSync(\`git rev-parse HEAD:${comp} 2>/dev/null\`)`),
|
|
22
22
|
* making a malicious entry like `foo.ts; rm -rf $HOME` a command-injection
|
|
23
23
|
* vector against any user who ran `apt-tools health-check`. The fix
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* exist, else stable by task id), and probes each branch's mergeability against
|
|
9
9
|
* the CURRENT base via the EXACT same `git merge-tree` detection the `detect`
|
|
10
10
|
* subcommand uses (#395). It emits a structured integration report the
|
|
11
|
-
*
|
|
11
|
+
* showrunner renders and the `apt:merge-conflict-resolution` flow consumes for
|
|
12
12
|
* any conflicted branch.
|
|
13
13
|
*
|
|
14
14
|
* READ-ONLY, like `detect`/`markers`: NO `git merge`, NO `git rebase`, NO index
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
* apt-tools merge integrate <project-dir> --batch <batch-id> [--base <ref>]
|
|
34
34
|
*
|
|
35
35
|
* --tasks Explicit canonical task-id list (what `fan-out resolve` returns and
|
|
36
|
-
* the
|
|
36
|
+
* the showrunner already holds). Primary form.
|
|
37
37
|
* --batch Recover the task-id list from the batch's worker rows
|
|
38
38
|
* `.aperant/team-status/fanout-<batch>-<task>.json` (the agent-id
|
|
39
39
|
* format fan-out.mjs spawns workers with: `fanout-${batch}-${task}`).
|
|
@@ -291,7 +291,7 @@ export function mergeIntegrate(targetDir, extraArgs) {
|
|
|
291
291
|
const task = state?.active_tasks?.[id] || null
|
|
292
292
|
|
|
293
293
|
// Tasks with no shipped branch can't be integrated — record them so the
|
|
294
|
-
//
|
|
294
|
+
// showrunner sees why, but never block the rest of the batch.
|
|
295
295
|
if (!task) {
|
|
296
296
|
needsHuman++
|
|
297
297
|
tasks.push({ task_id: id, status: 'unknown', reason: 'task not found in state.json' })
|