deepclause-pi 0.1.5 → 0.3.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.
Files changed (49) hide show
  1. package/README.md +36 -0
  2. package/dist/diagram/extract.d.ts +5 -0
  3. package/dist/diagram/extract.js +701 -0
  4. package/dist/diagram/grade.d.ts +41 -0
  5. package/dist/diagram/grade.js +70 -0
  6. package/dist/diagram/validate.d.ts +36 -0
  7. package/dist/diagram/validate.js +148 -0
  8. package/dist/diagram/viewer.d.ts +36 -0
  9. package/dist/diagram/viewer.js +99 -0
  10. package/dist/diagram/workspace.d.ts +24 -0
  11. package/dist/diagram/workspace.js +106 -0
  12. package/dist/index.d.ts +8 -1
  13. package/dist/index.js +462 -17
  14. package/dist/model.d.ts +16 -0
  15. package/dist/model.js +28 -0
  16. package/dist/planner.d.ts +27 -2
  17. package/dist/planner.js +109 -4
  18. package/dist/runtime.d.ts +15 -1
  19. package/dist/runtime.js +116 -3
  20. package/dist/workspace.d.ts +3 -0
  21. package/dist/workspace.js +20 -0
  22. package/docs/DIAGRAM_INTEGRATION_PROPOSAL.md +154 -0
  23. package/docs/SPECKIT.md +222 -0
  24. package/docs/SPEC_LAYER_PROPOSAL.md +1893 -0
  25. package/package.json +1 -1
  26. package/src/assets/AGENTS.md +82 -0
  27. package/src/assets/apply.dml +188 -0
  28. package/src/assets/spec_apply.dml +20 -0
  29. package/src/assets/spec_archive.dml +11 -0
  30. package/src/assets/spec_coverage.dml +26 -0
  31. package/src/assets/spec_graph.dml +12 -0
  32. package/src/assets/spec_merge.dml +10 -0
  33. package/src/assets/spec_query.dml +10 -0
  34. package/src/assets/spec_scaffold.dml +10 -0
  35. package/src/assets/spec_status.dml +7 -0
  36. package/src/assets/spec_validate.dml +9 -0
  37. package/src/assets/specs.dml +991 -0
  38. package/src/assets/vendor/mermaid.min.js +3636 -0
  39. package/src/assets/viewer.template.html +319 -0
  40. package/src/diagram/extract.ts +721 -0
  41. package/src/diagram/grade.ts +104 -0
  42. package/src/diagram/validate.ts +188 -0
  43. package/src/diagram/viewer.ts +144 -0
  44. package/src/diagram/workspace.ts +109 -0
  45. package/src/index.ts +507 -16
  46. package/src/model.ts +46 -0
  47. package/src/planner.ts +123 -3
  48. package/src/runtime.ts +117 -2
  49. package/src/workspace.ts +24 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "deepclause-pi",
