Metadata-Version: 2.5
Name: team-claude-doctor
Version: 0.1.0
Summary: Deterministic, team-aware AI workbench configuration auditor
Project-URL: Repository, https://github.com/dhk/team-claude-doctor
Project-URL: Issues, https://github.com/dhk/team-claude-doctor/issues
License-Expression: MIT
License-File: LICENSE
Requires-Python: >=3.11
Requires-Dist: httpx>=0.27
Requires-Dist: pydantic>=2
Requires-Dist: pyyaml>=6
Requires-Dist: typer>=0.12
Description-Content-Type: text/markdown

# team-claude-doctor

> **Work in progress.** This repository is being built in public. Expect the shape of the project to change quickly: explanatory images and research artifacts will increasingly be replaced or supplemented by working code, executable checks, and install instructions as the implementation lands.

Team-aware auditing for AI coding-workbench configuration. Phase 1 focuses on the instruction and memory surfaces around `CLAUDE.md`, `AGENTS.md`, rules, local overrides, and auto-memory, then compares what is present with a versioned team-conventions corpus.

![Where agent instructions come from](docs/agent-instruction-surfaces.svg)

## Where agent instructions come from

Agent instructions do not live in one file. Claude Code assembles context across organization policy, user-level preferences, repository conventions, path-scoped rules, local overrides, and auto-memory. The result is a hierarchy that is powerful but easy to misunderstand: what loads can depend on where a session starts, which files exist, which path is being read, and how fallback behavior is configured.

