@nurix/etna 0.20.36 → 0.20.38

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 (212) hide show
  1. package/data/catalog/rules/frontend.md +5 -5
  2. package/data/catalog/rules/pnpm.md +2 -2
  3. package/data/catalog/skills/nustack/SKILL.md +2 -2
  4. package/data/catalog/skills/nustack/references/cli-design.md +35 -35
  5. package/data/catalog/skills/nustack/references/monorepo-master-list.md +6 -6
  6. package/data/catalog/skills/nustack/references/monorepo-setup.md +13 -13
  7. package/data/catalog/skills/nustack/references/publishing.md +40 -39
  8. package/data/harness-index.json +1 -1
  9. package/data/harnesses/code/harness.json +2 -2
  10. package/data/harnesses/code/hooks/approved-packages.md +1 -2
  11. package/data/harnesses/code/rules/frontend.md +5 -5
  12. package/data/harnesses/code/rules/pnpm.md +2 -2
  13. package/data/harnesses/code/skills/boundary/SKILL.md +33 -22
  14. package/data/harnesses/code/skills/boundary/references/index.md +2 -4
  15. package/data/harnesses/code/skills/boundary/references/mechanisms.md +3 -10
  16. package/data/harnesses/code/skills/boundary/references/packs/build-config-runtime.md +1 -1
  17. package/data/harnesses/code/skills/boundary/references/packs/frontend.md +17 -17
  18. package/data/harnesses/code/skills/boundary/references/packs/generic-tail.md +1 -1
  19. package/data/harnesses/code/skills/brainstorm/README.md +11 -13
  20. package/data/harnesses/code/skills/brainstorm/SKILL.md +150 -132
  21. package/data/harnesses/code/skills/brainstorm/references/doctrine.md +48 -51
  22. package/data/harnesses/code/skills/brainstorm/references/harvest.md +51 -56
  23. package/data/harnesses/code/skills/brainstorm/references/session-schema.md +48 -42
  24. package/data/harnesses/code/skills/design/SKILL.md +31 -35
  25. package/data/harnesses/code/skills/design/components/charts.md +121 -43
  26. package/data/harnesses/code/skills/design/components/collections.md +209 -41
  27. package/data/harnesses/code/skills/design/components/feedback.md +86 -25
  28. package/data/harnesses/code/skills/design/components/hooks.md +198 -12
  29. package/data/harnesses/code/skills/design/components/index.md +93 -71
  30. package/data/harnesses/code/skills/design/components/inputs.md +249 -157
  31. package/data/harnesses/code/skills/design/components/layout.md +98 -38
  32. package/data/harnesses/code/skills/design/components/media.md +46 -25
  33. package/data/harnesses/code/skills/design/components/motion.md +56 -46
  34. package/data/harnesses/code/skills/design/components/navigation.md +54 -15
  35. package/data/harnesses/code/skills/design/components/overlays.md +51 -41
  36. package/data/harnesses/code/skills/design/components/setup.md +84 -5
  37. package/data/harnesses/code/skills/design/components/typography.md +72 -22
  38. package/data/harnesses/code/skills/design/components/utils.md +47 -13
  39. package/data/harnesses/code/skills/design/data/chrome/board-column.md +12 -12
  40. package/data/harnesses/code/skills/design/data/chrome/data-table.md +6 -6
  41. package/data/harnesses/code/skills/design/data/chrome/side-panel.md +15 -15
  42. package/data/harnesses/code/skills/design/data/chrome/sidebar.md +25 -25
  43. package/data/harnesses/code/skills/design/data/chrome/stat-cards.md +22 -22
  44. package/data/harnesses/code/skills/design/data/chrome/topbar.md +12 -12
  45. package/data/harnesses/code/skills/design/data/iconography.md +2 -2
  46. package/data/harnesses/code/skills/design/references/compose.md +14 -16
  47. package/data/harnesses/code/skills/design/references/emission.md +6 -6
  48. package/data/harnesses/code/skills/design/references/foundations.md +5 -5
  49. package/data/harnesses/code/skills/design/references/intake.md +6 -6
  50. package/data/harnesses/code/skills/design/references/object-pass.md +1 -1
  51. package/data/harnesses/code/skills/design/references/ship-gate.md +5 -5
  52. package/data/harnesses/code/skills/design/references/ux-patterns/Readme.md +4 -4
  53. package/data/harnesses/code/skills/design/references/ux-patterns/ai-layer.md +1 -1
  54. package/data/harnesses/code/skills/design/references/ux-patterns/container-choice.md +1 -1
  55. package/data/harnesses/code/skills/design/references/ux-patterns/dashboards.md +1 -1
  56. package/data/harnesses/code/skills/design/references/ux-patterns/modes.md +1 -1
  57. package/data/harnesses/code/skills/design/references/ux-patterns/object-model.md +2 -2
  58. package/data/harnesses/code/skills/design/references/ux-patterns/promotion-demotion.md +1 -1
  59. package/data/harnesses/code/skills/design/references/ux-patterns/settings.md +1 -1
  60. package/data/harnesses/code/skills/design/references/ux-patterns/standard-pages.md +1 -1
  61. package/data/harnesses/code/skills/design/scripts/README-validator.md +20 -8
  62. package/data/harnesses/code/skills/design/scripts/validate-design-md.mjs +15 -10
  63. package/data/harnesses/code/skills/documentation/SKILL.md +5 -5
  64. package/data/harnesses/code/skills/documentation/references/examples.md +22 -22
  65. package/data/harnesses/code/skills/documentation/references/frontmatter.md +3 -3
  66. package/data/harnesses/code/skills/documentation/references/instruction-style.md +3 -3
  67. package/data/harnesses/code/skills/documentation/references/source-comments.md +3 -3
  68. package/data/harnesses/code/skills/documentation/references/style-guide.md +5 -5
  69. package/data/harnesses/code/skills/documentation/references/untemplated.md +8 -8
  70. package/data/harnesses/code/skills/documentation/scripts/doc-lint.mjs +3 -2
  71. package/data/harnesses/code/skills/documentation/templates/Readme.md +1 -1
  72. package/data/harnesses/code/skills/documentation/templates/acceptance-criteria.md +1 -1
  73. package/data/harnesses/code/skills/documentation/templates/api-reference.md +1 -1
  74. package/data/harnesses/code/skills/documentation/templates/architecture-decision.md +3 -7
  75. package/data/harnesses/code/skills/documentation/templates/behavioral-checklist.md +1 -1
  76. package/data/harnesses/code/skills/documentation/templates/changelog-entry.md +1 -1
  77. package/data/harnesses/code/skills/documentation/templates/changelog-index.md +1 -1
  78. package/data/harnesses/code/skills/documentation/templates/docs-readme.md +3 -3
  79. package/data/harnesses/code/skills/documentation/templates/doctrine.md +1 -1
  80. package/data/harnesses/code/skills/documentation/templates/domain-model.md +1 -1
  81. package/data/harnesses/code/skills/documentation/templates/environment-registry.md +1 -1
  82. package/data/harnesses/code/skills/documentation/templates/feature.md +3 -3
  83. package/data/harnesses/code/skills/documentation/templates/handover.md +2 -2
  84. package/data/harnesses/code/skills/documentation/templates/implementation-map.md +1 -1
  85. package/data/harnesses/code/skills/documentation/templates/migration-runbook.md +1 -1
  86. package/data/harnesses/code/skills/documentation/templates/non-goals.md +1 -1
  87. package/data/harnesses/code/skills/documentation/templates/operations-procedure.md +2 -2
  88. package/data/harnesses/code/skills/documentation/templates/package.md +1 -1
  89. package/data/harnesses/code/skills/documentation/templates/protected-files.md +1 -1
  90. package/data/harnesses/code/skills/documentation/templates/root-readme.md +1 -1
  91. package/data/harnesses/code/skills/documentation/templates/security-overview.md +1 -1
  92. package/data/harnesses/code/skills/documentation/templates/system-overview.md +1 -1
  93. package/data/harnesses/code/skills/documentation/templates/system.md +1 -1
  94. package/data/harnesses/code/skills/documentation/templates/testing-strategy.md +1 -1
  95. package/data/harnesses/code/skills/documentation/templates/ux-behavior.md +3 -5
  96. package/data/harnesses/code/skills/issue-bridge/SKILL.md +51 -16
  97. package/data/harnesses/code/skills/issue-bridge/references/trackers/github.md +5 -5
  98. package/data/harnesses/code/skills/issue-bridge/references/trackers/jira.md +11 -8
  99. package/data/harnesses/code/skills/issue-bridge/references/trackers/linear.md +16 -11
  100. package/data/harnesses/code/skills/nustack-graph/SKILL.md +38 -29
  101. package/data/harnesses/code/skills/polygraph/references/dispatch.md +31 -18
  102. package/data/harnesses/code/skills/polygraph/references/rows.md +11 -6
  103. package/data/harnesses/code/skills/schema-design/SKILL.md +39 -41
  104. package/data/harnesses/code/skills/test/SKILL.md +38 -42
  105. package/data/harnesses/code/skills/testing/SKILL.md +83 -73
  106. package/data/harnesses/code/skills/workflow-mapper/SKILL.md +156 -193
  107. package/data/harnesses/code/skills/workflow-mapper/references/patterns.md +15 -15
  108. package/data/harnesses/delivery/harness.json +2 -2
  109. package/data/harnesses/delivery/skills/brainstorm/README.md +11 -13
  110. package/data/harnesses/delivery/skills/brainstorm/SKILL.md +150 -132
  111. package/data/harnesses/delivery/skills/brainstorm/references/doctrine.md +48 -51
  112. package/data/harnesses/delivery/skills/brainstorm/references/harvest.md +51 -56
  113. package/data/harnesses/delivery/skills/brainstorm/references/session-schema.md +48 -42
  114. package/data/harnesses/delivery/skills/cost-report/SKILL.md +10 -10
  115. package/data/harnesses/delivery/skills/documentation/SKILL.md +5 -5
  116. package/data/harnesses/delivery/skills/documentation/references/examples.md +22 -22
  117. package/data/harnesses/delivery/skills/documentation/references/frontmatter.md +3 -3
  118. package/data/harnesses/delivery/skills/documentation/references/instruction-style.md +3 -3
  119. package/data/harnesses/delivery/skills/documentation/references/source-comments.md +3 -3
  120. package/data/harnesses/delivery/skills/documentation/references/style-guide.md +5 -5
  121. package/data/harnesses/delivery/skills/documentation/references/untemplated.md +8 -8
  122. package/data/harnesses/delivery/skills/documentation/scripts/doc-lint.mjs +3 -2
  123. package/data/harnesses/delivery/skills/documentation/templates/Readme.md +1 -1
  124. package/data/harnesses/delivery/skills/documentation/templates/acceptance-criteria.md +1 -1
  125. package/data/harnesses/delivery/skills/documentation/templates/api-reference.md +1 -1
  126. package/data/harnesses/delivery/skills/documentation/templates/architecture-decision.md +3 -7
  127. package/data/harnesses/delivery/skills/documentation/templates/behavioral-checklist.md +1 -1
  128. package/data/harnesses/delivery/skills/documentation/templates/changelog-entry.md +1 -1
  129. package/data/harnesses/delivery/skills/documentation/templates/changelog-index.md +1 -1
  130. package/data/harnesses/delivery/skills/documentation/templates/docs-readme.md +3 -3
  131. package/data/harnesses/delivery/skills/documentation/templates/doctrine.md +1 -1
  132. package/data/harnesses/delivery/skills/documentation/templates/domain-model.md +1 -1
  133. package/data/harnesses/delivery/skills/documentation/templates/environment-registry.md +1 -1
  134. package/data/harnesses/delivery/skills/documentation/templates/feature.md +3 -3
  135. package/data/harnesses/delivery/skills/documentation/templates/handover.md +2 -2
  136. package/data/harnesses/delivery/skills/documentation/templates/implementation-map.md +1 -1
  137. package/data/harnesses/delivery/skills/documentation/templates/migration-runbook.md +1 -1
  138. package/data/harnesses/delivery/skills/documentation/templates/non-goals.md +1 -1
  139. package/data/harnesses/delivery/skills/documentation/templates/operations-procedure.md +2 -2
  140. package/data/harnesses/delivery/skills/documentation/templates/package.md +1 -1
  141. package/data/harnesses/delivery/skills/documentation/templates/protected-files.md +1 -1
  142. package/data/harnesses/delivery/skills/documentation/templates/root-readme.md +1 -1
  143. package/data/harnesses/delivery/skills/documentation/templates/security-overview.md +1 -1
  144. package/data/harnesses/delivery/skills/documentation/templates/system-overview.md +1 -1
  145. package/data/harnesses/delivery/skills/documentation/templates/system.md +1 -1
  146. package/data/harnesses/delivery/skills/documentation/templates/testing-strategy.md +1 -1
  147. package/data/harnesses/delivery/skills/documentation/templates/ux-behavior.md +3 -5
  148. package/data/harnesses/delivery/skills/escalate/SKILL.md +11 -11
  149. package/data/harnesses/delivery/skills/prompt-eval/SKILL.md +8 -8
  150. package/data/harnesses/delivery/skills/prompt-library/SKILL.md +30 -9
  151. package/data/harnesses/delivery/skills/route/SKILL.md +8 -8
  152. package/data/harnesses/etna/harness.json +2 -2
  153. package/data/harnesses/etna/skills/boundary/SKILL.md +33 -22
  154. package/data/harnesses/etna/skills/boundary/references/index.md +2 -4
  155. package/data/harnesses/etna/skills/boundary/references/mechanisms.md +3 -10
  156. package/data/harnesses/etna/skills/boundary/references/packs/build-config-runtime.md +1 -1
  157. package/data/harnesses/etna/skills/boundary/references/packs/frontend.md +17 -17
  158. package/data/harnesses/etna/skills/boundary/references/packs/generic-tail.md +1 -1
  159. package/data/harnesses/etna/skills/brainstorm/README.md +11 -13
  160. package/data/harnesses/etna/skills/brainstorm/SKILL.md +150 -132
  161. package/data/harnesses/etna/skills/brainstorm/references/doctrine.md +48 -51
  162. package/data/harnesses/etna/skills/brainstorm/references/harvest.md +51 -56
  163. package/data/harnesses/etna/skills/brainstorm/references/session-schema.md +48 -42
  164. package/data/harnesses/etna/skills/documentation/SKILL.md +5 -5
  165. package/data/harnesses/etna/skills/documentation/references/examples.md +22 -22
  166. package/data/harnesses/etna/skills/documentation/references/frontmatter.md +3 -3
  167. package/data/harnesses/etna/skills/documentation/references/instruction-style.md +3 -3
  168. package/data/harnesses/etna/skills/documentation/references/source-comments.md +3 -3
  169. package/data/harnesses/etna/skills/documentation/references/style-guide.md +5 -5
  170. package/data/harnesses/etna/skills/documentation/references/untemplated.md +8 -8
  171. package/data/harnesses/etna/skills/documentation/scripts/doc-lint.mjs +3 -2
  172. package/data/harnesses/etna/skills/documentation/templates/Readme.md +1 -1
  173. package/data/harnesses/etna/skills/documentation/templates/acceptance-criteria.md +1 -1
  174. package/data/harnesses/etna/skills/documentation/templates/api-reference.md +1 -1
  175. package/data/harnesses/etna/skills/documentation/templates/architecture-decision.md +3 -7
  176. package/data/harnesses/etna/skills/documentation/templates/behavioral-checklist.md +1 -1
  177. package/data/harnesses/etna/skills/documentation/templates/changelog-entry.md +1 -1
  178. package/data/harnesses/etna/skills/documentation/templates/changelog-index.md +1 -1
  179. package/data/harnesses/etna/skills/documentation/templates/docs-readme.md +3 -3
  180. package/data/harnesses/etna/skills/documentation/templates/doctrine.md +1 -1
  181. package/data/harnesses/etna/skills/documentation/templates/domain-model.md +1 -1
  182. package/data/harnesses/etna/skills/documentation/templates/environment-registry.md +1 -1
  183. package/data/harnesses/etna/skills/documentation/templates/feature.md +3 -3
  184. package/data/harnesses/etna/skills/documentation/templates/handover.md +2 -2
  185. package/data/harnesses/etna/skills/documentation/templates/implementation-map.md +1 -1
  186. package/data/harnesses/etna/skills/documentation/templates/migration-runbook.md +1 -1
  187. package/data/harnesses/etna/skills/documentation/templates/non-goals.md +1 -1
  188. package/data/harnesses/etna/skills/documentation/templates/operations-procedure.md +2 -2
  189. package/data/harnesses/etna/skills/documentation/templates/package.md +1 -1
  190. package/data/harnesses/etna/skills/documentation/templates/protected-files.md +1 -1
  191. package/data/harnesses/etna/skills/documentation/templates/root-readme.md +1 -1
  192. package/data/harnesses/etna/skills/documentation/templates/security-overview.md +1 -1
  193. package/data/harnesses/etna/skills/documentation/templates/system-overview.md +1 -1
  194. package/data/harnesses/etna/skills/documentation/templates/system.md +1 -1
  195. package/data/harnesses/etna/skills/documentation/templates/testing-strategy.md +1 -1
  196. package/data/harnesses/etna/skills/documentation/templates/ux-behavior.md +3 -5
  197. package/data/harnesses/etna/skills/workflow-mapper/SKILL.md +156 -193
  198. package/data/harnesses/etna/skills/workflow-mapper/references/patterns.md +15 -15
  199. package/data/harnesses/hr/harness.json +2 -2
  200. package/data/harnesses/hr/skills/evaluator/SKILL.md +71 -73
  201. package/data/harnesses/hr/skills/evaluator/criteria/code-quality.md +28 -47
  202. package/data/harnesses/hr/skills/evaluator/criteria/deployment-readiness.md +33 -43
  203. package/data/harnesses/hr/skills/evaluator/criteria/maintainability.md +34 -46
  204. package/data/harnesses/hr/skills/evaluator/criteria/mechanical-ambition.md +13 -13
  205. package/data/harnesses/hr/skills/evaluator/criteria/problem-substantiveness.md +7 -7
  206. package/data/harnesses/hr/skills/evaluator/criteria/testing.md +36 -41
  207. package/data/harnesses/hr/skills/evaluator/criteria/ux-mechanics.md +25 -11
  208. package/data/harnesses/hr/skills/evaluator/criteria/value-articulation.md +7 -7
  209. package/data/harnesses/hr/skills/evaluator/preflight.md +27 -46
  210. package/data/harnesses/hr/skills/interview-eval/SKILL.md +37 -42
  211. package/data/harnesses/hr/skills/interview-eval/rubric.md +21 -23
  212. package/package.json +2 -2
