Skip to content

Enforcement Tiers

Every convention transcend codifies can be rendered at one of three tiers. The tier is chosen per-rule during the interview, defaulting from the option’s tier_default in pillar.yaml adjusted by the project’s overall enforcement appetite.

TierMechanismBlocks?Renders
1 — DOCSCLAUDE.md summary + .claude/rules/<x>.md (path-scoped via paths:)norule.* + claudemd.* fragment
2 — ADVISORYnon-blocking PostToolUse / Stop hook that prints a reminderno+ hook.advisory.* block & script
3 — BLOCKINGPreToolUse hook that returns permissionDecision: deny (exit 2)yes+ hook.blocking.* block & script

Tier 1 is always emitted. Tier 2 and Tier 3 are additive. A single convention may be both Tier 2 and Tier 3 (e.g. nudge on every untested edit AND hard-block the push).

The interview asks for an overall appetite once, which caps and seeds per-rule defaults:

  • docs-only → cap at Tier 1 (no hooks generated).
  • advisory → cap at Tier 2; tier_default of 3 is clamped to 2.
  • strict → allow Tier 3; bump each option’s tier_default up one where the option is tier_eligible for the higher tier.

The developer can still override any individual rule’s tier in the per-rule pass.

ConventionTier 1Tier 2Tier 3
Tests green before pushrules/testing.md: “push only on green”untested-edit.sh warns when src changed, no test changedpush-gate.sh "tests" "{test_cmd}" on Bash(git push *)
No direct push to mainrules/git-workflow.mdon-protected-branch.sh reminds at Stop if on main with changesprotect-main.sh denies push targeting main (or bare push on it)
Module boundaryrules/architecture.md boundary tablemodule-boundary.sh warn notes cross-feature imports (PostToolUse)module-boundary.sh block denies them (PreToolUse)
Lint/typecheck cleanrules/quality-gates.mdlint-on-edit.sh (touched file only)push-gate.sh "lint/typecheck" "{lint_cmd} && {typecheck_cmd}"

Hook fragments are JSON files of the shape {"event": "<HookEventName>", "entry": {...}}; the generator appends each rendered entry to the target project’s settings.json hooks.<event> array and copies the referenced scripts into .claude/scripts/transcend/.

Scripts are POSIX sh (no bashisms), parse JSON via python3 (present on macOS/Linux) rather than jq, and avoid realpath/sed -i. Windows users need a POSIX shell (Git Bash / WSL); a .cmd shim is deferred to a later milestone.