@blxzer/cursor-trellis 0.3.5 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (156) hide show
  1. package/CHANGELOG.md +69 -0
  2. package/README.md +13 -0
  3. package/dist/cli/index.d.ts.map +1 -1
  4. package/dist/cli/index.js +3 -0
  5. package/dist/cli/index.js.map +1 -1
  6. package/dist/commands/goal/index.d.ts +3 -0
  7. package/dist/commands/goal/index.d.ts.map +1 -0
  8. package/dist/commands/goal/index.js +159 -0
  9. package/dist/commands/goal/index.js.map +1 -0
  10. package/dist/commands/goal/review.d.ts +6 -0
  11. package/dist/commands/goal/review.d.ts.map +1 -0
  12. package/dist/commands/goal/review.js +28 -0
  13. package/dist/commands/goal/review.js.map +1 -0
  14. package/dist/commands/sdk/run.d.ts.map +1 -1
  15. package/dist/commands/sdk/run.js +2 -27
  16. package/dist/commands/sdk/run.js.map +1 -1
  17. package/dist/commands/update.d.ts.map +1 -1
  18. package/dist/commands/update.js +5 -1
  19. package/dist/commands/update.js.map +1 -1
  20. package/dist/configurators/workflow.d.ts.map +1 -1
  21. package/dist/configurators/workflow.js +51 -2
  22. package/dist/configurators/workflow.js.map +1 -1
  23. package/dist/constants/paths.d.ts +4 -0
  24. package/dist/constants/paths.d.ts.map +1 -1
  25. package/dist/constants/paths.js +4 -0
  26. package/dist/constants/paths.js.map +1 -1
  27. package/dist/goal/action-packet.d.ts +89 -0
  28. package/dist/goal/action-packet.d.ts.map +1 -0
  29. package/dist/goal/action-packet.js +113 -0
  30. package/dist/goal/action-packet.js.map +1 -0
  31. package/dist/goal/audit.d.ts +14 -0
  32. package/dist/goal/audit.d.ts.map +1 -0
  33. package/dist/goal/audit.js +12 -0
  34. package/dist/goal/audit.js.map +1 -0
  35. package/dist/goal/constants.d.ts +26 -0
  36. package/dist/goal/constants.d.ts.map +1 -0
  37. package/dist/goal/constants.js +24 -0
  38. package/dist/goal/constants.js.map +1 -0
  39. package/dist/goal/paths.d.ts +8 -0
  40. package/dist/goal/paths.d.ts.map +1 -0
  41. package/dist/goal/paths.js +36 -0
  42. package/dist/goal/paths.js.map +1 -0
  43. package/dist/goal/preflight.d.ts +21 -0
  44. package/dist/goal/preflight.d.ts.map +1 -0
  45. package/dist/goal/preflight.js +97 -0
  46. package/dist/goal/preflight.js.map +1 -0
  47. package/dist/goal/review-seam.d.ts +44 -0
  48. package/dist/goal/review-seam.d.ts.map +1 -0
  49. package/dist/goal/review-seam.js +153 -0
  50. package/dist/goal/review-seam.js.map +1 -0
  51. package/dist/goal/reviewer-rules.d.ts +13 -0
  52. package/dist/goal/reviewer-rules.d.ts.map +1 -0
  53. package/dist/goal/reviewer-rules.js +153 -0
  54. package/dist/goal/reviewer-rules.js.map +1 -0
  55. package/dist/goal/reviewer.d.ts +9 -0
  56. package/dist/goal/reviewer.d.ts.map +1 -0
  57. package/dist/goal/reviewer.js +54 -0
  58. package/dist/goal/reviewer.js.map +1 -0
  59. package/dist/goal/runtime.d.ts +32 -0
  60. package/dist/goal/runtime.d.ts.map +1 -0
  61. package/dist/goal/runtime.js +242 -0
  62. package/dist/goal/runtime.js.map +1 -0
  63. package/dist/goal/sdk-client.d.ts +10 -0
  64. package/dist/goal/sdk-client.d.ts.map +1 -0
  65. package/dist/goal/sdk-client.js +34 -0
  66. package/dist/goal/sdk-client.js.map +1 -0
  67. package/dist/goal/state.d.ts +40 -0
  68. package/dist/goal/state.d.ts.map +1 -0
  69. package/dist/goal/state.js +37 -0
  70. package/dist/goal/state.js.map +1 -0
  71. package/dist/goal/task-triggers.d.ts +15 -0
  72. package/dist/goal/task-triggers.d.ts.map +1 -0
  73. package/dist/goal/task-triggers.js +23 -0
  74. package/dist/goal/task-triggers.js.map +1 -0
  75. package/dist/goal/walls.d.ts +12 -0
  76. package/dist/goal/walls.d.ts.map +1 -0
  77. package/dist/goal/walls.js +65 -0
  78. package/dist/goal/walls.js.map +1 -0
  79. package/dist/goal/worker-prompt.d.ts +13 -0
  80. package/dist/goal/worker-prompt.d.ts.map +1 -0
  81. package/dist/goal/worker-prompt.js +41 -0
  82. package/dist/goal/worker-prompt.js.map +1 -0
  83. package/dist/goal/worker.d.ts +42 -0
  84. package/dist/goal/worker.d.ts.map +1 -0
  85. package/dist/goal/worker.js +180 -0
  86. package/dist/goal/worker.js.map +1 -0
  87. package/dist/migrations/manifests/0.3.5.json +9 -0
  88. package/dist/migrations/manifests/0.3.6.json +9 -0
  89. package/dist/migrations/manifests/0.4.0.json +9 -0
  90. package/dist/templates/common/commands/continue.md +15 -3
  91. package/dist/templates/common/skills/check.md +7 -4
  92. package/dist/templates/cursor/agents/cstl-check.md +1 -0
  93. package/dist/templates/cursor/fixtures/expected-rules.d.ts.map +1 -1
  94. package/dist/templates/cursor/fixtures/expected-rules.js +6 -1
  95. package/dist/templates/cursor/fixtures/expected-rules.js.map +1 -1
  96. package/dist/templates/cursor/rules/cstl-cursor-modes.mdc +32 -0
  97. package/dist/templates/cursor/rules/cstl-triage.mdc +2 -4
  98. package/dist/templates/cursor/rules/retrieval-routing.mdc +26 -7
  99. package/dist/templates/markdown/index.d.ts +9 -0
  100. package/dist/templates/markdown/index.d.ts.map +1 -1
  101. package/dist/templates/markdown/index.js +9 -0
  102. package/dist/templates/markdown/index.js.map +1 -1
  103. package/dist/templates/markdown/spec/guides/artifact-locale-guide.md.txt +93 -0
  104. package/dist/templates/markdown/spec/guides/cross-platform-thinking-guide.md.txt +7 -7
  105. package/dist/templates/markdown/spec/guides/cursor-context-injection-guide.md.txt +38 -21
  106. package/dist/templates/markdown/spec/guides/cursor-native-modes-guide.md.txt +125 -0
  107. package/dist/templates/markdown/spec/guides/cursor-subagent-policy.md.txt +10 -8
  108. package/dist/templates/markdown/spec/guides/debug-loop-guide.md.txt +227 -0
  109. package/dist/templates/markdown/spec/guides/goal-release-regression-runbook.md.txt +132 -0
  110. package/dist/templates/markdown/spec/guides/index.md.txt +144 -104
  111. package/dist/templates/markdown/spec/guides/injection-budget-guide.md.txt +111 -0
  112. package/dist/templates/markdown/spec/guides/prototype-guide.md.txt +139 -0
  113. package/dist/templates/markdown/spec/guides/retrieval-daily-guide.md.txt +28 -6
  114. package/dist/templates/markdown/spec/guides/test-discipline-guide.md.txt +138 -0
  115. package/dist/templates/markdown/spec/guides/verification-strength-guide.md.txt +185 -0
  116. package/dist/templates/shared-hooks/session-start.py +10 -0
  117. package/dist/templates/trellis/config.yaml +18 -0
  118. package/dist/templates/trellis/index.d.ts +17 -0
  119. package/dist/templates/trellis/index.d.ts.map +1 -1
  120. package/dist/templates/trellis/index.js +40 -0
  121. package/dist/templates/trellis/index.js.map +1 -1
  122. package/dist/templates/trellis/pool/README.md +103 -0
  123. package/dist/templates/trellis/pool/items/.gitkeep +0 -0
  124. package/dist/templates/trellis/pool/plan.md +26 -0
  125. package/dist/templates/trellis/scripts/common/artifact_locale.py +278 -0
  126. package/dist/templates/trellis/scripts/common/codebase_retrieval_router.py +37 -2
  127. package/dist/templates/trellis/scripts/common/config.py +39 -0
  128. package/dist/templates/trellis/scripts/common/injection_budget.py +317 -0
  129. package/dist/templates/trellis/scripts/common/parent_orchestration.py +161 -5
  130. package/dist/templates/trellis/scripts/common/pool_store.py +702 -0
  131. package/dist/templates/trellis/scripts/common/retrieval_agent_instructions.py +9 -3
  132. package/dist/templates/trellis/scripts/common/session_context.py +32 -4
  133. package/dist/templates/trellis/scripts/common/session_memory.py +26 -0
  134. package/dist/templates/trellis/scripts/common/subagent_dispatch.py +74 -9
  135. package/dist/templates/trellis/scripts/common/task_context.py +18 -0
  136. package/dist/templates/trellis/scripts/common/task_dashboard.py +24 -1
  137. package/dist/templates/trellis/scripts/common/task_dependencies.py +673 -0
  138. package/dist/templates/trellis/scripts/common/task_gates.py +58 -5
  139. package/dist/templates/trellis/scripts/common/task_map.py +40 -8
  140. package/dist/templates/trellis/scripts/common/task_store.py +400 -39
  141. package/dist/templates/trellis/scripts/common/test_depends_mode_block.py +489 -0
  142. package/dist/templates/trellis/scripts/common/test_observable_defaults.py +135 -0
  143. package/dist/templates/trellis/scripts/common/test_pool_store.py +428 -0
  144. package/dist/templates/trellis/scripts/common/test_task_dependencies.py +345 -0
  145. package/dist/templates/trellis/scripts/cursor_retrieval_probe_prompt.md +14 -12
  146. package/dist/templates/trellis/scripts/generate_dispatch_prompt.py +182 -0
  147. package/dist/templates/trellis/scripts/injection_budget_probe.py +69 -0
  148. package/dist/templates/trellis/scripts/pool.py +192 -0
  149. package/dist/templates/trellis/scripts/retrieval_probe_matrix_template.json +3 -3
  150. package/dist/templates/trellis/scripts/spec_health_outcomes.py +160 -0
  151. package/dist/templates/trellis/scripts/task.py +85 -1
  152. package/dist/templates/trellis/scripts/verify_evidence_probe.py +138 -0
  153. package/dist/templates/trellis/tasks/locale/en/default-prd.md +19 -0
  154. package/dist/templates/trellis/tasks/locale/zh/default-prd.md +19 -0
  155. package/dist/templates/trellis/workflow.md +55 -5
  156. package/package.json +2 -2
