Summary
Ship the .pi/delegate/, .pi/fusion/, .pi/tasks/ ignore entries to subscriber repositories alongside the Pi pin the subscription controller already writes, and make verify-no-work-records fail when those directories are tracked. Today only .ai-work/ is covered, and the gate skips .pi/* entirely.
Current behaviour
Update Cratis AI Profile Subscription (.github/workflows/update-ai-profile-subscription.yml, .github/scripts/update-ai-profile-subscription.mjs) writes exactly two files in a subscriber: .cratis/ai.json and .pi/settings.json (README.md:22-23, workflow line 176). It writes nothing about ignoring Pi's runtime directories.
.github/workflows/verify-no-work-records.yml:58 skips .pi/* (with .ai/*, .claude/*, .github/*, .agents/*, .ai-work/*) for its name rule, so tracked content under .pi/fusion/ (candidates, attempts, evaluator output, every prompt and tool call of a fusion run), .pi/delegate/ and .pi/tasks/ is never inspected. These directories are session artifacts in the sense of the .ai-work/ rule (AGENTS.md:6-12) and they are large.
- There is no shared
.gitignore content in this repository (its own .gitignore is the two-line .ai-work/ entry) and none is shipped by the corpus, so each repository's Pi runtime state is ignored only if someone added the entries by hand. Cratis/AI's own .gitignore already carries .pi/delegate/, .pi/fusion/, .pi/tasks/ and .pi/*-session-*/; consumers do not.
Desired behaviour
- The subscription controller, when it writes
.pi/settings.json, also ensures a managed block in the subscriber's .gitignore (# cratis-ai: pi runtime state … .pi/delegate/, .pi/fusion/, .pi/tasks/, .pi/*-session-*/) and keeps .ai-work/ there; the block is idempotent and the change is part of the same reviewed PR the controller already opens. Dry run reports whether the block is missing.
verify-no-work-records adds a rule: tracked paths under .pi/delegate/, .pi/fusion/, .pi/tasks/ or .pi/*-session-*/ are violations (.pi/settings.json, .pi/extensions/ and other tracked adapter files stay allowed).
README.md documents the managed .gitignore block.
Acceptance
Done when:
- A controller dry run against a fixture subscriber without the block reports it;
--apply in a disposable checkout adds it once and a second run changes nothing.
- The gate fails on a fixture with a tracked
.pi/fusion/x/prompt.md and passes when the file is untracked.
Verify by:
node .github/scripts/update-ai-profile-subscription.mjs --repository tests/fixtures/subscriber-no-gitignore-block --release-manifest tests/fixtures/release-manifest.json # reports the missing block
node --test .github/scripts/ # controller fixtures including the gitignore block
.github/scripts/verify-no-work-records.sh --self-test # includes the new .pi rule once the exit-2/self-test issue lands
Mutation proof: remove .pi/fusion/ from the managed block in the fixture; the dry run reports the block as incomplete.
Out of scope
Whether Stagehand ingests Pi fusion evidence (a Stagehand decision); cleaning history in repositories that already track these directories (each repository's own PR).
Dependencies
Source: AI-Learning F-92. Depends on: nothing. Related: #68, #71 (first subscriber canary; the block ships with the first applied update); the exit-2/self-test issue in this repository.
Summary
Ship the
.pi/delegate/,.pi/fusion/,.pi/tasks/ignore entries to subscriber repositories alongside the Pi pin the subscription controller already writes, and makeverify-no-work-recordsfail when those directories are tracked. Today only.ai-work/is covered, and the gate skips.pi/*entirely.Current behaviour
Update Cratis AI Profile Subscription(.github/workflows/update-ai-profile-subscription.yml,.github/scripts/update-ai-profile-subscription.mjs) writes exactly two files in a subscriber:.cratis/ai.jsonand.pi/settings.json(README.md:22-23, workflow line 176). It writes nothing about ignoring Pi's runtime directories..github/workflows/verify-no-work-records.yml:58skips.pi/*(with.ai/*,.claude/*,.github/*,.agents/*,.ai-work/*) for its name rule, so tracked content under.pi/fusion/(candidates, attempts, evaluator output, every prompt and tool call of a fusion run),.pi/delegate/and.pi/tasks/is never inspected. These directories are session artifacts in the sense of the.ai-work/rule (AGENTS.md:6-12) and they are large..gitignorecontent in this repository (its own.gitignoreis the two-line.ai-work/entry) and none is shipped by the corpus, so each repository's Pi runtime state is ignored only if someone added the entries by hand. Cratis/AI's own.gitignorealready carries.pi/delegate/,.pi/fusion/,.pi/tasks/and.pi/*-session-*/; consumers do not.Desired behaviour
.pi/settings.json, also ensures a managed block in the subscriber's.gitignore(# cratis-ai: pi runtime state….pi/delegate/,.pi/fusion/,.pi/tasks/,.pi/*-session-*/) and keeps.ai-work/there; the block is idempotent and the change is part of the same reviewed PR the controller already opens. Dry run reports whether the block is missing.verify-no-work-recordsadds a rule: tracked paths under.pi/delegate/,.pi/fusion/,.pi/tasks/or.pi/*-session-*/are violations (.pi/settings.json,.pi/extensions/and other tracked adapter files stay allowed).README.mddocuments the managed.gitignoreblock.Acceptance
Done when:
--applyin a disposable checkout adds it once and a second run changes nothing..pi/fusion/x/prompt.mdand passes when the file is untracked.Verify by:
Mutation proof: remove
.pi/fusion/from the managed block in the fixture; the dry run reports the block as incomplete.Out of scope
Whether Stagehand ingests Pi fusion evidence (a Stagehand decision); cleaning history in repositories that already track these directories (each repository's own PR).
Dependencies
Source: AI-Learning F-92. Depends on: nothing. Related: #68, #71 (first subscriber canary; the block ships with the first applied update); the exit-2/self-test issue in this repository.