Reference · v0.44.0
Actions
From the pinned CLI source. Read upstream.
Current format policy: Portable .tine files default to v5 (since 0.42). --for-legacy writes v4. The .tine/ repository format is v3. tine evidence export writes v4.
Line attribution (0.42)
tine git attribute COMMIT [RUN...] [--sign-key KEY] [--no-configure] [--json]
tine git attribution COMMIT [--verify] [--pubkey KEY.pub] [--json]
tine git attribution COMMIT --format agent-trace
tine stats --ai-share [--rev REV] [--json]
tine git attribute diffs COMMIT against its first parent and matches each
added line to the recorded write that inserted it (the matching tine blame
uses), over the runs given, or else the runs the commit already links through
Tine-Run trailers or notes. The result is stored in the commit's
refs/notes/tine note as one Tine-Attribution: {...} line (schema
opentine-line-attribution/1): per file, ranges with start_line,
end_line, the run, step, seq, tool and model that wrote them, and
the content_hash (SHA-256) of the lines covered. Tine-Run lines for the
runs are kept or added, so tine git log sees the same note. With
--sign-key the record carries an Ed25519 tine-sig/3 block under the domain
opentine.line-attribution.v1:.
The record names no commit, so it stays true when git copies the note to a
rewritten commit. tine git attribute adds this to the repository's config
(skip with --no-configure):
git config --add notes.rewriteRef refs/notes/tine
With it, git commit --amend and git rebase (including rebase -i) copy the
note to the new commit. Set it yourself in clones where attribute has not
run; git does not copy notes by default.
tine git attribution COMMIT --verify checks the signature (against
--pubkey, or the embedded key as trust on first use) and that every range's
hash still matches the lines the commit adds; it exits 1 when either fails.
--format agent-trace prints the note as an Agent Trace
record: vcs is {"type": "git", "revision": COMMIT}, one conversation per
model with contributor ai, ranges with content_hash, and run and step ids
in metadata["io.github.0xcircuitbreaker.opentine"].
tine stats --ai-share blames every text file at --rev (default HEAD) and
counts the lines whose originating commit's attribution note credits them to
a run: total_lines, ai_lines, ai_share, by_model, per-file counts and
commits_with_attribution. Lines in commits without a note count as not
attributed.
Fleet records and delegation (0.43)
| Command | What it does |
|---|---|
tine key delegate KEY --to PUB --agent NAME --action NAME [--max-depth N] [--not-before T] [--not-after T | --days N] [--parent CHAIN] --out CHAIN [--json] | KEY signs an opentine-delegation/1 certificate (SPEC 4.10) giving PUB the named agents and tools (* is any) for the window (default now to now + 30 days); --out gets the chain, root first, with --parent's certificates before the new one. --agent and --action repeat |
tine key delegation show CHAIN [--json] | Each certificate's digest, issuer, subject, window, parent and scope |
tine key delegation verify CHAIN --signer PUB|FPR [--at T] [--agent NAME] [--action NAME] [--root FPR] [--json] | Verifies the chain offline for that signer at T (default now); exit 4 and the delegation.* code (expired, scope-violation, broken-chain, wrong-signer, bad-signature, too-deep, malformed) when it fails |
tine fleet record RUN.tine [--json] | The run's opentine-fleet/1 record (SPEC 4.11), captured from OPENTINE_FLEET_ID/_MEMBER/_ROLE/_PARENT, and the length of its delegation chain |
tine fleet record RUN.tine --sign-key KEY --out FILE | Writes an opentine-fleet-record/1 document: the record bound to the run's id and digest under a tine-sig/3 block |
tine fleet record RUN.tine --attest OUT --attest-key KEY | Writes an in-toto https://opentine.dev/attestation/fleet/v1 DSSE envelope whose subject is the run's digest |
tine fleet record FILE [--pubkey PUB] | On a signed fleet record: verifies it offline (exit 4 on failure); without --pubkey the embedded key is trusted on first use |
A capture with OPENTINE_DELEGATION=CHAIN stores the chain in the run;
tine verify RUN --offline then adds a required delegation check: the chain
must verify for the run's signer at its signing time, its agent (agt_ ref,
harness, fleet member or role) and every tool it used. The check's detail lists
the chain root first; its trust basis says whether the root is one of --pin.
A trusted .tine/agents.toml may also carry windows
([agents.NAME.lifecycle."sha256:<hex>"] not_after = "..."), as may a trust
policy's key_lifecycle table; the strictest window wins.
tine verify RUN --offline adds a key-lifecycle check whenever a window
names the signer key, judged against the report's verified signing_time (a
signature-bound RFC 3161 token): lifecycle.valid, lifecycle.expired,
lifecycle.not-yet-valid or lifecycle.revoked. With no verified time it is
unavailable-offline / lifecycle.unverified-time, except that a revoked key
fails (lifecycle.revoked-unverified-time) and a claimed signed_at outside
the window fails. Plain tine verify RUN --pubkey/--pin has no verified time:
it exits 4 (verification_failed) on those failures and otherwise notes that
the window was checked against an unverified time.
Timestamp tokens now fail with timestamp.signing-cert-mismatch (no single
ESS signingCertificate/V2 attribute binding the TSA certificate),
timestamp.critical-extension, timestamp.policy-not-allowed, or
timestamp.missing-eku when the timeStamping EKU is not critical or not alone;
genTime plus or minus the token's accuracy must lie inside the TSA validity.
An attestation's tine-attest/2 record must be signed by the DSSE envelope's
key; the detail says record bound (0.41 records name signer_key) or
record unbound (older records, still accepted). Keyless verification refuses
(exit 6) a TUF-installed trusted root whose stored metadata has expired.