@namewta/speculo 1.0.2 → 1.0.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 (83) hide show
  1. package/README.md +8 -3
  2. package/package.json +2 -2
  3. package/template/AGENTS.md +3 -1
  4. package/template/canonical/canonical-specdev-goal-plan.md +757 -225
  5. package/template/canonical/canonical-specdev-grill-with-docs.md +221 -133
  6. package/template/canonical/canonical-specdev-spec.md +73 -3
  7. package/template/canonical/canonical-specdev-tickets.md +681 -252
  8. package/template/canonical/canonical-specdev-wayfinder.md +330 -113
  9. package/template/commands/archive-and-consolidate.md +39 -3
  10. package/template/commands/git-history-squash.md +76 -0
  11. package/template/commands/git-repository-audit.md +3 -602
  12. package/template/commands/references/git-repository-audit-procedure.md +608 -0
  13. package/template/skills/archive-and-consolidate/SKILL.md +1 -1
  14. package/template/skills/archive-and-consolidate/references/entry-procedure.md +11 -3
  15. package/template/skills/git-history-squash/SKILL.md +2 -0
  16. package/template/skills/git-history-squash/references/entry-procedure.md +1 -1
  17. package/template/skills/writing-great-skills/SKILL.md +2 -0
  18. package/template/skills/writing-great-skills/references/document-contract.md +23 -0
  19. package/template/workflows/learning/common/rules/activation-and-memory.md +7 -3
  20. package/template/workflows/ops/common/rules/activation-and-memory.md +7 -3
  21. package/template/workflows/person/common/rules/activation-and-memory.md +7 -3
  22. package/template/workflows/specdev/G-grill-with-docs/G-grill-with-docs.md +13 -136
  23. package/template/workflows/specdev/G-grill-with-docs/references/interview-procedure.md +134 -0
  24. package/template/workflows/specdev/I-implement/I-implement.md +15 -189
  25. package/template/workflows/specdev/I-implement/evidence-template.md +12 -0
  26. package/template/workflows/specdev/I-implement/execution-preflight.md +1 -1
  27. package/template/workflows/specdev/I-implement/references/implementation-procedure.md +192 -0
  28. package/template/workflows/specdev/P-goal-plan/P-goal-plan.md +28 -143
  29. package/template/workflows/specdev/P-goal-plan/completion-control.md +1 -1
  30. package/template/workflows/specdev/P-goal-plan/references/goal-lifecycle.md +35 -0
  31. package/template/workflows/specdev/P-goal-plan/references/goal-tickets-map-template.md +15 -0
  32. package/template/workflows/specdev/P-goal-plan/references/map-control.md +28 -0
  33. package/template/workflows/specdev/{O-orchestrate-implementation/O-orchestrate-implementation.md → P-goal-plan/references/multi-change-plan.md} +21 -33
  34. package/template/workflows/specdev/P-goal-plan/references/replan-and-recovery.md +21 -0
  35. package/template/workflows/specdev/P-goal-plan/references/single-change-plan.md +149 -0
  36. package/template/workflows/specdev/R-review-architecture/R-review-architecture.md +48 -53
  37. package/template/workflows/specdev/R-review-architecture/architecture-review-template.md +19 -10
  38. package/template/workflows/specdev/R-review-architecture/proposal-to-ticket.md +3 -1
  39. package/template/workflows/specdev/R-review-architecture/review-rubric.md +52 -0
  40. package/template/workflows/specdev/README.md +36 -216
  41. package/template/workflows/specdev/T-tickets/T-tickets.md +19 -230
  42. package/template/workflows/specdev/T-tickets/references/planning-procedure.md +233 -0
  43. package/template/workflows/specdev/T-tickets/ticket-template.md +16 -0
  44. package/template/workflows/specdev/T-tickets/tickets-map-template.md +14 -0
  45. package/template/workflows/specdev/T-triage/T-triage.md +3 -1
  46. package/template/workflows/specdev/W-wayfinder/W-wayfinder.md +24 -118
  47. package/template/workflows/specdev/W-wayfinder/references/initiative-discovery.md +29 -0
  48. package/template/workflows/specdev/W-wayfinder/references/initiative-template.json +8 -0
  49. package/template/workflows/specdev/W-wayfinder/references/map-traversal.md +120 -0
  50. package/template/workflows/specdev/W-wayfinder/wayfinder-map-template.md +4 -0
  51. package/template/workflows/specdev/common/README.md +1 -1
  52. package/template/workflows/specdev/common/rules/activation-and-memory.md +7 -3
  53. package/template/workflows/specdev/common/rules/artifact-contract.md +10 -2
  54. package/template/workflows/specdev/common/rules/operating-governance.md +38 -0
  55. package/template/workflows/specdev/common/rules/parent-implementation-orchestration.md +6 -2
  56. package/template/workflows/specdev/common/rules/skill-invocation.md +27 -0
  57. package/template/workflows/specdev/common/rules/workflow-routing.md +24 -0
  58. package/template/workflows/specdev/common/rules/workflow-state-and-lifecycle.md +93 -0
  59. package/template/workflows/specdev/common/schemas/goal-tickets-map.schema.json +33 -0
  60. package/template/workflows/specdev/common/schemas/initiative.schema.json +94 -0
  61. package/template/workflows/specdev/common/schemas/ticket.schema.json +168 -1
  62. package/template/workflows/specdev/common/schemas/tickets-map.schema.json +74 -6
  63. package/template/workflows/specdev/common/skills/code-review/SKILL.md +3 -2
  64. package/template/workflows/specdev/common/skills/code-review/references/risk-review.md +25 -0
  65. package/template/workflows/specdev/common/skills/plan-quality-review/SKILL.md +10 -0
  66. package/template/workflows/specdev/common/skills/plan-quality-review/references/checklist.md +13 -0
  67. package/template/workflows/specdev/common/skills/subagent-delivery/SKILL.md +5 -83
  68. package/template/workflows/specdev/common/skills/subagent-delivery/references/dispatch-and-accept.md +87 -0
  69. package/template/workflows/specdev/common/tools/README.md +14 -2
  70. package/template/workflows/specdev/common/tools/plan-contract.mjs +256 -0
  71. package/template/workflows/specdev/common/tools/ticket-control.mjs +251 -0
  72. package/template/workflows/specdev/common/tools/validate-specdev.mjs +58 -40
  73. package/template/workflows/specdev/manifest.json +97 -1
  74. package/template/canonical/canonical-specdev-orchestrate-implementation.md +0 -2839
  75. package/template/workflows/specdev/O-orchestrate-implementation/implementation-evidence-template.md +0 -39
  76. package/template/workflows/specdev/O-orchestrate-implementation/implementation-map-template.md +0 -50
  77. package/template/workflows/specdev/O-orchestrate-implementation/implementation-plan-template.md +0 -61
  78. package/template/workflows/specdev/R-review-architecture/architecture-report-contract.md +0 -123
  79. package/template/workflows/specdev/R-review-architecture/architecture-review-report-template.html +0 -106
  80. /package/template/workflows/specdev/{O-orchestrate-implementation/conflict-and-drift.md → P-goal-plan/references/multi-conflict-and-drift.md} +0 -0
  81. /package/template/workflows/specdev/{O-orchestrate-implementation/execution-loop.md → P-goal-plan/references/multi-execution-loop.md} +0 -0
  82. /package/template/workflows/specdev/{O-orchestrate-implementation/input-readiness.md → P-goal-plan/references/multi-input-readiness.md} +0 -0
  83. /package/template/workflows/specdev/{O-orchestrate-implementation/super-dag.md → P-goal-plan/references/multi-super-dag.md} +0 -0
