@erclx/canon 5.31.0 → 5.32.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/backlog-triage/SKILL.md +1 -1
- package/claude/skills/canon-cli/REQUIREMENT.md +4 -6
- package/claude/skills/canon-cli/SKILL.md +2 -2
- package/claude/skills/canon-feedback/REQUIREMENT.md +1 -1
- package/claude/skills/canon-feedback/SKILL.md +10 -13
- package/claude/skills/canon-feedback-triage/REQUIREMENT.md +13 -14
- package/claude/skills/canon-feedback-triage/SKILL.md +49 -30
- package/claude/skills/canvas/REQUIREMENT.md +3 -4
- package/claude/skills/canvas/SKILL.md +5 -5
- package/{standards → claude/skills/canvas/references}/canvas.md +12 -1
- package/claude/skills/ci-workflow/REQUIREMENT.md +0 -1
- package/claude/skills/context-fold/REQUIREMENT.md +8 -20
- package/claude/skills/context-fold/SKILL.md +20 -44
- package/claude/skills/context-fold/references/classify.md +7 -8
- package/claude/skills/context-fold/references/completion-report.md +2 -6
- package/claude/skills/context-fold/references/context-refresh.md +5 -15
- package/claude/skills/context-fold/references/promoted-pages.md +3 -3
- package/claude/skills/context-fold/references/receipt-sweep.md +6 -17
- package/claude/skills/context-fold/references/unusable-baseline.md +4 -6
- package/claude/skills/create-rule/REQUIREMENT.md +0 -1
- package/claude/skills/create-skill/REQUIREMENT.md +6 -4
- package/claude/skills/create-skill/SKILL.md +8 -7
- package/{standards → claude/skills/create-skill/references}/skill-paths.md +1 -0
- 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 +0 -2
- package/claude/skills/design-taste/SKILL.md +1 -3
- package/claude/skills/design-taste/references/vocabulary.md +1 -1
- package/claude/skills/docs-sync/REQUIREMENT.md +3 -3
- 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 +4 -4
- package/claude/skills/draft-figure/references/architecture-set.md +4 -4
- package/claude/skills/draft-figure/references/hand-drawn.md +1 -1
- 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 +1 -1
- package/claude/skills/draft-identity/SKILL.md +9 -7
- package/claude/skills/draft-ready/REQUIREMENT.md +1 -1
- package/claude/skills/draft-ready/SKILL.md +6 -6
- 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-issue/references/issue.md +3 -3
- package/claude/skills/git-ship/REQUIREMENT.md +0 -2
- package/claude/skills/git-ship/SKILL.md +16 -24
- 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 +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 +1 -1
- package/claude/skills/review-pr/SKILL.md +5 -7
- package/claude/skills/review-ui/REQUIREMENT.md +0 -1
- package/claude/skills/review-ui/SKILL.md +1 -1
- package/claude/skills/role-orchestrator/REQUIREMENT.md +0 -3
- package/claude/skills/role-orchestrator/SKILL.md +8 -8
- package/claude/skills/role-orchestrator/references/orchestrator-dispatch.md +3 -3
- package/claude/skills/role-orchestrator/references/orchestrator-handoff.md +7 -10
- package/claude/skills/role-orchestrator/references/orchestrator-parked.md +2 -2
- package/claude/skills/role-orchestrator/references/orchestrator-refill.md +0 -3
- package/claude/skills/role-orchestrator/references/orchestrator-resume.md +1 -1
- package/claude/skills/role-planner/SKILL.md +2 -2
- package/claude/skills/role-reviewer/SKILL.md +1 -1
- package/claude/skills/role-worker/SKILL.md +2 -2
- 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 +8 -16
- 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 +4 -6
- package/claude/skills/session-resume/SKILL.md +3 -9
- package/claude/skills/session-worktree/SKILL.md +1 -1
- 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 +1 -1
- package/claude/skills/task-board/SKILL.md +4 -4
- package/claude/skills/task-board/references/archive.md +1 -1
- 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 +13 -8
- package/claude/skills/teach-workspace/SKILL.md +1 -1
- package/claude/skills/teach-workspace/references/revisit.md +1 -1
- package/{standards → claude/skills/teach-workspace/references}/teach.md +17 -5
- package/claude/skills/ux-audit/REQUIREMENT.md +2 -2
- package/claude/skills/ux-audit/SKILL.md +2 -3
- 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 +1 -6
- package/docs/agents/context-audit-checks.md +9 -23
- 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 +3 -5
- package/docs/agents/install-and-sync.md +6 -6
- package/docs/agents/intake.md +1 -1
- package/docs/agents/records-stale.md +5 -5
- package/docs/agents/records-validate.md +1 -1
- package/docs/agents/records.md +2 -2
- package/docs/agents/restated.md +1 -1
- package/docs/agents/rule-citations.md +1 -1
- 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 +1 -1
- package/docs/agents/teach.md +1 -1
- package/docs/agents/upstream.md +26 -2
- package/docs/target/migrations.md +24 -0
- package/docs/target/projects.md +5 -7
- package/docs/target/scenarios.md +2 -2
- package/docs/target/sync.md +3 -3
- package/docs/workflow/ai-workflow.md +7 -38
- package/docs/workflow/index.md +1 -1
- package/docs/workflow/operating-model.md +8 -8
- package/docs/workflow/parallel-features.md +7 -7
- package/docs/workflow/skill-map-on-request.md +12 -15
- package/docs/workflow/skill-map.md +20 -32
- package/docs/workflow/visual-design-workflow.md +11 -14
- package/governance/renames.toml +0 -19
- package/governance/rules/canon/605-worktrees.md +1 -1
- package/governance/rules/{standards → canon}/plan.md +4 -5
- package/governance/rules/canon/tasks.md +18 -0
- package/governance/stacks/base.toml +1 -1
- package/package.json +1 -1
- package/scripts/core/install-check.sh +1 -1
- package/scripts/core/regen-web-previews.ts +1 -1
- package/src/audits/catalog.ts +5 -97
- package/src/claude/cases/authoring.ts +0 -18
- package/src/claude/cases/misc.ts +0 -13
- package/src/claude/cases/setup.ts +3 -20
- package/src/claude/cases/workflow.ts +0 -33
- package/src/claude/seeds.ts +1 -7
- package/src/claude/skills-audit.ts +1 -1
- package/src/cli/help.ts +1 -4
- package/src/cli.ts +0 -4
- package/src/commands/claude.ts +8 -14
- package/src/commands/context.ts +18 -280
- package/src/commands/feedback.ts +22 -91
- package/src/commands/records.ts +5 -5
- package/src/commands/sync.ts +5 -3
- package/src/commands/upstream.ts +135 -0
- package/src/context/audit.ts +5 -14
- 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 +7 -12
- package/src/context/gate.ts +11 -91
- package/src/context/requirements.ts +13 -4
- package/src/counts/scan.ts +3 -3
- package/src/design/components.ts +2 -2
- package/src/feedback/body.ts +0 -12
- package/src/gate/measures.ts +6 -57
- package/src/gov/citations.ts +9 -3
- package/src/gov/restated.ts +3 -3
- package/src/markdown/structure.ts +2 -2
- package/src/migrate/record-layout.ts +3 -3
- package/src/records/ordinal.ts +1 -1
- package/src/records/prune.ts +2 -1
- package/src/records/stale-canonical.ts +2 -2
- package/src/roots/record.ts +1 -1
- package/src/sandbox/scenario.ts +115 -11
- package/src/shipped/references.ts +3 -3
- package/src/standards/read.ts +31 -0
- package/src/sync/seeds-report.ts +1 -1
- package/src/tasks/reach.ts +2 -2
- package/src/tasks/validate.ts +1 -1
- 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/context.md +3 -5
- package/standards/design.md +2 -3
- package/standards/index.md +0 -22
- package/standards/publish.md +1 -1
- package/standards/skill.md +1 -1
- package/tooling/base/reference.md +1 -1
- package/tooling/claude/reference.md +6 -20
- package/tooling/claude/seeds/.claude/hooks/records-index.sh +8 -20
- package/tooling/claude/seeds/.claude/hooks/standards-audit.sh +3 -3
- 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/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/groundwork.md +0 -13
- package/governance/rules/standards/intake.md +0 -12
- package/governance/rules/standards/memory.md +0 -12
- package/governance/rules/standards/ready.md +0 -13
- package/governance/rules/standards/requirements.md +0 -12
- package/governance/rules/standards/session.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/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/repo/metadata.ts +0 -206
- 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/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/tasks/reach.ts
CHANGED
|
@@ -11,7 +11,7 @@ const PLANS = 'plans'
|
|
|
11
11
|
const MARKDOWN = '.md'
|
|
12
12
|
const NONE_IDENTIFIED = 'None identified.'
|
|
13
13
|
|
|
14
|
-
/** The one group a dispatch reads, per `
|
|
14
|
+
/** The one group a dispatch reads, per `claude/skills/task-board/references/board.md`. */
|
|
15
15
|
const DISPATCH_GROUP = 'Run now'
|
|
16
16
|
|
|
17
17
|
export const REACH_REFUSALS = [
|
|
@@ -146,7 +146,7 @@ function namesFile(span: string): boolean {
|
|
|
146
146
|
* An entry carrying no colon at all is taken whole. The standard requires a
|
|
147
147
|
* reason rather than the punctuation introducing it, so the alternative is
|
|
148
148
|
* reading such an entry as declaring nothing, which reports every path it
|
|
149
|
-
* names as undeclared. `
|
|
149
|
+
* names as undeclared. `claude/skills/plan-feature/references/plan.md` fixes the colon form, so the
|
|
150
150
|
* conforming entry never reaches this fallback.
|
|
151
151
|
*
|
|
152
152
|
* A rename declares both sides, since both are paths the branch writes and
|
package/src/tasks/validate.ts
CHANGED
|
@@ -18,7 +18,7 @@ const ORDERING_FILE = 'priority.md'
|
|
|
18
18
|
const BACKLOG_FILE = 'backlog.md'
|
|
19
19
|
|
|
20
20
|
/**
|
|
21
|
-
* The readiness headings `
|
|
21
|
+
* The readiness headings `claude/skills/task-board/references/board.md` fixes. The names are the
|
|
22
22
|
* contract rather than a suggestion, so a board grouping under names of its own
|
|
23
23
|
* reads as carrying no group at all and the run refuses instead of reporting a
|
|
24
24
|
* clean board it never parsed.
|
package/src/teach/workspace.ts
CHANGED
|
@@ -30,7 +30,7 @@ export interface TeachRefused {
|
|
|
30
30
|
readonly detail: readonly string[]
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
/** The files and folders `
|
|
33
|
+
/** The files and folders `claude/skills/teach-workspace/references/teach.md` fixes for a workspace. */
|
|
34
34
|
export const TEACH_MISSION = 'MISSION.md'
|
|
35
35
|
export const TEACH_RESOURCES = 'RESOURCES.md'
|
|
36
36
|
export const TEACH_GLOSSARY = 'GLOSSARY.md'
|
package/src/upstream/cursor.ts
CHANGED
|
@@ -73,7 +73,7 @@ export function compareVersions(a: string, b: string): number {
|
|
|
73
73
|
|
|
74
74
|
// `fetch` reads this file, so a write that half-lands would leave a reader on a
|
|
75
75
|
// truncated cursor. A rename within one folder is atomic.
|
|
76
|
-
async function writeAtomic(path: string, body: string): Promise<void> {
|
|
76
|
+
export async function writeAtomic(path: string, body: string): Promise<void> {
|
|
77
77
|
mkdirSync(dirname(path), { recursive: true })
|
|
78
78
|
const temp = `${path}.${process.pid}.tmp`
|
|
79
79
|
writeFileSync(temp, body)
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from 'node:fs'
|
|
2
|
+
import { recordDir, SCRATCH } from '@/roots/record'
|
|
3
|
+
import { compareVersions, writeAtomic, type Cursor } from '@/upstream/cursor'
|
|
4
|
+
|
|
5
|
+
const DAY_MS = 86_400_000
|
|
6
|
+
const DUE_AFTER_DAYS = 7
|
|
7
|
+
|
|
8
|
+
// Ported from the groundwork's pre-filter script. It names canon's own surfaces,
|
|
9
|
+
// so an Added line matching it is one a digest would act on.
|
|
10
|
+
const VOCABULARY =
|
|
11
|
+
/plugin|skill|hook|SendMessage|ListAgents|agent view|agents view|worktree|subagent|background|routine|schedule|Monitor|mod\b|mods\b|CLAUDE\.md|rules|memory|permission|auto mode|stream-json|--bg|headless|-p\b|marketplace|session/i
|
|
12
|
+
const ADDED = /^Added/
|
|
13
|
+
const CACHE_MAX_AGE_MS = DAY_MS
|
|
14
|
+
|
|
15
|
+
/** What the gap between the cursor and the installed version holds. */
|
|
16
|
+
export interface Gap {
|
|
17
|
+
readonly releases: number
|
|
18
|
+
readonly lines: readonly string[]
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface DueInput {
|
|
22
|
+
/** The installed Claude Code version, or null when it could not be read. */
|
|
23
|
+
readonly installed: string | null
|
|
24
|
+
readonly cursor: Cursor | null
|
|
25
|
+
/** Null when the feed was not read, so only the age path can decide. */
|
|
26
|
+
readonly gap: Gap | null
|
|
27
|
+
readonly now: Date
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export type DueReason =
|
|
31
|
+
| 'no-cursor'
|
|
32
|
+
| 'week'
|
|
33
|
+
| 'vocabulary'
|
|
34
|
+
| 'current'
|
|
35
|
+
| 'recent'
|
|
36
|
+
| 'unknown-version'
|
|
37
|
+
|
|
38
|
+
export interface DueResult {
|
|
39
|
+
readonly due: boolean
|
|
40
|
+
readonly reason: DueReason
|
|
41
|
+
/** Releases in the gap, or null when it was not read. */
|
|
42
|
+
readonly releases: number | null
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export function passesVocabulary(line: string): boolean {
|
|
46
|
+
return ADDED.test(line) && VOCABULARY.test(line)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// A cursor date is a calendar day with no time, read at UTC midnight. An
|
|
50
|
+
// unreadable one gives NaN, which fails the age test and leaves the vocabulary
|
|
51
|
+
// path to decide.
|
|
52
|
+
function ageInDays(date: string, now: Date): number {
|
|
53
|
+
return (now.getTime() - Date.parse(`${date}T00:00:00Z`)) / DAY_MS
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Decides whether a digest is due.
|
|
58
|
+
*
|
|
59
|
+
* The age boundary is inclusive: a cursor exactly seven days old is due, since
|
|
60
|
+
* a week has passed. An installed version at or below the cursor is never due,
|
|
61
|
+
* which covers a downgrade as well as a run straight after a digest.
|
|
62
|
+
*/
|
|
63
|
+
export function decideDue(input: DueInput): DueResult {
|
|
64
|
+
const { installed, cursor, gap, now } = input
|
|
65
|
+
const releases = gap?.releases ?? null
|
|
66
|
+
|
|
67
|
+
if (cursor === null) return { due: true, reason: 'no-cursor', releases }
|
|
68
|
+
if (installed === null) {
|
|
69
|
+
return { due: false, reason: 'unknown-version', releases }
|
|
70
|
+
}
|
|
71
|
+
if (compareVersions(installed, cursor.version) <= 0) {
|
|
72
|
+
return { due: false, reason: 'current', releases }
|
|
73
|
+
}
|
|
74
|
+
if (ageInDays(cursor.date, now) >= DUE_AFTER_DAYS) {
|
|
75
|
+
return { due: true, reason: 'week', releases }
|
|
76
|
+
}
|
|
77
|
+
if (gap?.lines.some(passesVocabulary)) {
|
|
78
|
+
return { due: true, reason: 'vocabulary', releases }
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return { due: false, reason: 'recent', releases }
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* One reading of the feed, kept so a wave of sessions starting together spends
|
|
86
|
+
* one request rather than one each.
|
|
87
|
+
*/
|
|
88
|
+
export interface DueCache {
|
|
89
|
+
readonly checkedAt: string
|
|
90
|
+
readonly installed: string
|
|
91
|
+
readonly cursor: string
|
|
92
|
+
/** Null when the read failed, so a failure is held for the day too. */
|
|
93
|
+
readonly gap: Gap | null
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Scratch rather than the upstream record folder, which a records push backs
|
|
97
|
+
// whole. A file rewritten daily would add a commit to the history each time.
|
|
98
|
+
const cachePath = (root: string): string =>
|
|
99
|
+
recordDir(root, SCRATCH, 'upstream-due', 'check.json')
|
|
100
|
+
|
|
101
|
+
/** The stored reading when it is fresh and answers for this pair of versions. */
|
|
102
|
+
export function readDueCache(
|
|
103
|
+
root: string,
|
|
104
|
+
installed: string,
|
|
105
|
+
cursor: string,
|
|
106
|
+
now: Date,
|
|
107
|
+
): DueCache | null {
|
|
108
|
+
const path = cachePath(root)
|
|
109
|
+
if (!existsSync(path)) return null
|
|
110
|
+
|
|
111
|
+
try {
|
|
112
|
+
const cache = JSON.parse(readFileSync(path, 'utf8')) as DueCache
|
|
113
|
+
const age = now.getTime() - Date.parse(cache.checkedAt)
|
|
114
|
+
const isFresh = age >= 0 && age < CACHE_MAX_AGE_MS
|
|
115
|
+
const isSamePair = cache.installed === installed && cache.cursor === cursor
|
|
116
|
+
|
|
117
|
+
return isFresh && isSamePair ? cache : null
|
|
118
|
+
} catch {
|
|
119
|
+
return null
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
export async function writeDueCache(
|
|
124
|
+
root: string,
|
|
125
|
+
cache: DueCache,
|
|
126
|
+
): Promise<void> {
|
|
127
|
+
await writeAtomic(cachePath(root), `${JSON.stringify(cache)}\n`)
|
|
128
|
+
}
|
package/src/upstream/releases.ts
CHANGED
|
@@ -113,6 +113,7 @@ export async function walkReleases(
|
|
|
113
113
|
|
|
114
114
|
export function githubPageFetcher(
|
|
115
115
|
env: Record<string, string | undefined> = process.env,
|
|
116
|
+
signal?: AbortSignal,
|
|
116
117
|
): PageFetcher {
|
|
117
118
|
const token = env.GH_TOKEN ?? env.GITHUB_TOKEN
|
|
118
119
|
const headers: Record<string, string> = {
|
|
@@ -125,7 +126,7 @@ export function githubPageFetcher(
|
|
|
125
126
|
try {
|
|
126
127
|
const response = await fetch(
|
|
127
128
|
`${RELEASES_URL}?per_page=${PER_PAGE}&page=${page}`,
|
|
128
|
-
{ headers },
|
|
129
|
+
{ headers, signal },
|
|
129
130
|
)
|
|
130
131
|
if (response.status === 403 || response.status === 429) {
|
|
131
132
|
return {
|
package/standards/context.md
CHANGED
|
@@ -18,10 +18,8 @@ Governs per-domain narrative entries under `canon/context/`: their structure, th
|
|
|
18
18
|
|
|
19
19
|
Does not govern:
|
|
20
20
|
|
|
21
|
-
- Decisions filling a stack, delivery, boundary, layout, or build-principle slot, and system-wide risks: `architecture.md`
|
|
22
21
|
- Product scope, goals, and non-goals: `requirements.md`
|
|
23
22
|
- Path-scoped coding rules: `rule.md`
|
|
24
|
-
- Wireframes, which answer layout questions an entry hands off: `wireframes.md`
|
|
25
23
|
- Figures and architecture views, which answer structure questions an entry hands off: the `draft-figure` skill
|
|
26
24
|
- The consumer-facing reference under `docs/`, whose reader is operating the project without the source open: `docs.md`
|
|
27
25
|
|
|
@@ -88,10 +86,10 @@ Only the `development` entry carries this section. It is not a general-purpose h
|
|
|
88
86
|
## What goes in
|
|
89
87
|
|
|
90
88
|
- Per-domain narrative on how the code is structured and why
|
|
91
|
-
- Decisions that constrain the domain, whether or not their reasoning touches another one.
|
|
89
|
+
- Decisions that constrain the domain, whether or not their reasoning touches another one. A decision lives in the entry of the domain it constrains.
|
|
92
90
|
- Constraints, gotchas, things tried and rejected
|
|
93
91
|
- Domain-specific conventions that do not fit a `paths:`-scoped rule
|
|
94
|
-
- A measured figure,
|
|
92
|
+
- A measured figure, closed with a trailing `Measured at <short-sha> on <YYYY-MM-DD>.` naming a commit rather than a pull request number or a branch. Carry one anchor per figure and rewrite it in place when the number is re-read, whether or not it moved. An absent anchor reads as unchecked.
|
|
95
93
|
- A reference to another entry, spelled as the path that entry sits at rather than as its bare filename. A bare name resolves against whichever folder the reader is already in, so a domain that splits into subfolders strands every inbound reference and the break surfaces nowhere. A reference to a seed, a standard, or a file the project owns elsewhere keeps the form its own surface uses.
|
|
96
94
|
|
|
97
95
|
## What does not go in
|
|
@@ -103,7 +101,7 @@ Only the `development` entry carries this section. It is not a general-purpose h
|
|
|
103
101
|
- Rules. Those go in `.claude/rules/<scope>.md` with a `paths:` glob.
|
|
104
102
|
- Tutorials or human onboarding. Those go in `docs/` if a public audience exists.
|
|
105
103
|
- Generated content (API references). Generate, do not write by hand.
|
|
106
|
-
- Anything already in `canon/REQUIREMENTS.md
|
|
104
|
+
- Anything already in `canon/REQUIREMENTS.md`.
|
|
107
105
|
- The history of how the domain reached its current shape. An entry describes the repository as it stands, so a change number, release label, or date attached to a change goes wherever the project tracks work.
|
|
108
106
|
- A rejected alternative's provenance, which is the same rule at the one place the section above admits history. Keep what was tried and why it lost. Cut who tried it and when.
|
|
109
107
|
- The route to a decision: the rounds of candidates, the tuning steps a threshold passed through, the review pass that caught a miss. State the decision, what lost, and why, once and in the present tense. Cut the route. Git and the change that introduced it keep it.
|
package/standards/design.md
CHANGED
|
@@ -15,13 +15,12 @@ Governs the visual-intent document at `canon/DESIGN.md`: tokens described as int
|
|
|
15
15
|
|
|
16
16
|
Does not govern:
|
|
17
17
|
|
|
18
|
-
- Screen layout, on-screen copy, and interaction intent: `wireframes.md`
|
|
19
18
|
- Per-domain implementation narrative: `context.md`
|
|
20
19
|
|
|
21
20
|
## What goes in
|
|
22
21
|
|
|
23
22
|
- A token's exact value, anchored to the surface it was read from and tagged per `## The uncertainty tag` when unconfirmed. Fall back to intent language ("mid gray, muted text") only where no source exists yet to anchor from.
|
|
24
|
-
- Layout constraints and sizing rules not obvious from
|
|
23
|
+
- Layout constraints and sizing rules not obvious from the tokens and the code
|
|
25
24
|
- Visual rules a developer could get wrong without guidance
|
|
26
25
|
- Non-obvious omissions ("no motion", "no custom icons") that prevent scope creep
|
|
27
26
|
|
|
@@ -34,7 +33,7 @@ Does not govern:
|
|
|
34
33
|
## Format
|
|
35
34
|
|
|
36
35
|
- Use tables for token systems, one row per token. Write every other rule as a short bullet, one decision per line, within `## Prose budget`.
|
|
37
|
-
- Plain English over technical notation. If a section could be removed and the developer would still build correctly from
|
|
36
|
+
- Plain English over technical notation. If a section could be removed and the developer would still build correctly from the tokens and code alone, remove it.
|
|
38
37
|
- Keep table headers and role names intact so the render tooling can parse the token tables.
|
|
39
38
|
|
|
40
39
|
## Prose budget
|
package/standards/index.md
CHANGED
|
@@ -7,39 +7,17 @@ subtitle: Reference docs for consistent authoring across the toolkit and target
|
|
|
7
7
|
|
|
8
8
|
Reference docs for consistent authoring across the toolkit and target projects.
|
|
9
9
|
|
|
10
|
-
- [Architecture reference](architecture.md): Shape and content rules for canon/ARCHITECTURE.md
|
|
11
|
-
- [Board reference](board.md): Readiness groups, row cells, and ordering for priority.md, the unordered backlog.md beside it, and the generated index under .canon/tasks/
|
|
12
10
|
- [Branch reference](branch.md): Branch naming format and type conventions
|
|
13
|
-
- [Canvas reference](canvas.md): Page folders, frame files, the layout.json shape, token resolution, and what a frame must not assume on a local design canvas
|
|
14
11
|
- [Commit reference](commit.md): Commit message format and type conventions
|
|
15
12
|
- [Context entry reference](context.md): Shape and content rules for canon/context/<domain>.md entries
|
|
16
13
|
- [Design reference](design.md): Shape and content rules for canon/DESIGN.md
|
|
17
14
|
- [Docs reference](docs.md): Reader and jurisdiction, frontmatter, page structure, what a page links out to, the diagram permission, and when a category earns a subfolder
|
|
18
15
|
- [Figure reference](figures.md): When a figure earns its place, the render-first policy for a graph-shaped subject, freehand SVG as the escape hatch, and its wrapping, color, and accessibility rules
|
|
19
|
-
- [Glossary reference](glossary.md): Frontmatter, entry shape, ordering, and the rules deciding which terms a glossary carries
|
|
20
|
-
- [Groundwork spikes reference](groundwork-spikes.md): What each spike in a track's 08-spikes.md records, the sample rule, and the three folders that hold what a spike produced
|
|
21
|
-
- [Groundwork reference](groundwork.md): Folder layout, ordinal naming, reserved numbering, frontmatter and dating, required file contents, and conventions for a measurement track
|
|
22
|
-
- [Intake reference](intake.md): Folder layout, ordinal naming, reserved index number, frontmatter and dating, the item template, the answer contract, and retrieval
|
|
23
|
-
- [Memory reference](memory.md): Filename and type prefix, frontmatter, the body shape per type, links between entries, and the lifecycle from write to retire
|
|
24
|
-
- [Mermaid reference](mermaid.md): Direction and layout, node and edge budgets, accessibility fields, label punctuation, and render verification for a Mermaid diagram
|
|
25
|
-
- [Plan lifecycle reference](plan-lifecycle.md): When a feature plan is written, where it lives, how it changes mid-flight, and its move to the archive
|
|
26
|
-
- [Plan reference](plan.md): Filename and slug, the required sections, and the suggested-and-answer contract for a feature plan
|
|
27
16
|
- [Pull request reference](pr.md): Pull request title and body conventions
|
|
28
17
|
- [Publish reference](publish.md): Scan an author runs against finished text, the cross-reference form each destination takes, and the response to an unreadable source
|
|
29
18
|
- [Readme reference](readme.md): Readme voice, structure, and content conventions
|
|
30
|
-
- [Ready reference](ready.md): Folder layout, ordinal naming, the overview frontmatter, the thin-plan contract, and the archive lifecycle for a finished-file handoff
|
|
31
|
-
- [Requirements reference](requirements.md): Shape and content rules for canon/REQUIREMENTS.md
|
|
32
19
|
- [Governance rule reference](rule.md): Rule frontmatter, body shape, and voice for .claude/rules files
|
|
33
|
-
- [Session map reference](session.md): Filename and location, the sections a handoff carries, the write and read procedures, and how a role extends it
|
|
34
|
-
- [Skill path reference](skill-paths.md): Which root a file a skill body names resolves against, and how a body cites a standard
|
|
35
|
-
- [Practice skill reference](skill-practice.md): Closing sections and source ledger for a skill carrying engineering practice
|
|
36
|
-
- [Skill requirement reference](skill-requirement.md): Shape and content rules for the REQUIREMENT.md beside a skill
|
|
37
20
|
- [Claude skill reference](skill.md): Skill structure and authoring rules for Claude Code
|
|
38
21
|
- [Slug reference](slug.md): Transform from a git branch name to a slug, and the three responses to an empty result
|
|
39
22
|
- [Standard reference](standard.md): Shape and content rules for authoring a standard
|
|
40
|
-
- [Task decline reference](tasks-decline.md): Where a task decided against moves, the Declined line it carries, and what happens to its plan and board row
|
|
41
|
-
- [Tasks reference](tasks.md): Folder layout, filename convention, file format, origin lines, and archiving for task files under .canon/tasks/
|
|
42
|
-
- [Teach reference](teach.md): Workspace layout, ordinal naming, frontmatter, and the mission and learning-record formats for a learning workspace
|
|
43
23
|
- [Versioning reference](versioning.md): Phase label vs semver discipline across tasks, PRs, reviews, issues, commits, and tags
|
|
44
|
-
- [Wiki reference](wiki.md): Folder split, frontmatter, naming convention, and sourcing for a wiki reference page
|
|
45
|
-
- [Wireframe reference](wireframes.md): Shape and content rules for canon/wireframes/<surface>.md files
|
package/standards/publish.md
CHANGED
|
@@ -70,7 +70,7 @@ Qualifying it against `erclx/canon` fixes nothing, because a reader holding only
|
|
|
70
70
|
|
|
71
71
|
Write `owner/repo#123` and `owner/repo@abc1234` for a citation of a different, resolvable repository, across every such surface. `canon gate run` fails a push on a bare reference there, and a line whose bare form is the point carries `canon-allow-reference: <reason>` on itself or on the line above.
|
|
72
72
|
|
|
73
|
-
Choose the number over the sha where the citation names a decided change, since a pull request number resolves to the diff and the review behind it. Take the sha only for a tree or measurement state, the `Measured at <sha>` shape
|
|
73
|
+
Choose the number over the sha where the citation names a decided change, since a pull request number resolves to the diff and the review behind it. Take the sha only for a tree or measurement state, the `Measured at <sha>` shape a context entry already uses. The choice holds for both spellings this section fixes, the bare form a remote auto-links and the qualified form a cross-repository citation carries.
|
|
74
74
|
|
|
75
75
|
A commit message takes the bare form even though it is also read through the log, where nothing links. The remote is what the form is chosen for, since a reader in the log loses only a link that plain text never carried.
|
|
76
76
|
|
package/standards/skill.md
CHANGED
|
@@ -149,7 +149,7 @@ allowed-tools: <tools required>
|
|
|
149
149
|
### Output and tuning
|
|
150
150
|
|
|
151
151
|
- Skill success lines emit the full relative path from the project root (`<dir>/<file>`) for any file written, updated, or deleted. A bare filename names a file the reader cannot open. The `## Output` section of the project's instruction file sets the form that path takes, so a skill body states which path is emitted and leaves the form to that section.
|
|
152
|
-
- Before a skill writes anything, decide whether the output is a deliverable the project keeps or a toolkit session record. A deliverable lands among the project's own tracked files. A session record lands under `.canon/`, in the named subfolder for its kind (`tasks/`, `plans/`, `review/`, `
|
|
152
|
+
- Before a skill writes anything, decide whether the output is a deliverable the project keeps or a toolkit session record. A deliverable lands among the project's own tracked files. A session record lands under `.canon/`, in the named subfolder for its kind (`tasks/`, `plans/`, `review/`, `groundwork/`, `intake/`, `proposals/`, `diagrams/`, `teach/`, `ready/`, `feedback/`, `picks/`, `evidence/`, `transcripts/`, or `walkthroughs/`, with `tmp/` for scratch nothing else claims), never in a folder the body invents. A `review/` writer names its file `<kind>-<slug>.md` and writes it flat, and an `evidence/` folder takes the next two-digit ordinal as `<nn>-<slug>/`, numbered in the order the folders first appeared.
|
|
153
153
|
- Codify a skill's posted or generated output as a fenced template, and keep the body consistent with every capability the frontmatter description names.
|
|
154
154
|
- When a skill gathers user input or pre-seeds a template, attach a concrete proposed default to every question, derived from project context. Accept "use defaults" as a bulk-confirm.
|
|
155
155
|
- Separate correctness axes (routing, sourcing, escalation, decline) from shape axes (line count, formatting, variant sprawl) when tuning a skill. Tighten only on correctness regressions, never turning a soft cap hard for aesthetic drift.
|
|
@@ -45,7 +45,7 @@ Seeds live in `tooling/base/seeds/`. Sync drops each once on first install and n
|
|
|
45
45
|
|
|
46
46
|
- All shell scripts live in `scripts/`. Do not place a `.sh` file outside it.
|
|
47
47
|
- Dictionaries live in `.cspell/`, hooks in `.husky/`, seeded context docs in `canon/context/`.
|
|
48
|
-
- The `canon/context/` location matches the three-tier context model: project-wide invariants in `CLAUDE.md
|
|
48
|
+
- The `canon/context/` location matches the three-tier context model: project-wide invariants in `CLAUDE.md` and `canon/REQUIREMENTS.md`, path-scoped rules in `.claude/rules/`, and on-demand domain narrative in `canon/context/`. Indexes stay opt-in.
|
|
49
49
|
|
|
50
50
|
## Hooks
|
|
51
51
|
|
|
@@ -10,11 +10,9 @@ The claude stack installs the `.claude/` workflow directory into a project. Stat
|
|
|
10
10
|
CLAUDE.md ← seeded. Project context and rules, auto-loaded by Claude Code each session
|
|
11
11
|
|
|
12
12
|
canon/
|
|
13
|
-
├── REQUIREMENTS.md ← seeded. Project goals, non-goals
|
|
14
|
-
├── ARCHITECTURE.md ← seeded. Technical design decisions and open questions
|
|
13
|
+
├── REQUIREMENTS.md ← seeded. Project problem, goals, non-goals
|
|
15
14
|
├── DESIGN.md ← seeded. Visual intent and the decisions behind it
|
|
16
|
-
|
|
17
|
-
└── wireframes/ ← seeded. Per-surface regions and states. `index.md` is the discovery anchor; `<surface>.md` files hold the regions list, the states table, and the behavior bullets.
|
|
15
|
+
└── context/ ← seeded. Per-domain narrative. `index.md` is the discovery anchor.
|
|
18
16
|
|
|
19
17
|
.claude/
|
|
20
18
|
├── GOV.md ← retired. Removed by `canon gov sync` if present from a prior install
|
|
@@ -24,9 +22,8 @@ canon/
|
|
|
24
22
|
.canon/
|
|
25
23
|
├── tasks/ ← seeded. One file per task plus a generated index.md, local scratch only. `archive/` holds the tasks that shipped.
|
|
26
24
|
├── plans/ ← execution detail for multi-step tasks. `feature-*.md` entries swept by context-fold into `archive/`.
|
|
27
|
-
├── review/ ← one subfolder per producer. `branch/`
|
|
28
|
-
|
|
29
|
-
└── memory/ ← session facts no context entry owns. `index.md` regenerated by a hook.
|
|
25
|
+
├── review/ ← one subfolder per producer. `branch/` no longer written, `design/` for canon design render.
|
|
26
|
+
└── tmp/ ← ephemeral scratch space, safe to delete without loss
|
|
30
27
|
```
|
|
31
28
|
|
|
32
29
|
One ignore entry covers `.canon/` whole, so nothing under it is named separately and nothing tracked may ever land there. A project scaffolded before the move keeps its records under `.claude/`, and every command reads either root.
|
|
@@ -35,7 +32,7 @@ One ignore entry covers `.canon/` whole, so nothing under it is named separately
|
|
|
35
32
|
|
|
36
33
|
A project installed before the split still holds its records under `.claude/`. `canon migrate records` moves them and repoints every tracked file that cites one, reporting the plan until `--write` is passed.
|
|
37
34
|
|
|
38
|
-
Run `canon tooling sync claude . --write` first. The verb refuses while the project does not ignore `.canon/`, because every folder it relocates is ignored where it stands and landing one under a tracked root commits the
|
|
35
|
+
Run `canon tooling sync claude . --write` first. The verb refuses while the project does not ignore `.canon/`, because every folder it relocates is ignored where it stands and landing one under a tracked root commits the task board and the plans. Until the move runs, this project's records sit at a root the shipped ignore set no longer names, so a `git add -A` in that window picks them up.
|
|
39
36
|
|
|
40
37
|
The verb ships with the change that split the roots and is not in a published release yet, so an installed binary answers `unknown command` until one carries it. Run it out of a canon checkout in the meantime, as `bun src/cli.ts migrate records --root <project> --write`, and read the `ok` field out of `--json` rather than the exit code, which a shell wrapper around `canon` can flatten.
|
|
41
38
|
|
|
@@ -49,16 +46,6 @@ Convert by hand, once per project:
|
|
|
49
46
|
2. Run `canon indexes regen --no-stage --root . .canon/tasks/<any-task>.md` to build the catalog.
|
|
50
47
|
3. Delete `.claude/TASKS.md`, and swap its `.gitignore` entry for `.canon/tasks/`.
|
|
51
48
|
|
|
52
|
-
## Upgrading a hand-appended memory index
|
|
53
|
-
|
|
54
|
-
A project installed before the memory folder gained a generated index still holds `.canon/memory/MEMORY.md`, and its entries still carry `name` and `type` frontmatter. Nothing migrates it. `memory-capture` stops appending rows once the new seed lands, so the old file freezes at whatever it held while the folder keeps growing past it.
|
|
55
|
-
|
|
56
|
-
Convert by hand, once per project:
|
|
57
|
-
|
|
58
|
-
1. Rewrite each entry's `name` key to `title` and its `type` key to a sentence-case `category`, quoting any `description` that opens with a backtick or a colon so the frontmatter parses.
|
|
59
|
-
2. Replace `MEMORY.md` with an `index.md` carrying `title` and `subtitle` frontmatter and nothing else.
|
|
60
|
-
3. Run `canon indexes regen --no-stage --root . .canon/memory/index.md` to build the catalog, and compare its entry count against the file count before deleting anything.
|
|
61
|
-
|
|
62
49
|
## Gitignore
|
|
63
50
|
|
|
64
51
|
- `# Claude`: `.canon/`, `.claude/worktrees/`, `.claude/.tmp/` <!-- canon-keep-record-root -->
|
|
@@ -76,8 +63,7 @@ The first entry covers the whole record root, so a record folder added later nee
|
|
|
76
63
|
## CLAUDE.md
|
|
77
64
|
|
|
78
65
|
- Ships as a seed with placeholder project name, description, and key paths. Fill these in after init.
|
|
79
|
-
- Section layout: `Context`, `
|
|
80
|
-
- The memory rules favor signal over volume. Saving only after a second occurrence or an explicit user correction keeps entries focused on patterns worth preventing, not first-occurrence slips. The 3-line cap stops the built-in auto-memory from drifting into narrative writeups that bury the rule underneath the recovery story.
|
|
66
|
+
- Section layout: `Context`, `Commands`, `Key paths`. Each section groups rules that share a surface so skills can detect, extend, or skip by heading.
|
|
81
67
|
- The `Context` section points at `.claude/` state docs one line. `plan-feature` does the parallel read when invoked. The seed intentionally does not re-list every file.
|
|
82
68
|
|
|
83
69
|
## Seed docs
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
2
|
|
|
3
|
-
# Regenerates the index.md of
|
|
4
|
-
#
|
|
3
|
+
# Regenerates the index.md of the gitignored `tasks` record folder after a
|
|
4
|
+
# file in it changes.
|
|
5
5
|
#
|
|
6
|
-
#
|
|
7
|
-
#
|
|
6
|
+
# That folder is gitignored, so the whole-repo walk in `bun run check` drops
|
|
7
|
+
# it and never regenerates its index. Naming the file as a positional
|
|
8
8
|
# argument to `canon indexes regen` below bypasses that filter, which makes this
|
|
9
|
-
# hook the only trigger that reaches
|
|
9
|
+
# hook the only trigger that reaches the folder.
|
|
10
10
|
|
|
11
11
|
# Claude Code sends a payload and closes stdin. A bare read with nothing feeding
|
|
12
12
|
# it blocks forever and holds the session open, so the read is bounded. `read`
|
|
@@ -31,11 +31,9 @@ file_path=$(printf '%s' "$input" | jq -r '.tool_input.file_path // empty')
|
|
|
31
31
|
# said. The index then goes stale while every save reports success.
|
|
32
32
|
#
|
|
33
33
|
# A shell `case` `*` crosses `/`, so each arm also matches a file in a subfolder
|
|
34
|
-
# the index does not render: an archived or declined task,
|
|
35
|
-
#
|
|
36
|
-
#
|
|
37
|
-
# and a memory `declined/` is not special. The arms are ordered tasks first,
|
|
38
|
-
# and no path carries both segments today.
|
|
34
|
+
# the index does not render: an archived or declined task, or the index itself.
|
|
35
|
+
# Those exit here, before the regen call. A task under `review/` is
|
|
36
|
+
# indexed, and no other folder is read.
|
|
39
37
|
#
|
|
40
38
|
# The walk-up boundary has to come from the path, not from the session. Shared
|
|
41
39
|
# scratch resolves at the main worktree root, so a session inside a linked
|
|
@@ -45,8 +43,6 @@ file_path=$(printf '%s' "$input" | jq -r '.tool_input.file_path // empty')
|
|
|
45
43
|
case "$file_path" in
|
|
46
44
|
*/.canon/tasks/index.md | */.canon/tasks/archive/* | */.canon/tasks/declined/*) exit 0 ;;
|
|
47
45
|
*/.claude/tasks/index.md | */.claude/tasks/archive/* | */.claude/tasks/declined/*) exit 0 ;;
|
|
48
|
-
*/.canon/memory/index.md | */.canon/memory/review/* | */.canon/memory/archive/*) exit 0 ;;
|
|
49
|
-
*/.claude/memory/index.md | */.claude/memory/review/* | */.claude/memory/archive/*) exit 0 ;;
|
|
50
46
|
*/.canon/tasks/*.md)
|
|
51
47
|
folder=tasks
|
|
52
48
|
base=.canon
|
|
@@ -55,14 +51,6 @@ case "$file_path" in
|
|
|
55
51
|
folder=tasks
|
|
56
52
|
base=.claude
|
|
57
53
|
;;
|
|
58
|
-
*/.canon/memory/*.md)
|
|
59
|
-
folder=memory
|
|
60
|
-
base=.canon
|
|
61
|
-
;;
|
|
62
|
-
*/.claude/memory/*.md)
|
|
63
|
-
folder=memory
|
|
64
|
-
base=.claude
|
|
65
|
-
;;
|
|
66
54
|
*) exit 0 ;;
|
|
67
55
|
esac
|
|
68
56
|
root="${file_path%/"$base/$folder"/*}"
|
|
@@ -18,12 +18,12 @@ case "$file" in
|
|
|
18
18
|
*) exit 0 ;;
|
|
19
19
|
esac
|
|
20
20
|
|
|
21
|
-
#
|
|
21
|
+
# Three record folders, at either root. A skip list fixed at the old spelling
|
|
22
22
|
# audits a project's own session records the moment the move reaches it, which
|
|
23
23
|
# reports findings against prose nobody publishes.
|
|
24
24
|
case "$file" in
|
|
25
|
-
*.claude/.tmp/* | *.claude/
|
|
26
|
-
*.canon/tmp/* | *.canon/
|
|
25
|
+
*.claude/.tmp/* | *.claude/review/* | *.claude/plans/*) exit 0 ;;
|
|
26
|
+
*.canon/tmp/* | *.canon/review/* | *.canon/plans/*) exit 0 ;;
|
|
27
27
|
esac
|
|
28
28
|
|
|
29
29
|
[ -f "$file" ] || exit 0
|
|
@@ -4,12 +4,10 @@
|
|
|
4
4
|
|
|
5
5
|
## Context
|
|
6
6
|
|
|
7
|
-
- Before non-trivial work in a domain read `canon/context/<domain>.md
|
|
7
|
+
- Before non-trivial work in a domain read `canon/context/<domain>.md`. Pick which from the index anchor below.
|
|
8
8
|
|
|
9
9
|
@canon/REQUIREMENTS.md
|
|
10
|
-
@canon/ARCHITECTURE.md
|
|
11
10
|
@canon/context/index.md
|
|
12
|
-
@canon/wireframes/index.md
|
|
13
11
|
|
|
14
12
|
## Commands
|
|
15
13
|
|
|
@@ -1,18 +1,11 @@
|
|
|
1
1
|
# Requirements
|
|
2
2
|
|
|
3
|
+
[One line: the problem and who has it]
|
|
4
|
+
|
|
3
5
|
Authoring guidance: the requirements standard.
|
|
4
6
|
|
|
5
7
|
This record holds at most 600 words.
|
|
6
8
|
|
|
7
|
-
## Problem
|
|
8
|
-
|
|
9
9
|
## Goals
|
|
10
10
|
|
|
11
11
|
## Non-goals
|
|
12
|
-
|
|
13
|
-
## MVP features
|
|
14
|
-
|
|
15
|
-
1. Feature: description
|
|
16
|
-
2. Feature: description
|
|
17
|
-
|
|
18
|
-
## Constraints
|
|
@@ -58,7 +58,6 @@ const HOME_SECTIONS: CaptureSection[] = [
|
|
|
58
58
|
{ name: 'dispatch', selector: '#dispatch' },
|
|
59
59
|
{ name: 'workers', selector: '#workers' },
|
|
60
60
|
{ name: 'gate', selector: '#gate' },
|
|
61
|
-
{ name: 'memory', selector: '#memory' },
|
|
62
61
|
{ name: 'evidence', selector: '#evidence' },
|
|
63
62
|
{ name: 'loop', selector: '#loop' },
|
|
64
63
|
{ name: 'merge', selector: '#merge' },
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: Review findings
|
|
3
|
-
description: How auto-ship Step 7 splits the review receipt's findings by origin, which ones it repairs in place and which stop the chain, and the one-pass bound on the repair
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Evaluate the review findings
|
|
7
|
-
|
|
8
|
-
Step 7 of `auto-ship`. The session reads this file when Step 6 ran review rather than skipping it.
|
|
9
|
-
|
|
10
|
-
Read `.canon/review/branch-<slug>.md` at the main worktree root. Split every finding by origin before parsing the summary line (`X critical, Y should-fix, Z minor`), since the stop exists for a defect the branch inherited.
|
|
11
|
-
|
|
12
|
-
- **This run caused it, at any severity.** Fix it, re-run the Step 3 verify commands, re-read the fixed file against what the finding claimed, and continue. Do not report it as a stop or offer the fix as a choice.
|
|
13
|
-
- **It predates this run, critical or should-fix.** Stop: `❌ Review found non-minor issues that predate this run. See .canon/review/branch-<slug>.md. Fix and run /git-ship.`
|
|
14
|
-
- **It predates this run, minor only.** Continue. The minor findings stay in the on-disk review receipt. Fold any a reviewer needs into the PR's `## Technical Context`. Do not add a separate review-notes section to the PR body.
|
|
15
|
-
|
|
16
|
-
Read origin as causation rather than authorship, so staleness this run induced in a file it never opened is a finding it caused.
|
|
17
|
-
|
|
18
|
-
Bound the repair at one pass, the way Step 3 bounds verify. When that re-read shows the finding still standing, stop: `❌ A self-introduced finding survived one fix pass. See .canon/review/branch-<slug>.md. Fix and run /git-ship.`
|
|
19
|
-
|
|
20
|
-
This chain owns the receipt's lifetime. The `context-fold` sweep under Step 8 reaches only reports whose branch is gone, so it collects this one a branch later.
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: bash-cli-script
|
|
3
|
-
description: What a small non-interactive shell wrapper owes its caller, and the 100-line threshold past which the work belongs in TypeScript on Bun
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Bash CLI script requirement
|
|
7
|
-
|
|
8
|
-
## Gap
|
|
9
|
-
|
|
10
|
-
Without this skill, a wrapper is written with an interactive tool's habits. Progress lines, icons, and color land on stdout, so the script stops composing in a pipe and the caller parses a spinner as data. The failure is invisible in a terminal and total in CI.
|
|
11
|
-
|
|
12
|
-
The robustness failures are the ones that reach production. Without strict mode a failed stage inside a pipe exits zero and the script reports success on work that did not happen. An unset variable expands to nothing and a path built from it points somewhere nobody meant.
|
|
13
|
-
|
|
14
|
-
The size failure is the slow one. A shell script that keeps growing past a wrapper's job turns into the long file nobody will touch, and the [Google Shell Style Guide](https://google.github.io/styleguide/shellguide.html) puts the line at 100: past it, the script is rewritten in a more structured language. Without a stop before generating, a session writes the long script first and the rewrite never happens.
|
|
15
|
-
|
|
16
|
-
## Must
|
|
17
|
-
|
|
18
|
-
- Stop before generating when the script will run past 100 lines, and route the work to TypeScript on Bun citing the style guide
|
|
19
|
-
- Stop the same way on a request for prompts or a terminal UI, saying why
|
|
20
|
-
- Open with the strict-mode preamble, so a failed stage stops the script
|
|
21
|
-
- Keep data on stdout and put every log line, progress message, and error on stderr
|
|
22
|
-
- Exit non-zero with actionable context through one error helper
|
|
23
|
-
- Default every variable expansion rather than relying on it being set
|
|
24
|
-
- Guard a command that returns non-zero on a valid empty result
|
|
25
|
-
- Run the validation list before responding
|
|
26
|
-
|
|
27
|
-
## Must not
|
|
28
|
-
|
|
29
|
-
- Emit timeline frames, icons, color, or an interactive prompt
|
|
30
|
-
- Put a log or progress line on stdout
|
|
31
|
-
- Comment what the code already states
|
|
32
|
-
- Rewrite an existing long shell file on contact, which is a rewrite decision rather than an edit
|
|
33
|
-
|
|
34
|
-
## Guards
|
|
35
|
-
|
|
36
|
-
- A script that will run past 100 lines stops before any of it is written, and the session writes it in TypeScript on Bun instead.
|
|
37
|
-
- A request for prompts, a framed timeline, icons, or color stops with the same route.
|
|
38
|
-
|
|
39
|
-
## Out of scope
|
|
40
|
-
|
|
41
|
-
- A tool a person drives through prompts or a terminal UI, which is written in TypeScript on Bun
|
|
42
|
-
- A GitHub Actions workflow file, which `ci-workflow` owns
|
|
43
|
-
- Running, installing, or scheduling what it generates
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: bash-cli-script
|
|
3
|
-
description: Generates a small non-interactive Bash wrapper for automation, CI, and agent-run tasks, with strict mode, logs on stderr, a clean stdout, and explicit exit codes. Stops at 100 lines and routes the work to TypeScript on Bun. Use when asked for "a shell script", "a wrapper script", an automation or CI script, a cron job, or a pipeline helper. Do NOT use for a tool that prompts a person or draws a terminal UI, or for a script that will run past 100 lines. Both are written in TypeScript on Bun.
|
|
4
|
-
metadata:
|
|
5
|
-
family: generate
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# Bash CLI script
|
|
9
|
-
|
|
10
|
-
Generate small non-interactive Bash wrappers for automation, CI, and agent-run workflows. Shell is for small utilities and simple wrappers, and anything larger is written in TypeScript on Bun, which runs a script about as fast as bash starts one.
|
|
11
|
-
|
|
12
|
-
Load `${CLAUDE_SKILL_DIR}/references/template.md` for the base skeleton. Copy it and keep only what the task needs.
|
|
13
|
-
|
|
14
|
-
## Guards
|
|
15
|
-
|
|
16
|
-
- Estimate the script's length before writing any of it. When it will run past 100 lines, stop and write it in TypeScript on Bun instead, saying the threshold is the one the [Google Shell Style Guide](https://google.github.io/styleguide/shellguide.html) sets: "If you are writing a script that is more than 100 lines long ... you should rewrite it in a more structured language now". Stopping after generating wastes the draft and leaves a long script to argue against.
|
|
17
|
-
- A request for interactive prompts, a framed timeline, icons, or color stops the same way. Say that a tool a person drives is past what a wrapper is for, and offer the TypeScript route rather than generating a script with prompts.
|
|
18
|
-
- Editing an existing shell file already over 100 lines is not a new script. Edit it in place without growing it, and flag it for a rewrite rather than rewriting it on contact.
|
|
19
|
-
|
|
20
|
-
## Script setup
|
|
21
|
-
|
|
22
|
-
- Start with `#!/usr/bin/env bash` and `set -euo pipefail`.
|
|
23
|
-
- Do not rely on unset variables. Use `${VAR:-default}`.
|
|
24
|
-
|
|
25
|
-
## Output contract
|
|
26
|
-
|
|
27
|
-
- Write data to stdout. Write logs, progress, and errors to stderr.
|
|
28
|
-
- Keep stdout clean so the script composes in a pipe.
|
|
29
|
-
- Do not emit timeline frames, icons, or color.
|
|
30
|
-
|
|
31
|
-
## Error handling
|
|
32
|
-
|
|
33
|
-
- Define `die()` that prints an error to stderr and exits non-zero.
|
|
34
|
-
- Include actionable context in error messages.
|
|
35
|
-
- Guard commands that return non-zero on a valid empty result with `|| true`.
|
|
36
|
-
- Set explicit exit codes. Reserve 0 for success.
|
|
37
|
-
- Read a called command's machine-readable record where it emits one. An exit status separates success from failure and never names which failure, so a script routing on the reason reads the record and keeps the exit for the pass-fail decision alone.
|
|
38
|
-
|
|
39
|
-
## Code style
|
|
40
|
-
|
|
41
|
-
- Quote variables in expansions and test brackets.
|
|
42
|
-
- Comment only a fact the reader cannot recover from the code, and follow the code-comment rule in `.claude/rules/` when the project installs it.
|
|
43
|
-
- Use 2-space indentation.
|
|
44
|
-
|
|
45
|
-
## Validation
|
|
46
|
-
|
|
47
|
-
Before responding, verify:
|
|
48
|
-
|
|
49
|
-
- The script is 100 lines or fewer.
|
|
50
|
-
- File starts with `#!/usr/bin/env bash` and `set -euo pipefail`.
|
|
51
|
-
- Data goes to stdout, logs and errors go to stderr.
|
|
52
|
-
- No timeline frames, icons, or interactive prompts.
|
|
53
|
-
- Errors exit non-zero with context through `die()`.
|