@erclx/aitk 0.83.0 → 0.85.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/.claude-plugin/plugin.json +1 -1
- package/claude/skills/git-pr/references/labels.md +7 -1
- package/docs/agents/markdown-audit.md +3 -1
- package/governance/rules/claude/520-wireframes.md +9 -1
- package/governance/rules/claude/530-requirements.md +8 -0
- package/governance/rules/claude/540-architecture.md +10 -0
- package/governance/rules/claude/550-design.md +8 -0
- package/governance/rules/claude/555-tasks.md +8 -0
- package/governance/rules/claude/580-readme.md +8 -0
- package/governance/rules/claude/590-rule-authoring.md +11 -0
- package/governance/rules/claude/591-standard-authoring.md +8 -0
- package/governance/rules/core/070-planning.md +1 -0
- package/governance/rules/core/075-dependencies.md +25 -0
- package/governance/rules/lib/300-testing-ts.md +1 -1
- package/governance/rules/lib/360-security-server.md +39 -0
- package/governance/rules/lib/370-database.md +35 -0
- package/governance/stacks/python.toml +1 -1
- package/package.json +1 -1
- package/tooling/claude/seeds/.claude/hooks/standards-audit.sh +19 -2
|
@@ -40,7 +40,13 @@ The map is authored by hand and nothing detects a directory it fails to cover, s
|
|
|
40
40
|
|
|
41
41
|
Apply labels after the pull request resolves, never as a flag on the create. `gh pr create --label` fails whole on a label the remote does not carry, so a name the map got wrong opens no pull request at all and the run stops with the branch pushed and nothing to review. A `gh pr edit --add-label` against a pull request that already exists costs a warning instead, and it is one command across both the create and the edit path rather than two flags that have to stay in step.
|
|
42
42
|
|
|
43
|
-
|
|
43
|
+
Labelling runs whenever this skill runs and at no other time. Nothing else computes the set, so a push made any other way leaves the labels exactly as the last run left them. Any caller invoking this skill again reaches the step again, and it recomputes over the whole branch diff rather than over the new commits.
|
|
44
|
+
|
|
45
|
+
An ordinary branch therefore labels once, when the pull request opens. The return leg that answers a review hands its push to `git-followup`, which refreshes the body without invoking this skill, so the commits that answer a review reach no labelling step.
|
|
46
|
+
|
|
47
|
+
A follow-up push reaching a surface the earlier ones did not merges under-labelled, with nothing to report the miss. Keeping the step in one skill is worth that cost, since a review fix lands in the files the review named and rarely opens a surface the branch had not already touched.
|
|
48
|
+
|
|
49
|
+
`--add-label` adds and never removes. A label a person applied by hand is not this skill's to strip, and a re-run over a branch that has since dropped a surface keeps the label that surface earned.
|
|
44
50
|
|
|
45
51
|
## A label the remote does not carry
|
|
46
52
|
|
|
@@ -116,7 +116,9 @@ Four surfaces read the ban sets and two of them go through this verb. `.claude/h
|
|
|
116
116
|
|
|
117
117
|
The other two read the standards directly and neither is a consolidation left half done. `claude/skills/claude-standards-audit/SKILL.md` greps the banned tokens agent-side, which is a session reading prose rather than a process it can shell out to, and it ships to every target. The seed copy of the hook keeps its awk, because a scaffolded project may carry no `aitk` and `scripts/core/check-seed-independence.sh` exists to catch seed content depending on the toolkit CLI. Both are the likelier place for the next drift, since nothing compares either against the verb.
|
|
118
118
|
|
|
119
|
-
The hook prefers a checkout's own `src/cli.ts` over a globally installed binary, so it and the push stage read one build. A published binary lags a branch by whatever has not been released, which would put a ban kind added on the branch into the push and not into the edit. It reads its findings out of the `--json` record rather than off the exit code, so an older binary still reports where the fallback applies.
|
|
119
|
+
The hook prefers a checkout's own `src/cli.ts` over a globally installed binary, so it and the push stage read one build. A published binary lags a branch by whatever has not been released, which would put a ban kind added on the branch into the push and not into the edit. It reads its findings out of the `--json` record rather than off the exit code, so an older binary still reports where the fallback applies. It reads `bans.missingStandards` out of the same record, so a standard the verb found under neither root reaches the author as a check narrowed to what it could read.
|
|
120
|
+
|
|
121
|
+
A machine with neither runner still blocks no edit, and it says so rather than exiting clean. The push stage holds either way. An edit nobody checked and an edit carrying no violation are one silence to a reader, so the enforcement a machine lacks is reported rather than inferred.
|
|
120
122
|
|
|
121
123
|
The stage measures the whole corpus rather than the changed files. A `Do not use` bullet added to a standard bans a token retroactively, and no file in the push that adds the bullet was edited.
|
|
122
124
|
|
|
@@ -6,7 +6,15 @@ paths:
|
|
|
6
6
|
|
|
7
7
|
# Wireframe standards
|
|
8
8
|
|
|
9
|
+
## Layout and intent
|
|
10
|
+
|
|
11
|
+
- Draw each surface as an ASCII block inside a `plaintext` fence, one fence per distinct layout.
|
|
12
|
+
- Label a region with its role. Never label one with a class name, a token name, or a computed value.
|
|
13
|
+
- Carry on-screen copy verbatim, and mark copy the surface templates.
|
|
14
|
+
- State interaction intent, never the mechanism behind it. Send algorithms, handlers, and thresholds to a `.claude/context/` entry.
|
|
15
|
+
- Update a surface's wireframe in the same pull request that changes its layout or its interaction.
|
|
16
|
+
|
|
9
17
|
## Authority
|
|
10
18
|
|
|
11
19
|
- Follow `.claude/standards/wireframes.md` for layout and interaction intent: ASCII layout, region labels, variants, copy, and what moves to `.claude/context/`. It is the single source.
|
|
12
|
-
-
|
|
20
|
+
- Read it before adding or revising a surface.
|
|
@@ -6,6 +6,14 @@ paths:
|
|
|
6
6
|
|
|
7
7
|
# Requirements standards
|
|
8
8
|
|
|
9
|
+
## Scope and non-goals
|
|
10
|
+
|
|
11
|
+
- State a goal as a user-facing outcome, never as the implementation delivering it.
|
|
12
|
+
- Record explicit non-goals. Mark a deferred item `(deferred)`.
|
|
13
|
+
- Leave the MVP list as written once its features ship. Do not renumber it, extend it, or annotate an entry with status.
|
|
14
|
+
- Add later scope as a new section rather than as an extension of the MVP list.
|
|
15
|
+
- Drop a section rather than pad it. Include `## Distribution` only when the project ships outside its own repository.
|
|
16
|
+
|
|
9
17
|
## Authority
|
|
10
18
|
|
|
11
19
|
- Follow `.claude/standards/requirements.md` for what belongs in the problem, goals, non-goals, MVP features, tech stack, and constraints. It is the single source.
|
|
@@ -6,6 +6,16 @@ paths:
|
|
|
6
6
|
|
|
7
7
|
# Architecture standards
|
|
8
8
|
|
|
9
|
+
## Decisions
|
|
10
|
+
|
|
11
|
+
- Give each decision its own H3 under `## Key technical decisions`, naming what it chose and the alternative it passed over.
|
|
12
|
+
- Keep line-by-line function behavior and full type definitions out.
|
|
13
|
+
|
|
14
|
+
## Verification anchors
|
|
15
|
+
|
|
16
|
+
- Close a decision citing a measured number with `Measured at <short-sha> on <YYYY-MM-DD>.` Leave a decision citing none unanchored.
|
|
17
|
+
- Refresh that anchor whenever the number is re-read, whether or not it moved.
|
|
18
|
+
|
|
9
19
|
## Authority
|
|
10
20
|
|
|
11
21
|
- Follow `.claude/standards/architecture.md` for the overview, named decision entries, and risks. It is the single source.
|
|
@@ -6,6 +6,14 @@ paths:
|
|
|
6
6
|
|
|
7
7
|
# Design standards
|
|
8
8
|
|
|
9
|
+
## Tokens
|
|
10
|
+
|
|
11
|
+
- Describe a token as intent rather than as a computed value.
|
|
12
|
+
- Keep CSS classes, component filenames, and prop names out.
|
|
13
|
+
- Carry a token system as a table, one row per token, and a component rule as a short bullet.
|
|
14
|
+
- Keep the token table headers verbatim.
|
|
15
|
+
- Record a non-obvious omission, such as no motion or no custom icons.
|
|
16
|
+
|
|
9
17
|
## Authority
|
|
10
18
|
|
|
11
19
|
- Follow `.claude/standards/design.md` for visual intent, the token tables, and the render contract. It is the single source.
|
|
@@ -6,6 +6,14 @@ paths:
|
|
|
6
6
|
|
|
7
7
|
# Tasks standards
|
|
8
8
|
|
|
9
|
+
## What a task carries
|
|
10
|
+
|
|
11
|
+
- Name where the task came from, through a `Plan:`, `Groundwork:`, `Intake:`, or `Issue:` line under the title.
|
|
12
|
+
- Size the outcomes so one pull request closes all of them. Split the task before handing it off.
|
|
13
|
+
- Use `## Outcomes` and `## Findings` and add no third heading. Note status inline on an outcome.
|
|
14
|
+
- Keep class names, file paths, function names, and prop names out of every entry and title.
|
|
15
|
+
- Never delete a task file. A shipped task moves to the archive under its own name.
|
|
16
|
+
|
|
9
17
|
## Authority
|
|
10
18
|
|
|
11
19
|
- Follow `.claude/standards/tasks.md` for filenames, frontmatter, what belongs, and the task file format. It is the single source.
|
|
@@ -6,6 +6,14 @@ paths:
|
|
|
6
6
|
|
|
7
7
|
# README standards
|
|
8
8
|
|
|
9
|
+
## Audience and voice
|
|
10
|
+
|
|
11
|
+
- Write a repository-root README for someone deciding whether to commit to the project. A nested README keeps the reference voice.
|
|
12
|
+
- Address the reader in second person.
|
|
13
|
+
- Ground a claim in a command, a number, or a named constraint rather than an adjective.
|
|
14
|
+
- Name what the project does not do.
|
|
15
|
+
- Link out to full API documentation, license text, contribution guidelines, and troubleshooting rather than carrying them.
|
|
16
|
+
|
|
9
17
|
## Authority
|
|
10
18
|
|
|
11
19
|
- Follow `.claude/standards/readme.md` for voice, structure, required and optional sections, heading hierarchy, badge classes, per-project-type content, and what to link out rather than inline. It is the single source.
|
|
@@ -6,6 +6,17 @@ paths:
|
|
|
6
6
|
|
|
7
7
|
# Rule authoring standards
|
|
8
8
|
|
|
9
|
+
## Numbering
|
|
10
|
+
|
|
11
|
+
- Name a rule `.claude/rules/<subdirectory>/<n>-<slug>.md`, taking a number that collides with neither the project's rules nor any installed shared set.
|
|
12
|
+
- Give every rule a numeric prefix and keep the slug to one to three kebab words.
|
|
13
|
+
|
|
14
|
+
## Body
|
|
15
|
+
|
|
16
|
+
- State one directive per bullet in imperative voice. Do not explain the reasoning behind a rule.
|
|
17
|
+
- Cut a rule that resists crisp one-line phrasing.
|
|
18
|
+
- Do not restate a rule a sibling rule or `CLAUDE.md` already owns. Point once.
|
|
19
|
+
|
|
9
20
|
## Authority
|
|
10
21
|
|
|
11
22
|
- Follow `.claude/standards/rule.md` for rule frontmatter, body shape, and voice. It is the single source.
|
|
@@ -7,6 +7,14 @@ paths:
|
|
|
7
7
|
|
|
8
8
|
# Standard authoring standards
|
|
9
9
|
|
|
10
|
+
## The scope statement
|
|
11
|
+
|
|
12
|
+
- Govern one document type per standard, or one attribute across every document.
|
|
13
|
+
- Open with a `## Scope` section naming what the standard governs and a `Does not govern:` list, placed above the shape rules.
|
|
14
|
+
- Put the governed path in backticks in the first sentence, anchored deep enough to resolve from a project root. Keep an attribute standard's first sentence free of backticks and say in it that it governs an attribute.
|
|
15
|
+
- Give each `Does not govern:` entry an excluded concern and the owner it goes to. Cut an entry naming no owner.
|
|
16
|
+
- Declare a yield, an exemption, or a handoff from both sides of the boundary.
|
|
17
|
+
|
|
10
18
|
## Authority
|
|
11
19
|
|
|
12
20
|
- Follow `.claude/standards/standard.md` for a standard's frontmatter, shape, scope, and success criterion. It is the single source.
|
|
@@ -12,4 +12,5 @@ description: Enforce planning standards before implementation
|
|
|
12
12
|
- State where the search ran and why each candidate was rejected. Do not assert a search without naming its results.
|
|
13
13
|
- Propose the simplest solution that satisfies the requirement before implementing complex patterns.
|
|
14
14
|
- Write or update tests as part of every implementation plan.
|
|
15
|
+
- Write the test for a behavior before the code that implements it. Confirm visual output after implementing it, not before.
|
|
15
16
|
- Do not modify code without a confirmed plan.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Require a dependency to be declared in the manifest before it is imported
|
|
3
|
+
paths:
|
|
4
|
+
- '**/*.ts'
|
|
5
|
+
- '**/*.tsx'
|
|
6
|
+
- '**/*.js'
|
|
7
|
+
- '**/*.jsx'
|
|
8
|
+
- '**/*.py'
|
|
9
|
+
- '**/package.json'
|
|
10
|
+
- '**/pyproject.toml'
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# Dependency standards
|
|
14
|
+
|
|
15
|
+
## Declaration
|
|
16
|
+
|
|
17
|
+
- Declare a package in the project manifest before importing it anywhere in the source.
|
|
18
|
+
- Add a package with the package manager command that writes the manifest and the lockfile together, such as `bun add` or `uv add`. Never hand-edit the manifest and never install without recording the result.
|
|
19
|
+
- Commit the lockfile with the manifest change in the same commit.
|
|
20
|
+
- Declare a package used only by tests, builds, or tooling as a development dependency.
|
|
21
|
+
- Never import a package that arrives only as a transitive dependency of another package.
|
|
22
|
+
|
|
23
|
+
## Removal
|
|
24
|
+
|
|
25
|
+
- Remove a package from the manifest in the change that removes its last import.
|
|
@@ -32,7 +32,7 @@ paths:
|
|
|
32
32
|
## Conventions
|
|
33
33
|
|
|
34
34
|
- Use `.test.ts` / `.test.tsx` for unit tests.
|
|
35
|
-
- Use `.spec.ts` / `.spec.tsx` for integration tests
|
|
35
|
+
- Use `.spec.ts` / `.spec.tsx` for integration tests and for Playwright tests under `e2e/`.
|
|
36
36
|
- Do not make real network calls in unit tests.
|
|
37
37
|
- `describe()` labels use the exact identifier of the subject under test in its natural casing.
|
|
38
38
|
- `it()` descriptions use "should" + sentence case.
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Enforce server-side authorization, secret handling, and abuse limits on request handlers
|
|
3
|
+
paths:
|
|
4
|
+
- '**/*.py'
|
|
5
|
+
- '**/*.ts'
|
|
6
|
+
- '**/*.js'
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Server security standards
|
|
10
|
+
|
|
11
|
+
## Authorization
|
|
12
|
+
|
|
13
|
+
- Authorize every request on the server, whatever the client already checked.
|
|
14
|
+
- Derive the caller identity from the verified session or token. Never read it from a request body, query string, or header the client sets.
|
|
15
|
+
- Check that the caller owns or may reach the specific record a request names, not only that the caller is signed in.
|
|
16
|
+
- Deny by default. Grant a route access through an explicit allow.
|
|
17
|
+
|
|
18
|
+
## Credentials
|
|
19
|
+
|
|
20
|
+
- Hash passwords with a memory-hard algorithm and a per-record salt. Never store a reversible password.
|
|
21
|
+
- Compare tokens, signatures, and password hashes with a constant-time function.
|
|
22
|
+
- Expire and revoke sessions and refresh tokens on the server. Do not rely on client-side deletion.
|
|
23
|
+
|
|
24
|
+
## Secrets
|
|
25
|
+
|
|
26
|
+
- Read every secret from the environment or a secret manager at runtime.
|
|
27
|
+
- Never commit a secret, connection string, or private key to the repository.
|
|
28
|
+
- Never return a secret, connection string, or internal hostname in a response body.
|
|
29
|
+
|
|
30
|
+
## Abuse limits
|
|
31
|
+
|
|
32
|
+
- Rate-limit authentication, password reset, and any endpoint that sends mail or costs money per call.
|
|
33
|
+
- Set an explicit maximum body size and request timeout on every endpoint.
|
|
34
|
+
- Bound pagination parameters with a server-side maximum.
|
|
35
|
+
|
|
36
|
+
## Transport
|
|
37
|
+
|
|
38
|
+
- Serve every route over TLS and reject plaintext requests.
|
|
39
|
+
- Restrict CORS to an explicit origin list. Never reflect the request origin or pair a wildcard with credentials.
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Enforce persistence boundaries for migrations, query construction, transactions, and rollback
|
|
3
|
+
paths:
|
|
4
|
+
- '**/*.py'
|
|
5
|
+
- '**/*.ts'
|
|
6
|
+
- '**/*.js'
|
|
7
|
+
- '**/*.sql'
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Persistence standards
|
|
11
|
+
|
|
12
|
+
## Schema changes
|
|
13
|
+
|
|
14
|
+
- Express every schema change as a migration file committed to version control.
|
|
15
|
+
- Ship a tested rollback path with every migration that changes a schema.
|
|
16
|
+
- Never alter a deployed schema outside a migration.
|
|
17
|
+
- Never edit a migration that has run in a shared environment. Add a new one.
|
|
18
|
+
- Separate a destructive migration from the deploy that stops reading the dropped column.
|
|
19
|
+
|
|
20
|
+
## Query construction
|
|
21
|
+
|
|
22
|
+
- Pass every runtime value as a bound parameter.
|
|
23
|
+
- Never interpolate, concatenate, or format a value into a statement string.
|
|
24
|
+
- Name the columns a read needs. Do not select every column by wildcard.
|
|
25
|
+
|
|
26
|
+
## Transactions
|
|
27
|
+
|
|
28
|
+
- Give each transaction one owner that opens it, commits it, and rolls it back.
|
|
29
|
+
- Never open a transaction inside a function that was handed one.
|
|
30
|
+
- Keep network calls, queue publishes, and filesystem writes outside an open transaction.
|
|
31
|
+
|
|
32
|
+
## Access patterns
|
|
33
|
+
|
|
34
|
+
- Load related rows in the query that fetches their parents. Do not resolve a relation lazily inside an iteration.
|
|
35
|
+
- Scope a connection or session to the request that opened it and release it on exit.
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
extends = "base"
|
|
2
|
-
rules = ["110-python", "340-pydantic", "330-testing-py"]
|
|
2
|
+
rules = ["110-python", "340-pydantic", "330-testing-py", "360-security-server", "370-database"]
|
package/package.json
CHANGED
|
@@ -33,6 +33,7 @@ esac
|
|
|
33
33
|
# bullet added to markdown.md is parsed by nothing and enforces silently.
|
|
34
34
|
standard="${CLAUDE_PROJECT_DIR:-.}/.claude/standards/prose.md"
|
|
35
35
|
words=""
|
|
36
|
+
unread=""
|
|
36
37
|
if [ -f "$standard" ]; then
|
|
37
38
|
words=$(grep '^- Do not use ' "$standard" |
|
|
38
39
|
grep -o '`[^`]*`' |
|
|
@@ -40,6 +41,12 @@ if [ -f "$standard" ]; then
|
|
|
40
41
|
grep -x '[a-z][a-z]*' |
|
|
41
42
|
sort -u |
|
|
42
43
|
paste -sd '|' -)
|
|
44
|
+
else
|
|
45
|
+
# An absent standard empties the word list, and the awk below reads an empty
|
|
46
|
+
# list as nothing to look for rather than as nothing found. The path is kept
|
|
47
|
+
# so the report names what could not be read, since a file carrying no banned
|
|
48
|
+
# word and a file nobody checked produce the same silence otherwise.
|
|
49
|
+
unread="$standard"
|
|
43
50
|
fi
|
|
44
51
|
|
|
45
52
|
hits=$(awk -v words="$words" '
|
|
@@ -66,8 +73,18 @@ hits=$(awk -v words="$words" '
|
|
|
66
73
|
}
|
|
67
74
|
' "$file")
|
|
68
75
|
|
|
69
|
-
[ -z "$hits" ] && exit 0
|
|
76
|
+
[ -z "$hits" ] && [ -z "$unread" ] && exit 0
|
|
70
77
|
|
|
71
|
-
|
|
78
|
+
nl=$'\n'
|
|
79
|
+
msg=""
|
|
80
|
+
|
|
81
|
+
if [ -n "$unread" ]; then
|
|
82
|
+
msg=$(printf 'Standards-audit: no word ban checked in %s. Found no standard at %s, so only the character bans ran. Restore it with `aitk standards install`.' "$file" "$unread")
|
|
83
|
+
fi
|
|
84
|
+
|
|
85
|
+
if [ -n "$hits" ]; then
|
|
86
|
+
found=$(printf 'Standards-audit: prose.md and markdown.md violations in %s. Rewrite or restructure (do not lazy-swap).\n%s' "$file" "$hits")
|
|
87
|
+
msg="${msg:+$msg$nl}$found"
|
|
88
|
+
fi
|
|
72
89
|
|
|
73
90
|
jq -nc --arg msg "$msg" '{hookSpecificOutput:{hookEventName:"PostToolUse",additionalContext:$msg}}'
|