mirror of
https://github.com/Heretek-AI/heretek-claude-harness.git
synced 2026-10-12 02:03:47 +00:00
feat(trim): R5 spike purges + build artifact cleanup
- Delete 4 spike scripts (counterfactual_diffs, rlm_fast_gate,
staleness_metric, svok_provenance) — results retained in
docs/superpowers/spikes/*-results.md
- Delete 3 dead vision tests that imported the deleted spike scripts
(test_staleness_metric, test_counterfactual_diffs, test_svok_provenance)
- Delete PLAN.md (subsumed by docs/superpowers/roadmap.md)
- Delete plugins/hooks/{commands,hooks,scripts}/.gitkeep (dirs non-empty)
Verified:
- pytest: 458 pass (was 464; 6 spike tests removed)
- python scripts/validate.py: clean
- python scripts/generate_marketplace.py: clean (no drift)
build artifacts (coverage.xml, .coverage, reports/) were already gitignored
or untracked. Cleaned __pycache__/ (already gitignored).
PR1 of 5 in 2026-08-10-heretek-harness-trim spec.
Co-Authored-By: Claude <[email protected]>
This commit is contained in:
@@ -1,36 +0,0 @@
|
||||
# Heretek Marketplace — Plan
|
||||
|
||||
> One-page TL;DR. Full roadmap at `docs/superpowers/roadmap.md`. Design spec at `docs/superpowers/specs/2026-08-08-roadmap-restructure-design.md`.
|
||||
|
||||
## Status
|
||||
|
||||
v1.0.0 shipped 2026-08-05 (CHANGELOG). v1.x frozen.
|
||||
|
||||
## Active phases
|
||||
|
||||
| Phase | Scope | Tracking |
|
||||
|---|---|---|
|
||||
| v2 | Hooks + security | #89 |
|
||||
| v3 | MCP/ACI | #90 |
|
||||
| v3.5 | Observability (in flight) | #109-#124 + new tracking issue |
|
||||
| v4 | Workflow + eval | #91 |
|
||||
| v5 | BYOK + local | new tracking issue |
|
||||
| v6 | Meta-harness + ACP | new tracking issue |
|
||||
|
||||
## Common commands
|
||||
|
||||
```bash
|
||||
pytest -q
|
||||
python scripts/validate.py
|
||||
python scripts/generate_marketplace.py
|
||||
git diff --exit-code .claude-plugin/marketplace.json
|
||||
```
|
||||
|
||||
## See also
|
||||
|
||||
- `docs/superpowers/roadmap.md` — phased roadmap
|
||||
- `docs/superpowers/specs/` — design specs
|
||||
- `docs/superpowers/plans/` — implementation plans
|
||||
- `catalog/` — source of truth for plugin catalog
|
||||
- `CONTRIBUTING.md` — contribution guide
|
||||
- `SECURITY.md` — security reporting
|
||||
@@ -1,80 +0,0 @@
|
||||
"""Counterfactual diffs spike (#47) — prototype.
|
||||
|
||||
Given a unified diff touching dep pins, emits a side-by-side annotation
|
||||
showing "what would change if you bumped to latest stable."
|
||||
|
||||
This is research code. Production integration is a follow-up issue if
|
||||
the prototype proves out.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
from datetime import datetime, timezone
|
||||
from pathlib import Path
|
||||
|
||||
import yaml
|
||||
|
||||
CACHE_DIR = Path(__file__).resolve().parent.parent / "catalog" / "freshness"
|
||||
# Match `name==X.Y.Z` etc.
|
||||
PIN_RE = re.compile(r"^([+-])([a-zA-Z0-9_.+-]+)\s*([=<>~!]=)\s*(\d[^,;\s]*)", re.MULTILINE)
|
||||
|
||||
|
||||
def _latest_for(lib: str) -> str | None:
|
||||
cache_file = CACHE_DIR / f"{lib.lower().replace('.', '-')}.yaml"
|
||||
if not cache_file.exists():
|
||||
return None
|
||||
try:
|
||||
data = yaml.safe_load(cache_file.read_text())
|
||||
except yaml.YAMLError:
|
||||
return None
|
||||
return data.get("latest_version")
|
||||
|
||||
|
||||
def annotate_diff(diff: str) -> str:
|
||||
"""Annotate a diff with counterfactual "bump to latest" hints."""
|
||||
today = datetime.now(timezone.utc).date().isoformat()
|
||||
trailing_newline = "\n" if diff.endswith("\n") else ""
|
||||
annotated_lines = []
|
||||
|
||||
for line in diff.splitlines():
|
||||
match = PIN_RE.match(line)
|
||||
if not match:
|
||||
annotated_lines.append(line)
|
||||
continue
|
||||
|
||||
sign, name, _op, version = match.groups()
|
||||
latest = _latest_for(name)
|
||||
|
||||
if not latest or latest == version:
|
||||
annotated_lines.append(line)
|
||||
continue
|
||||
|
||||
annotated_lines.append(line)
|
||||
if sign == "-":
|
||||
annotated_lines.append(
|
||||
f"+# counterfactual: {name}=={latest} is also stable as of {today} "
|
||||
f"({_major_minor_diff(version, latest)} behind)"
|
||||
)
|
||||
|
||||
return "\n".join(annotated_lines) + trailing_newline
|
||||
|
||||
|
||||
def _major_minor_diff(pinned: str, latest: str) -> str:
|
||||
"""Render 'N minor' or 'N major' diff between pinned and latest."""
|
||||
try:
|
||||
p = tuple(int(x) for x in pinned.split(".")[:2])
|
||||
l = tuple(int(x) for x in latest.split(".")[:2])
|
||||
except ValueError:
|
||||
return "version diff"
|
||||
if len(p) < 2 or len(l) < 2:
|
||||
return "version diff"
|
||||
if p[0] != l[0]:
|
||||
return f"{l[0] - p[0]} major"
|
||||
return f"{l[1] - p[1]} minor"
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import sys
|
||||
|
||||
print(annotate_diff(sys.stdin.read()))
|
||||
@@ -1,56 +0,0 @@
|
||||
"""RLM fast-gate spike (#42) — minimal REPL + recursive LM scaffold.
|
||||
|
||||
This is research code, not production. Per the spike protocol, it runs on
|
||||
a 50-edit corpus and measures precision/recall/latency vs #43 AST-grep.
|
||||
|
||||
The scaffold:
|
||||
1. Receives an Edit payload (file_path + new_string) via stdin (JSON)
|
||||
2. Spawns a Python REPL pre-loaded with the edit content as a variable
|
||||
3. Calls a base LM to recursively inspect the edit (find deprecated APIs)
|
||||
4. Returns a verdict: "deprecated" | "clean"
|
||||
|
||||
Per the spike protocol, this is opt-in via env var ENABLE_RLM_SPIKE=1.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
|
||||
|
||||
def main() -> int: # nosonar — false positive: hook-script entrypoint always returns 0
|
||||
if os.environ.get("ENABLE_RLM_SPIKE") != "1":
|
||||
return 0
|
||||
|
||||
try:
|
||||
payload = json.loads(sys.stdin.read())
|
||||
except json.JSONDecodeError:
|
||||
return 0
|
||||
|
||||
tool_input = payload.get("tool_input", {})
|
||||
_file_path = tool_input.get("file_path", "")
|
||||
_new_string = tool_input.get("new_string", "")
|
||||
|
||||
start = time.time()
|
||||
# Minimal REPL: just print the edit content + a stub verdict for the spike.
|
||||
# Real recursive-LM logic lives in a follow-up commit; this is the scaffolding.
|
||||
verdict = "clean"
|
||||
latency_ms = (time.time() - start) * 1000
|
||||
|
||||
print(
|
||||
json.dumps(
|
||||
{
|
||||
"hookSpecificOutput": {
|
||||
"hookEventName": "PostToolUse",
|
||||
"additionalContext": f"rlm-spike: verdict={verdict} latency={latency_ms:.0f}ms (stub)",
|
||||
}
|
||||
}
|
||||
)
|
||||
)
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
@@ -1,110 +0,0 @@
|
||||
"""Cumulative codebase-staleness metric spike (#49) — prototype.
|
||||
|
||||
Walks git history, computes per-commit staleness score based on
|
||||
dep-pin-vs-latest-version distance.
|
||||
|
||||
This is research code. Production integration is a follow-up issue if
|
||||
the prototype proves out.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
import yaml
|
||||
|
||||
CACHE_DIR = Path(__file__).resolve().parent.parent / "catalog" / "freshness"
|
||||
PIN_RE = re.compile(r"^\s*([a-zA-Z0-9_.+-]+)\s*([=<>~!]=)\s*(\d[^,;\s]*)", re.MULTILINE)
|
||||
|
||||
|
||||
def _latest_for(lib: str) -> str | None:
|
||||
cache_file = CACHE_DIR / f"{lib.lower().replace('.', '-')}.yaml"
|
||||
if not cache_file.exists():
|
||||
return None
|
||||
try:
|
||||
return yaml.safe_load(cache_file.read_text()).get("latest_version")
|
||||
except yaml.YAMLError:
|
||||
return None
|
||||
|
||||
|
||||
def _version_distance(pinned: str, latest: str) -> int:
|
||||
"""Compute approximate major+minor distance between pinned and latest."""
|
||||
try:
|
||||
p = tuple(int(x) for x in pinned.split(".")[:2])
|
||||
l = tuple(int(x) for x in latest.split(".")[:2])
|
||||
except ValueError:
|
||||
return 0
|
||||
if len(p) < 2 or len(l) < 2:
|
||||
return 0
|
||||
return max(0, (l[0] - p[0]) * 100 + (l[1] - p[1]))
|
||||
|
||||
|
||||
def score_for_pins(pins: dict[str, str]) -> float:
|
||||
"""Compute staleness score for a dict of {lib: pinned_version}.
|
||||
|
||||
Returns a sum of distance scores. Lower is fresher.
|
||||
"""
|
||||
total = 0.0
|
||||
for lib, pinned in pins.items():
|
||||
latest = _latest_for(lib)
|
||||
if not latest:
|
||||
continue
|
||||
total += _version_distance(pinned, latest)
|
||||
return total
|
||||
|
||||
|
||||
def parse_pins_from_diff(diff_text: str) -> dict[str, str]:
|
||||
"""Extract dep pins from a unified diff (added lines only)."""
|
||||
pins = {}
|
||||
for match in PIN_RE.finditer(diff_text):
|
||||
# Only consider added lines (+ prefix)
|
||||
# Find the line's leading char
|
||||
start = match.start()
|
||||
# The line starts at the previous \n (or 0)
|
||||
line_start = diff_text.rfind("\n", 0, start) + 1
|
||||
if line_start < start and diff_text[line_start] == "+":
|
||||
lib, _, version = match.group(1), match.group(2), match.group(3)
|
||||
pins[lib] = version
|
||||
return pins
|
||||
|
||||
|
||||
def compute_history_scores(repo_dir: str = ".") -> list[tuple[str, float]]:
|
||||
"""Walk git history, return list of (commit_sha, staleness_score)."""
|
||||
result = subprocess.run(
|
||||
["git", "log", "--pretty=format:%H", "--", "requirements.txt", "pyproject.toml"],
|
||||
cwd=repo_dir,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=60,
|
||||
)
|
||||
if result.returncode != 0:
|
||||
return []
|
||||
|
||||
scores = []
|
||||
for sha in result.stdout.strip().splitlines():
|
||||
diff_result = subprocess.run(
|
||||
["git", "show", sha, "--", "requirements.txt", "pyproject.toml"],
|
||||
cwd=repo_dir,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=30,
|
||||
)
|
||||
if diff_result.returncode != 0:
|
||||
continue
|
||||
pins = parse_pins_from_diff(diff_result.stdout)
|
||||
scores.append((sha, score_for_pins(pins)))
|
||||
|
||||
return scores
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import csv
|
||||
import sys
|
||||
|
||||
scores = compute_history_scores()
|
||||
writer = csv.writer(sys.stdout)
|
||||
writer.writerow(["commit_sha", "staleness_score"])
|
||||
for sha, score in scores:
|
||||
writer.writerow([sha, score])
|
||||
@@ -1,99 +0,0 @@
|
||||
"""SVoK / provenance comments spike (#48) — prototype.
|
||||
|
||||
Given a code snippet, identifies external-API usages and emits provenance
|
||||
comments naming the doc-version consulted (from the freshness cache).
|
||||
|
||||
This is research code. Production integration is a follow-up issue if
|
||||
the prototype proves out.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
from datetime import datetime, timezone
|
||||
from pathlib import Path
|
||||
|
||||
import yaml
|
||||
|
||||
CACHE_DIR = Path(__file__).resolve().parent.parent / "catalog" / "freshness"
|
||||
# Match `import X` / `from X import Y` for top-level imports
|
||||
IMPORT_RE = re.compile(r"^(?:from|import)\s+([a-zA-Z_][a-zA-Z0-9_.]*)", re.MULTILINE)
|
||||
# Python import name -> catalog/freshness name aliases (catalog files are
|
||||
# spelled by package name on PyPI, not by import name).
|
||||
_PACKAGE_ALIASES: dict[str, str] = {
|
||||
"yaml": "pyyaml",
|
||||
"ruamel": "ruamel-yaml",
|
||||
}
|
||||
|
||||
|
||||
def _doc_version_for(lib: str) -> str | None:
|
||||
cache_file = CACHE_DIR / f"{lib.lower().replace('.', '-')}.yaml"
|
||||
if not cache_file.exists():
|
||||
return None
|
||||
try:
|
||||
data = yaml.safe_load(cache_file.read_text())
|
||||
except yaml.YAMLError:
|
||||
return None
|
||||
return data.get("latest_version")
|
||||
|
||||
|
||||
def _stdlib_libs() -> set[str]:
|
||||
"""Approximation — Python stdlib modules (limited set; production would be complete)."""
|
||||
return {
|
||||
"os",
|
||||
"sys",
|
||||
"json",
|
||||
"re",
|
||||
"pathlib",
|
||||
"collections",
|
||||
"typing",
|
||||
"datetime",
|
||||
"time",
|
||||
"itertools",
|
||||
"functools",
|
||||
"subprocess",
|
||||
"math",
|
||||
"random",
|
||||
"hashlib",
|
||||
"logging",
|
||||
"unittest",
|
||||
"io",
|
||||
}
|
||||
|
||||
|
||||
def emit_provenance_comments(code: str) -> str:
|
||||
"""Emit provenance comments naming doc-version for external APIs used."""
|
||||
imports = set()
|
||||
for match in IMPORT_RE.finditer(code):
|
||||
imports.add(match.group(1).split(".")[0])
|
||||
|
||||
external = imports - _stdlib_libs()
|
||||
today = datetime.now(timezone.utc).date().isoformat()
|
||||
provenance_lines = []
|
||||
|
||||
for lib in sorted(external):
|
||||
catalog_name = _PACKAGE_ALIASES.get(lib, lib)
|
||||
version = _doc_version_for(catalog_name)
|
||||
if version:
|
||||
provenance_lines.append(
|
||||
f"# generated against {catalog_name} docs v{version} (fetched {today})"
|
||||
)
|
||||
|
||||
if not provenance_lines:
|
||||
return code
|
||||
|
||||
# Insert provenance block after the first import line (or at top if no imports)
|
||||
lines = code.splitlines()
|
||||
insert_idx = 0
|
||||
for i, line in enumerate(lines):
|
||||
if line.startswith(("import ", "from ")):
|
||||
insert_idx = i + 1
|
||||
break
|
||||
|
||||
return "\n".join(lines[:insert_idx] + [""] + provenance_lines + [""] + lines[insert_idx:])
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import sys
|
||||
|
||||
print(emit_provenance_comments(sys.stdin.read()))
|
||||
@@ -1,26 +0,0 @@
|
||||
"""Tests for counterfactual_diffs_spike.py (#47)."""
|
||||
|
||||
import pytest
|
||||
from pathlib import Path
|
||||
|
||||
from scripts.counterfactual_diffs_spike import annotate_diff
|
||||
|
||||
|
||||
def test_annotate_diff_flags_stale_pin():
|
||||
"""#47: diff pinning requests==2.34.0 produces annotation when 2.35+ exists."""
|
||||
diff = "-requests==2.34.0\n"
|
||||
if not (Path("catalog/freshness") / "requests.yaml").exists():
|
||||
pytest.skip("populate catalog/freshness/requests.yaml first")
|
||||
|
||||
annotated = annotate_diff(diff)
|
||||
# Annotation should mention a newer version exists
|
||||
assert (
|
||||
"latest stable" in annotated.lower() or "counterfactual" in annotated.lower()
|
||||
), f"expected counterfactual annotation, got: {annotated}"
|
||||
|
||||
|
||||
def test_annotate_diff_passes_through_unrelated_changes():
|
||||
"""#47: diff that doesn't touch deps is passed through unchanged."""
|
||||
diff = "+# new comment\n+def foo(): pass\n"
|
||||
annotated = annotate_diff(diff)
|
||||
assert annotated == diff, "non-dep diff should be passed through unchanged"
|
||||
@@ -1,26 +0,0 @@
|
||||
"""Tests for staleness_metric_spike.py (#49)."""
|
||||
|
||||
import pytest
|
||||
from pathlib import Path
|
||||
|
||||
from scripts.staleness_metric_spike import score_for_pins
|
||||
|
||||
|
||||
def test_score_for_pins_with_fresh_pins_is_low():
|
||||
"""#49: fresh pins score near 0."""
|
||||
if not list(Path("catalog/freshness").glob("*.yaml")):
|
||||
pytest.skip("populate catalog/freshness/ first")
|
||||
|
||||
pins = {"requests": "2.34.0"} # assume latest is 2.34+
|
||||
score = score_for_pins(pins)
|
||||
assert score < 1.0, f"fresh pin should score low, got {score}"
|
||||
|
||||
|
||||
def test_score_for_pins_with_stale_pins_is_high():
|
||||
"""#49: stale pins score higher than fresh pins."""
|
||||
if not list(Path("catalog/freshness").glob("*.yaml")):
|
||||
pytest.skip("populate catalog/freshness/ first")
|
||||
|
||||
fresh = score_for_pins({"requests": "2.34.0"})
|
||||
stale = score_for_pins({"requests": "2.20.0"}) # 14 minor behind
|
||||
assert stale > fresh, f"stale pin should score higher than fresh: {stale} vs {fresh}"
|
||||
@@ -1,25 +0,0 @@
|
||||
"""Tests for svok_provenance_spike.py (#48)."""
|
||||
|
||||
import pytest
|
||||
from pathlib import Path
|
||||
|
||||
from scripts.svok_provenance_spike import emit_provenance_comments
|
||||
|
||||
|
||||
def test_emit_provenance_for_yaml_safe_load():
|
||||
"""#48: code using yaml.safe_load gets provenance comment for pyyaml."""
|
||||
code = "import yaml\ndata = yaml.safe_load(f)\n"
|
||||
if not (Path("catalog/freshness") / "pyyaml.yaml").exists():
|
||||
pytest.skip("populate catalog/freshness/pyyaml.yaml first")
|
||||
|
||||
annotated = emit_provenance_comments(code)
|
||||
assert "pyyaml" in annotated
|
||||
assert "generated against" in annotated or "docs v" in annotated.lower()
|
||||
|
||||
|
||||
def test_emit_provenance_unchanged_for_pure_stdlib():
|
||||
"""#48: code with no external API gets passed through (no provenance comments)."""
|
||||
code = "x = [1, 2, 3]\nprint(sum(x))\n"
|
||||
annotated = emit_provenance_comments(code)
|
||||
# Either identical, or only minor formatting
|
||||
assert annotated == code or "generated against" not in annotated
|
||||
Reference in New Issue
Block a user