@ahmed-g-gad/apothem 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (674) hide show
  1. package/CHANGELOG.md +60 -0
  2. package/LICENSE +21 -0
  3. package/LICENSES/MIT.txt +18 -0
  4. package/LICENSES/PSF-2.0.txt +47 -0
  5. package/README.md +549 -0
  6. package/bin/README.md +37 -0
  7. package/bin/apothem.mjs +78 -0
  8. package/package.json +75 -0
  9. package/pyproject.toml +347 -0
  10. package/src/apothem/README.md +52 -0
  11. package/src/apothem/__init__.py +66 -0
  12. package/src/apothem/__main__.py +28 -0
  13. package/src/apothem/_vendor/.keep +0 -0
  14. package/src/apothem/_vendor/__init__.py +25 -0
  15. package/src/apothem/_vendor/attr/__init__.py +104 -0
  16. package/src/apothem/_vendor/attr/__init__.pyi +389 -0
  17. package/src/apothem/_vendor/attr/_cmp.py +160 -0
  18. package/src/apothem/_vendor/attr/_cmp.pyi +13 -0
  19. package/src/apothem/_vendor/attr/_compat.py +99 -0
  20. package/src/apothem/_vendor/attr/_config.py +31 -0
  21. package/src/apothem/_vendor/attr/_funcs.py +497 -0
  22. package/src/apothem/_vendor/attr/_make.py +3406 -0
  23. package/src/apothem/_vendor/attr/_next_gen.py +674 -0
  24. package/src/apothem/_vendor/attr/_typing_compat.pyi +15 -0
  25. package/src/apothem/_vendor/attr/_version_info.py +89 -0
  26. package/src/apothem/_vendor/attr/_version_info.pyi +9 -0
  27. package/src/apothem/_vendor/attr/converters.py +162 -0
  28. package/src/apothem/_vendor/attr/converters.pyi +19 -0
  29. package/src/apothem/_vendor/attr/exceptions.py +95 -0
  30. package/src/apothem/_vendor/attr/exceptions.pyi +17 -0
  31. package/src/apothem/_vendor/attr/filters.py +72 -0
  32. package/src/apothem/_vendor/attr/filters.pyi +6 -0
  33. package/src/apothem/_vendor/attr/py.typed +0 -0
  34. package/src/apothem/_vendor/attr/setters.py +79 -0
  35. package/src/apothem/_vendor/attr/setters.pyi +20 -0
  36. package/src/apothem/_vendor/attr/validators.py +750 -0
  37. package/src/apothem/_vendor/attr/validators.pyi +140 -0
  38. package/src/apothem/_vendor/attr.LICENSE +21 -0
  39. package/src/apothem/_vendor/attrs/__init__.py +72 -0
  40. package/src/apothem/_vendor/attrs/__init__.pyi +314 -0
  41. package/src/apothem/_vendor/attrs/converters.py +3 -0
  42. package/src/apothem/_vendor/attrs/exceptions.py +3 -0
  43. package/src/apothem/_vendor/attrs/filters.py +3 -0
  44. package/src/apothem/_vendor/attrs/py.typed +0 -0
  45. package/src/apothem/_vendor/attrs/setters.py +3 -0
  46. package/src/apothem/_vendor/attrs/validators.py +3 -0
  47. package/src/apothem/_vendor/attrs.LICENSE +21 -0
  48. package/src/apothem/_vendor/jsonschema/__init__.py +120 -0
  49. package/src/apothem/_vendor/jsonschema/__main__.py +6 -0
  50. package/src/apothem/_vendor/jsonschema/_format.py +546 -0
  51. package/src/apothem/_vendor/jsonschema/_keywords.py +449 -0
  52. package/src/apothem/_vendor/jsonschema/_legacy_keywords.py +449 -0
  53. package/src/apothem/_vendor/jsonschema/_types.py +204 -0
  54. package/src/apothem/_vendor/jsonschema/_typing.py +29 -0
  55. package/src/apothem/_vendor/jsonschema/_utils.py +355 -0
  56. package/src/apothem/_vendor/jsonschema/benchmarks/__init__.py +5 -0
  57. package/src/apothem/_vendor/jsonschema/benchmarks/const_vs_enum.py +30 -0
  58. package/src/apothem/_vendor/jsonschema/benchmarks/contains.py +28 -0
  59. package/src/apothem/_vendor/jsonschema/benchmarks/import_benchmark.py +31 -0
  60. package/src/apothem/_vendor/jsonschema/benchmarks/issue232/issue.json +2653 -0
  61. package/src/apothem/_vendor/jsonschema/benchmarks/issue232.py +25 -0
  62. package/src/apothem/_vendor/jsonschema/benchmarks/json_schema_test_suite.py +12 -0
  63. package/src/apothem/_vendor/jsonschema/benchmarks/nested_schemas.py +56 -0
  64. package/src/apothem/_vendor/jsonschema/benchmarks/subcomponents.py +42 -0
  65. package/src/apothem/_vendor/jsonschema/benchmarks/unused_registry.py +35 -0
  66. package/src/apothem/_vendor/jsonschema/benchmarks/useless_applicator_schemas.py +106 -0
  67. package/src/apothem/_vendor/jsonschema/benchmarks/useless_keywords.py +32 -0
  68. package/src/apothem/_vendor/jsonschema/benchmarks/validator_creation.py +14 -0
  69. package/src/apothem/_vendor/jsonschema/cli.py +292 -0
  70. package/src/apothem/_vendor/jsonschema/exceptions.py +490 -0
  71. package/src/apothem/_vendor/jsonschema/protocols.py +230 -0
  72. package/src/apothem/_vendor/jsonschema/validators.py +1410 -0
  73. package/src/apothem/_vendor/jsonschema.LICENSE +19 -0
  74. package/src/apothem/_vendor/jsonschema_specifications/__init__.py +12 -0
  75. package/src/apothem/_vendor/jsonschema_specifications/_core.py +38 -0
  76. package/src/apothem/_vendor/jsonschema_specifications/schemas/draft201909/metaschema.json +42 -0
  77. package/src/apothem/_vendor/jsonschema_specifications/schemas/draft201909/vocabularies/applicator +56 -0
  78. package/src/apothem/_vendor/jsonschema_specifications/schemas/draft201909/vocabularies/content +17 -0
  79. package/src/apothem/_vendor/jsonschema_specifications/schemas/draft201909/vocabularies/core +57 -0
  80. package/src/apothem/_vendor/jsonschema_specifications/schemas/draft201909/vocabularies/format +14 -0
  81. package/src/apothem/_vendor/jsonschema_specifications/schemas/draft201909/vocabularies/meta-data +37 -0
  82. package/src/apothem/_vendor/jsonschema_specifications/schemas/draft201909/vocabularies/validation +98 -0
  83. package/src/apothem/_vendor/jsonschema_specifications/schemas/draft202012/metaschema.json +58 -0
  84. package/src/apothem/_vendor/jsonschema_specifications/schemas/draft202012/vocabularies/applicator +48 -0
  85. package/src/apothem/_vendor/jsonschema_specifications/schemas/draft202012/vocabularies/content +17 -0
  86. package/src/apothem/_vendor/jsonschema_specifications/schemas/draft202012/vocabularies/core +51 -0
  87. package/src/apothem/_vendor/jsonschema_specifications/schemas/draft202012/vocabularies/format-annotation +14 -0
  88. package/src/apothem/_vendor/jsonschema_specifications/schemas/draft202012/vocabularies/format-assertion +14 -0
  89. package/src/apothem/_vendor/jsonschema_specifications/schemas/draft202012/vocabularies/meta-data +37 -0
  90. package/src/apothem/_vendor/jsonschema_specifications/schemas/draft202012/vocabularies/unevaluated +15 -0
  91. package/src/apothem/_vendor/jsonschema_specifications/schemas/draft202012/vocabularies/validation +98 -0
  92. package/src/apothem/_vendor/jsonschema_specifications/schemas/draft3/metaschema.json +172 -0
  93. package/src/apothem/_vendor/jsonschema_specifications/schemas/draft4/metaschema.json +149 -0
  94. package/src/apothem/_vendor/jsonschema_specifications/schemas/draft6/metaschema.json +153 -0
  95. package/src/apothem/_vendor/jsonschema_specifications/schemas/draft7/metaschema.json +166 -0
  96. package/src/apothem/_vendor/jsonschema_specifications.LICENSE +19 -0
  97. package/src/apothem/_vendor/referencing/__init__.py +7 -0
  98. package/src/apothem/_vendor/referencing/_attrs.py +31 -0
  99. package/src/apothem/_vendor/referencing/_attrs.pyi +21 -0
  100. package/src/apothem/_vendor/referencing/_core.py +739 -0
  101. package/src/apothem/_vendor/referencing/exceptions.py +165 -0
  102. package/src/apothem/_vendor/referencing/jsonschema.py +642 -0
  103. package/src/apothem/_vendor/referencing/py.typed +0 -0
  104. package/src/apothem/_vendor/referencing/retrieval.py +94 -0
  105. package/src/apothem/_vendor/referencing/typing.py +61 -0
  106. package/src/apothem/_vendor/referencing.LICENSE +19 -0
  107. package/src/apothem/_vendor/rpds/__init__.py +251 -0
  108. package/src/apothem/_vendor/typing_extensions.LICENSE +279 -0
  109. package/src/apothem/_vendor/typing_extensions.py +4317 -0
  110. package/src/apothem/_vendor/vendor.txt +22 -0
  111. package/src/apothem/_vendor/yaml/__init__.py +389 -0
  112. package/src/apothem/_vendor/yaml/composer.py +138 -0
  113. package/src/apothem/_vendor/yaml/constructor.py +748 -0
  114. package/src/apothem/_vendor/yaml/cyaml.py +100 -0
  115. package/src/apothem/_vendor/yaml/dumper.py +61 -0
  116. package/src/apothem/_vendor/yaml/emitter.py +1137 -0
  117. package/src/apothem/_vendor/yaml/error.py +74 -0
  118. package/src/apothem/_vendor/yaml/events.py +85 -0
  119. package/src/apothem/_vendor/yaml/loader.py +63 -0
  120. package/src/apothem/_vendor/yaml/nodes.py +48 -0
  121. package/src/apothem/_vendor/yaml/parser.py +588 -0
  122. package/src/apothem/_vendor/yaml/reader.py +185 -0
  123. package/src/apothem/_vendor/yaml/representer.py +388 -0
  124. package/src/apothem/_vendor/yaml/resolver.py +226 -0
  125. package/src/apothem/_vendor/yaml/scanner.py +1435 -0
  126. package/src/apothem/_vendor/yaml/serializer.py +110 -0
  127. package/src/apothem/_vendor/yaml/tokens.py +103 -0
  128. package/src/apothem/_vendor/yaml.LICENSE +20 -0
  129. package/src/apothem/agents/README.md +60 -0
  130. package/src/apothem/agents/codebase-explorer.md +91 -0
  131. package/src/apothem/agents/convention-auditor.md +93 -0
  132. package/src/apothem/agents/dependency-auditor.md +97 -0
  133. package/src/apothem/agents/fact-checker.md +84 -0
  134. package/src/apothem/agents/mcp-builder.md +86 -0
  135. package/src/apothem/agents/memory-auditor.md +93 -0
  136. package/src/apothem/agents/prompt-evaluator.md +87 -0
  137. package/src/apothem/agents/quality-gate.md +103 -0
  138. package/src/apothem/agents/refactor-surgeon.md +74 -0
  139. package/src/apothem/agents/research-scout.md +73 -0
  140. package/src/apothem/agents/security-scanner.md +83 -0
  141. package/src/apothem/agents/test-runner.md +84 -0
  142. package/src/apothem/audit/README.md +73 -0
  143. package/src/apothem/audit/_scan_lib.py +182 -0
  144. package/src/apothem/audit/analyze_graph.py +260 -0
  145. package/src/apothem/audit/build_capability_graph.py +607 -0
  146. package/src/apothem/audit/build_inventory.py +657 -0
  147. package/src/apothem/audit/build_plans_provenance.py +997 -0
  148. package/src/apothem/audit/check_links.py +389 -0
  149. package/src/apothem/audit/classify_artifacts.py +381 -0
  150. package/src/apothem/audit/deprecated-tokens.txt +10 -0
  151. package/src/apothem/audit/execute_plans_migration.py +491 -0
  152. package/src/apothem/audit/known-projects.txt +15 -0
  153. package/src/apothem/audit/render_capability_index.py +467 -0
  154. package/src/apothem/audit/render_inventory.py +405 -0
  155. package/src/apothem/audit/scan_ai_surfaces.py +1125 -0
  156. package/src/apothem/audit/scan_ai_surfaces_coarse.py +261 -0
  157. package/src/apothem/audit/scan_drift_features.py +143 -0
  158. package/src/apothem/audit/scan_frontmatter.py +293 -0
  159. package/src/apothem/audit/scan_header_coverage.py +1134 -0
  160. package/src/apothem/audit/scan_plan_leakage.py +540 -0
  161. package/src/apothem/audit/scan_plans_discipline.py +188 -0
  162. package/src/apothem/audit/scan_secrets_pii.py +245 -0
  163. package/src/apothem/audit/scan_stale_tokens.py +296 -0
  164. package/src/apothem/audit/synthesize_drift.py +205 -0
  165. package/src/apothem/benchmarks/README.md +33 -0
  166. package/src/apothem/benchmarks/__init__.py +3 -0
  167. package/src/apothem/benchmarks/bench_agents.py +63 -0
  168. package/src/apothem/benchmarks/bench_hooks.py +93 -0
  169. package/src/apothem/benchmarks/bench_install.py +58 -0
  170. package/src/apothem/benchmarks/bench_tests.py +93 -0
  171. package/src/apothem/benchmarks/bench_validate_ecosystem.py +84 -0
  172. package/src/apothem/cli/README.md +33 -0
  173. package/src/apothem/cli/__init__.py +229 -0
  174. package/src/apothem/cli/_cmd_completion.py +88 -0
  175. package/src/apothem/cli/_cmd_diff.py +181 -0
  176. package/src/apothem/cli/_cmd_doctor.py +143 -0
  177. package/src/apothem/cli/_cmd_harnesses.py +167 -0
  178. package/src/apothem/cli/_cmd_install.py +327 -0
  179. package/src/apothem/cli/_cmd_migrate_workspace.py +143 -0
  180. package/src/apothem/cli/_cmd_profile.py +341 -0
  181. package/src/apothem/cli/_cmd_status.py +180 -0
  182. package/src/apothem/cli/_cmd_uninstall.py +215 -0
  183. package/src/apothem/cli/_cmd_update.py +397 -0
  184. package/src/apothem/cli/_cmd_verify.py +194 -0
  185. package/src/apothem/cli/_common_flags.py +90 -0
  186. package/src/apothem/cli/_epilogs.py +296 -0
  187. package/src/apothem/cli/_helpers.py +857 -0
  188. package/src/apothem/cli/_json_formatter.py +21 -0
  189. package/src/apothem/cli/_materialize.py +376 -0
  190. package/src/apothem/cli/completions/apothem.bash +30 -0
  191. package/src/apothem/cli/completions/apothem.fish +19 -0
  192. package/src/apothem/cli/completions/apothem.ps1 +27 -0
  193. package/src/apothem/cli/completions/apothem.zsh +42 -0
  194. package/src/apothem/cli/reference_export.py +126 -0
  195. package/src/apothem/commands/README.md +125 -0
  196. package/src/apothem/commands/a11y-audit.md +203 -0
  197. package/src/apothem/commands/architecture-review.md +194 -0
  198. package/src/apothem/commands/audit.md +165 -0
  199. package/src/apothem/commands/code-audit.md +218 -0
  200. package/src/apothem/commands/code-review.md +193 -0
  201. package/src/apothem/commands/dependency-audit.md +209 -0
  202. package/src/apothem/commands/docs-review.md +199 -0
  203. package/src/apothem/commands/elevate.md +285 -0
  204. package/src/apothem/commands/eval.md +149 -0
  205. package/src/apothem/commands/fortress.md +172 -0
  206. package/src/apothem/commands/freshify.md +168 -0
  207. package/src/apothem/commands/github-deploy-fresh.md +178 -0
  208. package/src/apothem/commands/github-deploy-next.md +167 -0
  209. package/src/apothem/commands/perf-audit.md +198 -0
  210. package/src/apothem/commands/plan-amend.md +104 -0
  211. package/src/apothem/commands/plan-audit.md +127 -0
  212. package/src/apothem/commands/plan-design.md +257 -0
  213. package/src/apothem/commands/plan-execute.md +495 -0
  214. package/src/apothem/commands/plan-generate.md +351 -0
  215. package/src/apothem/commands/plan-review.md +555 -0
  216. package/src/apothem/commands/plan-spec.md +359 -0
  217. package/src/apothem/commands/plan-status.md +222 -0
  218. package/src/apothem/commands/plan.md +173 -0
  219. package/src/apothem/commands/projectify.md +142 -0
  220. package/src/apothem/commands/release-readiness.md +142 -0
  221. package/src/apothem/commands/research-analysis.md +241 -0
  222. package/src/apothem/commands/research-design.md +231 -0
  223. package/src/apothem/commands/research-disseminate.md +225 -0
  224. package/src/apothem/commands/research-experiment.md +232 -0
  225. package/src/apothem/commands/research-ideate.md +213 -0
  226. package/src/apothem/commands/research-paper.md +252 -0
  227. package/src/apothem/commands/research-proposal.md +220 -0
  228. package/src/apothem/commands/research-publish.md +255 -0
  229. package/src/apothem/commands/research-review.md +251 -0
  230. package/src/apothem/commands/research-sources.md +266 -0
  231. package/src/apothem/commands/research-spec.md +255 -0
  232. package/src/apothem/commands/research-synthesis.md +233 -0
  233. package/src/apothem/commands/research-theory.md +218 -0
  234. package/src/apothem/commands/research.md +181 -0
  235. package/src/apothem/commands/security-audit.md +196 -0
  236. package/src/apothem/commands/supply-chain-audit.md +192 -0
  237. package/src/apothem/commands/test-suite.md +146 -0
  238. package/src/apothem/commands/threat-model-audit.md +199 -0
  239. package/src/apothem/commands/ux-review.md +202 -0
  240. package/src/apothem/commands/workflow.md +162 -0
  241. package/src/apothem/conformity/README.md +173 -0
  242. package/src/apothem/conformity/__init__.py +1 -0
  243. package/src/apothem/conformity/_grep_base.py +93 -0
  244. package/src/apothem/conformity/agent_capability_grep.py +306 -0
  245. package/src/apothem/conformity/agents_md_coverage_grep.py +382 -0
  246. package/src/apothem/conformity/agnosticism_grep.py +311 -0
  247. package/src/apothem/conformity/always_on_budget_grep.py +318 -0
  248. package/src/apothem/conformity/bare_except_grep.py +115 -0
  249. package/src/apothem/conformity/binding_reciprocity_grep.py +151 -0
  250. package/src/apothem/conformity/brand_mark_grep.py +272 -0
  251. package/src/apothem/conformity/commented_out_code_grep.py +176 -0
  252. package/src/apothem/conformity/completion_claim_grep.py +169 -0
  253. package/src/apothem/conformity/conventional_commit_grep.py +319 -0
  254. package/src/apothem/conformity/copilot_instructions_presence_grep.py +324 -0
  255. package/src/apothem/conformity/cross_platform_matrix_grep.py +297 -0
  256. package/src/apothem/conformity/determinism_grep.py +306 -0
  257. package/src/apothem/conformity/diagram_staleness_grep.py +154 -0
  258. package/src/apothem/conformity/dynamism_grep.py +284 -0
  259. package/src/apothem/conformity/editorconfig_presence_grep.py +281 -0
  260. package/src/apothem/conformity/file_header_grep.py +502 -0
  261. package/src/apothem/conformity/freshness_token_grep.py +233 -0
  262. package/src/apothem/conformity/frontmatter_grep.py +274 -0
  263. package/src/apothem/conformity/frontmatter_value_grep.py +386 -0
  264. package/src/apothem/conformity/gate.py +1386 -0
  265. package/src/apothem/conformity/gitattributes_presence_grep.py +238 -0
  266. package/src/apothem/conformity/harden_runner_grep.py +320 -0
  267. package/src/apothem/conformity/hedging_grep.py +129 -0
  268. package/src/apothem/conformity/license_author_consistency_grep.py +204 -0
  269. package/src/apothem/conformity/link_check.py +327 -0
  270. package/src/apothem/conformity/magic_number_grep.py +182 -0
  271. package/src/apothem/conformity/multi_surface_coherence_grep.py +620 -0
  272. package/src/apothem/conformity/naming_grep.py +224 -0
  273. package/src/apothem/conformity/no_global_plans_grep.py +339 -0
  274. package/src/apothem/conformity/no_toplevel_docs_grep.py +120 -0
  275. package/src/apothem/conformity/oidc_trusted_publishing_grep.py +291 -0
  276. package/src/apothem/conformity/option_annotation_grep.py +352 -0
  277. package/src/apothem/conformity/orphan_output_grep.py +206 -0
  278. package/src/apothem/conformity/permissions_minimum_scope_grep.py +299 -0
  279. package/src/apothem/conformity/plain_language_grep.py +559 -0
  280. package/src/apothem/conformity/plan_next_step_consistency_grep.py +450 -0
  281. package/src/apothem/conformity/plan_suite_structure_grep.py +534 -0
  282. package/src/apothem/conformity/plans_discipline_language_grep.py +245 -0
  283. package/src/apothem/conformity/production_ready_pr_grep.py +200 -0
  284. package/src/apothem/conformity/recommend_next_step_grep.py +250 -0
  285. package/src/apothem/conformity/redundancy_grep.py +401 -0
  286. package/src/apothem/conformity/reference_token_grep.py +230 -0
  287. package/src/apothem/conformity/registry_capability_consistency_grep.py +368 -0
  288. package/src/apothem/conformity/secret_leak_grep.py +193 -0
  289. package/src/apothem/conformity/semver_stability_grep.py +358 -0
  290. package/src/apothem/conformity/smoke_install_grep.py +194 -0
  291. package/src/apothem/conformity/static_version_grep.py +284 -0
  292. package/src/apothem/conformity/token_efficiency_grep.py +185 -0
  293. package/src/apothem/conformity/unpinned_action_grep.py +115 -0
  294. package/src/apothem/conformity/user_confirm_grep.py +74 -0
  295. package/src/apothem/conformity/workflow_concurrency_grep.py +283 -0
  296. package/src/apothem/harnesses/README.md +63 -0
  297. package/src/apothem/harnesses/__init__.py +16 -0
  298. package/src/apothem/harnesses/_shared/README.md +36 -0
  299. package/src/apothem/harnesses/_shared/__init__.py +12 -0
  300. package/src/apothem/harnesses/_shared/install_driver.py +281 -0
  301. package/src/apothem/harnesses/_shared/install_driver_apply.py +612 -0
  302. package/src/apothem/harnesses/_shared/install_driver_backup.py +535 -0
  303. package/src/apothem/harnesses/_shared/install_driver_converters.py +310 -0
  304. package/src/apothem/harnesses/_shared/install_driver_lifecycle.py +495 -0
  305. package/src/apothem/harnesses/_shared/install_driver_materialize.py +675 -0
  306. package/src/apothem/harnesses/_shared/install_driver_merge.py +656 -0
  307. package/src/apothem/harnesses/_shared/install_driver_pathsafety.py +137 -0
  308. package/src/apothem/harnesses/_shared/install_driver_planvalidation.py +240 -0
  309. package/src/apothem/harnesses/_shared/install_driver_removal.py +366 -0
  310. package/src/apothem/harnesses/_shared/install_driver_treeops.py +248 -0
  311. package/src/apothem/harnesses/_shared/install_driver_types.py +330 -0
  312. package/src/apothem/harnesses/_shared/wrapper_factories.py +448 -0
  313. package/src/apothem/harnesses/antigravity/STANDARD-CONVENTION-PIN.md +91 -0
  314. package/src/apothem/harnesses/antigravity/__init__.py +70 -0
  315. package/src/apothem/harnesses/antigravity/capabilities.yml +40 -0
  316. package/src/apothem/harnesses/antigravity/install.py +63 -0
  317. package/src/apothem/harnesses/antigravity/templates/GEMINI.md +40 -0
  318. package/src/apothem/harnesses/antigravity/templates/plugin.json +5 -0
  319. package/src/apothem/harnesses/antigravity/uninstall.py +22 -0
  320. package/src/apothem/harnesses/antigravity/update.py +10 -0
  321. package/src/apothem/harnesses/antigravity/verify.py +11 -0
  322. package/src/apothem/harnesses/claude_code/STANDARD-CONVENTION-PIN.md +65 -0
  323. package/src/apothem/harnesses/claude_code/__init__.py +107 -0
  324. package/src/apothem/harnesses/claude_code/capabilities.yml +42 -0
  325. package/src/apothem/harnesses/claude_code/install.py +147 -0
  326. package/src/apothem/harnesses/claude_code/templates/settings.json +351 -0
  327. package/src/apothem/harnesses/claude_code/uninstall.py +23 -0
  328. package/src/apothem/harnesses/claude_code/update.py +10 -0
  329. package/src/apothem/harnesses/claude_code/verify.py +11 -0
  330. package/src/apothem/harnesses/codebuddy/STANDARD-CONVENTION-PIN.md +74 -0
  331. package/src/apothem/harnesses/codebuddy/__init__.py +49 -0
  332. package/src/apothem/harnesses/codebuddy/capabilities.yml +34 -0
  333. package/src/apothem/harnesses/codebuddy/install.py +40 -0
  334. package/src/apothem/harnesses/codebuddy/templates/apothem-rules.md +37 -0
  335. package/src/apothem/harnesses/codebuddy/uninstall.py +25 -0
  336. package/src/apothem/harnesses/codebuddy/update.py +10 -0
  337. package/src/apothem/harnesses/codebuddy/verify.py +11 -0
  338. package/src/apothem/harnesses/codex/STANDARD-CONVENTION-PIN.md +79 -0
  339. package/src/apothem/harnesses/codex/__init__.py +72 -0
  340. package/src/apothem/harnesses/codex/capabilities.yml +40 -0
  341. package/src/apothem/harnesses/codex/install.py +69 -0
  342. package/src/apothem/harnesses/codex/templates/AGENTS.md +40 -0
  343. package/src/apothem/harnesses/codex/templates/hooks.json +127 -0
  344. package/src/apothem/harnesses/codex/uninstall.py +23 -0
  345. package/src/apothem/harnesses/codex/update.py +10 -0
  346. package/src/apothem/harnesses/codex/verify.py +11 -0
  347. package/src/apothem/harnesses/cursor/STANDARD-CONVENTION-PIN.md +79 -0
  348. package/src/apothem/harnesses/cursor/__init__.py +48 -0
  349. package/src/apothem/harnesses/cursor/capabilities.yml +42 -0
  350. package/src/apothem/harnesses/cursor/install.py +38 -0
  351. package/src/apothem/harnesses/cursor/templates/apothem-rules.mdc +40 -0
  352. package/src/apothem/harnesses/cursor/uninstall.py +25 -0
  353. package/src/apothem/harnesses/cursor/update.py +10 -0
  354. package/src/apothem/harnesses/cursor/verify.py +11 -0
  355. package/src/apothem/harnesses/gemini_cli/STANDARD-CONVENTION-PIN.md +102 -0
  356. package/src/apothem/harnesses/gemini_cli/__init__.py +52 -0
  357. package/src/apothem/harnesses/gemini_cli/capabilities.yml +43 -0
  358. package/src/apothem/harnesses/gemini_cli/install.py +43 -0
  359. package/src/apothem/harnesses/gemini_cli/templates/GEMINI.md +38 -0
  360. package/src/apothem/harnesses/gemini_cli/uninstall.py +25 -0
  361. package/src/apothem/harnesses/gemini_cli/update.py +10 -0
  362. package/src/apothem/harnesses/gemini_cli/verify.py +11 -0
  363. package/src/apothem/harnesses/github_copilot/STANDARD-CONVENTION-PIN.md +84 -0
  364. package/src/apothem/harnesses/github_copilot/__init__.py +47 -0
  365. package/src/apothem/harnesses/github_copilot/capabilities.yml +42 -0
  366. package/src/apothem/harnesses/github_copilot/install.py +40 -0
  367. package/src/apothem/harnesses/github_copilot/templates/copilot-instructions.md +33 -0
  368. package/src/apothem/harnesses/github_copilot/uninstall.py +25 -0
  369. package/src/apothem/harnesses/github_copilot/update.py +10 -0
  370. package/src/apothem/harnesses/github_copilot/verify.py +11 -0
  371. package/src/apothem/harnesses/glm/STANDARD-CONVENTION-PIN.md +77 -0
  372. package/src/apothem/harnesses/glm/__init__.py +56 -0
  373. package/src/apothem/harnesses/glm/capabilities.yml +33 -0
  374. package/src/apothem/harnesses/glm/install.py +45 -0
  375. package/src/apothem/harnesses/glm/templates/glm.toml +58 -0
  376. package/src/apothem/harnesses/glm/uninstall.py +25 -0
  377. package/src/apothem/harnesses/glm/update.py +10 -0
  378. package/src/apothem/harnesses/glm/verify.py +11 -0
  379. package/src/apothem/harnesses/hermes/STANDARD-CONVENTION-PIN.md +57 -0
  380. package/src/apothem/harnesses/hermes/__init__.py +33 -0
  381. package/src/apothem/harnesses/hermes/capabilities.yml +36 -0
  382. package/src/apothem/harnesses/hermes/install.py +17 -0
  383. package/src/apothem/harnesses/hermes/materializer.py +35 -0
  384. package/src/apothem/harnesses/hermes/uninstall.py +33 -0
  385. package/src/apothem/harnesses/hermes/update.py +10 -0
  386. package/src/apothem/harnesses/hermes/verify.py +11 -0
  387. package/src/apothem/harnesses/kimi_code/STANDARD-CONVENTION-PIN.md +128 -0
  388. package/src/apothem/harnesses/kimi_code/__init__.py +59 -0
  389. package/src/apothem/harnesses/kimi_code/capabilities.yml +40 -0
  390. package/src/apothem/harnesses/kimi_code/install.py +42 -0
  391. package/src/apothem/harnesses/kimi_code/templates/AGENTS.md +43 -0
  392. package/src/apothem/harnesses/kimi_code/uninstall.py +27 -0
  393. package/src/apothem/harnesses/kimi_code/update.py +10 -0
  394. package/src/apothem/harnesses/kimi_code/verify.py +11 -0
  395. package/src/apothem/harnesses/kiro/STANDARD-CONVENTION-PIN.md +77 -0
  396. package/src/apothem/harnesses/kiro/__init__.py +49 -0
  397. package/src/apothem/harnesses/kiro/capabilities.yml +36 -0
  398. package/src/apothem/harnesses/kiro/install.py +39 -0
  399. package/src/apothem/harnesses/kiro/templates/apothem-rules.md +36 -0
  400. package/src/apothem/harnesses/kiro/uninstall.py +25 -0
  401. package/src/apothem/harnesses/kiro/update.py +10 -0
  402. package/src/apothem/harnesses/kiro/verify.py +11 -0
  403. package/src/apothem/harnesses/open_claw/STANDARD-CONVENTION-PIN.md +62 -0
  404. package/src/apothem/harnesses/open_claw/__init__.py +35 -0
  405. package/src/apothem/harnesses/open_claw/capabilities.yml +35 -0
  406. package/src/apothem/harnesses/open_claw/install.py +17 -0
  407. package/src/apothem/harnesses/open_claw/materializer.py +36 -0
  408. package/src/apothem/harnesses/open_claw/uninstall.py +32 -0
  409. package/src/apothem/harnesses/open_claw/update.py +10 -0
  410. package/src/apothem/harnesses/open_claw/verify.py +11 -0
  411. package/src/apothem/harnesses/opencode/STANDARD-CONVENTION-PIN.md +76 -0
  412. package/src/apothem/harnesses/opencode/__init__.py +35 -0
  413. package/src/apothem/harnesses/opencode/capabilities.yml +43 -0
  414. package/src/apothem/harnesses/opencode/install.py +17 -0
  415. package/src/apothem/harnesses/opencode/materializer.py +31 -0
  416. package/src/apothem/harnesses/opencode/uninstall.py +34 -0
  417. package/src/apothem/harnesses/opencode/update.py +10 -0
  418. package/src/apothem/harnesses/opencode/verify.py +11 -0
  419. package/src/apothem/harnesses/qwen_code/STANDARD-CONVENTION-PIN.md +87 -0
  420. package/src/apothem/harnesses/qwen_code/__init__.py +37 -0
  421. package/src/apothem/harnesses/qwen_code/capabilities.yml +43 -0
  422. package/src/apothem/harnesses/qwen_code/install.py +19 -0
  423. package/src/apothem/harnesses/qwen_code/materializer.py +174 -0
  424. package/src/apothem/harnesses/qwen_code/templates/QWEN.md +30 -0
  425. package/src/apothem/harnesses/qwen_code/uninstall.py +34 -0
  426. package/src/apothem/harnesses/qwen_code/update.py +10 -0
  427. package/src/apothem/harnesses/qwen_code/verify.py +11 -0
  428. package/src/apothem/harnesses/trae/STANDARD-CONVENTION-PIN.md +70 -0
  429. package/src/apothem/harnesses/trae/__init__.py +49 -0
  430. package/src/apothem/harnesses/trae/capabilities.yml +34 -0
  431. package/src/apothem/harnesses/trae/install.py +38 -0
  432. package/src/apothem/harnesses/trae/templates/apothem-rules.md +37 -0
  433. package/src/apothem/harnesses/trae/uninstall.py +25 -0
  434. package/src/apothem/harnesses/trae/update.py +10 -0
  435. package/src/apothem/harnesses/trae/verify.py +11 -0
  436. package/src/apothem/harnesses/windsurf/STANDARD-CONVENTION-PIN.md +91 -0
  437. package/src/apothem/harnesses/windsurf/__init__.py +52 -0
  438. package/src/apothem/harnesses/windsurf/capabilities.yml +40 -0
  439. package/src/apothem/harnesses/windsurf/install.py +41 -0
  440. package/src/apothem/harnesses/windsurf/templates/apothem-rules.md +37 -0
  441. package/src/apothem/harnesses/windsurf/uninstall.py +25 -0
  442. package/src/apothem/harnesses/windsurf/update.py +10 -0
  443. package/src/apothem/harnesses/windsurf/verify.py +11 -0
  444. package/src/apothem/harnesses/zed/STANDARD-CONVENTION-PIN.md +92 -0
  445. package/src/apothem/harnesses/zed/__init__.py +57 -0
  446. package/src/apothem/harnesses/zed/capabilities.yml +38 -0
  447. package/src/apothem/harnesses/zed/install.py +41 -0
  448. package/src/apothem/harnesses/zed/templates/apothem-rules.md +32 -0
  449. package/src/apothem/harnesses/zed/uninstall.py +28 -0
  450. package/src/apothem/harnesses/zed/update.py +10 -0
  451. package/src/apothem/harnesses/zed/verify.py +11 -0
  452. package/src/apothem/hooks/README.md +81 -0
  453. package/src/apothem/hooks/__init__.py +24 -0
  454. package/src/apothem/hooks/askuserquestion_validator.py +380 -0
  455. package/src/apothem/hooks/dispatch.py +296 -0
  456. package/src/apothem/hooks/emit_hook_context.py +444 -0
  457. package/src/apothem/hooks/hooks.json +318 -0
  458. package/src/apothem/hooks/lib/README.md +39 -0
  459. package/src/apothem/hooks/lib/__init__.py +18 -0
  460. package/src/apothem/hooks/lib/bootstrap.ps1 +129 -0
  461. package/src/apothem/hooks/lib/bootstrap.sh +103 -0
  462. package/src/apothem/hooks/lib/events.py +51 -0
  463. package/src/apothem/hooks/lib/find-pwsh.ps1 +78 -0
  464. package/src/apothem/hooks/lib/find-pwsh.sh +76 -0
  465. package/src/apothem/hooks/lib/find-python.ps1 +63 -0
  466. package/src/apothem/hooks/lib/find-python.sh +97 -0
  467. package/src/apothem/hooks/lib/log.py +43 -0
  468. package/src/apothem/hooks/lib/resolve_root.py +264 -0
  469. package/src/apothem/hooks/messages/postcompact.md +14 -0
  470. package/src/apothem/hooks/messages/posttooluse-proactive-compaction.md +46 -0
  471. package/src/apothem/hooks/messages/precompact.md +14 -0
  472. package/src/apothem/hooks/messages/pretooluse-askuserquestion-recommended.md +65 -0
  473. package/src/apothem/hooks/messages/pretooluse-bash-plan-guard.md +97 -0
  474. package/src/apothem/hooks/messages/pretooluse-bash.md +39 -0
  475. package/src/apothem/hooks/messages/pretooluse-conformity.md +70 -0
  476. package/src/apothem/hooks/messages/pretooluse-dependency-guard.md +21 -0
  477. package/src/apothem/hooks/messages/pretooluse-edit-header-guard.md +61 -0
  478. package/src/apothem/hooks/messages/pretooluse-edit.md +21 -0
  479. package/src/apothem/hooks/messages/pretooluse-eval-guard.md +39 -0
  480. package/src/apothem/hooks/messages/pretooluse-notebookedit.md +11 -0
  481. package/src/apothem/hooks/messages/pretooluse-write-header-guard.md +45 -0
  482. package/src/apothem/hooks/messages/pretooluse-write-plan-guard.md +72 -0
  483. package/src/apothem/hooks/messages/pretooluse-write.md +21 -0
  484. package/src/apothem/hooks/messages/sessionstart.md +15 -0
  485. package/src/apothem/hooks/messages/stop.md +27 -0
  486. package/src/apothem/hooks/proactive_compaction_tracker.py +327 -0
  487. package/src/apothem/hooks/session_start_bootstrap.py +472 -0
  488. package/src/apothem/lib/README.md +42 -0
  489. package/src/apothem/lib/__init__.py +13 -0
  490. package/src/apothem/lib/atomic_io.py +189 -0
  491. package/src/apothem/lib/auditor.py +687 -0
  492. package/src/apothem/lib/clean_slate.py +396 -0
  493. package/src/apothem/lib/contexts.py +352 -0
  494. package/src/apothem/lib/data_home.py +255 -0
  495. package/src/apothem/lib/frontmatter.py +101 -0
  496. package/src/apothem/lib/harness_materializer.py +213 -0
  497. package/src/apothem/lib/harness_protocol.py +59 -0
  498. package/src/apothem/lib/harness_registry.py +282 -0
  499. package/src/apothem/lib/harness_registry_data.py +843 -0
  500. package/src/apothem/lib/install_ledger.py +347 -0
  501. package/src/apothem/lib/learning.py +540 -0
  502. package/src/apothem/lib/memory.py +347 -0
  503. package/src/apothem/lib/parallel_sweep.py +234 -0
  504. package/src/apothem/lib/plan_tiers.py +200 -0
  505. package/src/apothem/lib/plugin_bootstrap.py +132 -0
  506. package/src/apothem/lib/plugin_tree.py +599 -0
  507. package/src/apothem/lib/profile.py +755 -0
  508. package/src/apothem/lib/profile_projection.py +198 -0
  509. package/src/apothem/lib/propagation-manifest.yaml +878 -0
  510. package/src/apothem/lib/propagation.py +220 -0
  511. package/src/apothem/lib/python_resolver.py +189 -0
  512. package/src/apothem/lib/reporter.py +62 -0
  513. package/src/apothem/lib/workspace_migration.py +323 -0
  514. package/src/apothem/output-styles/README.md +41 -0
  515. package/src/apothem/output-styles/concise-engineer.md +49 -0
  516. package/src/apothem/output-styles/default-architect.md +52 -0
  517. package/src/apothem/output-styles/default.md +113 -0
  518. package/src/apothem/output-styles/forensic-auditor.md +63 -0
  519. package/src/apothem/py.typed +0 -0
  520. package/src/apothem/rules/README.md +121 -0
  521. package/src/apothem/rules/agent-capability-discipline-matrix.md +89 -0
  522. package/src/apothem/rules/agent-capability-discipline.md +78 -0
  523. package/src/apothem/rules/agent-orchestration-patterns.md +144 -0
  524. package/src/apothem/rules/agent-orchestration.md +65 -0
  525. package/src/apothem/rules/agents-md-convention.md +86 -0
  526. package/src/apothem/rules/agile-sprints-elements.md +135 -0
  527. package/src/apothem/rules/agile-sprints.md +64 -0
  528. package/src/apothem/rules/agnostic-posture-checklist.md +47 -0
  529. package/src/apothem/rules/agnostic-posture.md +48 -0
  530. package/src/apothem/rules/authoritative-referencing-quotation.md +50 -0
  531. package/src/apothem/rules/authoritative-referencing.md +66 -0
  532. package/src/apothem/rules/authority-inquiry-categories.md +58 -0
  533. package/src/apothem/rules/authority-inquiry.md +54 -0
  534. package/src/apothem/rules/auto-memory-topic-files.md +86 -0
  535. package/src/apothem/rules/auto-memory.md +67 -0
  536. package/src/apothem/rules/bidirectional-binding.md +123 -0
  537. package/src/apothem/rules/canonical-layout-reporting-tiers.md +212 -0
  538. package/src/apothem/rules/canonical-layout.md +60 -0
  539. package/src/apothem/rules/clean-architecture-layers.md +186 -0
  540. package/src/apothem/rules/clean-room-generation-protocols.md +124 -0
  541. package/src/apothem/rules/clean-room-generation.md +59 -0
  542. package/src/apothem/rules/code-craft-conventions.md +101 -0
  543. package/src/apothem/rules/code-craft-markdown.md +138 -0
  544. package/src/apothem/rules/code-craft-python.md +154 -0
  545. package/src/apothem/rules/code-craft-shell.md +192 -0
  546. package/src/apothem/rules/cognitive-identity-techniques.md +180 -0
  547. package/src/apothem/rules/cognitive-identity.md +81 -0
  548. package/src/apothem/rules/context-management-budget.md +46 -0
  549. package/src/apothem/rules/context-management-protocol.md +161 -0
  550. package/src/apothem/rules/context-management-scratch.md +128 -0
  551. package/src/apothem/rules/context-management.md +85 -0
  552. package/src/apothem/rules/definitiveness-virtues.md +67 -0
  553. package/src/apothem/rules/definitiveness.md +58 -0
  554. package/src/apothem/rules/determinism.md +81 -0
  555. package/src/apothem/rules/disclosure-ledger-markers.md +58 -0
  556. package/src/apothem/rules/disclosure-ledger.md +52 -0
  557. package/src/apothem/rules/dynamism.md +38 -0
  558. package/src/apothem/rules/etc-extension.md +57 -0
  559. package/src/apothem/rules/expertise-posture-elements.md +68 -0
  560. package/src/apothem/rules/expertise-posture.md +54 -0
  561. package/src/apothem/rules/freshness-facade.md +64 -0
  562. package/src/apothem/rules/harness-adapter-shape-schemas.md +162 -0
  563. package/src/apothem/rules/harness-adapter-shape.md +42 -0
  564. package/src/apothem/rules/host-discovery-manifests.md +50 -0
  565. package/src/apothem/rules/host-discovery.md +56 -0
  566. package/src/apothem/rules/i18n-discipline-locale-cohorts.md +120 -0
  567. package/src/apothem/rules/i18n-discipline.md +70 -0
  568. package/src/apothem/rules/interactive-questions-canonical-shapes.md +590 -0
  569. package/src/apothem/rules/interactive-questions-detail.md +41 -0
  570. package/src/apothem/rules/interactive-questions-sweep-matchers.md +184 -0
  571. package/src/apothem/rules/interactive-questions.md +89 -0
  572. package/src/apothem/rules/large-file-generation.md +112 -0
  573. package/src/apothem/rules/large-file-reading.md +59 -0
  574. package/src/apothem/rules/living-docs.md +85 -0
  575. package/src/apothem/rules/multi-agent-workflow.md +57 -0
  576. package/src/apothem/rules/operational-mandates-expanded.md +78 -0
  577. package/src/apothem/rules/operational-mandates.md +88 -0
  578. package/src/apothem/rules/option-annotation-form.md +60 -0
  579. package/src/apothem/rules/option-annotation.md +45 -0
  580. package/src/apothem/rules/own-voice-reimplementation.md +86 -0
  581. package/src/apothem/rules/performance-discipline.md +91 -0
  582. package/src/apothem/rules/persistent-conventions-vigilance-checklist.md +54 -0
  583. package/src/apothem/rules/persistent-conventions-vigilance.md +61 -0
  584. package/src/apothem/rules/plain-language.md +56 -0
  585. package/src/apothem/rules/planning-techniques.md +130 -0
  586. package/src/apothem/rules/pre-emission-gate-bars.md +86 -0
  587. package/src/apothem/rules/pre-emission-gate.md +54 -0
  588. package/src/apothem/rules/production-ready-prs-surfaces.md +162 -0
  589. package/src/apothem/rules/production-ready-prs.md +83 -0
  590. package/src/apothem/rules/propagation.md +63 -0
  591. package/src/apothem/rules/recommend-next-step.md +106 -0
  592. package/src/apothem/rules/refactoring-discipline.md +76 -0
  593. package/src/apothem/rules/session-closure.md +44 -0
  594. package/src/apothem/rules/sota-elevation-exemplars.md +76 -0
  595. package/src/apothem/rules/sota-elevation.md +52 -0
  596. package/src/apothem/rules/source-accessibility.md +58 -0
  597. package/src/apothem/rules/surgical-manipulation.md +48 -0
  598. package/src/apothem/rules/systemic-participation-relations.md +108 -0
  599. package/src/apothem/rules/systemic-participation.md +70 -0
  600. package/src/apothem/rules/ten-dimension-check-dimensions.md +52 -0
  601. package/src/apothem/rules/ten-dimension-check.md +59 -0
  602. package/src/apothem/rules/token-budget-discipline.md +81 -0
  603. package/src/apothem/rules/token-efficiency-rewrite-protocol.md +79 -0
  604. package/src/apothem/rules/token-efficiency-rewrite.md +77 -0
  605. package/src/apothem/rules/tool-use-discipline.md +48 -0
  606. package/src/apothem/rules/visual-leverage.md +102 -0
  607. package/src/apothem/schemas/NOTICE.md +9 -0
  608. package/src/apothem/schemas/README.md +104 -0
  609. package/src/apothem/schemas/__init__.py +176 -0
  610. package/src/apothem/schemas/advisory-finding.schema.json +111 -0
  611. package/src/apothem/schemas/agent.schema.json +106 -0
  612. package/src/apothem/schemas/authorship-header.txt +1 -0
  613. package/src/apothem/schemas/cohort-manifest.yaml +248 -0
  614. package/src/apothem/schemas/cohort-metadata-vocabulary.yaml +168 -0
  615. package/src/apothem/schemas/cohort.schema.json +113 -0
  616. package/src/apothem/schemas/command.schema.json +68 -0
  617. package/src/apothem/schemas/compatibility-matrix.yaml +432 -0
  618. package/src/apothem/schemas/context-fragment.schema.json +64 -0
  619. package/src/apothem/schemas/freshness-token-denylist.txt +51 -0
  620. package/src/apothem/schemas/handoff-manifest.yaml +353 -0
  621. package/src/apothem/schemas/header-exceptions.txt +141 -0
  622. package/src/apothem/schemas/header-visibility.yaml +39 -0
  623. package/src/apothem/schemas/learning-signal.schema.json +46 -0
  624. package/src/apothem/schemas/memory-record.schema.json +61 -0
  625. package/src/apothem/schemas/output-style.schema.json +40 -0
  626. package/src/apothem/schemas/plan.schema.json +51 -0
  627. package/src/apothem/schemas/plugin.schema.json +83 -0
  628. package/src/apothem/schemas/profile.example.yaml +70 -0
  629. package/src/apothem/schemas/profile.minimal.yaml +6 -0
  630. package/src/apothem/schemas/profile.schema.json +396 -0
  631. package/src/apothem/schemas/reference-token-denylist.txt +25 -0
  632. package/src/apothem/schemas/skill.schema.json +75 -0
  633. package/src/apothem/skills/README.md +93 -0
  634. package/src/apothem/skills/dependency-upgrade/SKILL.md +105 -0
  635. package/src/apothem/skills/dev-toolkit/SKILL.md +120 -0
  636. package/src/apothem/skills/diagram-authoring/SKILL.md +113 -0
  637. package/src/apothem/skills/document-authoring/SKILL.md +118 -0
  638. package/src/apothem/skills/ecosystem-audit/SKILL.md +108 -0
  639. package/src/apothem/skills/ecosystem-audit/references/audit-fortress.md +85 -0
  640. package/src/apothem/skills/ecosystem-audit/references/procedure.md +162 -0
  641. package/src/apothem/skills/eval-harness/SKILL.md +88 -0
  642. package/src/apothem/skills/incident-runbook/SKILL.md +92 -0
  643. package/src/apothem/skills/multi-source-research/SKILL.md +90 -0
  644. package/src/apothem/skills/plan-suite/SKILL.md +118 -0
  645. package/src/apothem/skills/plan-suite/master_template.md +1324 -0
  646. package/src/apothem/skills/projectify/SKILL.md +117 -0
  647. package/src/apothem/skills/prompt-engineering/SKILL.md +122 -0
  648. package/src/apothem/skills/refactor-extract/SKILL.md +85 -0
  649. package/src/apothem/skills/research-suite/SKILL.md +170 -0
  650. package/src/apothem/skills/research-suite/references/directory-structure.md +47 -0
  651. package/src/apothem/skills/research-suite/references/lifecycle.md +67 -0
  652. package/src/apothem/skills/research-suite/references/principal-investigator-framework.md +37 -0
  653. package/src/apothem/skills/research-suite/references/rigor-mandates.md +30 -0
  654. package/src/apothem/skills/research-suite/research_template.md +476 -0
  655. package/src/apothem/skills/secret-rotation/SKILL.md +87 -0
  656. package/src/apothem/skills/source-synthesis/SKILL.md +92 -0
  657. package/src/apothem/skills/surgical-guard/SKILL.md +118 -0
  658. package/src/apothem/skills/test-authoring/SKILL.md +85 -0
  659. package/src/apothem/skills/vuln-triage/SKILL.md +91 -0
  660. package/src/apothem/skills/workflow/SKILL.md +139 -0
  661. package/src/apothem/statuslines/README.md +26 -0
  662. package/src/apothem/statuslines/__init__.py +20 -0
  663. package/src/apothem/statuslines/conformity.json +5 -0
  664. package/src/apothem/statuslines/render.py +334 -0
  665. package/src/apothem/statuslines/statusline.md +50 -0
  666. package/src/apothem/templates/README.md +43 -0
  667. package/src/apothem/templates/agents-md-template.md +80 -0
  668. package/src/apothem/templates/consideration-log.md +39 -0
  669. package/src/apothem/templates/expertise-gap-log.md +56 -0
  670. package/src/apothem/templates/master-index-template.md +93 -0
  671. package/src/apothem/templates/potency-map.md +53 -0
  672. package/src/apothem/templates/preservation-audit.md +60 -0
  673. package/src/apothem/templates/question-resolution-audit.md +52 -0
  674. package/src/apothem/templates/trace-matrix-template.md +77 -0
