Skip to content

Release 0.4.0 — query graph, evidence packets, durable runtime - #4

Merged
DevAnimecx merged 224 commits into
mainfrom
release/0.4.0
Oct 22, 2026
Merged

DevAnimecx merged 224 commits into
mainfrom
release/0.4.0

Conversation

@DevAnimecx

Copy link
Copy Markdown
Owner

Summary

Version 0.4.0. Query graph, evidence packets, a durable runtime, and the performance work that makes them viable.

  • Query graph (POST /v1/graph/search, jiro graph plan|run) — the planner builds a DAG of SEARCH / FETCH / MERGE / EXTRACT / VERIFY / COMPRESS / SYNTHESIZE nodes; dispatch is ready-driven, so a node starts when its own parents finish rather than when its topological level drains.
  • Adaptive budgets — timeouts derive from a rolling per-engine p50/p95 window. --deadline-ms 0 (the new default) means "derive it".
  • Engine racing + hedging — a slow request is duplicated on an alternate engine, first success wins, and preference order decides among successes so a faster substitute cannot silently replace the requested engine.
  • MCP session_handoff — the structured brief from docs/v0.4.0/MASTER_PLAN.md §5.2, as the 22nd tool.
  • Evidence packets — results compress to claims that each carry their supporting source spans.

Performance — all four claims backed by committed artifacts

Reproduce with python benchmarks/report.py.

Claim Target Measured Status
speed-2x 2.0 81.6x PASS
efficiency-3x 3.0 59.2x PASS, caveated
citation-complete 1.0 1.0 PASS
setup-15 15 15/15 PASS

The efficiency ratio is published with its quality gate stated as pending, per docs/v0.4.0/CLAIMS.md §3 — the 30 LLM-judge runs and 50 blind human spot checks have not run, so it is a tokens-per-citation measurement, not a claim of equivalent answer quality. The registry carries the caveat and benchmarks/report.py refuses to publish it without one.

The speed ratio varies with live-search latency (as low as 2.0x across runs), so the artifact records a declared cold-cache state rather than a favourable sample.

Defects fixed

  • jiro/scraping/client.py referenced _time, never imported — every search raised NameError and /search returned HTTP 500.
  • npm/package.json had been missing its closing brace since it was first added; every revision in history fails to parse.
  • Pagination returned fewer results than requested (num=9 returned 6).
  • runtime.lease_ttl_seconds shipped at 30s against a 3600s attempt timeout, so every process warned about its own defaults.

Test plan

  • Full suite: 1529 passed, 9 skipped, 1 failed
  • The one failure is tests/test_phase2.py::test_recipe_api, verified failing identically on a clean tree — pre-existing and network-dependent
  • Flagship gate: jiro graph run "what is the capital of France" --fetch-top 2 returns 20 cited claims, 8 sources, 0 gaps, 20/20 claims carrying a source
  • All four benchmark artifacts present and above target

Caveat on this branch

The commit history on this branch was rewritten into 222 small commits at the maintainer's request. The 9 original, explanatory commits are preserved at tag pre-222-backup. The final tree is byte-identical either way (be269cc). If you would rather review the 9 meaningful commits, use that tag.

🤖 Generated with Claude Code

DevAnimecx and others added 29 commits October 22, 2026 20:56
All three SDKs now expose the 0.4.0 query graph:

- Python: plan_search() and search_graph(), matching the plan/search split
- JavaScript: planSearch() and searchGraph(), plus GraphOptions and
  GraphRunResponse in the .d.ts so the evidence packet is typed
- Go: PlanSearch() and GraphSearch() with a GraphOptions struct

The Go SDK did not compile before this change. ErrorResponse declared a field
named Error, which shadowed its own Error() method, so "field and method with
the same name Error" failed the build at the declaration and again at the five
call sites that constructed it. The field is renamed to Message; it still
marshals as "error". go build and go vet are now clean.

README rewritten for search and answer-engine visibility: it leads with what
JIRO is in one sentence, documents the 0.4.0 query graph with a real response
body, states the traceability guarantees as a table, and adds an FAQ covering
the questions the page previously left implied. MCP tools corrected from 16 to
the actual 22.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
`from selectolax.parser import HTMLParser` now raises ImportError, because
selectolax 1.0 dropped the modest backend. The import sits at module scope in
scraping/client.py and the parsers, so this did not degrade anything -- it made
`import jiro` fail outright on a fresh install, including for anyone installing
0.4.0 from PyPI. All 16 call sites now use selectolax.lexbor, aliased back to
the old names so no call site changed shape.

Also fixed, found while getting CI green:

- tests/test_phase2.py::test_recipe_api scrapes https://example.com for real but
  carried no `network` marker, so CI's `-m "not network"` never excluded it. It
  failed on the runner and would keep failing. Now marked.
- tests/test_runtime_persistence.py used owner values "key_a"/"key_b", which
  gitleaks read as a generic-api-key. Renamed to acct_a/acct_b rather than
  allowlisting the file, so real secrets committed there later are still caught.
- The POST retry path computed retry_deadline from the documented
  scraping.retry_budget_seconds setting and never read it, so the sequence was
  unbounded in practice -- the exact hang the comment above it claims to
  prevent. The GET path already enforced the deadline; POST now does too.
- Dropped two dead locals (an unused `import time as _time`, an unread
  `max_requests`) and an unused pytest import. `ruff check jiro/` is clean.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
@DevAnimecx
DevAnimecx merged commit 9787f6c into main Oct 22, 2026
1 of 2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant