You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Implementation plan for tracegrad v0.1.0, per design spec v0.2 (post-review). Python >= 3.11, managed with uv. Runtime deps: httpx, pydantic v2. Dev: pytest.
Design invariants (non-negotiable)
Determinism boundary: exactly two modules import llm — attribute and synthesize. Enforced by a lint test, not convention.
Analysis never writes the prompt.apply is the only writing command.
Evidence is mechanical: every quote substring-verified in code against the persisted distilled store, with a declared source field. Violations require an output quote.
Cross-batch trends are advisory — CIs and detectable-effect floors displayed, no automatic reverts.
aggregate.py: instruction table keyed by lineage, unified theme space (exact slug then single-link Jaccard >= 0.6 in sorted order), rates as {numerator, denominator} over the whole batch, gap ledger (graduation needs >= 2 distinct runs or sessions; retirement only on improved trend or explicit human resolve; restore on revert)
Stage 3 — Edit engine and gates (pure, tested before any model)
edits.py: normalization N() (NFKC, whitespace collapse, quote/dash folding) with offset map, span resolution by instruction_id + checksum, overlap rejection, right-to-left application, ADD anchor semantics (sibling after full span, indentation inherited, START/append sentinels), orphan-anchor rejection
gates.py: G1 edit cap; G2 accounting by re-diff; G3 REWRITE->ADD reclassification via clause-level diff (new imperative clause without token-overlap counterpart); G4 source-checked quotes + negation-window flag; G5 template-measured budget, zero-sum at ceiling; G6 rejection/revert memory with distinct-session bar; G7 variable spans untouchable; G8 duplicate-ADD rejection. Per-edit drop with named reason — never run-level abort
Stage 4 — Model layer and attribution
llm.py: backend registry with complete(system, user, *, cacheable_prefix=None, schema=None). openai: params only when set, capability-flagged reasoning/effort with retry-without fallback, OpenRouter HTTP-200 error body check, Retry-After honored, 900s synthesis timeout without retry-on-timeout, shared client, jobs-way concurrency. claude: isolated preset (--allowed-tools "", --strict-mcp-config --mcp-config '{}', empty --settings, system prompt passed properly, is_error checked). Generic harness presets + inline command. Defaults: attribution -> openai, synthesis -> claude, per-tier availability resolution
attribute.py: per-trace call at temperature 0 where supported, canonical theme vocabulary fed forward, full instrument-versioned cache key, minCoverage abort, blinded-attribution health sample with reported agreement rate
trends.py: two-proportion z-tests, CI on the difference, verdicts improved/regressed/eliminated/no-signal with minEffect, same-instrument re-attribution of affected clusters, all-cluster guardrails, two-consecutive-regressed hysteresis, convergence state, detectable-effect floors for status
cli.py: run (with --estimate), attribute, propose, trends, apply, status, init
Stage 6 — Tests and release
Unit: segmenter golden fixtures, N() and span ordering, every gate individually, ledger graduation/retirement/restore across simulated runs, trend math vs hand-computed values, denominator correctness
One to two weeks of careful work. The gates, edit engine, trend statistics, and state hardening are the modules that punish haste — they are also the product.
Implementation plan for tracegrad v0.1.0, per design spec v0.2 (post-review). Python >= 3.11, managed with uv. Runtime deps:
httpx,pydanticv2. Dev:pytest.Design invariants (non-negotiable)
llm—attributeandsynthesize. Enforced by a lint test, not convention.applyis the only writing command.outputquote.Build order
Stage 1 — Contracts and state
schema.py: Manifest (template file, engine, vars, sampling, judge fingerprint), Trace (prompt_hashrequired), AttributionResult (theme_slugon violations/harmful,quote_source), Edit (instruction_id-addressed,covers_theme,watch_metric), Report (applied_prompt_hash, cluster{theme, numerator, denominator}), StepVerdictconfig.py: rc loading,neverDeletepatterns,minEffect,minCoverage,convergenceRuns, harness presetsstate.py:.tracegrad/layout,O_EXCLlock, atomic writes (tmp + fsync +os.replace), append-only JSONL ledgers, per-run resume state,.gitignorewritten byinitStage 2 — Deterministic core (no model, golden fixtures)
ingest.py: validation, prompt-hash partitioning (dominant partition only), judge fingerprint check, judge canary comparison,meta.modelpartitioning, rationale-quality floordistill.py: template render (declared engine), reduction, redaction with stable placeholders, content-addresseddistilled/store,distill_config_hashinventory.py: versioned segmenter (bullets/numbered items/sentences, abbreviation-safe), content fingerprint + stablelineage_id, duplicate-text ordinals,origin: variablespans marked non-editableaggregate.py: instruction table keyed by lineage, unified theme space (exact slug then single-link Jaccard >= 0.6 in sorted order), rates as{numerator, denominator}over the whole batch, gap ledger (graduation needs >= 2 distinct runs or sessions; retirement only on improved trend or explicit human resolve; restore on revert)Stage 3 — Edit engine and gates (pure, tested before any model)
edits.py: normalization N() (NFKC, whitespace collapse, quote/dash folding) with offset map, span resolution by instruction_id + checksum, overlap rejection, right-to-left application, ADD anchor semantics (sibling after full span, indentation inherited, START/append sentinels), orphan-anchor rejectiongates.py: G1 edit cap; G2 accounting by re-diff; G3 REWRITE->ADD reclassification via clause-level diff (new imperative clause without token-overlap counterpart); G4 source-checked quotes + negation-window flag; G5 template-measured budget, zero-sum at ceiling; G6 rejection/revert memory with distinct-session bar; G7 variable spans untouchable; G8 duplicate-ADD rejection. Per-edit drop with named reason — never run-level abortStage 4 — Model layer and attribution
llm.py: backend registry withcomplete(system, user, *, cacheable_prefix=None, schema=None).openai: params only when set, capability-flagged reasoning/effort with retry-without fallback, OpenRouter HTTP-200errorbody check,Retry-Afterhonored, 900s synthesis timeout without retry-on-timeout, shared client,jobs-way concurrency.claude: isolated preset (--allowed-tools "",--strict-mcp-config --mcp-config '{}', empty--settings, system prompt passed properly,is_errorchecked). Generic harness presets + inlinecommand. Defaults: attribution -> openai, synthesis -> claude, per-tier availability resolutionattribute.py: per-trace call at temperature 0 where supported, canonical theme vocabulary fed forward, full instrument-versioned cache key,minCoverageabort, blinded-attribution health sample with reported agreement rateStage 5 — Synthesis, trends, apply, CLI
synthesize.py: thin — prompt assembly, per-edit re-prompt loop (max 2), "no edits warranted" path, failed-proposal autopsy dumptrends.py: two-proportion z-tests, CI on the difference, verdicts improved/regressed/eliminated/no-signal withminEffect, same-instrument re-attribution of affected clusters, all-cluster guardrails, two-consecutive-regressed hysteresis, convergence state, detectable-effect floors forstatusapply.py: review cards (diff, evidence + sources, flags), write-back ofapplied_prompt_hash+ accepted list, base-hash re-check, pre-write snapshot + revert, out-of-band-edit staleness markingcli.py:run(with--estimate),attribute,propose,trends,apply,status,initStage 6 — Tests and release
FakeBackend: fixture batch -> report -> partial acceptance -> resume-after-kill -> byte-exact applied promptclaude -pround-trip pinning JSON shape andis_errorexample/with a synthetic batch + manifest; README quickstart verified against itExplicitly deferred (post-v0.1.0)
prompt_hashalready carries arm assignment, so no schema change neededjinja-basictemplate engine (v0.1.0 shipsnone+format)Estimate
One to two weeks of careful work. The gates, edit engine, trend statistics, and state hardening are the modules that punish haste — they are also the product.