@@ -1,13 +1,13 @@
1
1
  # Deployment-Readiness — Extraction Plan
2
2
 
3
- - **Sub-criterion:** 1.3 (AI-only)
4
- - **Weight:** 12.5 pts (4 Code AI × 12.5 = 50 pts half)
3
+ - **Sub-criterion:** 1.3 (Production-Grade Code)
4
+ - **Weight:** 12.5 pts
5
5
  - **Contenders:** Filesystem probes + Hadolint + **observability markers** (structured-logging library presence, metrics/tracing library presence, `/health` endpoint detection) + LLM README/Dockerfile read (layered)
6
6
  - **Source quote:** _"Can this actually ship? Docker, config, health checks, or clear instructions to run it outside localhost."_
7
7
 
8
- Bands are **absolute** — per-signal thresholds in the _Banding_ section. Gates this recipe owns: **`DEMO`** (`deployment_readiness ≤ 1` when all 4 run-section/deploy signals are false OR README claims a deploy artifact that doesn't exist in the tree) and **`OBSERVABILITY`** (caps `deployment_readiness ≤ 3` when structured-logging library is absent AND metrics/tracing library is absent). Structured-logging detection: presence of `structlog` / `winston` / `pino` / `log-slog` / `zap` in deps OR JSON log format detected in code. Metrics/tracing detection: OpenTelemetry SDK / Prometheus client / Datadog agent / statsd client / a custom `/metrics` endpoint. Gate fires only when **both** categories are absent — a repo with structured logging but no metrics still ships above 3. Raw dump: `raw/deployment-readiness-observability-markers.json` with fields `{logging_lib: "<name>"|null, metrics_lib: "<name>"|null, has_health_endpoint: bool, json_log_detected: bool}`.
8
+ Bands are **absolute** — per-signal thresholds in _Aggregation_. This recipe owns two gates, each in its own section below: `DEMO` and `OBSERVABILITY`.
9
9
 
10
- > Five signals, integrated by the scorer. Serverless-native repos (no Dockerfile) can reach band 5 via PaaS/managed-platform path — see bands. No weighted-math internal split — the LLM emits a single 0–5 band and cites the most load-bearing signal.
10
+ Signals 1–5 feed the band and Signal 6 feeds the `OBSERVABILITY` gate. There is no weighted internal split — the LLM emits a single 0–5 band and cites the most load-bearing signal. Serverless-native repos with no Dockerfile reach band 5 through Path B.
11
11
 
12
12
  ---
13
13
 
@@ -71,7 +71,7 @@ Capture: `has_env_example`, `env_in_gitignore`, `tracked_env_files` (list; shoul
71
71
  ls <repo>/.github/workflows/ 2>/dev/null \
72
72
  | grep -iE 'deploy|release|publish|ship'
73
73
 
74
- # PaaS configs — broad 2026 landscape
74
+ # PaaS configs
75
75
  ls <repo>/{\
76
76
  vercel.json,netlify.toml,\
77
77
  fly.toml,\
@@ -105,7 +105,7 @@ find <repo> -maxdepth 3 -name 'kustomization.yaml' 2>/dev/null
105
105
  Capture:
106
106
 
107
107
  - `deploy_workflow_files` (list)
108
- - `paas_configs` (list of present files; extend the list as new deploy targets appear)
108
+ - `paas_configs` (list of present files)
109
109
  - `iac_dirs` (list of present dirs)
110
110
  - `has_any_deploy_artifact` = bool (OR across above + Signal 1 containerization)
111
111
 
@@ -171,7 +171,7 @@ Capture:
171
171
 
172
172
  ### Signal 6 — Observability markers (OBSERVABILITY gate trigger)
173
173
 
174
- Ships-to-prod requires signal — structured logs and metrics/traces. This signal looks for evidence that either is wired into the app. **Both** must be absent for the gate to fire; one present means the repo has the basics.
174
+ Look for evidence that structured logs or metrics/traces are wired into the app.
175
175
 
176
176
  ```bash
177
177
  # Structured-logging library — check deps (manifest) + imports (code) + JSON-log
@@ -202,8 +202,8 @@ grep -rnE "import.*\b($LOG_LIBS)\b|from\s+($LOG_LIBS)" \
202
202
  2>/dev/null | head -20
203
203
 
204
204
  # JSON log-format heuristic — bare `json.dumps(...)` inside what looks like a
205
- # log call. Weak signal; participates only as a fallback. Evaluator should
206
- # confirm with LLM when this is the only logging-arm match.
205
+ # log call. Weak, fallback only: confirm with the LLM read when this is the
206
+ # only logging-arm match.
207
207
  grep -rnE '(logger|log)\.(info|warn|error|debug)\([^)]*json\.(dumps|stringify)' \
208
208
  <repo>/src <repo>/app \
209
209
  --include='*.py' --include='*.ts' --include='*.js' --include='*.go' \
@@ -238,7 +238,7 @@ grep -rnE '["/]metrics["/\s(]' <repo>/src <repo>/app \
238
238
  --exclude-dir=node_modules 2>/dev/null | head -10
239
239
  ```
240
240
 
241
- Assemble observability markers JSON (the sub-agent writes the interpreted fields, not the raw grep):
241
+ Write the observability markers JSON with the interpreted fields, not the raw grep:
242
242
 
243
243
  ```json
244
244
  {
@@ -257,17 +257,17 @@ Capture:
257
257
  - `logging_lib` — name of the structured-logging library, or `null` if none found
258
258
  - `metrics_lib` — name of the metrics/tracing library, or `null` if none found
259
259
  - `has_metrics_endpoint` — bool (custom `/metrics` route found)
260
- - `has_json_log_format` — bool (heuristic match; low-confidence tiebreaker only)
260
+ - `has_json_log_format` — bool (`json_log_detected` in the markers file; heuristic match, low-confidence tiebreaker only)
261
261
  - `observability_logging_present` = `(logging_lib != null) OR has_json_log_format`
262
262
  - `observability_metrics_present` = `(metrics_lib != null) OR has_metrics_endpoint`
263
263
 
264
- **OBSERVABILITY gate trigger:** `observability_logging_present == false` AND `observability_metrics_present == false`. Both must be absent for the gate to fire — one present is enough to avoid the cap. Caps `deployment_readiness ≤ 3`.
264
+ These feed the [OBSERVABILITY gate](#observability-gate--both-arms-absent).
265
265
 
266
266
  ---
267
267
 
268
268
  ## Raw dumps (flat — files under `raw/` named `deployment-readiness-*`)
269
269
 
270
- Each signal writes its raw output to the flat `raw/` directory at the workspace root. Absent files = not extracted / not applicable. Aggregates go to `scorecard.yaml` under `data.`.
270
+ Each signal writes its raw output to the flat `raw/` directory; an absent file means not extracted or not applicable. Aggregates go to `scorecard.yaml` under `data.`.
271
271
 
272
272
  | File | Source signal | Shape / note |
273
273
  | --- | --- | --- |
@@ -281,7 +281,7 @@ Each signal writes its raw output to the flat `raw/` directory at the workspace
281
281
 
282
282
  ## Aggregation → 0–5 band
283
283
 
284
- Scorer integrates the 5 signals. Rough directionality:
284
+ Integrate Signals 1–5. Rough directionality:
285
285
 
286
286
  | Signal | Pulls score UP | Pulls score DOWN |
287
287
  | --- | --- | --- |
@@ -305,42 +305,32 @@ Scorer integrates the 5 signals. Rough directionality:
305
305
  | **1** | DEMO gate fires (see below); localhost-only repo |
306
306
  | **0** | Suppressed (DEMO gate caps at 1) |
307
307
 
308
- Serverless-native repos (Vercel/Fly/Cloudflare/Modal) reach band 5 via Path B — do not penalize absent Dockerfile if a PaaS config carries the deploy artifact.
308
+ Serverless-native repos (Vercel/Fly/Cloudflare/Modal) reach band 5 via Path B — **never** penalize an absent Dockerfile when a PaaS config carries the deploy artifact.
309
309
 
310
310
  ---
311
311
 
312
312
  ## DEMO gate — two-signal agreement
313
313
 
314
- Gate fires only when **all three** are absent AND the LLM + mechanical README read agree:
314
+ The gate fires on either trigger:
315
315
 
316
- ```
317
- has_container_artifact == false
318
- AND has_any_deploy_artifact == false (i.e. no GHA deploy, no PaaS config, no IaC)
319
- AND readme_has_run_section == false (mechanical heading grep)
320
- AND llm_has_run_section == false (LLM read)
321
- ```
316
+ 1. **No ship path, by agreement** — every one of these is false, so the mechanical README read and the LLM read agree:
317
+ - `has_container_artifact`
318
+ - `has_any_deploy_artifact` (no GHA deploy, no PaaS config, no IaC)
319
+ - `readme_has_run_section` (mechanical heading grep)
320
+ - `llm_has_run_section` (LLM read)
321
+ 2. **Phantom artifact** — the README claims a deploy artifact (Dockerfile / compose / k8s / target) that does not exist in the tree.
322
322
 
323
- **Why two-signal:** a single LLM judgment as a hard gate means one noisy call caps the score. Requiring heading grep + LLM agreement makes the gate robust to LLM noise. If `llm_confidence == low`, defer to mechanical-only (skip the LLM side of the AND).
323
+ Requiring the grep and the LLM to agree keeps one noisy LLM call from capping the score. If `llm_confidence == low`, drop the LLM term and decide on the mechanical terms alone.
324
324
 
325
- When fired, emit `gates_triggered: [DEMO]` and cap `deployment_readiness ≤ 1`.
325
+ When fired, add `DEMO` to `gates_triggered` and cap `deployment_readiness ≤ 1`.
326
326
 
327
327
  ---
328
328
 
329
329
  ## OBSERVABILITY gate — both arms absent
330
330
 
331
- Gate fires only when **both** observability arms are absent:
332
-
333
- ```
334
- observability_logging_present == false
335
- AND
336
- observability_metrics_present == false
337
- ```
338
-
339
- That is: the repo ships neither a structured-logging library (structlog / winston / pino / log-slog / zap / a detected JSON-log format) **nor** a metrics/tracing library (OpenTelemetry / Prometheus client / Datadog / statsd / a custom `/metrics` endpoint).
340
-
341
- **Why both-arms:** enterprise observability is "logs AND metrics", but a single-binary CLI or a thin FaaS handler may legitimately ship with just structured logs and skip metrics (or vice versa). Demanding both is punitive on small, valid shapes. The gate catches the repo that's shipping without _any_ production-grade signal — `print()`-only logging and no metrics — which is the failure we care about.
331
+ The gate fires only when `observability_logging_present == false` **and** `observability_metrics_present == false` — the repo ships neither a structured-logging library (structlog / loguru / winston / pino / log-slog / zap, or a detected JSON-log format) **nor** a metrics/tracing library (OpenTelemetry / Prometheus client / Datadog / statsd, or a custom `/metrics` endpoint). **Never** fire it on one missing arm: a single-binary CLI or a thin FaaS handler legitimately ships structured logs without metrics, or the reverse; the gate targets `print()`-only logging with no metrics at all.
342
332
 
343
- When fired, emit `gates_triggered: [OBSERVABILITY]` and cap `deployment_readiness ≤ 3`. Absent arm names ship in the evidence string: `"no structured logger AND no metrics/tracing — cap at 3"`.
333
+ When fired, add `OBSERVABILITY` to `gates_triggered`, cap `deployment_readiness ≤ 3`, and name the absent arms in evidence: `"no structured logger AND no metrics/tracing — cap at 3"`.
344
334
 
345
335
  ---
346
336
 
@@ -351,7 +341,7 @@ When fired, emit `gates_triggered: [OBSERVABILITY]` and cap `deployment_readines
351
341
  - Fully serverless (Vercel/Fly only, no Dockerfile) → Path B; PaaS config in Signal 3 carries deploy artifact weight.
352
342
  - LLM low-confidence → DEMO gate falls back to mechanical-only (README heading grep + artifact absence).
353
343
 
354
- Annotate evidence with `"Signals used: [...]"` and `"Path: A | B"` so the audit trail is explicit.
344
+ Annotate evidence with `"Signals used: [...]"` and `"Path: A | B"`.
355
345
 
356
346
  ---
357
347
 
@@ -406,9 +396,9 @@ data:
406
396
 
407
397
  ## Caveats
408
398
 
409
- - File presence ≠ working artifact. Only runtime verification (a separate manual pass) catches broken Dockerfiles / deploy workflows.
410
- - Hadolint catches form, not intent. A "clean" Dockerfile that installs nothing still lints green.
411
- - PaaS probe list needs periodic update — new deploy targets appear faster than the list evolves.
412
- - LLM sample is 1 README. Repos with multi-file docs (`docs/`, `CONTRIBUTING.md`, wiki) may be under-scored on the interpretive signal. Consider glob-and-concat for docs-heavy repos.
413
- - Localhost grep is a noisy counter-signal even with env-var exclusion — LLM notes should adjudicate when the count is > 0 but reasonable.
414
- - Two-signal DEMO gate may still false-negative on repos whose README has a heading like `## Getting Started` that only says `npm run dev` (LLM catches this; mechanical does not). That's why LLM is in the AND, not replaced.
399
+ - File presence ≠ working artifact. Only runtime verification (a separate manual pass) catches broken Dockerfiles or deploy workflows.
400
+ - Hadolint catches form, not intent — a Dockerfile that installs nothing still lints green.
401
+ - The PaaS probe list is non-exhaustive; extend it when a new deploy target appears.
402
+ - The LLM reads one README, so repos with multi-file docs (`docs/`, `CONTRIBUTING.md`, wiki) may be under-scored. Prefer globbing and concatenating the docs for docs-heavy repos.
403
+ - The localhost grep is noisy even with env-var exclusion — the LLM notes adjudicate when the count is > 0 but reasonable.
404
+ - The DEMO gate can still false-negative on a README whose `## Getting Started` heading only says `npm run dev`: the grep passes it and only the LLM term catches it, which is why the LLM stays in the AND rather than replacing the grep.
@@ -1,11 +1,11 @@
1
1
  # Maintainability — Extraction Plan
2
2
 
3
- - **Sub-criterion:** 1.4 (AI-only)
4
- - **Weight:** 12.5 pts (4 Code AI × 12.5 = 50 pts half)
3
+ - **Sub-criterion:** 1.4 (Production-Grade Code)
4
+ - **Weight:** 12.5 pts
5
5
  - **Contenders:** gitleaks + lizard (**per-language CCN**: Py 10 / JS-TS 10 / Java 12 / Go 15) + knip/deptry + **dep-vuln scan** (`pip-audit` / `npm audit --json` / `govulncheck` / Trivy) + LLM folder/README read (layered)
6
6
  - **Source quote:** _"Folder structure and clarity that makes it easy for another engineer to pick up and extend."_
7
7
 
8
- Bands are **absolute** — per-signal thresholds in the _Banding_ section. Gates this recipe owns: **`SECRETS`** (trigger: `gitleaks_findings ≥ 1`, caps `maintainability ≤ 2`) and **`VULN`** (fires when dep-vuln scan reports ≥ 1 CVE at CRITICAL OR ≥ 3 at HIGH across any dep, direct or transitive; caps `maintainability ≤ 2`). Dep-vuln tool selection by ecosystem: Python → `pip-audit`, JS/TS → `npm audit --json` (reads package-lock.json), Go → `govulncheck`, built container → `trivy image`. Skipped if no recognized package manifest. Data fields: `dep_vuln_critical` (int), `dep_vuln_high` (int), `dep_vuln_tool` (string), `dep_vuln_by_ecosystem` (map). Raw dumps: `raw/maintainability-dep-vuln-pip-audit.json` / `raw/maintainability-dep-vuln-npm-audit.json` / `raw/maintainability-dep-vuln-govulncheck.json` / `raw/maintainability-dep-vuln-trivy.json` (one file per tool that ran). lizard `--ccn` threshold uses a per-language lookup (see Signal 2 below).
8
+ Bands are **absolute** — per-signal thresholds in _Aggregation_. This recipe owns two gates — `SECRETS` and `VULN` — defined in § Gates.
9
9
 
10
10
  ---
11
11
 
@@ -35,14 +35,13 @@ Capture:
35
35
  ### Signal 2 — Polyglot complexity (lizard, per-language CCN)
36
36
 
37
37
  ```bash
38
- # 16+ langs. lizard auto-detects languages from file extensions — do NOT pass
39
- # `--languages`; it was removed in lizard 1.21+ and the wrapper errors with
40
- # `unrecognized arguments` (or, depending on the version, silently no-ops).
38
+ # lizard auto-detects 16+ languages from file extensions. Never pass
39
+ # `--languages` — lizard rejects it as `unrecognized arguments` or silently no-ops.
41
40
  lizard -o /tmp/lizard.csv <repo> \
42
41
  -x '*/node_modules/*' -x '*/.venv/*' -x '*/dist/*' -x '*/build/*'
43
42
  ```
44
43
 
45
- **Per-language CCN thresholds** — a function is "god" when its CCN exceeds the threshold for its language. Python/JS/TS are idiom-dense and deserve the tightest cap; Go's for/if-heavy control flow tolerates higher CCN before it becomes hard to read.
44
+ **Per-language CCN thresholds** — a function is "god" when its CCN exceeds its language's threshold. Go's for/if-heavy control flow tolerates a higher CCN before it becomes hard to read; idiom-dense Python/JS/TS get the tightest cap.
46
45
 
47
46
  | Language (lizard CSV column 7 / filename extension) | God-function CCN threshold |
48
47
  | --- | --- |
@@ -52,7 +51,7 @@ lizard -o /tmp/lizard.csv <repo> \
52
51
  | Go (`.go`) | > 15 |
53
52
  | Everything else | > 15 (fallback) |
54
53
 
55
- Parse using the per-language lookup. The lizard CSV has columns: `NLOC,CCN,token,param,length,location,file,name`. Key on file extension:
54
+ The lizard CSV columns are `NLOC,CCN,token,param,length,location,file,name`; key the lookup on file extension:
56
55
 
57
56
  ```bash
58
57
  # God-functions counted per-language threshold
@@ -94,19 +93,15 @@ Capture:
94
93
  Run per ecosystem present in the repo. Detect via package manifest:
95
94
 
96
95
  ```bash
97
- # JS/TS — install project deps BEFORE running knip. knip walks imports and
98
- # needs the repo's own node_modules to resolve them; a bare `npx knip` on a
99
- # freshly-cloned repo with no deps installed silently produces `_NOT_RUN` /
100
- # empty output (observed when a sub-app reported `Cannot find module 'vite'`
101
- # and knip never ran).
96
+ # JS/TS — install project deps BEFORE knip. knip resolves imports through the
97
+ # repo's own node_modules; on a fresh clone it silently yields `_NOT_RUN` /
98
+ # empty output (e.g. `Cannot find module 'vite'`).
102
99
  #
103
- # This branch is MANDATORY when package.json exists. The deps-install step is
104
- # not optional — do not skip it for time/budget reasons. If the install
105
- # genuinely fails (registry down, lockfile broken), knip still runs and
106
- # records the failure in /tmp/knip.err; the resulting `knip_NOT_RUN: true` in
107
- # the scorecard MUST be accompanied by a `knip_reason` quoting the install-step
108
- # error from /tmp/jsdeps.log. A reason of "deps-install step not executed this
109
- # pass" is non-conformant.
100
+ # MANDATORY when package.json exists — never skip the install for time or
101
+ # budget. If the install genuinely fails (registry down, lockfile broken), knip
102
+ # still runs and records the failure in /tmp/knip.err; `knip_NOT_RUN: true`
103
+ # MUST carry a `knip_reason` quoting the install error from /tmp/jsdeps.log.
104
+ # "deps-install step not executed this pass" is a non-conformant reason.
110
105
  if [ -f <repo>/package.json ]; then
111
106
  cd <repo>
112
107
  # Detect lock file → pick the matching package manager. If no lock file
@@ -125,17 +120,12 @@ if [ -f <repo>/package.json ]; then
125
120
  npx --yes knip --reporter json > /tmp/knip.json 2> /tmp/knip.err || true
126
121
  fi
127
122
 
128
- # Python — detect src-layout / Poetry packages declarations so deptry doesn't
129
- # false-positive on first-party imports. One observed project reported 292
130
- # bogus DEP001s because deptry treated `app.*` imports (declared via Poetry's
131
- # `packages = [{ include = "app", from = "src" }]`) as third-party.
132
- #
133
- # Strategy: pull every `tool.poetry.packages[].include` and every
134
- # `tool.setuptools.packages.find` package name out of pyproject.toml, plus
135
- # any top-level package directory under src/ (setuptools-src layout
136
- # convention). Pass them as a comma-separated list to --known-first-party.
137
- # Falls back gracefully (empty list → flag omitted) if no pyproject.toml or
138
- # no parseable declarations.
123
+ # Python — pass first-party packages to --known-first-party, or deptry reports
124
+ # every first-party import as a bogus DEP001 (e.g. `app.*` declared via Poetry's
125
+ # `packages = [{ include = "app", from = "src" }]`, hundreds of findings).
126
+ # Collect `tool.poetry.packages[].include` and `tool.setuptools.packages.find`
127
+ # names from pyproject.toml, plus every top-level dir under src/
128
+ # (setuptools-src convention). An empty list omits the flag.
139
129
  if [ -f <repo>/pyproject.toml ] || [ -f <repo>/requirements.txt ]; then
140
130
  cd <repo>
141
131
  kfp="" # known-first-party packages, comma-separated
@@ -270,15 +260,16 @@ elif [ -f <repo>/yarn.lock ]; then
270
260
  timeout 120 yarn npm audit --json > /tmp/npmaudit.json 2>/dev/null || true
271
261
  fi
272
262
 
273
- # Go — govulncheck walks the module graph. Skipped when go is not on PATH
274
- # (preflight.sh documents this; sub-agent emits _NOT_RUN when appropriate).
263
+ # Go — govulncheck walks the module graph. Without go on PATH preflight skips
264
+ # it; record the Go scan as `_NOT_RUN` with reason
265
+ # "govulncheck unavailable (go not installed)".
275
266
  if [ -f <repo>/go.mod ] && command -v govulncheck >/dev/null 2>&1; then
276
267
  cd <repo>
277
268
  timeout 180 govulncheck -json ./... > /tmp/govulncheck.json 2>/dev/null || true
278
269
  fi
279
270
 
280
- # Container — Trivy scans a built image OR the filesystem directly. FS scan is
281
- # cheaper (no docker build) and covers the same OS+lang package surface.
271
+ # Trivy — scan the filesystem, not a built image: same OS + language package
272
+ # surface, no docker build.
282
273
  timeout 180 trivy fs --format json --scanners vuln --quiet \
283
274
  <repo> > /tmp/trivy.json 2>/dev/null || true
284
275
  ```
@@ -320,7 +311,7 @@ Capture (aggregated across every tool that ran):
320
311
 
321
312
  ## Raw dumps (flat — files under `raw/` named `maintainability-*`)
322
313
 
323
- Each signal writes its raw output to the flat `raw/` directory at the workspace root. Absent files = not extracted / not applicable. Aggregates go to `scorecard.yaml` under `data.`.
314
+ Each signal writes its raw output to the flat `raw/` directory; an absent file means not extracted or not applicable. Aggregates go to `scorecard.yaml` under `data.`.
324
315
 
325
316
  | File | Source signal | Shape / note |
326
317
  | --- | --- | --- |
@@ -341,7 +332,7 @@ Each signal writes its raw output to the flat `raw/` directory at the workspace
341
332
 
342
333
  ## Aggregation → 0–5 band
343
334
 
344
- Scorer integrates the 5 signals. Rough directionality:
335
+ Integrate Signals 1–6. Rough directionality:
345
336
 
346
337
  | Signal | Pulls score UP | Pulls score DOWN |
347
338
  | --- | --- | --- |
@@ -372,9 +363,9 @@ Scorer integrates the 5 signals. Rough directionality:
372
363
  | `SECRETS` | `gitleaks_findings ≥ 1` (any secret in git history — even if rotated) | `maintainability ≤ 2` |
373
364
  | `VULN` | `dep_vuln_critical ≥ 1` OR `dep_vuln_high ≥ 3` across any ecosystem tool that ran (`pip-audit` / `npm audit` / `govulncheck` / `trivy fs`). Skipped when `dep_vuln_NOT_RUN == true` (no recognized manifest). | `maintainability ≤ 2` |
374
365
 
375
- The `SECRETS` gate fires even if the secret has been rotated out of HEAD — leaked-and-revoked still blocks "pick up and extend" because the leak is permanent in git history. `gitleaks_any_still_in_head` lets the scorer comment on severity but doesn't change the gate.
366
+ `SECRETS` fires even when the secret is rotated out of HEAD — the leak is permanent in git history, and "pick up and extend" assumes a trustworthy history. `gitleaks_any_still_in_head` never changes the gate; state the severity (still in HEAD vs. history-only) in evidence.
376
367
 
377
- The `VULN` gate fires on committed dependency manifests only; it does not attempt to resolve what version is actually running in production (runtime verification is out of scope — a separate maintainer follow-up). A repo that pins vulnerable versions but ships a build that avoids the vulnerable code path still takes the gate — the signal is "ships committed dependency hygiene", not "is exploitable at runtime".
368
+ `VULN` reads committed dependency manifests only — no runtime resolution, no version-pinning analysis (runtime verification is out of scope). A repo pinning a vulnerable version takes the gate even if its build avoids the vulnerable code path: the signal is committed dependency hygiene, not exploitability.
378
369
 
379
370
  ---
380
371
 
@@ -436,10 +427,7 @@ data:
436
427
 
437
428
  ## Caveats
438
429
 
439
- - **lizard CCN thresholds are language-idiomatic.** Python's 10 ≠ Kotlin's 12 ≠ Go's 15. The per-language lookup in Signal 2 sets the threshold per file extension; absolute and fixed.
440
- - **knip / deptry only cover their ecosystems.** Mixed repos run both and aggregate; there's no polyglot dep-hygiene tool.
441
- - **LLM "pickup" judgment is brittle at sample size = 3 sampled files.** Evidence should name the files sampled.
442
- - **`SECRETS` gate is conservative.** Fires even on rotated secrets — "pick up and extend" assumes trust in git history, and rotation doesn't erase the leak. Scorer should mention severity (`still_in_head` vs. history-only) in evidence.
443
- - **`VULN` gate is committed-manifest only.** Does not attempt runtime resolution or version-pinning analysis. A repo that pins a vulnerable version but ships a build that avoids the vulnerable code path still takes the gate — by design, it's a cleanliness signal, not an exploitability signal.
444
- - **`CONTRIBUTING.md` / ADR / RFC presence** is a weak signal — absence is common even in healthy repos. Don't penalize for missing; reward when present.
445
- - **Tech-debt markers** may be legitimate scoping comments (`TODO: address in v2`) or abandoned work. LLM adjudicates when count is suspiciously high.
430
+ - **knip / deptry cover only their ecosystems.** Mixed repos run both and aggregate; no polyglot dep-hygiene tool exists.
431
+ - **The LLM "pickup" judgment is brittle at 3 sampled files.** Evidence **must** name the files sampled.
432
+ - **`CONTRIBUTING.md` / ADR / RFC presence** is a weak signal — absence is common in healthy repos. Reward presence; never penalize absence.
433
+ - **Tech-debt markers** may be legitimate scoping comments (`TODO: address in v2`) or abandoned work; the LLM adjudicates when the count is suspiciously high.
@@ -5,7 +5,7 @@
5
5
  - **Contenders:** scc + Semgrep stub rule + git analytics + Tier-A build check + LLM README-vs-shipped diff (layered)
6
6
  - **Source quote:** _"Genuinely shippable scope."_
7
7
 
8
- This recipe measures the **mechanical** evidence of ambition (LoC, commits, delivery concentration, stubs, shipped-vs-promised ratio, Tier-A build) against the project's apparent size, and whether the built scope holds together. Bands are **absolute**. Gate this recipe owns: **`BROKEN`** (Tier-A build check fails outside `DEPS_NOT_INSTALLED`; caps **`mechanical_ambition ≤ 2`**).
8
+ This recipe measures the **mechanical** evidence of ambition — LoC, commits, delivery concentration, stubs, shipped-vs-promised ratio, Tier-A build — against the project's apparent size, and whether the built scope holds together. Bands are **absolute**. This recipe owns the `BROKEN` gate, defined in § Gates.
9
9
 
10
10
  ---
11
11
 
@@ -162,7 +162,7 @@ Aggregate `build_check_passed` bool — true if all applicable checks produced z
162
162
 
163
163
  Capture: `build_check_passed` (bool), `build_errors_summary` (string — first 20 lines for LLM context), `build_checks_applied` (list of checks that ran).
164
164
 
165
- **Escalation note:** if errors contain `Cannot find module` / `ModuleNotFoundError`, flag `DEPS_NOT_INSTALLED` — Tier-A can't distinguish "broken" from "needs install." Scorer may choose to escalate to Tier-B (shallow install) for such repos.
165
+ **Escalation:** if errors contain `Cannot find module` / `ModuleNotFoundError`, flag `DEPS_NOT_INSTALLED` — Tier-A cannot tell "broken" from "needs install". For such repos you may escalate to Tier-B (a shallow install).
166
166
 
167
167
  ### Signal 5 — LLM README-vs-shipped diff
168
168
 
@@ -192,7 +192,7 @@ Capture:
192
192
 
193
193
  ## Raw dumps (flat — files under `raw/` named `mechanical-ambition-*`)
194
194
 
195
- Each signal writes its raw output to the flat `raw/` directory at the workspace root. Absent files = not extracted. Aggregates go to `scorecard.yaml` under `data.`.
195
+ Each signal writes its raw output to the flat `raw/` directory; an absent file means not extracted. Aggregates go to `scorecard.yaml` under `data.`.
196
196
 
197
197
  | File | Source signal | Shape / note |
198
198
  | --- | --- | --- |
@@ -202,13 +202,13 @@ Each signal writes its raw output to the flat `raw/` directory at the workspace
202
202
  | `raw/mechanical-ambition-tier-a-build.log` | Signal 4 | Combined output of checks that ran (py_compile, ruff -F, tsc --noEmit, go vet, gofmt, node --check). First 20 lines per tool. |
203
203
  | `raw/mechanical-ambition-llm-read.md` | Signal 5 | README-vs-shipped diff: `{promises: [...], shipped: [...], shipped_ratio, scope_match_score, notable_gaps, one_sentence}` |
204
204
 
205
- Additional short-lived intermediates: the `stubs.yml` semgrep rule config is a skill artifact — generate it under `$SKILL_DIR/criteria/mechanical-ambition-stubs.yml` (or inline on-the-fly), not in the repo workspace.
205
+ The `stubs.yml` rule config is a scratch intermediate — write it to `/tmp/stubs.yml` (Signal 2), **never** into the scored repo or the workspace.
206
206
 
207
207
  ---
208
208
 
209
209
  ## Aggregation → 0–5 band
210
210
 
211
- Scorer integrates the 5 signals. Rough directionality:
211
+ Integrate Signals 1–5. Rough directionality:
212
212
 
213
213
  | Signal | Pulls score UP | Pulls score DOWN |
214
214
  | --- | --- | --- |
@@ -236,16 +236,16 @@ Scorer integrates the 5 signals. Rough directionality:
236
236
  | --- | --- | --- |
237
237
  | `BROKEN` | `build_check_passed == false` (and not because of `DEPS_NOT_INSTALLED`) | `mechanical_ambition ≤ 2` |
238
238
 
239
- Affects this sub-criterion only. Canonical gate list in [../SKILL.md](../SKILL.md).
239
+ Affects this sub-criterion only. The canonical gate list is [`SKILL.md` → Gates](../SKILL.md#gates-cap-specific-items-stack-additively).
240
240
 
241
241
  ---
242
242
 
243
243
  ## Fallback — signals missing
244
244
 
245
245
  - scc doesn't support a language → LoC count may under-report; document in evidence.
246
- - Semgrep stub rule misses project-specific stub patterns → LLM catches what regex missed; increase weight of Signal 5.
246
+ - Semgrep stub rule misses project-specific stub patterns → the LLM read catches what the rule missed; weight Signal 5 more heavily.
247
247
  - Repo has < 5 commits → git analytics degrade (cramming, commit-rate meaningless); rely on Signals 1, 2, 5.
248
- - `DEPS_NOT_INSTALLED` flag on Tier-A → `BROKEN` gate does NOT fire on this alone; scorer should either: (a) escalate to Tier-B, or (b) defer build-status judgment to the LLM's read of repo shape.
248
+ - `DEPS_NOT_INSTALLED` flag on Tier-A → the `BROKEN` gate does **not** fire on it alone; either escalate to Tier-B or defer build status to the LLM's read of repo shape.
249
249
  - README missing → Signal 5 is degraded; emit `llm_confidence: low`.
250
250
 
251
251
  Annotate evidence with `"Signals used: [...]"`.
@@ -293,8 +293,8 @@ data:
293
293
 
294
294
  ## Caveats
295
295
 
296
- - **Tier-A build check catches ~80% of breakage.** Import-resolution errors need deps installed. `DEPS_NOT_INSTALLED` flag suppresses the `BROKEN` gate when the check failed for install reasons.
297
- - **Stub detection via Semgrep misses project-specific patterns.** A function that returns hardcoded fake data without any stub marker looks "shipped" but isn't. LLM Signal 5 compensates.
298
- - **Delivery-concentration detection is heuristic.** Last-day share > 30% flags concentrated delivery but doesn't distinguish "final polish" from a single large drop. LLM evidence should adjudicate when the flag fires.
299
- - **`llm_shipped_ratio` depends on how the README frames features.** Terse READMEs may under-count promises; florid READMEs may over-count. Evidence should show the promise list.
300
- - **COCOMO is a sanity check, not a score driver.** `cocomo_estimated_months > 3` is a soft-overreach signal relative to the project's apparent size; `< 0.1` is a soft-underreach signal. Don't gate on it.
296
+ - **The Tier-A build check catches ~80% of breakage** — import-resolution errors need deps installed, which is what `DEPS_NOT_INSTALLED` covers.
297
+ - **Semgrep stub detection misses project-specific patterns.** A function returning hardcoded fake data with no stub marker looks shipped; Signal 5 compensates.
298
+ - **Delivery-concentration detection is heuristic.** A last-day share > 30% cannot tell final polish from a single large drop; the LLM evidence adjudicates when the flag fires.
299
+ - **`llm_shipped_ratio` depends on how the README frames features** — terse READMEs under-count promises, florid ones over-count. Evidence **must** show the promise list.
300
+ - **COCOMO is a sanity check, never a score driver or a gate.** `cocomo_estimated_months > 3` is a soft overreach signal relative to the project's apparent size; `< 0.1` a soft underreach signal.
@@ -4,13 +4,13 @@
4
4
  - **Weight:** 12.5 pts
5
5
  - **Source quote:** _"Is the problem clearly stated, non-trivial, with defined user/use-case?"_
6
6
 
7
- This recipe scores whether the problem is substantively framed — a crisp, non-trivial problem statement with a defined user and use-case, versus a toy-shaped placeholder.
7
+ This recipe scores whether the problem is substantively framed — a crisp, non-trivial problem statement with a defined user and use-case — or a toy-shaped placeholder.
8
8
 
9
9
  ---
10
10
 
11
11
  ## Extraction recipe
12
12
 
13
- LLM-primary. The evaluator reads the top of the repo (README, any PRD/SPEC doc, sample data, one or two handler files) and answers: **Is this a substantive, well-defined problem, or a toy-shaped placeholder?**
13
+ LLM-primary: read the top of the repo (README, any PRD/SPEC doc, sample data, one or two handler files) and decide whether it is a substantive, well-defined problem or a toy-shaped placeholder.
14
14
 
15
15
  ### Signal 1 — Problem framing (LLM interpretive)
16
16
 
@@ -21,7 +21,7 @@ Feed the LLM the following context:
21
21
  head -500 "$REPO/README.md" > /tmp/prob-sub-readme.md
22
22
 
23
23
  # PRD / SPEC / DESIGN docs if present
24
- find "$REPO" -maxdepth 3 -iname "PRD*.md" -o -iname "SPEC*.md" -o -iname "DESIGN*.md" \
24
+ find "$REPO" -maxdepth 3 \( -iname "PRD*.md" -o -iname "SPEC*.md" -o -iname "DESIGN*.md" \) \
25
25
  -not -path '*/node_modules/*' -not -path '*/.venv/*' 2>/dev/null \
26
26
  | xargs -I{} head -200 {} 2>/dev/null > /tmp/prob-sub-docs.md
27
27
 
@@ -33,7 +33,7 @@ find "$REPO" -maxdepth 4 \( -iname '*.csv' -o -iname '*.json' -o -iname 'sample*
33
33
  tree -L 2 -I 'node_modules|.venv|.git|dist|build' "$REPO" 2>/dev/null | head -80 > /tmp/prob-sub-tree.txt
34
34
  ```
35
35
 
36
- Write the LLM read to `raw/problem-substantiveness-llm-read.md`. The LLM emits:
36
+ Write the LLM read to `raw/problem-substantiveness-llm-read.md`. It emits:
37
37
 
38
38
  ```yaml
39
39
  detected_domain: "internal dev tooling" | "customer-facing SaaS" | "infra automation" | "ops observability" | "data pipeline" | "agent/LLM tooling" | ...
@@ -71,7 +71,7 @@ Aggregate the LLM output into `raw/problem-substantiveness-proxies.json`:
71
71
  | **1** | No problem statement, or README is an unmodified starter/template README. `problem_clarity_score ≤ 1`. |
72
72
  | **0** | Empty README + no PRD/SPEC + toy pattern detected. |
73
73
 
74
- **Toy-pattern auto-floor:** if `toy_pattern_detected == true` (hello-world, generic TODO, calculator, tic-tac-toe, etc.), cap the band at **2** regardless of other signals — a clear problem statement doesn't rescue a toy.
74
+ **Toy-pattern cap:** if `toy_pattern_detected == true` (hello-world, generic TODO, calculator, tic-tac-toe, etc.), cap the band at **2** regardless of other signals — a clear problem statement never rescues a toy.
75
75
 
76
76
  ---
77
77
 
@@ -84,5 +84,5 @@ Aggregate the LLM output into `raw/problem-substantiveness-proxies.json`:
84
84
 
85
85
  ## Not in scope
86
86
 
87
- - Judging whether the problem matches a specific organization's real priorities needs operational context — out of scope; this scores whether the problem is substantively framed, not whether it's the right problem for any given org to be solving.
88
- - Judging the quality of the implementation — that's 1.1–1.4 + 2.4. This recipe only looks at framing.
87
+ - **Whether it is the right problem for a given organization** — that needs operational context; this recipe scores only whether the problem is substantively framed.
88
+ - **Implementation quality** — scored by 1.1–1.4 and 2.4.