thoth-agents 0.3.10 → 0.3.12

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 (52) hide show
  1. package/README.md +119 -33
  2. package/dist/{chunk-TKIDBRM3.js → chunk-5UBJB5QO.js} +4 -1
  3. package/dist/{chunk-M2WF46BP.js → chunk-DX4U3AD3.js} +387 -231
  4. package/dist/{chunk-JBG7XMIG.js → chunk-VPVBYBPU.js} +602 -180
  5. package/dist/cli/codex-plugin-install.d.ts +16 -2
  6. package/dist/cli/index.js +7 -5
  7. package/dist/cli/tui/index.js +2 -2
  8. package/dist/config/constants.d.ts +3 -3
  9. package/dist/harness/adapters/claude-code.d.ts +8 -0
  10. package/dist/harness/adapters/codex-surfaces.d.ts +2 -2
  11. package/dist/harness/core/agent-pack.d.ts +60 -5
  12. package/dist/harness/core/sdd.d.ts +32 -19
  13. package/dist/harness/writers/codex-plugin-package.d.ts +1 -0
  14. package/dist/index.js +2 -2
  15. package/package.json +4 -4
  16. package/plugin/.claude-plugin/.thoth-agents-plugin-assets.json +7 -7
  17. package/plugin/.claude-plugin/plugin.json +1 -1
  18. package/plugin/.codex-plugin/plugin.json +1 -1
  19. package/plugin/agents/deep.md +10 -31
  20. package/plugin/agents/designer.md +10 -31
  21. package/plugin/agents/explorer.md +10 -30
  22. package/plugin/agents/librarian.md +10 -30
  23. package/plugin/agents/oracle.md +11 -31
  24. package/plugin/agents/orchestrator.md +48 -35
  25. package/plugin/agents/quick.md +10 -31
  26. package/plugin/skills/plan-reviewer/SKILL.md +54 -15
  27. package/plugin/skills/thoth-archive/SKILL.md +5 -0
  28. package/plugin/skills/thoth-archive/scripts/archive.mjs +30 -10
  29. package/plugin/skills/thoth-constitution/SKILL.md +5 -0
  30. package/plugin/skills/thoth-constitution/templates/constitution.md +19 -2
  31. package/plugin/skills/thoth-init/SKILL.md +5 -0
  32. package/plugin/skills/thoth-sdd/SKILL.md +48 -11
  33. package/plugin/skills/thoth-sdd/references/phases/implement.md +44 -6
  34. package/plugin/skills/thoth-sdd/references/phases/tasks.md +23 -2
  35. package/plugin/skills/thoth-sdd/references/phases/verify.md +7 -5
  36. package/plugin/skills/thoth-sdd/scripts/validate.mjs +263 -30
  37. package/plugin/skills/thoth-sdd/templates/tasks.md +18 -2
  38. package/skills/README.md +2 -1
  39. package/skills/plan-reviewer/SKILL.md +54 -15
  40. package/skills/thoth-archive/SKILL.md +5 -0
  41. package/skills/thoth-archive/scripts/archive.mjs +30 -10
  42. package/skills/thoth-constitution/SKILL.md +5 -0
  43. package/skills/thoth-constitution/templates/constitution.md +19 -2
  44. package/skills/thoth-init/SKILL.md +5 -0
  45. package/skills/thoth-sdd/SKILL.md +48 -11
  46. package/skills/thoth-sdd/references/phases/implement.md +44 -6
  47. package/skills/thoth-sdd/references/phases/tasks.md +23 -2
  48. package/skills/thoth-sdd/references/phases/verify.md +7 -5
  49. package/skills/thoth-sdd/scripts/validate.mjs +263 -30
  50. package/skills/thoth-sdd/templates/tasks.md +18 -2
  51. package/.agents/plugins/marketplace.json +0 -20
  52. package/.claude-plugin/marketplace.json +0 -21
@@ -1,6 +1,11 @@
1
1
  ---
2
2
  name: thoth-sdd
