@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,382 @@
1
+ # SPDX-License-Identifier: MIT
2
+
3
+ """Flag stale agent-companion files under the root-only AGENTS.md convention.
4
+
5
+ Why this enforcement exists. The repository carries a single agent-facing
6
+ canon at the root ``AGENTS.md``; per-folder operating guidance lives in each
7
+ folder's ``README.md``, which serves both the human reader and the agent
8
+ reader. Per-folder ``AGENTS.md`` companions are no longer required — a
9
+ meaningful folder without one passes. The one defect this sweep still guards
10
+ is staleness: a per-folder companion that an author kept (the rare standalone
11
+ companion the convention permits) must not fall behind its folder after the
12
+ folder's artifacts or conventions changed. An absent companion is never a
13
+ finding; only a present, committed-but-stale companion is.
14
+
15
+ The meaningful-folder set. A folder is *meaningful* when it is navigable —
16
+ a contributor or an agent reasons about it as a unit — and load-bearing. The
17
+ enumeration is the navigable-folder set the README convention applies to; it
18
+ is retained here as the source-of-truth for the freshness check's
19
+ folder-ownership map and is reported as ``folders_inspected`` for information.
20
+ The set is the union of two reproducible rules, minus a fixed exclusion list:
21
+
22
+ - **(A) Companion-anchored.** Any folder that already carries a contributor
23
+ ``README.md`` directly. Test-fixture leaf dirs (whose README is itself the
24
+ subject of a presence check) and single-artifact example scaffolds are
25
+ excluded — their README documents a fixture, not a navigable subsystem.
26
+ - **(B) Source-package.** Any ``src/apothem`` folder that directly contains a
27
+ Python source file but carries no README — the harness adapter packages,
28
+ the shared adapter helpers, the hook library. An agent operating inside one
29
+ of these packages needs the same orientation a README-bearing folder gives.
30
+
31
+ Constant exclusions across both rules: vendored trees, generated trees, the
32
+ git/cache/ephemera directories, rendered harness-output template leaves, and
33
+ the plan-suite scratch. Including any of those would pollute fixtures or
34
+ describe machinery no contributor navigates by hand. Materialized
35
+ harness-output ``AGENTS.md`` files under ``src/apothem/harnesses/*/templates/``
36
+ are product surfaces, not companions, and are excluded by the same rule.
37
+
38
+ Freshness. A *present* per-folder companion is *stale* when its folder's
39
+ directly-contained artifacts were last committed more recently than the
40
+ companion itself. The signal is the git commit timestamp, not the filesystem
41
+ mtime: a checkout rewrites mtimes, so only commit history carries the truth of
42
+ "what changed when". A single ``git log`` pass buckets every tracked file to
43
+ its nearest meaningful-folder ancestor; a folder is stale when its newest
44
+ content commit postdates its committed companion's commit. Folders with no
45
+ companion on disk are skipped entirely — absence is not a finding under the
46
+ root-only convention. Where git history is unavailable (a shallow clone, a
47
+ non-git tree), freshness is skipped and the sweep reports a clean pass — it
48
+ never blocks a fresh clone.
49
+
50
+ Posture. The result is advisory: the sweep surfaces findings and never
51
+ silent-blocks by default, honoring the agnostic gate posture. The orchestrator
52
+ reads the JSON ``advisory: true`` flag plus the inner ``passed`` field — a
53
+ stale-companion finding surfaces as ``advisory_findings_present`` without
54
+ gating the ``gate --all`` run. CI opts into strict enforcement separately.
55
+ ``_main`` always exits 0 so the advisory posture holds regardless of findings;
56
+ the verdict travels in the JSON, not the exit code.
57
+ """
58
+
59
+ from __future__ import annotations
60
+
61
+ import json
62
+ import subprocess
63
+ import sys
64
+ from dataclasses import asdict, dataclass, field
65
+ from pathlib import Path
66
+ from typing import Final
67
+
68
+ GREP_NAME: Final[str] = "agents-md-coverage-grep"
69
+ RULE_ANCHOR: Final[str] = "rules/agents-md-convention.md"
70
+
71
+ # Advisory posture: the sweep always exits 0 (the verdict travels in the JSON
72
+ # ``advisory`` / ``passed`` fields), so only the pass code is needed here.
73
+ EXIT_PASS: Final[int] = 0
74
+
75
+ # The agent-companion filename and its human-facing sibling.
76
+ COMPANION_NAME: Final[str] = "AGENTS.md"
77
+ README_NAME: Final[str] = "README.md"
78
+
79
+ # Bound the git invocation so a hung `git log` cannot stall the sweep; a
80
+ # timeout is treated as a transient git error and degrades to a clean pass.
81
+ GIT_TIMEOUT_SECONDS: Final[int] = 10
82
+
83
+ # Path segments that mark a directory as out of scope wherever they appear.
84
+ # Vendored trees, generated output, caches, and ephemera are never navigable
85
+ # subsystems an agent reasons about by hand.
86
+ _EXCLUDED_SEGMENTS: Final[frozenset[str]] = frozenset(
87
+ {
88
+ ".git",
89
+ "node_modules",
90
+ "_vendor",
91
+ "dist",
92
+ ".audit",
93
+ ".plans",
94
+ ".hypothesis",
95
+ ".mypy_cache",
96
+ ".pytest_cache",
97
+ ".ruff_cache",
98
+ ".venv",
99
+ "venv",
100
+ "__pycache__",
101
+ }
102
+ )
103
+
104
+ # Relative-path prefixes whose subtree is excluded as a whole.
105
+ _EXCLUDED_PREFIXES: Final[tuple[str, ...]] = (
106
+ "site/dist",
107
+ "site/node_modules",
108
+ )
109
+
110
+ # Rule-(A) carve-outs: a README under one of these is a fixture/example
111
+ # README, not a navigable-subsystem README. Matched as path substrings on the
112
+ # POSIX-relative folder path.
113
+ _FIXTURE_FOLDER_MARKERS: Final[tuple[str, ...]] = (
114
+ "tests/scripts/inject-header/fixtures",
115
+ "examples/minimal-",
116
+ )
117
+
118
+ # Rule-(B) scope: source-package folders live under this prefix.
119
+ _SOURCE_PACKAGE_PREFIX: Final[str] = "src/apothem"
120
+ _PYTHON_SUFFIX: Final[str] = ".py"
121
+
122
+
123
+ @dataclass(frozen=True)
124
+ class Finding:
125
+ """One stale present per-folder agent-companion file."""
126
+
127
+ surface: str
128
+ kind: str
129
+ detail: str
130
+ rule: str = RULE_ANCHOR
131
+
132
+
133
+ @dataclass(frozen=True)
134
+ class GrepResult:
135
+ """Aggregated coverage result for a single sweep."""
136
+
137
+ grep: str
138
+ root: str
139
+ folders_inspected: int
140
+ freshness_checked: bool
141
+ passed: bool
142
+ findings: list[Finding] = field(default_factory=list)
143
+
144
+ def to_json(self) -> str:
145
+ payload = {
146
+ "grep": self.grep,
147
+ "root": self.root,
148
+ "folders_inspected": self.folders_inspected,
149
+ "freshness_checked": self.freshness_checked,
150
+ "passed": self.passed,
151
+ "findings": [asdict(f) for f in self.findings],
152
+ "advisory": True,
153
+ }
154
+ return json.dumps(payload, indent=2)
155
+
156
+
157
+ def _has_excluded_segment(rel_posix: str) -> bool:
158
+ """Return True iff any path segment marks the path out of scope."""
159
+ if not rel_posix or rel_posix == ".":
160
+ return False
161
+ if any(rel_posix == p or rel_posix.startswith(p + "/") for p in _EXCLUDED_PREFIXES):
162
+ return True
163
+ return any(segment in _EXCLUDED_SEGMENTS for segment in rel_posix.split("/"))
164
+
165
+
166
+ def _is_fixture_folder(rel_posix: str) -> bool:
167
+ """Return True iff a folder is a test-fixture or single-artifact example leaf."""
168
+ if "/" in rel_posix:
169
+ parent, _, leaf = rel_posix.rpartition("/")
170
+ # tests/conformity/<matcher>/{fail,pass} — the README is the grep subject.
171
+ if leaf in {"fail", "pass"} and parent.startswith("tests/conformity/"):
172
+ return True
173
+ return any(marker in rel_posix for marker in _FIXTURE_FOLDER_MARKERS)
174
+
175
+
176
+ def _is_harness_template_leaf(rel_posix: str) -> bool:
177
+ """Return True iff a folder is a rendered harness-output template leaf."""
178
+ parts = rel_posix.split("/")
179
+ # src/apothem/harnesses/<name>/templates[/...]
180
+ return (
181
+ len(parts) >= 5
182
+ and parts[:3] == ["src", "apothem", "harnesses"]
183
+ and "templates" in parts[4:5]
184
+ )
185
+
186
+
187
+ def _rel_posix(path: Path, root_resolved: Path) -> str | None:
188
+ try:
189
+ rel = path.resolve().relative_to(root_resolved).as_posix()
190
+ except ValueError:
191
+ return None
192
+ return "." if rel == "" else rel
193
+
194
+
195
+ def meaningful_folders(root: Path) -> list[str]:
196
+ """Enumerate the meaningful-folder set under ``root``.
197
+
198
+ Pre-conditions: ``root`` is the repository root (or a subtree).
199
+ Post-conditions: returns the sorted, deduplicated POSIX-relative folder
200
+ paths (``.`` denotes the root) that satisfy rule (A) or rule (B) and pass
201
+ the constant exclusions. Re-running over an unchanged tree yields the
202
+ identical set — the enumeration is the single source of truth the
203
+ presence/freshness check and the documentation convention both consume.
204
+ """
205
+ root_resolved = root.resolve()
206
+ folders: set[str] = set()
207
+
208
+ # Rule (A): folders carrying a contributor README, minus fixture/example leaves.
209
+ for readme in root.rglob(README_NAME):
210
+ if not readme.is_file():
211
+ continue
212
+ rel = _rel_posix(readme.parent, root_resolved)
213
+ if rel is None or _has_excluded_segment(rel):
214
+ continue
215
+ if _is_fixture_folder(rel):
216
+ continue
217
+ folders.add(rel)
218
+
219
+ # Rule (B): src/apothem source-package folders without a README, minus
220
+ # vendored trees and rendered harness-template leaves.
221
+ for py_file in root.rglob(f"*{_PYTHON_SUFFIX}"):
222
+ if not py_file.is_file():
223
+ continue
224
+ rel = _rel_posix(py_file.parent, root_resolved)
225
+ if rel is None or rel == ".":
226
+ continue
227
+ if not (
228
+ rel == _SOURCE_PACKAGE_PREFIX
229
+ or rel.startswith(_SOURCE_PACKAGE_PREFIX + "/")
230
+ ):
231
+ continue
232
+ if _has_excluded_segment(rel) or _is_harness_template_leaf(rel):
233
+ continue
234
+ if (py_file.parent / README_NAME).is_file():
235
+ continue
236
+ folders.add(rel)
237
+
238
+ return sorted(folders)
239
+
240
+
241
+ def _last_commit_times(root: Path) -> dict[str, int] | None:
242
+ """Return a map of tracked-file POSIX path → last-commit unix timestamp.
243
+
244
+ One ``git log`` pass, newest commit first: the first time a path is seen
245
+ is its last-touching commit. Returns None when git history is unavailable
246
+ (no repository, shallow clone with no log, git absent, or timeout) so the
247
+ caller degrades to a presence-only sweep.
248
+ """
249
+ try:
250
+ completed = subprocess.run(
251
+ [
252
+ "git",
253
+ "-C",
254
+ str(root),
255
+ "log",
256
+ "--format=%x1e%ct",
257
+ "--name-only",
258
+ "--no-renames",
259
+ ],
260
+ capture_output=True,
261
+ text=True,
262
+ timeout=GIT_TIMEOUT_SECONDS,
263
+ check=False,
264
+ )
265
+ except (OSError, subprocess.SubprocessError):
266
+ return None
267
+ if completed.returncode != 0 or not completed.stdout:
268
+ return None
269
+
270
+ times: dict[str, int] = {}
271
+ current_ct: int | None = None
272
+ for raw_line in completed.stdout.splitlines():
273
+ if raw_line.startswith("\x1e"):
274
+ stamp = raw_line[1:].strip()
275
+ current_ct = int(stamp) if stamp.isdigit() else None
276
+ continue
277
+ path = raw_line.strip()
278
+ if not path or current_ct is None:
279
+ continue
280
+ # Newest-first: keep only the first (most recent) commit per path.
281
+ if path not in times:
282
+ times[path] = current_ct
283
+ return times
284
+
285
+
286
+ def _owning_folder(file_posix: str, folder_set: frozenset[str]) -> str:
287
+ """Map a tracked file to its nearest meaningful-folder ancestor.
288
+
289
+ A top-level file maps to ``.``. A file under a non-meaningful subdir walks
290
+ up to the nearest meaningful ancestor; a file under a child meaningful
291
+ folder is owned by that child, never the parent — ownership is disjoint.
292
+ """
293
+ parent = file_posix.rpartition("/")[0]
294
+ while parent:
295
+ if parent in folder_set:
296
+ return parent
297
+ parent = parent.rpartition("/")[0]
298
+ return "."
299
+
300
+
301
+ def check(root: Path) -> GrepResult:
302
+ """Enumerate meaningful folders; flag only present, stale companions.
303
+
304
+ Pre-conditions: ``root`` is the repository root (or an arbitrary subtree).
305
+ Post-conditions: under the root-only convention, a meaningful folder
306
+ without a per-folder ``AGENTS.md`` is never a finding — absence passes.
307
+ ``result.passed`` is True iff (when git history is available) no *present*,
308
+ committed per-folder companion is stale relative to its folder's
309
+ directly-contained artifacts; it is always True when git history is
310
+ unavailable.
311
+ """
312
+ folders = meaningful_folders(root)
313
+ folder_set = frozenset(folders)
314
+ findings: list[Finding] = []
315
+
316
+ # Freshness — git-commit truth; skipped when history is unavailable.
317
+ commit_times = _last_commit_times(root)
318
+ freshness_checked = commit_times is not None
319
+ if commit_times is not None:
320
+ content_ct: dict[str, int] = {}
321
+ companion_ct: dict[str, int] = {}
322
+ for path, ct in commit_times.items():
323
+ if _has_excluded_segment(path):
324
+ continue
325
+ owner = _owning_folder(path, folder_set)
326
+ if path.rpartition("/")[2] == COMPANION_NAME:
327
+ companion_folder = path.rpartition("/")[0] or "."
328
+ if companion_folder in folder_set:
329
+ companion_ct[companion_folder] = ct
330
+ continue
331
+ content_ct[owner] = max(content_ct.get(owner, 0), ct)
332
+ for folder in folders:
333
+ # Only committed companions can be stale; an uncommitted one is fresh.
334
+ if folder not in companion_ct:
335
+ continue
336
+ newest_content = content_ct.get(folder, 0)
337
+ if newest_content > companion_ct[folder]:
338
+ surface = (
339
+ COMPANION_NAME if folder == "." else f"{folder}/{COMPANION_NAME}"
340
+ )
341
+ findings.append(
342
+ Finding(
343
+ surface=surface,
344
+ kind="stale-companion",
345
+ detail=(
346
+ f"'{folder}' content changed after its {COMPANION_NAME} was "
347
+ "last updated; refresh the companion in the same change-set"
348
+ ),
349
+ )
350
+ )
351
+
352
+ return GrepResult(
353
+ grep=GREP_NAME,
354
+ root=str(root),
355
+ folders_inspected=len(folders),
356
+ freshness_checked=freshness_checked,
357
+ passed=not findings,
358
+ findings=findings,
359
+ )
360
+
361
+
362
+ def _read_input(argv: list[str]) -> Path:
363
+ if len(argv) >= 2:
364
+ return Path(argv[1])
365
+ return Path.cwd()
366
+
367
+
368
+ def _main(argv: list[str]) -> int:
369
+ root = _read_input(argv)
370
+ result = check(root)
371
+ print(result.to_json())
372
+ # Advisory posture: always exit 0 so the sweep never silent-blocks by
373
+ # default. The verdict travels in the JSON — the orchestrator reads the
374
+ # ``advisory: true`` flag plus the inner ``passed`` field (via
375
+ # ``gate._advisory_verdict``) and surfaces a stale-companion finding as
376
+ # ``advisory_findings_present`` without failing the ``gate --all`` run.
377
+ # CI opts into strict enforcement separately.
378
+ return EXIT_PASS
379
+
380
+
381
+ if __name__ == "__main__":
382
+ sys.exit(_main(sys.argv))
@@ -0,0 +1,311 @@
1
+ # SPDX-License-Identifier: MIT
2
+
3
+ """Flag harness bias and re-introduced enforcement presets in shipped surfaces.
4
+
5
+ Why this enforcement exists. The agnostic-posture rule
6
+ (``rules/agnostic-posture.md``) requires every shipped surface to be
7
+ harness-neutral and free of imposed enforcement: a clean install privileges
8
+ no harness and pre-sets no model, effort, or workflow. This sweep is the
9
+ mechanical guard for that posture's two failure classes — it is the
10
+ agnosticism counterpart of ``plain_language_grep`` (the two sweeps are paired
11
+ by the phase that introduces them).
12
+
13
+ Scope. Corpus-level standalone validator. Walks the working tree under the
14
+ supplied root and inspects ONLY the four shipped-surface directories:
15
+
16
+ - ``src/apothem/rules/`` — behavioral instruction files.
17
+ - ``src/apothem/commands/`` — slash-command definitions.
18
+ - ``src/apothem/output-styles/`` — output-style definitions.
19
+ - ``src/apothem/statuslines/`` — statusline definitions.
20
+
21
+ Every other path is out of scope: tests, plans, harness adapter packages
22
+ (whose per-harness catalog content legitimately names every harness), and
23
+ all source code outside the four prose surfaces.
24
+
25
+ Detection — two closed classes.
26
+
27
+ 1. **Harness bias.** The brand phrase ``Claude Code`` and the branded model
28
+ names ``Claude Opus`` / ``Claude Sonnet`` / ``Claude Haiku`` are
29
+ privileging forms: they tailor a shipped surface to one harness. The
30
+ canonical slug ``claude_code`` is the neutral catalog identifier — a line
31
+ that carries the slug is a per-harness catalog row (one entry among the
32
+ registered harnesses) and is exempt. Matches inside fenced code
33
+ blocks are excluded (a fenced example is not shipped prose).
34
+
35
+ 2. **Enforcement preset.** A shipped command, skill, or agent that
36
+ re-introduces an ``effort:`` or ``model:`` frontmatter default imposes a
37
+ preference the end user is meant to supply in conversation. The sweep
38
+ flags any non-empty ``effort:`` / ``model:`` key inside the YAML
39
+ frontmatter block of a command, skill, or agent definition.
40
+
41
+ Exit semantics. Exits 0 when zero findings across every in-scope file;
42
+ exits 2 on any finding. The exit-2 convention matches the conformity-gate
43
+ orchestrator's EXIT_FAIL constant. The gate renders this sweep as an
44
+ advisory by default; ``--strict`` (or ``APOTHEM_CONFORMITY_STRICT``)
45
+ restores blocking, per the agnostic-posture advisory-gate discipline.
46
+ """
47
+
48
+ from __future__ import annotations
49
+
50
+ import json
51
+ import re
52
+ import sys
53
+ from dataclasses import asdict, dataclass, field
54
+ from pathlib import Path
55
+ from typing import Final
56
+
57
+ GREP_NAME: Final[str] = "agnosticism-grep"
58
+ RULE_ANCHOR: Final[str] = (
59
+ "rules/agnostic-posture.md §3 (harness neutrality) + §1 (default-off)"
60
+ )
61
+
62
+ EXIT_PASS: Final[int] = 0
63
+ EXIT_FAIL: Final[int] = 2
64
+
65
+ # The four shipped-surface directories, relative to the repository root.
66
+ # A candidate Markdown file is in scope iff its POSIX-normalized relative
67
+ # path begins with one of these prefixes.
68
+ _SCOPE_PREFIXES: Final[tuple[str, ...]] = (
69
+ "src/apothem/rules/",
70
+ "src/apothem/commands/",
71
+ "src/apothem/output-styles/",
72
+ "src/apothem/statuslines/",
73
+ )
74
+ # Enforcement-preset scope. The shipped surfaces that carry an end-user-facing
75
+ # YAML frontmatter where a model/effort preset would impose a preference: the
76
+ # slash-commands, the skill definitions, and the agent definitions. The bias
77
+ # scan keeps its own (``_SCOPE_PREFIXES``) reach; the preset scan reaches all
78
+ # three so a re-introduced ``effort:`` / ``model:`` key is caught wherever a
79
+ # definition declares one.
80
+ _PRESET_PREFIXES: Final[tuple[str, ...]] = (
81
+ "src/apothem/commands/",
82
+ "src/apothem/skills/",
83
+ "src/apothem/agents/",
84
+ )
85
+
86
+ # Per-folder agent-companion files are agnostic shipped surfaces too: every
87
+ # AGENTS.md must privilege no single harness. They are swept for harness bias
88
+ # wherever they live in the tree. The rendered harness-output template fixture
89
+ # under a `templates/` leaf is NOT a companion — it is materialized output.
90
+ _COMPANION_BASENAME: Final[str] = "AGENTS.md"
91
+ _TEMPLATE_LEAF_FRAGMENT: Final[str] = "/templates/"
92
+
93
+ # Harness-bias forms. ``Claude Code`` (the brand phrase) and the branded
94
+ # model names privilege one harness; the slug ``claude_code`` is the
95
+ # neutral catalog identifier and is matched separately as the exemption
96
+ # signal. Whitespace between the two words is flexible so a line-wrapped
97
+ # brand phrase is still caught.
98
+ _BIAS_RE: Final[re.Pattern[str]] = re.compile(
99
+ r"(?i)\bClaude\s+(?:Code|Opus|Sonnet|Haiku)\b"
100
+ )
101
+
102
+ # A line carrying the canonical slug is a per-harness catalog row (one
103
+ # entry among the registered harnesses) and is exempt from the
104
+ # bias scan — the slug is the neutral identifier the agnostic posture
105
+ # permits.
106
+ _CATALOG_SLUG: Final[str] = "claude_code"
107
+
108
+ # Enforcement-preset frontmatter keys. A shipped command that pre-sets one
109
+ # of these imposes a preference the end user is meant to supply.
110
+ _PRESET_KEY_RE: Final[re.Pattern[str]] = re.compile(r"^(effort|model):\s*\S")
111
+
112
+ # Fenced code block delimiter — a line beginning with ``` at column 0.
113
+ _CODE_FENCE_RE: Final[re.Pattern[str]] = re.compile(r"^```")
114
+
115
+ # YAML frontmatter delimiter — a line that is exactly ``---``.
116
+ _FRONTMATTER_DELIM: Final[str] = "---"
117
+
118
+ _MARKDOWN_SUFFIX: Final[str] = ".md"
119
+
120
+
121
+ @dataclass(frozen=True)
122
+ class Finding:
123
+ """One agnosticism violation discovered in a shipped surface."""
124
+
125
+ path: str
126
+ line: int
127
+ match: str
128
+ context: str
129
+ detail: str
130
+ rule: str = RULE_ANCHOR
131
+
132
+
133
+ @dataclass(frozen=True)
134
+ class GrepResult:
135
+ """Aggregated walk result for a single corpus sweep."""
136
+
137
+ grep: str
138
+ root: str
139
+ scanned_count: int
140
+ passed: bool
141
+ findings: list[Finding] = field(default_factory=list)
142
+
143
+ def to_json(self) -> str:
144
+ payload = {
145
+ "grep": self.grep,
146
+ "root": self.root,
147
+ "scanned_count": self.scanned_count,
148
+ "passed": self.passed,
149
+ "findings": [asdict(f) for f in self.findings],
150
+ }
151
+ return json.dumps(payload, indent=2)
152
+
153
+
154
+ def _relative_posix(path: Path, root: Path) -> str | None:
155
+ """Return ``path`` relative to ``root`` in POSIX form, or None."""
156
+ try:
157
+ return path.resolve().relative_to(root.resolve()).as_posix()
158
+ except ValueError:
159
+ return None
160
+
161
+
162
+ def _in_scope(rel_posix: str) -> bool:
163
+ """Return True iff a relative path is a shipped-surface Markdown file.
164
+
165
+ Two surface classes are in scope: the four prose-surface directories
166
+ (rules / commands / output-styles / statuslines) and every per-folder
167
+ agent-companion file (``AGENTS.md``) wherever it lives — the companions
168
+ are agnostic shipped surfaces per the per-folder-AGENTS.md convention. A
169
+ rendered harness-output template fixture under a ``templates/`` leaf is
170
+ materialized output, not a companion, and is excluded.
171
+ """
172
+ if "/" in rel_posix and rel_posix.rsplit("/", 1)[-1] == _COMPANION_BASENAME:
173
+ return _TEMPLATE_LEAF_FRAGMENT not in rel_posix
174
+ if not rel_posix.endswith(_MARKDOWN_SUFFIX):
175
+ return False
176
+ return rel_posix.startswith(_SCOPE_PREFIXES)
177
+
178
+
179
+ def _scan_bias(rel_posix: str, content: str) -> list[Finding]:
180
+ """Flag privileging harness-brand phrases outside fenced code blocks.
181
+
182
+ A line carrying the canonical slug ``claude_code`` is a per-harness
183
+ catalog row and is exempt.
184
+ """
185
+ findings: list[Finding] = []
186
+ inside_fence = False
187
+ for line_index, line in enumerate(content.splitlines(), start=1):
188
+ if _CODE_FENCE_RE.match(line):
189
+ inside_fence = not inside_fence
190
+ continue
191
+ if inside_fence:
192
+ continue
193
+ if _CATALOG_SLUG in line.lower():
194
+ continue
195
+ for match in _BIAS_RE.finditer(line):
196
+ findings.append(
197
+ Finding(
198
+ path=rel_posix,
199
+ line=line_index,
200
+ match=match.group(),
201
+ context=line.strip(),
202
+ detail=(
203
+ "harness-bias: privileging brand reference in a shipped "
204
+ "surface — name the harness by its slug (claude_code) as "
205
+ "one catalog entry among the registered harnesses, or genericize to "
206
+ "'the harness'"
207
+ ),
208
+ )
209
+ )
210
+ return findings
211
+
212
+
213
+ def _scan_enforcement_preset(rel_posix: str, content: str) -> list[Finding]:
214
+ """Flag a re-introduced ``effort:`` / ``model:`` frontmatter preset.
215
+
216
+ Scans only the leading YAML frontmatter block (delimited by a pair of
217
+ ``---`` lines) of a command / skill / agent definition. Pre-setting
218
+ effort or model imposes a preference the end user is meant to supply in
219
+ conversation.
220
+ """
221
+ if not rel_posix.startswith(_PRESET_PREFIXES):
222
+ return []
223
+ lines = content.splitlines()
224
+ if not lines or lines[0].strip() != _FRONTMATTER_DELIM:
225
+ return []
226
+ findings: list[Finding] = []
227
+ for line_index, line in enumerate(lines[1:], start=2):
228
+ if line.strip() == _FRONTMATTER_DELIM:
229
+ break
230
+ if _PRESET_KEY_RE.match(line):
231
+ findings.append(
232
+ Finding(
233
+ path=rel_posix,
234
+ line=line_index,
235
+ match=line.strip(),
236
+ context=line.strip(),
237
+ detail=(
238
+ "enforcement-preset: shipped surface pre-sets a "
239
+ "model/effort preference — strip the frontmatter key so "
240
+ "the preference resolves only from an in-conversation "
241
+ "end-user choice"
242
+ ),
243
+ )
244
+ )
245
+ return findings
246
+
247
+
248
+ def _scan_file(path: Path, rel_posix: str) -> list[Finding]:
249
+ """Scan one Markdown file for the applicable finding classes.
250
+
251
+ The bias scan applies only to the four prose surfaces and the AGENTS.md
252
+ companions (``_in_scope``); the enforcement-preset scan additionally
253
+ reaches the skill and agent definitions (``_PRESET_PREFIXES``), so the
254
+ two classes are gated independently.
255
+ """
256
+ try:
257
+ content = path.read_text(encoding="utf-8")
258
+ except (OSError, UnicodeDecodeError):
259
+ return []
260
+ findings: list[Finding] = []
261
+ if _in_scope(rel_posix):
262
+ findings.extend(_scan_bias(rel_posix, content))
263
+ findings.extend(_scan_enforcement_preset(rel_posix, content))
264
+ return findings
265
+
266
+
267
+ def check(root: Path) -> GrepResult:
268
+ """Walk the shipped surfaces under ``root``; flag agnosticism violations.
269
+
270
+ Pre-conditions: ``root`` is the repository root (or an arbitrary subtree
271
+ containing ``src/apothem/{rules,commands,output-styles,statuslines}/``).
272
+ Post-conditions: ``result.passed`` is True iff every in-scope shipped
273
+ surface is free of privileging harness-brand references (outside fenced
274
+ code) and re-introduced enforcement presets.
275
+ """
276
+ findings: list[Finding] = []
277
+ scanned = 0
278
+ for path in sorted(root.rglob(f"*{_MARKDOWN_SUFFIX}")):
279
+ if not path.is_file():
280
+ continue
281
+ rel_posix = _relative_posix(path, root)
282
+ if rel_posix is None:
283
+ continue
284
+ if not (_in_scope(rel_posix) or rel_posix.startswith(_PRESET_PREFIXES)):
285
+ continue
286
+ scanned += 1
287
+ findings.extend(_scan_file(path, rel_posix))
288
+ return GrepResult(
289
+ grep=GREP_NAME,
290
+ root=str(root),
291
+ scanned_count=scanned,
292
+ passed=not findings,
293
+ findings=findings,
294
+ )
295
+
296
+
297
+ def _read_input(argv: list[str]) -> Path:
298
+ if len(argv) >= 2:
299
+ return Path(argv[1])
300
+ return Path.cwd()
301
+
302
+
303
+ def _main(argv: list[str]) -> int:
304
+ root = _read_input(argv)
305
+ result = check(root)
306
+ print(result.to_json())
307
+ return EXIT_PASS if result.passed else EXIT_FAIL
308
+
309
+
310
+ if __name__ == "__main__":
311
+ sys.exit(_main(sys.argv))