@danmoisan/drm-copilot-mcp 0.0.6 → 1.0.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 (62) hide show
  1. package/out/mcp-server.js +10213 -398
  2. package/package.json +2 -2
  3. package/resources/claude-customizations/.claude/hooks/enforce-completion-consistency.ps1 +127 -17
  4. package/resources/claude-customizations/.claude/hooks/enforce-completion-helpers.ps1 +163 -0
  5. package/resources/claude-customizations/.claude/hooks/enforce-orchestration-preimplementation-gate.ps1 +0 -12
  6. package/resources/claude-customizations/.claude/hooks/validate-orchestrator-output.ps1 +68 -1
  7. package/resources/config/orchestration-routing.json +3 -3
  8. package/resources/codex-and-agents-customizations/.codex/scripts/post-codex-worktree-session.ps1 +0 -5
  9. package/resources/scripts/dev_tools/__init__.py +0 -0
  10. package/resources/scripts/dev_tools/_orchestrator_state_human_interaction.py +0 -127
  11. package/resources/scripts/dev_tools/_orchestrator_state_routing.py +0 -216
  12. package/resources/scripts/dev_tools/agentic_sync.py +0 -819
  13. package/resources/scripts/dev_tools/codex_native_converter/__init__.py +0 -11
  14. package/resources/scripts/dev_tools/codex_native_converter/__main__.py +0 -6
  15. package/resources/scripts/dev_tools/codex_native_converter/cli.py +0 -11
  16. package/resources/scripts/dev_tools/new_active_feature_folder.py +0 -79
  17. package/resources/scripts/dev_tools/new_active_feature_folder_docs.py +0 -268
  18. package/resources/scripts/dev_tools/new_active_feature_folder_flow.py +0 -366
  19. package/resources/scripts/dev_tools/new_active_feature_folder_io.py +0 -306
  20. package/resources/scripts/dev_tools/new_active_feature_folder_markdown.py +0 -252
  21. package/resources/scripts/dev_tools/new_active_feature_folder_models.py +0 -136
  22. package/resources/scripts/dev_tools/new_potential_bug_entry.py +0 -465
  23. package/resources/scripts/dev_tools/potential_to_issue.py +0 -421
  24. package/resources/scripts/dev_tools/potential_to_issue_content.py +0 -212
  25. package/resources/scripts/dev_tools/pr_context/__init__.py +0 -0
  26. package/resources/scripts/dev_tools/pr_context/collector.py +0 -619
  27. package/resources/scripts/dev_tools/pr_context/feature_docs.py +0 -349
  28. package/resources/scripts/dev_tools/pr_context/git.py +0 -153
  29. package/resources/scripts/dev_tools/pr_context/github.py +0 -549
  30. package/resources/scripts/dev_tools/pr_context/models.py +0 -198
  31. package/resources/scripts/dev_tools/pr_context/render.py +0 -342
  32. package/resources/scripts/dev_tools/pr_context/render_feature_excerpts.py +0 -256
  33. package/resources/scripts/dev_tools/pr_context/render_pr_helpers.py +0 -291
  34. package/resources/scripts/dev_tools/pr_context/summary_helpers.py +0 -386
  35. package/resources/scripts/dev_tools/pr_context/verification_evidence.py +0 -171
  36. package/resources/scripts/dev_tools/prompt_mode_contract.py +0 -152
  37. package/resources/scripts/dev_tools/push_down_claude_customizations.py +0 -403
  38. package/resources/scripts/dev_tools/push_down_claude_filesystem.py +0 -472
  39. package/resources/scripts/dev_tools/push_down_claude_pack_selection.py +0 -401
  40. package/resources/scripts/dev_tools/push_down_codex_and_agents_customizations.py +0 -139
  41. package/resources/scripts/dev_tools/push_down_copilot_customizations.py +0 -504
  42. package/resources/scripts/dev_tools/push_down_copilot_customizations_filesystem.py +0 -217
  43. package/resources/scripts/dev_tools/push_down_copilot_customizations_rewrites.py +0 -293
  44. package/resources/scripts/dev_tools/resolve_file_prompt.py +0 -457
  45. package/resources/scripts/dev_tools/resolve_hard_lock_prompt.py +0 -444
  46. package/resources/scripts/dev_tools/validate_orchestration_artifacts.py +0 -246
  47. package/resources/scripts/dev_tools/validate_orchestration_review_artifacts.py +0 -107
  48. package/resources/scripts/dev_tools/validate_orchestrator_state.py +0 -505
  49. package/resources/scripts/dev_tools/validate_policy_audit_artifact.py +0 -472
  50. package/resources/templates/codex_native_converter.py +0 -35
  51. package/resources/templates/collect_commit_context.py +0 -212
  52. package/resources/templates/collect_pr_context.py +0 -74
  53. package/resources/templates/hello_python.py +0 -11
  54. package/resources/templates/new_active_feature_folder.py +0 -67
  55. package/resources/templates/new_potential_bug_entry.py +0 -54
  56. package/resources/templates/potential_to_issue.py +0 -55
  57. package/resources/templates/push_down_claude_customizations.py +0 -233
  58. package/resources/templates/push_down_codex_and_agents_customizations.py +0 -95
  59. package/resources/templates/push_down_copilot_customizations.py +0 -124
  60. package/resources/templates/resolve_atomic_plan_prompt.py +0 -75
  61. package/resources/templates/resolve_hard_lock_prompt.py +0 -65
  62. package/resources/templates/validate_orchestration_artifacts.py +0 -55
