Skip to content

Flatten the skill chain: short dispatchers, plan_branches folded, mandatory-load budget - #26

Merged
Jammy2211 merged 1 commit into
mainfrom
feature/skill-chain-flatten
Jul 8, 2026
Merged

Flatten the skill chain: short dispatchers, plan_branches folded, mandatory-load budget#26
Jammy2211 merged 1 commit into
mainfrom
feature/skill-chain-flatten

Conversation

@Jammy2211

Copy link
Copy Markdown
Contributor

Roadmap item 6. Three cuts to the ~1,100-line instruction chain a /feature walk loads:

  • SKILL.md dispatchers: the 5 workflow skills each restated the body plus generic Codex-adapter prose. Now ≤15 lines each; the generic rules live once in WORKFLOW.md → "Cross-harness notes". Load-bearing contracts (## API Changes, ## Scripts Changed, library-first gate) are kept in the dispatcher.
  • plan_branches folded into start_dev: it was only ever run at start_dev step 4 (and by start_dev_for_user). Procedure now in start_dev/reference.md → "Branch survey" (lazy), standalone skill retired (installed symlink removed too).
  • Line budget = mandatory load: check_skill_line_counts.sh sums SKILL.md + body per skill (reference.md exempt); all 29 skills within 200.

🤖 Generated with Claude Code

…lded

- The five workflow SKILL.md files carried ~20 lines each of per-skill
  Codex-adapter boilerplate restating the body; they are now <=15-line
  dispatchers (frontmatter + follow-the-body + the load-bearing contracts:
  API Changes / Scripts Changed / library-first gate). The generic adapter
  rules move to one "Cross-harness notes" section in WORKFLOW.md.
- plan_branches is folded into start_dev: the procedure lives in
  start_dev/reference.md ("Branch survey"), loaded only at step 4 instead of
  being a separately installed skill; references updated.
- check_skill_line_counts.sh now enforces the budget as MANDATORY LOAD
  (SKILL.md + body summed, reference.md exempt) rather than per file.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 8, 2026 10:34
@Jammy2211
Jammy2211 merged commit eb0c7fb into main Jul 8, 2026
@Jammy2211
Jammy2211 deleted the feature/skill-chain-flatten branch July 8, 2026 10:34

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR reduces duplication and mandatory-load size across PyAutoBrain workflow skills by centralizing cross-harness guidance in skills/WORKFLOW.md, folding /plan_branches into start_dev reference material, and enforcing a “mandatory-load” line budget.

Changes:

  • Centralize shared “cross-harness” adapter notes in skills/WORKFLOW.md and slim multiple workflow SKILL.md dispatchers to point at their body files.
  • Retire the standalone plan_branches skill by moving its procedure into skills/start_dev/reference.md and updating callers.
  • Update the skill line-count guard to evaluate mandatory-load size as SKILL.md + <skill>.md per directory.

Reviewed changes

Copilot reviewed 11 out of 14 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
skills/WORKFLOW.md Adds cross-harness guidance and removes /plan_branches from the workflow entry-point list.
skills/start_workspace/SKILL.md Flattens dispatcher to point at the body + shared workflow notes.
skills/start_library/SKILL.md Flattens dispatcher to point at the body + shared workflow notes.
skills/start_dev/start_dev.md Replaces /plan_branches step with “Branch survey” reference.
skills/start_dev/SKILL.md Flattens dispatcher to point at the body + shared workflow notes.
skills/start_dev/reference.md Adds “Branch survey” section (former /plan_branches).
skills/start_dev_for_user/start_dev_for_user.md Updates branch survey reference.
skills/ship_workspace/SKILL.md Flattens dispatcher while preserving key contracts (scripts changed, library-first gate).
skills/ship_library/SKILL.md Flattens dispatcher while preserving key contracts (API changes, downstream impact).
skills/repo_cleanup/SKILL.md Updates references away from plan_branches.
skills/plan_branches/SKILL.md Removes retired skill.
bin/README.md Updates documentation to remove plan_branches from the listed workflow skills.
bin/install.sh Updates installer docs to remove plan_branches mention.
bin/check_skill_line_counts.sh Changes guard to enforce a mandatory-load budget per skill directory.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Produce the two-level plan (high-level + detailed) as in `/start_dev` step 3, and
run `/plan_branches` reasoning — suggest `feature/<task-name>` and derive the
worktree root. We do **not** create or rename an issue.
run the branch survey (`start_dev/reference.md` → "Branch survey") — suggest
Jammy2211 pushed a commit that referenced this pull request Aug 10, 2026
…t on

PyAutoMind REFERENCE.md states the contract: Intake persists Difficulty: from
the shared sizing faculty "so the value shown up front is the one the Feature
Agent later acts on". It was not acted on. _feature.py mentioned Difficulty
once, where it PRINTED its own re-derived score, and read no header key at all
— not Difficulty:, not Status:, not Priority:, not Blocked-by:/Closes-when:.

The visible failure: `feature select` recommended a prompt declaring
Status: blocked, Priority: low AND an explicit Blocked-by: gate whose body says
"do not start before the queue runner has run cleanly".

Parsing lands in the sizing faculty, beside the derivation it overrides, so
declared and derived stay in one place and the bug/refactor conductors get the
same reading for free:

- declared_header() reads Difficulty/Status/Priority/Blocked-by/Closes-when,
  skipping fenced blocks. That skip is load-bearing, not tidiness: the bug
  prompt driving this fix QUOTES the offending header in a ```-block, so
  without it the bug report would declare itself blocked. Same rule and same
  reason as PyAutoMind lifecycle.py:draft_gate_refs.
- trailing `# note` comments are stripped, splitting on " #" so a Repo#123 ref
  survives intact (the live backlog has both forms on one line).
- an unrecognised Difficulty: value is ignored rather than trusted.

The ranker then honours them: declared difficulty overrides derived (with the
disagreement REPORTED, not silently resolved — the gap is evidence about the
heuristic); Priority: orders the shortlist above the difficulty term; and a
prompt declaring Status: blocked or an unresolved Blocked-by: sinks below
everything and can never be the recommended pick. It stays listed in its own
labelled band so a human can see and override, and next_action says do not
start.

declared_blocked() is deliberately conservative: this agent is offline and
cannot tell whether a gate has since closed, so an unresolved Blocked-by: reads
as blocked and the output points at `lifecycle.py issues --drafts`, which does
resolve refs against GitHub. Being wrongly held back is cheap and visible;
being wrongly recommended is the failure this exists to stop.

Measured on the live backlog: the blocked prompt drops from rank 1 to last of
27, correctly labelled, and two further blocked prompts surface that had not
been noticed by hand. draft_staleness_detection_signals moves from too-large
#26 to medium #5 — it derived too-large purely on file length, and length is a
bad size proxy because a prompt grows as it accumulates findings.

New tests are hermetic and pin the regression by the offending prompt's HEADER
SHAPE rather than the live file, so fixing the backlog cannot silently retire
them. Verified they actually bite: reverting only _feature.py fails 7 of the
10. Fixtures use invented repo names, so the file adds no tenant-firewall
instance facts.

Prompt: PyAutoMind draft/bug/pyautobrain/feature_ranker_ignores_header_keys.md

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WSCA1h6cSKMNwFmWEsxuCL
Jammy2211 added a commit that referenced this pull request Aug 10, 2026
…t on (#217)

PyAutoMind REFERENCE.md states the contract: Intake persists Difficulty: from
the shared sizing faculty "so the value shown up front is the one the Feature
Agent later acts on". It was not acted on. _feature.py mentioned Difficulty
once, where it PRINTED its own re-derived score, and read no header key at all
— not Difficulty:, not Status:, not Priority:, not Blocked-by:/Closes-when:.

The visible failure: `feature select` recommended a prompt declaring
Status: blocked, Priority: low AND an explicit Blocked-by: gate whose body says
"do not start before the queue runner has run cleanly".

Parsing lands in the sizing faculty, beside the derivation it overrides, so
declared and derived stay in one place and the bug/refactor conductors get the
same reading for free:

- declared_header() reads Difficulty/Status/Priority/Blocked-by/Closes-when,
  skipping fenced blocks. That skip is load-bearing, not tidiness: the bug
  prompt driving this fix QUOTES the offending header in a ```-block, so
  without it the bug report would declare itself blocked. Same rule and same
  reason as PyAutoMind lifecycle.py:draft_gate_refs.
- trailing `# note` comments are stripped, splitting on " #" so a Repo#123 ref
  survives intact (the live backlog has both forms on one line).
- an unrecognised Difficulty: value is ignored rather than trusted.

The ranker then honours them: declared difficulty overrides derived (with the
disagreement REPORTED, not silently resolved — the gap is evidence about the
heuristic); Priority: orders the shortlist above the difficulty term; and a
prompt declaring Status: blocked or an unresolved Blocked-by: sinks below
everything and can never be the recommended pick. It stays listed in its own
labelled band so a human can see and override, and next_action says do not
start.

declared_blocked() is deliberately conservative: this agent is offline and
cannot tell whether a gate has since closed, so an unresolved Blocked-by: reads
as blocked and the output points at `lifecycle.py issues --drafts`, which does
resolve refs against GitHub. Being wrongly held back is cheap and visible;
being wrongly recommended is the failure this exists to stop.

Measured on the live backlog: the blocked prompt drops from rank 1 to last of
27, correctly labelled, and two further blocked prompts surface that had not
been noticed by hand. draft_staleness_detection_signals moves from too-large
#26 to medium #5 — it derived too-large purely on file length, and length is a
bad size proxy because a prompt grows as it accumulates findings.

New tests are hermetic and pin the regression by the offending prompt's HEADER
SHAPE rather than the live file, so fixing the backlog cannot silently retire
them. Verified they actually bite: reverting only _feature.py fails 7 of the
10. Fixtures use invented repo names, so the file adds no tenant-firewall
instance facts.

Prompt: PyAutoMind draft/bug/pyautobrain/feature_ranker_ignores_header_keys.md


Claude-Session: https://claude.ai/code/session_01WSCA1h6cSKMNwFmWEsxuCL

Co-authored-by: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants