Code First
Encode lógica determinística em binário (Go/Rust); deixe lógica analítica em LLM (markdown). Múltiplas IAs (Claude, Codex, Gemini) interpretam markdown de forma sutilmente diferente — binário garante resultado idêntico cross-LLM. Stack hoje tem ~10% binário e ~90% markdown — invertido. Esta policy é expansão do princípio #3 de `policies/stack-principles.kmd`.
Encode the deterministic in code; leave the analytical to LLM. The default has been markdown; this policy inverts it where appropriate.
When this applies
Always — every time a command, audit, validator, sync, parser, or generator is being created or extended.
Why
Three LLMs (Claude, Codex, Gemini) interpreting the same markdown command will produce sutilmente diferente results. For mechanical operations this is a bug — not a feature. Binary tools eliminate the variance.
Concrete examples of past divergence in this Stack:
/k-commitstep "version bump" interpreted differently per LLM (somebumped patch, some bumped minor for the same change)
/k-parityPhase 2 "feature scan" produced different feature listsdepending on which heuristic the LLM picked
/k-test-gen-*(21 commands) generated subtly different test scaffolds
Token economy (secondary motivation)
Beyond determinism, every operation that lives in a binary is an operation the LLM no longer pays for. A markdown phase that an agent re-reads, re-interprets and re-executes on every invocation costs tokens per session. Promoting that phase to a binary collapses the recurring cost to a one-time cost (writing the binary) plus a constant (invoking it). For pipelines run dozens of times per week — /k-commit, /k-housekeep, /k-test, /k-audit — the savings compound across sessions and across LLMs.
This is a secondary motivation: determinism is the primary reason to promote, token economy is the multiplier that makes the case obvious in borderline situations (an algorithm that is almost deterministic with one analytical step still wins by extracting the deterministic core to a binary). When sizing a candidate, weigh both — drift cost plus per-session token cost — against the one-time cost of writing the binary.
Decision tree
Apply when scoping a new command or expanding an existing one:
| Question | Answer | Implementation |
|---|---|---|
| Input fixed → output fixed? | yes | binary (Go/Rust) |
| Stable heuristic with explicit rules? | yes | binary with config |
| Requires analysis / creativity / context / priority? | yes | LLM via markdown |
| Mix of the above? | mixed | LLM orchestrates binaries |
Rule of thumb: if you can write the algorithm in pseudocode without "and then the LLM decides", it's deterministic — make it a binary.
Inventory — current binaries (Stack today)
These already follow Code First:
| Binary | Purpose | Source |
|---|---|---|
koder-test-gate |
Regression test enforcement | dev/koder-tools/cmd/koder-test-gate |
koder-stackdoc |
Sync deep-dive docs from code | dev/koder-tools/cmd/koder-stackdoc |
kicon |
Generate icon variants per platform | products/dev/kicon |
khub |
Hub CLI client | products/dev/hub/cli |
Inventory — candidates to migrate
These are markdown commands with deterministic logic that should become binaries (proposed in ticket KSTACK-101):
| Candidate | Effort | Reason |
|---|---|---|
koder-spec-audit |
1d | Engine for /k-audit family |
koder-commit |
1.5d | Mechanical phases of /k-commit (linttestbuildcommittagreleasepush) |
koder-manifest |
1d | Parse UI → JSON for /k-test-gen-* |
koder-parity-scan |
0.5d | Feature scan logic of /k-parity Fase 2 |
koder-housekeep |
1d | Orchestrator for /k-housekeep |
koder-test-gen |
3d | Unify 21 /k-test-gen-* commands |
koder-backup |
1d | Wave-mode runner for /k-backup (discover repos → for each: commitsynccleanuptarverifyuploadpost-verifyrotatecleanup). Totalmente determinístico — bug histórico (2026-05-13): IA executando markdown gerou tar vazio por cd errado e não abortou em §6.3 mismatch que o spec exigia |
Anti-patterns
Don't:
- Default to markdown — the default has historically been markdown.
The decision now should be: "is there a reason this can't be a binary?" If no reason, make it a binary.
- Encode "if the LLM thinks it should…" — that's analytical.
Either write a deterministic rule or accept LLM variance.
- Bury determinism inside markdown narrative — if the spec includes
"for each X, do Y if Z", that's pseudocode → it's a binary.
Do:
- Prototype in markdown when shape is unclear. Markdown is fast to
iterate; binary is fast to repeat.
- Promote to binary when stable — 3+ uses without changes ≈ ready.
- LLM orchestrates binaries — the LLM-facing surface stays
declarative ("call koder-X with these args"), but the work is binary.
Conflicts
See policies/stack-principles.kmd §3 for resolution heuristics with:
- Divide and Conquer (no conflict — they compose: 3+ deterministic uses → binary)
- Velocidade de prototipagem (prototype markdown; promote when stable)
Audit
/k-audit code-first (futuro, parte do ticket KSTACK-101) executa esta policy em modo advisory:
- Walks `metacontextcommands