daita@system:~$ cat ./spec_kit_constitution_first_principles.md

Spec-Kit Constitution From First Principles: Stop Shipping Platitude Charters

Created: 2026-04-23 | Size: 15240 bytes

TL;DR

GitHub Spec-Kit ships with a /speckit.constitution command that writes your project's governing principles into .specify/memory/constitution.md, where every subsequent plan, spec, and task will read it. Most teams invoke it with the example prompt ("principles focused on code quality, testing standards, user experience consistency, and performance requirements") and get back four paragraphs of well-meaning nothing. That output has zero steering effect on the agent. A constitution that actually binds behavior has to be derived from first principles, the irreducible truths of the domains your code lives in, not from the buzzwords of the month. This post shows how to build one, using distributed systems, data engineering, software design, devops, and observability as the bedrock.

What The Constitution Actually Does

/speckit.constitution is the first step of Spec-Driven Development in GitHub Spec-Kit. It writes a single markdown file, .specify/memory/constitution.md, that is loaded as context on every downstream command (/speckit.specify, /speckit.plan, /speckit.tasks, /speckit.implement). The agent treats it as the foundational piece it must adhere to while generating plans and code.

That is the whole mechanism. There is no validator. There is no runtime check. The constitution is just a prompt fragment that the agent reads before it thinks. Its steering power is entirely a function of how specific, falsifiable, and decision-ready the rules inside it are.

Which is where the default invocation falls over.

Fence: This Is Not A Spec-Kit Tutorial

This post is not about how to install Spec-Kit, how its slash commands compose, or why spec-driven development beats vibe coding. We covered the what and why in What is GitHub Spec-Kit?. This post is about the single most leveraged artifact in the whole workflow, the constitution, and what content it needs to contain to actually change the code the agent writes.

The Platitude Problem

Run the example prompt verbatim:

text
/speckit.constitution Create principles focused on code quality, testing standards,
user experience consistency, and performance requirements

You will get back something structurally correct and operationally useless. "Code should be readable." "Tests should cover critical paths." "Performance should meet user expectations." The agent has no way to act on any of this. When it later has to choose between a three-service microservice plan and a single-binary plan, these rules are silent. When it has to choose between in-memory caching and Redis, these rules are silent. When it decides whether to add a new abstraction or inline the logic, these rules are silent.

The failure mode is the same one that plagues most engineering documents: the words sound like governance but do not constrain any decision. If a rule is compatible with every possible implementation, it is not a rule.

Derive From First Principles, Not From Topics

The fix is to stop writing principles about topics (quality, testing, UX, performance) and start writing principles from irreducible truths of the systems you are building. I have written up the first principles for five relevant domains, and they collapse into a very compact working set:

DomainIrreducible truths that matter
Distributed systemsCoordination costs a round trip. State is hard, compute is easy. Failure modes multiply with nodes.
Software designWorking memory is ~4-7 chunks. Change cost dominates creation cost. Coupling determines blast radius.
Data engineeringProducers and consumers live in different contexts. Semantic reconciliation is the work. Provenance is non-negotiable.
DevOpsSoftware has zero value until users touch it. Recovery beats prevention. Coordination cost is superlinear.
ObservabilityA system is observable if you can infer its state from its outputs. High cardinality preserves unknown questions. Attention is finite.

These are not style preferences. They are things that will still be true after the next framework churn cycle. A constitution grounded in them ages well and fires on real decisions.

Notice what is missing from the table. The Spec-Kit example prompt asks for user experience consistency alongside quality, testing, and performance. I dropped it on purpose. A principle is only load-bearing if it comes from a domain you have actually reasoned through from irreducible truths. I have not done that exercise for UX, so inventing a "UX consistency" principle here would be the same platitude trap in a different outfit. If your product is UX-heavy, treat that as a separate first-principles write-up (Fitts's law, Hick's law, Nielsen heuristics, accessibility constraints) and merge the result into the constitution once the reasoning exists. The correct move when a domain is not ready is to leave it out, not to ship a placeholder.

A Constitution You Can Actually Paste

Here is the prompt the team should run instead. It is long on purpose: the extra tokens are where the steering lives.

text
/speckit.constitution

Write principles grounded in first-principles reasoning across five domains:
distributed systems, software design, data engineering, devops, and observability.

Each principle must be decision-ready: a reviewer should be able to point at a
diff and say "this violates principle X" without interpretation.

Required principles:

1. Do not distribute by default.
   Vertical scaling and a single deployable is the starting point. A new process,
   service, or queue requires a written justification tied to one of: working-set
   overflow, genuinely independent compute, geographic latency, or organizational
   independence. Coordination is a cost measured in round trips, not milliseconds.

2. Optimize for deletion, not extension.
   A module must be small enough that one engineer can delete and rewrite it in a
   day. Reject speculative abstractions. Inline until it hurts, then extract.
   Duplication below three occurrences is cheaper than the wrong abstraction.

3. Make dependencies explicit.
   No hidden coupling, no implicit global state, no import-time side effects.
   A reader must be able to see every dependency of a function in its signature
   or at the top of its file. Dependency injection over singletons.

4. Contract at the boundary, not in the middle.
   Every producer/consumer boundary (HTTP, queue, file, database) must have a
   schema with a version. Semantic reconciliation happens at the boundary, owned
   by the side that understands both contexts. No shared mutable schemas.

5. Test the transformation, not the plumbing.
   Unit tests cover pure transformation logic. Integration tests cover the
   boundaries. Do not mock what you own; do mock what you do not. A green CI
   without a failing test for the bug you just fixed is not green.

