@thebassclef/lite 0.1.3 → 1.0.1
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/dist/cli.cjs +431 -135
- package/dist/cli.js +433 -137
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/lite/.bassclef-source.json +10 -0
- package/{substrate → dist/lite}/.claude/hooks/artifact-ingestion-gate.sh +0 -0
- package/{substrate → dist/lite}/.claude/hooks/assert-verify-steering.sh +0 -0
- package/{substrate → dist/lite}/.claude/hooks/bassclef-source-config-validate.sh +0 -0
- package/{substrate → dist/lite}/.claude/hooks/bassclef-sync.sh +0 -0
- package/{substrate → dist/lite}/.claude/hooks/compound-noun-scrub.sh +0 -0
- package/{substrate → dist/lite}/.claude/hooks/kiss-expansion-inject.sh +0 -0
- package/{substrate → dist/lite}/.claude/hooks/longrun-prep-compounding-sequence-check.sh +0 -0
- package/{substrate → dist/lite}/.claude/hooks/plain-english-steering.sh +0 -0
- package/{substrate → dist/lite}/.claude/hooks/post-skill-friction-check.sh +0 -0
- package/{substrate → dist/lite}/.claude/hooks/post-skill-telemetry.sh +0 -0
- package/{substrate → dist/lite}/.claude/hooks/pre-build-gate.sh +0 -0
- package/{substrate → dist/lite}/.claude/hooks/pre-commit-gate.sh +0 -0
- package/{substrate → dist/lite}/.claude/hooks/session-end.sh +0 -0
- package/{substrate → dist/lite}/.claude/hooks/session-reflection.sh +0 -0
- package/{substrate → dist/lite}/.claude/hooks/skill-body-grade-gate.sh +0 -0
- package/{substrate → dist/lite}/.claude/hooks/skill-body-intent-drift.sh +0 -0
- package/{substrate → dist/lite}/.claude/hooks/state-validate.sh +0 -0
- package/{substrate → dist/lite}/.claude/hooks/substrate-clarity-gate.sh +0 -0
- package/{substrate → dist/lite}/.claude/hooks/temperance-gate.sh +0 -0
- package/{substrate → dist/lite}/.claude/hooks/testing-tier-enforce.sh +0 -0
- package/{substrate → dist/lite}/.claude/hooks/turn-prose-grade-measure.sh +0 -0
- package/{substrate → dist/lite}/.claude/hooks/turn-prose-kiss-check.sh +0 -0
- package/{substrate → dist/lite}/.claude/hooks/vocabulary-migration-check.sh +0 -0
- package/{substrate → dist/lite}/.claude/hooks/whereami-utc-gate.sh +0 -0
- package/dist/lite/.claude/settings.json +212 -0
- package/dist/lite/CLAUDE.md +41 -0
- package/dist/lite/gitignore +58 -0
- package/dist/lite/standards/bassclef-wiring-manifest.json +497 -0
- package/dist/lite/whereami.md +24 -0
- package/package.json +8 -2
- package/substrate/.bassclef/lite-manifest.json +0 -2701
- package/substrate/.claude/agents/architect.md +0 -70
- package/substrate/.claude/agents/builder.md +0 -114
- package/substrate/.claude/agents/designer.md +0 -156
- package/substrate/.claude/agents/reviewer.md +0 -88
- package/substrate/.claude/hooks/longrun-prep-compounding-axis-check.sh +0 -492
- package/substrate/.claude/hooks/skill-step-list-check.sh +0 -171
- package/substrate/.claude/luminaries/alan-cooper.md +0 -170
- package/substrate/.claude/luminaries/alistair-cockburn.md +0 -140
- package/substrate/.claude/luminaries/amazon-pr-faq.md +0 -34
- package/substrate/.claude/luminaries/ash-maurya.md +0 -121
- package/substrate/.claude/luminaries/bill-buxton.md +0 -210
- package/substrate/.claude/luminaries/charles-sanders-peirce.md +0 -150
- package/substrate/.claude/luminaries/david-ogilvy.md +0 -192
- package/substrate/.claude/luminaries/don-norman.md +0 -173
- package/substrate/.claude/luminaries/edward-tufte.md +0 -179
- package/substrate/.claude/luminaries/eric-evans.md +0 -160
- package/substrate/.claude/luminaries/frederick-brooks.md +0 -50
- package/substrate/.claude/luminaries/gang-of-four.md +0 -157
- package/substrate/.claude/luminaries/glenford-myers.md +0 -230
- package/substrate/.claude/luminaries/hunt-thomas.md +0 -115
- package/substrate/.claude/luminaries/hyrum-wright.md +0 -94
- package/substrate/.claude/luminaries/jason-fried-dhh.md +0 -46
- package/substrate/.claude/luminaries/jesse-james-garrett.md +0 -154
- package/substrate/.claude/luminaries/john-ousterhout.md +0 -94
- package/substrate/.claude/luminaries/karl-popper.md +0 -132
- package/substrate/.claude/luminaries/kent-beck.md +0 -168
- package/substrate/.claude/luminaries/linus-torvalds.md +0 -218
- package/substrate/.claude/luminaries/martin-fowler.md +0 -164
- package/substrate/.claude/luminaries/michael-feathers.md +0 -125
- package/substrate/.claude/luminaries/michael-nygard.md +0 -118
- package/substrate/.claude/luminaries/robert-c-martin.md +0 -164
- package/substrate/.claude/luminaries/saltzer-schroeder.md +0 -194
- package/substrate/.claude/luminaries/sophia-prater.md +0 -193
- package/substrate/.claude/luminaries/stephen-toulmin.md +0 -131
- package/substrate/.claude/luminaries/tony-hoare.md +0 -170
- package/substrate/.claude/luminaries/vaughn-vernon.md +0 -50
- package/substrate/.claude/luminaries/w-edwards-deming.md +0 -158
- package/substrate/.claude/rules/accessor-library-discipline.md +0 -138
- package/substrate/.claude/rules/adr-discipline.md +0 -120
- package/substrate/.claude/rules/api-conventions.md +0 -125
- package/substrate/.claude/rules/artifact-ingestion.md +0 -179
- package/substrate/.claude/rules/assert-only-after-verify.md +0 -137
- package/substrate/.claude/rules/blocked-items.md +0 -146
- package/substrate/.claude/rules/bootstrap-pair-discipline.md +0 -141
- package/substrate/.claude/rules/branching.md +0 -28
- package/substrate/.claude/rules/cold-adopter-harness-discipline.md +0 -129
- package/substrate/.claude/rules/commit-conventions.md +0 -22
- package/substrate/.claude/rules/compounding-axis-fresh-analysis.md +0 -188
- package/substrate/.claude/rules/compounding-sequence-fresh-analysis.md +0 -188
- package/substrate/.claude/rules/context-engineering.md +0 -202
- package/substrate/.claude/rules/context-management.md +0 -85
- package/substrate/.claude/rules/defensive-bash.md +0 -68
- package/substrate/.claude/rules/deferred-actions.md +0 -233
- package/substrate/.claude/rules/destructive-operations.md +0 -69
- package/substrate/.claude/rules/diagnosis.md +0 -38
- package/substrate/.claude/rules/github-issue-flash-tweet.md +0 -156
- package/substrate/.claude/rules/guardrails.md +0 -73
- package/substrate/.claude/rules/hook-wire-on-author.md +0 -103
- package/substrate/.claude/rules/identifier-leak-prevention.md +0 -104
- package/substrate/.claude/rules/iteration-bet-brief-completeness.md +0 -54
- package/substrate/.claude/rules/lite-manifest-schema-change-discipline.md +0 -98
- package/substrate/.claude/rules/longrun-prep-plan-doc-compression.md +0 -89
- package/substrate/.claude/rules/loop-discipline.md +0 -81
- package/substrate/.claude/rules/manual-prod-approval.md +0 -100
- package/substrate/.claude/rules/marker-enrichment-discipline.md +0 -99
- package/substrate/.claude/rules/mobile-ephemeral-session.md +0 -109
- package/substrate/.claude/rules/new-dependency-check.md +0 -51
- package/substrate/.claude/rules/oo-ad-entry-point.md +0 -117
- package/substrate/.claude/rules/operator-facing-prose.md +0 -196
- package/substrate/.claude/rules/option-label-discipline.md +0 -108
- package/substrate/.claude/rules/pattern-annotation.md +0 -100
- package/substrate/.claude/rules/plain-english-discipline.md +0 -156
- package/substrate/.claude/rules/plan-enumeration-needs-value-props.md +0 -211
- package/substrate/.claude/rules/pr-body-shape.md +0 -317
- package/substrate/.claude/rules/pr-strategy.md +0 -167
- package/substrate/.claude/rules/pr-title-shape.md +0 -161
- package/substrate/.claude/rules/prototype-workflow.md +0 -65
- package/substrate/.claude/rules/reserved-skill-names.md +0 -123
- package/substrate/.claude/rules/schema-management.md +0 -49
- package/substrate/.claude/rules/sdlc-gates.md +0 -149
- package/substrate/.claude/rules/security.md +0 -37
- package/substrate/.claude/rules/session-artifacts.md +0 -236
- package/substrate/.claude/rules/skill-composition-declarations.md +0 -124
- package/substrate/.claude/rules/skill-description-clarity.md +0 -247
- package/substrate/.claude/rules/skill-procedure-step-list.md +0 -137
- package/substrate/.claude/rules/state-schema-validation.md +0 -162
- package/substrate/.claude/rules/stuck-signal-diagnostic.md +0 -140
- package/substrate/.claude/rules/substrate-config-schema.md +0 -98
- package/substrate/.claude/rules/test-list-discipline.md +0 -175
- package/substrate/.claude/rules/test-sufficiency.md +0 -210
- package/substrate/.claude/rules/testing-tier-config.md +0 -145
- package/substrate/.claude/rules/testing.md +0 -38
- package/substrate/.claude/rules/turn-estimate-grounding.md +0 -134
- package/substrate/.claude/rules/visual-hierarchy.md +0 -437
- package/substrate/.claude/rules/we-dont-break-adopters.md +0 -126
- package/substrate/.claude/rules/whereami-load-bearing.md +0 -202
- package/substrate/.claude/rules/writing-craft-discipline.md +0 -92
- package/substrate/.claude/rules/wu-sequencing-compounds.md +0 -145
- package/substrate/.claude/skills/build/SKILL.md +0 -640
- package/substrate/.claude/skills/chronicle/SKILL.md +0 -55
- package/substrate/.claude/skills/clean-artifacts/SKILL.md +0 -249
- package/substrate/.claude/skills/decompose/SKILL.md +0 -280
- package/substrate/.claude/skills/diagnose/SKILL.md +0 -297
- package/substrate/.claude/skills/feynman/SKILL.md +0 -90
- package/substrate/.claude/skills/howdoi/SKILL.md +0 -105
- package/substrate/.claude/skills/ia-model/SKILL.md +0 -108
- package/substrate/.claude/skills/interaction-design/SKILL.md +0 -112
- package/substrate/.claude/skills/interpret-input/SKILL.md +0 -180
- package/substrate/.claude/skills/journal/SKILL.md +0 -209
- package/substrate/.claude/skills/kiss/SKILL.md +0 -449
- package/substrate/.claude/skills/launch/SKILL.md +0 -915
- package/substrate/.claude/skills/lean-canvas/SKILL.md +0 -332
- package/substrate/.claude/skills/longrun/SKILL.md +0 -463
- package/substrate/.claude/skills/luminary/SKILL.md +0 -481
- package/substrate/.claude/skills/ogilvy-writing-audit/SKILL.md +0 -177
- package/substrate/.claude/skills/onboard-repo/SKILL.md +0 -1624
- package/substrate/.claude/skills/pattern-review/SKILL.md +0 -99
- package/substrate/.claude/skills/personas/SKILL.md +0 -207
- package/substrate/.claude/skills/promote/SKILL.md +0 -283
- package/substrate/.claude/skills/requirement/SKILL.md +0 -98
- package/substrate/.claude/skills/retro/SKILL.md +0 -117
- package/substrate/.claude/skills/riff/SKILL.md +0 -114
- package/substrate/.claude/skills/roadmap-reconcile/SKILL.md +0 -163
- package/substrate/.claude/skills/session-end/SKILL.md +0 -309
- package/substrate/.claude/skills/session-log/SKILL.md +0 -299
- package/substrate/.claude/skills/skills/SKILL.md +0 -228
- package/substrate/.claude/skills/spec/SKILL.md +0 -105
- package/substrate/.claude/skills/sprint/SKILL.md +0 -392
- package/substrate/.claude/skills/stage/SKILL.md +0 -384
- package/substrate/.claude/skills/state-a-problem/SKILL.md +0 -185
- package/substrate/.claude/skills/temperance/SKILL.md +0 -108
- package/substrate/.claude/skills/use-case/SKILL.md +0 -417
- package/substrate/.claude/skills/user-stories/SKILL.md +0 -268
- package/substrate/.claude/skills/value-prop/SKILL.md +0 -251
- package/substrate/.claude/skills/verify/SKILL.md +0 -160
- package/substrate/.claude/skills/visual-review/SKILL.md +0 -503
- package/substrate/.claude/skills/whats-the-plan/SKILL.md +0 -202
- package/substrate/.claude/skills/whereami/SKILL.md +0 -307
- package/substrate/AGENTS.md +0 -79
- package/substrate/CLAUDE-lite.md +0 -85
- package/substrate/CODE_OF_CONDUCT.md +0 -28
- package/substrate/CONTRIBUTING.md +0 -177
- package/substrate/README.md +0 -173
- package/substrate/SECURITY.md +0 -19
- package/substrate/architecture/decisions/ADR-029-release-pipeline.md +0 -79
- package/substrate/architecture/decisions/ADR-031-non-breaking-changes-adopter-discipline.md +0 -139
- package/substrate/architecture/decisions/ADR-032-adopter-sync-dispatcher-architecture.md +0 -192
- package/substrate/architecture/decisions/ADR-039-release-tagging-scheme.md +0 -145
- package/substrate/architecture/decisions/ADR-040-planning-skill-vocabulary-and-lite-profile.md +0 -155
- package/substrate/architecture/decisions/ADR-044-unified-skill-body-template.md +0 -162
- package/substrate/lib/clean-artifacts-sweep.sh +0 -112
- package/substrate/lib/code-comment-discipline.sh +0 -144
- package/substrate/lib/composer-preflight.sh +0 -459
- package/substrate/lib/hook-inject.sh +0 -255
- package/substrate/lib/luminary-pick.sh +0 -96
- package/substrate/lib/output-discipline.sh +0 -143
- package/substrate/lib/prose-scan-boundary.sh +0 -171
- package/substrate/lib/rewrite-check.sh +0 -214
- package/substrate/lib/state.sh +0 -1372
- package/substrate/lib/telemetry.sh +0 -205
- package/substrate/lib/tier-check.sh +0 -187
- package/substrate/lib/tier-dependency-audit.sh +0 -1088
- package/substrate/presence/install/bassclef-hook-connect.sh +0 -178
- package/substrate/presence/install/bassclef-sync.dispatcher.template.sh +0 -841
- package/substrate/presence/install/bassclef-sync.template.sh +0 -2076
- package/substrate/presence/install/schedule-auto-save.cron.sh +0 -88
- package/substrate/presence/install/schedule-auto-save.taskscheduler.md +0 -122
- package/substrate/scripts/aggregate-telemetry.sh +0 -217
- package/substrate/scripts/analyze-tier-dependencies.sh +0 -239
- package/substrate/scripts/generate-lite-manifest.sh +0 -505
- package/substrate/scripts/generate-tier-manifest.sh +0 -28
- package/substrate/scripts/intent-drift-check.sh +0 -456
- package/substrate/scripts/lite-manifest-drift-check.sh +0 -146
- package/substrate/scripts/render-lite-manifest-doc.sh +0 -150
- package/substrate/standards/adr-template.md +0 -86
- package/substrate/standards/api-conventions/nextjs.md +0 -84
- package/substrate/standards/artifact-composition.md +0 -209
- package/substrate/standards/bash-hook-safety.md +0 -246
- package/substrate/standards/bassclef-configs-schema.md +0 -232
- package/substrate/standards/bassclef-evolution.md +0 -143
- package/substrate/standards/bassclef-internal-jargon.md +0 -244
- package/substrate/standards/bassclef-managed-sentinel.md +0 -96
- package/substrate/standards/bassclef-source-config.md +0 -228
- package/substrate/standards/branch-stacking.md +0 -408
- package/substrate/standards/code-safety-principles.md +0 -176
- package/substrate/standards/composer-prerequisites.md +0 -155
- package/substrate/standards/deferred-actions-schema.md +0 -204
- package/substrate/standards/dependency-discipline/cargo.md +0 -39
- package/substrate/standards/dependency-discipline/gem.md +0 -43
- package/substrate/standards/dependency-discipline/go-mod.md +0 -41
- package/substrate/standards/dependency-discipline/npm.md +0 -42
- package/substrate/standards/dependency-discipline/pip.md +0 -42
- package/substrate/standards/deployment-topology/ec2-tailscale.md +0 -225
- package/substrate/standards/deployment-topology.md +0 -69
- package/substrate/standards/docs-sync-allowlist.md +0 -76
- package/substrate/standards/domain-and-dns.md +0 -145
- package/substrate/standards/frontend-stack.md +0 -67
- package/substrate/standards/frontmatter-schema.md +0 -154
- package/substrate/standards/graceful-exit.md +0 -227
- package/substrate/standards/hook-idempotency.md +0 -102
- package/substrate/standards/hook-injection-discipline.md +0 -202
- package/substrate/standards/hook-install-class.md +0 -215
- package/substrate/standards/input-handler-interface.md +0 -152
- package/substrate/standards/lite-manifest-schema-changes.md +0 -135
- package/substrate/standards/luminary-matching.md +0 -105
- package/substrate/standards/luminary-problem-patterns.md +0 -481
- package/substrate/standards/migration-discipline/active-record.md +0 -50
- package/substrate/standards/migration-discipline/alembic.md +0 -43
- package/substrate/standards/migration-discipline/gorm.md +0 -50
- package/substrate/standards/migration-discipline/prisma.md +0 -53
- package/substrate/standards/migration-discipline/sqlalchemy.md +0 -51
- package/substrate/standards/mobile-ephemeral-session.md +0 -167
- package/substrate/standards/model-routing-discipline.md +0 -160
- package/substrate/standards/ogilvy-writing-rules.md +0 -225
- package/substrate/standards/opener-discipline.md +0 -96
- package/substrate/standards/operator-facing-prose-discipline.md +0 -201
- package/substrate/standards/persona-schema.md +0 -229
- package/substrate/standards/pluggable-luminaries.md +0 -323
- package/substrate/standards/pr-body-discipline.md +0 -115
- package/substrate/standards/preview-state-schema.md +0 -189
- package/substrate/standards/project-directory-layout.md +0 -276
- package/substrate/standards/release-tagging.md +0 -137
- package/substrate/standards/reserved-skill-names.md +0 -120
- package/substrate/standards/scannable-multi-option-output.md +0 -261
- package/substrate/standards/sdlc-compliance.md +0 -286
- package/substrate/standards/sdlc-gates/typescript.md +0 -57
- package/substrate/standards/secrets-lifecycle.md +0 -210
- package/substrate/standards/security-scanner-adapter.md +0 -145
- package/substrate/standards/session-board.md +0 -256
- package/substrate/standards/skill-output-discipline.md +0 -90
- package/substrate/standards/state-spine-contract.md +0 -255
- package/substrate/standards/state-spine.md +0 -511
- package/substrate/standards/steering-hints/kiss-words.md +0 -11
- package/substrate/standards/substrate-config-schema.md +0 -267
- package/substrate/standards/tech-stack-config.md +0 -109
- package/substrate/standards/tier-dependency-analysis.md +0 -167
- package/substrate/standards/tier-runtime-deps/lite.md +0 -57
- package/substrate/standards/tier-tag-schema.md +0 -155
- package/substrate/standards/two-layer-config.md +0 -99
- package/substrate/standards/use-case-format.md +0 -292
- package/substrate/standards/user-story-invest.md +0 -268
- package/substrate/standards/velocity-and-appetite.md +0 -229
- package/substrate/standards/voice-input-pattern.md +0 -119
- package/substrate/standards/whereami-schema.md +0 -301
- package/substrate/standards/worktree-management.md +0 -211
- package/substrate/standards/writing-guide.md +0 -213
- package/substrate/templates/chronicle-template.md +0 -75
- package/substrate/templates/deferred-action-template.md +0 -45
- package/substrate/templates/memory-proposal-template.md +0 -77
- package/substrate/templates/persona-template.md +0 -200
- package/substrate/templates/pr-faq.md +0 -45
- package/substrate/templates/secret-rotation-template.md +0 -162
- package/substrate/templates/spec-template.md +0 -131
- package/substrate/templates/use-case-template.md +0 -194
- package/substrate/templates/user-story-template.md +0 -107
- package/substrate/templates/whereami-template.md +0 -101
|
@@ -1,255 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
# tier: lite
|
|
3
|
-
# install-class: dual
|
|
4
|
-
# lib/hook-inject.sh — shared helper for hooks that inject additionalContext
|
|
5
|
-
# per standards/hook-injection-discipline.md and resolve project resources
|
|
6
|
-
# per standards/hook-install-class.md.
|
|
7
|
-
#
|
|
8
|
-
# This library is SOURCED by hooks, not executed. It does not set -e/-u
|
|
9
|
-
# globally (would affect callers); functions enforce their own contracts.
|
|
10
|
-
#
|
|
11
|
-
# Authority: ADR-035 (substrate-as-system + hooks-as-steering-surfaces)
|
|
12
|
-
# Tier 0 strict TDD: lib/tests/hook-inject.test.sh
|
|
13
|
-
# Anchors: @luminary john-ousterhout (deep modules) + @luminary michael-nygard
|
|
14
|
-
# (fail-soft fallback chain) + @luminary tony-hoare (pre/post contracts)
|
|
15
|
-
#
|
|
16
|
-
# Exposed functions:
|
|
17
|
-
# emit_additional_context <event> <content> # JSON envelope to stdout
|
|
18
|
-
# emit_base_pair_reminders # plain-English + assert-verify reminder text
|
|
19
|
-
# resolve_standards_path <filename> # CLAUDE_PROJECT_DIR → env → HOME → fail
|
|
20
|
-
# resolve_config_path # same chain for bassclef-configs.jsonc
|
|
21
|
-
# extract_block_terms <jargon-file> # BLOCK-tier rows from wordlist
|
|
22
|
-
#
|
|
23
|
-
# Env vars consumed:
|
|
24
|
-
# CLAUDE_PROJECT_DIR — project root (Claude Code sets this)
|
|
25
|
-
# KISS_STANDARDS_FILE — override for standards path resolution
|
|
26
|
-
# BASSCLEF_CONFIG_FILE — override for config path resolution
|
|
27
|
-
# HOME_OVERRIDE — test-only; replaces $HOME for fixture isolation
|
|
28
|
-
#
|
|
29
|
-
# Per standards/hook-injection-discipline.md:
|
|
30
|
-
# - additionalContext capped at 10,000 chars (Anthropic limit)
|
|
31
|
-
# - JSON envelope shape: {"hookSpecificOutput": {"hookEventName": "...", "additionalContext": "..."}}
|
|
32
|
-
# - Fail-soft: all resolution helpers return non-zero with structured stderr; never silently pass
|
|
33
|
-
|
|
34
|
-
# === Constants ===
|
|
35
|
-
HOOK_INJECT_MAX_CONTENT=10000
|
|
36
|
-
|
|
37
|
-
# === Resolve $HOME with test-override support ===
|
|
38
|
-
__hook_inject_home() {
|
|
39
|
-
echo "${HOME_OVERRIDE:-$HOME}"
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
# === emit_additional_context ===
|
|
43
|
-
# Args:
|
|
44
|
-
# $1 — event name (e.g., UserPromptSubmit, Stop)
|
|
45
|
-
# $2 — content (the additionalContext string)
|
|
46
|
-
# Stdout: JSON envelope per Anthropic's hookSpecificOutput shape
|
|
47
|
-
# Exit: 0 success; 2 missing/invalid args
|
|
48
|
-
emit_additional_context() {
|
|
49
|
-
local event="${1:-}"
|
|
50
|
-
local content="${2-}" # NOT :- so explicit empty string is allowed (test case)
|
|
51
|
-
|
|
52
|
-
# Validate event arg
|
|
53
|
-
if [ -z "$event" ]; then
|
|
54
|
-
echo "emit_additional_context: missing event arg" >&2
|
|
55
|
-
echo " Usage: emit_additional_context <event-name> <content>" >&2
|
|
56
|
-
return 2
|
|
57
|
-
fi
|
|
58
|
-
|
|
59
|
-
# Reject event names with spaces (Anthropic events are single tokens)
|
|
60
|
-
if echo "$event" | grep -q ' '; then
|
|
61
|
-
echo "emit_additional_context: invalid event name '$event' (spaces not allowed)" >&2
|
|
62
|
-
echo " Anthropic hook events are single tokens like UserPromptSubmit, Stop, PostToolUse" >&2
|
|
63
|
-
return 2
|
|
64
|
-
fi
|
|
65
|
-
|
|
66
|
-
# Validate content arg presence (allow empty string but require the arg)
|
|
67
|
-
if [ $# -lt 2 ]; then
|
|
68
|
-
echo "emit_additional_context: missing content arg" >&2
|
|
69
|
-
echo " Usage: emit_additional_context <event-name> <content>" >&2
|
|
70
|
-
return 2
|
|
71
|
-
fi
|
|
72
|
-
|
|
73
|
-
# Truncate if exceeds Anthropic 10K cap
|
|
74
|
-
local truncated=0
|
|
75
|
-
if [ ${#content} -gt $HOOK_INJECT_MAX_CONTENT ]; then
|
|
76
|
-
content="${content:0:$HOOK_INJECT_MAX_CONTENT}"
|
|
77
|
-
truncated=1
|
|
78
|
-
fi
|
|
79
|
-
|
|
80
|
-
# Emit JSON envelope via jq for proper escaping
|
|
81
|
-
if command -v jq >/dev/null 2>&1; then
|
|
82
|
-
jq -n \
|
|
83
|
-
--arg event "$event" \
|
|
84
|
-
--arg content "$content" \
|
|
85
|
-
'{hookSpecificOutput: {hookEventName: $event, additionalContext: $content}}'
|
|
86
|
-
else
|
|
87
|
-
# jq-missing fallback: emit minimally-escaped JSON
|
|
88
|
-
# (lib design assumes jq present per standards/bash-hook-safety.md;
|
|
89
|
-
# this fallback exists so a jq-missing system still produces parseable output)
|
|
90
|
-
local esc_event="${event//\"/\\\"}"
|
|
91
|
-
local esc_content="${content//\"/\\\"}"
|
|
92
|
-
esc_content="${esc_content//$'\n'/\\n}"
|
|
93
|
-
printf '{"hookSpecificOutput":{"hookEventName":"%s","additionalContext":"%s"}}\n' \
|
|
94
|
-
"$esc_event" "$esc_content"
|
|
95
|
-
fi
|
|
96
|
-
|
|
97
|
-
if [ $truncated -eq 1 ]; then
|
|
98
|
-
echo "emit_additional_context: content truncated to $HOOK_INJECT_MAX_CONTENT chars (Anthropic limit)" >&2
|
|
99
|
-
fi
|
|
100
|
-
|
|
101
|
-
return 0
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
# === emit_base_pair_reminders ===
|
|
105
|
-
# Emits the shared base-pair reminder text for the 5 UserPromptExpansion
|
|
106
|
-
# hooks per bet 2026-07-01e. Content covers both R8 cures:
|
|
107
|
-
# 1. Plain-English discipline (per .claude/rules/operator-facing-prose.md)
|
|
108
|
-
# 2. Assert-verify discipline (per .claude/rules/assert-only-after-verify.md)
|
|
109
|
-
#
|
|
110
|
-
# Callers prepend this to their skill-specific content, then pass the
|
|
111
|
-
# combined string to emit_additional_context.
|
|
112
|
-
#
|
|
113
|
-
# Stdout: reminder text (no envelope; caller wraps)
|
|
114
|
-
# Exit: 0 always
|
|
115
|
-
emit_base_pair_reminders() {
|
|
116
|
-
cat <<'EOF'
|
|
117
|
-
**Plain check:** Before I make a claim in this turn, I read the source first and cite it. If I cannot cite the source, I do not ship the claim.
|
|
118
|
-
|
|
119
|
-
**Base-pair reminders — plain-English + assert-verify:**
|
|
120
|
-
|
|
121
|
-
Plain-English (per .claude/rules/operator-facing-prose.md):
|
|
122
|
-
- Grade-10 reading level. Subject-verb-object. Short sentences.
|
|
123
|
-
- Drop bassclef-internal jargon (composer, primitive, load-bearing, blast radius, tier-preset, operationalize, wirings). See standards/bassclef-internal-jargon.md for the substitution table.
|
|
124
|
-
- Keep standard tech vocab: API, hook, PR, schema, ORM.
|
|
125
|
-
|
|
126
|
-
Assert-verify (per .claude/rules/assert-only-after-verify.md):
|
|
127
|
-
- Every operator-facing assertion carries three parts: My claim + Evidence + Why the evidence supports the claim.
|
|
128
|
-
- Evidence means the source read inline (file path, ticket #, git SHA).
|
|
129
|
-
- Why the evidence supports the claim means one sentence tying the source to the claim.
|
|
130
|
-
- Optional sharpeners: Qualifier (Toulmin), Rebuttal (Popper), Alternatives (Peirce).
|
|
131
|
-
- If you cannot fill all three, do not ship the assertion. Read the source first.
|
|
132
|
-
- Toulmin's original vocabulary (claim / data / warrant) stays as the research citation in .claude/luminaries/stephen-toulmin.md.
|
|
133
|
-
EOF
|
|
134
|
-
return 0
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
# === resolve_standards_path ===
|
|
138
|
-
# Resolves a standards/ file via project → env → user → fail fallback.
|
|
139
|
-
# Args:
|
|
140
|
-
# $1 — relative filename under standards/ (e.g., "bassclef-internal-jargon.md")
|
|
141
|
-
# Stdout: resolved absolute path
|
|
142
|
-
# Exit: 0 success; 1 all layers fail; 2 missing arg
|
|
143
|
-
resolve_standards_path() {
|
|
144
|
-
local filename="${1:-}"
|
|
145
|
-
if [ -z "$filename" ]; then
|
|
146
|
-
echo "resolve_standards_path: missing filename arg" >&2
|
|
147
|
-
return 2
|
|
148
|
-
fi
|
|
149
|
-
|
|
150
|
-
local project_dir="${CLAUDE_PROJECT_DIR:-}"
|
|
151
|
-
local env_override="${KISS_STANDARDS_FILE:-}"
|
|
152
|
-
local home_dir
|
|
153
|
-
home_dir="$(__hook_inject_home)"
|
|
154
|
-
|
|
155
|
-
# Layer 1: project
|
|
156
|
-
if [ -n "$project_dir" ] && [ -f "$project_dir/standards/$filename" ]; then
|
|
157
|
-
echo "$project_dir/standards/$filename"
|
|
158
|
-
return 0
|
|
159
|
-
fi
|
|
160
|
-
|
|
161
|
-
# Layer 2: env override (only if env file actually exists; otherwise fall through)
|
|
162
|
-
if [ -n "$env_override" ] && [ -f "$env_override" ]; then
|
|
163
|
-
echo "$env_override"
|
|
164
|
-
return 0
|
|
165
|
-
fi
|
|
166
|
-
|
|
167
|
-
# Layer 3: user-level
|
|
168
|
-
if [ -f "$home_dir/standards/$filename" ]; then
|
|
169
|
-
echo "$home_dir/standards/$filename"
|
|
170
|
-
return 0
|
|
171
|
-
fi
|
|
172
|
-
|
|
173
|
-
# All layers failed — structured stderr with the fallback chain attempted
|
|
174
|
-
cat >&2 <<EOF
|
|
175
|
-
resolve_standards_path: '$filename' not found in any fallback layer
|
|
176
|
-
Layer 1 (project): ${project_dir:-<CLAUDE_PROJECT_DIR unset>}/standards/$filename
|
|
177
|
-
Layer 2 (env KISS_STANDARDS_FILE): ${env_override:-<unset>}
|
|
178
|
-
Layer 3 (user): $home_dir/standards/$filename
|
|
179
|
-
Per standards/hook-injection-discipline.md fail-soft contract.
|
|
180
|
-
EOF
|
|
181
|
-
return 1
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
# === resolve_config_path ===
|
|
185
|
-
# Resolves bassclef-configs.jsonc via project → env → user → fail.
|
|
186
|
-
# Stdout: resolved absolute path
|
|
187
|
-
# Exit: 0 success; 1 all layers fail
|
|
188
|
-
resolve_config_path() {
|
|
189
|
-
local project_dir="${CLAUDE_PROJECT_DIR:-}"
|
|
190
|
-
local env_override="${BASSCLEF_CONFIG_FILE:-}"
|
|
191
|
-
local home_dir
|
|
192
|
-
home_dir="$(__hook_inject_home)"
|
|
193
|
-
|
|
194
|
-
# Layer 1: project
|
|
195
|
-
if [ -n "$project_dir" ] && [ -f "$project_dir/.claude/bassclef-configs.jsonc" ]; then
|
|
196
|
-
echo "$project_dir/.claude/bassclef-configs.jsonc"
|
|
197
|
-
return 0
|
|
198
|
-
fi
|
|
199
|
-
|
|
200
|
-
# Layer 2: env override
|
|
201
|
-
if [ -n "$env_override" ] && [ -f "$env_override" ]; then
|
|
202
|
-
echo "$env_override"
|
|
203
|
-
return 0
|
|
204
|
-
fi
|
|
205
|
-
|
|
206
|
-
# Layer 3: user-level
|
|
207
|
-
if [ -f "$home_dir/.claude/bassclef-configs.jsonc" ]; then
|
|
208
|
-
echo "$home_dir/.claude/bassclef-configs.jsonc"
|
|
209
|
-
return 0
|
|
210
|
-
fi
|
|
211
|
-
|
|
212
|
-
cat >&2 <<EOF
|
|
213
|
-
resolve_config_path: bassclef-configs.jsonc not found in any fallback layer
|
|
214
|
-
Layer 1 (project): ${project_dir:-<CLAUDE_PROJECT_DIR unset>}/.claude/bassclef-configs.jsonc
|
|
215
|
-
Layer 2 (env BASSCLEF_CONFIG_FILE): ${env_override:-<unset>}
|
|
216
|
-
Layer 3 (user): $home_dir/.claude/bassclef-configs.jsonc
|
|
217
|
-
Per standards/hook-injection-discipline.md fail-soft contract.
|
|
218
|
-
EOF
|
|
219
|
-
return 1
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
# === extract_block_terms ===
|
|
223
|
-
# Parses a bassclef-internal-jargon.md style file + returns BLOCK-tier terms.
|
|
224
|
-
# Args:
|
|
225
|
-
# $1 — path to the jargon file
|
|
226
|
-
# Stdout: one term per line (BLOCK rows only)
|
|
227
|
-
# Exit: 0 success (even if zero terms found); 1 file missing; 2 missing arg
|
|
228
|
-
extract_block_terms() {
|
|
229
|
-
local file="${1:-}"
|
|
230
|
-
if [ -z "$file" ]; then
|
|
231
|
-
echo "extract_block_terms: missing file arg" >&2
|
|
232
|
-
return 2
|
|
233
|
-
fi
|
|
234
|
-
if [ ! -f "$file" ]; then
|
|
235
|
-
echo "extract_block_terms: file not found: $file" >&2
|
|
236
|
-
return 1
|
|
237
|
-
fi
|
|
238
|
-
|
|
239
|
-
# Parse markdown table rows: extract column 2 (term) where column 3 (tier) == BLOCK
|
|
240
|
-
# Format: | term | TIER | replacement |
|
|
241
|
-
awk -F'|' '
|
|
242
|
-
/BLOCK *\|/ {
|
|
243
|
-
# Get tier column (3rd field after split — col 1 is leading empty)
|
|
244
|
-
tier = $3
|
|
245
|
-
gsub(/^ +| +$/, "", tier)
|
|
246
|
-
if (tier == "BLOCK") {
|
|
247
|
-
term = $2
|
|
248
|
-
gsub(/^ +| +$/, "", term)
|
|
249
|
-
# Skip header rows (term column says "term" literally)
|
|
250
|
-
if (term != "term" && term != "") print term
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
' "$file"
|
|
254
|
-
return 0
|
|
255
|
-
}
|
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
# tier: lite
|
|
3
|
-
# andon-allow: docs/operator-private/[a-z-]+/20[0-9][0-9]-[0-9]{2}
|
|
4
|
-
#
|
|
5
|
-
# lib/luminary-pick.sh — bassclef catalog helper for the in-turn luminary picker.
|
|
6
|
-
#
|
|
7
|
-
# Shape A per docs/decompositions/2026-09-03-picker-harness-llm.md.
|
|
8
|
-
# Consult at docs/operator-private/consultations/2026-09-03-picker-shape.md
|
|
9
|
-
# picked Shape A 5-0 (Cooper, Linus, Ousterhout, Nygard, Feathers).
|
|
10
|
-
#
|
|
11
|
-
# The pick itself lives in each caller SKILL body:
|
|
12
|
-
# .claude/skills/pick-luminaries/SKILL.md
|
|
13
|
-
# .claude/skills/launch/SKILL.md
|
|
14
|
-
# .claude/skills/stage/SKILL.md
|
|
15
|
-
#
|
|
16
|
-
# Claude reads the catalog list from luminary_pick_catalog() below,
|
|
17
|
-
# reasons over the intent inside the current turn, writes the JSON.
|
|
18
|
-
# No shell-out. No separate API key required.
|
|
19
|
-
#
|
|
20
|
-
# This lib provides:
|
|
21
|
-
# - luminary_pick_catalog() — read catalog dir; emit sorted slug list
|
|
22
|
-
# - luminary_pick() — grace-window stub preserving signature through
|
|
23
|
-
# 2026-10-31 per ADR-031 we-dont-break-adopters
|
|
24
|
-
# - luminary_pick_status() — mode report for adopter debugging
|
|
25
|
-
#
|
|
26
|
-
# Usage from a caller SKILL body:
|
|
27
|
-
#
|
|
28
|
-
# source "${BASSCLEF_DIR:-$HOME/src/sunj-labs/bassclef}/lib/luminary-pick.sh"
|
|
29
|
-
# CATALOG=$(luminary_pick_catalog)
|
|
30
|
-
# # then Claude reasons over $CATALOG + intent, writes JSON in-turn
|
|
31
|
-
#
|
|
32
|
-
# Output JSON shape (produced by SKILL body prose, not by this lib):
|
|
33
|
-
# {
|
|
34
|
-
# "matched_luminaries": ["slug1", "slug2", ...],
|
|
35
|
-
# "rationale": "One short sentence per pick",
|
|
36
|
-
# "picker_version": "bassclef-harness-pick-2.0",
|
|
37
|
-
# "provider": "claude-code-harness"
|
|
38
|
-
# }
|
|
39
|
-
|
|
40
|
-
set -euo pipefail
|
|
41
|
-
|
|
42
|
-
# Read catalog dir and emit one line per luminary.
|
|
43
|
-
# Format: "<slug> (<domain>) — <name>"
|
|
44
|
-
# Sort: alphabetical by slug.
|
|
45
|
-
# Return: 0 on success (including empty catalog); non-zero if dir missing.
|
|
46
|
-
luminary_pick_catalog() {
|
|
47
|
-
local basedir="${BASSCLEF_DIR:-$HOME/src/sunj-labs/bassclef}"
|
|
48
|
-
local catalog_dir="${basedir}/state/luminary-implementations"
|
|
49
|
-
|
|
50
|
-
if [ ! -d "$catalog_dir" ]; then
|
|
51
|
-
echo "[luminary-pick-catalog] catalog dir missing: $catalog_dir" >&2
|
|
52
|
-
return 2
|
|
53
|
-
fi
|
|
54
|
-
|
|
55
|
-
(
|
|
56
|
-
shopt -s nullglob
|
|
57
|
-
set +e
|
|
58
|
-
for f in "$catalog_dir"/*.json; do
|
|
59
|
-
jq -r '"\(.luminary_slug) (\(.primary_domain // "unknown")) — \(.name // .luminary_slug)"' "$f" 2>/dev/null || true
|
|
60
|
-
done | sort -u
|
|
61
|
-
)
|
|
62
|
-
return 0
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
# Grace-window stub preserving the old function signature.
|
|
66
|
-
# Adopter scripts that source this lib and call luminary_pick continue
|
|
67
|
-
# to run. They see a stderr note pointing at the new home. Exit 0 so
|
|
68
|
-
# scripts checking exit code do not error.
|
|
69
|
-
# Retires 2026-10-31 per ADR-031.
|
|
70
|
-
luminary_pick() {
|
|
71
|
-
echo "[luminary-pick] moved to caller SKILL body prose per web#193." >&2
|
|
72
|
-
echo "[luminary-pick] adopters: see .claude/skills/pick-luminaries/SKILL.md" >&2
|
|
73
|
-
echo "[luminary-pick] grace-window stub retires 2026-10-31 per ADR-031." >&2
|
|
74
|
-
return 0
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
# Report picker mode. Kept for adopter debugging.
|
|
78
|
-
luminary_pick_status() {
|
|
79
|
-
echo "LIVE — in-turn picker per SKILL body prose (Shape A, web#193)"
|
|
80
|
-
return 0
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
|
|
84
|
-
case "${1:-}" in
|
|
85
|
-
catalog) luminary_pick_catalog ;;
|
|
86
|
-
status) luminary_pick_status ;;
|
|
87
|
-
*)
|
|
88
|
-
echo "Usage: $0 catalog # emit luminary catalog list"
|
|
89
|
-
echo " $0 status # report picker mode"
|
|
90
|
-
echo ""
|
|
91
|
-
echo "The pick itself moved to caller SKILL body prose per web#193."
|
|
92
|
-
echo "See .claude/skills/pick-luminaries/SKILL.md."
|
|
93
|
-
exit 0
|
|
94
|
-
;;
|
|
95
|
-
esac
|
|
96
|
-
fi
|
|
@@ -1,143 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
# tier: lite
|
|
3
|
-
# output-discipline.sh — classifier library for substrate output discipline audit.
|
|
4
|
-
#
|
|
5
|
-
# Answers per artifact: does this substrate file dispatch /kiss words on its
|
|
6
|
-
# operator-facing output? Returns one of four labels:
|
|
7
|
-
#
|
|
8
|
-
# PRESENT — body has /kiss dispatch pattern (dispatches /kiss words on output)
|
|
9
|
-
# ABSENT — body emits operator-facing prose but no /kiss dispatch found
|
|
10
|
-
# OPT_OUT — SKILL frontmatter declares no_operator_output: true
|
|
11
|
-
# NOT_APPLICABLE — artifact type does not emit operator-facing prose (rare;
|
|
12
|
-
# reserved for future opt-outs at type layer)
|
|
13
|
-
#
|
|
14
|
-
# The classifier reads the artifact body and checks for one of these patterns:
|
|
15
|
-
# - /kiss words --grade10 (canonical form per bassclef-upstream#858)
|
|
16
|
-
# - Dispatch .*kiss words (per audit-substrate-output-discipline SKILL Test 33)
|
|
17
|
-
# - /kiss dispatch (loose form)
|
|
18
|
-
#
|
|
19
|
-
# Per canvas docs/canvases/2026-07-25-substrate-output-discipline.md Stage 2.
|
|
20
|
-
# Ships as bet 2026-07-25a WU-A3 (bassclef-upstream#859 Iteration A).
|
|
21
|
-
#
|
|
22
|
-
# Usage — sourced by /audit-substrate-output-discipline skill + scripts/sweep-kiss-dispatch.sh.
|
|
23
|
-
# source lib/output-discipline.sh
|
|
24
|
-
# classify_artifact <artifact-type> <path> # prints label to stdout; exit 0 always
|
|
25
|
-
# has_kiss_dispatch <path> # exit 0 if present; exit 1 if absent
|
|
26
|
-
# has_opt_out <path> # exit 0 if opt-out declared; exit 1 if not
|
|
27
|
-
#
|
|
28
|
-
# Sister modules:
|
|
29
|
-
# - lib/mechanism-fidelity.sh (bet 27c WU-3) — sister audit classifier for rule-mechanism claims
|
|
30
|
-
# - scripts/intent-drift-check.sh — used by sweep script for cosine gate per edit
|
|
31
|
-
|
|
32
|
-
set -o pipefail
|
|
33
|
-
|
|
34
|
-
# === has_kiss_dispatch — bool ===
|
|
35
|
-
# Exit 0 if body contains a /kiss dispatch pattern; exit 1 otherwise.
|
|
36
|
-
#
|
|
37
|
-
# Per bassclef-upstream#1246 — the first alternative `/kiss words( --[a-z0-9]+)+`
|
|
38
|
-
# recognizes both single-flag (`/kiss words --grade10`) AND two-flag
|
|
39
|
-
# (`/kiss words --rewrite`, `/kiss words --grade8`, `/kiss words --rewrite --grade8`)
|
|
40
|
-
# forms explicitly. The Dispatch/dispatch alternatives remain as loose
|
|
41
|
-
# fallbacks for prose that mentions the dispatch verb without a bare invocation.
|
|
42
|
-
# Grace window per ADR-031 — the old single-flag form keeps passing while
|
|
43
|
-
# 91 skills sweep to the two-flag pointer.
|
|
44
|
-
has_kiss_dispatch() {
|
|
45
|
-
local file="$1"
|
|
46
|
-
[ -f "$file" ] || return 1
|
|
47
|
-
# Match any of the four canonical /kiss dispatch patterns
|
|
48
|
-
grep -qE '/kiss words( --[a-z0-9]+)+|Dispatch .{0,30}kiss words|dispatches /kiss on|dispatch .{0,30}/kiss' "$file" 2>/dev/null
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
# === has_opt_out — bool ===
|
|
52
|
-
# Exit 0 if SKILL frontmatter declares no_operator_output: true; exit 1 otherwise.
|
|
53
|
-
has_opt_out() {
|
|
54
|
-
local file="$1"
|
|
55
|
-
[ -f "$file" ] || return 1
|
|
56
|
-
# Extract frontmatter (between leading --- ... ---) and check for opt-out field
|
|
57
|
-
awk '/^---$/ { c++; if(c==2) exit; next } c==1' "$file" 2>/dev/null | grep -qE '^no_operator_output:[[:space:]]*true'
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
# === classify_artifact — return label ===
|
|
61
|
-
# Prints one of: PRESENT | ABSENT | OPT_OUT | NOT_APPLICABLE
|
|
62
|
-
# Exit 0 always (informational; not a gate).
|
|
63
|
-
classify_artifact() {
|
|
64
|
-
local artifact_type="$1"
|
|
65
|
-
local file="$2"
|
|
66
|
-
|
|
67
|
-
if [ ! -f "$file" ]; then
|
|
68
|
-
echo "NOT_APPLICABLE"
|
|
69
|
-
return 0
|
|
70
|
-
fi
|
|
71
|
-
|
|
72
|
-
# Opt-out declared in frontmatter (skills only today; extensible)
|
|
73
|
-
if has_opt_out "$file"; then
|
|
74
|
-
echo "OPT_OUT"
|
|
75
|
-
return 0
|
|
76
|
-
fi
|
|
77
|
-
|
|
78
|
-
# Check for /kiss dispatch pattern in body
|
|
79
|
-
if has_kiss_dispatch "$file"; then
|
|
80
|
-
echo "PRESENT"
|
|
81
|
-
else
|
|
82
|
-
echo "ABSENT"
|
|
83
|
-
fi
|
|
84
|
-
return 0
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
# === walk_type — enumerate all files of a given artifact type ===
|
|
88
|
-
# Prints one path per line. Used by audit skill to iterate.
|
|
89
|
-
# Usage: walk_type <artifact-type> [repo-root]
|
|
90
|
-
walk_type() {
|
|
91
|
-
local artifact_type="$1"
|
|
92
|
-
local repo_root="${2:-$(pwd)}"
|
|
93
|
-
|
|
94
|
-
case "$artifact_type" in
|
|
95
|
-
skill|skills)
|
|
96
|
-
find "$repo_root/.claude/skills" -maxdepth 2 -name "SKILL.md" -type f 2>/dev/null | sort
|
|
97
|
-
;;
|
|
98
|
-
rule|rules)
|
|
99
|
-
find "$repo_root/.claude/rules" -maxdepth 1 -name "*.md" -type f 2>/dev/null | sort
|
|
100
|
-
;;
|
|
101
|
-
standard|standards)
|
|
102
|
-
find "$repo_root/standards" -maxdepth 2 -name "*.md" -type f 2>/dev/null | sort
|
|
103
|
-
;;
|
|
104
|
-
hook|hooks)
|
|
105
|
-
find "$repo_root/.claude/hooks" -maxdepth 1 -name "*.sh" -type f 2>/dev/null | sort
|
|
106
|
-
;;
|
|
107
|
-
luminary|luminaries)
|
|
108
|
-
find "$repo_root/.claude/luminaries" -maxdepth 1 -name "*.md" -type f 2>/dev/null | sort
|
|
109
|
-
;;
|
|
110
|
-
adr|adrs)
|
|
111
|
-
find "$repo_root/architecture/decisions" -maxdepth 1 -name "ADR-*.md" -type f 2>/dev/null | sort
|
|
112
|
-
;;
|
|
113
|
-
persona|personas)
|
|
114
|
-
find "$repo_root/docs/personas" -maxdepth 1 -name "*.md" -type f 2>/dev/null | sort
|
|
115
|
-
;;
|
|
116
|
-
template|templates)
|
|
117
|
-
find "$repo_root/templates" -maxdepth 1 -name "*.md" -type f 2>/dev/null | sort
|
|
118
|
-
;;
|
|
119
|
-
*)
|
|
120
|
-
return 1
|
|
121
|
-
;;
|
|
122
|
-
esac
|
|
123
|
-
return 0
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
# === slug_from_path — extract slug from a file path ===
|
|
127
|
-
# Usage: slug_from_path <artifact-type> <path>
|
|
128
|
-
slug_from_path() {
|
|
129
|
-
local artifact_type="$1"
|
|
130
|
-
local file="$2"
|
|
131
|
-
|
|
132
|
-
case "$artifact_type" in
|
|
133
|
-
skill|skills)
|
|
134
|
-
basename "$(dirname "$file")"
|
|
135
|
-
;;
|
|
136
|
-
hook|hooks)
|
|
137
|
-
basename "$file" .sh
|
|
138
|
-
;;
|
|
139
|
-
*)
|
|
140
|
-
basename "$file" .md
|
|
141
|
-
;;
|
|
142
|
-
esac
|
|
143
|
-
}
|
|
@@ -1,171 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
# tier: lite
|
|
3
|
-
# install-class: dual
|
|
4
|
-
# lib/prose-scan-boundary.sh
|
|
5
|
-
#
|
|
6
|
-
# Deep module per @luminary john-ousterhout — narrow interface hides
|
|
7
|
-
# the boundary detection and counter file work behind 3 functions.
|
|
8
|
-
#
|
|
9
|
-
# Purpose — every prose scan hook (kiss, appositive, citation)
|
|
10
|
-
# strips fenced or echoed content BEFORE it scans, and writes counter
|
|
11
|
-
# state that plain-english-steering.sh injects into the next prompt.
|
|
12
|
-
#
|
|
13
|
-
# This closes #1443 canonical case — Stop side prose hooks that fire
|
|
14
|
-
# on verbatim BLOCKED banner echoes at session start plus operator
|
|
15
|
-
# picked shorthand labels. 5 rewrite cycles in 20 turns documented
|
|
16
|
-
# the cost during 2026-09-09b prep.
|
|
17
|
-
#
|
|
18
|
-
# Anchor luminaries:
|
|
19
|
-
# @luminary john-ousterhout — deep module hiding the boundary work
|
|
20
|
-
# @luminary donald-norman — feedback loop through the counter markers
|
|
21
|
-
# @luminary tony-hoare — pre and postcondition on each function
|
|
22
|
-
# @luminary michael-feathers — characterization tests pin behavior
|
|
23
|
-
#
|
|
24
|
-
# Consumers source this lib:
|
|
25
|
-
# source lib/prose-scan-boundary.sh
|
|
26
|
-
#
|
|
27
|
-
# Tests: lib/tests/prose-scan-boundary.test.sh (Tier 0 strict TDD)
|
|
28
|
-
|
|
29
|
-
# =========================================================================
|
|
30
|
-
# strip_scan_boundaries — remove content the scan should not read
|
|
31
|
-
# =========================================================================
|
|
32
|
-
# Interface: IProseScanBoundary (Larman)
|
|
33
|
-
# Inputs: $1 = message text
|
|
34
|
-
# Outputs: stdout — message with fenced or echoed content removed
|
|
35
|
-
# Exit: 0 always
|
|
36
|
-
#
|
|
37
|
-
# Removes:
|
|
38
|
-
# 1. BLOCKED banner blocks (session-start hook echoes; agent cannot rewrite)
|
|
39
|
-
# 2. <!--SCAN_SKIP-->...<!--/SCAN_SKIP--> explicit fence markers
|
|
40
|
-
# 3. Fenced code blocks (``` ... ```)
|
|
41
|
-
# 4. Inline code (`...`)
|
|
42
|
-
strip_scan_boundaries() {
|
|
43
|
-
local message_text="$1"
|
|
44
|
-
[ -z "$message_text" ] && return 0
|
|
45
|
-
# Python does the heavy lifting for regex-safe multiline strip.
|
|
46
|
-
# Fall back to raw text when python3 missing (fail-soft per Nygard).
|
|
47
|
-
if command -v python3 >/dev/null 2>&1; then
|
|
48
|
-
printf '%s' "$message_text" | python3 -c '
|
|
49
|
-
import sys
|
|
50
|
-
import re
|
|
51
|
-
|
|
52
|
-
text = sys.stdin.read()
|
|
53
|
-
|
|
54
|
-
# 1. Strip BLOCKED banner blocks. Banner shape:
|
|
55
|
-
# 🛑🛑🛑 BLOCKED 🛑🛑🛑
|
|
56
|
-
# ────────────
|
|
57
|
-
# content
|
|
58
|
-
# ────────────
|
|
59
|
-
# ACTION: resolve OR ...
|
|
60
|
-
# Silence is not deferral. ...
|
|
61
|
-
#
|
|
62
|
-
# Match the banner line and content until one of:
|
|
63
|
-
# - "Silence is not deferral" line followed by newline (canonical end)
|
|
64
|
-
# - Two consecutive newlines (paragraph break)
|
|
65
|
-
# - Next banner line
|
|
66
|
-
# - End of string
|
|
67
|
-
text = re.sub(
|
|
68
|
-
r"\U0001F6D1\U0001F6D1\U0001F6D1 BLOCKED \U0001F6D1\U0001F6D1\U0001F6D1"
|
|
69
|
-
r".*?"
|
|
70
|
-
r"(?:Silence is not deferral\.[^\n]*\n"
|
|
71
|
-
r"|\n\n(?=\S|\n|$)"
|
|
72
|
-
r"|(?=\U0001F6D1\U0001F6D1\U0001F6D1)"
|
|
73
|
-
r"|$)",
|
|
74
|
-
"",
|
|
75
|
-
text,
|
|
76
|
-
flags=re.DOTALL,
|
|
77
|
-
)
|
|
78
|
-
|
|
79
|
-
# 2. Strip explicit SCAN_SKIP fences
|
|
80
|
-
text = re.sub(
|
|
81
|
-
r"<!--SCAN_SKIP-->.*?<!--/SCAN_SKIP-->",
|
|
82
|
-
"",
|
|
83
|
-
text,
|
|
84
|
-
flags=re.DOTALL,
|
|
85
|
-
)
|
|
86
|
-
|
|
87
|
-
# 3. Strip fenced code blocks
|
|
88
|
-
text = re.sub(r"```.*?```", "", text, flags=re.DOTALL)
|
|
89
|
-
|
|
90
|
-
# 4. Strip inline code
|
|
91
|
-
text = re.sub(r"`[^`]+`", "", text)
|
|
92
|
-
|
|
93
|
-
sys.stdout.write(text)
|
|
94
|
-
'
|
|
95
|
-
else
|
|
96
|
-
# No python — return raw text so consumers still work
|
|
97
|
-
printf '%s' "$message_text"
|
|
98
|
-
fi
|
|
99
|
-
return 0
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
# =========================================================================
|
|
103
|
-
# write_prose_counter — persist a per-turn counter for the steering hook
|
|
104
|
-
# =========================================================================
|
|
105
|
-
# Interface: IProseCounterWriter (Larman)
|
|
106
|
-
# Inputs: $1 = counter name (e.g. "kiss_hits", "appositive_hits")
|
|
107
|
-
# $2 = numeric count
|
|
108
|
-
# $3 = optional JSON payload (findings, offenders, etc.)
|
|
109
|
-
# Outputs: writes state/markers/turn-prose-counters/<name>.json atomically
|
|
110
|
-
# Exit: 0 always (fail-soft on write error per Nygard)
|
|
111
|
-
write_prose_counter() {
|
|
112
|
-
local name="$1"
|
|
113
|
-
local count="$2"
|
|
114
|
-
local payload="${3:-{\}}"
|
|
115
|
-
[ -z "$name" ] && return 0
|
|
116
|
-
[ -z "$count" ] && count=0
|
|
117
|
-
local repo_root
|
|
118
|
-
repo_root="$(_prose_scan_repo_root)"
|
|
119
|
-
local dir="${repo_root}/state/markers/turn-prose-counters"
|
|
120
|
-
local out_file="${dir}/${name}.json"
|
|
121
|
-
mkdir -p "$dir" 2>/dev/null || return 0
|
|
122
|
-
local ts
|
|
123
|
-
ts="$(date -u +"%Y-%m-%dT%H:%M:%SZ" 2>/dev/null || echo "unknown")"
|
|
124
|
-
# Atomic write via tmp + mv
|
|
125
|
-
local tmp
|
|
126
|
-
tmp="$(mktemp "${dir}/.${name}.XXXXXX")" || return 0
|
|
127
|
-
cat > "$tmp" <<JSON
|
|
128
|
-
{
|
|
129
|
-
"counter": "${name}",
|
|
130
|
-
"count": ${count},
|
|
131
|
-
"updated_at": "${ts}",
|
|
132
|
-
"payload": ${payload}
|
|
133
|
-
}
|
|
134
|
-
JSON
|
|
135
|
-
mv "$tmp" "$out_file" 2>/dev/null || rm -f "$tmp"
|
|
136
|
-
return 0
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
# =========================================================================
|
|
140
|
-
# read_prose_counter — read a per-turn counter for prompt injection
|
|
141
|
-
# =========================================================================
|
|
142
|
-
# Interface: IProseCounterReader (Larman)
|
|
143
|
-
# Inputs: $1 = counter name
|
|
144
|
-
# Outputs: stdout — JSON content, or empty when marker missing
|
|
145
|
-
# Exit: 0 always (fail-soft per Nygard)
|
|
146
|
-
read_prose_counter() {
|
|
147
|
-
local name="$1"
|
|
148
|
-
[ -z "$name" ] && return 0
|
|
149
|
-
local repo_root
|
|
150
|
-
repo_root="$(_prose_scan_repo_root)"
|
|
151
|
-
local marker="${repo_root}/state/markers/turn-prose-counters/${name}.json"
|
|
152
|
-
[ -f "$marker" ] || return 0
|
|
153
|
-
cat "$marker" 2>/dev/null || true
|
|
154
|
-
return 0
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
# =========================================================================
|
|
158
|
-
# _prose_scan_repo_root — resolve repo root under both install classes
|
|
159
|
-
# =========================================================================
|
|
160
|
-
# Internal helper. Prefer $CLAUDE_PROJECT_DIR (project install), fall
|
|
161
|
-
# back to lib file's parent (operator install). Per install-class: dual
|
|
162
|
-
# discipline from ADR-035 substrate-as-system tenet.
|
|
163
|
-
_prose_scan_repo_root() {
|
|
164
|
-
if [ -n "${CLAUDE_PROJECT_DIR:-}" ] && [ -d "${CLAUDE_PROJECT_DIR}" ]; then
|
|
165
|
-
echo "${CLAUDE_PROJECT_DIR}"
|
|
166
|
-
return 0
|
|
167
|
-
fi
|
|
168
|
-
local script_dir
|
|
169
|
-
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
170
|
-
cd "${script_dir}/.." && pwd
|
|
171
|
-
}
|