---
title: "Invariant Principles"
---

> Documentation Index
> Fetch the complete documentation index at: https://nclsppr.github.io/project-foundation/llms.txt
> Use this file to discover all available pages before exploring further.

# Invariant Principles

These principles apply to every project, independent of its stack. Each principle defines a rule, its reason, and minimum evidence. An exception must be explicit, limited, and documented.

## P01. Understand the actual problem before you select the solution

**Rule.** Start with the users, context, constraints, risks, non-goals, and expected result. Select the technology after you understand these items.

**Reason.** An elegant solution to the wrong problem adds debt and creates no value.

**Minimum evidence.** Before the first stack decision, a short brief for an exploration or `PROJECT.md` for a durable project describes the problem, users, scope, and success criteria.

## P02. State the truth, including when it is incomplete

**Rule.** Never invent a fact, metric, customer, capability, verification result, responsibility, or production state. Clearly distinguish `current`, `target`, `experiment`, `example`, and `assumption`.

**Reason.** Plausible but false information quickly becomes a decision, commitment, or risk.

**Minimum evidence.** Important claims have a source. Unknown information and verification that cannot be completed are identified. Synthetic data is identified as synthetic.

## P03. Map the sources of truth

**Rule.** Identify one canonical source for each important concept. These concepts include the product, roadmap, architecture, contract, schema, design, configuration, operations, and decisions.

**Reason.** The term "canonical" has no value if it refers to multiple competing files.

**Minimum evidence.** `PROJECT.md` contains a source table. Derived artifacts, archives, and snapshots are identified as such.

## P04. Define one normative concept in one location

**Rule.** Do not copy a rule, command, or data that requires manual synchronization. Reference its source or automate its generation.

**Reason.** Duplicate documentation eventually contains incompatible instructions.

**Minimum evidence.** A search for the concept finds one normative source and its references. It does not find multiple editable copies. Generated files identify their source and are not edited manually.

## P05. Separate intent from reality

**Rule.** ADRs and canonical documents define intent. Code, configuration, and the environment that actually runs define the operational state. Make any difference between them visible as drift.

**Reason.** Desired documentation and an isolated local test do not prove what actually runs.

**Minimum evidence.** Before a decision or delivery, inspect the repository, worktree, versions, configuration, and, when relevant, the running process or service.

## P06. Select proportional complexity

**Rule.** Use the simplest architecture and dependencies that satisfy demonstrated constraints. Do not add a tool because it is new or because it duplicates an existing capability.

**Reason.** Each dependency creates costs for comprehension, updates, security, and operations.

**Minimum evidence.** A structural decision describes the unmet need, alternatives, and operating cost. The project can explain why each important layer exists.

## P07. Document decisions, not only results

**Rule.** Version each structural decision, including an important product decision. Record its context, alternatives, consequences, verification plan, and review conditions.

**Reason.** Without explicit trade-offs, a team repeats the same discussions or retains a decision that is no longer valid.

**Minimum evidence.** An accepted ADR exists before or with the implementation. A superseded decision references its replacement.

## P08. Respect authority and deliver a coherent work unit

**Rule.** A change includes one specific result, its tests, its documentation, and its derived artifacts. Preserve unrelated changes. Do not include opportunistic cleanup. A runbook describes a procedure. It does not grant permission to execute the procedure. An explicit target does not grant permission. Keep each external mutation, publication, or production action within the explicit authority of the task and the local policy.

**Reason.** A focused diff is easier to understand, verify, revert, and attribute.

**Minimum evidence.** The final diff matches the stated scope. Each file in the commit has a direct relation to the result. Each external mutation was authorized, and its target is identified.

## P09. Make execution reproducible

**Rule.** Specify versions, dependencies, variables, and commands for start, stop, verification, and reset. Put critical checks in a tool-neutral command that a person, an agent, and CI can run.

**Reason.** A tool-specific hook or a command known to one person is not a control.

**Minimum evidence.** A new clone can install, start, and verify the project with documented commands. Pin lockfiles and images according to the risk level.

## P10. Verify in proportion to risk

