@vigolium/piolium 0.0.1

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 (271) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +117 -0
  3. package/agents/access-auditor.md +300 -0
  4. package/agents/assumption-breaker.md +154 -0
  5. package/agents/attack-designer.md +116 -0
  6. package/agents/code-scanner.md +139 -0
  7. package/agents/concurrency-auditor.md +238 -0
  8. package/agents/confirm-writer.md +257 -0
  9. package/agents/context-reviewer.md +274 -0
  10. package/agents/cross-verifier.md +165 -0
  11. package/agents/cve-scout.md +381 -0
  12. package/agents/env-builder.md +282 -0
  13. package/agents/env-profiler.md +205 -0
  14. package/agents/evidence-collector.md +140 -0
  15. package/agents/finding-grader.md +142 -0
  16. package/agents/finding-writer.md +148 -0
  17. package/agents/flow-tracer.md +106 -0
  18. package/agents/goal-backtracer.md +146 -0
  19. package/agents/history-miner.md +467 -0
  20. package/agents/independent-verifier.md +118 -0
  21. package/agents/intent-mapper.md +183 -0
  22. package/agents/longshot-collector.md +128 -0
  23. package/agents/longshot-prober.md +126 -0
  24. package/agents/patch-auditor.md +73 -0
  25. package/agents/poc-author.md +124 -0
  26. package/agents/poc-runner.md +194 -0
  27. package/agents/probe-lead.md +269 -0
  28. package/agents/red-challenger.md +101 -0
  29. package/agents/report-composer.md +208 -0
  30. package/agents/review-adjudicator.md +216 -0
  31. package/agents/spec-auditor.md +155 -0
  32. package/agents/taint-tracer.md +265 -0
  33. package/agents/test-locator.md +209 -0
  34. package/agents/threat-modeler.md +132 -0
  35. package/agents/variant-scanner.md +108 -0
  36. package/agents/variant-spotter.md +110 -0
  37. package/bin/piolium.mjs +376 -0
  38. package/extensions/piolium/_vendor/yaml.bundle.d.mts +6 -0
  39. package/extensions/piolium/_vendor/yaml.bundle.mjs +139 -0
  40. package/extensions/piolium/agent-runner.ts +322 -0
  41. package/extensions/piolium/agents.ts +266 -0
  42. package/extensions/piolium/audit-state.ts +522 -0
  43. package/extensions/piolium/bundled-resources.ts +97 -0
  44. package/extensions/piolium/candidate-scan.ts +966 -0
  45. package/extensions/piolium/command-target.ts +177 -0
  46. package/extensions/piolium/console-stream.ts +57 -0
  47. package/extensions/piolium/export-results.ts +380 -0
  48. package/extensions/piolium/findings.ts +448 -0
  49. package/extensions/piolium/heartbeat.ts +182 -0
  50. package/extensions/piolium/help.ts +234 -0
  51. package/extensions/piolium/index.ts +1865 -0
  52. package/extensions/piolium/longshot.ts +530 -0
  53. package/extensions/piolium/matcher-suggestions.ts +196 -0
  54. package/extensions/piolium/matcher-utils.ts +83 -0
  55. package/extensions/piolium/modes/balanced.ts +750 -0
  56. package/extensions/piolium/modes/confirm-bootstrap.ts +186 -0
  57. package/extensions/piolium/modes/confirm.ts +697 -0
  58. package/extensions/piolium/modes/deep.ts +917 -0
  59. package/extensions/piolium/modes/diff.ts +177 -0
  60. package/extensions/piolium/modes/lite.ts +540 -0
  61. package/extensions/piolium/modes/longshot.ts +595 -0
  62. package/extensions/piolium/modes/merge.ts +204 -0
  63. package/extensions/piolium/modes/phase-runner.ts +267 -0
  64. package/extensions/piolium/modes/reinvest.ts +546 -0
  65. package/extensions/piolium/modes/revisit.ts +279 -0
  66. package/extensions/piolium/modes.ts +48 -0
  67. package/extensions/piolium/phase-labels.ts +123 -0
  68. package/extensions/piolium/phase-status-strip.ts +92 -0
  69. package/extensions/piolium/prompt-prefix-editor.ts +39 -0
  70. package/extensions/piolium/providers/anthropic-vertex.ts +836 -0
  71. package/extensions/piolium/recon.ts +409 -0
  72. package/extensions/piolium/result-stats.ts +105 -0
  73. package/extensions/piolium/retry.ts +120 -0
  74. package/extensions/piolium/scheduler.ts +212 -0
  75. package/extensions/piolium/secrets.ts +368 -0
  76. package/extensions/piolium/tools/web-tools.ts +148 -0
  77. package/package.json +77 -0
  78. package/skills/agentic-actions-auditor/SKILL.md +327 -0
  79. package/skills/agentic-actions-auditor/references/action-profiles.md +186 -0
  80. package/skills/agentic-actions-auditor/references/cross-file-resolution.md +209 -0
  81. package/skills/agentic-actions-auditor/references/foundations.md +94 -0
  82. package/skills/agentic-actions-auditor/references/vector-a-env-var-intermediary.md +77 -0
  83. package/skills/agentic-actions-auditor/references/vector-b-direct-expression-injection.md +83 -0
  84. package/skills/agentic-actions-auditor/references/vector-c-cli-data-fetch.md +83 -0
  85. package/skills/agentic-actions-auditor/references/vector-d-pr-target-checkout.md +88 -0
  86. package/skills/agentic-actions-auditor/references/vector-e-error-log-injection.md +88 -0
  87. package/skills/agentic-actions-auditor/references/vector-f-subshell-expansion.md +82 -0
  88. package/skills/agentic-actions-auditor/references/vector-g-eval-of-ai-output.md +91 -0
  89. package/skills/agentic-actions-auditor/references/vector-h-dangerous-sandbox-configs.md +102 -0
  90. package/skills/agentic-actions-auditor/references/vector-i-wildcard-allowlists.md +88 -0
  91. package/skills/audit/SKILL.md +562 -0
  92. package/skills/audit/assets/icon.svg +7 -0
  93. package/skills/audit/hooks/scripts/validate_phase_output.py +550 -0
  94. package/skills/audit/references/adversarial-review.md +148 -0
  95. package/skills/audit/references/architecture-aware-sast.md +306 -0
  96. package/skills/audit/references/audit-workflow.md +737 -0
  97. package/skills/audit/references/chamber-protocol.md +384 -0
  98. package/skills/audit/references/creative-attack-modes.md +221 -0
  99. package/skills/audit/references/deep-analysis.md +273 -0
  100. package/skills/audit/references/domain-attack-playbooks.md +1129 -0
  101. package/skills/audit/references/knowledge-base-template.md +513 -0
  102. package/skills/audit/references/real-env-validation.md +191 -0
  103. package/skills/audit/references/report-templates.md +417 -0
  104. package/skills/audit/references/triage-and-prereqs.md +134 -0
  105. package/skills/audit/scripts/consolidate_drafts.py +554 -0
  106. package/skills/audit/scripts/partition_findings.py +152 -0
  107. package/skills/audit/scripts/rg-hotspots.sh +121 -0
  108. package/skills/audit/scripts/stamp_file_state.py +349 -0
  109. package/skills/code-reviewer/SKILL.md +65 -0
  110. package/skills/codeql/SKILL.md +281 -0
  111. package/skills/codeql/references/build-fixes.md +90 -0
  112. package/skills/codeql/references/diagnostic-query-templates.md +339 -0
  113. package/skills/codeql/references/extension-yaml-format.md +209 -0
  114. package/skills/codeql/references/important-only-suite.md +153 -0
  115. package/skills/codeql/references/language-details.md +207 -0
  116. package/skills/codeql/references/macos-arm64e-workaround.md +179 -0
  117. package/skills/codeql/references/performance-tuning.md +111 -0
  118. package/skills/codeql/references/quality-assessment.md +172 -0
  119. package/skills/codeql/references/ruleset-catalog.md +63 -0
  120. package/skills/codeql/references/run-all-suite.md +92 -0
  121. package/skills/codeql/references/sarif-processing.md +79 -0
  122. package/skills/codeql/references/threat-models.md +51 -0
  123. package/skills/codeql/workflows/build-database.md +280 -0
  124. package/skills/codeql/workflows/create-data-extensions.md +261 -0
  125. package/skills/codeql/workflows/run-analysis.md +301 -0
  126. package/skills/differential-review/SKILL.md +220 -0
  127. package/skills/differential-review/adversarial.md +203 -0
  128. package/skills/differential-review/methodology.md +234 -0
  129. package/skills/differential-review/patterns.md +300 -0
  130. package/skills/differential-review/reporting.md +369 -0
  131. package/skills/fp-check/SKILL.md +125 -0
  132. package/skills/fp-check/references/bug-class-verification.md +114 -0
  133. package/skills/fp-check/references/deep-verification.md +143 -0
  134. package/skills/fp-check/references/evidence-templates.md +91 -0
  135. package/skills/fp-check/references/false-positive-patterns.md +115 -0
  136. package/skills/fp-check/references/gate-reviews.md +27 -0
  137. package/skills/fp-check/references/standard-verification.md +78 -0
  138. package/skills/insecure-defaults/SKILL.md +117 -0
  139. package/skills/insecure-defaults/references/examples.md +409 -0
  140. package/skills/last30days/SKILL.md +444 -0
  141. package/skills/sarif-parsing/SKILL.md +483 -0
  142. package/skills/sarif-parsing/resources/jq-queries.md +162 -0
  143. package/skills/sarif-parsing/resources/sarif_helpers.py +331 -0
  144. package/skills/security-threat-model/LICENSE.txt +201 -0
  145. package/skills/security-threat-model/SKILL.md +81 -0
  146. package/skills/security-threat-model/agents/openai.yaml +4 -0
  147. package/skills/security-threat-model/references/prompt-template.md +255 -0
  148. package/skills/security-threat-model/references/security-controls-and-assets.md +32 -0
  149. package/skills/semgrep/SKILL.md +212 -0
  150. package/skills/semgrep/references/rulesets.md +162 -0
  151. package/skills/semgrep/references/scan-modes.md +110 -0
  152. package/skills/semgrep/references/scanner-task-prompt.md +140 -0
  153. package/skills/semgrep/scripts/merge_sarif.py +203 -0
  154. package/skills/semgrep/workflows/scan-workflow.md +311 -0
  155. package/skills/semgrep-rule-creator/SKILL.md +168 -0
  156. package/skills/semgrep-rule-creator/references/quick-reference.md +202 -0
  157. package/skills/semgrep-rule-creator/references/workflow.md +240 -0
  158. package/skills/semgrep-rule-variant-creator/SKILL.md +205 -0
  159. package/skills/semgrep-rule-variant-creator/references/applicability-analysis.md +250 -0
  160. package/skills/semgrep-rule-variant-creator/references/language-syntax-guide.md +324 -0
  161. package/skills/semgrep-rule-variant-creator/references/workflow.md +518 -0
  162. package/skills/sharp-edges/SKILL.md +292 -0
  163. package/skills/sharp-edges/references/auth-patterns.md +252 -0
  164. package/skills/sharp-edges/references/case-studies.md +274 -0
  165. package/skills/sharp-edges/references/config-patterns.md +333 -0
  166. package/skills/sharp-edges/references/crypto-apis.md +190 -0
  167. package/skills/sharp-edges/references/lang-c.md +205 -0
  168. package/skills/sharp-edges/references/lang-csharp.md +285 -0
  169. package/skills/sharp-edges/references/lang-go.md +270 -0
  170. package/skills/sharp-edges/references/lang-java.md +263 -0
  171. package/skills/sharp-edges/references/lang-javascript.md +269 -0
  172. package/skills/sharp-edges/references/lang-kotlin.md +265 -0
  173. package/skills/sharp-edges/references/lang-php.md +245 -0
  174. package/skills/sharp-edges/references/lang-python.md +274 -0
  175. package/skills/sharp-edges/references/lang-ruby.md +273 -0
  176. package/skills/sharp-edges/references/lang-rust.md +272 -0
  177. package/skills/sharp-edges/references/lang-swift.md +287 -0
  178. package/skills/sharp-edges/references/language-specific.md +588 -0
  179. package/skills/spec-to-code-compliance/SKILL.md +357 -0
  180. package/skills/spec-to-code-compliance/resources/COMPLETENESS_CHECKLIST.md +69 -0
  181. package/skills/spec-to-code-compliance/resources/IR_EXAMPLES.md +417 -0
  182. package/skills/spec-to-code-compliance/resources/OUTPUT_REQUIREMENTS.md +105 -0
  183. package/skills/supply-chain-risk-auditor/SKILL.md +67 -0
  184. package/skills/supply-chain-risk-auditor/resources/results-template.md +41 -0
  185. package/skills/variant-analysis/METHODOLOGY.md +327 -0
  186. package/skills/variant-analysis/SKILL.md +142 -0
  187. package/skills/variant-analysis/resources/codeql/cpp.ql +119 -0
  188. package/skills/variant-analysis/resources/codeql/go.ql +69 -0
  189. package/skills/variant-analysis/resources/codeql/java.ql +71 -0
  190. package/skills/variant-analysis/resources/codeql/javascript.ql +63 -0
  191. package/skills/variant-analysis/resources/codeql/python.ql +80 -0
  192. package/skills/variant-analysis/resources/semgrep/cpp.yaml +98 -0
  193. package/skills/variant-analysis/resources/semgrep/go.yaml +63 -0
  194. package/skills/variant-analysis/resources/semgrep/java.yaml +61 -0
  195. package/skills/variant-analysis/resources/semgrep/javascript.yaml +60 -0
  196. package/skills/variant-analysis/resources/semgrep/python.yaml +72 -0
  197. package/skills/variant-analysis/resources/variant-report-template.md +75 -0
  198. package/skills/vuln-report/SKILL.md +137 -0
  199. package/skills/vuln-report/agents/openai.yaml +4 -0
  200. package/skills/vuln-report/references/report-template.md +135 -0
  201. package/skills/wooyun-legacy/SKILL.md +367 -0
  202. package/skills/wooyun-legacy/references/bank-penetration.md +222 -0
  203. package/skills/wooyun-legacy/references/checklists/command-execution-checklist.md +119 -0
  204. package/skills/wooyun-legacy/references/checklists/csrf-checklist.md +74 -0
  205. package/skills/wooyun-legacy/references/checklists/file-upload-checklist.md +108 -0
  206. package/skills/wooyun-legacy/references/checklists/info-disclosure-checklist.md +114 -0
  207. package/skills/wooyun-legacy/references/checklists/logic-flaws-checklist.md +95 -0
  208. package/skills/wooyun-legacy/references/checklists/misconfig-checklist.md +124 -0
  209. package/skills/wooyun-legacy/references/checklists/path-traversal-checklist.md +87 -0
  210. package/skills/wooyun-legacy/references/checklists/rce-checklist.md +93 -0
  211. package/skills/wooyun-legacy/references/checklists/sql-injection-checklist.md +97 -0
  212. package/skills/wooyun-legacy/references/checklists/ssrf-checklist.md +99 -0
  213. package/skills/wooyun-legacy/references/checklists/unauthorized-access-checklist.md +89 -0
  214. package/skills/wooyun-legacy/references/checklists/weak-password-checklist.md +115 -0
  215. package/skills/wooyun-legacy/references/checklists/xss-checklist.md +103 -0
  216. package/skills/wooyun-legacy/references/checklists/xxe-checklist.md +130 -0
  217. package/skills/wooyun-legacy/references/info-disclosure.md +975 -0
  218. package/skills/wooyun-legacy/references/logic-flaws.md +721 -0
  219. package/skills/wooyun-legacy/references/path-traversal.md +1191 -0
  220. package/skills/wooyun-legacy/references/telecom-penetration.md +156 -0
  221. package/skills/wooyun-legacy/references/unauthorized-access.md +980 -0
  222. package/skills/wooyun-legacy/references/xss.md +746 -0
  223. package/skills/zeroize-audit/SKILL.md +371 -0
  224. package/skills/zeroize-audit/configs/c.yaml +21 -0
  225. package/skills/zeroize-audit/configs/default.yaml +128 -0
  226. package/skills/zeroize-audit/configs/rust.yaml +83 -0
  227. package/skills/zeroize-audit/prompts/report_template.md +238 -0
  228. package/skills/zeroize-audit/prompts/system.md +163 -0
  229. package/skills/zeroize-audit/prompts/task.md +97 -0
  230. package/skills/zeroize-audit/references/compile-commands.md +231 -0
  231. package/skills/zeroize-audit/references/detection-strategy.md +191 -0
  232. package/skills/zeroize-audit/references/ir-analysis.md +252 -0
  233. package/skills/zeroize-audit/references/mcp-analysis.md +221 -0
  234. package/skills/zeroize-audit/references/poc-generation.md +470 -0
  235. package/skills/zeroize-audit/references/rust-zeroization-patterns.md +867 -0
  236. package/skills/zeroize-audit/schemas/input.json +83 -0
  237. package/skills/zeroize-audit/schemas/output.json +140 -0
  238. package/skills/zeroize-audit/tools/analyze_asm.sh +202 -0
  239. package/skills/zeroize-audit/tools/analyze_cfg.py +381 -0
  240. package/skills/zeroize-audit/tools/analyze_heap.sh +211 -0
  241. package/skills/zeroize-audit/tools/analyze_ir_semantic.py +429 -0
  242. package/skills/zeroize-audit/tools/diff_ir.sh +135 -0
  243. package/skills/zeroize-audit/tools/diff_rust_mir.sh +189 -0
  244. package/skills/zeroize-audit/tools/emit_asm.sh +67 -0
  245. package/skills/zeroize-audit/tools/emit_ir.sh +77 -0
  246. package/skills/zeroize-audit/tools/emit_rust_asm.sh +178 -0
  247. package/skills/zeroize-audit/tools/emit_rust_ir.sh +150 -0
  248. package/skills/zeroize-audit/tools/emit_rust_mir.sh +158 -0
  249. package/skills/zeroize-audit/tools/extract_compile_flags.py +284 -0
  250. package/skills/zeroize-audit/tools/generate_poc.py +1329 -0
  251. package/skills/zeroize-audit/tools/mcp/apply_confidence_gates.py +113 -0
  252. package/skills/zeroize-audit/tools/mcp/check_mcp.sh +68 -0
  253. package/skills/zeroize-audit/tools/mcp/normalize_mcp_evidence.py +125 -0
  254. package/skills/zeroize-audit/tools/scripts/check_llvm_patterns.py +481 -0
  255. package/skills/zeroize-audit/tools/scripts/check_mir_patterns.py +554 -0
  256. package/skills/zeroize-audit/tools/scripts/check_rust_asm.py +424 -0
  257. package/skills/zeroize-audit/tools/scripts/check_rust_asm_aarch64.py +300 -0
  258. package/skills/zeroize-audit/tools/scripts/check_rust_asm_x86.py +283 -0
  259. package/skills/zeroize-audit/tools/scripts/find_dangerous_apis.py +375 -0
  260. package/skills/zeroize-audit/tools/scripts/semantic_audit.py +923 -0
  261. package/skills/zeroize-audit/tools/track_dataflow.sh +196 -0
  262. package/skills/zeroize-audit/tools/validate_rust_toolchain.sh +298 -0
  263. package/skills/zeroize-audit/workflows/phase-0-preflight.md +150 -0
  264. package/skills/zeroize-audit/workflows/phase-1-source-analysis.md +144 -0
  265. package/skills/zeroize-audit/workflows/phase-2-compiler-analysis.md +139 -0
  266. package/skills/zeroize-audit/workflows/phase-3-interim-report.md +46 -0
  267. package/skills/zeroize-audit/workflows/phase-4-poc-generation.md +46 -0
  268. package/skills/zeroize-audit/workflows/phase-5-poc-validation.md +136 -0
  269. package/skills/zeroize-audit/workflows/phase-6-final-report.md +44 -0
  270. package/skills/zeroize-audit/workflows/phase-7-test-generation.md +42 -0
  271. package/themes/piolium-srcery.json +94 -0
