1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
/// On-disk state for ritalin contracts.
///
/// Layout (relative to current working directory):
/// .ritalin/scope.yaml — human-edited contract (outcome + metadata)
/// .ritalin/obligations.jsonl — append-only obligation ledger
/// .ritalin/evidence.jsonl — append-only verification evidence ledger
/// .task-incomplete — marker file; presence = "agent must keep working"
///
/// Why JSONL for ledgers? Append-only writes are atomic line-by-line on POSIX,
/// so we never corrupt the ledger even on crash. No locking needed for the
/// single-builder case; multi-writer scenarios should serialize through `gate`.
///
/// Why YAML for scope? Humans (and agents) read and write it directly;
/// JSON's lack of comments makes it hostile to in-line acceptance criteria.
use ;
use crateAppError;
/// Walk up from `cwd` looking for a `.ritalin/` directory, without crossing
/// into a *different* project's territory. A directory containing a `.git`
/// directory but no `.ritalin` is an independent repo root — the walk stops
/// there, so a stray `.ritalin` in e.g. `~/Projects` cannot capture the Stop
/// hook of every repo nested beneath it. A `.git` *file* (submodule or
/// linked worktree) is subordinate to a parent checkout by construction, so
/// the walk continues — `cd`-ing into a submodule of the contract's repo
/// must still find the contract. Outside any git repo the walk continues to
/// the filesystem root (pre-v0.4.5 behavior).
/// Acquire the exclusive contract lock (`.ritalin/.lock`), serializing id
/// allocation (`add`), destructive rewrites (`init`/`seed --force`), and
/// gate's pass-commit against each other. The lock lives on a dedicated
/// file that is never deleted — locking the ledger itself would guard
/// nothing once `--force` unlinks and recreates it, and append-only handles
/// cannot be locked on Windows. Advisory; released when the returned handle
/// drops (including on crash).
/// Find the ritalin state directory by walking up from cwd (stopping at the
/// git-repo boundary). Returns `.ritalin/` next to the first ancestor that
/// contains it, or `<cwd>/.ritalin/` if none is found.
/// Returns true if `.ritalin/` exists in the cwd ancestry within the current
/// git repo (or anywhere up the tree when not in a git repo).