skill-harness 0.2.1__tar.gz

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 (237) hide show
  1. skill_harness-0.2.1/.editorconfig +24 -0
  2. skill_harness-0.2.1/.gitattributes +12 -0
  3. skill_harness-0.2.1/.github/CODEOWNERS +16 -0
  4. skill_harness-0.2.1/.github/ISSUE_TEMPLATE/bug_report.yml +93 -0
  5. skill_harness-0.2.1/.github/ISSUE_TEMPLATE/config.yml +9 -0
  6. skill_harness-0.2.1/.github/ISSUE_TEMPLATE/feature_request.yml +62 -0
  7. skill_harness-0.2.1/.github/PULL_REQUEST_TEMPLATE.md +52 -0
  8. skill_harness-0.2.1/.github/dependabot.yml +60 -0
  9. skill_harness-0.2.1/.github/workflows/ci.yml +134 -0
  10. skill_harness-0.2.1/.github/workflows/depersonalization-gate.yml +51 -0
  11. skill_harness-0.2.1/.github/workflows/publish.yml +35 -0
  12. skill_harness-0.2.1/.gitignore +70 -0
  13. skill_harness-0.2.1/.pre-commit-config.yaml +167 -0
  14. skill_harness-0.2.1/AGENTS.md +17 -0
  15. skill_harness-0.2.1/CHANGELOG.md +272 -0
  16. skill_harness-0.2.1/CODE_OF_CONDUCT.md +83 -0
  17. skill_harness-0.2.1/CONTRIBUTING.md +109 -0
  18. skill_harness-0.2.1/LICENSE +21 -0
  19. skill_harness-0.2.1/PKG-INFO +240 -0
  20. skill_harness-0.2.1/README.md +199 -0
  21. skill_harness-0.2.1/SECURITY.md +85 -0
  22. skill_harness-0.2.1/assets/banner-dark.svg +15 -0
  23. skill_harness-0.2.1/assets/banner-light.svg +15 -0
  24. skill_harness-0.2.1/assets/social-preview.png +0 -0
  25. skill_harness-0.2.1/assets/social-preview.svg +27 -0
  26. skill_harness-0.2.1/docs/FAQ.md +48 -0
  27. skill_harness-0.2.1/docs/INVARIANTS.md +59 -0
  28. skill_harness-0.2.1/docs/PLAN.md +304 -0
  29. skill_harness-0.2.1/docs/PRD.md +986 -0
  30. skill_harness-0.2.1/docs/README.md +45 -0
  31. skill_harness-0.2.1/docs/RELEASE-NOTES-v0.1.md +272 -0
  32. skill_harness-0.2.1/docs/agents/domain.md +36 -0
  33. skill_harness-0.2.1/docs/agents/issue-tracker.md +45 -0
  34. skill_harness-0.2.1/docs/agents/triage-labels.md +15 -0
  35. skill_harness-0.2.1/docs/case-studies/ai-slop-sentinel-under-ablation.md +332 -0
  36. skill_harness-0.2.1/docs/case-studies/displaced-enforcement-skill-ablation-blind-spot.md +109 -0
  37. skill_harness-0.2.1/docs/case-studies/double-ceiling-structurally-unmeasured.md +127 -0
  38. skill_harness-0.2.1/docs/concepts/why-pythonutf8-on-windows.md +59 -0
  39. skill_harness-0.2.1/docs/concepts/why-unmeasured.md +106 -0
  40. skill_harness-0.2.1/docs/findings/v0.2-preregistration.md +391 -0
  41. skill_harness-0.2.1/docs/findings/v0.2-reaim-gate.md +75 -0
  42. skill_harness-0.2.1/docs/findings/why-naive-skill-benchmarks-mislead.md +103 -0
  43. skill_harness-0.2.1/docs/path-b-verified-2026-06-08.md +100 -0
  44. skill_harness-0.2.1/docs/supply-chain/inspect-audit-2026-07-09.md +40 -0
  45. skill_harness-0.2.1/docs/supply-chain/openai-audit-2026-06-08.md +301 -0
  46. skill_harness-0.2.1/examples/README.md +45 -0
  47. skill_harness-0.2.1/examples/reproduce-case-study.ps1 +100 -0
  48. skill_harness-0.2.1/examples/skills/ai-slop-sentinel-pointer.md +49 -0
  49. skill_harness-0.2.1/examples/skills/bayesian-eval-discipline-pointer.md +39 -0
  50. skill_harness-0.2.1/pyproject.toml +163 -0
  51. skill_harness-0.2.1/pyrightconfig.json +10 -0
  52. skill_harness-0.2.1/requirements-ci.txt +80 -0
  53. skill_harness-0.2.1/src/skill_harness/__init__.py +3 -0
  54. skill_harness-0.2.1/src/skill_harness/__main__.py +6 -0
  55. skill_harness-0.2.1/src/skill_harness/ablation/__init__.py +15 -0
  56. skill_harness-0.2.1/src/skill_harness/ablation/confound.py +362 -0
  57. skill_harness-0.2.1/src/skill_harness/ablation/operator.py +198 -0
  58. skill_harness-0.2.1/src/skill_harness/ablation/reconciler.py +138 -0
  59. skill_harness-0.2.1/src/skill_harness/ablation/render.py +252 -0
  60. skill_harness-0.2.1/src/skill_harness/ablation/runner.py +1534 -0
  61. skill_harness-0.2.1/src/skill_harness/ablation/sizing.py +183 -0
  62. skill_harness-0.2.1/src/skill_harness/ablation/stopping.py +274 -0
  63. skill_harness-0.2.1/src/skill_harness/ablation/subject.py +740 -0
  64. skill_harness-0.2.1/src/skill_harness/aggregation/__init__.py +44 -0
  65. skill_harness-0.2.1/src/skill_harness/aggregation/engine.py +767 -0
  66. skill_harness-0.2.1/src/skill_harness/aggregation/errors.py +88 -0
  67. skill_harness-0.2.1/src/skill_harness/aggregation/fit.py +349 -0
  68. skill_harness-0.2.1/src/skill_harness/aggregation/report.py +265 -0
  69. skill_harness-0.2.1/src/skill_harness/aggregation/status.py +205 -0
  70. skill_harness-0.2.1/src/skill_harness/aggregation/verdict.py +247 -0
  71. skill_harness-0.2.1/src/skill_harness/audit/__init__.py +117 -0
  72. skill_harness-0.2.1/src/skill_harness/cli/__init__.py +0 -0
  73. skill_harness-0.2.1/src/skill_harness/cli/diff_report.py +112 -0
  74. skill_harness-0.2.1/src/skill_harness/cli/main.py +2508 -0
  75. skill_harness-0.2.1/src/skill_harness/extractor/__init__.py +34 -0
  76. skill_harness-0.2.1/src/skill_harness/extractor/claude.py +320 -0
  77. skill_harness-0.2.1/src/skill_harness/extractor/errors.py +26 -0
  78. skill_harness-0.2.1/src/skill_harness/extractor/models.py +125 -0
  79. skill_harness-0.2.1/src/skill_harness/extractor/parser.py +103 -0
  80. skill_harness-0.2.1/src/skill_harness/extractor/pipeline.py +149 -0
  81. skill_harness-0.2.1/src/skill_harness/oracles/__init__.py +16 -0
  82. skill_harness-0.2.1/src/skill_harness/oracles/calibration/__init__.py +0 -0
  83. skill_harness-0.2.1/src/skill_harness/oracles/calibration/command.py +576 -0
  84. skill_harness-0.2.1/src/skill_harness/oracles/calibration/cost_projection.py +246 -0
  85. skill_harness-0.2.1/src/skill_harness/oracles/calibration/jsonl_parser.py +133 -0
  86. skill_harness-0.2.1/src/skill_harness/oracles/calibration/length_regression.py +133 -0
  87. skill_harness-0.2.1/src/skill_harness/oracles/errors.py +22 -0
  88. skill_harness-0.2.1/src/skill_harness/oracles/tier1/__init__.py +31 -0
  89. skill_harness-0.2.1/src/skill_harness/oracles/tier1/citation_presence_per_flag.py +211 -0
  90. skill_harness-0.2.1/src/skill_harness/oracles/tier1/compliance_proxy.py +114 -0
  91. skill_harness-0.2.1/src/skill_harness/oracles/tier1/fixtures/hedge_wordlist.json +61 -0
  92. skill_harness-0.2.1/src/skill_harness/oracles/tier1/hedge_index.py +114 -0
  93. skill_harness-0.2.1/src/skill_harness/oracles/tier1/structure_score.py +80 -0
  94. skill_harness-0.2.1/src/skill_harness/oracles/tier1/verbosity.py +85 -0
  95. skill_harness-0.2.1/src/skill_harness/oracles/tier2/__init__.py +1 -0
  96. skill_harness-0.2.1/src/skill_harness/oracles/tier2/injection_guard.py +51 -0
  97. skill_harness-0.2.1/src/skill_harness/oracles/tier2/judge.py +482 -0
  98. skill_harness-0.2.1/src/skill_harness/preflight.py +277 -0
  99. skill_harness-0.2.1/src/skill_harness/py.typed +0 -0
  100. skill_harness-0.2.1/src/skill_harness/storage/__init__.py +43 -0
  101. skill_harness-0.2.1/src/skill_harness/storage/context.py +61 -0
  102. skill_harness-0.2.1/src/skill_harness/storage/dual_write.py +183 -0
  103. skill_harness-0.2.1/src/skill_harness/storage/errors.py +47 -0
  104. skill_harness-0.2.1/src/skill_harness/storage/migrations.py +312 -0
  105. skill_harness-0.2.1/src/skill_harness/storage/migrations_sql/README.md +57 -0
  106. skill_harness-0.2.1/src/skill_harness/storage/migrations_sql/evidence/0001_initial.sql +221 -0
  107. skill_harness-0.2.1/src/skill_harness/storage/migrations_sql/evidence/0002_runs_trigger_split.sql +31 -0
  108. skill_harness-0.2.1/src/skill_harness/storage/migrations_sql/evidence/0003_admissible_verdicts_view.sql +35 -0
  109. skill_harness-0.2.1/src/skill_harness/storage/migrations_sql/evidence/0200_calibration_event_extensions.sql +34 -0
  110. skill_harness-0.2.1/src/skill_harness/storage/migrations_sql/evidence/0300_track_d_ablation.sql +63 -0
  111. skill_harness-0.2.1/src/skill_harness/storage/migrations_sql/evidence/0400_freeze_provenance.sql +40 -0
  112. skill_harness-0.2.1/src/skill_harness/storage/migrations_sql/evidence/0401_stale_frozen_view.sql +49 -0
  113. skill_harness-0.2.1/src/skill_harness/storage/migrations_sql/evidence/0500_subject_harness_pin.sql +19 -0
  114. skill_harness-0.2.1/src/skill_harness/storage/migrations_sql/evidence/0501_screen_store.sql +86 -0
  115. skill_harness-0.2.1/src/skill_harness/storage/migrations_sql/runtime/0001_initial.sql +77 -0
  116. skill_harness-0.2.1/src/skill_harness/storage/migrations_sql/runtime/0002_schema_migrations_triggers.sql +21 -0
  117. skill_harness-0.2.1/src/skill_harness/storage/models.py +709 -0
  118. skill_harness-0.2.1/src/skill_harness/storage/recovery.py +158 -0
  119. skill_harness-0.2.1/src/skill_harness/storage/repositories/__init__.py +6 -0
  120. skill_harness-0.2.1/src/skill_harness/storage/repositories/evidence/__init__.py +8 -0
  121. skill_harness-0.2.1/src/skill_harness/storage/repositories/evidence/calibration_events.py +138 -0
  122. skill_harness-0.2.1/src/skill_harness/storage/repositories/evidence/clauses.py +96 -0
  123. skill_harness-0.2.1/src/skill_harness/storage/repositories/evidence/confound_events.py +95 -0
  124. skill_harness-0.2.1/src/skill_harness/storage/repositories/evidence/frozen_cases.py +233 -0
  125. skill_harness-0.2.1/src/skill_harness/storage/repositories/evidence/judges.py +80 -0
  126. skill_harness-0.2.1/src/skill_harness/storage/repositories/evidence/metric_versions.py +88 -0
  127. skill_harness-0.2.1/src/skill_harness/storage/repositories/evidence/oracle_verdicts.py +82 -0
  128. skill_harness-0.2.1/src/skill_harness/storage/repositories/evidence/runs.py +104 -0
  129. skill_harness-0.2.1/src/skill_harness/storage/repositories/evidence/samples.py +110 -0
  130. skill_harness-0.2.1/src/skill_harness/storage/repositories/evidence/screens.py +152 -0
  131. skill_harness-0.2.1/src/skill_harness/storage/repositories/evidence/skills.py +86 -0
  132. skill_harness-0.2.1/src/skill_harness/storage/repositories/runtime/__init__.py +9 -0
  133. skill_harness-0.2.1/src/skill_harness/storage/repositories/runtime/cost_ledger.py +93 -0
  134. skill_harness-0.2.1/src/skill_harness/storage/repositories/runtime/current_calibration.py +130 -0
  135. skill_harness-0.2.1/src/skill_harness/storage/repositories/runtime/run_budget.py +131 -0
  136. skill_harness-0.2.1/src/skill_harness/storage/repositories/runtime/run_progress.py +86 -0
  137. skill_harness-0.2.1/src/skill_harness/storage/repositories/runtime/skill_imports_staging.py +88 -0
  138. skill_harness-0.2.1/src/skill_harness/storage/transaction.py +46 -0
  139. skill_harness-0.2.1/src/skill_harness/subject/__init__.py +21 -0
  140. skill_harness-0.2.1/src/skill_harness/subject/ingest.py +550 -0
  141. skill_harness-0.2.1/src/skill_harness/subject/inspect_adapter.py +408 -0
  142. skill_harness-0.2.1/src/skill_harness/subject/pin.py +184 -0
  143. skill_harness-0.2.1/src/skill_harness/subject/screen_backfill.py +185 -0
  144. skill_harness-0.2.1/src/skill_harness/subject/screen_ingest.py +208 -0
  145. skill_harness-0.2.1/tests/__init__.py +0 -0
  146. skill_harness-0.2.1/tests/ablation/__init__.py +0 -0
  147. skill_harness-0.2.1/tests/ablation/test_c5_resume_refuses_empty_user_message.py +234 -0
  148. skill_harness-0.2.1/tests/ablation/test_cli_d3_fixes.py +1314 -0
  149. skill_harness-0.2.1/tests/ablation/test_cli_run_ablation.py +490 -0
  150. skill_harness-0.2.1/tests/ablation/test_confound.py +576 -0
  151. skill_harness-0.2.1/tests/ablation/test_operator.py +203 -0
  152. skill_harness-0.2.1/tests/ablation/test_render.py +428 -0
  153. skill_harness-0.2.1/tests/ablation/test_runner.py +2355 -0
  154. skill_harness-0.2.1/tests/ablation/test_stopping.py +146 -0
  155. skill_harness-0.2.1/tests/ablation/test_subject_model_flag.py +392 -0
  156. skill_harness-0.2.1/tests/ablation/test_subject_openai.py +592 -0
  157. skill_harness-0.2.1/tests/conftest.py +58 -0
  158. skill_harness-0.2.1/tests/extractor/__init__.py +0 -0
  159. skill_harness-0.2.1/tests/extractor/fixtures/frontmatter_only.md +5 -0
  160. skill_harness-0.2.1/tests/extractor/fixtures/mostly_prose.md +26 -0
  161. skill_harness-0.2.1/tests/extractor/test_claude.py +313 -0
  162. skill_harness-0.2.1/tests/extractor/test_cli.py +354 -0
  163. skill_harness-0.2.1/tests/extractor/test_extractor_openrouter_fallback.py +284 -0
  164. skill_harness-0.2.1/tests/extractor/test_live.py +73 -0
  165. skill_harness-0.2.1/tests/extractor/test_models.py +187 -0
  166. skill_harness-0.2.1/tests/extractor/test_parser.py +153 -0
  167. skill_harness-0.2.1/tests/extractor/test_pipeline.py +290 -0
  168. skill_harness-0.2.1/tests/extractor/test_three_skills.py +204 -0
  169. skill_harness-0.2.1/tests/oracles/__init__.py +0 -0
  170. skill_harness-0.2.1/tests/oracles/calibration/__init__.py +0 -0
  171. skill_harness-0.2.1/tests/oracles/calibration/test_calibrate_cohen_kappa_observed_marginals.py +184 -0
  172. skill_harness-0.2.1/tests/oracles/calibration/test_calibrate_dry_run_default.py +281 -0
  173. skill_harness-0.2.1/tests/oracles/calibration/test_calibrate_judge_id_verification.py +132 -0
  174. skill_harness-0.2.1/tests/oracles/calibration/test_calibrate_max_usd_refuse.py +224 -0
  175. skill_harness-0.2.1/tests/oracles/calibration/test_calibrate_three_tier_state.py +208 -0
  176. skill_harness-0.2.1/tests/oracles/calibration/test_calibrate_writes_calibration_event.py +370 -0
  177. skill_harness-0.2.1/tests/oracles/calibration/test_cost_projection.py +400 -0
  178. skill_harness-0.2.1/tests/oracles/calibration/test_jsonl_parser.py +247 -0
  179. skill_harness-0.2.1/tests/oracles/calibration/test_length_regression_deterministic.py +313 -0
  180. skill_harness-0.2.1/tests/oracles/calibration/test_migration_0200.py +200 -0
  181. skill_harness-0.2.1/tests/oracles/tier1/__init__.py +0 -0
  182. skill_harness-0.2.1/tests/oracles/tier1/conftest.py +66 -0
  183. skill_harness-0.2.1/tests/oracles/tier1/test_citation_presence_per_flag.py +215 -0
  184. skill_harness-0.2.1/tests/oracles/tier1/test_compliance_proxy.py +119 -0
  185. skill_harness-0.2.1/tests/oracles/tier1/test_hedge_index.py +102 -0
  186. skill_harness-0.2.1/tests/oracles/tier1/test_meta_pytest_socket_fires.py +32 -0
  187. skill_harness-0.2.1/tests/oracles/tier1/test_structure_score.py +134 -0
  188. skill_harness-0.2.1/tests/oracles/tier1/test_verbosity.py +93 -0
  189. skill_harness-0.2.1/tests/oracles/tier2/__init__.py +0 -0
  190. skill_harness-0.2.1/tests/oracles/tier2/conftest.py +87 -0
  191. skill_harness-0.2.1/tests/oracles/tier2/fixtures/injection_negative.txt +38 -0
  192. skill_harness-0.2.1/tests/oracles/tier2/fixtures/injection_positive.txt +33 -0
  193. skill_harness-0.2.1/tests/oracles/tier2/test_injection_guard.py +126 -0
  194. skill_harness-0.2.1/tests/oracles/tier2/test_judge_response_malformed_inadmissible.py +173 -0
  195. skill_harness-0.2.1/tests/oracles/tier2/test_judge_response_shape.py +209 -0
  196. skill_harness-0.2.1/tests/oracles/tier2/test_position_swap_9cell.py +190 -0
  197. skill_harness-0.2.1/tests/property/__init__.py +0 -0
  198. skill_harness-0.2.1/tests/property/test_evidence_append_only.py +956 -0
  199. skill_harness-0.2.1/tests/storage/__init__.py +0 -0
  200. skill_harness-0.2.1/tests/storage/test_calibration_events_tiebreak_determinism.py +138 -0
  201. skill_harness-0.2.1/tests/test_ablation_report_verdict_id.py +277 -0
  202. skill_harness-0.2.1/tests/test_ablation_sizing.py +93 -0
  203. skill_harness-0.2.1/tests/test_admissibility_write_time_snapshot.py +298 -0
  204. skill_harness-0.2.1/tests/test_admissible_view.py +203 -0
  205. skill_harness-0.2.1/tests/test_aggregation_engine.py +1788 -0
  206. skill_harness-0.2.1/tests/test_aggregation_fit.py +793 -0
  207. skill_harness-0.2.1/tests/test_aggregation_report.py +458 -0
  208. skill_harness-0.2.1/tests/test_aggregation_status.py +487 -0
  209. skill_harness-0.2.1/tests/test_aggregation_verdict.py +136 -0
  210. skill_harness-0.2.1/tests/test_calibrate_cli.py +124 -0
  211. skill_harness-0.2.1/tests/test_cli_diff_skill.py +731 -0
  212. skill_harness-0.2.1/tests/test_cli_evaluate_skill.py +841 -0
  213. skill_harness-0.2.1/tests/test_cli_freeze.py +544 -0
  214. skill_harness-0.2.1/tests/test_cli_untrusted_text_sanitization.py +278 -0
  215. skill_harness-0.2.1/tests/test_concurrent_writers_serialize.py +123 -0
  216. skill_harness-0.2.1/tests/test_crash_recovery.py +234 -0
  217. skill_harness-0.2.1/tests/test_discover_rejects_duplicate_versions.py +58 -0
  218. skill_harness-0.2.1/tests/test_dual_write_partial.py +502 -0
  219. skill_harness-0.2.1/tests/test_evidence_repo_surface.py +115 -0
  220. skill_harness-0.2.1/tests/test_freeze_verdict_repo.py +326 -0
  221. skill_harness-0.2.1/tests/test_frozen_provenance_schema.py +280 -0
  222. skill_harness-0.2.1/tests/test_harness_version_fallback.py +31 -0
  223. skill_harness-0.2.1/tests/test_hypothesis_savepoint_isolation.py +119 -0
  224. skill_harness-0.2.1/tests/test_migration_0300.py +407 -0
  225. skill_harness-0.2.1/tests/test_models_validators.py +165 -0
  226. skill_harness-0.2.1/tests/test_pragmas.py +60 -0
  227. skill_harness-0.2.1/tests/test_repo_roundtrip.py +839 -0
  228. skill_harness-0.2.1/tests/test_screen_ingest.py +384 -0
  229. skill_harness-0.2.1/tests/test_skill_audit.py +181 -0
  230. skill_harness-0.2.1/tests/test_smoke.py +256 -0
  231. skill_harness-0.2.1/tests/test_stale_frozen_view.py +356 -0
  232. skill_harness-0.2.1/tests/test_storage_context.py +58 -0
  233. skill_harness-0.2.1/tests/test_storage_recovery.py +514 -0
  234. skill_harness-0.2.1/tests/test_structural_bans.py +221 -0
  235. skill_harness-0.2.1/tests/test_subject_ingest.py +356 -0
  236. skill_harness-0.2.1/tests/test_subject_layer.py +555 -0
  237. skill_harness-0.2.1/tests/test_transaction.py +113 -0
