@xenonbyte/da-vinci-workflow 0.1.13 → 0.1.15
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 +21 -1
- package/README.md +23 -1
- package/README.zh-CN.md +23 -1
- package/SKILL.md +15 -0
- package/commands/claude/dv/design.md +2 -0
- package/commands/claude/dv/verify.md +2 -0
- package/commands/codex/prompts/dv-design.md +2 -0
- package/commands/codex/prompts/dv-verify.md +1 -0
- package/commands/gemini/dv/design.toml +2 -0
- package/commands/gemini/dv/verify.toml +1 -0
- package/docs/mcp-aware-gate-implementation.md +291 -0
- package/docs/mcp-aware-gate-tests.md +244 -0
- package/docs/mcp-aware-gate.md +246 -0
- package/docs/mode-use-cases.md +2 -0
- package/docs/prompt-presets/README.md +1 -0
- package/docs/prompt-presets/desktop-app.md +4 -0
- package/docs/prompt-presets/mobile-app.md +4 -0
- package/docs/prompt-presets/tablet-app.md +4 -0
- package/docs/prompt-presets/web-app.md +4 -0
- package/docs/visual-adapters.md +9 -0
- package/docs/visual-assist-presets/README.md +4 -2
- package/docs/visual-assist-presets/desktop-app.md +2 -0
- package/docs/visual-assist-presets/mobile-app.md +2 -0
- package/docs/visual-assist-presets/tablet-app.md +2 -0
- package/docs/visual-assist-presets/web-app.md +2 -0
- package/docs/workflow-examples.md +9 -4
- package/docs/zh-CN/mcp-aware-gate-implementation.md +290 -0
- package/docs/zh-CN/mcp-aware-gate-tests.md +244 -0
- package/docs/zh-CN/mcp-aware-gate.md +249 -0
- package/docs/zh-CN/mode-use-cases.md +3 -0
- package/docs/zh-CN/prompt-presets/README.md +1 -0
- package/docs/zh-CN/prompt-presets/desktop-app.md +4 -0
- package/docs/zh-CN/prompt-presets/mobile-app.md +4 -0
- package/docs/zh-CN/prompt-presets/tablet-app.md +4 -0
- package/docs/zh-CN/prompt-presets/web-app.md +4 -0
- package/docs/zh-CN/visual-adapters.md +9 -0
- package/docs/zh-CN/visual-assist-presets/README.md +5 -3
- package/docs/zh-CN/visual-assist-presets/desktop-app.md +2 -0
- package/docs/zh-CN/visual-assist-presets/mobile-app.md +2 -0
- package/docs/zh-CN/visual-assist-presets/tablet-app.md +2 -0
- package/docs/zh-CN/visual-assist-presets/web-app.md +2 -0
- package/docs/zh-CN/workflow-examples.md +9 -4
- package/examples/greenfield-spec-markupflow/DA-VINCI.md +1 -0
- package/examples/greenfield-spec-markupflow/README.md +3 -0
- package/examples/greenfield-spec-markupflow/design-registry.md +3 -0
- package/examples/greenfield-spec-markupflow/pencil-design.md +4 -0
- package/lib/audit.js +348 -0
- package/lib/cli.js +47 -1
- package/lib/mcp-runtime-gate.js +342 -0
- package/package.json +3 -2
- package/references/artifact-templates.md +35 -3
- package/references/checkpoints.md +69 -1
- package/references/design-inputs.md +9 -1
- package/references/layout-hygiene.md +117 -0
- package/references/pencil-design-to-code.md +8 -0
- package/scripts/test-mcp-runtime-gate.js +199 -0
|
@@ -0,0 +1,342 @@
|
|
|
1
|
+
const path = require("path");
|
|
2
|
+
|
|
3
|
+
const PASS = "PASS";
|
|
4
|
+
const WARN = "WARN";
|
|
5
|
+
const BLOCK = "BLOCK";
|
|
6
|
+
const SKIP = "SKIP";
|
|
7
|
+
|
|
8
|
+
function normalizeArray(value) {
|
|
9
|
+
return Array.isArray(value) ? value.filter(Boolean) : [];
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function normalizeLiveScreens(liveScreens) {
|
|
13
|
+
return normalizeArray(liveScreens).map((screen) => ({
|
|
14
|
+
id: screen && screen.id ? String(screen.id) : "",
|
|
15
|
+
name: screen && screen.name ? String(screen.name) : ""
|
|
16
|
+
}));
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function unique(values) {
|
|
20
|
+
return [...new Set(values)];
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function getScreenIds(liveScreens) {
|
|
24
|
+
return unique(normalizeLiveScreens(liveScreens).map((screen) => screen.id).filter(Boolean));
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function getScreenNames(liveScreens) {
|
|
28
|
+
return unique(normalizeLiveScreens(liveScreens).map((screen) => screen.name).filter(Boolean));
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function normalizeEditorName(activeEditor) {
|
|
32
|
+
return typeof activeEditor === "string" ? activeEditor.trim() : "";
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function normalizeRegisteredPath(registeredPenPath) {
|
|
36
|
+
return typeof registeredPenPath === "string" ? registeredPenPath.trim() : "";
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function resolveProjectPath(projectRoot, targetPath) {
|
|
40
|
+
if (!targetPath) {
|
|
41
|
+
return "";
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (path.isAbsolute(targetPath)) {
|
|
45
|
+
return path.normalize(targetPath);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (!projectRoot) {
|
|
49
|
+
return "";
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return path.normalize(path.resolve(projectRoot, targetPath));
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function isUnnamedEditor(activeEditor) {
|
|
56
|
+
const normalized = normalizeEditorName(activeEditor).toLowerCase();
|
|
57
|
+
return normalized === "" || normalized === "new";
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function matchesRegisteredPath(activeEditor, registeredPenPath, projectRoot) {
|
|
61
|
+
const editor = normalizeEditorName(activeEditor);
|
|
62
|
+
const registered = normalizeRegisteredPath(registeredPenPath);
|
|
63
|
+
|
|
64
|
+
if (!editor || !registered) {
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const resolvedEditor = resolveProjectPath(projectRoot, editor);
|
|
69
|
+
const resolvedRegistered = resolveProjectPath(projectRoot, registered);
|
|
70
|
+
|
|
71
|
+
if (resolvedEditor && resolvedRegistered) {
|
|
72
|
+
return resolvedEditor === resolvedRegistered;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const editorHasPathSeparators = editor.includes("/") || editor.includes("\\");
|
|
76
|
+
if (editorHasPathSeparators) {
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return path.basename(editor) === path.basename(registered);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function missingIds(expectedIds, actualIds) {
|
|
84
|
+
const actualSet = new Set(actualIds);
|
|
85
|
+
return unique(expectedIds).filter((id) => !actualSet.has(id));
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function derivePhase(snapshot) {
|
|
89
|
+
return snapshot.phase || "completion";
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function evaluateSourceConvergence(snapshot) {
|
|
93
|
+
const notes = [];
|
|
94
|
+
const activeEditor = normalizeEditorName(snapshot.activeEditor);
|
|
95
|
+
const registeredPenPath = normalizeRegisteredPath(snapshot.registeredPenPath);
|
|
96
|
+
const projectRoot = typeof snapshot.projectRoot === "string" ? snapshot.projectRoot.trim() : "";
|
|
97
|
+
const shellVisiblePenExists = Boolean(snapshot.shellVisiblePenExists);
|
|
98
|
+
const documentedReconciliation = Boolean(snapshot.documentedReconciliation);
|
|
99
|
+
const noNewPencilEditsYet = Boolean(snapshot.noNewPencilEditsYet);
|
|
100
|
+
|
|
101
|
+
if (Boolean(snapshot.mcpAvailable) === false) {
|
|
102
|
+
return {
|
|
103
|
+
status: WARN,
|
|
104
|
+
notes: ["Pencil MCP is unavailable, so runtime source convergence could not be fully checked."]
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
if (isUnnamedEditor(activeEditor)) {
|
|
109
|
+
return {
|
|
110
|
+
status: BLOCK,
|
|
111
|
+
notes: ["Active Pencil editor is still an unnamed live document such as `new`."]
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
if (!registeredPenPath) {
|
|
116
|
+
return {
|
|
117
|
+
status: BLOCK,
|
|
118
|
+
notes: ["No registered project-local `.pen` path was provided for runtime comparison."]
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
if (!shellVisiblePenExists) {
|
|
123
|
+
return {
|
|
124
|
+
status: BLOCK,
|
|
125
|
+
notes: ["The registered project-local `.pen` file is not shell-visible on disk."]
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
if (!matchesRegisteredPath(activeEditor, registeredPenPath, projectRoot)) {
|
|
130
|
+
if (documentedReconciliation) {
|
|
131
|
+
return {
|
|
132
|
+
status: WARN,
|
|
133
|
+
notes: [
|
|
134
|
+
"Active Pencil editor does not match the registered project-local `.pen` path, but a documented reconciliation was provided."
|
|
135
|
+
]
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
return {
|
|
140
|
+
status: BLOCK,
|
|
141
|
+
notes: ["Active Pencil editor does not match the registered project-local `.pen` path."]
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
if (noNewPencilEditsYet) {
|
|
146
|
+
notes.push("No new Pencil edits were recorded yet; source convergence is only provisionally confirmed.");
|
|
147
|
+
return {
|
|
148
|
+
status: WARN,
|
|
149
|
+
notes
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
return {
|
|
154
|
+
status: PASS,
|
|
155
|
+
notes: ["Active Pencil editor matches the registered project-local `.pen` source and the file exists on disk."]
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
function evaluateScreenPresence(snapshot) {
|
|
160
|
+
const phase = derivePhase(snapshot);
|
|
161
|
+
const claimedAnchorIds = normalizeArray(snapshot.claimedAnchorIds);
|
|
162
|
+
const claimedReviewedScreenIds = normalizeArray(snapshot.claimedReviewedScreenIds);
|
|
163
|
+
const reviewTargets = normalizeArray(snapshot.reviewTargets);
|
|
164
|
+
const liveIds = getScreenIds(snapshot.liveScreens);
|
|
165
|
+
|
|
166
|
+
if (Boolean(snapshot.mcpAvailable) === false) {
|
|
167
|
+
return {
|
|
168
|
+
status: WARN,
|
|
169
|
+
notes: ["Pencil MCP is unavailable, so live screen presence could not be fully checked."]
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
if (phase === "first_write" && claimedAnchorIds.length === 0 && claimedReviewedScreenIds.length === 0 && reviewTargets.length === 0) {
|
|
174
|
+
return {
|
|
175
|
+
status: SKIP,
|
|
176
|
+
notes: ["No anchor or review ids were declared yet, so screen-presence checks were skipped at first-write stage."]
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
const missingAnchorIds = missingIds(claimedAnchorIds, liveIds);
|
|
181
|
+
const missingReviewedIds = missingIds(claimedReviewedScreenIds, liveIds);
|
|
182
|
+
const missingReviewTargets = missingIds(reviewTargets, liveIds);
|
|
183
|
+
|
|
184
|
+
const notes = [];
|
|
185
|
+
if (missingAnchorIds.length > 0) {
|
|
186
|
+
notes.push(`Missing claimed anchor ids in the active editor: ${missingAnchorIds.join(", ")}`);
|
|
187
|
+
}
|
|
188
|
+
if (missingReviewedIds.length > 0) {
|
|
189
|
+
notes.push(`Missing claimed reviewed screen ids in the active editor: ${missingReviewedIds.join(", ")}`);
|
|
190
|
+
}
|
|
191
|
+
if (missingReviewTargets.length > 0) {
|
|
192
|
+
notes.push(`Missing screenshot target ids in the active editor: ${missingReviewTargets.join(", ")}`);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
if (notes.length > 0) {
|
|
196
|
+
return {
|
|
197
|
+
status: BLOCK,
|
|
198
|
+
notes
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
if (claimedAnchorIds.length === 0 && claimedReviewedScreenIds.length === 0 && reviewTargets.length === 0) {
|
|
203
|
+
return {
|
|
204
|
+
status: WARN,
|
|
205
|
+
notes: ["No claimed anchor, reviewed, or screenshot target ids were provided for runtime verification."]
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
return {
|
|
210
|
+
status: PASS,
|
|
211
|
+
notes: ["Claimed anchor surfaces and review targets resolve in the active live editor."]
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
function evaluateReviewExecution(snapshot) {
|
|
216
|
+
const phase = derivePhase(snapshot);
|
|
217
|
+
const claimedReviewedScreenIds = normalizeArray(snapshot.claimedReviewedScreenIds);
|
|
218
|
+
const reviewTargets = normalizeArray(snapshot.reviewTargets);
|
|
219
|
+
const reviewBlockersIgnored = Boolean(snapshot.reviewBlockersIgnored);
|
|
220
|
+
const broadExpansionRequested = Boolean(snapshot.broadExpansionRequested);
|
|
221
|
+
|
|
222
|
+
if (Boolean(snapshot.mcpAvailable) === false) {
|
|
223
|
+
return {
|
|
224
|
+
status: WARN,
|
|
225
|
+
notes: ["Pencil MCP is unavailable, so runtime review execution could not be fully checked."]
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
if (phase === "first_write") {
|
|
230
|
+
return {
|
|
231
|
+
status: SKIP,
|
|
232
|
+
notes: ["Screenshot review is not required at first-write stage."]
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
if (claimedReviewedScreenIds.length === 0 && reviewTargets.length === 0) {
|
|
237
|
+
if (phase === "completion" || broadExpansionRequested) {
|
|
238
|
+
return {
|
|
239
|
+
status: BLOCK,
|
|
240
|
+
notes: ["No reviewed screen ids or screenshot targets were recorded for a stage that requires runtime review evidence."]
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
return {
|
|
245
|
+
status: WARN,
|
|
246
|
+
notes: ["No reviewed screen ids or screenshot targets were recorded yet."]
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
if (reviewBlockersIgnored) {
|
|
251
|
+
return {
|
|
252
|
+
status: BLOCK,
|
|
253
|
+
notes: ["Screenshot review recorded blocker-level issues that were ignored while the surface was still treated as approved."]
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
return {
|
|
258
|
+
status: PASS,
|
|
259
|
+
notes: ["Runtime review evidence exists for the approved surfaces."]
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
function combineStatuses(statuses) {
|
|
264
|
+
if (statuses.includes(BLOCK)) {
|
|
265
|
+
return BLOCK;
|
|
266
|
+
}
|
|
267
|
+
if (statuses.includes(WARN)) {
|
|
268
|
+
return WARN;
|
|
269
|
+
}
|
|
270
|
+
if (statuses.every((status) => status === SKIP)) {
|
|
271
|
+
return WARN;
|
|
272
|
+
}
|
|
273
|
+
return PASS;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
function evaluateMcpRuntimeGate(snapshot = {}) {
|
|
277
|
+
const sourceConvergence = evaluateSourceConvergence(snapshot);
|
|
278
|
+
const screenPresence = evaluateScreenPresence(snapshot);
|
|
279
|
+
const reviewExecution = evaluateReviewExecution(snapshot);
|
|
280
|
+
|
|
281
|
+
const finalStatus = combineStatuses([
|
|
282
|
+
sourceConvergence.status,
|
|
283
|
+
screenPresence.status === SKIP ? PASS : screenPresence.status,
|
|
284
|
+
reviewExecution.status === SKIP ? PASS : reviewExecution.status
|
|
285
|
+
]);
|
|
286
|
+
|
|
287
|
+
return {
|
|
288
|
+
phase: derivePhase(snapshot),
|
|
289
|
+
sourceConvergence,
|
|
290
|
+
screenPresence,
|
|
291
|
+
reviewExecution,
|
|
292
|
+
finalStatus,
|
|
293
|
+
activeEditor: normalizeEditorName(snapshot.activeEditor),
|
|
294
|
+
registeredPenPath:
|
|
295
|
+
typeof snapshot.registeredPenPath === "string" ? snapshot.registeredPenPath.trim() : "",
|
|
296
|
+
shellVisiblePenPath:
|
|
297
|
+
typeof snapshot.shellVisiblePenPath === "string" ? snapshot.shellVisiblePenPath.trim() : "",
|
|
298
|
+
shellVisiblePenExists: Boolean(snapshot.shellVisiblePenExists),
|
|
299
|
+
claimedAnchorIds: normalizeArray(snapshot.claimedAnchorIds),
|
|
300
|
+
claimedReviewedScreenIds: normalizeArray(snapshot.claimedReviewedScreenIds),
|
|
301
|
+
reviewTargets: normalizeArray(snapshot.reviewTargets),
|
|
302
|
+
liveScreenIds: getScreenIds(snapshot.liveScreens),
|
|
303
|
+
liveScreenNames: getScreenNames(snapshot.liveScreens)
|
|
304
|
+
};
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
function formatMcpRuntimeGateSection(snapshot, result, options = {}) {
|
|
308
|
+
const timestamp = options.timestamp || new Date().toISOString();
|
|
309
|
+
const notes = [
|
|
310
|
+
...result.sourceConvergence.notes,
|
|
311
|
+
...result.screenPresence.notes,
|
|
312
|
+
...result.reviewExecution.notes
|
|
313
|
+
];
|
|
314
|
+
|
|
315
|
+
return [
|
|
316
|
+
"## MCP Runtime Gate",
|
|
317
|
+
`- Time: ${timestamp}`,
|
|
318
|
+
`- Phase: ${result.phase}`,
|
|
319
|
+
`- Active editor: ${result.activeEditor || "(unavailable)"}`,
|
|
320
|
+
`- Registered \`.pen\` path: ${result.registeredPenPath || "(missing)"}`,
|
|
321
|
+
`- Shell-visible \`.pen\` path: ${result.shellVisiblePenPath || "(missing)"}`,
|
|
322
|
+
`- Shell-visible \`.pen\` exists: ${result.shellVisiblePenExists ? "yes" : "no"}`,
|
|
323
|
+
`- Claimed anchor ids: ${result.claimedAnchorIds.length > 0 ? result.claimedAnchorIds.join(", ") : "(none)"}`,
|
|
324
|
+
`- Reviewed screen ids: ${result.claimedReviewedScreenIds.length > 0 ? result.claimedReviewedScreenIds.join(", ") : "(none)"}`,
|
|
325
|
+
`- Screenshot target ids: ${result.reviewTargets.length > 0 ? result.reviewTargets.join(", ") : "(none)"}`,
|
|
326
|
+
`- Live screen ids: ${result.liveScreenIds.length > 0 ? result.liveScreenIds.join(", ") : "(none)"}`,
|
|
327
|
+
`- Source convergence: ${result.sourceConvergence.status}`,
|
|
328
|
+
`- Screen presence: ${result.screenPresence.status}`,
|
|
329
|
+
`- Review execution: ${result.reviewExecution.status}`,
|
|
330
|
+
`- Final runtime gate status: ${result.finalStatus}`,
|
|
331
|
+
`- Notes: ${notes.length > 0 ? notes.join(" | ") : "none"}`
|
|
332
|
+
].join("\n");
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
module.exports = {
|
|
336
|
+
PASS,
|
|
337
|
+
WARN,
|
|
338
|
+
BLOCK,
|
|
339
|
+
SKIP,
|
|
340
|
+
evaluateMcpRuntimeGate,
|
|
341
|
+
formatMcpRuntimeGateSection
|
|
342
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xenonbyte/da-vinci-workflow",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.15",
|
|
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"
|
|
@@ -21,7 +21,8 @@
|
|
|
21
21
|
],
|
|
22
22
|
"scripts": {
|
|
23
23
|
"postinstall": "node scripts/postinstall.js",
|
|
24
|
-
"validate-assets": "node scripts/validate-assets.js"
|
|
24
|
+
"validate-assets": "node scripts/validate-assets.js",
|
|
25
|
+
"test:mcp-runtime-gate": "node scripts/test-mcp-runtime-gate.js"
|
|
25
26
|
},
|
|
26
27
|
"engines": {
|
|
27
28
|
"node": ">=18"
|
|
@@ -36,6 +36,7 @@ project/
|
|
|
36
36
|
├── pencil-bindings.md
|
|
37
37
|
├── tasks.md
|
|
38
38
|
├── verification.md
|
|
39
|
+
├── exports/
|
|
39
40
|
└── specs/
|
|
40
41
|
└── <capability>/spec.md
|
|
41
42
|
```
|
|
@@ -175,8 +176,8 @@ Use this structure:
|
|
|
175
176
|
|
|
176
177
|
Field meaning:
|
|
177
178
|
|
|
178
|
-
- `Preferred adapters`: desired local-skill priority order
|
|
179
|
-
- `Scope`: allowed presentation-quality influence areas only
|
|
179
|
+
- `Preferred adapters`: desired local-skill priority order using adapter names that actually exist in the current environment
|
|
180
|
+
- `Scope`: allowed presentation-quality influence areas only, including anchor-surface composition when redesign quality matters
|
|
180
181
|
- `Fallback`: what to do when preferred adapters are unavailable
|
|
181
182
|
- `Require Adapter`: whether missing adapters should block the workflow
|
|
182
183
|
|
|
@@ -214,6 +215,11 @@ Use this structure:
|
|
|
214
215
|
- workspace density
|
|
215
216
|
- responsiveness expectations
|
|
216
217
|
|
|
218
|
+
## Layout Hygiene Profile
|
|
219
|
+
- Resolved profile: mobile / tablet / desktop / web
|
|
220
|
+
- Per-surface overrides when mixed product surfaces require them
|
|
221
|
+
- Blocker classes to watch during screenshot review
|
|
222
|
+
|
|
217
223
|
## Notes
|
|
218
224
|
- explicit user preferences
|
|
219
225
|
- inferred preferences
|
|
@@ -243,6 +249,7 @@ Use this structure:
|
|
|
243
249
|
- Which `.pen` file is authoritative
|
|
244
250
|
- Why that file should be preferred over live-only or external sources
|
|
245
251
|
- whether the active Pencil editor matches that same path
|
|
252
|
+
- whether the active Pencil editor is still an unnamed live document that must be reconciled before completion
|
|
246
253
|
|
|
247
254
|
## Visual Adapter Resolution
|
|
248
255
|
- Requested adapters
|
|
@@ -483,7 +490,9 @@ Use this structure:
|
|
|
483
490
|
- Which 1-3 anchor screens were designed first
|
|
484
491
|
- Structural-delta summary for each anchor surface
|
|
485
492
|
- Screenshot review status for each anchor
|
|
493
|
+
- Applied layout-hygiene profile for each reviewed anchor surface
|
|
486
494
|
- Whether screenshot review found hierarchy, spacing, clarity, or inconsistency issues
|
|
495
|
+
- Whether screenshot review found blocker-level layout-hygiene issues
|
|
487
496
|
- Whether each anchor was revised after screenshot review
|
|
488
497
|
- Whether broad multi-screen expansion is approved yet
|
|
489
498
|
|
|
@@ -504,7 +513,30 @@ Use this structure:
|
|
|
504
513
|
- Which states still need design coverage
|
|
505
514
|
|
|
506
515
|
## Screenshots
|
|
507
|
-
- Reference image paths or exported nodes
|
|
516
|
+
- Reference image paths or exported nodes under `.da-vinci/changes/<change-id>/exports/`
|
|
517
|
+
|
|
518
|
+
## MCP Runtime Gate
|
|
519
|
+
- Time
|
|
520
|
+
- Phase
|
|
521
|
+
- Active editor
|
|
522
|
+
- Registered `.pen` path
|
|
523
|
+
- Shell-visible `.pen` path
|
|
524
|
+
- Shell-visible `.pen` exists
|
|
525
|
+
- Claimed anchor ids
|
|
526
|
+
- Reviewed screen ids
|
|
527
|
+
- Screenshot target ids
|
|
528
|
+
- Live screen ids
|
|
529
|
+
- `Source convergence`
|
|
530
|
+
- `Screen presence`
|
|
531
|
+
- `Review execution`
|
|
532
|
+
- `Final runtime gate status`
|
|
533
|
+
- Notes
|
|
534
|
+
|
|
535
|
+
## Checkpoint Status
|
|
536
|
+
- `mcp runtime gate`
|
|
537
|
+
- `design-source checkpoint`
|
|
538
|
+
- `design checkpoint`
|
|
539
|
+
- `completion gate`
|
|
508
540
|
|
|
509
541
|
## Implementation Notes
|
|
510
542
|
- Important layout or styling constraints to preserve in code
|
|
@@ -48,6 +48,7 @@ Check:
|
|
|
48
48
|
- the active mode is correct
|
|
49
49
|
- the starting material is stable enough to write specs
|
|
50
50
|
- product form factor and visual direction are known, inferred, or explicitly deferred
|
|
51
|
+
- the form factor is specific enough to resolve the active layout-hygiene profile before screenshot review begins
|
|
51
52
|
- candidate pages or current pages are clear enough to move into `page-map.md`
|
|
52
53
|
- open questions are explicitly tracked
|
|
53
54
|
- workflow artifacts are being written to standard locations, especially keeping `.da-vinci/designs/` for `.pen` files rather than markdown notes
|
|
@@ -101,6 +102,7 @@ Check:
|
|
|
101
102
|
- when a primary adapter is active, the workflow wrote a visual thesis, content plan, and interaction thesis before broad anchor-surface generation
|
|
102
103
|
- complex redesigns have 1-3 fully composed anchor surfaces reviewed before broad multi-screen expansion
|
|
103
104
|
- each anchor surface includes a short explanation of how its composition differs structurally from the current layout truth
|
|
105
|
+
- the relevant form-factor-specific layout-hygiene profile was applied to each reviewed anchor surface and any other screen being treated as approval-ready
|
|
104
106
|
- each page has a clear visual anchor or primary working surface
|
|
105
107
|
- section hierarchy is readable without relying on decorative chrome
|
|
106
108
|
- the design does not collapse into generic card-grid or border-heavy filler UI
|
|
@@ -118,10 +120,13 @@ Result meanings:
|
|
|
118
120
|
|
|
119
121
|
Automatic failures:
|
|
120
122
|
|
|
123
|
+
- if anchor-surface design starts before the required discovery artifacts and design-source artifacts exist in their standard locations, treat the design checkpoint as `BLOCK`
|
|
121
124
|
- if broad Pencil generation starts before anchor surfaces are compositionally stable, treat the design checkpoint as `BLOCK`
|
|
122
125
|
- if more than roughly 20% of a screen's primary content area is unresolved placeholder scaffolding, treat the design checkpoint as `BLOCK`
|
|
123
126
|
- if multiple screens are effectively the same scaffold with title changes, treat the design checkpoint as `BLOCK`
|
|
124
127
|
- if screenshot review or image analysis calls out hierarchy, spacing, clarity, inconsistency, or unresolved-placeholder issues and the workflow marks the screen as passed without revision, treat the design checkpoint as `BLOCK`
|
|
128
|
+
- if any blocker-level condition from the active form-factor-specific layout-hygiene profile is present on a reviewed screen, treat the design checkpoint as `BLOCK`
|
|
129
|
+
- if an anchor surface required repeated rolled-back Pencil batches from unsupported properties and the workflow still treats that surface as approved without a clean schema-safe pass, treat the design checkpoint as `BLOCK`
|
|
125
130
|
- if a redesign screen materially mirrors the current XML grouping with only recolor, spacing tweaks, or minor rearrangement, treat the design checkpoint as `BLOCK`
|
|
126
131
|
|
|
127
132
|
## `design-source checkpoint`
|
|
@@ -133,9 +138,11 @@ Check:
|
|
|
133
138
|
- `design-registry.md` records one specific preferred project-local `.pen` path
|
|
134
139
|
- the preferred `.pen` path is workflow-owned state, not a hand-wavy placeholder
|
|
135
140
|
- the active Pencil editor path matches the preferred project-local `.pen` path, or the mismatch has been reconciled explicitly
|
|
141
|
+
- an unnamed live editor such as `new` is not being treated as the persisted project-local design source
|
|
136
142
|
- if the workflow created or edited Pencil work, the preferred project-local `.pen` file exists as a shell-visible file immediately after the first successful Pencil write, not just at workflow close
|
|
137
143
|
- if Pencil MCP only exposed a live document, the workflow reconstructed and wrote the registered project-local `.pen` file from MCP-readable document data before continuing
|
|
138
|
-
- `.da-vinci/designs/` is being used cleanly for project-local `.pen` files rather than mixed with workflow markdown
|
|
144
|
+
- `.da-vinci/designs/` is being used cleanly for project-local `.pen` files rather than mixed with workflow markdown, screenshots, or other exports
|
|
145
|
+
- exported screenshots are stored under `.da-vinci/changes/<change-id>/exports/` and are not being used as a substitute for the `.pen` source
|
|
139
146
|
- `design-registry.md`, `pencil-design.md`, and `pencil-bindings.md` describe the same active project-local `.pen` source clearly enough to map and implement from
|
|
140
147
|
|
|
141
148
|
Result meanings:
|
|
@@ -144,6 +151,36 @@ Result meanings:
|
|
|
144
151
|
- `WARN`: the workflow is intentionally staying on an older but still shell-visible baseline, or no new Pencil edits have happened yet
|
|
145
152
|
- `BLOCK`: the registered `.pen` path, the active Pencil work, and the shell-visible project-local file do not agree well enough to treat the design source as traceable
|
|
146
153
|
|
|
154
|
+
## `mcp runtime gate`
|
|
155
|
+
|
|
156
|
+
Run inside the active design session when Pencil MCP is available:
|
|
157
|
+
|
|
158
|
+
- after the first successful Pencil write
|
|
159
|
+
- before broad expansion beyond approved anchor surfaces
|
|
160
|
+
- before any terminal `design complete` or `workflow complete` claim
|
|
161
|
+
|
|
162
|
+
Check:
|
|
163
|
+
|
|
164
|
+
- the active editor is not still an unnamed live document such as `new`
|
|
165
|
+
- the active editor, registered project-local `.pen` path, and shell-visible `.pen` file are converged strongly enough to trust the runtime source
|
|
166
|
+
- claimed anchor ids exist in the active live editor
|
|
167
|
+
- claimed reviewed screens and screenshot targets exist in the active live editor
|
|
168
|
+
- screenshot-reviewed surfaces were not treated as approved while blocker-level review findings were ignored
|
|
169
|
+
- runtime-gate evidence is recorded in `pencil-design.md`
|
|
170
|
+
|
|
171
|
+
Result meanings:
|
|
172
|
+
|
|
173
|
+
- `PASS`: runtime source and live screen state are trustworthy enough to continue
|
|
174
|
+
- `WARN`: runtime evidence is partial or intentionally deferred, but not yet contradictory
|
|
175
|
+
- `BLOCK`: runtime truth is too weak or contradictory to continue or claim completion
|
|
176
|
+
|
|
177
|
+
Automatic failures:
|
|
178
|
+
|
|
179
|
+
- if the active editor is still `new`, treat the runtime gate as `BLOCK`
|
|
180
|
+
- if live anchor surfaces exist only in the current editor while no shell-visible `.pen` exists, treat the runtime gate as `BLOCK`
|
|
181
|
+
- if claimed anchor ids, reviewed screen ids, or screenshot targets do not resolve in the active editor, treat the runtime gate as `BLOCK`
|
|
182
|
+
- if blocker-level review findings were ignored while the workflow still approved the surface, treat the runtime gate as `BLOCK`
|
|
183
|
+
|
|
147
184
|
## `mapping checkpoint`
|
|
148
185
|
|
|
149
186
|
Run after `design-registry.md` and `pencil-bindings.md`.
|
|
@@ -154,6 +191,7 @@ Check:
|
|
|
154
191
|
- the preferred `.pen` path in `design-registry.md` is workflow-owned and specific, not hand-wavy
|
|
155
192
|
- the active Pencil editor path matches the preferred project-local `.pen` path, or the project-local file has been reconstructed explicitly
|
|
156
193
|
- the preferred project-local `.pen` file exists as a shell-visible file when the workflow created or edited Pencil work
|
|
194
|
+
- exported screenshots are treated only as review artifacts, not as page-to-design source of truth
|
|
157
195
|
- each implementation page has a Pencil page or an explicit exception
|
|
158
196
|
- shared layouts and shared regions are bound clearly enough to implement from
|
|
159
197
|
- route names and Pencil names are traceable
|
|
@@ -202,9 +240,39 @@ Examples of `BLOCK`:
|
|
|
202
240
|
- page-to-Pencil bindings are too weak to know which redesign screen to follow
|
|
203
241
|
- `design-registry.md` points to a project-local `.pen` path, but the workflow actually edited a different live editor document and did not reconcile the mismatch
|
|
204
242
|
- the workflow created or edited Pencil pages but no shell-visible `.pen` file exists under the registered project-local path
|
|
243
|
+
- `.da-vinci/designs/` contains workflow markdown or screenshot exports instead of `.pen` files only
|
|
205
244
|
- required permissions, environment access, or protected files are unavailable
|
|
206
245
|
- the implementation would overwrite the project baseline in a destructive way without an explicit go-ahead
|
|
207
246
|
|
|
247
|
+
## `completion gate`
|
|
248
|
+
|
|
249
|
+
Apply before reporting `design complete`, `workflow complete`, or any equivalent terminal state.
|
|
250
|
+
|
|
251
|
+
When shell access is available:
|
|
252
|
+
|
|
253
|
+
- use `da-vinci audit --mode integrity <project-path>` as a filesystem-truth sanity check during active work
|
|
254
|
+
- use `da-vinci audit --mode completion --change <change-id> <project-path>` before any terminal completion claim
|
|
255
|
+
- treat an audit failure as `BLOCK`
|
|
256
|
+
|
|
257
|
+
Check:
|
|
258
|
+
|
|
259
|
+
- the artifacts required for the active intent actually exist in their standard locations
|
|
260
|
+
- for `redesign-from-code` with active Pencil work, this normally includes `project-inventory.md`, `page-map.md`, `design-registry.md`, `design-brief.md`, `design.md`, `pencil-design.md`, and `pencil-bindings.md`
|
|
261
|
+
- if Pencil work happened, `design-source checkpoint` is at least `PASS`
|
|
262
|
+
- if design output is being treated as ready, `design checkpoint` is at least `PASS` or an explicitly accepted `WARN`
|
|
263
|
+
- if Pencil MCP is available, `mcp runtime gate` is at least `PASS` or an explicitly accepted `WARN`
|
|
264
|
+
- the registered project-local `.pen` file exists as a shell-visible file
|
|
265
|
+
- the active Pencil editor is not still an unnamed live document such as `new`
|
|
266
|
+
- `.da-vinci/designs/` contains `.pen` files only
|
|
267
|
+
- exported screenshots, if any, live under `.da-vinci/changes/<change-id>/exports/`
|
|
268
|
+
- screenshots are recorded only as review artifacts and not described as the persisted design source
|
|
269
|
+
|
|
270
|
+
Automatic failures:
|
|
271
|
+
|
|
272
|
+
- if the workflow claims the `.pen` source exists only "in memory", treat completion as `BLOCK`
|
|
273
|
+
- if the workflow claims success after exporting PNGs but without a shell-visible `.pen`, treat completion as `BLOCK`
|
|
274
|
+
- if the workflow reports completion without the required standard artifacts for the active stage, treat completion as `BLOCK`
|
|
275
|
+
|
|
208
276
|
## `execution checkpoint`
|
|
209
277
|
|
|
210
278
|
Run after each top-level task group during implementation.
|
|
@@ -9,7 +9,7 @@ Check for `DA-VINCI.md` first, then check whether the project already has persis
|
|
|
9
9
|
- if it exists, treat it as the project visual contract
|
|
10
10
|
- if `DA-VINCI.md` declares preferred visual adapters, treat them as optional design-assist preferences
|
|
11
11
|
- if `.da-vinci/designs/*.pen` exists, treat those files as project-local design inputs and record the exact preferred path in `design-registry.md`
|
|
12
|
-
- treat non-`.pen` files inside `.da-vinci/designs/` as artifact-placement drift that must be corrected instead of as valid design inputs
|
|
12
|
+
- treat non-`.pen` files inside `.da-vinci/designs/` as artifact-placement drift that must be corrected instead of as valid design inputs; screenshot exports belong under `.da-vinci/changes/<change-id>/exports/`
|
|
13
13
|
- if it does not exist, generate it from the best stable inputs before broad Pencil page generation
|
|
14
14
|
- avoid re-deriving the visual language page by page
|
|
15
15
|
|
|
@@ -37,6 +37,7 @@ If Pencil MCP is currently pointing at a different active editor:
|
|
|
37
37
|
|
|
38
38
|
- switch to the registered project-local path when possible
|
|
39
39
|
- otherwise reconstruct the project-local `.pen` file from MCP-readable document data before treating the workflow as traceable
|
|
40
|
+
- do not treat an unnamed live editor such as `new` as the resolved project-local path
|
|
40
41
|
|
|
41
42
|
## Minimum Inputs
|
|
42
43
|
|
|
@@ -72,6 +73,11 @@ Collect or infer:
|
|
|
72
73
|
- whether adapter use is required or optional
|
|
73
74
|
- fallback expectation when adapters are unavailable
|
|
74
75
|
|
|
76
|
+
6. layout hygiene profile
|
|
77
|
+
- resolved from the product form factor
|
|
78
|
+
- per-surface override only when the product intentionally mixes different surface classes
|
|
79
|
+
- blocker classes that must fail screenshot review
|
|
80
|
+
|
|
75
81
|
## Inference Order
|
|
76
82
|
|
|
77
83
|
Infer in this order:
|
|
@@ -97,6 +103,8 @@ Examples:
|
|
|
97
103
|
|
|
98
104
|
Write stable answers into `design-brief.md`.
|
|
99
105
|
|
|
106
|
+
Record the resolved layout-hygiene profile there as well, including any intentional per-surface overrides for mixed products.
|
|
107
|
+
|
|
100
108
|
If `DA-VINCI.md` did not already exist, generate it from those stable answers and save it as the project visual baseline.
|
|
101
109
|
|
|
102
110
|
If Pencil creates or updates a baseline during the workflow:
|