Skip to content

docs(atlas): truffle states its own design intent, graded by Project Atlas - #215

Merged
jamesyong-42 merged 6 commits into
mainfrom
atlas/dsl
Oct 29, 2026
Merged

jamesyong-42 merged 6 commits into
mainfrom
atlas/dsl

Conversation

@jamesyong-42

@jamesyong-42 jamesyong-42 commented Oct 17, 2026 •

Copy link
Copy Markdown
Member

Summary

Truffle's design intent was stated only in prose: CLAUDE.md, the RFCs and the crate docs. Nothing checked that the code still matched it. This PR adds an architecture atlas that Project Atlas grades against the code, plus guidance so agents keep it current. Please squash-merge with a docs(atlas): title so these documentation changes do not trigger a release.

Design checks

  • Protocol 10 (feat(core,sidecar): app capabilities in WhoIs, key expiry and sidecar exit events (protocol 10), bridge fixes for media streams #218) added Node::bridge_stats(), which returns BridgeStats from the private bridge module and broke bridge-is-private. That rule now has one sanctioned except. It names only BridgeStats and cites the module doc that makes the type public.
  • Seven accepted decisions that nothing confirmed are now confirmed by 15 new rules (RFC 003, 010, 013, 017, 022, 023 and 025). Two more rules guard the release scripts. 15 of the 23 decisions now verify, up from 8.
  • bench-keys-from-env now checks "never argv" in every bench argv parser. windows-key-press checks that both key readers filter Press.
  • A regression run broke the code once per new or tightened rule. All 17 rules it covered turned red, along with the decisions they confirm, and nothing else changed.
  • one-release-unit stays unconfirmed on purpose. truffle update, the auto-update and the install scripts install the CLI archive's sidecar with no checksum, and truffle-sidecar falls back to sidecar-slim on PATH at runtime. Both go against the release contract in docs/RELEASING.md. A comment above the decision records this until it is fixed or the contract is narrowed.

What lands

  • atlas/*.atlas:
    • Layers: RFC 012's stack, exhaustive.
      • truffle-core's modules are the tiers for Layers 3-6 under the Node API.
      • The apps, bindings, CLI and benchmark hub are Layer 7, and the Go sidecar is Layer 1.
      • Truffle Swift sits outside.
    • 15 domains, 23 components and runtime links, the wire and seam contracts, and 4 flows with 27 steps: discovery, send, file push and synced-store update.
    • Rules: 44, each citing the RFC, CLAUDE.md, README or code comment that states it (see "file#slug", resolved by the check).
    • Decisions: 23, with their real status. Some differ from their RFC headers, and the because says so.
  • @atlas comment lines only; no code changes (+72 lines, 0 deleted, in 20 source files):
    • Contracts: at their trait or enum.
    • Flow steps: above the function that does each step.
    • Unpublished crates: placement and single-crate rules at their roots.
    • crates.io crates (truffle-core, truffle, truffle-sidecar) carry no //! atlas text, so docs.rs shows nothing new.
  • CLAUDE.md "Atlas" and .claude/skills/atlas/SKILL.md:
    • place new code in the same change, and fix selectors on renames;
    • never weaken a rule: an except or a wider only list is the owner's call;
    • the check command; atlas commits are docs:/chore:.
  • atlas/atlas.baseline.json records today's findings as known, so check exits 0 and a new violation stands out.

Findings kept visible for a decision (7 claims, all known in the baseline):

  • layers-point-down and network-knows-no-upper-layer: the NetworkProvider egress verbs and tailscale::provider name egress types, which sit in the Node API tier.
  • layers-point-down and transport-knows-no-session: transport::websocket imports session::hello. That is the RFC 017 §8 hello inside the WebSocket handshake, which RFC 012 §3.4 calls transport-level.
  • apps-use-node-api: 66 imports from truffle-cli, truffle-napi, truffle-tauri-plugin and truffle-bench into Layers 3-6. Most are types Node's own API returns. RFC 015 §3 (bindings wrap Node<TailscaleProvider>) and RFC 027 prescribe some of them, so those RFCs and RFC 012 §3.1 disagree.
  • sync-wire: SyncMessage::Clear is consumed but never produced. RFC 025 §3.5 changed its role.
  • The layered-architecture and synced-store decisions, through the claims above.

Type of Change

  • 🐛 Bug fix (non-breaking change that fixes an issue)
  • ✨ New feature (non-breaking change that adds functionality)
  • 💥 Breaking change (fix or feature that would cause existing functionality to change)
  • 📝 Documentation update
  • 🔧 Refactor / chore (no functional changes)
  • 🔒 Security fix

Checklist

  • I have tested these changes locally: atlas check on adc42a5 (main 0.7.24 plus this atlas) gives 630 claims (590 verified, 33 asserted, 7 violated, 0 new, 7 known), 0 dangling, 0 ambiguous, 0 stale, and 100% layer and domain coverage of 90,142 production lines. The intent parser reports 0 errors and 0 warnings; all seven known findings retain their original counts.
  • I have added/updated tests for the changes (if applicable): n/a, comments and docs only.
  • I have updated documentation (if applicable)
  • Final-commit CI is green on adc42a5: Rust tests and doctests on Linux, macOS and Windows; live-network regressions; JavaScript checks; Clippy, rustdoc and cargo-deny; CodeQL. CI, live-network tests, CodeQL.
  • cargo fmt --check and git diff --check pass. The citation-fix commit passed the repository pre-commit hook.

Additional Context

  • The dependency graph and cargo-deny policy exactly match main. Main's #222 fixes RUSTSEC-2026-0385 and RUSTSEC-2026-0386 with ctutils 0.4.5 and Tokio 1.53.3. The original deterministic failure was not rerun; the rebased commit passed cargo-deny.
  • Three source-line citations were refreshed after rebasing onto main; all 23 line-based citations still point to the original evidence. The atlas rules and baseline are unchanged.
  • Atlas validation includes the workspace Rust documentation build with TRUFFLE_SIDECAR_SKIP_DOWNLOAD=1; it reports no Rust documentation build errors. The tool stores its build artifacts in its own cache.

🤖 Generated with Claude Code


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.

jamesyong-42 and others added 5 commits October 29, 2026 10:15
…Atlas

What the code cannot say about itself now lives in truffle and is graded
against the code: the RFC 012 layer stack (truffle-core's modules as tiers,
applications at Layer 7, the Go sidecar at Layer 1, Truffle Swift outside),
domains, runtime links, contracts, four hot-path flows, dependency rules and
the RFC decisions with their real status. Every rule and decision cites
CLAUDE.md, docs/, a README or a code comment with a checked see.

- atlas/*.atlas holds the structure, placement, rules and decisions.
- @atlas comment lines only, no code change: contracts at their trait or
  enum, flow steps above the function that does each step, and placement
  plus single-crate rules at the roots of the unpublished crates. The
  crates.io crates carry no //! atlas text, so docs.rs shows none.
- CLAUDE.md "Atlas" and the atlas skill: placement duties, renames, never
  weakening a rule, the check command, docs:/chore: commit types.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`atlas baseline` records the violations the atlas found when it landed,
so `check` exits 0 and a violation an agent introduces shows as new. They
stay violated, tagged known, and the guidance lists them with their counts:

- layers-point-down, network-knows-no-upper-layer: the NetworkProvider
  egress verbs and tailscale::provider name egress types (node-api tier);
- layers-point-down, transport-knows-no-session: transport::websocket
  imports session::hello (the RFC 017 hello gate);
- apps-use-node-api: truffle-cli, truffle-napi, truffle-tauri-plugin and
  truffle-bench name Layer 3-6 types, many of them returned by Node itself;
- sync-wire: SyncMessage::Clear is consumed but never produced;
- the layered-architecture and synced-store decisions, through those.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Protocol 10 (#218) added Node::bridge_stats(), which returns BridgeStats from
the private network::tailscale::bridge module, and made the tailscale module
doc list BridgeStats among its public types. On 0.7.20 that is a new
bridge-is-private violation (node -> tailscale::bridge).

The except names the symbol, so it sanctions only edges that name
BridgeStats; any other bridge type reaching above Layer 3 still fails. It
cites the module doc line that makes BridgeStats public.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… titles claim

Eight accepted decisions had no confirmed-by, so drift in them could not go
red. Seven now have rules that fail if the code reverses them:

- rust-core-go-shim (RFC 003): shim-speaks-no-mesh-protocol
- cli-daemon (RFC 010): daemon-ipc-is-local, commands-are-daemon-clients,
  no-star-or-election
- tui-is-the-daemon (RFC 013): tui-hosts-the-daemon,
  commands-are-daemon-clients
- app-namespacing (RFC 017): hostname-from-identity, apps-isolated
- peer-handles (RFC 022): peer-handles-interned, device-id-honest,
  from-is-the-connection
- http-serving (RFC 023): serve-engine-in-go, proxy-discovery-inert,
  no-fixed-sidecar-listener
- login-scoped-nodes (RFC 025): login-gate-at-admission-and-hello,
  store-slices-bound-to-sender

one-release-unit stays unconfirmed. release-lockstep and sidecar-fail-closed
check the release scripts, but truffle update, the auto-update and the
install scripts install the CLI archive's sidecar with no checksum, and
truffle-sidecar falls back to PATH at runtime; a comment above the decision
says so.

bench-keys-from-env now forbids a key on argv in every bench argv parser (a
clap field, long name or env binding, the app's argv, the Go baseline's
flags). windows-key-press requires the Press filter in both key readers and
forbids other key kinds and other readers. The agent -> daemon spawn link
also anchors daemon/client.rs, whose auto_up path starts the daemon too.
`let $shim` names the Go shim's production code.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The sample check output, the source-only warning and the egress line
references now match 0.7.20 with this atlas. The skill also notes `let $shim`,
the one sanctioned except, the one accepted decision left unconfirmed, and
that the function-scoped text checks dangle when the function is renamed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@jamesyong-42
jamesyong-42 merged commit e981b56 into main Oct 29, 2026
10 checks passed
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.

1 participant