Skip to content

Authority model spec + remove willow-channel crate#142

Merged
intendednull merged 13 commits into
mainfrom
claude/docs-write-one-page-authority-spec-what-enforces-w-26LUm
Apr 12, 2026
Merged

Authority model spec + remove willow-channel crate#142
intendednull merged 13 commits into
mainfrom
claude/docs-write-one-page-authority-spec-what-enforces-w-26LUm

Conversation

@intendednull
Copy link
Copy Markdown
Owner

Summary

Closes #132. Addresses #118, #109.

  • Authority spec (docs/specs/2026-04-12-state-authority-and-mutations.md): documents willow-state as the single source of truth, permission tiers, event flow, the required_permission() catch-all safety, and checklists for adding new permissions/event kinds
  • Permission pre-check: extract check_permission() from apply_event(), add InsertError::PermissionDenied, gate create_and_insert() so rejected events never enter the DAG or advance the sequence number
  • Remove willow-channel entirely: delete the crate (-1,188 lines), consolidate ChannelKind enum into willow-state, decouple invite system, rewrite all client mutations to use the event pipeline exclusively, remove the dual Server+ServerState representation

Key changes

Area What changed
crates/state/src/materialize.rs check_permission() public function; apply_event() calls it; required_permission() catch-all has exhaustive variant comment
crates/state/src/managed.rs create_and_insert() pre-checks permissions before signing
crates/state/src/dag.rs InsertError::PermissionDenied variant
crates/state/src/types.rs ChannelKind enum with serde aliases for backward compat
crates/client/ (14 files) Remove willow_channel::Server from ServerEntry, rewrite mutations to event-only, decouple invite, rewrite tests
crates/channel/ Deleted
CLAUDE.md Authority model section, updated dependency graph and repo structure

Net result

43 files changed, +1,547 / -1,892 lines. ~1,400 lines of legacy code removed.

Test plan

  • cargo test -p willow-state — 166 tests pass (10 new for check_permission + pre-check)
  • cargo test -p willow-client — 68 tests pass (invite tests rewritten, test_client() uses ManagedDag exclusively)
  • cargo clippy --workspace --tests — zero warnings
  • cargo check --workspace — clean compilation
  • Zero willow_channel references in source or Cargo.toml
  • Verified by independent subagent audit

https://claude.ai/code/session_01RpQAhYK9mVQrNB3nzTayjE

claude added 13 commits April 12, 2026 17:48
Closes #132. Adds docs/specs/authority-model.md documenting that
willow-state::apply_unchecked is the sole authority boundary, with
permission tier table, catch-all variant inventory, and checklists
for adding new permissions and event kinds.

https://claude.ai/code/session_01RpQAhYK9mVQrNB3nzTayjE
The old name implied no checks were performed, but this function is
the sole authority boundary where all permission checks happen.

https://claude.ai/code/session_01RpQAhYK9mVQrNB3nzTayjE
Replace the single authority-model spec with two focused specs:
- state-authority-and-mutations: defines willow-state as sole source of
  truth, permission tiers, pre-check before event creation to prevent
  rejected events from growing the DAG, and checklists
- willow-channel-removal: migration plan to delete the legacy crate and
  consolidate all types into willow-state

https://claude.ai/code/session_01RpQAhYK9mVQrNB3nzTayjE
- Add plan for state authority pre-check (extract check_permission,
  add PermissionDenied to InsertError, pre-check in create_and_insert)
- Add plan for willow-channel removal (8 steps: move ChannelKind,
  move invite types, rewrite mutations, remove Server from client,
  rewrite join path, rewrite tests, delete crate, update docs)
- Patch channel removal spec with audit findings: Channel struct field
  differences, test breakage inventory, Cargo.toml glob pattern

https://claude.ai/code/session_01RpQAhYK9mVQrNB3nzTayjE
Authority plan: note catch-all annotation is already in place.

Channel removal plan: add step ordering diagram, serde backward
compat for ChannelKind (alias attributes), genesis_author in invite
signature, servers.rs as step 3e, explicit step dependencies,
parse_permission call site, join path approach decision, fuller
test enumeration.

https://claude.ai/code/session_01RpQAhYK9mVQrNB3nzTayjE
Extract check_permission() from apply_event() so callers can verify
authorization before signing an event. Add PermissionDenied variant
to InsertError. ManagedDag::create_and_insert() now rejects before
signing if the author lacks the required permission — no sequence
number is advanced and no event enters the DAG.

Implements docs/specs/2026-04-12-state-authority-and-mutations.md.

10 new tests: check_permission tier coverage (admin propose, non-admin
reject, granted permission, missing permission, admin implicit pass,
unrestricted events, admin-only reject) and create_and_insert
pre-check (rejection, seq stability, success with grant).

https://claude.ai/code/session_01RpQAhYK9mVQrNB3nzTayjE
Move channel kind from String to a proper enum in willow-state::types.
Uses serde aliases ("text"/"voice") for backward compatibility with
existing serialized events. Update all 22 files across the workspace:
state, client, web, worker, replay, agent, common.

Step 1 of the willow-channel removal plan.

https://claude.ai/code/session_01RpQAhYK9mVQrNB3nzTayjE
Change generate_invite() to take raw data (server_name, server_id,
genesis_author, keys, topic_map) instead of &Server. Rewrite all 6
invite tests to construct keys directly instead of via Server::new().
Update 3 call sites (joining.rs, listeners.rs, lib.rs test).

Step 2 of the willow-channel removal plan.

https://claude.ai/code/session_01RpQAhYK9mVQrNB3nzTayjE
Remove Server from ServerEntry, replacing it with server_id + name.
Delete topic_map (derived from ServerState.channels on demand).
Rewrite all mutations to use event pipeline only — no more dual
Server+event mutation. Rewrite invite join path to build ServerEntry
directly from invite data. Rewrite test_client() to use ManagedDag
exclusively. Delete reconcile_topic_map(). Replace parse_permission
to use willow_state::Permission.

14 files changed, net -214 lines removed. Zero willow_channel
references remain in crate source.

Steps 3-6 of the willow-channel removal plan.

https://claude.ai/code/session_01RpQAhYK9mVQrNB3nzTayjE
Remove crates/channel/ entirely and drop the dependency from
willow-client/Cargo.toml. The workspace uses members = ["crates/*"]
so deleting the directory is sufficient.

Step 7 of the willow-channel removal plan.

https://claude.ai/code/session_01RpQAhYK9mVQrNB3nzTayjE
Remove willow-channel from repository structure, dependency graph,
and "Adding a new permission" checklist. Update permission checklist
to reference willow-state paths.

Step 8 of the willow-channel removal plan.

https://claude.ai/code/session_01RpQAhYK9mVQrNB3nzTayjE
@intendednull intendednull merged commit 593eac8 into main Apr 12, 2026
4 checks passed
@intendednull intendednull deleted the claude/docs-write-one-page-authority-spec-what-enforces-w-26LUm branch April 12, 2026 21:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[docs] Write one-page authority spec: what enforces what

2 participants