@miller-tech/uap 1.40.0 → 1.41.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 (150) hide show
  1. package/README.md +109 -642
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/cli/deliver-defaults.d.ts +23 -0
  4. package/dist/cli/deliver-defaults.d.ts.map +1 -0
  5. package/dist/cli/deliver-defaults.js +121 -0
  6. package/dist/cli/deliver-defaults.js.map +1 -0
  7. package/dist/cli/init.d.ts.map +1 -1
  8. package/dist/cli/init.js +29 -0
  9. package/dist/cli/init.js.map +1 -1
  10. package/dist/cli/setup.d.ts.map +1 -1
  11. package/dist/cli/setup.js +19 -0
  12. package/dist/cli/setup.js.map +1 -1
  13. package/dist/policies/policy-tools.d.ts +7 -0
  14. package/dist/policies/policy-tools.d.ts.map +1 -1
  15. package/dist/policies/policy-tools.js +24 -2
  16. package/dist/policies/policy-tools.js.map +1 -1
  17. package/docs/INDEX.md +48 -286
  18. package/docs/architecture/OVERVIEW.md +328 -0
  19. package/docs/architecture/PROTOCOL.md +204 -0
  20. package/docs/benchmarks/README.md +17 -192
  21. package/docs/getting-started/CONFIGURATION.md +237 -0
  22. package/docs/getting-started/INSTALLATION.md +125 -0
  23. package/docs/getting-started/QUICKSTART.md +115 -0
  24. package/docs/guides/COORDINATION.md +162 -0
  25. package/docs/guides/DELIVER.md +115 -0
  26. package/docs/guides/DEPLOY_BATCHING.md +212 -0
  27. package/docs/guides/DROIDS_AND_SKILLS.md +202 -0
  28. package/docs/guides/LOCAL_MODELS.md +148 -0
  29. package/docs/guides/MCP_ROUTER.md +195 -0
  30. package/docs/guides/MEMORY.md +235 -0
  31. package/docs/guides/MULTI_MODEL.md +223 -0
  32. package/docs/guides/POLICIES.md +190 -0
  33. package/docs/guides/WORKTREE_WORKFLOW.md +185 -0
  34. package/docs/integrations/MCP_ROUTER.md +147 -0
  35. package/docs/integrations/RTK.md +102 -0
  36. package/docs/reference/API.md +485 -0
  37. package/docs/reference/CLI.md +719 -0
  38. package/docs/reference/CONFIGURATION.md +90 -193
  39. package/docs/reference/DATABASE_SCHEMA.md +110 -344
  40. package/docs/reference/FEATURES.md +176 -472
  41. package/docs/reference/PATTERNS.md +102 -0
  42. package/docs/reference/PLATFORMS.md +83 -0
  43. package/package.json +3 -1
  44. package/src/policies/enforcers/7ebbc721-7540-4e9f-879a-770e0213a09b_architecture_review.py +101 -0
  45. package/src/policies/enforcers/__pycache__/_common.cpython-312.pyc +0 -0
  46. package/src/policies/enforcers/_common.py +100 -0
  47. package/src/policies/enforcers/artifact_hygiene.py +52 -0
  48. package/src/policies/enforcers/cluster_routing.py +63 -0
  49. package/src/policies/enforcers/codebase_read_before_plan.py +52 -0
  50. package/src/policies/enforcers/coord_overlap.py +81 -0
  51. package/src/policies/enforcers/delivery_enforcement.py +97 -0
  52. package/src/policies/enforcers/doc_live_over_report.py +50 -0
  53. package/src/policies/enforcers/expert_review_required.py +135 -0
  54. package/src/policies/enforcers/iac_parity.py +53 -0
  55. package/src/policies/enforcers/mcp_router_first.py +37 -0
  56. package/src/policies/enforcers/memory_before_plan.py +61 -0
  57. package/src/policies/enforcers/parallel_reads.py +50 -0
  58. package/src/policies/enforcers/rtk_wrap.py +44 -0
  59. package/src/policies/enforcers/schema_diff_gate.py +80 -0
  60. package/src/policies/enforcers/session_memory_write.py +52 -0
  61. package/src/policies/enforcers/task_required.py +131 -0
  62. package/src/policies/enforcers/test_gate.py +58 -0
  63. package/src/policies/enforcers/validate_plan_before_build.py +75 -0
  64. package/src/policies/enforcers/worktree_required.py +57 -0
  65. package/src/policies/schemas/policies/architecture-review.md +51 -0
  66. package/src/policies/schemas/policies/artifact-hygiene.md +29 -0
  67. package/src/policies/schemas/policies/cluster-routing.md +31 -0
  68. package/src/policies/schemas/policies/codebase-read-before-plan.md +30 -0
  69. package/src/policies/schemas/policies/coord-overlap.md +24 -0
  70. package/src/policies/schemas/policies/delivery-enforcement.md +45 -0
  71. package/src/policies/schemas/policies/doc-live-over-report.md +32 -0
  72. package/src/policies/schemas/policies/expert-review-required.md +60 -0
  73. package/src/policies/schemas/policies/iac-parity.md +31 -0
  74. package/src/policies/schemas/policies/mandatory-testing-deployment.md +147 -0
  75. package/src/policies/schemas/policies/mcp-router-first.md +24 -0
  76. package/src/policies/schemas/policies/memory-before-plan.md +24 -0
  77. package/src/policies/schemas/policies/merge-deploy-monitor-verify.md +145 -0
  78. package/src/policies/schemas/policies/parallel-reads.md +24 -0
  79. package/src/policies/schemas/policies/rtk-wrap.md +26 -0
  80. package/src/policies/schemas/policies/schema-diff-gate.md +30 -0
  81. package/src/policies/schemas/policies/session-memory-write.md +24 -0
  82. package/src/policies/schemas/policies/task-required.md +49 -0
  83. package/src/policies/schemas/policies/test-gate.md +24 -0
  84. package/src/policies/schemas/policies/validate-plan-before-build.md +28 -0
  85. package/src/policies/schemas/policies/worktree-required.md +28 -0
  86. package/templates/hooks/uap-policy-gate.sh +5 -0
  87. package/docs/AGENTS.md +0 -423
  88. package/docs/DOCUMENTATION_AUDIT_REPORT.md +0 -131
  89. package/docs/GETTING_STARTED.md +0 -288
  90. package/docs/PROJECT_ANALYSIS_REPORT.md +0 -510
  91. package/docs/architecture/COMPLETE_ARCHITECTURE.md +0 -748
  92. package/docs/architecture/EXPERT_STACK.md +0 -137
  93. package/docs/architecture/MULTI_MODEL.md +0 -224
  94. package/docs/architecture/PLATFORM_GATING.md +0 -68
  95. package/docs/architecture/SYSTEM_ANALYSIS.md +0 -334
  96. package/docs/architecture/UAP_COMPLIANCE.md +0 -217
  97. package/docs/architecture/UAP_PROTOCOL.md +0 -339
  98. package/docs/architecture/UAP_STRICT_DROIDS.md +0 -172
  99. package/docs/archive/BALLS_MODE_SELF_ANALYSIS.md +0 -260
  100. package/docs/archive/BENCHMARK_GAPS_AND_PLAN.md +0 -146
  101. package/docs/archive/FAILING_TASKS_SOLUTION_PLAN.md +0 -668
  102. package/docs/archive/JINJA2-SYSTEM-MESSAGE-FIX.md +0 -209
  103. package/docs/archive/MODEL_ROUTING_IMPLEMENTATION_SUMMARY.md +0 -281
  104. package/docs/archive/MODEL_ROUTING_OPTIMIZATION_PLAN.md +0 -320
  105. package/docs/archive/NPM-PUBLISH-V0.9.1.md +0 -240
  106. package/docs/archive/OPTIMIZATION_OPTIONS.md +0 -334
  107. package/docs/archive/PARALLELISM_GAPS_AND_OPTIONS.md +0 -422
  108. package/docs/archive/POLICY_GATE_IMPLEMENTATION.md +0 -245
  109. package/docs/archive/SETUP_IMPROVEMENTS.md +0 -213
  110. package/docs/archive/UAP_GENERIC_OPTIMIZATION_PLAN.md +0 -270
  111. package/docs/archive/UAP_OPTIMIZATION_PLAN.md +0 -701
  112. package/docs/archive/UAP_V103_PATTERN_DESIGN.md +0 -315
  113. package/docs/archive/UAP_V104_COMPLIANCE_DESIGN.md +0 -223
  114. package/docs/archive/changelog/2026-03-10_uap-100-compliance.md +0 -77
  115. package/docs/archive/changelog/2026-03-10_uap-full-system-verification.md +0 -109
  116. package/docs/archive/opencode-integration-guide.md +0 -740
  117. package/docs/archive/opencode-integration-quickref.md +0 -180
  118. package/docs/benchmarks/OVERNIGHT_RUNNER.md +0 -341
  119. package/docs/benchmarks/SPECULATIVE_DECODING_JOURNEY_2026-03.md +0 -221
  120. package/docs/benchmarks/VALIDATION_PLAN.md +0 -568
  121. package/docs/blog/SPECULATIVE_DECODING_PRODUCTION_PLAYBOOK.md +0 -139
  122. package/docs/blog/local-coding-agents.md +0 -266
  123. package/docs/blog/x-thread.md +0 -254
  124. package/docs/deployment/DEPLOYMENT.md +0 -895
  125. package/docs/deployment/DEPLOYMENT_STRATEGIES.md +0 -518
  126. package/docs/deployment/DEPLOY_BATCHER_ANALYSIS.md +0 -224
  127. package/docs/deployment/DEPLOY_BATCHING.md +0 -273
  128. package/docs/deployment/DEPLOY_BUCKETING_ANALYSIS.md +0 -420
  129. package/docs/deployment/QWEN35_LLAMA_CPP.md +0 -426
  130. package/docs/deployment/UAP_LLAMA_ANTHROPIC_PROXY_BOOTSTRAP.md +0 -279
  131. package/docs/getting-started/INTEGRATION.md +0 -628
  132. package/docs/getting-started/OVERVIEW.md +0 -324
  133. package/docs/getting-started/SETUP.md +0 -377
  134. package/docs/integrations/MCP_ROUTER_SETUP.md +0 -445
  135. package/docs/integrations/RTK_INTEGRATION.md +0 -468
  136. package/docs/operations/TROUBLESHOOTING.md +0 -660
  137. package/docs/pr/PR_SPECULATIVE_DOCS_TEMPLATE.md +0 -146
  138. package/docs/pr/UPSTREAM_PRS.md +0 -424
  139. package/docs/reference/API_REFERENCE.md +0 -903
  140. package/docs/reference/EXPERT_DROIDS.md +0 -219
  141. package/docs/reference/HARNESS-MATRIX.md +0 -318
  142. package/docs/reference/PATTERN_LIBRARY.md +0 -636
  143. package/docs/reference/UAP_CLI_REFERENCE.md +0 -620
  144. package/docs/research/BEHAVIORAL_PATTERNS.md +0 -228
  145. package/docs/research/DOMAIN_STRATEGIES.md +0 -316
  146. package/docs/research/MEMORY_SYSTEMS_COMPARISON.md +0 -812
  147. package/docs/research/PATTERN_ANALYSIS_2026-01-18.md +0 -436
  148. package/docs/research/PERFORMANCE_ANALYSIS_2026-01-18.md +0 -209
  149. package/docs/research/PERFORMANCE_TEST_PLAN.md +0 -383
  150. package/docs/research/TERMINAL_BENCH_LEARNINGS.md +0 -217