@@ -20,6 +20,11 @@ import { execFileSync } from "node:child_process";
20
20
  import { dirname, basename, extname, join, relative, resolve, sep } from "node:path";
21
21
  import { fileURLToPath } from "node:url";
22
22
 
23
+ import {
24
+ validateTicketPlan, validatePlanMap, validateInvocationCoverage,
25
+ validateGoalMap, validateInitiative, resolveProjectSource,
26
+ } from "./plan-contract.mjs";
27
+
23
28
  const DOMAIN_SCHEMA_VERSION = 3;
24
29
  const CONFIG_SCHEMA_VERSION = 5;
25
30
  const GOAL_PLAN_SCHEMA_VERSION = 6;
@@ -42,7 +47,6 @@ const EXPECTED_WORKS = new Set([
42
47
  "I-implement",
43
48
  "I-init-setup",
44
49
  "L-learn-change",
45
- "O-orchestrate-implementation",
46
50
  "P-goal-plan",
47
51
  "P-prototype",
48
52
  "R-review-architecture",
@@ -111,7 +115,6 @@ const VALID_STAGES = new Set([
111
115
  "review",
112
116
  "prototype",
113
117
  "wayfinder",
114
- "orchestrate-implementation",
115
118
  "complete",
116
119
  ]);
117
120
  const REQUIRED_TICKET_KEYS = new Set([
@@ -175,10 +178,11 @@ const STATE_ARTIFACT_BASENAMES = new Set([
175
178
  "diagnosis.md",
176
179
  "source.md",
177
180
  "architecture-review.md",
178
- "architecture-review.html",
179
181
  "wayfinder-map.md",
180
182
  "design-tree.json",
181
183
  "implementation-orchestration.md",
184
+ "initiative.json",
185
+ "goal-delivery.md",
182
186
  ]);
183
187
  const FORBIDDEN_OBSOLETE_BASENAMES = new Set([
184
188
  "source-issue.md",
@@ -240,7 +244,11 @@ function parseScalar(raw) {
240
244
  return value.slice(1, -1);
241
245
  }
242
246
  if (value.startsWith("[") && value.endsWith("]")) {
247
+ // JSON object arrays are used by the additive Skill invocation contract.
248
+ // Keep the existing plain YAML scalar-list form for old artifacts.
249
+ try { return JSON.parse(value); } catch { /* legacy scalar list below */ }
243
250
  const inner = value.slice(1, -1).trim();
251
+ if (inner.startsWith("{")) throw new Error("invalid JSON object array in frontmatter");
244
252
  if (!inner) return [];
245
253
  return inner.split(",").map((item) => parseScalar(item));
246
254
  }
@@ -296,6 +304,9 @@ function parseFrontmatter(path) {
296
304
  const colon = line.indexOf(":");
297
305
  if (colon < 0) continue;
298
306
  const key = line.slice(0, colon).trim();
307
+ if (["__proto__", "constructor", "prototype"].includes(key) || Object.hasOwn(meta, key)) {
308
+ throw new Error(`${path}: duplicate or unsafe frontmatter key ${key}`);
309
+ }
299
310
  const raw = line.slice(colon + 1).trim();
300
311
  if (!raw) {
301
312
  meta[key] = [];
@@ -854,13 +865,6 @@ function capabilityChecks(root) {
854
865
  ],
855
866
  ],
856
867
  ],
857
- [
858
- "orchestrate-implementation",
859
- [
860
- join(root, "O-orchestrate-implementation", "O-orchestrate-implementation.md"),
861
- ["Ready Spec", "Ready Tickets", "Implementation Map", "Implementation Plan", "lead-directed", "implementation_agent_limit", "serialization", "I-implement"],
862
- ],
863
- ],
864
868
  [
865
869
  "implement",
866
870
  [
@@ -900,7 +904,14 @@ function capabilityChecks(root) {
900
904
  "architecture-review",
901
905
  [
902
906
  join(root, "R-review-architecture", "R-review-architecture.md"),
903
- ["shallow", "interface", "locality", "Tailwind CDN", "Mermaid CDN", "最佳推荐"],
907
+ ["结构性坏味道", "code-judo", "删除测试", "高置信候选", "最佳推荐"],
908
+ ],
909
+ ],
910
+ [
911
+ "architecture-review-rubric",
912
+ [
913
+ join(root, "R-review-architecture", "review-rubric.md"),
914
+ ["删除测试", "文件大小", "高置信候选", "spaghetti growth"],
904
915
  ],
905
916
  ],
906
917
  [
@@ -938,15 +949,6 @@ function capabilityChecks(root) {
938
949
  errors.push(`capability '${ability}' lost markers: ${JSON.stringify(missing)}`);
939
950
  }
940
951
  }
941
- if (!isFile(join(root, "R-review-architecture", "architecture-review-report-template.html"))) {
942
- errors.push("architecture review lost its visual HTML report template");
943
- } else {
944
- const html = readText(join(root, "R-review-architecture", "architecture-review-report-template.html"));
945
- for (const marker of ["cdn.tailwindcss.com", "mermaid", "Before", "After", "top-recommendation"]) {
946
- if (!html.includes(marker)) errors.push(`architecture HTML template lost marker ${marker}`);
947
- }
948
- }
949
-
950
952
  for (const required of [
951
953
  "common/rules/codebase-design.md",
952
954
  "common/schemas/design-tree.schema.json",
@@ -954,14 +956,9 @@ function capabilityChecks(root) {
954
956
  "G-grill-with-docs/design-tree-template.json",
955
957
  "W-wayfinder/local-tracker-contract.md",
956
958
  "W-wayfinder/solution-comment-template.md",
957
- "R-review-architecture/architecture-report-contract.md",
958
959
  "common/rules/parent-implementation-orchestration.md",
959
960
  "common/schemas/implementation-map.schema.json",
960
961
  "common/schemas/implementation-plan.schema.json",
961
- "O-orchestrate-implementation/input-readiness.md",
962
- "O-orchestrate-implementation/implementation-map-template.md",
963
- "O-orchestrate-implementation/implementation-plan-template.md",
964
- "O-orchestrate-implementation/implementation-evidence-template.md",
965
962
  ]) {
966
963
  if (!isFile(join(root, required))) errors.push(`missing architecture/wayfinding contract ${required}`);
967
964
  }
@@ -1555,6 +1552,9 @@ function validateProjectSkillMatrix(body, label, errors, repoRoot = null) {
1555
1552
  errors.push(`${label}: project Skill Path escapes the project root: ${skillPath}`);
1556
1553
  } else if (!isFile(resolvedSkill)) {
1557
1554
  errors.push(`${label}: project Skill does not exist under --repo: ${skillPath}`);
1555
+ } else {
1556
+ try { resolveProjectSource(resolvedRepo, `<Path>${skillPath}</Path>`); }
1557
+ catch (error) { errors.push(`${label}: ${error.message}`); }
1558
1558
  }
1559
1559
  }
1560
1560
  entries.push({ appliesTo: new Set(appliesTo), path: skillPath });
@@ -1591,6 +1591,11 @@ function validateMap(path, errors, repoRoot = null) {
1591
1591
  return null;
1592
1592
  }
1593
1593
  const { meta, body } = parseFrontmatter(path);
1594
+ if (meta.artifact === "goal-tickets-map") {
1595
+ errors.push(...validateGoalMap({ path, meta, body }, dirname(path)).map(error => `${basename(path)}: ${error}`));
1596
+ return { path, meta, body, projectSkillMatrix: [], goalMap: true };
1597
+ }
1598
+ errors.push(...validatePlanMap({ path, meta, body }, dirname(path)).map(error => `${basename(path)}: ${error}`));
1594
1599
  if (meta.artifact !== "tickets-map" || meta.schema_version !== DOMAIN_SCHEMA_VERSION) {
1595
1600
  errors.push(`${basename(path)}: artifact/schema_version must be tickets-map/${DOMAIN_SCHEMA_VERSION}`);
1596
1601
  }
@@ -2392,13 +2397,13 @@ function validateGitEvidence(repoRoot, changeStatus, errors) {
2392
2397
  }
2393
2398
  }
2394
2399
 
2395
- function validateParentImplementation(change, parentStatus, stage, errors, warnings) {
2396
- const required = stage === "orchestrate-implementation";
2400
+ function validateParentImplementation(change, parentStatus, stage, errors, warnings, repoRoot = null) {
2401
+ const required = stage === "goal-plan";
2397
2402
  const mapPath = join(change, "implementation-map.md");
2398
2403
  const planPath = join(change, "implementation-plan.md");
2399
2404
  if (!required && !isFile(mapPath) && !isFile(planPath)) return null;
2400
- if (!isFile(mapPath)) errors.push("orchestrate-implementation stage requires implementation-map.md");
2401
- if (!isFile(planPath)) errors.push("orchestrate-implementation stage requires implementation-plan.md");
2405
+ if (!isFile(mapPath)) errors.push("goal-plan stage requires implementation-map.md");
2406
+ if (!isFile(planPath)) errors.push("goal-plan stage requires implementation-plan.md");
2402
2407
  if (!isFile(mapPath) || !isFile(planPath)) return null;
2403
2408
 
2404
2409
  const parentName = basename(change);
@@ -2552,7 +2557,7 @@ function validateParentImplementation(change, parentStatus, stage, errors, warni
2552
2557
  }
2553
2558
 
2554
2559
  const childMapPath = join(memberRoot, "tickets-map.md");
2555
- const childMap = isFile(childMapPath) ? validateMap(childMapPath, memberErrors) : null;
2560
+ const childMap = isFile(childMapPath) ? validateMap(childMapPath, memberErrors, repoRoot) : null;
2556
2561
  if (!childMap) memberErrors.push("Ready Tickets Map is required before parent creation");
2557
2562
  else {
2558
2563
  if (childMap.meta.change !== member) memberErrors.push("tickets-map.md: change must equal member directory name");
@@ -2569,6 +2574,7 @@ function validateParentImplementation(change, parentStatus, stage, errors, warni
2569
2574
  const childTickets = new Map();
2570
2575
  for (const name of ticketFiles) {
2571
2576
  const artifact = validateTicket(join(ticketRoot, name), memberErrors);
2577
+ if (artifact) memberErrors.push(...validateTicketPlan(artifact, { repoRoot }).map(error => `${name}: ${error}`));
2572
2578
  if (!artifact) continue;
2573
2579
  const ticketId = String(artifact.meta.id);
2574
2580
  if (artifact.meta.change !== member) memberErrors.push(`${name}: change must equal member directory name`);
@@ -2592,8 +2598,10 @@ function validateParentImplementation(change, parentStatus, stage, errors, warni
2592
2598
  memberErrors.push(`${ticketId}: parent creation requires status=ready and ready=true`);
2593
2599
  } else if (new Set(["ready", "in_progress", "review"]).has(artifact.meta.status) && artifact.meta.ready !== true) {
2594
2600
  memberErrors.push(`${ticketId}: executable Ticket must keep ready=true`);
2595
- } else if (new Set(["blocked", "deviated"]).has(artifact.meta.status) && map.meta.status !== "blocked" && plan.meta.status !== "blocked") {
2596
- memberErrors.push(`${ticketId}: blocked/deviated Ticket requires blocked parent artifacts`);
2601
+ } else if (new Set(["blocked", "deviated"]).has(artifact.meta.status)) {
2602
+ // A local blocker does not revoke unrelated nodes' execution gate.
2603
+ // The controller excludes this node and its dependency closure; only a
2604
+ // global blocker or an empty legal frontier pauses the whole parent.
2597
2605
  } else if (artifact.meta.status === "draft") {
2598
2606
  memberErrors.push(`${ticketId}: draft Ticket cannot belong to a parent implementation`);
2599
2607
  }
@@ -2601,6 +2609,7 @@ function validateParentImplementation(change, parentStatus, stage, errors, warni
2601
2609
  }
2602
2610
 
2603
2611
  if (childMap) {
2612
+ memberErrors.push(...validateInvocationCoverage(childTickets, childMap.projectSkillMatrix));
2604
2613
  validateProjectSkillCoverage(
2605
2614
  childMap.projectSkillMatrix,
2606
2615
  childTickets.keys(),
@@ -2772,8 +2781,8 @@ function validateParentImplementation(change, parentStatus, stage, errors, warni
2772
2781
  if (count > 1) errors.push(`repository/ref integration must be serialized for ${ref}; found ${count}`);
2773
2782
  }
2774
2783
 
2775
- if (required && parentStatus && new Set(["active", "blocked"]).has(parentStatus.change_status) && parentStatus.current_work !== "specdev/orchestrate-implementation") {
2776
- errors.push("parent active/blocked status must keep current_work=specdev/orchestrate-implementation");
2784
+ if (required && parentStatus && new Set(["active", "blocked"]).has(parentStatus.change_status) && !new Set(["specdev/goal-plan"]).has(parentStatus.current_work)) {
2785
+ errors.push("parent active/blocked status must keep current_work=specdev/goal-plan");
2777
2786
  }
2778
2787
  if (parentStatus?.change_status === "completed") {
2779
2788
  const incomplete = members.filter((member) => memberStatuses.get(member)?.change_status !== "completed");
@@ -2841,7 +2850,8 @@ function validateChange(change, stage = null, repoRoot = null) {
2841
2850
  }
2842
2851
 
2843
2852
  const changeStatus = validateChangeStatus(join(change, ".status.json"), basename(change), errors);
2844
- validateParentImplementation(change, changeStatus, stage, errors, warnings);
2853
+ validateParentImplementation(change, changeStatus, stage, errors, warnings, repoRoot);
2854
+ errors.push(...validateInitiative(change));
2845
2855
  if (isFile(join(change, "source-issue.md"))) {
2846
2856
  errors.push("obsolete source-issue.md is forbidden; use source.md without compatibility fallback");
2847
2857
  }
@@ -2862,13 +2872,14 @@ function validateChange(change, stage = null, repoRoot = null) {
2862
2872
  validatePrototypes(change, stage === "prototype", errors);
2863
2873
  validateChangeLearning(change, stage === "learn-change", errors);
2864
2874
 
2865
- const specRequired = new Set(["spec", "tickets", "goal-plan", "implement", "complete"]).has(stage) && !isFile(join(change, "implementation-map.md"));
2875
+ const isParentImplementation = isFile(join(change, "implementation-map.md"));
2876
+ const specRequired = new Set(["spec", "tickets", "goal-plan", "implement", "complete"]).has(stage) && !isParentImplementation;
2866
2877
  const specPath = join(change, "spec.md");
2867
2878
  const spec = isFile(specPath) || specRequired
2868
2879
  ? validateSpec(specPath, errors, warnings)
2869
2880
  : null;
2870
2881
  const ticketMode = isDirectory(join(change, "ticket"));
2871
- const mapRequired = new Set(["tickets", "goal-plan"]).has(stage) || (stage === "implement" && ticketMode);
2882
+ const mapRequired = !isParentImplementation && (new Set(["tickets", "goal-plan"]).has(stage) || (stage === "implement" && ticketMode));
2872
2883
  const mapPath = join(change, "tickets-map.md");
2873
2884
  const ticketsMap = isFile(mapPath) || mapRequired ? validateMap(mapPath, errors, repoRoot) : null;
2874
2885
  const goalPlanPath = join(change, "goal-plan.md");
@@ -2892,7 +2903,7 @@ function validateChange(change, stage = null, repoRoot = null) {
2892
2903
  }
2893
2904
 
2894
2905
  const ticketDir = join(change, "ticket");
2895
- const ticketsRequired = new Set(["tickets", "goal-plan"]).has(stage) || (stage === "implement" && ticketMode);
2906
+ const ticketsRequired = !isParentImplementation && (new Set(["tickets", "goal-plan"]).has(stage) || (stage === "implement" && ticketMode));
2896
2907
  const ticketFiles = isDirectory(ticketDir)
2897
2908
  ? readdirSync(ticketDir)
2898
2909
  .filter((name) => name.endsWith(".md"))
@@ -2909,6 +2920,7 @@ function validateChange(change, stage = null, repoRoot = null) {
2909
2920
  for (const path of ticketFiles) {
2910
2921
  const artifact = validateTicket(path, errors);
2911
2922
  if (!artifact) continue;
2923
+ errors.push(...validateTicketPlan(artifact, { repoRoot, requirePlan: stage === "implement" }).map(error => `${basename(path)}: ${error}`));
2912
2924
  const ticketId = String(artifact.meta.id);
2913
2925
  if (artifact.meta.change !== basename(change)) {
2914
2926
  errors.push(`${basename(path)}: change must equal directory name ${basename(change)}`);
@@ -2931,7 +2943,8 @@ function validateChange(change, stage = null, repoRoot = null) {
2931
2943
  }
2932
2944
  }
2933
2945
 
2934
- if (ticketsMap) {
2946
+ if (ticketsMap && !ticketsMap.goalMap) {
2947
+ errors.push(...validateInvocationCoverage(tickets, ticketsMap.projectSkillMatrix));
2935
2948
  validateProjectSkillCoverage(
2936
2949
  ticketsMap.projectSkillMatrix,
2937
2950
  tickets.keys(),
@@ -3210,4 +3223,9 @@ function main(argv) {
3210
3223
  return usage();
3211
3224
  }
3212
3225
 
3213
- process.exitCode = main(process.argv.slice(2));
3226
+ export { parseFrontmatter, validateChange, validateTicket, validateMap, pathsOverlap, findCycle };
3227
+
3228
+ if (process.argv[1] && resolve(process.argv[1]) === fileURLToPath(import.meta.url)) {
3229
+ try { process.exitCode = main(process.argv.slice(2)); }
3230
+ catch (error) { console.error(`ERROR: ${error.message}`); process.exitCode = 1; }
3231
+ }
@@ -1 +1,97 @@
1
- {"schema_version":1,"id":"specdev","version":"1.0.0","persistent_knowledge":["<Path>{roots.state}/specdev/adr/</Path>","<Path>{roots.state}/specdev/context/</Path>"],"stages":[{"id":"intake","after":[],"inputs":["request"],"outputs":["source","triage"],"risk":"read-only","context_budget":12000},{"id":"decide","after":["intake"],"inputs":["source","triage"],"outputs":["spec","adr"],"risk":"read-only","context_budget":20000},{"id":"plan","after":["decide"],"inputs":["spec"],"outputs":["ticket","plan"],"risk":"read-only","context_budget":18000},{"id":"execute","after":["plan"],"inputs":["ticket","plan"],"outputs":["code","evidence"],"risk":"local-reversible","context_budget":24000},{"id":"verify","after":["execute"],"inputs":["code","evidence"],"outputs":["verification"],"risk":"read-only","context_budget":12000},{"id":"learn","after":["verify"],"inputs":["verification"],"outputs":["learning"],"risk":"read-only","context_budget":10000}]}
1
+ {
2
+ "schema_version": 1,
3
+ "id": "specdev",
4
+ "version": "1.0.0",
5
+ "persistent_knowledge": [
6
+ "<Path>{roots.state}/specdev/adr/</Path>",
7
+ "<Path>{roots.state}/specdev/context/</Path>"
8
+ ],
9
+ "stages": [
10
+ {
11
+ "id": "intake",
12
+ "after": [],
13
+ "inputs": [
14
+ "request"
15
+ ],
16
+ "outputs": [
17
+ "source",
18
+ "triage"
19
+ ],
20
+ "risk": "read-only",
21
+ "context_budget": 12000
22
+ },
23
+ {
24
+ "id": "decide",
25
+ "after": [],
26
+ "inputs": [
27
+ "request-or-frozen-source"
28
+ ],
29
+ "outputs": [
30
+ "spec",
31
+ "adr"
32
+ ],
33
+ "risk": "read-only",
34
+ "context_budget": 20000
35
+ },
36
+ {
37
+ "id": "plan",
38
+ "after": [
39
+ "decide"
40
+ ],
41
+ "inputs": [
42
+ "spec"
43
+ ],
44
+ "outputs": [
45
+ "ticket",
46
+ "plan"
47
+ ],
48
+ "risk": "read-only",
49
+ "context_budget": 18000
50
+ },
51
+ {
52
+ "id": "execute",
53
+ "after": [
54
+ "plan"
55
+ ],
56
+ "inputs": [
57
+ "ticket",
58
+ "plan"
59
+ ],
60
+ "outputs": [
61
+ "code",
62
+ "evidence"
63
+ ],
64
+ "risk": "local-reversible",
65
+ "context_budget": 24000
66
+ },
67
+ {
68
+ "id": "verify",
69
+ "after": [
70
+ "execute"
71
+ ],
72
+ "inputs": [
73
+ "code",
74
+ "evidence"
75
+ ],
76
+ "outputs": [
77
+ "verification"
78
+ ],
79
+ "risk": "read-only",
80
+ "context_budget": 12000
81
+ },
82
+ {
83
+ "id": "learn",
84
+ "after": [
85
+ "verify"
86
+ ],
87
+ "inputs": [
88
+ "verification"
89
+ ],
90
+ "outputs": [
91
+ "learning"
92
+ ],
93
+ "risk": "read-only",
94
+ "context_budget": 10000
95
+ }
96
+ ]
97
+ }