Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,13 @@ L2 statutes live wherever *its* governance map says (see `process/statutes.md`).
source-vs-installed-artifact split above is specific to this repo, since it is both the
framework *and* a CLI consumer of itself.

**Ratifying an amendment in this repo's own `CONSTITUTION.md`** also bumps the header
`framework: constitution@X.Y.Z (self-hosted)` pin to the same number as the new ledger
entry — F-II requires the pin and the ledger to be one axis here, and nowhere else
(ADR-0002; see `cli/AGENTS.md`'s `LEDGER-SYNC` statute for the mechanized check, and
`skills/audit-structure`'s self-hosted-conditional check). This is repo-specific and
does not belong in `skills/ratify-amendment/SKILL.md`, which is vendored into every
consumer — no consumer is self-hosted, so that step would be dead weight in every
installed copy.

*This file serves as the entry-point index for the audit-structure and compile-prompt skills.*
75 changes: 64 additions & 11 deletions CONSTITUTION.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# The constitution framework — Constitution

```
framework: constitution@0.17.3 (self-hosted)
framework: constitution@0.17.5 (self-hosted)
ratifier: Chinmay
```

Expand Down Expand Up @@ -35,7 +35,7 @@ Ratification is agreement; conformance is reality; enforcement is reality's half
`HOLDS + UNGUARDED` is true-but-fragile, flagged as mechanization debt.

### Article F-I — Discovery before codification
`status: RATIFIED` · `conformance: HOLDS` · `enforcement: AUDITED` · `party: N/A`
`status: RATIFIED` · `conformance: VIOLATED` · `enforcement: AUDITED` · `party: N/A`

- **Principle** — No rule is added to this framework until it has been proven in at
least one live project. DSAMind is the founding instance.
Expand All @@ -44,6 +44,12 @@ Ratification is agreement; conformance is reality; enforcement is reality's half
the originating experiment + ADR in a consumer project.
- **Why** — a framework written from imagination ossifies around guesses; one written
from usage carries its evidence with it.
- **Conformance note (2026-07-05 re-audit)** — VIOLATED. [registry.md](registry.md)'s two
promoted-mechanism rows (F-V/F-VI, F-VII) cite ledger version ranges and doc sections
only — neither names an experiment file nor an ADR id. No `experiments/` directory
exists anywhere, in this repo or DSAMind; no promotion has ever gone through F-III's
pre-registered path. Tracked debt, not fixed as part of this audit — see
`audit-conformance` run, same session as ADR-0003.

### Article F-II — One home per rule
`status: RATIFIED` · `conformance: HOLDS` · `enforcement: AUDITED` · `party: N/A`
Expand All @@ -52,18 +58,21 @@ Ratification is agreement; conformance is reality; enforcement is reality's half
duplicated across layers, nor across the framework and an instance. A versioned
package manager installation (e.g., via a CLI) satisfies this rule: the package is the
single home, and the files it writes to the instance are its read-only build artifacts.
A version number is a governed fact too. Three exist, each with one home: the instance's
own Amendments Ledger version, the framework spec version it has adopted (the header
pin — a ratified claim, never bumped ahead of what's actually adopted), and the
framework tooling installed (the instance's own package manifest). These are never
compared to each other as if they were the same number — except in this framework's
own repo, where the pin and the ledger are the same number on purpose.
A version number is a governed fact too, and three exist, each with exactly one home:
1. the instance's own Amendments Ledger version,
2. the framework spec version it has adopted (the header pin — a ratified claim, never
bumped ahead of what's actually adopted),
3. the framework tooling installed (the instance's own package manifest).

These three are never compared as one axis, with one exception: in the framework's own
self-hosted repo, axis 1 and axis 2 are the same number by design. Axis 3 is never folded
into that collapse, even here.
- **Serves** — P1.
- **Fitness** — no rule's text appears verbatim in two layer documents; every cross-layer
reference (`serves` / `amends` / `supersedes` / `party`) resolves and every layer traces up;
no rule lives outside a layer. No check treats the ledger version, the header pin, and the
installed tooling version as one axis, except for this framework's own self-hosted repo.
Verified by the `audit-structure` skill.
no rule lives outside a layer. No check treats axis 1 and axis 2 as the same number for any
instance except the framework's own self-hosted repo; no check ever treats axis 3 as the
same number as either of the others, anywhere. Verified by the `audit-structure` skill.

### Article F-III — Experiments are pre-registered
`status: RATIFIED` · `conformance: HOLDS` · `enforcement: AUDITED` · `party: N/A`
Expand Down Expand Up @@ -165,6 +174,50 @@ on the same Article is the signal that the Article itself needs amending.
Superseded clauses are never deleted — they are kept here with a forward link and the
ADR that justified the change.

### [0.17.5] — 2026-07-05 — Re-audit Conformance
- **Audit:** Ran `audit-conformance` against all seven Articles, same session as ADR-0003.
- **Findings:**
- **F-I flips `HOLDS` → `VIOLATED`.** `registry.md`'s two promoted-mechanism rows cite
ledger ranges and doc sections, not an experiment file + ADR id, as the fitness text
requires. No `experiments/` directory exists anywhere (this repo or DSAMind); no
promotion has ever used F-III's pre-registered path. Tracked debt — not remediated
here (human declined the fitness-amendment option this session; left as-is).
- F-II through F-VII all maintain `conformance: HOLDS`, `enforcement: AUDITED`.
- F-III holds only vacuously — zero experiment files exist to check against; the
mechanism has never actually been exercised.
- F-VI's own fitness ("no Article marked HOLDS while its fitness fails") was itself
unmet before this pass, because of F-I's stale label — fixed by the F-I flip above.
- **Result:** One conformance flip (F-I). No `status` changes; nothing above the firewall.

### [0.17.4] — 2026-07-05 — Ratified by Chinmay: Article F-II's version-axis clause tightened (ADR-0003)
- **Ratified by Chinmay, 2026-07-05**, per [ADR-0003](decisions/0003-tighten-version-axis-clause.md).
- `derive-statutes`, run against F-II this session, found `[0.17.3]`'s two added sentences
disagreed on scope: Principle's self-hosted exception named two axes (pin + ledger);
Fitness listed all three before the same "except," reading like it covered all three. That
ambiguity had already produced a wrong statute (`cli/AGENTS.md` claimed the tooling axis
collapses too, citing F-II) — fixed in the same session, pending this ADR.
- **Article F-II — Principle and Fitness rewritten** (`status: RATIFIED`, unchanged), as a
numbered 3-axis list with the self-hosted exception scoped to axes 1+2 only in both
clauses. No behavior change — code and the statute already assumed this reading.
- `[0.17.3]` **SUPERSEDED — 2026-07-05 → ADR-0003.** The two sentences it added to
Principle:
> A version number is a governed fact too. Three exist, each with one home: the
> instance's own Amendments Ledger version, the framework spec version it has adopted
> (the header pin — a ratified claim, never bumped ahead of what's actually adopted), and
> the framework tooling installed (the instance's own package manifest). These are never
> compared to each other as if they were the same number — except in this framework's own
> repo, where the pin and the ledger are the same number on purpose.

And the one sentence it added to Fitness:
> No check treats the ledger version, the header pin, and the installed tooling version
> as one axis, except for this framework's own self-hosted repo.
- Agreement-only — no pre-registered experiment. Wording-only fix; the ambiguity itself was
the evidence.
- Above the firewall — F-II's `status` did not change (already `RATIFIED`); its Principle
and Fitness text did, transcribed per `ratify-amendment`.
- Self-hosted repo: header pin bumped to `0.17.4` alongside this ledger entry (F-II's own
pin↔ledger collapse, per this repo's root `AGENTS.md`).

### [0.17.3] — 2026-07-05 — Ratified by Chinmay: Article F-II extended — three version numbers, three homes
- **Ratified by Chinmay, 2026-07-05**, per [ADR-0002](decisions/0002-version-axis-separation.md).
- Found auditing DSAMind (`dsa_project`): the engine's `LEDGER-SYNC` check compared a
Expand Down
29 changes: 23 additions & 6 deletions cli/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,17 +34,34 @@ package-managed distribution mechanism, per
version and the repo's `package.json` from drifting apart instead.

- **`cli/package.json`'s `version` always equals this repo's `CONSTITUTION.md` header
version.** One number for the whole self-hosted repo — not a tool-version axis and a
spec-version axis drifting independently. Every `CONSTITUTION.md` version bump that
lands in the same change as a `cli/` publish updates both together; a bump to one
without the other is the bug, not a valid state.
· serves: F-II (one home for "what version is this")
version.** This is repo-specific practice, not an F-II requirement — F-II's ratified
text only blesses collapsing the header pin and the Amendments Ledger into one axis
here; it says nothing about the installed-tooling axis. Syncing the tooling version
too is a deliberate convenience this repo has chosen (mechanized by publish-on-merge),
not something the constitution mandates. A downstream consumer is not expected to do
this, and its own tooling version stays a genuinely independent third axis (F-II).
· serves: general craft (a repo-specific convenience, not an L1 mandate)
· enforced-by: CI (`.github/workflows/publish.yml` fails the publish job on any
mismatch between `cli/package.json` and the `CONSTITUTION.md` header; locally,
`constitution doctor` auto-syncs via `constitution.config.json`)
· why: two independently-numbered versions for one repo is exactly the confusion a
consumer hits first — "why does `constitution --version` say 1.0.0 when the spec
ledger is at 0.16.x." One axis removes the question.
ledger is at 0.16.x." One axis removes the question *for this repo*, by choice, not
by rule.

- **The self-hosted repo's `framework:` header pin and its newest Amendments Ledger
entry are the same axis and must match — this collapse is what F-II's ratified text
actually requires.** A downstream consumer's pin (the framework spec it adopted) and
its own ledger (its product's version) are legitimately independent and must never be
compared this way.
· serves: F-II (the pin↔ledger collapse, scoped to the self-hosted case only)
· enforced-by: CI (`.github/workflows/governance.yml` runs `constitution audit`,
which fails on `LEDGER-SYNC`) + hook (`constitution hooks install`'s pre-commit
gate runs the same check)
· why: this exact confusion is what ADR-0002 traces to — `LEDGER-SYNC`
(`src/engine/audit.ts:87-93`) used to fire unconditionally, wrongly comparing a
downstream consumer's adopted-spec pin against its own product ledger. The
`doc.selfHosted` scoping is the fix; see `decisions/0002-version-axis-separation.md`.

- **`skills/`, `templates/`, `process/` are vendored into `cli/` at build time
(`scripts/vendor.js`, run via `prebuild`/`prepack`) — never assume they exist as
Expand Down
4 changes: 2 additions & 2 deletions cli/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion cli/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@chinmaygit/constitution-cli",
"version": "0.17.3",
"version": "0.17.5",
"description": "The constitution governance engine: scaffold, audit, firewall-gate, compile, render, and track AI-native product development",
"license": "MIT",
"author": "Chinmay",
Expand Down
2 changes: 1 addition & 1 deletion cli/test/engine.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ describe('parse', () => {
]);
expect(inst.constitution.articles.every((a) => a.status === 'RATIFIED')).toBe(true);
expect(inst.statutes.length).toBeGreaterThan(5);
expect(inst.adrs).toHaveLength(2);
expect(inst.adrs).toHaveLength(3);
const findings = audit(inst);
expect(findings.filter((f) => f.severity === 'error')).toEqual([]);
});
Expand Down
6 changes: 3 additions & 3 deletions constitution.lock.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"lockVersion": 1,
"constitutionVersion": "0.17.3",
"constitutionVersion": "0.17.4",
"acceptedBy": "Chinmay",
"acceptedAt": "2026-07-05T08:45:28.047Z",
"acceptedAt": "2026-07-05T10:25:23.000Z",
"units": {
"P1": {
"kind": "preamble",
Expand All @@ -14,7 +14,7 @@
},
"F-II": {
"kind": "article",
"hash": "06ed10f12ad527f757a808764c7ee7f6fcc3432bfb06737a6180ad7a980334a5"
"hash": "1feb6f2adad3979f468a5937302a53e860d63e5b5c46da85bab12996d000b90d"
},
"F-III": {
"kind": "article",
Expand Down
51 changes: 51 additions & 0 deletions decisions/0003-tighten-version-axis-clause.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
---
id: 0003
title: Tighten F-II's version-axis clause into three numbered, unambiguous axes
status: accepted
date: 2026-07-05
supersedes: []
superseded_by: []
serves: [F-II]
amends: [F-II]
trigger: certiorari
---

## Question of law
ADR-0002 added a version-axis clause to F-II's Principle and Fitness. The two sentences
disagree on scope: Principle's self-hosted exception names two axes (pin + ledger); Fitness
lists all three before the same "except," reading like it covers all three. That ambiguity
already produced a wrong statute this session (`cli/AGENTS.md` claimed the tooling axis
collapses too, citing F-II).

## Ruling
Rewrite both sentences as a numbered list, with the exception scoped to axes 1+2 only in
both places. No behavior change — code and the corrected statute already assume the 2-axis
reading; this just makes the text say what's already true.

**Principle**, replace ADR-0002's two sentences with:
> A version number is a governed fact too, and three exist, each with exactly one home:
> 1. the instance's own Amendments Ledger version,
> 2. the framework spec version it has adopted (the header pin — never bumped ahead of
> what's actually adopted),
> 3. the framework tooling installed (the instance's own package manifest).
>
> These three are never compared as one axis, with one exception: in the framework's own
> self-hosted repo, axis 1 and axis 2 are the same number by design. Axis 3 is never folded
> into that collapse, even here.

**Fitness**, replace ADR-0002's sentence with:
> No check treats axis 1 and axis 2 as the same number for any instance except the
> framework's own self-hosted repo; no check ever treats axis 3 as the same number as
> either of the others, anywhere.

## Constitutional impact
Replaces those two sentences in F-II. `status`/`serves`/`enforcement`/`party` unchanged. Old
text kept verbatim in the ledger, marked `SUPERSEDED — <date>`, forward-linked here. Does not
supersede ADR-0002 — its ruling still stands, this only fixes the wording.

## Consequences
Closes the ambiguity; no enforcement changes.

## Alternatives considered
New Article instead of re-amending F-II — rejected, same reason as ADR-0002: still one home
per rule, just stated more precisely.
1 change: 1 addition & 0 deletions decisions/INDEX.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ an ADR) are L2 statutes — see [AGENTS.md](AGENTS.md).
|----|-------|--------|------|
| 0001 | Allow package-managed installation of skills to satisfy F-II | accepted | 2026-07-01 |
| 0002 | Three version numbers, three homes | accepted | 2026-07-05 |
| 0003 | Tighten F-II's version-axis clause into three numbered, unambiguous axes | accepted | 2026-07-05 |
18 changes: 14 additions & 4 deletions skills/audit-structure/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ metadata:
scope: project
layer: cross-cutting
enforces: F-II
version: "1.4.0"
version: "1.4.2"
---

# Audit the constitution's structural integrity (L0–L4)
Expand Down Expand Up @@ -63,7 +63,13 @@ below.
**4. Field & firewall integrity:**
- Every Article carries all required fields: `status`, `conformance`, `enforcement`, `party`, `serves`, `fitness`.
- Every L0/L1 amendment in the ledger names a human ratifier (F-IV).
- The instance's framework pin (`constitution@X`) matches `registry.md`; the header version matches the latest ledger entry and the latest tag.
- The instance's framework pin (`constitution@X`) matches `registry.md`. **Only in the
framework's own self-hosted repo** (header marked `(self-hosted)`) does the header pin
also have to match the latest ledger entry and the latest tag (F-II) — in any other
instance the pin (the framework spec it adopted) and the ledger (its own product
version) are legitimately independent axes and must **not** be compared this way
(ADR-0002; see `cli/AGENTS.md`'s `LEDGER-SYNC` statute for the mechanized version of
this same check).

**5. Anything OUTSIDE the layers (the headline):**
- A rule in the declared L2 statute homes that no layer claims — not tagged L2, no `serves`, not an Article, not an ADR. **Ungoverned rule** → either annotate it as a statute or delete it.
Expand All @@ -87,8 +93,12 @@ below.
other skill trust at day-to-day speed, with no scanning. **Then, only in this audit, cross-check
it against an independent scan** of the tree (e.g. `find . -iname 'AGENTS.md' -o -iname
'CLAUDE.md' -o -iname 'AGENTS.md'`, excluding `.claude/`, `.agents/`, `.cursor/`,
`node_modules/`, `dist/`, `.git/`) to catch a home that exists on disk but isn't declared. This
scan is this skill's job alone — the periodic safety net, not a per-task cost every skill pays.
`node_modules/`, `dist/`, `.git/`, **and anything `git check-ignore` reports** — a hardcoded
name list misses a repo's own generated/vendored copies under other names (e.g. this repo's
own `cli/skills/`, `cli/templates/`, `cli/process/` — gitignored build artifacts per
`cli/AGENTS.md`, not `dist/`-named but the same kind of thing)) to catch a home that exists on
disk but isn't declared. This scan is this skill's job alone — the periodic safety net, not a
per-task cost every skill pays.
2. **Run the checks** above. For each finding, record the exact location and what's broken.
3. **Classify** each: `broken-ref` · `orphan` · `duplication` · `ungoverned` · `map-gap` ·
`map-drift` · `field-gap` · `pin/version drift` · `promotion/demotion signal`.
Expand Down
Loading