@trac3er/oh-my-god 2.0.3 → 2.0.5

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 (259) hide show
  1. package/.agents/skills/omg/AGENTS.fragment.md +5 -0
  2. package/.agents/skills/omg/algorithms/SKILL.md +11 -0
  3. package/.agents/skills/omg/algorithms/openai.yaml +11 -0
  4. package/.agents/skills/omg/api-twin/SKILL.md +11 -0
  5. package/.agents/skills/omg/api-twin/openai.yaml +12 -0
  6. package/.agents/skills/omg/codex-mcp.toml +4 -0
  7. package/.agents/skills/omg/control-plane/SKILL.md +11 -0
  8. package/.agents/skills/omg/control-plane/openai.yaml +14 -0
  9. package/.agents/skills/omg/data-lineage/SKILL.md +11 -0
  10. package/.agents/skills/omg/data-lineage/openai.yaml +12 -0
  11. package/.agents/skills/omg/delta-classifier/SKILL.md +11 -0
  12. package/.agents/skills/omg/delta-classifier/openai.yaml +12 -0
  13. package/.agents/skills/omg/eval-gate/SKILL.md +11 -0
  14. package/.agents/skills/omg/eval-gate/openai.yaml +12 -0
  15. package/.agents/skills/omg/health/SKILL.md +11 -0
  16. package/.agents/skills/omg/health/openai.yaml +11 -0
  17. package/.agents/skills/omg/hook-governor/SKILL.md +11 -0
  18. package/.agents/skills/omg/hook-governor/openai.yaml +11 -0
  19. package/.agents/skills/omg/incident-replay/SKILL.md +11 -0
  20. package/.agents/skills/omg/incident-replay/openai.yaml +12 -0
  21. package/.agents/skills/omg/lsp-pack/SKILL.md +11 -0
  22. package/.agents/skills/omg/lsp-pack/openai.yaml +11 -0
  23. package/.agents/skills/omg/mcp-fabric/SKILL.md +11 -0
  24. package/.agents/skills/omg/mcp-fabric/openai.yaml +13 -0
  25. package/.agents/skills/omg/preflight/SKILL.md +11 -0
  26. package/.agents/skills/omg/preflight/openai.yaml +12 -0
  27. package/.agents/skills/omg/remote-supervisor/SKILL.md +11 -0
  28. package/.agents/skills/omg/remote-supervisor/openai.yaml +12 -0
  29. package/.agents/skills/omg/robotics/SKILL.md +11 -0
  30. package/.agents/skills/omg/robotics/openai.yaml +11 -0
  31. package/.agents/skills/omg/secure-worktree-pipeline/SKILL.md +11 -0
  32. package/.agents/skills/omg/secure-worktree-pipeline/openai.yaml +12 -0
  33. package/.agents/skills/omg/security-check/SKILL.md +11 -0
  34. package/.agents/skills/omg/security-check/openai.yaml +13 -0
  35. package/.agents/skills/omg/tracebank/SKILL.md +11 -0
  36. package/.agents/skills/omg/tracebank/openai.yaml +12 -0
  37. package/.agents/skills/omg/vision/SKILL.md +11 -0
  38. package/.agents/skills/omg/vision/openai.yaml +11 -0
  39. package/.claude-plugin/marketplace.json +3 -3
  40. package/.claude-plugin/plugin.json +1 -1
  41. package/.claude-plugin/scripts/uninstall.sh +2 -2
  42. package/.mcp.json +20 -4
  43. package/CHANGELOG.md +10 -0
  44. package/OMG-setup.sh +9 -3
  45. package/OMG_COMPAT_CONTRACT.md +92 -0
  46. package/README.md +24 -4
  47. package/SECURITY.md +6 -0
  48. package/commands/OMG:api-twin.md +22 -0
  49. package/commands/OMG:preflight.md +26 -0
  50. package/commands/OMG:security-check.md +28 -0
  51. package/commands/__init__.py +1 -0
  52. package/control_plane/__init__.py +2 -0
  53. package/control_plane/openapi.yaml +228 -0
  54. package/control_plane/server.py +123 -0
  55. package/control_plane/service.py +185 -0
  56. package/dist/enterprise/bundle/.agents/skills/omg/AGENTS.fragment.md +5 -0
  57. package/dist/enterprise/bundle/.agents/skills/omg/algorithms/SKILL.md +11 -0
  58. package/dist/enterprise/bundle/.agents/skills/omg/algorithms/openai.yaml +11 -0
  59. package/dist/enterprise/bundle/.agents/skills/omg/api-twin/SKILL.md +11 -0
  60. package/dist/enterprise/bundle/.agents/skills/omg/api-twin/openai.yaml +12 -0
  61. package/dist/enterprise/bundle/.agents/skills/omg/codex-mcp.toml +4 -0
  62. package/dist/enterprise/bundle/.agents/skills/omg/control-plane/SKILL.md +11 -0
  63. package/dist/enterprise/bundle/.agents/skills/omg/control-plane/openai.yaml +14 -0
  64. package/dist/enterprise/bundle/.agents/skills/omg/data-lineage/SKILL.md +11 -0
  65. package/dist/enterprise/bundle/.agents/skills/omg/data-lineage/openai.yaml +12 -0
  66. package/dist/enterprise/bundle/.agents/skills/omg/delta-classifier/SKILL.md +11 -0
  67. package/dist/enterprise/bundle/.agents/skills/omg/delta-classifier/openai.yaml +12 -0
  68. package/dist/enterprise/bundle/.agents/skills/omg/eval-gate/SKILL.md +11 -0
  69. package/dist/enterprise/bundle/.agents/skills/omg/eval-gate/openai.yaml +12 -0
  70. package/dist/enterprise/bundle/.agents/skills/omg/health/SKILL.md +11 -0
  71. package/dist/enterprise/bundle/.agents/skills/omg/health/openai.yaml +11 -0
  72. package/dist/enterprise/bundle/.agents/skills/omg/hook-governor/SKILL.md +11 -0
  73. package/dist/enterprise/bundle/.agents/skills/omg/hook-governor/openai.yaml +11 -0
  74. package/dist/enterprise/bundle/.agents/skills/omg/incident-replay/SKILL.md +11 -0
  75. package/dist/enterprise/bundle/.agents/skills/omg/incident-replay/openai.yaml +12 -0
  76. package/dist/enterprise/bundle/.agents/skills/omg/lsp-pack/SKILL.md +11 -0
  77. package/dist/enterprise/bundle/.agents/skills/omg/lsp-pack/openai.yaml +11 -0
  78. package/dist/enterprise/bundle/.agents/skills/omg/mcp-fabric/SKILL.md +11 -0
  79. package/dist/enterprise/bundle/.agents/skills/omg/mcp-fabric/openai.yaml +13 -0
  80. package/dist/enterprise/bundle/.agents/skills/omg/preflight/SKILL.md +11 -0
  81. package/dist/enterprise/bundle/.agents/skills/omg/preflight/openai.yaml +12 -0
  82. package/dist/enterprise/bundle/.agents/skills/omg/remote-supervisor/SKILL.md +11 -0
  83. package/dist/enterprise/bundle/.agents/skills/omg/remote-supervisor/openai.yaml +12 -0
  84. package/dist/enterprise/bundle/.agents/skills/omg/robotics/SKILL.md +11 -0
  85. package/dist/enterprise/bundle/.agents/skills/omg/robotics/openai.yaml +11 -0
  86. package/dist/enterprise/bundle/.agents/skills/omg/secure-worktree-pipeline/SKILL.md +11 -0
  87. package/dist/enterprise/bundle/.agents/skills/omg/secure-worktree-pipeline/openai.yaml +12 -0
  88. package/dist/enterprise/bundle/.agents/skills/omg/security-check/SKILL.md +11 -0
  89. package/dist/enterprise/bundle/.agents/skills/omg/security-check/openai.yaml +13 -0
  90. package/dist/enterprise/bundle/.agents/skills/omg/tracebank/SKILL.md +11 -0
  91. package/dist/enterprise/bundle/.agents/skills/omg/tracebank/openai.yaml +12 -0
  92. package/dist/enterprise/bundle/.agents/skills/omg/vision/SKILL.md +11 -0
  93. package/dist/enterprise/bundle/.agents/skills/omg/vision/openai.yaml +11 -0
  94. package/dist/enterprise/bundle/.claude-plugin/marketplace.json +36 -0
  95. package/dist/enterprise/bundle/.claude-plugin/plugin.json +23 -0
  96. package/dist/enterprise/bundle/.mcp.json +40 -0
  97. package/dist/enterprise/bundle/OMG_COMPAT_CONTRACT.md +92 -0
  98. package/dist/enterprise/bundle/registry/bundles/algorithms.yaml +45 -0
  99. package/dist/enterprise/bundle/registry/bundles/api-twin.yaml +48 -0
  100. package/dist/enterprise/bundle/registry/bundles/control-plane.yaml +61 -0
  101. package/dist/enterprise/bundle/registry/bundles/data-lineage.yaml +47 -0
  102. package/dist/enterprise/bundle/registry/bundles/delta-classifier.yaml +47 -0
  103. package/dist/enterprise/bundle/registry/bundles/eval-gate.yaml +47 -0
  104. package/dist/enterprise/bundle/registry/bundles/health.yaml +45 -0
  105. package/dist/enterprise/bundle/registry/bundles/hook-governor.yaml +97 -0
  106. package/dist/enterprise/bundle/registry/bundles/incident-replay.yaml +47 -0
  107. package/dist/enterprise/bundle/registry/bundles/lsp-pack.yaml +48 -0
  108. package/dist/enterprise/bundle/registry/bundles/mcp-fabric.yaml +53 -0
  109. package/dist/enterprise/bundle/registry/bundles/preflight.yaml +48 -0
  110. package/dist/enterprise/bundle/registry/bundles/remote-supervisor.yaml +49 -0
  111. package/dist/enterprise/bundle/registry/bundles/robotics.yaml +45 -0
  112. package/dist/enterprise/bundle/registry/bundles/secure-worktree-pipeline.yaml +54 -0
  113. package/dist/enterprise/bundle/registry/bundles/security-check.yaml +50 -0
  114. package/dist/enterprise/bundle/registry/bundles/tracebank.yaml +47 -0
  115. package/dist/enterprise/bundle/registry/bundles/vision.yaml +45 -0
  116. package/dist/enterprise/bundle/registry/omg-capability.schema.json +80 -0
  117. package/dist/enterprise/bundle/settings.json +381 -0
  118. package/dist/enterprise/manifest.json +255 -0
  119. package/dist/public/bundle/.agents/skills/omg/AGENTS.fragment.md +5 -0
  120. package/dist/public/bundle/.agents/skills/omg/algorithms/SKILL.md +11 -0
  121. package/dist/public/bundle/.agents/skills/omg/algorithms/openai.yaml +11 -0
  122. package/dist/public/bundle/.agents/skills/omg/api-twin/SKILL.md +11 -0
  123. package/dist/public/bundle/.agents/skills/omg/api-twin/openai.yaml +12 -0
  124. package/dist/public/bundle/.agents/skills/omg/codex-mcp.toml +4 -0
  125. package/dist/public/bundle/.agents/skills/omg/control-plane/SKILL.md +11 -0
  126. package/dist/public/bundle/.agents/skills/omg/control-plane/openai.yaml +14 -0
  127. package/dist/public/bundle/.agents/skills/omg/data-lineage/SKILL.md +11 -0
  128. package/dist/public/bundle/.agents/skills/omg/data-lineage/openai.yaml +12 -0
  129. package/dist/public/bundle/.agents/skills/omg/delta-classifier/SKILL.md +11 -0
  130. package/dist/public/bundle/.agents/skills/omg/delta-classifier/openai.yaml +12 -0
  131. package/dist/public/bundle/.agents/skills/omg/eval-gate/SKILL.md +11 -0
  132. package/dist/public/bundle/.agents/skills/omg/eval-gate/openai.yaml +12 -0
  133. package/dist/public/bundle/.agents/skills/omg/health/SKILL.md +11 -0
  134. package/dist/public/bundle/.agents/skills/omg/health/openai.yaml +11 -0
  135. package/dist/public/bundle/.agents/skills/omg/hook-governor/SKILL.md +11 -0
  136. package/dist/public/bundle/.agents/skills/omg/hook-governor/openai.yaml +11 -0
  137. package/dist/public/bundle/.agents/skills/omg/incident-replay/SKILL.md +11 -0
  138. package/dist/public/bundle/.agents/skills/omg/incident-replay/openai.yaml +12 -0
  139. package/dist/public/bundle/.agents/skills/omg/lsp-pack/SKILL.md +11 -0
  140. package/dist/public/bundle/.agents/skills/omg/lsp-pack/openai.yaml +11 -0
  141. package/dist/public/bundle/.agents/skills/omg/mcp-fabric/SKILL.md +11 -0
  142. package/dist/public/bundle/.agents/skills/omg/mcp-fabric/openai.yaml +13 -0
  143. package/dist/public/bundle/.agents/skills/omg/preflight/SKILL.md +11 -0
  144. package/dist/public/bundle/.agents/skills/omg/preflight/openai.yaml +12 -0
  145. package/dist/public/bundle/.agents/skills/omg/remote-supervisor/SKILL.md +11 -0
  146. package/dist/public/bundle/.agents/skills/omg/remote-supervisor/openai.yaml +12 -0
  147. package/dist/public/bundle/.agents/skills/omg/robotics/SKILL.md +11 -0
  148. package/dist/public/bundle/.agents/skills/omg/robotics/openai.yaml +11 -0
  149. package/dist/public/bundle/.agents/skills/omg/secure-worktree-pipeline/SKILL.md +11 -0
  150. package/dist/public/bundle/.agents/skills/omg/secure-worktree-pipeline/openai.yaml +12 -0
  151. package/dist/public/bundle/.agents/skills/omg/security-check/SKILL.md +11 -0
  152. package/dist/public/bundle/.agents/skills/omg/security-check/openai.yaml +13 -0
  153. package/dist/public/bundle/.agents/skills/omg/tracebank/SKILL.md +11 -0
  154. package/dist/public/bundle/.agents/skills/omg/tracebank/openai.yaml +12 -0
  155. package/dist/public/bundle/.agents/skills/omg/vision/SKILL.md +11 -0
  156. package/dist/public/bundle/.agents/skills/omg/vision/openai.yaml +11 -0
  157. package/dist/public/bundle/.claude-plugin/marketplace.json +36 -0
  158. package/dist/public/bundle/.claude-plugin/plugin.json +23 -0
  159. package/dist/public/bundle/.mcp.json +40 -0
  160. package/dist/public/bundle/OMG_COMPAT_CONTRACT.md +92 -0
  161. package/dist/public/bundle/registry/bundles/algorithms.yaml +45 -0
  162. package/dist/public/bundle/registry/bundles/api-twin.yaml +48 -0
  163. package/dist/public/bundle/registry/bundles/control-plane.yaml +61 -0
  164. package/dist/public/bundle/registry/bundles/data-lineage.yaml +47 -0
  165. package/dist/public/bundle/registry/bundles/delta-classifier.yaml +47 -0
  166. package/dist/public/bundle/registry/bundles/eval-gate.yaml +47 -0
  167. package/dist/public/bundle/registry/bundles/health.yaml +45 -0
  168. package/dist/public/bundle/registry/bundles/hook-governor.yaml +97 -0
  169. package/dist/public/bundle/registry/bundles/incident-replay.yaml +47 -0
  170. package/dist/public/bundle/registry/bundles/lsp-pack.yaml +48 -0
  171. package/dist/public/bundle/registry/bundles/mcp-fabric.yaml +53 -0
  172. package/dist/public/bundle/registry/bundles/preflight.yaml +48 -0
  173. package/dist/public/bundle/registry/bundles/remote-supervisor.yaml +49 -0
  174. package/dist/public/bundle/registry/bundles/robotics.yaml +45 -0
  175. package/dist/public/bundle/registry/bundles/secure-worktree-pipeline.yaml +54 -0
  176. package/dist/public/bundle/registry/bundles/security-check.yaml +50 -0
  177. package/dist/public/bundle/registry/bundles/tracebank.yaml +47 -0
  178. package/dist/public/bundle/registry/bundles/vision.yaml +45 -0
  179. package/dist/public/bundle/registry/omg-capability.schema.json +80 -0
  180. package/dist/public/bundle/settings.json +379 -0
  181. package/dist/public/manifest.json +255 -0
  182. package/docs/assets/omg-hud.svg +32 -0
  183. package/docs/install/claude-code.md +31 -0
  184. package/docs/install/codex.md +29 -0
  185. package/docs/migration/native-adoption.md +57 -0
  186. package/docs/proof.md +55 -0
  187. package/docs/release-checklist.md +38 -0
  188. package/docs/transcripts/crazy.md +17 -0
  189. package/docs/transcripts/setup.md +25 -0
  190. package/hooks/policy_engine.py +38 -7
  191. package/hooks/post-write.py +1 -1
  192. package/hooks/prompt-enhancer.py +1 -1
  193. package/hooks/security_validators.py +75 -0
  194. package/hooks/setup_wizard.py +43 -8
  195. package/hooks/shadow_manager.py +28 -2
  196. package/package.json +1 -1
  197. package/plugins/README.md +3 -1
  198. package/plugins/__init__.py +1 -0
  199. package/plugins/advanced/commands/OMG:deep-plan.md +1 -1
  200. package/plugins/advanced/commands/OMG:security-review.md +10 -113
  201. package/plugins/advanced/commands/OMG:ship.md +1 -1
  202. package/plugins/advanced/plugin.json +1 -10
  203. package/plugins/core/plugin.json +25 -2
  204. package/pyproject.toml +38 -2
  205. package/registry/__init__.py +1 -0
  206. package/registry/bundles/algorithms.yaml +45 -0
  207. package/registry/bundles/api-twin.yaml +48 -0
  208. package/registry/bundles/control-plane.yaml +61 -0
  209. package/registry/bundles/data-lineage.yaml +47 -0
  210. package/registry/bundles/delta-classifier.yaml +47 -0
  211. package/registry/bundles/eval-gate.yaml +47 -0
  212. package/registry/bundles/health.yaml +45 -0
  213. package/registry/bundles/hook-governor.yaml +97 -0
  214. package/registry/bundles/incident-replay.yaml +47 -0
  215. package/registry/bundles/lsp-pack.yaml +48 -0
  216. package/registry/bundles/mcp-fabric.yaml +53 -0
  217. package/registry/bundles/preflight.yaml +48 -0
  218. package/registry/bundles/remote-supervisor.yaml +49 -0
  219. package/registry/bundles/robotics.yaml +45 -0
  220. package/registry/bundles/secure-worktree-pipeline.yaml +54 -0
  221. package/registry/bundles/security-check.yaml +50 -0
  222. package/registry/bundles/tracebank.yaml +47 -0
  223. package/registry/bundles/vision.yaml +45 -0
  224. package/registry/omg-capability.schema.json +80 -0
  225. package/registry/verify_artifact.py +90 -0
  226. package/runtime/adapters/claude.py +3 -0
  227. package/runtime/adapters/gpt.py +3 -0
  228. package/runtime/adapters/local.py +3 -0
  229. package/runtime/adoption.py +1 -1
  230. package/runtime/api_twin.py +179 -0
  231. package/runtime/asset_loader.py +62 -0
  232. package/runtime/compat.py +24 -3
  233. package/runtime/contract_compiler.py +847 -0
  234. package/runtime/data_lineage.py +73 -0
  235. package/runtime/delta_classifier.py +81 -0
  236. package/runtime/domain_packs.py +46 -0
  237. package/runtime/ecosystem.py +1 -1
  238. package/runtime/eval_gate.py +50 -0
  239. package/runtime/guide_assert.py +45 -0
  240. package/runtime/incident_replay.py +47 -0
  241. package/runtime/mcp_config_writers.py +147 -30
  242. package/runtime/mcp_memory_server.py +1 -1
  243. package/runtime/omg_compat_contract_snapshot.json +9 -8
  244. package/runtime/omg_contract_snapshot.json +9 -8
  245. package/runtime/omg_mcp_server.py +207 -0
  246. package/runtime/preflight.py +73 -0
  247. package/runtime/providers/codex_provider.py +2 -12
  248. package/runtime/providers/gemini_provider.py +2 -21
  249. package/runtime/providers/kimi_provider.py +2 -21
  250. package/runtime/remote_supervisor.py +64 -0
  251. package/runtime/runtime_profile.py +61 -0
  252. package/runtime/security_check.py +464 -0
  253. package/runtime/subagent_dispatcher.py +117 -10
  254. package/runtime/team_router.py +3 -1
  255. package/runtime/tracebank.py +53 -0
  256. package/runtime/untrusted_content.py +102 -0
  257. package/scripts/omg.py +360 -2
  258. package/settings.json +81 -18
  259. package/tools/python_repl.py +33 -3
