guardian-framework 0.1.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 (216) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +463 -0
  3. package/dist/cli.js +12958 -0
  4. package/dist/exports.js +12765 -0
  5. package/package.json +61 -0
  6. package/templates/languages/go-patterns.md +411 -0
  7. package/templates/languages/java-patterns.md +545 -0
  8. package/templates/languages/python-patterns.md +312 -0
  9. package/templates/languages/rust-patterns.md +232 -0
  10. package/templates/languages/typescript-patterns.md +313 -0
  11. package/templates/pi/INDEX.md +437 -0
  12. package/templates/pi/agent/AGENTS.md +166 -0
  13. package/templates/pi/agents/architecture-coordinator.md +40 -0
  14. package/templates/pi/agents/architecture-validator.md +36 -0
  15. package/templates/pi/agents/bootstrap-implementer.md +37 -0
  16. package/templates/pi/agents/issue-factory.md +31 -0
  17. package/templates/pi/agents/operations-validator.md +32 -0
  18. package/templates/pi/agents/security-validator.md +33 -0
  19. package/templates/pi/architecture/CHANGELOG.md +78 -0
  20. package/templates/pi/architecture/decisions/ADR-template.md +76 -0
  21. package/templates/pi/architecture/diagrams/system-overview.md +159 -0
  22. package/templates/pi/architecture/modules/module-template.md +152 -0
  23. package/templates/pi/context/checklists.md +91 -0
  24. package/templates/pi/context/domain-workflow.md +180 -0
  25. package/templates/pi/context/output-formats.md +135 -0
  26. package/templates/pi/context/patterns-base.md +47 -0
  27. package/templates/pi/context/patterns.md +38 -0
  28. package/templates/pi/context/project.md +88 -0
  29. package/templates/pi/domain/exploration.md +93 -0
  30. package/templates/pi/domain/ubiquitous-language.md +24 -0
  31. package/templates/pi/extensions/architect-lib/generators.ts +528 -0
  32. package/templates/pi/extensions/architect-lib/helpers.ts +344 -0
  33. package/templates/pi/extensions/architect-lib/types.ts +117 -0
  34. package/templates/pi/extensions/architect.ts +1425 -0
  35. package/templates/pi/extensions/ask-user-question.ts +579 -0
  36. package/templates/pi/extensions/bash-guard.ts +556 -0
  37. package/templates/pi/extensions/config-reload.ts +115 -0
  38. package/templates/pi/extensions/coordinator.ts +304 -0
  39. package/templates/pi/extensions/curator.ts +543 -0
  40. package/templates/pi/extensions/domain-explorer.ts +990 -0
  41. package/templates/pi/extensions/filechanges.ts +656 -0
  42. package/templates/pi/extensions/goal-loop.ts +717 -0
  43. package/templates/pi/extensions/hooks.ts +452 -0
  44. package/templates/pi/extensions/kanban.ts +547 -0
  45. package/templates/pi/extensions/pipeline.ts +1246 -0
  46. package/templates/pi/extensions/plan-mode.ts +209 -0
  47. package/templates/pi/extensions/project-scaffolder.ts +284 -0
  48. package/templates/pi/extensions/read-only-mode.ts +192 -0
  49. package/templates/pi/extensions/redaction.ts +128 -0
  50. package/templates/pi/extensions/session-persistence.ts +174 -0
  51. package/templates/pi/extensions/slash-commands.ts +229 -0
  52. package/templates/pi/extensions/snippets.ts +201 -0
  53. package/templates/pi/extensions/validation-runner.ts +100 -0
  54. package/templates/pi/github/agents/architecture-coordinator.agent.md +27 -0
  55. package/templates/pi/github/agents/architecture-validator.agent.md +20 -0
  56. package/templates/pi/github/agents/bootstrap-implementer.agent.md +20 -0
  57. package/templates/pi/github/agents/epic-planner.agent.md +70 -0
  58. package/templates/pi/github/agents/issue-factory.agent.md +20 -0
  59. package/templates/pi/github/agents/operations-validator.agent.md +20 -0
  60. package/templates/pi/github/agents/security-validator.agent.md +20 -0
  61. package/templates/pi/github/copilot/settings.json +16 -0
  62. package/templates/pi/github/copilot-instructions.md +155 -0
  63. package/templates/pi/github/instructions/architecture.instructions.md +71 -0
  64. package/templates/pi/github/instructions/validation.instructions.md +69 -0
  65. package/templates/pi/github/workflows/01-planning-workflow.md +75 -0
  66. package/templates/pi/github/workflows/02-issue-generation-workflow.md +69 -0
  67. package/templates/pi/github/workflows/03-implementation-workflow.md +80 -0
  68. package/templates/pi/github/workflows/04-validation-workflow.md +68 -0
  69. package/templates/pi/preflight_report.json +99 -0
  70. package/templates/pi/prompts/blueprint-update.md +262 -0
  71. package/templates/pi/prompts/blueprint-validate.md +218 -0
  72. package/templates/pi/prompts/bug-fix.md +50 -0
  73. package/templates/pi/prompts/ci-blueprint.md +131 -0
  74. package/templates/pi/prompts/context-refresh.md +258 -0
  75. package/templates/pi/prompts/epic-plan.md +356 -0
  76. package/templates/pi/prompts/epic-template.md +186 -0
  77. package/templates/pi/prompts/feature-development.md +131 -0
  78. package/templates/pi/prompts/git-issues.md +243 -0
  79. package/templates/pi/prompts/hotfix.md +71 -0
  80. package/templates/pi/prompts/issue-closeout.md +342 -0
  81. package/templates/pi/prompts/issue-draft.md +218 -0
  82. package/templates/pi/prompts/issue-implementation-series.md +173 -0
  83. package/templates/pi/prompts/issue-merge.md +372 -0
  84. package/templates/pi/prompts/issue-template-set.md +392 -0
  85. package/templates/pi/prompts/issue-template.md +207 -0
  86. package/templates/pi/prompts/pattern-extract.md +269 -0
  87. package/templates/pi/prompts/plan-to-issues.md +430 -0
  88. package/templates/pi/prompts/refactoring.md +82 -0
  89. package/templates/pi/prompts/scope-analyzer.md +254 -0
  90. package/templates/pi/prompts/sync-check.md +230 -0
  91. package/templates/pi/scripts/categorize-issues.sh +171 -0
  92. package/templates/pi/scripts/ci/check_architecture_conformance.sh +748 -0
  93. package/templates/pi/scripts/ci/check_planning_packet.py +228 -0
  94. package/templates/pi/scripts/ci/run_hardening_stages.sh +264 -0
  95. package/templates/pi/scripts/ci/run_preflight.sh +649 -0
  96. package/templates/pi/scripts/ci/run_stage.sh +193 -0
  97. package/templates/pi/scripts/ci/stage_docs_policy.sh +82 -0
  98. package/templates/pi/scripts/ci/stage_integration.sh +3 -0
  99. package/templates/pi/scripts/ci/stage_lint.sh +130 -0
  100. package/templates/pi/scripts/ci/stage_migration_verify.sh +3 -0
  101. package/templates/pi/scripts/ci/stage_package_build.sh +3 -0
  102. package/templates/pi/scripts/ci/stage_release_readiness.sh +3 -0
  103. package/templates/pi/scripts/ci/stage_remaining.sh +242 -0
  104. package/templates/pi/scripts/ci/stage_security.sh +3 -0
  105. package/templates/pi/scripts/ci/stage_static_analysis.sh +114 -0
  106. package/templates/pi/scripts/ci/stage_unit.sh +119 -0
  107. package/templates/pi/scripts/ci/validate_agent_output.py +181 -0
  108. package/templates/pi/scripts/ci/validate_agent_output.sh +243 -0
  109. package/templates/pi/scripts/create-feature-branch.sh +136 -0
  110. package/templates/pi/scripts/create-mr.sh +117 -0
  111. package/templates/pi/scripts/fetch-issues.sh +131 -0
  112. package/templates/pi/scripts/generate-architecture.sh +161 -0
  113. package/templates/pi/scripts/git/close-epic.sh +69 -0
  114. package/templates/pi/scripts/git/close-issue.sh +35 -0
  115. package/templates/pi/scripts/git/create-tracking-issue.sh +174 -0
  116. package/templates/pi/scripts/git/link-issue-to-epic.sh +51 -0
  117. package/templates/pi/scripts/git/update-tracking-issue.sh +66 -0
  118. package/templates/pi/scripts/languages/go/validate-architecture.sh +139 -0
  119. package/templates/pi/scripts/languages/go/validate-canonical.sh +129 -0
  120. package/templates/pi/scripts/languages/go/validate-ci.sh +132 -0
  121. package/templates/pi/scripts/languages/go/validate-integration.sh +156 -0
  122. package/templates/pi/scripts/languages/go/validate-operations.sh +146 -0
  123. package/templates/pi/scripts/languages/go/validate-security.sh +135 -0
  124. package/templates/pi/scripts/languages/go/validate-tests.sh +125 -0
  125. package/templates/pi/scripts/languages/java/validate-annotations.sh +185 -0
  126. package/templates/pi/scripts/languages/java/validate-architecture.sh +159 -0
  127. package/templates/pi/scripts/languages/java/validate-canonical.sh +114 -0
  128. package/templates/pi/scripts/languages/java/validate-ci.sh +269 -0
  129. package/templates/pi/scripts/languages/java/validate-integration.sh +149 -0
  130. package/templates/pi/scripts/languages/java/validate-operations.sh +142 -0
  131. package/templates/pi/scripts/languages/java/validate-security.sh +174 -0
  132. package/templates/pi/scripts/languages/java/validate-spring-architecture.sh +227 -0
  133. package/templates/pi/scripts/languages/java/validate-tests.sh +159 -0
  134. package/templates/pi/scripts/languages/python/validate-architecture.sh +99 -0
  135. package/templates/pi/scripts/languages/python/validate-canonical.sh +124 -0
  136. package/templates/pi/scripts/languages/python/validate-ci.sh +130 -0
  137. package/templates/pi/scripts/languages/python/validate-integration.sh +119 -0
  138. package/templates/pi/scripts/languages/python/validate-operations.sh +107 -0
  139. package/templates/pi/scripts/languages/python/validate-security.sh +68 -0
  140. package/templates/pi/scripts/languages/python/validate-tests.sh +102 -0
  141. package/templates/pi/scripts/languages/rust/validate-architecture.sh +188 -0
  142. package/templates/pi/scripts/languages/rust/validate-canonical.sh +146 -0
  143. package/templates/pi/scripts/languages/rust/validate-ci.sh +147 -0
  144. package/templates/pi/scripts/languages/rust/validate-integration.sh +149 -0
  145. package/templates/pi/scripts/languages/rust/validate-operations.sh +154 -0
  146. package/templates/pi/scripts/languages/rust/validate-security.sh +153 -0
  147. package/templates/pi/scripts/languages/rust/validate-tests.sh +150 -0
  148. package/templates/pi/scripts/languages/typescript/validate-architecture.sh +157 -0
  149. package/templates/pi/scripts/languages/typescript/validate-canonical.sh +135 -0
  150. package/templates/pi/scripts/languages/typescript/validate-ci.sh +244 -0
  151. package/templates/pi/scripts/languages/typescript/validate-integration.sh +166 -0
  152. package/templates/pi/scripts/languages/typescript/validate-operations.sh +162 -0
  153. package/templates/pi/scripts/languages/typescript/validate-security.sh +169 -0
  154. package/templates/pi/scripts/languages/typescript/validate-tests.sh +158 -0
  155. package/templates/pi/scripts/merge-mr.sh +95 -0
  156. package/templates/pi/scripts/mr-validation.sh +228 -0
  157. package/templates/pi/scripts/validate-architecture-readiness.sh +153 -0
  158. package/templates/pi/scripts/validate-architecture.sh +22 -0
  159. package/templates/pi/scripts/validate-canonical.sh +22 -0
  160. package/templates/pi/scripts/validate-ci.sh +37 -0
  161. package/templates/pi/scripts/validate-integration.sh +22 -0
  162. package/templates/pi/scripts/validate-operations.sh +22 -0
  163. package/templates/pi/scripts/validate-security.sh +22 -0
  164. package/templates/pi/scripts/validate-tests.sh +22 -0
  165. package/templates/pi/scripts/validate-ubiquitous-language.sh +291 -0
  166. package/templates/pi/scripts/validation-cache.sh +139 -0
  167. package/templates/pi/skills/agents/architecture-coordinator.md +178 -0
  168. package/templates/pi/skills/agents/architecture-generator.md +79 -0
  169. package/templates/pi/skills/agents/architecture-validator.md +74 -0
  170. package/templates/pi/skills/agents/ci-mr-validator.md +46 -0
  171. package/templates/pi/skills/agents/code-developer.md +76 -0
  172. package/templates/pi/skills/agents/commit.md +46 -0
  173. package/templates/pi/skills/agents/curator.md +71 -0
  174. package/templates/pi/skills/agents/debug.md +59 -0
  175. package/templates/pi/skills/agents/documentation-maintainer.md +36 -0
  176. package/templates/pi/skills/agents/goal-loop.md +125 -0
  177. package/templates/pi/skills/agents/hooks.md +122 -0
  178. package/templates/pi/skills/agents/integration-validator.md +35 -0
  179. package/templates/pi/skills/agents/issue-creator.md +75 -0
  180. package/templates/pi/skills/agents/issue-factory.md +143 -0
  181. package/templates/pi/skills/agents/kanban.md +85 -0
  182. package/templates/pi/skills/agents/land.md +59 -0
  183. package/templates/pi/skills/agents/operations-validator.md +43 -0
  184. package/templates/pi/skills/agents/pipeline.md +113 -0
  185. package/templates/pi/skills/agents/plan-mode.md +77 -0
  186. package/templates/pi/skills/agents/pull.md +40 -0
  187. package/templates/pi/skills/agents/push.md +41 -0
  188. package/templates/pi/skills/agents/security-validator.md +85 -0
  189. package/templates/pi/skills/agents/session-persistence.md +119 -0
  190. package/templates/pi/skills/agents/slash-commands.md +117 -0
  191. package/templates/pi/skills/agents/snippets.md +99 -0
  192. package/templates/pi/skills/agents/subagent-registry.md +78 -0
  193. package/templates/pi/skills/agents/test-validator.md +42 -0
  194. package/templates/pi/skills/validators/architecture-validator.md +43 -0
  195. package/templates/pi/skills/validators/ci-validator.md +27 -0
  196. package/templates/pi/skills/validators/context-compaction.md +73 -0
  197. package/templates/pi/skills/validators/integration-validator.md +38 -0
  198. package/templates/pi/skills/validators/model-registry.md +96 -0
  199. package/templates/pi/skills/validators/operations-validator.md +34 -0
  200. package/templates/pi/skills/validators/security-guards.md +72 -0
  201. package/templates/pi/skills/validators/security-validator.md +41 -0
  202. package/templates/pi/skills/validators/system-prompt-tiers.md +69 -0
  203. package/templates/pi/skills/validators/test-validator.md +33 -0
  204. package/templates/pi/types.ts +62 -0
  205. package/templates/pi/validators/README.md +93 -0
  206. package/templates/pi/validators/default.toml +209 -0
  207. package/templates/pi/validators/spring.toml +142 -0
  208. package/templates/pi/workpad.md +53 -0
  209. package/templates/project/java/Dockerfile +14 -0
  210. package/templates/project/java/README.md +40 -0
  211. package/templates/project/java/pom.xml +132 -0
  212. package/templates/project/typescript/Dockerfile +15 -0
  213. package/templates/project/typescript/README.md +29 -0
  214. package/templates/project/typescript/package.json +23 -0
  215. package/templates/project/typescript/tsconfig.json +21 -0
  216. package/templates/workflow.md +123 -0