3
- description: Run thoth-agents Direct, Accelerated, or Full specification-driven development with Spec Kit-grade artifacts, OpenSpec-style durable deltas, fast-forward planning, and oracle-only analysis and verification.
3
+ description: Run thoth-agents Direct, Accelerated, or Full specification-driven development with Spec Kit-grade artifacts, OpenSpec-style durable deltas, fast-forward planning, and proportional independent verification.
4
+ license: MIT
5
+ compatibility: Requires Node.js >=22.13 for bundled validation scripts.
6
+ metadata:
7
+ author: thoth-agents
8
+ version: "1.0"
4
9
  ---
5
10
 
6
11
  # Thoth SDD
@@ -18,21 +23,53 @@ intent is clear and risk is low.
18
23
 
19
24
  Accelerated is a **fast-forward** route: root writes `spec.md`, `plan.md`, and
20
25
  `tasks.md` in one uninterrupted pass and creates optional artifacts only for a
21
- concrete risk. After `ready`, both artifact-backed routes pause once to offer
26
+ concrete risk. After `ready`, both artifact-backed routes offer
22
27
  `Review plan with Oracle (Recommended)` or `Proceed without review`. Full uses
23
28
  separate planning gates because uncertainty or failure cost justifies them.
24
29
 
25
30
  An explicitly named route counts as the user's selection. Otherwise assess and
26
- recommend Direct, Accelerated, or Full, then wait for the user to choose; the
27
- recommendation is not the decision. A generic request to “use SDD” makes
28
- Accelerated the minimum recommendation but does not force it.
31
+ recommend Direct, Accelerated, or Full, first summarize the relevant request
32
+ context, scope, clarity, risk, and why the recommendation fits, then ask. When a
33
+ native route question returns answerless, make at most three total attempts;
34
+ after the third answerless result, treat the recommended route as selected. Any
35
+ explicit answer wins. A generic request to “use SDD” makes Accelerated the
36
+ minimum recommendation but does not force it.
37
+
38
+ At the post-`ready` review choice, an explicit answer wins, including
39
+ `Proceed without review`. When the native question returns answerless, make at
40
+ most three total attempts; after the third answerless result, treat
41
+ `Review plan with Oracle (Recommended)` as selected. Once review is selected,
42
+ repair actionable same-intent planning blockers, revalidate affected gates, and
43
+ use a fresh Oracle for every new approval round until `[OKAY]`; stop instead on
44
+ a material human-owned blocker.
45
+
46
+ These bounded fallbacks apply only to the route, plan-review, and implementation
47
+ questions. Never apply them to secrets, destructive or security-sensitive
48
+ actions, or material human-owned product or architecture decisions.
29
49
 
30
50
  ## Ownership
31
51
 
32
52
  - Root owns sequential coordination artifacts, gate execution, and archive.
33
53
  - Explorer owns Full-route repository discovery.
34
- - Designer, quick, deep, or root may implement according to scope.
35
- - Oracle owns `plan-review` when the user selects it and **every** `verify`. The
54
+ - SDD routes govern artifacts and gates, not implementation ownership. Root,
55
+ `designer`, `quick`, or `deep` may implement in Direct, Accelerated, or Full.
56
+ - Root decides ownership from explicit safe user direction and demonstrated net
57
+ gain. Delegation benefits include specialization, context isolation,
58
+ independent bounded work, quality, latency, or total cost; root continuity
59
+ benefits include short or sequential work, shared mutable state, accumulated
60
+ context, rediscovery, and coordination overhead. Route, file count, or cheaper
61
+ model price alone never selects an owner.
62
+ - Only after deciding to delegate implementation, select `designer` for UI/UX,
63
+ `quick` for known narrow low-risk work, or `deep` for coupled, edge-case-heavy,
64
+ migration, concurrency, shared-contract, or high-risk work.
65
+ - Each mutable surface has one writer; independent non-overlapping surfaces may
66
+ split, while coupled surfaces use one `deep` writer and ordered handoffs.
67
+ - Oracle owns `plan-review` when review is explicitly selected or chosen by the
68
+ bounded recommended fallback. Every route requires
69
+ mandatory verification, but final-verification ownership is proportional:
70
+ trivial deterministic Direct work may be verified by Root when Root is not
71
+ self-approving its own implementation; materially risky Direct work and every
72
+ Accelerated or Full final verify require a fresh read-only Oracle. The
36
73
  implementation writer never approves its own work.