@@ -0,0 +1,73 @@
1
+ """Lineage manifests for generated OMG artifacts."""
2
+ from __future__ import annotations
3
+
4
+ from datetime import datetime, timezone
5
+ import json
6
+ from pathlib import Path
7
+ from typing import Any
8
+ from uuid import uuid4
9
+
10
+
11
+ def _now() -> str:
12
+ return datetime.now(timezone.utc).isoformat()
13
+
14
+
15
+ def build_lineage_manifest(
16
+ project_dir: str,
17
+ *,
18
+ artifact_type: str,
19
+ sources: list[dict[str, Any]],
20
+ privacy: str,
21
+ license: str,
22
+ derivation: dict[str, Any],
23
+ trace_id: str | None = None,
24
+ ) -> dict[str, Any]:
25
+ lineage_id = f"lineage-{uuid4().hex}"
26
+ payload = {
27
+ "schema": "DataLineageManifest",
28
+ "lineage_id": lineage_id,
29
+ "generated_at": _now(),
30
+ "artifact_type": artifact_type,
31
+ "sources": sources,
32
+ "privacy": privacy,
33
+ "license": license,
34
+ "derivation": derivation,
35
+ "trace_id": trace_id or "",
36
+ }
37
+ validation = validate_lineage_manifest(payload)
38
+ payload["status"] = validation["status"]
39
+ payload["errors"] = validation["errors"]
40
+
41
+ rel_path = Path(".omg") / "lineage" / f"{lineage_id}.json"
42
+ path = Path(project_dir) / rel_path
43
+ path.parent.mkdir(parents=True, exist_ok=True)
44
+ path.write_text(json.dumps(payload, indent=2, ensure_ascii=True) + "\n", encoding="utf-8")
45
+ payload["path"] = rel_path.as_posix()
46
+ return payload
47
+
48
+
49
+ def validate_lineage_manifest(payload: dict[str, Any]) -> dict[str, Any]:
50
+ errors: list[str] = []
51
+ if not payload.get("artifact_type"):
52
+ errors.append("artifact_type is required")
53
+ if not payload.get("privacy"):
54
+ errors.append("privacy is required")
55
+ if not payload.get("license"):
56
+ errors.append("license is required")
57
+ sources = payload.get("sources", [])
58
+ if not isinstance(sources, list) or not sources:
59
+ errors.append("sources are required")
60
+ else:
61
+ for idx, source in enumerate(sources):
62
+ if not isinstance(source, dict):
63
+ errors.append(f"source {idx} must be an object")
64
+ continue
65
+ if not source.get("license"):
66
+ errors.append(f"source {idx} missing license")
67
+ if not source.get("path"):
68
+ errors.append(f"source {idx} missing path")
69
+ return {
70
+ "schema": "DataLineageValidationResult",
71
+ "status": "ok" if not errors else "error",
72
+ "errors": errors,
73
+ }
@@ -0,0 +1,81 @@
1
+ """Repo-aware change classification for routing and policy attachment."""
2
+ from __future__ import annotations
3
+
4
+ import json
5
+ from pathlib import Path
6
+ import subprocess
7
+ from typing import Any
8
+
9
+
10
+ _CATEGORY_RULES: dict[str, tuple[str, ...]] = {
11
+ "auth": ("auth", "token", "secret", "login", "credential"),
12
+ "payment": ("payment", "billing", "invoice", "stripe", "checkout"),
13
+ "db": ("migration", "schema", "database", "sql", "postgres", "mysql"),
14
+ "infra": ("terraform", ".tf", "deploy", "helm", "k8s", "docker"),
15
+ "api": ("openapi", "swagger", "postman", "endpoint", "api"),
16
+ "data": ("dataset", "lineage", "privacy", "warehouse", "etl"),
17
+ "compliance": ("gdpr", "hipaa", "pci", "soc2", "privacy"),
18
+ "robotics": ("robot", "actuator", "sensor", "simulator"),
19
+ "vision": ("vision", "image", "camera", "cv"),
20
+ "health": ("health", "patient", "clinical", "medical"),
21
+ "algorithms": ("algorithm", "benchmark", "determinism", "complexity"),
22
+ }
23
+
24
+
25
+ def classify_project_changes(
26
+ project_dir: str,
27
+ *,
28
+ touched_files: list[str] | None = None,
29
+ goal: str = "",
30
+ ) -> dict[str, Any]:
31
+ files = touched_files if touched_files is not None else _discover_files(project_dir)
32
+ manifest_names = sorted(path.name for path in Path(project_dir).glob("*") if path.is_file())
33
+ haystacks = [goal.lower(), *[file.lower() for file in files], *[name.lower() for name in manifest_names]]
34
+
35
+ categories = {
36
+ category
37
+ for category, tokens in _CATEGORY_RULES.items()
38
+ if any(token in haystack for token in tokens for haystack in haystacks)
39
+ }
40
+ if not categories:
41
+ categories.add("implementation")
42
+
43
+ result = {
44
+ "schema": "DeltaClassification",
45
+ "project_dir": project_dir,
46
+ "goal": goal,
47
+ "categories": sorted(categories),
48
+ "touched_files": files,
49
+ "manifests": manifest_names,
50
+ }
51
+ return result
52
+
53
+
54
+ def _discover_files(project_dir: str) -> list[str]:
55
+ root = Path(project_dir)
56
+ git_dir = root / ".git"
57
+ if git_dir.exists():
58
+ proc = subprocess.run(
59
+ ["git", "diff", "--name-only", "HEAD"],
60
+ cwd=str(root),
61
+ capture_output=True,
62
+ text=True,
63
+ check=False,
64
+ timeout=10,
65
+ )
66
+ if proc.returncode == 0:
67
+ files = [line.strip() for line in proc.stdout.splitlines() if line.strip()]
68
+ if files:
69
+ return files
70
+
71
+ discovered: list[str] = []
72
+ for path in sorted(root.rglob("*")):
73
+ if not path.is_file():
74
+ continue
75
+ rel = path.relative_to(root).as_posix()
76
+ if rel.startswith(".omg/"):
77
+ continue
78
+ discovered.append(rel)
79
+ if len(discovered) >= 32:
80
+ break
81
+ return discovered
@@ -0,0 +1,46 @@
1
+ """Optional domain pack contracts for high-risk verticals."""
2
+ from __future__ import annotations
3
+
4
+ from typing import Any
5
+
6
+
7
+ DOMAIN_PACKS: dict[str, dict[str, Any]] = {
8
+ "robotics": {
9
+ "name": "robotics",
10
+ "required_approvals": ["actuation-approval"],
11
+ "required_evidence": ["simulator-replay", "kill-switch-check"],
12
+ "policy_modules": ["safe-actuation", "simulator-gate"],
13
+ "eval_hooks": ["robotics-sim"],
14
+ "replay_hooks": ["incident-replay"],
15
+ },
16
+ "vision": {
17
+ "name": "vision",
18
+ "required_approvals": [],
19
+ "required_evidence": ["dataset-provenance", "drift-check"],
20
+ "policy_modules": ["dataset-lineage", "drift-gate"],
21
+ "eval_hooks": ["vision-regression"],
22
+ "replay_hooks": ["incident-replay"],
23
+ },
24
+ "algorithms": {
25
+ "name": "algorithms",
26
+ "required_approvals": [],
27
+ "required_evidence": ["benchmark-harness", "determinism-check"],
28
+ "policy_modules": ["benchmark-gate", "determinism-gate"],
29
+ "eval_hooks": ["algorithm-benchmarks"],
30
+ "replay_hooks": ["incident-replay"],
31
+ },
32
+ "health": {
33
+ "name": "health",
34
+ "required_approvals": ["human-review"],
35
+ "required_evidence": ["audit-trail", "restricted-tools", "provenance"],
36
+ "policy_modules": ["human-review", "privacy-gate"],
37
+ "eval_hooks": ["health-safety"],
38
+ "replay_hooks": ["incident-replay"],
39
+ },
40
+ }
41
+
42
+
43
+ def get_domain_pack_contract(name: str) -> dict[str, Any]:
44
+ if name not in DOMAIN_PACKS:
45
+ raise KeyError(name)
46
+ return dict(DOMAIN_PACKS[name])
@@ -8,7 +8,7 @@ import subprocess
8
8
  from typing import Any
