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 category field in every koder.toml. Drives the obligation rule for the [self_hosted] block (policies/self-hosted-first.kmd § Anti-drift heuristic) and the per-category audit selection in policies/reuse-first.kmd sub-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_kit ships a Flutter framework + a developer-facing CLI) declares category for the dominant consumer pathway. The other surface gains a child koder.toml if 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 category and never updating when the module's role changes. An audit pass on rename/move events is recommended.
  • Using category to 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):

  1. If category present, value is in the enum.
  2. If category ∈ {engine, infra-tooling} AND a [self_hosted] block exists, the block's required fields (replaces, status) are populated.
  3. If category ∈ {engine, infra-tooling} AND [self_hosted] is absent, emit advisory warning (Phase 4) or strict error (Phase 5).
  4. The TOML is syntactically valid (tomllib parse).

10. Relationship to other policies

Referências