37
74
 
38
75
  ## Progressive loading
@@ -78,10 +115,10 @@ node "<skill-dir>/scripts/validate.mjs" --change openspec/changes/<feature> --ro
78
115
  - **Checklist**: run only when activated; the later `ready` gate includes it if
79
116
  present.
80
117
 
81
- `ready` validates the artifacts needed before the user chooses
82
- `Review plan with Oracle (Recommended)` or `Proceed without review`. Review
83
- approval remains separate from implementation confirmation and never satisfies
84
- final verification.
118
+ `ready` validates the artifacts needed before the explicit or bounded-default
119
+ `Review plan with Oracle (Recommended)` / `Proceed without review` choice.
120
+ Review approval remains separate from implementation confirmation and never
121
+ satisfies final verification.
85
122
  `closeout` additionally requires completed tasks, independent oracle PASS,
86
123
  complete FR/buildable-SC evidence, an observed PASS or explicit residual RISK
87
124
  for every outcome SC, and an archive report ready for the transactional archive
@@ -1,12 +1,42 @@
1
1
  # Implement contract
2
2
 
3
- **Owner**: root, designer, quick, or deep; exactly one writer per mutable surface
3
+ **Owner**: adaptive root, `designer`, `quick`, or `deep` in every route; exactly
4
+ one writer per mutable surface
4
5
 
5
- Root marks selected artifact-backed tasks `[~]`, then assigns exact paths,
6
- accepted FR/buildable-SC scope, non-goals, and verification commands. Use the
7
- mandatory `tdd` skill for behavior changes and work in vertical red/green
8
- slices. Child writers never edit task state; root marks `[x]` only after checking
9
- task-specific evidence.
6
+ SDD routes govern artifacts and gates, not implementation ownership. Before
7
+ implementation or dispatch, root records the decided owner, task-shape/net-gain
8
+ rationale, exact paths, accepted FR/buildable-SC scope, non-goals, and
9
+ verification commands. Route, file count, or cheaper model price alone is not an
10
+ ownership rationale.
11
+
12
+ Root may retain implementation when short or sequential work, shared mutable
13
+ state, accumulated context, rediscovery, or coordination overhead outweighs
14
+ delegation benefit. Delegate when specialization, context isolation, independent
15
+ bounded work, quality, latency, or total cost creates demonstrated net gain. If
16
+ root owns the surface, do not dispatch a writer. If a specialist owns it, send a
17
+ bounded handoff with the exact surface, requirements, and checks.
18
+
19
+ Root marks selected artifact-backed tasks `[~]`; Direct or no-artifact work has
20
+ no task state. Use the mandatory `tdd` skill for behavior changes and work in
21
+ vertical red/green slices. Child writers never edit task state; root marks `[x]`
22
+ only after checking task-specific evidence.
23
+
24
+ After deciding delegation creates net gain, select deterministically:
25
+
26
+ - `designer` for user-facing UI/UX, interaction, accessibility, responsive, or
27
+ visual-quality work;
28
+ - `quick` for a known narrow mechanical low-risk surface with exact targets;
29
+ - `deep` for coupled multi-file, shared-contract, migration, concurrency,
30
+ edge-case-heavy, or high-risk work.
31
+
32
+ Proven independent surfaces may use different writers only with non-overlapping
33
+ ownership. Overlapping or compatibility-coupled work uses one `deep` writer and
34
+ ordered handoffs. A writer escalates before expanding beyond its routing
35
+ boundary. Every route requires mandatory verification, and the implementation
36
+ writer never approves its own work. For trivial deterministic Direct work, Root
37
+ may run the proportionate focused checks when Root is not self-approving its own
38
+ implementation. For materially risky Direct work and every Accelerated or Full
39
+ final verify, root hands the unchanged candidate to a fresh read-only Oracle.
10
40
 
11
41
  Implementation evidence may refine an artifact without restarting the workflow:
12
42
 
@@ -17,3 +47,11 @@ Implementation evidence may refine an artifact without restarting the workflow:
17
47
  silently expanding this one.
18
48
 
19
49
  Report files changed, checks executed, deviations, and remaining work.
