create-claude-cabinet 0.6.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/LICENSE +21 -0
- package/README.md +196 -0
- package/bin/create-claude-cabinet.js +8 -0
- package/lib/cli.js +624 -0
- package/lib/copy.js +152 -0
- package/lib/db-setup.js +51 -0
- package/lib/metadata.js +42 -0
- package/lib/reset.js +193 -0
- package/lib/settings-merge.js +93 -0
- package/package.json +29 -0
- package/templates/EXTENSIONS.md +311 -0
- package/templates/README.md +485 -0
- package/templates/briefing/_briefing-api-template.md +21 -0
- package/templates/briefing/_briefing-architecture-template.md +16 -0
- package/templates/briefing/_briefing-cabinet-template.md +20 -0
- package/templates/briefing/_briefing-identity-template.md +18 -0
- package/templates/briefing/_briefing-scopes-template.md +39 -0
- package/templates/briefing/_briefing-template.md +148 -0
- package/templates/briefing/_briefing-work-tracking-template.md +18 -0
- package/templates/cabinet/committees-template.yaml +49 -0
- package/templates/cabinet/composition-patterns.md +240 -0
- package/templates/cabinet/eval-protocol.md +208 -0
- package/templates/cabinet/lifecycle.md +93 -0
- package/templates/cabinet/output-contract.md +148 -0
- package/templates/cabinet/prompt-guide.md +266 -0
- package/templates/hooks/cor-upstream-guard.sh +79 -0
- package/templates/hooks/git-guardrails.sh +67 -0
- package/templates/hooks/skill-telemetry.sh +66 -0
- package/templates/hooks/skill-tool-telemetry.sh +54 -0
- package/templates/hooks/stop-hook.md +56 -0
- package/templates/memory/patterns/_pattern-template.md +119 -0
- package/templates/memory/patterns/pattern-intelligence-first.md +41 -0
- package/templates/rules/enforcement-pipeline.md +151 -0
- package/templates/scripts/cor-drift-check.cjs +84 -0
- package/templates/scripts/finding-schema.json +94 -0
- package/templates/scripts/load-triage-history.js +151 -0
- package/templates/scripts/merge-findings.js +126 -0
- package/templates/scripts/pib-db-schema.sql +68 -0
- package/templates/scripts/pib-db.js +365 -0
- package/templates/scripts/triage-server.mjs +98 -0
- package/templates/scripts/triage-ui.html +536 -0
- package/templates/skills/audit/SKILL.md +273 -0
- package/templates/skills/audit/phases/finding-output.md +56 -0
- package/templates/skills/audit/phases/member-execution.md +83 -0
- package/templates/skills/audit/phases/member-selection.md +44 -0
- package/templates/skills/audit/phases/structural-checks.md +54 -0
- package/templates/skills/audit/phases/triage-history.md +45 -0
- package/templates/skills/cabinet-accessibility/SKILL.md +180 -0
- package/templates/skills/cabinet-anti-confirmation/SKILL.md +172 -0
- package/templates/skills/cabinet-architecture/SKILL.md +279 -0
- package/templates/skills/cabinet-boundary-man/SKILL.md +265 -0
- package/templates/skills/cabinet-cor-health/SKILL.md +342 -0
- package/templates/skills/cabinet-data-integrity/SKILL.md +157 -0
- package/templates/skills/cabinet-debugger/SKILL.md +221 -0
- package/templates/skills/cabinet-historian/SKILL.md +253 -0
- package/templates/skills/cabinet-organized-mind/SKILL.md +338 -0
- package/templates/skills/cabinet-process-therapist/SKILL.md +261 -0
- package/templates/skills/cabinet-qa/SKILL.md +205 -0
- package/templates/skills/cabinet-record-keeper/SKILL.md +168 -0
- package/templates/skills/cabinet-roster-check/SKILL.md +297 -0
- package/templates/skills/cabinet-security/SKILL.md +181 -0
- package/templates/skills/cabinet-small-screen/SKILL.md +154 -0
- package/templates/skills/cabinet-speed-freak/SKILL.md +169 -0
- package/templates/skills/cabinet-system-advocate/SKILL.md +194 -0
- package/templates/skills/cabinet-technical-debt/SKILL.md +115 -0
- package/templates/skills/cabinet-usability/SKILL.md +189 -0
- package/templates/skills/cabinet-workflow-cop/SKILL.md +238 -0
- package/templates/skills/cor-upgrade/SKILL.md +302 -0
- package/templates/skills/debrief/SKILL.md +409 -0
- package/templates/skills/debrief/phases/auto-maintenance.md +48 -0
- package/templates/skills/debrief/phases/close-work.md +88 -0
- package/templates/skills/debrief/phases/health-checks.md +54 -0
- package/templates/skills/debrief/phases/inventory.md +40 -0
- package/templates/skills/debrief/phases/loose-ends.md +52 -0
- package/templates/skills/debrief/phases/record-lessons.md +67 -0
- package/templates/skills/debrief/phases/report.md +59 -0
- package/templates/skills/debrief/phases/update-state.md +48 -0
- package/templates/skills/debrief/phases/upstream-feedback.md +129 -0
- package/templates/skills/debrief-quick/SKILL.md +12 -0
- package/templates/skills/execute/SKILL.md +293 -0
- package/templates/skills/execute/phases/cabinet.md +49 -0
- package/templates/skills/execute/phases/commit-and-deploy.md +66 -0
- package/templates/skills/execute/phases/load-plan.md +49 -0
- package/templates/skills/execute/phases/validators.md +50 -0
- package/templates/skills/execute/phases/verification-tools.md +67 -0
- package/templates/skills/extract/SKILL.md +168 -0
- package/templates/skills/investigate/SKILL.md +160 -0
- package/templates/skills/link/SKILL.md +52 -0
- package/templates/skills/menu/SKILL.md +61 -0
- package/templates/skills/onboard/SKILL.md +356 -0
- package/templates/skills/onboard/phases/detect-state.md +79 -0
- package/templates/skills/onboard/phases/generate-briefing.md +127 -0
- package/templates/skills/onboard/phases/generate-session-loop.md +87 -0
- package/templates/skills/onboard/phases/interview.md +233 -0
- package/templates/skills/onboard/phases/modularity-menu.md +162 -0
- package/templates/skills/onboard/phases/options.md +98 -0
- package/templates/skills/onboard/phases/post-onboard-audit.md +121 -0
- package/templates/skills/onboard/phases/summary.md +122 -0
- package/templates/skills/onboard/phases/work-tracking.md +231 -0
- package/templates/skills/orient/SKILL.md +251 -0
- package/templates/skills/orient/phases/auto-maintenance.md +48 -0
- package/templates/skills/orient/phases/briefing.md +53 -0
- package/templates/skills/orient/phases/cabinet.md +46 -0
- package/templates/skills/orient/phases/context.md +63 -0
- package/templates/skills/orient/phases/data-sync.md +35 -0
- package/templates/skills/orient/phases/health-checks.md +50 -0
- package/templates/skills/orient/phases/work-scan.md +69 -0
- package/templates/skills/orient-quick/SKILL.md +12 -0
- package/templates/skills/plan/SKILL.md +358 -0
- package/templates/skills/plan/phases/cabinet-critique.md +47 -0
- package/templates/skills/plan/phases/calibration-examples.md +75 -0
- package/templates/skills/plan/phases/completeness-check.md +44 -0
- package/templates/skills/plan/phases/composition-check.md +36 -0
- package/templates/skills/plan/phases/overlap-check.md +62 -0
- package/templates/skills/plan/phases/plan-template.md +69 -0
- package/templates/skills/plan/phases/present.md +60 -0
- package/templates/skills/plan/phases/research.md +43 -0
- package/templates/skills/plan/phases/work-tracker.md +95 -0
- package/templates/skills/publish/SKILL.md +74 -0
- package/templates/skills/pulse/SKILL.md +242 -0
- package/templates/skills/pulse/phases/auto-fix-scope.md +40 -0
- package/templates/skills/pulse/phases/checks.md +58 -0
- package/templates/skills/pulse/phases/output.md +54 -0
- package/templates/skills/seed/SKILL.md +257 -0
- package/templates/skills/seed/phases/build-member.md +93 -0
- package/templates/skills/seed/phases/evaluate-existing.md +61 -0
- package/templates/skills/seed/phases/maintain.md +92 -0
- package/templates/skills/seed/phases/scan-signals.md +86 -0
- package/templates/skills/triage-audit/SKILL.md +251 -0
- package/templates/skills/triage-audit/phases/apply-verdicts.md +90 -0
- package/templates/skills/triage-audit/phases/load-findings.md +38 -0
- package/templates/skills/triage-audit/phases/triage-ui.md +66 -0
- package/templates/skills/unlink/SKILL.md +35 -0
- package/templates/skills/validate/SKILL.md +116 -0
- package/templates/skills/validate/phases/validators.md +53 -0
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# UserPromptSubmit hook for skill telemetry
|
|
3
|
+
# Detects /skill-name invocations and logs to JSONL
|
|
4
|
+
#
|
|
5
|
+
# Configuration (environment variables with defaults):
|
|
6
|
+
# TELEMETRY_FILE — where to write JSONL records
|
|
7
|
+
# DEBUG_LOG — where to write debug output
|
|
8
|
+
# SKILL_DIR — where to discover skills (scans */SKILL.md)
|
|
9
|
+
|
|
10
|
+
TELEMETRY_DIR="${TELEMETRY_DIR:-${HOME}/.claude/telemetry}"
|
|
11
|
+
TELEMETRY_FILE="${TELEMETRY_FILE:-${TELEMETRY_DIR}/telemetry.jsonl}"
|
|
12
|
+
DEBUG_LOG="${DEBUG_LOG:-${TELEMETRY_DIR}/hook-debug.log}"
|
|
13
|
+
SKILL_DIR="${SKILL_DIR:-${HOME}/.claude/skills}"
|
|
14
|
+
|
|
15
|
+
# Ensure telemetry directory exists
|
|
16
|
+
mkdir -p "$(dirname "$TELEMETRY_FILE")"
|
|
17
|
+
mkdir -p "$(dirname "$DEBUG_LOG")"
|
|
18
|
+
|
|
19
|
+
# Auto-discover skill names from skills/*/SKILL.md
|
|
20
|
+
SKILLS=""
|
|
21
|
+
for skill_path in "$SKILL_DIR"/*/SKILL.md; do
|
|
22
|
+
[ -f "$skill_path" ] || continue
|
|
23
|
+
skill=$(basename "$(dirname "$skill_path")")
|
|
24
|
+
[ "$skill" = "perspectives" ] && continue
|
|
25
|
+
[ "$skill" = "_template" ] && continue
|
|
26
|
+
SKILLS="$SKILLS $skill"
|
|
27
|
+
done
|
|
28
|
+
|
|
29
|
+
# Read hook input from stdin, extract prompt and session_id
|
|
30
|
+
INPUT=$(cat)
|
|
31
|
+
eval "$(echo "$INPUT" | python3 -c "
|
|
32
|
+
import sys, json, shlex
|
|
33
|
+
try:
|
|
34
|
+
data = json.load(sys.stdin)
|
|
35
|
+
print(f'PROMPT={shlex.quote(data.get(\"prompt\", \"\"))}')
|
|
36
|
+
print(f'SESSION_ID={shlex.quote(data.get(\"session_id\", \"unknown\"))}')
|
|
37
|
+
except:
|
|
38
|
+
print('PROMPT=\"\"')
|
|
39
|
+
print('SESSION_ID=\"unknown\"')
|
|
40
|
+
" 2>/dev/null)"
|
|
41
|
+
|
|
42
|
+
# Check if prompt starts with a slash command
|
|
43
|
+
if [[ "$PROMPT" =~ ^/([a-z-]+) ]]; then
|
|
44
|
+
COMMAND="${BASH_REMATCH[1]}"
|
|
45
|
+
|
|
46
|
+
# Check if it's a known skill
|
|
47
|
+
for skill in $SKILLS; do
|
|
48
|
+
if [[ "$COMMAND" == "$skill" ]]; then
|
|
49
|
+
TIMESTAMP=$(date -u '+%Y-%m-%dT%H:%M:%SZ')
|
|
50
|
+
python3 -c "
|
|
51
|
+
import json
|
|
52
|
+
record = {
|
|
53
|
+
'ts': '$TIMESTAMP',
|
|
54
|
+
'event': 'skill-invoke',
|
|
55
|
+
'skill': '$COMMAND',
|
|
56
|
+
'session_id': '$SESSION_ID'
|
|
57
|
+
}
|
|
58
|
+
print(json.dumps(record))
|
|
59
|
+
" >> "$TELEMETRY_FILE"
|
|
60
|
+
echo "--- skill-telemetry $TIMESTAMP skill=$COMMAND ---" >> "$DEBUG_LOG"
|
|
61
|
+
break
|
|
62
|
+
fi
|
|
63
|
+
done
|
|
64
|
+
fi
|
|
65
|
+
|
|
66
|
+
exit 0
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# PostToolUse hook for Skill tool telemetry
|
|
3
|
+
# Captures programmatic Skill invocations (not user-typed /slash-commands)
|
|
4
|
+
# Complements skill-telemetry.sh (UserPromptSubmit) for full coverage
|
|
5
|
+
#
|
|
6
|
+
# Configuration (environment variables with defaults):
|
|
7
|
+
# TELEMETRY_FILE — where to write JSONL records
|
|
8
|
+
# DEBUG_LOG — where to write debug output
|
|
9
|
+
|
|
10
|
+
TELEMETRY_DIR="${TELEMETRY_DIR:-${HOME}/.claude/telemetry}"
|
|
11
|
+
TELEMETRY_FILE="${TELEMETRY_FILE:-${TELEMETRY_DIR}/telemetry.jsonl}"
|
|
12
|
+
DEBUG_LOG="${DEBUG_LOG:-${TELEMETRY_DIR}/hook-debug.log}"
|
|
13
|
+
|
|
14
|
+
# Ensure telemetry directory exists
|
|
15
|
+
mkdir -p "$(dirname "$TELEMETRY_FILE")"
|
|
16
|
+
mkdir -p "$(dirname "$DEBUG_LOG")"
|
|
17
|
+
|
|
18
|
+
# Read hook input from stdin
|
|
19
|
+
INPUT=$(cat)
|
|
20
|
+
|
|
21
|
+
# Extract skill name and session_id from the tool input
|
|
22
|
+
eval "$(echo "$INPUT" | python3 -c "
|
|
23
|
+
import sys, json, shlex
|
|
24
|
+
try:
|
|
25
|
+
data = json.load(sys.stdin)
|
|
26
|
+
tool_input = data.get('tool_input', {})
|
|
27
|
+
if isinstance(tool_input, str):
|
|
28
|
+
tool_input = json.loads(tool_input)
|
|
29
|
+
skill = tool_input.get('skill', '')
|
|
30
|
+
session_id = data.get('session_id', 'unknown')
|
|
31
|
+
print(f'SKILL={shlex.quote(skill)}')
|
|
32
|
+
print(f'SESSION_ID={shlex.quote(session_id)}')
|
|
33
|
+
except:
|
|
34
|
+
print('SKILL=\"\"')
|
|
35
|
+
print('SESSION_ID=\"unknown\"')
|
|
36
|
+
" 2>/dev/null)"
|
|
37
|
+
|
|
38
|
+
if [[ -n "$SKILL" ]]; then
|
|
39
|
+
TIMESTAMP=$(date -u '+%Y-%m-%dT%H:%M:%SZ')
|
|
40
|
+
python3 -c "
|
|
41
|
+
import json
|
|
42
|
+
record = {
|
|
43
|
+
'ts': '$TIMESTAMP',
|
|
44
|
+
'event': 'skill-invoke',
|
|
45
|
+
'skill': '$SKILL',
|
|
46
|
+
'source': 'tool',
|
|
47
|
+
'session_id': '$SESSION_ID'
|
|
48
|
+
}
|
|
49
|
+
print(json.dumps(record))
|
|
50
|
+
" >> "$TELEMETRY_FILE"
|
|
51
|
+
echo "--- skill-tool-telemetry $TIMESTAMP skill=$SKILL ---" >> "$DEBUG_LOG"
|
|
52
|
+
fi
|
|
53
|
+
|
|
54
|
+
exit 0
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# Stop Hook Template
|
|
2
|
+
|
|
3
|
+
The Stop hook fires when a session is ending. It checks whether
|
|
4
|
+
substantive work was done without running the session-closing skill
|
|
5
|
+
(e.g., `/debrief`). If yes, it prompts to run it.
|
|
6
|
+
|
|
7
|
+
## How to Install
|
|
8
|
+
|
|
9
|
+
Add this to your `.claude/settings.json` under the `hooks` key:
|
|
10
|
+
|
|
11
|
+
```json
|
|
12
|
+
{
|
|
13
|
+
"hooks": {
|
|
14
|
+
"Stop": [
|
|
15
|
+
{
|
|
16
|
+
"matcher": "",
|
|
17
|
+
"hooks": [
|
|
18
|
+
{
|
|
19
|
+
"type": "prompt",
|
|
20
|
+
"prompt": "Check if substantive work was done without running the session-closing skill. If yes, prompt to run it.",
|
|
21
|
+
"statusMessage": "Checking session close compliance..."
|
|
22
|
+
}
|
|
23
|
+
]
|
|
24
|
+
}
|
|
25
|
+
]
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## How It Works
|
|
31
|
+
|
|
32
|
+
- **Event:** `Stop` — fires when the user ends the session
|
|
33
|
+
- **Type:** `prompt` — an LLM-evaluated check, not a deterministic script
|
|
34
|
+
- **Compliance:** ~80% — prompt-type hooks are advisory, not blocking
|
|
35
|
+
|
|
36
|
+
## Customization
|
|
37
|
+
|
|
38
|
+
Replace the prompt text with your project's specific closing skill name:
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
"Check if substantive work was done without /debrief. If yes, prompt to run it."
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
This is the single most important anti-entropy hook in the methodology.
|
|
45
|
+
Without it, sessions end without capturing what happened, and the next
|
|
46
|
+
session starts blind. The session loop (orient → work → debrief) is the
|
|
47
|
+
system's learning mechanism. This hook guards the debrief step.
|
|
48
|
+
|
|
49
|
+
## Limitations
|
|
50
|
+
|
|
51
|
+
This is a prompt-type hook, not a command hook. It asks the LLM to check
|
|
52
|
+
and prompt — it doesn't deterministically block the session from ending.
|
|
53
|
+
Compliance is imperfect. This is an honest example of the anti-entropy
|
|
54
|
+
principle in action: debrief compliance has been a recurring friction
|
|
55
|
+
point in the reference implementation, promoted to a hook. It's better
|
|
56
|
+
than without. It's not 100%.
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
# Pattern File Format Template
|
|
2
|
+
|
|
3
|
+
This documents the frontmatter schema for feedback patterns — the
|
|
4
|
+
reusable structure for any project's feedback-to-enforcement pipeline.
|
|
5
|
+
|
|
6
|
+
## How Patterns Work
|
|
7
|
+
|
|
8
|
+
Patterns consolidate recurring observations (friction, mistakes, things
|
|
9
|
+
that worked) into named rules with enforcement classification. They are
|
|
10
|
+
the intermediate step between raw feedback captures and enforced rules.
|
|
11
|
+
|
|
12
|
+
## The Schema
|
|
13
|
+
|
|
14
|
+
```yaml
|
|
15
|
+
---
|
|
16
|
+
name: pattern-descriptive-name
|
|
17
|
+
description: >
|
|
18
|
+
One-line description of what this pattern captures. Should be specific
|
|
19
|
+
enough to decide relevance without reading the full content.
|
|
20
|
+
type: pattern
|
|
21
|
+
sources:
|
|
22
|
+
- feedback-observation-that-led-to-this.md
|
|
23
|
+
- another-observation.md
|
|
24
|
+
- a-third-observation.md
|
|
25
|
+
enforcement: guide | detect | prevent | document
|
|
26
|
+
promotion_candidates:
|
|
27
|
+
- rule-or-hook-name-if-ready-for-promotion
|
|
28
|
+
---
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Fields
|
|
32
|
+
|
|
33
|
+
### `name`
|
|
34
|
+
Descriptive slug. Convention: `pattern-{domain}-{topic}` or just
|
|
35
|
+
`pattern-{topic}`.
|
|
36
|
+
|
|
37
|
+
### `description`
|
|
38
|
+
One-line summary. Used by orient/debrief to decide whether to load
|
|
39
|
+
the full pattern. Be specific — "deployment issues" is too vague;
|
|
40
|
+
"silent deployment failures and stale build log output" is useful.
|
|
41
|
+
|
|
42
|
+
### `type`
|
|
43
|
+
Always `pattern` for consolidated feedback patterns.
|
|
44
|
+
|
|
45
|
+
### `sources`
|
|
46
|
+
List of raw observation files that were consolidated into this pattern.
|
|
47
|
+
Preserves provenance — you can trace any rule back to the specific
|
|
48
|
+
incidents that motivated it.
|
|
49
|
+
|
|
50
|
+
### `enforcement`
|
|
51
|
+
How this pattern should be enforced. Determines promotion target:
|
|
52
|
+
|
|
53
|
+
| Value | Meaning | Compliance | Promotion Target |
|
|
54
|
+
|-------|---------|------------|-----------------|
|
|
55
|
+
| **guide** | Prompt context (CLAUDE.md or memory) | ~60-80% | Rules file or CLAUDE.md section |
|
|
56
|
+
| **detect** | Validation script or PostToolUse hook | ~80-90% | Validation script |
|
|
57
|
+
| **prevent** | PreToolUse hook or pre-commit hook | ~100% | Deterministic hook |
|
|
58
|
+
| **document** | Reference material, not a rule | N/A | Documentation |
|
|
59
|
+
|
|
60
|
+
### `promotion_candidates`
|
|
61
|
+
Specific rules within this pattern that are ready to move up the
|
|
62
|
+
compliance stack. Empty list `[]` if nothing is ready for promotion.
|
|
63
|
+
|
|
64
|
+
## Body Structure
|
|
65
|
+
|
|
66
|
+
After the frontmatter, the body follows this structure:
|
|
67
|
+
|
|
68
|
+
```markdown
|
|
69
|
+
## Principle
|
|
70
|
+
|
|
71
|
+
One paragraph: the core lesson this pattern encodes.
|
|
72
|
+
|
|
73
|
+
## Rules
|
|
74
|
+
|
|
75
|
+
- Concrete, actionable rules derived from the principle.
|
|
76
|
+
- Each rule should be testable — you can tell whether it was followed.
|
|
77
|
+
|
|
78
|
+
## When This Applies
|
|
79
|
+
|
|
80
|
+
When to apply these rules (triggers, file types, situations).
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Example
|
|
84
|
+
|
|
85
|
+
```yaml
|
|
86
|
+
---
|
|
87
|
+
name: pattern-deployment-verification
|
|
88
|
+
description: >
|
|
89
|
+
Silent deployment failures and stale CLI output — always verify
|
|
90
|
+
deployments through authoritative sources, not just CLI success messages.
|
|
91
|
+
type: pattern
|
|
92
|
+
sources:
|
|
93
|
+
- feedback-railway-stale-logs.md
|
|
94
|
+
- feedback-deploy-without-verify.md
|
|
95
|
+
- feedback-silent-build-failure.md
|
|
96
|
+
enforcement: detect
|
|
97
|
+
promotion_candidates:
|
|
98
|
+
- post-deploy-verification-hook
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## Principle
|
|
102
|
+
|
|
103
|
+
Deployment tools report success based on submission, not outcome. The
|
|
104
|
+
CLI saying "deployed" means "I sent the request," not "it's running."
|
|
105
|
+
Always verify through the deployment platform's authoritative source.
|
|
106
|
+
|
|
107
|
+
## Rules
|
|
108
|
+
|
|
109
|
+
- After every deploy, verify the change is live (hit the endpoint,
|
|
110
|
+
check the dashboard, read the build log from the platform itself).
|
|
111
|
+
- If the CLI build log is stale, use the web dashboard as fallback.
|
|
112
|
+
- Never assume a deploy worked because the command exited 0.
|
|
113
|
+
|
|
114
|
+
## When This Applies
|
|
115
|
+
|
|
116
|
+
Any deployment to a remote platform (Railway, Vercel, AWS, etc.).
|
|
117
|
+
Also applies to LaunchAgent restarts and any operation where the
|
|
118
|
+
success indicator is decoupled from the actual outcome.
|
|
119
|
+
```
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: pattern-intelligence-first
|
|
3
|
+
description: Intelligence over regex — use structured JSON between tools, don't let regex gatekeep LLM access, research thoroughly before coding
|
|
4
|
+
type: pattern
|
|
5
|
+
sources:
|
|
6
|
+
- feedback-intelligence-vs-regex.md
|
|
7
|
+
- feedback-intelligence-not-regex.md
|
|
8
|
+
- feedback-research-before-iterating.md
|
|
9
|
+
- feedback-use-framework-docs-mcp.md
|
|
10
|
+
enforcement: guide
|
|
11
|
+
promotion_candidates: []
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Principle
|
|
15
|
+
|
|
16
|
+
When the task is semantic (understanding structure, classifying items,
|
|
17
|
+
extracting meaning), regex is the wrong tool. It creates brittle parsers
|
|
18
|
+
that break on edge cases the author didn't anticipate. Similarly, when
|
|
19
|
+
building detection or integration features, blind iteration wastes hours
|
|
20
|
+
that 30 minutes of research would have saved. **Use intelligence for
|
|
21
|
+
semantic work and research for unfamiliar territory.**
|
|
22
|
+
|
|
23
|
+
## Rules
|
|
24
|
+
|
|
25
|
+
- **Use structured output (JSON) not brittle delimiter parsing** for
|
|
26
|
+
tool-to-tool data pipelines. When an LLM produces output that another
|
|
27
|
+
tool consumes, use JSON — never regex over free text.
|
|
28
|
+
- **Never let regex gatekeep LLM access to content.** If content needs
|
|
29
|
+
semantic understanding, try focused LLM extraction first, fall back to
|
|
30
|
+
full content only if needed.
|
|
31
|
+
- **Research thoroughly before coding** detection/integration features.
|
|
32
|
+
Don't iterate blind — 30 minutes of research saves hours of wrong
|
|
33
|
+
approaches.
|
|
34
|
+
- **Check framework-docs MCP before web-searching.** If a library/service
|
|
35
|
+
has an `llms.txt`, add it to `.mcp.json`. The docs are faster and more
|
|
36
|
+
accurate than web search.
|
|
37
|
+
|
|
38
|
+
## When This Applies
|
|
39
|
+
|
|
40
|
+
When building parsers, data pipelines between tools, content extraction
|
|
41
|
+
systems, or any feature that integrates with unfamiliar APIs or platforms.
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
# Enforcement Pipeline
|
|
2
|
+
|
|
3
|
+
Rules don't arrive fully formed. They start as friction — something went
|
|
4
|
+
wrong, someone noticed, it got written down. This pipeline turns friction
|
|
5
|
+
into structure over time.
|
|
6
|
+
|
|
7
|
+
## The Compliance Stack
|
|
8
|
+
|
|
9
|
+
Not all rules need the same enforcement. The stack gives each rule a
|
|
10
|
+
natural home based on two questions: *Can it be checked mechanically?*
|
|
11
|
+
and *What's the cost of violation?*
|
|
12
|
+
|
|
13
|
+
| Layer | Mechanism | Compliance | Best For |
|
|
14
|
+
| -------------- | --------------------------- | ---------- | ---------------------------------- |
|
|
15
|
+
| CLAUDE.md | Prompt context | ~60-80% | Intent, heuristics, judgment calls |
|
|
16
|
+
| .claude/rules/ | Scoped prompt | ~80% | Path-specific constraints |
|
|
17
|
+
| Hooks | Deterministic shell scripts | ~100% | Hard guardrails |
|
|
18
|
+
|
|
19
|
+
A principle like "ask rather than assume when something affects
|
|
20
|
+
correctness" belongs in CLAUDE.md. It requires judgment. A rule like
|
|
21
|
+
"never commit without a fid tag" belongs in a hook. It's deterministic,
|
|
22
|
+
and the consequence of violating it is severe.
|
|
23
|
+
|
|
24
|
+
**The best enforcement isn't enforcement at all — it's structural
|
|
25
|
+
encoding that makes the wrong thing impossible.** A pre-commit hook
|
|
26
|
+
doesn't remind you to do something. It blocks the commit until the
|
|
27
|
+
condition is met. The wrong state can't enter the system. When you can
|
|
28
|
+
encode a rule structurally (API rejects invalid input, schema enforces
|
|
29
|
+
constraints), prefer that over any compliance layer.
|
|
30
|
+
|
|
31
|
+
## Pipeline Stages
|
|
32
|
+
|
|
33
|
+
### 1. Capture (every session, during debrief)
|
|
34
|
+
|
|
35
|
+
Record what went wrong or what worked unexpectedly. Raw observations,
|
|
36
|
+
not polished rules.
|
|
37
|
+
|
|
38
|
+
- Save to memory or a feedback directory (raw observation files)
|
|
39
|
+
- Check if it fits an existing pattern:
|
|
40
|
+
- **MERGE** — same ground as an existing pattern → update that pattern
|
|
41
|
+
- **KEEP_SEPARATE** — distinct observation → stays as individual file
|
|
42
|
+
- **REPLACE** — supersedes an existing observation → remove old
|
|
43
|
+
- **UPDATE** — enriches an existing pattern → add to pattern's evidence
|
|
44
|
+
- If 3+ related observations accumulate without a pattern, create one
|
|
45
|
+
|
|
46
|
+
### 2. Classify (at capture time)
|
|
47
|
+
|
|
48
|
+
Every observation or pattern gets an enforcement type:
|
|
49
|
+
|
|
50
|
+
- **prevent** — candidate for a hook (~100% compliance needed)
|
|
51
|
+
- **detect** — candidate for a validation script or post-action check
|
|
52
|
+
- **guide** — stays as prompt context (CLAUDE.md or rules file)
|
|
53
|
+
- **document** — reference material, not a rule
|
|
54
|
+
|
|
55
|
+
Classification drives what promotion means for that pattern.
|
|
56
|
+
|
|
57
|
+
### 3. Promote (periodic review)
|
|
58
|
+
|
|
59
|
+
When observations about the same class of problem accumulate, they
|
|
60
|
+
consolidate into a pattern and may move up the compliance stack.
|
|
61
|
+
|
|
62
|
+
**Promotion criteria are intelligence, not thresholds.** There is no
|
|
63
|
+
magic number of observations that triggers promotion. One catastrophic
|
|
64
|
+
incident can justify immediate promotion to a hook. A dozen minor
|
|
65
|
+
annoyances might stay as guidance forever. The human decides what to
|
|
66
|
+
promote and when, informed by severity and pattern, not by count.
|
|
67
|
+
|
|
68
|
+
Promotion moves a rule up the stack:
|
|
69
|
+
- CLAUDE.md guidance → `.claude/rules/` file (scoped, more reliable)
|
|
70
|
+
- Rules file → hook (deterministic, ~100% compliance)
|
|
71
|
+
- Any layer → structural encoding (makes the wrong thing impossible)
|
|
72
|
+
|
|
73
|
+
### 4. Encode (after promotion approval)
|
|
74
|
+
|
|
75
|
+
Implement the promoted rule at its target layer:
|
|
76
|
+
- **CLAUDE.md promotion:** Add to root CLAUDE.md or create/update a
|
|
77
|
+
`.claude/rules/` file
|
|
78
|
+
- **Hook promotion:** Add to `.claude/settings.json` hooks section.
|
|
79
|
+
Command hooks for deterministic checks, prompt hooks for semantic
|
|
80
|
+
evaluation.
|
|
81
|
+
- **Structural encoding:** Modify API, schema, or validation to reject
|
|
82
|
+
invalid states directly
|
|
83
|
+
|
|
84
|
+
### 5. Monitor (ongoing)
|
|
85
|
+
|
|
86
|
+
Are the rules working?
|
|
87
|
+
- Are hooks firing correctly?
|
|
88
|
+
- Is the same friction appearing despite encoding? (If yes, the
|
|
89
|
+
encoding is wrong — either the rule is at the wrong layer or the
|
|
90
|
+
implementation doesn't catch the actual failure mode.)
|
|
91
|
+
- Are there dead rules? (Rules that reference files or patterns that
|
|
92
|
+
no longer exist.)
|
|
93
|
+
- Is unabsorbed feedback accumulating without being consolidated?
|
|
94
|
+
|
|
95
|
+
## Pattern File Format
|
|
96
|
+
|
|
97
|
+
Use the pattern template in `memory/patterns/_pattern-template.md` for
|
|
98
|
+
capturing consolidated patterns. Each pattern file has frontmatter with
|
|
99
|
+
the enforcement type, sources (raw observations that fed into it), and
|
|
100
|
+
promotion candidates (specific rules ready for promotion).
|
|
101
|
+
|
|
102
|
+
## Where Each Step Lives
|
|
103
|
+
|
|
104
|
+
| Step | Owner | When |
|
|
105
|
+
|------|-------|------|
|
|
106
|
+
| Capture + Classify | /debrief | Every session |
|
|
107
|
+
| Pattern analysis | Periodic review | As feedback accumulates |
|
|
108
|
+
| Promotion checkpoint | Review cadence | When patterns mature |
|
|
109
|
+
| Enforcement health | /orient or /pulse | Regular check |
|
|
110
|
+
|
|
111
|
+
## Audit Findings as Promotion Input
|
|
112
|
+
|
|
113
|
+
The audit system feeds the enforcement pipeline. When the same type of
|
|
114
|
+
finding keeps getting approved across multiple audit runs, it signals a
|
|
115
|
+
recurring problem that detection alone isn't solving. That's a promotion
|
|
116
|
+
candidate.
|
|
117
|
+
|
|
118
|
+
**The virtuous cycle:** Audit detects a pattern → triage approves it →
|
|
119
|
+
the fix is applied → the same finding appears again next audit → this
|
|
120
|
+
time, instead of just fixing it again, the pattern gets promoted to a
|
|
121
|
+
rule or hook that *prevents* it from recurring. The audit catches
|
|
122
|
+
problems; the enforcement pipeline prevents them.
|
|
123
|
+
|
|
124
|
+
**Signals that a finding should become a rule:**
|
|
125
|
+
- Same finding (or same class of finding) approved in 3+ audit runs
|
|
126
|
+
- Finding addresses something mechanically checkable (could be a hook)
|
|
127
|
+
- Finding addresses something that requires judgment but has a clear
|
|
128
|
+
principle (could be a CLAUDE.md rule or `.claude/rules/` file)
|
|
129
|
+
- The cost of violation is high enough to justify enforcement
|
|
130
|
+
|
|
131
|
+
**Signals that a finding should stay a finding:**
|
|
132
|
+
- One-time issue that was fixed and won't recur
|
|
133
|
+
- Context-dependent — the right answer changes each time
|
|
134
|
+
- Low severity — enforcement overhead exceeds violation cost
|
|
135
|
+
|
|
136
|
+
The audit skill's triage history tracks which findings recur. The
|
|
137
|
+
enforcement pipeline's pattern files track which recurring findings are
|
|
138
|
+
ready for promotion. Together, they create a feedback loop from
|
|
139
|
+
observation to prevention.
|
|
140
|
+
|
|
141
|
+
## Current State
|
|
142
|
+
|
|
143
|
+
<!--
|
|
144
|
+
Track your project's enforcement pipeline state here:
|
|
145
|
+
|
|
146
|
+
- **N pattern files** in memory/patterns/
|
|
147
|
+
- **N raw observations** in memory/archive/ (or wherever you store them)
|
|
148
|
+
- **N rules files** in .claude/rules/
|
|
149
|
+
- **N hooks** in .claude/settings.json
|
|
150
|
+
- **N promotion candidates** identified
|
|
151
|
+
-->
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// CoR Drift Check — detect modified upstream-managed files
|
|
3
|
+
//
|
|
4
|
+
// Compares current file hashes against .corrc.json manifest hashes.
|
|
5
|
+
// Reports files that have been modified since install (drift).
|
|
6
|
+
//
|
|
7
|
+
// Usage:
|
|
8
|
+
// node scripts/cor-drift-check.js # exit 0 if clean, 1 if drift
|
|
9
|
+
// node scripts/cor-drift-check.js --json # output JSON for programmatic use
|
|
10
|
+
// node scripts/cor-drift-check.js --fix # show what /cor-upgrade would fix
|
|
11
|
+
|
|
12
|
+
const fs = require('fs');
|
|
13
|
+
const path = require('path');
|
|
14
|
+
const crypto = require('crypto');
|
|
15
|
+
|
|
16
|
+
const projectRoot = findProjectRoot();
|
|
17
|
+
if (!projectRoot) {
|
|
18
|
+
console.error('No .corrc.json found — not a CoR project.');
|
|
19
|
+
process.exit(2);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const metadataPath = path.join(projectRoot, '.corrc.json');
|
|
23
|
+
const metadata = JSON.parse(fs.readFileSync(metadataPath, 'utf8'));
|
|
24
|
+
const manifest = metadata.manifest || {};
|
|
25
|
+
|
|
26
|
+
function findProjectRoot() {
|
|
27
|
+
let dir = process.cwd();
|
|
28
|
+
while (dir !== path.dirname(dir)) {
|
|
29
|
+
if (fs.existsSync(path.join(dir, '.corrc.json'))) return dir;
|
|
30
|
+
dir = path.dirname(dir);
|
|
31
|
+
}
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function hashContent(content) {
|
|
36
|
+
return crypto.createHash('sha256').update(content).digest('hex').slice(0, 16);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const drifted = [];
|
|
40
|
+
const missing = [];
|
|
41
|
+
const clean = [];
|
|
42
|
+
|
|
43
|
+
for (const [relPath, expectedHash] of Object.entries(manifest)) {
|
|
44
|
+
const fullPath = path.join(projectRoot, relPath);
|
|
45
|
+
|
|
46
|
+
if (!fs.existsSync(fullPath)) {
|
|
47
|
+
missing.push(relPath);
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const content = fs.readFileSync(fullPath, 'utf8');
|
|
52
|
+
const currentHash = hashContent(content);
|
|
53
|
+
|
|
54
|
+
if (currentHash !== expectedHash) {
|
|
55
|
+
drifted.push(relPath);
|
|
56
|
+
} else {
|
|
57
|
+
clean.push(relPath);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const args = process.argv.slice(2);
|
|
62
|
+
|
|
63
|
+
if (args.includes('--json')) {
|
|
64
|
+
console.log(JSON.stringify({ drifted, missing, clean: clean.length }, null, 2));
|
|
65
|
+
} else {
|
|
66
|
+
if (drifted.length === 0 && missing.length === 0) {
|
|
67
|
+
console.log(`All ${clean.length} CoR-managed files match upstream hashes.`);
|
|
68
|
+
} else {
|
|
69
|
+
if (drifted.length > 0) {
|
|
70
|
+
console.log(`Drifted (${drifted.length} files modified from upstream):`);
|
|
71
|
+
for (const f of drifted) console.log(` ${f}`);
|
|
72
|
+
}
|
|
73
|
+
if (missing.length > 0) {
|
|
74
|
+
console.log(`Missing (${missing.length} files deleted):`);
|
|
75
|
+
for (const f of missing) console.log(` ${f}`);
|
|
76
|
+
}
|
|
77
|
+
console.log(`\nClean: ${clean.length} files match.`);
|
|
78
|
+
if (args.includes('--fix')) {
|
|
79
|
+
console.log('\nRun /cor-upgrade to restore drifted files to upstream versions.');
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
process.exit(drifted.length > 0 || missing.length > 0 ? 1 : 0);
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"type": "object",
|
|
4
|
+
"required": ["findings", "meta"],
|
|
5
|
+
"properties": {
|
|
6
|
+
"findings": {
|
|
7
|
+
"type": "array",
|
|
8
|
+
"items": {
|
|
9
|
+
"type": "object",
|
|
10
|
+
"required": ["id", "perspective", "severity", "title", "description", "autoFixable"],
|
|
11
|
+
"properties": {
|
|
12
|
+
"id": {
|
|
13
|
+
"type": "string",
|
|
14
|
+
"description": "Unique finding ID: {cabinet-member}-{NNNN}",
|
|
15
|
+
"pattern": "^[a-z-]+-\\d{4}$"
|
|
16
|
+
},
|
|
17
|
+
"perspective": {
|
|
18
|
+
"type": "string",
|
|
19
|
+
"description": "Cabinet member name matching the directory name in skills/cabinet-*/",
|
|
20
|
+
"pattern": "^[a-z][a-z0-9-]+$"
|
|
21
|
+
},
|
|
22
|
+
"severity": {
|
|
23
|
+
"type": "string",
|
|
24
|
+
"enum": ["critical", "warn", "info", "idea"],
|
|
25
|
+
"description": "critical = data loss/breakage, warn = degradation/drift, info = improvement opportunity, idea = suggestion"
|
|
26
|
+
},
|
|
27
|
+
"title": {
|
|
28
|
+
"type": "string",
|
|
29
|
+
"maxLength": 120,
|
|
30
|
+
"description": "Short description of the finding"
|
|
31
|
+
},
|
|
32
|
+
"description": {
|
|
33
|
+
"type": "string",
|
|
34
|
+
"description": "Full explanation of the finding"
|
|
35
|
+
},
|
|
36
|
+
"assumption": {
|
|
37
|
+
"type": "string",
|
|
38
|
+
"description": "What the auditor assumes the intent was"
|
|
39
|
+
},
|
|
40
|
+
"evidence": {
|
|
41
|
+
"type": "string",
|
|
42
|
+
"description": "What was observed that led to this finding"
|
|
43
|
+
},
|
|
44
|
+
"question": {
|
|
45
|
+
"type": "string",
|
|
46
|
+
"description": "What the auditor is uncertain about — invites human judgment"
|
|
47
|
+
},
|
|
48
|
+
"file": {
|
|
49
|
+
"type": "string",
|
|
50
|
+
"description": "Primary file path relative to repo root, if applicable"
|
|
51
|
+
},
|
|
52
|
+
"line": {
|
|
53
|
+
"type": "integer",
|
|
54
|
+
"description": "Line number in the file, if applicable"
|
|
55
|
+
},
|
|
56
|
+
"suggestedFix": {
|
|
57
|
+
"type": "string",
|
|
58
|
+
"description": "Proposed fix or approach"
|
|
59
|
+
},
|
|
60
|
+
"type": {
|
|
61
|
+
"type": "string",
|
|
62
|
+
"enum": ["finding", "positive"],
|
|
63
|
+
"default": "finding",
|
|
64
|
+
"description": "finding = issue to triage, positive = health confirmation (not triageable)"
|
|
65
|
+
},
|
|
66
|
+
"autoFixable": {
|
|
67
|
+
"type": "boolean",
|
|
68
|
+
"description": "Whether a fix agent could resolve this without human judgment"
|
|
69
|
+
},
|
|
70
|
+
"reference": {
|
|
71
|
+
"type": "string",
|
|
72
|
+
"description": "URL or source reference"
|
|
73
|
+
},
|
|
74
|
+
"tags": {
|
|
75
|
+
"type": "array",
|
|
76
|
+
"items": { "type": "string" },
|
|
77
|
+
"description": "Categorization tags for filtering"
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
"meta": {
|
|
83
|
+
"type": "object",
|
|
84
|
+
"required": ["perspective", "timestamp"],
|
|
85
|
+
"properties": {
|
|
86
|
+
"perspective": { "type": "string" },
|
|
87
|
+
"timestamp": { "type": "string", "format": "date-time" },
|
|
88
|
+
"commitHash": { "type": "string" },
|
|
89
|
+
"durationSeconds": { "type": "number" },
|
|
90
|
+
"model": { "type": "string" }
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|