human-to-code 0.1.3 → 0.1.5

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 (211) hide show
  1. package/Readme.md +6 -0
  2. package/assets/brand/BRAND.md +31 -0
  3. package/assets/brand/favicon-512.png +0 -0
  4. package/assets/brand/favicon.svg +5 -0
  5. package/assets/brand/logo-concept.png +0 -0
  6. package/assets/brand/logo-mark-dark.svg +7 -0
  7. package/assets/brand/logo-mark.svg +7 -0
  8. package/assets/brand/social-card.png +0 -0
  9. package/assets/brand/social-card.svg +42 -0
  10. package/assets/brand/wordmark-dark.svg +10 -0
  11. package/assets/brand/wordmark.svg +10 -0
  12. package/dist/analysis/adapters/general.d.ts.map +1 -0
  13. package/dist/analysis/adapters/general.js.map +1 -0
  14. package/dist/analysis/adapters/node.d.ts.map +1 -0
  15. package/dist/{adapters → analysis/adapters}/node.js +6 -0
  16. package/dist/analysis/adapters/node.js.map +1 -0
  17. package/dist/{adapters → analysis/adapters}/python.d.ts +5 -0
  18. package/dist/analysis/adapters/python.d.ts.map +1 -0
  19. package/dist/analysis/adapters/python.js.map +1 -0
  20. package/dist/analysis/adapters/rust.d.ts.map +1 -0
  21. package/dist/{adapters → analysis/adapters}/rust.js +5 -0
  22. package/dist/analysis/adapters/rust.js.map +1 -0
  23. package/dist/analysis/analyzer-types.d.ts.map +1 -0
  24. package/dist/analysis/analyzer-types.js.map +1 -0
  25. package/dist/analysis/analyzer-utils.d.ts.map +1 -0
  26. package/dist/{analyzer-utils.js → analysis/analyzer-utils.js} +5 -0
  27. package/dist/analysis/analyzer-utils.js.map +1 -0
  28. package/dist/analysis/analyzer.d.ts.map +1 -0
  29. package/dist/analysis/analyzer.js.map +1 -0
  30. package/dist/{support-matrix.d.ts → analysis/support-matrix.d.ts} +6 -0
  31. package/dist/analysis/support-matrix.d.ts.map +1 -0
  32. package/dist/analysis/support-matrix.js.map +1 -0
  33. package/dist/cli.d.ts.map +1 -1
  34. package/dist/cli.js +42 -28
  35. package/dist/cli.js.map +1 -1
  36. package/dist/{config.d.ts → config/config.d.ts} +1 -1
  37. package/dist/config/config.d.ts.map +1 -0
  38. package/dist/config/config.js.map +1 -0
  39. package/dist/{discovery.d.ts → config/discovery.d.ts} +1 -1
  40. package/dist/config/discovery.d.ts.map +1 -0
  41. package/dist/config/discovery.js.map +1 -0
  42. package/dist/context/compiler-skills.d.ts.map +1 -0
  43. package/dist/context/compiler-skills.js.map +1 -0
  44. package/dist/{compiler-tools.d.ts → context/compiler-tools.d.ts} +1 -1
  45. package/dist/context/compiler-tools.d.ts.map +1 -0
  46. package/dist/context/compiler-tools.js.map +1 -0
  47. package/dist/context/context.d.ts.map +1 -0
  48. package/dist/{context.js → context/context.js} +1 -1
  49. package/dist/context/context.js.map +1 -0
  50. package/dist/context/documentation.d.ts.map +1 -0
  51. package/dist/{documentation.js → context/documentation.js} +2 -2
  52. package/dist/context/documentation.js.map +1 -0
  53. package/dist/core/contracts.d.ts.map +1 -0
  54. package/dist/core/contracts.js.map +1 -0
  55. package/dist/core/types.d.ts.map +1 -0
  56. package/dist/core/types.js.map +1 -0
  57. package/dist/index.d.ts +27 -22
  58. package/dist/index.d.ts.map +1 -1
  59. package/dist/index.js +31 -20
  60. package/dist/index.js.map +1 -1
  61. package/dist/{patch.d.ts → pipeline/patch.d.ts} +1 -1
  62. package/dist/pipeline/patch.d.ts.map +1 -0
  63. package/dist/{patch.js → pipeline/patch.js} +1 -1
  64. package/dist/pipeline/patch.js.map +1 -0
  65. package/dist/{planner.d.ts → pipeline/planner.d.ts} +3 -3
  66. package/dist/pipeline/planner.d.ts.map +1 -0
  67. package/dist/{planner.js → pipeline/planner.js} +1 -1
  68. package/dist/pipeline/planner.js.map +1 -0
  69. package/dist/{run-store.d.ts → pipeline/run-store.d.ts} +1 -1
  70. package/dist/pipeline/run-store.d.ts.map +1 -0
  71. package/dist/{run-store.js → pipeline/run-store.js} +2 -2
  72. package/dist/pipeline/run-store.js.map +1 -0
  73. package/dist/{simple.d.ts → pipeline/simple.d.ts} +47 -0
  74. package/dist/pipeline/simple.d.ts.map +1 -0
  75. package/dist/{simple.js → pipeline/simple.js} +110 -7
  76. package/dist/pipeline/simple.js.map +1 -0
  77. package/dist/pipeline/snapshot.d.ts.map +1 -0
  78. package/dist/{snapshot.js → pipeline/snapshot.js} +1 -1
  79. package/dist/pipeline/snapshot.js.map +1 -0
  80. package/dist/{validation.d.ts → pipeline/validation.d.ts} +1 -1
  81. package/dist/pipeline/validation.d.ts.map +1 -0
  82. package/dist/{validation.js → pipeline/validation.js} +1 -1
  83. package/dist/pipeline/validation.js.map +1 -0
  84. package/dist/{workflow.d.ts → pipeline/workflow.d.ts} +7 -5
  85. package/dist/pipeline/workflow.d.ts.map +1 -0
  86. package/dist/{workflow.js → pipeline/workflow.js} +20 -13
  87. package/dist/pipeline/workflow.js.map +1 -0
  88. package/dist/{certification.d.ts → providers/certification.d.ts} +1 -1
  89. package/dist/providers/certification.d.ts.map +1 -0
  90. package/dist/{certification.js → providers/certification.js} +1 -1
  91. package/dist/providers/certification.js.map +1 -0
  92. package/dist/{provider.d.ts → providers/provider.d.ts} +2 -2
  93. package/dist/providers/provider.d.ts.map +1 -0
  94. package/dist/{provider.js → providers/provider.js} +2 -2
  95. package/dist/providers/provider.js.map +1 -0
  96. package/dist/{providers.d.ts → providers/providers.d.ts} +1 -1
  97. package/dist/providers/providers.d.ts.map +1 -0
  98. package/dist/{providers.js → providers/providers.js} +3 -3
  99. package/dist/providers/providers.js.map +1 -0
  100. package/dist/{schemas.d.ts → providers/schemas.d.ts} +6 -6
  101. package/dist/providers/schemas.d.ts.map +1 -0
  102. package/dist/providers/schemas.js.map +1 -0
  103. package/dist/security/pinned-http.d.ts.map +1 -0
  104. package/dist/security/pinned-http.js.map +1 -0
  105. package/dist/{secret-scan.d.ts → security/secret-scan.d.ts} +1 -1
  106. package/dist/security/secret-scan.d.ts.map +1 -0
  107. package/dist/{secret-scan.js → security/secret-scan.js} +1 -1
  108. package/dist/security/secret-scan.js.map +1 -0
  109. package/docs/ARCHITECTURE.md +150 -0
  110. package/docs/MODULES.md +91 -0
  111. package/docs/SCALABILITY.md +144 -0
  112. package/docs/roadmap/README.md +69 -0
  113. package/docs/roadmap/bash.md +46 -0
  114. package/docs/roadmap/csharp.md +44 -0
  115. package/docs/roadmap/dart.md +43 -0
  116. package/docs/roadmap/docker.md +46 -0
  117. package/docs/roadmap/go.md +47 -0
  118. package/docs/roadmap/html-css.md +47 -0
  119. package/docs/roadmap/java.md +48 -0
  120. package/docs/roadmap/kotlin.md +44 -0
  121. package/docs/roadmap/php.md +42 -0
  122. package/docs/roadmap/ruby.md +46 -0
  123. package/docs/roadmap/sql.md +48 -0
  124. package/docs/roadmap/swift.md +43 -0
  125. package/docs/roadmap/terraform.md +47 -0
  126. package/docs/roadmap/yaml.md +47 -0
  127. package/package.json +2 -1
  128. package/dist/adapters/general.d.ts.map +0 -1
  129. package/dist/adapters/general.js.map +0 -1
  130. package/dist/adapters/node.d.ts.map +0 -1
  131. package/dist/adapters/node.js.map +0 -1
  132. package/dist/adapters/python.d.ts.map +0 -1
  133. package/dist/adapters/python.js.map +0 -1
  134. package/dist/adapters/rust.d.ts.map +0 -1
  135. package/dist/adapters/rust.js.map +0 -1
  136. package/dist/analyzer-types.d.ts.map +0 -1
  137. package/dist/analyzer-types.js.map +0 -1
  138. package/dist/analyzer-utils.d.ts.map +0 -1
  139. package/dist/analyzer-utils.js.map +0 -1
  140. package/dist/analyzer.d.ts.map +0 -1
  141. package/dist/analyzer.js.map +0 -1
  142. package/dist/certification.d.ts.map +0 -1
  143. package/dist/certification.js.map +0 -1
  144. package/dist/compiler-skills.d.ts.map +0 -1
  145. package/dist/compiler-skills.js.map +0 -1
  146. package/dist/compiler-tools.d.ts.map +0 -1
  147. package/dist/compiler-tools.js.map +0 -1
  148. package/dist/config.d.ts.map +0 -1
  149. package/dist/config.js.map +0 -1
  150. package/dist/context.d.ts.map +0 -1
  151. package/dist/context.js.map +0 -1
  152. package/dist/contracts.d.ts.map +0 -1
  153. package/dist/contracts.js.map +0 -1
  154. package/dist/discovery.d.ts.map +0 -1
  155. package/dist/discovery.js.map +0 -1
  156. package/dist/documentation.d.ts.map +0 -1
  157. package/dist/documentation.js.map +0 -1
  158. package/dist/patch.d.ts.map +0 -1
  159. package/dist/patch.js.map +0 -1
  160. package/dist/pinned-http.d.ts.map +0 -1
  161. package/dist/pinned-http.js.map +0 -1
  162. package/dist/planner.d.ts.map +0 -1
  163. package/dist/planner.js.map +0 -1
  164. package/dist/provider.d.ts.map +0 -1
  165. package/dist/provider.js.map +0 -1
  166. package/dist/providers.d.ts.map +0 -1
  167. package/dist/providers.js.map +0 -1
  168. package/dist/run-store.d.ts.map +0 -1
  169. package/dist/run-store.js.map +0 -1
  170. package/dist/schemas.d.ts.map +0 -1
  171. package/dist/schemas.js.map +0 -1
  172. package/dist/secret-scan.d.ts.map +0 -1
  173. package/dist/secret-scan.js.map +0 -1
  174. package/dist/simple.d.ts.map +0 -1
  175. package/dist/simple.js.map +0 -1
  176. package/dist/snapshot.d.ts.map +0 -1
  177. package/dist/snapshot.js.map +0 -1
  178. package/dist/support-matrix.d.ts.map +0 -1
  179. package/dist/support-matrix.js.map +0 -1
  180. package/dist/types.d.ts.map +0 -1
  181. package/dist/types.js.map +0 -1
  182. package/dist/validation.d.ts.map +0 -1
  183. package/dist/validation.js.map +0 -1
  184. package/dist/workflow.d.ts.map +0 -1
  185. package/dist/workflow.js.map +0 -1
  186. /package/dist/{adapters → analysis/adapters}/general.d.ts +0 -0
  187. /package/dist/{adapters → analysis/adapters}/general.js +0 -0
  188. /package/dist/{adapters → analysis/adapters}/node.d.ts +0 -0
  189. /package/dist/{adapters → analysis/adapters}/python.js +0 -0
  190. /package/dist/{adapters → analysis/adapters}/rust.d.ts +0 -0
  191. /package/dist/{analyzer-types.d.ts → analysis/analyzer-types.d.ts} +0 -0
  192. /package/dist/{analyzer-types.js → analysis/analyzer-types.js} +0 -0
  193. /package/dist/{analyzer-utils.d.ts → analysis/analyzer-utils.d.ts} +0 -0
  194. /package/dist/{analyzer.d.ts → analysis/analyzer.d.ts} +0 -0
  195. /package/dist/{analyzer.js → analysis/analyzer.js} +0 -0
  196. /package/dist/{support-matrix.js → analysis/support-matrix.js} +0 -0
  197. /package/dist/{config.js → config/config.js} +0 -0
  198. /package/dist/{discovery.js → config/discovery.js} +0 -0
  199. /package/dist/{compiler-skills.d.ts → context/compiler-skills.d.ts} +0 -0
  200. /package/dist/{compiler-skills.js → context/compiler-skills.js} +0 -0
  201. /package/dist/{compiler-tools.js → context/compiler-tools.js} +0 -0
  202. /package/dist/{context.d.ts → context/context.d.ts} +0 -0
  203. /package/dist/{documentation.d.ts → context/documentation.d.ts} +0 -0
  204. /package/dist/{contracts.d.ts → core/contracts.d.ts} +0 -0
  205. /package/dist/{contracts.js → core/contracts.js} +0 -0
  206. /package/dist/{types.d.ts → core/types.d.ts} +0 -0
  207. /package/dist/{types.js → core/types.js} +0 -0
  208. /package/dist/{snapshot.d.ts → pipeline/snapshot.d.ts} +0 -0
  209. /package/dist/{schemas.js → providers/schemas.js} +0 -0
  210. /package/dist/{pinned-http.d.ts → security/pinned-http.d.ts} +0 -0
  211. /package/dist/{pinned-http.js → security/pinned-http.js} +0 -0
