@xenonbyte/da-vinci-workflow 0.2.3 → 0.2.4

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 (41) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/README.md +32 -7
  3. package/README.zh-CN.md +151 -7
  4. package/commands/claude/dv/build.md +5 -0
  5. package/commands/claude/dv/continue.md +4 -0
  6. package/commands/claude/dv/tasks.md +6 -0
  7. package/commands/claude/dv/verify.md +2 -0
  8. package/commands/codex/prompts/dv-build.md +5 -0
  9. package/commands/codex/prompts/dv-continue.md +4 -0
  10. package/commands/codex/prompts/dv-tasks.md +6 -0
  11. package/commands/codex/prompts/dv-verify.md +2 -0
  12. package/commands/gemini/dv/build.toml +5 -0
  13. package/commands/gemini/dv/continue.toml +4 -0
  14. package/commands/gemini/dv/tasks.toml +6 -0
  15. package/commands/gemini/dv/verify.toml +2 -0
  16. package/commands/templates/dv-continue.shared.md +4 -0
  17. package/docs/discipline-and-orchestration-upgrade.md +83 -0
  18. package/docs/dv-command-reference.md +18 -2
  19. package/docs/execution-chain-migration.md +23 -0
  20. package/docs/prompt-entrypoints.md +5 -0
  21. package/docs/skill-usage.md +16 -0
  22. package/docs/workflow-overview.md +17 -0
  23. package/docs/zh-CN/dv-command-reference.md +16 -2
  24. package/docs/zh-CN/execution-chain-migration.md +23 -0
  25. package/docs/zh-CN/prompt-entrypoints.md +5 -0
  26. package/docs/zh-CN/skill-usage.md +16 -0
  27. package/docs/zh-CN/workflow-overview.md +17 -0
  28. package/lib/audit-parsers.js +148 -1
  29. package/lib/cli.js +106 -1
  30. package/lib/execution-profile.js +143 -0
  31. package/lib/execution-signals.js +19 -1
  32. package/lib/lint-tasks.js +86 -2
  33. package/lib/planning-parsers.js +255 -18
  34. package/lib/supervisor-review.js +2 -1
  35. package/lib/task-execution.js +160 -0
  36. package/lib/task-review.js +197 -0
  37. package/lib/verify.js +152 -1
  38. package/lib/workflow-state.js +452 -30
  39. package/lib/worktree-preflight.js +214 -0
  40. package/package.json +1 -1
  41. package/references/artifact-templates.md +56 -6
