Command line
zikaron offers the same ledger operations as the window, one subcommand per action. It is built for scripts: the output is a single JSON value, and the verdict is in the exit code. The full output shapes, exit codes, refusal reasons and flags are in CLI-SCHEMA.md in the source; zikaron contract also prints that contract as one value, made from the same tables in the code. The one exception is zikaron mcp: it speaks the Model Context Protocol on standard input and output, one message per line; see AI apps below.
Where it is
- Installed from the dmg
/Applications/ZIKARON.app/Contents/MacOS/zikaron. Turn on “Enable the zikaron command” under “Terminal” in the app’s Settings › Command line and AI control and it places a link at/usr/local/bin/zikaron, with macOS asking for an administrator password when needed; turn it on in the app once it is in Applications.- Installed from the pkg
/usr/local/bin/zikaron, ready right after installing; “Enable the zikaron command” shows “Taken by another install”, and you can leave it as it is.- Installed from the deb
/usr/bin/zikaron; “Enable the zikaron command” shows “Provided by the installed package”. With the AppImage, install the.debfor the command line; the switch shows “Not supported for this install”. “Copy config” under “Connect an AI app” is grey in the AppImage and in an app opened straight from its disk image, likewise.- Windows
zikaron.exein the unpacked folder, run in a terminal; double-clicked, it only flashes a window. “Enable the zikaron command” writes the folder into this user’sPath, and terminals opened afterwards findzikaron.- Built from source
target/release/zikaron; “Enable the zikaron command” links it into/usr/local/binon macOS and~/.local/binon Linux, a folder that has to be on yourPATH.
Three conventions
- Standard output is one canonical JSON value
- Each call prints one value, ending at the value’s last character. The byte format follows law §3.4: compact, members sorted by bytes.
- Misuse leaves standard output empty
- For wrong arguments or an unreadable path, the exit code is 2, standard output has zero bytes, and the first line of standard error reads
<reason> <subject>. The subject uses the command line’s own names alone: a flag from the flag table is written--name, and any other value or path is named only by where it stands among the arguments and its length, as inE_UNREADABLE #3 (15 bytes), so a private key or a node address carrying an access key stays with you, and terminals and logs see its place and length alone. A second line explains it for people, in Chinese when the system locale (the first ofLC_ALL,LC_MESSAGES,LANGandLANGUAGEthat is set) is Chinese and in English otherwise, and is outside the contract. Whether standard output holds any bytes tells a caller an answer from a misuse. - Status words pass through unchanged
GREEN,PARTIAL,FAIL,COMPLETE,GAPSand the like are written by the cores and passed on by the command line as they are.
When the law refuses an entry being written (E_ENTRY with the token E_BODY_FIELD, exit code 1), standard error carries one more line for people, naming the member and the flag that gives it, for example statement_md: missing or malformed; given by --statement; this line also follows the system language, is words for people, and leaves standard output and the exit code as they are.
Files are written one way: --out first writes a whole temporary file alongside, syncs it to disk, then renames it into place; when a file of that name already exists, the write stops and the existing file keeps every byte. kit-verify --originals-to takes originals out one way too: laid out in a staging folder inside the chosen folder, each checked against its fingerprint, then placed one by one, replacing nothing; a name already in the chosen folder refuses the whole batch, and nothing is written.
Exit codes
| Code | Meaning | Example |
|---|---|---|
| 0 | Answered, affirmative | GREEN, COMPLETE |
| 1 | Answered, negative | The entry was refused, the write would break the ledger (E_WOULD_BREAK), the node refuses the gas estimate for a reason about this transaction or estimates it above 200,000 (E_GAS_REFUSED), the transaction was included but failed (E_TX_STATUS), what was sent before has lapsed (E_TX_VOID), a grant file does not open (E_GRANT_FILE), the chain already holds this key’s anchor of a hash given (E_ON_CHAIN), a record kit does not hold (E_KIT) or an original in it is not the one recorded (E_RECORDS), originals not taken out (E_EXTRACT, nothing written in the chosen folder), an encrypted record package that does not open, is damaged, or whose recipient address has no anchor on chain (E_ADDRESSED), attest or succeed through the desktop (E_ON_DESKTOP), the desktop refused the action (E_DESKTOP_REFUSED) or refused an anchoring before anything went out (E_SEND_REFUSED), network refusals aside, the credential missing, expired or malformed (E_CREDENTIAL_MISSING, E_CREDENTIAL_EXPIRED, E_CREDENTIAL_SHAPE), the desktop writing the data folder at this moment (E_HOME_HELD), a writer mark naming another machine (E_HOME_OTHER_MACHINE), a folder the desktop adopted (E_ADOPTED), a read-only data folder or a broken ledger (E_READ_ONLY), a ledger handed off (E_HANDED_OFF), a handoff not taken (E_HANDOFF), or the verdict is FAIL, BROKEN_CHAIN or NO_LABEL |
| 2 | Misuse | Wrong arguments, an unreadable path, --key together with --key-file, a key file others can read, --form registry without --registry, --home with a verb or flag that does not take it, --key or --key-file with a data folder’s --ledger, anchor --ledger with --endpoint or any other of the eight flags it refuses, a --ledger naming a sealed folder outside its data folder, --to with --to-key or either with --as folder, a malformed address or a key off the curve, an encrypted package with no key to open it (E_ARGS --key --ledger --home), kit-verify given --key with --ledger, mcp given any flag; standard output is empty |
| 3 | Answered, in between | PARTIAL, GAPS, UNAVAILABLE; an anchor through the desktop or with the credential that was only queued (E_QUEUED); a record kit with a record not anchored, the chain not read or an original missing (E_RECORDS) |
| 4 | Answer absent | Node unreachable, nodes disagreeing, scan refused, no randomness available, a node refusing the gas estimate for its own reasons (E_UNREACHABLE), no answer from the desktop (E_DESKTOP), a network refusal from the desktop (E_DESKTOP_REFUSED), an anchoring refused for the network before anything went out (E_SEND_REFUSED), a recipient’s key not found while some network was not read through (E_ADDRESSED, token ADDRESS_CHAIN_UNREAD; through the desktop, E_DESKTOP_REFUSED with that code) |
The weight of this table is that 3 and 4 each have a code of their own. Fold “not yet on chain” into 0, and a buyer takes an unanchored grant as cleared; fold it into 1, and a passing “not yet known” reads as “forged”. Fold “node unreachable” into 1, and a network fault reads as “this chain is fake”. A failed scan is an absent answer, and the caller retries or changes nodes.
Twenty-six subcommands
| Subcommand | What it does |
|---|---|
keygen | Generate a key and print its address and private key |
init ✦ | Write the ledger’s creation entry into an empty ledger |
history ✦ | Append a record (--file records a file by the app’s convention) |
grant ✦ | Sign a grant and write it to the ledger |
revoke ✦ | Sign a revocation and write it to the ledger (ruling file digest optional) |
adopt ✦ | Write an adoption entry; a co-signature with only one of its two halves is refused |
attest ✦ | Produce a co-signature with an outside key |
succeed ✦ | Write a succession entry (a key rotation or a handover) |
annotate ✦ | Write a note |
retract ✦ | Write a deletion entry (the target must be a record in this ledger that is still undeleted) |
anchor ✦ | Anchor hashes on chain, through the registry contract or as a bare self-transfer; before signing it asks whether the chain already holds them, then estimates gas, and a rerun asks first; with --ledger naming a ledger in a desktop data folder, it sends that folder’s queue with the credential |
scan | Scan for anchors using the chain settings (--endpoint takes http and https; with --ledger in place of --basis, the scan range comes from that data folder’s settings and ledger; with no --endpoint, the data folder’s own nodes, with the credential) |
audit | Audit a ledger against scan results and print a report and verdict (--ledger takes a ledger folder, a ledger in a desktop data folder (with the credential), a ledger mirror or a record kit (a .zkit file or a folder); --out saves this run’s audit input; an encrypted record package is refused with E_ADDRESSED (ADDRESSED_ELSEWHERE); kit-verify opens it) |
check-grant | Run the six checks on a grant (--grant takes a grant entry file or a .zkgrant grant file; over a desktop data folder’s ledger it reads the issuer’s whole ledger and so answers whether the grant was revoked) |
chain-check | Check a sublicense chain hop by hop (--hop <grant file>[=<audit input file>], repeatable) |
depth | Depth readings for a record |
fpm-sign | Sign a fingerprint manifest |
ack-sign | Sign an acknowledgement |
badge | Encode or decode a credential (exactly one of --encode and --decode) |
kit-export ✦ | Export a record kit, written once it passes its self-check; one file by default, a folder with --as folder; --to <address> or --to-key <public key> encrypts that one file to one recipient |
kit-verify ✦ | Verify a record kit record by record (--kit takes a .zkit file or a folder): is each original the one recorded, is it anchored, judged as the desktop’s “Verify record” judges; --fragment gives a scan reading, and without it every record is unread; --originals-to takes the matching originals out into a folder that exists; an encrypted package is opened with --ledger <home>/ledger (this machine’s identities, with the credential), --key or --key-file |
hand-over | Write the whole ledger into a handoff file (--out); this place stops writing it |
take-over | Take a handoff that follows on (--handoff); this place writes again |
show | Show an entry’s author, ID, type, previous entry, sequence and content |
mcp | Lets AI apps call the command line through the Model Context Protocol (standard input and output, one message per line); see AI apps below |
contract | Print the command line’s own contract: verbs, each verb’s flags (and its other table with --home), exit codes and refusal reasons |
The twelve marked ✦ take --home: eleven are handed to the desktop, and succeed with --home always answers E_ON_DESKTOP; see Through the desktop below. Any other first word counts as misuse, with exit code 2.
Flags
All sixty-two flags are long flags, and each takes a value; every subcommand has its own table of flags, and a flag outside it counts as misuse. Members the law requires in an entry’s body may all be left off the command line; the core then refuses the entry under the law, and the command line checks the few items it needs for its own work. That way each rule of judgment exists once, in the core.
--key-file- Reads the private key from a file instead of
--key, one or the other; the file must be readable by its owner alone. Every subcommand that takes--keytakes it. --originals-to- Taken by
kit-verify: a folder that exists, into which every original matching its record is taken out, all of them or nothing written (E_EXTRACT); a signed folder comes out whole; taken, the answer addstaken(the names) andpath. --originals- Taken by
kit-exportfrom a data folder the desktop keeps (by--ledgerwith the credential, or--homethrough the desktop):noneis its one word, and the chosen records’ originals stay out of the package. Left out, they go in, taken as the desktop’s export page takes them, and the answer listsoriginalsandleftOut. Given with a plain ledger folder, it is misuse; that folder’s originals are each given with--file. --to,--to-key- Taken by
kit-export, one or the other:--tois the recipient’s address, whose public key the command line recovers from an anchoring transaction that address itself signed on chain;--to-keyis a public key,0xand 66 or 130 hex digits, a point of the curve. Only one file is encrypted, so either with--as folderis misuse.--toon a plain ledger folder needs--endpoint(each chain one the built-in deployments table names); on a desktop data folder’s ledger, that data folder’s network and this machine’s read-only networks are read, and--endpointis refused. --key(kit-verify)- The key that opens an encrypted record package; a plain package takes none. Given with
--ledger, misuse. --proxy- Taken by
anchor,scanandkit-exportwith--to:system(the default),none, or one proxy addressscheme://[user[:password]@]host:port, the schemehttp,https,socks5(orsocks5h) orsocks4(orsocks4a, a user id alone); the user name and password are percent-encoded, at most 255 bytes each, and a password written on the command line is visible to other processes of this machine while the command runs. Nodes on this machine are always reached straight; with a proxy address, private, link-local and.localnodes are too.systemreads the terminal’s proxy variables first: when any ofhttps_proxy,http_proxyorall_proxy(either case) is set, they are followed, withno_proxy, on every system; with none set, the system’s proxy settings are read: the automatic configuration script the system names first, then the explicit proxies (macOS its network settings, Windows the settings the system answers, Linux the KDE or GSettings settings stored on disk, else the environment); the system’s automatic proxy discovery is left unread. The data folder roads with the credential (anchor --ledger,scan --ledgerwith no--endpoint,kit-export --to --ledger) without--proxyuse this machine’s proxy setting, and its following the system reads the system’s settings alone, leaving the terminal’s proxy variables unread;anchor --ledgertakes no--proxy. --home- Hands the work to the running desktop app; see below.
Each subcommand’s flags and the environment variables (the overall deadline of each exchange with a node ZKA_TIMEOUT_SECS, 30 seconds by default; the answer limit ZKA_MAX_ANSWER_BYTES, 64 MiB by default; and so on) are listed in CLI-SCHEMA.md.
Example
Generate a key, create a ledger, record a file, anchor it, audit:
zikaron keygen
# {"address":"0x…","ok":true,"privkey":"0x…"}
zikaron init --ledger ./ledger --key-file ./key.txt --statement "Records of my work"
zikaron history --ledger ./ledger --key-file ./key.txt --file manuscript.pdf
# {"entryId":"0x…","ledger":"…","ok":true,"seq":1,"written":true}
zikaron anchor --key-file ./key.txt --endpoint <chain-id>=<node> \
--form registry --registry <contract address> --hash <entryId>
zikaron scan --endpoint <chain-id>=<node one> --endpoint <chain-id>=<node two> \
--basis basis.json > fragment.json
zikaron audit --ledger ./ledger --fragment fragment.json
echo $?history --file fills the entry by the convention the app uses to record a file: content is the SHA-256 of the file’s bytes, and mode is {"mark":"bytes-sha256/1","toolchain":<the SHA-256 of the text "bytes-sha256/1">}; for one file, the command line and the app write these two members alike. You can also leave out --file and give --content, --mark and --toolchain yourself; the two ways cannot be mixed.
Node addresses may be http:// or https://, in any case, an IPv6 address in brackets; https checks the certificate chain and host name against the roots compiled into the program, the same transport the app uses. Every question has one 30-second overall deadline, an address that resolves to several IP addresses has each tried, a reading question cut off mid-connection is asked once more on a fresh connection, and a transaction is broadcast once; an access key inside a node address is hidden in all output.
anchor takes exactly one --endpoint: it reads that node’s base fee and the paid tips of the last 20 blocks, sets the fee by the app’s rule (blocks whose median is zero are left out unless all are zero), then asks the node to estimate gas for this very transaction and carries one and a half times the estimate, rounded up, at most 200,000. If the node refuses the estimate for a reason about this transaction (it would revert), or estimates it above 200,000, it refuses with E_GAS_REFUSED; if the node refuses for its own reasons (a rate limit, an unsupported method, credentials needed, a wrong chain and the like) or does not answer, it reports E_UNREACHABLE; either way the command stops before broadcasting. Once sent, it asks for the receipt round after round until --wait-secs runs out.
What the chain holds stays unsent. With --form registry and --hash, before signing, anchor asks its node whether the registry already holds this key’s anchor of any of those hashes (the Anchored logs read as the scan reads them, from the registry’s deployment block to the head). Any one there answers E_ON_CHAIN, names listing them and tx and blockNumber the earliest, and nothing is sent; a node that cannot answer gives E_UNREACHABLE, and nothing is sent. --form bare and --calldata are sent as given.
A rerun asks first. Run with its own key, anchor keeps the nonce and hash of every transaction it signs for one anchoring (the same chain, key, recipient and data) in cli-sent/ in the machine folder, before broadcasting, and keeps these two alone. When the same command runs again, it first asks the node where those transactions stand, by their hashes: one already included is answered as included; one still in the pool is waited on; if none is held and their nonce is unused, it signs again at that same nonce, so at most one can ever be included; if their nonce was used by another transaction, it answers E_TX_VOID and stops there, and the next run starts afresh. Running the same command again after it succeeded therefore answers the earlier transaction, and one anchoring is paid for once.
Each question scan asks names the senders in the scan range, so only their logs come back; when a node declines, the same question is asked again, and only after three refusals is the range split. basis.json states the scan range: which chains, which registry contracts, which senders, and the start and end blocks; the format is in law §9.4. The command line keeps no record of facts checked before, and every scan asks about every log.
Audited before written
Every subcommand that writes an entry (init and retract included) passes through one gate: once the entry is signed, the core audits “this ledger plus this entry” offline, and any chain finding of law §8.3 the ledger did not already have (an old key writing after a key change, a sequence gap, a second entry at one place, a link to the wrong entry) refuses the write with E_WOULD_BREAK, names listing the findings, and not one byte is written. --seq and --prev given by hand pass the same gate. When a ledger holds two roots and no --root is given, every write is refused with E_TIP_FORKED.
Through the desktop
With --home <the desktop’s data folder>, eleven subcommands, init, history, grant, revoke, adopt, attest, annotate, retract, anchor, kit-export and kit-verify, are handed to the running ZIKARON Desk, unlocked and holding that data folder as its writer: the entry is written into the desktop’s ledger with the desktop’s identity and shows in its window at once; kit-verify is verified by the desktop on its own networks, a package encrypted to one of its identities opened with that identity first; the private keys and the passcode stay in the desktop, and the desktop does all the writing.
- While “Through the desktop app” is on in Settings › Command line and AI control and the desktop holds the data folder, it keeps a local channel open for it: on macOS and Linux a socket file in the machine folder readable and writable by its owner alone, on Windows a named pipe only this user can reach. Once connected, each side asks the system who the other runs as and refuses another user. Locking, closing or switching the data folder, or quitting, closes the channel; while “With a credential” is on, the desktop keeps it closed.
- Arguments are judged for misuse as usual first; with
--home, each subcommand has a table of its own, and the desktop decides the ledger, key and sequence itself (historytakes--fileand--note, andanchortakes--homealone, for example); a flag outside the table is misuse. Requests are done one at a time in the order they arrive, along the same action path in the desktop as a click. anchorfollows “Putting on chain from the command line” under “Anchoring” in Settings › Command line and AI control: “Send automatically” sends as the queue page’s “Put all on chain” does, answering asanchor --ledgerdoes; “Queue only” only queues and answersE_QUEUED(exit 3).attestandsucceedalways answerE_ON_DESKTOP: attesting asks for the passcode, given on the desktop alone, and handing the ledger to another key is done on the desktop by hand, sosucceedleaves the desktop unasked.kit-exporttakes--entry,--note,--out,--as(one file by default),--to,--to-keyand--originals; the chosen records’ originals go in as the desktop’s export page takes them (none with--originals none), other attachments and proof bundles are chosen on the desktop, and the key for--tois looked for on the desktop’s network and read-only networks.kit-verifytakes--kitand--originals-to.- When the desktop is locked, has not opened that data folder or has quit, the answer is
E_DESKTOP(exit 4); while “With a credential” is on, itsdetailisALONE: write without--home.anchorrefused before anything goes out answersE_SEND_REFUSED, andE_ON_CHAINwhen the chain already holds the anchors; another verb the desktop refuses answersE_DESKTOP_REFUSED, itstokenthe desktop’s own code; a network refusal is exit 4, any other 1. Whenkit-verifytakes no originals out or opens no encrypted package,tokenis the desktop’s code (EXTRACT_EXISTS,EXTRACT_LINKand the like, or the codes ofE_ADDRESSED);ADDRESS_CHAIN_UNREADexits 4.
The command line with --home finds the machine folder by the desktop’s own rule. The flags each subcommand takes with --home are in section 11 of CLI-SCHEMA.md.
With a credential
The “Automation level” group in Settings › Command line and AI control has two switches, and there is one command-line path at any time. With “Through the desktop app” on, the way is --home. With “With a credential” on, “Through the desktop app” is greyed and the desktop keeps its channel shut; the command line, without --home, reads and writes the ledgers the desktop keeps sealed and sends their queues with a credential in the machine folder that only its owner can read and write, the desktop open, locked or closed. Turning “With a credential” on asks for the passcode and a validity: days, hours and minutes, together a minute to a year, or “Does not expire”.
- Writing: with
--ledgernaming theledgerfolder in a data folder,history,grant,revoke,adopt,succeed,annotateandretractwrite the sealed ledger with the credential, signing with the key the desktop’s vault keeps for that identity and role;--keyand--key-fileare misuse there. The entry passes the same audit (E_WOULD_BREAK) and is queued for anchoring as the desktop queues its own; the file ofhistory --filegoes into this machine’s index of signed files, so an exported record kit carries the original.initis refused there withE_NOT_EMPTY. - Reading:
audit,check-grant,chain-check,depth,show --entryandkit-exportread that ledger by the same opening, taking no writer lock.kit-exporttakes the originals, the terms documents and theanchored-on:line as the desktop does, the originals staying out with--originals none;scan --ledgertakes its scan range from the data folder’s settings and ledger, its last block the head its nodes give, and with no--endpointits nodes from the data folder’s settings too.kit-export --tolooks for the recipient’s key on the data folder’s network and this machine’s read-only networks.kit-verify --ledgertakes, with the same credential, every seat’s key of every identity on this machine to open an encrypted record package. - Sending:
anchor --ledgersends the data folder’s queue with the credential: the chain, registry and nodes from the data folder’s settings, the proxy from this machine’s; it refuses--key,--key-file,--endpoint,--form,--registry,--hash,--calldataand--proxy, and--wait-secsdefaults to 90 seconds. At “Send automatically” it sends everything the queue can send, waits for the receipt and settles it; at “Queue only” it answersE_QUEUED. With nothing to send and a batch in flight, it asks about that batch by its hash; a batch no node’s pool holds whose nonce is still unused is signed again as recorded at that nonce and sent under “Send automatically”; with neither, the answer isE_SEND_REFUSEDwithtokenQUEUE_EMPTY. “Resend with higher fees” is pressed on the desktop alone. - Taking turns with the lock: the command line takes the data folder’s writer lock for each write and lets it go after; the desktop then does the same, reading again first if the command line wrote. A send holds the lock while it readies, signs and broadcasts the batch, lets it go during the receipt wait and takes it back to settle; a lock not taken back within sixty seconds answers
E_HOME_HELD, the batch staying in flight. - Write gates, asked before a write, a send or a handoff: a data folder under its read-only mark (
LEDGER_NOT_FETCHED,NEWER_ELSEWHERE) or a ledger whose own entries break its chain (BROKEN) answersE_READ_ONLYfor a write or a handoff andE_SEND_REFUSEDfor a send,tokenthat code; a ledger handed off answersE_HANDED_OFFfor a write andE_SEND_REFUSED(HANDED_OFF) for a send. - Refusals, each exit 1 with nothing written:
E_CREDENTIAL_MISSING(the switch is off),E_CREDENTIAL_EXPIRED(expired, and removed),E_CREDENTIAL_SHAPE(it fails to read or open, or belongs to an earlier master key),E_HOME_HELD(the desktop is writing at this moment; try again shortly),E_HOME_OTHER_MACHINE(the writer mark names another machine). The reading verbs are refused by the three credential reasons andE_HOME_OTHER_MACHINEalike. - The folder after adoption: once the desktop has taken in a plain ledger the command line made (“Import key”, then “Adopt existing ledger folder”), every write to its original folder,
hand-overandtake-overincluded, answersE_ADOPTED, with “With a credential” on or off, and the folder keeps every byte; to go on writing it from the command line, turn on “With a credential” and give theledgerin the data folder.
Taking originals out and encrypted record packages
kit-verify --kit <package> --originals-to <folder> verifies record by record as usual, then takes the originals that match their records into that folder under the names they had; a signed folder comes out whole under the paths it was signed with. The originals are read from the package again, laid out in a staging folder inside the chosen folder, each checked against its fingerprint, then placed one by one, replacing nothing; a name already there, a link, two originals taking one name, or any step failing answers E_EXTRACT, takes back what was placed, and leaves the chosen folder as it was. A plain package needs no home and no key.
kit-export --to <address> or --to-key <public key> exports one .zkit only the recipient opens; the answer is the plain package’s. kit-verify opens it: with the credential, --ledger <home>/ledger offers this machine’s identities; directly, --key or --key-file; through the desktop, the desktop’s identities. The opened plaintext sits in a folder of its own in the system’s temporary place and is removed when the command ends. No key opening it answers ADDRESSED_NOT_RECIPIENT, a segment that fails ADDRESSED_BROKEN, a head that does not read ADDRESSED_HEAD. The format is under Files and formats.
Handing a ledger over
A ledger can pass back and forth between two places, such as a command line’s ledger folder on a remote machine and the desktop’s data folder here, one place writing at any time. hand-over --ledger <this place> --out <file> writes the whole ledger into a handoff file (.zkhand) and this place stops writing it: a write answers E_HANDED_OFF; a handoff lost on the way is made again, the same, by running it once more. take-over --ledger <this place> --handoff <file> takes a handoff that follows on: every entry this place has is in it and its entries make one line; then the entries this place lacks are written in sequence and this place writes again. A place that handed its ledger off takes back only the handoff after its own. Anything else answers E_HANDOFF, token NOT_BACK, AHEAD, NOT_ONE_LINE, E_HANDOFF_NOTE or the file layout’s code. This machine’s side reads and writes with the credential, the desktop locked or not, and a desktop that is open shows the new entries at once. Whether an entry is on chain stays out of the handoff: the desktop reads it from the chain at its next ledger check and queues only what the chain lacks.
AI apps
zikaron mcp lets AI apps call the command line through the Model Context Protocol (MCP): the AI app starts it as a child process, and each line on standard input and output is one JSON-RPC 2.0 message, one canonical JSON value; it opens no port and no local channel and writes no file, and exits 0 when its input closes. It takes no flag and holds no right of its own: each tool call starts this same program again and runs that verb as a person would type it, answering with that command’s bytes and exit code. A write tool checks at each call whether this machine holds the credential: if so it goes --ledger <home>/ledger, otherwise --home <home>. Protocol versions 2025-11-25 and 2025-06-18 are spoken; the full contract is section 13 of CLI-SCHEMA.md, and how to connect is under Integration.
Time is injected by the caller
Deadlines and periods are judged by chain time and the moment injected with --now; when --now is left off, chain time alone applies. Every moment comes from the caller, so the same input always reaches the same verdict.
Reading the app’s own ledger
A ledger in ZIKARON Desk’s data folder is encrypted (its files start with zikaron-local/2) and the command line holds no passcode. While “With a credential” is on in Settings › Command line and AI control, the command line reads and writes the ledgers in the desktop’s data folders with that credential; see With a credential above. A ledger folder copied out of its data folder fails to read, refused as misuse with exit code 2:
E_UNREADABLE #3 (40 bytes)
Locked: this is local data ZIKARON Desk keeps sealed; the command line reads it only as the ledger of a home the desktop keeps, with the credentialTo write into the app’s own ledger, turn on “With a credential” and point --ledger at the ledger folder in the data folder, or hand the work to the desktop with --home. To let a command line elsewhere read it, export a “Ledger mirror” or a record kit in the app first: the --ledger of audit (and, through it, check-grant, chain-check and depth) and of show --entry can point straight at the mirror folder (the level holding mirror.json) or a record kit (a .zkit file or a folder); a kit is first checked under the kit law and refused with E_KIT if it does not hold; an encrypted record package is refused with E_ADDRESSED (ADDRESSED_ELSEWHERE), and kit-verify opens it. The subcommands that write entries take ledger folders and the ledgers in desktop data folders, and init takes ledger folders alone; to pass one ledger between two places, use hand-over and take-over; see Handing a ledger over above.