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,649 @@
1
+ #!/usr/bin/env bash
2
+ # Guardian Local Developer Workflow — Preflight Engine
3
+ #
4
+ # Runs the applicable local preflight subset of CI checks before you commit.
5
+ # Detects changed files, runs only affected checks, generates reports.
6
+ #
7
+ # Usage:
8
+ # ./run_preflight.sh # Run all checks
9
+ # ./run_preflight.sh --staged # Check staged files only
10
+ # ./run_preflight.sh --stage=security # Run only security stage
11
+ # ./run_preflight.sh --json # JSON output for CI/agent integration
12
+ # ./run_preflight.sh --verbose # Verbose output
13
+ # ./run_preflight.sh --staged --stage=lint --json # Combine options
14
+
15
+ set -euo pipefail
16
+
17
+ PI_DIR=".pi"
18
+ CI_DIR="${PI_DIR}/scripts/ci"
19
+ GIT_DIR="$(git rev-parse --show-toplevel 2>/dev/null || echo ".")"
20
+
21
+ # Colors
22
+ RED='\033[0;31m'
23
+ GREEN='\033[0;32m'
24
+ YELLOW='\033[1;33m'
25
+ BLUE='\033[0;34m'
26
+ NC='\033[0m'
27
+
28
+ # Options
29
+ STAGED=false
30
+ STAGE=""
31
+ JSON=false
32
+ VERBOSE=false
33
+ REPORT_FILE="preflight_report.json"
34
+
35
+ # Counters
36
+ TOTAL=0
37
+ PASSED=0
38
+ FAILED=0
39
+ SKIPPED=0
40
+ STAGES_RUN=()
41
+ RESULTS=()
42
+ START_TIME=$(date +%s)
43
+
44
+ # ── Argument Parsing ──
45
+
46
+ while [[ $# -gt 0 ]]; do
47
+ case $1 in
48
+ --staged) STAGED=true; shift ;;
49
+ --stage=*) STAGE="${1#*=}"; shift ;;
50
+ --json) JSON=true; shift ;;
51
+ --verbose) VERBOSE=true; shift ;;
52
+ *) shift ;;
53
+ esac
54
+ done
55
+
56
+ # ── Helper Functions ──
57
+
58
+ log_info() {
59
+ if [[ "$JSON" == "false" ]]; then
60
+ echo -e "${BLUE}[INFO]${NC} $1"
61
+ fi
62
+ }
63
+
64
+ log_pass() {
65
+ if [[ "$JSON" == "false" ]]; then
66
+ echo -e " ${GREEN}[PASS]${NC} $1 (${2}s)"
67
+ fi
68
+ ((PASSED++))
69
+ ((TOTAL++))
70
+ RESULTS+=("{\"name\": \"$1\", \"status\": \"pass\", \"message\": \"\", \"duration\": $2}")
71
+ }
72
+
73
+ log_fail() {
74
+ if [[ "$JSON" == "false" ]]; then
75
+ echo -e " ${RED}[FAIL]${NC} $1 — $2 (${3}s)"
76
+ fi
77
+ ((FAILED++))
78
+ ((TOTAL++))
79
+ RESULTS+=("{\"name\": \"$1\", \"status\": \"fail\", \"message\": \"$2\", \"duration\": $3}")
80
+ }
81
+
82
+ log_skip() {
83
+ if [[ "$JSON" == "false" ]]; then
84
+ echo -e " ${YELLOW}[SKIP]${NC} $1 — $2"
85
+ fi
86
+ ((SKIPPED++))
87
+ ((TOTAL++))
88
+ RESULTS+=("{\"name\": \"$1\", \"status\": \"skip\", \"message\": \"$2\", \"duration\": 0}")
89
+ }
90
+
91
+ # ── Change Detection ──
92
+
93
+ detect_changed_files() {
94
+ if [[ "$STAGED" == "true" ]]; then
95
+ git diff --cached --name-only 2>/dev/null || true
96
+ else
97
+ git diff --name-only HEAD~1 HEAD 2>/dev/null || git ls-files 2>/dev/null || true
98
+ fi
99
+ }
100
+
101
+ should_run_stage() {
102
+ local stage="$1"
103
+ if [[ -n "$STAGE" && "$STAGE" != "$stage" ]]; then
104
+ return 1
105
+ fi
106
+
107
+ if [[ "$STAGED" == "true" ]]; then
108
+ # Check if any staged files match the stage
109
+ case "$stage" in
110
+ docs_policy)
111
+ git diff --cached --name-only 2>/dev/null | grep -qE "\.md$" && return 0
112
+ ;;
113
+ architecture_conformance|static_analysis)
114
+ git diff --cached --name-only 2>/dev/null | grep -qE "\.(py|ts|rs|go)$" && return 0
115
+ ;;
116
+ lint)
117
+ git diff --cached --name-only 2>/dev/null | grep -qE "\.(py|ts|rs|go)$" && return 0
118
+ ;;
119
+ unit|integration)
120
+ git diff --cached --name-only 2>/dev/null | grep -qE "(test|spec)\.(py|ts|rs|go)$" && return 0
121
+ ;;
122
+ security)
123
+ git diff --cached --name-only 2>/dev/null | grep -qE "\.(py|ts|rs|go|env|yml|yaml)$" && return 0
124
+ ;;
125
+ migration_verify)
126
+ git diff --cached --name-only 2>/dev/null | grep -qE "(migration|alembic|schema)" && return 0
127
+ ;;
128
+ release_readiness)
129
+ git diff --cached --name-only 2>/dev/null | grep -qE "(runbook|dr-plan|RUNBOOK|DR)" && return 0
130
+ ;;
131
+ *)
132
+ return 0
133
+ ;;
134
+ esac
135
+ return 1
136
+ fi
137
+ return 0
138
+ }
139
+
140
+ # ── Service Detection ──
141
+
142
+ check_postgres() {
143
+ if command -v psql &>/dev/null && psql -h localhost -U postgres -c "SELECT 1" &>/dev/null 2>&1; then
144
+ return 0
145
+ fi
146
+ return 1
147
+ }
148
+
149
+ check_redis() {
150
+ if command -v redis-cli &>/dev/null && redis-cli ping 2>/dev/null | grep -q "PONG"; then
151
+ return 0
152
+ fi
153
+ return 1
154
+ }
155
+
156
+ check_docker() {
157
+ if command -v docker &>/dev/null && docker info &>/dev/null 2>&1; then
158
+ return 0
159
+ fi
160
+ return 1
161
+ }
162
+
163
+ # ── Stage Runners ──
164
+
165
+ run_stage_docs_policy() {
166
+ if ! should_run_stage "docs_policy"; then return 0; fi
167
+
168
+ local stage_start=$(date +%s)
169
+ log_info "Running stage: docs_policy"
170
+
171
+ # MR traceability check
172
+ local t=$(date +%s)
173
+ if [[ -f "${CI_DIR}/check_mr_traceability.sh" ]]; then
174
+ if bash "${CI_DIR}/check_mr_traceability.sh" >/dev/null 2>&1; then
175
+ log_pass "check_mr_traceability.sh" "$(( $(date +%s) - t ))"
176
+ else
177
+ log_fail "check_mr_traceability.sh" "traceability check failed" "$(( $(date +%s) - t ))"
178
+ fi
179
+ else
180
+ log_skip "check_mr_traceability.sh" "script not found"
181
+ fi
182
+
183
+ # Docs sync guard
184
+ t=$(date +%s)
185
+ if [[ -f "${CI_DIR}/check_docs_sync.sh" ]]; then
186
+ if bash "${CI_DIR}/check_docs_sync.sh" >/dev/null 2>&1; then
187
+ log_pass "check_docs_sync.sh" "$(( $(date +%s) - t ))"
188
+ else
189
+ log_fail "check_docs_sync.sh" "docs sync check failed" "$(( $(date +%s) - t ))"
190
+ fi
191
+ else
192
+ log_skip "check_docs_sync.sh" "script not found"
193
+ fi
194
+ }
195
+
196
+ run_stage_architecture_conformance() {
197
+ if ! should_run_stage "architecture_conformance"; then return 0; fi
198
+
199
+ log_info "Running stage: architecture_conformance"
200
+ local t=$(date +%s)
201
+
202
+ if [[ -f "${CI_DIR}/check_architecture_conformance.sh" ]]; then
203
+ if bash "${CI_DIR}/check_architecture_conformance.sh" >/dev/null 2>&1; then
204
+ log_pass "check_architecture_conformance.sh" "$(( $(date +%s) - t ))"
205
+ else
206
+ log_fail "check_architecture_conformance.sh" "conformance checks failed" "$(( $(date +%s) - t ))"
207
+ # Show verbose output on failure
208
+ if [[ "$VERBOSE" == "true" ]]; then
209
+ bash "${CI_DIR}/check_architecture_conformance.sh" 2>&1 | tail -30
210
+ fi
211
+ fi
212
+ else
213
+ log_skip "check_architecture_conformance.sh" "script not found"
214
+ fi
215
+ }
216
+
217
+ run_stage_lint() {
218
+ if ! should_run_stage "lint"; then return 0; fi
219
+
220
+ log_info "Running stage: lint"
221
+
222
+ # Detect language
223
+ local lang=""
224
+ if [[ -f "pyproject.toml" || -f "requirements.txt" ]]; then lang="python"
225
+ elif [[ -f "package.json" ]]; then lang="typescript"
226
+ elif [[ -f "Cargo.toml" ]]; then lang="rust"
227
+ elif [[ -f "go.mod" ]]; then lang="go"
228
+ fi
229
+
230
+ case "$lang" in
231
+ python)
232
+ local t=$(date +%s)
233
+ if command -v ruff &>/dev/null; then
234
+ if ruff check . >/dev/null 2>&1; then
235
+ log_pass "ruff check" "$(( $(date +%s) - t ))"
236
+ else
237
+ log_fail "ruff check" "lint errors found" "$(( $(date +%s) - t ))"
238
+ fi
239
+ t=$(date +%s)
240
+ if ruff format --check . >/dev/null 2>&1; then
241
+ log_pass "ruff format --check" "$(( $(date +%s) - t ))"
242
+ else
243
+ log_fail "ruff format --check" "format errors found" "$(( $(date +%s) - t ))"
244
+ fi
245
+ else
246
+ log_skip "ruff" "not installed"
247
+ fi
248
+ ;;
249
+ typescript)
250
+ local t=$(date +%s)
251
+ if command -v biome &>/dev/null; then
252
+ if biome check . >/dev/null 2>&1; then
253
+ log_pass "biome check" "$(( $(date +%s) - t ))"
254
+ else
255
+ log_fail "biome check" "lint errors found" "$(( $(date +%s) - t ))"
256
+ fi
257
+ t=$(date +%s)
258
+ if biome format --check . >/dev/null 2>&1; then
259
+ log_pass "biome format --check" "$(( $(date +%s) - t ))"
260
+ else
261
+ log_fail "biome format --check" "format errors found" "$(( $(date +%s) - t ))"
262
+ fi
263
+ else
264
+ log_skip "biome" "not installed"
265
+ fi
266
+ ;;
267
+ rust)
268
+ local t=$(date +%s)
269
+ if command -v cargo &>/dev/null; then
270
+ if cargo clippy -- -D warnings >/dev/null 2>&1; then
271
+ log_pass "cargo clippy" "$(( $(date +%s) - t ))"
272
+ else
273
+ log_fail "cargo clippy" "clippy warnings found" "$(( $(date +%s) - t ))"
274
+ fi
275
+ t=$(date +%s)
276
+ if cargo fmt --check >/dev/null 2>&1; then
277
+ log_pass "cargo fmt --check" "$(( $(date +%s) - t ))"
278
+ else
279
+ log_fail "cargo fmt --check" "format errors found" "$(( $(date +%s) - t ))"
280
+ fi
281
+ else
282
+ log_skip "cargo" "not installed"
283
+ fi
284
+ ;;
285
+ go)
286
+ local t=$(date +%s)
287
+ if command -v golangci-lint &>/dev/null; then
288
+ if golangci-lint run >/dev/null 2>&1; then
289
+ log_pass "golangci-lint" "$(( $(date +%s) - t ))"
290
+ else
291
+ log_fail "golangci-lint" "lint errors found" "$(( $(date +%s) - t ))"
292
+ fi
293
+ else
294
+ log_skip "golangci-lint" "not installed"
295
+ fi
296
+ t=$(date +%s)
297
+ if command -v gofmt &>/dev/null; then
298
+ if [[ -z "$(gofmt -d . 2>/dev/null)" ]]; then
299
+ log_pass "gofmt --check" "$(( $(date +%s) - t ))"
300
+ else
301
+ log_fail "gofmt --check" "format errors found" "$(( $(date +%s) - t ))"
302
+ fi
303
+ else
304
+ log_skip "gofmt" "not installed"
305
+ fi
306
+ ;;
307
+ *)
308
+ log_skip "lint" "no project configuration found"
309
+ ;;
310
+ esac
311
+ }
312
+
313
+ run_stage_static_analysis() {
314
+ if ! should_run_stage "static_analysis"; then return 0; fi
315
+
316
+ log_info "Running stage: static_analysis"
317
+
318
+ # Type checking
319
+ local t=$(date +%s)
320
+ if [[ -f "pyproject.toml" ]] && command -v mypy &>/dev/null; then
321
+ if mypy . --ignore-missing-imports >/dev/null 2>&1; then
322
+ log_pass "mypy" "$(( $(date +%s) - t ))"
323
+ else
324
+ log_fail "mypy" "type errors found" "$(( $(date +%s) - t ))"
325
+ fi
326
+ elif [[ -f "tsconfig.json" ]] && command -v tsc &>/dev/null; then
327
+ if tsc --noEmit >/dev/null 2>&1; then
328
+ log_pass "tsc --noEmit" "$(( $(date +%s) - t ))"
329
+ else
330
+ log_fail "tsc --noEmit" "type errors found" "$(( $(date +%s) - t ))"
331
+ fi
332
+ elif [[ -f "Cargo.toml" ]] && command -v cargo &>/dev/null; then
333
+ if cargo check >/dev/null 2>&1; then
334
+ log_pass "cargo check" "$(( $(date +%s) - t ))"
335
+ else
336
+ log_fail "cargo check" "compilation errors" "$(( $(date +%s) - t ))"
337
+ fi
338
+ else
339
+ log_skip "type_check" "no type checker available"
340
+ fi
341
+
342
+ # Architecture sanity
343
+ t=$(date +%s)
344
+ if [[ -f "${CI_DIR}/check_arch_sanity.sh" ]]; then
345
+ if bash "${CI_DIR}/check_arch_sanity.sh" >/dev/null 2>&1; then
346
+ log_pass "check_arch_sanity.sh" "$(( $(date +%s) - t ))"
347
+ else
348
+ log_fail "check_arch_sanity.sh" "sanity check failed" "$(( $(date +%s) - t ))"
349
+ fi
350
+ else
351
+ log_skip "check_arch_sanity.sh" "script not found"
352
+ fi
353
+
354
+ # Import boundaries
355
+ t=$(date +%s)
356
+ if [[ -f "${CI_DIR}/check_import_boundaries.sh" ]]; then
357
+ if bash "${CI_DIR}/check_import_boundaries.sh" >/dev/null 2>&1; then
358
+ log_pass "check_import_boundaries.sh" "$(( $(date +%s) - t ))"
359
+ else
360
+ log_fail "check_import_boundaries.sh" "boundary violations found" "$(( $(date +%s) - t ))"
361
+ fi
362
+ else
363
+ log_skip "check_import_boundaries.sh" "script not found"
364
+ fi
365
+ }
366
+
367
+ run_stage_unit() {
368
+ if ! should_run_stage "unit"; then return 0; fi
369
+
370
+ log_info "Running stage: unit"
371
+
372
+ local t=$(date +%s)
373
+ if command -v pytest &>/dev/null && [[ -d "tests/unit" ]]; then
374
+ if pytest tests/unit -q --tb=short >/dev/null 2>&1; then
375
+ log_pass "pytest tests/unit" "$(( $(date +%s) - t ))"
376
+ else
377
+ log_fail "pytest tests/unit" "unit test failures" "$(( $(date +%s) - t ))"
378
+ fi
379
+ elif command -v bun &>/dev/null && [[ -d "tests" ]]; then
380
+ if bun test -t "unit" >/dev/null 2>&1; then
381
+ log_pass "bun test (unit)" "$(( $(date +%s) - t ))"
382
+ else
383
+ log_fail "bun test (unit)" "unit test failures" "$(( $(date +%s) - t ))"
384
+ fi
385
+ elif command -v cargo &>/dev/null; then
386
+ if cargo test --lib >/dev/null 2>&1; then
387
+ log_pass "cargo test --lib" "$(( $(date +%s) - t ))"
388
+ else
389
+ log_fail "cargo test --lib" "unit test failures" "$(( $(date +%s) - t ))"
390
+ fi
391
+ elif command -v go &>/dev/null; then
392
+ if go test ./... -short >/dev/null 2>&1; then
393
+ log_pass "go test" "$(( $(date +%s) - t ))"
394
+ else
395
+ log_fail "go test" "unit test failures" "$(( $(date +%s) - t ))"
396
+ fi
397
+ else
398
+ log_skip "unit" "no test runner found"
399
+ fi
400
+ }
401
+
402
+ run_stage_integration() {
403
+ if ! should_run_stage "integration"; then return 0; fi
404
+
405
+ log_info "Running stage: integration"
406
+
407
+ if ! check_postgres || ! check_redis; then
408
+ log_skip "integration" "PostgreSQL or Redis not available"
409
+ if [[ "$VERBOSE" == "true" ]]; then
410
+ log_info "Start services: docker run -d postgres:16 && docker run -d redis:7"
411
+ fi
412
+ return 0
413
+ fi
414
+
415
+ local t=$(date +%s)
416
+ if command -v pytest &>/dev/null && [[ -d "tests/integration" ]]; then
417
+ if pytest tests/integration -q --tb=short >/dev/null 2>&1; then
418
+ log_pass "pytest tests/integration" "$(( $(date +%s) - t ))"
419
+ else
420
+ log_fail "pytest tests/integration" "integration test failures" "$(( $(date +%s) - t ))"
421
+ fi
422
+ else
423
+ log_skip "integration" "no integration tests found"
424
+ fi
425
+ }
426
+
427
+ run_stage_security() {
428
+ if ! should_run_stage "security"; then return 0; fi
429
+
430
+ log_info "Running stage: security"
431
+
432
+ # Secret scan
433
+ local t=$(date +%s)
434
+ if [[ -f "${CI_DIR}/secret_scan.sh" ]]; then
435
+ if bash "${CI_DIR}/secret_scan.sh" >/dev/null 2>&1; then
436
+ log_pass "secret_scan.sh" "$(( $(date +%s) - t ))"
437
+ else
438
+ log_fail "secret_scan.sh" "secrets detected" "$(( $(date +%s) - t ))"
439
+ fi
440
+ else
441
+ # Fallback: basic grep
442
+ if grep -rE "(sk-[A-Za-z0-9]{32,}|ghp_[A-Za-z0-9]{36}|AKIA[0-9A-Z]{16})" . --include="*.py" --include="*.ts" --include="*.env" 2>/dev/null | grep -v ".git" | grep -v "node_modules" | head -1 | grep -q .; then
443
+ log_fail "secret_scan" "potential secrets found" "$(( $(date +%s) - t ))"
444
+ else
445
+ log_pass "secret_scan" "$(( $(date +%s) - t ))"
446
+ fi
447
+ fi
448
+
449
+ # Dependency audit
450
+ t=$(date +%s)
451
+ if command -v pip-audit &>/dev/null; then
452
+ if pip-audit --skip-editable >/dev/null 2>&1; then
453
+ log_pass "pip-audit" "$(( $(date +%s) - t ))"
454
+ else
455
+ log_fail "pip-audit" "vulnerable dependencies" "$(( $(date +%s) - t ))"
456
+ fi
457
+ elif command -v npm &>/dev/null && [[ -f "package.json" ]]; then
458
+ if npm audit --audit-level=high >/dev/null 2>&1; then
459
+ log_pass "npm audit" "$(( $(date +%s) - t ))"
460
+ else
461
+ log_fail "npm audit" "high/critical vulnerabilities" "$(( $(date +%s) - t ))"
462
+ fi
463
+ else
464
+ log_skip "dependency_audit" "no package manager audit tool found"
465
+ fi
466
+ }
467
+
468
+ run_stage_migration_verify() {
469
+ if ! should_run_stage "migration_verify"; then return 0; fi
470
+
471
+ log_info "Running stage: migration_verify"
472
+
473
+ if ! check_postgres; then
474
+ log_skip "migration_verify" "PostgreSQL not available"
475
+ return 0
476
+ fi
477
+
478
+ local t=$(date +%s)
479
+ if command -v alembic &>/dev/null; then
480
+ if alembic upgrade head >/dev/null 2>&1; then
481
+ log_pass "alembic upgrade head" "$(( $(date +%s) - t ))"
482
+ else
483
+ log_fail "alembic upgrade head" "migration failed" "$(( $(date +%s) - t ))"
484
+ fi
485
+ else
486
+ log_skip "migration_verify" "alembic not installed"
487
+ fi
488
+ }
489
+
490
+ run_stage_package_build() {
491
+ if ! should_run_stage "package_build"; then return 0; fi
492
+
493
+ log_info "Running stage: package_build"
494
+
495
+ if ! check_docker; then
496
+ log_skip "package_build" "Docker not available"
497
+ return 0
498
+ fi
499
+
500
+ if [[ ! -f "Dockerfile" ]]; then
501
+ log_skip "package_build" "no Dockerfile found"
502
+ return 0
503
+ fi
504
+
505
+ local t=$(date +%s)
506
+ if docker build -t guardian:local >/dev/null 2>&1; then
507
+ log_pass "docker build" "$(( $(date +%s) - t ))"
508
+ else
509
+ log_fail "docker build" "build failed" "$(( $(date +%s) - t ))"
510
+ fi
511
+ }
512
+
513
+ run_stage_release_readiness() {
514
+ if ! should_run_stage "release_readiness"; then return 0; fi
515
+
516
+ log_info "Running stage: release_readiness"
517
+
518
+ local t=$(date +%s)
519
+ if [[ -f "${PI_DIR}/scripts/validate-architecture-readiness.sh" ]]; then
520
+ if bash "${PI_DIR}/scripts/validate-architecture-readiness.sh" >/dev/null 2>&1; then
521
+ log_pass "validate-architecture-readiness.sh" "$(( $(date +%s) - t ))"
522
+ else
523
+ log_fail "validate-architecture-readiness.sh" "readiness checks failed" "$(( $(date +%s) - t ))"
524
+ if [[ "$VERBOSE" == "true" ]]; then
525
+ bash "${PI_DIR}/scripts/validate-architecture-readiness.sh" 2>&1 | tail -30
526
+ fi
527
+ fi
528
+ else
529
+ log_skip "validate-architecture-readiness.sh" "script not found"
530
+ fi
531
+ }
532
+
533
+ # ── Main ──
534
+
535
+ CHANGED_FILES=$(detect_changed_files)
536
+
537
+ if [[ -n "$CHANGED_FILES" && "$JSON" == "false" ]]; then
538
+ log_info "Changed files:"
539
+ echo "$CHANGED_FILES" | while IFS= read -r f; do
540
+ [[ -n "$f" ]] && echo " - $f"
541
+ done
542
+ fi
543
+
544
+ # Run all stages
545
+ run_stage_docs_policy
546
+ run_stage_architecture_conformance
547
+ run_stage_lint
548
+ run_stage_static_analysis
549
+ run_stage_unit
550
+ run_stage_integration
551
+ run_stage_security
552
+ run_stage_migration_verify
553
+ run_stage_package_build
554
+ run_stage_release_readiness
555
+
556
+ # Calculate duration
557
+ END_TIME=$(date +%s)
558
+ DURATION=$((END_TIME - START_TIME))
559
+
560
+ # Determine overall status
561
+ if [[ $FAILED -gt 0 ]]; then
562
+ STATUS="fail"
563
+ else
564
+ STATUS="pass"
565
+ fi
566
+
567
+ # Output
568
+ if [[ "$JSON" == "true" ]]; then
569
+ # JSON output
570
+ if [[ ${#STAGES_RUN[@]} -gt 0 ]]; then
571
+ STAGES_JSON=$(printf '%s\n' "${STAGES_RUN[@]}" | jq -R . | jq -s .)
572
+ else
573
+ STAGES_JSON="[]"
574
+ fi
575
+ if [[ ${#RESULTS[@]} -gt 0 ]]; then
576
+ RESULTS_JSON=$(printf '%s\n' "${RESULTS[@]}" | jq -s .)
577
+ else
578
+ RESULTS_JSON="[]"
579
+ fi
580
+
581
+ cat << EOF
582
+ {
583
+ "timestamp": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
584
+ "mode": "$([ "$STAGED" == "true" ] && echo "staged" || echo "all")",
585
+ "stages_run": ${STAGES_JSON:-[]},
586
+ "summary": {
587
+ "total": ${TOTAL},
588
+ "passed": ${PASSED},
589
+ "failed": ${FAILED},
590
+ "skipped": ${SKIPPED}
591
+ },
592
+ "duration_seconds": ${DURATION},
593
+ "results": ${RESULTS_JSON:-[]},
594
+ "status": "${STATUS}"
595
+ }
596
+ EOF
597
+ else
598
+ # Human-readable output
599
+ echo ""
600
+ echo "================================"
601
+ echo "PREFLIGHT SUMMARY"
602
+ echo "================================"
603
+ echo "Total checks: ${TOTAL}"
604
+ echo -e "Passed: ${GREEN}${PASSED}${NC}"
605
+ echo -e "Failed: ${RED}${FAILED}${NC}"
606
+ echo -e "Skipped: ${YELLOW}${SKIPPED}${NC}"
607
+ echo "Duration: ${DURATION}s"
608
+ echo "Report: ${REPORT_FILE}"
609
+ echo "================================"
610
+
611
+ if [[ $FAILED -eq 0 ]]; then
612
+ echo -e "${GREEN}✅ Preflight passed${NC}"
613
+ else
614
+ echo -e "${RED}❌ Preflight failed (${FAILED} check(s))${NC}"
615
+ echo "Fix the issues above before committing."
616
+ fi
617
+ fi
618
+
619
+ # Save report
620
+ if [[ "$JSON" == "true" ]]; then
621
+ if [[ ${#STAGES_RUN[@]} -gt 0 ]]; then
622
+ STAGES_JSON=$(printf '%s\n' "${STAGES_RUN[@]}" | jq -R . | jq -s .)
623
+ else
624
+ STAGES_JSON="[]"
625
+ fi
626
+ if [[ ${#RESULTS[@]} -gt 0 ]]; then
627
+ RESULTS_JSON=$(printf '%s\n' "${RESULTS[@]}" | jq -s .)
628
+ else
629
+ RESULTS_JSON="[]"
630
+ fi
631
+ cat << EOF > "$REPORT_FILE"
632
+ {
633
+ "timestamp": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
634
+ "mode": "$([ "$STAGED" == "true" ] && echo "staged" || echo "all")",
635
+ "stages_run": ${STAGES_JSON:-[]},
636
+ "summary": {
637
+ "total": ${TOTAL},
638
+ "passed": ${PASSED},
639
+ "failed": ${FAILED},
640
+ "skipped": ${SKIPPED}
641
+ },
642
+ "duration_seconds": ${DURATION},
643
+ "results": ${RESULTS_JSON:-[]},
644
+ "status": "${STATUS}"
645
+ }
646
+ EOF
647
+ fi
648
+
649
+ exit $([ $FAILED -gt 0 ] && echo 1 || echo 0)