tensor-grep ledger (EXPERIMENTAL, ADVISORY-tier)
Verified against tg 1.110.14 (LIVE 2026-08-11 gotcontext-saddle — Slice 1 rollup
- Slice 2
findrepo-visibility reconfirmed; prior 1.101.22 / 1.93.0 #706).
tg ledger is ADVISORY-tier, not MANDATORY or OPTIONAL, in the vocabulary a multi-agent-coordination
ecosystem needs to stay legible (the same MANDATORY/OPTIONAL/ADVISORY split the ruah coordination
layer uses): a claim never blocks an edit, overlaps are reported for the caller to decide, and treating
one as a lock is a misuse of the contract, not a bug in it.
When to use
| Need | Command |
|---|---|
| Tell sibling agents "I'm touching this symbol/file" | tg ledger claim |
| See live claims on a root | tg ledger list |
| Drop a claim | tg ledger release |
| Publish an artifact for reuse (evidence / blast-radius / context / map) | tg ledger record |
| Reuse a prior artifact instead of recomputing | tg ledger find |
Advisory only — claim never blocks an edit. Overlaps are reported for the caller to decide.
Slice 1 — claims (PATH-canonicalization FIXED, v1.93.0/#706)
tg ledger claim REPO --symbol open_session --intent edit --agent-id "$AGENT_ID" --json
tg ledger list REPO --json
tg ledger release REPO --claim-id "$CLAIM_ID" --json
# or: tg ledger release REPO --symbol open_session --agent-id "$AGENT_ID" --json
- Fixed behavior (v1.93.0, #706 — the root cause of the 1.92.1-era "PATH trap" was PHYSICAL: each
command resolved the store directory from the literal PATH argument, so
claim core/hooksandlist .landed in two different on-disk stores). Claims now canonicalize to the nearest.gitancestor (a worktree's.gitFILE — not just a directory — is resolved correctly; a non-git dir falls back to the literal path), soclaim core/hooksandlist .(orlist $REPO_ROOT, or any other subtree PATH under the same repo) hit the same store.list [PATH]additionally rolls scope UP: a claim recorded atcore/hooksis visible from alistat the repo root, matched by a segment-wise_scope_containscheck (root-relative POSIX segments), not a naive string-prefix compare — socore/hooks-extracan no longer false-match a claim scoped tocore/hooks.ClaimRecordgained a storedscopefield (root-relative POSIX path), but onlylistmatches against it (the_scope_containsrollup above).releasedeliberately does NOT scope-match: it matches ONLY by exact--claim-id, or--symbolrestricted to the resolved agent's OWN live claims — the PATH SCOPING paragraph ofrelease_claim's docstring says why (adding rollup-scope matching to release would let one call silently drop an unrelated sibling agent's claim that merely shares a symbol name under a broader/ancestor scope). Scope awareness enteredreleaseonly on the FAILURE path: areleasewith--claim-id/--symbolthat matches nothing now emitsunmatched_reason+ a boundedlive_claims_elsewherelist (so the caller can see the claim IS there, just not under the id/symbol asked for) instead of a barereleased_count: 0. A bare-path release with neither--claim-idnor--symbolnow fails closed ("requires --claim-id or --symbol") rather than silently no-op'ing. - Migration note: claim/list/release stores written before #706 (keyed by the pre-fix literal-path scheme) become invisible orphans under the new canonical-store resolution — their content is TTL-bounded (see below) and safe to hand-delete; they are not corrupt, just superseded.
- Exit
0on success (including overlaps present, or release of unknown/expired claim). - Exit
2only on fail-closed (lock timeout,--filesoutside root, write failure, or the new bare-path-release-with-no-identifier case above). - TTL default 900s (
TG_LEDGER_CLAIM_TTL_SECONDS) — deliberately shorter than a long-running agent session and shorter than some comparable tools (e.g. a 1800s TTL inchump) but longer than others (e.g.ContextNest's 120s) — the choice trades "a crashed agent's claim ages out reasonably fast" against "a normal edit-verify-commit loop doesn't need to re-claim mid-task." --agent-idis never inferred; falls back toTG_LEDGER_AGENT_IDthenTG_EVIDENCE_AGENT_ID(elseanonymousviaprepare --claim, which also stampscoordination.claim.agent_id_hint).- Worktrees are store BOUNDARIES, not shared stores (verified 2026-08-12 against
ledger_store.py): the canonical-store fix walks up to the nearest.gitentry via_discover_repo_root, which only tests(current / ".git").exists()and returns that directory —.exists()does not care whether.gitis a directory (normal checkout) or a FILE (git worktree/submodule), and there is ZERO gitdir/commondir resolution anywhere insrc/(re-verify:rg -n "commondir" src/returns nothing). A worktree's.gitFILE is therefore a boundary marker: each worktree gets its OWN claims store rooted at the worktree directory, and sibling worktrees of one logical repo do NOT share a store — a claim made in worktree A is invisible totg ledger listin worktree B. (An earlier pass of this doc claimed the opposite — "resolves to the real common store, siblings SHOULD share" — which the code never did.) Cross-worktree coordination is thus NOT something the ledger gives you for free; dogfood-confirm on your own setup (tg ledger claimin worktree A,tg ledger listin worktree B — expect zero overlap) before depending on any cross-worktree visibility for something load-bearing; don't assume it from this doc alone. - External backing for "narrow the claim": AgenticFlict-class research on AI-authored PRs measures
merge-conflict rate rising sharply with edit footprint (~9.9% at a 2-line change vs ~30% at 25+ lines,
~27.67% overall for AI-authored PRs) — prefer
REPO/srcover whole-repo scope and a single-symbol claim over a broad one; a narrow claim is not just politeness, it measurably lowers the chance two agents' real edits collide even though the ledger itself never blocks either one.
Dogfood: claim/list/release round-trip PASS from any subtree PATH under the same repo (v1.93.0/#706
closing dogfood); record+find fresh PASS including find . after record core/hooks (1.101.17).
Slice 2 — findings reuse (repo-visible find as of 1.101.17 dogfood)
Live dogfood (1.101.17): after tg ledger record core/hooks --receipt …,
tg ledger find PATH --symbol S --fresh-only returns fresh findings for
PATH in {., core/hooks, core, $REPO_ROOT, core/skills} — same-repo visibility,
not limited to the literal record PATH. Prefer an explicit PATH on record still;
do not assume cross-repo visibility. Older skills claiming Slice 2 is strictly
literal-path-rooted are stale relative to this binary.
tg evidence emit REPO --capsule capsule.json --query "task" --json --agent-id "$AGENT_ID" > receipt.json
tg ledger record REPO --receipt receipt.json --artifact-kind evidence-receipt --symbol open_session --agent-id "$AGENT_ID" --json
tg ledger find REPO --symbol open_session --artifact-kind evidence-receipt --fresh-only --json
# also OK: tg ledger find . --symbol open_session --fresh-only --json
--artifact-kind: evidence-receipt | blast-radius | context-pack | repo-map.
find exit contract (3-state):
| Exit | Meaning |
|---|---|
0 |
≥1 fresh finding (revision matches — safe to reuse) |
1 |
nothing matched or matches exist but none fresh → recompute |
2 |
fail-closed (missing --symbol, corrupt index/blob) |
Dogfood (1.101.17): after record, find at . / subtree / abs root → exit 0, any_fresh: true.
Agent loop with ledger
tg ledger claim REPO/src --symbol SYM --agent-id "$AGENT_ID" --json
# if overlaps: coordinate or proceed knowingly (advisory)
tg agent REPO/src "task" --json > capsule.json
tg evidence emit REPO --capsule capsule.json --query "task" --json --agent-id "$AGENT_ID" > receipt.json
tg ledger record REPO --receipt receipt.json --symbol SYM --agent-id "$AGENT_ID" --json
tg ledger release REPO --symbol SYM --agent-id "$AGENT_ID" --json
Claim visibility is not proof of correctness — this loop is coordination, not verification.
A clean claim/release round-trip (like a conflict-free git rebase) only proves agents
coordinated; it says nothing about whether the merged result is right. Motivating incident:
a multi-PR drain sequentially rebased several parallel PRs onto a shared test_lang_registry
file — every rebase was conflict-free, but a silent auto-merge had dropped a lang_* import,
caught only when the test suite was re-run afterward (ImportError), not by the clean rebase
itself. Run real validation (tests, dogfood) before/after release, not just an uncontested
claim — the ledger tells you who touched what, never whether it's correct.
Related
tensor-grep,tensor-grep-enterprise-agent,tensor-grep-enterprise-review-bundle- Surface/schema may change in a minor release — re-check
tg ledger --helpon upgrades