Design studies built on primary sources. Each one takes a concrete problem in a real codebase, works out from the code why the obvious answer is wrong, and produces a decision a stranger could audit.
| File | Purpose |
|---|---|
STANDARD.md |
The rules of the genre: evidence discipline, pedagogy, structure, checklist |
TEMPLATE.md |
The skeleton to copy when starting an article |
README.md |
This file: the map, the index, and the cross-reference graph |
articles/
README.md <- the map
STANDARD.md <- the rules
TEMPLATE.md <- the skeleton
<category>/
<slug>.md <- English, the canonical file
<slug>.ru.md <- translation, structurally identical
One level of categories. Slugs name the subject, never the project or the issue number: the case an article is built on is metadata, not identity. STANDARD.md section 5 explains why that rule earns its keep.
| Category | Holds | Articles |
|---|---|---|
api-design |
The shape of a public interface: naming, ergonomics, what the type system can enforce | 1 |
compilers-and-codegen |
Macros, transpilation, code generation, language subsets | 0 |
web-architecture |
Servers, protocols, middleware, the plumbing between them | 0 (1 pending migration) |
systems-and-runtime |
Concurrency, memory, scheduling, the layer under the application | 0 |
tooling-and-ci |
Build systems, linting, release automation, developer workflow | 0 |
correctness-and-testing |
Test design, verification, what evidence of correctness is worth | 0 |
open-source-process |
Contributing, maintainership, review dynamics, why patches stall | 0 |
A directory is created when its first article lands, not before. Categories with zero articles exist here as a taxonomy, so that a new piece has an obvious home and the collection does not drift into one folder per project.
| Slug | Category | Status | Subject | Languages | Words | Reading |
|---|---|---|---|---|---|---|
signal-mutation-api-under-dual-compilation |
api-design |
merged | How the shape of a write API for reactive state is decided by the compilation model underneath it, not by taste | en, ru | 12975 / 11512 | 69 / 68 min |
Word and reading columns are English first, then the translation. The formula and the command to recompute both are in STANDARD.md section 5; they are stated per language because a Russian text of the same article is shorter in words and slower per word.
Status vocabulary: design (analysis only, nothing built), submitted (patch open upstream), merged, rejected, evergreen (not tied to a patch at all).
| Item | Action |
|---|---|
| The hyper study, still outside the collection | Migrate to web-architecture/, reslug to a subject-based name, add frontmatter, add its Related section |
Edges use the fixed relation vocabulary from STANDARD.md section 7. Two rules: every edge is reciprocal, and every edge carries a reason. This table is where both are verified.
| From | To | Relation | Why follow it |
|---|---|---|---|
signal-mutation-api-under-dual-compilation |
hyper study (pending migration) | shares-method |
Both are small upstream changes whose difficulty lives entirely in structure rather than in code: one is blocked by a missing borrow-end in the target language, the other by a dependency cycle between crates. Read together, they are two instances of the same investigative shape. |
As the graph grows, keep it readable by preferring few strong edges to many weak ones. An edge that a reader would not actually follow is noise, and the Related section of an article is the first place a reader decides whether the collection is worth their time.
Target: the raprogramm-website repository, a Leptos 0.8 client-rendered app built with Trunk, routed by leptos_router, deployed to Firebase. The site carries a language enum (en, ru, ko, vi, zh, English as fallback), which is why the file naming in section 1 uses the same codes.
Status: built. The contract below is what the collection guarantees and what the site relies on; both sides now exist.
| Guarantee | Detail |
|---|---|
| One canonical file per article | <category>/<slug>.md, English |
| Translations discoverable by name | <category>/<slug>.<lang>.md, codes matching the site's language enum |
| Machine-readable metadata | YAML frontmatter at the top of every file, fields defined in TEMPLATE.md |
| Length metadata | words, code_lines and reading_minutes in the frontmatter of every file, per language, kept current |
| Stable identity | The slug never changes after publication; a rename is a redirect, not an edit |
| Stable section numbers | Cross-references point at section numbers, so the numbering in TEMPLATE.md is fixed |
| Self-contained markdown | No includes, no macros; images live beside the article and are referenced by bare relative file name |
| One form for code citations | Every reference to source is path:lines alone inside backticks, defined in STANDARD.md section 10.1, with the full repository-relative path in Appendix A |
| A pinned commit per article | Section 0.4 states the upstream repository and the exact commit that all of the article's citations were read at |
| One form for internal references | Sections, appendices and constraint labels are written as plain words in the fixed forms of STANDARD.md section 10.2, in the language of the file |
| Figures beside the article | <slug>-<name>.<ext>, with <slug>-<name>.<lang>.<ext> when the figure contains text, and alt text that describes the figure in full |
| Piece | Shape |
|---|---|
| Content location | scripts/sync-articles.sh copies the tree into assets/articles/ so Trunk ships it as static files, and regenerates the index |
| Index | A generated assets/articles/index.json: an array of the frontmatter blocks plus the file path, so the list page never parses markdown |
| Routes | /articles for the index and /articles/:slug for one article. A flat slug is enough because slugs are unique across the collection, and it keeps the URL free of a taxonomy that may be reorganised later |
| Rendering | pulldown-cmark compiled to wasm, with frontmatter stripped, headings anchored, a table of contents collected, and fenced code highlighted by a table-driven tokenizer |
| Code panels | A backticked path:lines citation is rendered as a button. The cited lines are cut out of the repository at the article's pinned commit when the site is published, so opening the button shows the real code, with syntax highlighting, line numbers, the cited lines marked, and a link to the repository |
| Reference buttons | section 3, Appendix B.2, C3 and their Russian counterparts are rendered as buttons that show the target's heading and a short summary of what is there |
| Figures | Relative image sources are resolved against the article's own directory, since the page URL and the content directory differ. A figure opens full screen when it is tapped and scales down to the width of a phone |
| Tables | A table scrolls horizontally inside its own box, and the first column is held at its natural width so that identifiers in it are never wrapped or truncated |
| Prefetch | The index and an article's markdown are fetched on hover and touch and kept in memory, so a route mounts with content on its first frame |
| Transitions | The platform's View Transition API, entered only once the incoming route's data has arrived |
| Homepage entry | The articles button, linking to /articles, which is also the shared element the collection title morphs from |
Nothing beyond writing in the forms of STANDARD.md section 10. A code citation is written the way it has always been written here, crates/foo/src/bar.rs:126-147 in backticks, and the code panel follows from it; there is no separate include, no snippet marker in the source repository and no second copy of the code in the article to keep aligned. An internal reference is written as the words section 2.6 or Appendix B.2 or C3, in Russian in any grammatical case, and the button follows from that. A figure is a file dropped beside the markdown and named relatively.
Two of these change what an article contains, not only how it looks. Because a reference arrives with the heading and the summary of its target, the sentence that used to remind the reader what section 2.6 established is now redundant, and so is every parenthetical re-explanation of a constraint. Cutting them is the cheapest length reduction available to an article of this genre, and it is the reason the checklist has a group for the reading surface. Because a citation opens the real lines at the pinned commit, a fenced block that merely repeats those lines is also redundant, and it was the more expensive of the two to keep honest.
Long articles with tables and fenced code are the whole content here, so the reading view is the product. Four things matter more than they will seem to at the time: word count and reading time shown on both the index card and the article header, taken from the frontmatter rather than computed in the browser; a table of contents built from the headings, because articles run past nine hundred lines; horizontal scrolling confined to code blocks and tables rather than the page; and a visible language switch on the article itself, since a translation is a sibling file and not a separate page.
The reading time is not decoration on a collection like this. An hour-long article with no stated length reads as a wall and gets closed; the same article labelled honestly, next to the twelve-minute path through it from section 0.2, gets started. Show both numbers wherever an article is listed.
- Pick the category by the question the article answers, not by the technology it touches.
- Copy
TEMPLATE.mdto<category>/<slug>.mdand fill it in, deleting the instruction comments as each section is written. Write code citations, internal references and figures in the forms ofSTANDARD.mdsection 10 from the first draft: they are what the site turns into panels and buttons, and writing them right is what keeps the article from restating itself. - Write the English file to completion before starting any translation. A translation made from a moving original never converges.
- Mirror it to
<slug>.<lang>.md, then diff the headings of the two files to confirm structural parity. - Recompute words, code lines and reading time for each language with the command in
STANDARD.mdsection 5, and write them into both the header block and the frontmatter. - Run the checklist in
STANDARD.mdsection 8. - Add the article to the index in section 3 above, with its length columns, and its edges to the graph in section 4, checking that each new edge is reciprocated in the article on the other end.