Decisions
27 decisions described. A decision is a choice made for the project, with its context, its options and what it affects.
| Decision | Date | First line | Links |
|---|---|---|---|
| Bounded neighbourhood | 2026-09-12 | Co-occurrence is accumulated per paragraph and never materialised as a full matrix. Only the fifty best neighbours of each node are kept, ranked by count then by identifier. | 50 |
| Purpose-built contract viewer | 2026-09-13 | The contract of an API is shown by a viewer the tool builds itself, rather than by the interactive API console the specification first named for OpenAPI contracts. That console weighs more than the page budget of the site, expects to fetch the specification over the network, and offers to call the API from the page; the site is static, works from the disk, keeps every page under its budget and never calls the systems it documents. | 35 |
| One familiar chrome | 2026-09-13 | The default theme looks like a wiki its readers already know, from the analyst to the architect: spaces, a tree, a breadcrumb, a title, the text, a table of contents. What distinguishes the site is not the layout but the right panel, which shows where a subject is evoked elsewhere without anyone having written those references. Four choices hold the chrome together. One type family for the text, headings included, the hierarchy coming from size and weight, and a monospace family for paths and identifiers only. Labels in plain language, "Related pages", "Cited", "Something to correct?", never the vocabulary of the pipeline. No account: the site is static and public, without avatar, profile or share button, and the top bar carries no build statistic. An accent that is rare, marking links and the current position, never a status or a decoration; the dark mode is a second palette measured on its own, not an inversion of the light one. The page reads at three widths, the tree and the blocks of the panel folding as native disclosures where the screen has no room, so that the same HTML serves a phone and a desk without a script. | 28 |
| White label by default | 2026-09-13 | The generated site carries the organisation's identity and nothing of the tool's. The name, logo, favicon, font families, corner radius, light and dark palettes, footer and additional stylesheet all come from theme.yaml, validated by the theme schema; a faulty key is reported by its path like a configuration error. The footer credits the tool only when the project asks for it (footer.credit: true, a plain link to the repository); by default nothing a reader sees names it. Font files are shipped by the project itself and bound with @font-face rules: the site emits no request to any other host. Light and dark modes follow the system preference, the reader can force one with the mode switch and the choice is remembered; without JavaScript the theme's default applies. The accent colour never carries information on its own: wherever the default theme uses it, an underline, an outline, a weight or a text carries the same meaning. | 27 |
| Reproducible builds | 2026-09-13 | Two builds of the same sources write the same bytes. Every list is sorted canonically before it is written, findings by check, source, path, line and message, entities by identifier, links by their triple, provenances by method, path and line; a step that runs in parallel sorts its results before writing them; nothing random is ever written, and the only timestamp is the at field of the build log, also the at of the build block of the model, pinned by SOURCE_DATE_EPOCH following the reproducible-builds convention. A double-build test and a continuous-integration step compare every file of two builds of the golden corpus, so that a published site can be diffed against the previous one. | 25 |
| Slots, islands and layers | 2026-09-13 | The site is a set of named slots rendered at build by components, each with a typed view model that is the contract between the generator and a theme; the published HTML carries the full content of every page. Only interactive components are hydrated: an island is served as its static markup inside an element carrying its props, and one small bundle per island, named after a hash of its content, mounts the same component on it, loaded only by the pages that use it, so that a page loads no framework code unless one of its islands needs it. Every such bundle is a classic script, never a module: some browsers refuse a module script on a page opened from the disk, and the site promises to work there; only the document viewer, imported on demand by its island, is a module. Styling is native CSS in four cascade layers, tokens, base, components and project, the project's stylesheet winning every cascade by construction. Without JavaScript the content stays reachable: mentions in native disclosure elements, the search field a plain form, the mode switch hidden. A budget of 150 kB per page is measured on every build. | 23 |
| Locale per source | 2026-09-12 | Each source declares its locale as a BCP 47 tag, defaulting to the project locale. A language is described by data, never by code: a pack holding its name, its apostrophes, its collation options, its plural suffix rules and its stopwords, which the locale selects together with the type prefixes of the profile for that language; word segmentation and collation come from the platform's Unicode implementation. The engine ships en and fr; a regional variant such as fr-CA uses the pack of its language until a plugin registers a more specific one, other languages are packs shipped by plugins, and a tag with no pack is a build error. The adding a language pack process is the path. | 22 |
| Self-hosted fonts | 2026-09-13 | A font family named in theme.yaml is not a download: the project ships its font files itself under the assets of its theme and binds them with @font-face rules in its stylesheet, and the default theme emits no request to any other host. The two families of the default theme, Instrument Sans for the text and IBM Plex Mono for paths and identifiers, ship with the site under assets/fonts/ with their licence, so that a project without a theme of its own reads in them from the disk. A test checks that no page and no stylesheet references a font host. The site therefore works from the disk, behind a proxy that reaches nothing, and without telling a third party who reads which page; the price is a folder of font files, in the site for the default families and in the configuration repository for a project's own, the white label fixture of the tool showing the layout. | 22 |
| MinHash for twin resources | 2026-09-13 | The text similarity that helps recognise the forms of one document works on extracted text, never on binary content, and never compares every pair. Each text goes to its comparison form, then to shingles of five words, then to a MinHash signature of 128 functions under a fixed seed; LSH banding, four rows per band, enumerates the candidate pairs, two signatures that share no band being never compared, so that the full matrix is never built. In auto mode the pairs estimated at 0.5 or more have their exact Jaccard index recomputed on the full shingle sets, and the finding gives the share of lines in common; a pair whose word counts differ by more than half is an inclusion rather than a duplicate and its content signal is capped. Resources are sorted by identifier before anything else, so two runs give the same result. | 21 |
| Single extraction path | 2026-09-13 | The text of an office document comes from the PDF the converter produced, never from the document's own format. A reader still opens the original file, for its native properties, but the words that enter the search index, the recognition and the comparison of twin resources are read from the PDF, page by page, with one PDF library; a PDF given as a source goes through the same reading, and a transcript, which no converter touches, gives its cues. | 21 |
| Links are authoritative | 2026-09-12 | A markdown link to another note is the strongest relation the tool knows: confidence 1.00, above anything inferred, and a frontmatter reference comes next at 0.90. What an author wrote is never overturned by what the tool recognised: the relation of a mapped section or of a typed attribute stands, inference only fills what nobody declared, and the page tells a written link from a recognised word by the way it is drawn. A link to a missing file is an error, a link to a document attaches it, a link from a note to itself yields nothing, and several links to one target are one link with several provenances. | 20 |
| Lock file for human decisions | 2026-09-13 | concordance.lock.yaml, in the configuration repository, records what a person decided and the tool must not reconsider: accepted and rejected links, merged and separated twin resources, rejected term candidates. The build reads the file the lock key names, validates it against its schema and stops on a missing or invalid one, as on a configuration error: a decision is never dropped in silence. The keyword discovery honours rejected_terms, compared on the normalised form of the language pack, and the reconciliation of twin resources the merged and separated pairs, whatever the score; the links are recorded for a later version, and the configuration validator says so. The build log counts the decisions applied. Nothing is ever written into a knowledge repository, and a decision lives next to the configuration, versioned, reviewed like any change. | 17 |
| Type-driven neighbour order | 2026-09-13 | The neighbourhood panel of a page lists neighbour types in a priority order declared per type in the profile: operations first on an API, accessed objects on a screen, what it applies to on a rule. Every displayed neighbour carries the rank of its type; unlisted types and keyword pages share the last rank, confidence decides within a group, and the panel is truncated after this ordering. A type without a declaration keeps the order by decreasing confidence. The order is profile data, never a condition in a template: the panel renders the list as received and separates the groups by rank alone. | 17 |
| Types as modules | 2026-09-13 | A type of the profile is a folder that carries everything the type needs: its declaration, its labels per interface language, its note template and, when the generic page is not enough, the components that render it. The core types are written that way and the default profile is assembled from them, so that the format the engine ships is the format a team extends it with: a project keeps its own modules in a folder its profile names, a plugin contributes modules through a contribution point of the plugin API, and the build merges them before the keys of the project profile, plugins first, refusing a module of a core type, which is extended through the profile, and two modules of one type. The site never learns a type slug: the entity page exposes the declaration of the type and every attribute of the note, declared and not, and a dedicated component for a type, an attribute or a mapped section is resolved by name, the project theme first, then the module, then the generic page, which remains correct when nothing specific is said. | 17 |
| Paginated mentions | 2026-09-12 | The first twenty mentions of an entity are in the served HTML; the rest loads from a JSON fragment specific to that entity. Never a global index. | 16 |
| Declarative profile | 2026-09-12 | The meta-model is a YAML profile validated by a schema. The engine knows only types, attributes, relations and scores. Adding a type or a relation pair is a profile change, never a code change. | 15 |
| Fonts from a third-party host | 2026-09-12 | The first draft of the theme named its font families by loading them from a public font host, as most static sites do: one stylesheet link, no file to ship. Superseded by self-hosted fonts: a page that fetches a font from another host does not work from the disk, leaks the address of every reader to that host, and contradicts the rule that the site emits no request the project did not choose. | 14 |
| Deterministic identifiers | 2026-09-12 | An entity's identifier is its source name and its relative path without extension or type suffix, slugified; a frontmatter identifier takes precedence. Never a random identifier. The identifier is the page address. | 13 |
| Findings, not failures | 2026-09-12 | A content anomaly becomes a finding, never a crash. The build fails only when the configuration says so. Every check is a pure function in a registry shared by the build and the linter, and a test enforces their parity. | 13 |
| ICU message catalogues | 2026-09-13 | Every label of the generated site goes through a message catalogue per locale in ICU MessageFormat, plurals, selections, numbers and dates expressed in the message itself, stored as JSON in the format translation platforms exchange. Message identifiers are typed from the source catalogue, so that a missing key or variable fails the build, and a test checks that every locale carries every key. Messages are resolved at build: the published HTML contains final strings and no localisation library runs in the browser; dates and numbers use the platform formatters. A project overrides any message through the labels of its theme.yaml. | 13 |
20 decisions of 27 — pagination by twenty. The Links column counts the related pages, which brings the most central decisions of the journey to the top.