@freetesh/canon 0.0.0-stage → 0.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +15 -0
- package/.claude-plugin/plugin.json +5 -0
- package/LICENSE +21 -0
- package/README.md +161 -2
- package/cli/dist/api.d.ts +3 -0
- package/cli/dist/api.js +4 -0
- package/cli/dist/check.d.ts +19 -0
- package/cli/dist/check.js +40 -0
- package/cli/dist/checks/architecture.d.ts +23 -0
- package/cli/dist/checks/architecture.js +135 -0
- package/cli/dist/checks/canonical-values.d.ts +2 -0
- package/cli/dist/checks/canonical-values.js +48 -0
- package/cli/dist/checks/commands.d.ts +7 -0
- package/cli/dist/checks/commands.js +33 -0
- package/cli/dist/checks/context-layout.d.ts +5 -0
- package/cli/dist/checks/context-layout.js +83 -0
- package/cli/dist/checks/context-size.d.ts +2 -0
- package/cli/dist/checks/context-size.js +46 -0
- package/cli/dist/checks/features.d.ts +2 -0
- package/cli/dist/checks/features.js +38 -0
- package/cli/dist/checks/index.d.ts +2 -0
- package/cli/dist/checks/index.js +34 -0
- package/cli/dist/checks/listing.d.ts +2 -0
- package/cli/dist/checks/listing.js +51 -0
- package/cli/dist/checks/metrics-definitions.d.ts +2 -0
- package/cli/dist/checks/metrics-definitions.js +14 -0
- package/cli/dist/checks/pipeline.d.ts +8 -0
- package/cli/dist/checks/pipeline.js +34 -0
- package/cli/dist/checks/refs.d.ts +2 -0
- package/cli/dist/checks/refs.js +92 -0
- package/cli/dist/checks/shared-files.d.ts +22 -0
- package/cli/dist/checks/shared-files.js +84 -0
- package/cli/dist/checks/sources.d.ts +2 -0
- package/cli/dist/checks/sources.js +40 -0
- package/cli/dist/checks/stale-copies.d.ts +2 -0
- package/cli/dist/checks/stale-copies.js +18 -0
- package/cli/dist/checks/standards-copies.d.ts +2 -0
- package/cli/dist/checks/standards-copies.js +57 -0
- package/cli/dist/checks/tasks.d.ts +2 -0
- package/cli/dist/checks/tasks.js +66 -0
- package/cli/dist/checks/types.d.ts +23 -0
- package/cli/dist/checks/types.js +1 -0
- package/cli/dist/checks/wiki-frontmatter.d.ts +3 -0
- package/cli/dist/checks/wiki-frontmatter.js +84 -0
- package/cli/dist/commands/add.d.ts +3 -0
- package/cli/dist/commands/add.js +24 -0
- package/cli/dist/commands/approve.d.ts +2 -0
- package/cli/dist/commands/approve.js +20 -0
- package/cli/dist/commands/check.d.ts +3 -0
- package/cli/dist/commands/check.js +19 -0
- package/cli/dist/commands/copies.d.ts +3 -0
- package/cli/dist/commands/copies.js +23 -0
- package/cli/dist/commands/doctor.d.ts +2 -0
- package/cli/dist/commands/doctor.js +16 -0
- package/cli/dist/commands/hooks.d.ts +6 -0
- package/cli/dist/commands/hooks.js +55 -0
- package/cli/dist/commands/init.d.ts +3 -0
- package/cli/dist/commands/init.js +78 -0
- package/cli/dist/commands/learn.d.ts +3 -0
- package/cli/dist/commands/learn.js +36 -0
- package/cli/dist/commands/mcp.d.ts +2 -0
- package/cli/dist/commands/mcp.js +11 -0
- package/cli/dist/commands/pipeline.d.ts +3 -0
- package/cli/dist/commands/pipeline.js +26 -0
- package/cli/dist/commands/search.d.ts +2 -0
- package/cli/dist/commands/search.js +13 -0
- package/cli/dist/commands/standards.d.ts +3 -0
- package/cli/dist/commands/standards.js +26 -0
- package/cli/dist/commands/status.d.ts +3 -0
- package/cli/dist/commands/status.js +11 -0
- package/cli/dist/commands/sync.d.ts +3 -0
- package/cli/dist/commands/sync.js +23 -0
- package/cli/dist/commands/ui.d.ts +3 -0
- package/cli/dist/commands/ui.js +64 -0
- package/cli/dist/commands/weigh.d.ts +2 -0
- package/cli/dist/commands/weigh.js +16 -0
- package/cli/dist/config/load.d.ts +23 -0
- package/cli/dist/config/load.js +116 -0
- package/cli/dist/config/schema.d.ts +200 -0
- package/cli/dist/config/schema.js +116 -0
- package/cli/dist/doctor.d.ts +12 -0
- package/cli/dist/doctor.js +31 -0
- package/cli/dist/format.d.ts +6 -0
- package/cli/dist/format.js +35 -0
- package/cli/dist/index.d.ts +2 -0
- package/cli/dist/index.js +48 -0
- package/cli/dist/init.d.ts +46 -0
- package/cli/dist/init.js +119 -0
- package/cli/dist/learn.d.ts +44 -0
- package/cli/dist/learn.js +80 -0
- package/cli/dist/lib/env.d.ts +7 -0
- package/cli/dist/lib/env.js +6 -0
- package/cli/dist/lib/files.d.ts +3 -0
- package/cli/dist/lib/files.js +23 -0
- package/cli/dist/lib/frontmatter.d.ts +6 -0
- package/cli/dist/lib/frontmatter.js +16 -0
- package/cli/dist/lib/qmd.d.ts +9 -0
- package/cli/dist/lib/qmd.js +13 -0
- package/cli/dist/lib/system.d.ts +4 -0
- package/cli/dist/lib/system.js +19 -0
- package/cli/dist/packs.d.ts +40 -0
- package/cli/dist/packs.js +85 -0
- package/cli/dist/pipeline.d.ts +20 -0
- package/cli/dist/pipeline.js +30 -0
- package/cli/dist/standards.d.ts +14 -0
- package/cli/dist/standards.js +42 -0
- package/cli/dist/status.d.ts +3 -0
- package/cli/dist/status.js +26 -0
- package/cli/dist/sync.d.ts +19 -0
- package/cli/dist/sync.js +30 -0
- package/cli/dist/ui.d.ts +15 -0
- package/cli/dist/ui.js +69 -0
- package/package.json +54 -4
- package/packs/expo/pack.yaml +5 -0
- package/packs/firebase/pack.yaml +5 -0
- package/packs/nextjs/pack.yaml +5 -0
- package/packs/react/pack.yaml +5 -0
- package/packs/revenuecat/pack.yaml +5 -0
- package/packs/uniwind/pack.yaml +5 -0
- package/scripts/log-verdict.mjs +56 -0
- package/skills/ask/SKILL.md +40 -0
- package/skills/decision/SKILL.md +36 -0
- package/skills/ingest/SKILL.md +45 -0
- package/skills/standards/SKILL.md +16 -0
- package/skills/weigh/SKILL.md +160 -0
- package/skills/wiki-lint/SKILL.md +67 -0
- package/standards/README.md +14 -0
- package/standards/agent-contract.md +47 -0
- package/standards/constitution.md +104 -0
- package/standards/context-layout.md +129 -0
- package/standards/dev-methods.md +29 -0
- package/standards/wiki-schema.md +71 -0
- package/templates/dependency-cruiser/app.cjs +23 -0
- package/templates/dependency-cruiser/base.cjs +52 -0
- package/templates/dependency-cruiser/package.cjs +31 -0
- package/templates/dependency-cruiser/root.cjs +15 -0
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: weigh
|
|
3
|
+
description: Decision gate run BEFORE acting on a non-trivial request in a product repo — a new feature, screen or product, a new dependency or library, a migration or rewrite, a schema, money, pricing or store change, a release or deploy, deleting something, or a change that spans more than one product. Weighs the request against the canon constitution, the product's wiki and ADRs, existing features and tasks, cost vs value, and writing less code, then returns do it / do it differently / push back with citations. Also use when the user types /weigh or asks "should we…", "is it worth…", "does this make sense".
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Weigh before acting
|
|
7
|
+
|
|
8
|
+
You are deciding whether and how to do a request — not doing it yet.
|
|
9
|
+
Request: `$ARGUMENTS` (empty = the user's latest request in this conversation).
|
|
10
|
+
|
|
11
|
+
## Skip the gate when it is trivial
|
|
12
|
+
|
|
13
|
+
Answer and act directly, with no verdict block, when **all** are true: one file,
|
|
14
|
+
no new dependency, no schema / money / store / release / delete, and the change is
|
|
15
|
+
fully specified (a typo, a spacing fix, a copy edit the user dictated). A
|
|
16
|
+
product's `.claude/canon.yaml` may tighten this under `weigh.trivial`.
|
|
17
|
+
|
|
18
|
+
## Steps
|
|
19
|
+
|
|
20
|
+
1. **Restate the goal** in one line — what outcome the user wants, not the
|
|
21
|
+
mechanism they named. A named mechanism ("use library X", "move to Firebase")
|
|
22
|
+
is a proposal to weigh, not a given. Then **list the claims** the request
|
|
23
|
+
makes or rests on: "users want it", "it will help retention", "it is
|
|
24
|
+
missing", "it is slow". The request is not a fact (C-14); each claim is
|
|
25
|
+
checked in step 4.
|
|
26
|
+
|
|
27
|
+
2. **Rules.** Run `canon standards --constitution` for the principle titles
|
|
28
|
+
(canon's and any the team added), and read the constitution files that
|
|
29
|
+
`canon standards` lists — or `../../standards/constitution.md` (relative to
|
|
30
|
+
this skill) if the CLI is not installed. Note every principle the request
|
|
31
|
+
touches, by ID. Read a standard from `canon standards` only if the request is
|
|
32
|
+
in its area.
|
|
33
|
+
|
|
34
|
+
3. **Domain.** Search before you judge. Run `mcp__plugin_canon_qmd__query` with
|
|
35
|
+
the goal in plain words, then the key nouns, scoped with `collections` to
|
|
36
|
+
this product's `<repo>-wiki` and `<repo>-features` (the names `canon init`
|
|
37
|
+
gives them; add `pack-<name>` when the question is about a vendor's API). Other products' hits are noise here; step 5 is where
|
|
38
|
+
siblings are searched. Read the top hits with `mcp__plugin_canon_qmd__get`. Look for: an ADR that already
|
|
39
|
+
decided this, a canonical value it would change, a concept it would break.
|
|
40
|
+
If qmd is unavailable, read `.context/wiki/index.md` and `decisions/`.
|
|
41
|
+
**Architecture:** if `.claude/canon.yaml` lists the `architecture` module, read
|
|
42
|
+
the repo's `.dependency-cruiser.cjs` and its wiki architecture concept page.
|
|
43
|
+
A request whose code would need an import a rule forbids is DO IT
|
|
44
|
+
DIFFERENTLY (name the allowed path) or PUSH BACK; one that changes a rule
|
|
45
|
+
is **too-large** unless a decision page already approves it. Cite the rule
|
|
46
|
+
by its `name`.
|
|
47
|
+
|
|
48
|
+
4. **Claims.** Mark each claim from step 1 **backed**, **partly backed** or
|
|
49
|
+
**not backed**, with the fact and its source. Look in what step 3 read, the
|
|
50
|
+
code and `.context/raw/`. When that is not enough, look for a data source:
|
|
51
|
+
query qmd for `SOURCE` pages in this product's wiki. Each says what it holds,
|
|
52
|
+
how to read it (`mcp:`, `skill:`, `cli:` or `manual:`) and which claims it
|
|
53
|
+
answers. For `manual:`, ask the user for the numbers and say where to find
|
|
54
|
+
them; do not guess. If one fits, run its query and follow the query rules in `wiki-schema.md`
|
|
55
|
+
("Data sources"): read only, one or two small queries, counts not people.
|
|
56
|
+
Save a result that decides the verdict to `.context/raw/`. If the tool is not
|
|
57
|
+
available, say so and leave the claim not backed. If no source fits, name
|
|
58
|
+
the kind of source that would answer it ("an analytics tool with weekly
|
|
59
|
+
active users"). Never mark a claim backed because the user said it again.
|
|
60
|
+
|
|
61
|
+
5. **Duplicates and conflicts.** Check `.context/features/` and `.context/tasks.md`
|
|
62
|
+
of this product, and the features collections of sibling products in qmd:
|
|
63
|
+
is this already planned, built, shelved, or in progress elsewhere? Would it
|
|
64
|
+
conflict with something in `## Now`?
|
|
65
|
+
|
|
66
|
+
6. **Cost vs value.**
|
|
67
|
+
- Size: **small** (1 file, < 50 lines) · **medium** (2–5 files, < 200 lines) ·
|
|
68
|
+
**large** (5+ files) · **too-large** (architecture change — split it).
|
|
69
|
+
- Ongoing cost: new dependency, new service bill, more to maintain, more to
|
|
70
|
+
test, store review risk.
|
|
71
|
+
- Value: name the user or the metric it moves (`metrics/definitions.yml` if
|
|
72
|
+
the product has one). If neither can be named, say "value unproven". A
|
|
73
|
+
value claim is checked like any other claim, in step 4.
|
|
74
|
+
- Evidence: say which evidence from `dev-methods.md` the work must leave — a
|
|
75
|
+
feature page, a failing test first, or a metric and snapshot.
|
|
76
|
+
|
|
77
|
+
7. **Write less.** Climb the ladder and stop at the first rung that works:
|
|
78
|
+
delete it → reuse something in this repo → reuse from a sibling product or
|
|
79
|
+
shared script → platform or standard library → an existing well-used package
|
|
80
|
+
→ fewer lines → new code. If the `ponytail` plugin is installed, follow its
|
|
81
|
+
ladder for this step.
|
|
82
|
+
|
|
83
|
+
8. **Too-large, or the user asked for a second opinion?** Then, and only then,
|
|
84
|
+
ask the `challenger` agent for an independent read. It costs tens of
|
|
85
|
+
thousands of tokens, so hand it what you already have: the request, the repo
|
|
86
|
+
path, your draft verdict, and every file and wiki page you read with one line
|
|
87
|
+
on what each says. It checks your reasoning and looks only where you did
|
|
88
|
+
not. Where you and it disagree, show both. A large request is weighed by you
|
|
89
|
+
alone.
|
|
90
|
+
|
|
91
|
+
## Verdict
|
|
92
|
+
|
|
93
|
+
Reply with exactly this block, then stop or proceed as the verdict says:
|
|
94
|
+
|
|
95
|
+
```
|
|
96
|
+
Verdict: DO IT | DO IT DIFFERENTLY | PUSH BACK
|
|
97
|
+
Goal: <one line>
|
|
98
|
+
Size: small | medium | large | too-large
|
|
99
|
+
Why:
|
|
100
|
+
- <C-xx> <one line> — <file or wiki page cited>
|
|
101
|
+
- ...
|
|
102
|
+
Instead: <only for DO IT DIFFERENTLY — the cheaper or safer way>
|
|
103
|
+
Claims:
|
|
104
|
+
- "<claim>" — backed | partly backed | not backed — <fact and source, or what was searched>
|
|
105
|
+
Assumed: <every claim not backed, or "none">
|
|
106
|
+
Open questions: <only if a real ambiguity blocks a good answer>
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
- Every bullet under **Why** cites a principle ID and a source (a wiki page, ADR,
|
|
110
|
+
standard, feature, file or saved query result). A reason with no source is an
|
|
111
|
+
opinion: drop it, or list it under **Assumed**.
|
|
112
|
+
- **DO IT** only when **Assumed** is "none". Proceed with the work in the same
|
|
113
|
+
turn.
|
|
114
|
+
- **DO IT DIFFERENTLY** → proceed with the *Instead* version only if the user
|
|
115
|
+
already accepted it and **Assumed** is "none"; otherwise stop and ask.
|
|
116
|
+
- **PUSH BACK** → stop. Do not start the work, not even a part of it.
|
|
117
|
+
- **Something is assumed** → stop, and give the user three choices: bring the
|
|
118
|
+
facts (and say where they would go), agree to terms, or drop it. Any terms
|
|
119
|
+
you show, here or later, are a numbered list, so the user can agree line by
|
|
120
|
+
line.
|
|
121
|
+
|
|
122
|
+
Write the whole reply in plain words (C-15): short sentences, common words, no
|
|
123
|
+
jargon the wiki does not define.
|
|
124
|
+
|
|
125
|
+
## Terms (when the user wants to go on anyway)
|
|
126
|
+
|
|
127
|
+
When the user wants to go on despite a PUSH BACK or an assumption, write the
|
|
128
|
+
terms as a numbered list: what is in scope, what is out, which rule changes and
|
|
129
|
+
which stays, and how the assumption will be checked later (a metric and a
|
|
130
|
+
date). A fact the user gives in chat is saved to `.context/raw/` first, then
|
|
131
|
+
listed as a fact, not as proof of more than it shows.
|
|
132
|
+
|
|
133
|
+
Proceed only after the user agrees in writing ("agree", or "agree to 1–4").
|
|
134
|
+
"Go ahead" to a verdict is not agreement to terms that were never shown. Work
|
|
135
|
+
covers only the terms agreed to.
|
|
136
|
+
|
|
137
|
+
## Logging (every verdict)
|
|
138
|
+
|
|
139
|
+
Log every verdict once, when you know what happened next. A trivial request
|
|
140
|
+
that skipped the gate is not logged. `--outcome` is one of:
|
|
141
|
+
|
|
142
|
+
- `proceeded` — work went ahead as the verdict said (DO IT, or an accepted
|
|
143
|
+
*Instead*).
|
|
144
|
+
- `stopped` — you stopped and asked, and the user has not answered yet. Log it
|
|
145
|
+
when you stop; if the user later overrides, log a second line.
|
|
146
|
+
- `overridden` — the user went on against a PUSH BACK, rejected a DO IT
|
|
147
|
+
DIFFERENTLY, or agreed to terms. `--reason` is required: the user's reason,
|
|
148
|
+
verbatim. Pass each agreed term with its own `--term`.
|
|
149
|
+
- `dropped` — the user chose to drop the request.
|
|
150
|
+
|
|
151
|
+
```bash
|
|
152
|
+
node ../../scripts/log-verdict.mjs --verdict push-back --outcome overridden \
|
|
153
|
+
--principles C-04,C-14 --request "<one line>" \
|
|
154
|
+
--reason "<the user's reason, verbatim>" --term "<term 1>" --term "<term 2>"
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
(path relative to this skill). It writes to `.context/raw/canon/verdicts.jsonl`
|
|
158
|
+
in the current repo. Never edit or delete existing lines. `canon learn` reads
|
|
159
|
+
the log across products: how often the gate stops work, and which rules keep
|
|
160
|
+
being overridden.
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: wiki-lint
|
|
3
|
+
description: Audit .context/wiki/ for drift — broken [[links]], orphan pages, contradictions between entities, stale last-verified dates, unprocessed raw files. Optionally auto-fix safe issues and regenerate .context/wiki/index.md. Usage `/wiki-lint` (audit) or `/wiki-lint --fix` (audit + auto-fix).
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
You are linting the wiki at `.context/wiki/` against the wiki schema (the `wiki-schema.md` that `canon standards` lists — a team's own replaces canon's; without the CLI, `../../standards/wiki-schema.md` relative to this skill).
|
|
7
|
+
|
|
8
|
+
Mode: `$ARGUMENTS` (empty = audit only; `--fix` = audit + auto-fix safe issues).
|
|
9
|
+
|
|
10
|
+
## Steps
|
|
11
|
+
|
|
12
|
+
1. **Read the wiki schema** to refresh the folders, the one test and the caps.
|
|
13
|
+
|
|
14
|
+
2. **Run `canon check` first** if the CLI is installed. It checks frontmatter,
|
|
15
|
+
placeholders, caps, dated decision names, duplicate IDs, staleness and
|
|
16
|
+
prices held by no entity in under a second,
|
|
17
|
+
plus any checker the repo declares. Start from its output rather than
|
|
18
|
+
re-deriving it.
|
|
19
|
+
|
|
20
|
+
3. **Enumerate pages.** List every `.md` file under `.context/wiki/` (excluding `index.md` and `CLAUDE.md`). For each, parse the frontmatter.
|
|
21
|
+
|
|
22
|
+
4. **Build the graph:**
|
|
23
|
+
- Map `id → file path`.
|
|
24
|
+
- For each page, extract all `[[wikilink]]` tokens from the body.
|
|
25
|
+
- Build inbound and outbound link sets per page.
|
|
26
|
+
|
|
27
|
+
5. **Run the checks below.** Group findings into **Blockers** and **Warnings**.
|
|
28
|
+
|
|
29
|
+
### Blockers (must be fixed)
|
|
30
|
+
|
|
31
|
+
| Check | Rule |
|
|
32
|
+
|---|---|
|
|
33
|
+
| Broken `[[wikilink]]` | Target page does not exist |
|
|
34
|
+
| Duplicate `id` | Two pages claim the same ID |
|
|
35
|
+
| Contradictory canonical value | Two `entity` pages list the same key with different values |
|
|
36
|
+
| Placeholder text | `TBD`, `none yet`: write the fact or delete the section |
|
|
37
|
+
| `type` does not match folder | If a page sets `type`, it lives in that type's folder |
|
|
38
|
+
|
|
39
|
+
### Warnings
|
|
40
|
+
|
|
41
|
+
| Check | Rule |
|
|
42
|
+
|---|---|
|
|
43
|
+
| Over a cap | Page 60 lines, decision 30, README 30, tasks 100 |
|
|
44
|
+
| Restates code, a design or git | Delete the lines; link the source instead |
|
|
45
|
+
| Two pages on one topic | Merge into one, edited in place |
|
|
46
|
+
| Stale `last-verified` | > 90 days from today. |
|
|
47
|
+
| Unprocessed raw file | A file under `.context/raw/` that no wiki page references in its `Sources`. |
|
|
48
|
+
| User-facing string violates copy rules | Check quoted copy against the rules in the root `CLAUDE.md`. Best-effort. |
|
|
49
|
+
|
|
50
|
+
6. **Auto-fix (only if `--fix` is in `$ARGUMENTS`):**
|
|
51
|
+
- Regenerate `.context/wiki/index.md` from scratch: enumerate pages by type, sort alphabetically by slug, keep the structure the file already has.
|
|
52
|
+
- Fix `last-verified` to today's date on any page whose body was edited in the working tree.
|
|
53
|
+
- **Never** auto-fix: contradictory canonical values, broken `[[wikilinks]]`, merges or cuts. These need a human decision.
|
|
54
|
+
|
|
55
|
+
7. **Report.** Print:
|
|
56
|
+
- Counts: pages, blockers, warnings, auto-fixes applied.
|
|
57
|
+
- Per-finding lines: `[BLOCKER|WARN] <path>:<rule> — <detail>`.
|
|
58
|
+
- For each blocker, one suggested fix.
|
|
59
|
+
- For broken `[[wikilinks]]`, list candidate existing pages by name similarity.
|
|
60
|
+
|
|
61
|
+
## Rules
|
|
62
|
+
|
|
63
|
+
- **Never edit pages other than auto-fixes above.** Lint reports; the user (or `/ingest`) fixes.
|
|
64
|
+
- **Never delete pages from this skill.** Propose the cut; the user approves it. Git keeps what is deleted.
|
|
65
|
+
- **Never modify `.context/raw/`** except to warn about unprocessed files.
|
|
66
|
+
- If a blocker resists auto-fix, exit non-zero (in CI mode) but always print the full report first.
|
|
67
|
+
- Today's date is in the session context — use it for staleness math (>90 days).
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# standards/
|
|
2
|
+
|
|
3
|
+
canon's default standards. `canon standards` lists the ones that apply to a repo:
|
|
4
|
+
these first, then each folder named under `standards:` in the estate's and the
|
|
5
|
+
repo's `.claude/canon.yaml`. A configured file with the same name as one of these
|
|
6
|
+
replaces it; a configured `constitution.md` adds principles instead.
|
|
7
|
+
|
|
8
|
+
| File | What it holds |
|
|
9
|
+
|---|---|
|
|
10
|
+
| `constitution.md` | The principles a request is weighed against (C-01 to C-13) |
|
|
11
|
+
| `wiki-schema.md` | Wiki page types, frontmatter, required sections, lint rules |
|
|
12
|
+
| `context-layout.md` | The `.context/` ten-folder layout, where each kind of document lives, `features/` and `tasks.md` formats |
|
|
13
|
+
| `dev-methods.md` | The evidence spec-, test- and data-driven work leaves behind |
|
|
14
|
+
| `agent-contract.md` | What every agent does before, during and after work |
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Agent contract
|
|
2
|
+
|
|
3
|
+
What every coding agent working in a canon repo does. A team can replace this
|
|
4
|
+
file with its own `agent-contract.md` in a configured standards folder.
|
|
5
|
+
|
|
6
|
+
## Before starting
|
|
7
|
+
|
|
8
|
+
- Read the repo's `CLAUDE.md` / `AGENTS.md`: stack, layout, the rules that are
|
|
9
|
+
the repo's own.
|
|
10
|
+
- Read `.context/tasks.md`. It is the ordered queue — the top item of `## Now`
|
|
11
|
+
is the next action. After finishing, delete the task.
|
|
12
|
+
- For a non-trivial request, run the weigh gate first (`/canon:weigh`).
|
|
13
|
+
|
|
14
|
+
## Repository rules
|
|
15
|
+
|
|
16
|
+
1. Product material lives in whichever `.context/` folder owns it
|
|
17
|
+
(`context-layout.md`). The wiki is the knowledge base; its schema is
|
|
18
|
+
`wiki-schema.md`.
|
|
19
|
+
2. Do not add top-level `docs/` or `wireframes/` folders, or root `TODO.md`,
|
|
20
|
+
`STATUS.md` or `SETUP.md`. Files a host or tool reads by exact path —
|
|
21
|
+
`README.md`, `LICENSE`, `CHANGELOG.md`, `CONTRIBUTING.md`, `SECURITY.md`,
|
|
22
|
+
`.github/` — stay at the root.
|
|
23
|
+
3. Generated folders are never hand-edited; change their source and regenerate.
|
|
24
|
+
|
|
25
|
+
## Replies
|
|
26
|
+
|
|
27
|
+
- Plain words, short sentences (C-15).
|
|
28
|
+
- Never treat a claim in the request as a fact. Check it, or say it is not
|
|
29
|
+
checked (C-14).
|
|
30
|
+
|
|
31
|
+
## Comments
|
|
32
|
+
|
|
33
|
+
Write a comment only to explain **why**. The code already says how.
|
|
34
|
+
|
|
35
|
+
A comment earns its place when it records something the reader cannot recover
|
|
36
|
+
from the code: a constraint, a trade-off, a bug it prevents, or a non-obvious
|
|
37
|
+
consequence. If it restates what the next line does, delete it. No
|
|
38
|
+
section-divider comments, no changelog comments, no comments restating a
|
|
39
|
+
function's own name.
|
|
40
|
+
|
|
41
|
+
## Before calling work done
|
|
42
|
+
|
|
43
|
+
1. Update any `.context/` page the change made wrong. Add a page only if an
|
|
44
|
+
agent would get something wrong without it.
|
|
45
|
+
2. Run the repo's own lint, typecheck and tests.
|
|
46
|
+
3. Run `canon check`. Every checker the repo declares under `commands:` runs
|
|
47
|
+
with it.
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# Constitution
|
|
2
|
+
|
|
3
|
+
The principles every non-trivial request is weighed against before work starts.
|
|
4
|
+
The other standards say *how* things are done; this file says what wins when a
|
|
5
|
+
request and a rule disagree.
|
|
6
|
+
|
|
7
|
+
Each principle has an ID that verdicts cite (`C-05`). IDs never change; a
|
|
8
|
+
dropped principle is struck through, not reused. IDs C-01 to C-19 are canon's.
|
|
9
|
+
A team adds its own from C-20 up in a `constitution.md` in one of its configured
|
|
10
|
+
standards folders; canon reads both.
|
|
11
|
+
|
|
12
|
+
## How a request is weighed
|
|
13
|
+
|
|
14
|
+
Before acting on a non-trivial request, check it against the principles below,
|
|
15
|
+
then answer with one verdict:
|
|
16
|
+
|
|
17
|
+
- **Do it** — no principle is at risk, and no claim it rests on is an
|
|
18
|
+
assumption (C-14).
|
|
19
|
+
- **Do it differently** — the goal is fine; the way asked breaks a principle.
|
|
20
|
+
Name the principle and give the cheaper or safer way.
|
|
21
|
+
- **Push back** — the request breaks a principle outright, or the cost is
|
|
22
|
+
clearly higher than the value. Stop until the owner gives a reason; log it.
|
|
23
|
+
|
|
24
|
+
Every verdict cites principle IDs and the files (wiki page, ADR, standard) it
|
|
25
|
+
relied on. A verdict with no citation is an opinion, not a verdict.
|
|
26
|
+
|
|
27
|
+
## Principles
|
|
28
|
+
|
|
29
|
+
### C-01 Shipping beats starting
|
|
30
|
+
A request that finishes or unblocks something already in flight outranks one
|
|
31
|
+
that starts something new. Ask: what does this move closer to a user?
|
|
32
|
+
|
|
33
|
+
### C-02 One home per fact
|
|
34
|
+
Every rule, value and artifact has exactly one source; everything else imports,
|
|
35
|
+
links or is generated from it. A second copy is a future contradiction.
|
|
36
|
+
|
|
37
|
+
### C-03 Knowledge is written down, in the repo
|
|
38
|
+
A decision that lives only in chat or in one machine's memory is lost. Decisions
|
|
39
|
+
become ADRs; canonical values become wiki entities; both live in git. Check the
|
|
40
|
+
wiki and ADRs before answering from memory.
|
|
41
|
+
|
|
42
|
+
### C-04 Decided things stay decided — until a new decision says otherwise
|
|
43
|
+
A request that contradicts an ADR is not done silently. Either it follows the
|
|
44
|
+
ADR, or a new ADR supersedes it, with the reason.
|
|
45
|
+
|
|
46
|
+
### C-05 Value must beat cost
|
|
47
|
+
Weigh effort, tokens, money and the maintenance it adds forever against who
|
|
48
|
+
gains and how much. Name the user or the metric it moves; if neither can be
|
|
49
|
+
named, the value is unproven.
|
|
50
|
+
|
|
51
|
+
### C-06 Write less
|
|
52
|
+
Before writing code: can something be deleted, reused from this repo or a
|
|
53
|
+
sibling, done with the platform or standard library, or done in fewer lines?
|
|
54
|
+
New code is the last rung, not the first.
|
|
55
|
+
|
|
56
|
+
### C-07 Tested tools over custom ones
|
|
57
|
+
Use a maintained, widely used tool before building one. Build only what no tool
|
|
58
|
+
covers, and keep it small.
|
|
59
|
+
|
|
60
|
+
### C-08 Products evolve together
|
|
61
|
+
A fix that applies to more than one product goes into the shared standard,
|
|
62
|
+
template or script — not into one product by hand. A product differs from the
|
|
63
|
+
others only with a written reason.
|
|
64
|
+
|
|
65
|
+
### C-09 Hard rules are code
|
|
66
|
+
A rule that must never break is enforced by a linter, a check or a hook, not by
|
|
67
|
+
prose. When prose keeps getting broken, turn it into a check.
|
|
68
|
+
|
|
69
|
+
### C-10 Secrets are never lost and never leaked
|
|
70
|
+
Every credential is backed up the moment it exists; no secret value goes into a
|
|
71
|
+
commit, a Markdown file or a chat reply.
|
|
72
|
+
|
|
73
|
+
### C-11 Verified, one step at a time
|
|
74
|
+
Prove each step works before the next. Report failures as failures. Commit when
|
|
75
|
+
asked; push only when asked.
|
|
76
|
+
|
|
77
|
+
### C-12 Reversible before irreversible
|
|
78
|
+
Prefer the change that can be undone. Deletes, force-pushes, store submissions,
|
|
79
|
+
production deploys and permission changes are confirmed first, every time.
|
|
80
|
+
Changing who can see, install or use what ships — a repo's visibility, a
|
|
81
|
+
licence, a package name, merging or splitting repos — is in this class: weigh it
|
|
82
|
+
before anything else, and when the owner picks an option, say what each one
|
|
83
|
+
loses first.
|
|
84
|
+
|
|
85
|
+
### C-13 Users' money and data are handled exactly
|
|
86
|
+
Money in integer minor units; privacy promises match what the code does; store
|
|
87
|
+
claims match the app. Correctness beats speed here.
|
|
88
|
+
|
|
89
|
+
### C-14 Facts, not assumptions
|
|
90
|
+
A request is not a fact. Every claim in it ("users want this", "it is slow",
|
|
91
|
+
"it is missing") is checked against the repo and the repo's data sources. A
|
|
92
|
+
claim with no fact behind it is an assumption. Work that rests on an assumption
|
|
93
|
+
does not start until the user agrees to it, in writing, as numbered terms.
|
|
94
|
+
|
|
95
|
+
### C-15 Plain words
|
|
96
|
+
Short sentences and common words. No jargon unless the repo's wiki defines it.
|
|
97
|
+
Say what was checked, what was found and what happens next.
|
|
98
|
+
|
|
99
|
+
## Weights
|
|
100
|
+
|
|
101
|
+
A repo's `.claude/canon.yaml` may raise or lower the weight of a principle under
|
|
102
|
+
`weigh.weights` (a game might weigh C-05 higher; a finance product C-13). It may
|
|
103
|
+
not remove one without a written reason, and every override shows up in
|
|
104
|
+
`canon check`.
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
# The `.context/` layout
|
|
2
|
+
|
|
3
|
+
Every repo keeps its non-code product material in `.context/`, in the same ten
|
|
4
|
+
folders. Each has one job, and none is a bucket meaning "everything else". A team
|
|
5
|
+
can replace this file with its own `context-layout.md` in a configured standards
|
|
6
|
+
folder.
|
|
7
|
+
|
|
8
|
+
```
|
|
9
|
+
<repo>/.context/
|
|
10
|
+
├── README.md what this is, and where to start
|
|
11
|
+
├── tasks.md the ordered queue. The top item is the next action.
|
|
12
|
+
├── raw/ sources you didn't write. Immutable.
|
|
13
|
+
├── wiki/ everything you concluded. Schema: wiki-schema.md
|
|
14
|
+
├── features/ what's next.
|
|
15
|
+
├── designs/ what it looks like.
|
|
16
|
+
├── listing/ what the stores show.
|
|
17
|
+
├── marketing/ how it's sold.
|
|
18
|
+
├── metrics/ the numbers.
|
|
19
|
+
├── support/ what you tell users.
|
|
20
|
+
├── legal/ what you promise.
|
|
21
|
+
└── ops/ how you run it.
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Rules
|
|
25
|
+
|
|
26
|
+
1. **Ten folders, one job each.** There is no `documents/`, `research/`,
|
|
27
|
+
`architecture/` or `decisions/` folder: a research brief is a wiki synthesis
|
|
28
|
+
page, an architecture note is a wiki concept, an ADR is `wiki/decisions/`.
|
|
29
|
+
A product that truly needs another folder adds it in `.claude/canon.yaml`,
|
|
30
|
+
with the reason: `context: { folders: [{ folder: research, reason: … }] }`.
|
|
31
|
+
The ten cannot be removed.
|
|
32
|
+
2. **`README.md` and `tasks.md` are the only files at `.context/` root.**
|
|
33
|
+
A repo names only what it uses. Its README, its `canon.yaml` and its docs never
|
|
34
|
+
list a folder, file or tool it does without; absence is shown by absence.
|
|
35
|
+
3. **Nothing is created empty.** A folder appears with its first file — git does
|
|
36
|
+
not track empty folders, so a placeholder disappears on clone. `raw/` is the
|
|
37
|
+
one exception and carries a `.gitkeep`.
|
|
38
|
+
4. **One home per artifact; everything else is an export.** Source art lives in
|
|
39
|
+
`designs/`; store images and press kits are generated from it.
|
|
40
|
+
5. **Authored vs generated is visible.** A generated file is committed but never
|
|
41
|
+
hand-edited.
|
|
42
|
+
|
|
43
|
+
## What a repo is expected to have
|
|
44
|
+
|
|
45
|
+
| Stage | Expected |
|
|
46
|
+
|---|---|
|
|
47
|
+
| any repo | `README.md` · `tasks.md` |
|
|
48
|
+
| uses the `docs` or `knowledge` module | + `raw/` · `wiki/` · `features/` |
|
|
49
|
+
| draws its UI | + `designs/` (optional; an estate can require it with a command) |
|
|
50
|
+
| has a store presence | + `listing/` |
|
|
51
|
+
| is live to users | + `marketing/` · `metrics/` · `support/` · `legal/` |
|
|
52
|
+
| once something runs | + `ops/` |
|
|
53
|
+
|
|
54
|
+
## Naming and frontmatter
|
|
55
|
+
|
|
56
|
+
- Dated sources (`raw/`) → ISO date: `YYYY-MM-DD-slug.md`.
|
|
57
|
+
- Features → zero-padded number: `NNNN-slug.md`.
|
|
58
|
+
- Everything else is named by topic and edited in place.
|
|
59
|
+
- Frontmatter: `last-verified`, kebab-case keys. See the wiki schema.
|
|
60
|
+
|
|
61
|
+
## Where each kind of document lives
|
|
62
|
+
|
|
63
|
+
Teams name documents many ways. Each name maps to one home; there is no
|
|
64
|
+
separate folder per name.
|
|
65
|
+
|
|
66
|
+
| Document | Home |
|
|
67
|
+
|---|---|
|
|
68
|
+
| ADR | `wiki/decisions/<topic>.md`, overwritten when the choice changes |
|
|
69
|
+
| RFC | `features/`; once accepted, the choice goes in `wiki/decisions/` |
|
|
70
|
+
| PRD | `features/`, `type: feature` |
|
|
71
|
+
| Experiment | `features/`, `type: experiment`; the result is a decision page |
|
|
72
|
+
| Initiative | `wiki/synthesis/`, linking its features and decisions |
|
|
73
|
+
| Finding | the dated data in `raw/`; what it means in `wiki/synthesis/` or a concept |
|
|
74
|
+
| Know-how | `wiki/concepts/`; `ops/` when it is a runbook |
|
|
75
|
+
| Bug | the issue tracker; a wiki concept only when it teaches a rule |
|
|
76
|
+
| Data source | `wiki/entities/` — see the wiki schema, "Data sources" |
|
|
77
|
+
|
|
78
|
+
If a document fits none of these for a real product, add a wiki type or a
|
|
79
|
+
folder in `.claude/canon.yaml` with its reason — not a new convention by hand.
|
|
80
|
+
|
|
81
|
+
## `features/` — what is next
|
|
82
|
+
|
|
83
|
+
One page per feature, `NNNN-<slug>.md`:
|
|
84
|
+
|
|
85
|
+
```markdown
|
|
86
|
+
---
|
|
87
|
+
id: FEAT-0031
|
|
88
|
+
type: feature # feature | experiment | chore | platform
|
|
89
|
+
status: building # planned | building | shipped | shelved | superseded
|
|
90
|
+
last-verified: 2026-04-02
|
|
91
|
+
release: 3.4.0
|
|
92
|
+
---
|
|
93
|
+
## Summary · ## Motivation · ## Acceptance scenarios (Given/When/Then)
|
|
94
|
+
## Out of scope · ## Open questions
|
|
95
|
+
## Store copy
|
|
96
|
+
> One or two sentences users will read in the release notes.
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
An experiment adds `## Hypothesis`, `## Metric` (a name from
|
|
100
|
+
`metrics/definitions.yml`) and `## Result` once it has run.
|
|
101
|
+
|
|
102
|
+
The wiki describes what *is*; `features/` describes what is *next*. A shipped
|
|
103
|
+
feature goes `status: shipped`.
|
|
104
|
+
|
|
105
|
+
## `tasks.md` — open work only
|
|
106
|
+
|
|
107
|
+
```markdown
|
|
108
|
+
# Tasks
|
|
109
|
+
|
|
110
|
+
## Now <!-- position is the dependency; do in order -->
|
|
111
|
+
1. [ ] T001 Add a screenshot mode `feat:0002` ~1d
|
|
112
|
+
2. [ ] T002 Write the capture flows needs:T001 ~3h
|
|
113
|
+
|
|
114
|
+
## Parallel <!-- independent, safe to batch -->
|
|
115
|
+
- [ ] T004 Move the SKU IDs into the wiki ~1h
|
|
116
|
+
|
|
117
|
+
## Blocked
|
|
118
|
+
- [ ] T005 Submit the iOS build
|
|
119
|
+
blocked-by: store account access since:2026-09-16
|
|
120
|
+
unblock: ask for the role next-check:2026-10-06
|
|
121
|
+
|
|
122
|
+
## Waiting <!-- deferred by time, not by a task -->
|
|
123
|
+
- [ ] T006 Second-language listing wait:2026-11-01
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
Delete a task when it is done — the commit records it. No `## Done`, no session
|
|
127
|
+
notes. Cap: 100 lines. A blocker with no unblocking action and no check date is a
|
|
128
|
+
silent leak. A task that needs more than a line and a continuation is a
|
|
129
|
+
`features/` page.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Development methods
|
|
2
|
+
|
|
3
|
+
canon does not run a method; it checks that the method left evidence a later
|
|
4
|
+
reader (or the weigh gate) can follow. A team replaces this file with its own
|
|
5
|
+
`dev-methods.md` in a configured standards folder.
|
|
6
|
+
|
|
7
|
+
| Method | The evidence it leaves |
|
|
8
|
+
|---|---|
|
|
9
|
+
| Spec-driven | A `features/` page with acceptance scenarios, written before the code. Code and tests cite its ID (`FEAT-0031`) or a wiki ID (`FLOW.…`, `DECISION.…`). |
|
|
10
|
+
| Test-driven | A test that failed before the change and passes after. Bug fixes start with the failing test. The test path goes in the feature page or decision. |
|
|
11
|
+
| Data-driven | A named metric in `metrics/definitions.yml`, the query that measured it, and a dated snapshot in `raw/`. The decision cites the snapshot, not a memory of a dashboard. |
|
|
12
|
+
|
|
13
|
+
## Which one, when
|
|
14
|
+
|
|
15
|
+
- **New behaviour users see** → spec-driven: the feature page comes first.
|
|
16
|
+
- **Logic that can break** (money, parsing, data writes, a bug fix) → test-driven.
|
|
17
|
+
- **A bet on what users want** → data-driven: an experiment page with its metric
|
|
18
|
+
before the build, the result as a decision after.
|
|
19
|
+
|
|
20
|
+
They combine. A paywall change is a spec (what users see), tests (the price
|
|
21
|
+
logic) and an experiment (does conversion move).
|
|
22
|
+
|
|
23
|
+
## Rules
|
|
24
|
+
|
|
25
|
+
1. No evidence, not done. "It works" without a test, a scenario or a number is
|
|
26
|
+
an opinion.
|
|
27
|
+
2. Evidence lives in the repo (C-03). A dashboard link alone is not evidence —
|
|
28
|
+
it changes; the snapshot in `raw/` does not.
|
|
29
|
+
3. When a method keeps being skipped, make it a check (C-09), not a longer doc.
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# Wiki — rules
|
|
2
|
+
|
|
3
|
+
`.context/wiki/` holds what an agent would get wrong without being told. `.context/raw/` holds
|
|
4
|
+
sources, never edited. Answer from the wiki, not from raw.
|
|
5
|
+
|
|
6
|
+
## The test
|
|
7
|
+
|
|
8
|
+
Keep a line only if an agent would make a mistake without it. Never write what the
|
|
9
|
+
code, an HTML design, or `git log` already says. Describe what is true **now**:
|
|
10
|
+
history is git's job.
|
|
11
|
+
|
|
12
|
+
## Folders
|
|
13
|
+
|
|
14
|
+
| Folder | Holds | Example |
|
|
15
|
+
|---|---|---|
|
|
16
|
+
| `concepts/` | a rule or invariant | `money-in-minor-units` |
|
|
17
|
+
| `entities/` | canonical values (prices, SKUs, limits) — the one home for each | `plan-pro` |
|
|
18
|
+
| `decisions/` | one file per topic: the current choice | `pricing` |
|
|
19
|
+
| `surfaces/` | a screen's notes: what its HTML can't show (only screens that have some) | `paywall` |
|
|
20
|
+
| `synthesis/` | research and cross-cutting analysis | `tax-table-verification-ay-2026-27` |
|
|
21
|
+
|
|
22
|
+
There is no page per screen: the HTML design is the screen spec. A screen gets a
|
|
23
|
+
`surfaces/<slug>.md` only when it has a constraint or decision invisible in its pixels;
|
|
24
|
+
the design set's notes button shows it, and `routes.js` sets `notes: null` for every
|
|
25
|
+
other screen. A user journey worth keeping is a concept.
|
|
26
|
+
A product may add a folder in `.claude/canon.yaml` under `wiki.types`, with a reason.
|
|
27
|
+
|
|
28
|
+
## Pages
|
|
29
|
+
|
|
30
|
+
- Frontmatter: `last-verified: YYYY-MM-DD` is the only required field. `id` is kept
|
|
31
|
+
where code references it (`SOURCE.*`, entity keys).
|
|
32
|
+
- Write only the sections you have something to say in. No `TBD`, no `none yet`.
|
|
33
|
+
- One file per topic, edited in place. No dated names, no `v2`, no supersede chains.
|
|
34
|
+
- Caps: page 60 lines, decision 30. Synthesis is exempt.
|
|
35
|
+
- Link with `[[slug]]` (the file name without `.md`). `index.md` is one line per page.
|
|
36
|
+
|
|
37
|
+
## Decisions
|
|
38
|
+
|
|
39
|
+
```markdown
|
|
40
|
+
---
|
|
41
|
+
last-verified: 2026-10-27
|
|
42
|
+
---
|
|
43
|
+
# Pricing
|
|
44
|
+
**Choice:** annual plan only, ₹249 ([[plan-pro]]).
|
|
45
|
+
**Why:** monthly churn was 3× annual in the 2026-06 test.
|
|
46
|
+
**Rejected:** monthly plan (churn) · lifetime deal (no recurring revenue).
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
When the choice changes, overwrite the file. `Rejected:` is what stops the same idea
|
|
50
|
+
being proposed again; keep it. Fix lists and audit results go in commit messages or
|
|
51
|
+
`CHANGELOG.md`, not here.
|
|
52
|
+
|
|
53
|
+
## Data sources
|
|
54
|
+
|
|
55
|
+
Each tool that holds product data is one entity page, `id: SOURCE.<NAME>`, with a
|
|
56
|
+
`## How to query` section and a `SOURCE.<NAME>.ACCESS` row: `mcp: <server>`,
|
|
57
|
+
`skill: <name>`, `cli: <command>` (also listed in `doctor.tools`) or `manual: <where>`.
|
|
58
|
+
Queries are read-only, one or two per claim, with a row limit. Save counts and
|
|
59
|
+
rates to `raw/YYYY-MM-DD-<source>-<slug>.md`, never rows that name a person. Never
|
|
60
|
+
put a key or token on the page.
|
|
61
|
+
|
|
62
|
+
## Not for
|
|
63
|
+
|
|
64
|
+
Code docs (they go next to the code) · tasks (`tasks.md`) · plans (`features/`) ·
|
|
65
|
+
chat logs · session notes · changelogs.
|
|
66
|
+
|
|
67
|
+
## Checked by `canon check`
|
|
68
|
+
|
|
69
|
+
`wiki-frontmatter` (last-verified, placeholders, stale > 90 days) · `context-size`
|
|
70
|
+
(caps, dated decision names, no `flows/`) · `canonical-values` (a
|
|
71
|
+
price in a decision or screen note is held by an entity) · `sources`.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/* global module */
|
|
2
|
+
// This app's architecture rules, enforced by `canon check` (architecture module).
|
|
3
|
+
// canon wrote this starter once; it is yours now. Add the layers this app has
|
|
4
|
+
// and keep the why in a wiki concept page.
|
|
5
|
+
// Rule reference: https://github.com/sverweij/dependency-cruiser/blob/main/doc/rules-reference.md
|
|
6
|
+
|
|
7
|
+
/** @type {import('dependency-cruiser').IConfiguration} */
|
|
8
|
+
module.exports = {
|
|
9
|
+
extends: "../../.dependency-cruiser.base.cjs",
|
|
10
|
+
forbidden: [
|
|
11
|
+
{
|
|
12
|
+
name: "no-app-to-app",
|
|
13
|
+
comment: "An app never imports another app; share code through packages/.",
|
|
14
|
+
severity: "error",
|
|
15
|
+
from: {},
|
|
16
|
+
to: { path: "^\\.\\./[^./]" },
|
|
17
|
+
},
|
|
18
|
+
],
|
|
19
|
+
options: {
|
|
20
|
+
// The level `canon ui` draws the architecture graph at: one box per match.
|
|
21
|
+
reporterOptions: { archi: { collapsePattern: "^src/[^/]+/[^/]+|^src/[^/]+|^[^/.][^/]*|^\\.\\./\\.\\./packages/[^/]+" } },
|
|
22
|
+
},
|
|
23
|
+
};
|