9
9
 
10
10
  ECOSYSTEM_SCHEMA = "OmgEcosystemCatalog"
11
- ECOSYSTEM_CATALOG_VERSION = "1.0.0"
11
+ ECOSYSTEM_CATALOG_VERSION = "2.0.5"
12
12
  ECOSYSTEM_LOCK_SCHEMA = "OmgEcosystemLock"
13
13
  DEFAULT_ECOSYSTEM_REPO_DIR = ".omg/ecosystem/repos"
14
14
  DEFAULT_ECOSYSTEM_LOCK_PATH = ".omg/state/ecosystem-lock.json"
@@ -0,0 +1,50 @@
1
+ """Reproducible evaluation results for release gating."""
2
+ from __future__ import annotations
3
+
4
+ from datetime import datetime, timezone
5
+ import json
6
+ from pathlib import Path
7
+ from typing import Any
8
+
9
+
10
+ EVAL_GATE_LATEST_REL_PATH = Path(".omg") / "evals" / "latest.json"
11
+ EVAL_GATE_HISTORY_REL_PATH = Path(".omg") / "evals" / "history.jsonl"
12
+
13
+
14
+ def _now() -> str:
15
+ return datetime.now(timezone.utc).isoformat()
16
+
17
+
18
+ def evaluate_trace(
19
+ project_dir: str,
20
+ *,
21
+ trace_id: str,
22
+ suites: list[str],
23
+ metrics: dict[str, float],
24
+ regression_threshold: float = 0.95,
25
+ ) -> dict[str, Any]:
26
+ scorecard = {name: float(metrics.get(name, 0.0)) for name in suites}
27
+ regressed = any(score < regression_threshold for score in scorecard.values())
28
+ result = {
29
+ "schema": "EvalGateResult",
30
+ "trace_id": trace_id,
31
+ "evaluated_at": _now(),
32
+ "status": "fail" if regressed else "ok",
33
+ "suites": suites,
34
+ "metrics": scorecard,
35
+ "summary": {
36
+ "regressed": regressed,
37
+ "regression_threshold": regression_threshold,
38
+ },
39
+ }
40
+
41
+ latest_path = Path(project_dir) / EVAL_GATE_LATEST_REL_PATH
42
+ latest_path.parent.mkdir(parents=True, exist_ok=True)
43
+ latest_path.write_text(json.dumps(result, indent=2, ensure_ascii=True) + "\n", encoding="utf-8")
44
+
45
+ history_path = Path(project_dir) / EVAL_GATE_HISTORY_REL_PATH
46
+ with history_path.open("a", encoding="utf-8") as handle:
47
+ handle.write(json.dumps(result, ensure_ascii=True) + "\n")
48
+
49
+ result["path"] = EVAL_GATE_LATEST_REL_PATH.as_posix()
50
+ return result
@@ -0,0 +1,45 @@
1
+ """Rule-based output assertions for OMG guide checks."""
2
+ from __future__ import annotations
3
+
4
+ from typing import Any
5
+
6
+
7
+ def guide_assert(candidate: str, rules: dict[str, Any]) -> dict[str, Any]:
8
+ text = candidate or ""
9
+ lowered = text.lower()
10
+ violations: list[dict[str, str]] = []
11
+
12
+ for goal in _as_list(rules.get("goals")):
13
+ if "todo" in goal.lower() and "todo" in lowered:
14
+ violations.append({"rule_type": "goal", "rule": goal, "reason": "candidate still includes TODO markers"})
15
+
16
+ for non_goal in _as_list(rules.get("non_goals")):
17
+ if _mentions(lowered, non_goal):
18
+ violations.append({"rule_type": "non_goal", "rule": non_goal, "reason": "candidate mentions an explicit non-goal"})
19
+
20
+ for criterion in _as_list(rules.get("acceptance_criteria")):
21
+ if "production-ready" in criterion.lower() and any(token in lowered for token in ("todo", "insecure", "placeholder")):
22
+ violations.append({"rule_type": "acceptance_criteria", "rule": criterion, "reason": "candidate contains non-production wording"})
23
+
24
+ return {
25
+ "schema": "GuideAssertionResult",
26
+ "verdict": "fail" if violations else "pass",
27
+ "violations": violations,
28
+ "summary": {
29
+ "rule_count": sum(len(_as_list(rules.get(key))) for key in ("goals", "non_goals", "acceptance_criteria", "architecture_constraints", "style_rules", "risk_appetite")),
30
+ "violation_count": len(violations),
31
+ },
32
+ }
33
+
34
+
35
+ def _as_list(value: Any) -> list[str]:
36
+ if not isinstance(value, list):
37
+ return []
38
+ return [str(item) for item in value if str(item).strip()]
39
+
40
+
41
+ def _mentions(lowered_candidate: str, rule: str) -> bool:
42
+ tokens = [token.lower() for token in rule.split() if len(token) >= 4]
43
+ if not tokens:
44
+ return False
45
+ return all(token in lowered_candidate for token in tokens)
@@ -0,0 +1,47 @@
1
+ """Replayable incident pack generation."""
2
+ from __future__ import annotations
3
+
4
+ from datetime import datetime, timezone
5
+ import json
6
+ from pathlib import Path
7
+ from typing import Any
8
+ from uuid import uuid4
9
+
10
+
11
+ def _now() -> str:
12
+ return datetime.now(timezone.utc).isoformat()
13
+
14
+
15
+ def build_incident_pack(
16
+ project_dir: str,
17
+ *,
18
+ title: str,
19
+ failing_tests: list[str],
20
+ logs: list[str],
21
+ diff_summary: dict[str, Any],
22
+ trace_id: str | None = None,
23
+ ) -> dict[str, Any]:
24
+ incident_id = f"incident-{uuid4().hex}"
25
+ payload = {
26
+ "schema": "IncidentReplayPack",
27
+ "incident_id": incident_id,
28
+ "title": title,
29
+ "generated_at": _now(),
30
+ "trace_id": trace_id or "",
31
+ "failing_tests": failing_tests,
32
+ "logs": logs,
33
+ "diff_summary": diff_summary,
34
+ "reproduction_steps": [
35
+ "Replay the failing tests.",
36
+ "Inspect the attached logs.",
37
+ "Validate the diff summary before patching.",
38
+ ],
39
+ "regression_guards": failing_tests,
40
+ }
41
+
42
+ rel_path = Path(".omg") / "incidents" / f"{incident_id}.json"
43
+ path = Path(project_dir) / rel_path
44
+ path.parent.mkdir(parents=True, exist_ok=True)
45
+ path.write_text(json.dumps(payload, indent=2, ensure_ascii=True) + "\n", encoding="utf-8")
46
+ payload["path"] = rel_path.as_posix()
47
+ return payload
@@ -5,6 +5,12 @@ import os
5
5
  from pathlib import Path