@@ -0,0 +1,144 @@
1
+ # Scalability and engineering practices
2
+
3
+ How to grow this codebase without eroding its guarantees. The safety
4
+ invariants in [CONTRIBUTING.md](../CONTRIBUTING.md#non-negotiable-safety-invariants)
5
+ are the hard floor; this document covers the structural practices that keep
6
+ the code readable and extensible as it scales.
7
+
8
+ ## Layering rules
9
+
10
+ Source lives in layered domain folders (see
11
+ [ARCHITECTURE.md](ARCHITECTURE.md)). The rules:
12
+
13
+ 1. **Imports point upward only.** A module may import from its own folder or
14
+ a layer above it (`core` at the top, `pipeline` at the bottom, entry points
15
+ below everything). If you need a downward import, the type or helper you
16
+ want belongs in a higher layer — move it, don't bend the arrow.
17
+ 2. **`core/` stays dependency-free.** Nothing in `core/` imports from any
18
+ other folder or from an SDK. It is the shared vocabulary; keeping it leaf
19
+ is what prevents import cycles as the codebase grows.
20
+ 3. **Entry points stay thin.** `cli.ts` parses arguments, maps statuses to
21
+ exit codes, and prints; `index.ts` only re-exports. Behavior belongs in a
22
+ layer, where it is testable without a TTY.
23
+ 4. **One module, one responsibility.** New functionality gets a new file in
24
+ the right folder rather than growing an existing file past its purpose.
25
+ If a file needs a paragraph to describe, it is two files.
26
+ 5. **Every module starts with a `/** … */` header** stating what it does and,
27
+ where relevant, what it deliberately does not do. The headers are the
28
+ first line of documentation; keep them true when behavior changes.
29
+
30
+ ## Extension points
31
+
32
+ The codebase has three designed seams. Extending along them requires no
33
+ changes to the layers above.
34
+
35
+ ### Adding an ecosystem (e.g. Django, Spring)
36
+
37
+ 1. Implement `EcosystemAdapter` (`analysis/analyzer-types.ts`) in a new
38
+ `analysis/adapters/<name>.ts`. Analysis must stay static: inspect only the
39
+ bounded `AnalyzerContext`; never import project modules, evaluate config,
40
+ or spawn tools. Emit version evidence and candidate validation commands.
41
+ 2. Declare the recognized variants/versions in `analysis/support-matrix.ts`,
42
+ starting at `preview` tier. Support is declared, never inferred.
43
+ 3. Register the adapter in `DEFAULT_ECOSYSTEM_ADAPTERS`
44
+ (`analysis/analyzer.ts`).
45
+ 4. Add a skill pack in `context/compiler-skills.ts` for the ecosystem's
46
+ conventions (policy data only — it grants no authority).
47
+ 5. Add positive and adversarial fixtures per the analyzer checklist in
48
+ CONTRIBUTING.md: conflicting lockfiles, ambiguous workspaces, symlinks,
49
+ partial scans, stable ordering and fingerprints.
50
+
51
+ ### Adding a provider (e.g. Anthropic)
52
+
53
+ 1. Implement `ProviderAdapter` (`providers/provider.ts`) in
54
+ `providers/providers.ts` (or a sibling file) using only Node built-ins and
55
+ `security/pinned-http.ts` for transport. No new runtime dependencies.
56
+ 2. Route all output through the existing schema gate (`generateValidated`)
57
+ and budget accounting — pessimistic pre-request reservation, reconciliation
58
+ on provider-reported usage, conservative charge on failure.
59
+ 3. Bind credentials to the endpoint via `apiKeyEnv` only; require reviewed
60
+ pricing bounds for remote endpoints; never advertise context tools to a
61
+ non-loopback destination.
62
+ 4. Wire the name through `config/config.ts` validation and the CLI factory in
63
+ `cli.ts`. No silent fallback of provider, model, or endpoint — ever.
64
+ 5. Test with injected fetch/DNS/clock seams per the provider checklist in
65
+ CONTRIBUTING.md.
66
+
67
+ ### Evolving an artifact schema
68
+
69
+ Artifacts (`*V1` in `core/contracts.ts`) are the contracts between stages and
70
+ between releases:
71
+
72
+ - **Additive and compatible?** Extend the V1 type and its exact validator
73
+ together, plus the JSON Schema in `providers/schemas.ts` if the artifact
74
+ crosses the provider boundary.
75
+ - **Meaning changes?** New version (`*V2`), new validator, explicit migration
76
+ (the `migrate-config` command is the pattern). Never silently reinterpret a
77
+ stored artifact — run records outlive releases.
78
+ - Unknown fields always remain errors. Loosening exact-key validation is a
79
+ design discussion, not a patch.
80
+
81
+ ## Code conventions
82
+
83
+ - **TypeScript strict, no escape hatches.** `strict` and
84
+ `noUncheckedIndexedAccess` stay on; avoid `any` and non-null assertions —
85
+ validate at the boundary and let types flow.
86
+ - **Zero production dependencies.** HTTP, hashing, JSON, and process handling
87
+ use Node built-ins. Adding a runtime dependency changes the supply-chain
88
+ posture and needs a design discussion first.
89
+ - **Errors are typed and named.** Each layer exports its own error classes
90
+ (`ArtifactValidationError`, `ProviderError`, `PatchSafetyError`, …) so the
91
+ CLI can map failures to exit codes without string matching. Error messages
92
+ never contain secret values.
93
+ - **Determinism by default.** Stable ordering for anything hashed, listed, or
94
+ persisted; inject clock/randomness/network/exec as parameters so tests can
95
+ control them.
96
+ - **Statuses, not booleans.** Multi-outcome operations return the typed run
97
+ statuses (`VERIFIED`/`NEEDS_INPUT`/`UNSUPPORTED`/`INCONCLUSIVE`/`FAILED`/
98
+ `SECURITY_BLOCKED`), and only `VERIFIED` is success.
99
+
100
+ ## Testing practices
101
+
102
+ - Every `src/**/x.ts` with behavior has a mirror `test/x.test.ts`; keep the
103
+ mirror when adding or moving modules.
104
+ - Tests are deterministic and offline: injected fetch/DNS/environment/clock
105
+ seams, no real provider, network, or container daemon (the validation tests
106
+ stub the sandbox probe).
107
+ - New behavior ships with its most plausible misuse and failure cases, not
108
+ just the happy path — the per-area checklists in CONTRIBUTING.md are the
109
+ bar.
110
+ - Secret-handling tests use unmistakably synthetic values and assert that raw
111
+ values never appear in errors, reports, or stored artifacts.
112
+ - `npm run typecheck && npm test && npm run build && npm run package:check`
113
+ must pass from a clean install before review; CI runs the same set.
114
+
115
+ ## Documentation practices
116
+
117
+ Documentation is layered like the code — update the layer that owns the fact:
118
+
119
+ | Layer | Owns | Update when |
120
+ | --- | --- | --- |
121
+ | Module headers | What one file does | The file's behavior changes |
122
+ | [docs/MODULES.md](MODULES.md) | The per-file map | A module is added, moved, or repurposed |
123
+ | [docs/ARCHITECTURE.md](ARCHITECTURE.md) | Layers, flow, design decisions | A layer, stage, or invariant-relevant design changes |
124
+ | [Readme.md](../Readme.md) | User-facing behavior and guarantees | CLI behavior, config, statuses, or limitations change |
125
+ | [SECURITY.md](../SECURITY.md) | Trust model | Any trust-boundary change |
126
+ | [CONTRIBUTING.md](../CONTRIBUTING.md) | Invariants and checklists | The engineering bar itself changes |
127
+
128
+ A pull request that changes behavior updates the affected documentation in
129
+ the same change — documentation drift is treated as a defect, and honest
130
+ wording is part of review (never describe a fail-closed limitation as a
131
+ feature gap to be papered over).
132
+
133
+ ## Growth guardrails
134
+
135
+ - **When a folder accumulates unrelated concerns, split the folder**, not
136
+ just the file — the layer list in ARCHITECTURE.md is expected to grow.
137
+ - **New capability starts fail-closed.** Ship recognition at `preview`,
138
+ refuse ambiguity, and let certification evidence — not confidence — promote
139
+ it. This is what keeps adding surface area from multiplying risk.
140
+ - **No bypass flags.** If a gate is inconvenient, the fix is evidence or
141
+ design, never a flag that converts a non-success status into exit 0.
142
+ - **Entry-point stability.** `src/index.ts` and `src/cli.ts` stay at the
143
+ source root so `dist/index.js` and `dist/cli.js` (package `main`/`bin`)
144
+ never move; reorganize beneath them freely.
@@ -0,0 +1,69 @@
1
+ # Language & framework support roadmap
2
+
3
+ One file per language/framework we intend to support. Each file is an
4
+ integration plan, not a promise of a date — items are implemented one by one,
5
+ and a plan graduates out of this folder when its profile ships.
6
+
7
+ ## The four support levels
8
+
9
+ Support in human-to-code is layered; "supporting a language" means moving it
10
+ up this ladder deliberately:
11
+
12
+ 1. **Direct path** (`src/pipeline/simple.ts`) — the language has an entry in
13
+ `LANGUAGE_PROFILES` (output extension + prompt label) and, if it has an
14
+ inline-comment form, its source extensions are in `SCANNED_EXTENSIONS` for
15
+ `@human` markers. No grounding, no validation; receipt-and-confirm only.
16
+ *Today: TypeScript, JavaScript, Python, Rust, Go, Java, Ruby, C#, C++, C.*
17
+ 2. **General fallback** (`src/analysis/adapters/general.ts`) — any declared
18
+ language can flow through the guided pipeline ungrounded, permanently
19
+ `INCONCLUSIVE`. This exists for every language already; it is the floor,
20
+ not a goal.
21
+ 3. **Grounded profile** — a static `EcosystemAdapter` recognizes real
22
+ projects, collects version evidence, and emits a validation plan; the
23
+ variant is declared in the support matrix at `preview` tier. This is what
24
+ each plan in this folder describes.
25
+ 4. **Certified** — the profile passes the benchmark gate in
26
+ `src/providers/certification.ts` (≥25 tasks × 3 runs × ≥95% strong-sandbox
27
+ pass rate per provider/model). Never self-declared.
28
+
29
+ ## What every plan must cover
30
+
31
+ The integration steps are fixed by [docs/SCALABILITY.md](../SCALABILITY.md#adding-an-ecosystem-eg-django-spring);
32
+ each plan fills in the language-specific facts:
33
+
34
+ | Section | It answers |
35
+ | --- | --- |
36
+ | Status today | Which level (1/2) the language sits at right now. |
37
+ | Target profile | The `Ecosystem` name, variants, and version range for the support matrix. |
38
+ | Detection signals | Manifests/lockfiles/config the static adapter may read — never execute. |
39
+ | Version evidence | Where exact resolved versions come from (lockfile, manifest pin). |
40
+ | Validation plan | Candidate commands (argv arrays) the sandbox would run — build, test, lint. |
41
+ | Skill pack | Conventions the `compiler-skills.ts` policy pack must encode. |
42
+ | Risks & gates | What must be treated as elevated risk or refused (codegen hooks, FFI, migrations…). |
43
+ | Checklist | The mechanical steps, in order, with test obligations. |
44
+
45
+ Ground rules that apply to every plan (from CONTRIBUTING.md's invariants):
46
+ analysis stays static and read-only; new variants start at `preview`; support
47
+ is declared in `support-matrix.ts`, never inferred; ambiguity returns
48
+ `NEEDS_INPUT`/`UNSUPPORTED` rather than guessing; adding an `Ecosystem` value
49
+ is a schema-visible change and updates `analyzer-types.ts`, skills selection,
50
+ and the certification profile keys together.
51
+
52
+ ## Plans
53
+
54
+ | Plan | Kind | Sits at level | Target |
55
+ | --- | --- | --- | --- |
56
+ | [go.md](go.md) | language | 1 (direct path) | Go modules ecosystem |
57
+ | [java.md](java.md) | language | 1 (direct path) | Maven/Gradle ecosystem |
58
+ | [csharp.md](csharp.md) | language | 1 (direct path) | .NET SDK ecosystem |
59
+ | [ruby.md](ruby.md) | language | 1 (direct path) | Bundler/Rails ecosystem |
60
+ | [php.md](php.md) | language | 2 (general only) | Composer/Laravel ecosystem |
61
+ | [swift.md](swift.md) | language | 2 (general only) | SwiftPM ecosystem |
62
+ | [kotlin.md](kotlin.md) | language | 2 (general only) | Gradle/Android ecosystem |
63
+ | [dart.md](dart.md) | language | 2 (general only) | Pub/Flutter ecosystem |
64
+ | [bash.md](bash.md) | language | 2 (general only) | Shell-script profile |
65
+ | [sql.md](sql.md) | language | 2 (general only) | Migration-aware SQL profile |
66
+ | [yaml.md](yaml.md) | config | 2 (general only) | Schema-validated config profile |
67
+ | [html-css.md](html-css.md) | language | 2 (general only) | Static web profile |
68
+ | [docker.md](docker.md) | infra | 2 (general only) | Dockerfile/Compose profile |
69
+ | [terraform.md](terraform.md) | infra | 2 (general only) | Terraform/HCL profile |
@@ -0,0 +1,46 @@
1
+ # Bash / shell-script support plan
2
+
3
+ ## Status today
4
+ Level 2 only: not in `LANGUAGE_PROFILES`; `.sh` not scanned for markers
5
+ (`# @human` markers would already parse — the `#` comment form is supported
6
+ by the marker regex — but `.sh` files are not in `SCANNED_EXTENSIONS`).
7
+
8
+ ## Target profile
9
+ - `Ecosystem`: `shell`.
10
+ - Variant: `script-collection` — a repo (or subtree) of `*.sh`/`*.bash`
11
+ scripts. There is no manifest, so this profile is signal-based:
12
+ shebang lines + extension inventory, and it should stay deliberately
13
+ narrow. Anything ambiguous stays with the general fallback.
14
+ - Versions: bash ≥ 4 assumed by image; POSIX-sh scripts flagged by shebang.
15
+
16
+ ## Detection signals (static only)
17
+ - Shebangs (`#!/usr/bin/env bash`, `#!/bin/sh`), `.shellcheckrc`,
18
+ `Makefile` targets referencing scripts, `bats` test files (`*.bats`).
19
+
20
+ ## Version evidence
21
+ No package manager: dependency grounding is out of scope. The profile's
22
+ honesty lever is that generation is anchored to shellcheck-clean patterns
23
+ rather than external APIs.
24
+
25
+ ## Validation plan
26
+ - `["shellcheck", "<changed scripts>"]` and `["bash", "-n", "<script>"]`
27
+ syntax checks; `["bats", "test/"]` when a bats suite exists. All in the
28
+ sandbox image — scripts themselves are never executed outside it.
29
+
30
+ ## Skill pack
31
+ `set -euo pipefail` discipline, quoting rules, `trap` cleanup, no curl-pipe
32
+ patterns (aligns with the validator's implicit-downloader rejection),
33
+ portable vs bash-specific constructs by shebang.
34
+
35
+ ## Risks & gates
36
+ Every script is arbitrary code — validation runs syntax/lint/bats only,
37
+ never the script itself. Scripts that self-modify or fetch remote content
38
+ must be flagged as elevated risk in contracts.
39
+
40
+ ## Checklist
41
+ 0. Add `bash` to `LANGUAGE_PROFILES` (`.sh`) and `.sh`/`.bash` to `SCANNED_EXTENSIONS`.
42
+ 1. `Ecosystem` union + `analysis/adapters/shell.ts` (small, signal-based).
43
+ 2. `shell/script-collection` at `preview`.
44
+ 3. Register adapter; shell skill pack.
45
+ 4. Tests: shebang inventory, non-script repos not claimed, bats detection, stable fingerprints.
46
+ 5. Docs updates.
@@ -0,0 +1,44 @@
1
+ # C# / .NET support plan
2
+
3
+ ## Status today
4
+ Level 1: `LANGUAGE_PROFILES` has `csharp` (`.cs`), and `.cs` is scanned for
5
+ inline `// @human` markers. No grounded profile.
6
+
7
+ ## Target profile
8
+ - `Ecosystem`: `dotnet`.
9
+ - Variants: `sdk-project` (single `.csproj`), `solution` (`.sln` with
10
+ multiple projects), with ASP.NET Core detected as a framework signal.
11
+ - Versions: .NET 8 LTS+ (from `<TargetFramework>`).
12
+
13
+ ## Detection signals (static only)
14
+ - `.sln` project references; `.csproj` `<TargetFramework>`, `<PackageReference>`,
15
+ `<Nullable>`, `<ImplicitUsings>`.
16
+ - `Program.cs` minimal-hosting vs `Startup.cs` as entry-point signals;
17
+ `*.Tests.csproj` for test roots. Never invoke `dotnet`.
18
+
19
+ ## Version evidence
20
+ `packages.lock.json` when `RestorePackagesWithLockFile` is enabled gives
21
+ exact versions; otherwise `<PackageReference Version="...">` literals. Range
22
+ versions without a lockfile leave the dependency unproven for API grounding.
23
+
24
+ ## Validation plan
25
+ - `["dotnet", "build", "--nologo"]`, `["dotnet", "test", "--nologo"]` against
26
+ a preinstalled SDK image matching `<TargetFramework>`; NuGet restore needs
27
+ either a no-network local cache or is `INCONCLUSIVE` (validation has no network).
28
+
29
+ ## Skill pack
30
+ Nullable-reference-type discipline; DI via `IServiceCollection`; xUnit
31
+ conventions; `record` for DTOs; generated `obj/`/`bin/` and `*.Designer.cs`
32
+ protected.
33
+
34
+ ## Risks & gates
35
+ Source generators/analyzers in project files, `unsafe` blocks, P/Invoke
36
+ (`DllImport`), and EF Core migrations are elevated-risk; migrations are
37
+ generated for review, never applied (existing invariant).
38
+
39
+ ## Checklist
40
+ 1. `Ecosystem` union + `analysis/adapters/dotnet.ts`.
41
+ 2. `dotnet/sdk-project`, `dotnet/solution` at `preview`.
42
+ 3. Register adapter; .NET skill pack.
43
+ 4. Tests: solution/project graph ambiguity, lockfile vs floating versions, offline-restore behavior, stable fingerprints.
44
+ 5. Docs updates.
@@ -0,0 +1,43 @@
1
+ # Dart / Flutter support plan
2
+
3
+ ## Status today
4
+ Level 2 only: not in `LANGUAGE_PROFILES`; `.dart` not scanned for markers.
5
+
6
+ ## Target profile
7
+ - `Ecosystem`: `dart`.
8
+ - Variants: `package` (pure Dart), `flutter-app` (validation limited to
9
+ `flutter test` unit/widget tests — no device/emulator).
10
+ - Versions: Dart ≥ 3.0 (from `environment.sdk` in `pubspec.yaml`).
11
+
12
+ ## Detection signals (static only)
13
+ - `pubspec.yaml` (`environment`, `dependencies`, `flutter:` section),
14
+ `pubspec.lock`, `lib/`, `test/`, `analysis_options.yaml`. The `flutter`
15
+ SDK dependency distinguishes the variants. Never run `dart`/`flutter` CLIs.
16
+
17
+ ## Version evidence
18
+ `pubspec.lock` is exact and required for grounding; caret ranges in
19
+ `pubspec.yaml` alone are unproven.
20
+
21
+ ## Validation plan
22
+ - `["dart", "analyze"]` + `["dart", "test"]`, or `["flutter", "test"]` for
23
+ the flutter variant, in an image with the SDK and a primed pub cache
24
+ (sandbox has no network for `pub get`).
25
+
26
+ ## Skill pack
27
+ Effective-Dart naming/layout, null-safety, widget test conventions,
28
+ `build_runner` outputs (`*.g.dart`, `*.freezed.dart`) protected as
29
+ generated files.
30
+
31
+ ## Risks & gates
32
+ `build_runner` codegen (never run by the tool; generated files protected),
33
+ platform channels/FFI, and Flutter platform folders (`android/`, `ios/`)
34
+ which follow their own ecosystems' rules — treat as prohibited paths
35
+ initially.
36
+
37
+ ## Checklist
38
+ 0. Add `dart` to `LANGUAGE_PROFILES` (`.dart`) and scan `.dart` for `// @human`.
39
+ 1. `Ecosystem` union + `analysis/adapters/dart.ts`.
40
+ 2. `dart/package`, `dart/flutter-app` at `preview`.
41
+ 3. Register adapter; Dart/Flutter skill pack.
42
+ 4. Tests: lock absence, flutter vs pure-dart, generated-file protection, stable fingerprints.
43
+ 5. Docs updates.
@@ -0,0 +1,46 @@
1
+ # Docker / containerfile support plan
2
+
3
+ ## Status today
4
+ Level 2 only. Note the tool already *consumes* Docker/Podman as its
5
+ validation sandbox (`src/pipeline/validation.ts`); this plan is about
6
+ generating and editing Dockerfiles/Compose files as change targets.
7
+
8
+ ## Target profile
9
+ - `Ecosystem`: `container`.
10
+ - Variants: `dockerfile` (Dockerfile/Containerfile present),
11
+ `compose` (`compose.yaml`/`docker-compose.yml`), usually attached as a
12
+ secondary workspace signal to the ecosystem that owns the app.
13
+ - Versions: Compose schema version; base-image tags/digests as evidence.
14
+
15
+ ## Detection signals (static only)
16
+ - `Dockerfile*`, `Containerfile`, `compose*.y(a)ml`, `.dockerignore`;
17
+ `FROM` lines (stage graph), `COPY --from` references — all textual.
18
+
19
+ ## Version evidence
20
+ Base images pinned by digest are proven; tag-only `FROM` lines are recorded
21
+ as unpinned evidence and the skill pack pushes toward digests. Compose
22
+ `image:` entries likewise.
23
+
24
+ ## Validation plan
25
+ - `["hadolint", "Dockerfile"]` lint in the sandbox image;
26
+ `["docker", "compose", "config", "-q"]` for Compose syntax (offline,
27
+ no engine calls beyond config parsing). An actual `docker build` is
28
+ arbitrary remote-fetching execution — out of scope for validation; at
29
+ most a later opt-in tier with a network-off buildkit and preloaded bases.
30
+
31
+ ## Skill pack
32
+ Multi-stage builds, non-root `USER`, explicit `WORKDIR`, no secrets in
33
+ layers/ARGs (aligns with the secret scanner), `.dockerignore` completeness,
34
+ healthchecks, digest pinning.
35
+
36
+ ## Risks & gates
37
+ `FROM` changes, new `RUN curl | sh` patterns (refuse — matches the
38
+ implicit-downloader rejection), privileged/host-mount Compose options, and
39
+ port/secret exposure are elevated-risk requiring contract authorization.
40
+
41
+ ## Checklist
42
+ 1. `Ecosystem` union + `analysis/adapters/container.ts`.
43
+ 2. `container/dockerfile`, `container/compose` at `preview`.
44
+ 3. Skill pack; patch-policy tests for RUN-pattern and privilege gating.
45
+ 4. Tests: multi-stage graphs, digest vs tag evidence, compose schema versions.
46
+ 5. Docs updates.
@@ -0,0 +1,47 @@
1
+ # Go support plan
2
+
3
+ ## Status today
4
+ Level 1: `LANGUAGE_PROFILES` has `go` (`.go`), and `.go` is in
5
+ `SCANNED_EXTENSIONS`, so whole-file `.human` and inline `// @human` markers
6
+ already work through the direct path. No grounded profile.
7
+
8
+ ## Target profile
9
+ - `Ecosystem`: `go` (new union member in `analyzer-types.ts`).
10
+ - Variants: `module` (single `go.mod`), `workspace` (`go.work`), with
11
+ HTTP-framework signals (net/http, chi, gin, echo) recorded as profile
12
+ signals, not variants, until one earns its own entry.
13
+ - Versions: Go ≥ 1.21 (from the `go` directive in `go.mod`).
14
+
15
+ ## Detection signals (static only)
16
+ - `go.mod` — module path, `go`/`toolchain` directives, `require` blocks.
17
+ - `go.sum` — presence distinguishes resolved deps; `go.work`/`go.work.sum`
18
+ for workspaces. Conflicting nested modules without `go.work` → `NEEDS_INPUT`.
19
+ - `*_test.go` naming for test roots; `cmd/`, `internal/`, `pkg/` conventions
20
+ for entry-point/source-root inventory. Never run `go list`.
21
+
22
+ ## Version evidence
23
+ `go.mod` `require` lines give exact pinned versions (Go modules pin by
24
+ design); `go.sum` corroborates. Both are protected/lockfile paths the model
25
+ must not edit.
26
+
27
+ ## Validation plan (sandbox argv arrays)
28
+ - `["go", "build", "./..."]`, `["go", "vet", "./..."]`, `["go", "test", "./..."]`.
29
+ - Needs a Go toolchain image; record the `go` directive so an image mismatch
30
+ is `INCONCLUSIVE`, not a guess.
31
+
32
+ ## Skill pack
33
+ Module-path-relative imports only; table-driven tests; error-wrapping
34
+ (`%w`) conventions; no `init()` side effects; generated files
35
+ (`*_gen.go`, `zz_generated*`) are protected.
36
+
37
+ ## Risks & gates
38
+ `cgo`, `unsafe`, `//go:generate`, build tags, and replace directives are
39
+ elevated-risk and need explicit contract authorization — same posture as
40
+ Rust's `unsafe`/FFI gates.
41
+
42
+ ## Checklist
43
+ 1. Add `go` to the `Ecosystem` union + `analysis/adapters/go.ts` implementing `EcosystemAdapter`.
44
+ 2. Declare `go/module` + `go/workspace` in `support-matrix.ts` at `preview`.
45
+ 3. Register in `DEFAULT_ECOSYSTEM_ADAPTERS`; add a Go skill pack in `compiler-skills.ts`.
46
+ 4. Tests per CONTRIBUTING's analyzer checklist: nested modules, missing `go.sum`, `go.work` ambiguity, cgo detection, stable fingerprints.
47
+ 5. Update `docs/MODULES.md` and the support matrix section of the README.
@@ -0,0 +1,47 @@
1
+ # HTML & CSS support plan
2
+
3
+ ## Status today
4
+ Level 2 only: not in `LANGUAGE_PROFILES`. React/Vite workspaces already
5
+ cover most component markup/styling through the existing node adapter; this
6
+ plan is for *static* sites and stylesheet-centric projects.
7
+
8
+ ## Target profile
9
+ - `Ecosystem`: `static-web`.
10
+ - Variant: `static-site` — plain HTML/CSS/vanilla-JS trees (like this
11
+ repo's `website/`), optionally with a recognized static generator config
12
+ (Eleventy, Astro static) as a later variant.
13
+ - Signals: `index.html` at a root, no framework manifest claiming the tree.
14
+
15
+ ## Detection signals (static only)
16
+ - `index.html` + sibling `*.css`/`*.js` without `package.json` build
17
+ tooling; `<link rel="stylesheet">`/`<script src>` graphs (textual);
18
+ generator configs (`.eleventy.js`, `astro.config.*`) detected but not
19
+ executed.
20
+
21
+ ## Version evidence
22
+ CDN dependencies (script/link URLs) are recorded as evidence with their
23
+ pinned versions when the URL encodes one; unpinned CDN URLs are flagged —
24
+ the skill pack should push toward pinned or vendored assets.
25
+
26
+ ## Validation plan
27
+ - `["npx", "html-validate", "<files>"]` and `["npx", "stylelint", "<files>"]`
28
+ style checks with tools preinstalled in the image; link-graph check
29
+ (internal hrefs resolve) implementable in-process without execution.
30
+
31
+ ## Skill pack
32
+ Semantic landmarks, heading order, alt text, `prefers-reduced-motion` and
33
+ `prefers-color-scheme` support, no inline event handlers, responsive images
34
+ — accessibility is the correctness bar for markup.
35
+
36
+ ## Risks & gates
37
+ Third-party `<script src>` additions are supply-chain-sensitive →
38
+ elevated-risk, must be pinned and contract-authorized. Inline scripts are
39
+ ordinary code and reviewed as such.
40
+
41
+ ## Checklist
42
+ 0. Add `html`/`css` to `LANGUAGE_PROFILES` (`.html`, `.css`) for the direct path.
43
+ 1. `Ecosystem` union + `analysis/adapters/static-web.ts`.
44
+ 2. `static-web/static-site` at `preview`.
45
+ 3. Skill pack centred on accessibility conventions.
46
+ 4. Tests: framework-owned trees not double-claimed, CDN pin detection, link-graph checks.
47
+ 5. Docs updates.
@@ -0,0 +1,48 @@
1
+ # Java support plan
2
+
3
+ ## Status today
4
+ Level 1: `LANGUAGE_PROFILES` has `java` (`.java`), and `.java` is scanned for
5
+ inline `// @human` markers. No grounded profile.
6
+
7
+ ## Target profile
8
+ - `Ecosystem`: `java`.
9
+ - Variants: `maven` (`pom.xml`) and `gradle` (`build.gradle`/`.kts`,
10
+ `settings.gradle`), with Spring Boot recorded as a framework signal first
11
+ and promoted to its own variant once the adapter proves reliable.
12
+ - Versions: JDK 17+ (from `maven.compiler.release` / Gradle toolchain block).
13
+
14
+ ## Detection signals (static only)
15
+ - `pom.xml` parent/modules for Maven multi-module ownership.
16
+ - `settings.gradle(.kts)` `include(...)` for Gradle subprojects — parsed
17
+ textually and conservatively; unresolvable dynamic includes → `NEEDS_INPUT`.
18
+ - `src/main/java`, `src/test/java` for source/test roots; `@SpringBootApplication`
19
+ as an entry-point signal. Never execute Maven/Gradle.
20
+
21
+ ## Version evidence
22
+ Maven: exact `<version>` pins in `pom.xml` (property-indirected versions
23
+ resolved only when the property is a literal in the same reactor).
24
+ Gradle: version catalogs (`gradle/libs.versions.toml`) and lockfiles
25
+ (`gradle.lockfile`) when present; otherwise the dependency is unproven and
26
+ API grounding for it must refuse.
27
+
28
+ ## Validation plan
29
+ - Maven: `["mvn", "-B", "-q", "verify"]`. Gradle: `["./gradlew", "--no-daemon", "build"]`
30
+ only when the wrapper exists (wrapper jars are arbitrary code — sandbox only).
31
+ - JDK image recorded by version; mismatch is `INCONCLUSIVE`.
32
+
33
+ ## Skill pack
34
+ Package/directory correspondence; constructor injection over field injection
35
+ (Spring); JUnit 5 conventions; no reflection-based config edits; generated
36
+ sources under `target/`/`build/` are protected.
37
+
38
+ ## Risks & gates
39
+ Annotation processors, Gradle build-script edits, `module-info.java`
40
+ changes, and dependency additions are elevated-risk; build scripts are
41
+ executable code and must never be model-editable.
42
+
43
+ ## Checklist
44
+ 1. `Ecosystem` union + `analysis/adapters/java.ts`.
45
+ 2. `java/maven`, `java/gradle` at `preview` in `support-matrix.ts`.
46
+ 3. Register adapter; Java/Spring skill pack.
47
+ 4. Adversarial tests: multi-module reactors, dynamic Gradle includes, version properties, wrapper absence, stable fingerprints.
48
+ 5. Docs updates (MODULES.md, README support matrix).
@@ -0,0 +1,44 @@
1
+ # Kotlin support plan
2
+
3
+ ## Status today
4
+ Level 2 only: not in `LANGUAGE_PROFILES`; `.kt` not scanned for markers.
5
+
6
+ ## Target profile
7
+ - `Ecosystem`: `kotlin` (JVM/Gradle first; Android later as its own variant
8
+ because of SDK/emulator validation constraints).
9
+ - Variants: `gradle-jvm`, then `android` (deferred until a headless
10
+ validation story exists — unit tests only, no instrumented tests).
11
+ - Versions: Kotlin ≥ 1.9 (from the Kotlin Gradle plugin version in the
12
+ version catalog or build script literals).
13
+
14
+ ## Detection signals (static only)
15
+ - `build.gradle.kts` with `kotlin("jvm")`/`org.jetbrains.kotlin` plugin
16
+ (textual, conservative), `gradle/libs.versions.toml`,
17
+ `src/main/kotlin`, `src/test/kotlin`; `AndroidManifest.xml` marks the
18
+ android variant. Never execute Gradle.
19
+
20
+ ## Version evidence
21
+ Version catalogs and `gradle.lockfile` when present; literal plugin/dependency
22
+ versions otherwise. Dynamic version expressions leave deps unproven.
23
+
24
+ ## Validation plan
25
+ - `["./gradlew", "--no-daemon", "test"]` (wrapper = arbitrary code, sandbox
26
+ only, deps preinstalled/cached offline). Android: `testDebugUnitTest` only.
27
+
28
+ ## Skill pack
29
+ Null-safety idioms, data classes, coroutines conventions (structured
30
+ concurrency, no `GlobalScope`), JUnit5/Kotest layout, `build/` and generated
31
+ KSP/KAPT output protected.
32
+
33
+ ## Risks & gates
34
+ KSP/KAPT processors, Gradle script edits, multiplatform targets, and JNI are
35
+ elevated-risk. Shares most gates with the Java plan — build one Gradle
36
+ inventory helper both adapters reuse (`analyzer-utils.ts` addition).
37
+
38
+ ## Checklist
39
+ 0. Add `kotlin` to `LANGUAGE_PROFILES` (`.kt`) and scan `.kt`/`.kts` for `// @human`.
40
+ 1. `Ecosystem` union + `analysis/adapters/kotlin.ts` (shared Gradle helpers with java.md's adapter).
41
+ 2. `kotlin/gradle-jvm` at `preview`; `kotlin/android` deferred and documented.
42
+ 3. Register adapter; Kotlin skill pack.
43
+ 4. Tests: catalog vs literal versions, multiplatform refusal, Android detection, stable fingerprints.
44
+ 5. Docs updates.
@@ -0,0 +1,42 @@
1
+ # PHP support plan
2
+
3
+ ## Status today
4
+ Level 2 only: not in `LANGUAGE_PROFILES` (direct path would fall back to a
5
+ `.txt` profile) and `.php` is not scanned for markers.
6
+
7
+ ## Target profile
8
+ - `Ecosystem`: `php`.
9
+ - Variants: `composer-app`, `laravel` (artisan + `bootstrap/app.php`),
10
+ `symfony` later.
11
+ - Versions: PHP ≥ 8.2 (from `composer.json` `require.php`).
12
+
13
+ ## Detection signals (static only)
14
+ - `composer.json` (`require`, `autoload.psr-4`), `composer.lock`,
15
+ `artisan`, `routes/`, `app/Http/` for Laravel; `phpunit.xml(.dist)` for
16
+ tests. Never run composer or artisan.
17
+
18
+ ## Version evidence
19
+ `composer.lock` `packages[].version` is exact; `composer.json` ranges alone
20
+ leave dependencies unproven.
21
+
22
+ ## Validation plan
23
+ - `["vendor/bin/phpunit"]`; `["vendor/bin/phpstan", "analyse"]` when
24
+ configured; `["php", "-l", "<changed files>"]` as a cheap syntax gate.
25
+ `vendor/` must be preinstalled in the image (no network).
26
+
27
+ ## Skill pack
28
+ PSR-4 path↔namespace correspondence, PSR-12 style, Laravel conventions
29
+ (form requests for validation, Eloquent scopes), `vendor/` and framework
30
+ cache dirs protected.
31
+
32
+ ## Risks & gates
33
+ Laravel migrations review-only; `eval`/dynamic includes opaque to import
34
+ grounding; service-provider registration changes are elevated-risk.
35
+
36
+ ## Checklist
37
+ 0. Add `php` to `LANGUAGE_PROFILES` (`.php`) and `.php` to `SCANNED_EXTENSIONS` — direct-path quick win.
38
+ 1. `Ecosystem` union + `analysis/adapters/php.ts`.
39
+ 2. `php/composer-app`, `php/laravel` at `preview`.
40
+ 3. Register adapter; PHP/Laravel skill pack.
41
+ 4. Tests: missing lockfile, PSR-4 mismatches, Laravel vs plain-composer ambiguity, stable fingerprints.
42
+ 5. Docs updates.