3
- "version": "0.1.5",
3
+ "version": "0.3.0",
4
4
  "description": "Pi-hosted runtime for DeepClause DML programs",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -52,6 +52,10 @@ Generated steps use `executor=dml` for contained model reasoning and `executor=p
52
52
 
53
53
  Contextual plans require explicit user execution with `/dc-run plans/<name>.dml` and confirmation. They cannot run through model-callable `dc_run`, because that would nest a pi agent turn inside the calling agent turn.
54
54
 
55
+ ### Change plans
56
+
57
+ `/dc-plan <request> --change=<slug>` targets a change instead of `plans/`. The same planning turn first creates `changes/<slug>/` with normal file tools (proposal.md, one delta spec per capability under `specs/`, optional design.md), then commits `changes/<slug>/tasks.dml`: `plan_task/2` facts with `satisfies` (scenario ids) and declarative `checks`, plus the managed `plan_task_status/2` block. Every step must declare at least one check. Re-running the same change without `--update` fails once `tasks.dml` exists; `--update` (or a leading `update` keyword) regenerates it and resets every status to pending. Review it with `/dc-check <slug>` and execute it with `/dc-apply <slug>`.
58
+
55
59
  ## Program structure and arguments
56
60
 
57
61
  Pi passes zero to three positional **strings** to `agent_main`:
@@ -375,6 +379,84 @@ DML is most valuable when an application needs more structure than a prompt and
375
379
 
376
380
  Poor fits include long-running background services, high-frequency shell automation that would require many approval prompts, workflows needing unrestricted pi tools, secret handling, or durable state without an explicit workspace storage design.
377
381
 
382
+ ## Diagrams
383
+
384
+ Pi can turn any DML file into a self-contained, offline Mermaid viewer. Ask for one in plain language:
385
+
386
+ > "Make a presentation-grade diagram of .pi/deepclause/skills/my_skill.dml"
387
+ > "Give me a specification-grade diagram of src/report.dml"
388
+
389
+ Pi calls the `dc_diagram` model tool with the DML path and a grade:
390
+
391
+ - **presentation** — about 8-12 nodes, plain language, headline numbers (slides and overviews).
392
+ - **specification** — function names, task/tool roles, post-conditions (engineers).
393
+
394
+ The tool extracts a deterministic Mermaid seed, has pi rewrite it in the chosen grade, validates the result, writes the viewer under `.pi/deepclause/diagrams/`, and opens it. The DML file may live anywhere (workspace-relative or absolute); only the generated viewer stays under `.pi/deepclause/`.
395
+
396
+ Do not hand-write Mermaid for the user, and do not copy diagram tooling into the workspace. Regenerating a grade replaces only that grade's sidecar (`<name>.presentation.mmd` / `<name>.specification.mmd`).
397
+
398
+ ## Specs and deltas
399
+
400
+ DeepClause keeps behaviour specs separate from executable plans:
401
+
402
+ - `.pi/deepclause/specs/**/*.spec.md` — capability specs, the source of truth for behaviour.
403
+ - `.pi/deepclause/changes/<slug>/specs/**/*.md` — change deltas.
404
+ - `.pi/deepclause/lib/specs.dml` — the deterministic parser/validator used by the spec skills.
405
+ - `.pi/deepclause/lib/apply.dml` — the task driver (verify, retry, status write-back).
406
+ - `.pi/deepclause/skills/spec_validate.dml`, `spec_status.dml`, `spec_query.dml`, `spec_graph.dml`.
407
+
408
+ `tasks.dml` uses `plan_task/2` and `plan_task_status/2` — **not** `task/2`, which collides with
409
+ DML's built-in `task/N` predicate and will not unify after being read.
410
+
411
+ Specs are plain Markdown and must describe **behaviour only** — no commands, file paths,
412
+ library choices, or implementation plans; those belong in `design.md` or `tasks.dml`.
413
+ Structure:
414
+
415
+ - `## Purpose`
416
+ - `### Requirement: <name>` followed by prose using SHALL / MUST / SHOULD
417
+ - `#### Scenario: <name>` with `- **WHEN**` and `- **THEN**` (exactly four hashes)
418
+
419
+ Delta files wrap requirements in `## ADDED Requirements`, `## MODIFIED Requirements`,
420
+ `## REMOVED Requirements`, or `## RENAMED Requirements`. `MODIFIED` carries the full
421
+ replacement requirement.
422
+
423
+ Validate and inspect without spending model tokens:
424
+
425
+ - `/dc-check` — parse and validate every spec and delta; reports 3-hash scenarios, missing
426
+ scenarios and duplicates with line numbers.
427
+ - `/dc-run spec_status` — capability and delta inventory.
428
+ - `/dc-run spec_query <capability>` — one capability's requirements and scenarios.
429
+ - `/dc-run spec_graph capabilities|changes` — deterministic Mermaid graph.
430
+ - `/dc-run spec_merge <change>` — preview the delta merge into `specs/` (read-only).
431
+ - `/dc-run spec_coverage <change>` — which delta scenarios are covered by `tasks.dml`,
432
+ which tasks lack checks, and which `satisfies` ids are unknown. `/dc-check` reports the
433
+ same coverage and treats uncovered scenarios as errors once a `tasks.dml` exists.
434
+ - `/dc-run spec_scaffold <change>` — print a draft `tasks.dml` with one task per delta
435
+ scenario (read-only; fill in executor, tools, expected and checks).
436
+ - `/dc-run spec_apply <change> plan` — list the tasks and the approved verification commands
437
+ (read-only).
438
+ - `/dc-apply <change>` — execute the remaining tasks, verify each task's declarative checks
439
+ (`exists`, `cmd`, `model`), retry with the failure feedback (up to 3 attempts), and rewrite the
440
+ `plan_task_status/2` block in `tasks.dml`. The `cmd(...)` set is approved once before the run;
441
+ each command runs through the allowlisted `dc_verify_run` tool. A git snapshot is recorded first
442
+ (in `change.json`, with `applyState`). If the run does not finish, the working tree and the
443
+ `done`/`failed` statuses are **preserved**: re-run `/dc-apply <change>` to resume from the
444
+ remaining tasks, or `/dc-apply <change> --abort` to discard the apply and restore the snapshot.
445
+ A dirty tree refuses a fresh snapshot, so the apply then proceeds without rollback.
446
+
447
+ After `/dc-plan`, `/dc-apply` and `/dc-archive` leave uncommitted changes, the extension offers
448
+ to commit them (`git add -A` with a suggested message) or reminds you to. A clean tree is what
449
+ lets the next `/dc-apply` take a rollback snapshot; consider gitignoring
450
+ `.pi/deepclause/diagrams/` and `.pi/deepclause/changes/*/change.json`.
451
+ - `/dc-archive <change>` — show the preview, confirm, write the merged spec, then move the
452
+ change to `changes/archive/`. The DML step (`spec_archive.dml`) is marked `% Mutating: true`,
453
+ so `/dc-run` refuses it directly; always archive through `/dc-archive` so the merge is reviewed
454
+ first and the change folder is moved.
455
+ - `dc_spec_graph` — pi tool that renders the capability/change graph in the diagram viewer.
456
+
457
+ These skills are pure DML utilities: do not add model calls or runtime tools to them, and do
458
+ not rewrite the parser by hand.
459
+
378
460
  ## Conservative editing rules