6
6
  from typing import cast
7
7
 
8
+ from hooks.security_validators import (
9
+ toml_quote_string,
10
+ validate_server_name,
11
+ validate_server_url,
12
+ )
13
+
8
14
 
9
15
  def _atomic_write_text(path: Path, content: str) -> None:
10
16
  path.parent.mkdir(parents=True, exist_ok=True)
@@ -29,22 +35,61 @@ def _write_json(path: Path, data: dict[str, object]) -> None:
29
35
  _atomic_write_text(path, json.dumps(data, indent=2) + "\n")
30
36
 
31
37
 
32
- def write_claude_mcp_config(project_dir: str, server_url: str, server_name: str = "memory-server") -> None:
33
- config_path = Path(project_dir) / ".mcp.json"
34
- config = _load_json(config_path)
38
+ def _validated_server_input(server_url: str, server_name: str) -> tuple[str, str]:
39
+ return validate_server_url(server_url), validate_server_name(server_name)
40
+
41
+
42
+ def _validated_stdio_input(command: str, args: list[str], server_name: str) -> tuple[str, list[str], str]:
43
+ normalized_name = validate_server_name(server_name)
44
+ normalized_command = str(command).strip()
45
+ if not normalized_command or "\n" in normalized_command or "\r" in normalized_command:
46
+ raise ValueError("Invalid command: newline characters are not allowed")
47
+ normalized_args = [str(arg) for arg in args]
48
+ for arg in normalized_args:
49
+ if "\n" in arg or "\r" in arg:
50
+ raise ValueError("Invalid args: newline characters are not allowed")
51
+ return normalized_command, normalized_args, normalized_name
52
+
53
+
54
+ def _write_json_mcp_server(path: Path, server_name: str, payload: dict[str, object]) -> None:
55
+ config = _load_json(path)
35
56
  mcp_servers = config.get("mcpServers")
