This document states the discipline layer for the public v0.1.0 release. These rules exist so the docs, tests, runtime behavior, and mounted admin seam stay aligned.

Principles

  • Runtime decisions must be deterministic for the same inputs
  • Rules are evaluated in order, and first match wins
  • Tenant and environment scope must be explicit, not ambient
  • Merge-blocking tests should prefer fake-backed workflows over live infra
  • Telemetry and audit paths must not carry raw PII by default

Determinism

Evaluation should produce the same result for the same flag definition, context, and snapshot. Sticky bucketing depends on stable inputs, so callers should provide explicit targeting identity instead of relying on hidden process state or request-global magic.

Precedence

Rulesets are ordered documents. The first rule that matches controls the decision; the default value applies only when no rule matches. Documentation, tests, and operator workflows should describe precedence in that order rather than implying score-based or merge-based behavior.

Tenancy and environment scope

Scope is always carried through explicit inputs such as tenant_key, environment, and host-provided session/query values. Do not assume cross-tenant defaults or implicit environment switching. If a host app mounts rulestead_admin, preserve the documented ?env= query convention and provide the session values the package expects.

Testing posture

The default test posture is fake first. Use Rulestead.Fake and the published test helpers for merge-blocking coverage, then layer integration tests on top when a seam specifically needs real framework proof. This keeps runtime tests fast, reproducible, and independent of live database setup on the hot path.

Privacy and redaction

Telemetry and audit output should describe what happened without leaking raw traits, actor payloads, or secrets. The public telemetry contract is documented in guides/flows/telemetry.md; treat its bounded metadata spine and redaction rules as the default for adjacent instrumentation and operational docs.

Mechanical guardrails

These conventions are backed by existing enforcement, not just prose:

  • custom Credo checks already block raw trait keys in telemetry metadata
  • custom Credo checks already block raw trait keys in logger metadata
  • custom Credo checks already push evaluation entrypoints through the intended context boundary

When you change a public-facing seam, update the docs and tests in the same change so the contract remains auditable.