deepclause-pi 0.2.0 → 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.
- package/README.md +13 -0
- package/dist/diagram/viewer.d.ts +6 -0
- package/dist/diagram/viewer.js +5 -0
- package/dist/index.d.ts +8 -1
- package/dist/index.js +323 -18
- package/dist/planner.d.ts +27 -2
- package/dist/planner.js +109 -4
- package/dist/runtime.d.ts +15 -1
- package/dist/runtime.js +116 -3
- package/dist/workspace.d.ts +3 -0
- package/dist/workspace.js +20 -0
- package/docs/SPECKIT.md +222 -0
- package/docs/SPEC_LAYER_PROPOSAL.md +1893 -0
- package/package.json +1 -1
- package/src/assets/AGENTS.md +66 -0
- package/src/assets/apply.dml +188 -0
- package/src/assets/spec_apply.dml +20 -0
- package/src/assets/spec_archive.dml +11 -0
- package/src/assets/spec_coverage.dml +26 -0
- package/src/assets/spec_graph.dml +12 -0
- package/src/assets/spec_merge.dml +10 -0
- package/src/assets/spec_query.dml +10 -0
- package/src/assets/spec_scaffold.dml +10 -0
- package/src/assets/spec_status.dml +7 -0
- package/src/assets/spec_validate.dml +9 -0
- package/src/assets/specs.dml +991 -0
- package/src/diagram/viewer.ts +11 -0
- package/src/index.ts +351 -16
- package/src/planner.ts +123 -3
- package/src/runtime.ts +117 -2
- package/src/workspace.ts +24 -0
package/package.json
CHANGED
package/src/assets/AGENTS.md
CHANGED
|
@@ -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`:
|
|
@@ -391,6 +395,68 @@ The tool extracts a deterministic Mermaid seed, has pi rewrite it in the chosen
|
|
|
391
395
|
|
|
392
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`).
|
|
393
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
|
+
|
|
394
460
|
## Conservative editing rules
|
|
395
461
|
|
|
396
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,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).
|