You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Given a fresh adopter who just forked apexyard and is running /setup for the first time
When/setup reaches Step 2b (split-portfolio mode) or any step that edits .gitignore / .claude/project-config.json / similar fork-root files
Then the require-active-ticket.sh PreToolUse hook blocks the edit because no .claude/session/current-ticket marker exists yet — and there's nothing the adopter can do about it without filing a placeholder ticket against a project that doesn't exist yet.
Expected: /setup is the bootstrap skill — it runs BEFORE any portfolio is configured, BEFORE any projects are registered, BEFORE any tickets can exist. The ticket-first gate must not block the skill that creates the conditions under which tickets can exist.
Repro
Fresh fork of me2resh/apexyard. Don't configure anything.
Open Claude Code at the fork root. Run /setup.
Pick the split-portfolio path (or any path that edits .gitignore or .claude/project-config.json).
The Edit tool call is blocked by require-active-ticket.sh:
BLOCKED: No active ticket set for this session.
ApexYard requires a ticket BEFORE any code changes …
There is no recoverable path forward without violating the rule's spirit:
Option A: file a placeholder ticket against… nothing? No project is registered yet.
Option B: declare a fake ticket against me2resh/apexyard itself for /setup runs — fragile + ceremony-heavy.
This is the first interaction a fresh adopter has with the framework's safety system. If /setup immediately deadlocks on a hook the adopter has no way to satisfy, one of two things happens:
The adopter abandons the framework (worst case for adoption).
Either way, the framework fails its own first-impression test.
Proposed fix
require-active-ticket.sh should exempt bootstrap skills. Same shape as the existing path exemptions (.claude/, docs/, projects/*/docs/, any *.md), but scoped by active-skill detection rather than path.
Detection mechanism
Two reasonable options:
Read the SkillStart hook context. When a skill is active, write a session marker .claude/session/active-skill containing the skill name. The ticket hook reads it and exempts known-bootstrap skills (setup, handover, update).
Scan the user-prompt history. The most-recent user message contains /setup (or /handover, /update) — exempt the next N tool calls.
Option 1 is more reliable. Option 2 is simpler to implement.
Exempt skill list (default)
# .claude/project-config.defaults.json → ticket.bootstrap_skillsbootstrap_skills:
- setup
- handover # may need to edit registry/ + projects/ before a ticket can exist
- update # may need to edit framework files during upstream-sync
Adopters can extend this list in .claude/project-config.json if they have custom bootstrap skills.
Why config-driven
The default list ships with sensible exemptions. Forks that have additional bootstrap skills (or want to remove some) configure via override. Same pattern as the existing config layer.
Acceptance Criteria
require-active-ticket.sh checks for an active-skill marker (or equivalent detection) BEFORE checking for a ticket marker
When the active skill is in the configured bootstrap_skills list, the ticket check is skipped
setup, handover, update are in the default bootstrap_skills list in .claude/project-config.defaults.json
Tests cover: bootstrap skill active → exempt; non-bootstrap skill active → enforced as today; no active skill marker (legacy) → enforced as today
Doc note in .claude/rules/workflow-gates.md § "Pre-Build Gate" explaining the exemption
Verified: a fresh fork can complete /setup end-to-end without filing a placeholder ticket
Active-skill detection mechanism — needs a SkillStart hook or equivalent. May require small framework infrastructure work to expose the active-skill state to PreToolUse hooks. Implementation depth depends on what Claude Code exposes.
Given / When / Then
Given a fresh adopter who just forked apexyard and is running
/setupfor the first timeWhen
/setupreaches Step 2b (split-portfolio mode) or any step that edits.gitignore/.claude/project-config.json/ similar fork-root filesThen the
require-active-ticket.shPreToolUse hook blocks the edit because no.claude/session/current-ticketmarker exists yet — and there's nothing the adopter can do about it without filing a placeholder ticket against a project that doesn't exist yet.Expected:
/setupis the bootstrap skill — it runs BEFORE any portfolio is configured, BEFORE any projects are registered, BEFORE any tickets can exist. The ticket-first gate must not block the skill that creates the conditions under which tickets can exist.Repro
me2resh/apexyard. Don't configure anything./setup..gitignoreor.claude/project-config.json).Edittool call is blocked byrequire-active-ticket.sh:me2resh/apexyarditself for/setupruns — fragile + ceremony-heavy.pathlib.Path.write_text()— see [Bug] require-active-ticket.sh bypassable via Bash file writes (echo>, python -c, tee, sed -i, etc.) #151 for that side of the bug.Why this matters
This is the first interaction a fresh adopter has with the framework's safety system. If
/setupimmediately deadlocks on a hook the adopter has no way to satisfy, one of two things happens:Either way, the framework fails its own first-impression test.
Proposed fix
require-active-ticket.shshould exempt bootstrap skills. Same shape as the existing path exemptions (.claude/,docs/,projects/*/docs/, any*.md), but scoped by active-skill detection rather than path.Detection mechanism
Two reasonable options:
.claude/session/active-skillcontaining the skill name. The ticket hook reads it and exempts known-bootstrap skills (setup,handover,update)./setup(or/handover,/update) — exempt the next N tool calls.Option 1 is more reliable. Option 2 is simpler to implement.
Exempt skill list (default)
Adopters can extend this list in
.claude/project-config.jsonif they have custom bootstrap skills.Why config-driven
The default list ships with sensible exemptions. Forks that have additional bootstrap skills (or want to remove some) configure via override. Same pattern as the existing config layer.
Acceptance Criteria
require-active-ticket.shchecks for an active-skill marker (or equivalent detection) BEFORE checking for a ticket markerbootstrap_skillslist, the ticket check is skippedsetup,handover,updateare in the defaultbootstrap_skillslist in.claude/project-config.defaults.json.claude/rules/workflow-gates.md§ "Pre-Build Gate" explaining the exemption/setupend-to-end without filing a placeholder ticketRisks / Dependencies
/setupworks; illegit bypass via Bash still works).SkillStarthook or equivalent. May require small framework infrastructure work to expose the active-skill state to PreToolUse hooks. Implementation depth depends on what Claude Code exposes..claude/project-config.jsonalready supports extension; addingticket.bootstrap_skillsis additive.