36
57
  if not isinstance(mcp_servers, dict):
37
58
  mcp_servers = {}
38
59
  config["mcpServers"] = mcp_servers
39
- mcp_servers[server_name] = {"type": "http", "url": server_url}
40
- _write_json(config_path, config)
60
+ mcp_servers[server_name] = payload
61
+ _write_json(path, config)
41
62
 
42
63
 
43
- def write_codex_mcp_config(server_url: str, server_name: str = "memory-server") -> None:
44
- config_path = Path.home() / ".codex" / "config.toml"
45
- config_path.parent.mkdir(parents=True, exist_ok=True)
64
+ def write_claude_mcp_config(project_dir: str, server_url: str, server_name: str = "memory-server") -> None:
65
+ server_url, server_name = _validated_server_input(server_url, server_name)
66
+ config_path = Path(project_dir) / ".mcp.json"
67
+ _write_json_mcp_server(config_path, server_name, {"type": "http", "url": server_url})
68
+
69
+
70
+ def write_claude_mcp_stdio_config(
71
+ project_dir: str,
72
+ *,
73
+ command: str,
74
+ args: list[str],
75
+ server_name: str = "omg-control",
76
+ ) -> None:
77
+ command, args, server_name = _validated_stdio_input(command, args, server_name)
78
+ config_path = Path(project_dir) / ".mcp.json"
79
+ _write_json_mcp_server(config_path, server_name, {"command": command, "args": args})
80
+
46
81
 
