rust-port
Skill0 starsChanged 13 days agoMITView on GitHub
Loads for any design, planning, spike, or implementation work on porting the cc-candybar daemon to Rust — a request that says "rust port", "rewrite in rust", "rust daemon", "port the var-system / template engine / rich text to rust", "reactive_graph", or the memory diagnosis that precedes the port (vmmap, V8 heap statistics over time, why RSS breaches). It carries the port's hard boundaries, the design-first workflow per component, the phase sequence with its exit criteria, the parity and licence gates, and what "done" means; the reasoning and the facts live in design-docs/RUST-PORT.md. It is not for ordinary work on the TypeScript daemon or on the existing rust-client — those need no port context, and loading it would frame a bug fix as port work.
7 other projects use a version of this.
Adopted by
Most recently taken up by
- XGENT-ai/skillstheir own version, first seen Nov 8, 2026
- po4yka/rust-skillstheir own version, first seen Nov 8, 2026
- weedmo/skillstheir own version, first seen Nov 8, 2026
- kabudu/engineering-agent-skillstheir own version, first seen Nov 1, 2026
- fedemelo/agent-configtheir own version, first seen Nov 1, 2026
- tuan3w/herdr-mobiletheir own version, first seen Nov 1, 2026
Used with
Projects with it also use rust-review and rust-best-practices.
Other files people use alongside this one.
Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
CloudflareSkillrust-review
Rust code review for workerd. Covers CXX FFI safety, unsafe code patterns, JSG resource conventions, error handling, and a review checklist adapted from the C++ review skills. Load this skill when reviewing Rust code in src/rust/.
Also in 6 projects that use this
MicrosoftSkillrust-best-practices
Guide for writing idiomatic Rust code based on Apollo GraphQL's best practices handbook. Use this skill when: (1) writing new Rust code or functions, (2) reviewing or refactoring existing Rust code, (3) deciding between borrowing vs cloning or ownership patterns, (4) implementing error handling with Result types, (5) optimizing Rust code for performance, (6) writing tests or documentation for Rust projects.
Also in 4 projects that use this
Other versions7 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 7
- morganlinton/BeautifulRust★ 1.8ksame name
- tuan3w/herdr-mobile★ 29same name
- po4yka/rust-skills★ 5same name
- fedemelo/agent-config★ 4same name
- kabudu/engineering-agent-skills★ 3same name
- weedmo/skills★ 1same name
- XGENT-ai/skills★ 1same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
The file
We split this skill into the rules it gives an agent
4 rules. 0 are common, 2 are distinctive, and 2 are very specific to this project.
0
Common
Most of the 7 edited versions we read keep these.
2
Distinctive
This author's own choices. Worth a look.
2
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 18
The laws carry over verbatim: Every [LAW:…] in CLAUDE.md is cited inline in Rust exactly as in TS: // [LAW:one-source-of-truth] reason, or …
- Distinctive: line 25
Before writing Rust for a module:
- Distinctive: line 27
Read the TS module AND its tests.
- Very specific: line 28
Write the Rust type shapes first.
“Common” is measured: kept by at least 6 in 10 of the 7 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Porting the daemon to Rust
The doc is the source of truth
design-docs/RUST-PORT.md holds every fact and every reason. Read it first — Summary, then the sections your work touches (Component map before any crate, Reactive runtime before the store, Sequencing before claiming a phase is done). This skill holds workflow and hard constraints, never the doc's reasoning — and neither do you. When a decision changes, edit the doc — Open questions for a spike's outcome, the section that carries the fact otherwise — in the same PR as the code. A skill that argues with the doc is drift; the doc wins, and you fix the skill.
Boundaries — the lines nothing will re-ask
The code you build keeps reminding you of the destination and never of these.
- Behaviour-preserving. Same socket path (
/tmp/cc-candybar-$UID/socket), same wire format and protocol version, same config files and resolution order, same rendered bytes for the same payload. A feature change or a TS bug fix is a separate ticket on the TS daemon FIRST, then ported. It is never smuggled into the port. - Permissive licences only. MIT, Apache-2.0, BSD, Zlib, MIT/Apache dual. Before adding any crate, read the licence from the crates.io licence field and record it beside the dependency. GPL, LGPL, MPL, AGPL, and unlicensed are refused — no "it's only a build dep", no exception.
- The laws carry over verbatim. Every
[LAW:…]in CLAUDE.md is cited inline in Rust exactly as in TS:// [LAW:one-source-of-truth] reason, or// [LAW:…] exception: reason. A ported module that dropped its law markers is not ported. - The TS daemon keeps shipping through phase 3, fixes and releases as before. Nothing in
src/is deleted or degraded during phases 0–3. - No parallel renderer, ever. At cutover the TS daemon is deleted, not kept as a fallback. Two renderers is what every law in this repo exists to prevent.
- Phase N+1 does not start until phase N's exit criterion is met and recorded in
Sequencing. A phase you feel is done but have not written down is not done.
Design first, for every component
Before writing Rust for a module:
- Read the TS module AND its tests. The tests are the behaviour; the module is one implementation.
- Write the Rust type shapes first. Every discriminated union becomes an
enum, its arms enumerated from the TS TYPE, never from the TS control flow.Presence = present | absent | Unchecked{path,error}becomes an enum with three arms and everymatchover it is total — no wildcard arm, nounreachable!(). - For any predicate or parser, write the accept/reject table before the function.
- Name which law each type enforces, in its doc comment.
- Only then implement.
What the port preserves and Component map say which modules exist and what each guards; this list is the order you do them in.
The three libraries (phase 1)
Three crates, per Component map: styled text and colour (from rich-js — OKLCH lives there, the daemon keeps no colour math), the template engine (from go-template-js, an own port: Go syntax, an opaque styled-text value flowing through typed functions — Template engine records why no existing crate fits), and the reactive runtime (the MobX subset). The maintainer has ported the first two once already; the runtime is the one with a real decision in it.
The reactive runtime
The MobX surface is five primitives — signal, keepAlive computed, reaction, runInAction, createAtom — in three files: src/var-system/store.ts, src/var-system/sources.ts, src/daemon/session-state.ts. The doc's Reactive runtime section and its Translation points carry the mapping onto reactive_graph and the own-runtime alternative; this skill does not repeat them, so they cannot drift.
A phase-1 spike decides between the two on those translation points, and its outcome is written to the doc's Open questions. keepAlive-style caching with zero observers is verified by a test before any code relies on it. Do not skip the spike because one option "seems obviously fine".
Workflow
Git, every time: clean tree; main at 0 ahead / 0 behind, or stop and report the state; branch; commit the finished work; push; open a PR — and address the PR's reviews in the same response as opening it. Run lit quickstart first; each phase is an epic, each component a child ticket; a ticket closes when merged, never when green.
Verification
cargo testper crate, and the Rust counterpart of each TS test the component had.- The byte-parity gate (phase 2 exit). Drive BOTH daemons over isolated sockets with the same request JSON and diff the response bytes. Isolation:
CC_CANDYBAR_SOCKETset to a short path (under 104 chars), each daemon's PID captured at spawn and killed by PID (never by socket lookup), export + spawn + verify + kill in ONE shell call, and the user's real daemon never touched. - Memory. RSS over time under the maintainer's real session count — the live daemon, not a synthetic render loop.
Phase 0: diagnose before you justify
Why rewrite names the reason; the measurement decides whether it is true. vmmap the live daemon and sample v8.getHeapStatistics() / process.memoryUsage() over time. The exit criterion is the doc's Sequencing phase-0 entry, in full, not a paraphrase. If most resident memory is file-backed pages or subprocess churn, a port reproduces it — which is why this comes first.
Temptations, rehearsed
- "Keep the TS daemon as a fallback for a release or two." That is a parallel renderer with a shutdown date nobody will honour. Delete it at cutover.
- "The reviewer says this crate is unmaintained; the maintained one is MPL." Refused. Write the code or find a permissive crate.
- "This union has five arms in TS but only three are reachable; I'll model three." Model five. The type is the program; reachability is today's control flow.
- "I found a TS bug; I'll fix it in the Rust version only." Ticket on the TS daemon first, then port the fix. Otherwise the parity diff lies.
- "The parity diff is one byte of whitespace, close enough." One byte is a different terminal cell. The gate is byte-equal.
- "The Go spec has this template feature; the DSL doesn't use it, but I'll add it." The engine serves the config DSL, not the spec. Port what the tests pin.
Done
A phase is done when its Sequencing exit criterion is met AND recorded in the doc. The port is done when the doc's Sequencing phase-4 exit is met, in full, as written there. Short of that, report the phase and its state; do not call it done.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