@@ -0,0 +1,24 @@
1
+ # https://editorconfig.org
2
+ root = true
3
+
4
+ [*]
5
+ charset = utf-8
6
+ end_of_line = lf
7
+ indent_style = space
8
+ indent_size = 4
9
+ insert_final_newline = true
10
+ trim_trailing_whitespace = true
11
+ max_line_length = 100
12
+
13
+ [*.{md,markdown}]
14
+ trim_trailing_whitespace = false
15
+ max_line_length = off
16
+
17
+ [*.{yml,yaml,json,toml}]
18
+ indent_size = 2
19
+
20
+ [*.{ps1,cmd,bat}]
21
+ end_of_line = crlf
22
+
23
+ [Makefile]
24
+ indent_style = tab
@@ -0,0 +1,12 @@
1
+ * text=auto eol=lf
2
+ *.py text eol=lf
3
+ *.md text eol=lf
4
+ *.sql text eol=lf
5
+ *.toml text eol=lf
6
+ *.yaml text eol=lf
7
+ *.yml text eol=lf
8
+ *.json text eol=lf
9
+ *.sh text eol=lf
10
+ *.ps1 text eol=crlf
11
+ *.cmd text eol=crlf
12
+ *.bat text eol=crlf
@@ -0,0 +1,16 @@
1
+ # Every change in this repo is reviewed by @MrBinnacle until a wider
2
+ # team forms. Sub-paths can list additional reviewers later without
3
+ # removing the global owner.
4
+
5
+ * @MrBinnacle
6
+
7
+ # Architectural artifacts — extra scrutiny zone. Any change to the
8
+ # load-bearing invariants should be discussed in an issue first.
9
+ /docs/PRD.md @MrBinnacle
10
+ /docs/PLAN.md @MrBinnacle
11
+ /src/skill_harness/storage/migrations_sql/ @MrBinnacle
12
+
13
+ # Storage / migrations gate — SCHEMA + SECURITY seat sign-off per A30 + dev-team-council
14
+ src/skill_harness/storage/migrations_sql/* @MrBinnacle
15
+ /.github/ @MrBinnacle
16
+ /SECURITY.md @MrBinnacle
@@ -0,0 +1,93 @@
1
+ name: Bug report
2
+ description: Report a reproducible defect in Skill Harness
3
+ title: "[bug] "
4
+ labels: ["bug", "needs-triage"]
5
+ body:
6
+ - type: markdown
7
+ attributes:
8
+ value: |
9
+ Thanks for taking the time to file a bug report. Skill Harness is pre-1.0 and moving fast, so some parts are still rough. Please confirm this is a defect (something behaves contrary to the PRD or its tests) and not a missing feature before filing.
10
+
11
+ - type: textarea
12
+ id: summary
13
+ attributes:
14
+ label: Summary
15
+ description: One or two sentences describing what's wrong.
16
+ validations:
17
+ required: true
18
+
19
+ - type: textarea
20
+ id: reproduce
21
+ attributes:
22
+ label: Steps to reproduce
23
+ description: Exact commands or code that produce the bug.
24
+ placeholder: |
25
+ 1. Create venv: `python -m venv .venv`
26
+ 2. Install: `pip install -e ".[dev]"`
27
+ 3. Run: `pytest -q tests/test_X.py::test_Y`
28
+ 4. Observe: ...
29
+ validations:
30
+ required: true
31
+
32
+ - type: textarea
33
+ id: expected
34
+ attributes:
35
+ label: Expected behavior
36
+ description: What should happen instead? Link the docs/PRD.md section if relevant.
37
+ validations:
38
+ required: true
39
+
40
+ - type: textarea
41
+ id: actual
42
+ attributes:
43
+ label: Actual behavior
44
+ description: What actually happens. Include exact error messages and tracebacks.
45
+ render: shell
46
+ validations:
47
+ required: true
48
+
49
+ - type: input
50
+ id: version
51
+ attributes:
52
+ label: skill-harness version
53
+ placeholder: "0.2.0 (or commit SHA)"
54
+ validations:
55
+ required: true
56
+
57
+ - type: input
58
+ id: python
59
+ attributes:
60
+ label: Python version
61
+ placeholder: "3.13.1"
62
+ validations:
63
+ required: true
64
+
65
+ - type: dropdown
66
+ id: os
67
+ attributes:
68
+ label: Operating system
69
+ options:
70
+ - Linux
71
+ - Windows
72
+ - macOS
73
+ - Other (specify in extra context)
74
+ validations:
75
+ required: true
76
+
77
+ - type: textarea
78
+ id: extra
79
+ attributes:
80
+ label: Extra context
81
+ description: Logs, config, anything else relevant. Redact any API keys.
82
+
83
+ - type: checkboxes
84
+ id: checks
85
+ attributes:
86
+ label: Pre-flight
87
+ options:
88
+ - label: I have searched existing issues and confirmed this is not a duplicate
89
+ required: true
90
+ - label: I have read CONTRIBUTING.md
91
+ required: true
92
+ - label: This report contains no secrets (API keys, tokens, credentials)
93
+ required: true
@@ -0,0 +1,9 @@
1
+ blank_issues_enabled: false
2
+
3
+ contact_links:
4
+ - name: Security vulnerability
5
+ url: https://github.com/MrBinnacle/skill-harness/security/advisories/new
6
+ about: Report a vulnerability privately. Do NOT open a public issue for security defects.
7
+ - name: Architecture discussion
8
+ url: https://github.com/MrBinnacle/skill-harness/discussions
9
+ about: For architectural questions, alternative designs, or anything that touches the load-bearing invariants in docs/INVARIANTS.md, open a discussion before an issue.
@@ -0,0 +1,62 @@
1
+ name: Feature request
2
+ description: Suggest new functionality
3
+ title: "[feat] "
4
+ labels: ["enhancement", "needs-triage"]
5
+ body:
6
+ - type: markdown
7
+ attributes:
8
+ value: |
9
+ Before filing, please skim `docs/PRD.md` § 18 (CLI surface), `docs/PLAN.md` (build tracks), and the "Out of scope for v0.1" section of `docs/PLAN.md`. Many "missing features" are explicitly deferred to v0.2 or beyond — those don't need new issues.
10
+
11
+ - type: textarea
12
+ id: problem
13
+ attributes:
14
+ label: Problem
15
+ description: What can't you do today? Who is the user?
16
+ validations:
17
+ required: true
18
+
19
+ - type: textarea
20
+ id: proposal
21
+ attributes:
22
+ label: Proposed solution
23
+ description: Sketch the design. Be concrete enough for someone else to estimate.
24
+ validations:
25
+ required: true
26
+
27
+ - type: textarea
28
+ id: alternatives
29
+ attributes:
30
+ label: Alternatives considered
31
+ description: What else did you weigh, and why does this proposal win?
32
+
33
+ - type: dropdown
34
+ id: scope
35
+ attributes:
36
+ label: Scope
37
+ options:
38
+ - Inside PRD v1.0 scope (clarification / refinement)
39
+ - Inside docs/PLAN.md track scope (build work)
40
+ - Explicitly deferred past v0.1 (docs/PLAN.md “Out of scope”)
41
+ - Outside current scope (extension proposal)
42
+ validations:
43
+ required: true
44
+
45
+ - type: textarea
46
+ id: prior-art
47
+ attributes:
48
+ label: Prior art
49
+ description: |
50
+ For statistical / eval-design proposals, cite the literature.
51
+ For SQLite / Python tooling, link the relevant docs.
52
+ New defaults without citations are unlikely to be accepted.
53
+
54
+ - type: checkboxes
55
+ id: checks
56
+ attributes:
57
+ label: Pre-flight
58
+ options:
59
+ - label: I have read docs/PRD.md and docs/PLAN.md
60
+ required: true
61
+ - label: This is not already covered by an existing docs/PLAN.md track
62
+ required: true
@@ -0,0 +1,52 @@
1
+ <!--
2
+ Thanks for the PR.
3
+
4
+ Before you submit, please confirm:
5
+
6
+ - [ ] You read `CONTRIBUTING.md` and `docs/INVARIANTS.md`
7
+ - [ ] `ruff check src tests` is clean
8
+ - [ ] `ruff format --check src tests` is clean
9
+ - [ ] `mypy src tests` is clean
10
+ - [ ] `pytest -q` is green
11
+ - [ ] New tests cover the new behavior (TDD discipline — see CONTRIBUTING.md)
12
+
13
+ If this PR touches PRD §-tagged invariants, link the relevant
14
+ docs/PRD.md section.
15
+ -->
16
+
17
+ ## Summary
18
+
19
+ <!-- 1–3 sentences. What changed and why. -->
20
+
21
+ ## Track / scope
22
+
23
+ <!-- Which build track does this land in? A=storage, B=extractor, C=oracle,
24
+ D=runner, E=aggregation, CLI=cli, DOCS=docs, CI=ci, OTHER=specify. -->
25
+
26
+ - [ ] A — Storage
27
+ - [ ] B — Extractor
28
+ - [ ] C — Oracle library
29
+ - [ ] D — Ablation runner
30
+ - [ ] E — Aggregation + CLI
31
+ - [ ] DOCS / CI / OTHER (specify):
32
+
33
+ ## Invariant / decision reference
34
+
35
+ <!-- If this PR realizes or modifies a locked invariant (docs/PRD.md) or a
36
+ published finding (docs/findings/), name it. Otherwise: N/A. -->
37
+
38
+ ## Test plan
39
+
40
+ - [ ] Unit tests added/updated
41
+ - [ ] Integration tests added (where applicable)
42
+ - [ ] `pytest -q` green locally
43
+ - [ ] Manual verification (describe):
44
+
45
+ ## Breaking change?
46
+
47
+ - [ ] No
48
+ - [ ] Yes (describe migration path in body below)
49
+
50
+ ## Notes for the reviewer
51
+
52
+ <!-- Edge cases, alternative designs considered, follow-up work. -->
@@ -0,0 +1,60 @@
1
+ version: 2
2
+
3
+ updates:
4
+ # Python dependencies (pyproject.toml)
5
+ - package-ecosystem: pip
6
+ directory: "/"
7
+ schedule:
8
+ interval: weekly
9
+ day: monday
10
+ time: "06:00"
11
+ timezone: "UTC"
12
+ open-pull-requests-limit: 5
13
+ labels:
14
+ - dependencies
15
+ - python
16
+ commit-message:
17
+ prefix: "chore(deps)"
18
+ include: scope
19
+ groups:
20
+ anthropic-stack:
21
+ patterns:
22
+ - "anthropic"
23
+ - "httpx"
24
+ - "httpcore"
25
+ - "anyio"
26
+ - "h11"
27
+ pydantic-stack:
28
+ patterns:
29
+ - "pydantic"
30
+ - "pydantic-core"
31
+ - "annotated-types"
32
+ - "typing-extensions"
33
+ dev-tooling:
34
+ dependency-type: development
35
+ patterns:
36
+ - "pytest*"
37
+ - "ruff"
38
+ - "mypy"
39
+ - "mypy_extensions"
40
+ - "hypothesis"
41
+ - "coverage"
42
+
43
+ # GitHub Actions
44
+ - package-ecosystem: github-actions
45
+ directory: "/"
46
+ schedule:
47
+ interval: weekly
48
+ day: monday
49
+ time: "06:00"
50
+ timezone: "UTC"
51
+ open-pull-requests-limit: 3
52
+ labels:
53
+ - dependencies
54
+ - github-actions
55
+ commit-message:
56
+ prefix: "ci(deps)"
57
+ include: scope
58
+ groups:
59
+ actions:
60
+ patterns: ["*"]
@@ -0,0 +1,134 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+ workflow_dispatch:
9
+
10
+ concurrency:
11
+ group: ci-${{ github.workflow }}-${{ github.ref }}
12
+ cancel-in-progress: true
13
+
14
+ permissions:
15
+ contents: read
16
+
17
+ jobs:
18
+ lint:
19
+ name: Lint + format
20
+ runs-on: ubuntu-latest
21
+ timeout-minutes: 5
22
+ steps:
23
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
24
+ - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
25
+ with:
26
+ python-version: "3.13"
27
+ cache: pip
28
+ cache-dependency-path: |
29
+ pyproject.toml
30
+ requirements-ci.txt
31
+ - name: Install
32
+ run: |
33
+ python -m pip install --upgrade pip
34
+ python -m pip install -c requirements-ci.txt -e ".[dev]"
35
+ - name: ruff check
36
+ run: ruff check src tests
37
+ - name: ruff format --check
38
+ run: ruff format --check src tests
39
+
40
+ typecheck:
41
+ name: mypy --strict
42
+ runs-on: ubuntu-latest
43
+ timeout-minutes: 5
44
+ steps:
45
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
46
+ - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
47
+ with:
48
+ python-version: "3.13"
49
+ cache: pip
50
+ cache-dependency-path: |
51
+ pyproject.toml
52
+ requirements-ci.txt
53
+ - name: Install
54
+ run: |
55
+ python -m pip install --upgrade pip
56
+ python -m pip install -c requirements-ci.txt -e ".[dev]"
57
+ - name: mypy
58
+ # Full strict scope (src + tests) restored 2026-07-10 — repo issue #2
59
+ # burn-down; the tests/ override relaxation of 2026-07-09 is removed.
60
+ run: mypy --strict src/ tests/
61
+
62
+ test:
63
+ name: Test (${{ matrix.os }} · py${{ matrix.python-version }})
64
+ runs-on: ${{ matrix.os }}
65
+ timeout-minutes: 10
66
+ # PYTHONHASHSEED=0 required by tests/oracles/tier1 autouse fixture for
67
+ # A33 mechanical-validity bit-equality discipline.
68
+ env:
69
+ PYTHONHASHSEED: "0"
70
+ strategy:
71
+ fail-fast: false
72
+ matrix:
73
+ os: [ubuntu-latest, windows-latest]
74
+ python-version: ["3.12", "3.13"]
75
+ steps:
76
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
77
+ - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
78
+ with:
79
+ python-version: ${{ matrix.python-version }}
80
+ cache: pip
81
+ cache-dependency-path: |
82
+ pyproject.toml
83
+ requirements-ci.txt
84
+ - name: Install
85
+ run: |
86
+ python -m pip install --upgrade pip
87
+ python -m pip install -c requirements-ci.txt -e ".[dev]"
88
+ - name: pytest
89
+ # `-m "not live"` mirrors local gate; live tests require ANTHROPIC_API_KEY
90
+ # (not provisioned in CI). Live test surface = tests/extractor/test_live.py.
91
+ run: pytest -q -m "not live" --cov=src/skill_harness --cov-report=term-missing
92
+ - name: Upload coverage
93
+ if: matrix.os == 'ubuntu-latest' && matrix.python-version == '3.13'
94
+ uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
95
+ with:
96
+ name: coverage-report
97
+ path: .coverage
98
+ if-no-files-found: ignore
99
+
100
+ structural-bans:
101
+ name: Structural bans (raw sqlite3.connect / oracle_verdicts / timestamp ORDER BY)
102
+ runs-on: ubuntu-latest
103
+ timeout-minutes: 5
104
+ steps:
105
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
106
+ - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
107
+ with:
108
+ python-version: "3.13"
109
+ # S5: pinned — see depersonalization-gate.yml's identical step for the
110
+ # rationale (any future release runs immediately in this job otherwise).
111
+ - run: python -m pip install pre-commit==4.6.0
112
+ - name: sqlite3.connect() ban (A23 Sec.3 PRAGMA/FK discipline, PRD.md #17a)
113
+ run: pre-commit run ban-raw-sqlite-connect --all-files
114
+ - name: oracle_verdicts raw-access allowlist (A29, PRD.md #17)
115
+ run: pre-commit run ban-raw-oracle-verdicts --all-files
116
+ - name: timestamp-final ORDER BY ban (deterministic tie-break on append-only tables)
117
+ run: pre-commit run ban-timestamp-final-order-by --all-files
118
+
119
+ all-green:
120
+ name: All checks green
121
+ needs: [lint, typecheck, test, structural-bans]
122
+ runs-on: ubuntu-latest
123
+ if: always()
124
+ steps:
125
+ - name: Verify all dependent jobs succeeded
126
+ run: |
127
+ if [[ "${{ needs.lint.result }}" != "success" ]] || \
128
+ [[ "${{ needs.typecheck.result }}" != "success" ]] || \
129
+ [[ "${{ needs.test.result }}" != "success" ]] || \
130
+ [[ "${{ needs.structural-bans.result }}" != "success" ]]; then
131
+ echo "One or more required checks failed."
132
+ exit 1
133
+ fi
134
+ echo "All checks passed."
@@ -0,0 +1,51 @@
1
+ # De-personalization gate — CI enforcement at the public boundary.
2
+ #
3
+ # The local pre-commit hooks (.pre-commit-config.yaml) only protect a clone where
4
+ # `pre-commit install` has been run; git hooks are not version-controlled, so a fresh
5
+ # clone is dormant. This workflow re-runs the residue check on every push/PR to main —
6
+ # committed, always enforced, independent of anyone's local setup. Belt to the local
7
+ # hooks' suspenders.
8
+ #
9
+ # It runs ONLY the residue-* hooks (language: pygrep, zero external deps) so it stays
10
+ # fast and does not duplicate the heavier ruff/mypy work that ci.yml covers
11
+ # (gitleaks runs as a local pre-commit hook only, not in CI).
12
+ # The .pre-commit-config.yaml is the single source of truth for the patterns.
13
+ name: de-personalization gate
14
+
15
+ on:
16
+ push:
17
+ branches: [main]
18
+ pull_request:
19
+
20
+ permissions:
21
+ contents: read
22
+
23
+ jobs:
24
+ residue-check:
25
+ runs-on: ubuntu-latest
26
+ timeout-minutes: 5
27
+ steps:
28
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
29
+ - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
30
+ with:
31
+ python-version: "3.13"
32
+ # S5: pinned (was a floating install — any future pre-commit release
33
+ # would execute in this job on the next run, and this job IS the
34
+ # residue-gate security control; a compromised release could silently
35
+ # neuter it). NOTE: this inline `pip install` is NOT covered by
36
+ # Dependabot's pip ecosystem (it only parses manifest files, not
37
+ # workflow run: steps) — bumping this pin is a manual PR, same as any
38
+ # other CI-only tool version. (pre-commit's OWN transitive deps —
39
+ # cfgv/identify/nodeenv/pyyaml/virtualenv — are still unpinned here;
40
+ # this closes the top-level "any new release runs immediately" gap,
41
+ # not the full transitive supply chain.)
42
+ - run: python -m pip install pre-commit==4.6.0
43
+ - name: Residue sweep (private-provenance identifiers in *.md)
44
+ run: |
45
+ rc=0
46
+ for hook in residue-writ residue-sec-id residue-wi-id \
47
+ residue-research-dir residue-private-repo-dir \
48
+ residue-private-repo-link; do
49
+ pre-commit run "$hook" --all-files || rc=1
50
+ done
51
+ exit $rc
@@ -0,0 +1,35 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+
7
+ jobs:
8
+ build:
9
+ runs-on: ubuntu-latest
10
+ steps:
11
+ - uses: actions/checkout@v4
12
+ - uses: actions/setup-python@v5
13
+ with:
14
+ python-version: "3.12"
15
+ - run: python -m pip install build
16
+ - run: python -m build
17
+ - uses: actions/upload-artifact@v4
18
+ with:
19
+ name: dist
20
+ path: dist/
21
+
22
+ publish:
23
+ needs: build
24
+ runs-on: ubuntu-latest
25
+ environment: pypi
26
+ permissions:
27
+ id-token: write # OIDC trusted publishing — no API token
28
+ steps:
29
+ - uses: actions/download-artifact@v4
30
+ with:
31
+ name: dist
32
+ path: dist/
33
+ # SHA-pinned pypi-publish v1.14.1 — paste the full SHA from the
34
+ # Marketplace snippet's `uses:` line (starts ba38b8e...)
35
+ - uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,70 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ *.so
6
+ .Python
7
+ build/
8
+ dist/
9
+ *.egg-info/
10
+ *.egg
11
+ .eggs/
12
+
13
+ # Virtual envs
14
+ .venv/
15
+ uv.lock
16
+ venv/
17
+ env/
18
+ ENV/
19
+
20
+ # Test / type / lint caches
21
+ .pytest_cache/
22
+ .mypy_cache/
23
+ .ruff_cache/
24
+ .cache/
25
+ .coverage
26
+ .coverage.*
27
+ htmlcov/
28
+ coverage.xml
29
+ *.cover
30
+
31
+ # SQLite
32
+ *.db
33
+ *.db-wal
34
+ *.db-shm
35
+ *.sqlite
36
+ *.sqlite3
37
+
38
+ # IDE
39
+ .vscode/
40
+ .idea/
41
+ *.swp
42
+ *.swo
43
+
44
+ # OS
45
+ .DS_Store
46
+ Thumbs.db
47
+
48
+ # Claude state (kept locally, not committed)
49
+ .claude/state/
50
+ .claude/cache/
51
+ .claude/worktrees/
52
+
53
+ # Logs
54
+ *.log
55
+ logs/
56
+
57
+ # Local config / secrets
58
+ .env
59
+ .env.*
60
+ !.env.example
61
+ # Internal scan reports (local-only)
62
+ .supply-chain-risk-auditor/
63
+
64
+ # Claire tool worktree remnants (stale, local-only)
65
+ .claire/
66
+
67
+ # Internal process records + agent config (removed from public HEAD 2026-07-08)
68
+ .private/
69
+ .claude/
70
+ /CLAUDE.md