47
- existing = config_path.read_text() if config_path.exists() else ""
82
+ def write_codex_mcp_config(
83
+ server_url: str,
84
+ server_name: str = "memory-server",
85
+ *,
86
+ config_path: str | Path | None = None,
87
+ ) -> None:
88
+ server_url, server_name = _validated_server_input(server_url, server_name)
89
+ target_path = Path(config_path) if config_path is not None else Path.home() / ".codex" / "config.toml"
90
+ target_path.parent.mkdir(parents=True, exist_ok=True)
91
+
92
+ existing = target_path.read_text() if target_path.exists() else ""
48
93
  lines = existing.splitlines(keepends=True)
49
94
 
50
95
  header_unquoted = f"[mcp_servers.{server_name}]"
@@ -60,7 +105,7 @@ def write_codex_mcp_config(server_url: str, server_name: str = "memory-server")
60
105
  block = [
61
106
  f"{header_unquoted}\n",
62
107
  'type = "http"\n',
63
- f'url = "{server_url}"\n',
108
+ f'url = "{toml_quote_string(server_url)}"\n',
64
109
  "\n",
65
110
  ]
66
111
 
@@ -68,7 +113,7 @@ def write_codex_mcp_config(server_url: str, server_name: str = "memory-server")
68
113
  if existing and not existing.endswith("\n"):