**Rule.** Verification covers the layer that changed and the affected final surface. Combine automation, inspection, and manual tests when each method provides different evidence.

**Reason.** A successful build does not prove that an interface is correct, a contract is compatible, a deployment is healthy, or restoration is possible.

**Minimum evidence.** The definition of done enables the applicable gates. The delivery report lists the commands, environments, and observed results. It does not make broader claims than the evidence supports.

## P11. Secure changes and test rollback

**Rule.** Do not store secrets in Git, logs, or conversations. Resolve the exact target before each destructive action. Back up important data before a migration, and test the restoration.

**Reason.** An untested backup, an exposed secret, or an implicit target is not a control.

**Minimum evidence.** A dedicated mechanism injects secrets. Risky changes have a checkpoint and a rollback procedure. Data changes also have restoration evidence.

## P12. Isolate experiments

**Rule.** Clearly identify an experiment. Separate it from the canonical surface. Do not use real data by default. Provide a command or procedure to remove it.

**Reason.** A prototype that silently shares production routes, data, or contracts becomes an accidental migration.

**Minimum evidence.** The experiment profile documents its purpose, owner, duration, limits, access, data, and removal path.

## P13. Design for accessibility, resilience, and actual cost

**Rule.** Accessibility, performance, error states, fallbacks, and operations are not final refinements. Design them with the product.

**Reason.** A feature is not complete if it is inaccessible, too slow, not observable, or not recoverable.

**Minimum evidence.** Define and test applicable budgets and scenarios. Depending on the project, these can include keyboard access, focus, contrast, reduced motion, mobile use, load, errors, degraded operation, health, and restoration.

## P14. Stay close to production

**Rule.** Delivery does not stop with local code. Document how to deploy, observe, back up, restore, and diagnose the project in its actual environment.

**Reason.** Production is where architecture assumptions meet dependencies, data, and users.

**Minimum evidence.** Verify the last delivered artifact or SHA on its target surface. Explicitly keep unverified external limits open.

## P15. Build a system, not a hero

**Rule.** Share context, responsibility, runbooks, and useful commands. A critical operation must not depend on one person's memory or an undocumented command.

**Reason.** Hidden knowledge increases recovery time and incident risk.

**Minimum evidence.** Each critical area has an owner, recovery documentation, and a verification path that another person or agent can execute.

## P16. Give each Markdown file a classification and an audience

**Rule.** Each maintained Markdown file belongs to the project documentation. Classify it as public, internal, reference, or archive. Keep it accessible from the catalog and Nimbus. Nimbus is the mandatory documentation engine for all projects. Another engine can supplement Nimbus but cannot replace it. A generated rendering never becomes a second editorial source.

**Reason.** An orphan file disappears from shared knowledge. Publishing all Markdown files without classification can expose runbooks, evidence, or internal information to the wrong audience.

**Minimum evidence.** `documentation.json` classifies each `.md` file exactly once. `DOCUMENTATION-CATALOG.md` provides complete navigation. The `verify` command checks the catalog, adapter, and Nimbus build. Do not edit the generated collection. A publication respects the defined audiences.

## P17. Record each delivered change

**Rule.** Add each delivered change to `CHANGELOG.md`. The entry describes the observable effect, the applicable date or version, and any required migration. Git contains the complete technical diff. The changelog provides a durable, project-oriented description.

**Reason.** A commit sequence alone does not explain what changed for users, operators, or future contributors.

**Minimum evidence.** The change is under an unreleased section or in the delivered version. The commit identifies the exact changed files. An important decision also references its ADR.

## P18. Commit and push each verified work unit

**Rule.** When a task permits changes to a Git repository that has a remote repository, commit each coherent and verified work unit. Then push it before you start other work. Push directly to the canonical branch when direct write access is permitted. If the canonical branch is protected or requires review, push to a dedicated branch for the scope. Do not keep a completed work unit only in the worktree or local history. Do not mix unrelated changes in the commit. Do not intentionally commit a state that is known to be invalid.

