@erclx/canon 5.31.0 → 5.33.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/README.md +1 -1
- package/claude/.claude-plugin/plugin.json +1 -1
- package/claude/skills/api-design/references/adopted.md +1 -1
- package/claude/skills/auto-ship/REQUIREMENT.md +4 -16
- package/claude/skills/auto-ship/SKILL.md +13 -58
- package/claude/skills/auto-ship/references/draft-mark.md +2 -2
- package/claude/skills/auto-ship/references/failure-recovery.md +1 -5
- package/claude/skills/auto-ship/references/tier-failures.md +1 -1
- package/claude/skills/auto-ship/references/ui-checklist.md +2 -2
- package/claude/skills/auto-ship/references/verb-absent.md +3 -27
- package/claude/skills/auto-ship/references/worktree-name.md +1 -1
- package/claude/skills/backlog-triage/REQUIREMENT.md +2 -2
- package/claude/skills/backlog-triage/SKILL.md +2 -2
- package/claude/skills/canon-cli/REQUIREMENT.md +19 -18
- package/claude/skills/canon-cli/SKILL.md +75 -32
- package/claude/skills/canon-feedback/REQUIREMENT.md +1 -1
- package/claude/skills/canon-feedback/SKILL.md +11 -14
- package/claude/skills/canon-feedback-triage/REQUIREMENT.md +13 -14
- package/claude/skills/canon-feedback-triage/SKILL.md +49 -30
- package/claude/skills/{canvas → canvas-board}/REQUIREMENT.md +5 -6
- package/claude/skills/{canvas → canvas-board}/SKILL.md +7 -7
- package/{standards → claude/skills/canvas-board/references}/canvas.md +12 -1
- package/{standards → claude/skills/canvas-board/references}/design.md +13 -5
- package/claude/skills/ci-workflow/REQUIREMENT.md +0 -1
- package/claude/skills/context-fold/REQUIREMENT.md +28 -48
- package/claude/skills/context-fold/SKILL.md +26 -95
- package/claude/skills/context-fold/references/classify.md +7 -8
- package/claude/skills/context-fold/references/completion-report.md +4 -8
- package/claude/skills/context-fold/references/context-refresh.md +7 -17
- package/{standards → claude/skills/context-fold/references}/context.md +19 -10
- package/claude/skills/context-fold/references/unusable-baseline.md +4 -8
- package/claude/skills/create-rule/REQUIREMENT.md +0 -1
- package/claude/skills/create-rule/SKILL.md +2 -2
- package/{standards → claude/skills/create-rule/references}/rule.md +12 -5
- package/claude/skills/create-skill/REQUIREMENT.md +6 -4
- package/claude/skills/create-skill/SKILL.md +10 -9
- package/{standards → claude/skills/create-skill/references}/skill-paths.md +1 -0
- package/{standards → claude/skills/create-skill/references}/skill.md +18 -15
- package/claude/skills/decision-escalate/REQUIREMENT.md +1 -1
- package/claude/skills/decision-escalate/SKILL.md +1 -1
- package/claude/skills/design-taste/REQUIREMENT.md +3 -5
- package/claude/skills/design-taste/SKILL.md +2 -4
- package/claude/skills/design-taste/references/vocabulary.md +1 -1
- package/claude/skills/docs-sync/REQUIREMENT.md +3 -3
- package/claude/skills/docs-sync/SKILL.md +3 -3
- package/{standards → claude/skills/docs-sync/references}/docs.md +11 -0
- package/{standards → claude/skills/docs-sync/references}/readme.md +9 -2
- package/claude/skills/document-health/REQUIREMENT.md +2 -2
- package/claude/skills/document-health/SKILL.md +4 -5
- package/claude/skills/document-health/references/axes.md +4 -6
- package/claude/skills/draft-and-pick/REQUIREMENT.md +16 -14
- package/claude/skills/draft-and-pick/SKILL.md +40 -32
- package/claude/skills/draft-and-pick/references/live-arms.md +9 -9
- package/claude/skills/draft-doc/REQUIREMENT.md +5 -5
- package/claude/skills/draft-doc/SKILL.md +9 -10
- package/claude/skills/draft-doc/references/requirements.md +61 -0
- package/claude/skills/draft-doc/references/wiki-kind.md +53 -0
- package/claude/skills/draft-doc/references/wiki.md +50 -30
- package/claude/skills/draft-figure/REQUIREMENT.md +2 -2
- package/claude/skills/draft-figure/SKILL.md +5 -5
- package/claude/skills/draft-figure/references/architecture-set.md +4 -4
- package/claude/skills/draft-figure/references/hand-drawn.md +2 -2
- package/claude/skills/draft-figure/references/mermaid-path.md +55 -0
- package/claude/skills/draft-figure/references/mermaid.md +43 -34
- package/claude/skills/draft-identity/REQUIREMENT.md +3 -3
- package/claude/skills/draft-identity/SKILL.md +10 -8
- package/claude/skills/draft-ready/REQUIREMENT.md +1 -1
- package/claude/skills/draft-ready/SKILL.md +7 -7
- package/claude/skills/draft-ready/references/assembly.md +1 -1
- package/{standards → claude/skills/draft-ready/references}/ready.md +13 -5
- package/claude/skills/git-branch/SKILL.md +1 -1
- package/{standards → claude/skills/git-branch/references}/branch.md +1 -1
- package/claude/skills/git-commit/SKILL.md +2 -2
- package/claude/skills/git-followup/REQUIREMENT.md +1 -1
- package/claude/skills/git-followup/SKILL.md +1 -1
- package/claude/skills/git-issue/SKILL.md +1 -1
- package/claude/skills/git-issue/references/issue.md +3 -3
- package/claude/skills/git-pr/SKILL.md +13 -13
- package/claude/skills/git-pr/references/evidence.md +2 -2
- package/claude/skills/git-pr/references/final-command.md +38 -14
- package/claude/skills/git-pr/references/labels.md +5 -1
- package/{standards → claude/skills/git-pr/references}/pr.md +19 -9
- package/{standards → claude/skills/git-pr/references}/publish.md +5 -3
- package/claude/skills/git-pr/references/task-number.md +1 -1
- package/claude/skills/git-ship/REQUIREMENT.md +0 -2
- package/claude/skills/git-ship/SKILL.md +5 -12
- package/claude/skills/git-split/SKILL.md +3 -3
- package/claude/skills/git-stage/SKILL.md +1 -1
- package/claude/skills/plan-feature/REQUIREMENT.md +1 -1
- package/claude/skills/plan-feature/SKILL.md +2 -6
- package/{standards → claude/skills/plan-feature/references}/plan.md +9 -10
- package/claude/skills/plan-groundwork/SKILL.md +5 -6
- package/{standards → claude/skills/plan-groundwork/references}/groundwork.md +17 -4
- package/claude/skills/plan-intake/SKILL.md +2 -3
- package/{standards → claude/skills/plan-intake/references}/intake.md +17 -2
- package/claude/skills/plan-intake-answer/REQUIREMENT.md +1 -1
- package/claude/skills/plan-intake-answer/SKILL.md +1 -1
- package/claude/skills/review-address/SKILL.md +2 -2
- package/claude/skills/review-address/references/post-review-findings.md +1 -1
- package/claude/skills/review-craft/REQUIREMENT.md +3 -3
- package/claude/skills/review-craft/SKILL.md +2 -2
- package/claude/skills/review-craft/references/ui.md +4 -4
- package/claude/skills/review-pr/REQUIREMENT.md +2 -2
- package/claude/skills/review-pr/SKILL.md +8 -10
- package/claude/skills/review-pr/references/body-variants.md +2 -2
- package/claude/skills/review-pr/references/key-changes.md +3 -3
- package/claude/skills/review-pr/references/post.md +4 -2
- package/claude/skills/review-ui/REQUIREMENT.md +1 -2
- package/claude/skills/review-ui/SKILL.md +2 -2
- package/claude/skills/review-ui/references/post.md +1 -1
- package/claude/skills/role-orchestrator/REQUIREMENT.md +3 -3
- package/claude/skills/role-orchestrator/SKILL.md +10 -10
- package/claude/skills/role-orchestrator/references/orchestrator-dispatch.md +3 -3
- package/claude/skills/role-orchestrator/references/orchestrator-handoff.md +9 -9
- package/claude/skills/role-orchestrator/references/orchestrator-launch.md +23 -1
- package/claude/skills/role-orchestrator/references/orchestrator-parked.md +2 -2
- package/claude/skills/role-orchestrator/references/orchestrator-refill.md +2 -5
- package/claude/skills/role-orchestrator/references/orchestrator-resume.md +4 -1
- package/claude/skills/role-planner/REQUIREMENT.md +2 -1
- package/claude/skills/role-planner/SKILL.md +15 -4
- package/claude/skills/role-reviewer/SKILL.md +2 -2
- package/claude/skills/role-worker/REQUIREMENT.md +1 -0
- package/claude/skills/role-worker/SKILL.md +11 -3
- package/claude/skills/session-compact/REQUIREMENT.md +1 -4
- package/claude/skills/session-compact/SKILL.md +3 -13
- package/claude/skills/session-compact/references/handoff-note.md +2 -2
- package/claude/skills/session-map/REQUIREMENT.md +1 -9
- package/claude/skills/session-map/SKILL.md +9 -17
- package/{standards → claude/skills/session-map/references}/session.md +17 -11
- package/claude/skills/session-relay/REQUIREMENT.md +1 -1
- package/claude/skills/session-resume/REQUIREMENT.md +6 -8
- package/claude/skills/session-resume/SKILL.md +3 -9
- package/claude/skills/session-worktree/SKILL.md +6 -6
- package/claude/skills/session-worktree/references/main-root-writes.md +2 -2
- package/claude/skills/systematic-debugging/REQUIREMENT.md +0 -1
- package/claude/skills/target-check/REQUIREMENT.md +3 -3
- package/claude/skills/target-check/SKILL.md +1 -1
- package/claude/skills/target-check/references/domains.md +1 -1
- package/claude/skills/target-setup/REQUIREMENT.md +4 -4
- package/claude/skills/target-setup/SKILL.md +3 -3
- package/claude/skills/target-setup/references/detect.md +2 -2
- package/claude/skills/task-board/REQUIREMENT.md +7 -12
- package/claude/skills/task-board/SKILL.md +9 -21
- package/{standards → claude/skills/task-board/references}/board.md +9 -0
- package/claude/skills/task-board/references/decline.md +1 -1
- package/{standards → claude/skills/task-board/references}/tasks.md +15 -10
- package/claude/skills/task-complete/REQUIREMENT.md +47 -0
- package/claude/skills/task-complete/SKILL.md +86 -0
- package/claude/skills/{task-board → task-complete}/references/archive.md +5 -5
- package/claude/skills/task-complete/references/receipt-sweep.md +32 -0
- package/claude/skills/task-complete/references/unusable-baseline.md +19 -0
- package/claude/skills/teach-workspace/REQUIREMENT.md +6 -2
- package/claude/skills/teach-workspace/SKILL.md +9 -5
- package/claude/skills/teach-workspace/references/lesson-craft.md +1 -1
- package/claude/skills/teach-workspace/references/promotion-fold.md +29 -0
- package/claude/skills/teach-workspace/references/promotion.md +3 -3
- package/claude/skills/teach-workspace/references/revisit.md +1 -1
- package/{standards → claude/skills/teach-workspace/references}/teach.md +17 -5
- package/claude/skills/ui-checklist/SKILL.md +1 -1
- package/claude/skills/ux-audit/REQUIREMENT.md +2 -2
- package/claude/skills/ux-audit/SKILL.md +3 -4
- package/claude/skills/ux-measure/SKILL.md +1 -1
- package/claude/skills/write-human/REQUIREMENT.md +0 -1
- package/claude/skills/write-human/SKILL.md +1 -1
- package/docs/agents/audits.md +1 -1
- package/docs/agents/canvas.md +1 -1
- package/docs/agents/commands.md +4 -8
- package/docs/agents/context-audit-checks.md +11 -25
- package/docs/agents/context-audit.md +7 -15
- package/docs/agents/context-classify.md +5 -5
- package/docs/agents/counts.md +5 -5
- package/docs/agents/drift-surfaces.md +2 -2
- package/docs/agents/index.md +5 -7
- package/docs/agents/indexes.md +1 -1
- package/docs/agents/install-and-sync.md +6 -11
- package/docs/agents/intake.md +1 -1
- package/docs/agents/key-changes.md +5 -5
- package/docs/agents/label-coverage.md +11 -0
- package/docs/agents/migrate.md +1 -1
- package/docs/agents/records-push.md +2 -2
- package/docs/agents/records-stale.md +13 -48
- package/docs/agents/records-validate.md +4 -8
- package/docs/agents/records.md +6 -28
- package/docs/agents/restated.md +1 -1
- package/docs/agents/rule-citations.md +2 -2
- package/docs/agents/sandbox.md +4 -4
- package/docs/agents/skills-audit.md +2 -2
- package/docs/agents/state-scoped-risk.md +2 -2
- package/docs/agents/superseded.md +2 -2
- package/docs/agents/tasks-plans.md +1 -1
- package/docs/agents/tasks-validate.md +1 -1
- package/docs/agents/tasks.md +3 -3
- package/docs/agents/teach.md +1 -1
- package/docs/agents/upstream.md +26 -2
- package/docs/target/migrations.md +32 -0
- package/docs/target/projects.md +5 -7
- package/docs/target/scenarios.md +2 -2
- package/docs/target/sync.md +4 -4
- package/docs/workflow/ai-workflow.md +7 -38
- package/docs/workflow/index.md +1 -1
- package/docs/workflow/operating-model.md +10 -10
- package/docs/workflow/parallel-features.md +12 -12
- package/docs/workflow/skill-map-on-request.md +21 -24
- package/docs/workflow/skill-map.md +23 -34
- package/docs/workflow/visual-design-workflow.md +13 -16
- package/governance/renames.toml +0 -30
- package/governance/rules/canon/605-worktrees.md +1 -1
- package/governance/rules/canon/context.md +13 -0
- package/governance/rules/{standards → canon}/plan.md +4 -5
- package/governance/rules/canon/tasks.md +18 -0
- package/governance/rules/claude/skill.md +17 -0
- package/governance/stacks/base.toml +2 -4
- package/package.json +4 -4
- package/scripts/core/install-check.sh +4 -4
- package/scripts/core/regen-web-previews.ts +1 -1
- package/scripts/lib/ui.sh +0 -159
- package/src/audits/catalog.ts +5 -98
- package/src/claude/cases/authoring.ts +0 -18
- package/src/claude/cases/misc.ts +1 -14
- package/src/claude/cases/setup.ts +7 -20
- package/src/claude/cases/workflow.ts +6 -34
- package/src/claude/seeds.ts +1 -7
- package/src/claude/skills-audit.ts +3 -3
- package/src/cli/help.ts +4 -5
- package/src/cli/ui.ts +2 -3
- package/src/cli.ts +0 -4
- package/src/commands/claude.ts +9 -15
- package/src/commands/context.ts +18 -280
- package/src/commands/feedback.ts +22 -91
- package/src/commands/gov.ts +2 -15
- package/src/commands/labels.ts +326 -7
- package/src/commands/migrate.ts +6 -1
- package/src/commands/pr.ts +1 -1
- package/src/commands/records.ts +17 -403
- package/src/commands/sandbox.ts +3 -6
- package/src/commands/sync.ts +5 -3
- package/src/commands/tasks.ts +3 -3
- package/src/commands/upstream.ts +135 -0
- package/src/context/audit.ts +10 -19
- package/src/context/classify/extract.ts +6 -13
- package/src/context/classify/patterns.ts +2 -41
- package/src/context/classify/prompts.ts +2 -6
- package/src/context/classify/run.ts +3 -3
- package/src/context/folders.ts +8 -13
- package/src/context/gate.ts +11 -91
- package/src/context/requirements.ts +13 -4
- package/src/counts/scan.ts +3 -3
- package/src/design/budget.ts +1 -1
- package/src/design/components.ts +3 -3
- package/src/design/document.ts +1 -1
- package/src/design/regen.ts +1 -1
- package/src/design/render.ts +1 -1
- package/src/feedback/body.ts +0 -12
- package/src/gate/measures.ts +7 -58
- package/src/gate/sequencer.ts +56 -1
- package/src/gate/stages.ts +1 -7
- package/src/gov/citations.ts +9 -3
- package/src/gov/install.ts +2 -3
- package/src/gov/restated.ts +3 -3
- package/src/gov/stacks.ts +1 -1
- package/src/hooks/post-merge.ts +1 -1
- package/src/labels/apply.ts +39 -0
- package/src/labels/format.ts +3 -3
- package/src/labels/phase.ts +3 -3
- package/src/labels/sections.ts +43 -0
- package/src/markdown/structure.ts +2 -2
- package/src/migrate/record-layout.ts +3 -3
- package/src/migrate/skill-names.ts +20 -1
- package/src/pr/paths.ts +4 -4
- package/src/records/backup.ts +16 -6
- package/src/records/ordinal.ts +1 -1
- package/src/records/prune.ts +2 -1
- package/src/records/stale-canonical.ts +33 -3
- package/src/records/validate.ts +2 -188
- package/src/roots/record.ts +1 -1
- package/src/sandbox/census.ts +1 -1
- package/src/sandbox/coverage.ts +2 -6
- package/src/sandbox/equivalence.ts +5 -44
- package/src/sandbox/expect.ts +4 -4
- package/src/sandbox/provision.ts +13 -36
- package/src/sandbox/scenario.ts +137 -55
- package/src/sandbox/tree.ts +2 -6
- package/src/shipped/references.ts +3 -3
- package/src/standards/read.ts +44 -0
- package/src/sync/git.ts +1 -1
- package/src/sync/seeds-report.ts +1 -1
- package/src/tasks/archive.ts +5 -5
- package/src/tasks/branch.ts +3 -3
- package/src/tasks/label.ts +1 -1
- package/src/tasks/reach.ts +2 -2
- package/src/tasks/record.ts +2 -2
- package/src/tasks/validate.ts +2 -2
- package/src/teach/workspace.ts +1 -1
- package/src/upstream/cursor.ts +1 -1
- package/src/upstream/due.ts +128 -0
- package/src/upstream/releases.ts +2 -1
- package/standards/index.md +0 -35
- package/standards/standard.md +1 -7
- package/tooling/base/reference.md +2 -2
- package/tooling/base/seeds/.github/pull_request_template.md +2 -2
- package/tooling/claude/reference.md +7 -21
- package/tooling/claude/seeds/.claude/hooks/pr-create-log.sh +9 -1
- package/tooling/claude/seeds/.claude/hooks/records-index.sh +8 -20
- package/tooling/claude/seeds/.claude/hooks/review-post-scan.sh +171 -0
- package/tooling/claude/seeds/.claude/hooks/standards-audit.sh +3 -3
- package/tooling/claude/seeds/.claude/settings.json +9 -0
- package/tooling/claude/seeds/CLAUDE.md +1 -3
- package/tooling/claude/seeds/canon/REQUIREMENTS.md +2 -9
- package/tooling/web/configs/e2e/screenshot.ts +0 -1
- package/claude/skills/auto-ship/references/review-findings.md +0 -20
- package/claude/skills/bash-cli-script/REQUIREMENT.md +0 -43
- package/claude/skills/bash-cli-script/SKILL.md +0 -53
- package/claude/skills/bash-cli-script/references/template.md +0 -19
- package/claude/skills/canon-operator/REQUIREMENT.md +0 -62
- package/claude/skills/canon-operator/SKILL.md +0 -113
- package/claude/skills/canon-rollout/REQUIREMENT.md +0 -59
- package/claude/skills/canon-rollout/SKILL.md +0 -140
- package/claude/skills/canon-rollout/references/failure-recovery.md +0 -20
- package/claude/skills/context-fold/references/anchor-sweep.md +0 -58
- package/claude/skills/context-fold/references/promoted-pages.md +0 -29
- package/claude/skills/context-fold/references/receipt-sweep.md +0 -43
- package/claude/skills/context-fold/references/wireframe-sweep.md +0 -45
- package/claude/skills/create-standard/REQUIREMENT.md +0 -33
- package/claude/skills/create-standard/SKILL.md +0 -31
- package/claude/skills/design-extract/REQUIREMENT.md +0 -42
- package/claude/skills/design-extract/SKILL.md +0 -108
- package/claude/skills/draft-and-pick/references/frame.html +0 -118
- package/claude/skills/draft-doc/references/wireframes.md +0 -48
- package/claude/skills/markdown-propose/REQUIREMENT.md +0 -47
- package/claude/skills/markdown-propose/SKILL.md +0 -122
- package/claude/skills/markdown-propose/references/format.md +0 -118
- package/claude/skills/memory-capture/REQUIREMENT.md +0 -50
- package/claude/skills/memory-capture/SKILL.md +0 -117
- package/claude/skills/memory-review/REQUIREMENT.md +0 -52
- package/claude/skills/memory-review/SKILL.md +0 -129
- package/claude/skills/memory-review/references/later-phases.md +0 -118
- package/claude/skills/memory-review/references/receipt-format.md +0 -64
- package/claude/skills/project-commands/REQUIREMENT.md +0 -42
- package/claude/skills/project-commands/SKILL.md +0 -87
- package/claude/skills/repo-metadata/REQUIREMENT.md +0 -37
- package/claude/skills/repo-metadata/SKILL.md +0 -54
- package/claude/skills/restate-plainly/REQUIREMENT.md +0 -41
- package/claude/skills/restate-plainly/SKILL.md +0 -41
- package/claude/skills/review-branch/REQUIREMENT.md +0 -40
- package/claude/skills/review-branch/SKILL.md +0 -137
- package/claude/skills/seed-sync/REQUIREMENT.md +0 -45
- package/claude/skills/seed-sync/SKILL.md +0 -158
- package/claude/skills/sketch-design/REQUIREMENT.md +0 -38
- package/claude/skills/sketch-design/SKILL.md +0 -94
- package/claude/skills/ux-walkthrough/REQUIREMENT.md +0 -56
- package/claude/skills/ux-walkthrough/SKILL.md +0 -53
- package/claude/skills/ux-walkthrough/references/builds.md +0 -15
- package/claude/skills/ux-walkthrough/references/candidate-pages.md +0 -11
- package/claude/skills/ux-walkthrough/references/measuring.md +0 -22
- package/claude/skills/ux-walkthrough/references/record.md +0 -36
- package/claude/skills/ux-walkthrough/references/relay.md +0 -25
- package/docs/agents/architecture-record.md +0 -36
- package/docs/agents/review-classification.md +0 -76
- package/governance/rules/canon/603-memory.md +0 -11
- package/governance/rules/lang/120-bash.md +0 -18
- package/governance/rules/standards/architecture.md +0 -13
- package/governance/rules/standards/context.md +0 -14
- package/governance/rules/standards/design.md +0 -12
- package/governance/rules/standards/groundwork.md +0 -13
- package/governance/rules/standards/intake.md +0 -12
- package/governance/rules/standards/memory.md +0 -12
- package/governance/rules/standards/readme.md +0 -12
- package/governance/rules/standards/ready.md +0 -13
- package/governance/rules/standards/requirements.md +0 -12
- package/governance/rules/standards/rule.md +0 -13
- package/governance/rules/standards/session.md +0 -13
- package/governance/rules/standards/skill.md +0 -21
- package/governance/rules/standards/standard.md +0 -13
- package/governance/rules/standards/tasks.md +0 -15
- package/governance/rules/standards/teach.md +0 -14
- package/governance/rules/standards/wiki.md +0 -13
- package/governance/rules/standards/wireframes.md +0 -13
- package/scripts/config.sh +0 -11
- package/scripts/lib/gov.sh +0 -14
- package/scripts/lib/sandbox-fixtures.sh +0 -191
- package/scripts/lib/sandbox-git.sh +0 -125
- package/scripts/lib/sandbox-path.sh +0 -50
- package/scripts/sandbox-hook.sh +0 -99
- package/src/autoship/classify.ts +0 -75
- package/src/autoship/paths.ts +0 -50
- package/src/commands/autoship.ts +0 -129
- package/src/commands/repo.ts +0 -393
- package/src/context/architecture.ts +0 -654
- package/src/context/wireframe-states.ts +0 -238
- package/src/gov/standard-rules.ts +0 -179
- package/src/records/migrate.ts +0 -78
- package/src/records/stale.ts +0 -243
- package/src/repo/metadata.ts +0 -206
- package/src/sandbox/hooks.ts +0 -128
- package/standards/architecture.md +0 -127
- package/standards/memory.md +0 -158
- package/standards/mermaid.md +0 -64
- package/standards/requirements.md +0 -79
- package/standards/wiki.md +0 -77
- package/standards/wireframes.md +0 -143
- package/tooling/claude/seeds/.claude/memory/index.md +0 -8
- package/tooling/claude/seeds/canon/ARCHITECTURE.md +0 -23
- package/tooling/claude/seeds/canon/wireframes/index.md +0 -8
- /package/{standards → claude/skills/create-skill/references}/skill-practice.md +0 -0
- /package/{standards → claude/skills/create-skill/references}/skill-requirement.md +0 -0
- /package/{standards → claude/skills/draft-figure/references}/figures.md +0 -0
- /package/{standards → claude/skills/git-branch/references}/slug.md +0 -0
- /package/{standards → claude/skills/git-commit/references}/commit.md +0 -0
- /package/{standards → claude/skills/git-commit/references}/versioning.md +0 -0
- /package/{standards → claude/skills/plan-feature/references}/plan-lifecycle.md +0 -0
- /package/{standards → claude/skills/plan-groundwork/references}/groundwork-spikes.md +0 -0
- /package/{standards → claude/skills/task-board/references}/tasks-decline.md +0 -0
- /package/{standards → claude/skills/teach-workspace/references}/glossary.md +0 -0
|
@@ -1,17 +1,26 @@
|
|
|
1
1
|
import { readFile } from 'node:fs/promises'
|
|
2
2
|
import { join, relative } from 'node:path'
|
|
3
|
-
import { wordCount } from '@/context/architecture'
|
|
4
3
|
import { bodyLines } from '@/markdown/scan'
|
|
5
4
|
import { surfaceDir } from '@/roots/surface'
|
|
6
5
|
|
|
7
6
|
/**
|
|
8
7
|
* The record this measures, relative to `root`, resolved at either surface
|
|
9
|
-
* root
|
|
8
|
+
* root, since a project that has moved holds it under either.
|
|
10
9
|
*/
|
|
11
10
|
export function requirementsRel(root: string): string {
|
|
12
11
|
return relative(root, surfaceDir(root, 'REQUIREMENTS.md'))
|
|
13
12
|
}
|
|
14
13
|
|
|
14
|
+
/**
|
|
15
|
+
* Counts whitespace-delimited tokens, the unit the record's word cap is stated
|
|
16
|
+
* in. A code span counts as the tokens it holds, so a line citing a long path
|
|
17
|
+
* pays for it the way a reader does. A caller gating on the count hands in
|
|
18
|
+
* prose with fenced lines already dropped.
|
|
19
|
+
*/
|
|
20
|
+
export function wordCount(text: string): number {
|
|
21
|
+
return text.match(/\S+/g)?.length ?? 0
|
|
22
|
+
}
|
|
23
|
+
|
|
15
24
|
export interface RequirementsReport {
|
|
16
25
|
readonly rel: string
|
|
17
26
|
/** The whole record's word count, frontmatter left out. */
|
|
@@ -43,8 +52,8 @@ function isMissing(error: unknown): boolean {
|
|
|
43
52
|
/**
|
|
44
53
|
* Measures the record, or reports nothing when the project carries none.
|
|
45
54
|
*
|
|
46
|
-
* Absent rather than zeroed,
|
|
47
|
-
* record present and unreadable propagates
|
|
55
|
+
* Absent rather than zeroed, so a project with no record is never told it holds an
|
|
56
|
+
* empty one, and a record present and unreadable propagates.
|
|
48
57
|
*/
|
|
49
58
|
export async function measureRequirements(
|
|
50
59
|
root: string,
|
package/src/counts/scan.ts
CHANGED
|
@@ -35,8 +35,8 @@ export type CountsReport =
|
|
|
35
35
|
|
|
36
36
|
/**
|
|
37
37
|
* A calendar date, which reads a sentence as a historical record rather than
|
|
38
|
-
* a live claim about the tree.
|
|
39
|
-
*
|
|
38
|
+
* a live claim about the tree. The context entries
|
|
39
|
+
* carry a figure this way deliberately, and every one of them stays
|
|
40
40
|
* correct forever, so a sentence carrying one is read past rather than
|
|
41
41
|
* matched.
|
|
42
42
|
*/
|
|
@@ -142,7 +142,7 @@ const QUANTIFIERS = ['all']
|
|
|
142
142
|
* match at all. No syntactic rule tells a qualifier that narrows a catalog
|
|
143
143
|
* from one that only restates it, and the sentence was true when written, so
|
|
144
144
|
* the fix was not a narrower matcher: the clause was dated as a past state,
|
|
145
|
-
* the way
|
|
145
|
+
* the way a context entry dates its own figures, which is the class
|
|
146
146
|
* the date exclusion below already reads past.
|
|
147
147
|
*/
|
|
148
148
|
const ARTICLES = ['the', 'a', 'an']
|
package/src/design/budget.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The prose budget `
|
|
2
|
+
* The prose budget `claude/skills/canvas-board/references/design.md` sets for a design record, and the
|
|
3
3
|
* counter the `design` gate stage reads it through.
|
|
4
4
|
*
|
|
5
5
|
* The limits live here and in the standard, never in the stage, so the stage
|
package/src/design/components.ts
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
* `buildDesignCss`'s `components` option, which is what widening that option
|
|
16
16
|
* from a boolean to `boolean | readonly Component[]` bought.
|
|
17
17
|
*
|
|
18
|
-
* It does not live in `canon/DESIGN.md`. `
|
|
18
|
+
* It does not live in `canon/DESIGN.md`. `claude/skills/canvas-board/references/design.md` keeps CSS class
|
|
19
19
|
* names out of that record and says they live in code, which is here.
|
|
20
20
|
*/
|
|
21
21
|
|
|
@@ -250,8 +250,8 @@ const TEACH_CHROME: Component = {
|
|
|
250
250
|
'navigation shared by every teach page. Recovered from two gitignored',
|
|
251
251
|
'course.css files that predate a regression that dropped this layer from the',
|
|
252
252
|
"generator, and rewritten onto this module's tokens rather than the",
|
|
253
|
-
'incompatible palette they carried. See canon/
|
|
254
|
-
'the shape.',
|
|
253
|
+
'incompatible palette they carried. See canon/context/features/teach/chrome.md',
|
|
254
|
+
'for the shape.',
|
|
255
255
|
].join('\n '),
|
|
256
256
|
reads: [
|
|
257
257
|
'--color-background',
|
package/src/design/document.ts
CHANGED
|
@@ -94,7 +94,7 @@ function borderRows(tokens: readonly BorderToken[]): string[][] {
|
|
|
94
94
|
* and every reason behind them lives in the entry.
|
|
95
95
|
*/
|
|
96
96
|
const LEAD = [
|
|
97
|
-
'Authoring guidance: `
|
|
97
|
+
'Authoring guidance: `claude/skills/canvas-board/references/design.md`. Rendered from `src/design/tokens.ts` by `canon design regen`, so edit the module and never this file.',
|
|
98
98
|
'Why each value was chosen lives in `canon/context/design/tokens.md`.',
|
|
99
99
|
].join(' ')
|
|
100
100
|
|
package/src/design/regen.ts
CHANGED
|
@@ -16,7 +16,7 @@ import { NEUTRAL_TOKENS } from '@/design/neutral'
|
|
|
16
16
|
* gate stage is what keeps silently out of it.
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
|
-
/** The rendered record, at the path `
|
|
19
|
+
/** The rendered record, at the path `claude/skills/canvas-board/references/design.md` fixes for it. */
|
|
20
20
|
export const DESIGN_DOCUMENT = join('canon', 'DESIGN.md')
|
|
21
21
|
|
|
22
22
|
/**
|
package/src/design/render.ts
CHANGED
|
@@ -105,7 +105,7 @@ interface Confidence {
|
|
|
105
105
|
}
|
|
106
106
|
|
|
107
107
|
/**
|
|
108
|
-
* The columns the confidence ratio reads, fixed by `
|
|
108
|
+
* The columns the confidence ratio reads, fixed by `claude/skills/canvas-board/references/design.md`. The
|
|
109
109
|
* first column of each table names its row, and `Multiplier` and `When used`
|
|
110
110
|
* restate what the row already carries, so none of them is something a source
|
|
111
111
|
* could anchor and none belongs in the denominator.
|
package/src/feedback/body.ts
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
const SLUG_FALLBACK = 'general'
|
|
2
|
-
const SLUG_MAX_LENGTH = 40
|
|
3
1
|
const TITLE_MAX_LENGTH = 72
|
|
4
2
|
|
|
5
3
|
/**
|
|
@@ -79,16 +77,6 @@ function surfaceField(body: string): string | undefined {
|
|
|
79
77
|
return readField(body, 'Surface')?.split('\n')[0]?.trim()
|
|
80
78
|
}
|
|
81
79
|
|
|
82
|
-
export function deriveSlug(body: string): string {
|
|
83
|
-
const slug = (surfaceField(body) ?? '')
|
|
84
|
-
.toLowerCase()
|
|
85
|
-
.replace(/[^a-z0-9]+/g, '-')
|
|
86
|
-
.replace(/^-+|-+$/g, '')
|
|
87
|
-
.slice(0, SLUG_MAX_LENGTH)
|
|
88
|
-
.replace(/-+$/g, '')
|
|
89
|
-
return slug || SLUG_FALLBACK
|
|
90
|
-
}
|
|
91
|
-
|
|
92
80
|
/**
|
|
93
81
|
* Each label must exist on the toolkit repository, because `gh issue create`
|
|
94
82
|
* refuses the whole issue on an unknown label rather than dropping it.
|
package/src/gate/measures.ts
CHANGED
|
@@ -7,14 +7,6 @@ import {
|
|
|
7
7
|
type ClientCommand,
|
|
8
8
|
clientCommandCitationsIn,
|
|
9
9
|
} from '@/gate/client-commands'
|
|
10
|
-
import {
|
|
11
|
-
isOverCount,
|
|
12
|
-
isOverLength,
|
|
13
|
-
isOverRisks,
|
|
14
|
-
measureArchitecture,
|
|
15
|
-
missingRevisit,
|
|
16
|
-
overWords,
|
|
17
|
-
} from '@/context/architecture'
|
|
18
10
|
import { isOverWordCap, measureRequirements } from '@/context/requirements'
|
|
19
11
|
import {
|
|
20
12
|
auditSkills,
|
|
@@ -253,62 +245,19 @@ function citedPaths(record: { paths?: unknown } | undefined): string[] {
|
|
|
253
245
|
}
|
|
254
246
|
|
|
255
247
|
/**
|
|
256
|
-
* The
|
|
257
|
-
* architecture record carries five: the line ceiling its allowances derive,
|
|
258
|
-
* the entry cap, the revisit sentence closing each decision, the words a
|
|
259
|
-
* decision may hold, and the bullets its Risks section may hold. The
|
|
260
|
-
* requirements record carries one, its own word count.
|
|
248
|
+
* The requirements record against the word cap it states for itself.
|
|
261
249
|
*
|
|
262
250
|
* Read in-process rather than through `context audit`, whose one gating stage
|
|
263
|
-
* here runs `--citations-only` and never opens
|
|
264
|
-
*
|
|
265
|
-
*
|
|
266
|
-
* passes, since each rule belongs to the record rather than to the toolkit.
|
|
251
|
+
* here runs `--citations-only` and never opens the record. A project carrying
|
|
252
|
+
* no record, or a record stating no cap, passes, since the rule belongs to the
|
|
253
|
+
* record rather than to the toolkit.
|
|
267
254
|
*/
|
|
268
255
|
export const canonicalRecords: Measure = async (ctx) => {
|
|
269
|
-
const
|
|
270
|
-
measureArchitecture(ctx.root),
|
|
271
|
-
measureRequirements(ctx.root),
|
|
272
|
-
])
|
|
256
|
+
const requirements = await measureRequirements(ctx.root)
|
|
273
257
|
|
|
274
258
|
const failures: string[] = []
|
|
275
259
|
const emissions: Emission[] = []
|
|
276
260
|
|
|
277
|
-
if (report === undefined) {
|
|
278
|
-
emissions.push(info('No architecture record to measure'))
|
|
279
|
-
} else {
|
|
280
|
-
const decisions = report.decisions.length
|
|
281
|
-
const lackingRevisit = missingRevisit(report)
|
|
282
|
-
const longDecisions = overWords(report)
|
|
283
|
-
failures.push(
|
|
284
|
-
...[
|
|
285
|
-
isOverCount(report) &&
|
|
286
|
-
`${decisions} decisions against a cap of ${report.entryCap}. Merge two or retire one in ${report.rel}, never compress.`,
|
|
287
|
-
isOverLength(report) &&
|
|
288
|
-
`${report.lines} lines against a ceiling of ${report.ceiling} in ${report.rel}.`,
|
|
289
|
-
lackingRevisit.length > 0 &&
|
|
290
|
-
`No revisit sentence in ${lackingRevisit.map((heading) => `"${heading}"`).join(', ')}. Close each with one opening "Revisit when" in ${report.rel}.`,
|
|
291
|
-
longDecisions.length > 0 &&
|
|
292
|
-
`${longDecisions.map((entry) => `"${entry.heading}" (${entry.words})`).join(', ')} past ${report.wordCap} words a decision in ${report.rel}. Cut the reasoning to the trade, never split one decision across two headings.`,
|
|
293
|
-
isOverRisks(report) &&
|
|
294
|
-
`${report.risksBullets} risk bullets against a cap of ${report.riskCap} in ${report.rel}. Drop what is no longer open.`,
|
|
295
|
-
].filter((failure): failure is string => typeof failure === 'string'),
|
|
296
|
-
)
|
|
297
|
-
|
|
298
|
-
const cap =
|
|
299
|
-
report.entryCap === undefined
|
|
300
|
-
? 'no entry cap stated'
|
|
301
|
-
: `a cap of ${report.entryCap}`
|
|
302
|
-
emissions.push(info(`${decisions} decisions against ${cap}`))
|
|
303
|
-
if (report.riskCap !== undefined && report.risksBullets === undefined) {
|
|
304
|
-
emissions.push(
|
|
305
|
-
info(
|
|
306
|
-
`No Risks section to count against a cap of ${report.riskCap} in ${report.rel}`,
|
|
307
|
-
),
|
|
308
|
-
)
|
|
309
|
-
}
|
|
310
|
-
}
|
|
311
|
-
|
|
312
261
|
if (requirements === undefined) {
|
|
313
262
|
emissions.push(info('No requirements record to measure'))
|
|
314
263
|
} else if (isOverWordCap(requirements)) {
|
|
@@ -368,7 +317,7 @@ export const designProse: Measure = async (ctx) => {
|
|
|
368
317
|
if (failures.length > 0) {
|
|
369
318
|
return {
|
|
370
319
|
emissions: [],
|
|
371
|
-
failure: `${failures.join(' ')} Cut to the budget in
|
|
320
|
+
failure: `${failures.join(' ')} Cut to the budget in claude/skills/canvas-board/references/design.md, moving the why to the context entry.`,
|
|
372
321
|
}
|
|
373
322
|
}
|
|
374
323
|
if (emissions.length === 0)
|
|
@@ -415,7 +364,7 @@ export const skillProvenance: Measure = async (ctx) => {
|
|
|
415
364
|
/**
|
|
416
365
|
* Every listed practice skill against the closing sections, and every skill on
|
|
417
366
|
* the wider ledger list against the ledger, both of which
|
|
418
|
-
* `
|
|
367
|
+
* `claude/skills/create-skill/references/skill-practice.md` requires.
|
|
419
368
|
*
|
|
420
369
|
* Read in-process for the reason `skillProvenance` is, so the verb keeps its
|
|
421
370
|
* missing-requirement-only exit. The list names shipped folders alone, so a
|
package/src/gate/sequencer.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs'
|
|
2
|
+
import { availableParallelism } from 'node:os'
|
|
1
3
|
import { join } from 'node:path'
|
|
2
4
|
import { execa } from 'execa'
|
|
3
5
|
import type {
|
|
@@ -44,6 +46,28 @@ export interface StageResult {
|
|
|
44
46
|
readonly queuedMs?: number
|
|
45
47
|
}
|
|
46
48
|
|
|
49
|
+
export interface LoadReading {
|
|
50
|
+
/** The 1-minute load average. */
|
|
51
|
+
readonly loadAverage: number
|
|
52
|
+
readonly cores: number
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Reads the 1-minute load average from `/proc/loadavg`. A platform without
|
|
57
|
+
* it, as macOS, has no reading to give, so this answers `undefined` rather
|
|
58
|
+
* than throwing into a stage that has already failed.
|
|
59
|
+
*/
|
|
60
|
+
export function readProcLoad(): LoadReading | undefined {
|
|
61
|
+
try {
|
|
62
|
+
const first = readFileSync('/proc/loadavg', 'utf8').split(' ')[0]
|
|
63
|
+
const loadAverage = Number.parseFloat(first)
|
|
64
|
+
if (!Number.isFinite(loadAverage)) return undefined
|
|
65
|
+
return { loadAverage, cores: availableParallelism() }
|
|
66
|
+
} catch {
|
|
67
|
+
return undefined
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
47
71
|
export interface GateContext extends MeasureContext {
|
|
48
72
|
/** Whether the format stage writes or checks. */
|
|
49
73
|
readonly write: boolean
|
|
@@ -58,6 +82,11 @@ export interface GateContext extends MeasureContext {
|
|
|
58
82
|
* wait and reads as a hung suite.
|
|
59
83
|
*/
|
|
60
84
|
readonly onQueue?: (label: string, holder: LockHolder) => void
|
|
85
|
+
/**
|
|
86
|
+
* Reads the machine load a failed locked stage ran under. Defaults to
|
|
87
|
+
* `/proc/loadavg`, and answers `undefined` where there is none.
|
|
88
|
+
*/
|
|
89
|
+
readonly readLoad?: () => LoadReading | undefined
|
|
61
90
|
}
|
|
62
91
|
|
|
63
92
|
export interface ChangedSet {
|
|
@@ -195,7 +224,11 @@ async function executeStage(
|
|
|
195
224
|
]
|
|
196
225
|
|
|
197
226
|
try {
|
|
198
|
-
const outcome =
|
|
227
|
+
const outcome = withLoadLine(
|
|
228
|
+
await runChecks(stage, ctx, queued),
|
|
229
|
+
stage,
|
|
230
|
+
ctx,
|
|
231
|
+
)
|
|
199
232
|
return held.waitedOn === undefined
|
|
200
233
|
? outcome
|
|
201
234
|
: { ...outcome, queuedMs: held.waitedMs }
|
|
@@ -204,6 +237,28 @@ async function executeStage(
|
|
|
204
237
|
}
|
|
205
238
|
}
|
|
206
239
|
|
|
240
|
+
/**
|
|
241
|
+
* The lock serializes suites and does nothing about the rest of the box, so a
|
|
242
|
+
* starved spawn test and a real failure read alike. The load beside the
|
|
243
|
+
* failure is what lets a report tell them apart.
|
|
244
|
+
*/
|
|
245
|
+
function withLoadLine(
|
|
246
|
+
outcome: StageOutcome,
|
|
247
|
+
stage: Stage,
|
|
248
|
+
ctx: GateContext,
|
|
249
|
+
): StageOutcome {
|
|
250
|
+
if (outcome.status !== 'failed') return outcome
|
|
251
|
+
|
|
252
|
+
const reading = (ctx.readLoad ?? readProcLoad)()
|
|
253
|
+
if (reading === undefined) return outcome
|
|
254
|
+
|
|
255
|
+
const text = `Load average ${reading.loadAverage} on ${reading.cores} cores when the ${stage.label} stage failed`
|
|
256
|
+
return {
|
|
257
|
+
...outcome,
|
|
258
|
+
emissions: [...outcome.emissions, { kind: 'info', text }],
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
207
262
|
async function runChecks(
|
|
208
263
|
stage: Stage,
|
|
209
264
|
ctx: GateContext,
|
package/src/gate/stages.ts
CHANGED
|
@@ -198,17 +198,11 @@ export const STAGES: readonly Stage[] = [
|
|
|
198
198
|
argv: ['gov', 'regen'],
|
|
199
199
|
failure: 'Consumed-copy regen failed',
|
|
200
200
|
},
|
|
201
|
-
{
|
|
202
|
-
kind: 'drift',
|
|
203
|
-
pathspec: 'governance/rules/standards',
|
|
204
|
-
failure:
|
|
205
|
-
'Standard-pointer rules drifted. Run bun run check and commit governance/rules/standards and .claude/rules.',
|
|
206
|
-
},
|
|
207
201
|
{
|
|
208
202
|
kind: 'drift',
|
|
209
203
|
pathspec: '.claude/rules',
|
|
210
204
|
failure:
|
|
211
|
-
'Consumed copies drifted. Run bun run check and commit
|
|
205
|
+
'Consumed copies drifted. Run bun run check and commit .claude/rules.',
|
|
212
206
|
},
|
|
213
207
|
],
|
|
214
208
|
success: 'Consumed copies clean',
|
package/src/gov/citations.ts
CHANGED
|
@@ -6,6 +6,7 @@ import { isMarked } from '@/sweep/exempt-marker'
|
|
|
6
6
|
import { gitEnv } from '@/git/env'
|
|
7
7
|
import { listRuleFiles } from '@/gov/payload'
|
|
8
8
|
import { parseFrontmatter } from '@/indexes/frontmatter'
|
|
9
|
+
import { movedStandardPath } from '@/standards/read'
|
|
9
10
|
import { findBacktickSpans } from '@/markdown/backticks'
|
|
10
11
|
|
|
11
12
|
/**
|
|
@@ -177,8 +178,9 @@ export function classifySpan(span: string): CitationForm | undefined {
|
|
|
177
178
|
*
|
|
178
179
|
* A standard name takes the authoring root alone, matching `standardRoots` in
|
|
179
180
|
* `@/standards/read`, which reads `standards/` at the working root and then the
|
|
180
|
-
* package corpus
|
|
181
|
-
* only where those two roots
|
|
181
|
+
* package corpus, plus the skill reference a retired name moved to. This verb
|
|
182
|
+
* refuses a tree holding no rule corpus, so it runs only where those two roots
|
|
183
|
+
* are one directory. `internal/standards/` is
|
|
182
184
|
* deliberately absent: `canon standards <name>` never reaches it, so admitting it
|
|
183
185
|
* here would pass a citation that refuses for the session opening it, which is a
|
|
184
186
|
* gate failing open.
|
|
@@ -191,7 +193,11 @@ function candidatesFor(
|
|
|
191
193
|
cited: string,
|
|
192
194
|
ruleFile: string,
|
|
193
195
|
): string[] {
|
|
194
|
-
if (form === 'standard')
|
|
196
|
+
if (form === 'standard') {
|
|
197
|
+
const moved = movedStandardPath(cited)
|
|
198
|
+
|
|
199
|
+
return [join('standards', `${cited}.md`), ...(moved ? [moved] : [])]
|
|
200
|
+
}
|
|
195
201
|
if (form === 'sibling') return [join(dirname(ruleFile), cited)]
|
|
196
202
|
return [cited]
|
|
197
203
|
}
|
package/src/gov/install.ts
CHANGED
|
@@ -66,9 +66,8 @@ export function installedRuleNames(
|
|
|
66
66
|
}
|
|
67
67
|
|
|
68
68
|
/**
|
|
69
|
-
*
|
|
70
|
-
*
|
|
71
|
-
* subdirectory and installs flat.
|
|
69
|
+
* A rule sitting directly under `governance/rules/` has no subdirectory and
|
|
70
|
+
* installs flat.
|
|
72
71
|
*/
|
|
73
72
|
export function ruleSubdir(src: string, rulesRoot: string): string {
|
|
74
73
|
const subdir = dirname(relative(rulesRoot, src))
|
package/src/gov/restated.ts
CHANGED
|
@@ -36,8 +36,8 @@ const SKILL_ROOTS: readonly string[] = [SHIPPED_SKILLS_REL, PROJECT_SKILLS_REL]
|
|
|
36
36
|
/**
|
|
37
37
|
* Path pairs whose duplication is deliberate and already recorded.
|
|
38
38
|
*
|
|
39
|
-
* The seed is authored from the always-loaded file and
|
|
40
|
-
*
|
|
39
|
+
* The seed is authored from the always-loaded file and a hand merge
|
|
40
|
+
* reconciles the two, so a bullet appearing in both is the design
|
|
41
41
|
* rather than a defect. Excluding by pair rather than by content is what the
|
|
42
42
|
* plan settled on: the duplication is a location fact this repository already
|
|
43
43
|
* records, and a content test would have to rediscover it on every run.
|
|
@@ -611,7 +611,7 @@ function authorityFor(
|
|
|
611
611
|
if (candidate.kind === 'seed') {
|
|
612
612
|
return {
|
|
613
613
|
authority: 'claude-md',
|
|
614
|
-
reason: `${INSTRUCTIONS_REL} is authored first and the seed carries it to a target, so an edit starts there and reaches the seed through
|
|
614
|
+
reason: `${INSTRUCTIONS_REL} is authored first and the seed carries it to a target, so an edit starts there and reaches the seed through a hand merge`,
|
|
615
615
|
}
|
|
616
616
|
}
|
|
617
617
|
|
package/src/gov/stacks.ts
CHANGED
|
@@ -79,7 +79,7 @@ export function loadGovStack(
|
|
|
79
79
|
* shape rather than two the caller has to tell apart.
|
|
80
80
|
*
|
|
81
81
|
* The directory wins over a rule file of the same name. They cannot collide
|
|
82
|
-
* while `
|
|
82
|
+
* while `claude/skills/create-rule/references/rule.md` requires a numeric prefix on a rule slug, since a
|
|
83
83
|
* band folder carries none.
|
|
84
84
|
*/
|
|
85
85
|
export function expandStackEntry(root: string, entry: string): string[] {
|
package/src/hooks/post-merge.ts
CHANGED
|
@@ -163,7 +163,7 @@ function archiveLines(
|
|
|
163
163
|
}
|
|
164
164
|
return (
|
|
165
165
|
`\n📋 Task not archived for #${number}: ${text(fields, 'message') ?? reason}\n` +
|
|
166
|
-
|
|
166
|
+
`Run /task-complete archive #${number} to resolve it by hand.\n\n`
|
|
167
167
|
)
|
|
168
168
|
}
|
|
169
169
|
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/** What a label apply decided to do, before any write. */
|
|
2
|
+
export interface LabelDiff {
|
|
3
|
+
/** Earned labels the pull request lacks and the remote carries, so addable. */
|
|
4
|
+
readonly toAdd: readonly string[]
|
|
5
|
+
/** Every earned label the pull request lacks, whether or not it is addable. */
|
|
6
|
+
readonly owed: readonly string[]
|
|
7
|
+
/** Owed labels the remote does not carry, which are reported and never created. */
|
|
8
|
+
readonly missingOnRemote: readonly string[]
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Diffs what a branch earns against what its pull request already carries and
|
|
13
|
+
* what the remote can attach.
|
|
14
|
+
*
|
|
15
|
+
* The diff only adds. A label on the pull request that the map does not earn
|
|
16
|
+
* is a person's decision and never appears here, so nothing in the result can
|
|
17
|
+
* be turned into a removal. Order follows `earned`, which the map declares, so
|
|
18
|
+
* two runs over one branch produce one list.
|
|
19
|
+
*
|
|
20
|
+
* A label the remote lacks is separated from the addable set rather than
|
|
21
|
+
* dropped, because the REST add endpoint creates any label it is handed and
|
|
22
|
+
* that write to the repository settings is not the map's call.
|
|
23
|
+
*/
|
|
24
|
+
export function diffLabels(
|
|
25
|
+
earned: readonly string[],
|
|
26
|
+
present: readonly string[],
|
|
27
|
+
remote: readonly string[],
|
|
28
|
+
): LabelDiff {
|
|
29
|
+
const has = new Set(present)
|
|
30
|
+
const carried = new Set(remote)
|
|
31
|
+
|
|
32
|
+
const owed = earned.filter((label) => !has.has(label))
|
|
33
|
+
|
|
34
|
+
return {
|
|
35
|
+
owed,
|
|
36
|
+
toAdd: owed.filter((label) => carried.has(label)),
|
|
37
|
+
missingOnRemote: owed.filter((label) => !carried.has(label)),
|
|
38
|
+
}
|
|
39
|
+
}
|
package/src/labels/format.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Which rule in `
|
|
2
|
+
* Which rule in `claude/skills/git-pr/references/pr.md`'s `## Title` section a title breaks.
|
|
3
3
|
*
|
|
4
4
|
* `structure` stands alone rather than beside the other three, because a
|
|
5
5
|
* title failing the shape match has no parsed `<type>`, `<scope>`, or
|
|
@@ -28,9 +28,9 @@ const LEADING_LETTERS = /^[A-Za-z]+/
|
|
|
28
28
|
|
|
29
29
|
/**
|
|
30
30
|
* Grades a pull request title, or a commit subject sharing the same form,
|
|
31
|
-
* against `
|
|
31
|
+
* against `claude/skills/git-pr/references/pr.md`'s structure, casing, and length rules.
|
|
32
32
|
*
|
|
33
|
-
* Does not check `<type>` against `
|
|
33
|
+
* Does not check `<type>` against `claude/skills/git-commit/references/commit.md`'s fixed enum.
|
|
34
34
|
* `pr.md`'s own `## Title` section states format, casing, and length only,
|
|
35
35
|
* and names no type list of its own to check against.
|
|
36
36
|
*/
|
package/src/labels/phase.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { RECORD_ENTRIES, RECORD_ROOTS } from '@/roots/record'
|
|
|
3
3
|
import type { RecordRoot } from '@/roots/record'
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
|
-
* The two version namespaces `
|
|
6
|
+
* The two version namespaces `claude/skills/git-commit/references/versioning.md` keeps apart, and why a
|
|
7
7
|
* pull request cannot be sorted between them by pattern alone.
|
|
8
8
|
*
|
|
9
9
|
* A phase label (`v68.5`) and a semver reference (`v3.44`) both match
|
|
@@ -186,7 +186,7 @@ const RELEASE_TITLE_PREFIX = 'chore(main): release '
|
|
|
186
186
|
* phase label past this check. Together they name release-please's own act of
|
|
187
187
|
* opening the pull request, which nothing else on the remote can perform.
|
|
188
188
|
*/
|
|
189
|
-
function isReleasePullRequest(input: PhaseScanInput): boolean {
|
|
189
|
+
export function isReleasePullRequest(input: PhaseScanInput): boolean {
|
|
190
190
|
return (
|
|
191
191
|
input.headRefName.startsWith(RELEASE_HEAD_PREFIX) &&
|
|
192
192
|
input.title.startsWith(RELEASE_TITLE_PREFIX)
|
|
@@ -265,7 +265,7 @@ function sessionLinks(text: string): string[] {
|
|
|
265
265
|
* The split runs on the pull request rather than on each token. A release
|
|
266
266
|
* pull request's tokens are read as the semver references its generated body
|
|
267
267
|
* legitimately carries, and every other pull request's tokens are read as
|
|
268
|
-
* leaked phase labels, which is what `
|
|
268
|
+
* leaked phase labels, which is what `claude/skills/git-commit/references/versioning.md` names the
|
|
269
269
|
* defect this exists to catch.
|
|
270
270
|
*
|
|
271
271
|
* A release pull request reports no board reference either, and the ground is
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { linesOutsideFences } from '@/markdown/scan'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The closed list of section headings a pull request body may carry, in the
|
|
5
|
+
* sentence case `claude/skills/git-pr/references/pr.md` states.
|
|
6
|
+
*/
|
|
7
|
+
const ALLOWED_HEADINGS: readonly string[] = [
|
|
8
|
+
'## Summary',
|
|
9
|
+
'## Key changes',
|
|
10
|
+
'## Technical context',
|
|
11
|
+
'## Testing',
|
|
12
|
+
'## For the reviewer',
|
|
13
|
+
]
|
|
14
|
+
|
|
15
|
+
const REQUIRED_HEADINGS: readonly string[] = ['## Summary', '## Key changes']
|
|
16
|
+
|
|
17
|
+
const H2 = /^##\s/
|
|
18
|
+
|
|
19
|
+
export interface SectionsCheck {
|
|
20
|
+
/** Level-two headings the closed list does not hold, as written. */
|
|
21
|
+
readonly outside: readonly string[]
|
|
22
|
+
/** Required headings the body never carries. */
|
|
23
|
+
readonly missing: readonly string[]
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Grades the level-two headings of a pull request body against the closed list.
|
|
28
|
+
*
|
|
29
|
+
* The comparison is exact, so `## Key Changes` fails. `canon pr key-changes`
|
|
30
|
+
* reads its section case-insensitively, which keeps a body posted before the
|
|
31
|
+
* rename parsing while the scan holds new text to one spelling. Subheadings and
|
|
32
|
+
* fenced lines are not headings, so the list governs level two alone.
|
|
33
|
+
*/
|
|
34
|
+
export function checkSections(body: string): SectionsCheck {
|
|
35
|
+
const headings = linesOutsideFences(body)
|
|
36
|
+
.map((line) => line.trim())
|
|
37
|
+
.filter((line) => H2.test(line))
|
|
38
|
+
|
|
39
|
+
return {
|
|
40
|
+
outside: headings.filter((heading) => !ALLOWED_HEADINGS.includes(heading)),
|
|
41
|
+
missing: REQUIRED_HEADINGS.filter((heading) => !headings.includes(heading)),
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -6,7 +6,7 @@ const HEADING = /^#{1,6}\s/
|
|
|
6
6
|
* A section marker holding its line alone, which is the signpost a document
|
|
7
7
|
* uses where its own template asks for bold rather than a heading.
|
|
8
8
|
*
|
|
9
|
-
* `
|
|
9
|
+
* `claude/skills/plan-feature/references/plan.md` gives `## Summary` a heading and marks the four sections
|
|
10
10
|
* below it this way, so a conforming plan read as one run from its first line
|
|
11
11
|
* to its last and all seven live plans reported past the depth checkpoint, at
|
|
12
12
|
* 106 to 166 rendered lines. A measure firing on a whole corpus says nothing
|
|
@@ -659,7 +659,7 @@ function measureParagraph(block: readonly BodyLine[]): CadenceFinding {
|
|
|
659
659
|
*
|
|
660
660
|
* `compromise` reported 2 percent. It tags a fronted past participle as a
|
|
661
661
|
* finite past-tense verb, so all twelve of those sentences in
|
|
662
|
-
*
|
|
662
|
+
* the repository's architecture record at that commit read as carrying one, eleven opening `Measured at`
|
|
663
663
|
* and one `Overturned by`, which is the exact shape the measure exists to
|
|
664
664
|
* catch. It is not even consistent with itself there: `Measured at` tags a verb
|
|
665
665
|
* and `Measured against` tags an adjective.
|
|
@@ -346,9 +346,9 @@ function entriesOf(dir: string, isDirectory: boolean): string[] {
|
|
|
346
346
|
}
|
|
347
347
|
|
|
348
348
|
/**
|
|
349
|
-
* What `draft-and-pick` Step 6
|
|
350
|
-
*
|
|
351
|
-
*
|
|
349
|
+
* What `draft-and-pick` Step 6 writes into the folder it archives a choice to:
|
|
350
|
+
* a capture per canvas frame, named `arm-<id>`. A design handoff marks a pick
|
|
351
|
+
* folder an earlier skill wrote. A folder carrying neither is evidence.
|
|
352
352
|
*/
|
|
353
353
|
const PICK_FILE = /^(?:arm-[^.]+\..+|design-handoff\.md)$/
|
|
354
354
|
|
|
@@ -99,6 +99,25 @@ export const SKILL_NAME_MAP: Readonly<Record<string, string>> = {
|
|
|
99
99
|
'draft-diagram': 'draft-figure',
|
|
100
100
|
}
|
|
101
101
|
|
|
102
|
+
/**
|
|
103
|
+
* The skills that took a two-word name from a single word, which the map above
|
|
104
|
+
* may not carry as a bare key.
|
|
105
|
+
*
|
|
106
|
+
* `canvas` became `canvas-board`, and a bare `canvas` key would rewrite every
|
|
107
|
+
* unrelated use of the word: `canon canvas serve`, `src/canvas/`,
|
|
108
|
+
* `.canon/canvas/`, and the `internal-canvas` skill. So each row keys on a form
|
|
109
|
+
* only the skill spells, a plugin invocation or a skill folder path. The tail
|
|
110
|
+
* guard rejects a following `-`, so a rewritten `canon:canvas-board` is not
|
|
111
|
+
* matched again.
|
|
112
|
+
*
|
|
113
|
+
* What this leaves behind is a prose mention of the skill by its bare name,
|
|
114
|
+
* which has no token for a sweep to find and is fixed by hand.
|
|
115
|
+
*/
|
|
116
|
+
export const SKILL_CITATION_MAP: Readonly<Record<string, string>> = {
|
|
117
|
+
'canon:canvas': 'canon:canvas-board',
|
|
118
|
+
'skills/canvas': 'skills/canvas-board',
|
|
119
|
+
}
|
|
120
|
+
|
|
102
121
|
/**
|
|
103
122
|
* The skill rename.
|
|
104
123
|
*
|
|
@@ -132,7 +151,7 @@ export const SKILL_NAME_MAP: Readonly<Record<string, string>> = {
|
|
|
132
151
|
* listing every sweep reads never reaches them.
|
|
133
152
|
*/
|
|
134
153
|
export const SKILL_NAME_RULES: RenameRules = defineRenameRules({
|
|
135
|
-
replacements: SKILL_NAME_MAP,
|
|
154
|
+
replacements: { ...SKILL_NAME_MAP, ...SKILL_CITATION_MAP },
|
|
136
155
|
keepMarker: 'canon-keep-retired',
|
|
137
156
|
wholeToken: true,
|
|
138
157
|
excludedPrefixes: ['scripts/eval/result-'],
|