69
114
  existing += "\n"
70
115
  content = existing + "".join(block)
71
- _atomic_write_text(config_path, content)
116
+ _atomic_write_text(target_path, content)
72
117
  return
73
118
 
74
119
  end_idx = len(lines)
@@ -79,26 +124,98 @@ def write_codex_mcp_config(server_url: str, server_name: str = "memory-server")
79
124
  break
80
125
 
81
126
  updated_lines = lines[:start_idx] + block + lines[end_idx:]
82
- _atomic_write_text(config_path, "".join(updated_lines))
127
+ _atomic_write_text(target_path, "".join(updated_lines))
83
128
 
84
129
 
85
- def write_gemini_mcp_config(server_url: str, server_name: str = "memory-server") -> None:
86
- config_path = Path.home() / ".gemini" / "settings.json"
87
- config = _load_json(config_path)
88
- mcp_servers = config.get("mcpServers")
89
- if not isinstance(mcp_servers, dict):
90
- mcp_servers = {}
91
- config["mcpServers"] = mcp_servers
92
- mcp_servers[server_name] = {"httpUrl": server_url}
93
- _write_json(config_path, config)
130
+ def write_codex_mcp_stdio_config(
131
+ *,
132
+ command: str,
133
+ args: list[str],
134
+ server_name: str = "omg-control",
135
+ config_path: str | Path | None = None,
136
+ ) -> None:
137
+ command, args, server_name = _validated_stdio_input(command, args, server_name)
138
+ target_path = Path(config_path) if config_path is not None else Path.home() / ".codex" / "config.toml"
139
+ target_path.parent.mkdir(parents=True, exist_ok=True)
94
140
 
141
+ existing = target_path.read_text() if target_path.exists() else ""
142
+ lines = existing.splitlines(keepends=True)
143
+ header_unquoted = f"[mcp_servers.{server_name}]"
144
+ header_quoted = f"[mcp_servers.\"{server_name}\"]"
145
+ headers = {header_unquoted, header_quoted}
95
146
 