A default or a convenience exception cannot disable this principle. The only exceptions are a task that explicitly requires read-only or local-only work, a restriction from higher authority, no remote repository, or an external network, authentication, or platform blocker. In these cases, report the local SHA and the exact blocker. Resume the push when the blocker no longer exists.

**Reason.** Completed work that exists only locally is not visible, is fragile, is difficult to review, and cannot be reliably resumed by another person or CI. Small published work units reduce work loss, shorten reviews, and make rollback precise.

**Minimum evidence.** The commit contains one verified work unit. Its SHA exists on the expected remote branch, and the final worktree state is known. Use the canonical branch directly when its policy permits this. Otherwise, identify the remote branch and review path. Observe available remote checks before you report that delivery is complete.

## P19. Orchestrate the local environment with Docker Compose

**Rule.** Each project versions a `compose.yaml` file at its root and uses Docker Compose as the canonical path for integrated local execution. Declare the applications, databases, queues, email interceptors, storage services, proxies, and other dependencies required for local execution in this file. A command that runs directly on the host can make an internal loop faster, but it does not replace the common path. A Minimal pack with no local process can keep `services: {}`. A Standard, Full, or Critical pack declares at least one service.

Pin external images by digest. A long-running service has a health check. A finite command without a health check has the explicit label `foundation.lifecycle=job`. A default or local exception cannot disable this principle. A higher-level restriction or a platform without Docker can prevent execution, but it cannot remove the versioned contract or its CI gate. Document the exact blocker.

**Reason.** A collection of host commands and implicit versions creates different environments on different machines. It also excludes actual dependencies from verification. Compose provides a portable contract to start, wait for, diagnose, and stop the same service graph.

**Minimum evidence.** The `verify` command and CI call `scripts/check_compose.py`. The script verifies the configuration, digests, health checks, and pack. For each project that has a service, `docker compose up --build --wait` reaches a healthy state. The checks for the primary path pass. Then `docker compose down` stops the environment without deleting data by default.

## P20. Use controlled technical English

**Rule.** Use English for all deliverables, communications, documentation, code comments, logs, and other technical content. Follow the principles of ASD-STE100 Simplified Technical English. Use precise and unambiguous terms. Use short declarative sentences. Use the active voice when appropriate. Use one term consistently for each concept. Avoid unnecessary synonyms, vague language, marketing language, and unnecessary jargon. Use ISO/IEC/IEEE 24765 terminology when it applies. Preserve proper names, external identifiers, quotations, and terms that an external contract requires.

This principle does not declare formal conformance with ASD-STE100.

**Reason.** Variable or ambiguous terminology increases review time, differences in interpretation, and the risk of implementation or operation errors.

**Minimum evidence.** A review of changed content checks the use of English, term consistency, sentence structure, and unexplained jargon. If domain terminology differs from ISO/IEC/IEEE 24765, identify the canonical glossary or contract. An exception identifies the externally required term, its source, its scope, and its reason.

## P21. Emit safe, structured, and actionable log records

**Rule.** If a project emits first-party runtime log records, each log record must be structured. A runtime log record is diagnostic or operational telemetry that first-party code sends to a logging sink or writes to a stream for collection as telemetry. A defined user-facing command result and build or test progress output is not a runtime log record. If a platform collects that output as application telemetry, the platform mapping applies `P21`. Calling diagnostic telemetry console output does not exempt it from this rule. A log record represents one occurrence. Its event name identifies the stable type of occurrence.

Each log record contains the occurrence time in UTC, a normalized severity that is one of `DEBUG`, `INFO`, `WARN`, or `ERROR`, a stable service or executable identifier, and a short English message from a constant call-site template. Add the deployed revision and environment when known. Add the active trace and span identifiers, or another trusted correlation identifier, when the occurrence belongs to an operation. Add a stable, low-cardinality error type when the occurrence is a failure. Every `INFO`, `WARN`, and `ERROR` log record has a stable, lowercase, dot-separated event name. A `DEBUG` log record needs an event name only when an automated or operational consumer depends on it. Put variable values in typed structured fields. Do not put them only in the message. Do not put high-cardinality values in event names or field names.