@@ -0,0 +1,196 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ # Track data-flow of sensitive variables to detect untracked copies.
5
+ #
6
+ # Usage:
7
+ # track_dataflow.sh --src path/to/file.c --config config.yaml --out /tmp/dataflow.json
8
+ #
9
+ # Detects:
10
+ # - memcpy/memmove of sensitive buffers
11
+ # - Struct assignments (potential copies)
12
+ # - Function arguments passed by value
13
+ # - Return by value (secrets in return values)
14
+
15
+ usage() {
16
+ echo "Usage: $0 --src <file> --out <analysis.json> [--config <config.yaml>]" >&2
17
+ }
18
+
19
+ json_escape() {
20
+ local s="$1"
21
+ s="${s//\\/\\\\}"
22
+ s="${s//\"/\\\"}"
23
+ s="${s//$'\n'/\\n}"
24
+ s="${s//$'\t'/\\t}"
25
+ printf '%s' "$s"
26
+ }
27
+
28
+ SRC=""
29
+ CONFIG=""
30
+ OUT=""
31
+
32
+ while [[ $# -gt 0 ]]; do
33
+ case "$1" in
34
+ --src)
35
+ SRC="$2"
36
+ shift 2
37
+ ;;
38
+ --config)
39
+ CONFIG="$2"
40
+ shift 2
41
+ ;;
42
+ --out)
43
+ OUT="$2"
44
+ shift 2
45
+ ;;
46
+ *)
47
+ echo "Unknown arg: $1" >&2
48
+ usage
49
+ exit 2
50
+ ;;
51
+ esac
52
+ done
53
+
54
+ if [[ -z "$SRC" || -z "$OUT" ]]; then
55
+ usage
56
+ exit 2
57
+ fi
58
+
59
+ if [[ ! -f "$SRC" ]]; then
60
+ echo "Source file not found: $SRC" >&2
61
+ exit 2
62
+ fi
63
+
64
+ # Load sensitive name patterns from config (if provided)
65
+ SENSITIVE_PATTERN="(secret|key|seed|priv|private|sk|shared_secret|nonce|token|pwd|pass)"
66
+ if [[ -n "$CONFIG" ]] && [[ -f "$CONFIG" ]]; then
67
+ # Extract patterns from YAML (POSIX-compatible, no grep -P)
68
+ PATTERNS=$(grep -A 20 "^sensitive_name_regex:" "$CONFIG" | sed -n 's/.*"\([^"]*\)".*/\1/p' | head -1 || echo "")
69
+ if [[ -n "$PATTERNS" ]]; then
70
+ SENSITIVE_PATTERN="$PATTERNS"
71
+ else
72
+ echo "WARNING: config file provided but no patterns extracted from $CONFIG" >&2
73
+ fi
74
+ fi
75
+
76
+ # Arrays to collect findings
77
+ MEMCPY_COPIES=()
78
+ STRUCT_ASSIGNS=()
79
+ FUNC_ARGS=()
80
+ RETURN_VALUES=()
81
+ RETURN_RE='return[[:space:]]+([a-zA-Z_][a-zA-Z0-9_]*)[[:space:]]*;'
82
+ CALL_RE='([a-zA-Z_][a-zA-Z0-9_]*)[[:space:]]*\(([^)]*)\)'
83
+
84
+ # Parse source code
85
+ LINE_NUM=0
86
+ IN_FUNCTION=""
87
+
88
+ while IFS= read -r line; do
89
+ ((LINE_NUM++))
90
+
91
+ # Skip comments (simple heuristic)
92
+ [[ "$line" =~ ^[[:space:]]*// ]] && continue
93
+ [[ "$line" =~ ^[[:space:]]*\* ]] && continue
94
+
95
+ # Track function boundaries
96
+ if [[ "$line" =~ ^[a-zA-Z_][a-zA-Z0-9_]*[[:space:]]+([a-zA-Z_][a-zA-Z0-9_]*)[[:space:]]*\( ]]; then
97
+ IN_FUNCTION="${BASH_REMATCH[1]}"
98
+ fi
99
+
100
+ # Detect memcpy/memmove of sensitive data
101
+ if [[ "$line" =~ (memcpy|memmove)[[:space:]]*\([^,]*,[[:space:]]*([a-zA-Z_][a-zA-Z0-9_]*) ]]; then
102
+ FUNC="${BASH_REMATCH[1]}"
103
+ SRC_VAR="${BASH_REMATCH[2]}"
104
+ if [[ "$SRC_VAR" =~ $SENSITIVE_PATTERN ]]; then
105
+ MEMCPY_COPIES+=("{\"line\": $LINE_NUM, \"function\": \"$FUNC\", \"variable\": \"$SRC_VAR\", \"context\": \"$(json_escape "$line")\"}")
106
+ fi
107
+ fi
108
+
109
+ # Detect struct assignments (potential copies)
110
+ if [[ "$line" =~ ([a-zA-Z_][a-zA-Z0-9_]*)[[:space:]]*=[[:space:]]*\*([a-zA-Z_][a-zA-Z0-9_]*) ]]; then
111
+ DEST="${BASH_REMATCH[1]}"
112
+ MATCH_SRC="${BASH_REMATCH[2]}"
113
+ if [[ "$MATCH_SRC" =~ $SENSITIVE_PATTERN ]] || [[ "$DEST" =~ $SENSITIVE_PATTERN ]]; then
114
+ STRUCT_ASSIGNS+=("{\"line\": $LINE_NUM, \"dest\": \"$DEST\", \"source\": \"$MATCH_SRC\", \"context\": \"$(json_escape "$line")\"}")
115
+ fi
116
+ fi
117
+
118
+ # Detect return by value
119
+ if [[ "$line" =~ $RETURN_RE ]]; then
120
+ RET_VAR="${BASH_REMATCH[1]}"
121
+ if [[ "$RET_VAR" =~ $SENSITIVE_PATTERN ]]; then
122
+ RETURN_VALUES+=("{\"line\": $LINE_NUM, \"function\": \"$IN_FUNCTION\", \"variable\": \"$RET_VAR\", \"context\": \"$(json_escape "$line")\"}")
123
+ fi
124
+ fi
125
+
126
+ # Detect function calls with sensitive arguments (simple heuristic)
127
+ if [[ "$line" =~ $CALL_RE ]]; then
128
+ CALLED_FUNC="${BASH_REMATCH[1]}"
129
+ ARGS="${BASH_REMATCH[2]}"
130
+ # Check if any argument matches sensitive pattern
131
+ if [[ "$ARGS" =~ $SENSITIVE_PATTERN ]]; then
132
+ # Extract variable names from arguments
133
+ for arg in ${ARGS//,/ }; do
134
+ arg="${arg#"${arg%%[! ]*}"}" # trim leading spaces
135
+ arg="${arg%"${arg##*[! ]}"}" # trim trailing spaces
136
+ if [[ "$arg" =~ ^[a-zA-Z_][a-zA-Z0-9_]*$ ]] && [[ "$arg" =~ $SENSITIVE_PATTERN ]]; then
137
+ FUNC_ARGS+=("{\"line\": $LINE_NUM, \"called_function\": \"$CALLED_FUNC\", \"argument\": \"$arg\", \"context\": \"$(json_escape "$line")\"}")
138
+ fi
139
+ done
140
+ fi
141
+ fi
142
+
143
+ done <"$SRC"
144
+
145
+ # Generate JSON report
146
+ mkdir -p "$(dirname "$OUT")"
147
+
148
+ cat >"$OUT" <<EOF
149
+ {
150
+ "source_file": "$SRC",
151
+ "sensitive_pattern": "$SENSITIVE_PATTERN",
152
+ "findings": {
153
+ "memcpy_copies": [
154
+ $(
155
+ IFS=,
156
+ echo "${MEMCPY_COPIES[*]}"
157
+ )
158
+ ],
159
+ "struct_assignments": [
160
+ $(
161
+ IFS=,
162
+ echo "${STRUCT_ASSIGNS[*]}"
163
+ )
164
+ ],
165
+ "function_arguments": [
166
+ $(
167
+ IFS=,
168
+ echo "${FUNC_ARGS[*]}"
169
+ )
170
+ ],
171
+ "return_values": [
172
+ $(
173
+ IFS=,
174
+ echo "${RETURN_VALUES[*]}"
175
+ )
176
+ ]
177
+ },
178
+ "summary": {
179
+ "total_copies": $((${#MEMCPY_COPIES[@]} + ${#STRUCT_ASSIGNS[@]} + ${#FUNC_ARGS[@]} + ${#RETURN_VALUES[@]})),
180
+ "memcpy_count": ${#MEMCPY_COPIES[@]},
181
+ "struct_assign_count": ${#STRUCT_ASSIGNS[@]},
182
+ "func_arg_count": ${#FUNC_ARGS[@]},
183
+ "return_value_count": ${#RETURN_VALUES[@]}
184
+ }
185
+ }
186
+ EOF
187
+
188
+ # Validate JSON output
189
+ if command -v jq &>/dev/null; then
190
+ if ! jq empty "$OUT" 2>/dev/null; then
191
+ echo "ERROR: generated JSON is malformed: $OUT" >&2
192
+ exit 1
193
+ fi
194
+ fi
195
+
196
+ echo "OK: data-flow analysis written to $OUT"
@@ -0,0 +1,298 @@
1
+ #!/usr/bin/env bash
2
+ # validate_rust_toolchain.sh — Preflight check for Rust zeroize-audit prerequisites.
3
+ #
4
+ # Validates that all tools required by the Rust analysis pipeline are available
5
+ # and functional. Outputs a JSON status report.
6
+ #
7
+ # Exit codes:
8
+ # 0 all required tools available (warnings may still be present)
9
+ # 1 at least one required tool is missing
10
+ # 2 argument error
11
+
12
+ set -euo pipefail
13
+
14
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
15
+
16
+ usage() {
17
+ cat <<'EOF'
18
+ Usage:
19
+ validate_rust_toolchain.sh [options]
20
+
21
+ Options:
22
+ --manifest <Cargo.toml> Check that the manifest exists and the crate builds
23
+ --json Output machine-readable JSON (default: human-readable)
24
+ --help Show this help text
25
+
26
+ Checks (required):
27
+ - cargo on PATH
28
+ - cargo +nightly available
29
+ - uv on PATH (for Python analysis scripts)
30
+
31
+ Checks (optional, warning only):
32
+ - rustfilt on PATH (for symbol demangling)
33
+ - cargo-expand on PATH (for macro expansion debugging)
34
+
35
+ If --manifest is provided, additionally:
36
+ - Manifest file exists
37
+ - cargo check passes for the crate
38
+ EOF
39
+ }
40
+
41
+ die_arg() {
42
+ echo "validate_rust_toolchain.sh: $*" >&2
43
+ exit 2
44
+ }
45
+
46
+ MANIFEST=""
47
+ JSON_OUTPUT=false
48
+
49
+ while [[ $# -gt 0 ]]; do
50
+ case "$1" in
51
+ --manifest)
52
+ [[ -n "${2-}" ]] || die_arg "missing value for --manifest"
53
+ MANIFEST="$2"
54
+ shift 2
55
+ ;;
56
+ --json)
57
+ JSON_OUTPUT=true
58
+ shift
59
+ ;;
60
+ --help | -h)
61
+ usage
62
+ exit 0
63
+ ;;
64
+ *)
65
+ die_arg "unknown argument: $1"
66
+ ;;
67
+ esac
68
+ done
69
+
70
+ # ---------------------------------------------------------------------------
71
+ # Tool checks
72
+ # ---------------------------------------------------------------------------
73
+
74
+ declare -A TOOL_STATUS
75
+ declare -A TOOL_VERSION
76
+ ERRORS=()
77
+ WARNINGS=()
78
+
79
+ check_tool() {
80
+ local name="$1"
81
+ local required="$2"
82
+ local cmd="${3:-$name}"
83
+
84
+ if command -v "$cmd" &>/dev/null; then
85
+ TOOL_STATUS["$name"]="present"
86
+ local ver
87
+ # Use a separate variable so we can distinguish a version-check failure
88
+ # (e.g. shared-library missing) from the tool simply not being on PATH.
89
+ if ver=$("$cmd" --version 2>/dev/null | head -1); then
90
+ TOOL_VERSION["$name"]="$ver"
91
+ else
92
+ TOOL_VERSION["$name"]="(version check failed)"
93
+ WARNINGS+=("$name is present but '--version' failed — tool may be broken")
94
+ fi
95
+ else
96
+ if [[ "$required" == "true" ]]; then
97
+ TOOL_STATUS["$name"]="missing"
98
+ ERRORS+=("$name is required but not found on PATH")
99
+ else
100
+ TOOL_STATUS["$name"]="missing"
101
+ WARNINGS+=("$name is not found on PATH (optional: ${4:-enhanced analysis})")
102
+ fi
103
+ fi
104
+ }
105
+
106
+ check_tool "cargo" "true"
107
+ check_tool "uv" "true"
108
+ check_tool "rustfilt" "false" "rustfilt" "Rust symbol demangling in assembly analysis"
109
+ check_tool "cargo-expand" "false" "cargo-expand" "macro expansion debugging"
110
+
111
+ # Check cargo +nightly
112
+ NIGHTLY_STATUS="unavailable"
113
+ NIGHTLY_VERSION="unknown"
114
+ if [[ "${TOOL_STATUS[cargo]}" == "present" ]]; then
115
+ if cargo +nightly --version &>/dev/null 2>&1; then
116
+ NIGHTLY_STATUS="available"
117
+ NIGHTLY_VERSION=$(cargo +nightly --version 2>/dev/null | head -1 || echo "unknown")
118
+ else
119
+ NIGHTLY_STATUS="unavailable"
120
+ ERRORS+=("cargo +nightly is required but the nightly toolchain is not installed (run: rustup toolchain install nightly)")
121
+ fi
122
+ fi
123
+
124
+ # Check that emit/analysis scripts exist
125
+ declare -A SCRIPT_STATUS
126
+ REQUIRED_SCRIPTS=(
127
+ "emit_rust_mir.sh"
128
+ "emit_rust_ir.sh"
129
+ "emit_rust_asm.sh"
130
+ )
131
+ OPTIONAL_SCRIPTS=(
132
+ "diff_rust_mir.sh"
133
+ "scripts/check_mir_patterns.py"
134
+ "scripts/check_llvm_patterns.py"
135
+ "scripts/check_rust_asm.py"
136
+ "scripts/semantic_audit.py"
137
+ "scripts/find_dangerous_apis.py"
138
+ )
139
+
140
+ for script in "${REQUIRED_SCRIPTS[@]}"; do
141
+ if [[ -f "$SCRIPT_DIR/$script" ]]; then
142
+ SCRIPT_STATUS["$script"]="present"
143
+ else
144
+ SCRIPT_STATUS["$script"]="missing"
145
+ ERRORS+=("required script $script not found at $SCRIPT_DIR/$script")
146
+ fi
147
+ done
148
+
149
+ for script in "${OPTIONAL_SCRIPTS[@]}"; do
150
+ if [[ -f "$SCRIPT_DIR/$script" ]]; then
151
+ SCRIPT_STATUS["$script"]="present"
152
+ else
153
+ SCRIPT_STATUS["$script"]="missing"
154
+ WARNINGS+=("optional script $script not found at $SCRIPT_DIR/$script")
155
+ fi
156
+ done
157
+
158
+ # Check manifest and crate build (if requested)
159
+ MANIFEST_STATUS="not_checked"
160
+ BUILD_STATUS="not_checked"
161
+ if [[ -n "$MANIFEST" ]]; then
162
+ if [[ -f "$MANIFEST" ]]; then
163
+ MANIFEST_STATUS="present"
164
+ if [[ "$NIGHTLY_STATUS" == "available" ]]; then
165
+ cargo_err=$(mktemp) || {
166
+ ERRORS+=("mktemp failed — cannot capture cargo output")
167
+ cargo_err="/dev/null"
168
+ }
169
+ if cargo +nightly check --manifest-path "$MANIFEST" 2>"$cargo_err"; then
170
+ BUILD_STATUS="pass"
171
+ else
172
+ BUILD_STATUS="fail"
173
+ # Include up to 20 lines of cargo output so callers can diagnose
174
+ # the failure without re-running manually.
175
+ cargo_snippet=$(head -20 "$cargo_err" 2>/dev/null | tr '\n' ' ')
176
+ ERRORS+=("cargo check failed for $MANIFEST: ${cargo_snippet:-see stderr}")
177
+ fi
178
+ rm -f "$cargo_err"
179
+ else
180
+ BUILD_STATUS="skipped"
181
+ WARNINGS+=("cargo check skipped (nightly not available)")
182
+ fi
183
+ else
184
+ MANIFEST_STATUS="missing"
185
+ ERRORS+=("manifest not found: $MANIFEST")
186
+ fi
187
+ fi
188
+
189
+ # ---------------------------------------------------------------------------
190
+ # Output
191
+ # ---------------------------------------------------------------------------
192
+
193
+ OVERALL_STATUS="ready"
194
+ [[ ${#ERRORS[@]} -gt 0 ]] && OVERALL_STATUS="blocked"
195
+
196
+ if [[ "$JSON_OUTPUT" == true ]]; then
197
+ # Build tool statuses as JSON
198
+ TOOLS_JSON="{"
199
+ first=true
200
+ for name in cargo uv rustfilt cargo-expand; do
201
+ [[ "$first" == true ]] && first=false || TOOLS_JSON+=","
202
+ TOOLS_JSON+="\"$name\":{\"status\":\"${TOOL_STATUS[$name]:-unknown}\",\"version\":\"${TOOL_VERSION[$name]:-unknown}\"}"
203
+ done
204
+ TOOLS_JSON+="}"
205
+
206
+ # Build script statuses as JSON
207
+ SCRIPTS_JSON="{"
208
+ first=true
209
+ for script in "${REQUIRED_SCRIPTS[@]}" "${OPTIONAL_SCRIPTS[@]}"; do
210
+ [[ "$first" == true ]] && first=false || SCRIPTS_JSON+=","
211
+ SCRIPTS_JSON+="\"$script\":\"${SCRIPT_STATUS[$script]:-unknown}\""
212
+ done
213
+ SCRIPTS_JSON+="}"
214
+
215
+ # Build errors/warnings arrays using Python for correct JSON escaping.
216
+ # The sed-based approach only escaped double quotes but not backslashes,
217
+ # newlines, or control characters — all of which can appear in cargo output.
218
+ _json_str_array() {
219
+ # Read lines from stdin, emit a JSON array of properly escaped strings.
220
+ python3 -c '
221
+ import json, sys
222
+ items = [l.rstrip("\n") for l in sys.stdin]
223
+ print(json.dumps(items))
224
+ '
225
+ }
226
+ ERRORS_JSON=$(printf '%s\n' "${ERRORS[@]+"${ERRORS[@]}"}" | _json_str_array)
227
+ WARNINGS_JSON=$(printf '%s\n' "${WARNINGS[@]+"${WARNINGS[@]}"}" | _json_str_array)
228
+
229
+ cat <<EOF
230
+ {
231
+ "status": "$OVERALL_STATUS",
232
+ "tools": $TOOLS_JSON,
233
+ "nightly": {"status": "$NIGHTLY_STATUS", "version": "$NIGHTLY_VERSION"},
234
+ "scripts": $SCRIPTS_JSON,
235
+ "manifest": {"status": "$MANIFEST_STATUS", "build": "$BUILD_STATUS"},
236
+ "errors": $ERRORS_JSON,
237
+ "warnings": $WARNINGS_JSON
238
+ }
239
+ EOF
240
+ else
241
+ echo "=== Rust Toolchain Validation ==="
242
+ echo ""
243
+ echo "Tools:"
244
+ for name in cargo uv rustfilt cargo-expand; do
245
+ status="${TOOL_STATUS[$name]:-unknown}"
246
+ version="${TOOL_VERSION[$name]:-}"
247
+ if [[ "$status" == "present" ]]; then
248
+ echo " [OK] $name ($version)"
249
+ else
250
+ echo " [MISS] $name"
251
+ fi
252
+ done
253
+ echo ""
254
+ echo "Nightly: $NIGHTLY_STATUS ($NIGHTLY_VERSION)"
255
+ echo ""
256
+ echo "Scripts:"
257
+ for script in "${REQUIRED_SCRIPTS[@]}"; do
258
+ status="${SCRIPT_STATUS[$script]:-unknown}"
259
+ if [[ "$status" == "present" ]]; then
260
+ echo " [OK] $script"
261
+ else
262
+ echo " [MISS] $script (required)"
263
+ fi
264
+ done
265
+ for script in "${OPTIONAL_SCRIPTS[@]}"; do
266
+ status="${SCRIPT_STATUS[$script]:-unknown}"
267
+ if [[ "$status" == "present" ]]; then
268
+ echo " [OK] $script"
269
+ else
270
+ echo " [MISS] $script (optional)"
271
+ fi
272
+ done
273
+
274
+ if [[ -n "$MANIFEST" ]]; then
275
+ echo ""
276
+ echo "Manifest: $MANIFEST ($MANIFEST_STATUS)"
277
+ echo "Build: $BUILD_STATUS"
278
+ fi
279
+
280
+ if [[ ${#ERRORS[@]} -gt 0 ]]; then
281
+ echo ""
282
+ echo "ERRORS:"
283
+ for err in "${ERRORS[@]}"; do
284
+ echo " - $err"
285
+ done
286
+ fi
287
+ if [[ ${#WARNINGS[@]} -gt 0 ]]; then
288
+ echo ""
289
+ echo "WARNINGS:"
290
+ for warn in "${WARNINGS[@]}"; do
291
+ echo " - $warn"
292
+ done
293
+ fi
294
+ echo ""
295
+ echo "Overall: $OVERALL_STATUS"
296
+ fi
297
+
298
+ [[ "$OVERALL_STATUS" == "ready" ]]
@@ -0,0 +1,150 @@
1
+ # Phase 0 — Preflight, Configuration, and Work Directory
2
+
3
+ ## Preconditions
4
+
5
+ None — this is the first phase.
6
+
7
+ ## Instructions
8
+
9
+ Spawn agent `0-preflight` via `Task` with:
10
+
11
+ | Parameter | Value |
12
+ |---|---|
13
+ | `path` | `{{path}}` |
14
+ | `compile_db` | `{{compile_db}}` |
15
+ | `cargo_manifest` | `{{cargo_manifest}}` |
16
+ | `config` | `{{config}}` |
17
+ | `languages` | `{{languages}}` |
18
+ | `max_tus` | `{{max_tus}}` |
19
+ | `mcp_mode` | `{{mcp_mode}}` |
20
+ | `mcp_timeout_ms` | `{{mcp_timeout_ms}}` |
21
+ | `mcp_required_for_advanced` | `{{mcp_required_for_advanced}}` |
22
+ | `enable_asm` | `{{enable_asm}}` |
23
+ | `enable_semantic_ir` | `{{enable_semantic_ir}}` |
24
+ | `enable_cfg` | `{{enable_cfg}}` |
25
+ | `enable_runtime_tests` | `{{enable_runtime_tests}}` |
26
+ | `opt_levels` | `{{opt_levels}}` |
27
+ | `poc_categories` | `{{poc_categories}}` |
28
+ | `poc_output_dir` | `{{poc_output_dir}}` |
29
+ | `baseDir` | `{baseDir}` |
30
+
31
+ The agent creates the work directory, runs all preflight checks, merges configuration, enumerates TUs, and writes `orchestrator-state.json`.
32
+
33
+ ### What the `0-preflight` agent must do
34
+
35
+ **Step 1 — Determine language mode** from inputs:
36
+ - `compile_db` set and `cargo_manifest` not set → `language_mode=c`
37
+ - `cargo_manifest` set and `compile_db` not set → `language_mode=rust`
38
+ - Both set → `language_mode=mixed`
39
+ - Neither set → **stop the run**: at least one of `compile_db` or `cargo_manifest` is required.
40
+
41
+ **Step 2 — C/C++ preflight** (skip if `language_mode=rust`):
42
+
43
+ 1. Verify `compile_db` file exists at the given path.
44
+ 2. Verify at least one entry in the compile DB resolves to an existing source file and working directory.
45
+ 3. Attempt a trial compilation of one representative TU using its captured flags to confirm the codebase is buildable.
46
+ 4. Verify `{baseDir}/tools/extract_compile_flags.py` exists and is executable.
47
+ 5. Verify `{baseDir}/tools/emit_ir.sh` exists and is executable.
48
+ 6. If `enable_asm=true`: verify `{baseDir}/tools/emit_asm.sh` exists; if missing, set `enable_asm=false` and emit a warning.
49
+ 7. If `mcp_mode != off`: run `{baseDir}/tools/mcp/check_mcp.sh` to probe MCP availability.
50
+ - If `mcp_mode=require` and MCP is unreachable: **stop the run** and report the MCP failure.
51
+ - If `mcp_mode=prefer` and MCP is unreachable: set `mcp_available=false`, continue, and apply confidence downgrades in the report assembly phase.
52
+
53
+ **Step 3 — Common preflight** (always):
54
+
55
+ 8. Verify `{baseDir}/tools/generate_poc.py` exists and is executable. If missing: **stop the run** — PoC generation is mandatory.
56
+
57
+ **Step 4 — Rust preflight** (skip if `language_mode=c`):
58
+
59
+ 9. Verify `cargo_manifest` file exists (must be a `Cargo.toml` path).
60
+ 10. Run `cargo check --manifest-path <cargo_manifest>` to confirm the crate is buildable. If it fails: **stop the run**.
61
+ 11. Verify `cargo +nightly --version` succeeds. If not: **stop the run** — nightly toolchain is required for MIR and LLVM IR emission.
62
+ - Note: use `~/.cargo/bin/cargo +nightly` (rustup proxy) rather than a system cargo that may not support the `+toolchain` syntax.
63
+ 12. Verify `uv --version` succeeds. If not: **stop the run** — `uv` is required to run Python analysis scripts.
64
+ 13. Verify `{baseDir}/tools/emit_rust_mir.sh` exists and is executable. If missing: **stop the run** — MIR analysis is required.
65
+ 14. Verify `{baseDir}/tools/emit_rust_ir.sh` exists and is executable. If missing: **stop the run** — LLVM IR analysis is required.
66
+ 15. For each tool below: if missing or not executable, warn and mark that capability as skipped (do not fail the run):
67
+ - `{baseDir}/tools/emit_rust_asm.sh` — if missing, set `enable_asm=false` for Rust; warn `STACK_RETENTION`/`REGISTER_SPILL` findings will be skipped.
68
+ - `{baseDir}/tools/diff_rust_mir.sh` — if missing, warn that MIR-level optimization comparison will be skipped.
69
+ 16. For each Python script below: if missing, warn and mark that sub-step as skipped (do not fail the run):
70
+ - `{baseDir}/tools/scripts/semantic_audit.py`
71
+ - `{baseDir}/tools/scripts/find_dangerous_apis.py`
72
+ - `{baseDir}/tools/scripts/check_mir_patterns.py`
73
+ - `{baseDir}/tools/scripts/check_llvm_patterns.py`
74
+ - `{baseDir}/tools/scripts/check_rust_asm.py` — if missing, assembly analysis findings (`STACK_RETENTION`, `REGISTER_SPILL`) will be skipped even if `enable_asm=true`.
75
+
76
+ **Step 5 — TU / crate enumeration**:
77
+
78
+ - **C/C++** (skip if `language_mode=rust`): Parse `compile_db` and enumerate all translation units. Apply `max_tus` limit if set. Filter by `languages`. Compute `tu_hash = sha1(source_path)[:8]` for each TU. Run a lightweight grep across TU sources for sensitive name patterns (from merged config) to produce `sensitive_candidates`.
79
+ - **Rust** (skip if `language_mode=c`): Compute `rust_tu_hash = sha1(abspath(cargo_manifest))[:8]`. Set `rust_crate_root = dirname(cargo_manifest)`.
80
+
81
+ **Step 6 — Create work directory**:
82
+
83
+ ```bash
84
+ RUN_ID=$(date +%Y%m%d%H%M%S)
85
+ WORKDIR="/tmp/zeroize-audit-${RUN_ID}"
86
+ mkdir -p "${WORKDIR}"/{mcp-evidence,source-analysis,compiler-analysis,rust-compiler-analysis,report,poc,tests,agent-inputs}
87
+ ```
88
+
89
+ **Step 7 — Write `{workdir}/preflight.json`**:
90
+
91
+ ```json
92
+ {
93
+ "run_id": "<RUN_ID>",
94
+ "timestamp": "<ISO-8601>",
95
+ "repo": "<path>",
96
+ "language_mode": "<c|rust|mixed>",
97
+ "compile_db": "<compile_db or null>",
98
+ "cargo_manifest": "<cargo_manifest or null>",
99
+ "rust_crate_root": "<dirname(cargo_manifest) or null>",
100
+ "rust_tu_hash": "<hash or null>",
101
+ "opt_levels": ["O0", "O1", "O2"],
102
+ "mcp_mode": "<mcp_mode>",
103
+ "mcp_available": true,
104
+ "enable_asm": true,
105
+ "enable_semantic_ir": false,
106
+ "enable_cfg": false,
107
+ "enable_runtime_tests": false,
108
+ "tu_count": 0,
109
+ "tu_list": [{"file": "/path/to/file.c", "tu_hash": "a1b2c3d4"}],
110
+ "sensitive_candidates": [],
111
+ "tools_verified": ["uv", "cargo+nightly"],
112
+ "notes": ""
113
+ }
114
+ ```
115
+
116
+ **Step 8 — Write `{workdir}/orchestrator-state.json`** with the full state structure.
117
+
118
+ Report each preflight failure with the specific check that failed and the remediation step.
119
+
120
+ **After completion**: The agent's response includes the `workdir` path. Read `{workdir}/orchestrator-state.json` to initialize:
121
+
122
+ - `workdir` — use for all subsequent phases
123
+ - `routing.mcp_available` — MCP probe result
124
+ - `routing.tu_count` — number of TUs to process
125
+ - `key_file_paths.config` — path to merged config file
126
+
127
+ ## State Update
128
+
129
+ The `0-preflight` agent writes the initial `orchestrator-state.json`. No additional update needed by the orchestrator.
130
+
131
+ ## Error Handling
132
+
133
+ | Failure | Behavior |
134
+ |---|---|
135
+ | Agent fails or times out | Stop the run, report failure |
136
+ | Neither `compile_db` nor `cargo_manifest` provided | Stop the run |
137
+ | Preflight validation fails | Stop the run (agent reports specific check and remediation) |
138
+ | Config load fails | Stop the run |
139
+ | Preflight tool check fails | Stop the run |
140
+ | MCP unreachable + `mcp_mode=require` | Stop the run |
141
+ | MCP unreachable + `mcp_mode=prefer` | Continue — `routing.mcp_available` will be `false` |
142
+ | `cargo check` fails (Rust preflight) | Stop the run — crate must be buildable |
143
+ | `cargo +nightly` not available (Rust preflight) | Stop the run — nightly required for MIR/IR emission |
144
+ | `uv` not available (Rust preflight) | Stop the run — required for Python analysis scripts |
145
+ | `emit_rust_asm.sh` missing (Rust preflight) | Warn, set `enable_asm=false` for Rust, continue |
146
+ | Python script missing (Rust preflight) | Warn and skip that sub-step, continue |
147
+
148
+ ## Next Phase
149
+
150
+ Phase 1 — Source Analysis