UCF-RS Agent Guide¶
This guide is for AI agents and automated callers that use UCF-RS as a tool — to create, check, or maintain citations while working in a codebase.
This is different from AGENTS.md at the repository root,
which is contributor guidance for coding agents modifying UCF-RS's own
source code. If you're editing UCF-RS itself, read that file. If you're an
agent citing evidence in a project that uses UCF-RS, this is your guide.
The contract, in one paragraph¶
UCF-RS authority is append-only and explicit. You may activate a range as a
citation, but you must never assume text similarity, symbol names, or AST
position means a citation still holds — only an explicit resolve /
status check tells you that. You must never accept changed_unaccepted,
missing, or ambiguous evidence on the caller's behalf; surface it and let
a human or an explicit accept/reconcile command resolve it.
Rules¶
- Do not infer evidence. Don't add citations based on surrounding
context, symbol names, AST identity, or fuzzy matches. Every citation
comes from an explicit
activate(orpreflightfirst, if you want to validate before committing). - Do not silently persist markers into source. UCF-RS's entire value is that source stays clean — never write your own comment-based citation markers into files as a workaround.
- Prefer managed edits. If you're editing a file that has active
citations, use
apply-edit(or thedocument.apply_edit/ offline-queue server methods) instead of writing the file directly, so cited ranges transform correctly instead of silently going stale. - Never treat changed evidence as valid.
changed_unacceptedmeans the text moved since acceptance. Don't re-activate over it or ignore it — either callacceptafter confirming the new text is correct, or leave it for the human/workflow that owns acceptance decisions. - Never guess merges offline. If
replay-offlinereturns a conflict because authoritative state advanced, don't retry blindly — re-readstatusand decide a fresh course of action. - Treat
E_RECOVERY_RETRY_REQUIREDas a stop sign, not an error to suppress. If a mutating command returnsucf-rs.recovery_required.v1, a prior interrupted transaction was just completed as a side effect and your requested mutation did not run. Re-inspect current state (status,transaction inspect) and reissue the command with fresh preconditions — don't loop the same call blindly. - Never delete or hand-edit
.ucf-rs/files. Userecoverandtransaction inspect/transaction abandonfor anything resembling a stuck or divergent state. - Treat exports as non-authoritative.
export ledger,export blocks, andrenderoutput are regenerable projections. Don't reason about current truth from a stale export — re-runstatus(with--strictif you need to detect ledger staleness) first. - Default to redacted output. Don't request or forward evidence text
(
export blocks,virtual-blocks) unless the task explicitly requires content, not just status/hashes/ranges.
Recommended interaction pattern¶
- Preflight before activating, if the caller can tolerate the extra round trip — it validates without mutating authority, so you can catch a bad range before it's recorded.
- Activate with an explicit, stable handle.
- Check
status --format json(orresolvefor a specific document) before treating anything as currently valid. Parse the JSON; don't rely on prior state. - On
changed_unaccepted/missing/ambiguous, stop and report rather than resolving it yourself unless you were explicitly instructed how to handle that class of conflict. - Accept explicitly only when you have a clear basis to do so (e.g. a human confirmed the new text, or the task explicitly authorizes it).
- Export/render only when asked, and prefer metadata-level exports
(
export ledger) over content-bearing ones (export blocks) by default.
Programmatic access¶
For scripted or headless use, serve accepts JSONL over stdin/stdout, or
local HTTP:
Request shape (simple or JSON-RPC-compatible):
{"jsonrpc": "2.0", "id": "1", "method": "partition.activate", "params": {"handle": "AUTH-ROTATE", "path": "src/auth.py", "lines": "1:4", "task_context": true}}
(lines uses the same "START:END" string format as the CLI's --lines.
task_context is the server equivalent of --task-context — set it true
when the handle isn't already in docs/handle-registry.jsonl.)
Available methods:
| Method | Purpose |
|---|---|
status.current |
Current authority/projection report |
citation.resolve |
Overlays for a document path |
session.open |
Session id, document revision hash, server epoch |
partition.preflight |
Validate an activation without mutating authority |
partition.activate |
Append activation records |
document.apply_edit |
Apply a managed edit delta, transform/refresh ranges |
document.queue_offline_edit |
Queue and apply a local disconnected edit |
offline.replay |
Replay queued offline edits through authority |
partition.accept |
Accept the latest managed partition content |
export.ledger |
Write the deterministic ledger projection |
If you're calling this over HTTP rather than stdio, remember the transport
has no authentication and no TLS and defaults to loopback-only. Don't
bind or advise binding to a non-loopback host unless the human operator has
explicitly opted into --unsafe-remote and understands the exposure.
Minimal example session¶
python scripts/ucf_rs.py init
python scripts/ucf_rs.py preflight --handle AUTH-ROTATE --path src/auth.py --lines 1:4 --task-context
python scripts/ucf_rs.py activate --handle AUTH-ROTATE --path src/auth.py --lines 1:4 --task-context
python scripts/ucf_rs.py status --format json
# note the partition_id in the activate/status output, e.g. AUTH-ROTATE/001 —
# lifecycle commands key off that, not the handle
# ... later, after the file changes ...
python scripts/ucf_rs.py resolve --path src/auth.py
# if changed_unaccepted and confirmed correct:
python scripts/ucf_rs.py accept --partition-id AUTH-ROTATE/001
python scripts/ucf_rs.py export ledger
Omit --task-context once the handle is already registered in
docs/handle-registry.jsonl (or .ucf-rs/handle-cache.jsonl via
import-registry) — without it and without a registry/cache entry,
activate/preflight exit with code 2 (EXIT_VALIDATION_ERROR) and a
plain-text error: ... message on stderr (not JSON, even under
--format json), so check the exit code rather than only trying to parse
stdout. Operational check failures (status --strict, including
E_STORE_UNINITIALIZED on an uninitialized store, reconcile --partition-id
when not reconciled, and session open with diagnostics) exit with code 1
(EXIT_CHECK_FAILURE).
See also¶
- User Guide — the same workflow from a human operator's point of view
- Doc-to-Code Audit Recipe — auditing documentation claims against a codebase using existing UCF-RS features and a sidecar file
docs/commands.md— full command and server referencedocs/data-policy.md— exactly what is and isn't disclosed by defaultAGENTS.md— guidance for agents contributing to UCF-RS's own codebase (not the same audience as this guide)