@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
package/src/commands/claude.ts
CHANGED
|
@@ -157,21 +157,17 @@ interface RoutingOptions {
|
|
|
157
157
|
readonly json?: boolean
|
|
158
158
|
}
|
|
159
159
|
|
|
160
|
-
const SEEDED_FILES: readonly string[] = [
|
|
161
|
-
|
|
162
|
-
'REQUIREMENTS.md',
|
|
163
|
-
'DESIGN.md',
|
|
164
|
-
]
|
|
165
|
-
const SEEDED_DIRS: readonly string[] = ['memory', 'tasks', 'wireframes']
|
|
160
|
+
const SEEDED_FILES: readonly string[] = ['REQUIREMENTS.md', 'DESIGN.md']
|
|
161
|
+
const SEEDED_DIRS: readonly string[] = ['tasks']
|
|
166
162
|
|
|
167
163
|
/**
|
|
168
164
|
* Where a `SEEDED_DIRS` entry resolves for the sync presence check.
|
|
169
165
|
*
|
|
170
|
-
*
|
|
171
|
-
*
|
|
172
|
-
* `.
|
|
173
|
-
*
|
|
174
|
-
*
|
|
166
|
+
* A tracked surface entry resolves under `canon/` ahead of `.claude/`, while
|
|
167
|
+
* `tasks` is a session record resolved under `.canon/` ahead of
|
|
168
|
+
* `.claude/`. Routing every name through `recordDir` would report a migrated
|
|
169
|
+
* target's surface folder as missing, since that resolver never checks
|
|
170
|
+
* `canon/`.
|
|
175
171
|
*/
|
|
176
172
|
export function seededDirPath(resolved: string, name: string): string {
|
|
177
173
|
return SURFACE_ENTRIES.includes(name)
|
|
@@ -390,7 +386,7 @@ export function register(program: Command): void {
|
|
|
390
386
|
skills
|
|
391
387
|
.command('audit')
|
|
392
388
|
.description(
|
|
393
|
-
'Report both skill corpora against the mechanical rules in
|
|
389
|
+
'Report both skill corpora against the mechanical rules in claude/skills/create-skill/references/skill.md',
|
|
394
390
|
)
|
|
395
391
|
.argument('[path]', 'Project root, defaulting to the current directory')
|
|
396
392
|
.helpOption('-h, --help', 'Show this help message')
|
|
@@ -615,9 +611,7 @@ async function runSync(target: string): Promise<number> {
|
|
|
615
611
|
|
|
616
612
|
// A record folder resolves at either root, so a migrated target is reported as
|
|
617
613
|
// seeded rather than sent to `canon claude init` to re-create records it
|
|
618
|
-
// already holds.
|
|
619
|
-
// through `surfaceDir`, since a migrated target holds it at `canon/` rather
|
|
620
|
-
// than under either record root.
|
|
614
|
+
// already holds.
|
|
621
615
|
logStep('Seeded')
|
|
622
616
|
for (const name of SEEDED_FILES) {
|
|
623
617
|
if (existsSync(join(resolved, '.claude', name))) logInfo(name)
|
package/src/commands/context.ts
CHANGED
|
@@ -18,18 +18,6 @@ import {
|
|
|
18
18
|
requiredSections,
|
|
19
19
|
type SectionFinding,
|
|
20
20
|
} from '@/context/audit'
|
|
21
|
-
import {
|
|
22
|
-
architectureRel,
|
|
23
|
-
type ArchitectureReport,
|
|
24
|
-
coveredCount,
|
|
25
|
-
isOverCount,
|
|
26
|
-
isOverLength,
|
|
27
|
-
isOverRisks,
|
|
28
|
-
measureArchitecture,
|
|
29
|
-
missingRevisit,
|
|
30
|
-
overWords,
|
|
31
|
-
testableCount,
|
|
32
|
-
} from '@/context/architecture'
|
|
33
21
|
import { auditCitations, type CitationReport } from '@/context/citations'
|
|
34
22
|
import {
|
|
35
23
|
CANONICAL_DOC_TYPES,
|
|
@@ -65,10 +53,6 @@ import {
|
|
|
65
53
|
type RequirementsReport,
|
|
66
54
|
} from '@/context/requirements'
|
|
67
55
|
import { auditIndexes, type FolderDrift } from '@/context/index-drift'
|
|
68
|
-
import {
|
|
69
|
-
measureWireframeFolder,
|
|
70
|
-
type WireframeStatesReport,
|
|
71
|
-
} from '@/context/wireframe-states'
|
|
72
56
|
import { RENDER_WIDTH } from '@/markdown/structure'
|
|
73
57
|
import {
|
|
74
58
|
frameError,
|
|
@@ -104,7 +88,7 @@ export function register(program: Command): void {
|
|
|
104
88
|
context
|
|
105
89
|
.command('audit')
|
|
106
90
|
.description(
|
|
107
|
-
'Report required sections, entry length, citations, reference form, catalog tables, provenance, index drift,
|
|
91
|
+
'Report required sections, entry length, citations, reference form, catalog tables, provenance, index drift, and the requirements record against its own word cap',
|
|
108
92
|
)
|
|
109
93
|
.argument('[path]', 'Project root, defaulting to the current directory')
|
|
110
94
|
.helpOption('-h, --help', 'Show this help message')
|
|
@@ -127,21 +111,14 @@ export function register(program: Command): void {
|
|
|
127
111
|
' 1 refused, with the reason on stderr',
|
|
128
112
|
' 2 a gating finding is present',
|
|
129
113
|
'',
|
|
130
|
-
'An unresolved citation always gates.
|
|
131
|
-
'
|
|
132
|
-
'
|
|
133
|
-
'
|
|
134
|
-
'
|
|
135
|
-
'
|
|
136
|
-
'
|
|
137
|
-
'
|
|
138
|
-
'gates past it. A record stating none of these is reported and',
|
|
139
|
-
'never gated. --gate widens the gate to the other two',
|
|
140
|
-
'findings that are facts rather than judgments: a missing required',
|
|
141
|
-
'section and index drift. A context entry requires Overview and',
|
|
142
|
-
'Layout, and a wireframe requires Regions, States, Copy, and Not on',
|
|
143
|
-
'this surface. Entry length, reference form, table, provenance, and the',
|
|
144
|
-
'record claim classification are judgments under both.',
|
|
114
|
+
'An unresolved citation always gates. A requirements record',
|
|
115
|
+
'stating a word cap gates past it, on any run except',
|
|
116
|
+
'--citations-only, which never measures it. A record stating no',
|
|
117
|
+
'cap is reported and never gated. --gate widens the gate to the',
|
|
118
|
+
'other two findings that are facts rather than judgments: a',
|
|
119
|
+
'missing required section and index drift. A context entry',
|
|
120
|
+
'requires Overview and Layout. Entry length, reference form,',
|
|
121
|
+
'table, and provenance are judgments under both.',
|
|
145
122
|
'',
|
|
146
123
|
'Depth and bullet weight are stated over every markdown file rather',
|
|
147
124
|
'than over a context entry, so `canon markdown audit` measures them.',
|
|
@@ -177,7 +154,7 @@ export function register(program: Command): void {
|
|
|
177
154
|
.option('--base <ref>', 'Far side of the range, defaulting to the trunk')
|
|
178
155
|
.option(
|
|
179
156
|
'--doc-types <list>',
|
|
180
|
-
`Comma-separated canonical doc types (default: all
|
|
157
|
+
`Comma-separated canonical doc types (default: all three: ${CANONICAL_DOC_TYPES.join(', ')})`,
|
|
181
158
|
)
|
|
182
159
|
.option(
|
|
183
160
|
'--backend <name>',
|
|
@@ -201,7 +178,7 @@ export function register(program: Command): void {
|
|
|
201
178
|
'Examples:',
|
|
202
179
|
' canon context classify diff',
|
|
203
180
|
' canon context classify diff --base origin/main --json',
|
|
204
|
-
' canon context classify diff --doc-types context
|
|
181
|
+
' canon context classify diff --doc-types context',
|
|
205
182
|
'',
|
|
206
183
|
].join('\n'),
|
|
207
184
|
)
|
|
@@ -212,13 +189,13 @@ export function register(program: Command): void {
|
|
|
212
189
|
classify
|
|
213
190
|
.command('sweep')
|
|
214
191
|
.description(
|
|
215
|
-
'Classify every section of the
|
|
192
|
+
'Classify every section of the three canonical doc types, split at H3',
|
|
216
193
|
)
|
|
217
194
|
.argument('[path]', 'Project root, defaulting to the current directory')
|
|
218
195
|
.helpOption('-h, --help', 'Show this help message')
|
|
219
196
|
.option(
|
|
220
197
|
'--doc-types <list>',
|
|
221
|
-
`Comma-separated canonical doc types (default: all
|
|
198
|
+
`Comma-separated canonical doc types (default: all three: ${CANONICAL_DOC_TYPES.join(', ')})`,
|
|
222
199
|
)
|
|
223
200
|
.option(
|
|
224
201
|
'--backend <name>',
|
|
@@ -612,7 +589,7 @@ async function runAudit(
|
|
|
612
589
|
return refuse('bad-folder-list', names, gateOnly, root, opts.json ?? false)
|
|
613
590
|
}
|
|
614
591
|
|
|
615
|
-
// The root base is opt-in. A target carrying a root
|
|
592
|
+
// The root base is opt-in. A target carrying a root folder of its own would
|
|
616
593
|
// otherwise be audited against a standard it never adopted, on a bare run
|
|
617
594
|
// that named nothing.
|
|
618
595
|
const named = opts.folder !== undefined
|
|
@@ -667,17 +644,7 @@ async function runAudit(
|
|
|
667
644
|
// Absent under `--citations-only` and null when the project carries no
|
|
668
645
|
// record. A run that never looked and a project with nothing to look at are
|
|
669
646
|
// different answers, and one value for both reports the second as the first.
|
|
670
|
-
const record = gateOnly ? undefined : await measureArchitecture(root)
|
|
671
647
|
const requirements = gateOnly ? undefined : await measureRequirements(root)
|
|
672
|
-
const wireframes = gateOnly
|
|
673
|
-
? []
|
|
674
|
-
: (
|
|
675
|
-
await Promise.all(
|
|
676
|
-
folders
|
|
677
|
-
.filter((folder) => folder.name === 'wireframes')
|
|
678
|
-
.map((folder) => measureWireframeFolder(root, folder)),
|
|
679
|
-
)
|
|
680
|
-
).flat()
|
|
681
648
|
|
|
682
649
|
if (gateOnly) {
|
|
683
650
|
reportGate(citations)
|
|
@@ -691,9 +658,7 @@ async function runAudit(
|
|
|
691
658
|
reportTables(entries)
|
|
692
659
|
reportProvenance(entries, folders)
|
|
693
660
|
reportDrift(drift)
|
|
694
|
-
reportRecord(record, root)
|
|
695
661
|
reportRequirements(requirements, root)
|
|
696
|
-
reportWireframeStates(wireframes)
|
|
697
662
|
outro()
|
|
698
663
|
}
|
|
699
664
|
|
|
@@ -730,22 +695,15 @@ async function runAudit(
|
|
|
730
695
|
// Null says the run opened the project and found no record, which a
|
|
731
696
|
// target that never wrote one is entitled to. Absent says the run
|
|
732
697
|
// never looked, which is `--citations-only`.
|
|
733
|
-
architecture: gateOnly ? undefined : (record ?? null),
|
|
734
|
-
// The same three states for the requirements record.
|
|
735
698
|
requirements: gateOnly ? undefined : (requirements ?? null),
|
|
736
|
-
// Absent under `--citations-only`, for the same reason as above. An
|
|
737
|
-
// empty array under the ordinary run says the project carries no
|
|
738
|
-
// wireframes folder or no entry carrying a States table, which is a
|
|
739
|
-
// fact rather than an unmeasured run.
|
|
740
|
-
wireframes: gateOnly ? undefined : wireframes,
|
|
741
699
|
checkpoints: {
|
|
742
700
|
lines: LENGTH_CHECKPOINT,
|
|
743
701
|
renderWidth: RENDER_WIDTH,
|
|
744
702
|
provenanceFolder: PROVENANCE_FOLDER,
|
|
745
703
|
requiredSections: REQUIRED_SECTIONS,
|
|
746
704
|
// Keyed on the audited folder name. The flat key above stays for a
|
|
747
|
-
// caller that read it
|
|
748
|
-
//
|
|
705
|
+
// caller that read it first, since removing it would break that
|
|
706
|
+
// caller without an error.
|
|
749
707
|
requiredSectionsByFolder: REQUIRED_SECTIONS_BY_FOLDER,
|
|
750
708
|
},
|
|
751
709
|
})}\n`,
|
|
@@ -754,17 +712,10 @@ async function runAudit(
|
|
|
754
712
|
|
|
755
713
|
const gating = isGating({
|
|
756
714
|
unresolvedCitations: citations.unresolved.length,
|
|
757
|
-
recordOverLength: record !== undefined && isOverLength(record),
|
|
758
|
-
recordOverCount: record !== undefined && isOverCount(record),
|
|
759
|
-
recordMissingRevisit:
|
|
760
|
-
record !== undefined && missingRevisit(record).length > 0,
|
|
761
|
-
recordOverWords: record !== undefined && overWords(record).length > 0,
|
|
762
|
-
recordOverRisks: record !== undefined && isOverRisks(record),
|
|
763
715
|
requirementsOverWords:
|
|
764
716
|
requirements !== undefined && isOverWordCap(requirements),
|
|
765
717
|
sections,
|
|
766
718
|
drift,
|
|
767
|
-
wireframes,
|
|
768
719
|
widened,
|
|
769
720
|
})
|
|
770
721
|
|
|
@@ -945,8 +896,7 @@ function reportReferenceForm(
|
|
|
945
896
|
|
|
946
897
|
/**
|
|
947
898
|
* Names the path each finding belongs to, which is an entry in the folder named
|
|
948
|
-
* under `.claude/`, the folder itself in a domain split across one
|
|
949
|
-
* file in any wireframe folder. States
|
|
899
|
+
* under `.claude/`, and the folder itself in a domain split across one. States
|
|
950
900
|
* the reach on every run for the reason the provenance report does.
|
|
951
901
|
*
|
|
952
902
|
* This prints ahead of the four readability measures because a missing section
|
|
@@ -983,7 +933,7 @@ function reportSections(
|
|
|
983
933
|
)
|
|
984
934
|
}
|
|
985
935
|
logInfo(
|
|
986
|
-
'A heading at any level counts. Each entry answers for itself, except in a context domain split across a folder, where a sibling answers for the rest.
|
|
936
|
+
'A heading at any level counts. Each entry answers for itself, except in a context domain split across a folder, where a sibling answers for the rest.',
|
|
987
937
|
)
|
|
988
938
|
|
|
989
939
|
if (missing.length === 0) {
|
|
@@ -1136,178 +1086,6 @@ function reportProvenance(
|
|
|
1136
1086
|
)
|
|
1137
1087
|
}
|
|
1138
1088
|
|
|
1139
|
-
/** How each classification reads in the report. */
|
|
1140
|
-
const CLAIM_LABEL: Record<string, string> = {
|
|
1141
|
-
countable: 'countable claim',
|
|
1142
|
-
invariant: 'structural invariant',
|
|
1143
|
-
neither: 'reasoning only',
|
|
1144
|
-
}
|
|
1145
|
-
|
|
1146
|
-
/**
|
|
1147
|
-
* Reports the architecture record against the ceiling it states for itself and
|
|
1148
|
-
* against what a machine could test in it.
|
|
1149
|
-
*
|
|
1150
|
-
* The length reading is a fact and gates. Everything below it names candidates
|
|
1151
|
-
* a reader adjudicates, because deciding whether a sentence states a claim is a
|
|
1152
|
-
* judgment no parser settles, and a stored verdict would age the way the
|
|
1153
|
-
* anchors it sits beside already do. Nothing is stored: every run reclassifies,
|
|
1154
|
-
* so an entry rewritten tomorrow is read as it stands then.
|
|
1155
|
-
*/
|
|
1156
|
-
function reportRecord(
|
|
1157
|
-
report: ArchitectureReport | undefined,
|
|
1158
|
-
root: string,
|
|
1159
|
-
): void {
|
|
1160
|
-
logStep('Architecture record')
|
|
1161
|
-
|
|
1162
|
-
if (report === undefined) {
|
|
1163
|
-
logInfo(
|
|
1164
|
-
`Out of scope. The project carries no ${architectureRel(root)}, so there was no record to measure.`,
|
|
1165
|
-
)
|
|
1166
|
-
return
|
|
1167
|
-
}
|
|
1168
|
-
|
|
1169
|
-
const decisions = report.decisions.length
|
|
1170
|
-
const { allowances } = report
|
|
1171
|
-
|
|
1172
|
-
logInfo(
|
|
1173
|
-
`${plural(report.words, 'word')} across ${plural(report.lines, 'line')}. The whole file's count never gates.`,
|
|
1174
|
-
)
|
|
1175
|
-
if (report.risksWords !== undefined) {
|
|
1176
|
-
logInfo(
|
|
1177
|
-
`\`## Risks / open questions\` holds ${plural(report.risksWords, 'word')}.`,
|
|
1178
|
-
)
|
|
1179
|
-
}
|
|
1180
|
-
|
|
1181
|
-
const longDecisions = overWords(report)
|
|
1182
|
-
if (report.wordCap === undefined) {
|
|
1183
|
-
logInfo(
|
|
1184
|
-
'No word cap a decision stated, so each decision word count is reported and never gated.',
|
|
1185
|
-
)
|
|
1186
|
-
} else if (longDecisions.length > 0) {
|
|
1187
|
-
for (const entry of longDecisions) {
|
|
1188
|
-
logError(
|
|
1189
|
-
`"${entry.heading}" holds ${entry.words} words against a cap of ${report.wordCap} a decision.`,
|
|
1190
|
-
)
|
|
1191
|
-
}
|
|
1192
|
-
} else {
|
|
1193
|
-
logInfo(
|
|
1194
|
-
`Every decision fits the cap of ${report.wordCap} words a decision.`,
|
|
1195
|
-
)
|
|
1196
|
-
}
|
|
1197
|
-
|
|
1198
|
-
if (report.riskCap === undefined) {
|
|
1199
|
-
logInfo('No risk bullet cap stated, so the Risks section is never gated.')
|
|
1200
|
-
} else if (report.risksBullets === undefined) {
|
|
1201
|
-
logWarn(
|
|
1202
|
-
`The record states a cap of ${report.riskCap} risk bullets and carries no \`## Risks / open questions\` section to count.`,
|
|
1203
|
-
)
|
|
1204
|
-
} else if (isOverRisks(report)) {
|
|
1205
|
-
logError(
|
|
1206
|
-
`${plural(report.risksBullets, 'risk bullet')} against a cap of ${report.riskCap}, nested bullets counted.`,
|
|
1207
|
-
)
|
|
1208
|
-
} else {
|
|
1209
|
-
logInfo(
|
|
1210
|
-
`${plural(report.risksBullets, 'risk bullet')} against a cap of ${report.riskCap}, nested bullets counted.`,
|
|
1211
|
-
)
|
|
1212
|
-
}
|
|
1213
|
-
|
|
1214
|
-
if (allowances === undefined) {
|
|
1215
|
-
logInfo(
|
|
1216
|
-
`Covers ${report.rel} alone. No standard sets a length rule for it and this record states none, so its ${plural(report.lines, 'line')} across ${plural(decisions, 'decision')} are reported and nothing is gated.`,
|
|
1217
|
-
)
|
|
1218
|
-
logInfo(
|
|
1219
|
-
'A record declaring an allowance for its frame and one a decision is measured against the ceiling those two derive. That rule belongs to whichever record writes it, never to the toolkit.',
|
|
1220
|
-
)
|
|
1221
|
-
} else {
|
|
1222
|
-
logInfo(
|
|
1223
|
-
`Covers ${report.rel} alone, which states its own allowance of ${plural(allowances.frame, 'line')} for the frame and ${allowances.perDecision} a decision.`,
|
|
1224
|
-
)
|
|
1225
|
-
if (isOverLength(report)) {
|
|
1226
|
-
logError(
|
|
1227
|
-
`${report.lines} lines against a ceiling of ${report.ceiling} from ${plural(decisions, 'decision')}`,
|
|
1228
|
-
)
|
|
1229
|
-
} else {
|
|
1230
|
-
logInfo(
|
|
1231
|
-
`${report.lines} lines against a ceiling of ${report.ceiling} from ${plural(decisions, 'decision')}.`,
|
|
1232
|
-
)
|
|
1233
|
-
}
|
|
1234
|
-
logInfo(
|
|
1235
|
-
`The ceiling rises with the decision count, so adding a decision buys ${allowances.perDecision} lines and the check passes exactly when the file grew.`,
|
|
1236
|
-
)
|
|
1237
|
-
}
|
|
1238
|
-
|
|
1239
|
-
if (report.entryCap === undefined) {
|
|
1240
|
-
logInfo(
|
|
1241
|
-
`${plural(decisions, 'decision')} and no entry cap stated, so the count is reported and never gated.`,
|
|
1242
|
-
)
|
|
1243
|
-
} else if (isOverCount(report)) {
|
|
1244
|
-
logError(
|
|
1245
|
-
`${plural(decisions, 'decision')} against a cap of ${report.entryCap}. Merge two or retire one, never compress.`,
|
|
1246
|
-
)
|
|
1247
|
-
} else {
|
|
1248
|
-
logInfo(
|
|
1249
|
-
`${plural(decisions, 'decision')} against a cap of ${report.entryCap}.`,
|
|
1250
|
-
)
|
|
1251
|
-
}
|
|
1252
|
-
|
|
1253
|
-
const revisited = report.decisions.filter((entry) => entry.revisit).length
|
|
1254
|
-
const lackingRevisit = missingRevisit(report)
|
|
1255
|
-
if (!report.revisitRequired) {
|
|
1256
|
-
logInfo(
|
|
1257
|
-
`${revisited} of ${plural(decisions, 'decision')} close with a revisit sentence, and the record states no revisit clause, so this is reported and never gated.`,
|
|
1258
|
-
)
|
|
1259
|
-
} else if (lackingRevisit.length > 0) {
|
|
1260
|
-
for (const heading of lackingRevisit) {
|
|
1261
|
-
logError(
|
|
1262
|
-
`"${heading}" carries no sentence opening "Revisit when", which the record requires of every decision.`,
|
|
1263
|
-
)
|
|
1264
|
-
}
|
|
1265
|
-
} else {
|
|
1266
|
-
logInfo(
|
|
1267
|
-
`Every one of ${plural(decisions, 'decision')} closes with the revisit sentence the record requires.`,
|
|
1268
|
-
)
|
|
1269
|
-
}
|
|
1270
|
-
|
|
1271
|
-
if (decisions === 0) {
|
|
1272
|
-
logWarn('The record declares no decision, so nothing was classified.')
|
|
1273
|
-
return
|
|
1274
|
-
}
|
|
1275
|
-
|
|
1276
|
-
const testable = testableCount(report)
|
|
1277
|
-
const covered = coveredCount(report)
|
|
1278
|
-
|
|
1279
|
-
logInfo(
|
|
1280
|
-
'A countable claim carries a figure a run could recompute and an invariant quantifies over a named tree a walk could falsify. Both are candidates a reader settles, and neither gates.',
|
|
1281
|
-
)
|
|
1282
|
-
logInfo(
|
|
1283
|
-
'A figure spelled in words reads as uncounted, since a cardinal in prose is pronominal more often than measured. Entries are counted by heading, so a heading carrying several decisions counts once and the total reads low by however many it holds.',
|
|
1284
|
-
)
|
|
1285
|
-
const line = `${testable} of ${decisions} carry a claim a machine could test, ${covered} of which name a check that exists`
|
|
1286
|
-
// A record whose every testable claim names a check has nothing to act on,
|
|
1287
|
-
// and so does one carrying no testable claim at all. Warning on both is how
|
|
1288
|
-
// a section becomes one nobody reads after the second run.
|
|
1289
|
-
if (testable > covered) logWarn(line)
|
|
1290
|
-
else logInfo(`${line}.`)
|
|
1291
|
-
logInfo(
|
|
1292
|
-
'Coverage reads the entry rather than the tree, so a claim some check happens to cover without the entry naming it reads as unchecked.',
|
|
1293
|
-
)
|
|
1294
|
-
|
|
1295
|
-
pipeOutput(
|
|
1296
|
-
report.decisions
|
|
1297
|
-
.map((entry) => {
|
|
1298
|
-
const kind = CLAIM_LABEL[entry.claim] ?? entry.claim
|
|
1299
|
-
const evidence =
|
|
1300
|
-
entry.figures.length > 0 ? ` ${entry.figures.join(' ')}` : ''
|
|
1301
|
-
const checks =
|
|
1302
|
-
entry.checks.length > 0
|
|
1303
|
-
? `\n checked by ${entry.checks.join(', ')}`
|
|
1304
|
-
: ''
|
|
1305
|
-
return `${report.rel}:${entry.line} ${kind}${evidence} ${plural(entry.words, 'word')}\n ${entry.heading}${checks}`
|
|
1306
|
-
})
|
|
1307
|
-
.join('\n'),
|
|
1308
|
-
)
|
|
1309
|
-
}
|
|
1310
|
-
|
|
1311
1089
|
/** Reports the requirements record against the word cap it states, if any. */
|
|
1312
1090
|
function reportRequirements(
|
|
1313
1091
|
report: RequirementsReport | undefined,
|
|
@@ -1353,43 +1131,3 @@ function reportDrift(drift: readonly FolderDrift[]): void {
|
|
|
1353
1131
|
logWarn(plural(lines.length, 'disagreement'))
|
|
1354
1132
|
pipeOutput(lines.join('\n'))
|
|
1355
1133
|
}
|
|
1356
|
-
|
|
1357
|
-
function reportWireframeStates(
|
|
1358
|
-
wireframes: readonly WireframeStatesReport[],
|
|
1359
|
-
): void {
|
|
1360
|
-
logStep('Wireframe states')
|
|
1361
|
-
|
|
1362
|
-
const withRows = wireframes.filter((entry) => entry.rows.length > 0)
|
|
1363
|
-
if (withRows.length === 0) {
|
|
1364
|
-
logInfo(
|
|
1365
|
-
'No wireframe carries a States table, so nothing was checked against its evidence folders.',
|
|
1366
|
-
)
|
|
1367
|
-
return
|
|
1368
|
-
}
|
|
1369
|
-
|
|
1370
|
-
const lines = withRows.flatMap((entry) => [
|
|
1371
|
-
...entry.missingFolders.map(
|
|
1372
|
-
(finding) =>
|
|
1373
|
-
`${entry.rel}:${finding.line} ${finding.state} no folder at ${finding.path}`,
|
|
1374
|
-
),
|
|
1375
|
-
...entry.unlistedFolders.map(
|
|
1376
|
-
(finding) =>
|
|
1377
|
-
`${entry.rel} ${finding.root}/${finding.folder} named in no row`,
|
|
1378
|
-
),
|
|
1379
|
-
...(entry.sketchWithEvidence
|
|
1380
|
-
? [
|
|
1381
|
-
`${entry.rel}:${entry.sketchLine} a plaintext sketch sits beside evidence that already exists`,
|
|
1382
|
-
]
|
|
1383
|
-
: []),
|
|
1384
|
-
])
|
|
1385
|
-
|
|
1386
|
-
if (lines.length === 0) {
|
|
1387
|
-
logInfo(
|
|
1388
|
-
`${plural(withRows.length, 'wireframe')} checked, every state matched one-to-one with its evidence folder.`,
|
|
1389
|
-
)
|
|
1390
|
-
return
|
|
1391
|
-
}
|
|
1392
|
-
|
|
1393
|
-
logWarn(plural(lines.length, 'finding'))
|
|
1394
|
-
pipeOutput(lines.join('\n'))
|
|
1395
|
-
}
|
package/src/commands/feedback.ts
CHANGED
|
@@ -1,18 +1,13 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { join } from 'node:path'
|
|
3
|
-
import type { Command } from 'commander'
|
|
1
|
+
import { Option, type Command } from 'commander'
|
|
4
2
|
import {
|
|
5
3
|
deriveDomainLabels,
|
|
6
|
-
deriveSlug,
|
|
7
4
|
deriveTitle,
|
|
8
5
|
missingField,
|
|
9
6
|
missingFieldMessage,
|
|
10
7
|
} from '@/feedback/body'
|
|
11
|
-
import { checkoutMismatchWarning, PROJECT_ROOT } from '@/roots/project'
|
|
12
|
-
import { creationRel } from '@/roots/record'
|
|
13
8
|
import { createGithubIssue } from '@/feedback/github'
|
|
14
9
|
import { issueFailureMessage } from '@/feedback/github-format'
|
|
15
|
-
import { frameError, frameSuccess
|
|
10
|
+
import { frameError, frameSuccess } from '@/cli/ui'
|
|
16
11
|
|
|
17
12
|
function readStdin(): Promise<string> {
|
|
18
13
|
return new Promise((resolveStream, rejectStream) => {
|
|
@@ -25,62 +20,17 @@ function readStdin(): Promise<string> {
|
|
|
25
20
|
})
|
|
26
21
|
}
|
|
27
22
|
|
|
28
|
-
function timestamp(): string {
|
|
29
|
-
const d = new Date()
|
|
30
|
-
const pad = (n: number): string => n.toString().padStart(2, '0')
|
|
31
|
-
return `${d.getFullYear()}${pad(d.getMonth() + 1)}${pad(d.getDate())}-${pad(d.getHours())}${pad(d.getMinutes())}${pad(d.getSeconds())}`
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* A registry install ships no `.claude/`, so a local write would land inside
|
|
36
|
-
* `node_modules/` and report a project-relative path the operator cannot find.
|
|
37
|
-
* The toolkit source is the only root where local scratch reaches a maintainer.
|
|
38
|
-
*/
|
|
39
|
-
function isToolkitSource(): boolean {
|
|
40
|
-
return existsSync(join(PROJECT_ROOT, '.claude'))
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* One producer, one record folder. Feedback is not a review, so it writes
|
|
45
|
-
* under a root folder of its own rather than inside `review/`, and `canon
|
|
46
|
-
* records push` backs it with no list edit, since it carries every `.canon/`
|
|
47
|
-
* entry it does not exclude.
|
|
48
|
-
*/
|
|
49
|
-
function writeLocal(body: string, mismatch: string | undefined): string {
|
|
50
|
-
// Resolved against the same root the write joins onto. `creationRel` reads
|
|
51
|
-
// whichever root already carries a `feedback/` folder and falls back to the
|
|
52
|
-
// creation root when neither does.
|
|
53
|
-
const relativeDir = creationRel(PROJECT_ROOT, 'feedback')
|
|
54
|
-
const feedbackDir = join(PROJECT_ROOT, relativeDir)
|
|
55
|
-
mkdirSync(feedbackDir, { recursive: true })
|
|
56
|
-
const filename = `feedback-${deriveSlug(body)}-${timestamp()}.md`
|
|
57
|
-
const filePath = join(feedbackDir, filename)
|
|
58
|
-
writeFileSync(filePath, `${body}\n`, 'utf8')
|
|
59
|
-
|
|
60
|
-
// Manual frame rather than `frameSuccess`, since the mismatch warning is a
|
|
61
|
-
// frame-interior line landing between the opener and the command title,
|
|
62
|
-
// matching the convention `#1587` set at its other six sites.
|
|
63
|
-
const { GREEN, GREY, NC, WHITE } = palette(process.stderr)
|
|
64
|
-
process.stderr.write(`${GREY}┌${NC}\n`)
|
|
65
|
-
if (mismatch !== undefined) logWarn(mismatch)
|
|
66
|
-
process.stderr.write(
|
|
67
|
-
`${GREY}│${NC} ${WHITE}canon feedback${NC}\n${GREY}│${NC}\n${GREY}│${NC} ${GREEN}✓${NC} ${join(relativeDir, filename)}\n${GREY}└${NC}\n`,
|
|
68
|
-
)
|
|
69
|
-
return filePath
|
|
70
|
-
}
|
|
71
|
-
|
|
72
23
|
export function register(program: Command): void {
|
|
73
24
|
program
|
|
74
25
|
.command('feedback')
|
|
75
26
|
.helpOption('-h, --help', 'Show this help message')
|
|
76
27
|
.description(
|
|
77
|
-
'
|
|
78
|
-
)
|
|
79
|
-
.option(
|
|
80
|
-
'--github',
|
|
81
|
-
'Open a GitHub issue on the toolkit repo instead of writing local scratch',
|
|
28
|
+
'Open a GitHub issue on the toolkit repo from a feedback block on stdin',
|
|
82
29
|
)
|
|
83
|
-
|
|
30
|
+
// A cached plugin still pipes `--github`, and commander rejects an unknown
|
|
31
|
+
// option, so the flag stays accepted and hidden for one release.
|
|
32
|
+
.addOption(new Option('--github').hideHelp())
|
|
33
|
+
.action(async () => {
|
|
84
34
|
if (process.stdin.isTTY) {
|
|
85
35
|
frameError(
|
|
86
36
|
'No feedback on stdin. Pipe a markdown block: pbpaste | canon feedback',
|
|
@@ -95,8 +45,8 @@ export function register(program: Command): void {
|
|
|
95
45
|
return
|
|
96
46
|
}
|
|
97
47
|
|
|
98
|
-
//
|
|
99
|
-
//
|
|
48
|
+
// A report missing its surface is no more useful in the tracker than
|
|
49
|
+
// anywhere else, so validation runs before any `gh` call.
|
|
100
50
|
const absent = missingField(body)
|
|
101
51
|
if (absent) {
|
|
102
52
|
frameError(missingFieldMessage(absent))
|
|
@@ -104,39 +54,20 @@ export function register(program: Command): void {
|
|
|
104
54
|
return
|
|
105
55
|
}
|
|
106
56
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
process.stdout.write(`${result.url}\n`)
|
|
116
|
-
return
|
|
117
|
-
}
|
|
118
|
-
const reason = issueFailureMessage(result)
|
|
119
|
-
if (!isToolkitSource()) {
|
|
120
|
-
frameError(reason)
|
|
121
|
-
process.exitCode = 1
|
|
122
|
-
return
|
|
123
|
-
}
|
|
124
|
-
const { NC, YELLOW } = palette(process.stderr)
|
|
125
|
-
process.stderr.write(
|
|
126
|
-
`${YELLOW}! ${reason} Wrote local scratch instead.${NC}\n`,
|
|
127
|
-
)
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
if (!isToolkitSource()) {
|
|
131
|
-
frameError(
|
|
132
|
-
'Local scratch needs the toolkit source. Re-run with --github to open an issue instead.',
|
|
133
|
-
)
|
|
134
|
-
process.exitCode = 1
|
|
57
|
+
const result = await createGithubIssue({
|
|
58
|
+
title: deriveTitle(body),
|
|
59
|
+
body,
|
|
60
|
+
labels: ['feedback', ...deriveDomainLabels(body)],
|
|
61
|
+
})
|
|
62
|
+
if (result.ok) {
|
|
63
|
+
frameSuccess('canon feedback', result.url)
|
|
64
|
+
process.stdout.write(`${result.url}\n`)
|
|
135
65
|
return
|
|
136
66
|
}
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
process.stdout.write(`${
|
|
67
|
+
// The block goes to stdout so the session can paste it where the issue
|
|
68
|
+
// would have gone, and the reason frames on stderr.
|
|
69
|
+
frameError(issueFailureMessage(result))
|
|
70
|
+
process.stdout.write(`${body}\n`)
|
|
71
|
+
process.exitCode = 1
|
|
141
72
|
})
|
|
142
73
|
}
|
package/src/commands/gov.ts
CHANGED
|
@@ -12,7 +12,6 @@ import { checkoutMismatchWarning, PROJECT_ROOT } from '@/roots/project'
|
|
|
12
12
|
import { creationRel, SCRATCH } from '@/roots/record'
|
|
13
13
|
import { createGovAdapter } from '@/gov/adapter'
|
|
14
14
|
import { regenConsumedRules } from '@/gov/consumed'
|
|
15
|
-
import { regenStandardRules } from '@/gov/standard-rules'
|
|
16
15
|
import { installRules, lookupRules } from '@/gov/install'
|
|
17
16
|
import { buildGovCatalog, describeRule, describeStack } from '@/gov/list'
|
|
18
17
|
import { buildRulesPayload, listRuleFiles } from '@/gov/payload'
|
|
@@ -191,18 +190,14 @@ export function register(program: Command): void {
|
|
|
191
190
|
|
|
192
191
|
gov
|
|
193
192
|
.command('regen')
|
|
194
|
-
.description(
|
|
195
|
-
"Rebuild the standard-pointer rules and a repository's own .claude/rules/",
|
|
196
|
-
)
|
|
193
|
+
.description("Rebuild a repository's own .claude/rules/")
|
|
197
194
|
.helpOption('-h, --help', 'Show this help message')
|
|
198
195
|
.option('--root <path>', 'Repository root to regenerate', PROJECT_ROOT)
|
|
199
196
|
.addHelpText(
|
|
200
197
|
'after',
|
|
201
198
|
[
|
|
202
199
|
'',
|
|
203
|
-
'
|
|
204
|
-
'fields in each standard under standards/. Then reads',
|
|
205
|
-
'internal/governance.toml and installs the stack it names, plus any',
|
|
200
|
+
'Reads internal/governance.toml and installs the stack it names, plus any',
|
|
206
201
|
'rules under internal/rules/. Unlike install and sync, this runs',
|
|
207
202
|
'against the toolkit root, whose .claude/rules/ is produced output.',
|
|
208
203
|
'',
|
|
@@ -1121,14 +1116,6 @@ async function runRegen(
|
|
|
1121
1116
|
|
|
1122
1117
|
const root = resolve(opts.root ?? PROJECT_ROOT)
|
|
1123
1118
|
|
|
1124
|
-
// The consumed copy installs from `governance/rules/`, so the band this
|
|
1125
|
-
// writes has to be fresh before that copy is built from it.
|
|
1126
|
-
const generated = await regenStandardRules(root)
|
|
1127
|
-
if (!generated.ok) {
|
|
1128
|
-
process.stderr.write(`Standard-rules regen failed: ${generated.reason}\n`)
|
|
1129
|
-
return 1
|
|
1130
|
-
}
|
|
1131
|
-
|
|
1132
1119
|
const result = await regenConsumedRules(root)
|
|
1133
1120
|
|
|
1134
1121
|
if (!result.ok) {
|