379
461
 
380
462
  When modifying an existing skill:
@@ -0,0 +1,188 @@
1
+ %%% apply.dml — deterministic task driver, consulted by spec_apply.dml.
2
+ %%%
3
+ %%% Reads changes/<change>/tasks.dml (plan_task/2 + plan_task_status/2),
4
+ %%% executes the remaining tasks, verifies each task's checks, retries with
5
+ %%% feedback, and rewrites the managed status block.
6
+ %%%
7
+ %%% Execution is delegated per task: executor=pi calls the pi_agent_step bridge;
8
+ %%% executor=dml uses task/N with the current model. Checks are declarative:
9
+ %%% exists(Path), cmd(Command), model(Question).
10
+
11
+ :- consult('.pi/deepclause/lib/specs.dml').
12
+
13
+ sp_change_dir(Change, Dir) :- atomic_list_concat([".pi/deepclause/changes/", Change], Dir).
14
+
15
+ file_exists(Path) :-
16
+ ( atom_string(PathAtom, Path)
17
+ -> true
18
+ ; PathAtom = Path
19
+ ),
20
+ catch((open(PathAtom, read, Stream), close(Stream)), _, fail).
21
+
22
+ remaining_tasks(Tasks, Statuses, Remaining) :-
23
+ findall(plan_task(Id, Props), (
24
+ member(plan_task(Id, Props), Tasks),
25
+ \+ sp_status_done(Statuses, Id)
26
+ ), Remaining).
27
+
28
+ %% Snapshot/accept are optional: without the tools (or outside git) the apply just
29
+ %% proceeds without rollback, and the report says so.
30
+ take_snapshot(Snap) :-
31
+ ( catch(exec(dc_apply_snapshot, S), Err, S = error(Err)),
32
+ nonvar(S)
33
+ -> Snap = S
34
+ ; Snap = none
35
+ ).
36
+
37
+ accept_apply(none) :- !.
38
+ accept_apply(error(_)) :- !.
39
+ accept_apply(_) :- catch(exec(dc_apply_accept, _), _, true).
40
+
41
+ rollback_line(none, "rollback: unavailable (snapshot tool inactive or not a git repo)").
42
+ rollback_line(error(Err), Line) :- !, format(string(Line), "rollback: unavailable (~w)", [Err]).
43
+ rollback_line(Ref, Line) :-
44
+ format(string(Line), "rollback: snapshot ~w recorded (restored by /dc-apply on a non-OK run)", [Ref]).
45
+
46
+ run_plan(Change, Max, Report) :-
47
+ sp_change_dir(Change, Dir),
48
+ atomic_list_concat([Dir, "/tasks.dml"], TasksPath),
49
+ sp_tasks(Dir, Tasks),
50
+ take_snapshot(Snap),
51
+ sp_task_statuses(Dir, Statuses0),
52
+ remaining_tasks(Tasks, Statuses0, Remaining),
53
+ length(Tasks, Total),
54
+ length(Remaining, RemainingCount),
55
+ format(string(Start), "apply ~w: ~w tasks, ~w remaining, max ~w attempts", [Change, Total, RemainingCount, Max]),
56
+ output(Start),
57
+ run_all(TasksPath, Change, Remaining, Max, Statuses0, Statuses),
58
+ sp_task_statuses(Dir, FinalStatuses),
59
+ findall(Id, (member(plan_task(Id, _), Tasks), \+ sp_status_done(FinalStatuses, Id)), Outstanding),
60
+ length(Outstanding, OutstandingCount),
61
+ Done is Total - OutstandingCount,
62
+ sp_count_repairs(FinalStatuses, Repairs),
63
+ format(string(Header), "apply ~w: ~w/~w tasks verified (~w repairs)", [Change, Done, Total, Repairs]),
64
+ ( OutstandingCount =:= 0
65
+ -> accept_apply(Snap),
66
+ Result = ["status: OK"]
67
+ ; findall(Line, (member(Id, Outstanding), format(string(Line), " outstanding: ~w", [Id])), Lines),
68
+ Result = ["status: INCOMPLETE"|Lines]
69
+ ),
70
+ rollback_line(Snap, RollbackLine),
71
+ append([Header], Result, Body0),
72
+ append(Body0, [RollbackLine], Body),
73
+ atomics_to_string(Body, "\n", Report).
74
+
75
+ run_all(_, _, [], _, Statuses, Statuses).
76
+ run_all(TasksPath, Change, [plan_task(Id, Props)|Rest], Max, Statuses0, Statuses) :-
77
+ run_task(TasksPath, Statuses0, Change, Id, Props, Max, Statuses1),
78
+ run_all(TasksPath, Change, Rest, Max, Statuses1, Statuses).
79
+
80
+ run_task(TasksPath, Statuses0, Change, Id, Props, Max, Statuses) :-
81
+ attempt(TasksPath, Statuses0, Change, Id, Props, 1, Max, none, Statuses).
82
+
83
+ attempt(TasksPath, Statuses0, Change, Id, Props, N, Max, Feedback, Statuses) :-
84
+ N =< Max,
85
+ format(string(Progress), "task ~w attempt ~w/~w", [Id, N, Max]),
86
+ output(Progress),
87
+ execute(Change, Id, Props, Feedback, Summary),
88
+ verify(Props, Summary, Verdict),
89
+ ( Verdict = ok
90
+ -> sp_set_status(Statuses0, Id, done(N), Statuses),
91
+ sp_write_statuses(TasksPath, Statuses),
92
+ format(string(Done), "task ~w verified on attempt ~w", [Id, N]),
93
+ output(Done)
94
+ ; Verdict = fail(Evidence),
95
+ N1 is N + 1,
96
+ sp_set_status(Statuses0, Id, failed(N1, Evidence), Statuses1),
97
+ sp_write_statuses(TasksPath, Statuses1),
98
+ format(string(Msg), "task ~w failed verification: ~w", [Id, Evidence]),
99
+ output(Msg),
100
+ attempt(TasksPath, Statuses1, Change, Id, Props, N1, Max, Evidence, Statuses)
101
+ ).
102
+ attempt(_, Statuses, _, Id, _, N, Max, _, Statuses) :-
103
+ N > Max,
104
+ format(string(Msg), "task ~w exhausted ~w attempts", [Id, Max]),
105
+ output(Msg).
106
+
107
+ execute(Change, Id, Props, Feedback, Summary) :-
108
+ catch(get_dict(executor, Props, Executor), _, Executor = dml),
109
+ catch(get_dict(do, Props, Do), _, Do = ""),
110
+ catch(get_dict(expected, Props, Expected), _, Expected = ""),
111
+ build_instruction(Id, Do, Expected, Feedback, Instruction),
112
+ ( Executor == pi
113
+ -> catch(get_dict(tools, Props, Tools), _, Tools = []),
114
+ exec(pi_agent_step(instruction: Instruction, tools: Tools, expected: Expected, skills: []), Summary)
115
+ ; task(Instruction, string(Summary))
116
+ ).
117
+
118
+ build_instruction(Id, Do, Expected, none, Instruction) :-
119
+ format(string(Instruction), "Task ~w. ~w~nExpected result: ~w", [Id, Do, Expected]).
120
+ build_instruction(Id, Do, Expected, Feedback, Instruction) :-
121
+ Feedback \= none,
122
+ format(string(Instruction),
123
+ "Task ~w. ~w~nExpected result: ~w~n~nThe previous attempt failed verification: ~w~nFix only what is needed; do not redo the whole task.",
124
+ [Id, Do, Expected, Feedback]).
125
+
126
+ verify(Props, Summary, Verdict) :-
127
+ catch(get_dict(checks, Props, Checks), _, Checks = []),
128
+ findall(Message, (member(Check, Checks), run_check(Check, Message), Message \= ok), Failures),
129
+ ( Summary == ""
130
+ -> Verdict = fail("delegated step returned no summary")
131
+ ; Failures == []
132
+ -> Verdict = ok
133
+ ; atomic_list_concat(Failures, "; ", Evidence),
134
+ Verdict = fail(Evidence)
135
+ ).
136
+
137
+ run_check(exists(Path), Result) :-
138
+ ( file_exists(Path)
139
+ -> Result = ok
140
+ ; format(string(Result), "missing artifact ~w", [Path])
141
+ ).
142
+ run_check(cmd(Command), Result) :- run_check(cmd(Command, 1), Result).
143
+ run_check(cmd(Command, _), Result) :-
144
+ catch(exec(dc_verify_run(command: Command), Dict), Err, Dict = error(Err)),
145
+ ( Dict = error(Err)
146
+ -> format(string(Result), "command error: ~w", [Err])
147
+ ; get_dict(exitCode, Dict, Code),
148
+ ( Code =:= 0
149
+ -> Result = ok
150
+ ; catch(get_dict(stderr, Dict, ErrText), _, ErrText = ""),
151
+ normalize_space(string(Short), ErrText),
152
+ format(string(Result), "command failed: ~w (~w)", [Command, Short])
153
+ )
154
+ ).
155
+ run_check(model(Question), Result) :-
156
+ format(string(Instruction), "Verify by inspection only; do not modify. ~w Reply PASS or FAIL with a short reason.", [Question]),
157
+ catch(exec(pi_agent_step(instruction: Instruction, tools: ["read"], expected: "PASS or FAIL", skills: []), Verdict), _, Verdict = ""),
158
+ ( sub_string(Verdict, _, _, _, "PASS")
159
+ -> Result = ok
160
+ ; format(string(Result), "model check failed: ~w", [Verdict])
161
+ ).
162
+
163
+ check_command(cmd(Command), Command) :- !.
164
+ check_command(cmd(Command, _), Command) :- !.
165
+
166
+ plan_report(Change, Report) :-
167
+ sp_change_dir(Change, Dir),
168
+ sp_tasks(Dir, Tasks),
169
+ length(Tasks, Total),
170
+ findall(Line, (
171
+ member(plan_task(Id, Props), Tasks),
172
+ catch(get_dict(checks, Props, Checks), _, Checks = []),
173
+ catch(get_dict(do, Props, Do), _, Do = ""),
174
+ format(string(Line), " task ~w: ~w checks: ~w", [Id, Do, Checks])
175
+ ), Lines),
176
+ findall(Command, (
177
+ member(plan_task(_, Props), Tasks),
178
+ catch(get_dict(checks, Props, Checks), _, Checks = []),
179
+ member(Check, Checks),
180
+ check_command(Check, Command)
181
+ ), Commands0),
182
+ sort(Commands0, Commands),
183
+ findall(CommandLine, (member(Command, Commands), format(string(CommandLine), "command: ~w", [Command])), CommandLines),
184
+ format(string(Header), "apply plan ~w: ~w tasks", [Change, Total]),
185
+ append([Header], Lines, A),
186
+ append(A, [""], B),
187
+ append(B, CommandLines, Body),
188
+ atomics_to_string(Body, "\n", Report).
@@ -0,0 +1,20 @@
1
+ % spec_apply — execute a change's tasks.dml with verification and bounded retries.
2
+ % Mutating: true
3
+ % Usage: /dc-run spec_apply <change> (or /dc-apply <change>)
4
+ % /dc-run spec_apply <change> plan (preview, read-only)
5
+ :- consult('.pi/deepclause/lib/apply.dml').
6
+
7
+ agent_main(Change, "plan") :-
8
+ plan_report(Change, Report),
9
+ answer(Report).
10
+
11
+ agent_main(Change) :-
12
+ run_plan(Change, 3, Report),
13
+ answer(Report).
14
+
15
+ agent_main(Change, _Mode) :-
16
+ run_plan(Change, 3, Report),
17
+ answer(Report).
18
+
19
+ agent_main :-
20
+ answer("usage: /dc-run spec_apply <change> [plan]").
@@ -0,0 +1,11 @@
1
+ % spec_archive — merge a change delta into specs/ and move the change to archive/.
2
+ % Mutating: true
3
+ % Usage: /dc-run spec_archive <change>
4
+ :- consult('.pi/deepclause/lib/specs.dml').
5
+
6
+ agent_main(Change) :-
7
+ sp_archive(Change, apply, Report),
8
+ answer(Report).
9
+
10
+ agent_main :-
11
+ answer("usage: /dc-run spec_archive <change>").
@@ -0,0 +1,26 @@
1
+ % spec_coverage — scenario coverage of a change by its tasks.dml.
2
+ % Usage: /dc-run spec_coverage <change>
3
+ :- consult('.pi/deepclause/lib/specs.dml').
4
+
5
+ agent_main(Change) :-
6
+ atomic_list_concat([".pi/deepclause/changes/", Change], ChangeDir),
7
+ sp_coverage(ChangeDir, Scenarios, Tasks, Uncovered, NoCheck, Orphan),
8
+ length(Scenarios, ScenarioCount),
9
+ length(Tasks, TaskCount),
10
+ length(Uncovered, UncoveredCount),
11
+ Covered is ScenarioCount - UncoveredCount,
12
+ format(string(Header), "scenario coverage ~w: ~w/~w covered, ~w tasks", [Change, Covered, ScenarioCount, TaskCount]),
13
+ ( Uncovered == []
14
+ -> UncoveredLines = [" all scenarios covered"]
15
+ ; findall(Line, (member(Id, Uncovered), format(string(Line), " uncovered: ~w", [Id])), UncoveredLines)
16
+ ),
17
+ findall(Line2, (member(Id, NoCheck), format(string(Line2), " task without checks: ~w", [Id])), NoCheckLines),
18
+ findall(Line3, (member(Id, Orphan), format(string(Line3), " satisfies unknown scenario: ~w", [Id])), OrphanLines),
19
+ append([Header], UncoveredLines, A),
20
+ append(A, NoCheckLines, B),
21
+ append(B, OrphanLines, Body),
22
+ atomics_to_string(Body, "\n", Report),
23
+ answer(Report).
24
+
25
+ agent_main :-
26
+ answer("usage: /dc-run spec_coverage <change>").
@@ -0,0 +1,12 @@
1
+ % spec_graph — deterministic Mermaid graphs of specs and changes.
2
+ % Usage: /dc-run spec_graph [capabilities|changes]
3
+ % Views: capabilities (default), changes.
4
+ :- consult('.pi/deepclause/lib/specs.dml').
5
+
6
+ agent_main :-
7
+ sp_graph(capabilities, Mermaid),
8
+ answer(Mermaid).
9
+
10
+ agent_main(View) :-
11
+ sp_graph(View, Mermaid),
12
+ answer(Mermaid).
@@ -0,0 +1,10 @@
1
+ % spec_merge — preview merging a change delta into specs/ (read-only).
2
+ % Usage: /dc-run spec_merge <change>
3
+ :- consult('.pi/deepclause/lib/specs.dml').
4
+
5
+ agent_main(Change) :-
6
+ sp_archive(Change, plan, Report),
7
+ answer(Report).
8
+
9
+ agent_main :-
10
+ answer("usage: /dc-run spec_merge <change>").
@@ -0,0 +1,10 @@
1
+ % spec_query — deterministic capability inspector.
2
+ % Usage: /dc-run spec_query <capability> e.g. /dc-run spec_query ui/theme
3
+ :- consult('.pi/deepclause/lib/specs.dml').
4
+
5
+ agent_main(Capability) :-
6
+ sp_query(Capability, Report),
7
+ answer(Report).
8
+
9
+ agent_main :-
10
+ answer("usage: /dc-run spec_query <capability> e.g. ui/theme").
@@ -0,0 +1,10 @@
1
+ % spec_scaffold — draft a tasks.dml for a change from its delta scenarios (read-only).
2
+ % Usage: /dc-run spec_scaffold <change>
3
+ :- consult('.pi/deepclause/lib/specs.dml').
4
+
5
+ agent_main(Change) :-
6
+ sp_scaffold(Change, Draft),
7
+ answer(Draft).
8
+
9
+ agent_main :-
10
+ answer("usage: /dc-run spec_scaffold <change>").
@@ -0,0 +1,7 @@
1
+ % spec_status — deterministic spec/delta inventory.
2
+ % Usage: /dc-run spec_status
3
+ :- consult('.pi/deepclause/lib/specs.dml').
4
+
5
+ agent_main :-
6
+ sp_status(Report),
7
+ answer(Report).
@@ -0,0 +1,9 @@
1
+ % spec_validate — deterministic spec/delta validation.
2
+ % Usage: /dc-run spec_validate
3
+ % Pure DML: no model calls, no runtime tools. Reports structural errors with
4
+ % line numbers (3-hash scenarios, missing scenarios, duplicates).
5
+ :- consult('.pi/deepclause/lib/specs.dml').
6
+
7
+ agent_main :-
8
+ sp_check_all(Report),
9
+ answer(Report).