@@ -0,0 +1,173 @@
1
+ <!-- SPDX-License-Identifier: MIT -->
2
+
3
+ # conformity
4
+
5
+ > **Role.** Pre-emission conformity validators. `gate.py` orchestrates a fleet of mechanical `*_grep` matchers (plus the link checker) against a Write/Edit input, returning a pass/fail verdict before the artifact is emitted.
6
+
7
+ ## Orchestrator
8
+
9
+ | File | Purpose |
10
+ |------|---------|
11
+ | `gate.py` | The conformity-gate orchestrator — dispatches every matcher against a Write/Edit input and aggregates the verdicts. |
12
+ | `__init__.py` | Package marker. |
13
+
14
+ ## Matcher families
15
+
16
+ ### Authorship & structure
17
+
18
+ | File | Checks |
19
+ |------|--------|
20
+ | `file_header_grep.py` | Canonical authorship-header presence and form. |
21
+ | `frontmatter_grep.py` | Required frontmatter fields on artifact classes that carry them. |
22
+ | `frontmatter_value_grep.py` | Frontmatter `enum`/`pattern` values against the per-class JSON Schema (agents, commands, skills) — the value-level counterpart to `frontmatter_grep`'s key check. |
23
+ | `naming_grep.py` | Naming-convention conformance. |
24
+ | `binding_reciprocity_grep.py` | Reciprocal five-direction bindings — half-edge detection. |
25
+ | `always_on_budget_grep.py` | Always-on rule body token budget (the 500-token ceiling). |
26
+ | `agent_capability_grep.py` | Every harness declares its agentic-capability matrix. |
27
+ | `agents_md_coverage_grep.py` | Stale agent-companion files under the root-only AGENTS.md convention. |
28
+ | `registry_capability_consistency_grep.py` | Registry capability cells not backed by install / materializer / projection evidence. |
29
+ | `recommend_next_step_grep.py` | `## Recommended Next Step` block presence on command / skill terminal surfaces. |
30
+ | `determinism_grep.py` | Deterministic output shape across command and skill surfaces. |
31
+ | `no_toplevel_docs_grep.py` | A top-level `docs/` directory at the repository root. |
32
+
33
+ ### Prose & narrative discipline
34
+
35
+ | File | Checks |
36
+ |------|--------|
37
+ | `hedging_grep.py` | Hedging vocabulary in prescriptive prose. |
38
+ | `option_annotation_grep.py` | Per-option `(Recommended)` label-to-body bind (H6): canonical capital postfix iff body `recommendation: recommended`, no spurious or lowercase postfix, at most one recommended option in a single-select set. |
39
+ | `completion_claim_grep.py` | Unsupported absolute-guarantee completion claims in cohort prose (spec §4.2 honesty) — e.g., "guaranteed to pass", "always works", "100% complete", "cannot fail". |
40
+ | `diagram_staleness_grep.py` | Diagram verification dates against the structure they abstract. |
41
+ | `multi_surface_coherence_grep.py` | Coherence across paired/multi-surface artifacts. |
42
+ | `plain_language_grep.py` | Mechanistic / harness-internal vocabulary in user-facing prose. |
43
+ | `token_efficiency_grep.py` | Filler phrases, throat-clearing openers, content-free qualifiers. |
44
+ | `redundancy_grep.py` | Substantively-duplicated paragraphs across the governed corpus. |
45
+ | `agnosticism_grep.py` | Harness bias and re-introduced enforcement presets in shipped surfaces. |
46
+
47
+ ### Plans discipline
48
+
49
+ | File | Checks |
50
+ |------|--------|
51
+ | `no_global_plans_grep.py` | Writes to a global plans directory. |
52
+ | `plans_discipline_language_grep.py` | Plans-discipline language violations. |
53
+ | `orphan_output_grep.py` | Orphan outputs — no consumer / no index entry / no producer attribution. |
54
+ | `user_confirm_grep.py` | Unfilled `<USER-CONFIRM:…>` placeholders. |
55
+ | `plan_suite_structure_grep.py` | Plan-suite structure — suite-locality, closed vocabulary, numeric-prefix discipline. |
56
+ | `plan_next_step_consistency_grep.py` | Plan-suite infra files' Recommended-Next-Step footer consistency (advisory). |
57
+
58
+ ### Code craft
59
+
60
+ | File | Checks |
61
+ |------|--------|
62
+ | `bare_except_grep.py` | Bare / overly-broad `except` clauses. |
63
+ | `commented_out_code_grep.py` | Commented-out code blocks. |
64
+ | `magic_number_grep.py` | Magic numbers in logic without named constants. |
65
+
66
+ ### Supply chain & security
67
+
68
+ | File | Checks |
69
+ |------|--------|
70
+ | `secret_leak_grep.py` | Secret literals committed to source — vendor-prefixed credential patterns plus a high-entropy heuristic, with a canonical-banner allow-list. |
71
+ | `unpinned_action_grep.py` | Unpinned GitHub Actions `uses:` references. |
72
+ | `permissions_minimum_scope_grep.py` | Every workflow declares a minimum-scope `permissions:` block. |
73
+ | `harden_runner_grep.py` | Every workflow job opens with a conformant harden-runner step. |
74
+ | `workflow_concurrency_grep.py` | Concurrency group + per-job timeout discipline on workflows. |
75
+ | `oidc_trusted_publishing_grep.py` | Release workflows use OIDC trusted publishing. |
76
+ | `cross_platform_matrix_grep.py` | CI declares a cross-platform OS × Python matrix. |
77
+ | `editorconfig_presence_grep.py` | Canonical `.editorconfig` present at the project root. |
78
+ | `gitattributes_presence_grep.py` | Repo-root `.gitattributes` carries the canonical contract. |
79
+
80
+ ### Release & branding
81
+
82
+ | File | Checks |
83
+ |------|--------|
84
+ | `production_ready_pr_grep.py` | Same-change-set production-readiness discipline. |
85
+ | `license_author_consistency_grep.py` | Verifies the root LICENSE carries an author line. |
86
+ | `brand_mark_grep.py` | Brand-mark usage. |
87
+ | `smoke_install_grep.py` | Install-script smoke-check markers. |
88
+ | `copilot_instructions_presence_grep.py` | `copilot-instructions.md` presence. |
89
+ | `dynamism_grep.py` | Static-string version embeds in dynamism-required surfaces. |
90
+ | `static_version_grep.py` | Version-bearing sites resolve dynamically, not as static literals. |
91
+ | `semver_stability_grep.py` | Semver stability (the change-set-scoped M15 mechanical fraction). |
92
+ | `conventional_commit_grep.py` | HEAD commit messages against the Conventional-Commits grammar. |
93
+ | `freshness_token_grep.py` | Freshness-narrative phrases on shipped public surfaces. |
94
+
95
+ ### Link integrity
96
+
97
+ | File | Checks |
98
+ |------|--------|
99
+ | `link_check.py` | Validate Markdown internal links against the on-disk reference graph. |
100
+
101
+ ## Operating contract
102
+
103
+ `gate.py` is the single dispatch surface. It owns two matcher registries —
104
+ `GREP_MODULES` (per-Write matchers with a `check(content, path)` signature, run
105
+ on the Write/Edit body) and `STANDALONE_MODULES` (corpus walkers that take a
106
+ root directory and walk the tree, git index, or a fixed surface set) — plus the
107
+ CLI surface (`--all`, `--check <name>`, `--list`, `--hook`, `--strict`) and the
108
+ scope/short-circuit logic. The invariants a matcher must hold to:
109
+
110
+ - **Advisory by default.** The gate reports findings and exits zero so the write
111
+ proceeds; strict blocking is opt-in via `--strict` or a truthy
112
+ `APOTHEM_CONFORMITY_STRICT`. A matcher's standalone `to_json()` carries
113
+ `"advisory": true`, and its CLI `_main` may exit non-zero on findings (the
114
+ orchestrator treats the standalone exit code as the strict signal). Never
115
+ hard-block a write from inside a matcher.
116
+ - **Fail-open isolation.** The orchestrator wraps every matcher load and
117
+ `check()` call; a raised exception is recorded and surfaced, never swallowed,
118
+ and never fail-closes the write. Do not catch-and-suppress inside a matcher;
119
+ let the orchestrator's boundary handle errors.
120
+ - **Dataclass result shape.** Matchers return a frozen `GrepResult` carrying
121
+ `passed: bool` and `findings: list[Finding]`; `Finding` carries the surface,
122
+ kind/issue, and a `detail` string. The orchestrator duck-types
123
+ `getattr(result, "passed", ...)` and `result.findings`, so the field names are
124
+ the contract.
125
+ - **Registry-name forms.** `STANDALONE_MODULES` entries are stored hyphenated
126
+ (`reference-token-grep`) for CLI ergonomics; the on-disk filename is
127
+ underscored (`reference_token_grep.py`). `GREP_MODULES` entries are
128
+ underscored. `_resolve_validator` normalizes both forms.
129
+ - **Plan/scope short-circuits are gate-owned.** `.plans/` paths, out-of-scope
130
+ writes, and harness runtime-state subtrees (`projects/`, `memory/`)
131
+ short-circuit to a silent pass in the orchestrator. A per-Write matcher MUST
132
+ NOT itself special-case `.plans/`; rely on the gate's `_is_plan_suite_path`
133
+ short-circuit.
134
+ - Denylist/schema data a matcher consumes lives in [`../schemas/`](../schemas/),
135
+ never inlined in the module.
136
+
137
+ ## Adding or modifying a matcher
138
+
139
+ To **add a matcher**:
140
+
141
+ 1. Author `<name>_grep.py` here. Define frozen `Finding` and `GrepResult`
142
+ dataclasses; `GrepResult.to_json()` emits `"advisory": true`. Expose the
143
+ entry callable — **per-Write**:
144
+ `check(content: str, path: Path | None = None) -> GrepResult`; **corpus
145
+ walker**: `check(root: Path) -> GrepResult` plus a `_main(argv)` that prints
146
+ JSON and returns `EXIT_PASS` (0) / `EXIT_FAIL` (2).
147
+ 2. **Register** in `gate.py`: add the underscored name to `GREP_MODULES` for
148
+ per-Write, OR the hyphenated name to `STANDALONE_MODULES` for a corpus walker.
149
+ 3. Add **fixtures and tests** under `tests/conformity/<name>/` (pass/fail cases)
150
+ and a test module under `tests/conformity/`. For standalone walkers, also
151
+ register the matcher in `tests/conformity/test_standalone_greps_inprocess.py`
152
+ so it runs in-process in the suite.
153
+ 4. Keep within the **per-grep wall-clock budget** (`PER_GREP_BUDGET_SECONDS` in
154
+ `gate.py`); the hook has a 10s `PreToolUse` ceiling and the orchestrator flags
155
+ any matcher approaching the per-grep budget as a watch item. Cheap structural
156
+ scans run before expensive regex sweeps.
157
+
158
+ To **modify or remove a matcher**: keep the registry entry, fixtures, and the
159
+ in-process test list in sync in the same change-set; an orphaned entry or a
160
+ registered name with no script surfaces as a load error.
161
+
162
+ Validate every change here:
163
+
164
+ ```bash
165
+ python -m apothem.conformity.gate --all .
166
+ python -m pytest tests/conformity
167
+ python -m ruff check .
168
+ python -m mypy src/apothem/cli/ src/apothem/harnesses/
169
+ ```
170
+
171
+ ## Related
172
+
173
+ - [`hooks/`](../hooks/) — the dispatcher that fires the gate on PreToolUse Write/Edit events.
@@ -0,0 +1 @@
1
+ # SPDX-License-Identifier: MIT
@@ -0,0 +1,93 @@
1
+ # SPDX-License-Identifier: MIT
2
+
3
+ """Shared scaffolding for path-based conformity matchers.
4
+
5
+ Why this module exists. The path-based conformity matchers
6
+ (``check(content, path) -> GrepResult``) each defined a byte-identical
7
+ ``GrepResult`` dataclass, an identical ``to_json`` serialiser, and a
8
+ near-identical ``_read_input`` / ``_main`` / ``__main__`` skeleton. Hoisting
9
+ that boilerplate here removes the duplication while preserving every matcher's
10
+ observable behaviour: the JSON report shape, the exit codes, and the
11
+ stdin-or-path input contract are unchanged.
12
+
13
+ Scope. This base serves matchers whose canonical report payload is exactly
14
+ ``{grep, path, passed, findings}`` — optionally carrying a ``note`` emitted
15
+ only when present. Matchers with ``root``-based payloads, extra report keys,
16
+ or always-emitted ``advisory`` flags keep their own ``GrepResult`` because
17
+ their serialised shape diverges from this one.
18
+ """
19
+
20
+ from __future__ import annotations
21
+
22
+ import json
23
+ import sys
24
+ from collections.abc import Callable
25
+ from dataclasses import asdict, dataclass, field
26
+ from pathlib import Path
27
+ from typing import Any, Final, Protocol
28
+
29
+ EXIT_PASS: Final[int] = 0
30
+ EXIT_FAIL: Final[int] = 2
31
+ STDIN_FLAG: Final[str] = "--stdin"
32
+
33
+
34
+ class _Finding(Protocol):
35
+ """Structural type for a per-matcher finding dataclass."""
36
+
37
+
38
+ @dataclass(frozen=True)
39
+ class GrepResult:
40
+ """Canonical path-based matcher report.
41
+
42
+ Pre-conditions: ``findings`` holds the matcher-specific finding dataclasses
43
+ (each a frozen ``@dataclass``). Post-conditions: ``to_json`` emits the
44
+ canonical ``{grep, path, passed, findings}`` payload, including ``note``
45
+ only when it is not ``None``.
46
+ """
47
+
48
+ grep: str
49
+ path: str | None
50
+ passed: bool
51
+ findings: list[Any] = field(default_factory=list)
52
+ note: str | None = None
53
+
54
+ def to_json(self) -> str:
55
+ payload: dict[str, object] = {
56
+ "grep": self.grep,
57
+ "path": self.path,
58
+ "passed": self.passed,
59
+ "findings": [asdict(f) for f in self.findings],
60
+ }
61
+ if self.note is not None:
62
+ payload["note"] = self.note
63
+ return json.dumps(payload, indent=2)
64
+
65
+
66
+ def read_input(argv: list[str]) -> tuple[str, Path | None]:
67
+ """Return ``(content, path)`` from a path argument or stdin.
68
+
69
+ Pre-conditions: ``argv`` is ``sys.argv`` (``argv[0]`` is the script name).
70
+ Post-conditions: when ``argv[1]`` is a path (not ``--stdin``), the file is
71
+ read and returned with its ``Path``; otherwise stdin is read with a
72
+ ``None`` path.
73
+ """
74
+ if len(argv) >= 2 and argv[1] != STDIN_FLAG:
75
+ path = Path(argv[1])
76
+ return path.read_text(encoding="utf-8"), path
77
+ return sys.stdin.read(), None
78
+
79
+
80
+ def run_grep(
81
+ check: Callable[[str, Path | None], GrepResult],
82
+ argv: list[str],
83
+ ) -> int:
84
+ """Run ``check`` over the resolved input, print the report, return the exit.
85
+
86
+ Pre-conditions: ``check`` returns a :class:`GrepResult`. Post-conditions:
87
+ the JSON report is printed to stdout; the return is ``EXIT_PASS`` when the
88
+ result passed, ``EXIT_FAIL`` otherwise.
89
+ """
90
+ content, path = read_input(argv)
91
+ result = check(content, path)
92
+ print(result.to_json())
93
+ return EXIT_PASS if result.passed else EXIT_FAIL
@@ -0,0 +1,306 @@
1
+ # SPDX-License-Identifier: MIT
2
+
3
+ """Verify every harness declares its agentic-capability matrix.
4
+
5
+ Why this validator exists. The agent-capability discipline (per
6
+ ``rules/agent-capability-discipline.md``) requires every harness in
7
+ the 17-harness cohort to declare a structured capability matrix in its
8
+ template tree so adapter authors, operators, and downstream tooling can
9
+ reason about the harness's agentic surface without inspecting source.
10
+ The installed machine-readable projection names thirteen fields:
11
+ ``mcp_servers`` (list of MCP servers the harness can host),
12
+ ``sub_agent_dispatch`` (bool — whether the harness spawns sub-agents),
13
+ ``custom_command_support`` (yes/no/discovery-pending),
14
+ ``recommended_postfix_rendering`` (how recommended option labels render),
15
+ ``long_context_compaction`` (native or profile-managed long-session
16
+ continuity), ``context_ignore_surface`` (native ignore surface or declared
17
+ absence), ``standard_convention_pin`` (the sibling pin file),
18
+ ``tool_surface_restrictions`` (list of tool-surface constraints),
19
+ ``system_prompt_template_path`` (str pointer to the harness's system-prompt
20
+ template), ``agent_memory_surface`` (str naming the harness's memory
21
+ surface), ``layered_context_surface`` (native hierarchy or profile-managed
22
+ projection), ``lsp_symbol_navigation`` (native/plugin-backed symbol lookup
23
+ or tracked gap), and ``hook_learning_capture`` (where recurring hook lessons
24
+ are persisted without pass-class chatter).
25
+
26
+ Detection. For each harness directory at
27
+ ``src/apothem/harnesses/<harness>/`` that exists, look for one of three
28
+ declaration files: ``capabilities.yml`` / ``capabilities.yaml`` /
29
+ ``agent_capabilities.md``. The YAML form is parsed; the Markdown form is
30
+ inspected for the thirteen field markers as ``- field_name:`` lines. A
31
+ harness whose directory is present but whose declaration is absent OR
32
+ whose declaration is missing any required projection field produces a
33
+ finding.
34
+
35
+ Pre-materialization tolerance. Some harness directories may not yet exist
36
+ on disk in early repository states. The validator is absence-tolerant: when zero harness
37
+ directories are present, it exits 0 with an informational
38
+ ``harnesses_not_yet_materialized`` message so the gate does not block
39
+ the early absence-tolerant state. Once at least one harness directory exists, the
40
+ validator enforces the discipline on every present harness.
41
+
42
+ Exit semantics. Exits 0 when every present harness declares a complete
43
+ capability matrix (or when zero harness directories exist). Exits 2 on
44
+ any present harness lacking the declaration or missing any required
45
+ field. The exit-2 convention matches the conformity-gate orchestrator's
46
+ ``EXIT_FAIL`` constant.
47
+ """
48
+
49
+ from __future__ import annotations
50
+
51
+ import json
52
+ import sys
53
+ from dataclasses import asdict, dataclass, field
54
+ from pathlib import Path
55
+ from typing import Final
56
+
57
+ import yaml
58
+
59
+ GREP_NAME: Final[str] = "agent-capability-grep"
60
+ RULE_ANCHOR: Final[str] = "agent-capability-discipline (per-harness capability matrix)"
61
+
62
+ EXIT_PASS: Final[int] = 0
63
+ EXIT_FAIL: Final[int] = 2
64
+
65
+ # The 17-harness cohort. Each entry is the directory name (package key)
66
+ # under src/apothem/harnesses/. The cohort is derived from the registry's
67
+ # SUPPORTED_PACKAGE_KEYS so a newly-registered adapter (e.g. codebuddy,
68
+ # kiro, trae, zed) is validated without editing this tuple. When the
69
+ # registry cannot be imported (an unusual mount layout the standalone
70
+ # subprocess cannot reach), the validator falls back to the static cohort
71
+ # so it never silently shrinks its sweep below the known full set.
72
+ _FALLBACK_HARNESS_COHORT: Final[tuple[str, ...]] = (
73
+ "antigravity",
74
+ "claude_code",
75
+ "codex",
76
+ "cursor",
77
+ "gemini_cli",
78
+ "github_copilot",
79
+ "hermes",
80
+ "kimi_code",
81
+ "open_claw",
82
+ "opencode",
83
+ "qwen_code",
84
+ "windsurf",
85
+ "codebuddy",
86
+ "kiro",
87
+ "trae",
88
+ "zed",
89
+ "glm",
90
+ )
91
+
92
+
93
+ def _resolve_cohort() -> tuple[str, ...]:
94
+ """Return the harness package-key cohort, derived from the registry.
95
+
96
+ Imports ``SUPPORTED_PACKAGE_KEYS`` from the harness registry so the
97
+ cohort tracks the registered adapter set automatically. Falls back to
98
+ the static full cohort if the import fails.
99
+ """
100
+ try:
101
+ from apothem.lib.harness_registry import SUPPORTED_PACKAGE_KEYS
102
+ except Exception: # import boundary: fall back to the static cohort
103
+ return _FALLBACK_HARNESS_COHORT
104
+ return tuple(SUPPORTED_PACKAGE_KEYS)
105
+
106
+
107
+ HARNESS_COHORT: Final[tuple[str, ...]] = _resolve_cohort()
108
+
109
+ # The required capability-matrix fields for the installed projection.
110
+ REQUIRED_FIELDS: Final[tuple[str, ...]] = (
111
+ "mcp_servers",
112
+ "sub_agent_dispatch",
113
+ "custom_command_support",
114
+ "recommended_postfix_rendering",
115
+ "long_context_compaction",
116
+ "context_ignore_surface",
117
+ "layered_context_surface",
118
+ "lsp_symbol_navigation",
119
+ "hook_learning_capture",
120
+ "standard_convention_pin",
121
+ "tool_surface_restrictions",
122
+ "system_prompt_template_path",
123
+ "agent_memory_surface",
124
+ )
125
+
126
+ # Declaration filenames the validator probes per harness, in priority order.
127
+ DECLARATION_FILENAMES: Final[tuple[str, ...]] = (
128
+ "capabilities.yml",
129
+ "capabilities.yaml",
130
+ "agent_capabilities.md",
131
+ )
132
+
133
+
134
+ @dataclass(frozen=True)
135
+ class Finding:
136
+ """One harness lacking a complete capability matrix."""
137
+
138
+ harness: str
139
+ detail: str
140
+ missing_fields: list[str] = field(default_factory=list)
141
+ rule: str = RULE_ANCHOR
142
+
143
+
144
+ @dataclass(frozen=True)
145
+ class GrepResult:
146
+ """Aggregated walk result for a single cohort sweep."""
147
+
148
+ grep: str
149
+ root: str
150
+ harnesses_present: int
151
+ harnesses_total: int
152
+ passed: bool
153
+ informational: str | None = None
154
+ findings: list[Finding] = field(default_factory=list)
155
+
156
+ def to_json(self) -> str:
157
+ payload = {
158
+ "grep": self.grep,
159
+ "root": self.root,
160
+ "harnesses_present": self.harnesses_present,
161
+ "harnesses_total": self.harnesses_total,
162
+ "passed": self.passed,
163
+ "informational": self.informational,
164
+ "findings": [asdict(f) for f in self.findings],
165
+ }
166
+ return json.dumps(payload, indent=2)
167
+
168
+
169
+ def _harnesses_dir(root: Path) -> Path:
170
+ return root / "src" / "apothem" / "harnesses"
171
+
172
+
173
+ def _find_declaration(harness_dir: Path) -> Path | None:
174
+ """Probe the harness directory tree for a declaration file.
175
+
176
+ Looks at the harness root and at ``templates/`` inside it (the
177
+ rule allows either location). Returns the first match in
178
+ ``DECLARATION_FILENAMES`` priority order, or None when absent.
179
+ """
180
+ candidate_dirs = (harness_dir, harness_dir / "templates")
181
+ for directory in candidate_dirs:
182
+ for filename in DECLARATION_FILENAMES:
183
+ candidate = directory / filename
184
+ if candidate.is_file():
185
+ return candidate
186
+ return None
187
+
188
+
189
+ def _parse_yaml_declaration(path: Path) -> dict[str, object]:
190
+ """Load a YAML declaration into a dict. Empty or non-mapping → {}."""
191
+ try:
192
+ raw = path.read_text(encoding="utf-8")
193
+ except OSError:
194
+ return {}
195
+ try:
196
+ loaded = yaml.safe_load(raw)
197
+ except yaml.YAMLError:
198
+ return {}
199
+ if isinstance(loaded, dict):
200
+ return loaded
201
+ return {}
202
+
203
+
204
+ def _parse_markdown_declaration(path: Path) -> dict[str, object]:
205
+ """Scan a Markdown declaration for ``- field_name:`` field markers.
206
+
207
+ The Markdown form admits any prose around the field markers; this
208
+ parser is presence-only — it records each required field's
209
+ presence (mapping to a placeholder True value) without inspecting
210
+ the field's substantive value. The YAML form is the rigorous
211
+ surface; the Markdown form is the lightweight alternative.
212
+ """
213
+ try:
214
+ text = path.read_text(encoding="utf-8")
215
+ except OSError:
216
+ return {}
217
+ found: dict[str, object] = {}
218
+ for line in text.splitlines():
219
+ stripped = line.strip()
220
+ for field_name in REQUIRED_FIELDS:
221
+ # Accept `- field_name:` or `field_name:` at line start.
222
+ if stripped.startswith(f"- {field_name}:") or stripped.startswith(
223
+ f"{field_name}:"
224
+ ):
225
+ found[field_name] = True
226
+ return found
227
+
228
+
229
+ def _missing_fields(declaration: dict[str, object]) -> list[str]:
230
+ return [f for f in REQUIRED_FIELDS if f not in declaration]
231
+
232
+
233
+ def check(root: Path) -> GrepResult:
234
+ """Walk the harness cohort under root; flag incomplete declarations."""
235
+ harnesses_dir = _harnesses_dir(root)
236
+ findings: list[Finding] = []
237
+ present_count = 0
238
+ for harness in HARNESS_COHORT:
239
+ harness_dir = harnesses_dir / harness
240
+ if not harness_dir.is_dir():
241
+ continue
242
+ present_count += 1
243
+ declaration_path = _find_declaration(harness_dir)
244
+ if declaration_path is None:
245
+ findings.append(
246
+ Finding(
247
+ harness=harness,
248
+ detail=(
249
+ "no capability declaration found; expected one of "
250
+ f"{list(DECLARATION_FILENAMES)} under {harness_dir} "
251
+ "or its templates/ subdirectory"
252
+ ),
253
+ missing_fields=list(REQUIRED_FIELDS),
254
+ )
255
+ )
256
+ continue
257
+ if declaration_path.suffix in {".yml", ".yaml"}:
258
+ declaration = _parse_yaml_declaration(declaration_path)
259
+ else:
260
+ declaration = _parse_markdown_declaration(declaration_path)
261
+ missing = _missing_fields(declaration)
262
+ if missing:
263
+ findings.append(
264
+ Finding(
265
+ harness=harness,
266
+ detail=(
267
+ f"declaration at {declaration_path} is missing "
268
+ f"{len(missing)} of {len(REQUIRED_FIELDS)} required "
269
+ "capability-matrix fields"
270
+ ),
271
+ missing_fields=missing,
272
+ )
273
+ )
274
+ informational: str | None = None
275
+ if present_count == 0:
276
+ informational = (
277
+ "harnesses_not_yet_materialized: zero of "
278
+ f"{len(HARNESS_COHORT)} harness directories present under "
279
+ f"{harnesses_dir}; validator is in an absence-tolerant pass"
280
+ )
281
+ return GrepResult(
282
+ grep=GREP_NAME,
283
+ root=str(root),
284
+ harnesses_present=present_count,
285
+ harnesses_total=len(HARNESS_COHORT),
286
+ passed=not findings,
287
+ informational=informational,
288
+ findings=findings,
289
+ )
290
+
291
+
292
+ def _read_input(argv: list[str]) -> Path:
293
+ if len(argv) >= 2:
294
+ return Path(argv[1])
295
+ return Path.cwd()
296
+
297
+
298
+ def _main(argv: list[str]) -> int:
299
+ root = _read_input(argv)
300
+ result = check(root)
301
+ print(result.to_json())
302
+ return EXIT_PASS if result.passed else EXIT_FAIL
303
+
304
+
305
+ if __name__ == "__main__":
306
+ sys.exit(_main(sys.argv))