@@ -1,4 +1,4 @@
1
- #!/usr/bin/env python3
1
+ #!/usr/bin/env python
2
2
  """
3
3
  Task quality gate helpers.
4
4
 
@@ -15,6 +15,11 @@ from dataclasses import dataclass, field
15
15
  from datetime import datetime, timezone
16
16
  from pathlib import Path
17
17
 
18
+ from .task_dependencies import (
19
+ describe_dependencies,
20
+ read_depends_mode,
21
+ scope_children_for_task,
22
+ )
18
23
  from .task_map import (
19
24
  get_child_state,
20
25
  load_task_map,
@@ -144,6 +149,7 @@ STABLE_TASK_KEYS = (
144
149
  "kind",
145
150
  "mode",
146
151
  "contract_epoch",
152
+ "depends_on",
147
153
  )
148
154
 
149
155
 
@@ -161,6 +167,7 @@ class GateGuardResult:
161
167
  is_full_task: bool = False
162
168
  closeout_profile: str = "lite"
163
169
  auto_gate_records: dict[str, dict] = field(default_factory=dict)
170
+ deps_blocking_summary: list[str] = field(default_factory=list)
164
171
 
165
172
 
166
173
  def utc_now() -> str:
@@ -610,8 +617,19 @@ def validate_start_execution(
610
617
  task_dir: Path,
611
618
  task_data: dict | None,
612
619
  approved: bool,
620
+ *,
621
+ ignore_deps: bool = False,
622
+ enforce_deps_block: bool = False,
613
623
  ) -> GateGuardResult:
614
- """Validate start-execution readiness."""
624
+ """Validate start-execution readiness.
625
+
626
+ Dependency policy (Plan B, per adjudication 05 §3.1/§3.2):
627
+ - enforce_deps_block=True is passed ONLY by the mutating `--approved` path.
628
+ mode=block + unmet deps then fail unless ignore_deps=True.
629
+ - mode=off silences dependency warnings entirely.
630
+ - every other path (--check, warn mode) keeps Plan A semantics: deps are
631
+ warnings that never fail the guard.
632
+ """
615
633
  errors: list[str] = []
616
634
  if task_data is None:
617
635
  return GateGuardResult(ok=False, errors=["task.json"])
@@ -691,6 +709,29 @@ def validate_start_execution(
691
709
  if not approved:
692
710
  errors.append("--approved is required for mutation")
693
711
 
712
+ warnings: list[str] = []
713
+ deps_blocking_summary: list[str] = []
714
+ if task_data is not None:
715
+ scope = scope_children_for_task(task_dir, task_data)
716
+ report = describe_dependencies(
717
+ task_dir,
718
+ task_data,
719
+ scope_children=scope,
720
+ )
721
+ depends_mode = read_depends_mode(task_data)
722
+ if enforce_deps_block and depends_mode == "block":
723
+ deps_blocking_summary = report.blocking_errors()
724
+ if ignore_deps:
725
+ warnings.extend(report.warnings())
726
+ else:
727
+ errors.extend(deps_blocking_summary)
728
+ elif depends_mode != "off":
729
+ warnings.extend(report.warnings())
730
+ if depends_mode == "block" and not enforce_deps_block:
731
+ warnings.append(
732
+ "dependency policy mode=block: --approved would fail unless --ignore-deps"
733
+ )
734
+
694
735
  baseline_record = None
695
736
  if not errors:
696
737
  baseline_record = make_baseline_record(
@@ -700,12 +741,14 @@ def validate_start_execution(
700
741
  return GateGuardResult(
701
742
  ok=not errors,
702
743
  errors=errors,
744
+ warnings=warnings,
703
745
  contract_fingerprint=contract_fingerprint,
704
746
  artifact_fingerprints=artifact_fingerprints,
705
747
  required_gates=required_gates,
706
748
  baseline_record=baseline_record,
707
749
  is_full_task=full_task,
708
750
  auto_gate_records=auto_gate_records,
751
+ deps_blocking_summary=deps_blocking_summary,
709
752
  )
710
753
 
711
754
 
@@ -737,9 +780,19 @@ def validate_start_execution_check(
737
780
  task_dir: Path,
738
781
  task_data: dict | None,
739
782
  ) -> GateGuardResult:
740
- """Validate start-execution preflight without requiring approval."""
741
- result = validate_start_execution(task_dir, task_data, approved=True)
742
- return result
783
+ """Validate start-execution preflight without requiring approval.
784
+
785
+ NOTE (adjudication 05 §3.1 trap): the check path deliberately passes
786
+ enforce_deps_block=False — even when the task is in mode=block, --check
787
+ must never fail on dependencies; it only surfaces warnings. Only the
788
+ mutating --approved path may set enforce_deps_block=True.
789
+ """
790
+ return validate_start_execution(
791
+ task_dir,
792
+ task_data,
793
+ approved=True,
794
+ enforce_deps_block=False,
795
+ )
743
796
 
744
797
 
745
798
  def validate_transition_readiness(
@@ -127,6 +127,37 @@ def remove_child_from_task_map(
127
127
  write_task_map(parent_dir, data, body, f"Unlinked Child `{child_name}`.")
128
128
 
129
129
 
130
+ def resolve_child_map_id(
131
+ parent_data: dict,
132
+ child_dir: Path,
133
+ child_data: dict | None = None,
134
+ ) -> str:
135
+ """Resolve task-map child id for a child directory (nested slash slugs)."""
136
+ structural = parent_data.get("children", [])
137
+ if not isinstance(structural, list):
138
+ structural = []
139
+
140
+ leaf = child_dir.name
141
+ if leaf in structural:
142
+ return leaf
143
+
144
+ if child_data:
145
+ for key in ("name", "id"):
146
+ value = child_data.get(key)
147
+ if isinstance(value, str) and value in structural:
148
+ return value
149
+
150
+ suffix_matches = [
151
+ cid
152
+ for cid in structural
153
+ if isinstance(cid, str) and (cid == leaf or cid.endswith(f"/{leaf}"))
154
+ ]
155
+ if len(suffix_matches) == 1:
156
+ return suffix_matches[0]
157
+
158
+ return leaf
159
+
160
+
130
161
  def set_child_state(
131
162
  parent_dir: Path,
132
163
  parent_data: dict,
@@ -183,7 +214,7 @@ def validate_parent_child_integration(
183
214
  ) -> list[str]:
184
215
  """Validate a Parent-controlled Child integration state transition."""
185
216
  errors: list[str] = []
186
- child_name = child_dir.name
217
+ child_name = resolve_child_map_id(parent_data, child_dir, child_data)
187
218
  if state not in PARENT_CONTROLLED_STATES:
188
219
  errors.append(f"state is not Parent-controlled: {state}")
189
220
  if not _short_text(evidence):
@@ -295,10 +326,11 @@ def set_parent_child_integration_state(
295
326
  if errors:
296
327
  return False, errors
297
328
 
329
+ child_name = resolve_child_map_id(parent_data, child_dir, child_data)
298
330
  data = ensure_task_map(parent_dir, parent_data, list(parent_data.get("children", [])))
299
- child = get_child_entry(data, child_dir.name)
331
+ child = get_child_entry(data, child_name)
300
332
  if child is None:
301
- return False, [f"child missing from task-map.md: {child_dir.name}"]
333
+ return False, [f"child missing from task-map.md: {child_name}"]
302
334
 
303
335
  child["state"] = state
304
336
  child["evidence"] = evidence
@@ -316,12 +348,12 @@ def set_parent_child_integration_state(
316
348
  queue = []
317
349
  data["integration_queue"] = queue
318
350
  if state == "integrating":
319
- if child_dir.name not in queue:
320
- queue.append(child_dir.name)
321
- elif child_dir.name in queue:
322
- data["integration_queue"] = [item for item in queue if item != child_dir.name]
351
+ if child_name not in queue:
352
+ queue.append(child_name)
353
+ elif child_name in queue:
354
+ data["integration_queue"] = [item for item in queue if item != child_name]
323
355
 
324
- event = f"Parent set Child `{child_dir.name}` integration state to `{state}`. Evidence: {evidence}."
356
+ event = f"Parent set Child `{child_name}` integration state to `{state}`. Evidence: {evidence}."
325
357
  if ref:
326
358
  event = f"{event} Ref: {ref}."
327
359
  if merge_ref: