guardian-framework 0.1.100 → 0.1.102

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 (25) hide show
  1. package/dist/cli.js +1 -1
  2. package/dist/exports.js +1 -1
  3. package/package.json +1 -1
  4. package/templates/pi/extensions/architect-lib/generators.ts +15 -29
  5. package/templates/pi/preflight_report.json +1 -1
  6. package/templates/pi/scripts/languages/go/validate-architecture.sh +1 -1
  7. package/templates/pi/scripts/languages/go/validate-canonical.sh +3 -3
  8. package/templates/pi/scripts/languages/go/validate-ci.sh +1 -1
  9. package/templates/pi/scripts/languages/go/validate-integration.sh +1 -1
  10. package/templates/pi/scripts/languages/go/validate-security.sh +2 -2
  11. package/templates/pi/scripts/languages/java/validate-annotations.sh +1 -1
  12. package/templates/pi/scripts/languages/java/validate-architecture.sh +1 -1
  13. package/templates/pi/scripts/languages/java/validate-canonical.sh +2 -2
  14. package/templates/pi/scripts/languages/python/validate-architecture.sh +2 -2
  15. package/templates/pi/scripts/languages/python/validate-canonical.sh +2 -2
  16. package/templates/pi/scripts/languages/python/validate-integration.sh +1 -1
  17. package/templates/pi/scripts/languages/python/validate-security.sh +1 -1
  18. package/templates/pi/scripts/languages/rust/validate-architecture.sh +1 -1
  19. package/templates/pi/scripts/languages/rust/validate-canonical.sh +2 -2
  20. package/templates/pi/scripts/languages/rust/validate-integration.sh +3 -3
  21. package/templates/pi/scripts/languages/rust/validate-tests.sh +2 -2
  22. package/templates/pi/scripts/languages/typescript/validate-architecture.sh +1 -1
  23. package/templates/pi/scripts/languages/typescript/validate-canonical.sh +2 -2
  24. package/templates/pi/scripts/languages/typescript/validate-integration.sh +4 -4
  25. package/templates/pi/scripts/languages/typescript/validate-security.sh +2 -2
package/dist/cli.js CHANGED
@@ -3197,7 +3197,7 @@ __export(exports_package, {
3197
3197
  bin: () => bin,
3198
3198
  author: () => author
3199
3199
  });
3200
- var name = "guardian-framework", version = "0.1.100", description = "Token-optimized agentic framework scaffolder with pi-first architecture", type = "module", main = "dist/exports.js", exports, types = "dist/exports.d.ts", bin, files, engines, scripts, publishConfig, pi, repository, homepage = "https://github.com/arman-jalili/guardian-framework#readme", bugs, dependencies, devDependencies, keywords, author = "Arman Wolkensteiner-Jalili", license = "MIT", package_default;
3200
+ var name = "guardian-framework", version = "0.1.102", description = "Token-optimized agentic framework scaffolder with pi-first architecture", type = "module", main = "dist/exports.js", exports, types = "dist/exports.d.ts", bin, files, engines, scripts, publishConfig, pi, repository, homepage = "https://github.com/arman-jalili/guardian-framework#readme", bugs, dependencies, devDependencies, keywords, author = "Arman Wolkensteiner-Jalili", license = "MIT", package_default;
3201
3201
  var init_package = __esm(() => {
3202
3202
  exports = {
3203
3203
  ".": {
package/dist/exports.js CHANGED
@@ -1982,7 +1982,7 @@ __export(exports_package, {
1982
1982
  bin: () => bin,
1983
1983
  author: () => author
1984
1984
  });
1985
- var name = "guardian-framework", version = "0.1.100", description = "Token-optimized agentic framework scaffolder with pi-first architecture", type = "module", main = "dist/exports.js", exports, types = "dist/exports.d.ts", bin, files, engines, scripts, publishConfig, pi, repository, homepage = "https://github.com/arman-jalili/guardian-framework#readme", bugs, dependencies, devDependencies, keywords, author = "Arman Wolkensteiner-Jalili", license = "MIT", package_default;
1985
+ var name = "guardian-framework", version = "0.1.102", description = "Token-optimized agentic framework scaffolder with pi-first architecture", type = "module", main = "dist/exports.js", exports, types = "dist/exports.d.ts", bin, files, engines, scripts, publishConfig, pi, repository, homepage = "https://github.com/arman-jalili/guardian-framework#readme", bugs, dependencies, devDependencies, keywords, author = "Arman Wolkensteiner-Jalili", license = "MIT", package_default;
1986
1986
  var init_package = __esm(() => {
1987
1987
  exports = {
1988
1988
  ".": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "guardian-framework",
3
- "version": "0.1.100",
3
+ "version": "0.1.102",
4
4
  "description": "Token-optimized agentic framework scaffolder with pi-first architecture",
5
5
  "type": "module",
6
6
  "main": "dist/exports.js",
@@ -133,30 +133,6 @@ function isJavaProject(cwd?: string): boolean {
133
133
  }
134
134
  }
135
135
 
136
- /** Get the test runner command for a project language. */
137
- function testRunnerFromCwd(cwd?: string): string | null {
138
- if (!cwd) return null;
139
- try {
140
- if (existsSync(join(cwd, "Cargo.toml"))) return "cargo test";
141
- if (existsSync(join(cwd, "go.mod"))) return "go test";
142
- if (existsSync(join(cwd, "pyproject.toml")) || existsSync(join(cwd, "requirements.txt"))) return "pytest";
143
- if (existsSync(join(cwd, "package.json"))) return "bun test";
144
- } catch {}
145
- return null;
146
- }
147
-
148
- /** Get the implementation file suffix for a project language. */
149
- function implSuffix(cwd?: string): string {
150
- if (!cwd) return "ts";
151
- try {
152
- if (existsSync(join(cwd, "pom.xml")) || existsSync(join(cwd, "build.gradle")) || existsSync(join(cwd, "build.gradle.kts"))) return "java";
153
- if (existsSync(join(cwd, "Cargo.toml"))) return "rs";
154
- if (existsSync(join(cwd, "go.mod"))) return "go";
155
- if (existsSync(join(cwd, "pyproject.toml")) || existsSync(join(cwd, "requirements.txt"))) return "py";
156
- } catch {}
157
- return "ts";
158
- }
159
-
160
136
  // ── Issue Generation ──
161
137
 
162
138
  export function generateIssueMarkdown(
@@ -182,7 +158,7 @@ export function generateIssueMarkdown(
182
158
  // Language-aware test paths
183
159
  const isJava = isJavaProject(cwd);
184
160
  const testBaseDir = isJava ? "src/test/java" : "tests/unit";
185
- const testRunnerHint = isJava ? "mvn test" : testRunnerFromCwd(cwd) || "bun test";
161
+ const testRunnerHint = isJava ? "mvn test" : "bun test";
186
162
 
187
163
  const testLine = tdd
188
164
  ? ` - "update: ${testBaseDir}/ (failing tests already generated — make them pass)"`
@@ -276,7 +252,7 @@ ${yamlAcs}
276
252
  All Acceptance Criteria in that file must be satisfied before this issue is closed.
277
253
  Component focus: ${comp.name}.
278
254
  CONCRETE IMPLEMENTATIONS MUST BE CREATED — interface stubs from the contract freeze
279
- are not sufficient. Each domain service/aggregate needs a concrete .impl.${implSuffix(cwd)} file.
255
+ are not sufficient. Each domain service/aggregate needs a concrete .impl.${isJava ? "java" : "ts"} file.
280
256
 
281
257
  file_changes:
282
258
  - "create: src/${moduleId}/domain/"
@@ -331,7 +307,7 @@ ${stepsMarkdown}
331
307
  > **Agent instructions:**
332
308
  > 1. Open \`.pi/architecture/modules/${slice.module}.md\` — read the full Acceptance Criteria table
333
309
  > 2. Identify which rows are your responsibility for **${comp.name}**
334
- > 3. Create concrete implementation files (\`.impl.${implSuffix(cwd)}\`) in \`src/${moduleId}/\` — the interface stubs from the contract freeze are NOT enough
310
+ > 3. Create concrete implementation files (\`.impl.${isJava ? "java" : "ts"}\`) in \`src/${moduleId}/\` — the interface stubs from the contract freeze are NOT enough
335
311
  > 4. Each domain aggregate/service must have a working implementation with business logic
336
312
  > 5. Verify each AC row is satisfied in \`src/\` before marking done
337
313
  > 6. Run validators and create MR
@@ -466,8 +442,8 @@ ${implSteps.length > 0
466
442
 
467
443
  > **Agent:** Create interface-only files. No implementation. Use Clean Architecture layers:
468
444
  > 1. Read the architecture module to understand each component's role
469
- > 2. Place domain interfaces in domain/, service interfaces in application/, API contracts in interfaces/http/
470
- > 3. DTOs with proper validation decorators go in application/
445
+ > 2. Place domain interfaces in domain/, service interfaces in application/, DTOs in application/
446
+ > 3. Controllers/routers are CONCRETE — they do NOT get interfaces. The concrete router/handler class goes directly in interfaces/http/ without a separate contract file.
471
447
  > 4. Event schemas go in domain/event/
472
448
  > 5. Repository interfaces go in infrastructure/repository/
473
449
  >
@@ -598,6 +574,16 @@ run_stage "11" "${moduleId}_proofing" \\
598
574
  > 3. Self-documenting with --help
599
575
  > 4. Exit 0 for pass, 1 for fail
600
576
  >
577
+ > CRITICAL: Do NOT map handler type files to separate impl files. Controllers/routers
578
+ > are concrete — they DO NOT have a separate interface. The contract checker must:
579
+ > - ✅ Verify domain and application interfaces have impls
580
+ > - ✅ Verify DTO schemas exist and match the module doc
581
+ > - ❌ NOT check for a handlers.ts → router.impl.ts mapping (handlers are concrete)
582
+ > - ❌ NOT create separate contract files for the HTTP layer
583
+ >
584
+ > For the HTTP layer, just verify the router file exists in interfaces/http/. That\'s
585
+ > the concrete handler — no interface needed.
586
+ >
601
587
  > End by running the full CI pipeline to verify integration:
602
588
  > \`bash .pi/scripts/ci/run_hardening_stages.sh\`
603
589
  `;
@@ -1,5 +1,5 @@
1
1
  {
2
- "timestamp": "2026-07-19T05:59:04Z",
2
+ "timestamp": "2026-07-20T12:29:56Z",
3
3
  "mode": "all",
4
4
  "stages_run": [],
5
5
  "summary": {
@@ -40,7 +40,7 @@ fi
40
40
  echo ""
41
41
  echo "--- Canonical References ---"
42
42
  if [ -d ".pi/architecture/modules" ]; then
43
- MODULE_COUNT=$(find .pi/architecture/modules -name "*.md" 2>/dev/null | wc -l | tr -d ' ')
43
+ MODULE_COUNT=$(find .pi/architecture/modules -name "*.md" 2>/dev/null | wc -l | tr -d ' ') || true
44
44
  pass "Canonical architecture documents found ($MODULE_COUNT modules)"
45
45
  else
46
46
  warn "No canonical architecture directory (.pi/architecture/modules) found"
@@ -20,7 +20,7 @@ echo ""
20
20
  # ---------------------------------------------------------------------------
21
21
  echo "--- Architecture Reference Tracing ---"
22
22
  if [ -f "go.mod" ]; then
23
- GO_FILES=$(find . -name "*.go" -not -path "./vendor/*" 2>/dev/null | wc -l | tr -d ' ')
23
+ GO_FILES=$(find . -name "*.go" -not -path "./vendor/*" 2>/dev/null | wc -l | tr -d ' ') || true
24
24
  if [ "$GO_FILES" -gt 0 ]; then
25
25
  CANONICAL_REFS=$(grep -rlE '//\s*(Canonical:|@canonical|Reference:|Canonical\s+ref)' . --include="*.go" 2>/dev/null | wc -l | tr -d ' ') || true
26
26
  if [ "$CANONICAL_REFS" -gt 0 ]; then
@@ -75,7 +75,7 @@ echo ""
75
75
  echo "--- Package Documentation ---"
76
76
  if [ -f "go.mod" ]; then
77
77
  PKG_FILES_WITH_DOC=$(grep -rlE '//\s*Package\s+\w+\s+(implements|provides|defines|is|contains)' . --include="*.go" 2>/dev/null | wc -l | tr -d ' ') || true
78
- GO_PACKAGES=$(go list ./... 2>/dev/null | wc -l | tr -d ' ')
78
+ GO_PACKAGES=$(go list ./... 2>/dev/null | wc -l | tr -d ' ') || true
79
79
  if [ "$GO_PACKAGES" -gt 0 ] && [ "$PKG_FILES_WITH_DOC" -gt 0 ]; then
80
80
  pass "Package documentation found in $PKG_FILES_WITH_DOC files"
81
81
  else
@@ -91,7 +91,7 @@ fi
91
91
  echo ""
92
92
  echo "--- ADR Linkage ---"
93
93
  if [ -d ".pi/architecture/decisions" ]; then
94
- ADR_COUNT=$(find .pi/architecture/decisions -name "*.md" 2>/dev/null | wc -l | tr -d ' ')
94
+ ADR_COUNT=$(find .pi/architecture/decisions -name "*.md" 2>/dev/null | wc -l | tr -d ' ') || true
95
95
  if [ "$ADR_COUNT" -gt 0 ]; then
96
96
  ADR_REFS=$(grep -rlE '//\s*ADR[-_]?\d+' . --include="*.go" 2>/dev/null | wc -l | tr -d ' ') || true
97
97
  if [ "$ADR_REFS" -gt 0 ]; then
@@ -42,7 +42,7 @@ fi
42
42
  echo ""
43
43
  echo "--- Tests ---"
44
44
  if [ -f "go.mod" ]; then
45
- TEST_FILES=$(find . -name "*_test.go" -not -path "./vendor/*" 2>/dev/null | wc -l | tr -d ' ')
45
+ TEST_FILES=$(find . -name "*_test.go" -not -path "./vendor/*" 2>/dev/null | wc -l | tr -d ' ') || true
46
46
  if [ "$TEST_FILES" -gt 0 ]; then
47
47
  if go test ./... -count=1 2>/dev/null; then
48
48
  pass "All tests passed"
@@ -65,7 +65,7 @@ fi
65
65
  echo ""
66
66
  echo "--- Contract Tests ---"
67
67
  if [ -f "go.mod" ]; then
68
- CONTRACT_FILES=$(find . -name "*_contract_test.go" -not -path "./vendor/*" 2>/dev/null | wc -l | tr -d ' ')
68
+ CONTRACT_FILES=$(find . -name "*_contract_test.go" -not -path "./vendor/*" 2>/dev/null | wc -l | tr -d ' ') || true
69
69
  if [ "$CONTRACT_FILES" -gt 0 ]; then
70
70
  pass "Contract test files found ($CONTRACT_FILES files)"
71
71
  else
@@ -67,7 +67,7 @@ if command -v govulncheck &>/dev/null && [ -f "go.mod" ]; then
67
67
  warn "govulncheck reported findings (review manually)"
68
68
  fi
69
69
  elif [ -f "go.mod" ]; then
70
- DEP_COUNT=$(go list -m all 2>/dev/null | wc -l | tr -d ' ')
70
+ DEP_COUNT=$(go list -m all 2>/dev/null | wc -l | tr -d ' ') || true
71
71
  warn "govulncheck not available; $DEP_COUNT dependencies require manual review"
72
72
  else
73
73
  warn "Not in a Go module, skipping dependency audit"
@@ -99,7 +99,7 @@ fi
99
99
  echo ""
100
100
  echo "--- Input Validation ---"
101
101
  if [ -f "go.mod" ]; then
102
- TEXT_TEMPLATE=$(grep -rl '"text/template"' . --include="*.go" 2>/dev/null | grep -v "_test.go" | wc -l | tr -d ' ')
102
+ TEXT_TEMPLATE=$(grep -rl '"text/template"' . --include="*.go" 2>/dev/null | grep -v "_test.go" | wc -l | tr -d ' ') || true
103
103
  HTML_TEMPLATE=$(grep -rl '"html/template"' . --include="*.go" 2>/dev/null | wc -l | tr -d ' ') || true
104
104
  if [ "$TEXT_TEMPLATE" -eq 0 ]; then
105
105
  pass "No text/template usage in production code (html/template auto-escapes)"
@@ -95,7 +95,7 @@ if [ -d "$SRC_DIR" ]; then
95
95
  if [ -n "$FIELD_AUTOWIRED" ]; then
96
96
  # Count field-level @Autowired (not constructor)
97
97
  FIELD_COUNT=$(echo "$FIELD_AUTOWIRED" | wc -l | tr -d ' ')
98
- CONSTRUCTOR_COUNT=$(grep -rn "@Autowired\s*$" "$SRC_DIR" --include="*.java" 2>/dev/null | grep -v "//\|/\*" | wc -l | tr -d ' ')
98
+ CONSTRUCTOR_COUNT=$(grep -rn "@Autowired\s*$" "$SRC_DIR" --include="*.java" 2>/dev/null | grep -v "//\|/\*" | wc -l | tr -d ' ') || true
99
99
 
100
100
  # Heuristic: more field injections than constructor injections
101
101
  if [ "$FIELD_COUNT" -gt "$CONSTRUCTOR_COUNT" ]; then
@@ -86,7 +86,7 @@ fi
86
86
  echo ""
87
87
  echo "--- Canonical References ---"
88
88
  if [ -d ".pi/architecture/modules" ]; then
89
- MODULE_COUNT=$(find .pi/architecture/modules -name "*.md" 2>/dev/null | wc -l | tr -d ' ')
89
+ MODULE_COUNT=$(find .pi/architecture/modules -name "*.md" 2>/dev/null | wc -l | tr -d ' ') || true
90
90
  pass "Canonical architecture documents found ($MODULE_COUNT modules)"
91
91
  else
92
92
  warn "No .pi/architecture/modules directory found"
@@ -39,7 +39,7 @@ fi
39
39
  echo ""
40
40
  echo "--- Implementation File References ---"
41
41
  if [ -d "$SRC_DIR" ]; then
42
- JAVA_FILES=$(find "$SRC_DIR" -name "*.java" 2>/dev/null | wc -l | tr -d ' ')
42
+ JAVA_FILES=$(find "$SRC_DIR" -name "*.java" 2>/dev/null | wc -l | tr -d ' ') || true
43
43
  if [ "$JAVA_FILES" -gt 0 ]; then
44
44
  # Check for canonical reference headers in Java files
45
45
  WITH_REFS=0
@@ -81,7 +81,7 @@ fi
81
81
  echo ""
82
82
  echo "--- ADR References ---"
83
83
  if [ -d ".pi/architecture/decisions" ]; then
84
- ADR_COUNT=$(find .pi/architecture/decisions -name "*.md" -not -name "ADR-template.md" 2>/dev/null | wc -l | tr -d ' ')
84
+ ADR_COUNT=$(find .pi/architecture/decisions -name "*.md" -not -name "ADR-template.md" 2>/dev/null | wc -l | tr -d ' ') || true
85
85
  if [ "$ADR_COUNT" -gt 0 ]; then
86
86
  pass "Architecture Decision Records found ($ADR_COUNT ADRs)"
87
87
  else
@@ -41,7 +41,7 @@ fi
41
41
  echo ""
42
42
  echo "--- Canonical References ---"
43
43
  if [ -d ".pi/architecture/modules" ]; then
44
- MODULE_COUNT=$(find .pi/architecture/modules -name "*.md" 2>/dev/null | wc -l | tr -d ' ')
44
+ MODULE_COUNT=$(find .pi/architecture/modules -name "*.md" 2>/dev/null | wc -l | tr -d ' ') || true
45
45
  pass "Canonical architecture documents found ($MODULE_COUNT modules)"
46
46
  else
47
47
  warn "No canonical architecture directory found"
@@ -50,7 +50,7 @@ fi
50
50
  # Domain models
51
51
  echo ""
52
52
  echo "--- Domain Models ---"
53
- DOMAIN_FILES=$(find "$SRC_DIR" -path "*/domain/*.py" 2>/dev/null | wc -l | tr -d ' ')
53
+ DOMAIN_FILES=$(find "$SRC_DIR" -path "*/domain/*.py" 2>/dev/null | wc -l | tr -d ' ') || true
54
54
  if [ "$DOMAIN_FILES" -gt 0 ]; then
55
55
  pass "Domain model files found ($DOMAIN_FILES files)"
56
56
  else
@@ -26,7 +26,7 @@ SRC_DIR="${1:-src}"
26
26
 
27
27
  # ── Architecture reference tracing ──
28
28
  echo "--- Architecture Reference Tracing ---"
29
- TOTAL_PY_FILES=$(find "$SRC_DIR" -name "*.py" 2>/dev/null | wc -l | tr -d ' ')
29
+ TOTAL_PY_FILES=$(find "$SRC_DIR" -name "*.py" 2>/dev/null | wc -l | tr -d ' ') || true
30
30
  if [ "$TOTAL_PY_FILES" -gt 0 ]; then
31
31
  FILES_WITH_REFS=$(grep -rlE "(Canonical:|@canonical|Reference:.*\.pi/architecture)" "$SRC_DIR" --include="*.py" 2>/dev/null | wc -l | tr -d ' ') || true
32
32
  PCT=$((FILES_WITH_REFS * 100 / TOTAL_PY_FILES))
@@ -92,7 +92,7 @@ fi
92
92
  echo ""
93
93
  echo "--- ADR Linkage ---"
94
94
  if [ -d ".pi/architecture/decisions" ]; then
95
- ADR_COUNT=$(find .pi/architecture/decisions -name "ADR-*.md" 2>/dev/null | wc -l | tr -d ' ')
95
+ ADR_COUNT=$(find .pi/architecture/decisions -name "ADR-*.md" 2>/dev/null | wc -l | tr -d ' ') || true
96
96
  ADR_REFS=$(grep -rlE "ADR-[0-9]+" "$SRC_DIR" --include="*.py" 2>/dev/null | wc -l | tr -d ' ') || true
97
97
  if [ "$ADR_REFS" -gt 0 ]; then
98
98
  pass "ADR references found in $ADR_REFS source files ($ADR_COUNT ADRs exist)"
@@ -49,7 +49,7 @@ fi
49
49
  # ── Contract Tests ──
50
50
  echo ""
51
51
  echo "--- Contract Tests ---"
52
- CONTRACT_COUNT=$(find tests -name "*contract*" -o -name "*pact*" 2>/dev/null | wc -l | tr -d ' ')
52
+ CONTRACT_COUNT=$(find tests -name "*contract*" -o -name "*pact*" 2>/dev/null | wc -l | tr -d ' ') || true
53
53
  if [ "$CONTRACT_COUNT" -gt 0 ]; then
54
54
  pass "Contract test files found ($CONTRACT_COUNT)"
55
55
  else
@@ -23,7 +23,7 @@ echo "============================================"
23
23
 
24
24
  # Hardcoded secrets
25
25
  echo "--- Hardcoded Secrets ---"
26
- SECRET_COUNT=$(grep -rE "(api_key|secret_key|password|token)\s*=\s*['\"][^'\"]{8,}" "$SRC_DIR" --include="*.py" 2>/dev/null | grep -v "__init__" | grep -v "test" | wc -l | tr -d ' ')
26
+ SECRET_COUNT=$(grep -rE "(api_key|secret_key|password|token)\s*=\s*['\"][^'\"]{8,}" "$SRC_DIR" --include="*.py" 2>/dev/null | grep -v "__init__" | grep -v "test" | wc -l | tr -d ' ') || true
27
27
  if [ "$SECRET_COUNT" -eq 0 ]; then
28
28
  pass "No hardcoded secrets detected"
29
29
  else
@@ -64,7 +64,7 @@ fi
64
64
  echo ""
65
65
  echo "--- Canonical References ---"
66
66
  if [ -d ".pi/architecture/modules" ]; then
67
- MODULE_COUNT=$(find .pi/architecture/modules -name "*.md" 2>/dev/null | wc -l | tr -d ' ')
67
+ MODULE_COUNT=$(find .pi/architecture/modules -name "*.md" 2>/dev/null | wc -l | tr -d ' ') || true
68
68
  if [ "$MODULE_COUNT" -gt 0 ]; then
69
69
  pass "Architecture modules defined ($MODULE_COUNT module files)"
70
70
  else
@@ -43,7 +43,7 @@ CANONICAL_REFS=0
43
43
  TOTAL_RS=0
44
44
 
45
45
  # Count all Rust source files
46
- TOTAL_RS=$(find src -name "*.rs" 2>/dev/null | wc -l | tr -d ' ')
46
+ TOTAL_RS=$(find src -name "*.rs" 2>/dev/null | wc -l | tr -d ' ') || true
47
47
  if [ "$TOTAL_RS" -gt 0 ]; then
48
48
  # Look for canonical reference patterns in doc comments
49
49
  CANONICAL_REFS=$(grep -rE '(///\s*Canonical:|//!\s*@canonical|///\s*Reference:)' src/ 2>/dev/null | wc -l | tr -d ' ') || true
@@ -108,7 +108,7 @@ fi
108
108
  echo ""
109
109
  echo "--- ADR Linkage ---"
110
110
  if [ -d ".pi/architecture/decisions" ]; then
111
- ADR_FILES=$(find .pi/architecture/decisions -name "*.md" 2>/dev/null | wc -l | tr -d ' ')
111
+ ADR_FILES=$(find .pi/architecture/decisions -name "*.md" 2>/dev/null | wc -l | tr -d ' ') || true
112
112
  if [ "$ADR_FILES" -gt 0 ]; then
113
113
  ADR_REFS=$(grep -rE '///\s*ADR-' src/ 2>/dev/null | wc -l | tr -d ' ') || true
114
114
  if [ "$ADR_REFS" -gt 0 ]; then
@@ -40,7 +40,7 @@ fi
40
40
  # ---------------------------------------------------------------------------
41
41
  echo "--- Integration Test Runner ---"
42
42
  if [ -d "tests" ]; then
43
- INT_TEST_FILES=$(find tests -name "*.rs" 2>/dev/null | wc -l | tr -d ' ')
43
+ INT_TEST_FILES=$(find tests -name "*.rs" 2>/dev/null | wc -l | tr -d ' ') || true
44
44
  if [ "$INT_TEST_FILES" -gt 0 ]; then
45
45
  if cargo test --test '*' --quiet 2>/dev/null; then
46
46
  pass "Integration tests passed ($INT_TEST_FILES test files)"
@@ -70,7 +70,7 @@ fi
70
70
  # ---------------------------------------------------------------------------
71
71
  echo ""
72
72
  echo "--- Contract Tests ---"
73
- CONTRACT_TESTS=$(find . -name "*contract*test*.rs" -o -name "*test*contract*.rs" 2>/dev/null | wc -l | tr -d ' ')
73
+ CONTRACT_TESTS=$(find . -name "*contract*test*.rs" -o -name "*test*contract*.rs" 2>/dev/null | wc -l | tr -d ' ') || true
74
74
  if [ "$CONTRACT_TESTS" -gt 0 ]; then
75
75
  pass "Contract test files found ($CONTRACT_TESTS)"
76
76
  else
@@ -101,7 +101,7 @@ fi
101
101
  # ---------------------------------------------------------------------------
102
102
  echo ""
103
103
  echo "--- Database Integration ---"
104
- DB_INTEG=$(find . -name "*_integration_test.rs" -o -name "*db*test*.rs" 2>/dev/null | wc -l | tr -d ' ')
104
+ DB_INTEG=$(find . -name "*_integration_test.rs" -o -name "*db*test*.rs" 2>/dev/null | wc -l | tr -d ' ') || true
105
105
  if [ "$DB_INTEG" -gt 0 ]; then
106
106
  pass "Database integration test files found ($DB_INTEG)"
107
107
  else
@@ -42,7 +42,7 @@ echo "--- Unit Tests ---"
42
42
  if cargo test --lib --quiet 2>/dev/null; then
43
43
  pass "Library unit tests passed"
44
44
  else
45
- LIB_SOURCES=$(find src -name "*.rs" 2>/dev/null | wc -l | tr -d ' ')
45
+ LIB_SOURCES=$(find src -name "*.rs" 2>/dev/null | wc -l | tr -d ' ') || true
46
46
  if [ "$LIB_SOURCES" -eq 0 ]; then
47
47
  pass "No library source files (skipped)"
48
48
  else
@@ -65,7 +65,7 @@ if [ -d "tests" ]; then
65
65
  fi
66
66
  else
67
67
  # Run all integration test files
68
- TEST_COUNT=$(find tests -name "*.rs" 2>/dev/null | wc -l | tr -d ' ')
68
+ TEST_COUNT=$(find tests -name "*.rs" 2>/dev/null | wc -l | tr -d ' ') || true
69
69
  if [ "$TEST_COUNT" -gt 0 ]; then
70
70
  if cargo test --test '*' --quiet 2>/dev/null; then
71
71
  pass "Integration tests passed"
@@ -44,7 +44,7 @@ fi
44
44
  echo ""
45
45
  echo "--- Canonical References ---"
46
46
  if [ -d ".pi/architecture/modules" ]; then
47
- MODULE_COUNT=$(find .pi/architecture/modules -name "*.md" 2>/dev/null | wc -l | tr -d ' ')
47
+ MODULE_COUNT=$(find .pi/architecture/modules -name "*.md" 2>/dev/null | wc -l | tr -d ' ') || true
48
48
  pass "Canonical architecture documents found ($MODULE_COUNT modules)"
49
49
  else
50
50
  warn "No .pi/architecture/modules directory found"
@@ -24,7 +24,7 @@ echo "--- Architecture Reference Tracing ---"
24
24
  CANONICAL_REFS=0
25
25
  TOTAL_TS_FILES=0
26
26
  if [ -d "$SRC_DIR" ]; then
27
- TOTAL_TS_FILES=$(find "$SRC_DIR" -name "*.ts" -o -name "*.tsx" 2>/dev/null | wc -l | tr -d ' ')
27
+ TOTAL_TS_FILES=$(find "$SRC_DIR" -name "*.ts" -o -name "*.tsx" 2>/dev/null | wc -l | tr -d ' ') || true
28
28
  CANONICAL_REFS=$(find "$SRC_DIR" -type f \( -name "*.ts" -o -name "*.tsx" \) -exec grep -lE '(// Canonical:|@canonical).*\.pi/architecture/' {} + 2>/dev/null | wc -l | tr -d ' ') || true
29
29
  if [ "$TOTAL_TS_FILES" -gt 0 ] && [ "$CANONICAL_REFS" -gt 0 ]; then
30
30
  PCT=$((CANONICAL_REFS * 100 / TOTAL_TS_FILES))
@@ -99,7 +99,7 @@ fi
99
99
  echo ""
100
100
  echo "--- ADR Linkage ---"
101
101
  if [ -d ".pi/architecture/decisions" ]; then
102
- ADR_FILES=$(find .pi/architecture/decisions -name "*.md" 2>/dev/null | wc -l | tr -d ' ')
102
+ ADR_FILES=$(find .pi/architecture/decisions -name "*.md" 2>/dev/null | wc -l | tr -d ' ') || true
103
103
  ADR_REFS=$(find "$SRC_DIR" -type f \( -name "*.ts" -o -name "*.tsx" \) -exec grep -rlE '(@adr|ADR-)' {} + 2>/dev/null | wc -l | tr -d ' ') || true
104
104
  if [ "$ADR_FILES" -gt 0 ] && [ "$ADR_REFS" -gt 0 ]; then
105
105
  pass "ADR references found: $ADR_REFS files link to $ADR_FILES decisions"
@@ -64,9 +64,9 @@ fi
64
64
  echo ""
65
65
  echo "--- Docker/Compose ---"
66
66
  if [ -f "docker-compose.yml" ] || [ -f "docker-compose.yaml" ]; then
67
- SERVICES=$(grep -E "^\s{2}\w+:" docker-compose.yml 2>/dev/null | grep -vE "^\s{2}version:|^\s{2}services:" | wc -l | tr -d ' ')
67
+ SERVICES=$(grep -E "^\s{2}\w+:" docker-compose.yml 2>/dev/null | grep -vE "^\s{2}version:|^\s{2}services:" | wc -l | tr -d ' ') || true
68
68
  if [ -f "docker-compose.yaml" ] && [ "$SERVICES" -eq 0 ]; then
69
- SERVICES=$(grep -E "^\s{2}\w+:" docker-compose.yaml 2>/dev/null | grep -vE "^\s{2}version:|^\s{2}services:" | wc -l | tr -d ' ')
69
+ SERVICES=$(grep -E "^\s{2}\w+:" docker-compose.yaml 2>/dev/null | grep -vE "^\s{2}version:|^\s{2}services:" | wc -l | tr -d ' ') || true
70
70
  fi
71
71
  pass "Docker Compose found ($SERVICES services — integration tests may require running services)"
72
72
  else
@@ -81,7 +81,7 @@ echo "--- Contract Tests ---"
81
81
  CONTRACT_FILES=0
82
82
  for dir in tests test; do
83
83
  if [ -d "$dir" ]; then
84
- COUNT=$(find "$dir" -name "*.contract.test.ts" -o -name "*.contract.test.tsx" 2>/dev/null | wc -l | tr -d ' ')
84
+ COUNT=$(find "$dir" -name "*.contract.test.ts" -o -name "*.contract.test.tsx" 2>/dev/null | wc -l | tr -d ' ') || true
85
85
  CONTRACT_FILES=$((CONTRACT_FILES + COUNT))
86
86
  fi
87
87
  done
@@ -116,7 +116,7 @@ echo "--- Database Integration ---"
116
116
  DB_INTEGRATION_FILES=0
117
117
  for dir in tests test; do
118
118
  if [ -d "$dir" ]; then
119
- COUNT=$(find "$dir" -name "*_integration.test.ts" -o -name "*_integration.test.tsx" -o -name "*.db.test.ts" -o -name "*.db.test.tsx" 2>/dev/null | wc -l | tr -d ' ')
119
+ COUNT=$(find "$dir" -name "*_integration.test.ts" -o -name "*_integration.test.tsx" -o -name "*.db.test.ts" -o -name "*.db.test.tsx" 2>/dev/null | wc -l | tr -d ' ') || true
120
120
  DB_INTEGRATION_FILES=$((DB_INTEGRATION_FILES + COUNT))
121
121
  fi
122
122
  done
@@ -121,7 +121,7 @@ if [ "$SANITIZE_LIBS" -gt 0 ]; then
121
121
  pass "Sanitization libraries detected ($SANITIZE_LIBS files)"
122
122
  else
123
123
  # Only warn if there are TSX files (likely has JSX/DOM rendering)
124
- TSX_COUNT=$(find . -name "*.tsx" -not -path "./node_modules/*" -not -path "./.next/*" -not -path "./dist/*" 2>/dev/null | wc -l | tr -d ' ')
124
+ TSX_COUNT=$(find . -name "*.tsx" -not -path "./node_modules/*" -not -path "./.next/*" -not -path "./dist/*" 2>/dev/null | wc -l | tr -d ' ') || true
125
125
  if [ "$TSX_COUNT" -gt 0 ]; then
126
126
  warn "No sanitization library found in TSX files (consider DOMPurify or sanitize-html)"
127
127
  else
@@ -137,7 +137,7 @@ echo "--- HTTPS Enforcement ---"
137
137
  HTTP_ONLY=0
138
138
  for ext in ts tsx; do
139
139
  COUNT=$(find . -name "*.$ext" -not -path "./node_modules/*" -not -path "./.next/*" -not -path "./dist/*" \
140
- -exec grep -E "['\"]http://(?!localhost)" {} + 2>/dev/null | grep -ivE "(test|spec|mock|example|dev)" | wc -l | tr -d ' ')
140
+ -exec grep -E "['\"]http://(?!localhost)" {} + 2>/dev/null | grep -ivE "(test|spec|mock|example|dev)" | wc -l | tr -d ' ') || true
141
141
  HTTP_ONLY=$((HTTP_ONLY + COUNT))
142
142
  done
143
143
  if [ "$HTTP_ONLY" -eq 0 ]; then