From d650de687a524dc02197a10b55e75dd62bf2479c Mon Sep 17 00:00:00 2001 From: Kriday Dave Date: Sat, 22 Aug 2026 21:57:26 +0000 Subject: [PATCH] Reposition docs around custody serving the court --- CONTRIBUTING.md | 39 ++++++++++++++------- Cargo.toml | 2 +- README.md | 78 ++++++++++++++++++++++++++++-------------- TODO.md | 2 +- oot-vision-report.html | 3 ++ visibility.toml | 14 ++++++-- 6 files changed, 95 insertions(+), 43 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 15f9581..98256a6 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,10 +1,11 @@ # Contributing to Oot -Oot is the court for code. It adjudicates **changes**, not commits or branches. A change is a content-addressed delta between two snapshots, and it can arrive from a human on git, an agent on Jujutsu, or a model in memory. If you have been burned by repository-level permissions, by a secret that should never have been a file, or by a diff that went public too early, this is your project. +Oot is the court for code. It adjudicates **changes**, not commits or branches. A change is a content-addressed delta between two snapshots, and it can arrive from a human on git, an agent on Jujutsu, or a model in memory. The bridge runs both ways: git and Jujutsu are first-class sources, and the exporter hands history back as byte-identical git. If you have been burned by repository-level permissions, by a secret that should never have been a file, or by a diff that went public too early, this is your project. ## Who should contribute -- **VCS adapter authors.** Oot reads snapshots from git and Jujutsu but owns neither. Turning those snapshots into Changes is real, unglamorous work. +- **VCS adapter and exporter authors.** Oot reads snapshots from git and Jujutsu, keeps its own store, and exports back to git. Turning snapshots into Changes, and stores back into git history, is real, unglamorous work. +- **Store & exporter contributors.** `.oot/` holds a bare git object database plus a change-id DAG; export rewrites trees under visibility policy while staying byte-faithful when unfiltered. Storage people welcome. - **Policy people.** Embargoed releases are run by hand today (GitHub Security Advisories, the Git project's git-security list). The people who have done this know where it leaks. - **Language experts.** The structural engine needs heuristics for what counts as a real conflict in each language. - **Anyone who has shipped the wrong merge.** Your war stories become our test cases. @@ -18,13 +19,14 @@ A **Change** is a delta between two snapshots. It carries an **Intent** (what it The repo is a seed, not the finished runtime. The build order is fixed because each piece feeds the next. 1. **Change ingestion.** Adapters that turn git and Jujutsu snapshots into the Change type. This is the front door. -2. **Visibility policy.** The governance spine. Private paths, private branches, embargo schedules. Driven by a config file, not code. This leads because the `.env`, monorepo-privacy, and private-branch problems are the reason Oot exists. -3. **Meaning disputes.** The structural engine (tree-sitter today) plus a hosted intent check. Flags changes that agree on tokens but disagree on meaning. One axis, after visibility. -4. **Docket format.** The on-disk record of an adjudication, including visibility and embargo state, so a human can review later. -5. **In-memory execution.** The path that runs with no materialized tree, for agents. -6. **Hosted model client.** The intent scoring and embargo distribution. The only part that is not open source. +2. **Store & exporter. DONE.** The `.oot/` store keeps history natively: bare git odb, change-id DAG, `record`, `log`, `status`, and export that reproduces byte-identical SHAs when unfiltered and strips private paths when filtered. +3. **Visibility policy.** The governance spine. Private paths, private branches, embargo schedules. Driven by a config file, not code. This leads because the `.env`, monorepo-privacy, and private-branch problems are the reason Oot exists. +4. **Meaning disputes.** The structural engine (tree-sitter today) plus a hosted intent check. Flags changes that agree on tokens but disagree on meaning. One axis, after visibility. +5. **Docket format.** The on-disk record of an adjudication, including visibility and embargo state, so a human can review later. +6. **In-memory execution.** The path that runs with no materialized tree, for agents. +7. **Hosted model client.** The intent scoring and embargo distribution. The only part that is not open source. -The original one-line pitch was "Git settles lines, Oot settles meaning." That framing is now one axis of three. Governance (visibility and embargo) leads; meaning follows. +The original one-line pitch was "Git settles lines, Oot settles meaning." Governance (visibility and embargo) leads; meaning follows; custody carries both. ## The docket contract @@ -50,17 +52,30 @@ A dispute has four required fields: `id`, `location`, `kind` (`meaning` or `visi ## Dev setup -You need a recent Rust toolchain. Once the runtime exists: +You need a recent Rust toolchain. ```bash cargo build --release cargo test ``` -Run the runtime against a fixture change to see a docket: +Run the runtime against this repo's fixtures to see a docket: ```bash -./target/release/oot adjudicate --change feature/auth-refactor +./target/release/oot adjudicate --change feature/auth-refactor \ + --base fixtures/repo/base --head fixtures/repo/head \ + --visibility fixtures/visibility.toml +# exits 1 on purpose: the fixture touches secrets/.env, so it cloaks +``` + +Walk the native store path, end to end: + +```bash +./target/release/oot init +./target/release/oot status +GIT_AUTHOR_NAME=you GIT_AUTHOR_EMAIL=you@example.com ./target/release/oot record -m "my change" +./target/release/oot log +./target/release/oot export --out /tmp/exported # add ./visibility.toml to filter private paths ``` ## Conventions @@ -73,7 +88,7 @@ Run the runtime against a fixture change to see a docket: ## License -The adjudication runtime, docket format, and adapters are MIT licensed. The hosted model is a paid service and is not part of this repo. Contributions to the open parts land under MIT. +The adjudication runtime, the docket format, the adapters, and the store with its exporter are MIT licensed. The hosted model is a paid service and is not part of this repo. Contributions to the open parts land under MIT. ## Start here diff --git a/Cargo.toml b/Cargo.toml index 1ae9ff7..a6f35f1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ name = "oot" version = "0.1.0" edition = "2021" -description = "Git settles lines. Oot settles meaning." +description = "Repos track lines. Oot governs changes: who may see them, what they mean, and when they may ship." license = "MIT" [dependencies] diff --git a/README.md b/README.md index c121552..e716ad3 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ > Repos track lines. Oot governs changes: who may see them, what they mean, and when they may ship. -Oot is the court for code. It does not manage your commits or your branches. It adjudicates your **changes**: who is allowed to see a change, when it may become public, and what it means. A change can come from a human on git, an agent on Jujutsu, or a model running in memory. Oot judges all of them the same way. The project began as a five minute sketch about semantic merge conflicts. The real target is wider: governance over changes, with meaning as one axis among three. +Oot is the court for code. It governs your **changes**: who may see them, what they mean, and when they may ship. Governance needs custody, so since August 2026 Oot keeps its own history in a native `.oot/` store whose unit is the change, with `record`, `log`, `status`, and visibility-filtered export built on it. Git remains the universal interchange format. Every store exports back to byte-identical git history, and GitHub is reached through that exporter rather than through a fork of git. Today the store serves the court; the declared direction is for it to become the source control itself. A change can still arrive from a human on git, an agent on Jujutsu, or a model running in memory, and Oot judges all of them the same way. The project began as a five minute sketch about semantic merge conflicts. The real target is wider: governance over changes, with meaning as one axis among three. ## Why this exists @@ -10,13 +10,14 @@ Agents now write a large share of our merges. A 2026 study of 142,652 AI-agent p The deeper problem is that Git's primitives are the wrong shape for this world. Permissions are repository-level, so keeping one file private means a third-party secret manager and a prayer ([git-crypt](https://github.com/AGWA/git-crypt) exists, but it does encryption, not policy). Branches and pull requests add overhead that tools like [Jujutsu](https://github.com/jj-vcs/jj) have already shown we do not need. And a materialized working tree is a bottleneck: cloning or reinstalling thousands of small files takes 30 to 40 seconds on macOS APFS where Linux does it in 3 to 12. -Oot does not try to replace Git or Jujutsu. It sits above them and above the actor, and it answers the questions they were never built to answer. +Git and Jujutsu track lines. Oot holds history in order to govern it, and it answers the questions they were never built to answer. ## How Oot thinks: changes, not commits -Oot's unit is the **Change**, a content-addressed delta between two snapshots. No branch name, no commit message, no checkout required. From that one idea the rest follows. +Oot's unit is the **Change**, a content-addressed delta between two snapshots. Judging one needs no checkout and no working tree. From that one idea the rest follows. - **Change**. A delta between two snapshots, from anywhere. +- **Store**. Native history in `.oot/`: a bare git object database plus change records whose parents are change ids rather than commit shas. `record`, `log`, `status`, and `export` build on it. - **Visibility**. The governance spine. A policy on paths or branches: `private-to`, `embargo-until`, `public`. This is the `.env`, monorepo-privacy, and private-branch problem, handled as policy rather than cryptography. - **Intent**. What the change claims to mean. Semantic disputes are checked against this. Meaning is one axis, not the whole product. - **Dispute**. A point of disagreement. Either *visibility* (a policy is violated) or *meaning* (two changes diverge in intent). @@ -25,45 +26,48 @@ Oot's unit is the **Change**, a content-addressed delta between two snapshots. N ## How it works -A change arrives. Oot runs its checks and prints a docket. +A change arrives. Oot runs its checks and prints a docket. Real run against this repo's fixtures: ```bash -$ oot adjudicate --change feature/auth-refactor +$ ./target/release/oot adjudicate --change feature/auth-refactor \ + --base fixtures/repo/base --head fixtures/repo/head \ + --visibility fixtures/visibility.toml OOT DOCKET ───────────────────────────────────────── change: feature/auth-refactor - from: jj bookmark @ main - base: main@a3f7c1d - head: feature@b8e2f4a + from: git + base: fixtures/repo/base + head: fixtures/repo/head - meaning: 4 disputes detected - visibility: 1 private path, 1 embargoed until 2026-09-01 - scope: auth flow, token refresh - authors: @kriday, @agent-7 + meaning: 1 disputes detected + visibility: 1 private path(s) - dispute-01: token refresh logic (line 42) [meaning] - dispute-02: error handling (line 87) [meaning] - dispute-03: return type mismatch (line 103) [meaning] - dispute-04: secrets/.env touched by @agent-7 [visibility] + intent: secrets/.env, src/lib.rs + authors: @you - verdict: ▶ ADJUDICATED. 1 requires review, 1 cloaked + dispute-01: both sides changed `login` (src/lib.rs:1) [meaning] + dispute-02: private path secrets/.env touched by @you (secrets/.env) [visibility] + + verdict: ▶ CLOAKED . 1 requires review, cloaked embargo: patch held for maintainers until 2026-09-01 [a]ccept · [r]eject · [d]ocket ``` -If a dispute crosses policy, Oot blocks the change or cloaks the private parts. If the change is a security fix, Oot can hold it under embargo and distribute it quietly to maintainers before the diff goes public, the way the Git project and GitHub Security Advisories already do manually ([OSSF guide](https://github.com/ossf/oss-vulnerability-guide), [Git embargo process](https://www.kernel.org/pub/software/scm/git/docs/howto/coordinate-embargoed-releases.html)). +This run exits 1 because the change touched `secrets/.env`, a private path, so it gets cloaked. Exit code 0 means the verdict was `adjudicated`; every other verdict is nonzero, so CI and agent loops can gate on it. + +If a dispute crosses policy, Oot blocks the change or cloaks the private parts. If the change is a security fix, Oot can hold it under embargo until a date you set in the policy, the way the Git project and GitHub Security Advisories already do manually ([OSSF guide](https://github.com/ossf/oss-vulnerability-guide), [Git embargo process](https://www.kernel.org/pub/software/scm/git/docs/howto/coordinate-embargoed-releases.html)). Detection and enforcement ship today; quietly distributing held patches to maintainers is still on the roadmap. ## Where Oot sits -- **Storage is someone else's job.** Oot reads snapshots from git or Jujutsu. It never owns the repository. +- **Custody, then interchange.** Oot keeps its own history in `.oot/`, a native store whose unit is the change. Git is the export target: an unfiltered export reproduces every original commit SHA, byte for byte (pinned by the round-trip tests), while adapters still read snapshots straight from git and Jujutsu. - **Execution is content-addressed.** The engine takes byte blobs and works on the parse tree. It never assumes a checked-out working tree, so it runs inside an agent's memory isolate and an agent in a worktree cannot hold `main` hostage. - **Cryptography is delegated.** Actual encryption goes to git-crypt or a hosted key service. Oot owns the policy and the gate, not the math. ## Status -Working seed — the engine runs, the docket renders, and git + Jujutsu ingestion are in-memory. Current focus: using Oot to govern Oot's own changes. +Working seed. The engine runs, the docket renders, git and Jujutsu ingestion are in-memory, and the native store ships with import, record, log, status, and export. Current focus: using Oot to govern Oot's own changes. - [x] Change ingestion from git snapshots (in-memory via `git ls-tree`/`cat-file`) and materialized dirs - [x] Jujutsu ingestion (in-memory via `jj file list`/`file show`, revset resolution, first-class conflict detection) @@ -73,19 +77,31 @@ Working seed — the engine runs, the docket renders, and git + Jujutsu ingestio - [x] In-memory execution path (no materialized tree required for git) - [x] Git adapter with 3-way adjudication - [x] Jujutsu adapter with 3-way adjudication (`--source jj`, revsets accepted) +- [x] Native store: `.oot/` holds a bare git object database plus a change-id DAG (parents stored as change ids, not commit shas) +- [x] Import from git: all branches, idempotent via a sha map +- [x] `oot record`: captures the working copy as a native change, refuses no-op records +- [x] `oot log` / `oot status`: `[git]`/`[oot]` provenance tags, offset-aware dates +- [x] Export to git: byte-identical round-trip, including merge commits, binaries, unicode messages, and non-UTC offsets; signatures survive downstream of unrebuilt changes +- [x] Visibility-filtered export: changes touching private paths are withheld, kept trees rebuilt minus those paths, empty results skipped, embargoed stores refuse export entirely, every decision logged to `.oot/export-log.jsonl` Same-named definitions in one file (e.g. a `render` method on two classes) are each tracked separately: diffing matches identical bodies first, then pairs the rest, so only the definition that actually changed is reported. +Honest limits live in [TODO.md](./TODO.md) under "Deliberate cuts": nested ignore rules and negation patterns in pure-Oot projects, tags, signatures downstream of rebuilt history, gc, and more. + ## License -The adjudication runtime, the docket format, and the adapters are MIT licensed. A court that hides its deliberations is not a court, so the gate stays open. +The adjudication runtime, the docket format, the adapters, and the store with its exporter are MIT licensed. A court that hides its deliberations is not a court, so the gate stays open. -## Someday +## Roadmap Deliberately unbuilt. These need users to be worth their cost, and there are none yet. -- **Hosted intent scoring** — a model that checks what a change claims to mean against what it actually does. The structural engine catches *that* code changed; this would catch *what it means*. Needs a server, a model, and someone paying for both. -- **Embargo distribution** — the courier half of embargo: quietly shipping held patches to maintainers before the public diff drops. Needs keyed private channels and maintainer auth. The detection half already ships. +- **Working-copy update.** Materialize a stored change back onto disk, `oot update` style. Planned next; today you read history with `log` and export to git to check anything out. +- **Store-to-court adjudication.** Run the engine straight off stored changes instead of snapshots. Planned. +- **Hosted intent scoring.** A model that checks what a change claims to mean against what it actually does. The structural engine catches *that* code changed; this would catch *what it means*. Needs a server, a model, and someone paying for both. +- **Embargo distribution.** The courier half of embargo: quietly shipping held patches to maintainers before the public diff drops. Needs keyed private channels and maintainer auth. The detection half already ships. +- **Per-subtree signature reuse.** Any filtered export currently rebuilds every commit, so even clean signed commits lose signatures. Reusing unchanged subtrees would keep more of them. +- **Store gc and pruning.** The store grows without bounds today. ## Try it @@ -93,17 +109,27 @@ Deliberately unbuilt. These need users to be worth their cost, and there are non git clone https://github.com/Epoch-AI-Lab/oot.git cd oot cargo build --release -# materialized dirs + +# adjudicate a fixture change (exits 1: the fixture touches secrets/.env) ./target/release/oot adjudicate --change feature/auth-refactor --base fixtures/repo/base --head fixtures/repo/head --visibility fixtures/visibility.toml + # or 3-way git (in-memory, no checkout) ./target/release/oot adjudicate --change feature/auth-refactor --base-ref main --head-ref feature/auth --repo . + # or 3-way jujutsu (revsets welcome) ./target/release/oot adjudicate --source jj --change greet --base-ref 'bookmarks(exact:main)' --head-ref '@-' + +# or skip snapshots entirely: keep history natively in .oot/ +./target/release/oot init +./target/release/oot status +GIT_AUTHOR_NAME=you GIT_AUTHOR_EMAIL=you@example.com ./target/release/oot record -m "first change" +./target/release/oot log +./target/release/oot export --out exported # auto-applies ./visibility.toml when present ``` ## Contribute -We need people who have been burned by the primitives Oot sits above: +We need people who have been burned by repository-level permissions, leaked diffs, and clean merges that ship bugs: - **VCS adapter authors** who know git and Jujutsu internals and can turn snapshots into Changes. - **Policy people** who have run embargoed releases and know where the process leaks. diff --git a/TODO.md b/TODO.md index 9c58c48..ecde882 100644 --- a/TODO.md +++ b/TODO.md @@ -298,7 +298,7 @@ court; the declared direction is that it becomes the source control itself." ## Night-run status - [ ] PR-O1 fix/rename-rename-dispute -- [ ] PR-O2 docs/positioning +- [x] PR-O2 docs/positioning - [ ] PR-O3 feat/store-court - [ ] PR-O4 feat/oot-update diff --git a/oot-vision-report.html b/oot-vision-report.html index 206111f..93557b4 100644 --- a/oot-vision-report.html +++ b/oot-vision-report.html @@ -153,6 +153,9 @@ +
+ Superseded 2026-08-22: Oot now keeps its own store; see TODO.md for the decision. +
diff --git a/visibility.toml b/visibility.toml index 9953128..6c6bd72 100644 --- a/visibility.toml +++ b/visibility.toml @@ -1,8 +1,16 @@ # Oot governing Oot. # -# Path fragments (substring match) that must never appear in a change's -# head snapshot. Touched paths raise High-severity visibility disputes, -# which cloak the change and exit nonzero. +# This one file feeds two consumers: +# +# - `oot adjudicate`: a change whose head snapshot touches a path below +# raises a High-severity visibility dispute. The change is cloaked and +# the run exits nonzero. +# - `oot export`: changes touching these paths are withheld entirely, kept +# trees are rebuilt minus those paths, and an active embargo schedule +# makes export refuse outright. Every decision lands in +# `.oot/export-log.jsonl`. +# +# Path fragments are matched by substring against touched paths. private_paths = [".env", "secrets/", ".pem"] # No embargo schedule for this repo yet; add `embargo_until = "YYYY-MM-DD"`