The diagram above is a compact map of that instruction surface. The SVG is kept as the version-controlled source; [re-rendering instructions](docs/agent-instruction-surfaces-rendering.md) document the semantic connector requirements and reference the [DHK Design System](https://www.dhk.io/design-system.md). One particularly useful example is the `CLAUDE.local.md` / `AGENTS.md` interaction: adding a local override can change whether `AGENTS.md` is read unless the fallback mode is configured accordingly.

The diagram distills roughly 100,000 words of research into 272 words — coincidentally, the conventional word count of the Gettysburg Address.

**Original research:** [Instruction-File Landscape & team-claude-doctor Positioning](docs/research-brief.md)

## What this project is becoming

The goal is not another single-player linter. Claude Code already provides native prompt-auditing capabilities. team-claude-doctor is intended to add the team layer: discover how a working environment is configured, compare it with accepted team conventions and vendor behavior, surface divergence, and turn useful practices discovered in real work into explicit, reviewable guidance.

The current research brief describes the Phase 1 scan surface, multi-tool instruction-file behavior, the proposed team corpus, and the distinction between vendor-baseline findings, team-convention divergence, and acknowledged team overrides.

## Implementation status

The Phase 1 CLI is available from a checkout. It remains an early implementation; the supported checks and limitations are documented below.

A read-only, deterministic audit CLI for AI coding workbench configuration.
It inspects Claude, Codex, Copilot and Gemini instruction files and checks
explicit team conventions. It never calls an LLM, executes instructions, edits
workspace files, or invokes Claude Code automatically.

## Install and run

From a checkout (Python 3.11+ and [uv](https://docs.astral.sh/uv/) required):

```sh
uv sync
uv run team-claude-doctor version
uv run team-claude-doctor corpus sync --help
uv run team-claude-doctor audit --help
uv run team-claude-doctor audit .
uv run team-claude-doctor audit . --adapter claude --adapter codex --json
uv tool install .
```

The package and entry point are named `team-claude-doctor`. Once a release is
published to PyPI, `uv tool install team-claude-doctor` can install it by name;
this repository change does not publish a release.

The CLI discovers the enclosing Git root using filesystem markers, including
worktree `.git` files. Outside a Git repository it audits personal scopes only.
It does not require the Git executable except when fetching a `git:` corpus.
Use `--config FILE` to choose an explicit configuration. Otherwise the CLI reads
`.claude-doctor.yaml` at the detected root (or current workspace for non-repos).
Relative corpus and cache paths are resolved against that root.

Exit status is **0** for a completed audit without error findings, **1** for team
violations, and **2** for invalid inputs or an incomplete audit (for example an
unreadable instruction file or unavailable configured corpus). JSON includes
findings, source selection, and notes; invalid input returns an `error` object.
Human-readable findings are grouped by vendor baseline, team divergence, and
declared deviations; JSON retains its flat findings list.
Warnings alone do not fail a complete audit. Findings contain `id`, `adapter`,
`layer`, `severity`, `path`, `message`, `reference` URL, and an optional suggested
`fix`. Reports include paths and declared override metadata, not instruction-file
contents. Review reports before sharing them.

## Team conventions

Start with `.claude-doctor.yaml.example` and `corpus/conventions.example.yaml`.
Examples are never activated automatically. A minimal configuration is:

```yaml
team: example-team
corpus:
  source: path:corpus/conventions.example.yaml
adapters: [claude, codex, copilot, gemini]
delegate_doctor_audit: true
```

A corpus is a YAML mapping with `team`, integer `version`, `conventions`, and
optional `overrides`. Supported conventions are `canonical_entry`, `claude_shim`,
`gemini_shim`, `rules_dir`, and `agents_prefix`. The canonical file must contain
text; shim checks require the configured standalone line. Directory checks apply
to Claude. Copilot instructions differing from the canonical file produce a review
finding, even when they mention or link to that file. References do not prove
alignment; textual difference is not proof of a semantic contradiction. No Copilot cross-file precedence is invented.

- **vendor-baseline**: structural diagnostics and a reminder to run Claude Code
  `/doctor prompt-audit` for native conflict, staleness, size and hook checks.
- **team**: violations of configured conventions are errors with suggested fixes.
  Embedded examples never impose team preferences on unconfigured users.
- **deviation**: declared team overrides are informational when both rationale
  and owner are nonblank, warnings otherwise. They remain visible even when
  team checks pass. Free-form override text is metadata, not executable policy;
  it does not silently disable a check or interpret prose as a numeric rule.

Unrelated personal preferences are not flagged. `delegate_doctor_audit: false`
reports that duplicate native checks are unavailable and exits 2, rather than
pretending to run them. Corpus check files in `corpus/checks/` are validated,
versioned YAML-frontmatter definitions bundled in the wheel; Phase 1 check logic
is implemented in Python, not dynamically loaded from downloaded prose.

## Corpus sources and cache

| Source | Input |
| --- | --- |
| `path:/local` or a relative path | A conventions YAML file, or directory containing `conventions.yaml` |
| `https://...` | A direct conventions YAML response; redirects are not followed |
| `gh:owner/repo` | `corpus/conventions.yaml` from the configured `ref` (default `main`), via public GitHub raw HTTPS |
| `git:https://...` | `corpus/conventions.yaml` fetched into a temporary bare Git repository; supports refs accepted by Git fetch; no checkout or hooks |
| `drive:folder-id` | Exactly one `conventions.yaml` file in the folder, using Google Drive API read access |

For Drive, set `TEAM_CLAUDE_DOCTOR_DRIVE_TOKEN` to an OAuth access token with
read access to the folder. The CLI does not perform OAuth login or refresh.
For private Git repositories use an existing Git credential helper; embedded
credentials in Git URLs and non-HTTPS Git transports are rejected. `gh:` does
not use the desktop app's GitHub connection.

Remote sources are cached beneath `~/.claude-doctor/corpus/<team>/`, or the
configured `corpus.cache`. Cache identity includes the source and ref. Only
validated, normalized corpora with a matching team are cached. A fetch failure
uses a valid cache with an explicit stale warning, then the embedded baseline;
both are incomplete audits (exit 2). Local source failures use the baseline.
If the embedded definitions are unavailable, the report marks report-only mode.
The scanner itself is filesystem-only; only configured corpus resolution uses
network access. Remote responses and individual text files are limited to 1 MB.

### Explicit corpus sync

`team-claude-doctor corpus sync [WORKSPACE]` validates the configured source and
atomically updates its cache, including for local corpus files. It supports
`--config FILE` and `--json`; no instruction scan is performed. Exit 0 means a
current corpus was successfully cached. Exit 2 means the source is unavailable,
only stale cached data is available, or the cache could not be written. Existing
cache data is preserved on failed refreshes. JSON exposes `status`, `source`,
`team`, `cache_path`, and `notes`; missing/invalid configuration returns `error`.
Malformed Drive listings follow the same fallback path as other fetch failures.

## Scope and limitations

Claude collection includes managed policy, root and `.claude/CLAUDE.md`, `CLAUDE.local.md`,
`.claude/rules/`, personal `~/.claude/CLAUDE.md`, and the current project's
path-keyed auto-memory file. Root `AGENTS.md` is its fallback only when no
project Claude instruction file or `CLAUDE.local.md` exists. Unreadable native
files do not enable the fallback. It does not scan unrelated
projects' auto-memory. Alternate Claude project-key encodings are not discovered.

Codex scans per-directory `AGENTS.md` and `AGENTS.override.md`, personal files,
and legacy `CODEX.md`/`instructions.md` names. Its scope helper orders user,
root and nested files, selecting an override at each level and placing nearest
instructions last. The audit does not attempt to interpret conflicting prose.

Copilot scans `.github/copilot-instructions.md`, scoped instruction files,
`AGENTS.md`, and personal instructions; scoped files must have valid YAML and a
nonempty string `applyTo`. Gemini scans root/personal `GEMINI.md`,
`.gemini/config.yaml` and `.gemini/styleguide.md`, validating config YAML shape.
These paths follow this project's Phase 1 spec; the CLI does not guarantee a
particular vendor runtime will load every discovered file.

Instruction symlinks and common generated directories are skipped. An unreadable
file is reported as unreadable, not silently treated as absent. Managed Claude policy is read from `/Library/Application Support/ClaudeCode/CLAUDE.md`
on macOS or `/etc/claude-code/CLAUDE.md` on Linux, following the research brief.
Managed discovery for other platforms and tools is not implemented.
Semantic contradiction detection, arbitrary custom check execution, automatic
fixes, and Phase 2 recommendation diffs are outside this implementation.

## Development

```sh
uv sync
uv run pytest
uv run ruff check .
uv run ruff format --check .
uv build
```

Tests isolate personal scopes and use fixtures under `tests/fixtures/`; network
resolver tests use HTTP mocks. No live provider calls are needed for the suite.


CI runs tests, lint, distribution builds and installed-wheel smoke checks on
Python 3.11–3.14 on Linux and Python 3.12 on macOS. The smoke checks run outside
the checkout with synthetic instruction files and an isolated home directory.

## License

MIT; see [LICENSE](LICENSE). The license is included in the source and wheel
distributions. No PyPI release is published by the CI workflow.