96
- def write_kimi_mcp_config(server_url: str, server_name: str = "memory-server") -> None:
97
- config_path = Path.home() / ".kimi" / "mcp.json"
98
- config = _load_json(config_path)
99
- mcp_servers = config.get("mcpServers")
100
- if not isinstance(mcp_servers, dict):
101
- mcp_servers = {}
102
- config["mcpServers"] = mcp_servers
103
- mcp_servers[server_name] = {"type": "http", "url": server_url}
104
- _write_json(config_path, config)
147
+ start_idx: int | None = None
148
+ for idx, line in enumerate(lines):
149
+ if line.strip() in headers:
150
+ start_idx = idx
151
+ break
152
+
153
+ args_text = ", ".join(f'"{toml_quote_string(arg)}"' for arg in args)
154
+ block = [
155
+ f"{header_unquoted}\n",
156
+ f'command = "{toml_quote_string(command)}"\n',
157
+ f"args = [{args_text}]\n",
158
+ "\n",
159
+ ]
160
+
161
+ if start_idx is None:
162
+ if existing and not existing.endswith("\n"):
163
+ existing += "\n"
164
+ _atomic_write_text(target_path, existing + "".join(block))
165
+ return
166
+
167
+ end_idx = len(lines)
168
+ for idx in range(start_idx + 1, len(lines)):
169
+ stripped = lines[idx].strip()
170
+ if stripped.startswith("[") and stripped.endswith("]"):
171
+ end_idx = idx
172
+ break
173
+
174
+ updated_lines = lines[:start_idx] + block + lines[end_idx:]
175
+ _atomic_write_text(target_path, "".join(updated_lines))
176
+
177
+
178
+ def write_gemini_mcp_config(
179
+ server_url: str,
180
+ server_name: str = "memory-server",
181
+ *,
182
+ config_path: str | Path | None = None,
183
+ ) -> None:
184
+ server_url, server_name = _validated_server_input(server_url, server_name)
185
+ target_path = Path(config_path) if config_path is not None else Path.home() / ".gemini" / "settings.json"
186
+ _write_json_mcp_server(target_path, server_name, {"httpUrl": server_url})
187
+
188
+
189
+ def write_gemini_mcp_stdio_config(
190
+ *,
191
+ command: str,
192
+ args: list[str],
193
+ server_name: str = "omg-control",
194
+ config_path: str | Path | None = None,
195
+ ) -> None:
196
+ command, args, server_name = _validated_stdio_input(command, args, server_name)
197
+ target_path = Path(config_path) if config_path is not None else Path.home() / ".gemini" / "settings.json"
198
+ _write_json_mcp_server(target_path, server_name, {"command": command, "args": args})
199
+
200
+
201
+ def write_kimi_mcp_config(
202
+ server_url: str,
203
+ server_name: str = "memory-server",
204
+ *,
205
+ config_path: str | Path | None = None,
206
+ ) -> None:
207
+ server_url, server_name = _validated_server_input(server_url, server_name)
208
+ target_path = Path(config_path) if config_path is not None else Path.home() / ".kimi" / "mcp.json"
209
+ _write_json_mcp_server(target_path, server_name, {"type": "http", "url": server_url})
210
+
211
+
212
+ def write_kimi_mcp_stdio_config(
213
+ *,
214
+ command: str,
215
+ args: list[str],
216
+ server_name: str = "omg-control",
217
+ config_path: str | Path | None = None,
218
+ ) -> None:
219
+ command, args, server_name = _validated_stdio_input(command, args, server_name)
220
+ target_path = Path(config_path) if config_path is not None else Path.home() / ".kimi" / "mcp.json"
221
+ _write_json_mcp_server(target_path, server_name, {"command": command, "args": args})
@@ -66,7 +66,7 @@ mcp = FastMCP("OMG Memory Server", lifespan=lifespan)
66
66
 
67
67
  @mcp.custom_route("/health", methods=["GET"])
68
68
  async def health(_: Request) -> JSONResponse:
69
- return JSONResponse({"status": "ok", "version": "1.0.0"})
69
+ return JSONResponse({"status": "ok", "version": "2.0.5"})
70
70
 
71
71
 
72
72
  @mcp.tool()
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "schema": "OmgCompatContractSnapshot",
3
- "contract_version": "1.0.0",
3
+ "contract_version": "2.0.5",
4
4
  "count": 47,
5
5
  "contracts": [
6
6
  {
@@ -736,19 +736,19 @@
736
736
  },
737
737
  {
738
738
  "skill": "security-review",
739
- "route": "secure",
739
+ "route": "security_check",
740
740
  "maturity": "native",
741
741
  "inputs": {
742
- "required": [
742
+ "required": [],
743
+ "optional": [
743
744
  "problem"
744
- ],
745
- "optional": []
745
+ ]
746
746
  },
747
747
  "outputs": {
748
- "schema": "PolicyDecision"
748
+ "schema": "SecurityCheckResult"
749
749
  },
750
750
  "side_effects": [],
751
- "notes": ""
751
+ "notes": "Deprecated alias to the canonical OMG security-check engine."
752
752
  },
753
753
  {
754
754
  "skill": "skill",
@@ -911,5 +911,6 @@
911
911
  ],
912
912
  "notes": "Writes long-form memory artifact for writing workflows."
913
913
  }
914
- ]
914
+ ],
915
+ "generated_at": "2026-03-07T04:51:08.940394+00:00"
915
916
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "schema": "OmgCompatContractSnapshot",
3
- "contract_version": "1.0.0",
3
+ "contract_version": "2.0.5",
4
4
  "count": 47,
5
5
  "contracts": [
6
6
  {
@@ -736,19 +736,19 @@
736
736
  },
737
737
  {
738
738
  "skill": "security-review",
739
- "route": "secure",
739
+ "route": "security_check",
740
740
  "maturity": "native",
741
741
  "inputs": {
742
- "required": [
742
+ "required": [],
743
+ "optional": [
743
744
  "problem"
744
- ],
745
- "optional": []
745
+ ]
746
746
  },
747
747
  "outputs": {
748
- "schema": "PolicyDecision"
748
+ "schema": "SecurityCheckResult"
749
749
  },
750
750
  "side_effects": [],
751
- "notes": ""
751
+ "notes": "Deprecated alias to the canonical OMG security-check engine."
752
752
  },
753
753
  {
754
754
  "skill": "skill",
@@ -911,5 +911,6 @@
911
911
  ],
912
912
  "notes": "Writes long-form memory artifact for writing workflows."
913
913
  }
914
- ]
914
+ ],
915
+ "generated_at": "2026-03-07T04:51:08.940453+00:00"
915
916
  }