diff --git a/ftl_code_expert/cli.py b/ftl_code_expert/cli.py index 0536bfc..240abab 100644 --- a/ftl_code_expert/cli.py +++ b/ftl_code_expert/cli.py @@ -2986,6 +2986,51 @@ def _build_negative_issue_body(belief: dict) -> str: return "\n".join(lines) +def _ensure_labels(platform: str, repo_slug: str, required: set[str]) -> None: + """Create any missing labels on the target repo.""" + if platform == "github": + result = subprocess.run( + ["gh", "label", "list", "--repo", repo_slug, "-L", "1000", + "--json", "name", "-q", ".[].name"], + capture_output=True, text=True, + ) + existing = set(result.stdout.strip().splitlines()) if result.returncode == 0 else set() + for label in required - existing: + click.echo(f" Creating label: {label}", err=True) + r = subprocess.run( + ["gh", "label", "create", label, "--repo", repo_slug, + "--description", "Auto-created by code-expert file-issues"], + capture_output=True, text=True, + ) + if r.returncode != 0: + click.echo(f" Failed to create label {label}: {r.stderr.strip()}", err=True) + elif platform == "gitlab": + result = subprocess.run( + ["glab", "label", "list", "--repo", repo_slug, "-F", "json"], + capture_output=True, text=True, + ) + existing: set[str] = set() + if result.returncode == 0 and result.stdout.strip(): + try: + parsed = json.loads(result.stdout) + if isinstance(parsed, list): + for item in parsed: + if isinstance(item, dict): + name = item.get("name", "") + if name: + existing.add(name) + except (json.JSONDecodeError, TypeError, AttributeError): + pass + for label in required - existing: + click.echo(f" Creating label: {label}", err=True) + r = subprocess.run( + ["glab", "label", "create", "--name", label, "--repo", repo_slug], + capture_output=True, text=True, + ) + if r.returncode != 0: + click.echo(f" Failed to create label {label}: {r.stderr.strip()}", err=True) + + def _create_issue(platform: str, repo_slug: str, title: str, body: str, labels: list[str]) -> str | None: """Create an issue and return its URL, or None on failure.""" @@ -3494,6 +3539,11 @@ def file_issues(ctx, repo_slug, platform_override, labels, dry_run, skip_confirm click.echo(f" {unconfirmed} belief(s) no longer present in code", err=True) remaining = confirmed + # Ensure required labels exist + if not dry_run and remaining: + required_labels = {"reasons-gate", "reasons-negative"} | set(labels) + _ensure_labels(platform, repo_slug, required_labels) + # File issues filed = [] skipped_ids = list(existing) diff --git a/ftl_code_expert/data/CLAUDE.md.template b/ftl_code_expert/data/CLAUDE.md.template index 985bdeb..c65a552 100644 --- a/ftl_code_expert/data/CLAUDE.md.template +++ b/ftl_code_expert/data/CLAUDE.md.template @@ -56,6 +56,45 @@ reasons compact code-expert update --since-last # walk commits + propose + derive + summary code-expert generate-summary # standalone morning summary +# Verification +code-expert verify # check one belief against current code +code-expert verify --all # verify all IN beliefs +code-expert verify --gated # verify beliefs blocking downstream chains +code-expert verify --negative --retract # verify negative beliefs, retract stale ones +code-expert infer-sources --all # infer source files for beliefs missing them + # Status code-expert status ``` + +## Using the Reasons Database + +When a `reasons.db` exists, **search beliefs before reading code**. The belief network contains verified claims about the codebase — architecture, patterns, bugs, invariants — that persist across sessions. + +### Answering questions about the code + +1. `reasons search ""` — find beliefs relevant to the question +2. `reasons show ` — read the full belief, its justification chain, and metadata +3. `reasons explain ` — trace why a belief is IN or OUT +4. Read the actual source code to confirm the belief still holds +5. If a belief is stale, run `code-expert verify ` to formally check it + +### Before modifying code + +1. `reasons search ""` — find beliefs about the affected code +2. Check for negative beliefs (bugs, gaps, risks) that the change might interact with +3. Check for gated beliefs — changes might unblock or break downstream reasoning chains +4. After making changes, verify affected beliefs: `code-expert verify --category ` + +### Key reasons commands + +```bash +reasons search "thread safety" # semantic search across all beliefs +reasons show # full details including dependents +reasons explain # trace justification chain (why IN or OUT) +reasons list # all nodes with status +reasons list --negative # bugs, gaps, risks +reasons list --gated # beliefs blocked by negative findings +``` + +The belief network is the project's accumulated knowledge. Searching it first avoids re-discovering what is already known and surfaces constraints that pure code reading would miss.