| name | philosophy-discovery |
| description | Use to discover a target repo's engineering philosophy from its on-disk conventions (CLAUDE.md + .claude/skills/**/SKILL.md). Required for the Principal Engineer agent in prod tier; invoked at the start of its review so findings can be grounded in the repo's own rules rather than reviewer opinion. |
Philosophy Discovery
Your job: surface the target repo's engineering philosophy into a reviewable bundle so a reviewer can audit a diff against rules the repo has actually written down — never against rules the reviewer invented.
You do not judge. You do not synthesize. You collect, label, and return. The calling agent (Principal Engineer, per the prod tier) reads the bundle and forms the verdict.
Where Philosophy Lives
A repo's philosophy — its conventions, its house style, the "how we do things here" — lives in exactly two on-disk locations by convention:
-
CLAUDE.md at the target repo root. Loaded into every Claude Code session by default. Short, high-signal: tech stack, coding conventions, commands, pointers to deeper docs. This file is authoritative when it exists.
-
SKILL.md files under .claude/skills/. Each skill documents a specific workflow or rule set (testing pyramid, dispatch patterns, review protocol, etc.). They load on demand, but for philosophy audit purposes you treat them all as in-scope.
Nothing else counts as "philosophy" for this skill. READMEs, ADRs, and wiki pages may contain useful context, but they are NOT the auditable source — they are not the contract the repo has committed to keeping Claude-aligned. Stick to the two sources above.
Worktree Context
You are invoked from inside a task worktree. AoE creates the worktree as a full git worktree checkout of the target repo at the task's integration branch — every tracked file the repo has appears at the worktree root. That includes CLAUDE.md and .claude/skills/. There is no "parent repo" to reach out to; the worktree is the target repo's checkout, just on a different branch.
<target-repo>/ ← main checkout (wherever the user clones)
└── .worktrees/
└── tpm-<slug>-<task-id>/ ← YOUR CWD — full checkout at integration branch
├── CLAUDE.md ← source (a), tracked file, lives HERE
├── .claude/
│ └── skills/
│ ├── some-skill/
│ │ └── SKILL.md ← source (b), tracked file, lives HERE
│ └── another-skill/
│ └── SKILL.md ← source (b)
└── .tpm/ ← ephemeral per-task scratch
From your CWD:
CLAUDE.md is at ./CLAUDE.md.
- Skills live at
./.claude/skills/**/SKILL.md.
Do NOT resolve these paths via ../. The parent directory of the worktree is the .worktrees/ scratch area (or wherever AoE places worktrees) — it does not contain the target repo's tracked files. Reaching outside the worktree is a bug, not a feature.
The Discovery Process
Step 1 — Probe for CLAUDE.md
if [ -f ./CLAUDE.md ]; then
echo "found: ./CLAUDE.md"
fi
If present, capture its path and full content. Do not edit, do not trim — the reviewer wants the raw text.
Step 2 — Enumerate skills
find ./.claude/skills -type f -name 'SKILL.md' 2>/dev/null | sort
Or, equivalently, using a glob inside the Read/Glob tooling: ./.claude/skills/**/SKILL.md.
For each match, capture its path and full content. Sort by path so bundle order is deterministic between runs — the reviewer should see the same order every time to make diff comparisons possible across review iterations.
Step 3 — Assemble the bundle
Produce a labelled list — one entry per source file. Each entry has two fields: the path (so the reviewer can cite it) and the content verbatim.
- source_path: ./CLAUDE.md
content: |
<full file content, verbatim>
- source_path: ./.claude/skills/testing-pyramid/SKILL.md
content: |
<full file content, verbatim>
- source_path: ./.claude/skills/review-protocol/SKILL.md
content: |
<full file content, verbatim>
The labelled-list shape is the canonical shape for this skill. Not a concatenated blob — a list of {source_path, content} pairs. The reviewer needs to cite specific sources in findings; the path has to survive into the final review body.
Step 4 — Handle the "no sources" case
If neither ./CLAUDE.md nor any ./.claude/skills/**/SKILL.md exists, return an empty bundle:
[]
The empty bundle is a valid, explicit result — not an error. Per the prod-tier contract (see agents/principal-engineer.md, D-05 in the plan), when sources are missing the calling agent emits verdict APPROVED with a note saying "no philosophy to audit against". The missing sources must never be allowed to block a merge and must never be substituted by reviewer intuition.
If only one of the two source types is present (e.g. CLAUDE.md exists but no skills, or skills exist but no CLAUDE.md), the bundle is not empty — it contains whatever was found. Only when both are absent do you return [].
Baseline vs HEAD — Avoiding Tautological Audits
The worktree's HEAD includes the task's in-flight commits. If the task itself edits CLAUDE.md or adds/modifies a SKILL.md, reading the philosophy at HEAD means auditing the diff against a rule it just wrote. That's tautological — the audit will always pass because the rule was drafted to fit the code.
To avoid this, read the philosophy sources at the integration branch tip (the baseline the task's commits landed on top of), not at HEAD. The integration branch is recorded in the plan frontmatter (integration_branch, e.g. feature/mode-tiers) and echoed in .tpm/STATE.md.
Example commands (run from the worktree CWD, replace <base> with the integration branch name):
git cat-file -e "<base>:CLAUDE.md" 2>/dev/null && \
git show "<base>:CLAUDE.md"
git ls-tree -r "<base>" --name-only | grep -E '^\.claude/skills/.*/SKILL\.md$'
git show "<base>:.claude/skills/testing-pyramid/SKILL.md"
Record each source's path as it appears in the tree (e.g. ./CLAUDE.md — same shape as worktree paths) and annotate in the bundle that the content was read at <base>, so the reviewer knows they are auditing against the pre-task rules.
If the task's diff adds or modifies a philosophy file, the reviewer MAY additionally note the drift in their finding body ("CLAUDE.md grew a new rule in this PR; auditing against baseline only"), but the bundle itself stays baseline-scoped. Do not mix HEAD and baseline content in the same entry.
Special case: if the task is bootstrapping the philosophy (the baseline has no CLAUDE.md and no .claude/skills/, and this PR adds them), the baseline bundle is [] — fall through to the no-sources fallback. The PR ships the rules; the next PR is the first one audited against them.
Output Convention
Skills are prompt documents, not functions — this skill doesn't "return" a value at runtime. What it prescribes is a textual discipline for the calling agent: when the Principal Engineer quotes the philosophy in its review, it must present the sources in a consistent, reviewable shape.
Convention: the calling agent embeds the discovered sources into its own response as a fenced YAML block (or a clearly delimited section) using the labelled-list shape from Step 3. Each entry carries source_path + verbatim content. Paths are kept relative to the worktree CWD (so ./CLAUDE.md, not an absolute path) so the reviewer's citations stay stable across machines.
The discipline matters because:
- Citations in findings reference
source_path literally. If the path format drifts, citations become ambiguous.
- The empty bundle case needs a visible marker (the literal
[] block). Silence is not the same as "no philosophy" — the reviewer must be able to see the discovery step ran and found nothing.
- Summarizing or paraphrasing before embedding destroys the reviewer's ability to quote exact text. The convention is verbatim content, not a précis.
The calling agent is responsible for reading and interpreting the embedded sources. This skill does not summarize, rank, or pre-filter.
Anti-patterns
- Inferring philosophy from file paths or framework signals instead of reading the sources. Seeing
tsconfig.json and assuming "strict TypeScript" or seeing jest.config.js and assuming "TDD" is fabrication. The philosophy is what CLAUDE.md / SKILL.md say, not what the reviewer would guess from the stack.
- Fabricating rules that aren't in the discovered text. If the sources are silent on a convention, the bundle is silent on it too. The reviewer must not hallucinate a "this repo probably wants X" rule — they can only cite text that the bundle contains.
- Reaching outside the worktree for philosophy sources. The worktree is a full checkout of the target repo at the integration branch, so tracked philosophy files (
CLAUDE.md, .claude/skills/) live at the worktree root. Stay inside: use ./CLAUDE.md and ./.claude/skills/**/SKILL.md, never ../.
- Auditing against HEAD when the task modifies a philosophy file. Reading the rule the PR just wrote makes the audit tautological. Read baseline content via
git show <base>:… when philosophy files are touched by the diff.
- Summarizing or paraphrasing before embedding. Emit raw file content in the bundle. The reviewer cites exact text in findings; paraphrase destroys the citation.
- Silently dropping a source because it looked irrelevant. If it matches the path convention, include it. Relevance is the reviewer's job, not discovery's.
- Treating "no sources found" as an error. It is a valid outcome. Embed the literal empty-bundle marker (
[]) and let the calling agent apply the APPROVED-with-note fallback.
Example
Worktree CWD: /home/you/tpm-aoe/.worktrees/tpm-auth-task-02/ (a full checkout of tpm-aoe at the integration branch).
Tracked philosophy files visible from the worktree:
./CLAUDE.md
./.claude/skills/testing-pyramid/SKILL.md
./.claude/skills/dispatch-session/SKILL.md
Discovery run:
test -f ./CLAUDE.md && echo found: ./CLAUDE.md
find ./.claude/skills -type f -name 'SKILL.md' | sort
If the task's diff does not modify any philosophy file, read them directly from the worktree. If it does, repeat the probe at the integration branch tip using git show <base>:… and use those contents instead.
Bundle embedded in the reviewer's response:
- source_path: ./CLAUDE.md
content: |
# CLAUDE.md
...
- source_path: ./.claude/skills/dispatch-session/SKILL.md
content: |
---
name: dispatch-session
...
- source_path: ./.claude/skills/testing-pyramid/SKILL.md
content: |
---
name: testing-pyramid
...
The Principal Engineer agent reads this bundle and audits the diff against rules the bundle contains — nothing more, nothing less.