Skip to content

Commit 9db5fee

Browse files
docs: update CHANGELOG and README for 0.10.0 — semantic freshness
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 3d198c2 commit 9db5fee

2 files changed

Lines changed: 91 additions & 1 deletion

File tree

CHANGELOG.md

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,34 @@
22

33
All notable changes to `attune-help` are documented here.
44

5-
## 0.9.1 — 2026-04-30
5+
## 0.10.0 — 2026-04-30
66

77
### Added
88

9+
- **Phase 1 semantic freshness**`attune_help.freshness` package with
10+
`SymbolExtractor` and `SymbolRecord`. Extracts normalized public-symbol
11+
signatures from Python source using `ast`; stable across docstring edits,
12+
body rewrites, and formatter passes, but changes on parameter, return-type,
13+
decorator, or base-class edits.
14+
15+
- **`compute_semantic_hash`** in `attune_help.staleness` (also exported from
16+
`attune_help`). For pure-Python features, hashes the aggregated
17+
`signature_hash` values of every public symbol rather than raw file bytes.
18+
Result: docstring-only edits and `black`/`ruff` formatter passes no longer
19+
trigger spurious template regeneration. Non-Python files and features with
20+
mixed content fall back to the existing byte-SHA path transparently.
21+
`SyntaxError` in a `.py` file also falls back gracefully.
22+
23+
- **`compute_source_hash` is now semantic-aware** — the function signature
24+
is unchanged; pure-Python features automatically use semantic hashing from
25+
this release. No frontmatter format changes; existing templates regenerate
26+
exactly once on the next maintenance pass and then stabilize.
27+
28+
- **`scripts/validate_against_corpus.py`** — 3-sweep dev harness (parse
29+
integrity, determinism, HEAD vs HEAD^ drift classification). Validated
30+
clean against the attune-ai corpus: 323 `.py` files across 24 features,
31+
zero parse errors, 24/24 deterministic, zero signature drifts.
32+
933
- **`aliases` frontmatter** on three templates so the alias-weighted RAG
1034
retriever surfaces them on synonym queries:
1135
- `concepts/tool-refactor-plan.md` — aliases: technical debt, code cleanup
@@ -16,6 +40,14 @@ All notable changes to `attune-help` are documented here.
1640

1741
- `.gitignore` now excludes `.pypirc` to prevent credential leaks.
1842

43+
### Known limitations
44+
45+
- Pure re-export shim modules (files that only contain `from pkg import …`
46+
with no function or class definitions) produce zero symbols. Features whose
47+
`files:` list points exclusively to shims will hash as if empty. Mitigation:
48+
list the upstream implementation file alongside the shim in `features.yaml`.
49+
Full per-symbol frontmatter (Option B) is deferred pending telemetry.
50+
1951
---
2052

2153
## 0.9.0 — 2026-04-24

README.md

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,64 @@ class RedisStorage(SessionStorage):
223223
def save(self, user_id: str, state: dict) -> None: ...
224224
```
225225

226+
## Staleness Detection
227+
228+
`attune-help` tracks whether your help templates are up to date with
229+
your source code using SHA-256 hashes stored in template frontmatter.
230+
231+
### Basic usage
232+
233+
```python
234+
from attune_help import load_manifest, check_staleness
235+
236+
manifest = load_manifest(".help")
237+
report = check_staleness(manifest, help_dir=".help", project_root=".")
238+
239+
for entry in report.stale_features:
240+
print(f"{entry} is stale — regenerate with attune-ai")
241+
```
242+
243+
### Semantic hashing (v0.10+)
244+
245+
For pure-Python features, `compute_source_hash` automatically uses
246+
**semantic hashing**: only public-symbol *contracts* (parameters, return
247+
types, decorators, base classes) contribute to the hash. Docstring
248+
edits, body rewrites, and formatter passes (`black`, `ruff`) are
249+
ignored. This eliminates spurious template regenerations when nothing
250+
meaningful changed.
251+
252+
```python
253+
from attune_help import compute_source_hash, compute_semantic_hash
254+
from attune_help.manifest import Feature
255+
256+
feat = Feature(name="auth", description="", files=["src/auth/**"])
257+
258+
# compute_source_hash uses semantic hashing automatically for .py-only features
259+
hash1, files = compute_source_hash(feat, project_root=".")
260+
261+
# Call compute_semantic_hash directly when you need the semantic hash
262+
# regardless of file mix (e.g. for reporting)
263+
hash2, files = compute_semantic_hash(feat, project_root=".")
264+
```
265+
266+
Mixed-content features (Python + Jinja, YAML, etc.) and features with
267+
syntax errors in their source files fall back to byte-level SHA
268+
automatically — no configuration required.
269+
270+
### Corpus validation
271+
272+
A 3-sweep validation harness ships in `scripts/validate_against_corpus.py`:
273+
274+
```bash
275+
# Validate against any repo with a .help/features.yaml
276+
python scripts/validate_against_corpus.py --repo /path/to/your/repo
277+
```
278+
279+
Sweeps: (1) parse integrity — all `.py` files parse cleanly; (2)
280+
determinism — identical hashes on two consecutive calls; (3) HEAD vs
281+
HEAD^ — classifies symbol changes as signature drift / body-only /
282+
add / remove.
283+
226284
## License
227285

228286
Apache 2.0

0 commit comments

Comments
 (0)