From f2cf7bc73e9db17dd78c3f857b4e94d29dcf3c99 Mon Sep 17 00:00:00 2001 From: Christophe Henner Date: Wed, 7 Oct 2026 19:42:46 +0200 Subject: [PATCH] chore(aethyme): update generated deployment to v0.8.23 Co-Authored-By: Claude Opus 5.5 (1M context) --- .claude/hooks/aethyme-load-context.sh | 88 ++++++ .../skills/aethyme-review-rule-maker/SKILL.md | 194 +++++++++++++ .../references/review-rules.md | 147 ++++++++++ .claude/skills/aethyme/SKILL.md | 83 ++++++ .claude/skills/aethyme/aethyme-explore | 27 ++ .claude/skills/aethyme/references/broker.md | 263 ++++++++++++++++++ .../skills/aethyme/references/dead-code.md | 66 +++++ .claude/skills/aethyme/references/explore.md | 123 ++++++++ .../skills/aethyme/references/graph-task.md | 147 ++++++++++ .claude/skills/aethyme/references/policy.md | 91 ++++++ .claude/skills/repo-act/SKILL.md | 44 +++ .claude/skills/repo-onboarding/SKILL.md | 83 ++++++ .../skills/aethyme-review-rule-maker/SKILL.md | 194 +++++++++++++ .../references/review-rules.md | 147 ++++++++++ .codex/skills/aethyme/SKILL.md | 83 ++++++ .codex/skills/aethyme/aethyme-explore | 27 ++ .codex/skills/aethyme/references/broker.md | 263 ++++++++++++++++++ .codex/skills/aethyme/references/dead-code.md | 66 +++++ .codex/skills/aethyme/references/explore.md | 123 ++++++++ .../skills/aethyme/references/graph-task.md | 147 ++++++++++ .codex/skills/aethyme/references/policy.md | 91 ++++++ .codex/skills/repo-act/SKILL.md | 44 +++ .codex/skills/repo-onboarding/SKILL.md | 83 ++++++ .gitignore | 20 ++ AGENTS.md | 56 ++++ CLAUDE.md | 56 ++++ 26 files changed, 2756 insertions(+) create mode 100755 .claude/hooks/aethyme-load-context.sh create mode 100644 .claude/skills/aethyme-review-rule-maker/SKILL.md create mode 100644 .claude/skills/aethyme-review-rule-maker/references/review-rules.md create mode 100644 .claude/skills/aethyme/SKILL.md create mode 100755 .claude/skills/aethyme/aethyme-explore create mode 100644 .claude/skills/aethyme/references/broker.md create mode 100644 .claude/skills/aethyme/references/dead-code.md create mode 100644 .claude/skills/aethyme/references/explore.md create mode 100644 .claude/skills/aethyme/references/graph-task.md create mode 100644 .claude/skills/aethyme/references/policy.md create mode 100644 .claude/skills/repo-act/SKILL.md create mode 100644 .claude/skills/repo-onboarding/SKILL.md create mode 100644 .codex/skills/aethyme-review-rule-maker/SKILL.md create mode 100644 .codex/skills/aethyme-review-rule-maker/references/review-rules.md create mode 100644 .codex/skills/aethyme/SKILL.md create mode 100755 .codex/skills/aethyme/aethyme-explore create mode 100644 .codex/skills/aethyme/references/broker.md create mode 100644 .codex/skills/aethyme/references/dead-code.md create mode 100644 .codex/skills/aethyme/references/explore.md create mode 100644 .codex/skills/aethyme/references/graph-task.md create mode 100644 .codex/skills/aethyme/references/policy.md create mode 100644 .codex/skills/repo-act/SKILL.md create mode 100644 .codex/skills/repo-onboarding/SKILL.md create mode 100644 AGENTS.md create mode 100644 CLAUDE.md diff --git a/.claude/hooks/aethyme-load-context.sh b/.claude/hooks/aethyme-load-context.sh new file mode 100755 index 0000000..79ee337 --- /dev/null +++ b/.claude/hooks/aethyme-load-context.sh @@ -0,0 +1,88 @@ +#!/usr/bin/env bash +# Aethyme SessionStart hook: load AGENTS.md / CLAUDE.md content into +# `additionalContext` so headless Claude Code sessions (e.g. evaluation +# runs launched via `claude --dangerously-skip-permissions`) discover the +# in-repo agent instructions even when the harness skips the standard +# CWD-CLAUDE.md auto-load. +# +# This script is deployed by `aethyme deploy --repo ` and +# wired into the project's .claude/settings.local.json under +# hooks.SessionStart. +# +# Output protocol: the script must emit a single JSON object on stdout +# of the shape +# {"hookSpecificOutput": {"hookEventName": "SessionStart", +# "additionalContext": ""}} +# Empty stdout (or non-zero exit) = no context injected. + +set -uo pipefail + +cwd="${CLAUDE_PROJECT_DIR:-${PWD}}" + +# Resolve the installed router once, for both telemetry and the JSON envelope. +# Empty means "no router" — telemetry is skipped and the envelope cannot be +# emitted. Repository deployment never embeds a source-checkout path. +if command -v aethyme >/dev/null 2>&1; then + aethyme_bin="aethyme" +else + aethyme_bin="" +fi + +agents="$cwd/AGENTS.md" +claude_md="$cwd/CLAUDE.md" + +context="" + +if [[ -f "$agents" ]]; then + context="$(cat -- "$agents")" +fi + +# Append CLAUDE.md only if it exists AND differs from AGENTS.md +# (typical setup deploys both with identical content). +if [[ -f "$claude_md" ]]; then + if [[ -z "$context" ]] || ! diff -q "$agents" "$claude_md" >/dev/null 2>&1; then + if [[ -n "$context" ]]; then + context+=$'\n\n---\n\n' + fi + context+="$(cat -- "$claude_md")" + fi +fi + +if [[ -z "$context" ]]; then + exit 0 +fi + +# Best-effort telemetry via the native router. The native command also ledgers +# its own arg-parse failures, so this fire-and-forget call does not fail +# invisibly. +if [[ -n "$aethyme_bin" ]] && [[ -d "$cwd" ]]; then + "$aethyme_bin" repo record-wrapper-invocation \ + "$cwd" \ + --wrapper aethyme-sessionstart-hook \ + --detail source=claude-hook \ + >/dev/null 2>&1 || true +fi + +# Interactive Claude Code sessions auto-load the project's CLAUDE.md and +# AGENTS.md themselves, so emitting the same bytes here bills the whole +# policy a second time -- and because it lands in the cached prefix, that +# duplicate is re-read on every turn, not once per session. Only a headless +# harness that skips the standard CWD auto-load needs this injection, and +# the eval runner is what creates that case; it marks every arm with +# AETHYME_EVAL_ARM. The telemetry above stays unconditional so a session +# start is still observable on both paths. +if [[ -z "${AETHYME_EVAL_ARM:-}" ]]; then + exit 0 +fi + +# Emit the JSON envelope via the native router (python-retirement Phase +# 6, 2026-08-01; previously a bare `python3` heredoc calling json.dumps +# — the last Python invocation on the product path). Output is +# byte-identical to the heredoc's. Context goes over a pipe, not argv, +# so a large AGENTS.md cannot blow the argument-list limit. +if [[ -z "$aethyme_bin" ]]; then + # No router reachable: emit nothing rather than an unescaped + # envelope. Empty stdout = no context injected, per the protocol. + exit 0 +fi +printf '%s' "$context" | "$aethyme_bin" repo hook-envelope diff --git a/.claude/skills/aethyme-review-rule-maker/SKILL.md b/.claude/skills/aethyme-review-rule-maker/SKILL.md new file mode 100644 index 0000000..40383f7 --- /dev/null +++ b/.claude/skills/aethyme-review-rule-maker/SKILL.md @@ -0,0 +1,194 @@ +--- +name: aethyme-review-rule-maker +description: Write or tune this repository's Aethyme review rules -- which + changes need which reviews, who performs them, and what appears on the pull + request. Use when asked to set up, enable, debug, or change review routing, + review triggers, PR labels, or the `[review.*]` tables in + `.aethyme/config.toml`. +--- + +# Aethyme Review Rule Maker + +Three tables in `.aethyme/config.toml` decide which reviews a change needs +(`[review.trigger]`), who performs them (`[review.routing]`), and what the pull +request shows (`[review.projection]`). All three are off by default. This skill +is the procedure for writing them against a real repository instead of from +imagination. + +Full field grammar: [`references/review-rules.md`](references/review-rules.md). +Load it when you need a field's exact name, type, or default. + +## The one rule that shapes everything else + +**A rule is a floor an author cannot lower.** Eligibility is the union of what +the repository requires and what the author declared in commit trailers, never +the intersection. So the cost of a rule that is too broad is wasted reviews, +and the cost of one that is too narrow is a missed review. Write the narrow +guards first and widen them with evidence. + +## Procedure + +### 1. Read the current state before changing anything + +```bash +aethyme broker advanced review plan --base --pr 0 +``` + +It performs nothing. `trigger_enabled`, `routing_enabled`, +`projection_enabled` tell you what is already on; `changed_paths` and +`classification` tell you whether the command is reading the tree you expect. +If `changed_paths` is 0 against a branch with work on it, you are standing in +the wrong worktree -- compare `policy_root` and `change_root` in the report. + +### 2. Find the paths that must never miss a review + +Do not guess, and do not ask the user to guess. Look, then propose a list for +them to cut down. Search for the places where a change can grant itself +authority or move money: + +```bash +# CI that can mint credentials, and anything that edits it +ls .github/workflows/ .gitlab-ci.yml 2>/dev/null +# authentication, authorization, secrets, crypto +rg -l --files-with-matches -i 'authenticat|authoriz|\bjwt\b|secret|credential|private_key' --glob '!**/test*' | head -30 +# money and data destruction +rg -l -i 'stripe|payment|charge|refund|DROP TABLE|delete_all' --glob '!**/test*' | head -20 +# schema migrations +fd -t d -d 3 'migrations?' 2>/dev/null | head +``` + +Present the candidates and say which you would keep. A list of three to six +paths is a working guard; a list of forty is a repository-wide review under +another name, and the schedule will end up silently dropping most of it. + +### 3. Name the dimensions + +`require = [...]` takes free strings, not an enum. Pick names the repository +would use in conversation -- `code`, `security`, `performance`, `data`, +`accessibility`, `i18n`. Each name is separately routed and separately +budgeted, so a dimension is worth creating exactly when it would go to a +different reviewer or deserve a different quota. Two dimensions that always +go to the same place with the same budget should be one. + +### 4. Write the trigger table only, and leave the rest off + +```toml +[review.trigger] +enabled = true + +[[review.trigger.rule]] +name = "always-code-review" +require = ["code"] + +[[review.trigger.rule]] +name = "security-sensitive-paths" +require = ["security"] +paths = [".github/workflows/**", "src/auth/**"] +``` + +Routing and projection stay off through this step. A wrong rule now costs a +line in a JSON report; a wrong rule with projection on costs a label on +somebody's pull request. + +### 5. Replay it against real history + +This is the step that separates a rule that works from one that reads well. +Take branches that actually merged and check what the policy would have said: + +```bash +for base in HEAD~1 HEAD~5 HEAD~20; do + echo "=== $base ===" + aethyme broker advanced review plan --base "$base" --pr 0 \ + | python3 -c 'import json,sys; d=json.load(sys.stdin); print([ (e["review_type"], e["because"]) for e in d["eligible"] ])' +done +``` + +Read the `because` array, not just the dimension: it names the rule that +fired. A dimension appearing with a rule you did not expect is the rule to fix. + +Two failure shapes to look for specifically: + +- **Every change eligible for everything.** Usually a rule with no conditions + that was meant to have one, or `paths` written with a leading `/` or a + `./` prefix -- paths are repository-relative, exactly as `git diff + --name-only` prints them. +- **A guarded path producing nothing.** Check the glob: `*` matches one + segment and `**` matches any number including zero, so `src/*/auth.rs` does + not match `src/a/b/auth.rs` but `src/**/auth.rs` does. + +### 6. Set the budget before turning on a backend + +Rules decide what a change deserves. `schedule` decides what it gets, and it +is the half that keeps an active branch from spending forty security reviews. + +```toml +[review.trigger.default_schedule] +debounce_seconds = 600 +max_per_pull_request = 8 + +[review.trigger.schedule.security] +debounce_seconds = 0 +max_per_pull_request = 0 +``` + +Ask the concrete question rather than the abstract one: *on the busiest pull +request this repository had last month, how many reviews of each dimension +would have been acceptable?* That number is `max_per_pull_request`. Exempt a +dimension from the cap only when a missed one is worse than a wasted one -- +which is usually true of `security` and usually false of everything else. + +### 7. Turn on projection, then routing + +In that order. Projection writes a comment and labels, which a human can read +and delete. Routing starts agents and mentions bots, which a human cannot +un-start. + +```toml +[review.projection] +enabled = true +label_prefix = "aethyme/" +reserved = ["skip-review"] +``` + +`label_prefix` is the whole safety mechanism: Aethyme never touches a label +outside it. `reserved` names labels inside it that Aethyme reads and never +writes -- that is where a human parks a decision the broker must not +recompute away. + +```toml +[review.routing] +enabled = true + +[review.routing.default_route] +backend = "record" + +[review.routing.route.security] +backend = "chau7" +max_concurrent = 1 +``` + +Keep `default_route` on `record`. A dimension someone adds later then gets +written down rather than silently starting an agent nobody budgeted for. + +## Asking the coder for classification + +Rules can read what the author declared. Trailers cost a coding agent nothing +-- it is already writing a commit message and already knows what it changed: + +``` +Area: backend +Surface: auth +Risk: high +Review: security +``` + +To get them written, add the instruction to `.aethyme/overrides/agents.json` +and rerun `aethyme deploy --repo "$PWD"`. Do not rely on them for a +guard: a trailer is one line of unverified text, which is exactly why it can +escalate a review and can never waive one. + +## What to hand back + +A diff of `.aethyme/config.toml`, plus the `review plan` output for two or +three real changes showing what the new rules decide. Do not report a policy as +working on the strength of it parsing. diff --git a/.claude/skills/aethyme-review-rule-maker/references/review-rules.md b/.claude/skills/aethyme-review-rule-maker/references/review-rules.md new file mode 100644 index 0000000..6741031 --- /dev/null +++ b/.claude/skills/aethyme-review-rule-maker/references/review-rules.md @@ -0,0 +1,147 @@ +# `[review.*]` field reference + +Every table lives in `.aethyme/config.toml` at the repository root, is read +independently, and is off unless it says `enabled = true`. Unknown keys are +rejected at load rather than ignored, so a typo fails loudly. + +## `[review.trigger]` + +| Key | Type | Default | Meaning | +| --- | --- | --- | --- | +| `enabled` | bool | `false` | Off means no dimension is ever eligible. | +| `schema_version` | int | current | A version newer than the broker understands is an error, never a fallback. | +| `rule` | array of tables | `[]` | See below. | +| `default_schedule` | table | 600s / 8 / false | Budget for a dimension with no entry in `schedule`. | +| `schedule.` | table | -- | Budget for one dimension. | + +### `[[review.trigger.rule]]` + +A rule fires when **every** condition it names holds. A rule that names no +condition matches every change. + +| Key | Type | Required | Meaning | +| --- | --- | --- | --- | +| `require` | list of strings | **yes** | Dimensions this rule demands. An empty or missing `require` is rejected at load. | +| `name` | string | no | Appears in the decision's `because`. Name every rule; the report is unreadable otherwise. | +| `on` | list | no | Lifecycle transitions. Empty means any. | +| `paths` | list of globs | no | Repository-relative. Matching any one path satisfies the condition. | +| `areas` | list | no | `Area:` values the author declared. | +| `surfaces` | list | no | `Surface:` values the author declared. | +| `min_risk` | string | no | Declared `Risk:` at or above this level. | +| `from_fork` | bool | no | Only when the change comes from a fork. | +| `first_time_contributor` | bool | no | Only when the author has not landed here before. | +| `authored_by_model` | bool | no | `true` only when a `Model:` trailer names one; `false` only when none does. | +| `models` | list | no | Only when the declared `Model:` is one of these, compared case-insensitively. | + +**Globs.** `*` matches exactly one path segment. `**` matches any number of +segments including zero. Paths are repository-relative with no leading `/` or +`./`, exactly as `git diff --name-only` prints them. + +**`on` values.** `pull_request_opened`, `ready_for_review`, `reopened`, +`replacement_commit` (force-push, amend, rebase), `additional_commit`, +`base_retargeted`, `review_dismissed`, `scheduled`, `manual`. + +`replacement_commit` and `additional_commit` are separate on purpose: a +force-push that rewrites the same logical change and a commit stacked on top of +already-reviewed work justify different responses. + +`merge_queue_entered` is **rejected at load**: nothing a tick can ask the +provider distinguishes it, so a rule waiting for it would never fire. Do not +write it. + +The transition is derived by comparing the pull request against the last +observation of it, not delivered by a webhook, so it is available to any tick +and needs no inbound endpoint. + +**`min_risk` ranking.** `none` < `low` < `high` = `critical`. An unrecognised +value ranks *above* `low`, so a typo in a risk trailer escalates rather than +silently downgrading. + +### `[review.trigger.schedule.]` + +| Key | Type | Default | Meaning | +| --- | --- | --- | --- | +| `debounce_seconds` | int | `600` | Minimum gap between two reviews of this dimension on one pull request. Inside the window the decision is `defer`, which a later tick reconsiders -- not `skip`, which is settled. | +| `max_per_pull_request` | int | `8` | Cap per pull request. `0` means no cap. | +| `always_on_new_head` | bool | `false` | Re-review when the head moves even past the cap. | + +A dimension already reviewed at the current head is skipped before either of +these is consulted. + +## `[review.routing]` + +| Key | Type | Default | Meaning | +| --- | --- | --- | --- | +| `enabled` | bool | `false` | Off means every dimension is recorded and nothing is performed. | +| `workspace_root` | string | `.aethyme/reviews` | Where a Chau7 review's workspace is created. Relative to the repository root. | +| `default_route` | table | `backend = "record"` | Route for a dimension with no entry in `route`. | +| `route.` | table | -- | Route for one dimension. | + +### `[review.routing.route.]` + +| Key | Type | Default | Meaning | +| --- | --- | --- | --- | +| `backend` | `chau7` \| `provider_comment` \| `record` | **required** | Who performs it. | +| `mention` | string | -- | **Required for `provider_comment`.** Stored without the `@`. | +| `instructions` | string | -- | Appended to the generated Chau7 prompt. The generated part is not replaceable. | +| `max_concurrent` | int | `2` | Reviews of this dimension in flight at once, repository-wide. `0` is unbounded. | +| `stale_after_minutes` | int | `360` | Give up on an unfinished review after this long without an update, mark it `abandoned`, and ask again. Stops a dead reviewer holding a slot forever. `0` is never. | + +Budgets are per dimension, so a saturated security queue does not stop a code +review being requested. + +A Chau7 review whose workspace already holds a live tab is deferred rather than +started twice. The check is on the directory, not the branch: a tab that +wandered onto another branch still occupies that workspace. + +## `[review.projection]` + +| Key | Type | Default | Meaning | +| --- | --- | --- | --- | +| `enabled` | bool | `false` | Off means no comment and no label. | +| `comment` | bool | `true` | Maintain one Aethyme-owned comment, found by the marker `` and edited in place. | +| `label_prefix` | string | `aethyme/` | Every label Aethyme writes starts with this. A label outside it is somebody else's and is never touched. Empty is rejected at load. | +| `label_areas` | bool | `true` | `aethyme/area:backend` | +| `label_surfaces` | bool | `true` | `aethyme/surface:auth` | +| `label_risk` | bool | `true` | `aethyme/risk:high` | +| `label_reviews` | bool | `true` | `aethyme/review:security`, while one is outstanding. | +| `reserved` | list of strings | `[]` | Label suffixes inside the prefix that Aethyme reads and never writes or removes. | +| `create_missing_labels` | bool | `true` | `gh pr edit --add-label` fails outright on an unknown label. | + +`reserved` is the difference between a recomputable label and a decided one. +`aethyme/area:backend` can be deleted and rederived from a trailer still in the +commit. A human's `aethyme/skip-review` has no source to rederive from -- once +written, it *is* the source, and without `reserved` reconciliation would see an +unrecognised label under its own prefix and delete the only record of that +judgement. + +## Commit trailers + +| Trailer | Read by | Projected as | +| --- | --- | --- | +| `Area:` | a rule's `areas` | `aethyme/area:` | +| `Surface:` | a rule's `surfaces` | `aethyme/surface:` | +| `Risk:` | a rule's `min_risk` | `aethyme/risk:` | +| `Review:` | nothing -- asks for a dimension directly | `aethyme/review:` | +| `Model:` | a rule's `authored_by_model` and `models` | nothing -- who wrote a change is the author's to disclose | + +Values are comma-separated and case-insensitive. Trailers may appear anywhere +in the body and are merged across every commit in the change: areas and +surfaces union, the highest risk wins, and the first `Model:` declared wins. + +`Model:` is a declaration, not a detection. `Co-Authored-By` is deliberately not +read: it is written by convention, carries a display name rather than a stable +identifier, and appears on commits a model only helped with. + +A declaration can add a review and can never remove one. + +## Errors at load + +| Error | Cause | +| --- | --- | +| `rule N requires no review types` | A rule with an empty `require`. | +| `rule N waits for , which no tick can report` | `on` names `merge_queue_entered`. Remove it; the rule would never fire. | +| `unknown field` | A typo, or a field from a newer broker. | +| `schema_version N is newer than this broker understands` | Upgrade `aethyme`, or pin the policy. It refuses rather than falling back, because silently reviewing nothing is the failure this must not have. | +| `route uses provider_comment without a mention` | `provider_comment` with no bot to mention. | +| `label_prefix must not be empty` | An empty prefix would make every label in the repository Aethyme's. | diff --git a/.claude/skills/aethyme/SKILL.md b/.claude/skills/aethyme/SKILL.md new file mode 100644 index 0000000..34d14c9 --- /dev/null +++ b/.claude/skills/aethyme/SKILL.md @@ -0,0 +1,83 @@ +--- +name: aethyme +description: Use Aethyme's high-level Explore intents, current repository + analyzers, and code graph for navigation, caller tracing, derived facts, + dead-code analysis, and task context. +--- + +# Aethyme Navigation + +Use this skill for repository navigation, task localization, caller tracing, +dead-code analysis, graph context, compact task packs, and the repository's +broker and commit policy. Start with this contract; load a reference only if +the first result is insufficient. + +## Setup + +```bash +AETHYME_BIN="${AETHYME_BIN:-aethyme}" +REPO="$PWD" +``` + +Important: `python -m src.cli ...` was removed — the Python CLI no longer +exists, so that spelling fails outright. Use the `aethyme` binary for +graph, task, facts, intents, analyze, enhance, and Explore. + +## Default Contract + +Explore is a navigation aid, not an authority: every result is verified against +source before it is relied on. It is most useful for "where is X" questions; +skip it when a direct read or a tiny grep already answers the task. + +1. One call for the common case. It prints the compact projection and the top + 2 verified source spans (at most 80 lines each): + +```bash +"$AETHYME_BIN" explore --repo "$REPO" --request "" --format brief +``` + +2. When you need the JSON (audit, a deeper follow-up, or more than two spans), + make one bounded Explore call instead, save it to a temp file, and print + only the compact projection: + +```bash +AETHYME_JSON="$(mktemp -t aethyme-explore.XXXXXX.json)" +"$AETHYME_BIN" explore --repo "$REPO" --request "" --format answer-json --show-observability --depth 0 > "$AETHYME_JSON" +"$AETHYME_BIN" explore-summary --from "$AETHYME_JSON" +"$AETHYME_BIN" verify-targets --repo "$REPO" --from "$AETHYME_JSON" --max-targets 2 --max-lines 80 +``` + + Inspect only: `safe_to_use_as_answer`, `trust_policy`, `subsystems`, + `top_verification_targets`, `verification_steps`, and + `observability.readiness`. + +3. Use the returned spans first. If still unverified, read one missing line range + at a time. Keep each manual command under about 120 output lines / 20k chars + and the whole post-Explore source verification under about 200 lines. + +4. If `safe_to_use_as_answer=false`, follow `verification_steps` and the top + subsystem lanes as an investigation plan. Do not run broad `rg`, `rg + --files`, repository-wide grep, multi-file `sed`, or `rg -C` context dumps + unless the top targets fail. + +5. Escalate deliberately. Prefer one deeper Explore call over several unrelated + commands. Use `--depth 1/2/3` only when the previous result did not provide + enough evidence to act. + +## Load References Only When Needed + +- `references/explore.md`: depth, intent, trust/observability, retry rules. +- `references/graph-task.md`: graph views, task scope, context/prompt packs. +- `references/dead-code.md`: usage-boundary, public API, facts, ambiguity. +- `references/broker.md`: sessions, leases, gates, Git/GitHub coordination, + publication, advisories, recovery. +- `references/policy.md`: commit format, branch and review practice, generated + files and overrides, verifying the enhancement. + +## When Not To Use Aethyme + +- A simple file read, exact path lookup, or tiny grep already answers the task. +- You already have one decisive Aethyme result and only need narrow source + verification. +- The task asks for eval baselines, prior reports, or generated reference + artifacts as evidence; those must not be used for benchmark answers. diff --git a/.claude/skills/aethyme/aethyme-explore b/.claude/skills/aethyme/aethyme-explore new file mode 100755 index 0000000..82210a7 --- /dev/null +++ b/.claude/skills/aethyme/aethyme-explore @@ -0,0 +1,27 @@ +#!/usr/bin/env bash +# Native Rust thin client for `aethyme explore` — the canonical hot path. +# +# This wrapper is the convenience entry point for in-repo skill consumers. +# The aethyme binary routes to the native engine daemon for sub-second warm +# latency. If no daemon is running, it starts the Rust daemon and retries; +# the first map build can take a minute on large repos. +# +# Replaced the soft-retired Python `python -m src.cli explore` wrapper +# on 2026-05-08 (task #59 — Python explore hard-deleted). +# +# The installed router is resolved through PATH; deployment never embeds a +# source-checkout path. +set -euo pipefail + +REPO="${PWD}" + +# Best-effort telemetry via the native router. +if command -v aethyme >/dev/null 2>&1 && [[ -d "$REPO" ]]; then + aethyme repo record-wrapper-invocation \ + "$REPO" \ + --wrapper aethyme-explore \ + --detail source=wrapper \ + >/dev/null 2>&1 || true +fi + +exec aethyme explore "$@" diff --git a/.claude/skills/aethyme/references/broker.md b/.claude/skills/aethyme/references/broker.md new file mode 100644 index 0000000..d913f79 --- /dev/null +++ b/.claude/skills/aethyme/references/broker.md @@ -0,0 +1,263 @@ +## Broker Coordination (multi-agent repository) + +This repository coordinates concurrent agent sessions through the Aethyme +broker. Other agents may be working in sibling worktrees right now. The +`aethyme` router and its engine sibling are installed once for the user; +check the paired runtime with `aethyme --version` and +`aethyme-engine-cli --version`. +Follow this protocol: + +When `aethyme broker advanced hooks install` is active (or its pre-commit command is +wired into an existing hook manager), Git enforces the session boundary on +protected branches: local broker state requires the exact worktree to belong +to a live session, and fetched upstream divergence blocks the commit before +Git writes it. Staged changes remain intact and the refusal prints a valid +adoption or reconciliation command. This enforcement is local-only; without a +local broker database, contributors who have not deployed Aethyme are not +blocked. + +1. **Broker entry point, before editing**: check current activity, create an + isolated broker worktree, and work from that checkout: + + ```bash + aethyme broker status --json # who is working on what + aethyme broker start --task "" --short-name "" --path + ``` + + `cd` into the reported worktree before editing. If you are already in a + dedicated worktree, use + `aethyme broker start --adopt --task "" --short-name "" --path ` instead. + Repeat `--path` for every file or trailing-slash directory known up front. + The broker validates the whole set first, then creates the session plus + explicit leases atomically. Omit `--path` only when no target is known yet. + If `status` shows another session holding leases on the files you plan + to change, prefer working elsewhere first or say so in your report — + overlapping edits will conflict at merge time. + When you edit a file another live session is changing, the broker tells you + in context who, where and whether Git would conflict, never blocking the + edit; `aethyme broker advanced note send --to-session ` reaches that + agent, and its notes reach you at your next turn. + +2. **Lease additional shared files before the diff exists**. Prefer the + atomic `start --path` / `start --adopt --path` declaration above for initial intent. If the + session already exists and scope expands, claim the new path explicitly: + + ```bash + aethyme broker advanced leases claim --session + aethyme broker advanced leases release --session + ``` + + Use a trailing `/` for directory leases. Implicit leases refresh from + changed files, but explicit leases are clearer for planned shared edits. + A claim is refused only by another explicit lease whose holder is actively + working, and never in a `verify-only` repository; every other overlap comes + back as a warning naming the holder, with the `note send` command to + coordinate. + + Orchestration with no path -- a release, a merge chain -- is claimed by + name instead: `aethyme broker advanced ownership claim "release v1.2.0" + --session --reason ""`. `status` shows every claim, + its holder and when the holder last acted; a claim is refused only while + its holder is working, and a quiet holder's claim is taken over. + +3. **Guard broad rewrite commands**. For formatters, code generators, or any + command likely to touch many files, run through the broker guard: + + ```bash + aethyme broker advanced exec --session -- + ``` + + The guard fails if the command leaves dirty paths outside your explicit + leases or in files that were untracked before your session began. + +4. **While working**: commit early and small. Only committed work can be + verified and integrated. Never switch branches inside someone else's + worktree; never edit files outside your own worktree. + + **If `.aethyme/config.toml`, as committed on the default branch, sets + `[delivery] push_session_branches = true`, push your session branch as you + go.** Work that exists only in a worktree + is lost with it, and nobody can review what was never pushed. After each + commit: + + ```bash + aethyme broker push --session + ``` + + This pushes your own session branch (`agent/`) to the default + branch's remote and touches no other ref. A fast-forward is pushed plainly; + a branch you rewrote (for example after a rebase) is pushed only under a + lease on the commit the broker last pushed for your session. Uncommitted + files are reported, not pushed, so commit before you push. Once there is a first meaningful commit, open a draft + pull request, and keep pushing to it until it is ready for review: + + ```bash + aethyme broker push --session --pr + ``` + + `--pr` opens a draft PR, or reports the one already open. The policy is + the authorization for exactly these two things -- pushing your own session + branch and opening a draft PR -- and nothing more: it does not authorize + merging, marking a PR ready, or pushing any other ref. `broker status` and + `broker doctor` report sessions with unpushed commits, and + `aethyme broker finish` refuses to close a session while its commits are + unpushed. If the work should genuinely not be kept, say so explicitly with + `aethyme broker finish --session --abandon --reason ""`. + Each push also fetches the default branch and reports how far your branch + is behind it and whether merging would conflict, with the command to catch + up; `broker status` shows the same as `session.behind-main`. Catch up with + `aethyme broker sync --session ` when it warns, before the pull request + reports the conflict: it rebases an unpublished branch or merges the default + branch into a published one, and changes nothing if that would conflict. + Sync is local only: it never pushes, so run `aethyme broker push --session + ` afterwards to publish the caught-up branch. + `broker start` and `start --reuse` refresh the default branch first, so a + new worktree starts from the latest fetched tip. In a repository + with `[promote] mode = "verify-only"`, `broker submit` is a pre-flight + against the current default branch; the integration branch is not used. + When `broker status` shows `coordination.land-shared-edit-first`, another + session changes the same lines or symbol as yours: follow it -- the named + session lands only the shared edit as its own small PR, then both rebase + on the default branch -- rather than waiting or building on the other + session's unmerged branch. + Without the policy, pushing stays a separately authorized action (step 9). + +5. **Gate resources are per worker**. Broker gate runs take path-scoped owner + locks and export `AETHYME_GATE_WORKER_ID` plus `AETHYME_TEST_DB_SUFFIX`. + Gate commands that need a test database, cache namespace, or similar + external state should suffix it with that value instead of sharing one + fixed name. + + If this repository declares committed graph fragments authoritative in + `.aethyme/config.toml`, graph freshness is an enforced deployment-integrity + check, not a semantic gate suggestion. Session gates, full-tree CI, + repository pre-push, and submit verify the exact tree in a disposable + checkout and refuse stale or wrong-version fragments without rewriting your + worktree. Run `aethyme graph status --repo .`, review + `aethyme graph refresh plan --repo . --diff`, and authorize only its full + digest with `aethyme graph refresh execute --repo . --confirm `. + Never rebuild committed fragments with an unpinned binary. If execution was + interrupted, use the exact `graph refresh recover --plan ` + handoff; do not retry blindly. + + Graph support is repository opt-in. Explore never generates graph state. + If Explore reports `graph_store_missing`, continue with its bounded manual + verification steps, or materialize the verified committed fragments for + this worktree with `aethyme graph materialize --repo .`. Do not enable graph + authority merely to silence a degraded response. + +6. **When your task is complete**, use verified broker integration by + default instead of manually combining concurrent session branches: + + ```bash + aethyme broker submit --session + ``` + + This simulates the merge and runs only the checks your diff affects. + Submit replays session-owned commits as an ordered, single-parent patch + series. If your session contains an owned merge commit, submission refuses + safely and prints the accepted checkpoint plus an exact recovery sequence. + Follow it in order: preserve the current HEAD on the named recovery branch + before flattening the reviewed tree change. Never reset first. + `broker submit` promotes to the local integration branch; it does not + publish a remote branch, create a pull request, or push a release tag. + Publication is a separate, explicitly authorized operator action. When + publication is authorized, review the exact promoted prefix first, then + confirm the plan's full publication SHA: + + ```bash + aethyme broker advanced ship plan --entry + aethyme broker advanced ship execute --entry --confirm + ``` + + Prefer this reviewed broker ship workflow over a raw push. Never infer + publication authority from permission to edit, submit, or promote. + Without publication authority, stop after submit and report the promoted + entry. Under `push_session_branches` (step 4), your pushed session branch + and its draft PR are the delivery: report the PR rather than a promoted + entry. Repositories that deliver through pull requests usually also set + `[promote] mode = "verify-only"`, so verified work does not pile up + unpublished on the local integration branch. + Report the outcome (verified / rejected / conflict) in your summary. + Afterwards, finish the session with + `aethyme broker finish --session `, or point it at a follow-up task + with `aethyme broker start --reuse --task "..." --short-name ""`. `finish` closes broker + state but deliberately leaves the worktree available for review or reuse. + When it reports cleanup is safe, reclaim that exact worktree with + `aethyme broker finish cleanup `. Operators can periodically review all + retained broker-owned worktrees with + `aethyme broker finish cleanup --all-cleaned` and apply the unchanged plan + explicitly with `aethyme broker finish cleanup --all-cleaned --apply`. + +7. **If a file named `.aethyme/broker-action-required.md` appears in your + worktree**, read it immediately: your submission conflicted. It names + the conflicting files, the blocking session, and the exact rebase + steps. Resolve, commit, and resubmit. + +8. **Treat broker advisories as delivered work context, not as blockers.** + The broker surfaces outstanding session advisories after post-commit, + before expensive gates, and on common broker commands. When a notice + appears—or after rebasing or reusing a worktree—inspect + `aethyme broker status --json` before continuing on the named paths. + + `.aethyme/broker-advisory.md` is a gitignored persistence projection; it + is not automatically visible to agents and the broker database remains + authoritative. Read it when a delivery surface points to it. Directory + leases cover descendants, and repeated overlaps are deduplicated and + deterministically ordered. Acknowledging a notice stops repeat delivery + but does not clear the queue entry's unpublished path exposure. Session + close and rebase do not clear it either. Only verified publication or + confirmed external reconciliation resolves an exposure; publishing a + selected integration prefix clears only entries contained in the verified + remote tip. Advisories never expand gate selection or block submit, + promotion, or shipping. + +9. **Git operations remain available to agents.** The broker coordinates + concurrent work; it does not remove Git capabilities. When the user's + request or the repository's documented workflow authorizes the resulting + local or remote state change, agents may perform every required Git + operation, including clone, fetch, pull, switch, branch, add, commit, + stash, merge, cherry-pick, rebase, revert, reset, tag, push (including + force-push when explicitly authorized), and deletion of an exact ref. + + Operations that require coordination **must go through the broker**. Use a + dedicated broker workflow when one exists (for example `broker submit` for + verified integration). Run other coordinated Git operations through the + durable Git operation coordinator: + + ```bash + aethyme broker advanced git --session \ + [--repo ] --reason "" -- ... + ``` + + Read-only GitHub CLI inspection and explicitly authorized local `gh auth` + setup may run directly. Every GitHub repository or account mutation + (pull requests, issues, comments, workflows, releases, settings, secrets, + or non-GET API calls) must use the GitHub operation coordinator: + + ```bash + aethyme broker advanced gh --session \ + --repo --reason "" -- ... + ``` + + The broker classifies known commands and fails closed on ambiguity. Add + `--effect write|destructive --scope ` before `--` for an + unrecognized command. Destructive operations also require `--destructive`. + Every coordinated write requires a concise `--reason` identifying the user + request or documented workflow that authorized it. + If a crashed command leaves an unknown outcome, inspect external state and + use `aethyme broker advanced operations reconcile`; do not retry blindly. + + Direct Git is limited to read-only inspection and operations confined to + the isolated session worktree and session branch that cannot affect other + sessions. Direct `gh` is limited to read-only inspection and local + authentication setup. Any command that + can move shared refs, the default branch, + `aethyme/integration`, remote-tracking refs, tags, or remote state is + coordinated and must not run outside the broker. For destructive or remote + operations, resolve the exact repository and refs first, preserve unrelated + work, and require the authorization that operation normally needs. + Do not infer permission to publish merely from permission to edit or submit. + An explicitly authorized operator or release workflow may merge, tag, push, + force-push, or delete refs through the broker; authorization does not permit + bypassing coordination. \ No newline at end of file diff --git a/.claude/skills/aethyme/references/dead-code.md b/.claude/skills/aethyme/references/dead-code.md new file mode 100644 index 0000000..2171bbb --- /dev/null +++ b/.claude/skills/aethyme/references/dead-code.md @@ -0,0 +1,66 @@ +# Dead Code And API Boundary Reference + +Read this for dead-code, public API caller audits, usage-boundary questions, +and ambiguous internal/external caller decisions. + +## Table Of Contents + +- Start with usage-boundary Explore +- Direct analyzer fallback +- Facts commands +- Status interpretation +- Verification discipline + +## Start With Usage-Boundary Explore + +Use the specialized Explore intent first for boundary usage and public API +caller questions: + +```bash +"$AETHYME_BIN" explore --repo "$REPO" --intent usage_boundary_query --request "" --scope "" --search-root src --search-root tests --format answer-json --show-observability +``` + +For PHP scopes, this intent uses the scope-first `analyze-usage-boundary` +engine path and avoids building the full repository graph. If +`safe_to_use_as_answer=false`, use the returned `verification_steps[]` before +declaring a function unused. + +## Direct Analyzer Fallback + +Use the direct analyzer when the user explicitly asks for the legacy dead-code +shape or when Explore asks you to verify with the analyzer: + +```bash +aethyme analyze dead-code --repo "$REPO" --scope "" --boundary outside-directory --format eval-json --show-observability +``` + +Use `--roots ","` when the repository is large and the task gives +likely search roots. + +## Facts Commands + +For harder cases, derive public surface first, then inspect one target's usage: + +```bash +aethyme facts public-functions --repo "$REPO" --scope "" --json-output +aethyme facts function-usage --repo "$REPO" --target "" --boundary "" --json-output +``` + +## Status Interpretation + +- `Unused`: no internal or external code callers found. +- `Ambiguous`: no external code callers found, but internal callers or + docs/config-only references exist. This may satisfy a boundary prompt but may + not be safe to remove. +- `Used`: at least one caller exists outside the boundary. + +Read `excluded_functions` and ambiguity fields before finalizing. A symbol +excluded for visibility, generated code, or test-only usage should not be +silently promoted into the answer. + +## Verification Discipline + +Dead-code answers require source-backed evidence. Verify returned definitions, +callers, docs/config references, and boundary classification with targeted +reads or narrow grep. Do not use eval baselines, prior reports, or generated +reference artifacts as evidence for benchmark answers. diff --git a/.claude/skills/aethyme/references/explore.md b/.claude/skills/aethyme/references/explore.md new file mode 100644 index 0000000..61598f1 --- /dev/null +++ b/.claude/skills/aethyme/references/explore.md @@ -0,0 +1,123 @@ +# Explore Reference + +Read this when the initial short skill card is not enough to decide which +Explore depth or intent to use. + +## Table Of Contents + +- Default flow +- Trust and observability +- Progressive Disclosure: `--depth` +- Intent selection +- Retry rules + +## Default Flow + +Explore ranks candidates; it does not decide. Treat every result as a +navigation aid and verify it against source before relying on it. Explore +earns its keep on "where is X" questions. It is not a mandatory first step, +and a direct read or a tiny grep is the better tool when it already answers. + +For most questions, one call is enough. `--format brief` prints the compact +projection (trust, readiness, subsystems, verification steps) and the top 2 +verified source spans, at most 80 lines each. It reads the same answer document +as the JSON format, starts on `--depth 0`, and `--repo` defaults to the current +directory: + +```bash +"$AETHYME_BIN" explore --request "" --format brief +``` + +When you need the machine-readable document (audit, a later `--detail full` +comparison, or more than two spans), make one bounded JSON call instead. Save +the full JSON to a temp file, then print a compact projection for agent-facing +inspection: + +```bash +AETHYME_JSON="$(mktemp -t aethyme-explore.XXXXXX.json)" +"$AETHYME_BIN" explore --repo "$REPO" --request "" --format answer-json --show-observability --depth 0 > "$AETHYME_JSON" +"$AETHYME_BIN" explore-summary --from "$AETHYME_JSON" +"$AETHYME_BIN" verify-targets --repo "$REPO" --from "$AETHYME_JSON" --max-targets 2 --max-lines 80 +``` + +Inspect only the printed projection first: `safe_to_use_as_answer`, +`trust_policy`, `subsystems`, `top_verification_targets`, +`verification_steps`, and `observability.readiness`. Keep the full JSON file +for audit/debug or a later `--detail full` comparison; do not dump it into the +conversation by default. + +Verify from the bounded source spans first. Read full target files only if +those spans are insufficient. Read only the missing line range from one target +at a time, keep each manual verification command under about 120 output lines / +20k chars, and keep the whole post-Explore source verification under about 200 +lines. Do not run broad `rg`, `rg --files`, repository-wide grep, multi-file +`sed`, or `rg -C` context dumps unless the top targets fail. + +## Progressive Disclosure: `--depth` + +`explore` accepts `--depth N` where `N` is 0..=3. Lower rungs are cheap and +broad; higher rungs are more expensive and specific. + +- `--depth 0`: paths + names for many candidates. Discovery. +- `--depth 1`: paths + names + signatures for a shorter list. Triage. +- `--depth 2`: 20-line snippets for the top few. Read the code. +- `--depth 3`: full content + call-graph closure for one anchor. Commit-level + and the most expensive rung. + +Start at 0 unless you already know the symbol. If the user names a precise +symbol, file, or function, skip discovery and use `--depth 2` or `--depth 3` on +that anchor. If the task is vague, start at `--depth 0`. + +Escalate one rung at a time. Stop when you have enough to act. If `--depth 1` +returns one clearly correct candidate, jump to a focused `--depth 3` query for +that candidate instead of loading richer context for every candidate. + +When NOT to escalate: if `--depth 0` gives one unambiguous candidate and normal +source reading or narrow grep can verify it, do that. Do not call a deeper +engine command as a formality. + +The legacy `--detail compact|standard|full` flag still works for callers that +use the old budget vocabulary. When both flags are passed, `--depth` wins. + +## Intent Selection + +Use the default `task_localization_query` unless the task clearly fits a +specialized intent. + +```bash +"$AETHYME_BIN" explore --repo "$REPO" --request "" --format answer-json --show-observability --depth 0 +``` + +Use `behavior_localization_query` for debugging, workflows, or "which files +implement this behavior" tasks: + +```bash +"$AETHYME_BIN" explore --repo "$REPO" --intent behavior_localization_query --request "" --format answer-json --show-observability --depth 0 +``` + +Use `usage_boundary_query` for dead-code, public API caller audits, or +boundary usage questions: + +```bash +"$AETHYME_BIN" explore --repo "$REPO" --intent usage_boundary_query --request "" --scope "" --search-root src --search-root tests --format answer-json --show-observability +``` + +List the intent catalog only when you need to choose among intents: + +```bash +aethyme intents --request "" --format compact-json +``` + +## Retry Rules + +If `degraded_reasons` reports a graph timeout, read +`observability.degradation_guidance` before retrying. For very large +repositories where first-response speed matters more than graph coverage, pass: + +```bash +"$AETHYME_BIN" explore --repo "$REPO" --request "" --format answer-json --show-observability --params '{"graph_query_timeout_ms":500}' +``` + +Retry with a narrower request when the first result names an area but not a +specific file. Do not retry with a broader request unless the result contains no +usable answer, hints, or verification path. diff --git a/.claude/skills/aethyme/references/graph-task.md b/.claude/skills/aethyme/references/graph-task.md new file mode 100644 index 0000000..1f7afbe --- /dev/null +++ b/.claude/skills/aethyme/references/graph-task.md @@ -0,0 +1,147 @@ +# Graph And Task Reference + +Read this for graph views, task scope, task packs, and context-pack assembly. +Prefer `explore` first for broad questions; use these commands after you have a +candidate node, symbol, area, or task. + +## Table Of Contents + +- Before you run a graph command (graph store posture) +- Repository orientation +- Graph navigation +- Impact of a change +- Task scope and anchors +- Context packs +- Verification discipline + +## Before You Run A Graph Command + +**Every `aethyme graph`, `aethyme task`, `aethyme query`, `aethyme facts` and +`aethyme analyze` command below reads a local graph store. If that store is +absent, they all refuse.** Explore is the exception: it works without one. + +Graph authority is **disabled by default**. In a repository that has not been +enrolled, every command on this page fails. Check before building a plan on +top of them: + +```bash +aethyme graph status --repo "$REPO" +``` + +- **exit 0** — the store is present and current; the commands below work. +- **exit 1** — the store is missing, stale, or blocked. The printed `next:` line + names the exact command to run. Do not substitute a different one. +- **`--json`** — always exits 0 and carries `fragments.status`, + `derived_store.status`, `blockers[]` and `next_action`; branch on those + fields instead of the exit code when you are parsing. + +If it reports that graph authority is disabled, enrollment is a repository +change and not yours to make unprompted — say so and fall back to `explore`, +which needs no store. Never fall back to repo-wide `rg`/`find` merely because +the graph is unavailable; report the posture instead. + +## Repository Orientation + +Use overview only when the user asks for repo orientation or the initial +Explore answer is too broad: + +```bash +aethyme graph overview "$REPO" --json-output +``` + +## Graph Navigation + +Inspect a node and nearby graph context: + +```bash +aethyme graph node "$REPO" "" --json-output +aethyme graph expand "$REPO" "" --json-output +``` + +Caller/callee evidence: + +```bash +aethyme graph callers "$REPO" "" --json-output +aethyme graph callees "$REPO" "" --json-output +``` + +`node`, `expand` and the relation commands accept either `--json` or +`--json-output`; the two spellings mean the same thing. A misspelled flag is an +error (exit 2) rather than a silent no-op, so a typo will surface immediately. + +`graph callers` and `graph callees` exit **1 with `node not found`** when the +target does not resolve, and exit **0 with `"items": []`** when the node exists +but has no such relation. That distinction tells a misspelled symbol apart from +a genuine empty result — check the exit code, not just the payload. + +Look one up when you are unsure of the spelling: + +```bash +aethyme query symbol "$REPO" "" +``` + +Coverage limits worth knowing before you trust a call graph: method calls and +dynamic dispatch are not extracted, and a bare call whose name is ambiguous in +the repository is deliberately left unresolved rather than guessed. An absent +edge usually means "not resolvable", not "not called". + +Use relation commands to narrow a known node. Do not run every relation command +for the same node unless each result changes the next step. + +## Impact Of A Change + +Before editing, ask what the change reaches — callers, importers, tests and +configs — from a diff: + +```bash +aethyme graph impact --repo "$REPO" --revision HEAD --diff +``` + +Add `--mode imports` for an import-level view and `--json` for machine output. +This is the highest-value pre-edit command in the toolset. The report states its +own `status` and `confidence`: when the graph does not match the requested +revision it withholds paths and says so — treat that as "verify manually", not +as "no impact". + +## Task Scope And Anchors + +Use task commands when the user asks "where should I work?", "what files are in +scope?", or "what should I inspect next?" and the initial Explore answer is not +enough. + +```bash +aethyme task anchors --repo "$REPO" --task "" --json-output +aethyme task scope --repo "$REPO" --task "" --json-output +aethyme task next --repo "$REPO" --task "" --json-output +``` + +Read reasons and risks before expanding scope. A file with a clear reason beats +a larger list with weak evidence. + +## Context Packs + +Use a pack when you need a compact prompt-ready bundle instead of reading many +files manually. + +```bash +aethyme task context --repo "$REPO" --task "" --json-output +aethyme task pack --repo "$REPO" --task "" --json-output +``` + +Inspect selected files, selected symbols, snippets, and token estimates. If a +pack is too large, narrow the task or anchor before asking for a larger pack. + +## Verification Discipline + +Graph/task output is a candidate selector, not a substitute for reading code. +After a graph or task command, verify with targeted file reads or symbol grep +against the returned paths. Avoid raw `rg --files`, broad `find`, or +repo-wide grep unless Aethyme returned no usable candidates. + +Two ways the graph can quietly disagree with the source you are reading: + +1. **The store is stale.** `graph status` is the check; do not infer freshness + from a successful query. +2. **The extraction is incomplete.** Unresolved edges and absent callers are + expected in the coverage gaps listed above. Absence of evidence in the graph + is not evidence of absence in the code. diff --git a/.claude/skills/aethyme/references/policy.md b/.claude/skills/aethyme/references/policy.md new file mode 100644 index 0000000..c7b4e40 --- /dev/null +++ b/.claude/skills/aethyme/references/policy.md @@ -0,0 +1,91 @@ +# Repository Policy Reference + +Read this when you need the full commit format, the branch and review +practices, or how the generated agent files are maintained. The generated root +`AGENTS.md` / `CLAUDE.md` carries only the compressed form of each rule. + +## Table Of Contents + +- Generated files and overrides +- Orientation skills +- Commit hygiene +- Branch and review practices +- Verifying the enhancement + +## Generated Files And Overrides + +`AGENTS.md` and `CLAUDE.md` at the repository root are generated by Aethyme. +Do not edit them directly: `aethyme deploy verify` reports direct edits as +drift. Customize repo-specific policy through `.aethyme/overrides/agents.json` +(`repo_summary`, `hard_constraints`, `validation_rules`, +`commit_hygiene_notes`, `summon_policy_notes`, `maintainer_markdown`) and +repo-specific orientation through `.aethyme/overrides/onboarding.json`, then +rerun `aethyme deploy --repo "$PWD"`. + +Do not run `python -m src.cli ...` for anything; the Python CLI was removed +entirely and that spelling now fails. Use the installed `aethyme` binary for +Explore, `graph`, `task`, `intents`, `facts`, `analyze`, and `deploy`. + +## Orientation Skills + +If `.codex/skills/repo-onboarding/SKILL.md` or +`.claude/skills/repo-onboarding/SKILL.md` exists, load it first when the +repository is unfamiliar or the request asks for a repo overview, setup, +entrypoints, or where to begin. `repo-act` (same two locations) turns that +orientation into execution planning, debugging checklists, and validation +steps. `.aethyme/generated/experience-status.md` summarizes how the enhancement +is being used. + +## Commit Hygiene + +Use typed commit messages. + +- Subject: `type(scope): short summary` +- Allowed types: `fix`, `feat`, `refactor`, `perf`, `test`, `docs`, `build`, `chore`, `revert` +- Substantive commits (`fix`, `feat`, `refactor`, `perf`) must include: + - `Problem` + - `Decision` + - `Rationale` + - `Validation` +- Non-substantive commits (`test`, `docs`, `build`, `chore`, `revert`) may use a subject-only message; structured bodies remain optional. +- Section content may start on the header line (`Problem: text`) or the following line (`Problem:` then `text`). + +Useful commands: + +```bash +aethyme repo commit-message-template --type fix --scope +aethyme repo lint-commit-message .git/COMMIT_EDITMSG +``` + +## Branch And Review Practices + +These scale with the number of agents working a repository at once, where a +habit that costs one agent a minute costs a fleet an hour. + +- **Do not merge the default branch into a working branch to keep it current.** + Merge or rebase only to resolve an actual conflict, and only in your own + worktree. Catch-up merges add conflict surface and history noise for no + safety unless the branch is genuinely required to be fresh. If the default + branch enforces branch-freshness (GitHub's "Require branches to be up to date + before merging"), update immediately before merging rather than reflexively + throughout the branch's life. +- **A check may be required on a pull request only if it is scoped to the diff + and finishes in minutes.** Anything heavier belongs once per merge batch or + once per release. With one agent an unscoped required check is an annoyance; + with several it becomes the dominant cost and serialises the fleet. +- **Cherry-picking to patch an already-certified release is standard; + cherry-picking to assemble a release from trunk is not.** Assembling produces + a combination nobody tested, and hides dependencies between the changes being + picked. Cut a release from a tested point instead, then patch it. + +## Verifying The Enhancement + +To confirm the enhancement is intact in this repository: + +```bash +aethyme deploy verify --repo "$PWD" +``` + +Returns nonzero if any generated root file, Aethyme skill, Aethyme skill +reference, or repo-onboarding skill is missing or has unsubstituted +placeholders. diff --git a/.claude/skills/repo-act/SKILL.md b/.claude/skills/repo-act/SKILL.md new file mode 100644 index 0000000..11e255c --- /dev/null +++ b/.claude/skills/repo-act/SKILL.md @@ -0,0 +1,44 @@ +--- +name: repo-act +description: Use after repo-onboarding or Explore when moving from orientation into execution planning, debugging checklists, and validation steps. Skip when only broad repo orientation is needed. +--- + +# Repo Act: map-generator + +## When to Use + +- Load this after repo-onboarding when the next step is execution or validation planning. +- Skip it for broad repo overview questions with no action plan yet. + +## Debugging Checklist + +- Load repo-onboarding first if the repository or area is unfamiliar. +- Run Aethyme Explore on the user task before broad manual search. +- Verify answer candidates before concluding when trust_policy is not answer-safe. +- Identify the nearest fast test or validation command before editing. +- Inspect caution zones before changing generated or vendored areas. + +## Validation Checklist + +- Run the fastest relevant test command first. +- Check likely entrypoints and impacted callers before finishing. +- Re-run lint/build only after the focused validation passes. +- Document any override-based maintainer note that affected the change plan. + +## Useful Commands + +- `fast_test`: `cargo test --workspace` +- `build`: `cargo build --workspace` +- `dev`: `cargo run` + +## Primary Entrypoints + +- `app`: `Procfile:web` (Procfile process entrypoint) +- `cli`: `crates/mapgen-cli/src/main.rs` (tracked Rust binary entrypoint in `.`) +- `test`: `tests` (conventional test root) + +## Likely Entrypoints + +- `Procfile:web` (Procfile process entrypoint) +- `crates/mapgen-cli/src/main.rs` (tracked Rust binary entrypoint in `.`) +- `crates/mapgen-server/src/main.rs` (tracked Rust binary entrypoint in `.`) diff --git a/.claude/skills/repo-onboarding/SKILL.md b/.claude/skills/repo-onboarding/SKILL.md new file mode 100644 index 0000000..8f7fab0 --- /dev/null +++ b/.claude/skills/repo-onboarding/SKILL.md @@ -0,0 +1,83 @@ +--- +name: repo-onboarding +description: Use when starting work in an unfamiliar repository, when the task asks for repo overview, setup, architecture, entrypoints, test commands, or where to begin. Skip for narrow file-scoped edits once the relevant paths are already known. +--- + +# Repo Onboarding: map-generator + +## When to Use + +- Load this skill first when the repository is unfamiliar or the request is broad. +- Recommended when: first task in repo, repo overview, setup or run instructions, architecture or entrypoints, where should I start, broad debugging or feature-localization request. +- Skip when: known file-scoped edit, follow-up inside already identified area, task already localized to concrete files. +- Use `.codex/skills/aethyme/SKILL.md` or `.claude/skills/aethyme/SKILL.md` for Aethyme's short operating contract after orientation; load its `references/` files only when needed. + +## Repo Identity + +- Kind: `repository` +- Languages: `rust, typescript` +- Package manager: `cargo` +- Key manifests: `Cargo.toml, Procfile, crates/mapgen-cli/Cargo.toml, crates/mapgen-core/Cargo.toml, crates/mapgen-data/Cargo.toml, crates/mapgen-server/Cargo.toml, crates/mapgen-spec/Cargo.toml, crates/mapgen-wasm/Cargo.toml, crates/mapgen-wasm/package.json` + +## Workspaces + +- `.` (primary; cargo; manifest `Cargo.toml`; high confidence) +- `crates/mapgen-wasm` (supporting; npm; manifest `crates/mapgen-wasm/package.json`; high confidence) + +## Start Here + +- `dev`: `cargo run` +- `fast_test`: `cargo test --workspace` +- `build`: `cargo build --workspace` + +## Supporting Commands + +- `cargo run` (dev; medium confidence from `Cargo.toml`) +- `./target/release/mapgen-server` (dev; medium confidence from `Procfile:web`) +- `cargo test` (fast_test; high confidence from `Cargo.toml`) +- `cargo test --workspace` (fast_test; high confidence from `Cargo.toml`) + Workspace: `.` +- `cargo build` (build; high confidence from `Cargo.toml`) + +## Entrypoints + +- `app`: `Procfile:web` (Procfile process entrypoint; high confidence) +- `cli`: `crates/mapgen-cli/src/main.rs` (tracked Rust binary entrypoint in `.`; high confidence) +- `test`: `tests` (conventional test root; medium confidence) + +## Additional Entrypoints + +- `Procfile:web` (process; role=app; Procfile process entrypoint; high confidence) +- `crates/mapgen-cli/src/main.rs` (file; role=cli; tracked Rust binary entrypoint in `.`; high confidence) + Executable: `mapgen` +- `crates/mapgen-server/src/main.rs` (file; role=cli; tracked Rust binary entrypoint in `.`; high confidence) + Executable: `mapgen-server` +- `tests` (directory; role=test; conventional test root; medium confidence) + +## Repo Map + +- `.github` (automation; automation and CI configuration; high confidence) +- `docs` (docs; documentation area; high confidence) +- `scripts` (tooling; developer tooling or scripts; high confidence) +- `tests` (tests; conventional test directory; high confidence) + +## Aethyme Recipes + +- `aethyme explore --repo "$PWD" --request "" --format answer-json` + Purpose: Broad repository orientation for a user request +- `aethyme repo inspect "$PWD" --mode brief --json-output` + Purpose: Quick deterministic repo summary +- `aethyme graph callers "$PWD" "" --json-output` + Purpose: Trace likely impact before editing + +## Generated and Dangerous Paths + +- Generated/vendor `.aethyme/generated`: tracked generated or vendored surface; verify ownership before editing +- Sensitive `.github/workflows`: repository automation; changes can affect publication or shared CI + +## Freshness + +- Source digest: `9d585c352194147824bc58c079ba104409fa5271d4cab3e0f4363992fb631475` +- Tracked source files: `131` +- Overrides applied: `False` +- Sections generated: `repo, workspaces, primary_workspace, commands, areas, entrypoints, caution_zones, generated_paths, dangerous_paths, navigation_recipes, summon, freshness` diff --git a/.codex/skills/aethyme-review-rule-maker/SKILL.md b/.codex/skills/aethyme-review-rule-maker/SKILL.md new file mode 100644 index 0000000..40383f7 --- /dev/null +++ b/.codex/skills/aethyme-review-rule-maker/SKILL.md @@ -0,0 +1,194 @@ +--- +name: aethyme-review-rule-maker +description: Write or tune this repository's Aethyme review rules -- which + changes need which reviews, who performs them, and what appears on the pull + request. Use when asked to set up, enable, debug, or change review routing, + review triggers, PR labels, or the `[review.*]` tables in + `.aethyme/config.toml`. +--- + +# Aethyme Review Rule Maker + +Three tables in `.aethyme/config.toml` decide which reviews a change needs +(`[review.trigger]`), who performs them (`[review.routing]`), and what the pull +request shows (`[review.projection]`). All three are off by default. This skill +is the procedure for writing them against a real repository instead of from +imagination. + +Full field grammar: [`references/review-rules.md`](references/review-rules.md). +Load it when you need a field's exact name, type, or default. + +## The one rule that shapes everything else + +**A rule is a floor an author cannot lower.** Eligibility is the union of what +the repository requires and what the author declared in commit trailers, never +the intersection. So the cost of a rule that is too broad is wasted reviews, +and the cost of one that is too narrow is a missed review. Write the narrow +guards first and widen them with evidence. + +## Procedure + +### 1. Read the current state before changing anything + +```bash +aethyme broker advanced review plan --base --pr 0 +``` + +It performs nothing. `trigger_enabled`, `routing_enabled`, +`projection_enabled` tell you what is already on; `changed_paths` and +`classification` tell you whether the command is reading the tree you expect. +If `changed_paths` is 0 against a branch with work on it, you are standing in +the wrong worktree -- compare `policy_root` and `change_root` in the report. + +### 2. Find the paths that must never miss a review + +Do not guess, and do not ask the user to guess. Look, then propose a list for +them to cut down. Search for the places where a change can grant itself +authority or move money: + +```bash +# CI that can mint credentials, and anything that edits it +ls .github/workflows/ .gitlab-ci.yml 2>/dev/null +# authentication, authorization, secrets, crypto +rg -l --files-with-matches -i 'authenticat|authoriz|\bjwt\b|secret|credential|private_key' --glob '!**/test*' | head -30 +# money and data destruction +rg -l -i 'stripe|payment|charge|refund|DROP TABLE|delete_all' --glob '!**/test*' | head -20 +# schema migrations +fd -t d -d 3 'migrations?' 2>/dev/null | head +``` + +Present the candidates and say which you would keep. A list of three to six +paths is a working guard; a list of forty is a repository-wide review under +another name, and the schedule will end up silently dropping most of it. + +### 3. Name the dimensions + +`require = [...]` takes free strings, not an enum. Pick names the repository +would use in conversation -- `code`, `security`, `performance`, `data`, +`accessibility`, `i18n`. Each name is separately routed and separately +budgeted, so a dimension is worth creating exactly when it would go to a +different reviewer or deserve a different quota. Two dimensions that always +go to the same place with the same budget should be one. + +### 4. Write the trigger table only, and leave the rest off + +```toml +[review.trigger] +enabled = true + +[[review.trigger.rule]] +name = "always-code-review" +require = ["code"] + +[[review.trigger.rule]] +name = "security-sensitive-paths" +require = ["security"] +paths = [".github/workflows/**", "src/auth/**"] +``` + +Routing and projection stay off through this step. A wrong rule now costs a +line in a JSON report; a wrong rule with projection on costs a label on +somebody's pull request. + +### 5. Replay it against real history + +This is the step that separates a rule that works from one that reads well. +Take branches that actually merged and check what the policy would have said: + +```bash +for base in HEAD~1 HEAD~5 HEAD~20; do + echo "=== $base ===" + aethyme broker advanced review plan --base "$base" --pr 0 \ + | python3 -c 'import json,sys; d=json.load(sys.stdin); print([ (e["review_type"], e["because"]) for e in d["eligible"] ])' +done +``` + +Read the `because` array, not just the dimension: it names the rule that +fired. A dimension appearing with a rule you did not expect is the rule to fix. + +Two failure shapes to look for specifically: + +- **Every change eligible for everything.** Usually a rule with no conditions + that was meant to have one, or `paths` written with a leading `/` or a + `./` prefix -- paths are repository-relative, exactly as `git diff + --name-only` prints them. +- **A guarded path producing nothing.** Check the glob: `*` matches one + segment and `**` matches any number including zero, so `src/*/auth.rs` does + not match `src/a/b/auth.rs` but `src/**/auth.rs` does. + +### 6. Set the budget before turning on a backend + +Rules decide what a change deserves. `schedule` decides what it gets, and it +is the half that keeps an active branch from spending forty security reviews. + +```toml +[review.trigger.default_schedule] +debounce_seconds = 600 +max_per_pull_request = 8 + +[review.trigger.schedule.security] +debounce_seconds = 0 +max_per_pull_request = 0 +``` + +Ask the concrete question rather than the abstract one: *on the busiest pull +request this repository had last month, how many reviews of each dimension +would have been acceptable?* That number is `max_per_pull_request`. Exempt a +dimension from the cap only when a missed one is worse than a wasted one -- +which is usually true of `security` and usually false of everything else. + +### 7. Turn on projection, then routing + +In that order. Projection writes a comment and labels, which a human can read +and delete. Routing starts agents and mentions bots, which a human cannot +un-start. + +```toml +[review.projection] +enabled = true +label_prefix = "aethyme/" +reserved = ["skip-review"] +``` + +`label_prefix` is the whole safety mechanism: Aethyme never touches a label +outside it. `reserved` names labels inside it that Aethyme reads and never +writes -- that is where a human parks a decision the broker must not +recompute away. + +```toml +[review.routing] +enabled = true + +[review.routing.default_route] +backend = "record" + +[review.routing.route.security] +backend = "chau7" +max_concurrent = 1 +``` + +Keep `default_route` on `record`. A dimension someone adds later then gets +written down rather than silently starting an agent nobody budgeted for. + +## Asking the coder for classification + +Rules can read what the author declared. Trailers cost a coding agent nothing +-- it is already writing a commit message and already knows what it changed: + +``` +Area: backend +Surface: auth +Risk: high +Review: security +``` + +To get them written, add the instruction to `.aethyme/overrides/agents.json` +and rerun `aethyme deploy --repo "$PWD"`. Do not rely on them for a +guard: a trailer is one line of unverified text, which is exactly why it can +escalate a review and can never waive one. + +## What to hand back + +A diff of `.aethyme/config.toml`, plus the `review plan` output for two or +three real changes showing what the new rules decide. Do not report a policy as +working on the strength of it parsing. diff --git a/.codex/skills/aethyme-review-rule-maker/references/review-rules.md b/.codex/skills/aethyme-review-rule-maker/references/review-rules.md new file mode 100644 index 0000000..6741031 --- /dev/null +++ b/.codex/skills/aethyme-review-rule-maker/references/review-rules.md @@ -0,0 +1,147 @@ +# `[review.*]` field reference + +Every table lives in `.aethyme/config.toml` at the repository root, is read +independently, and is off unless it says `enabled = true`. Unknown keys are +rejected at load rather than ignored, so a typo fails loudly. + +## `[review.trigger]` + +| Key | Type | Default | Meaning | +| --- | --- | --- | --- | +| `enabled` | bool | `false` | Off means no dimension is ever eligible. | +| `schema_version` | int | current | A version newer than the broker understands is an error, never a fallback. | +| `rule` | array of tables | `[]` | See below. | +| `default_schedule` | table | 600s / 8 / false | Budget for a dimension with no entry in `schedule`. | +| `schedule.` | table | -- | Budget for one dimension. | + +### `[[review.trigger.rule]]` + +A rule fires when **every** condition it names holds. A rule that names no +condition matches every change. + +| Key | Type | Required | Meaning | +| --- | --- | --- | --- | +| `require` | list of strings | **yes** | Dimensions this rule demands. An empty or missing `require` is rejected at load. | +| `name` | string | no | Appears in the decision's `because`. Name every rule; the report is unreadable otherwise. | +| `on` | list | no | Lifecycle transitions. Empty means any. | +| `paths` | list of globs | no | Repository-relative. Matching any one path satisfies the condition. | +| `areas` | list | no | `Area:` values the author declared. | +| `surfaces` | list | no | `Surface:` values the author declared. | +| `min_risk` | string | no | Declared `Risk:` at or above this level. | +| `from_fork` | bool | no | Only when the change comes from a fork. | +| `first_time_contributor` | bool | no | Only when the author has not landed here before. | +| `authored_by_model` | bool | no | `true` only when a `Model:` trailer names one; `false` only when none does. | +| `models` | list | no | Only when the declared `Model:` is one of these, compared case-insensitively. | + +**Globs.** `*` matches exactly one path segment. `**` matches any number of +segments including zero. Paths are repository-relative with no leading `/` or +`./`, exactly as `git diff --name-only` prints them. + +**`on` values.** `pull_request_opened`, `ready_for_review`, `reopened`, +`replacement_commit` (force-push, amend, rebase), `additional_commit`, +`base_retargeted`, `review_dismissed`, `scheduled`, `manual`. + +`replacement_commit` and `additional_commit` are separate on purpose: a +force-push that rewrites the same logical change and a commit stacked on top of +already-reviewed work justify different responses. + +`merge_queue_entered` is **rejected at load**: nothing a tick can ask the +provider distinguishes it, so a rule waiting for it would never fire. Do not +write it. + +The transition is derived by comparing the pull request against the last +observation of it, not delivered by a webhook, so it is available to any tick +and needs no inbound endpoint. + +**`min_risk` ranking.** `none` < `low` < `high` = `critical`. An unrecognised +value ranks *above* `low`, so a typo in a risk trailer escalates rather than +silently downgrading. + +### `[review.trigger.schedule.]` + +| Key | Type | Default | Meaning | +| --- | --- | --- | --- | +| `debounce_seconds` | int | `600` | Minimum gap between two reviews of this dimension on one pull request. Inside the window the decision is `defer`, which a later tick reconsiders -- not `skip`, which is settled. | +| `max_per_pull_request` | int | `8` | Cap per pull request. `0` means no cap. | +| `always_on_new_head` | bool | `false` | Re-review when the head moves even past the cap. | + +A dimension already reviewed at the current head is skipped before either of +these is consulted. + +## `[review.routing]` + +| Key | Type | Default | Meaning | +| --- | --- | --- | --- | +| `enabled` | bool | `false` | Off means every dimension is recorded and nothing is performed. | +| `workspace_root` | string | `.aethyme/reviews` | Where a Chau7 review's workspace is created. Relative to the repository root. | +| `default_route` | table | `backend = "record"` | Route for a dimension with no entry in `route`. | +| `route.` | table | -- | Route for one dimension. | + +### `[review.routing.route.]` + +| Key | Type | Default | Meaning | +| --- | --- | --- | --- | +| `backend` | `chau7` \| `provider_comment` \| `record` | **required** | Who performs it. | +| `mention` | string | -- | **Required for `provider_comment`.** Stored without the `@`. | +| `instructions` | string | -- | Appended to the generated Chau7 prompt. The generated part is not replaceable. | +| `max_concurrent` | int | `2` | Reviews of this dimension in flight at once, repository-wide. `0` is unbounded. | +| `stale_after_minutes` | int | `360` | Give up on an unfinished review after this long without an update, mark it `abandoned`, and ask again. Stops a dead reviewer holding a slot forever. `0` is never. | + +Budgets are per dimension, so a saturated security queue does not stop a code +review being requested. + +A Chau7 review whose workspace already holds a live tab is deferred rather than +started twice. The check is on the directory, not the branch: a tab that +wandered onto another branch still occupies that workspace. + +## `[review.projection]` + +| Key | Type | Default | Meaning | +| --- | --- | --- | --- | +| `enabled` | bool | `false` | Off means no comment and no label. | +| `comment` | bool | `true` | Maintain one Aethyme-owned comment, found by the marker `` and edited in place. | +| `label_prefix` | string | `aethyme/` | Every label Aethyme writes starts with this. A label outside it is somebody else's and is never touched. Empty is rejected at load. | +| `label_areas` | bool | `true` | `aethyme/area:backend` | +| `label_surfaces` | bool | `true` | `aethyme/surface:auth` | +| `label_risk` | bool | `true` | `aethyme/risk:high` | +| `label_reviews` | bool | `true` | `aethyme/review:security`, while one is outstanding. | +| `reserved` | list of strings | `[]` | Label suffixes inside the prefix that Aethyme reads and never writes or removes. | +| `create_missing_labels` | bool | `true` | `gh pr edit --add-label` fails outright on an unknown label. | + +`reserved` is the difference between a recomputable label and a decided one. +`aethyme/area:backend` can be deleted and rederived from a trailer still in the +commit. A human's `aethyme/skip-review` has no source to rederive from -- once +written, it *is* the source, and without `reserved` reconciliation would see an +unrecognised label under its own prefix and delete the only record of that +judgement. + +## Commit trailers + +| Trailer | Read by | Projected as | +| --- | --- | --- | +| `Area:` | a rule's `areas` | `aethyme/area:` | +| `Surface:` | a rule's `surfaces` | `aethyme/surface:` | +| `Risk:` | a rule's `min_risk` | `aethyme/risk:` | +| `Review:` | nothing -- asks for a dimension directly | `aethyme/review:` | +| `Model:` | a rule's `authored_by_model` and `models` | nothing -- who wrote a change is the author's to disclose | + +Values are comma-separated and case-insensitive. Trailers may appear anywhere +in the body and are merged across every commit in the change: areas and +surfaces union, the highest risk wins, and the first `Model:` declared wins. + +`Model:` is a declaration, not a detection. `Co-Authored-By` is deliberately not +read: it is written by convention, carries a display name rather than a stable +identifier, and appears on commits a model only helped with. + +A declaration can add a review and can never remove one. + +## Errors at load + +| Error | Cause | +| --- | --- | +| `rule N requires no review types` | A rule with an empty `require`. | +| `rule N waits for , which no tick can report` | `on` names `merge_queue_entered`. Remove it; the rule would never fire. | +| `unknown field` | A typo, or a field from a newer broker. | +| `schema_version N is newer than this broker understands` | Upgrade `aethyme`, or pin the policy. It refuses rather than falling back, because silently reviewing nothing is the failure this must not have. | +| `route uses provider_comment without a mention` | `provider_comment` with no bot to mention. | +| `label_prefix must not be empty` | An empty prefix would make every label in the repository Aethyme's. | diff --git a/.codex/skills/aethyme/SKILL.md b/.codex/skills/aethyme/SKILL.md new file mode 100644 index 0000000..34d14c9 --- /dev/null +++ b/.codex/skills/aethyme/SKILL.md @@ -0,0 +1,83 @@ +--- +name: aethyme +description: Use Aethyme's high-level Explore intents, current repository + analyzers, and code graph for navigation, caller tracing, derived facts, + dead-code analysis, and task context. +--- + +# Aethyme Navigation + +Use this skill for repository navigation, task localization, caller tracing, +dead-code analysis, graph context, compact task packs, and the repository's +broker and commit policy. Start with this contract; load a reference only if +the first result is insufficient. + +## Setup + +```bash +AETHYME_BIN="${AETHYME_BIN:-aethyme}" +REPO="$PWD" +``` + +Important: `python -m src.cli ...` was removed — the Python CLI no longer +exists, so that spelling fails outright. Use the `aethyme` binary for +graph, task, facts, intents, analyze, enhance, and Explore. + +## Default Contract + +Explore is a navigation aid, not an authority: every result is verified against +source before it is relied on. It is most useful for "where is X" questions; +skip it when a direct read or a tiny grep already answers the task. + +1. One call for the common case. It prints the compact projection and the top + 2 verified source spans (at most 80 lines each): + +```bash +"$AETHYME_BIN" explore --repo "$REPO" --request "" --format brief +``` + +2. When you need the JSON (audit, a deeper follow-up, or more than two spans), + make one bounded Explore call instead, save it to a temp file, and print + only the compact projection: + +```bash +AETHYME_JSON="$(mktemp -t aethyme-explore.XXXXXX.json)" +"$AETHYME_BIN" explore --repo "$REPO" --request "" --format answer-json --show-observability --depth 0 > "$AETHYME_JSON" +"$AETHYME_BIN" explore-summary --from "$AETHYME_JSON" +"$AETHYME_BIN" verify-targets --repo "$REPO" --from "$AETHYME_JSON" --max-targets 2 --max-lines 80 +``` + + Inspect only: `safe_to_use_as_answer`, `trust_policy`, `subsystems`, + `top_verification_targets`, `verification_steps`, and + `observability.readiness`. + +3. Use the returned spans first. If still unverified, read one missing line range + at a time. Keep each manual command under about 120 output lines / 20k chars + and the whole post-Explore source verification under about 200 lines. + +4. If `safe_to_use_as_answer=false`, follow `verification_steps` and the top + subsystem lanes as an investigation plan. Do not run broad `rg`, `rg + --files`, repository-wide grep, multi-file `sed`, or `rg -C` context dumps + unless the top targets fail. + +5. Escalate deliberately. Prefer one deeper Explore call over several unrelated + commands. Use `--depth 1/2/3` only when the previous result did not provide + enough evidence to act. + +## Load References Only When Needed + +- `references/explore.md`: depth, intent, trust/observability, retry rules. +- `references/graph-task.md`: graph views, task scope, context/prompt packs. +- `references/dead-code.md`: usage-boundary, public API, facts, ambiguity. +- `references/broker.md`: sessions, leases, gates, Git/GitHub coordination, + publication, advisories, recovery. +- `references/policy.md`: commit format, branch and review practice, generated + files and overrides, verifying the enhancement. + +## When Not To Use Aethyme + +- A simple file read, exact path lookup, or tiny grep already answers the task. +- You already have one decisive Aethyme result and only need narrow source + verification. +- The task asks for eval baselines, prior reports, or generated reference + artifacts as evidence; those must not be used for benchmark answers. diff --git a/.codex/skills/aethyme/aethyme-explore b/.codex/skills/aethyme/aethyme-explore new file mode 100755 index 0000000..82210a7 --- /dev/null +++ b/.codex/skills/aethyme/aethyme-explore @@ -0,0 +1,27 @@ +#!/usr/bin/env bash +# Native Rust thin client for `aethyme explore` — the canonical hot path. +# +# This wrapper is the convenience entry point for in-repo skill consumers. +# The aethyme binary routes to the native engine daemon for sub-second warm +# latency. If no daemon is running, it starts the Rust daemon and retries; +# the first map build can take a minute on large repos. +# +# Replaced the soft-retired Python `python -m src.cli explore` wrapper +# on 2026-05-08 (task #59 — Python explore hard-deleted). +# +# The installed router is resolved through PATH; deployment never embeds a +# source-checkout path. +set -euo pipefail + +REPO="${PWD}" + +# Best-effort telemetry via the native router. +if command -v aethyme >/dev/null 2>&1 && [[ -d "$REPO" ]]; then + aethyme repo record-wrapper-invocation \ + "$REPO" \ + --wrapper aethyme-explore \ + --detail source=wrapper \ + >/dev/null 2>&1 || true +fi + +exec aethyme explore "$@" diff --git a/.codex/skills/aethyme/references/broker.md b/.codex/skills/aethyme/references/broker.md new file mode 100644 index 0000000..d913f79 --- /dev/null +++ b/.codex/skills/aethyme/references/broker.md @@ -0,0 +1,263 @@ +## Broker Coordination (multi-agent repository) + +This repository coordinates concurrent agent sessions through the Aethyme +broker. Other agents may be working in sibling worktrees right now. The +`aethyme` router and its engine sibling are installed once for the user; +check the paired runtime with `aethyme --version` and +`aethyme-engine-cli --version`. +Follow this protocol: + +When `aethyme broker advanced hooks install` is active (or its pre-commit command is +wired into an existing hook manager), Git enforces the session boundary on +protected branches: local broker state requires the exact worktree to belong +to a live session, and fetched upstream divergence blocks the commit before +Git writes it. Staged changes remain intact and the refusal prints a valid +adoption or reconciliation command. This enforcement is local-only; without a +local broker database, contributors who have not deployed Aethyme are not +blocked. + +1. **Broker entry point, before editing**: check current activity, create an + isolated broker worktree, and work from that checkout: + + ```bash + aethyme broker status --json # who is working on what + aethyme broker start --task "" --short-name "" --path + ``` + + `cd` into the reported worktree before editing. If you are already in a + dedicated worktree, use + `aethyme broker start --adopt --task "" --short-name "" --path ` instead. + Repeat `--path` for every file or trailing-slash directory known up front. + The broker validates the whole set first, then creates the session plus + explicit leases atomically. Omit `--path` only when no target is known yet. + If `status` shows another session holding leases on the files you plan + to change, prefer working elsewhere first or say so in your report — + overlapping edits will conflict at merge time. + When you edit a file another live session is changing, the broker tells you + in context who, where and whether Git would conflict, never blocking the + edit; `aethyme broker advanced note send --to-session ` reaches that + agent, and its notes reach you at your next turn. + +2. **Lease additional shared files before the diff exists**. Prefer the + atomic `start --path` / `start --adopt --path` declaration above for initial intent. If the + session already exists and scope expands, claim the new path explicitly: + + ```bash + aethyme broker advanced leases claim --session + aethyme broker advanced leases release --session + ``` + + Use a trailing `/` for directory leases. Implicit leases refresh from + changed files, but explicit leases are clearer for planned shared edits. + A claim is refused only by another explicit lease whose holder is actively + working, and never in a `verify-only` repository; every other overlap comes + back as a warning naming the holder, with the `note send` command to + coordinate. + + Orchestration with no path -- a release, a merge chain -- is claimed by + name instead: `aethyme broker advanced ownership claim "release v1.2.0" + --session --reason ""`. `status` shows every claim, + its holder and when the holder last acted; a claim is refused only while + its holder is working, and a quiet holder's claim is taken over. + +3. **Guard broad rewrite commands**. For formatters, code generators, or any + command likely to touch many files, run through the broker guard: + + ```bash + aethyme broker advanced exec --session -- + ``` + + The guard fails if the command leaves dirty paths outside your explicit + leases or in files that were untracked before your session began. + +4. **While working**: commit early and small. Only committed work can be + verified and integrated. Never switch branches inside someone else's + worktree; never edit files outside your own worktree. + + **If `.aethyme/config.toml`, as committed on the default branch, sets + `[delivery] push_session_branches = true`, push your session branch as you + go.** Work that exists only in a worktree + is lost with it, and nobody can review what was never pushed. After each + commit: + + ```bash + aethyme broker push --session + ``` + + This pushes your own session branch (`agent/`) to the default + branch's remote and touches no other ref. A fast-forward is pushed plainly; + a branch you rewrote (for example after a rebase) is pushed only under a + lease on the commit the broker last pushed for your session. Uncommitted + files are reported, not pushed, so commit before you push. Once there is a first meaningful commit, open a draft + pull request, and keep pushing to it until it is ready for review: + + ```bash + aethyme broker push --session --pr + ``` + + `--pr` opens a draft PR, or reports the one already open. The policy is + the authorization for exactly these two things -- pushing your own session + branch and opening a draft PR -- and nothing more: it does not authorize + merging, marking a PR ready, or pushing any other ref. `broker status` and + `broker doctor` report sessions with unpushed commits, and + `aethyme broker finish` refuses to close a session while its commits are + unpushed. If the work should genuinely not be kept, say so explicitly with + `aethyme broker finish --session --abandon --reason ""`. + Each push also fetches the default branch and reports how far your branch + is behind it and whether merging would conflict, with the command to catch + up; `broker status` shows the same as `session.behind-main`. Catch up with + `aethyme broker sync --session ` when it warns, before the pull request + reports the conflict: it rebases an unpublished branch or merges the default + branch into a published one, and changes nothing if that would conflict. + Sync is local only: it never pushes, so run `aethyme broker push --session + ` afterwards to publish the caught-up branch. + `broker start` and `start --reuse` refresh the default branch first, so a + new worktree starts from the latest fetched tip. In a repository + with `[promote] mode = "verify-only"`, `broker submit` is a pre-flight + against the current default branch; the integration branch is not used. + When `broker status` shows `coordination.land-shared-edit-first`, another + session changes the same lines or symbol as yours: follow it -- the named + session lands only the shared edit as its own small PR, then both rebase + on the default branch -- rather than waiting or building on the other + session's unmerged branch. + Without the policy, pushing stays a separately authorized action (step 9). + +5. **Gate resources are per worker**. Broker gate runs take path-scoped owner + locks and export `AETHYME_GATE_WORKER_ID` plus `AETHYME_TEST_DB_SUFFIX`. + Gate commands that need a test database, cache namespace, or similar + external state should suffix it with that value instead of sharing one + fixed name. + + If this repository declares committed graph fragments authoritative in + `.aethyme/config.toml`, graph freshness is an enforced deployment-integrity + check, not a semantic gate suggestion. Session gates, full-tree CI, + repository pre-push, and submit verify the exact tree in a disposable + checkout and refuse stale or wrong-version fragments without rewriting your + worktree. Run `aethyme graph status --repo .`, review + `aethyme graph refresh plan --repo . --diff`, and authorize only its full + digest with `aethyme graph refresh execute --repo . --confirm `. + Never rebuild committed fragments with an unpinned binary. If execution was + interrupted, use the exact `graph refresh recover --plan ` + handoff; do not retry blindly. + + Graph support is repository opt-in. Explore never generates graph state. + If Explore reports `graph_store_missing`, continue with its bounded manual + verification steps, or materialize the verified committed fragments for + this worktree with `aethyme graph materialize --repo .`. Do not enable graph + authority merely to silence a degraded response. + +6. **When your task is complete**, use verified broker integration by + default instead of manually combining concurrent session branches: + + ```bash + aethyme broker submit --session + ``` + + This simulates the merge and runs only the checks your diff affects. + Submit replays session-owned commits as an ordered, single-parent patch + series. If your session contains an owned merge commit, submission refuses + safely and prints the accepted checkpoint plus an exact recovery sequence. + Follow it in order: preserve the current HEAD on the named recovery branch + before flattening the reviewed tree change. Never reset first. + `broker submit` promotes to the local integration branch; it does not + publish a remote branch, create a pull request, or push a release tag. + Publication is a separate, explicitly authorized operator action. When + publication is authorized, review the exact promoted prefix first, then + confirm the plan's full publication SHA: + + ```bash + aethyme broker advanced ship plan --entry + aethyme broker advanced ship execute --entry --confirm + ``` + + Prefer this reviewed broker ship workflow over a raw push. Never infer + publication authority from permission to edit, submit, or promote. + Without publication authority, stop after submit and report the promoted + entry. Under `push_session_branches` (step 4), your pushed session branch + and its draft PR are the delivery: report the PR rather than a promoted + entry. Repositories that deliver through pull requests usually also set + `[promote] mode = "verify-only"`, so verified work does not pile up + unpublished on the local integration branch. + Report the outcome (verified / rejected / conflict) in your summary. + Afterwards, finish the session with + `aethyme broker finish --session `, or point it at a follow-up task + with `aethyme broker start --reuse --task "..." --short-name ""`. `finish` closes broker + state but deliberately leaves the worktree available for review or reuse. + When it reports cleanup is safe, reclaim that exact worktree with + `aethyme broker finish cleanup `. Operators can periodically review all + retained broker-owned worktrees with + `aethyme broker finish cleanup --all-cleaned` and apply the unchanged plan + explicitly with `aethyme broker finish cleanup --all-cleaned --apply`. + +7. **If a file named `.aethyme/broker-action-required.md` appears in your + worktree**, read it immediately: your submission conflicted. It names + the conflicting files, the blocking session, and the exact rebase + steps. Resolve, commit, and resubmit. + +8. **Treat broker advisories as delivered work context, not as blockers.** + The broker surfaces outstanding session advisories after post-commit, + before expensive gates, and on common broker commands. When a notice + appears—or after rebasing or reusing a worktree—inspect + `aethyme broker status --json` before continuing on the named paths. + + `.aethyme/broker-advisory.md` is a gitignored persistence projection; it + is not automatically visible to agents and the broker database remains + authoritative. Read it when a delivery surface points to it. Directory + leases cover descendants, and repeated overlaps are deduplicated and + deterministically ordered. Acknowledging a notice stops repeat delivery + but does not clear the queue entry's unpublished path exposure. Session + close and rebase do not clear it either. Only verified publication or + confirmed external reconciliation resolves an exposure; publishing a + selected integration prefix clears only entries contained in the verified + remote tip. Advisories never expand gate selection or block submit, + promotion, or shipping. + +9. **Git operations remain available to agents.** The broker coordinates + concurrent work; it does not remove Git capabilities. When the user's + request or the repository's documented workflow authorizes the resulting + local or remote state change, agents may perform every required Git + operation, including clone, fetch, pull, switch, branch, add, commit, + stash, merge, cherry-pick, rebase, revert, reset, tag, push (including + force-push when explicitly authorized), and deletion of an exact ref. + + Operations that require coordination **must go through the broker**. Use a + dedicated broker workflow when one exists (for example `broker submit` for + verified integration). Run other coordinated Git operations through the + durable Git operation coordinator: + + ```bash + aethyme broker advanced git --session \ + [--repo ] --reason "" -- ... + ``` + + Read-only GitHub CLI inspection and explicitly authorized local `gh auth` + setup may run directly. Every GitHub repository or account mutation + (pull requests, issues, comments, workflows, releases, settings, secrets, + or non-GET API calls) must use the GitHub operation coordinator: + + ```bash + aethyme broker advanced gh --session \ + --repo --reason "" -- ... + ``` + + The broker classifies known commands and fails closed on ambiguity. Add + `--effect write|destructive --scope ` before `--` for an + unrecognized command. Destructive operations also require `--destructive`. + Every coordinated write requires a concise `--reason` identifying the user + request or documented workflow that authorized it. + If a crashed command leaves an unknown outcome, inspect external state and + use `aethyme broker advanced operations reconcile`; do not retry blindly. + + Direct Git is limited to read-only inspection and operations confined to + the isolated session worktree and session branch that cannot affect other + sessions. Direct `gh` is limited to read-only inspection and local + authentication setup. Any command that + can move shared refs, the default branch, + `aethyme/integration`, remote-tracking refs, tags, or remote state is + coordinated and must not run outside the broker. For destructive or remote + operations, resolve the exact repository and refs first, preserve unrelated + work, and require the authorization that operation normally needs. + Do not infer permission to publish merely from permission to edit or submit. + An explicitly authorized operator or release workflow may merge, tag, push, + force-push, or delete refs through the broker; authorization does not permit + bypassing coordination. \ No newline at end of file diff --git a/.codex/skills/aethyme/references/dead-code.md b/.codex/skills/aethyme/references/dead-code.md new file mode 100644 index 0000000..2171bbb --- /dev/null +++ b/.codex/skills/aethyme/references/dead-code.md @@ -0,0 +1,66 @@ +# Dead Code And API Boundary Reference + +Read this for dead-code, public API caller audits, usage-boundary questions, +and ambiguous internal/external caller decisions. + +## Table Of Contents + +- Start with usage-boundary Explore +- Direct analyzer fallback +- Facts commands +- Status interpretation +- Verification discipline + +## Start With Usage-Boundary Explore + +Use the specialized Explore intent first for boundary usage and public API +caller questions: + +```bash +"$AETHYME_BIN" explore --repo "$REPO" --intent usage_boundary_query --request "" --scope "" --search-root src --search-root tests --format answer-json --show-observability +``` + +For PHP scopes, this intent uses the scope-first `analyze-usage-boundary` +engine path and avoids building the full repository graph. If +`safe_to_use_as_answer=false`, use the returned `verification_steps[]` before +declaring a function unused. + +## Direct Analyzer Fallback + +Use the direct analyzer when the user explicitly asks for the legacy dead-code +shape or when Explore asks you to verify with the analyzer: + +```bash +aethyme analyze dead-code --repo "$REPO" --scope "" --boundary outside-directory --format eval-json --show-observability +``` + +Use `--roots ","` when the repository is large and the task gives +likely search roots. + +## Facts Commands + +For harder cases, derive public surface first, then inspect one target's usage: + +```bash +aethyme facts public-functions --repo "$REPO" --scope "" --json-output +aethyme facts function-usage --repo "$REPO" --target "" --boundary "" --json-output +``` + +## Status Interpretation + +- `Unused`: no internal or external code callers found. +- `Ambiguous`: no external code callers found, but internal callers or + docs/config-only references exist. This may satisfy a boundary prompt but may + not be safe to remove. +- `Used`: at least one caller exists outside the boundary. + +Read `excluded_functions` and ambiguity fields before finalizing. A symbol +excluded for visibility, generated code, or test-only usage should not be +silently promoted into the answer. + +## Verification Discipline + +Dead-code answers require source-backed evidence. Verify returned definitions, +callers, docs/config references, and boundary classification with targeted +reads or narrow grep. Do not use eval baselines, prior reports, or generated +reference artifacts as evidence for benchmark answers. diff --git a/.codex/skills/aethyme/references/explore.md b/.codex/skills/aethyme/references/explore.md new file mode 100644 index 0000000..61598f1 --- /dev/null +++ b/.codex/skills/aethyme/references/explore.md @@ -0,0 +1,123 @@ +# Explore Reference + +Read this when the initial short skill card is not enough to decide which +Explore depth or intent to use. + +## Table Of Contents + +- Default flow +- Trust and observability +- Progressive Disclosure: `--depth` +- Intent selection +- Retry rules + +## Default Flow + +Explore ranks candidates; it does not decide. Treat every result as a +navigation aid and verify it against source before relying on it. Explore +earns its keep on "where is X" questions. It is not a mandatory first step, +and a direct read or a tiny grep is the better tool when it already answers. + +For most questions, one call is enough. `--format brief` prints the compact +projection (trust, readiness, subsystems, verification steps) and the top 2 +verified source spans, at most 80 lines each. It reads the same answer document +as the JSON format, starts on `--depth 0`, and `--repo` defaults to the current +directory: + +```bash +"$AETHYME_BIN" explore --request "" --format brief +``` + +When you need the machine-readable document (audit, a later `--detail full` +comparison, or more than two spans), make one bounded JSON call instead. Save +the full JSON to a temp file, then print a compact projection for agent-facing +inspection: + +```bash +AETHYME_JSON="$(mktemp -t aethyme-explore.XXXXXX.json)" +"$AETHYME_BIN" explore --repo "$REPO" --request "" --format answer-json --show-observability --depth 0 > "$AETHYME_JSON" +"$AETHYME_BIN" explore-summary --from "$AETHYME_JSON" +"$AETHYME_BIN" verify-targets --repo "$REPO" --from "$AETHYME_JSON" --max-targets 2 --max-lines 80 +``` + +Inspect only the printed projection first: `safe_to_use_as_answer`, +`trust_policy`, `subsystems`, `top_verification_targets`, +`verification_steps`, and `observability.readiness`. Keep the full JSON file +for audit/debug or a later `--detail full` comparison; do not dump it into the +conversation by default. + +Verify from the bounded source spans first. Read full target files only if +those spans are insufficient. Read only the missing line range from one target +at a time, keep each manual verification command under about 120 output lines / +20k chars, and keep the whole post-Explore source verification under about 200 +lines. Do not run broad `rg`, `rg --files`, repository-wide grep, multi-file +`sed`, or `rg -C` context dumps unless the top targets fail. + +## Progressive Disclosure: `--depth` + +`explore` accepts `--depth N` where `N` is 0..=3. Lower rungs are cheap and +broad; higher rungs are more expensive and specific. + +- `--depth 0`: paths + names for many candidates. Discovery. +- `--depth 1`: paths + names + signatures for a shorter list. Triage. +- `--depth 2`: 20-line snippets for the top few. Read the code. +- `--depth 3`: full content + call-graph closure for one anchor. Commit-level + and the most expensive rung. + +Start at 0 unless you already know the symbol. If the user names a precise +symbol, file, or function, skip discovery and use `--depth 2` or `--depth 3` on +that anchor. If the task is vague, start at `--depth 0`. + +Escalate one rung at a time. Stop when you have enough to act. If `--depth 1` +returns one clearly correct candidate, jump to a focused `--depth 3` query for +that candidate instead of loading richer context for every candidate. + +When NOT to escalate: if `--depth 0` gives one unambiguous candidate and normal +source reading or narrow grep can verify it, do that. Do not call a deeper +engine command as a formality. + +The legacy `--detail compact|standard|full` flag still works for callers that +use the old budget vocabulary. When both flags are passed, `--depth` wins. + +## Intent Selection + +Use the default `task_localization_query` unless the task clearly fits a +specialized intent. + +```bash +"$AETHYME_BIN" explore --repo "$REPO" --request "" --format answer-json --show-observability --depth 0 +``` + +Use `behavior_localization_query` for debugging, workflows, or "which files +implement this behavior" tasks: + +```bash +"$AETHYME_BIN" explore --repo "$REPO" --intent behavior_localization_query --request "" --format answer-json --show-observability --depth 0 +``` + +Use `usage_boundary_query` for dead-code, public API caller audits, or +boundary usage questions: + +```bash +"$AETHYME_BIN" explore --repo "$REPO" --intent usage_boundary_query --request "" --scope "" --search-root src --search-root tests --format answer-json --show-observability +``` + +List the intent catalog only when you need to choose among intents: + +```bash +aethyme intents --request "" --format compact-json +``` + +## Retry Rules + +If `degraded_reasons` reports a graph timeout, read +`observability.degradation_guidance` before retrying. For very large +repositories where first-response speed matters more than graph coverage, pass: + +```bash +"$AETHYME_BIN" explore --repo "$REPO" --request "" --format answer-json --show-observability --params '{"graph_query_timeout_ms":500}' +``` + +Retry with a narrower request when the first result names an area but not a +specific file. Do not retry with a broader request unless the result contains no +usable answer, hints, or verification path. diff --git a/.codex/skills/aethyme/references/graph-task.md b/.codex/skills/aethyme/references/graph-task.md new file mode 100644 index 0000000..1f7afbe --- /dev/null +++ b/.codex/skills/aethyme/references/graph-task.md @@ -0,0 +1,147 @@ +# Graph And Task Reference + +Read this for graph views, task scope, task packs, and context-pack assembly. +Prefer `explore` first for broad questions; use these commands after you have a +candidate node, symbol, area, or task. + +## Table Of Contents + +- Before you run a graph command (graph store posture) +- Repository orientation +- Graph navigation +- Impact of a change +- Task scope and anchors +- Context packs +- Verification discipline + +## Before You Run A Graph Command + +**Every `aethyme graph`, `aethyme task`, `aethyme query`, `aethyme facts` and +`aethyme analyze` command below reads a local graph store. If that store is +absent, they all refuse.** Explore is the exception: it works without one. + +Graph authority is **disabled by default**. In a repository that has not been +enrolled, every command on this page fails. Check before building a plan on +top of them: + +```bash +aethyme graph status --repo "$REPO" +``` + +- **exit 0** — the store is present and current; the commands below work. +- **exit 1** — the store is missing, stale, or blocked. The printed `next:` line + names the exact command to run. Do not substitute a different one. +- **`--json`** — always exits 0 and carries `fragments.status`, + `derived_store.status`, `blockers[]` and `next_action`; branch on those + fields instead of the exit code when you are parsing. + +If it reports that graph authority is disabled, enrollment is a repository +change and not yours to make unprompted — say so and fall back to `explore`, +which needs no store. Never fall back to repo-wide `rg`/`find` merely because +the graph is unavailable; report the posture instead. + +## Repository Orientation + +Use overview only when the user asks for repo orientation or the initial +Explore answer is too broad: + +```bash +aethyme graph overview "$REPO" --json-output +``` + +## Graph Navigation + +Inspect a node and nearby graph context: + +```bash +aethyme graph node "$REPO" "" --json-output +aethyme graph expand "$REPO" "" --json-output +``` + +Caller/callee evidence: + +```bash +aethyme graph callers "$REPO" "" --json-output +aethyme graph callees "$REPO" "" --json-output +``` + +`node`, `expand` and the relation commands accept either `--json` or +`--json-output`; the two spellings mean the same thing. A misspelled flag is an +error (exit 2) rather than a silent no-op, so a typo will surface immediately. + +`graph callers` and `graph callees` exit **1 with `node not found`** when the +target does not resolve, and exit **0 with `"items": []`** when the node exists +but has no such relation. That distinction tells a misspelled symbol apart from +a genuine empty result — check the exit code, not just the payload. + +Look one up when you are unsure of the spelling: + +```bash +aethyme query symbol "$REPO" "" +``` + +Coverage limits worth knowing before you trust a call graph: method calls and +dynamic dispatch are not extracted, and a bare call whose name is ambiguous in +the repository is deliberately left unresolved rather than guessed. An absent +edge usually means "not resolvable", not "not called". + +Use relation commands to narrow a known node. Do not run every relation command +for the same node unless each result changes the next step. + +## Impact Of A Change + +Before editing, ask what the change reaches — callers, importers, tests and +configs — from a diff: + +```bash +aethyme graph impact --repo "$REPO" --revision HEAD --diff +``` + +Add `--mode imports` for an import-level view and `--json` for machine output. +This is the highest-value pre-edit command in the toolset. The report states its +own `status` and `confidence`: when the graph does not match the requested +revision it withholds paths and says so — treat that as "verify manually", not +as "no impact". + +## Task Scope And Anchors + +Use task commands when the user asks "where should I work?", "what files are in +scope?", or "what should I inspect next?" and the initial Explore answer is not +enough. + +```bash +aethyme task anchors --repo "$REPO" --task "" --json-output +aethyme task scope --repo "$REPO" --task "" --json-output +aethyme task next --repo "$REPO" --task "" --json-output +``` + +Read reasons and risks before expanding scope. A file with a clear reason beats +a larger list with weak evidence. + +## Context Packs + +Use a pack when you need a compact prompt-ready bundle instead of reading many +files manually. + +```bash +aethyme task context --repo "$REPO" --task "" --json-output +aethyme task pack --repo "$REPO" --task "" --json-output +``` + +Inspect selected files, selected symbols, snippets, and token estimates. If a +pack is too large, narrow the task or anchor before asking for a larger pack. + +## Verification Discipline + +Graph/task output is a candidate selector, not a substitute for reading code. +After a graph or task command, verify with targeted file reads or symbol grep +against the returned paths. Avoid raw `rg --files`, broad `find`, or +repo-wide grep unless Aethyme returned no usable candidates. + +Two ways the graph can quietly disagree with the source you are reading: + +1. **The store is stale.** `graph status` is the check; do not infer freshness + from a successful query. +2. **The extraction is incomplete.** Unresolved edges and absent callers are + expected in the coverage gaps listed above. Absence of evidence in the graph + is not evidence of absence in the code. diff --git a/.codex/skills/aethyme/references/policy.md b/.codex/skills/aethyme/references/policy.md new file mode 100644 index 0000000..c7b4e40 --- /dev/null +++ b/.codex/skills/aethyme/references/policy.md @@ -0,0 +1,91 @@ +# Repository Policy Reference + +Read this when you need the full commit format, the branch and review +practices, or how the generated agent files are maintained. The generated root +`AGENTS.md` / `CLAUDE.md` carries only the compressed form of each rule. + +## Table Of Contents + +- Generated files and overrides +- Orientation skills +- Commit hygiene +- Branch and review practices +- Verifying the enhancement + +## Generated Files And Overrides + +`AGENTS.md` and `CLAUDE.md` at the repository root are generated by Aethyme. +Do not edit them directly: `aethyme deploy verify` reports direct edits as +drift. Customize repo-specific policy through `.aethyme/overrides/agents.json` +(`repo_summary`, `hard_constraints`, `validation_rules`, +`commit_hygiene_notes`, `summon_policy_notes`, `maintainer_markdown`) and +repo-specific orientation through `.aethyme/overrides/onboarding.json`, then +rerun `aethyme deploy --repo "$PWD"`. + +Do not run `python -m src.cli ...` for anything; the Python CLI was removed +entirely and that spelling now fails. Use the installed `aethyme` binary for +Explore, `graph`, `task`, `intents`, `facts`, `analyze`, and `deploy`. + +## Orientation Skills + +If `.codex/skills/repo-onboarding/SKILL.md` or +`.claude/skills/repo-onboarding/SKILL.md` exists, load it first when the +repository is unfamiliar or the request asks for a repo overview, setup, +entrypoints, or where to begin. `repo-act` (same two locations) turns that +orientation into execution planning, debugging checklists, and validation +steps. `.aethyme/generated/experience-status.md` summarizes how the enhancement +is being used. + +## Commit Hygiene + +Use typed commit messages. + +- Subject: `type(scope): short summary` +- Allowed types: `fix`, `feat`, `refactor`, `perf`, `test`, `docs`, `build`, `chore`, `revert` +- Substantive commits (`fix`, `feat`, `refactor`, `perf`) must include: + - `Problem` + - `Decision` + - `Rationale` + - `Validation` +- Non-substantive commits (`test`, `docs`, `build`, `chore`, `revert`) may use a subject-only message; structured bodies remain optional. +- Section content may start on the header line (`Problem: text`) or the following line (`Problem:` then `text`). + +Useful commands: + +```bash +aethyme repo commit-message-template --type fix --scope +aethyme repo lint-commit-message .git/COMMIT_EDITMSG +``` + +## Branch And Review Practices + +These scale with the number of agents working a repository at once, where a +habit that costs one agent a minute costs a fleet an hour. + +- **Do not merge the default branch into a working branch to keep it current.** + Merge or rebase only to resolve an actual conflict, and only in your own + worktree. Catch-up merges add conflict surface and history noise for no + safety unless the branch is genuinely required to be fresh. If the default + branch enforces branch-freshness (GitHub's "Require branches to be up to date + before merging"), update immediately before merging rather than reflexively + throughout the branch's life. +- **A check may be required on a pull request only if it is scoped to the diff + and finishes in minutes.** Anything heavier belongs once per merge batch or + once per release. With one agent an unscoped required check is an annoyance; + with several it becomes the dominant cost and serialises the fleet. +- **Cherry-picking to patch an already-certified release is standard; + cherry-picking to assemble a release from trunk is not.** Assembling produces + a combination nobody tested, and hides dependencies between the changes being + picked. Cut a release from a tested point instead, then patch it. + +## Verifying The Enhancement + +To confirm the enhancement is intact in this repository: + +```bash +aethyme deploy verify --repo "$PWD" +``` + +Returns nonzero if any generated root file, Aethyme skill, Aethyme skill +reference, or repo-onboarding skill is missing or has unsubstituted +placeholders. diff --git a/.codex/skills/repo-act/SKILL.md b/.codex/skills/repo-act/SKILL.md new file mode 100644 index 0000000..11e255c --- /dev/null +++ b/.codex/skills/repo-act/SKILL.md @@ -0,0 +1,44 @@ +--- +name: repo-act +description: Use after repo-onboarding or Explore when moving from orientation into execution planning, debugging checklists, and validation steps. Skip when only broad repo orientation is needed. +--- + +# Repo Act: map-generator + +## When to Use + +- Load this after repo-onboarding when the next step is execution or validation planning. +- Skip it for broad repo overview questions with no action plan yet. + +## Debugging Checklist + +- Load repo-onboarding first if the repository or area is unfamiliar. +- Run Aethyme Explore on the user task before broad manual search. +- Verify answer candidates before concluding when trust_policy is not answer-safe. +- Identify the nearest fast test or validation command before editing. +- Inspect caution zones before changing generated or vendored areas. + +## Validation Checklist + +- Run the fastest relevant test command first. +- Check likely entrypoints and impacted callers before finishing. +- Re-run lint/build only after the focused validation passes. +- Document any override-based maintainer note that affected the change plan. + +## Useful Commands + +- `fast_test`: `cargo test --workspace` +- `build`: `cargo build --workspace` +- `dev`: `cargo run` + +## Primary Entrypoints + +- `app`: `Procfile:web` (Procfile process entrypoint) +- `cli`: `crates/mapgen-cli/src/main.rs` (tracked Rust binary entrypoint in `.`) +- `test`: `tests` (conventional test root) + +## Likely Entrypoints + +- `Procfile:web` (Procfile process entrypoint) +- `crates/mapgen-cli/src/main.rs` (tracked Rust binary entrypoint in `.`) +- `crates/mapgen-server/src/main.rs` (tracked Rust binary entrypoint in `.`) diff --git a/.codex/skills/repo-onboarding/SKILL.md b/.codex/skills/repo-onboarding/SKILL.md new file mode 100644 index 0000000..8f7fab0 --- /dev/null +++ b/.codex/skills/repo-onboarding/SKILL.md @@ -0,0 +1,83 @@ +--- +name: repo-onboarding +description: Use when starting work in an unfamiliar repository, when the task asks for repo overview, setup, architecture, entrypoints, test commands, or where to begin. Skip for narrow file-scoped edits once the relevant paths are already known. +--- + +# Repo Onboarding: map-generator + +## When to Use + +- Load this skill first when the repository is unfamiliar or the request is broad. +- Recommended when: first task in repo, repo overview, setup or run instructions, architecture or entrypoints, where should I start, broad debugging or feature-localization request. +- Skip when: known file-scoped edit, follow-up inside already identified area, task already localized to concrete files. +- Use `.codex/skills/aethyme/SKILL.md` or `.claude/skills/aethyme/SKILL.md` for Aethyme's short operating contract after orientation; load its `references/` files only when needed. + +## Repo Identity + +- Kind: `repository` +- Languages: `rust, typescript` +- Package manager: `cargo` +- Key manifests: `Cargo.toml, Procfile, crates/mapgen-cli/Cargo.toml, crates/mapgen-core/Cargo.toml, crates/mapgen-data/Cargo.toml, crates/mapgen-server/Cargo.toml, crates/mapgen-spec/Cargo.toml, crates/mapgen-wasm/Cargo.toml, crates/mapgen-wasm/package.json` + +## Workspaces + +- `.` (primary; cargo; manifest `Cargo.toml`; high confidence) +- `crates/mapgen-wasm` (supporting; npm; manifest `crates/mapgen-wasm/package.json`; high confidence) + +## Start Here + +- `dev`: `cargo run` +- `fast_test`: `cargo test --workspace` +- `build`: `cargo build --workspace` + +## Supporting Commands + +- `cargo run` (dev; medium confidence from `Cargo.toml`) +- `./target/release/mapgen-server` (dev; medium confidence from `Procfile:web`) +- `cargo test` (fast_test; high confidence from `Cargo.toml`) +- `cargo test --workspace` (fast_test; high confidence from `Cargo.toml`) + Workspace: `.` +- `cargo build` (build; high confidence from `Cargo.toml`) + +## Entrypoints + +- `app`: `Procfile:web` (Procfile process entrypoint; high confidence) +- `cli`: `crates/mapgen-cli/src/main.rs` (tracked Rust binary entrypoint in `.`; high confidence) +- `test`: `tests` (conventional test root; medium confidence) + +## Additional Entrypoints + +- `Procfile:web` (process; role=app; Procfile process entrypoint; high confidence) +- `crates/mapgen-cli/src/main.rs` (file; role=cli; tracked Rust binary entrypoint in `.`; high confidence) + Executable: `mapgen` +- `crates/mapgen-server/src/main.rs` (file; role=cli; tracked Rust binary entrypoint in `.`; high confidence) + Executable: `mapgen-server` +- `tests` (directory; role=test; conventional test root; medium confidence) + +## Repo Map + +- `.github` (automation; automation and CI configuration; high confidence) +- `docs` (docs; documentation area; high confidence) +- `scripts` (tooling; developer tooling or scripts; high confidence) +- `tests` (tests; conventional test directory; high confidence) + +## Aethyme Recipes + +- `aethyme explore --repo "$PWD" --request "" --format answer-json` + Purpose: Broad repository orientation for a user request +- `aethyme repo inspect "$PWD" --mode brief --json-output` + Purpose: Quick deterministic repo summary +- `aethyme graph callers "$PWD" "" --json-output` + Purpose: Trace likely impact before editing + +## Generated and Dangerous Paths + +- Generated/vendor `.aethyme/generated`: tracked generated or vendored surface; verify ownership before editing +- Sensitive `.github/workflows`: repository automation; changes can affect publication or shared CI + +## Freshness + +- Source digest: `9d585c352194147824bc58c079ba104409fa5271d4cab3e0f4363992fb631475` +- Tracked source files: `131` +- Overrides applied: `False` +- Sections generated: `repo, workspaces, primary_workspace, commands, areas, entrypoints, caution_zones, generated_paths, dangerous_paths, navigation_recipes, summon, freshness` diff --git a/.gitignore b/.gitignore index bfdea57..16fa773 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,23 @@ !.aethyme/config.toml .chau7/ .playwright-mcp/ + +# aethyme-broker:begin (managed block — do not edit inside) +.aethyme/broker.db* +.aethyme/logs/ +.aethyme/locks/ +.aethyme/reports/ +.aethyme/run/ +.aethyme/worktrees/ +.aethyme/broker-action-required.md +.aethyme/broker-advisory.md +.aethyme/graph_store.redb +.aethyme/graph_store.redb.indexing +.aethyme/generated/experience-status.json +.aethyme/generated/experience-status.md +.aethyme/generated/experience-telemetry.jsonl +.aethyme/reviews/ +.aethyme/worktree-sizes.json +.aethyme/gc-journal.json +.aethyme/gc.lock +# aethyme-broker:end diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..1e41f91 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,56 @@ +# Agent Instructions + + +Generated by Aethyme; do not edit. Customize `.aethyme/overrides/agents.json` +(policy) or `.aethyme/overrides/onboarding.json` (orientation), then run +`aethyme deploy --repo "$PWD"`. + +## This repository + +`map-generator`: rust repository (cargo). Fast test: `cargo test --workspace`. App entrypoint: `Procfile:web`. +Orientation: `.claude/skills/repo-onboarding/SKILL.md`, then `.claude/skills/repo-act/SKILL.md` (Codex: `.codex/skills/repo-onboarding/SKILL.md`, `.codex/skills/repo-act/SKILL.md`). Status: `.aethyme/generated/experience-status.md`. + +## Broker Coordination: before and after an edit + +Other agents may be working in sibling worktrees. + +1. `aethyme broker start --task ""`, then work only in the worktree it + reports and follow the working agreement it prints. Never edit another + session's worktree. +2. Commit early and small, and after each commit run + `aethyme broker push --session `. Once there is a first meaningful + commit, open a draft PR with `aethyme broker push --session --pr`, and + keep pushing until it is ready. Run `aethyme broker sync --session ` + before resuming a reused session and whenever push reports the branch is + behind the default branch. Never leave work only in the worktree. +3. When done: `aethyme broker submit --session `, then + `aethyme broker finish --session ` (it refuses while commits are unpushed). + +This repository's `push_session_branches` policy authorizes pushing your own +session branch and opening a draft PR; nothing else. Other remote or shared Git +and GitHub writes go through `aethyme broker advanced git` and +`aethyme broker advanced gh`. If `.aethyme/broker-action-required.md` appears, +read it first. Leases, gates, advisories and recovery: `references/broker.md`. + +## Finding code + +For "where is X" questions, try `aethyme explore --request "" --format brief` +first: one call prints a ranked summary and the top verified source spans. It +is a navigation aid, not an answer. Verify the spans before relying on them. +Read code in a session worktree, not the main checkout: it trails +`aethyme/integration` by design, and Explore flags answers from a stale tree. + +## Commits + +Subject `type(scope): summary`. Types: `fix`, `feat`, `refactor`, `perf`, `test`, `docs`, `build`, `chore`, `revert`. +Substantive commits (`fix`, `feat`, `refactor`, `perf`) need `Problem`, `Decision`, `Rationale` and `Validation` sections; the others may be subject-only. +Check with `aethyme repo lint-commit-message `. + +## Everything else + +Load the Aethyme skill: `.claude/skills/aethyme/SKILL.md` (Codex: +`.codex/skills/aethyme/SKILL.md`). Its `references/` hold the detail: +`explore.md` (depth, intents, retries), `broker.md` (leases, gates, Git and +GitHub coordination, publication, recovery), `policy.md` (commit format, +branch and review practice, verifying these files), `graph-task.md` and +`dead-code.md`. diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..1e41f91 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,56 @@ +# Agent Instructions + + +Generated by Aethyme; do not edit. Customize `.aethyme/overrides/agents.json` +(policy) or `.aethyme/overrides/onboarding.json` (orientation), then run +`aethyme deploy --repo "$PWD"`. + +## This repository + +`map-generator`: rust repository (cargo). Fast test: `cargo test --workspace`. App entrypoint: `Procfile:web`. +Orientation: `.claude/skills/repo-onboarding/SKILL.md`, then `.claude/skills/repo-act/SKILL.md` (Codex: `.codex/skills/repo-onboarding/SKILL.md`, `.codex/skills/repo-act/SKILL.md`). Status: `.aethyme/generated/experience-status.md`. + +## Broker Coordination: before and after an edit + +Other agents may be working in sibling worktrees. + +1. `aethyme broker start --task ""`, then work only in the worktree it + reports and follow the working agreement it prints. Never edit another + session's worktree. +2. Commit early and small, and after each commit run + `aethyme broker push --session `. Once there is a first meaningful + commit, open a draft PR with `aethyme broker push --session --pr`, and + keep pushing until it is ready. Run `aethyme broker sync --session ` + before resuming a reused session and whenever push reports the branch is + behind the default branch. Never leave work only in the worktree. +3. When done: `aethyme broker submit --session `, then + `aethyme broker finish --session ` (it refuses while commits are unpushed). + +This repository's `push_session_branches` policy authorizes pushing your own +session branch and opening a draft PR; nothing else. Other remote or shared Git +and GitHub writes go through `aethyme broker advanced git` and +`aethyme broker advanced gh`. If `.aethyme/broker-action-required.md` appears, +read it first. Leases, gates, advisories and recovery: `references/broker.md`. + +## Finding code + +For "where is X" questions, try `aethyme explore --request "" --format brief` +first: one call prints a ranked summary and the top verified source spans. It +is a navigation aid, not an answer. Verify the spans before relying on them. +Read code in a session worktree, not the main checkout: it trails +`aethyme/integration` by design, and Explore flags answers from a stale tree. + +## Commits + +Subject `type(scope): summary`. Types: `fix`, `feat`, `refactor`, `perf`, `test`, `docs`, `build`, `chore`, `revert`. +Substantive commits (`fix`, `feat`, `refactor`, `perf`) need `Problem`, `Decision`, `Rationale` and `Validation` sections; the others may be subject-only. +Check with `aethyme repo lint-commit-message `. + +## Everything else + +Load the Aethyme skill: `.claude/skills/aethyme/SKILL.md` (Codex: +`.codex/skills/aethyme/SKILL.md`). Its `references/` hold the detail: +`explore.md` (depth, intents, retries), `broker.md` (leases, gates, Git and +GitHub coordination, publication, recovery), `policy.md` (commit format, +branch and review practice, verifying these files), `graph-task.md` and +`dead-code.md`.