Tags: infinri/Writ
Tags
Skip the host-settings assertion when ~/.claude/settings.json is absent The test asserts a stale Bash permission was removed from the HOST's installed global config; CI runners never had one. Its two guarded siblings (pol5b4 global-settings check, the installed-systemd-unit check) already skip this way; this was the only bare host-state read left in the suite.
v1.5.0: Unify bible ingestion under writ import-markdown
writ import-markdown becomes the single canonical entry point for ingesting
every node type under bible/ (Rule + Skill + Playbook + AntiPattern + Phase +
Technique + Rationalization + SubagentRole + WorkedExample + ForbiddenResponse).
Pre-1.5.0 the CLI handled only Rule nodes; methodology required shelling out
to scripts/migrate.py --methodology-dir. The duplicate parse/validate/write
loop collapses into one library module that both call sites consume
(DRY-DUP-002). Per-node-type dispatch becomes a registry lookup (SOLID-OCP-002),
and validation failures surface as typed IngestError instead of raw Pydantic
tracebacks (API-ERROR-002).
Added:
- writ/graph/methodology_ingest.py library (ingest_path, ingest_edges,
INGESTER_REGISTRY, KNOWN_NODE_TYPES, IngestReport, IngestError)
- --only TYPE[,...] and --dry-run flags on writ import-markdown
- tests/_writ_cmd.py shared CLI resolver (.venv/bin/writ -> python -m
writ.cli fallback) consumed by every test that subprocess-invokes the CLI
- tests/test_import_markdown_unified.py (27 tests, 7 classes)
- tests/test_methodology_ingest.py (14 unit tests)
Changed:
- writ/cli.py import_markdown rewritten as a thin Typer wrapper over the
library. writ migrate now in-process; exit-code contract preserved.
- scripts/migrate.py reduced from 257 lines to a ~71-line shim that
preserves --bible-dir / --methodology-dir / --dry-run argparse surface
and re-exports run_migration + run_methodology_migration for the
test_phase6bcd_verification import contract.
- tests/conftest.py::pytest_sessionfinish, tests/test_retrieval.py,
tests/test_post_suite_neo4j_restoration.py, tests/test_graph_proximity.py,
tests/test_embeddings.py shell out to writ import-markdown bible/ (was:
scripts/migrate.py --methodology-dir bible/methodology).
- tests/test_ingest.py::TestMigrationIntegration uses MERGE-aware unique
rule_id count (the 286-vs-276 disparity was 10 enforcement-rule IDs that
legitimately live in both bible/<topic>/rules.md and
bible/methodology/<topic>/rules.md).
- .github/actions/setup-writ/action.yml + .github/workflows/pr.yml call
writ import-markdown bible/. CI gains methodology coverage.
- README.md, bible/methodology/PBK-AUTHOR-001.md,
docs/extraction/{04,08,09}-*.md, benchmarks/bench_targets.py,
scripts/instrument-cold-start.py, .claude/CODEBASE.md, templates/CLAUDE.md
-- migrate.py user-facing references repointed at writ import-markdown.
- Version 1.3.0 -> 1.5.0 across pyproject.toml, .claude-plugin/plugin.json,
.claude-plugin/marketplace.json (both metadata.version and
plugins[0].version). tests/test_version_consistency.py EXPECTED_VERSION
bumped accordingly.
- CHANGELOG.md prepends a [1.5.0] entry that documents both the absorption
work (commit 0882dd6) and this commit's unify work as a single release.
Fixed:
- writ import-markdown no longer auto-exports the full graph when invoked
against a subdirectory. Pre-fix, running writ import-markdown
bible/methodology/ triggered an auto-export whose file-location lookup
only scanned within the subdir; rules whose original files lived outside
scope fell through to <output_dir>/<domain>/rules.md, creating bogus
duplicates like bible/methodology/process/rules.md. Auto-export is now
gated on path.resolve() == DEFAULT_BIBLE_DIR.resolve(). Regression tests
in tests/test_import_markdown_unified.py::TestImportMarkdownEdgeCases
cover the subdir-skip and default-root-still-fires cases.
Notes:
- Backwards compat: python scripts/migrate.py [--bible-dir ...]
[--methodology-dir ...] [--dry-run] and from scripts.migrate import
run_migration continue to work unchanged. The shim prints a deprecation
notice to stderr on direct invocation but does not change exit codes.
- Intentional behavior change: writ import-markdown with no flags now
imports methodology too. Pre-1.5.0 invocations relying on the Rule-only
side effect should add --only Rule to preserve the old scope.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
v1.3.0: per-turn test pipeline + log_friction_event quoting fix
Per-turn test-execution: PostToolUse mark + Stop-hook runner batch the
turn's writes, resolve source -> test via a config-driven path matcher
(generic conventions + Magento layout by default; project override via
.claude/writ.json), invoke pytest / go test / phpunit grouped by runner,
and surface real failures via the existing emit-summary helper. Silent on
pass, terse on fail, per-runner friction telemetry.
Path knowledge is no longer hardcoded in the bash hooks: a new
bin/lib/test_paths.py helper owns match-src / match-test / resolve-test /
runner-for, consumed by both new hooks plus available for any future hook.
Behind that surface this release also repairs a long-standing JSON-quoting
bug in log_friction_event (the ${4:-{}} default-value form was appending a
stray } to every JSON extras argument, breaking json.loads for every
caller that passed extras -- around twenty hooks). Quoting the default
literal {} repairs the parse without touching any caller; friction-log
entries now carry their full payload as designed.
Also fixed: a set -e interaction in the run hook's run_group that aborted
the script when phpunit returned non-zero (warnings-only runs treated as
hook failures); the PHPUnit warning-vs-failure conflation in the summarizer
(numbered warning lists were counted as failures); and a heredoc quoting
bug in validate-test-file.sh that emitted an IndexError traceback on every
internal plan.md update Claude makes.
Magento PHPUnit invocation now passes --cache-directory=/tmp/writ-phpunit-cache
--do-not-cache-result so the result-cache permission warning is suppressed
on default-permission Magento checkouts. Allure extension warning is
documented as environmental and not interpreted as a failure.
71 tests pass (6 version-consistency + 65 new). cache/ added to .gitignore.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
v1.1.0 - Real-corpus benchmark + Item 1-6 corrections Headline changes (see commit log 6f66e09..faa0a20 for full detail): - Item 1c/1d: ENF-SYS-003 cron-job race-condition relabel; SOLID-DIP-002 trigger edit (Q81) - Item 2: live-vs-synthetic latency gap diagnosed across four hypotheses - Item 3: domain hit-rate enforced at top-5 on real corpus - Item 4: HNSW cache check before encoding; cold-start O(N) -> O(1) warm - Item 5: compression ratio measured on real corpus; non-monotonicity documented - Item 6: user-facing version refs aligned to v1.1.0 - Docs: HANDBOOK + PROMOTIONAL-BRIEF + extraction docs updated with v1.1.0 benchmarks - Tooling: per-stage cold-start instrumentation script (evidence source for Item 4)
v1.0.1: Plugin distribution Writ is now installable as a Claude Code plugin via: claude plugin marketplace add infinri/Writ claude plugin install writ@writ Published to PyPI as claude-writ. The standalone install at ~/.claude/skills/writ/ is byte-identical to v1.0.0 and continues to work. See CHANGELOG.md for the full set of changes.
Writ v1.0.0 -- First production release (2026-05-10)
A Claude Code harness with two co-equal layers:
* Knowledge layer: a hybrid-RAG service running a five-stage retrieval
pipeline (domain filter, BM25 via Tantivy, ANN via hnswlib over ONNX
all-MiniLM-L6-v2 embeddings, graph traversal via pre-computed
adjacency cache, two-pass weighted ranking) over a Neo4j-backed
knowledge graph. 0.590 ms p95 end-to-end at 276 rules.
* Enforcement layer: a session-aware state machine plus 30 hook scripts
wired into Claude Code. Four-mode workflow (Conversation, Debug,
Review, Work) with two Work-mode gates (plan-approval and
test-skeletons). Approval requires a one-time token; agent
self-approval is structurally blocked.
The 220-rule public out-of-the-box rulebook (Security, Clean Code, DRY,
SOLID, Architecture, Testing, Error Handling, Performance & Caching,
Scaling, API Design, Process & Lifecycle, Documentation) is seeded into
the live corpus alongside Writ-specific rules, bringing the live count
to 276 rules / 30 mandatory. 19 of the mandatory rules are backed by
six cross-language regex analyzers in bin/run-analysis.sh.
See CHANGELOG.md for the full release notes.
Verification at release: 1441 tests pass, 15 skipped, 0 failed; live
service reports 276/30/warm; MRR@5 = 0.4886 against the 19-query
ambiguous evaluation set (floor 0.45); hit rate = 0.7636 against the
165-query ground-truth corpus (floor 0.75).
License: MIT. Authored by Lucio Saldivar.