@@ -1,216 +0,0 @@
1
- """Routing and mandatory handoff invariants for orchestrator checkpoints."""
2
-
3
- from __future__ import annotations
4
-
5
- import json
6
- from pathlib import Path
7
- from typing import Any, cast
8
-
9
- ROUTING_MATRIX_PATH = (
10
- Path(__file__).resolve().parents[2] / "config" / "orchestration-routing.json"
11
- )
12
-
13
-
14
- def load_routing_matrix(path: Path = ROUTING_MATRIX_PATH) -> dict[str, Any]:
15
- """Load the repository routing matrix from disk."""
16
-
17
- loaded: object = json.loads(path.read_text(encoding="utf-8"))
18
- return cast("dict[str, Any]", loaded)
19
-
20
-
21
- def _string_list(value: object) -> list[str] | None:
22
- """Return a list of strings only when the value has that exact shape."""
23
-
24
- if not isinstance(value, list):
25
- return None
26
- values = cast("list[object]", value)
27
- if not all(isinstance(item, str) and item.strip() for item in values):
28
- return None
29
- return cast("list[str]", values)
30
-
31
-
32
- def _route_list(route: dict[str, Any], key: str) -> list[str]:
33
- """Read a required string-list field from one route entry."""
34
-
35
- value = _string_list(route.get(key))
36
- return [] if value is None else value
37
-
38
-
39
- def _state_list(
40
- state: dict[str, Any], key: str, route_id: str, expected: list[str]
41
- ) -> list[str] | None:
42
- """Validate a state list against the routing matrix list."""
43
-
44
- value = _string_list(state.get(key))
45
- if value is None:
46
- return None
47
- if value != expected:
48
- return None
49
- return value
50
-
51
-
52
- def _list_receipts(receipts: object) -> list[dict[str, Any]]:
53
- """Return legacy list delegation receipts as typed dictionaries."""
54
-
55
- if not isinstance(receipts, list):
56
- return []
57
- receipt_list = cast("list[object]", receipts)
58
- return [
59
- cast("dict[str, Any]", item) for item in receipt_list if isinstance(item, dict)
60
- ]
61
-
62
-
63
- def _receipt_agents(state: dict[str, Any]) -> set[str]:
64
- """Collect agent names from delegation receipts."""
65
-
66
- agents: set[str] = set()
67
- for receipt in _list_receipts(state.get("delegation_receipts")):
68
- agent_name = receipt.get("agent_name")
69
- if isinstance(agent_name, str) and agent_name.strip():
70
- agents.add(agent_name)
71
- return agents
72
-
73
-
74
- def _receipt_skills(state: dict[str, Any]) -> set[str]:
75
- """Collect acknowledged skill names from skill receipts."""
76
-
77
- skills: set[str] = set()
78
- receipts = state.get("skill_receipts")
79
- if not isinstance(receipts, list):
80
- return skills
81
- for receipt in cast("list[object]", receipts):
82
- if not isinstance(receipt, dict):
83
- continue
84
- receipt_map = cast("dict[str, object]", receipt)
85
- skill = receipt_map.get("skill")
86
- required = receipt_map.get("required")
87
- evidence = receipt_map.get("evidence")
88
- if (
89
- isinstance(skill, str)
90
- and skill.strip()
91
- and required is True
92
- and isinstance(evidence, str)
93
- and evidence.strip()
94
- ):
95
- skills.add(skill)
96
- return skills
97
-
98
-
99
- def _mcp_tools(state: dict[str, Any]) -> set[str]:
100
- """Collect successful MCP tool receipts from checkpoint state."""
101
-
102
- tools: set[str] = set()
103
- receipts = state.get("mcp_call_receipts")
104
- if not isinstance(receipts, list):
105
- return tools
106
- for receipt in cast("list[object]", receipts):
107
- if not isinstance(receipt, dict):
108
- continue
109
- receipt_map = cast("dict[str, object]", receipt)
110
- tool = receipt_map.get("tool")
111
- ok = receipt_map.get("ok")
112
- evidence = receipt_map.get("evidence")
113
- if (
114
- isinstance(tool, str)
115
- and tool.strip()
116
- and ok is True
117
- and isinstance(evidence, str)
118
- and evidence.strip()
119
- ):
120
- tools.add(tool)
121
- return tools
122
-
123
-
124
- def _validate_empty_list_field(state: dict[str, Any], key: str) -> list[str]:
125
- """Require a checkpoint field to exist as an empty list."""
126
-
127
- value = state.get(key)
128
- if not isinstance(value, list):
129
- return [f"Checkpoint {key} must be an empty list at completion."]
130
- if value:
131
- return [f"Checkpoint {key} must be empty at completion."]
132
- return []
133
-
134
-
135
- def _validate_lifecycle_operations(state: dict[str, Any]) -> list[str]:
136
- """Reject lifecycle-operation records that did not use MCP."""
137
-
138
- operations = state.get("lifecycle_operations")
139
- if operations is None:
140
- return []
141
- if not isinstance(operations, list):
142
- return ["Checkpoint lifecycle_operations must be a list when present."]
143
- errors: list[str] = []
144
- for index, operation in enumerate(cast("list[object]", operations)):
145
- if not isinstance(operation, dict):
146
- errors.append(
147
- f"Checkpoint lifecycle_operations #{index} must be an object."
148
- )
149
- continue
150
- operation_map = cast("dict[str, object]", operation)
151
- if operation_map.get("surface") != "mcp":
152
- errors.append(
153
- f"Checkpoint lifecycle_operations #{index} did not use MCP surface."
154
- )
155
- return errors
156
-
157
-
158
- def validate_routing_contract(
159
- state: dict[str, Any], *, routing_matrix: dict[str, Any] | None = None
160
- ) -> list[str]:
161
- """Validate mandatory route, handoff, skill, and MCP completion evidence."""
162
-
163
- matrix = routing_matrix if routing_matrix is not None else load_routing_matrix()
164
- raw_routes = matrix.get("routes")
165
- if not isinstance(raw_routes, dict):
166
- return ["Routing matrix missing routes object."]
167
- routes = cast("dict[str, object]", raw_routes)
168
-
169
- route_id = state.get("route_id", state.get("path_selected"))
170
- if not isinstance(route_id, str) or not route_id.strip():
171
- return ["Checkpoint route_id or path_selected must select a route."]
172
- raw_route = routes.get(route_id)
173
- if not isinstance(raw_route, dict):
174
- return [f"Checkpoint selected route has no routing-matrix entry: {route_id}."]
175
- route_map = cast("dict[str, Any]", raw_route)
176
-
177
- errors: list[str] = []
178
- required_agents = _route_list(route_map, "required_agents")
179
- required_skills = _route_list(route_map, "required_skills")
180
- required_mcp_tools = _route_list(route_map, "required_mcp_tools")
181
-
182
- if _state_list(state, "required_agents", route_id, required_agents) is None:
183
- errors.append(
184
- "Checkpoint required_agents must match routing matrix for route "
185
- f"{route_id}."
186
- )
187
- if _state_list(state, "required_skills", route_id, required_skills) is None:
188
- errors.append(
189
- "Checkpoint required_skills must match routing matrix for route "
190
- f"{route_id}."
191
- )
192
- if _state_list(state, "required_mcp_tools", route_id, required_mcp_tools) is None:
193
- errors.append(
194
- "Checkpoint required_mcp_tools must match routing matrix for route "
195
- f"{route_id}."
196
- )
197
-
198
- actual_agents = _receipt_agents(state)
199
- for agent in required_agents:
200
- if agent not in actual_agents:
201
- errors.append(f"Checkpoint missing required agent receipt: {agent}.")
202
-
203
- actual_skills = _receipt_skills(state)
204
- for skill in required_skills:
205
- if skill not in actual_skills:
206
- errors.append(f"Checkpoint missing required skill receipt: {skill}.")
207
-
208
- actual_tools = _mcp_tools(state)
209
- for tool in required_mcp_tools:
210
- if tool not in actual_tools:
211
- errors.append(f"Checkpoint missing successful MCP receipt: {tool}.")
212
-
213
- errors.extend(_validate_empty_list_field(state, "local_execution_overrides"))
214
- errors.extend(_validate_empty_list_field(state, "delegation_bypasses"))
215
- errors.extend(_validate_lifecycle_operations(state))
216
- return errors