@@ -0,0 +1,131 @@
1
+ #!/usr/bin/env python3
2
+ """task-required enforcer: a UAP task must be in_progress before mutating work.
3
+
4
+ Blocks Edit/Write/MultiEdit (outside exempt prefixes) and the ship actions
5
+ git commit / git push / gh pr create when no row in .uap/tasks/tasks.db has
6
+ status='in_progress'. Closes UAP protocol step 4 — which was previously
7
+ text-injection only and therefore skippable.
8
+
9
+ Fail-open: if UAP task tracking is not initialised (no tasks.db) or the DB is
10
+ unreadable, the operation is allowed — so non-UAP repos are unaffected.
11
+ Override: set UAP_NO_TASK=1 to bypass.
12
+ """
13
+ from __future__ import annotations
14
+ import os
15
+ import re
16
+ import sqlite3
17
+ import sys
18
+ from pathlib import Path
19
+
20
+ sys.path.insert(0, str(Path(__file__).parent))
21
+ from _common import emit, parse_cli, repo_root, run # noqa: E402
22
+
23
+ EDIT_OPS = {"edit", "write", "multiedit"}
24
+
25
+ # Meta / infra / docs paths that do not require a task (mirror worktree_required,
26
+ # plus .policy-tools/ which is the policy-system's own runtime artifact dir).
27
+ EXEMPT_PREFIXES = (
28
+ ".claude/",
29
+ ".cursor/",
30
+ ".opencode/",
31
+ ".codex/",
32
+ ".forge/",
33
+ ".uap/",
34
+ ".policy-tools/",
35
+ "src/policies/",
36
+ "scripts/",
37
+ "docs/",
38
+ )
39
+
40
+ # Bash ship actions gated even though Bash itself is otherwise unrestricted.
41
+ SHIP_PATTERNS = (
42
+ re.compile(r"\bgit\s+(commit|push)\b"),
43
+ re.compile(r"\bgh\s+pr\s+create\b"),
44
+ )
45
+
46
+
47
+ def main_repo_root() -> Path:
48
+ """Resolve the primary worktree root, even when invoked from a linked
49
+ worktree — `git rev-parse --git-common-dir` always points at the main
50
+ .git, whose parent is the primary checkout."""
51
+ rc, out, _ = run(["git", "rev-parse", "--git-common-dir"])
52
+ if rc == 0 and out.strip():
53
+ p = Path(out.strip())
54
+ if not p.is_absolute():
55
+ p = (Path.cwd() / p).resolve()
56
+ return p.parent
57
+ return repo_root()
58
+
59
+
60
+ def in_progress_task_state():
61
+ """True if an in_progress task exists, False if none, None if UAP task
62
+ tracking is not set up / DB unreadable (caller treats None as allow)."""
63
+ db = main_repo_root() / ".uap" / "tasks" / "tasks.db"
64
+ if not db.exists():
65
+ return None
66
+ try:
67
+ con = sqlite3.connect(f"file:{db}?mode=ro", uri=True, timeout=2)
68
+ try:
69
+ n = con.execute(
70
+ "SELECT COUNT(*) FROM tasks WHERE status='in_progress'"
71
+ ).fetchone()[0]
72
+ finally:
73
+ con.close()
74
+ return n > 0
75
+ except Exception: # noqa: BLE001
76
+ return None
77
+
78
+
79
+ def main() -> None:
80
+ op, args = parse_cli()
81
+
82
+ if os.environ.get("UAP_NO_TASK") == "1":
83
+ emit(True, "UAP_NO_TASK override set")
84
+
85
+ op_l = op.lower()
86
+ is_edit = op_l in EDIT_OPS
87
+ is_bash = op_l == "bash"
88
+ if not is_edit and not is_bash:
89
+ emit(True, "not a mutating operation")
90
+
91
+ if is_bash:
92
+ cmd = args.get("command") or args.get("cmd") or ""
93
+ if not any(p.search(cmd) for p in SHIP_PATTERNS):
94
+ emit(True, "not a ship action")
95
+ gate_label = "ship action (git commit/push, gh pr create)"
96
+ else:
97
+ target = (
98
+ args.get("file_path")
99
+ or args.get("path")
100
+ or args.get("target")
101
+ or ""
102
+ )
103
+ if not target:
104
+ emit(True, "no file path in args")
105
+ root = repo_root()
106
+ try:
107
+ rel = str(Path(target).resolve().relative_to(root))
108
+ except ValueError:
109
+ emit(True, "target outside repo")
110
+ if any(rel.startswith(p) for p in EXEMPT_PREFIXES):
111
+ emit(True, f"exempt path: {rel}")
112
+ gate_label = f"edit of '{rel}'"
113
+
114
+ state = in_progress_task_state()
115
+ if state is None:
116
+ emit(True, "UAP task tracking not initialised — fail-open")
117
+ if state:
118
+ emit(True, "in_progress UAP task present")
119
+
120
+ emit(
121
+ False,
122
+ f"task-required: no in_progress UAP task — {gate_label} blocked. "
123
+ 'Run: uap task create --type <task|bug|feature> --title "<desc>" '
124
+ "then: uap task update <id> --status in_progress "
125
+ "(or: uap task claim <id> to also spin a worktree). "
126
+ "Override for one-off meta-work: UAP_NO_TASK=1.",
127
+ )
128
+
129
+
130
+ if __name__ == "__main__":
131
+ main()
@@ -0,0 +1,58 @@
1
+ #!/usr/bin/env python3
2
+ """test-gate enforcer: changed services under services|apps need test deltas."""
3
+ from __future__ import annotations
4
+ import re
5
+ import sys
6
+ from pathlib import Path
7
+
8
+ sys.path.insert(0, str(Path(__file__).parent))
9
+ from _common import emit, parse_cli, run, worktree_root # noqa: E402
10
+
11
+ PR_OPS_RE = re.compile(
12
+ r"\b(pr[-_ ]?ready|pr-create|gh pr create|signoff|ready[-_ ]for[-_ ]review|merge)\b",
13
+ re.I,
14
+ )
15
+ SVC_RE = re.compile(r"^(services|apps)/([^/]+)/")
16
+ TEST_RE = re.compile(
17
+ r"(/tests?/|__tests__/|\.test\.(ts|tsx|js|py)$|_test\.(py|go)$|\.spec\.(ts|tsx|js)$)"
18
+ )
19
+
20
+
21
+ def main() -> None:
22
+ op, args = parse_cli()
23
+ cmd = (args.get("command") or "").lower()
24
+ if not (PR_OPS_RE.search(op) or PR_OPS_RE.search(cmd)):
25
+ emit(True, "not a PR-ready gate point")
26
+
27
+ root = worktree_root() # git diff must run against the working tree, not MAIN_ROOT
28
+ rc, out, _ = run(
29
+ ["git", "diff", "--name-only", "origin/main...HEAD"], cwd=root, timeout=10
30
+ )
31
+ if rc != 0:
32
+ emit(True, "cannot compute diff vs origin/main")
33
+
34
+ changed = [l for l in out.splitlines() if l.strip()]
35
+ svcs_touched: set[str] = set()
36
+ for f in changed:
37
+ m = SVC_RE.match(f)
38
+ if m:
39
+ svcs_touched.add(f"{m.group(1)}/{m.group(2)}")
40
+
41
+ if not svcs_touched:
42
+ emit(True, "no services/apps changes in diff")
43
+
44
+ svcs_with_tests = {
45
+ s for s in svcs_touched if any(f.startswith(s) and TEST_RE.search(f) for f in changed)
46
+ }
47
+ missing = svcs_touched - svcs_with_tests
48
+ if missing:
49
+ emit(
50
+ False,
51
+ f"test-gate: the following services changed without test deltas: {', '.join(sorted(missing))}",
52
+ )
53
+
54
+ emit(True, "all changed services include test deltas")
55
+
56
+
57
+ if __name__ == "__main__":
58
+ main()
@@ -0,0 +1,75 @@
1
+ #!/usr/bin/env python3
2
+ """validate-plan-before-build enforcer.
3
+
4
+ On the first mutating tool call after a plan is marked ready, block and require
5
+ the agent to run the `validate the plan` prompt. State tracked in .uap/plan_state.json.
6
+ """
7
+ from __future__ import annotations
8
+ import json
9
+ import os
10
+ import sys
11
+ import time
12
+ from pathlib import Path
13
+
14
+ sys.path.insert(0, str(Path(__file__).parent))
15
+ from _common import emit, parse_cli # noqa: E402
16
+
17
+ STATE = Path(os.environ.get("UAP_STATE_DIR", ".uap")) / "plan_state.json"
18
+ MUTATING_OPS = {"Edit", "Write", "MultiEdit", "edit", "write", "multiedit"}
19
+ BUILD_BASH_RE = (
20
+ "git commit",
21
+ "git push",
22
+ "kubectl apply",
23
+ "helm upgrade",
24
+ "helm install",
25
+ "terraform apply",
26
+ "npm run build",
27
+ "pnpm build",
28
+ )
29
+
30
+
31
+ def load_state() -> dict:
32
+ if not STATE.exists():
33
+ return {}
34
+ try:
35
+ return json.loads(STATE.read_text())
36
+ except json.JSONDecodeError:
37
+ return {}
38
+
39
+
40
+ def save_state(s: dict) -> None:
41
+ STATE.parent.mkdir(parents=True, exist_ok=True)
42
+ STATE.write_text(json.dumps(s))
43
+
44
+
45
+ def main() -> None:
46
+ op, args = parse_cli()
47
+ state = load_state()
48
+
49
+ # Mutating?
50
+ cmd = (args.get("command") or "").lower()
51
+ mutating = op in MUTATING_OPS or any(p in cmd for p in BUILD_BASH_RE)
52
+ if not mutating:
53
+ emit(True, "not a build/mutation op")
54
+
55
+ plan_ready = bool(state.get("plan_ready"))
56
+ validated_at = float(state.get("validated_at", 0))
57
+ ready_at = float(state.get("ready_at", 0))
58
+
59
+ if not plan_ready:
60
+ emit(True, "no active plan-ready marker")
61
+
62
+ if validated_at and validated_at >= ready_at:
63
+ emit(True, "plan validated since marking ready")
64
+
65
+ emit(
66
+ False,
67
+ "validate-plan-before-build: plan is ready but not validated. "
68
+ "Run the prompt `validate the plan` before making changes. "
69
+ "After a pass, write {\"validated_at\": <epoch>} to .uap/plan_state.json.",
70
+ inject_prompt="validate the plan",
71
+ )
72
+
73
+
74
+ if __name__ == "__main__":
75
+ main()
@@ -0,0 +1,57 @@
1
+ #!/usr/bin/env python3
2
+ """worktree-required enforcer: Edit/Write must target a .worktrees/ path."""
3
+ from __future__ import annotations
4
+ import os
5
+ import sys
6
+ from pathlib import Path
7
+
8
+ sys.path.insert(0, str(Path(__file__).parent))
9
+ from _common import emit, parse_cli, repo_root # noqa: E402
10
+
11
+ EXEMPT_PREFIXES = (
12
+ ".claude/",
13
+ ".cursor/",
14
+ ".opencode/",
15
+ ".codex/",
16
+ ".forge/",
17
+ ".uap/",
18
+ "src/policies/",
19
+ "scripts/",
20
+ "docs/",
21
+ )
22
+ EDIT_OPS = {"Edit", "Write", "MultiEdit", "edit", "write", "multiedit"}
23
+
24
+
25
+ def main() -> None:
26
+ op, args = parse_cli()
27
+ if op not in EDIT_OPS:
28
+ emit(True, "not a file-edit operation")
29
+
30
+ target = args.get("file_path") or args.get("path") or args.get("target") or ""
31
+ if not target:
32
+ emit(True, "no file path in args")
33
+
34
+ root = repo_root()
35
+ try:
36
+ rel = str(Path(target).resolve().relative_to(root))
37
+ except ValueError:
38
+ emit(True, "target outside repo")
39
+
40
+ if rel.startswith(".worktrees/"):
41
+ emit(True, "target inside a worktree")
42
+
43
+ if any(rel.startswith(p) for p in EXEMPT_PREFIXES):
44
+ emit(True, f"exempt path: {rel}")
45
+
46
+ if os.environ.get("UAP_NO_WORKTREE") == "1":
47
+ emit(True, "UAP_NO_WORKTREE override set")
48
+
49
+ emit(
50
+ False,
51
+ f"worktree-required: '{rel}' must be edited inside .worktrees/NNN-<slug>/. "
52
+ "Run: uap worktree create <slug>",
53
+ )
54
+
55
+
56
+ if __name__ == "__main__":
57
+ main()
@@ -0,0 +1,51 @@
1
+ # architecture-review
2
+
3
+ **Category**: quality
4
+ **Level**: REQUIRED
5
+ **Enforcement Stage**: review
6
+ **Tags**: uap, architecture, review, adr, enforcement
7
+
8
+ ## Rule
9
+
10
+ When a PR-ready / merge operation is attempted and the diff vs. upstream touches
11
+ architecturally significant paths, the change MUST be accompanied by either an
12
+ ADR or an active waiver. Qualifying ("trigger") paths:
13
+
14
+ - `src/types/**`
15
+ - `**/schemas/**`
16
+ - `src/index.ts`
17
+ - `docs/architecture/**` (excluding `docs/architecture/adr/`)
18
+ - `src/coordination/capability-router.ts`, `src/coordination/pattern-router.ts`
19
+
20
+ The requirement is satisfied by either:
21
+
22
+ - an ADR under `docs/architecture/adr/*.md` added or modified in the same diff, or
23
+ - an active waiver `policies/waivers/*architecture-review*.md`.
24
+
25
+ Otherwise the ship/merge op is blocked.
26
+
27
+ ## Why
28
+
29
+ This policy backs the `architect-reviewer` droid's stated authority. The
30
+ enforcer already existed and ran, but had **no policy document** describing it —
31
+ agents and reviewers had no canonical reference for when architecture review is
32
+ required or how to satisfy it. Significant decisions (public types, schemas,
33
+ top-level exports, routing logic) carry high blast radius and cost of reversal;
34
+ requiring an ADR (or an explicit waiver) ensures they are recorded and reviewed
35
+ rather than slipping through in an unrelated change.
36
+
37
+ ## Enforcement
38
+
39
+ Python enforcer `architecture_review.py` fires on PR-ready/merge operations,
40
+ computes `git diff --name-only origin/master...HEAD` (falling back to
41
+ `origin/main`), matches the trigger paths, and blocks unless an ADR is present
42
+ in the diff or a matching waiver exists.
43
+
44
+ Fail-open: if the upstream diff cannot be computed, the operation is allowed.
45
+ Waivers are granted by `compliance-officer`.
46
+
47
+ ```rules
48
+ - title: "Architecturally significant diffs require an ADR or waiver before merge"
49
+ keywords: [merge, pr-ready, gh pr create, signoff, ready-for-review, src/types, schemas, src/index.ts]
50
+ antiPatterns: [no-adr, unreviewed-architecture, skip-architecture-review]
51
+ ```
@@ -0,0 +1,29 @@
1
+ # artifact-hygiene
2
+
3
+ **Category**: quality
4
+ **Level**: REQUIRED
5
+ **Enforcement Stage**: pre-exec
6
+ **Tags**: git, hygiene, artifacts
7
+
8
+ ## Rule
9
+
10
+ Binary artifacts (`*.png`, `*.jpg`, `*.pdf`, `*.zip`, `*.tar.gz`, `*.db`, `*.sqlite*`) MUST NOT be committed outside:
11
+
12
+ - `docs/**`
13
+ - `tests/**/__screenshots__/**`
14
+ - `apps/**/public/**`, `apps/**/static/**`, `apps/**/assets/**`
15
+ - `agents/data/memory/**` (scoped state)
16
+
17
+ ## Why
18
+
19
+ Repo root currently has 80+ loose audit PNGs, screenshots, and stale DBs — bloats the repo, confuses reviewers, breaks shallow clones. Keeping artifacts in curated subdirs preserves git performance.
20
+
21
+ ## Enforcement
22
+
23
+ Python enforcer `artifact_hygiene.py` inspects `git status` / new Write targets and rejects blocked paths.
24
+
25
+ ```rules
26
+ - title: "Binary artifacts belong in curated dirs"
27
+ keywords: [write, create-file, commit, git-add]
28
+ antiPatterns: [.png, .jpg, .zip, .tar.gz, .sqlite]
29
+ ```
@@ -0,0 +1,31 @@
1
+ # cluster-routing
2
+
3
+ **Category**: infrastructure
4
+ **Level**: REQUIRED
5
+ **Enforcement Stage**: pre-exec
6
+ **Tags**: kubernetes, istio, multi-cluster, iac
7
+
8
+ ## Rule
9
+
10
+ `kubectl apply|patch|create|edit|delete` and `helm install|upgrade|uninstall` MUST target the cluster context matching the component's domain:
11
+
12
+ - **Observability** (Grafana, Prometheus, OpenObserve, Fluent Bit, ServiceMonitor, alerts, dashboards) → `do-syd1-pay2u-openobserve`
13
+ - **Authentication / Identity** (Zitadel, OIDC, IAM CRDs) → `do-syd1-zitadel`
14
+ - **Everything else** (apps, APIs, CMS, web, ML services, PgDog, Redis, Postgres/CNPG) → `do-syd1-pay2u`
15
+
16
+ ## Why
17
+
18
+ AGENTS.md codifies the 3-cluster split. Cross-cluster mistakes cost 10–30 min per rollback plus reconciliation. Cross-cluster traffic MUST use public HTTPS URLs, never cluster-internal DNS.
19
+
20
+ ## Enforcement
21
+
22
+ Python enforcer `cluster_routing.py` checks `kubectl config current-context` against the manifest's domain before allowing the command.
23
+
24
+ ```rules
25
+ - title: "kubectl context must match component domain"
26
+ keywords: [kubectl, helm, apply, patch, install, upgrade]
27
+ antiPatterns: [wrong-context, cross-cluster-dns]
28
+ - title: "Cross-cluster calls must use public HTTPS"
29
+ keywords: [cross-cluster, service-mesh]
30
+ antiPatterns: [svc.cluster.local, internal-dns]
31
+ ```
@@ -0,0 +1,30 @@
1
+ # codebase-read-before-plan
2
+
3
+ **Category**: workflow
4
+ **Level**: REQUIRED
5
+ **Enforcement Stage**: pre-exec
6
+ **Tags**: planning, exploration, accuracy
7
+
8
+ ## Rule
9
+
10
+ Before emitting any implementation plan (plans with ≥2 steps or touching any code path), the agent MUST have read the relevant existing codebase in the same session:
11
+
12
+ - At least one `Read` of a file in the target service/app, OR
13
+ - At least one `Grep` / `Glob` over the target paths, OR
14
+ - A completed `Agent(subagent_type=Explore)` for the target domain
15
+
16
+ Plans produced without this evidence are rejected.
17
+
18
+ ## Why
19
+
20
+ Planning without reading generates drift-prone, hallucinated plans that conflict with existing conventions. User's directive: ground plans in the actual codebase first.
21
+
22
+ ## Enforcement
23
+
24
+ Python enforcer `codebase_read_before_plan.py` scans the recent tool-call log for read operations against files within the plan's declared scope; blocks plan emission if none found.
25
+
26
+ ```rules
27
+ - title: "Plans must follow codebase reads"
28
+ keywords: [plan, design, propose, architect, implement]
29
+ antiPatterns: [plan-without-read, unread-scope, blind-plan]
30
+ ```
@@ -0,0 +1,24 @@
1
+ # coord-overlap
2
+
3
+ **Category**: workflow
4
+ **Level**: RECOMMENDED
5
+ **Enforcement Stage**: pre-exec
6
+ **Tags**: agents, coordination, parallelism
7
+
8
+ ## Rule
9
+
10
+ Before spawning a second or subsequent Agent/sub-agent that will write files, call `uap coordination check <paths>` to detect overlap with in-flight agents.
11
+
12
+ ## Why
13
+
14
+ Multi-harness setup (.claude, .cursor, .opencode, .codex, .forge all present) creates collision risk. Overlap causes lost work and merge pain. `uap coordination check` is already available — unused.
15
+
16
+ ## Enforcement
17
+
18
+ Python enforcer `coord_overlap.py` queries `agents/data/coordination/coordination.db` for active reservations on the target paths and blocks if conflicts exist.
19
+
20
+ ```rules
21
+ - title: "Parallel agents require overlap check"
22
+ keywords: [agent, spawn, subagent, parallel, delegate]
23
+ antiPatterns: [skip-coord, no-reservation, overlap-ignore]
24
+ ```
@@ -0,0 +1,45 @@
1
+ # delivery-enforcement
2
+
3
+ **Category**: safety
4
+ **Level**: RECOMMENDED
5
+ **Enforcement Stage**: pre-exec
6
+ **Tags**: uap, delivery, deliver, convergence, enforcement
7
+
8
+ ## Rule
9
+
10
+ Substantive coding work SHOULD go through the `uap deliver` convergence loop,
11
+ which drives a model to verified completion against the project's real gates
12
+ (build, type-check, tests) rather than ad-hoc hand edits.
13
+
14
+ The enforcer fires on `Edit` / `Write` / `MultiEdit` operations targeting
15
+ source-code files. It is satisfied when any of the following holds:
16
+
17
+ - the edit runs inside a deliver-driven context (`UAP_DELIVER_ACTIVE=1`),
18
+ - an explicit operator override is set (`UAP_DELIVER_BYPASS=1`),
19
+ - the target is not source code, or is a docs/config/script/policy/test path.
20
+
21
+ Otherwise the policy applies.
22
+
23
+ ## Why
24
+
25
+ `uap deliver` exists and is auto-routable (CLI + MCP `deliver` tool), and it
26
+ classifies task complexity to enable the right convergence aids automatically.
27
+ But nothing previously *encouraged or required* coding agents to use it — the
28
+ capability was available, not enforced. This policy closes that gap: it makes
29
+ the expectation explicit and, when a team opts in, enforces it.
30
+
31
+ ## Enforcement
32
+
33
+ Python enforcer `delivery_enforcement.py`.
34
+
35
+ **Default mode is ADVISORY** — it always allows the edit and logs a one-line
36
+ nudge toward `uap deliver`. Installing the policy therefore never breaks normal
37
+ editing.
38
+
39
+ **Strict mode is opt-in** via `UAP_ENFORCE_DELIVERY=block`: a direct source
40
+ edit outside a deliver context is then blocked (exit 2) until the work is routed
41
+ through `uap deliver` or `UAP_DELIVER_BYPASS=1` is set.
42
+
43
+ Exempt by construction: non-source files; `docs/`, `scripts/`, `policies/`,
44
+ `src/policies/`, test files (deliver protects those itself); and tooling
45
+ dot-dirs (`.claude/`, `.uap/`, `.worktrees/`, …).
@@ -0,0 +1,32 @@
1
+ # doc-live-over-report
2
+
3
+ **Category**: quality
4
+ **Level**: REQUIRED
5
+ **Enforcement Stage**: pre-exec
6
+ **Tags**: docs, hygiene, debt
7
+
8
+ ## Rule
9
+
10
+ New files matching these patterns under `infra/**`, `docs/**`, or repo root are BLOCKED:
11
+
12
+ - `*_REPORT.md`
13
+ - `*_COMPLETE.md`
14
+ - `*_SUMMARY.md`
15
+ - `*_FIX_<date>.md`, `*_<YYYY-MM-DD>.md`
16
+ - `*_PLAN.md` (use tasks, not doc files)
17
+
18
+ Agents MUST update canonical README.md / runbooks instead.
19
+
20
+ ## Why
21
+
22
+ The repo contains ~30 retrospective markdown reports under `infra/` — they rot, nobody reads them, and they bury live docs. The user's global rule: truth lives in code + canonical docs, not dated reports.
23
+
24
+ ## Enforcement
25
+
26
+ Python enforcer `doc_live_over_report.py` inspects the target path of `Write` operations and rejects matching filenames.
27
+
28
+ ```rules
29
+ - title: "No dated retrospective doc files"
30
+ keywords: [write, create-file, markdown]
31
+ antiPatterns: [_REPORT.md, _COMPLETE.md, _SUMMARY.md, _PLAN.md, _FIX_]
32
+ ```
@@ -0,0 +1,60 @@
1
+ # expert-review-required
2
+
3
+ **Category**: quality
4
+ **Level**: REQUIRED
5
+ **Enforcement Stage**: review
6
+ **Tags**: uap, review, quality, enforcement, parallel-expert-review
7
+
8
+ ## Rule
9
+
10
+ A parallel expert review MUST precede shipping a non-trivial change. When no
11
+ review artifact exists for the current branch (or the artifact is stale relative
12
+ to `HEAD`), the enforcer blocks the ship actions:
13
+
14
+ - `git commit`, `git push`
15
+ - `gh pr create`
16
+ - merge / pr-ready / signoff / ready-for-review operations
17
+
18
+ Review artifact: `.uap/reviews/<branch-slug>.json`, written by the
19
+ `parallel-expert-review` skill on consolidation. The slug is an **injective
20
+ percent-encoding** of the branch name (`%`→`%25`, `/`→`%2F`) so distinct refs
21
+ like `feature/foo` and `feature-foo` never collide on one artifact. Recognised
22
+ shape:
23
+
24
+ ```json
25
+ { "branch": "<name>", "head": "<sha>", "verdict": "approve", "reviewers": ["code-quality-reviewer", "security-code-reviewer", "..."] }
26
+ ```
27
+
28
+ If the artifact records a `branch` that differs from the current branch, or a
29
+ `head` that differs from the current `HEAD`, the review is rejected (mismatch /
30
+ stale) and the op is blocked until a fresh review is recorded. Including
31
+ `branch` and `head` is strongly recommended so the artifact unambiguously
32
+ identifies what it covers.
33
+
34
+ ## Why
35
+
36
+ The `parallel-expert-review` skill (and the `architect-reviewer` droid) claim
37
+ review is "REQUIRED by policy", but no enforcer ever checked that a review
38
+ actually ran — the requirement was advisory and silently skippable. This policy
39
+ makes review a hard, artifact-backed gate: ship actions fail until the review
40
+ fan-out (code-quality, security, performance, documentation, test-coverage) has
41
+ run and its consolidated verdict is recorded for the current HEAD.
42
+
43
+ This is the review analogue of `task-required` and `worktree-required`: convert
44
+ a protocol step that was best-effort into an enforced precondition.
45
+
46
+ ## Enforcement
47
+
48
+ Python enforcer `expert_review_required.py` resolves the current branch and
49
+ HEAD via git, then checks `.uap/reviews/<branch-slug>.json` (slug = branch name
50
+ with `/` → `-`). Missing artifact → block; present but `head` mismatch → block
51
+ (stale); present and current → allow.
52
+
53
+ Fail-open: if the branch/HEAD cannot be resolved (detached HEAD, non-git tree),
54
+ the operation is allowed. Override for one-off meta-work: `UAP_NO_REVIEW=1`.
55
+
56
+ ```rules
57
+ - title: "A parallel expert review must precede ship"
58
+ keywords: [git commit, git push, gh pr create, merge, pr-ready, signoff, ready-for-review]
59
+ antiPatterns: [no-review, unreviewed-ship, skip-review]
60
+ ```
@@ -0,0 +1,31 @@
1
+ # iac-parity
2
+
3
+ **Category**: infrastructure
4
+ **Level**: REQUIRED
5
+ **Enforcement Stage**: pre-exec
6
+ **Tags**: terraform, helm, iac, drift, reproducibility
7
+
8
+ ## Rule
9
+
10
+ Any live-state change MUST be paired with an IaC change in the same worktree:
11
+
12
+ - `kubectl patch|apply|edit|create|delete` → must also modify `infra/terraform/**`, `infra/helm_charts/**`, or `infra/kubernetes/**`
13
+ - Helm `--set` overrides → must also update `values.yaml`
14
+ - DigitalOcean / cloud console changes are forbidden; use Terraform
15
+
16
+ ## Why
17
+
18
+ User's global rule: "always apply state changes to IaC to ensure reproducibility." The repo has ~30 `IAC_PARITY_*`/`DRIFT_ANALYSIS_*` retrospectives — each a drift incident. Catching at author-time eliminates the loop.
19
+
20
+ ## Enforcement
21
+
22
+ Python enforcer `iac_parity.py` verifies the worktree has staged/unstaged diffs under the IaC paths when a mutating cluster command is issued.
23
+
24
+ ```rules
25
+ - title: "Live state changes require IaC diff"
26
+ keywords: [kubectl, helm, doctl, terraform, aws, gcloud, apply, patch, create, delete, edit]
27
+ antiPatterns: [--force, --no-iac, manual-console]
28
+ - title: "No ad-hoc cloud console changes"
29
+ keywords: [doctl, aws, gcloud, console]
30
+ antiPatterns: [click-ops, manual-edit]
31
+ ```