Use `DEBUG` for detailed diagnostic information that is not necessary during normal operation. Use `INFO` for an expected and significant lifecycle, business, or state transition. Use `WARN` for an unexpected degraded or at-risk condition when no technical operation has reached a failed final outcome. This level includes an operation that completes or recovers through a fallback. Use `ERROR` when a technical operation reaches a failed final outcome, data consistency is uncertain, or the process cannot continue. An expected input rejection, negative business result, routine client cancellation, cache miss, or individual retry attempt is not a technical error.

Normalize framework-specific levels to these four meanings before applying the contract. Treat `TRACE` as `DEBUG`. Treat `FATAL` as `ERROR` and add a structured process-termination outcome. Map any other level to its closest semantic meaning. Apply the event-name requirement after this mapping. Do not map numeric severity values directly between formats. A platform can preserve its native severity in a separate optional field.

Log an exception once, in the component that handles the failure or reports its final outcome. Preserve its cause. Do not log it and rethrow it unchanged. Pass the exception object to the logging interface only when the logging path applies the `P21` data controls before the log record reaches any sink. Otherwise, extract approved exception fields explicitly. Record the exception type. Record its stack trace when the trace is useful and the data-protection rules permit it.

Each message follows `P20` and describes one occurrence. Its template is constant at the call site, but its wording is not a compatibility contract. Use both the stable event name and the human-readable message. Do not introduce an opaque numeric log code unless an external contract requires it. Keep an external or user-facing error code separate from the internal event name. An automated consumer selects the stable event name and fields. It does not match message text.

Apply `P11` to every level. Do not record a secret, credential, token, session value, connection string, raw authorization data, or raw request or response body. Record personal or other sensitive data only when an approved purpose requires the minimum value. Treat exception messages as potentially sensitive. Sanitize and bound untrusted values before logging. Define access, retention, and deletion for retained log records.

Keep audit and security log records separate from diagnostic verbosity. When they apply, identify the actor or originating system, action, target reference, outcome, occurrence time, origin, and correlation. Apply the preceding data-minimization rule: record no secrets and only the approved minimum personal or sensitive data. The application log level cannot disable these records. Do not sample them. Define their access, integrity, retention, deletion, and failure behavior according to the applicable legal or security contract. That contract can require the protected action to stop when audit recording fails.

`INFO` and `DEBUG` log records can be sampled under a documented policy. Do not sample `WARN` and `ERROR` log records during normal operation. A volume-protection control can suppress repeated `WARN` or `ERROR` log records only if it preserves one representative log record and a separate bounded counter counts observed and suppressed occurrences before export. Document whether exporter failure can lose that counter. Diagnostic log export must not become an unbounded queue or a synchronous remote dependency, and its failure must not change a reported business result.

Log severity does not define alert priority. An alert uses stable fields and an actionable condition, owner, response, and runbook. Prefer user-visible symptoms and service objectives to generic counts of log records.

`P21` cannot be disabled for first-party runtime log records. A platform mapping can change serialized field names, enrichment location, presentation, or transport. It preserves the required semantics and documents the mapping. An external source or legacy format that cannot meet this rule requires an explicit and limited exception. The exception identifies the source, missing fields, compensating mapping or isolation, owner, and review or removal condition.

**Reason.** Free text alone is unstable for queries and alerts. A code alone does not explain the occurrence to an operator. Structured log records support correlation, automation, and diagnosis. Controlled messages support people. Correct severity, bounded volume, and data minimization reduce alert fatigue, operating cost, and disclosure risk.

**Minimum evidence.** The project verification command checks representative log records at each severity that the project uses for the required schema, severity, applicable correlation, and synthetic sensitive-data exclusion. When a component can report a failed technical operation, a failure-path test shows one `ERROR` log record from the component that reports the final outcome. Each automated consumer selects a stable event name or field, not message text. The project records its production threshold, sampling, retention, audit applicability, and alert ownership. A project that emits no first-party runtime log records marks this principle as not applicable.

Source: https://nclsppr.github.io/project-foundation/principles/index.mdx