50
+
51
+ ## Native dispatch groups and waves
52
+
53
+ For each ready group, confirm prerequisites, ordered lane tasks, exact path
54
+ union, owner, requirements, and checks. Select the capacity-bounded set of
55
+ undispatched ready lanes and create one fresh native specialist assignment per admitted lane. Issue every dispatch in that native wave before any wait, status,
56
+ result collection, or root implementation action. Retain handles; when terminal evidence frees capacity, dispatch the next undispatched ready lane before waiting again. Validate terminal evidence per lane, while root alone updates task state. Cross the declared barrier only after every lane is terminal and reconciled. Preserve truthful capability/capacity fallback: when native
57
+ concurrency is unavailable or width is one, use a truthful sequential fallback.
@@ -22,6 +22,27 @@ not justify artificial implementation tasks.
22
22
 
23
23
  Order test-first work before its implementation, group tasks by independently
24
24
  deliverable story, identify the MVP, and state dependencies. `[P]` is permitted
25
- only when mutable paths provably do not overlap and the Parallel execution
26
- section names a concrete pairing. If there is no safe parallel work, use
25
+ only for tasks assigned to a declared lane whose mutable path union does not
26
+ overlap another lane in the same group. If there is no safe parallel work, use
27
27
  `- None: <evidence-backed reason>` instead. Avoid ceremonial tasks.
28
+
29
+ ## Parallel execution
30
+
31
+ Declare safe work with this exact grammar:
32
+
33
+ ### Group P1
34
+
35
+ - Lane L1: T001 -> T002 | Owner: deep
36
+ - Lane L2: T003 -> T004 | Owner: quick
37
+ - Prerequisites: None
38
+ - Barrier: Final verification
39
+ - Rationale: Both lane path sets are disjoint and neither lane consumes peer output.
40
+
41
+ Groups and lanes are sequential and unique. Every `[P]` task belongs to exactly one lane; non-`[P]` tasks do not. Lane surfaces are the union of exact task
42
+ paths, and lanes in a group have disjoint surfaces and no cross-lane dependency.
43
+ The `Rationale` must explicitly state path-disjointness and cross-lane dependency
44
+ evidence so structural validation can gate the evidence shape and Oracle can
45
+ judge whether the claim is true.
46
+ Prerequisites name known tasks outside the group; the barrier is a downstream
47
+ task or `Final verification` after all lane members. If no group exists, use
48
+ only `- None: <evidence-backed reason>` and no task may use `[P]`.
@@ -1,10 +1,12 @@
1
1
  # Verify contract
2
2
 
3
- **Owner**: oracle, always read-only and independent
3
+ **Owner**: route- and risk-aware; Root for trivial deterministic Direct, otherwise a fresh read-only Oracle
4
4
 
5
- Oracle verifies Direct, Accelerated, and Full work. The root or writer that
6
- implemented the change cannot substitute for oracle. Inspect changed code and
7
- run or validate the smallest sufficient checks.
5
+ Every route requires mandatory verification. Trivial deterministic Direct work
6
+ may be verified by Root with focused deterministic checks. Materially risky
7
+ Direct work and Accelerated or Full final verification use a fresh read-only
8
+ Oracle. The implementation writer never approves its own work. Inspect changed
9
+ code and run or validate the smallest sufficient checks.
8
10
 
9
11
  Judge three dimensions separately: **completeness** of accepted scope and
10
12
  coverage, **correctness** against behavioral contracts and executed evidence,
@@ -16,7 +18,7 @@ task.
16
18
 
17
19
  Return `pass` or `fail`, compliance matrix, commands/results, stable findings,
18
20
  critical issues, warnings, and remediation anchors. For Direct, return the
19
- verdict in-session. For Accelerated and Full, root persists oracle's exact result
21
+ verdict in-session regardless of owner. For Accelerated and Full, root persists Oracle's exact result
20
22
  using `<skill-dir>/templates/verify-report.md`, where `<skill-dir>` is the
21
23
  directory containing the installed `thoth-sdd/SKILL.md`. Fail routes to converge
22
24
  (straight back to implement for Direct); PASS permits closeout and archive for