@@ -0,0 +1,114 @@
1
+ #!/usr/bin/env bash
2
+ # Stage 4: Static Analysis
3
+ #
4
+ # Verifies:
5
+ # - Type checking (mypy/tsc/cargo check/go vet)
6
+ # - Import boundary checks
7
+ # - Architecture sanity checks
8
+ # - Settings/env collision checks
9
+
10
+ set -euo pipefail
11
+
12
+ FAIL=0
13
+ PASS=0
14
+
15
+ log_pass() { echo " ✓ PASS: $1"; ((PASS++)); }
16
+ log_fail() { echo " ✗ FAIL: $1 — $2"; ((FAIL++)); }
17
+
18
+ echo " Running static analysis..."
19
+
20
+ # Type checking
21
+ echo " Type checking..."
22
+ if command -v mypy &>/dev/null && [[ -d "app" ]]; then
23
+ if mypy app --ignore-missing-imports 2>/dev/null; then
24
+ log_pass "mypy type check"
25
+ else
26
+ log_fail "mypy type check" "Type errors found"
27
+ fi
28
+ elif command -v tsc &>/dev/null && [[ -f "tsconfig.json" ]]; then
29
+ if tsc --noEmit 2>/dev/null; then
30
+ log_pass "tsc type check"
31
+ else
32
+ log_fail "tsc type check" "Type errors found"
33
+ fi
34
+ elif command -v cargo &>/dev/null && [[ -f "Cargo.toml" ]]; then
35
+ if cargo check 2>/dev/null; then
36
+ log_pass "cargo check"
37
+ else
38
+ log_fail "cargo check" "Compilation errors"
39
+ fi
40
+ elif command -v go &>/dev/null && [[ -f "go.mod" ]]; then
41
+ if go vet ./... 2>/dev/null; then
42
+ log_pass "go vet"
43
+ else
44
+ log_fail "go vet" "Vet errors found"
45
+ fi
46
+ else
47
+ echo " No type checker found, skipping."
48
+ fi
49
+
50
+ # Import boundary checks
51
+ echo " Checking import boundaries..."
52
+ if [[ -f ".pi/scripts/ci/check_import_boundaries.py" ]]; then
53
+ if python3 ".pi/scripts/ci/check_import_boundaries.py" 2>/dev/null; then
54
+ log_pass "import boundary check"
55
+ else
56
+ log_fail "import boundary check" "Boundary violations found"
57
+ fi
58
+ else
59
+ # Basic check: no domain→infrastructure imports
60
+ violations=0
61
+ if [[ -d "app/domain" ]]; then
62
+ while IFS= read -r file; do
63
+ if grep -qE "from.*infrastructure|from.*api|import.*infrastructure" "$file" 2>/dev/null; then
64
+ ((violations++))
65
+ log_fail "import boundary" "$(basename "$file") imports from infrastructure/api"
66
+ fi
67
+ done < <(find app/domain -name "*.py" 2>/dev/null)
68
+ fi
69
+ if [[ $violations -eq 0 ]]; then
70
+ log_pass "import boundary check (no cross-layer violations)"
71
+ fi
72
+ fi
73
+
74
+ # Architecture sanity
75
+ echo " Running architecture sanity checks..."
76
+ if [[ -f ".pi/scripts/ci/check_arch_sanity.py" ]]; then
77
+ if python3 ".pi/scripts/ci/check_arch_sanity.py" 2>/dev/null; then
78
+ log_pass "architecture sanity"
79
+ else
80
+ log_fail "architecture sanity" "Sanity checks failed"
81
+ fi
82
+ else
83
+ log_pass "architecture sanity (no script found, skipping)"
84
+ fi
85
+
86
+ # Settings/env collision
87
+ echo " Checking settings/env collision..."
88
+ if [[ -f ".env.example" && -f ".env" ]]; then
89
+ collisions=0
90
+ while IFS= read -r line; do
91
+ var_name=$(echo "$line" | cut -d= -f1)
92
+ if [[ -n "$var_name" && "$var_name" != \#* ]]; then
93
+ example_val=$(grep "^${var_name}=" ".env.example" 2>/dev/null | cut -d= -f2-)
94
+ actual_val=$(grep "^${var_name}=" ".env" 2>/dev/null | cut -d= -f2-)
95
+ if [[ "$example_val" == "$actual_val" && -n "$example_val" ]]; then
96
+ ((collisions++))
97
+ log_fail "env collision" "${var_name} in .env matches .env.example value"
98
+ fi
99
+ fi
100
+ done < <(grep -v "^#" ".env.example" 2>/dev/null | grep "=" || true)
101
+ if [[ $collisions -eq 0 ]]; then
102
+ log_pass "settings/env collision check (no collisions)"
103
+ fi
104
+ else
105
+ log_pass "settings/env collision check (no .env files)"
106
+ fi
107
+
108
+ if [[ $FAIL -gt 0 ]]; then
109
+ echo " Static analysis FAILED (${FAIL} failure(s))"
110
+ exit 1
111
+ fi
112
+
113
+ echo " Static analysis passed (${PASS} check(s))"
114
+ exit 0
@@ -0,0 +1,119 @@
1
+ #!/usr/bin/env bash
2
+ # Stage 5: Unit Tests
3
+ #
4
+ # Verifies:
5
+ # - Domain tests
6
+ # - Application tests
7
+ # - Contract tests
8
+ # - Verification tests
9
+ # - Coverage threshold check
10
+
11
+ set -euo pipefail
12
+
13
+ FAIL=0
14
+ PASS=0
15
+ COVERAGE_PCT=0
16
+
17
+ log_pass() { echo " ✓ PASS: $1"; ((PASS++)); }
18
+ log_fail() { echo " ✗ FAIL: $1 — $2"; ((FAIL++)); }
19
+
20
+ echo " Running unit tests..."
21
+
22
+ if command -v pytest &>/dev/null; then
23
+ # Domain tests
24
+ if [[ -d "tests/unit/domain" ]]; then
25
+ if pytest tests/unit/domain -v 2>/dev/null; then
26
+ log_pass "unit: domain tests"
27
+ else
28
+ log_fail "unit: domain tests" "Domain test failures"
29
+ fi
30
+ else
31
+ log_pass "unit: domain tests (no domain tests found)"
32
+ fi
33
+
34
+ # Application tests
35
+ if [[ -d "tests/unit/application" ]]; then
36
+ if pytest tests/unit/application -v 2>/dev/null; then
37
+ log_pass "unit: application tests"
38
+ else
39
+ log_fail "unit: application tests" "Application test failures"
40
+ fi
41
+ else
42
+ log_pass "unit: application tests (no application tests found)"
43
+ fi
44
+
45
+ # Contract tests
46
+ if [[ -d "tests/contract" ]]; then
47
+ if pytest tests/contract -v 2>/dev/null; then
48
+ log_pass "unit: contract tests"
49
+ else
50
+ log_fail "unit: contract tests" "Contract test failures"
51
+ fi
52
+ else
53
+ log_pass "unit: contract tests (no contract tests found)"
54
+ fi
55
+
56
+ # Verification tests
57
+ if [[ -d "tests/verification" ]]; then
58
+ if pytest tests/verification -v 2>/dev/null; then
59
+ log_pass "unit: verification tests"
60
+ else
61
+ log_fail "unit: verification tests" "Verification test failures"
62
+ fi
63
+ else
64
+ log_pass "unit: verification tests (no verification tests found)"
65
+ fi
66
+
67
+ # Coverage threshold check
68
+ echo " Checking coverage threshold..."
69
+ if [[ -f ".pi/scripts/ci/check_coverage_thresholds.py" ]]; then
70
+ if python3 ".pi/scripts/ci/check_coverage_thresholds.py" 2>/dev/null; then
71
+ log_pass "coverage threshold check"
72
+ else
73
+ log_fail "coverage threshold check" "Coverage below threshold"
74
+ fi
75
+ else
76
+ # Basic coverage check
77
+ coverage_file="coverage.xml"
78
+ if [[ -f "$coverage_file" ]]; then
79
+ COVERAGE_PCT=$(grep -oP 'line-rate="[^"]*"' "$coverage_file" 2>/dev/null | head -1 | cut -d'"' -f2 || echo "0")
80
+ threshold="${COVERAGE_THRESHOLD:-80}"
81
+ COVERAGE_INT=$(echo "$COVERAGE_PCT * 100" | bc 2>/dev/null || echo "0")
82
+ if [[ $COVERAGE_INT -ge $threshold ]]; then
83
+ log_pass "coverage threshold (${COVERAGE_PCT} >= ${threshold}%)"
84
+ else
85
+ log_fail "coverage threshold" "${COVERAGE_PCT} < ${threshold}%"
86
+ fi
87
+ else
88
+ log_pass "coverage threshold check (no coverage file found)"
89
+ fi
90
+ fi
91
+ elif command -v bun &>/dev/null && [[ -f "package.json" ]]; then
92
+ if bun test 2>/dev/null; then
93
+ log_pass "unit: all tests (bun)"
94
+ else
95
+ log_fail "unit: all tests (bun)" "Test failures"
96
+ fi
97
+ elif command -v cargo &>/dev/null && [[ -f "Cargo.toml" ]]; then
98
+ if cargo test 2>/dev/null; then
99
+ log_pass "unit: all tests (cargo)"
100
+ else
101
+ log_fail "unit: all tests (cargo)" "Test failures"
102
+ fi
103
+ elif command -v go &>/dev/null && [[ -f "go.mod" ]]; then
104
+ if go test ./... 2>/dev/null; then
105
+ log_pass "unit: all tests (go)"
106
+ else
107
+ log_fail "unit: all tests (go)" "Test failures"
108
+ fi
109
+ else
110
+ echo " No test runner found, skipping unit tests."
111
+ fi
112
+
113
+ if [[ $FAIL -gt 0 ]]; then
114
+ echo " Unit test stage FAILED (${FAIL} failure(s))"
115
+ exit 1
116
+ fi
117
+
118
+ echo " Unit test stage passed (${PASS} check(s))"
119
+ exit 0
@@ -0,0 +1,181 @@
1
+ #!/usr/bin/env python3
2
+ """Validate agent output schema compliance.
3
+
4
+ Validates that agent-generated outputs conform to expected schemas per agent role.
5
+ Checks required sections, contradiction patterns, and structural consistency.
6
+
7
+ Usage:
8
+ python scripts/ci/validate_agent_output.py --input=output.md
9
+ python scripts/ci/validate_agent_output.py --input=output.md --schema=architecture-validator
10
+ python scripts/ci/validate_agent_output.py --input=output.md --json
11
+
12
+ Exit codes:
13
+ 0 - Output is valid
14
+ 1 - Validation errors found
15
+ 2 - Script error
16
+ """
17
+
18
+ from __future__ import annotations
19
+
20
+ import argparse
21
+ import json
22
+ import re
23
+ import sys
24
+ from pathlib import Path
25
+
26
+
27
+ SCHEMAS: dict[str, dict] = {
28
+ "architecture-validator": {
29
+ "required_sections": [
30
+ "## Decision",
31
+ "## Blocking findings",
32
+ "## Non-blocking recommendations",
33
+ "## Section reference verification",
34
+ "## Acceptance criteria verification",
35
+ ],
36
+ "contradiction_checks": [
37
+ {
38
+ "pattern1": r"## Decision\s*\n\s*-\s*`?pass`?",
39
+ "pattern2": r"## Non-blocking recommendations\s*\n\s*-",
40
+ "message": "Decision is 'pass' but recommendations exist (should be 'pass_with_recommendations')",
41
+ },
42
+ ],
43
+ },
44
+ "epic-plan": {
45
+ "required_sections": [
46
+ "## Stream classification",
47
+ "## Scope summary",
48
+ "## In scope",
49
+ "## Out of scope",
50
+ "## Impacted layers",
51
+ "## Risk classification",
52
+ "## Dependency graph",
53
+ "## Mandatory validators",
54
+ "## Mandatory CI gates",
55
+ "## Forbidden shortcuts",
56
+ "## First implementation issue recommendation",
57
+ ],
58
+ "contradiction_checks": [],
59
+ },
60
+ "issue-draft": {
61
+ "required_sections": [
62
+ "## Why",
63
+ "## Scope",
64
+ "## In scope",
65
+ "## Out of scope",
66
+ "## Dependencies",
67
+ "## Acceptance criteria",
68
+ "## Verification",
69
+ "## Canonical references",
70
+ ],
71
+ "contradiction_checks": [],
72
+ },
73
+ "implementation-report": {
74
+ "required_sections": [
75
+ "## Readiness check",
76
+ "## Acceptance criteria trace map",
77
+ "## Files changed",
78
+ "## Tests and CI impacts",
79
+ "## Toolchain validation",
80
+ "## Done / not done against acceptance criteria",
81
+ ],
82
+ "contradiction_checks": [],
83
+ },
84
+ "generic": {
85
+ "required_sections": ["## Summary"],
86
+ "contradiction_checks": [],
87
+ },
88
+ }
89
+
90
+
91
+ def extract_section(content: str, heading: str) -> str:
92
+ pattern = re.compile(rf"^{re.escape(heading)}\s*$", re.MULTILINE)
93
+ match = pattern.search(content)
94
+ if not match:
95
+ return ""
96
+ start = match.end()
97
+ next_heading = re.search(r"^##\s+", content[start:], re.MULTILINE)
98
+ end = start + next_heading.start() if next_heading else len(content)
99
+ return content[start:end].strip()
100
+
101
+
102
+ def check_contradictions(content: str, checks: list[dict]) -> list[dict]:
103
+ results: list[dict] = []
104
+ for check in checks:
105
+ has_p1 = bool(re.search(check["pattern1"], content, re.MULTILINE))
106
+ has_p2 = bool(re.search(check["pattern2"], content, re.MULTILINE))
107
+ if has_p1 and has_p2:
108
+ results.append({
109
+ "check": "contradiction",
110
+ "status": "fail",
111
+ "message": check["message"],
112
+ })
113
+ else:
114
+ results.append({
115
+ "check": f"contradiction: {check['message'][:40]}",
116
+ "status": "pass",
117
+ })
118
+ return results
119
+
120
+
121
+ def main() -> int:
122
+ parser = argparse.ArgumentParser(description="Validate agent output schema compliance")
123
+ parser.add_argument("--input", required=True, help="Path to agent output markdown")
124
+ parser.add_argument("--schema", default="generic", help="Schema to validate against")
125
+ parser.add_argument("--json", action="store_true", help="Emit JSON output")
126
+ args = parser.parse_args()
127
+
128
+ input_path = Path(args.input)
129
+ if not input_path.exists():
130
+ print(f"Error: Input file not found: {args.input}", file=sys.stderr)
131
+ return 2
132
+
133
+ content = input_path.read_text(encoding="utf-8")
134
+ schema = SCHEMAS.get(args.schema, SCHEMAS["generic"])
135
+ all_checks: list[dict] = []
136
+
137
+ # Check required sections
138
+ for section in schema["required_sections"]:
139
+ if section in content:
140
+ all_checks.append({"check": f"section:{section}", "status": "pass"})
141
+ else:
142
+ all_checks.append({
143
+ "check": f"section:{section}",
144
+ "status": "fail",
145
+ "message": f"Missing required section: {section}",
146
+ })
147
+
148
+ # Check contradictions
149
+ contradiction_results = check_contradictions(content, schema["contradiction_checks"])
150
+ all_checks.extend(contradiction_results)
151
+
152
+ # Summary
153
+ passed = sum(1 for c in all_checks if c["status"] == "pass")
154
+ failed = sum(1 for c in all_checks if c["status"] == "fail")
155
+
156
+ if args.json:
157
+ output = {
158
+ "input": str(input_path),
159
+ "schema": args.schema,
160
+ "timestamp": __import__("datetime").datetime.utcnow().isoformat() + "Z",
161
+ "summary": {"total": len(all_checks), "passed": passed, "failed": failed},
162
+ "checks": all_checks,
163
+ "status": "pass" if failed == 0 else "fail",
164
+ }
165
+ print(json.dumps(output, indent=2))
166
+ else:
167
+ print(f"\nAgent Output Validation ({args.schema}): {args.input}")
168
+ print(f"{'='*50}")
169
+ for check in all_checks:
170
+ icon = "PASS" if check["status"] == "pass" else "FAIL"
171
+ print(f" [{icon}] {check['check']}")
172
+ if check["status"] == "fail" and "message" in check:
173
+ print(f" {check['message']}")
174
+ print(f"\nSummary: {passed} passed, {failed} failed, {len(all_checks)} total")
175
+ print(f"Result: {'VALID' if failed == 0 else 'INVALID'}")
176
+
177
+ return 0 if failed == 0 else 1
178
+
179
+
180
+ if __name__ == "__main__":
181
+ sys.exit(main())
@@ -0,0 +1,243 @@
1
+ #!/usr/bin/env bash
2
+ # Guardian — Agent Output Validator
3
+ #
4
+ # Validates agent-generated output for schema compliance, consistency, and completeness.
5
+ #
6
+ # Usage:
7
+ # bash validate_agent_output.sh --input=output.md --schema=architecture-validator
8
+ # bash validate_agent_output.sh --input=output.md --json
9
+ # bash validate_agent_output.sh --input=output.md --no-coverage
10
+
11
+ set -euo pipefail
12
+
13
+ INPUT=""
14
+ SCHEMA="generic"
15
+ JSON=false
16
+ NO_COVERAGE=false
17
+
18
+ # Colors
19
+ RED='\033[0;31m'
20
+ GREEN='\033[0;32m'
21
+ YELLOW='\033[1;33m'
22
+ NC='\033[0m'
23
+
24
+ CHECKS_PASSED=0
25
+ CHECKS_FAILED=0
26
+ RESULTS=()
27
+
28
+ while [[ $# -gt 0 ]]; do
29
+ case $1 in
30
+ --input) INPUT="$2"; shift 2 ;;
31
+ --schema) SCHEMA="$2"; shift 2 ;;
32
+ --json) JSON=true; shift ;;
33
+ --no-coverage) NO_COVERAGE=true; shift ;;
34
+ *) shift ;;
35
+ esac
36
+ done
37
+
38
+ if [[ -z "$INPUT" || ! -f "$INPUT" ]]; then
39
+ echo "Error: --input <file> is required"
40
+ exit 1
41
+ fi
42
+
43
+ CONTENT=$(cat "$INPUT")
44
+
45
+ # ── Validation Functions ──
46
+
47
+ check_section_present() {
48
+ local section="$1"
49
+ if echo "$CONTENT" | grep -qi "$section"; then
50
+ RESULTS+=("{\"check\": \"$section\", \"status\": \"pass\"}")
51
+ ((CHECKS_PASSED++))
52
+ if [[ "$JSON" == "false" ]]; then
53
+ echo -e " ${GREEN}✓${NC} Section present: $section"
54
+ fi
55
+ else
56
+ RESULTS+=("{\"check\": \"$section\", \"status\": \"fail\", \"message\": \"Section '$section' not found\"}")
57
+ ((CHECKS_FAILED++))
58
+ if [[ "$JSON" == "false" ]]; then
59
+ echo -e " ${RED}✗${NC} Missing section: $section"
60
+ fi
61
+ fi
62
+ }
63
+
64
+ check_no_contradictions() {
65
+ # Check for common contradiction patterns
66
+ local contradictions=0
67
+
68
+ # Check for "must not" followed by "must" about the same topic
69
+ while IFS= read -r line; do
70
+ topic=$(echo "$line" | grep -oP '^\s*[-*]\s+\*\*[^*]+\*\*' | head -1 || echo "")
71
+ if [[ -n "$topic" ]]; then
72
+ # Count must/must not for this topic
73
+ must_count=$(echo "$CONTENT" | grep -ci "${topic}.*must " || echo 0)
74
+ must_not_count=$(echo "$CONTENT" | grep -ci "${topic}.*must not\|${topic}.*must not " || echo 0)
75
+ if [[ $must_count -gt 0 && $must_not_count -gt 0 ]]; then
76
+ ((contradictions++))
77
+ fi
78
+ fi
79
+ done < <(echo "$CONTENT" | grep -E "^\s*[-*]\s+\*\*" || true)
80
+
81
+ if [[ $contradictions -eq 0 ]]; then
82
+ RESULTS+=("{\"check\": \"no_contradictions\", \"status\": \"pass\"}")
83
+ ((CHECKS_PASSED++))
84
+ if [[ "$JSON" == "false" ]]; then
85
+ echo -e " ${GREEN}✓${NC} No internal contradictions"
86
+ fi
87
+ else
88
+ RESULTS+=("{\"check\": \"no_contradictions\", \"status\": \"fail\", \"message\": \"Found $contradictions contradictions\"}")
89
+ ((CHECKS_FAILED++))
90
+ if [[ "$JSON" == "false" ]]; then
91
+ echo -e " ${RED}✗${NC} Found $contradictions contradictions"
92
+ fi
93
+ fi
94
+ }
95
+
96
+ check_decision_consistency() {
97
+ # Check that all decisions have supporting evidence
98
+ local decisions=$(echo "$CONTENT" | grep -ci "decision\|recommendation\|conclusion" || echo 0)
99
+ local evidence=$(echo "$CONTENT" | grep -ci "evidence\|because\|reason\|rationale\|justification" || echo 0)
100
+
101
+ if [[ $decisions -eq 0 ]] || [[ $evidence -gt 0 ]]; then
102
+ RESULTS+=("{\"check\": \"decision_consistency\", \"status\": \"pass\"}")
103
+ ((CHECKS_PASSED++))
104
+ if [[ "$JSON" == "false" ]]; then
105
+ echo -e " ${GREEN}✓${NC} Decision consistency"
106
+ fi
107
+ else
108
+ RESULTS+=("{\"check\": \"decision_consistency\", \"status\": \"fail\", \"message\": \"Decisions without supporting evidence\"}")
109
+ ((CHECKS_FAILED++))
110
+ if [[ "$JSON" == "false" ]]; then
111
+ echo -e " ${RED}✗${NC} Decisions without supporting evidence"
112
+ fi
113
+ fi
114
+ }
115
+
116
+ check_acceptance_criteria() {
117
+ # Check that acceptance criteria are present and evaluable
118
+ local has_criteria=$(echo "$CONTENT" | grep -ci "acceptance criteria\|criteria\|must\|should\|required" || echo 0)
119
+ local has_checklist=$(echo "$CONTENT" | grep -c "\- \[ \]" || echo 0)
120
+
121
+ if [[ $has_criteria -gt 0 ]]; then
122
+ RESULTS+=("{\"check\": \"acceptance_criteria\", \"status\": \"pass\"}")
123
+ ((CHECKS_PASSED++))
124
+ if [[ "$JSON" == "false" ]]; then
125
+ echo -e " ${GREEN}✓${NC} Acceptance criteria present"
126
+ fi
127
+ else
128
+ RESULTS+=("{\"check\": \"acceptance_criteria\", \"status\": \"fail\", \"message\": \"No acceptance criteria found\"}")
129
+ ((CHECKS_FAILED++))
130
+ if [[ "$JSON" == "false" ]]; then
131
+ echo -e " ${RED}✗${NC} No acceptance criteria found"
132
+ fi
133
+ fi
134
+ }
135
+
136
+ check_canonical_references() {
137
+ local has_refs=$(echo "$CONTENT" | grep -c "Canonical Reference\|canonical.*reference\|\.pi/architecture" || echo 0)
138
+
139
+ if [[ $has_refs -gt 0 ]]; then
140
+ RESULTS+=("{\"check\": \"canonical_references\", \"status\": \"pass\"}")
141
+ ((CHECKS_PASSED++))
142
+ if [[ "$JSON" == "false" ]]; then
143
+ echo -e " ${GREEN}✓${NC} Canonical references present"
144
+ fi
145
+ else
146
+ RESULTS+=("{\"check\": \"canonical_references\", \"status\": \"fail\", \"message\": \"No canonical references found\"}")
147
+ ((CHECKS_FAILED++))
148
+ if [[ "$JSON" == "false" ]]; then
149
+ echo -e " ${RED}✗${NC} No canonical references found"
150
+ fi
151
+ fi
152
+ }
153
+
154
+ # ── Schema-Specific Checks ──
155
+
156
+ case "$SCHEMA" in
157
+ architecture-validator)
158
+ check_section_present "## Summary"
159
+ check_section_present "## Findings"
160
+ check_section_present "## Recommendations"
161
+ check_section_present "## Acceptance Criteria"
162
+ check_section_present "## Canonical References"
163
+ check_no_contradictions
164
+ check_decision_consistency
165
+ check_acceptance_criteria
166
+ check_canonical_references
167
+ ;;
168
+
169
+ epic-plan)
170
+ check_section_present "## Why"
171
+ check_section_present "## Target Outcome"
172
+ check_section_present "## Scope"
173
+ check_section_present "## In Scope"
174
+ check_section_present "## Out of Scope"
175
+ check_section_present "## Impacted Layers"
176
+ check_section_present "## Architecture Constraints"
177
+ check_section_present "## Dependency Map"
178
+ check_section_present "## Canonical References"
179
+ check_acceptance_criteria
180
+ check_canonical_references
181
+ ;;
182
+
183
+ issue-draft)
184
+ check_section_present "## Intent"
185
+ check_section_present "## Scope"
186
+ check_section_present "## In Scope"
187
+ check_section_present "## Out of Scope"
188
+ check_section_present "## Dependencies"
189
+ check_section_present "## Acceptance Criteria"
190
+ check_section_present "## Canonical References"
191
+ check_acceptance_criteria
192
+ check_canonical_references
193
+ ;;
194
+
195
+ *)
196
+ # Generic validation
197
+ check_section_present "## Summary"
198
+ check_no_contradictions
199
+ check_decision_consistency
200
+ check_acceptance_criteria
201
+ ;;
202
+ esac
203
+
204
+ # ── Summary ──
205
+
206
+ TOTAL=$((CHECKS_PASSED + CHECKS_FAILED))
207
+
208
+ if [[ "$JSON" == "true" ]]; then
209
+ RESULTS_JSON=$(printf '%s\n' "${RESULTS[@]}" | jq -s .)
210
+ cat << EOF
211
+ {
212
+ "timestamp": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
213
+ "input": "$INPUT",
214
+ "schema": "$SCHEMA",
215
+ "summary": {
216
+ "total": $TOTAL,
217
+ "passed": $CHECKS_PASSED,
218
+ "failed": $CHECKS_FAILED
219
+ },
220
+ "checks": ${RESULTS_JSON},
221
+ "status": "$([ $CHECKS_FAILED -gt 0 ] && echo "fail" || echo "pass")"
222
+ }
223
+ EOF
224
+ else
225
+ echo ""
226
+ echo "================================"
227
+ echo "AGENT OUTPUT VALIDATION SUMMARY"
228
+ echo "================================"
229
+ echo "Input: $INPUT"
230
+ echo "Schema: $SCHEMA"
231
+ echo "Total checks: $TOTAL"
232
+ echo -e "Passed: ${GREEN}${CHECKS_PASSED}${NC}"
233
+ echo -e "Failed: ${RED}${CHECKS_FAILED}${NC}"
234
+ echo "================================"
235
+
236
+ if [[ $CHECKS_FAILED -eq 0 ]]; then
237
+ echo -e "${GREEN}✅ Agent output validation passed${NC}"
238
+ else
239
+ echo -e "${RED}❌ Agent output validation failed (${CHECKS_FAILED} check(s))${NC}"
240
+ fi
241
+ fi
242
+
243
+ exit $([ $CHECKS_FAILED -gt 0 ] && echo 1 || echo 0)