@erclx/canon 5.13.0 → 5.14.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.
Files changed (41) hide show
  1. package/claude/.claude-plugin/plugin.json +1 -1
  2. package/claude/skills/api-design/SKILL.md +3 -2
  3. package/claude/skills/deprecation-migration/REQUIREMENT.md +62 -0
  4. package/claude/skills/deprecation-migration/SKILL.md +115 -0
  5. package/claude/skills/deprecation-migration/references/adopted.md +50 -0
  6. package/claude/skills/git-followup/REQUIREMENT.md +1 -0
  7. package/claude/skills/git-followup/SKILL.md +3 -0
  8. package/claude/skills/git-pr/REQUIREMENT.md +1 -0
  9. package/claude/skills/git-pr/SKILL.md +1 -1
  10. package/claude/skills/git-pr/references/evidence.md +2 -2
  11. package/claude/skills/git-ship/REQUIREMENT.md +3 -0
  12. package/claude/skills/git-ship/SKILL.md +12 -1
  13. package/claude/skills/review-ui/REQUIREMENT.md +5 -2
  14. package/claude/skills/review-ui/SKILL.md +12 -4
  15. package/claude/skills/review-ui/references/driving.md +5 -3
  16. package/claude/skills/review-ui/references/post.md +3 -2
  17. package/docs/agents/commands.md +1 -1
  18. package/docs/agents/index.md +1 -0
  19. package/docs/agents/markdown-audit.md +1 -1
  20. package/docs/agents/pr-evidence.md +5 -0
  21. package/docs/agents/pr-frames.md +112 -0
  22. package/docs/workflow/skill-map.md +15 -14
  23. package/package.json +1 -1
  24. package/src/claude/cases/misc.ts +5 -0
  25. package/src/claude/skills-audit.ts +1 -0
  26. package/src/commands/pr.ts +452 -0
  27. package/src/context/architecture.ts +5 -2
  28. package/src/gate/boundaries.ts +509 -0
  29. package/src/gate/measures.ts +8 -19
  30. package/src/gate/stages.ts +12 -28
  31. package/src/pr/frames.ts +323 -0
  32. package/src/tooling/manifest.ts +2 -3
  33. package/src/tooling/seeds.ts +37 -0
  34. package/tooling/claude/manifest.toml +3 -3
  35. package/scripts/core/check-capability-seeding.sh +0 -134
  36. package/scripts/core/check-ignore-parity.sh +0 -141
  37. package/scripts/core/check-plugin-boundary.sh +0 -45
  38. package/scripts/core/check-seed-independence.sh +0 -62
  39. package/scripts/core/check-skill-paths.sh +0 -24
  40. package/scripts/core/list-seed-roots.sh +0 -18
  41. package/scripts/lib/tooling.sh +0 -37