@@ -540,6 +540,97 @@ function exactTaskPath(line) {
540
540
  return normalized.toLowerCase();
541
541
  }
542
542
 
543
+ function taskDependencyEdges(content) {
544
+ return [...content.matchAll(/\bT\d{3}(?:\s*->\s*T\d{3})+\b/g)].flatMap(
545
+ ([chain]) => {
546
+ const ids = chain.match(/\bT\d{3}\b/g) ?? [];
547
+ return ids.slice(1).map((target, index) => ({
548
+ source: ids[index],
549
+ target,
550
+ }));
551
+ },
552
+ );
553
+ }
554
+
555
+ function parseParallelGroups(content) {
556
+ const lines = content.split(/\r?\n/);
557
+ const headingIndexes = lines
558
+ .map((line, index) => (/^###\s+Group\s+P\d+\s*$/.test(line) ? index : -1))
559
+ .filter((index) => index >= 0);
560
+ const groups = [];
561
+ let valid = headingIndexes.length > 0;
562
+
563
+ if (
564
+ lines
565
+ .slice(0, headingIndexes[0] ?? lines.length)
566
+ .some((line) => line.trim())
567
+ ) {
568
+ valid = false;
569
+ }
570
+
571
+ for (const [groupIndex, start] of headingIndexes.entries()) {
572
+ const end = headingIndexes[groupIndex + 1] ?? lines.length;
573
+ const groupId = /^###\s+Group\s+P(\d+)\s*$/.exec(lines[start])?.[1];
574
+ const body = lines.slice(start + 1, end).filter((line) => line.trim());
575
+ const lanes = [];
576
+ let prerequisites;
577
+ let barrier;
578
+ let rationale;
579
+ for (const line of body) {
580
+ const lane =
581
+ /^- Lane L(\d+): (T\d{3}(?: -> T\d{3})*)(?: \| Owner: (\S+))?\s*$/.exec(
582
+ line,
583
+ );
584
+ if (lane) {
585
+ lanes.push({
586
+ number: Number.parseInt(lane[1], 10),
587
+ taskIds: lane[2].split(' -> '),
588
+ owner: lane[3],
589
+ });
590
+ continue;
591
+ }
592
+ const prerequisiteLine =
593
+ /^- Prerequisites: (None|T\d{3}(?:, T\d{3})*)\s*$/.exec(line);
594
+ if (prerequisiteLine && prerequisites === undefined) {
595
+ prerequisites =
596
+ prerequisiteLine[1] === 'None' ? [] : prerequisiteLine[1].split(', ');
597
+ continue;
598
+ }
599
+ const barrierLine = /^- Barrier: (Final verification|T\d{3})\s*$/.exec(
600
+ line,
601
+ );
602
+ if (barrierLine && barrier === undefined) {
603
+ barrier = barrierLine[1];
604
+ continue;
605
+ }
606
+ const rationaleLine = /^- Rationale: (\S.*)$/.exec(line);
607
+ if (rationaleLine && rationale === undefined) {
608
+ rationale = rationaleLine[1];
609
+ continue;
610
+ }
611
+ valid = false;
612
+ }
613
+ if (
614
+ groupId === undefined ||
615
+ lanes.length < 2 ||
616
+ rationale === undefined ||
617
+ !isConcreteEvidence(rationale) ||
618
+ lanes.some((lane, index) => lane.number !== index + 1)
619
+ ) {
620
+ valid = false;
621
+ }
622
+ groups.push({
623
+ number: Number.parseInt(groupId ?? '0', 10),
624
+ lanes,
625
+ prerequisites,
626
+ barrier,
627
+ rationale,
628
+ });
629
+ }
630
+ if (groups.some((group, index) => group.number !== index + 1)) valid = false;
631
+ return { groups, valid };
632
+ }
633
+
543
634
  function validateTasks(content, errors, spec) {
544
635
  const artifact = 'tasks.md';
545
636
  const taskLines = content
@@ -644,12 +735,6 @@ function validateTasks(content, errors, spec) {
644
735
  }));
645
736
  const tasksById = new Map(taskRecords.map((task) => [task.id, task]));
646
737
  const hasParallelTask = taskRecords.some((task) => task.parallel);
647
- const parallelLines = (parallelSection ?? '')
648
- .split(/\r?\n/)
649
- .map((line) => [line, [...new Set(line.match(/\bT\d{3}\b/g) ?? [])]])
650
- .filter(([, ids]) => ids.length >= 2);
651
- const referencedTaskIds = new Set(parallelLines.flatMap(([, ids]) => ids));
652
- const hasParallelExample = parallelLines.length > 0;
653
738
  const noParallelMatch = /^-\s+None:\s*(\S.*)$/im.exec(parallelSection ?? '');
654
739
  const explainsNoParallelWork =
655
740
  noParallelMatch !== null && isConcreteEvidence(noParallelMatch[1]);
@@ -657,42 +742,190 @@ function validateTasks(content, errors, spec) {
657
742
  left === right ||
658
743
  left.startsWith(`${right}/`) ||
659
744
  right.startsWith(`${left}/`);
660
- const unknownReferences = [...referencedTaskIds].filter(
661
- (id) => !tasksById.has(id),
745
+ const noneOnly =
746
+ explainsNoParallelWork &&
747
+ parallelSection?.trim() === noParallelMatch?.[0].trim();
748
+ const { groups, valid: validGroupGrammar } = parseParallelGroups(
749
+ parallelSection ?? '',
662
750
  );
663
- const omittedParallelTasks = taskRecords
664
- .filter((task) => task.parallel && !referencedTaskIds.has(task.id))
665
- .map((task) => task.id);
666
- const examplesWithoutParallelTask = parallelLines.some(
667
- ([, ids]) => !ids.some((id) => tasksById.get(id)?.parallel),
751
+ const declaredDependencies = taskDependencyEdges(
752
+ sectionContent(content, 'Dependencies') ?? '',
668
753
  );
669
- const overlappingExamples = parallelLines.some(([, ids]) => {
670
- const paths = ids.map((id) => tasksById.get(id)?.path);
671
- if (paths.some((path) => path === undefined)) return true;
672
- return paths.some((path, index) =>
673
- paths.slice(index + 1).some((other) => pathsOverlap(path, other)),
674
- );
675
- });
754
+ const hasGroups = groups.length > 0;
676
755
  if (
677
756
  parallelSection === undefined ||
678
- (explainsNoParallelWork && hasParallelExample) ||
679
- (hasParallelTask &&
680
- (!hasParallelExample ||
681
- explainsNoParallelWork ||
682
- unknownReferences.length > 0 ||
683
- omittedParallelTasks.length > 0 ||
684
- examplesWithoutParallelTask ||
685
- overlappingExamples)) ||
686
- (!hasParallelTask && !explainsNoParallelWork)
757
+ (hasParallelTask && (!hasGroups || explainsNoParallelWork)) ||
758
+ (!hasParallelTask && !noneOnly) ||
759
+ (explainsNoParallelWork && !noneOnly)
687
760
  ) {
688
761
  errors.push(
689
762
  issue(
690
763
  'SDD-TASK-PARALLEL',
691
764
  artifact,
692
- 'Document existing [P] tasks with non-overlapping paths, or explain why no safe parallel work exists.',
765
+ 'Declare strict parallel groups for [P] tasks, or provide one exclusive evidence-backed None reason.',
766
+ ),
767
+ );
768
+ }
769
+ if (hasGroups && !validGroupGrammar) {
770
+ errors.push(
771
+ issue(
772
+ 'SDD-TASK-LANE-GRAMMAR',
773
+ artifact,
774
+ 'Groups and lanes must use unique sequential IDs, at least two lanes, and every required field.',
693
775
  ),
694
776
  );
695
777
  }
778
+
779
+ if (hasGroups && validGroupGrammar) {
780
+ const memberships = groups.flatMap((group) =>
781
+ group.lanes.flatMap((lane) =>
782
+ lane.taskIds.map((taskId) => ({ group, lane, taskId })),
783
+ ),
784
+ );
785
+ const membershipCounts = new Map();
786
+ for (const { taskId } of memberships) {
787
+ membershipCounts.set(taskId, (membershipCounts.get(taskId) ?? 0) + 1);
788
+ }
789
+ const invalidMembership =
790
+ memberships.some(({ taskId }) => !tasksById.get(taskId)?.parallel) ||
791
+ taskRecords.some(
792
+ (task) => task.parallel && membershipCounts.get(task.id) !== 1,
793
+ );
794
+ if (invalidMembership) {
795
+ errors.push(
796
+ issue(
797
+ 'SDD-TASK-LANE-MEMBERSHIP',
798
+ artifact,
799
+ 'Every [P] task must belong to exactly one lane, and lane members must be known [P] tasks.',
800
+ ),
801
+ );
802
+ }
803
+
804
+ if (
805
+ groups.some((group) =>
806
+ group.lanes.some(
807
+ (lane) => !['designer', 'quick', 'deep'].includes(lane.owner),
808
+ ),
809
+ )
810
+ ) {
811
+ errors.push(
812
+ issue(
813
+ 'SDD-TASK-LANE-OWNER',
814
+ artifact,
815
+ 'Every lane owner must be designer, quick, or deep.',
816
+ ),
817
+ );
818
+ }
819
+
820
+ for (const group of groups) {
821
+ const rationale = group.rationale ?? '';
822
+ const hasPathIndependenceEvidence =
823
+ /\b(?:path|file|surface)s?\b/i.test(rationale) &&
824
+ /\b(?:disjoint|non[- ]?overlap(?:ping)?)\b/i.test(rationale);
825
+ const hasDependencyIndependenceEvidence =
826
+ /\b(?:dependenc(?:y|ies)|consum(?:e|es|ing)|peer output|data flow)\b/i.test(
827
+ rationale,
828
+ );
829
+ if (!hasPathIndependenceEvidence || !hasDependencyIndependenceEvidence) {
830
+ errors.push(
831
+ issue(
832
+ 'SDD-TASK-LANE-RATIONALE',
833
+ artifact,
834
+ 'Parallel rationale must state concrete path-disjointness and cross-lane dependency evidence for Oracle review.',
835
+ ),
836
+ );
837
+ }
838
+
839
+ const memberIds = new Set(group.lanes.flatMap((lane) => lane.taskIds));
840
+ const prerequisites = group.prerequisites ?? [];
841
+ if (
842
+ group.prerequisites === undefined ||
843
+ new Set(prerequisites).size !== prerequisites.length ||
844
+ prerequisites.some(
845
+ (taskId) => !tasksById.has(taskId) || memberIds.has(taskId),
846
+ )
847
+ ) {
848
+ errors.push(
849
+ issue(
850
+ 'SDD-TASK-LANE-PREREQUISITE',
851
+ artifact,
852
+ 'Prerequisites must be unique known tasks outside the group.',
853
+ ),
854
+ );
855
+ }
856
+
857
+ const memberNumbers = [...memberIds].map((id) =>
858
+ Number.parseInt(id.slice(1), 10),
859
+ );
860
+ const barrierNumber = /^T\d{3}$/.test(group.barrier ?? '')
861
+ ? Number.parseInt(group.barrier.slice(1), 10)
862
+ : undefined;
863
+ if (
864
+ group.barrier !== 'Final verification' &&
865
+ (barrierNumber === undefined ||
866
+ !tasksById.has(group.barrier) ||
867
+ memberIds.has(group.barrier) ||
868
+ prerequisites.includes(group.barrier) ||
869
+ memberNumbers.some((number) => barrierNumber <= number))
870
+ ) {
871
+ errors.push(
872
+ issue(
873
+ 'SDD-TASK-LANE-BARRIER',
874
+ artifact,
875
+ 'A task barrier must be a known downstream non-member task, or use exact Final verification.',
876
+ ),
877
+ );
878
+ }
879
+
880
+ const laneByTask = new Map(
881
+ group.lanes.flatMap((lane) =>
882
+ lane.taskIds.map((taskId) => [taskId, lane.number]),
883
+ ),
884
+ );
885
+ if (
886
+ declaredDependencies.some(
887
+ ({ source, target }) =>
888
+ laneByTask.has(source) &&
889
+ laneByTask.has(target) &&
890
+ laneByTask.get(source) !== laneByTask.get(target),
891
+ )
892
+ ) {
893
+ errors.push(
894
+ issue(
895
+ 'SDD-TASK-LANE-DEPENDENCY',
896
+ artifact,
897
+ 'Declared dependencies cannot connect different lanes in one group.',
898
+ ),
899
+ );
900
+ }
901
+
902
+ const lanePaths = group.lanes.map((lane) =>
903
+ lane.taskIds.map((taskId) => tasksById.get(taskId)?.path),
904
+ );
905
+ const overlaps = lanePaths.some((paths, index) =>
906
+ lanePaths
907
+ .slice(index + 1)
908
+ .some((otherPaths) =>
909
+ paths.some(
910
+ (path) =>
911
+ path !== undefined &&
912
+ otherPaths.some(
913
+ (other) => other !== undefined && pathsOverlap(path, other),
914
+ ),
915
+ ),
916
+ ),
917
+ );
918
+ if (overlaps) {
919
+ errors.push(
920
+ issue(
921
+ 'SDD-TASK-LANE-OVERLAP',
922
+ artifact,
923
+ 'Mutable task paths cannot overlap across lanes in one group.',
924
+ ),
925
+ );
926
+ }
927
+ }
928
+ }
696
929
  }
697
930
 
698
931
  function validateChecklist(content, errors, spec, requireComplete) {
@@ -32,8 +32,24 @@ for them.
32
32
 
33
33
  ## Parallel execution
34
34
 
35
- [Replace the anchor with exactly one form: concrete task pairings covering every
36
- `[P]` task, or `- None: <evidence-backed reason>`. Never keep both forms.]
35
+ Use this exact grammar when safe parallel work exists:
36
+
37
+ ### Group P1
38
+
39
+ - Lane L1: T001 -> T002 | Owner: deep
40
+ - Lane L2: T003 -> T004 | Owner: quick
41
+ - Prerequisites: None
42
+ - Barrier: Final verification
43
+ - Rationale: Both lane path sets are disjoint and neither lane consumes peer output.
44
+
45
+ Groups and lanes are sequential and unique. Every `[P]` task belongs to exactly one lane; non-`[P]` tasks do not. Lane surfaces are the union of exact task
46
+ paths, and lanes in a group have disjoint surfaces and no cross-lane dependency.
47
+ The `Rationale` must explicitly state path-disjointness and cross-lane dependency
48
+ evidence so structural validation can gate the evidence shape and Oracle can
49
+ judge whether the claim is true.
50
+ Prerequisites name known tasks outside the group; the barrier is a downstream
51
+ task or `Final verification` after all lane members. If no group exists, use
52
+ only `- None: <evidence-backed reason>` and no task may use `[P]`.
37
53
 
38
54
  <!-- PARALLEL-EXECUTION-EVIDENCE -->
39
55
 
@@ -1,20 +0,0 @@
1
- {
2
- "name": "thoth-agents",
3
- "interface": {
4
- "displayName": "thoth-agents Adaptive Orchestration"
5
- },
6
- "plugins": [
7
- {
8
- "name": "thoth-agents",
9
- "source": {
10
- "source": "local",
11
- "path": "./plugin"
12
- },
13
- "policy": {
14
- "installation": "AVAILABLE",
15
- "authentication": "ON_INSTALL"
16
- },
17
- "category": "Productivity"
18
- }
19
- ]
20
- }
@@ -1,21 +0,0 @@
1
- {
2
- "$schema": "https://anthropic.com/claude-code/marketplace.schema.json",
3
- "name": "thoth-agents",
4
- "description": "Adaptive orchestration with seven roles and runtime-autonomous direct, accelerated, and full Spec Kit-compatible SDD routes.",
5
- "owner": {
6
- "name": "thoth-agents maintainers"
7
- },
8
- "plugins": [
9
- {
10
- "name": "thoth-agents",
11
- "description": "Adaptive root orchestration, six specialist subagents, and a runtime-autonomous Spec Kit-compatible SDD bundle.",
12
- "version": "0.3.10",
13
- "author": {
14
- "name": "thoth-agents maintainers"
15
- },
16
- "source": "./plugin",
17
- "category": "productivity",
18
- "homepage": "https://github.com/EremesNG/thoth-agents"
19
- }
20
- ]
21
- }