DEMO — the full loop in exact commands¶
Everything below runs from the repo root on Linux/macOS with stable Rust.
outcrop = target/debug/outcrop; build it once:
cargo build -p outcrop-cli
alias outcrop="$PWD/target/debug/outcrop"
1. Seed a corpus¶
The deterministic OKF v0.2 sample bundle is committed at fixtures/corpus
(regenerable byte-identically with cargo run -p corpus-gen). Work on a copy:
cp -r fixtures/corpus /tmp/bundle
outcrop --root /tmp/bundle init --yes
--yes skips the confirmation init shows before importing an existing,
non-empty directory into a new workspace; drop it to see the prompt when
running this interactively (a plain outcrop --root /tmp/bundle init also
works unattended, since the prompt only appears at a real terminal).
2. Query¶
outcrop --root /tmp/bundle query "SELECT count(*) AS n FROM projects"
outcrop --root /tmp/bundle query "SELECT name, status, priority FROM projects WHERE status = 'active' LIMIT 5"
outcrop --root /tmp/bundle query "SELECT _path, score FROM search('watcher debounce') LIMIT 3"
outcrop --root /tmp/bundle query "SELECT source, target, depth FROM neighbors('projects/project-aurora', 2) LIMIT 10"
outcrop --root /tmp/bundle query "SELECT section_overview FROM projects WHERE _path = 'projects/project-basalt.md'"
3. Edit in Obsidian (or any external editor) → change is detected¶
Simulate an external editor touching a file directly:
sed -i '' -e 's/^team: research$/team: platform/' /tmp/bundle/people/guido-milner.md 2>/dev/null \
|| sed -i 's/^team: research$/team: platform/' /tmp/bundle/people/guido-milner.md
outcrop --root /tmp/bundle pending # shows: modified people/guido-milner.md
outcrop --root /tmp/bundle adopt -m "Guido moved to platform"
outcrop --root /tmp/bundle query "SELECT team FROM people WHERE _path = 'people/guido-milner.md'"
External edits are first-class: pending surfaces them, adopt records them
in History, discard restores the committed state byte-identically. (The
embedded file watcher does the same detection live inside the server —
external writes never lock anyone out and never corrupt.)
4. Create a scenario and diverge¶
outcrop --root /tmp/bundle scenario create reorg-draft
outcrop --root /tmp/bundle set projects/project-aurora.md status=paused --scenario reorg-draft -m "Pause Aurora in draft"
outcrop --root /tmp/bundle set projects/project-aurora.md status=done -m "Aurora shipped on main"
outcrop --root /tmp/bundle scenario diff reorg-draft # field-level: status active->paused vs main
Snapshot isolation, visibly:
outcrop --root /tmp/bundle query "SELECT status FROM projects WHERE name = 'Project Aurora'" --scenario reorg-draft # paused
outcrop --root /tmp/bundle query "SELECT status FROM projects WHERE name = 'Project Aurora'" # done
5. Propose a merge, hit a conflict, resolve it¶
outcrop --root /tmp/bundle merge reorg-draft
# -> 1 conflict: projects/project-aurora.md field `status` (mine: done, theirs: paused); exit 1
outcrop --root /tmp/bundle merge reorg-draft --keep 'projects/project-aurora.md:status=mine'
outcrop --root /tmp/bundle query "SELECT status FROM projects WHERE name = 'Project Aurora'" # done (kept mine)
outcrop --root /tmp/bundle history
Edits to different fields of the same record auto-merge with no conflict. A merge whose result violates a folder schema still completes — the records land on the needs-attention list instead (constraints flag, never corrupt).
6. Constraint tools¶
outcrop --root /tmp/bundle validate # all 11 planted corpus violations, grouped
outcrop --root /tmp/bundle validate projects # 5 violations; exit code 1
outcrop --root /tmp/bundle set projects/project-basalt.md status=bogus -m nope
# -> blocked by folder policy (projects/_schema.yaml: policy: block); file untouched; exit 1
7. Snapshots and restore¶
outcrop --root /tmp/bundle snapshot before-experiments
outcrop --root /tmp/bundle set projects/project-basalt.md priority=1 -m "Experiment"
outcrop --root /tmp/bundle get projects/project-basalt.md --snapshot before-experiments # old value, no checkout
outcrop --root /tmp/bundle history # copy an ENTRY_ID
outcrop --root /tmp/bundle restore <ENTRY_ID> # restores as a new History entry
8. MCP (agents)¶
outcrop --root /tmp/bundle mcp
Speak newline-delimited JSON-RPC on stdio (protocol 2024-11-05), e.g.:
{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"demo","version":"0"}}}
{"jsonrpc":"2.0","method":"notifications/initialized"}
{"jsonrpc":"2.0","id":2,"method":"tools/list"}
{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"query","arguments":{"sql":"SELECT count(*) FROM notes"}}}
Or register it with Claude Code (.mcp.json):
{"mcpServers": {"outcrop": {"command": "/path/to/outcrop", "args": ["--root", "/tmp/bundle", "mcp"]}}}
The scripted end-to-end session used to verify this (query → scenario → upsert → isolation check → diff → merge → validate) is recorded in RUNLOG.md.
9. The engine + macOS canvas¶
No server to start — the canvas spawns-or-adopts the shared engine for the
bundle over a Unix socket (docs/ENGINE.md). On a Mac (needs Xcode toolchain;
see clients/apple/README.md for the one-time protoc generation step):
cargo build -p outcrop-cli --release
export OUTCROP_BIN="$PWD/target/release/outcrop"
export OUTCROP_ROOT=/tmp/bundle
cd clients/apple && swift run OutcropCanvas
outcrop --root /tmp/bundle engine status shows the engine the canvas
started (version, uptime, attached clients); it lingers briefly after the
canvas quits, then goes away on its own. outcrop engine stop retires it
early. TCP (outcrop serve --grpc <addr>) remains an explicit opt-in for
remote use.
Add a query card and a graph card, then flip the scenario picker between
main and reorg-draft — every card re-renders against the selected
scenario: same canvas, two data states, side by side.
Record card (authoring v1)¶
Toolbar → Add Record Card → ⏎ loads projects/project-aurora.md → Edit →
change status to paused → Save → card shows Saved; re-run a query card to
see the new value. Set status to bogus → Save → the card explains the
block (the projects folder's rules) and keeps your edits. Flip the scenario
picker → the card re-loads that scenario's version of the record.
Canvas UI (refined)¶
In the canvas: ⌘E toggles the Explorer; search the bundle from the sidebar and click a hit to open its record card; ⌘1/⌘2/⌘3 (or the right-edge palette) add cards at the visible center; drag a card (no jump-to-cursor, lands on top); pinch or ⌘+/⌘−/⌘0 to zoom; ⌘S saves — watch "Saved just now" in the toolbar.
Canvas unit tests: cd clients/apple && swift test (run the protoc
generation step first — see clients/apple/README.md).
Coming: the on-demand engine¶
The manual serve --grpc step above is being replaced by a shared
on-demand engine (see docs/ENGINE.md): any client — canvas, MCP, CLI —
finds or starts one engine per bundle over a Unix socket, and it winds
itself down ~45s after the last client leaves. outcrop engine status
will show who's attached.