@@ -1,45 +0,0 @@
1
- #!/usr/bin/env bash
2
- set -e
3
- set -o pipefail
4
-
5
- SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
6
- PROJECT_ROOT="${PROJECT_ROOT:-$(cd "$SCRIPT_DIR/../.." && pwd)}"
7
-
8
- INTERNAL_ROOT="$PROJECT_ROOT/internal"
9
- PLUGIN_ROOT="$PROJECT_ROOT/claude"
10
-
11
- # `find` writes to stderr and returns non-zero for a missing root, inside a
12
- # process substitution whose status nothing reads. Without this the walk covers
13
- # nothing and the check reports the boundary clean having never measured it.
14
- if [ ! -d "$PLUGIN_ROOT" ]; then
15
- echo "No plugin root at ${PLUGIN_ROOT#"$PROJECT_ROOT/"}, boundary unverifiable." >&2
16
- exit 1
17
- fi
18
-
19
- # `realpath` resolves each walked path below. Absent, `set -e` aborts on the
20
- # substitution and the stage reports a leak for a tool that is not installed,
21
- # which is the same unmeasured-tree-with-a-verdict shape the guard above closes.
22
- if ! command -v realpath >/dev/null 2>&1; then
23
- echo "realpath is not installed, boundary unverifiable." >&2
24
- exit 1
25
- fi
26
-
27
- # The plugin reaches `standards/` through a symlink, which an
28
- # installer dereferences with no code in the path to filter. Walking the plugin
29
- # tree with symlinks followed is what an install actually copies, so resolving
30
- # each file and rejecting anything under `internal/` asserts the boundary at the
31
- # only place it can be measured.
32
- leaked=""
33
- while IFS= read -r file; do
34
- resolved=$(realpath "$file")
35
- case "$resolved" in
36
- "$INTERNAL_ROOT"/*) leaked="$leaked ${file#"$PROJECT_ROOT/"} -> ${resolved#"$PROJECT_ROOT/"}"$'\n' ;;
37
- esac
38
- done < <(find -L "$PLUGIN_ROOT" -type f)
39
-
40
- if [ -n "$leaked" ]; then
41
- echo "Plugin ships toolkit-internal content:" >&2
42
- printf '%s' "$leaked" >&2
43
- echo "Author internal content under internal/, which nothing under claude/ reaches." >&2
44
- exit 1
45
- fi
@@ -1,62 +0,0 @@
1
- #!/usr/bin/env bash
2
- set -e
3
- set -o pipefail
4
-
5
- SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
6
- PROJECT_ROOT="${PROJECT_ROOT:-$(cd "$SCRIPT_DIR/../.." && pwd)}"
7
-
8
- source "$PROJECT_ROOT/scripts/lib/tooling.sh"
9
-
10
- TOOLKIT_TOKEN="canon"
11
- TOOLING_ROOT="$PROJECT_ROOT/tooling"
12
-
13
- # `find` writes to stderr and returns non-zero for a missing root, inside a
14
- # process substitution whose status nothing reads. Without this the walk covers
15
- # nothing and the check reports the seeds independent having never read one.
16
- if [ ! -d "$TOOLING_ROOT" ]; then
17
- echo "No tooling root at ${TOOLING_ROOT#"$PROJECT_ROOT/"}, seed independence unverifiable." >&2
18
- exit 1
19
- fi
20
-
21
- # An empty discovery is a real state rather than a broken walk, and the Seed
22
- # standards stage already reports it as a skip. Failing here would have the two
23
- # stages disagree about what the same condition means.
24
- seed_roots=$(collect_seed_roots)
25
- if [ -z "$seed_roots" ]; then
26
- echo "No seed root carries .claude/ or canon/, nothing to check." >&2
27
- exit 0
28
- fi
29
-
30
- # Markdown alone. The seed tree also ships hooks that call the toolkit CLI on
31
- # purpose, each reporting a named stale-index warning when the binary is absent,
32
- # and scoping by extension leaves them outside this walk without an exemption
33
- # list that would have to be maintained against them.
34
- cited=""
35
- measured=0
36
- while IFS= read -r seed_root; do
37
- while IFS= read -r file; do
38
- measured=$((measured + 1))
39
- # A token followed by `/` is the tracked surface root, a folder the seed
40
- # itself installs, rather than the binary. Every other spelling still
41
- # reports, which keeps a verb, a plugin skill prefix, and a bare mention in.
42
- while IFS= read -r hit; do
43
- cited="$cited ${file#"$PROJECT_ROOT/"}:$hit"$'\n'
44
- done < <(grep -nE "${TOOLKIT_TOKEN}([^/]|$)" "$file" || true)
45
- done < <(find "$PROJECT_ROOT/$seed_root" -type f -name '*.md')
46
- done <<<"$seed_roots"
47
-
48
- # Roots resolved and no markdown under any of them is a walk that covered
49
- # nothing, which is the verdict-without-a-measurement the guards above refuse for
50
- # a missing tree. Reporting a pass here would say the seeds cite no CLI on the
51
- # strength of having read no prose.
52
- if [ "$measured" -eq 0 ]; then
53
- echo "Seed roots resolved but carry no markdown, seed independence unverifiable." >&2
54
- exit 1
55
- fi
56
-
57
- if [ -n "$cited" ]; then
58
- echo "Seed prose cites the toolkit CLI:" >&2
59
- printf '%s' "$cited" >&2
60
- echo "A scaffolded project may not have $TOOLKIT_TOKEN installed. State the capability the line needs rather than the binary that supplies it." >&2
61
- exit 1
62
- fi
@@ -1,24 +0,0 @@
1
- #!/usr/bin/env bash
2
- set -e
3
- set -o pipefail
4
-
5
- SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
6
- PROJECT_ROOT="${PROJECT_ROOT:-$(cd "$SCRIPT_DIR/../.." && pwd)}"
7
-
8
- SKILLS_DIR="$PROJECT_ROOT/claude/skills"
9
-
10
- # A shipped skill runs from a target project, where the toolkit's own wiki/ does
11
- # not exist. Anchoring on a non-path character keeps a target's .claude/wiki/ legal.
12
- BANNED_PATH_PATTERN='(^|[^[:alnum:]._/-])wiki/'
13
-
14
- [ -d "$SKILLS_DIR" ] || exit 0
15
-
16
- matches=$(grep -rnE "$BANNED_PATH_PATTERN" "$SKILLS_DIR" || true)
17
-
18
- [ -z "$matches" ] && exit 0
19
-
20
- echo "Shipped skills reference a repo-local path that does not exist in a target project:"
21
- echo "$matches" | sed "s|^$PROJECT_ROOT/||"
22
- echo
23
- echo "Reach supporting prose through a canon docs command, a standard cited at the flat root, or inlined text."
24
- exit 1
@@ -1,18 +0,0 @@
1
- #!/usr/bin/env bash
2
- # Prints every seed root carrying a `.claude/` or a `canon/`, one per line and
3
- # relative to the project root.
4
- #
5
- # The discovery rule has one definition, `collect_seed_roots` in
6
- # `scripts/lib/tooling.sh`, which `check-seed-independence.sh` already reads.
7
- # This file is the route a caller outside bash takes to that same answer, so a
8
- # stack seeding either root later reaches both readers and the two stages
9
- # measuring seed content cannot disagree about which roots exist.
10
- set -e
11
- set -o pipefail
12
-
13
- SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
14
- PROJECT_ROOT="${PROJECT_ROOT:-$(cd "$SCRIPT_DIR/../.." && pwd)}"
15
-
16
- source "$PROJECT_ROOT/scripts/lib/tooling.sh"
17
-
18
- collect_seed_roots
@@ -1,37 +0,0 @@
1
- #!/usr/bin/env bash
2
-
3
- TOOLING_STACK_EXCLUDE=("claude")
4
-
5
- is_tooling_stack_excluded() {
6
- local name="$1"
7
- local excluded
8
- for excluded in "${TOOLING_STACK_EXCLUDE[@]}"; do
9
- if [ "$name" = "$excluded" ]; then
10
- return 0
11
- fi
12
- done
13
- return 1
14
- }
15
-
16
- list_tooling_stacks() {
17
- local tooling_dir="${1:-$PROJECT_ROOT/tooling}"
18
- local name
19
- while IFS= read -r entry; do
20
- name=$(basename "$entry")
21
- is_tooling_stack_excluded "$name" && continue
22
- echo "$name"
23
- done < <(find "$tooling_dir" -mindepth 1 -maxdepth 1 -type d | sort)
24
- }
25
-
26
- # Seed roots that carry a `.claude/` or a `canon/`, emitted relative to
27
- # `PROJECT_ROOT`. Every stage measuring seed content discovers through this
28
- # rather than naming a stack, so a stack seeding either root later arrives
29
- # covered with no edit to any caller. A stack seeding only tracked surfaces
30
- # carries `canon/` alone, which a `.claude/` test would drop from both stages.
31
- collect_seed_roots() {
32
- local dir
33
- for dir in "$PROJECT_ROOT"/tooling/*/seeds; do
34
- [ -d "$dir/.claude" ] || [ -d "$dir/canon" ] || continue
35
- printf '%s\n' "${dir#"$PROJECT_ROOT"/}"
36
- done
37
- }