Skip to content

v0.12.0 — retry policy, stale-while-revalidate, scoped find, safe writes

Latest

Choose a tag to compare

@renezander030 renezander030 released this 05 Sep 05:29
· 2 commits to main since this release
v0.12.0
2b8e562
  • One retry policy for every adapter's HTTP path. A 429, a gateway 5xx, a 500 whose body names a query or rate limit (TickTick's exceed_query_limit), a 403 carrying Retry-After or an exhausted rate-limit window (GitHub), and dropped connections are retried with jittered exponential backoff that honors Retry-After and x-ratelimit-reset. TickTick, Notion, GitHub, Airtable and Google ride the same @reneza/ats-core/retry; a plain 4xx returns on the first attempt. Knobs: ATS_HTTP_RETRIES (3; 0 disables), ATS_HTTP_RETRY_BASE_MS, ATS_HTTP_RETRY_MAX_MS.
  • Stale-while-revalidate corpus cache. Past the 5-minute TTL, find answers immediately from the stale copy — the result says corpus.stale: true, revalidating: true — while a detached ats cache sync refreshes the cache for the next call. One refresh lease at a time; concurrent calls share it. ATS_CORPUS_STALE_MAX_MS (24h) is the ceiling past which a read refreshes first; ats find … --fresh always refreshes first. ats cache status and ats doctor show stale / servable / revalidating. The TickTick adapter gains bulkFetch() in retrieval shape, so ats cache sync, find, dedup and garden all read the same cache.
  • Scoped retrieval: ats find … --project <id|name> / --projects a,b. The corpus is filtered before any branch runs and branches that reach past it (hybrid, native search) are filtered on the way back. A project may be its full id, short id, composite backend:id, or name (leading decorations ignored); a partial name resolves when it names exactly one project, and several matches come back as scope.candidates. The result carries scope: { projects, matched, of }.
  • A confidence verdict on every find. confidence: { verdict, reason, branchesRun, topAgreement } reads branch agreement on the top hit: strong (two or more branches agree, or the title is the query), weak (several ran, one found it), moderate (one branch ran), none. --min-sources N is the matching precision gate. The verdict lands in the usage log and the ats agent-setup policy block tells agents to read it before acting.
  • Additive updates and compare-and-swap. ats update … --append "…" / --prepend "…" add to the body that is there; --if-match <hash> lands the write only while the body still carries that contentHash (exit 3 otherwise, with the current hash in the message). ats get and ats update return contentHash; a staged compare-and-swap write is re-verified at apply time. The argument parser binds values that begin with a dash when they are not flag-shaped (--append "- 2026-09-05: shipped") and accepts --key=value.
  • Idempotent creates. ats create … --if-absent returns the active task that already carries the title in the project instead of creating another; --idempotency-key <k> records what the first call produced — a task, or a staged review item — and a repeat with the same key replays it. Keys age out after ATS_IDEMPOTENCY_TTL_MS (7 days).
  • One review gate for every write surface. guardWrite in @reneza/ats-core is the enforcement of intent.approvalRequired, security.approvalRequiredFor and ATS_REVIEW_ALL; the CLI and the MCP server's create_task / update_task both stage through it, so a gated target holds whichever surface an agent uses.
  • Zero-result recovery. An empty ats notes find answers { query, count: 0, notes: [], suggestions, hint } with the nearest items from the fused find; an empty ats tasks search carries the same suggestions; a missed ats get names the nearest items in its error. A hit keeps its shape.
  • Full provenance in ats kg export --cypher. Every FACT relationship carries status, tValid / tInvalid, confidence, source, proposer, proposal id, ratifier and ratification time, task reference, and — for retracted facts — who retracted it and why. --include-retracted adds the closed facts, so the script is a complete record of what the store believed and when.