@erclx/canon 5.63.0 → 5.64.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/CHANGELOG.md +16 -0
- package/claude/.claude-plugin/plugin.json +1 -1
- package/claude/skills/api-design/references/adopted.md +1 -1
- package/claude/skills/context-fold/REQUIREMENT.md +2 -3
- package/claude/skills/context-fold/SKILL.md +1 -11
- package/claude/skills/context-fold/references/completion-report.md +8 -9
- package/claude/skills/create-skill/references/skill-practice.md +16 -1
- package/claude/skills/design-taste/references/adopted.md +17 -97
- package/claude/skills/design-taste/references/tells.md +2 -2
- package/claude/skills/document-health/REQUIREMENT.md +1 -1
- package/claude/skills/document-health/SKILL.md +3 -14
- package/claude/skills/document-health/references/axes.md +14 -16
- package/docs/agents/audits.md +2 -6
- package/docs/agents/context-audit.md +1 -1
- package/governance/ledger/skills/api-design/SKILL.md +62 -0
- package/governance/ledger/skills/code-craft/SKILL.md +53 -0
- package/governance/ledger/skills/deprecation-migration/SKILL.md +68 -0
- package/governance/ledger/skills/design-taste/SKILL.md +64 -0
- package/governance/ledger/skills/design-taste/craft.md +66 -0
- package/governance/ledger/skills/design-taste/kinds.md +58 -0
- package/governance/ledger/skills/design-taste/systems.md +42 -0
- package/governance/ledger/skills/design-taste/tells.md +103 -0
- package/package.json +1 -1
- package/src/audits/catalog.ts +0 -52
- package/src/claude/skills-audit.ts +117 -41
- package/src/cli/retired.ts +8 -0
- package/src/commands/claude.ts +11 -2
- package/src/commands/context.ts +0 -425
- package/src/context/citations.ts +9 -3
- package/src/gate/measures.ts +1 -1
- package/src/git/files.ts +8 -3
- package/src/markdown/gated.ts +1 -1
- package/src/markdown/scope.ts +0 -1
- package/claude/skills/context-fold/references/classify.md +0 -87
- package/src/context/classify/extract.ts +0 -443
- package/src/context/classify/ollama.ts +0 -172
- package/src/context/classify/patterns.ts +0 -75
- package/src/context/classify/prompts.ts +0 -74
- package/src/context/classify/run.ts +0 -348
- package/src/context/classify/settings.ts +0 -196
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [5.64.0](https://github.com/erclx/canon/compare/v5.63.0...v5.64.0) (2026-10-24)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* **context:** remove the content classifier ([#2695](https://github.com/erclx/canon/issues/2695)) ([6d92b50](https://github.com/erclx/canon/commit/6d92b50bd0042a12d62574a034b1658eb6486e54))
|
|
9
|
+
* **skills:** ledger the craft skill bodies on their concern groups ([#2700](https://github.com/erclx/canon/issues/2700)) ([02655a5](https://github.com/erclx/canon/commit/02655a5ede3879e572145316461e2c61e307985b))
|
|
10
|
+
* **skills:** source every design-taste rule bullet in a ledger ([#2691](https://github.com/erclx/canon/issues/2691)) ([bb57e71](https://github.com/erclx/canon/commit/bb57e71e7db56ac4fc4d66f85e826b4ac2a3ae4a))
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### Bug Fixes
|
|
14
|
+
|
|
15
|
+
* **claude:** resolve seeded records at either surface root ([#2696](https://github.com/erclx/canon/issues/2696)) ([288336c](https://github.com/erclx/canon/commit/288336c07c57c1a9b26a4cc6ea97c988f3338988))
|
|
16
|
+
* **context:** skip the install stamp in the citation scan ([#2699](https://github.com/erclx/canon/issues/2699)) ([d2f0425](https://github.com/erclx/canon/commit/d2f0425bd33f69cf9f3529769d06e916a716b0d5))
|
|
17
|
+
* **git:** leave deleted tracked paths out of the repository listing ([#2698](https://github.com/erclx/canon/issues/2698)) ([baa91e5](https://github.com/erclx/canon/commit/baa91e5a2a5d11bab9567bedf494eae5b63f7c09))
|
|
18
|
+
|
|
3
19
|
## [5.63.0](https://github.com/erclx/canon/compare/v5.62.0...v5.63.0) (2026-10-24)
|
|
4
20
|
|
|
5
21
|
|
|
@@ -17,7 +17,7 @@ Adopted as the opening group, stated as design rules rather than as an observati
|
|
|
17
17
|
|
|
18
18
|
### One version per dependency
|
|
19
19
|
|
|
20
|
-
[Software Engineering at Google, ch.
|
|
20
|
+
[Software Engineering at Google, ch. 16](https://abseil.io/resources/swe-book/html/ch16.html) states the One-Version Rule, keeping one version of each dependency in a repository, so a change to it migrates every caller rather than leaving two versions live. Adopted under additive change for a caller that cannot pin, which is any module imported from inside one repository.
|
|
21
21
|
|
|
22
22
|
## Adopted from one external skill
|
|
23
23
|
|
|
@@ -16,14 +16,13 @@ The context entries describe the repository the session opened with. An entry ke
|
|
|
16
16
|
- Name the context entries in a trigger phrase, so a bare request to sync the docs separates this skill from `docs-sync`
|
|
17
17
|
- Take the refresh scope from the diff and write tracked docs at the current worktree root, only when the diff adds, moves, or removes a folder, falsifies a bullet, or changes a trap
|
|
18
18
|
- Report a requirements or direction change in one line naming `document-health` rather than writing it
|
|
19
|
-
- Close on `canon context audit`
|
|
20
|
-
-
|
|
19
|
+
- Close on `canon context audit` over the fold's whole baseline, reporting findings on files this run wrote or the diff carries
|
|
20
|
+
- Continue the fold when a check cannot run
|
|
21
21
|
|
|
22
22
|
## Must not
|
|
23
23
|
|
|
24
24
|
- Write the task board, the design record, `CLAUDE.md`, the requirements record, or a promoted page
|
|
25
25
|
- Create an entry for a domain the catalog does not list, or report a finding on an entry this run never touched
|
|
26
|
-
- Pick a classifier backend, re-run the classifier after a fix, or apply a finding whose quote is not found exactly once
|
|
27
26
|
- Stop the fold on a finding, a refusal, or a missing subcommand
|
|
28
27
|
|
|
29
28
|
## Out of scope
|
|
@@ -62,7 +62,7 @@ Write each updated file immediately. Claude Code's tool permission dialog is the
|
|
|
62
62
|
|
|
63
63
|
## Step 4: audit what the fold touched
|
|
64
64
|
|
|
65
|
-
Run the structural audit
|
|
65
|
+
Run the structural audit and the markdown audit, and answer each before the report. Findings never stop the fold.
|
|
66
66
|
|
|
67
67
|
### Structural audit
|
|
68
68
|
|
|
@@ -85,16 +85,6 @@ Run `canon markdown audit <path>` over every entry Step 3 wrote this run, and fi
|
|
|
85
85
|
- Report a finding in a section Step 3 left alone as `⚠ Audit: <rel>, <finding>`, since the rule above keeps unrelated sections as they are
|
|
86
86
|
- Report a refusal as `⚠ Audit: <message>` and continue
|
|
87
87
|
|
|
88
|
-
### Classify
|
|
89
|
-
|
|
90
|
-
Skip the classifier only when the Diff baseline section could not resolve a base ref at all, reporting `⚠ No diff to scope against. Skipped the classify check.` The verb needs a resolvable ref, which is the one condition it cannot answer for itself.
|
|
91
|
-
|
|
92
|
-
Otherwise read `${CLAUDE_SKILL_DIR}/references/classify.md` for the invocation, its scope, the record fields, applying a finding, the one-line keep reason, the unreachable and missing-subcommand lines, and the report shape.
|
|
93
|
-
|
|
94
|
-
- `${CLAUDE_SKILL_DIR}` names this skill's own directory, resolved once when the skill loaded, so read the reference by that resolved path
|
|
95
|
-
- Never guess a `.claude/skills/context-fold/references/classify.md` path from the install-time layout, which is a different root than this skill's own files
|
|
96
|
-
- The invocation is `canon context classify diff --base <base> --json`, and it runs whether or not that reference resolves
|
|
97
|
-
|
|
98
88
|
## After completion
|
|
99
89
|
|
|
100
90
|
Read `${CLAUDE_SKILL_DIR}/references/completion-report.md` before printing anything, for the line each outcome prints, the lines Step 2 and Step 4 add, and when the closing line is suppressed.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: Completion report
|
|
3
|
-
description: The lines context-fold prints once every step has run, being one per file updated, the direction-change note, Step 4's audit
|
|
3
|
+
description: The lines context-fold prints once every step has run, being one per file updated, the direction-change note, Step 4's audit lines, and the closing line with when it is suppressed
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Completion report
|
|
@@ -9,15 +9,14 @@ The close of `context-fold`. The session reads this file once every step has run
|
|
|
9
9
|
|
|
10
10
|
## Lines
|
|
11
11
|
|
|
12
|
-
| When
|
|
13
|
-
|
|
|
14
|
-
| Per file updated
|
|
15
|
-
| Step 2 noted a requirements change
|
|
16
|
-
| Per audit finding Step 4 reported
|
|
17
|
-
|
|
|
18
|
-
| No file updated and Step 4 reported nothing | `✅ No changes needed.` |
|
|
12
|
+
| When | Line |
|
|
13
|
+
| ------------------------------------------- | -------------------------------------------------------------------------------- |
|
|
14
|
+
| Per file updated | `✅ Updated: <path written>` |
|
|
15
|
+
| Step 2 noted a requirements change | `↪ Direction changed this session: run document-health on canon/REQUIREMENTS.md` |
|
|
16
|
+
| Per audit finding Step 4 reported | `⚠ Audit:` in the shape the body gives |
|
|
17
|
+
| No file updated and Step 4 reported nothing | `✅ No changes needed.` |
|
|
19
18
|
|
|
20
|
-
Do not shorten or paraphrase the audit
|
|
19
|
+
Do not shorten or paraphrase the audit lines here or in the reply, since the finding is what a reader checks it against.
|
|
21
20
|
|
|
22
21
|
## Suppressing the closing line
|
|
23
22
|
|
|
@@ -9,7 +9,7 @@ Applies to a practice skill, one carrying engineering judgment a session applies
|
|
|
9
9
|
|
|
10
10
|
## Scope
|
|
11
11
|
|
|
12
|
-
Governs the closing sections of a practice skill's `skills/<name>/SKILL.md
|
|
12
|
+
Governs the closing sections of a practice skill's `skills/<name>/SKILL.md`, the source ledger at `skills/<name>/references/adopted.md` beside it, and the per-bullet ledgers a listed skill carries.
|
|
13
13
|
|
|
14
14
|
Does not govern:
|
|
15
15
|
|
|
@@ -47,6 +47,21 @@ Follow every concern group with `## Excuses and rebuttals`, `## Red flags`, and
|
|
|
47
47
|
- State what was adopted, what was declined, and why for each, so a later session extends the position rather than re-deriving it.
|
|
48
48
|
- Draw first from the default shelf, [Software Engineering at Google](https://abseil.io/resources/swe-book/html/toc.html) and [Google's engineering practices](https://google.github.io/eng-practices/), and record a source from elsewhere the same way.
|
|
49
49
|
|
|
50
|
+
## Per-bullet ledgers
|
|
51
|
+
|
|
52
|
+
A skill whose files list outside-practice directives one per bullet takes a ledger per such file beside `adopted.md`, with one table row per bullet under each H2, the way a governance rule's ledger does.
|
|
53
|
+
|
|
54
|
+
- Once a skill joins the per-bullet list `canon claude skills audit` keeps, every reference but `adopted.md` takes a ledger, so one added later fails until its rows land
|
|
55
|
+
- Exempt by name a checklist restating rules a ledgered file sources, which would cite each source twice, and a glossary, whose definitions direct nothing
|
|
56
|
+
- Mark the skill's `SKILL.md` for a ledger too when the body carries directives of its own
|
|
57
|
+
- Keep the rows outside the plugin, so a target pays nothing for them
|
|
58
|
+
- Move a source out of `adopted.md` once its row lands in a ledger, since two copies drift on the first edit. `adopted.md` keeps the catalog-level record and the sources behind any unledgered file.
|
|
59
|
+
|
|
60
|
+
The audit counts a few lines in a ledgered file apart from a rule's.
|
|
61
|
+
|
|
62
|
+
- Ledger a listed body's concern groups alone, every H2 before its closing sections or `## What this delegates`, since those restate the groups' rules or route
|
|
63
|
+
- Give a top-level ordered step a row the way a bullet takes one, and a `## Contents` list none, since it repeats the headings
|
|
64
|
+
|
|
50
65
|
## Which skills are practice skills
|
|
51
66
|
|
|
52
67
|
- `canon claude skills audit` keeps the list of practice skills and checks each listed one for the three closing sections and the ledger.
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: Adopted and declined
|
|
3
|
-
description: Where each design-taste rule comes from, being a quoted authority, the community catalog of model-output tells, or a house threshold,
|
|
3
|
+
description: Where each design-taste rule comes from, being a quoted authority, the community catalog of model-output tells, or a house threshold, where the per-bullet rows for the body and the rule references sit, and what was declined and why
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Adopted and declined
|
|
7
7
|
|
|
8
|
-
Every rule in this skill traces to one of three origins. A reader arguing against a rule finds its origin
|
|
8
|
+
Every rule in this skill traces to one of three origins. A reader arguing against a rule finds its origin through this record, and a session extending the skill adds a row rather than re-deriving one.
|
|
9
9
|
|
|
10
10
|
- **An authority.** A typographer, a usability lab, a platform guideline, or the CSS reference states the rule, and the row quotes the passage relied on.
|
|
11
11
|
- **The catalog.** Community prompt skills recorded what models draw when nothing states a direction. A tell from them is an observation of model output, not established practice.
|
|
@@ -15,97 +15,41 @@ A rule a quoted passage only partly backs names the part it backs, and the rest
|
|
|
15
15
|
|
|
16
16
|
## Contents
|
|
17
17
|
|
|
18
|
+
- [Where the rows sit](#where-the-rows-sit)
|
|
18
19
|
- [The layer model](#the-layer-model)
|
|
19
|
-
- [Craft rules an authority states](#craft-rules-an-authority-states)
|
|
20
|
-
- [Systems rules an authority states](#systems-rules-an-authority-states)
|
|
21
|
-
- [Tells an authority states](#tells-an-authority-states)
|
|
22
20
|
- [The catalog](#the-catalog)
|
|
23
|
-
- [House choices](#house-choices)
|
|
24
21
|
- [Declined from the catalogs](#declined-from-the-catalogs)
|
|
25
22
|
- [Declined from the systems reference](#declined-from-the-systems-reference)
|
|
26
23
|
- [Carried as a caution](#carried-as-a-caution)
|
|
27
24
|
|
|
28
|
-
##
|
|
29
|
-
|
|
30
|
-
The body's layer order subdivides the five planes of Jesse James Garrett's [The Elements of User Experience](http://www.jjg.net/elements/). Its second chapter states the dependency the order rests on, that "Each plane is dependent on the planes below it."
|
|
31
|
-
|
|
32
|
-
The same passage gives the constraint running the other way, that "the choices available to us on each plane are constrained by the decisions we make about issues on the planes below it". The nine layers and the grey-box stage are the skill's own subdivision of those planes.
|
|
33
|
-
|
|
34
|
-
## Craft rules an authority states
|
|
35
|
-
|
|
36
|
-
Rows for `craft.md`, grouped by its sections.
|
|
37
|
-
|
|
38
|
-
### Type detail
|
|
39
|
-
|
|
40
|
-
Each rule below is stated by the type reference or the CSS property that implements it.
|
|
41
|
-
|
|
42
|
-
| Rule | Source |
|
|
43
|
-
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
44
|
-
| Measure | [Practical Typography](https://practicaltypography.com/line-length.html): "Aim for an average line length of 45–90 characters, including spaces." |
|
|
45
|
-
| Figures in columns | [MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/font-variant-numeric): `tabular-nums` sets figures "the same size, allowing them to be easily aligned" |
|
|
46
|
-
| Small caps tracked | [Practical Typography](https://practicaltypography.com/letterspacing.html): "always add 5–12% extra letterspacing to text in all caps or small caps" |
|
|
47
|
-
| Large type tighter | The same page: typographers "will often remove letterspacing from lowercase text used at larger sizes" |
|
|
48
|
-
| Orphans | [MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/text-wrap): `balance` suits "a short number of lines, such as headings, captions, and blockquotes" |
|
|
49
|
-
| Hanging punctuation | [MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/hanging-punctuation): "An opening bracket or quote at the start of the first formatted line" hangs |
|
|
50
|
-
|
|
51
|
-
Casing is the `ui-craft` copy reference's, which `craft.md` points at rather than restating.
|
|
52
|
-
|
|
53
|
-
### Optical size, hierarchy, and unfinished work
|
|
54
|
-
|
|
55
|
-
The rows below back one bullet each. The error row backs the fix half of its bullet alone.
|
|
56
|
-
|
|
57
|
-
| Rule | Source |
|
|
58
|
-
| --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
59
|
-
| Optical size | [Wikipedia, Overshoot](https://en.wikipedia.org/wiki/Overshoot_%28typography%29): round letters overshoot "to achieve an optical effect of being the same size" |
|
|
60
|
-
| Hierarchy from weight | [Practical Typography](https://practicaltypography.com/headings.html): with a bold heading, "you can also try reducing the point size" |
|
|
61
|
-
| Where the reader is | [NN/g](https://www.nngroup.com/articles/navigation-you-are-here/): "Navigation should not only show where you can go but also where you are now." |
|
|
62
|
-
| Error opens on a fix | [NN/g](https://www.nngroup.com/articles/error-message-guidelines/): "offer some potential remedies" |
|
|
63
|
-
|
|
64
|
-
That an apology should not lead the error is the catalog's observation, since the NN/g page allows one on a total failure.
|
|
65
|
-
|
|
66
|
-
### Craft rules from the catalog
|
|
25
|
+
## Where the rows sit
|
|
67
26
|
|
|
68
|
-
|
|
27
|
+
Each bullet in the skill body's concern groups and in `craft.md`, `kinds.md`, `systems.md`, and `tells.md` has its own source row in a ledger outside the plugin, one ledger per file and one row per bullet under the H2 the bullet sits under.
|
|
69
28
|
|
|
70
|
-
|
|
29
|
+
- The toolkit's skill audit fails a ledgered file whose bullets and rows disagree in count under any heading, and a target never carries the rows
|
|
30
|
+
- The body's `## What this delegates` takes no rows, since it routes rather than directs
|
|
31
|
+
- `preflight.md` takes no ledger, since its boxes restate the rules the four ledgered references source
|
|
32
|
+
- `vocabulary.md` takes none either, since it defines terms rather than directing
|
|
33
|
+
- This record keeps the layer model behind the body's order, and what was read and declined
|
|
71
34
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
| Rule | Source |
|
|
75
|
-
| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
76
|
-
| Between groups beats within | [NN/g](https://www.nngroup.com/articles/gestalt-proximity/): "Items close together are likely to be perceived as part of the same group" |
|
|
77
|
-
| One gap everywhere fails | The same page: a tight label reads as one group "compared to a larger margin before the next label-field pair" |
|
|
78
|
-
| Adjacent steps differ | [Practical Typography](https://practicaltypography.com/headings.html): "Use the smallest increment necessary to make a visible difference." |
|
|
79
|
-
| Fewer steps than feel enough | The same page: "Limit yourself to three levels of headings. Two is better." |
|
|
80
|
-
| Weights beside sizes | The bold heading passage under craft above |
|
|
81
|
-
| Dark mode re-derived | [Apple HIG](https://developer.apple.com/design/human-interface-guidelines/dark-mode): dark colors "aren't necessarily inversions of their light counterparts" |
|
|
82
|
-
|
|
83
|
-
### Systems rules from the catalog
|
|
84
|
-
|
|
85
|
-
Geometric spacing steps, space responding to the viewport, body size anchoring the scale, and line height moving opposite to size are catalog observations. Practical Typography gives a line spacing range for body text alone, so it does not back the last.
|
|
86
|
-
|
|
87
|
-
Every palette rule but the dark mode row is catalog as well, being accent by rarity, one neutral temperature, the separation of surfaces from content, a semantic color kept off the accent, and the saturation budget.
|
|
88
|
-
|
|
89
|
-
## Tells an authority states
|
|
35
|
+
## The layer model
|
|
90
36
|
|
|
91
|
-
|
|
37
|
+
The body's layer order subdivides the five planes of Jesse James Garrett's [The Elements of User Experience](http://www.jjg.net/elements/). Its second chapter states the dependency the order rests on, that "Each plane is dependent on the planes below it."
|
|
92
38
|
|
|
93
|
-
|
|
94
|
-
| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
95
|
-
| Unstyled platform control | [MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Properties/color-scheme): it adapts "The default colors of form controls" |
|
|
96
|
-
| Transparency with no checkerboard | [Wikipedia](https://en.wikipedia.org/wiki/Transparency_%28graphic%29): an editor "shows transparency by a special pattern, e.g. a checkerboard pattern" |
|
|
97
|
-
| Shortcut beside its command | [NN/g](https://www.nngroup.com/articles/ui-copy/): shortcuts sit "to the far right of the menu" and "alongside the command text in tool tips" |
|
|
39
|
+
The same passage gives the constraint running the other way, that "the choices available to us on each plane are constrained by the decisions we make about issues on the planes below it". The nine layers and the grey-box stage are the skill's own subdivision of those planes.
|
|
98
40
|
|
|
99
41
|
## The catalog
|
|
100
42
|
|
|
101
|
-
|
|
43
|
+
Most tells in `tells.md`, and the ten defaults in the body, came from community prompt skills that recorded what models draw unguided. None of them is a design authority. Each tell is an observation of model output, falsifiable against a render, rather than established practice.
|
|
102
44
|
|
|
103
45
|
- **[Taste-Skill](https://github.com/leonxlnx/taste-skill)** and its fork **[claude-taste-skill](https://github.com/nxpatterns/claude-taste-skill)** supplied the composition, content, surface, and motion tells
|
|
104
46
|
- **[UI/UX Pro Max](https://github.com/nextlevelbuilder/ui-ux-pro-max-skill)** was first read through a vendor listing and later from its repository. Its ranking puts accessibility first, and its lookup corpus was declined.
|
|
105
47
|
- **[frontend-design](https://github.com/anthropics/skills/tree/main/skills/frontend-design)**, Anthropic's skill, supplied the five clusters current AI design falls into, restated in `tells.md`
|
|
106
48
|
- **[Impeccable](https://github.com/pbakaus/impeccable)** supplied what a visual direction may lend an application screen and the category self-check, restated in `kinds.md`. Its themed browser surfaces lie behind the platform control tell.
|
|
107
49
|
|
|
108
|
-
No sentence from any of them is copied. Each idea is restated and cited
|
|
50
|
+
No sentence from any of them is copied. Each idea is restated and cited in the ledger row for its bullet.
|
|
51
|
+
|
|
52
|
+
Most Taste-Skill tells came from its v2 experimental skill, which its author later moved to [taste-skill-classics](https://github.com/Leonxlnx/taste-skill-classics), and the rows link it there.
|
|
109
53
|
|
|
110
54
|
### Adopted with no change
|
|
111
55
|
|
|
@@ -115,30 +59,6 @@ The three equal cards, the centered hero over a wash, enumerated eyebrows, scrol
|
|
|
115
59
|
|
|
116
60
|
Source items naming an icon set, a component library, a font by name, or an animation package were rewritten to state what the rule is about. "Do not use Inter" became one family doing every job, since the defensible claim is about pairing and role separation rather than about one typeface.
|
|
117
61
|
|
|
118
|
-
## House choices
|
|
119
|
-
|
|
120
|
-
Each threshold below is the toolkit's, chosen so a tell can be counted rather than judged.
|
|
121
|
-
|
|
122
|
-
| Threshold | Source |
|
|
123
|
-
| ----------------------------- | ---------------------------------------------------------------------------------------------- |
|
|
124
|
-
| About eight spacing values | House choice: past it, a count tells a scale from arithmetic on a finished surface |
|
|
125
|
-
| Five to seven type steps | House choice: fewer forces size to carry every level, and more holds steps nobody tells apart |
|
|
126
|
-
| Two or three section tiers | House choice: enough tiers for rhythm, few enough that each section takes one |
|
|
127
|
-
| One marquee | House choice: a second sliding strip is where the device reads as filler |
|
|
128
|
-
| Two consecutive splits | House choice: a third alternation is where the pattern reads as filler |
|
|
129
|
-
| Four first-screen text items | House choice: a label, a headline, a supporting line, and the actions, so a fifth is countable |
|
|
130
|
-
| One layout family, five items | House choice: a repeated shape and a long run become counts a reviewer can check |
|
|
131
|
-
|
|
132
|
-
The uppercase label count belongs to the `ui-craft` copy reference, whose own ledger records it as a house choice.
|
|
133
|
-
|
|
134
|
-
### The focus ring's weight
|
|
135
|
-
|
|
136
|
-
One more lock is the toolkit's own choice.
|
|
137
|
-
|
|
138
|
-
| Threshold | Source |
|
|
139
|
-
| --------------- | -------------------------------------------------------------------------------------------------------- |
|
|
140
|
-
| One ring weight | House choice: a ring varying by component reads as several products. The `ui-craft` skill owns the floor |
|
|
141
|
-
|
|
142
62
|
## Declined from the catalogs
|
|
143
63
|
|
|
144
64
|
Each item below is real advice placed in the wrong surface, or a rule that decides nothing.
|
|
@@ -77,7 +77,7 @@ The browser and the operating system draw some parts of every page, and a themed
|
|
|
77
77
|
|
|
78
78
|
## The countable limits
|
|
79
79
|
|
|
80
|
-
These rules carry numbers, so they are checked by counting rather than by judging. Each number is a house choice made so the tell can be counted, and
|
|
80
|
+
These rules carry numbers, so they are checked by counting rather than by judging. Each number is a house choice made so the tell can be counted, and its source row records it as one.
|
|
81
81
|
|
|
82
82
|
- **A layout family appears once.** Once a section uses a shape, no other section on the surface uses it. Eight sections need at least four distinct families.
|
|
83
83
|
- **Two consecutive splits, never three.** Alternating image sides reads as considered twice and as filler by the third. Break it with a full-width section, a vertical stack, or a grid.
|
|
@@ -96,4 +96,4 @@ These rules carry numbers, so they are checked by counting rather than by judgin
|
|
|
96
96
|
|
|
97
97
|
## Adopted, declined, and why
|
|
98
98
|
|
|
99
|
-
Most items here are observations of what models draw unguided, gathered from community prompt skills rather than from a design authority. The record of which were
|
|
99
|
+
Most items here are observations of what models draw unguided, gathered from community prompt skills rather than from a design authority. The record of which catalogs were read, which items were declined, and why sits in `adopted.md` beside this file, and it says where each item's own source row sits.
|
|
@@ -16,7 +16,7 @@ Length, placement, and staleness answer to different evidence, and one list hand
|
|
|
16
16
|
- Report per document across the length, placement, and staleness axes, marking each finding with its evidence class, read through the verb owning each measurement and its record's checkpoints
|
|
17
17
|
- Propose a split or an owner as a structure line for each overgrown entry and doubled or unnamed coverage finding, with the headings and the reason
|
|
18
18
|
- Ship the staleness axis as a reading rather than cutting it for lacking a verb
|
|
19
|
-
- Report a refusal, an absent key, or a missing subcommand as an unread axis naming the cause
|
|
19
|
+
- Report a refusal, an absent key, or a missing subcommand as an unread axis naming the cause
|
|
20
20
|
- Run standalone, reading the requirements record for drift with its reminder, and the design record through `canon design audit --json` and its review reminder, routing findings to `design-record`
|
|
21
21
|
|
|
22
22
|
## Must not
|
|
@@ -34,16 +34,7 @@ canon markdown audit --json
|
|
|
34
34
|
canon context audit --json
|
|
35
35
|
```
|
|
36
36
|
|
|
37
|
-
The first answers length, carrying the bullet, paragraph, and depth checkpoints and the per-file weights read against them. The second answers placement for the folders it resolves, carrying entry length, reference form, and index drift.
|
|
38
|
-
|
|
39
|
-
Then read which classifier would run, and deepen placement with the verdicts per section:
|
|
40
|
-
|
|
41
|
-
```bash
|
|
42
|
-
canon context classifier show
|
|
43
|
-
canon context classify sweep --json
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
The first names the backend, the model, and the source that decided both. Report which layer answered, since a project with the model layer off reads from the regex layer alone and the sweep says nothing about which one it used.
|
|
37
|
+
The first answers length, carrying the bullet, paragraph, and depth checkpoints and the per-file weights read against them. The second answers placement for the folders it resolves, carrying entry length, reference form, and index drift. Placement reads `shapeFindings`, `extraSections`, and each entry's `provenance`, all `measured`.
|
|
47
38
|
|
|
48
39
|
Take the checkpoints from the record each verb returns rather than from a number written here. A checkpoint the CLI moves reaches this report with no edit, and a number held in this body goes stale on its own cadence.
|
|
49
40
|
|
|
@@ -58,7 +49,6 @@ Emit the line only for a folder with an entry past the line checkpoint whose Lay
|
|
|
58
49
|
A refusal, an absent key, and a subcommand the project's binary does not carry each leave an axis unread. Report it as unread against the documents it would have covered, name the read that could not be taken, and name the cause.
|
|
59
50
|
|
|
60
51
|
- `canon context audit` refuses with `reason: "no-folders"` where the layout is not the expected one. Reading that honest refusal as an empty finding set reports a healthy corpus nothing looked at.
|
|
61
|
-
- A narrower read is not an unread one. The sweep running on its regex layer alone still answered, so report it with the layer named.
|
|
62
52
|
|
|
63
53
|
### The design record
|
|
64
54
|
|
|
@@ -92,10 +82,9 @@ Nothing triggers this review but a request. A finished review hands the rewrite
|
|
|
92
82
|
|
|
93
83
|
Give each document its three axes, and give each axis three things: the state, the evidence class, and the command or skill that repairs it. Naming the repair is not running it. A length finding names `document-repair`, which rewrites a folder to zero and gates it.
|
|
94
84
|
|
|
95
|
-
The
|
|
85
|
+
The two classes are what keep the axes apart:
|
|
96
86
|
|
|
97
87
|
- `measured`: a verb returned a number read against a stated checkpoint
|
|
98
|
-
- `classified`: a verb returned a verdict carrying its own confidence
|
|
99
88
|
- `read`: this session's judgment, backed by no verb
|
|
100
89
|
|
|
101
90
|
Emit no verdict across the three. Two answer from verbs and one answers from a reading, so a roll-up is a figure that lies about the third. Emit no score across the documents either, for the same reason one level up.
|
|
@@ -131,7 +120,7 @@ Structure `canon/context/surfaces/`: `cli.md` (300 lines) splits into `cli.md` t
|
|
|
131
120
|
|
|
132
121
|
The line is a proposal for the operator, with the headings each entry takes and why. Health applies nothing, and `document-repair` offers the proposal before it rewrites.
|
|
133
122
|
|
|
134
|
-
Keep the evidence line under the table on every run. A table read without it flattens a judgment into a measurement, which is the one shape the
|
|
123
|
+
Keep the evidence line under the table on every run. A table read without it flattens a judgment into a measurement, which is the one shape the two classes exist to prevent.
|
|
135
124
|
|
|
136
125
|
### The design record row
|
|
137
126
|
|
|
@@ -35,24 +35,25 @@ Weight is a judgment a reader settles rather than a defect, as the verb states f
|
|
|
35
35
|
|
|
36
36
|
## Placement
|
|
37
37
|
|
|
38
|
-
| Field | Value
|
|
39
|
-
| -------------- |
|
|
40
|
-
| Measures | Whether a document's content sits in the file that owns it, and whether the catalogs pointing at it resolve
|
|
41
|
-
|
|
|
42
|
-
| Evidence class | `measured`
|
|
38
|
+
| Field | Value |
|
|
39
|
+
| -------------- | ----------------------------------------------------------------------------------------------------------- |
|
|
40
|
+
| Measures | Whether a document's content sits in the file that owns it, and whether the catalogs pointing at it resolve |
|
|
41
|
+
| Verb | `canon context audit --json` |
|
|
42
|
+
| Evidence class | `measured` |
|
|
43
43
|
|
|
44
44
|
The audit answers required sections, entry length, citation resolution, reference form, catalog tables, provenance, and index drift. Required sections reach context entries.
|
|
45
45
|
|
|
46
46
|
- A citation resolving to nothing is a fact and gates
|
|
47
47
|
- Entry length, reference form, table shape, and provenance are judgments under every flag
|
|
48
48
|
|
|
49
|
-
### The
|
|
49
|
+
### The audit's placement arrays
|
|
50
50
|
|
|
51
|
-
|
|
51
|
+
Three parts of the audit record name content sitting outside the shape its folder allows. Each is a count or a list the verb returned, so every placement finding is `measured`.
|
|
52
52
|
|
|
53
|
-
-
|
|
54
|
-
-
|
|
55
|
-
-
|
|
53
|
+
- `shapeFindings`: an entry whose sections break the shape its folder holds, such as a Decisions section or a sixth gotcha
|
|
54
|
+
- `extraSections`: an H2 outside the closed set the folder allows
|
|
55
|
+
- `entries[].provenance`: an entry narrating how it came to be, which is history rather than a description of the tree
|
|
56
|
+
- **Routes to:** the document that owns the passage. The record names no owner, so the project's own content-ownership rules decide the destination.
|
|
56
57
|
|
|
57
58
|
### The structure line
|
|
58
59
|
|
|
@@ -66,12 +67,9 @@ The audit record's `length` array lists each entry past the line checkpoint, and
|
|
|
66
67
|
|
|
67
68
|
A proposal names headings and a reason, so an operator judges a concrete split. A split nobody can act on names none of those.
|
|
68
69
|
|
|
69
|
-
### When
|
|
70
|
+
### When the verb resolves nothing
|
|
70
71
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
- The audit refuses with `reason: "no-folders"`, naming the folders it looked for. Report that refusal as an unread axis.
|
|
74
|
-
- The sweep with the model layer off answers from its regex layer alone, a narrower read rather than a refusal, so say which layer answered
|
|
72
|
+
The audit resolves its folders by surface root rather than by a path written into it, so a project laid out differently resolves nothing. It then refuses with `reason: "no-folders"`, naming the folders it looked for. Report that refusal as an unread axis.
|
|
75
73
|
|
|
76
74
|
## The design record
|
|
77
75
|
|
|
@@ -139,7 +137,7 @@ A reading is the weakest evidence in the report and the most consequential findi
|
|
|
139
137
|
The axes are not equally actionable, and a report flattening them implies they are. Each is worth reporting and each is worth a different response, so the class travels beside the state on every row rather than once in a preamble a reader skims.
|
|
140
138
|
|
|
141
139
|
- A length finding is a number against a checkpoint
|
|
142
|
-
- A placement finding is a
|
|
140
|
+
- A placement finding is a count or a list the audit returned
|
|
143
141
|
- A staleness finding is a judgment with nothing behind it
|
|
144
142
|
|
|
145
143
|
Shipping staleness on weaker evidence than the other two is the trade taken deliberately. Cutting it would leave the report answering the two questions that were never the operator's complaint.
|
package/docs/agents/audits.md
CHANGED
|
@@ -57,18 +57,15 @@ An audit that finds no corpus reports `absent`, which moves neither the verdict
|
|
|
57
57
|
|
|
58
58
|
**In `bun run check`.**
|
|
59
59
|
|
|
60
|
-
`bun run check` runs `--corpus tracked --corpus per-machine` as a reporting stage after the gating stages, and never fails on it. `summary` is a flat object of unique scalar keys that a shell stage greps without a JSON parser. `deps` runs weekly instead.
|
|
61
|
-
|
|
62
|
-
The placement entry runs pinned to `--backend off`, so its tally stays comparable across machines. Each audit runs as the CLI the caller is running, never a global `canon`.
|
|
60
|
+
`bun run check` runs `--corpus tracked --corpus per-machine` as a reporting stage after the gating stages, and never fails on it. `summary` is a flat object of unique scalar keys that a shell stage greps without a JSON parser. `deps` runs weekly instead. Each audit runs as the CLI the caller is running, never a global `canon`.
|
|
63
61
|
|
|
64
62
|
**Catalog.**
|
|
65
63
|
|
|
66
|
-
`canon audits list` reports the first
|
|
64
|
+
`canon audits list` reports the first 18 rows. The rows marked `outside` run by hand or from a skill and sit beside the aggregate.
|
|
67
65
|
|
|
68
66
|
| Id | Verb | Measures | Finding |
|
|
69
67
|
| -------------------- | ----------------------------------- | ---------------------------------------------------------------------------------- | -------------- |
|
|
70
68
|
| `context` | `canon context audit` | Context folder structure, citations, and the requirements record's word cap | Gates |
|
|
71
|
-
| `placement` | `canon context classify sweep` | Keep, rewrite, and move tally per context section, regex layer only | Reports |
|
|
72
69
|
| `markdown` | `canon markdown audit` | Bans, dead links, density, and reference shape | Gates |
|
|
73
70
|
| `skills` | `canon claude skills audit` | Both skill corpora against the skill standards | Gates |
|
|
74
71
|
| `skills-reach` | `canon claude skills reach` | Skill bodies citing a path no target receives | Reports |
|
|
@@ -90,7 +87,6 @@ The placement entry runs pinned to `--backend off`, so its tally stays comparabl
|
|
|
90
87
|
| `outside` | `canon gov superseded <old> <new>` | Where the tree still asserts a value a changed convention no longer produces | Reports |
|
|
91
88
|
| `outside` | `canon claude skills drift <ref>` | Shipped skill bodies rewritten since a ref | Reports |
|
|
92
89
|
| `outside` | `canon claude routing` | Per `CLAUDE.md` section, how many bullets name a path and whether a rule covers it | Reports |
|
|
93
|
-
| `outside` | `canon context classify diff` | Classification of the chunks a git range changed | Reports |
|
|
94
90
|
|
|
95
91
|
A deliberate secret takes a `canon-allow-secret: <reason>` marker. A deliberate citation takes `canon-allow-citation: <reason>` and a deliberate superseded value takes `canon-allow-superseded: <reason>`, each on its own line or the one above. Run any verb with `--help` for its flags and refusal reasons.
|
|
96
92
|
|
|
@@ -62,7 +62,7 @@ The exit code follows the mode the run took. The bullets cover where the gate ru
|
|
|
62
62
|
- A root resolving no audited folder refuses with `1` and warns, a root measuring no entry warns, and a seed short a section fails with `2`
|
|
63
63
|
- A seed omitting a required section on purpose sets `stub: true` in its frontmatter. Only the value `true` counts, and both install paths strip the field.
|
|
64
64
|
|
|
65
|
-
The citation check skips fenced blocks, fixture and harness trees including `*.test.ts`, and a path into a folder the project lacks.
|
|
65
|
+
The citation check skips fenced blocks, fixture and harness trees including `*.test.ts`, the install stamp at any of its spellings, and a path into a folder the project lacks.
|
|
66
66
|
|
|
67
67
|
Append `<!-- audit-ignore-citations: <path> -->` to a line that displays a path without pointing at it. The marker excuses only the paths it names, and a bare `<!-- audit-ignore-citations -->` excuses every citation on the line. In seeds, plugin skill bodies, and stack references, which install into a target, reword the line instead.
|
|
68
68
|
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: API design skill ledger
|
|
3
|
+
description: Sources for claude/skills/api-design/SKILL.md, one row per bullet in its concern groups
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# API design skill ledger
|
|
7
|
+
|
|
8
|
+
The field is interface design across functions, flags, file formats, and endpoints. Google's API Improvement Proposals and its engineering book carry compatibility, the IETF carries the error and deprecation formats, and Stripe's own docs carry idempotency. The closing sections and `## What this delegates` restate these rules or route, so they take no table.
|
|
9
|
+
|
|
10
|
+
## Decide what a caller can observe
|
|
11
|
+
|
|
12
|
+
| Bullet | Source | Read |
|
|
13
|
+
| -------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------- |
|
|
14
|
+
| A shape built for the caller | [agent-skills, API and interface design](https://github.com/addyosmani/agent-skills/blob/2686b620fc1fed2e8f60c704839c766b8594c6b6/skills/api-and-interface-design/SKILL.md): "Don't leak implementation details. If users can observe it, they will depend on it." | 2026-10-24 |
|
|
15
|
+
| Ordering, timing, and error text count | [Software Engineering at Google, ch. 1](https://abseil.io/resources/swe-book/html/ch01.html): "all observable behaviors of your system will be depended on by somebody", worked through hash iteration ordering | 2026-10-24 |
|
|
16
|
+
| As small as the first caller needs | [AIP-180](https://google.aip.dev/180): new components "may be added to existing APIs in the same major version", while "Removing a component is a backwards incompatible change" | 2026-10-24 |
|
|
17
|
+
| One name for one concept | [AIP-140](https://google.aip.dev/140): "APIs should endeavor to use the same name for the same concept and different names for different concepts" | 2026-10-24 |
|
|
18
|
+
|
|
19
|
+
## Write the contract first
|
|
20
|
+
|
|
21
|
+
| Bullet | Source | Read |
|
|
22
|
+
| ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------- |
|
|
23
|
+
| The signature before the body | [agent-skills, API and interface design](https://github.com/addyosmani/agent-skills/blob/2686b620fc1fed2e8f60c704839c766b8594c6b6/skills/api-and-interface-design/SKILL.md): "Define the interface before implementing it. The contract is the spec" | 2026-10-24 |
|
|
24
|
+
| What it does, returns, and refuses | [agent-skills, API and interface design](https://github.com/addyosmani/agent-skills/blob/2686b620fc1fed2e8f60c704839c766b8594c6b6/skills/api-and-interface-design/SKILL.md): its contract names the refusal beside the return, "Returns a single task or throws NotFoundError" | 2026-10-24 |
|
|
25
|
+
| Machine output on its own channel | [Command Line Interface Guidelines](https://clig.dev/): "Log messages, errors, and so on should all be sent to stderr", so piped commands never feed them "into the next command" | 2026-10-24 |
|
|
26
|
+
| The safe behavior is the default | [Command Line Interface Guidelines](https://clig.dev/): "Confirm before doing anything dangerous", prompting interactively "or requiring them to pass -f or --force otherwise" | 2026-10-24 |
|
|
27
|
+
|
|
28
|
+
## Keep one error shape per surface
|
|
29
|
+
|
|
30
|
+
| Bullet | Source | Read |
|
|
31
|
+
| -------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
|
|
32
|
+
| A stable code beside the message | [RFC 9457](https://www.rfc-editor.org/rfc/rfc9457.html): consumers "MUST use the "type" URI" as "the problem type's primary identifier", and "Consumers SHOULD NOT parse the "detail" member for information" | 2026-10-24 |
|
|
33
|
+
| No internals in the message | [RFC 9457](https://www.rfc-editor.org/rfc/rfc9457.html): generators "are encouraged to avoid making implementation details such as a stack dump available through the HTTP interface" | 2026-10-24 |
|
|
34
|
+
| Reuse the project's error type | [agent-skills, API and interface design](https://github.com/addyosmani/agent-skills/blob/2686b620fc1fed2e8f60c704839c766b8594c6b6/skills/api-and-interface-design/SKILL.md): "Pick one error strategy and use it everywhere" | 2026-10-24 |
|
|
35
|
+
|
|
36
|
+
## Validate at the boundary
|
|
37
|
+
|
|
38
|
+
| Bullet | Source | Read |
|
|
39
|
+
| ----------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
|
|
40
|
+
| Check once where input enters | [Parse, don't validate](https://lexi-lambda.github.io/blog/2019/11/05/parse-don-t-validate/): checks spread through processing deprive "the program of the ability to reject invalid input instead of processing it" | 2026-10-24 |
|
|
41
|
+
| Trust the value inside | [Parse, don't validate](https://lexi-lambda.github.io/blog/2019/11/05/parse-don-t-validate/): shotgun parsing mixes checks "with and spread across processing code", hoping "one or another would catch all the "bad" cases" | 2026-10-24 |
|
|
42
|
+
| Parse into a typed value | [Parse, don't validate](https://lexi-lambda.github.io/blog/2019/11/05/parse-don-t-validate/): "Get your data into the most precise representation you need as quickly as you can. Ideally, this should happen at the boundary of your system" | 2026-10-24 |
|
|
43
|
+
| A value read back is input | [OWASP Input Validation Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Input_Validation_Cheat_Sheet.html): "Validate data from internal APIs, partner feeds, queues, and stored records when it crosses a trust boundary" | 2026-10-24 |
|
|
44
|
+
|
|
45
|
+
## Change additively
|
|
46
|
+
|
|
47
|
+
| Bullet | Source | Read |
|
|
48
|
+
| ----------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
|
|
49
|
+
| Optional, with the old behavior default | [AIP-180](https://google.aip.dev/180): code written against the previous surface "must continue to be treated the same way as before. New required fields must not be added" | 2026-10-24 |
|
|
50
|
+
| No rename or removal in place | [AIP-180](https://google.aip.dev/180): "Renaming a component is semantically equivalent to "remove and add"", and a service "may add the new component, but must not remove the existing one" | 2026-10-24 |
|
|
51
|
+
| No new meaning or type under a name | [AIP-180](https://google.aip.dev/180): fields "must not have their type changed", and APIs "must not change visible behavior or semantics in ways that are likely to break reasonable user code" | 2026-10-24 |
|
|
52
|
+
| One live version for an unpinned caller | [Software Engineering at Google, ch. 16](https://abseil.io/resources/swe-book/html/ch16.html): "Developers must never have a choice of "What version of this component should I depend upon?"", named the One-Version Rule | 2026-10-24 |
|
|
53
|
+
| Deprecation recorded where a caller looks | [RFC 9745](https://www.rfc-editor.org/rfc/rfc9745.html): a response signals "that the resource will be or has been deprecated" and links "to a resource that provides further information about planned or existing deprecation" | 2026-10-24 |
|
|
54
|
+
|
|
55
|
+
## Make a retried write safe
|
|
56
|
+
|
|
57
|
+
| Bullet | Source | Read |
|
|
58
|
+
| -------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
|
|
59
|
+
| Answer a repeat with the stored result | [Stripe idempotent requests](https://docs.stripe.com/api/idempotent_requests): "Stripe saves the status code and body of the first request made with a given idempotency key", and "Retries with the same key return the saved response" | 2026-10-24 |
|
|
60
|
+
| Claim the key atomically | [Implementing Stripe-like idempotency keys in Postgres](https://brandur.org/idempotency-keys): a unique index on the key, locked "so that no other requests that might be operating concurrently also try the operation" | 2026-10-24 |
|
|
61
|
+
| A reused key with another body fails | [Stripe idempotent requests](https://docs.stripe.com/api/idempotent_requests): the layer "compares incoming parameters to those of the original request and errors if they're not the same to prevent accidental misuse" | 2026-10-24 |
|
|
62
|
+
| Keep the key past the retry window | [Stripe idempotent requests](https://docs.stripe.com/api/idempotent_requests): keys go once "at least 24 hours old", and "We generate a new request if a key is reused after the original is pruned" | 2026-10-24 |
|