6. Emit structured events, derive everything else.
   Logs, metrics, and traces are projections of one primitive: the structured
   event. High-cardinality fields (user id, request id, tenant id, feature flag
   state) are required, not optional. No unstructured log lines in new code.

7. Recovery over prevention.
   Every change must be revertible in under five minutes without a code change.
   Feature flags gate risky paths. Migrations are expand-then-contract. Rollback
   is tested as part of the deploy, not assumed.

8. Attention is finite.
   Every alert must correspond to a user-visible symptom and a runbook. Dashboards
   are saved queries, not decoration. Delete signals that have not fired a
   useful page in 90 days.

9. Value is realized at the user, not at merge.
   A PR is not done until the change is in the hands of users, observable, and
   revertible. "Shipped" means deployed, instrumented, and monitored, not merged.

10. Commands are discoverable; local dev matches CI.
    Every repeatable action (build, test, lint, migrate, deploy, seed) is a
    single named command listed in one place and runnable with no hidden
    arguments. The command a developer runs locally is the same command CI
    runs. No "works on my machine" gap, no CI-only shell steps, no undocumented
    makefile targets. If a new contributor cannot list every command in 30
    seconds, the interface is broken.

Output the constitution in the standard Spec-Kit format with Rationale,
Rule, and How To Apply sections for each principle.

Compare the steering power. When the agent later plans a feature and proposes splitting the write path across three services, principle 1 forces it to write a justification or pick a single-binary plan. When it proposes a BaseRepository<T> hierarchy for two entities, principle 2 blocks it. When it suggests adding a counter metric, principle 6 redirects it to an event with dimensions. None of this is possible with "performance should meet user expectations".

Ready-Made Constitutions

The prompt above is scoped to backend/systems work. Different project types need different subsets. We host versioned markdown templates that you can hand directly to /speckit.constitution:

Project typeURL
Backend / systems (10 principles)daita.io/constitutions/v1/backend-systems.md
Frontend / SPA (9 principles, adds a11y, web vitals, state placement)daita.io/constitutions/v1/frontend-spa.md
Data pipeline (9 principles, adds contracts, provenance, idempotency)daita.io/constitutions/v1/data-pipeline.md
CLI tool (9 principles, adds exit-code contract, composability, startup budget)daita.io/constitutions/v1/cli-tool.md
AI agent codebase (10 principles, adds evals, context budget, blast radius)daita.io/constitutions/v1/agent-codebase.md
Monorepo / multi-activity (6 core + activity-scoped rules)daita.io/constitutions/v1/monorepo.md

Usage pattern:

text
/speckit.constitution fetch https://daita.io/constitutions/v1/backend-systems.md
and apply it as the constitution, preserving the exact language of each
principle. Do not paraphrase. Render in the Spec-Kit template with Rationale,
Rule, and How To Apply sections per principle.

Spec-Kit's slash command does not natively fetch URLs, but the agent running behind it (Claude Code, Cursor, and others) does. The agent reads the URL, applies the content, and writes .specify/memory/constitution.md. URLs are versioned (/v1/) so a future revision does not silently change the constitution under a running project.

Why This Works

Three reasons, all mechanical.

Specificity creates matchable tokens. Principle 1 mentions "round trip", "working-set overflow", and "vertical scaling". Those tokens light up during planning because they describe the shape of the decision. Vague principles never match because the agent's plan does not contain the word "quality".

Falsifiability makes review possible. A reviewer (human or agent) can point at a diff and say "this violates principle 3, the new controller pulls from a module-level singleton". "Good code quality" fails this test. It has no negation.

Irreducibility makes principles durable. These rules do not reference Kubernetes, microservices, OpenTelemetry, or any framework. They will survive the next architecture fashion cycle intact, which is exactly what a constitution is supposed to do.

What Does Not Belong In The Constitution

Equally important, and the reason most constitutions rot in six months: the file is not a dumping ground. Keep the following out:

  • Tool names and versions. "Use Postgres 16", "use Redis", "use Vitest". These rot the moment the team migrates. If the underlying principle matters (durability, low-latency cache, test isolation), write the principle, not the tool.
  • Library and framework preferences. "Prefer React Query over SWR". Move these to a CONVENTIONS.md or a linter config. They do not belong in a document that steers architectural plans.
  • Style-guide rules. Line length, import order, naming casing. That is what formatters and linters are for. Encoding them in the constitution wastes context tokens the agent could spend on actual decision pressure.
  • Workflow preferences for the human. "Always open a draft PR first", "use conventional commits". Those go in CLAUDE.md, AGENTS.md, or team-docs, not in the file that shapes /speckit.plan output.
  • Aspirations without enforcement. "We value quality." If there is no test a reviewer can apply, delete it.

Rule of thumb: if a rule does not change at least one downstream plan or diff, it is decoration. If it references a specific vendor, tool, or framework, it is fragile. Move it somewhere else.

The Test

Delete a principle from the constitution and ask: would any plan the agent produces look different? If the answer is no, the principle was decoration. Keep doing this until every rule on the page changes at least one downstream decision. That is your working constitution. Everything else is a README pretending to be governance.


References

  1. GitHub Spec-Kit v0.7.4, original source, spec-driven development toolkit and /speckit.constitution command.
  2. Distributed Systems From First Principles, related post, six irreducible truths underlying system design.
  3. First Principles for Software Design, cognitive load, coupling, deletion over extension.
  4. First Principles: Data Engineering and ETLs, contracts, semantic reconciliation, provenance.
  5. First Principles of DevOps, value gap, recovery over prevention, coordination cost.
  6. First Principles for Software Observability, structured events, high cardinality, attention as a scarce resource.
  7. What is GitHub Spec-Kit?, related post, primer on spec-driven development workflow.

daita@system:~$ _