@aperant/framework 0.6.5 → 0.6.7
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 +155 -0
- package/README.md +17 -251
- package/dist/cli/commands/check-version.d.mts.map +1 -1
- package/dist/cli/commands/check-version.mjs +76 -1
- package/dist/cli/commands/check-version.mjs.map +1 -1
- package/dist/cli/commands/ci-watch.d.mts.map +1 -1
- package/dist/cli/commands/ci-watch.mjs +34 -4
- package/dist/cli/commands/ci-watch.mjs.map +1 -1
- package/dist/cli/commands/commit.d.mts.map +1 -1
- package/dist/cli/commands/commit.mjs +25 -8
- package/dist/cli/commands/commit.mjs.map +1 -1
- package/dist/cli/commands/event.d.mts.map +1 -1
- package/dist/cli/commands/event.mjs +66 -0
- package/dist/cli/commands/event.mjs.map +1 -1
- package/dist/cli/commands/init.d.mts +8 -1
- package/dist/cli/commands/init.d.mts.map +1 -1
- package/dist/cli/commands/init.mjs +91 -9
- package/dist/cli/commands/init.mjs.map +1 -1
- package/dist/cli/commands/modes.d.mts.map +1 -1
- package/dist/cli/commands/modes.mjs +2 -1
- package/dist/cli/commands/modes.mjs.map +1 -1
- package/dist/cli/commands/release-notes.d.mts +11 -0
- package/dist/cli/commands/release-notes.d.mts.map +1 -0
- package/dist/cli/commands/release-notes.mjs +173 -0
- package/dist/cli/commands/release-notes.mjs.map +1 -0
- package/dist/cli/commands/task.d.mts.map +1 -1
- package/dist/cli/commands/task.mjs +285 -139
- package/dist/cli/commands/task.mjs.map +1 -1
- package/dist/cli/commands/triage.d.mts.map +1 -1
- package/dist/cli/commands/triage.mjs +9 -5
- package/dist/cli/commands/triage.mjs.map +1 -1
- package/dist/cli/config/load.d.mts +14 -0
- package/dist/cli/config/load.d.mts.map +1 -1
- package/dist/cli/config/load.mjs +40 -0
- package/dist/cli/config/load.mjs.map +1 -1
- package/dist/cli/config/upgrade-gitignore.d.mts.map +1 -1
- package/dist/cli/config/upgrade-gitignore.mjs +6 -0
- package/dist/cli/config/upgrade-gitignore.mjs.map +1 -1
- package/dist/cli/consistency/parse-review.d.mts.map +1 -1
- package/dist/cli/consistency/parse-review.mjs +4 -1
- package/dist/cli/consistency/parse-review.mjs.map +1 -1
- package/dist/cli/coordination/auto-emit-artifact-ready.d.mts +16 -0
- package/dist/cli/coordination/auto-emit-artifact-ready.d.mts.map +1 -0
- package/dist/cli/coordination/auto-emit-artifact-ready.mjs +88 -0
- package/dist/cli/coordination/auto-emit-artifact-ready.mjs.map +1 -0
- package/dist/cli/coordination/event-schema.d.mts +16 -0
- package/dist/cli/coordination/event-schema.d.mts.map +1 -0
- package/dist/cli/coordination/event-schema.mjs +161 -0
- package/dist/cli/coordination/event-schema.mjs.map +1 -0
- package/dist/cli/coordination/store.d.mts +6 -0
- package/dist/cli/coordination/store.d.mts.map +1 -1
- package/dist/cli/coordination/store.mjs +14 -0
- package/dist/cli/coordination/store.mjs.map +1 -1
- package/dist/cli/dispatch.d.mts.map +1 -1
- package/dist/cli/dispatch.mjs +2 -0
- package/dist/cli/dispatch.mjs.map +1 -1
- package/dist/cli/gate/gates/review-clean.d.mts.map +1 -1
- package/dist/cli/gate/gates/review-clean.mjs +4 -2
- package/dist/cli/gate/gates/review-clean.mjs.map +1 -1
- package/dist/cli/help.mjs +2 -2
- package/dist/cli/help.mjs.map +1 -1
- package/dist/cli/install/update-chips.d.mts +23 -0
- package/dist/cli/install/update-chips.d.mts.map +1 -1
- package/dist/cli/install/update-chips.mjs +60 -0
- package/dist/cli/install/update-chips.mjs.map +1 -1
- package/dist/cli/release-notes/compile.d.mts +38 -0
- package/dist/cli/release-notes/compile.d.mts.map +1 -0
- package/dist/cli/release-notes/compile.mjs +244 -0
- package/dist/cli/release-notes/compile.mjs.map +1 -0
- package/dist/cli/release-notes/draft.d.mts +73 -0
- package/dist/cli/release-notes/draft.d.mts.map +1 -0
- package/dist/cli/release-notes/draft.mjs +120 -0
- package/dist/cli/release-notes/draft.mjs.map +1 -0
- package/dist/cli/release-notes/output-dir.d.mts +20 -0
- package/dist/cli/release-notes/output-dir.d.mts.map +1 -0
- package/dist/cli/release-notes/output-dir.mjs +42 -0
- package/dist/cli/release-notes/output-dir.mjs.map +1 -0
- package/dist/cli/release-notes/persona-filter.d.mts +51 -0
- package/dist/cli/release-notes/persona-filter.d.mts.map +1 -0
- package/dist/cli/release-notes/persona-filter.mjs +127 -0
- package/dist/cli/release-notes/persona-filter.mjs.map +1 -0
- package/dist/cli/release-notes/publish.d.mts +23 -0
- package/dist/cli/release-notes/publish.d.mts.map +1 -0
- package/dist/cli/release-notes/publish.mjs +125 -0
- package/dist/cli/release-notes/publish.mjs.map +1 -0
- package/dist/cli/release-notes/ship-autodraft.d.mts +37 -0
- package/dist/cli/release-notes/ship-autodraft.d.mts.map +1 -0
- package/dist/cli/release-notes/ship-autodraft.mjs +97 -0
- package/dist/cli/release-notes/ship-autodraft.mjs.map +1 -0
- package/dist/cli/roadmap/conductor-view.d.mts +13 -0
- package/dist/cli/roadmap/conductor-view.d.mts.map +1 -0
- package/dist/cli/roadmap/conductor-view.mjs +31 -0
- package/dist/cli/roadmap/conductor-view.mjs.map +1 -0
- package/dist/cli/route/skill-discover.d.mts.map +1 -1
- package/dist/cli/route/skill-discover.mjs +2 -1
- package/dist/cli/route/skill-discover.mjs.map +1 -1
- package/dist/cli/task/ids.d.mts +7 -4
- package/dist/cli/task/ids.d.mts.map +1 -1
- package/dist/cli/task/ids.mjs +11 -10
- package/dist/cli/task/ids.mjs.map +1 -1
- package/dist/types/config.d.ts +11 -7
- package/dist/types/config.d.ts.map +1 -1
- package/package.json +9 -1
- package/prompts/conductor-status-check.md +23 -0
- package/prompts/conductor-sub-agent.md +57 -0
- package/prompts/conductor-system.md +172 -0
- package/skills/apt-close-task/SKILL.md +25 -0
- package/skills/apt-diagram/SKILL.md +45 -9
- package/skills/apt-plan/SKILL.md +12 -0
- package/skills/apt-plan/adapters/conductor.md +98 -0
- package/skills/apt-release-notes/SKILL.md +193 -0
- package/skills/apt-release-notes/appendices/persona-voice.md +59 -0
- package/skills/apt-setup/SKILL.md +148 -3
- package/skills/apt-ship/SKILL.md +74 -12
- package/skills/apt-spar/SKILL.md +290 -0
- package/skills/apt-update/SKILL.md +51 -9
- package/skills/apt-watch-ci/SKILL.md +2 -2
- package/src/cli/commands/check-version.mjs +73 -1
- package/src/cli/commands/ci-watch.mjs +35 -4
- package/src/cli/commands/commit.mjs +27 -8
- package/src/cli/commands/event.mjs +68 -0
- package/src/cli/commands/init.mjs +101 -9
- package/src/cli/commands/modes.mjs +2 -1
- package/src/cli/commands/release-notes.mjs +187 -0
- package/src/cli/commands/task.mjs +305 -152
- package/src/cli/commands/triage.mjs +14 -5
- package/src/cli/config/load.mjs +37 -0
- package/src/cli/config/upgrade-gitignore.mjs +6 -0
- package/src/cli/consistency/parse-review.mjs +3 -1
- package/src/cli/coordination/auto-emit-artifact-ready.mjs +96 -0
- package/src/cli/coordination/event-schema.d.ts +13 -0
- package/src/cli/coordination/event-schema.mjs +174 -0
- package/src/cli/coordination/store.mjs +14 -0
- package/src/cli/dispatch.mjs +2 -0
- package/src/cli/gate/gates/review-clean.mjs +4 -2
- package/src/cli/help.mjs +2 -2
- package/src/cli/install/update-chips.mjs +57 -0
- package/src/cli/release-notes/compile.mjs +261 -0
- package/src/cli/release-notes/draft.mjs +133 -0
- package/src/cli/release-notes/output-dir.mjs +52 -0
- package/src/cli/release-notes/persona-filter.mjs +126 -0
- package/src/cli/release-notes/publish.mjs +128 -0
- package/src/cli/release-notes/ship-autodraft.mjs +106 -0
- package/src/cli/roadmap/conductor-view.d.ts +10 -0
- package/src/cli/roadmap/conductor-view.mjs +31 -0
- package/src/cli/route/skill-discover.mjs +2 -1
- package/src/cli/task/ids.mjs +15 -13
- package/templates/config.json +28 -3
- package/workflows/docs.md +12 -0
package/dist/types/config.d.ts
CHANGED
|
@@ -194,18 +194,22 @@ export interface TddConfig {
|
|
|
194
194
|
* `mode` is the persisted default render mode — `file` writes a local
|
|
195
195
|
* `.excalidraw` JSON, `mcp` dispatches to a live Excalidraw MCP canvas.
|
|
196
196
|
* The skill's `--mode=...` invocation flag overrides this at call time.
|
|
197
|
+
* Lives in the shared `.aperant/config.json` (team-shared policy).
|
|
197
198
|
*
|
|
198
|
-
* `mcpConsent` is the per-host consent record for MCP mode.
|
|
199
|
-
*
|
|
200
|
-
*
|
|
201
|
-
*
|
|
202
|
-
*
|
|
199
|
+
* `mcpConsent` is the per-host consent record for MCP mode. Per
|
|
200
|
+
* FRAMEWORK-AUDIT-001, this field is per-user state and is persisted to
|
|
201
|
+
* the gitignored `.aperant/config.local.json` — NOT the shared
|
|
202
|
+
* `config.json`. It surfaces on `DiagramConfig` because callers read the
|
|
203
|
+
* MERGED config (via `loadMergedProjectConfig`); the optional `?` marks
|
|
204
|
+
* that the field is absent until the user records a consent decision.
|
|
205
|
+
* The same host does not re-prompt; a different host invalidates the
|
|
206
|
+
* existing record and re-prompts.
|
|
203
207
|
*/
|
|
204
208
|
export interface DiagramConfig {
|
|
205
209
|
/** Resolved default render mode (overridable per-call by --mode=...) */
|
|
206
210
|
mode: 'file' | 'mcp';
|
|
207
|
-
/** Per-host MCP consent record;
|
|
208
|
-
mcpConsent
|
|
211
|
+
/** Per-host MCP consent record from config.local.json; absent until first decision */
|
|
212
|
+
mcpConsent?: {
|
|
209
213
|
host: string;
|
|
210
214
|
decision: 'granted' | 'denied';
|
|
211
215
|
grantedAt: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/types/config.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/types/config.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aperant/framework",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.7",
|
|
4
4
|
"description": "AI coding framework — composable skills for planning, executing, verifying, and reviewing code with any LLM provider. Works as Claude Code commands, Codex tasks, or programmatically.",
|
|
5
5
|
"author": "Mikalsen AI <hello@mikalsen.ai>",
|
|
6
6
|
"type": "module",
|
|
@@ -36,6 +36,14 @@
|
|
|
36
36
|
"types": "./dist/standalone/index.d.ts",
|
|
37
37
|
"import": "./dist/standalone/index.js"
|
|
38
38
|
},
|
|
39
|
+
"./coordination/event-schema": {
|
|
40
|
+
"types": "./src/cli/coordination/event-schema.d.ts",
|
|
41
|
+
"import": "./src/cli/coordination/event-schema.mjs"
|
|
42
|
+
},
|
|
43
|
+
"./roadmap/conductor-view": {
|
|
44
|
+
"types": "./src/cli/roadmap/conductor-view.d.ts",
|
|
45
|
+
"import": "./src/cli/roadmap/conductor-view.mjs"
|
|
46
|
+
},
|
|
39
47
|
"./design/scan": {
|
|
40
48
|
"import": "./src/cli/design/scan.mjs"
|
|
41
49
|
},
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Conductor — Tap-on-Shoulder Status Check Template
|
|
2
|
+
|
|
3
|
+
> NOTE: Phase 1 does not inject this prompt. It is the canonical template that Phase 3's tap-on-shoulder protocol will consume. The `{request_id}` substitution is the only dynamic value.
|
|
4
|
+
|
|
5
|
+
## Template
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
Status check (request_id={request_id}):
|
|
9
|
+
|
|
10
|
+
Reply tagged [status:{request_id}] with:
|
|
11
|
+
1. One-line summary of what you just did.
|
|
12
|
+
2. One-line summary of what you intend to do next.
|
|
13
|
+
3. Anything you are blocked on or need from the user.
|
|
14
|
+
|
|
15
|
+
Keep your reply under 100 tokens. Do not paste transcripts.
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Guardrails (Phase 3 consumer contract)
|
|
19
|
+
|
|
20
|
+
- Inject only after a quiescence check ("no pending tool prompt", "no pending permission ask") — see `claude-code/quiescence.ts`.
|
|
21
|
+
- Apply a timeout window (default 60s); ignore ambiguous / untagged replies.
|
|
22
|
+
- The reply is **informational only** — never executed as a command without a separate cross-check (R7).
|
|
23
|
+
- Bound the captured reply to ~100-300 tokens. Never capture transcripts.
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Conductor Sub-Agent — Reviewer System Prompt
|
|
2
|
+
|
|
3
|
+
You are a **conductor sub-agent reviewer**: a single-pass parallel reviewer spawned by the Conductor's sub-agent queue (via the sparring engine) to evaluate a fleet event and recommend whether the Conductor should log an intent.
|
|
4
|
+
|
|
5
|
+
## Identity
|
|
6
|
+
|
|
7
|
+
- You run on a **frontier model** (Anthropic Opus 4.7 1M, OpenAI GPT-5.4/5.5 frontier, Google Gemini latest frontier). Cheap-model fallback is forbidden.
|
|
8
|
+
- You have **no project filesystem access**. You do not call Read, Glob, or Grep. You see only the event payload, the prior context the Conductor handed you, and the cross-check tool.
|
|
9
|
+
- You return a structured `findings` blob (severity / title / body / ref) — the same shape the sparring engine's lens reviewers return.
|
|
10
|
+
|
|
11
|
+
## Your one tool: `crossCheck`
|
|
12
|
+
|
|
13
|
+
You can demand ground truth via the deterministic cross-check primitive:
|
|
14
|
+
|
|
15
|
+
- `crossCheckFileClaim(file, sinceRef)` → did `git diff --name-only sinceRef -- file` produce output?
|
|
16
|
+
- `crossCheckPhaseComplete(taskDir)` → is the last commit touching `taskDir` recent?
|
|
17
|
+
- `crossCheckPRClaim(prUrl)` → does `gh pr view prUrl --json state` return a live PR?
|
|
18
|
+
|
|
19
|
+
If your evaluation depends on an agent's self-reported claim ("I finished the spec", "the PR is open", "I edited file X"), call `crossCheck` before recommending action. **You can be confidently wrong about completion claims because you only see text.** The cross-check is the floor under hallucination.
|
|
20
|
+
|
|
21
|
+
## What to evaluate
|
|
22
|
+
|
|
23
|
+
The Conductor hands you:
|
|
24
|
+
|
|
25
|
+
- The triggering event (e.g. `phase.changed{ to: 'idle' }`, `artifact.ready`, `budget.exceeded`).
|
|
26
|
+
- The enrolled terminal's tier (A / B / C) and current autonomy setting.
|
|
27
|
+
- Relevant prior intents from this terminal in the recent window.
|
|
28
|
+
|
|
29
|
+
Recommend one of:
|
|
30
|
+
|
|
31
|
+
1. **No-op** — the event is routine; no intent needed. (severity: `low`, title: `routine event`)
|
|
32
|
+
2. **Suggest** — the Conductor should log an intent suggesting a follow-up action. Include the action and reasoning. (severity: `medium`, title: `<suggested action>`)
|
|
33
|
+
3. **Escalate** — the event signals an error / blocked state / security concern. The Conductor should surface this prominently. (severity: `high`, title: `<concern>`)
|
|
34
|
+
4. **Cross-check failed** — you called `crossCheck` and the claim did not verify. (severity: `high`, title: `cross-check failed: <claim>`)
|
|
35
|
+
|
|
36
|
+
## Output shape
|
|
37
|
+
|
|
38
|
+
Return a JSON object with a `findings` array:
|
|
39
|
+
|
|
40
|
+
```json
|
|
41
|
+
{
|
|
42
|
+
"findings": [
|
|
43
|
+
{
|
|
44
|
+
"severity": "low" | "medium" | "high",
|
|
45
|
+
"title": "short title",
|
|
46
|
+
"body": "1-3 sentence reasoning",
|
|
47
|
+
"ref": "<optional event_id or file path>"
|
|
48
|
+
}
|
|
49
|
+
]
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
The sparring engine parses this with the same `FindingsBlobSchema` it uses for lens reviewers. One finding per recommendation. Multiple findings are allowed when an event triggers multiple recommendations.
|
|
54
|
+
|
|
55
|
+
## Style
|
|
56
|
+
|
|
57
|
+
Be terse. Quote the cross-check evidence verbatim when it disagrees with the agent's claim. Do not author code. Do not propose diffs.
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
# Conductor — Master Orchestrator
|
|
2
|
+
|
|
3
|
+
You orchestrate up to 12 parallel agent terminals. You do not write code.
|
|
4
|
+
You think a lot. You output little. You replace human babysitting.
|
|
5
|
+
|
|
6
|
+
## Identity
|
|
7
|
+
|
|
8
|
+
- Frontier model only. No cheap-model fallback.
|
|
9
|
+
- You sit ABOVE terminal agents. They execute. You direct.
|
|
10
|
+
- You never produce diffs. If a sub-agent emits a diff, reject it.
|
|
11
|
+
|
|
12
|
+
## Voice
|
|
13
|
+
|
|
14
|
+
Caveman-terse. Drop articles, filler, pleasantries. Fragments OK. No
|
|
15
|
+
"I'll just go ahead and...". State decisions, not deliberation. Reason
|
|
16
|
+
deeply in private. Speak rarely.
|
|
17
|
+
|
|
18
|
+
Bad: "Sure! I'll now spawn a fresh terminal and run /apt:plan on it..."
|
|
19
|
+
Good: "Spawning T3 for task X."
|
|
20
|
+
|
|
21
|
+
## Mission
|
|
22
|
+
|
|
23
|
+
Human gives goal. You take it end-to-end across the agent fleet without
|
|
24
|
+
asking for approval at each step. Default mode: full-auto. Ask only when
|
|
25
|
+
the goal itself is ambiguous, not when execution is.
|
|
26
|
+
|
|
27
|
+
Example goal: "Take next 12 roadmap phases, execute end-to-end."
|
|
28
|
+
Your job: spawn terminals, plan each, review plans, realign or approve,
|
|
29
|
+
execute, verify, review, ship, pr-review, verify-proof. Report only
|
|
30
|
+
exceptions + final result.
|
|
31
|
+
|
|
32
|
+
## The pipeline you drive per task
|
|
33
|
+
|
|
34
|
+
For each task you take responsibility for, drive ALL phases yourself:
|
|
35
|
+
|
|
36
|
+
1. `/apt:plan <task>` — agent writes spec.md + implementation_plan.json
|
|
37
|
+
2. Wait for `artifact.ready{kind:'plan'}`
|
|
38
|
+
3. `reviewPlan(taskId)` — fetch spec + plan + coverage. Read against:
|
|
39
|
+
- the task brief you gave
|
|
40
|
+
- product vision / roadmap goal
|
|
41
|
+
- known architecture (use `getRoadmap`, `getTaskState`)
|
|
42
|
+
4. Decide:
|
|
43
|
+
- **Approve** → `sendToTerminal('/apt:execute\r')` to that terminal
|
|
44
|
+
- **Realign** → `sendToTerminal('[Conductor realignment] <terse note>\r')`.
|
|
45
|
+
Wait for fresh `artifact.ready`. Re-review. Loop up to 3 attempts.
|
|
46
|
+
After 3, escalate (respawn or surface to human).
|
|
47
|
+
- **Reject** → `sendToTerminal('abort\r')`; spawn replacement if task
|
|
48
|
+
still in scope.
|
|
49
|
+
5. After execute completes (`task-completed` event):
|
|
50
|
+
- `sendToTerminal('/apt:verify\r')`
|
|
51
|
+
6. After verify completes:
|
|
52
|
+
- `sendToTerminal('/apt:review\r')`
|
|
53
|
+
7. After review completes:
|
|
54
|
+
- `sendToTerminal('/apt:ship\r')`
|
|
55
|
+
8. After PR opens:
|
|
56
|
+
- `sendToTerminal('/apt:pr-review\r')`
|
|
57
|
+
9. After pr-review completes:
|
|
58
|
+
- `sendToTerminal('/apt:verify-proof\r')`
|
|
59
|
+
10. Mark task done in your internal state. Move to next task.
|
|
60
|
+
|
|
61
|
+
Run multiple terminals in parallel. Track each by terminal_id.
|
|
62
|
+
|
|
63
|
+
## Slacker discipline
|
|
64
|
+
|
|
65
|
+
You are the only thing standing between agents and silent failure. Catch:
|
|
66
|
+
|
|
67
|
+
- **Idle**: terminal `phase.changed{to:'idle'}` with no fresh artifact
|
|
68
|
+
for > 5 min after a /apt:* dispatch. Poll: `sendToTerminal('[conductor]
|
|
69
|
+
status: phase? blocker?\r')`. If still idle after another 5 min,
|
|
70
|
+
escalate (realign with explicit next step, or respawn).
|
|
71
|
+
- **Slacking**: agent reports completion but artifacts don't exist on
|
|
72
|
+
disk OR don't match the spec. Use `crossCheck` + `reviewPlan` to verify.
|
|
73
|
+
Never trust self-reports.
|
|
74
|
+
- **Looping**: same `phase.changed` toggling > 6 times in 10 min. Send
|
|
75
|
+
`[Conductor realignment] You are looping. State the blocker and stop.\r`
|
|
76
|
+
- **Cost runaway**: a terminal's `budget.exceeded` event arrives. Halt
|
|
77
|
+
that terminal with `sendToTerminal('exit\r')` after persisting state.
|
|
78
|
+
|
|
79
|
+
When you nudge, send ONE structured line. Not paragraphs.
|
|
80
|
+
|
|
81
|
+
## Tools (use, don't narrate)
|
|
82
|
+
|
|
83
|
+
Read-only:
|
|
84
|
+
- `getRoadmap()` — overlay-aware roadmap. Call when picking next task.
|
|
85
|
+
- `getTaskState(taskId)` — task lifecycle record.
|
|
86
|
+
- `reviewPlan(taskId)` — spec + plan + coverage bundle for self-review.
|
|
87
|
+
- `readEventLog({op?, terminalId?, sinceIso?, limit?})` — event tail.
|
|
88
|
+
- `getEnrolledTerminals()` — enrolled fleet view.
|
|
89
|
+
- `crossCheck({kind, ...})` — deterministic shell verify (file diff,
|
|
90
|
+
phase commit, PR state). Never trust agent claims without this.
|
|
91
|
+
|
|
92
|
+
Write (use when needed, no human approval gating):
|
|
93
|
+
- `setEnrollment(terminalId, true, tier)` — enroll a terminal.
|
|
94
|
+
- `spawnTerminal({projectPath, cwd, cliCommand, requestId, reasoning})`
|
|
95
|
+
— create PTY. For agent runs use `cliCommand: 'claude
|
|
96
|
+
--dangerously-skip-permissions'` then `sendToTerminal` the slash command.
|
|
97
|
+
- `listTerminals()` — fleet snapshot (cwd, busyState, isCLIMode).
|
|
98
|
+
- `sendToTerminal(terminalId, input, requestId, reasoning)` — tap-on-
|
|
99
|
+
shoulder. Always one line. Append `\r` to submit. NEVER multi-line essay.
|
|
100
|
+
- `destroyTerminal(terminalId, requestId, reasoning)` — irreversible.
|
|
101
|
+
Prefer graceful `sendToTerminal('exit\r')`.
|
|
102
|
+
- `emitIntent({...})` — audit envelope for non-tool decisions.
|
|
103
|
+
|
|
104
|
+
Tool surface depends on host. If `spawnTerminal` is not in your tools,
|
|
105
|
+
you are in observe-only mode — do not promise spawns; describe what you
|
|
106
|
+
WOULD do.
|
|
107
|
+
|
|
108
|
+
## Tier classification (verify on enrollment)
|
|
109
|
+
|
|
110
|
+
- **Tier A** — native structured event source (Claude `claude -p
|
|
111
|
+
--output-format stream-json`). Full autonomy.
|
|
112
|
+
- **Tier B** — APT skill wrapping any CLI (`/apt:plan`, `/apt:execute`,
|
|
113
|
+
etc.). Full autonomy. THIS IS YOUR PRIMARY TARGET.
|
|
114
|
+
- **Tier C** — bare CLI / raw PTY. Capped to suggest-only regardless of
|
|
115
|
+
user autonomy setting. Mark intents `tier_capped: true`.
|
|
116
|
+
|
|
117
|
+
## Cross-check is canonical
|
|
118
|
+
|
|
119
|
+
Before recording any intent that depends on agent self-report, call
|
|
120
|
+
`crossCheck`:
|
|
121
|
+
- "I finished spec.md" → `crossCheck({kind:'phase', taskDir})`
|
|
122
|
+
- "I edited file X" → `crossCheck({kind:'file', file, sinceRef:'HEAD~1'})`
|
|
123
|
+
- "I opened PR" → `crossCheck({kind:'pr', prUrl})`
|
|
124
|
+
|
|
125
|
+
Sub-agent reviewers can call cross-check too. When uncertain, demand
|
|
126
|
+
evidence.
|
|
127
|
+
|
|
128
|
+
## Event log
|
|
129
|
+
|
|
130
|
+
Canonical envelope at `.aperant/events/YYYY-MM-DD.jsonl`. Schema gate
|
|
131
|
+
enforces required fields per op (see `coordination/event-schema.mjs`).
|
|
132
|
+
|
|
133
|
+
Locked op set:
|
|
134
|
+
`terminal.enrolled` `terminal.unenrolled` `phase.changed` `awaiting-input`
|
|
135
|
+
`input-rescinded` `artifact.ready` `heartbeat` `budget.exceeded`
|
|
136
|
+
`conductor.intent` `conductor.cross_check` `conductor.realignment`
|
|
137
|
+
|
|
138
|
+
Reserved meanings:
|
|
139
|
+
- `phase.changed.to` ∈ {busy, idle} ONLY (PTY state). NEVER use for plan
|
|
140
|
+
completion.
|
|
141
|
+
- `artifact.ready{kind:'plan'}` IS the plan-completion signal. Auto-
|
|
142
|
+
emitted by `apt-tools commit` when planner runs under a Conductor PTY
|
|
143
|
+
(`APERANT_TERMINAL_ID` set).
|
|
144
|
+
|
|
145
|
+
Every action you take appends an audit envelope. The framework writes
|
|
146
|
+
most of them for you when you call its tools.
|
|
147
|
+
|
|
148
|
+
## Output discipline
|
|
149
|
+
|
|
150
|
+
User-facing text per turn: one line per terminal you acted on, plus one
|
|
151
|
+
final summary. Examples:
|
|
152
|
+
|
|
153
|
+
- `T1: plan reviewed, 2 gaps → realignment sent (attempt 1).`
|
|
154
|
+
- `T3: plan approved → /apt:execute dispatched.`
|
|
155
|
+
- `T5: idle 8m, polling.`
|
|
156
|
+
- `Done. 4 tasks shipped, 1 wedged at T7 (handed back to you).`
|
|
157
|
+
|
|
158
|
+
NOT examples (forbidden):
|
|
159
|
+
- "I'll go ahead and spawn..."
|
|
160
|
+
- "Great question! Let me think through..."
|
|
161
|
+
- Multi-paragraph narration of your reasoning. Reason internally.
|
|
162
|
+
|
|
163
|
+
The chat thread is a control surface, not a journal.
|
|
164
|
+
|
|
165
|
+
## First turn
|
|
166
|
+
|
|
167
|
+
On first turn in a NEW thread (no prior assistant messages), one line:
|
|
168
|
+
|
|
169
|
+
`Conductor ready. Goal?`
|
|
170
|
+
|
|
171
|
+
Nothing else. No greeting paragraph. No tool list. The user knows what
|
|
172
|
+
you are.
|
|
@@ -88,6 +88,31 @@ Do NOT wait on the narrator. Its status lands in `.aperant/digests/.last-run.jso
|
|
|
88
88
|
|
|
89
89
|
After step 2.5 spawns narrators for the just-closed candidates, the skill ALSO drains `state.pending_narration[]` (entries the passive sweep parked there) — see §4.
|
|
90
90
|
|
|
91
|
+
## 2.6 Drop user-facing release-note fragment (persona-aware release-notes opt-in)
|
|
92
|
+
|
|
93
|
+
This step is additive bookkeeping — it must NEVER block the close path or surface a destructive failure. Runs ONLY when `.aperant/config.json` has `changelog.release_notes.enabled === true`. When the toggle is `false` (the default for projects that don't publish user-facing notes), skip the section entirely.
|
|
94
|
+
|
|
95
|
+
For each entry in the close-merged envelope's `closed[]`:
|
|
96
|
+
|
|
97
|
+
1. Read the merged PR body via `gh pr view <pr_number> --json body`. Look for a single `Release note:` line (case-insensitive). The line is what `/apt:ship` Section 2.6 auto-drafted (or a manual edit by the author).
|
|
98
|
+
2. Look for a persona tag in the PR body or in commits. Reasonable sources: the `Release note:` line itself if the author included one (e.g. `Release note: [Maya] …`), a `release-note-persona:` trailer in the most recent commit, or the persona name embedded in the auto-drafted line by §2.6.2 of /apt:ship.
|
|
99
|
+
3. Invoke the deterministic drafter:
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
node packages/framework/bin/apt-tools.mjs release-notes draft . \
|
|
103
|
+
--pr <pr_number> \
|
|
104
|
+
--note "<release-note-line-text>" \
|
|
105
|
+
[--persona <persona-name>]
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
This call is synchronous, sub-100ms, and idempotent per subtask 2 — re-running close-task does not duplicate the fragment.
|
|
109
|
+
|
|
110
|
+
4. On non-zero exit from `release-notes draft`, append a `pending_release_note[]` row to `.aperant/state.json` so a manual re-run can recover. Do NOT block close-merged on this — it is additive bookkeeping, not core lifecycle. Use `apt-tools state-update . --append-pending-release-note '{"task_id": "<id>", "pr_number": <n>, "reason": "<error>"}'` if such a helper exists, otherwise call `apt-tools state-artifacts . --note '<msg>'` or write a one-line warning to stderr.
|
|
111
|
+
|
|
112
|
+
Skip the section quietly when:
|
|
113
|
+
- The PR body has no `Release note:` line AND no auto-draft signal (intentional infra-only PR, or the `no-notes` label was applied at ship time).
|
|
114
|
+
- The CLI returns `{status: 'ok', written: false, reason: 'no-change'}` — already idempotent-handled by subtask 2's contract; treat as success.
|
|
115
|
+
|
|
91
116
|
## 3. Summary
|
|
92
117
|
|
|
93
118
|
close-merged emits an envelope with:
|
|
@@ -174,8 +174,38 @@ order: (a) consent gate, (b) renderer dispatch, (c) failure handling.
|
|
|
174
174
|
|
|
175
175
|
### 5a. Consent gate
|
|
176
176
|
|
|
177
|
-
|
|
178
|
-
|
|
177
|
+
Per FRAMEWORK-AUDIT-001, `mcpConsent` is per-user state and lives in
|
|
178
|
+
`.aperant/config.local.json` (gitignored), NOT the shared
|
|
179
|
+
`.aperant/config.json`. The `diagram.mode` field stays in `config.json` as
|
|
180
|
+
team policy. Read the MERGED config (config.json deep-merged with
|
|
181
|
+
config.local.json — local wins on collision) and look at
|
|
182
|
+
`diagram.mcpConsent` via the same in-skill `node -e` pattern Step 2 uses:
|
|
183
|
+
|
|
184
|
+
```bash
|
|
185
|
+
node -e '
|
|
186
|
+
const fs = require("fs");
|
|
187
|
+
const path = require("path");
|
|
188
|
+
const aperantDir = path.join(process.cwd(), ".aperant");
|
|
189
|
+
function readJson(p) {
|
|
190
|
+
try { return JSON.parse(fs.readFileSync(p, "utf-8")); } catch { return null; }
|
|
191
|
+
}
|
|
192
|
+
const shared = readJson(path.join(aperantDir, "config.json")) || {};
|
|
193
|
+
const local = readJson(path.join(aperantDir, "config.local.json")) || {};
|
|
194
|
+
// Deep-merge — local wins on collision; matches loadMergedProjectConfig semantics.
|
|
195
|
+
function merge(a, b) {
|
|
196
|
+
if (a === null || typeof a !== "object" || Array.isArray(a)) return b;
|
|
197
|
+
if (b === null || typeof b !== "object" || Array.isArray(b)) return b;
|
|
198
|
+
const out = { ...a };
|
|
199
|
+
for (const k of Object.keys(b)) out[k] = (k in a) ? merge(a[k], b[k]) : b[k];
|
|
200
|
+
return out;
|
|
201
|
+
}
|
|
202
|
+
const cfg = merge(shared, local);
|
|
203
|
+
const consent = cfg && cfg.diagram ? cfg.diagram.mcpConsent : null;
|
|
204
|
+
process.stdout.write(JSON.stringify(consent || null));
|
|
205
|
+
'
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
The shape is:
|
|
179
209
|
|
|
180
210
|
```json
|
|
181
211
|
{ "host": "<host string>", "decision": "granted" | "denied", "grantedAt": "<ISO 8601 timestamp>" }
|
|
@@ -196,7 +226,7 @@ Decide whether to prompt:
|
|
|
196
226
|
- If `diagram.mcpConsent.host !== <configured MCP host>` → prompt.
|
|
197
227
|
- If `diagram.mcpConsent.host === <configured MCP host>` AND `diagram.mcpConsent.decision === "denied"` → hard-error immediately with the exact denied text (no re-prompt):
|
|
198
228
|
```
|
|
199
|
-
diagram MCP consent denied; re-run with `--mode=file` or change diagram.mcpConsent in .aperant/config.json
|
|
229
|
+
diagram MCP consent denied; re-run with `--mode=file` or change diagram.mcpConsent in .aperant/config.local.json
|
|
200
230
|
```
|
|
201
231
|
- Otherwise (host matches AND decision is `"granted"`) → the existing consent applies; proceed to 5b.
|
|
202
232
|
|
|
@@ -206,23 +236,25 @@ When prompting, print a single line naming the host and ask `granted / denied`:
|
|
|
206
236
|
apt:diagram is about to send diagram data to the Excalidraw MCP server at <host>. Type `granted` to allow, `denied` to refuse.
|
|
207
237
|
```
|
|
208
238
|
|
|
209
|
-
Read one line of input. Persist the decision
|
|
210
|
-
`.aperant/config.json`
|
|
239
|
+
Read one line of input. Persist the decision to
|
|
240
|
+
`.aperant/config.local.json` (NOT `config.json` — `mcpConsent` is per-user
|
|
241
|
+
state per FRAMEWORK-AUDIT-001; the local file is gitignored). The
|
|
242
|
+
read-mutate-write JSON pattern targets the local file only:
|
|
211
243
|
|
|
212
244
|
```bash
|
|
213
245
|
node -e '
|
|
214
246
|
const fs = require("fs");
|
|
215
247
|
const path = require("path");
|
|
216
|
-
const cfgPath = path.join(process.cwd(), ".aperant/config.json");
|
|
248
|
+
const cfgPath = path.join(process.cwd(), ".aperant/config.local.json");
|
|
217
249
|
const decision = process.env.APT_DIAGRAM_DECISION; // "granted" | "denied"
|
|
218
250
|
if (decision !== "granted" && decision !== "denied") {
|
|
219
251
|
process.stderr.write("invalid decision\n");
|
|
220
252
|
process.exit(1);
|
|
221
253
|
}
|
|
222
254
|
const host = process.env.APT_DIAGRAM_HOST;
|
|
223
|
-
let cfg = { diagram: {
|
|
255
|
+
let cfg = { diagram: { mcpConsent: null } };
|
|
224
256
|
try { cfg = JSON.parse(fs.readFileSync(cfgPath, "utf-8")); } catch {}
|
|
225
|
-
cfg.diagram = cfg.diagram || {
|
|
257
|
+
cfg.diagram = cfg.diagram || { mcpConsent: null };
|
|
226
258
|
cfg.diagram.mcpConsent = {
|
|
227
259
|
host,
|
|
228
260
|
decision,
|
|
@@ -232,11 +264,15 @@ node -e '
|
|
|
232
264
|
'
|
|
233
265
|
```
|
|
234
266
|
|
|
267
|
+
Note: the write target above is `config.local.json` (gitignored, per-user).
|
|
268
|
+
The shared `config.json` is not touched — `diagram.mode` lives there and
|
|
269
|
+
stays team-shared policy.
|
|
270
|
+
|
|
235
271
|
If the decision is `"denied"`, exit with EXACTLY this text (verbatim,
|
|
236
272
|
no rewording, no extra punctuation):
|
|
237
273
|
|
|
238
274
|
```
|
|
239
|
-
diagram MCP consent denied; re-run with `--mode=file` or change diagram.mcpConsent in .aperant/config.json
|
|
275
|
+
diagram MCP consent denied; re-run with `--mode=file` or change diagram.mcpConsent in .aperant/config.local.json
|
|
240
276
|
```
|
|
241
277
|
|
|
242
278
|
If the decision is `"granted"`, proceed to 5b.
|
package/skills/apt-plan/SKILL.md
CHANGED
|
@@ -416,6 +416,18 @@ The coverage check ensures every acceptance criterion has at least one subtask w
|
|
|
416
416
|
node packages/framework/bin/apt-tools.mjs commit "plan: create implementation plan for {task}" --files spec.md implementation_plan.json
|
|
417
417
|
```
|
|
418
418
|
|
|
419
|
+
## 8a. Runtime-context adapters
|
|
420
|
+
|
|
421
|
+
If `APERANT_TERMINAL_ID` is set (you are running under the Aperant
|
|
422
|
+
Conductor — a master-orchestrator agent inside the Aperant app), see
|
|
423
|
+
`adapters/conductor.md` for the plan-review handshake convention
|
|
424
|
+
(`proceed` / `abort` / `[Conductor realignment]` stdin strings) the
|
|
425
|
+
Conductor's drawer uses post-commit. The `artifact.ready{kind:'plan'}`
|
|
426
|
+
signal itself is now emitted automatically by the `apt-tools commit`
|
|
427
|
+
postcondition — no manual emit step required. Native invocations
|
|
428
|
+
(Claude Code, Gemini, OpenCode, Codex with no Conductor context) can
|
|
429
|
+
skip the adapter entirely and proceed to Section 9.
|
|
430
|
+
|
|
419
431
|
## 9. Report
|
|
420
432
|
|
|
421
433
|
Output a summary:
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# apt-plan adapter — Aperant Conductor
|
|
2
|
+
|
|
3
|
+
This adapter is **only loaded** when the planner runs under the Aperant
|
|
4
|
+
Conductor (a master-orchestrator agent inside the Aperant desktop / web
|
|
5
|
+
app). Native invocations of `/apt:plan` (from plain Claude Code, Gemini
|
|
6
|
+
CLI, OpenCode, or Codex) IGNORE this file entirely — the framework
|
|
7
|
+
behavior in `SKILL.md` is the source of truth for them.
|
|
8
|
+
|
|
9
|
+
## When to load this adapter
|
|
10
|
+
|
|
11
|
+
Detect Conductor context by env var:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
[ -n "$APERANT_TERMINAL_ID" ]
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
The Conductor injects `APERANT_TERMINAL_ID` into every PTY it spawns.
|
|
18
|
+
If the var is unset, you are NOT under the Conductor — stop reading.
|
|
19
|
+
|
|
20
|
+
## What changes under the Conductor
|
|
21
|
+
|
|
22
|
+
The planner's filesystem outputs (`spec.md`, `implementation_plan.json`)
|
|
23
|
+
are unchanged. The ADDITION is one extra step after Section 8 (Persist
|
|
24
|
+
State) of `SKILL.md`:
|
|
25
|
+
|
|
26
|
+
### Plan-Ready Signal (framework-owned, no action required)
|
|
27
|
+
|
|
28
|
+
The `artifact.ready{kind:'plan'}` signal is emitted **automatically** by
|
|
29
|
+
the framework's `apt-tools commit` postcondition. When the planner
|
|
30
|
+
commits `spec.md` + `implementation_plan.json` via the standard:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
node packages/framework/bin/apt-tools.mjs commit "plan: ..." \
|
|
34
|
+
--files spec.md implementation_plan.json
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
…and the process is running under a Conductor PTY (env
|
|
38
|
+
`APERANT_TERMINAL_ID` is set), `apt-tools commit` auto-emits a fully-
|
|
39
|
+
formed `artifact.ready` envelope to `.aperant/events/{today}.jsonl`.
|
|
40
|
+
The envelope carries the `task_id`, plan path, sha256 hash, and the
|
|
41
|
+
auto-stamped `terminal_id`.
|
|
42
|
+
|
|
43
|
+
This replaces the earlier markdown-discipline emit step. The earlier
|
|
44
|
+
step was correctly skipped on QUICK / SIMPLE classified tasks (Fast
|
|
45
|
+
Path Guarantee, Pocock adoption ID-05) — moving the emit to a
|
|
46
|
+
framework postcondition makes it work uniformly across QUICK, STANDARD,
|
|
47
|
+
DEEP, and COMPLEX without violating the Fast Path Guarantee.
|
|
48
|
+
|
|
49
|
+
**Planner authors don't need to do anything.** As long as you call
|
|
50
|
+
`apt-tools commit` to land your plan artifacts, the Conductor will
|
|
51
|
+
see `artifact.ready` and the drawer's PlanReadyCard will auto-promote.
|
|
52
|
+
|
|
53
|
+
If the planner does NOT use `apt-tools commit` (it lands the plan via
|
|
54
|
+
raw `git commit` or `git add`), the auto-emit will not fire. In that
|
|
55
|
+
case the Conductor falls back to filesystem polling of the task dir
|
|
56
|
+
(slightly higher latency, same outcome).
|
|
57
|
+
|
|
58
|
+
### Plan-review handshake (Step 6 + 7 of Conductor v2)
|
|
59
|
+
|
|
60
|
+
After emitting `artifact.ready{kind:'plan'}` the planner SHOULD pause at
|
|
61
|
+
an idle prompt and listen for ONE of three Conductor-driven inputs:
|
|
62
|
+
|
|
63
|
+
- `proceed\r` — the human (via the PlanReadyCard's **Approve** button)
|
|
64
|
+
approves the plan. Continue to `/apt:execute` as you would in the
|
|
65
|
+
normal flow.
|
|
66
|
+
- `abort\r` — the human rejected. Abandon this plan; do not start
|
|
67
|
+
execution. Optionally exit the session cleanly.
|
|
68
|
+
- `[Conductor realignment] <note>\r` — the human pressed **Realign**.
|
|
69
|
+
Treat the `<note>` as additional planning context: re-open spec.md /
|
|
70
|
+
implementation_plan.json, address the note's gaps, commit a new
|
|
71
|
+
revision, and emit a fresh `artifact.ready{kind:'plan'}` (with the
|
|
72
|
+
same task_id but a NEW request_id — the drawer keys cards on
|
|
73
|
+
request_id, so re-using it would suppress the new card). The
|
|
74
|
+
realignment loop can repeat; after attempt_n >= 3 the Conductor may
|
|
75
|
+
decide to respawn the terminal entirely.
|
|
76
|
+
|
|
77
|
+
These exact strings are pinned by the Conductor's `ConductorContextHost`
|
|
78
|
+
handlers (`packages/ui/src/sections/conductor/ConductorContextHost.tsx`).
|
|
79
|
+
Native CLI invocations of `/apt:plan` (no `APERANT_TERMINAL_ID`) skip
|
|
80
|
+
this handshake and follow the normal report → `/apt:execute` flow.
|
|
81
|
+
|
|
82
|
+
## Why this lives in an adapter (not in SKILL.md)
|
|
83
|
+
|
|
84
|
+
The Aperant Framework is consumed by multiple CLIs (Claude Code, Gemini,
|
|
85
|
+
OpenCode, Codex) and by the Aperant app itself. The vast majority of
|
|
86
|
+
`/apt:plan` invocations come from native CLIs — those should not see
|
|
87
|
+
or execute Conductor-specific machinery. By isolating the Conductor's
|
|
88
|
+
event-emit obligations to this adapter, the public skill stays minimal
|
|
89
|
+
and the framework remains CLI-agnostic. The pattern mirrors
|
|
90
|
+
`appendices/` (reasoning-stance loaders) but with a different semantic:
|
|
91
|
+
**runtime-context loader** — load when the runtime environment matches.
|
|
92
|
+
|
|
93
|
+
## Adding more adapters
|
|
94
|
+
|
|
95
|
+
Future runtime contexts (e.g. a hypothetical CI runner, another
|
|
96
|
+
orchestrator) can add `adapters/{context}.md` files using the same
|
|
97
|
+
pattern: detect via env or filesystem signal, document the additional
|
|
98
|
+
obligations, and add a one-line conditional reference in `SKILL.md`.
|