koder.toml — `category` field
koder-toml specs/koder-toml/category.kmd
Top-level `category` field in `koder.toml` placing each module in one of six canonical buckets. Drives the anti-drift heuristic for `policies/self-hosted-first.kmd` and unlocks per-category audit rules. Defined by `policies-RFC-002-self-hosted-first.md` Phase 4.
Corpo da especificação
Spec — koder.toml top-level category field
Normative schema for the top-level
categoryfield in everykoder.toml. Drives the obligation rule for the[self_hosted]block (policies/self-hosted-first.kmd § Anti-drift heuristic) and the per-category audit selection inpolicies/reuse-first.kmdsub-policies.
1. Where the field lives
Top-level scalar in koder.toml, alongside [package], [app], [backlog], etc.:
# koder.toml
category = "engine"
[package]
name = "koder-lang"
version = "7.28.0"
…
[backlog]
prefix = "LANG"
[self_hosted]
…
The field is declarative: it does not affect build behaviour. Tooling that consumes koder.toml (koder-spec-audit, khub, kicon, etc.) reads it to decide which audits and rules apply.
2. Schema
| Field | Type | Required | Notes |
|---|---|---|---|
category |
enum string | optional in Phase 4; required in Phase 5 (koder-spec-audit self-hosted --validate strict) |
One of the six values in §3 below. |
The field is at the top level of the TOML document, not inside any table.
3. Enum values
Six canonical buckets. New buckets require an RFC amendment.
| Value | Meaning | Examples |
|---|---|---|
product |
End-user product (UI + business value). Covers UI apps, mobile apps, web apps, CLIs/TUIs whose primary audience is humans, and landing pages. | products/horizontal/talk, products/vertical/edictus, products/dev/hub, products/dev/kterm |
engine |
Embeddable component imported and executed inside other modules. Native code with hot paths, ML runtimes, codecs, language runtimes, parsers. | engines/kodec, engines/lang/lang, engines/lang/kvg, engines/sdk/koder_kit (the Flutter framework counts as engine, not lib, when the consumer embeds it) |
infra-tooling |
Operationally-deployed component or build-time tool that the Stack runs / consumes (web servers, schedulers, registries, build CLIs, audit binaries). | infra/net/jet, products/dev/kicon, products/dev/koder-tools/cmd/*, infra/observe/jet, infra/data/kdb/next |
runtime-lib |
Embeddable library callable from product/engine code at runtime (not embedded as a framework). Typically distributed as a language SDK. | engines/sdk/go, engines/sdk/js, engines/sdk/python, engines/sdk/rust |
protocol |
Wire format / message envelope / on-disk schema definition module (proto files, kpkg.toml schema, federation handshake, etc.). | engines/sdk/koder_ipc, engines/sdk/koder_chat, engines/sdk/store, products/dev/hub/depot/proto |
sdk-binding |
Language-specific binding to a multi-language SDK (FFI wrappers, generated clients). | engines/kodec/bindings/go, engines/sdk/koder_kit/lib (when the host SDK is multi-language) |
Edge cases. A module with both engine and product surfaces (e.g.
engines/sdk/koder_kitships a Flutter framework + a developer-facing CLI) declarescategoryfor the dominant consumer pathway. The other surface gains a childkoder.tomlif the path layout already supports sub-modules.
4. Obligation rule for [self_hosted]
When category ∈ {engine, infra-tooling} AND the module has a non-Koder external alternative that products of the Stack might otherwise reach for, the [self_hosted] block defined in policies/self-hosted-first.kmd is mandatory.
Decision tree:
category = engine | infra-tooling ?
├── no → [self_hosted] is optional (declare anyway if module has an external counterpart)
└── yes → does an external alternative exist that products would otherwise use?
├── no → [self_hosted] is optional (no decision to govern)
└── yes → [self_hosted] is REQUIRED with at minimum:
• replaces (non-empty list)
• status (enum)
• gates_passed and gates_pending (may be empty arrays)
koder-spec-audit self-hosted --validate <module> enforces this in Phase 5. In Phase 4 (where this spec lands), the rule is advisory — the audit warns but does not fail.
5. Mandatoriness timeline
| Phase | Field state | Audit behaviour |
|---|---|---|
| Phase 4 (this spec) | Optional; documented for opt-in adoption | koder-spec-audit self-hosted --validate warns when missing |
| Phase 5 of RFC-002 | Mandatory for all koder.toml files |
Audit fails build when missing |
Backwards-compatible: existing koder.toml files without category continue to work; the audit warns but does not block.
6. Sticky retrofit policy
When a koder.toml is touched for any reason during Phase 4, the toucher SHOULD add the category field if it's missing. By Phase 5 the field is required, so opportunistic adoption smooths the transition.
7. Examples
Engine with self-hosted block
category = "engine"
[package]
name = "koder-lang"
version = "7.28.0"
[backlog]
prefix = "LANG"
[self_hosted]
replaces = ["rust", "go", "c", "c++"]
status = "stable"
gates_passed = ["feature_parity:hot_path_lib", "performance:hot_path", "production_proven:kodec"]
gates_pending = ["capability:c_linking", "capability:async_runtime", "production_proven:beyond_kodec"]
Infra-tooling without external alternative
category = "infra-tooling"
[app]
slug = "koder-lock"
[backlog]
prefix = "LOCK"
# No [self_hosted] block — the tool is Koder-internal,
# no external counterpart to govern.
Product (no obligation; declared anyway for clarity)
category = "product"
[app]
slug = "kterm"
name = "Koder Term"
version = "1.3.2"
[backlog]
prefix = "KTERM"
# No [self_hosted] block — kterm IS the product, not a tech-stack
# decision being weighed against an external alternative.
8. Anti-patterns
- Declaring
categoryand never updating when the module's role changes. An audit pass on rename/move events is recommended. - Using
categoryto encode multiple concerns (e.g.category = "engine-runtime-lib"). The enum is exclusive; sub-modules are the escape hatch when a module genuinely spans buckets. - Setting
category = "engine"on a Flutter app to game the obligation rule into requiring[self_hosted]. The category reflects the dominant consumer pathway, not a desired audit outcome.
9. Validation rules (enforced by audit)
koder-spec-audit self-hosted --validate (or koder-spec-audit koder-toml --validate):
- If
categorypresent, value is in the enum. - If
category ∈ {engine, infra-tooling}AND a[self_hosted]block exists, the block's required fields (replaces, status) are populated. - If
category ∈ {engine, infra-tooling}AND[self_hosted]is absent, emit advisory warning (Phase 4) or strict error (Phase 5). - The TOML is syntactically valid (
tomllibparse).
10. Relationship to other policies
policies/self-hosted-first.kmd— consumes this field for the anti-drift heuristic and the obligation rule.policies/reuse-first.kmd— sub-policies underpolicies/reuse/apply per-category; thecategoryfield is the structured route to "which sub-policy governs this module".meta/docs/stack/rfcs/policies-RFC-002-self-hosted-first.md§5 — RFC migration plan; this spec is Phase 4 product.
Referências
meta/docs/stack/rfcs/policies-RFC-002-self-hosted-first.mdpolicies/self-hosted-first.kmdpolicies/reuse-first.kmd