Developer guide
How the workspace defends its own claims — what a gate is here, why prose that can rot is replaced by a test, and where each family of gates lives.
This tree is for somebody changing Vike Trader rather than running it. It is organised around one
idea that shapes almost every rule in the repository: a claim that can rot is either derived or
gated, never restated in prose. That is decision record 0007, whose own Status: line is the
authority for whether it still stands — this page does not carry a third copy of that word.
Why the doctrine exists
It was not a preference. Three independent measurements from the tree that motivated the gates:
- Citations. 26 of the 33 in-repo
path:linecitations were stale, and seven fully-qualified paths pointed at files that no longer existed. Git archaeology showed every one was exactly right on the day it was written.crates/vike-model/src/venue_margin_support.rsalone carried four that landed on a blank line, a};, and a doc-comment fragment. - Hand copies of a derived list. The local recipes' CI crate roster had drifted one crate behind
the derivation, the repository's own guidance file four behind, and the release workflow's third
copy six behind — while one feature lane named four features where the suite named six. Every one
of them green, because nothing checked.
xtask/src/lib.rs's header records what replaced them, and what still lives elsewhere. - Counts in prose. The library-layer settings work-list was written down as 63, then 59, and measured 77. It grew across five pull requests that each had no reason to notice, while every prose statement of it went stale.
The decisive datum is the citation one. The only path:line citations that had not rotted pointed
into frozen vendored third-party code. A line number into living code is structurally doomed — so
crates/vike-ops/tests/citation_gate.rs does not police line numbers, it bans them, and the
repair is the rot-proof form the tree had already invented on its own before any gate existed:
`crates/bridges/bybit/src/exec.rs`'s `DEFAULT_LEVERAGE`A symbol citation survives every edit a line number does not, and it breaks only when the cited thing is genuinely renamed or deleted — which is exactly when the documentation is wrong.
What a gate looks like here
Almost all of them are text-only: they walk the real tree, strip comments and string literals,
and compare two things that must not disagree. No cargo invocation, no symbol resolution, no new
dependency. crates/vike-ops/tests/settings_registry.rs is the shape the rest are modelled on, and
crates/vike-ops/tests/layer_gate.rs and crates/vike-ops/tests/local_gate_mirrors_ci.rs say so in
their own headers. They fail a pull request; they are not review comments.
Five properties recur, and they are worth recognising when you read a failure:
The five recurring properties
Gate the class, not the instance. A defect that was an advertised-but-unreachable settings
layer did not get a test for that layer — it got crates/vike-config/tests/layers_are_reachable.rs,
which drives every layer named in PRECEDENCE and panics on one with no scenario rather than
skipping it.
A ratchet where a flat ban is unavailable. settings_registry.rs's LIBRARY_PIN pins the set
of offending rows as a fixed-size array, so its declared length is the count and no prose is
allowed to be the authority. It may shrink, never grow.
Measure the blind spot; do not assume it. MAP_LOOKUP_PROVEN in the same file fails equally on
an addition, because a blind spot that is only ever an upper bound is not measured, just assumed
smaller.
A gate that walks nothing passes everything. Every walking gate carries a file-count floor. That
earned its keep immediately: layers_are_reachable.rs's first version rooted one directory too
high, the self-crate filter emptied the walk, and it failed on the floor rather than passing
vacuously.
False positives are worse than no gate, because they teach people to write exceptions. So
citation_gate.rs checks only the unambiguous subset and declines bare shorthand paths — roughly
297 such tokens — on purpose, and every exception table carries a per-row written reason.
And one rule about writing a gate: mutation-prove it, then verify the mutation actually applied. One
attempt appended its test mutation to the end of a file and landed in the #[cfg(test)] half the
gate correctly discards — it silently did nothing, and the gate stayed green.
The families
Building
The workspace, the feature lanes, the one committed cargo config, and why there is no cargo xtask alias.
CI derivation
One implementation of what CI runs, and the five gates that hold the local recipes and CI to one spelling.
Structure gates
Dependency direction, compile-time paths, and re-spelled primitives — how to read each failure.
Adding a venue
The scaffold whose work-list is derived from the tree, and the shared homes a venue consumes.
Settings gates
The environment registry, the credential-store ratchet, and the two consumption gates.
Docs gates
Six gates over prose — citations, documented defaults, documented commands, and the two indexes.
Safety gates
The gates over the kill switches, the graceful stop, the live-account lock, and every paper mount.
Supply chain
What a workflow may fetch onto a trading box, the unsafe ratchet, and the cargo deny bans table.
Release gates
The container image, the deploy layout, the release artifacts, and the public mirror.
Drift gates
The committed generated artifacts, and why the looser-looking comparison is the correct one.
Testing
The tiers: unit, property, conformance, gate, smoke, latency.
The architectural rule the structure gates enforce is explained on Architecture; how to read a settled verdict is on Decision records.
alerts.json
The persisted alert rule set — its schema, its forward-compatibility discipline, where the daemon reads and writes it, and which of its triggers a headless node can actually fire.
Building
The workspace roster, the feature lanes a default build never compiles, the one committed cargo config, and why the xtask convention is spelled differently here.