@@ -0,0 +1,214 @@
1
+ const fs = require("fs");
2
+ const path = require("path");
3
+ const { spawnSync } = require("child_process");
4
+ const { STATUS } = require("./workflow-contract");
5
+
6
+ function runGit(projectRoot, args) {
7
+ return spawnSync("git", args, {
8
+ cwd: projectRoot,
9
+ encoding: "utf8",
10
+ maxBuffer: 8 * 1024 * 1024
11
+ });
12
+ }
13
+
14
+ function checkIgnoredDirectory(projectRoot, directoryPath) {
15
+ const relativePath = path.relative(projectRoot, directoryPath) || path.basename(directoryPath);
16
+ const result = runGit(projectRoot, ["check-ignore", relativePath]);
17
+ if (result.error) {
18
+ return {
19
+ directory: directoryPath,
20
+ relativePath,
21
+ ignored: false,
22
+ error: `failed to execute git check-ignore: ${result.error.message || "unknown error"}`
23
+ };
24
+ }
25
+ if (result.status === 0) {
26
+ return {
27
+ directory: directoryPath,
28
+ relativePath,
29
+ ignored: true,
30
+ error: null
31
+ };
32
+ }
33
+ if (result.status === 1) {
34
+ return {
35
+ directory: directoryPath,
36
+ relativePath,
37
+ ignored: false,
38
+ error: null
39
+ };
40
+ }
41
+ const statusText = Number.isFinite(result.status) ? `exit ${result.status}` : "unknown status";
42
+ const stderr = String(result.stderr || "").trim();
43
+ return {
44
+ directory: directoryPath,
45
+ relativePath,
46
+ ignored: false,
47
+ error: `git check-ignore failed (${statusText})${stderr ? `: ${stderr}` : ""}`
48
+ };
49
+ }
50
+
51
+ function readPackageScripts(projectRoot) {
52
+ const packagePath = path.join(projectRoot, "package.json");
53
+ if (!fs.existsSync(packagePath)) {
54
+ return {};
55
+ }
56
+ try {
57
+ const payload = JSON.parse(fs.readFileSync(packagePath, "utf8"));
58
+ return payload && payload.scripts && typeof payload.scripts === "object" ? payload.scripts : {};
59
+ } catch (_error) {
60
+ return {};
61
+ }
62
+ }
63
+
64
+ function runWorktreePreflight(projectPathInput, options = {}) {
65
+ const projectRoot = path.resolve(projectPathInput || process.cwd());
66
+ const findings = {
67
+ failures: [],
68
+ warnings: [],
69
+ notes: []
70
+ };
71
+
72
+ const candidateDirs = [".worktrees", "worktrees"]
73
+ .map((name) => path.join(projectRoot, name))
74
+ .filter((candidate) => fs.existsSync(candidate));
75
+ const gitStatus = runGit(projectRoot, ["status", "--porcelain"]);
76
+ const gitStatusSummary = {
77
+ healthy: false,
78
+ exitCode: Number.isFinite(gitStatus.status) ? gitStatus.status : null,
79
+ message: ""
80
+ };
81
+ const dirtyEntries = [];
82
+ if (gitStatus.error) {
83
+ gitStatusSummary.message = `failed to execute git status: ${gitStatus.error.message || "unknown error"}`;
84
+ findings.warnings.push(
85
+ "Unable to execute `git status`; worktree-isolation preflight cannot be trusted in the current environment."
86
+ );
87
+ } else if (gitStatus.status !== 0) {
88
+ const stderr = String(gitStatus.stderr || "").trim();
89
+ gitStatusSummary.message = stderr || "git status returned non-zero exit";
90
+ if (/not a git repository/i.test(stderr)) {
91
+ findings.warnings.push(
92
+ "Current project is not a git repository; worktree-isolation preflight is advisory-only and recommends isolation."
93
+ );
94
+ } else {
95
+ findings.warnings.push(
96
+ `git status failed (${gitStatusSummary.exitCode !== null ? gitStatusSummary.exitCode : "unknown exit"}); worktree-isolation checks may be unreliable.`
97
+ );
98
+ }
99
+ } else {
100
+ gitStatusSummary.healthy = true;
101
+ const lines = String(gitStatus.stdout || "")
102
+ .split(/\r?\n/)
103
+ .map((line) => line.trim())
104
+ .filter(Boolean);
105
+ dirtyEntries.push(...lines);
106
+ }
107
+
108
+ const ignoreChecks = [];
109
+ if (candidateDirs.length > 0) {
110
+ if (!gitStatusSummary.healthy) {
111
+ findings.warnings.push(
112
+ "Skipped git-ignore safety checks for worktree directories because git status is unavailable."
113
+ );
114
+ } else {
115
+ for (const candidate of candidateDirs) {
116
+ const check = checkIgnoredDirectory(projectRoot, candidate);
117
+ ignoreChecks.push(check);
118
+ if (check.error) {
119
+ findings.warnings.push(
120
+ `Unable to verify git-ignore state for ${check.relativePath}: ${check.error}`
121
+ );
122
+ continue;
123
+ }
124
+ if (!check.ignored) {
125
+ findings.failures.push(
126
+ `Worktree directory ${check.relativePath} is not git-ignored; isolation setup is unsafe.`
127
+ );
128
+ } else {
129
+ findings.notes.push(`Worktree directory ${check.relativePath} is git-ignored.`);
130
+ }
131
+ }
132
+ }
133
+ }
134
+
135
+ if (dirtyEntries.length > 0) {
136
+ findings.warnings.push(
137
+ `Workspace is dirty (${dirtyEntries.length} change(s)); isolated execution is recommended before bounded parallel work.`
138
+ );
139
+ }
140
+
141
+ const scripts = readPackageScripts(projectRoot);
142
+ if (!scripts.test) {
143
+ findings.warnings.push("No `test` script found in package.json; baseline verification heuristics are weak.");
144
+ } else {
145
+ findings.notes.push("Detected package.json test script for baseline verification checks.");
146
+ }
147
+
148
+ if (candidateDirs.length === 0) {
149
+ findings.notes.push("No project-local worktree directory found (.worktrees/ or worktrees/).");
150
+ }
151
+
152
+ const status =
153
+ findings.failures.length > 0
154
+ ? STATUS.BLOCK
155
+ : findings.warnings.length > 0
156
+ ? STATUS.WARN
157
+ : STATUS.PASS;
158
+
159
+ const recommendedIsolation =
160
+ dirtyEntries.length > 0 ||
161
+ options.parallelPreferred === true ||
162
+ findings.failures.length > 0 ||
163
+ !gitStatusSummary.healthy;
164
+
165
+ return {
166
+ status,
167
+ advisory: true,
168
+ projectRoot,
169
+ failures: findings.failures,
170
+ warnings: findings.warnings,
171
+ notes: findings.notes,
172
+ summary: {
173
+ worktreeDirectories: candidateDirs.map((candidate) => path.relative(projectRoot, candidate)),
174
+ ignoreChecks,
175
+ dirtyEntries: dirtyEntries.length,
176
+ gitStatus: gitStatusSummary,
177
+ recommendedIsolation
178
+ }
179
+ };
180
+ }
181
+
182
+ function formatWorktreePreflightReport(result) {
183
+ const lines = [
184
+ "Worktree preflight",
185
+ `Project: ${result.projectRoot}`,
186
+ `Status: ${result.status}`,
187
+ `Advisory: ${result.advisory ? "yes" : "no"}`,
188
+ `Recommended isolation: ${result.summary.recommendedIsolation ? "yes" : "no"}`
189
+ ];
190
+ if (result.failures.length > 0) {
191
+ lines.push("Failures:");
192
+ for (const failure of result.failures) {
193
+ lines.push(`- ${failure}`);
194
+ }
195
+ }
196
+ if (result.warnings.length > 0) {
197
+ lines.push("Warnings:");
198
+ for (const warning of result.warnings) {
199
+ lines.push(`- ${warning}`);
200
+ }
201
+ }
202
+ if (result.notes.length > 0) {
203
+ lines.push("Notes:");
204
+ for (const note of result.notes) {
205
+ lines.push(`- ${note}`);
206
+ }
207
+ }
208
+ return lines.join("\n");
209
+ }
210
+
211
+ module.exports = {
212
+ runWorktreePreflight,
213
+ formatWorktreePreflightReport
214
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xenonbyte/da-vinci-workflow",
3
- "version": "0.2.3",
3
+ "version": "0.2.4",
4
4
  "description": "Requirement-to-design-to-code workflow skill for Codex, Claude, and Gemini",
5
5
  "bin": {
6
6
  "da-vinci": "bin/da-vinci.js",
@@ -662,21 +662,46 @@ Use this structure:
662
662
  ```md
663
663
  # Tasks
664
664
 
665
+ ## Discipline Markers (Machine-readable)
666
+ - design_approval: approved @ <ISO-8601 timestamp>
667
+ - plan_self_review: complete @ <ISO-8601 timestamp>
668
+ - operator_review_ack: accepted @ <ISO-8601 timestamp>
669
+
665
670
  ## 1. Setup
666
- - [ ] Project or page setup
671
+ - [ ] 1.1 Project or page setup
672
+ - Target files: `<repo path>`
673
+ - Verification command: `<exact command>`
674
+ - Execution intent: `serial`
675
+ - Review intent: `true`
667
676
 
668
677
  ## 2. UI Structure
669
- - [ ] Implement major sections from Pencil
678
+ - [ ] 2.1 Implement major sections from Pencil
679
+ - Target files: `<repo path>`
680
+ - Verification command: `<exact command>`
681
+ - Execution intent: `bounded_parallel`
682
+ - Review intent: `true`
670
683
 
671
684
  ## 3. Behavior
672
- - [ ] Implement states and interactions from spec
685
+ - [ ] 3.1 Implement states and interactions from spec
686
+ - Target files: `<repo path>`
687
+ - Verification command: `<exact command>`
688
+ - Execution intent: `review_required`
689
+ - Review intent: `true`
673
690
 
674
691
  ## 4. Integration
675
- - [ ] Wire required data or services
692
+ - [ ] 4.1 Wire required data or services
693
+ - Target files: `<repo path>`
694
+ - Verification command: `<exact command>`
695
+ - Execution intent: `serial`
696
+ - Review intent: `true`
676
697
 
677
698
  ## 5. Verification
678
- - [ ] Check requirement coverage
679
- - [ ] Check Pencil coverage
699
+ - [ ] 5.1 Check requirement coverage
700
+ - [ ] 5.2 Check Pencil coverage
701
+ - Verification command: `da-vinci verify-bindings --project <path> [--change <id>]`
702
+ - Verification command: `da-vinci verify-implementation --project <path> [--change <id>]`
703
+ - Verification command: `da-vinci verify-structure --project <path> [--change <id>]`
704
+ - Verification command: `da-vinci verify-coverage --project <path> [--change <id>]`
680
705
 
681
706
  ## Metadata Hints (Machine-readable)
682
707
  - Spec slice: `<slice-id>`
@@ -699,8 +724,12 @@ Prefer top-level task groups. They are required for execution checkpoints.
699
724
  Additional guidance:
700
725
 
701
726
  - keep top-level task groups in `X. Title` form to support task-group execution metadata
727
+ - keep checklist numbering in `X.Y` form and avoid placeholder wording such as `TBD` or `TODO`
728
+ - keep discipline markers parseable and timestamped so stale approvals can be detected
702
729
  - include explicit verification actions so `lint-tasks` and `verify-coverage` can consume intent deterministically
703
730
  - keep task text concrete enough that coverage tools can map behavior and state work
731
+ - include explicit file targets or code-area references for each task group
732
+ - include execution intent (`serial`, `bounded_parallel`, or `review_required`) and review intent metadata per group
704
733
 
705
734
  Recommended path:
706
735
 
@@ -780,6 +809,27 @@ Use this structure:
780
809
  - explicit test evidence summary
781
810
  - open gaps
782
811
 
812
+ ## Task Review Evidence
813
+ ### Task Review <task-group-id> (spec)
814
+ - Status: PASS / WARN / BLOCK
815
+ - Reviewer: `<name>`
816
+ - Summary: `<summary>`
817
+ - Issues: `<issue list>`
818
+ - Recorded at: `<ISO-8601 timestamp>`
819
+
820
+ ### Task Review <task-group-id> (quality)
821
+ - Status: PASS / WARN / BLOCK
822
+ - Reviewer: `<name>`
823
+ - Summary: `<summary>`
824
+ - Issues: `<issue list>`
825
+ - Recorded at: `<ISO-8601 timestamp>`
826
+
827
+ ## Verification Freshness
828
+ - verification baseline timestamp
829
+ - latest verify signal timestamps by surface
830
+ - freshness outcome: `fresh` / `stale`
831
+ - stale reasons when freshness is not satisfied
832
+
783
833
  ## Context Delta
784
834
  - Add concise entries after each `execution checkpoint`
785
835
  - Required fields: `time`, `checkpoint_type`, `goal`, `decision`, `constraints`, `impact`, `status`, `next_action`