Getting to a Skeleton: The Design Interview
The previous page assumes you can already answer the design questions a
skeleton encodes. Often you canāt yet, and staring at an empty lib.rs
doesnāt produce the answers. The agent can help here too, in a different
role: before the session where it writes code, run a session where it
asks you questions.
The setup
Start a separate session with a prompt like this:
Youāre helping me design a Rust module before any code is written. Do not write code in this session. Interview me, one question at a time, about the decisions my type and signature skeleton depends on. Cover at least: the environment (std or no_std, threads or async, target platform), performance (data sizes, throughput, latency budgets, and whether zero-copy is justified by a measurement), ownership (which data lives where, for how long, and who may mutate it), failure policy (what can fail, which failures callers react to, and what may panic), and change (which sets of variants are closed, and where new implementations must plug in). Challenge vague answers. When I donāt know an answer, record it as an open spec question instead of assuming one. Stop after roughly ten to twelve questions or twenty minutes, whichever comes first. At the end, produce two lists: the decisions we made and the open questions.
Two rules while it runs:
- You answer; the agent asks. If it starts proposing code, remind it: no code in this session.
- End after roughly ten to twelve questions or twenty minutes, then require the two lists. The cap keeps the interview useful without letting it replace engineering judgment or the skeleton work.
- āI donāt knowā is a legitimate answer. It goes on the open-questions list and becomes a question for whoever owns the spec, instead of a guess buried in a signature.
From answers to skeleton
Hereās the interview that produces the SignalDecoder skeleton from the
previous page:
| The agent asks | You answer | The decision |
|---|---|---|
| How large is a signal database, and how often is it loaded? | Tens of kilobytes, once at startup. | Parse to owned data. Startup cost is irrelevant, so no zero-copy in from_dbc. |
| Who calls decode, and from how many threads? | Several reader threads, on the hot path. | decode takes &self with no interior mutability, so a decoder is shareable. |
| What happens on a frame whose id isnāt in the database? | Common; the bus carries messages we donāt model. | Option. Absence is a normal outcome, not an error. |
| Do callers react differently to different database load errors? | The config tooling shows them to a person. | An error enum with a source() chain, so the report reads as a path. |
| Is the set of signal value types closed? | Numeric only for now; strings are possible later. | An enum for decoded values. Adding a variant later is a compile-checked change. |
The skeleton on the previous page is the record of these answers. Write it, freeze it, and start a fresh session for generation: the new session receives the skeleton and its doc comments, not the interview transcript. If a decision exists only in the transcript, itās not in the spec yet.
The division of labor is the same in both sessions: the agent asks questions or fills in bodies. The skeleton is yours to write.