v0.3.0 — YAML crusher, categorical drop summaries
Three features, all live-validated against a real Kubernetes triage agent (forge + gpt-5.4 / claude-sonnet-4-6).
YAML / describe crusher
New crush.YAMLCrusher + detect.YAMLLike content type: kubectl get -o yaml, kubectl describe, and config dumps now compress structurally instead of falling through to the log rule. Dependency-free indentation-tree parsing (tolerant of describe's near-YAML), deepest-first subtree folding — inner bulky blocks (env lists, managedFields, tolerations) fold before parents; a parent's residue only folds if still bulky — plus long-scalar-value folding (last-applied-configuration style). Each fold gets its own marker, so the model expands exactly the subtree it needs. The fidelity floor applies per subtree: a crashing container's section carries error vocabulary and survives whole, with zero k8s-specific knowledge.
Measured live: kubectl describe pod 75% (was 12–20% under the log rule), kubectl get -o yaml 49%.
Categorical drop summaries
Markers and sentinels now say what was dropped, not just how much:
- JSON records:
<<ctxzip:HASH 142_records_offloaded>> [offloaded: 96 Running, 31 Succeeded, 15 other]— grouped by status-like fields (status/phase/reason/…, one nested probe deep). - Text/log lines:
[offloaded: 67 running ago), 21 running]— top line-signature groups.
The model can answer count/distribution questions from the marker alone instead of expanding, and knows when expansion is warranted.
crush.IsErrorLike export
The error-vocabulary floor is now callable by hosts, so integration layers (like forge's keep_patterns learning loop) can exclude floor-kept terms from pattern suggestions instead of duplicating the vocabulary.
Compatibility
No breaking API changes. Marker format, store contract, and deterministic-compression guarantees unchanged — prompt-cache prefix stability verified live (cache_creation: 0 re-writes across a 4-call anthropic invocation).