Metadata-Version: 2.4
Name: gh-address-cr
Version: 2.4.3
Summary: Deterministic PR review-resolution control plane runtime.
Author: rbbtsn0w
License-Expression: MIT
Project-URL: Homepage, https://github.com/RbBtSn0w/gh-address-cr
Project-URL: Source, https://github.com/RbBtSn0w/gh-address-cr
Project-URL: Issues, https://github.com/RbBtSn0w/gh-address-cr/issues
Keywords: ai-agent,github,pull-request,code-review,cli
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Quality Assurance
Classifier: Topic :: Software Development :: Version Control :: Git
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: packaging>=24
Dynamic: license-file

# gh-address-cr skill

An auditable PR-session workflow skill and runtime CLI for AI coding agents.

Project architecture governance lives in `.specify/memory/constitution.md`.
The installed skill contract remains `skill/SKILL.md`; keep
repo-root governance and packaged-skill instructions in their own scopes.

It now treats a Pull Request as the session root and can ingest both:

- GitHub review threads
- local AI-agent review findings

Both become session items that move through one evidence-first workflow with a final gate.
For handled GitHub threads, replying and resolving are still two separate required operations.
`final-gate` now also verifies that every terminal GitHub thread has durable reply evidence, not only that unresolved-thread count reached zero.

## Runtime / Skill Split

The deterministic implementation belongs to the runtime package:

- console entrypoint: `gh-address-cr`
- module entrypoint: `python3 -m gh_address_cr`
- source package: `src/gh_address_cr/`

The packaged skill remains under `skill/` and acts as a thin adapter:

- `skill/SKILL.md` explains agent behavior
- `skill/scripts/cli.py` is a compatibility shim
- `skill/runtime-requirements.json` declares runtime compatibility
- `skill/agents/` and `skill/references/` provide hints and reference docs

The shim must delegate to the runtime or fail loudly before mutating session state. Runtime state machines, leases, GitHub side effects, evidence ledgers, and final-gate behavior must not be reimplemented as skill-owned workflow code.

## Installation

### Install the released runtime CLI

Use this path when you want the stable `gh-address-cr` executable from PyPI. The runtime CLI requires Python 3.10 or newer.

```bash
pipx install gh-address-cr
gh-address-cr --help
python -m gh_address_cr --help
```

The `uv` equivalent is:

```bash
uv tool install gh-address-cr
gh-address-cr --help
python -m gh_address_cr --help
```

These commands install the Python runtime package. They do not install or update the packaged skill adapter under `skill/`.

### Install with Homebrew

Use this path when you want the stable `gh-address-cr` executable through Homebrew on macOS or Linuxbrew. Homebrew installs the same released runtime package from the PyPI sdist through the `RbBtSn0w/homebrew-tap` formula.

```bash
brew tap RbBtSn0w/tap
brew install gh-address-cr
gh-address-cr --help
gh-address-cr agent manifest
```

Upgrade and test the installed formula with:

```bash
brew upgrade gh-address-cr
brew test gh-address-cr
```

The Homebrew tap installs the runtime CLI only. It does not install or update the packaged skill adapter under `skill/`.

### GitHub-direct runtime validation install

Use this path only for pre-release validation of the current repository state before a PyPI release is available.

```bash
pipx install git+https://github.com/RbBtSn0w/gh-address-cr.git
gh-address-cr --help
gh-address-cr agent manifest
```

The `uv` equivalent is:

```bash
uv tool install git+https://github.com/RbBtSn0w/gh-address-cr.git
gh-address-cr --help
gh-address-cr agent manifest
```

### Local editable development install

Use this path when editing this repository.

```bash
python3 -m pip install -e .
gh-address-cr --help
python3 -m gh_address_cr --help
gh-address-cr agent manifest
```

### Packaged skill install

Use this path when installing the Codex/agent skill adapter. This does not install the runtime CLI package; install the runtime separately with `pipx`, `uv tool`, GitHub-direct validation, or local editable development commands above.

```bash
npx skills add https://github.com/RbBtSn0w/gh-address-cr --skill skill
npx skills check
```

After installing the skill, verify that a runtime CLI is available:

```bash
gh-address-cr --help
gh-address-cr adapter check-runtime
```

### Upgrade from skill-shim usage

If you previously relied on `python3 skill/scripts/cli.py` from the packaged skill compatibility shim, reinstall the runtime CLI with `pipx` or `uv tool` instead of reinstalling the skill as a substitute:

```bash
pipx reinstall gh-address-cr
# or
uv tool upgrade gh-address-cr
```

Then verify:

```bash
gh-address-cr --help
gh-address-cr agent manifest
```

If PyPI does not yet contain `gh-address-cr`, use the GitHub-direct runtime validation install until a release is published.

Runtime install for local development:

```bash
python3 -m pip install -e .
gh-address-cr --help
python3 -m gh_address_cr --help
gh-address-cr adapter check-runtime
```

Native runtime ownership is now split by responsibility:

- `src/gh_address_cr/core/session.py`: PR-scoped session loading, saving, and workspace paths
- `src/gh_address_cr/core/workflow.py`: agent classification, leases, action requests, accepted responses, and deterministic publishing transitions
- `src/gh_address_cr/core/gate.py`: final-gate policy evaluation and the native `Gatekeeper`
- `src/gh_address_cr/github/client.py`: GitHub CLI IO for thread listing, replies, resolves, and pending reviews
- `src/gh_address_cr/intake/findings.py`: findings parsing, normalization, source-scoped fingerprints, and fixed finding blocks
- `src/gh_address_cr/legacy_scripts/`: compatibility shims for packaged runtime script paths

The native packages under `core/`, `github/`, and `intake/` must not import `legacy_scripts`.
Public high-level commands (`active-pr`, `review`, `address`, `threads`, `findings`, and `adapter`) are routed through the native runtime package. Core script entrypoints such as `session_engine.py`, `cr_loop.py`, and `control_plane.py` now delegate to native modules; the remaining `legacy_scripts` files are compatibility surfaces for older direct script invocations.

## Public Interface

`gh-address-cr` should be understood first as a PR-scoped workflow orchestrator with one public main entrypoint plus a lightweight thread-only shortcut:

- `active-pr`
- `review`
- `address`

Advanced/internal integration entrypoints:

- `threads`
- `findings`
- `adapter`
- `review-to-findings`
- `agent manifest`
- `agent classify`
- `agent next`
- `agent submit`
- `agent submit-batch`
- `agent fix`
- `agent fix-all`
- `agent resolve-stale`
- `agent evidence`
- `agent publish`
- `agent leases`
- `agent reclaim`
- `final-gate`

Fail-fast contract:

- `review` does not bind to any one review skill or tool name.
- `review` is the public main entrypoint.
- If findings are absent, `review` returns `WAITING_FOR_EXTERNAL_REVIEW` and writes a standard producer handoff request instead of waiting on `stdin`.
- External producer output must be findings JSON or fixed `finding` blocks.
- `findings` still requires explicit findings JSON input.
- `review-to-findings` does not accept arbitrary Markdown. It only accepts the fixed `finding` block format.
- `review`, `threads`, and `adapter` also fail immediately when `gh` is missing from `PATH`.
- For `adapter`, wrapper `--human` and `--machine` belong before `adapter`. Arguments after `<adapter_cmd...>` are passed through to the adapter command unchanged.
- The high-level CLI commands are the agent-safe public surface. Treat low-level scripts as implementation details.

`review` is the default orchestrator. It either:

- consumes explicit findings input when `--input` is supplied, or
- generates an external review handoff and waits for a producer-compatible result

High-level entrypoints emit machine-readable JSON summaries by default. Use `--human` when a person needs narrative text. `--machine` remains a compatibility alias. Use `--lean` or `--summary` with `address`, `threads`, and `review --auto-simple` when agents need low-token thread rows.

Minimal invocation model:

```text
/gh-address-cr active-pr [--repo <owner/repo>] [--head <branch>]
/gh-address-cr review <owner/repo> <pr_number>
/gh-address-cr address <owner/repo> <pr_number> --lean
```

Advanced/internal integrations are documented later in this README.

Stable machine summary fields:

- `status`
- `repo`
- `pr_number`
- `item_id`
- `item_kind`
- `counts`
- `artifact_path`
- `reason_code`
- `waiting_on`
- `next_action`
- `commands`
- `exit_code`
- `diagnostics` (optional, for GitHub CLI/API failures)

`reason_code` is the stable machine reason. `waiting_on` is the stable wait-state category.
`counts.*` may be `null` in preflight wait/fail states before GitHub or session scans run.
When present, `diagnostics` includes the underlying `gh` command, `returncode`, `stderr_category` (`auth`, `network`, `sandbox`, `environment`, `rate_limit`, `not_found`, `api`, or `unknown`), and a bounded redacted `stderr_excerpt`.
`commands` contains executable templates for common next steps such as `address --lean`, `agent publish`, `agent fix-all`, `agent resolve-stale`, and `final-gate`.
The `threads` command and lightweight address states may also include a `threads` array with actionable thread context for agents. Full output includes `thread_id`, `path`, `line`, `body`, `url`, state/status, reply evidence, and accepted-response presence. Lean output keeps only `item_id`, `thread_id`, `path`, `line`, `state`, `status`, `is_resolved`, `is_outdated`, `claimable`, `accepted_response_present`, and `reply_evidence_present`.

### Metadata Commands

```bash
# Display version
gh-address-cr --version
# or
gh-address-cr version
```

## Multi-Agent Coordination

The runtime is the coordinator. AI agents consume structured requests and return structured evidence.

```bash
gh-address-cr agent manifest
gh-address-cr agent classify owner/repo 123 local-finding:abc --classification fix --note "Real defect."
gh-address-cr agent next owner/repo 123 --role fixer --agent-id codex-fixer-1
gh-address-cr agent submit owner/repo 123 --input action-response.json
gh-address-cr agent submit owner/repo 123 --input action-response.json --publish
gh-address-cr agent submit-batch owner/repo 123 --input batch-response.json
gh-address-cr agent evidence add owner/repo 123 --name local-verified --commit <sha> --files src/example.py --validation "python3 -m unittest tests.test_example=passed"
gh-address-cr agent fix owner/repo 123 github-thread:THREAD_ID --commit <sha> --files src/example.py --summary "Fixed it." --why "The guarded path covers the review case." --validation "python3 -m unittest tests.test_example=passed" --publish
gh-address-cr agent fix-all owner/repo 123 --commit <sha> --files src/shared.py --validation "python3 -m unittest tests.test_shared=passed"
gh-address-cr agent resolve-stale owner/repo 123 --commit <sha> --files src/stale.py --validation "python3 -m unittest tests.test_stale=passed" --match-files
gh-address-cr agent publish owner/repo 123
gh-address-cr agent leases owner/repo 123
gh-address-cr agent reclaim owner/repo 123
gh-address-cr agent orchestrate {start,step,status,stop,resume,submit} owner/repo 123
gh-address-cr doctor owner/repo 123
gh-address-cr final-gate owner/repo 123
```

Classification and resolution are deliberately separate protocol phases:

- `agent classify` records triage evidence on the item before a mutating fixer lease exists. If `agent next --role fixer` returns `MISSING_CLASSIFICATION`, run `agent classify ... --classification <fix|clarify|defer|reject> --note <why>` first.
- `agent submit` consumes a fixer or verifier `ActionResponse`. Its `resolution` field is the response decision for an already leased request. If submit returns `MISSING_RESOLUTION`, add `"resolution": "fix|clarify|defer|reject"` to the response JSON and rerun `agent submit`. Use `--publish` only for accepted GitHub review-thread fix responses when the runtime should post the reply and resolve the thread in the same command.

Role split:

- `coordinator`: deterministic runtime CLI
- `review_producer`: external findings producer
- `triage`: classifies review items as fix/clarify/defer/reject
- `fixer`: modifies code and returns evidence
- `verifier`: validates evidence and test results
- `publisher`: deterministic runtime role for GitHub replies/resolves
- `gatekeeper`: deterministic final-gate role

Parallel work is lease-based. Independent items may be claimed concurrently, but overlapping file, item, thread, or GitHub side-effect conflict keys are rejected. AI agents must not post replies or resolve GitHub threads directly; accepted evidence is published by the runtime.
After `agent submit` returns `ACTION_ACCEPTED`, follow the returned `next_action`; GitHub-thread fixes publish through `agent publish`.
Use `agent submit-batch` only for GitHub review-thread `fix` evidence when one commit/files/validation set addresses multiple leased threads. The batch payload still references each thread's issued `request_id` and `lease_id`, and each item supplies its own `summary`/`why`; the runtime expands it into per-item accepted evidence before `agent publish`. Prefer `agent fix-all` when the session already contains matching GitHub thread items and a single commit/files/validation set covers them; it still classifies, claims, and submits through the existing lease and batch evidence path. Use `agent resolve-stale --match-files` for matching `STALE` threads; stale synchronization is still runtime-mediated evidence and publish/final-gate work, not a direct state flip.
The default manifest advertises `max_parallel_claims: 2`. This is a lease-safety limit, not a batch-size target. The same agent may claim multiple GitHub review-thread fixer leases that overlap only by file path so one same-file commit can be submitted as common batch evidence; thread side effects remain item-scoped. For many small review-thread fixes, claim the currently allowed active leases, repair them together when one commit covers them, submit a batch response, publish, then claim the next set.

Reusable evidence profiles reduce repeated commit/files/validation text across responses:

```bash
gh-address-cr agent evidence add owner/repo 123 \
  --name local-verified \
  --commit abc123 \
  --files src/example.py,tests/test_example.py \
  --validation "python3 -m unittest tests.test_example=passed"
```

Later `ActionResponse` or `BatchActionResponse.common` payloads may include `"evidence_ref": "local-verified"` and still provide per-item `note`, `summary`, and `why`.
When `--validation` is provided without an explicit `=result` suffix, the entire value is treated as the command and the result defaults to `passed`; this keeps commands with environment assignments such as `PYENV_VERSION=3.10.19 python -m unittest` intact.

`agent next` writes both `request_path` and `response_skeleton_path`. Fill the response skeleton when you need a local artifact with the correct `schema_version`, `request_id`, `lease_id`, `agent_id`, `item_id`, `resolution`, `validation_commands`, and GitHub-thread `fix_reply` shape. Required user-supplied fields are intentionally empty in the skeleton so an unedited template is rejected instead of published.

Minimal `BatchActionResponse` shape:

```json
{
  "schema_version": "1.0",
  "agent_id": "codex-fixer-1",
  "resolution": "fix",
  "common": {
    "files": ["src/example.py", "tests/test_example.py"],
    "validation_commands": [
      {"command": "python3 -m unittest tests.test_example", "result": "passed"}
    ],
    "fix_reply": {
      "commit_hash": "abc123",
      "test_command": "python3 -m unittest tests.test_example",
      "test_result": "passed"
    }
  },
  "items": [
    {
      "request_id": "req_1",
      "lease_id": "lease_1",
      "item_id": "github-thread:THREAD_1",
      "summary": "Fixed thread 1.",
      "why": "The input is now validated before use."
    }
  ]
}
```

Manual helper path for an issued runtime `ActionRequest`:

```bash
gh-address-cr submit-action <action-request.json> \
  --agent-id codex-fixer-1 \
  --resolution fix \
  --note "Fixed the thread." \
  --commit-hash abc123 \
  --files src/example.py \
  --validation-cmd "python3 -m unittest tests.test_example=passed" \
  --output-dir /tmp/gh-address-cr-response

gh-address-cr agent submit owner/repo 123 --input <generated-action-response.json>
```

The helper also accepts older loop-request artifacts with top-level `repo` and `pr_number`, but runtime `ActionRequest` files use `repository_context.repo` and `repository_context.pr_number`. Use `--output-dir` when the runtime workspace is not writable from the current sandbox.

Main entrypoint examples:

```text
$gh-address-cr review <PR_URL>
```

High-level entrypoints:

- `review`
  - public main entrypoint
  - runs the full PR review workflow automatically
  - waits for external producer handoff when findings are absent
  - supports `--auto-simple` for the lightweight GitHub thread-only path
  - handles both local findings and GitHub review threads in one run
  - emits a machine-readable JSON summary by default
- `address`
  - lightweight GitHub thread-only entrypoint for simple PRs
  - does not wait for external review findings or ingest local findings
  - emits `WAITING_FOR_SIMPLE_ADDRESS` with an actionable request artifact when threads need agent evidence
  - the request artifact includes `claimable_item_ids`, thread rows, commands, and a `batch_response_skeleton` for leased thread evidence
- `doctor`
  - checks GitHub CLI availability/auth, viewer lookup, optional repository access, and runtime cache writeability
  - use before retrying blocked workflows with auth, network, sandbox, or cache-permission symptoms
- `threads`
  - advanced/internal: GitHub review threads only
  - emits a machine-readable JSON summary by default
- `findings`
  - advanced/internal: existing findings JSON only
  - handles local findings only; it does not process GitHub review threads
  - emits a machine-readable JSON summary by default
- `adapter`
  - advanced/internal: adapter-produced findings plus PR orchestration, including GitHub thread handling
  - emits a machine-readable JSON summary by default
- `review-to-findings`
  - advanced/internal: fixed-format finding blocks to findings JSON

Automatic external review handoff:

- `review` writes `producer-request.md` when findings are absent
- any external review producer may satisfy the handoff
- preferred handoff file: `incoming-findings.json`
- fallback handoff file: `incoming-findings.md`
- `incoming-findings.md` must contain fixed `finding` blocks
- rerun the same `review` command after writing one of the handoff files
- plain narrative Markdown is not accepted

Producer contract:

- `gh-address-cr` does not require a specific skill name
- it accepts output from any external review producer
- the producer may be another skill, a command, or another review tool
- the only required contract is findings JSON or fixed `finding` blocks

Minimal user prompt:

```text
使用 $gh-address-cr 完整处理这个 PR：<PR_URL>
```

Typical flows:

```text
// Main flow: start the PR session
$gh-address-cr review <PR_URL>

// If findings are absent, `review` returns WAITING_FOR_EXTERNAL_REVIEW
// and writes:
// - producer-request.md
// - incoming-findings.json
// - incoming-findings.md

// If you are also the review producer, write findings JSON to incoming-findings.json
// or fixed `finding` blocks to incoming-findings.md now.
// Do not write a plain Markdown-only review report.

// After any external review producer fills a handoff file, rerun the same command
$gh-address-cr review <PR_URL>

// If review returns BLOCKED, inspect loop-request-*.json, apply fix/clarify/defer,
// then rerun the same review command

// Adapter wrapper output flag comes before `adapter`
gh-address-cr --human adapter owner/repo 123 python3 tools/review_adapter.py

// Flags after the adapter command belong to the adapter itself
gh-address-cr adapter owner/repo 123 python3 tools/review_adapter.py --base main --human
```

Minimal valid `review-to-findings` input:

````text
```finding
title: Missing null guard
path: src/example.py
line: 12
body: Potential null dereference.
```
````

This converter rejects plain narrative Markdown review output.

Prompt patterns:

```text
先运行 `$gh-address-cr review <PR_URL>`。

如果当前 PR 还没有 findings，`review` 应进入 `WAITING_FOR_EXTERNAL_REVIEW`，
写出 `producer-request.md`、`incoming-findings.json`、`incoming-findings.md`。

如果你自己就是外部 review producer，就在当前任务里直接生成 findings JSON，
写入 `incoming-findings.json`；或者生成固定格式的 `finding` blocks`，
写入 `incoming-findings.md`。不要只输出普通 Markdown 审查报告。

收到 handoff 后，重新运行同一条 `review` 命令，继续处理 session、GitHub review threads、fix 和 final-gate，直到通过。
```

Ready-to-use prompt variants:

- Short generic:

```text
使用 $gh-address-cr 完整处理这个 PR：<PR_URL>。
```

- Explicit `$code-review` producer:

```text
使用 $gh-address-cr 完整处理这个 PR：<PR_URL>。

先运行 $gh-address-cr review。
如果返回 WAITING_FOR_EXTERNAL_REVIEW，就使用 $code-review 作为外部 review producer。
按照 producer-request.md 的要求交接：
- 优先把 findings JSON 写入 incoming-findings.json
- 如果只能输出固定格式的 `finding` blocks，就写入 incoming-findings.md
- 不要只输出普通 Markdown 审查报告

写入 handoff 文件后，重新运行同一条 $gh-address-cr review 命令，
继续处理 session、GitHub threads、fix、reply/resolve 和 final-gate，直到通过。
```

- Any external review producer:

```text
使用 $gh-address-cr 完整处理这个 PR：<PR_URL>。

先运行 $gh-address-cr review。
如果返回 WAITING_FOR_EXTERNAL_REVIEW，就使用当前环境中可用的外部 review 能力完成审查。
按照 producer-request.md 的要求交接：
- 优先把 findings JSON 写入 incoming-findings.json
- 如果只能输出固定格式的 `finding` blocks，就写入 incoming-findings.md
- 不要只输出普通 Markdown 审查报告

写入 handoff 文件后，重新运行同一条 $gh-address-cr review 命令，
继续处理 session、GitHub threads、fix、reply/resolve 和 final-gate，直到通过。
```

## AI Agent Feedback

When the skill itself blocks progress, file a feedback issue in this repository instead of silently dropping the problem.

- By default, feedback issues are filed to `RbBtSn0w/gh-address-cr`. Override `--target-repo` only when the skill owner explicitly directs you to use a different feedback repository.
- Use feedback issues for skill-level problems such as contradictory instructions, missing automation, documentation gaps, or repeatable tooling failures that are not caused by the repository under review.
- Do not file feedback issues for normal PR findings, target-repository bugs, or expected wait states such as `WAITING_FOR_EXTERNAL_REVIEW`.
- Do not include usernames, emails, tokens, machine names, or absolute local paths in feedback issues.
- Prefer safe technical diagnostics such as failing command, exit code, status, `reason_code`, `waiting_on`, `run_id`, and skill version.
- For PR-scoped feedback, always provide `--using-repo` and `--using-pr` so the issue body names the repository and pull request under review. If they are omitted, `submit_feedback.py` will try to infer them from `--source-command` or `--failing-command`, but explicit values are preferred.
- When `--using-repo` and `--using-pr` are provided, the helper auto-collects the latest local evidence from the PR workspace when available:
  - `last-machine-summary.json`
  - `session.json`
  - `audit_summary.md`
  - cached PR head SHA from `github_pr_cache.json`
- The helper deduplicates repeated reports by fingerprint and skips creating a new issue when the same feedback issue is already open or was closed recently within the cooldown window.
- The repository issue format lives in `.github/ISSUE_TEMPLATE/ai-agent-feedback.md`.
- Repository-root helper command:

```bash
gh-address-cr submit-feedback \
  --category workflow-gap \
  --title "blocked without a recovery step" \
  --summary "review stopped in a blocked state without enough operator guidance." \
  --expected "the skill should identify the next command or artifact to inspect." \
  --actual "the workflow stopped and the next action was ambiguous." \
  --source-command "gh-address-cr review owner/repo 123" \
  --failing-command "gh-address-cr final-gate owner/repo 123" \
  --exit-code 5 \
  --status BLOCKED \
  --reason-code WAITING_FOR_FIX \
  --waiting-on human_fix \
  --run-id cr-loop-20260417T120000Z \
  --skill-version 1.2.0 \
  --using-repo owner/repo \
  --using-pr 123 \
  --artifact /tmp/loop-request.json
```

- Unified CLI passthrough:

```bash
gh-address-cr submit-feedback --category workflow-gap --title "..." --summary "..." --expected "..." --actual "..."
```

## Choosing Fixes

`gh-address-cr` is not "fix every comment immediately". The intended workflow is:

1. verify the claim in current HEAD
2. classify it as `fix`, `clarify`, `defer`, or `reject`
3. only modify code after the item is confirmed and in scope

Use these defaults:

- `fix`
  - correctness bugs
  - session/gate/loop mismatches
  - concurrency or state hazards
  - CLI or wrapper compatibility regressions
  - packaging/runtime/CI breakage
- `clarify`
  - reviewer misunderstood current behavior
- `defer`
  - issue is real but would expand the PR into a larger redesign
- `reject`
  - suggestion is technically incorrect or would violate an intentional contract

Do not stretch the PR just to silence a thread. If the item is valid but not appropriate for the current scope, defer it with a concrete rationale.

## Advanced / Developer Integration

The public user flow above does not require manual `--input`, producer selection, or mode routing.
The following commands remain available for explicit integrations, repository-root automation, and debugging.

`findings --sync` requires an explicit `--source` so missing local findings stay scoped to one producer.

For explicit automation or repository-root invocation, the main command is:

```bash
gh-address-cr active-pr [--repo <owner/repo>] [--head <branch>]
gh-address-cr review <owner/repo> <pr_number> [--input <path>|-] [--human]
gh-address-cr address <owner/repo> <pr_number> [--human|--lean]
```

For `producer=code-review`, generate the standardized bridge prompt with:

```bash
gh-address-cr prepare-code-review <local|mixed> <owner/repo> <pr_number>
```

This does not run another skill by itself. It emits the exact findings contract and ingest target so a local review producer can feed `gh-address-cr` without prompt drift.

If the upstream review output is Markdown review blocks, convert it first with:

```bash
gh-address-cr review-to-findings <owner/repo> <pr_number> --input -
```

The converter writes the standardized findings JSON to the cache-backed PR workspace by default and also prints the JSON to stdout.

Advanced CLI examples:

```text
$gh-address-cr address <PR_URL> --lean
$gh-address-cr review --auto-simple <PR_URL>
$gh-address-cr threads <PR_URL> --lean
$gh-address-cr findings <PR_URL> --input findings.json
$gh-address-cr findings <PR_URL> --input - --sync
$gh-address-cr adapter <PR_URL> <adapter_cmd...>
$gh-address-cr review-to-findings <owner/repo> <pr_number> --input -
$gh-address-cr --human adapter <owner/repo> <pr_number> <adapter_cmd...>
$gh-address-cr adapter <owner/repo> <pr_number> <adapter_cmd...> --human --machine
```

For `adapter`, the last two examples mean different things:

- `$gh-address-cr --human adapter ...`
  - switches the wrapper output to human-oriented text
- `$gh-address-cr adapter ... --human --machine`
  - passes `--human --machine` to the adapter command itself
  - it does not change the wrapper output mode

`code-review` intake is now adapter-backed. Once you have structured findings JSON, the intake layer routes it through the built-in adapter instead of maintaining a separate special-case ingest path.

Use the prompt patterns above as the canonical templates. Do not keep a second, shorter variant with weaker rules.

If you omit the producer where it is required:

- `local` and `mixed` will fail because the dispatcher cannot infer whether you mean `json`, `code-review`, or `adapter`
- `ingest` will assume `json`
- `remote` does not accept a producer at all

## Automatic Review Workflow

`review` is the autonomous runner built on top of the existing intake and gate layers.

- It performs repeated intake, item selection, action execution, and gate evaluation internally.
- By default it uses an internal fixer handoff for the current AI agent.
- If a finding cannot be resolved automatically, the workflow writes an internal fixer request artifact into the PR cache artifacts directory and exits `BLOCKED` for the agent to handle.
- `--fixer-cmd` remains available as an advanced integration path.
- External fixer commands must read a JSON payload from stdin and return JSON:
  - `resolution`: `fix`, `clarify`, or `defer`
  - `note`
  - for GitHub thread `fix`: `fix_reply`
    - `summary`
    - `commit_hash`
    - `files`
    - optional `severity`, `why`, `test_command`, `test_result`
    - `validation_commands` may be used as default validation evidence when `test_command` / `test_result` are omitted
  - for GitHub thread `clarify` or `defer`: `reply_markdown`
  - optional `validation_commands`
- `adapter` producer is re-run on each iteration.
- `json` and `code-review` producers are treated as one-shot inputs for the current review run.
- The workflow exits with one of:
  - `PASSED`
  - `NEEDS_HUMAN`
  - `BLOCKED`

Advanced external-fixer example:

```bash
gh-address-cr adapter owner/repo 123 python3 tools/review_adapter.py
```

By default, the skill stores its PR progress + audit artifacts in a user cache directory
(override with `GH_ADDRESS_CR_STATE_DIR`). If the cache is purged, the workflow can be rebuilt
from GitHub thread state; the main downside is potential repeated work.

Advanced producer categories:

- `code-review`
- `json`
- `adapter`

Producer naming rule:

- `code-review` is a producer category, not a hardcoded skill name.
- It can be backed by `/code-review`, `/code-review-aa`, `/code-review-bb`, `/code-review-cc`, or any other review step that emits structured findings JSON.
- `gh-address-cr` only cares about the findings contract, not the upstream tool name.

Producer selection rule:

- `remote`
  - no producer is needed
- `ingest`
  - producer may be omitted; default is `json`
- `local` or `mixed`
  - producer must be explicit

Use this mapping:

| Upstream situation | Producer to use |
| --- | --- |
| Only GitHub review threads | none (`remote`) |
| Existing findings JSON file | `json` |
| A review-style skill/command emits findings JSON first | `code-review` |
| A command directly prints findings JSON as its interface | `adapter` |

Important:

- `producer=code-review` is the category even if the upstream tool is named `/code-review-aa` or `/code-review-bb`.
- Do not put the upstream tool name itself into the producer slot.
- Example:
  - correct: `review <owner/repo> <pr>`
  - incorrect: `code-review-aa <owner/repo> <pr>`

Meaning:

- `remote`
  - only GitHub review threads are part of the session
- `local`
  - only locally produced findings are part of the session
- `mixed`
  - GitHub review threads and local findings are both part of the session
- `ingest`
  - import existing findings JSON into the session without running a local adapter

This keeps `gh-address-cr` as the session/gate/orchestration layer while letting different review producers feed findings into the same PR workflow.

The exact dispatch behavior for each supported `mode + producer` combination is documented in:

- `skill/references/mode-producer-matrix.md`

The preferred automation entrypoint is now:

```bash
gh-address-cr review <owner/repo> <pr_number> [--input <path>|-] [--human]
```

## Core Workflow

```text
       [ Start PR Review Session ]
                   |
                   v
+-------------------------------------+      (Fetch PR threads, exclude handled)
|          1. gh-address-cr run-once             | <-----------------------------------------+
+------------------+------------------+                                           |
                   |                                                              |
                   v [Generates Snapshot, Syncs Session, Lists Work]              |
                   |                                                              |
+------------------+------------------+      (THE "BRAIN" STEP: Analyze & Decide) |
|    2. Analysis & Decision Matrix    |                                           |
+------------------+------------------+                                           |
                   |                                                              |
         +---------+---------+-----------------------+                            |
         |                   |                       |                            |
    [ ACCEPT ]          [ CLARIFY ]             [ DEFER ]                         |
   (Bug/Logic)        (Misunderstood)       (High-cost Nit)                       |
         |                   |                       |                            |
         v                   v                       v                            |
+--------+--------+ +--------+--------+     +--------+--------+                   |
| 3a. Change Code | | 3b. Explain     |     | 3c. Explain     |                   |
|     & Test      | |     Logic       |     |     Trade-offs  |                   |
+--------+--------+ +--------+--------+     +--------+--------+                   |
         |                   |                       |                            |
         v                   v                       v                            |
+--------+--------+ +--------+--------+     +--------+--------+                   |
| 4a. generate_   | | 4b. generate_   |     | 4c. generate_   |                   |
|    reply     | |    reply     |     |    reply     |                   |
|    --mode fix   | |  --mode clarify |     |   --mode defer  |                   |
+--------+--------+ +--------+--------+     +--------+--------+                   |
         |                   |                       |                            |
         +---------+---------+-----------------------+                            |
                   |                                                              |
                   v [Generates reply markdown in the PR workspace]               |
                   |                                                              |
+------------------+------------------+      (GitHub API: Reply)                  |
|         5. gh-address-cr post-reply            |                                           |
+------------------+------------------+                                           |
                   |                                                              |
+------------------+------------------+      (MANDATORY for all paths)            |
|       6. gh-address-cr resolve-thread          |      (Local state marked 'Handled')       |
+------------------+------------------+                                           |
                   |                                                              |
+------------------+------------------+      (HARD GATE: Re-fetch GitHub state)   |
|         7. gh-address-cr final-gate            |-------------------------------------------+
+------------------+------------------+      [ Failed: Unresolved > 0 (Loop back) ]
                   |
                   | [ Passed: Unresolved == 0 ]
                   v
+-------------------------------------+
|         8. Audit Summary            |      (Output SHA256 & Final Confirmation)
+-------------------------------------+
                   |
                   v
               [ Done ]
```

## PR Session Architecture

`gh-address-cr` now ships the session engine through the runtime package and exposes it through `gh-address-cr session-engine ...`.

The implementation model is now:

- Python owns the stateful logic and GitHub/local-review orchestration.
- `gh-address-cr` is the only stable automation entrypoint for runtime work.
- `skill/scripts/cli.py` remains a compatibility shim for installed skill payloads.
- Tests are organized around Python behavior first, then CLI syntax compatibility.

- `github_thread` items are synced from GraphQL thread snapshots.
- `local_finding` items are ingested from a local review adapter.
- local findings can now be explicitly closed in-session with `gh-address-cr session-engine close-item`.
- `gh-address-cr final-gate` evaluates both:
  - session blocking item count
  - unresolved GitHub thread count
  - terminal GitHub thread reply-evidence count
  - current-login pending review count
  - optional PR checks when `--require-checks` or `--require-required-checks` is supplied

The session state is stored in a PR-scoped workspace under the user cache directory:

- workspace: `<owner>__<repo>/pr-<pr>/`
- session: `session.json`
- GitHub snapshots: `threads.jsonl`
- handled threads: `handled_threads.txt`
- audit log: `audit.jsonl`
- trace log: `trace.jsonl`
- audit summary: `audit_summary.md`
- findings: `findings-*.json` and `code-review-findings.json`
- replies: `reply-*.md`
- loop requests: `loop-request-*.json`
- validation records: `validation-*.json`

If `gh-address-cr final-gate --auto-clean` passes, the current PR workspace is archived before deletion under:

- archive root: `archive/<owner>__<repo>/pr-<pr>/<run_id>/`

To inspect one run after the fact, use:

```bash
gh-address-cr audit-report --run-id <run_id> <owner/repo> <pr_number>
```

The session also tracks loop-safety metadata per item:

- `repeat_count`: how many times the same local finding was re-ingested
- `reopen_count`: how many times a previously closed/deferred/clarified item was reopened
- claim lease fields so stale ownership can be reclaimed

## Optional Telemetry Export

Local audit files remain the canonical repository contract:

- `audit.jsonl`
- `trace.jsonl`
- `audit_summary.md`

The distributed CLI now ships with a zero-config hosted relay endpoint:

- `https://gh-address-cr.hamiltonsnow.workers.dev/v1/logs`

By default, each audit/trace event is also emitted as an OTLP/HTTP JSON `logs` record to that Cloudflare Worker.

Recommended deployment shape:

- CLI client
- Cloudflare Worker as the security relay
- Better Stack as the backend

This keeps the Better Stack source token out of the CLI runtime while preserving local audit artifacts for `audit-report`, archive, and tests. End users do not need to set telemetry environment variables for the hosted path.

Repository-root reference docs:

- setup guide: `skill/references/otel-worker-better-stack.md`
- Worker example: `skill/references/otel-worker-better-stack/worker.mjs`
- Wrangler example: `skill/references/otel-worker-better-stack/wrangler.example.jsonc`

For self-hosting or explicit override, CLI-side OpenTelemetry configuration still supports standard env vars:

```bash
export OTEL_SERVICE_NAME="gh-address-cr-cli"
export OTEL_RESOURCE_ATTRIBUTES="deployment.environment=personal,service.namespace=skills"
export OTEL_EXPORTER_OTLP_ENDPOINT="https://gh-address-cr-telemetry.example.workers.dev"
export OTEL_EXPORTER_OTLP_PROTOCOL="http/json"
```

Notes:

- `OTEL_EXPORTER_OTLP_ENDPOINT` is treated as a base URL, so `/v1/logs` is appended automatically
- `OTEL_EXPORTER_OTLP_LOGS_ENDPOINT` may be used instead when you want an exact logs endpoint
- local audit files are still written even if telemetry export is disabled or fails
- export failures are recorded locally as `telemetry_export` diagnostics in `trace.jsonl`

## Local AI Review Ingestion

Use `gh-address-cr run-local-review` to feed local AI findings into the PR session:

```bash
gh-address-cr run-local-review --source local-agent:codex owner/repo 123 ./adapter.sh --base main --head HEAD
```

Adapter contract:

- adapter prints a JSON array to stdout
- each finding should include `title`, `body`, `path`, `line`
- optional fields: `severity`, `category`, `confidence`

This path does not auto-post to GitHub. It creates local session items that can be fixed and verified in the same workflow as remote review threads.

If the producer is a local `code-review` run, use the built-in adapter backend:

```bash
gh-address-cr prepare-code-review mixed owner/repo 123
cat findings.json | gh-address-cr review owner/repo 123 --input -
```

Input rule:

- if you already have a real findings JSON file from another tool, use `--input <path>`
- if findings are being produced in the current step, prefer `--input -` and pipe them over `stdin`
- do not create ad-hoc temporary findings files in the project workspace just to drive the workflow
- use `--sync` when you want missing local findings from the same source to auto-close on refresh

`prepare-code-review` now also returns:

- `workspace_dir`
- `findings_output_path`
- `reply_output_path`
- `loop_request_path`

Use that cache-backed findings path instead of creating review artifacts in the project workspace.

If your review tool already produces findings JSON, you do not need a custom adapter command. Use `gh-address-cr ingest-findings` instead:

```bash
cat findings.json | gh-address-cr ingest-findings --source local-agent:code-review owner/repo 123
```

Accepted input shapes:

- JSON array of finding objects
- JSON object with `findings`, `issues`, or `results`
- NDJSON, one finding object per line

Field normalization is intentionally broad so external tools can map in without a custom schema bridge:

- `path` or `file` or `filename`
- `line` or `start_line` or `position`
- `title` or `rule` or `check`
- `body` or `message` or `description`

Minimum accepted finding shape:

```json
[
  {
    "title": "Missing null guard",
    "body": "Potential null dereference.",
    "path": "src/example.py",
    "line": 12
  }
]
```

This is the long-term integration path for any local code-review tool. If it can emit structured findings JSON, `gh-address-cr` can ingest it into the PR session.

To publish a local finding back to GitHub as a review comment:

```bash
gh-address-cr publish-finding --repo owner/repo --pr 123 local-finding:<fingerprint>
```

To reclaim expired item claims inside a PR session:

```bash
gh-address-cr session-engine reclaim-stale-claims owner/repo 123
```

To apply a terminal local finding resolution atomically, use:

```bash
gh-address-cr session-engine resolve-local-item owner/repo 123 local-finding:<fingerprint> fix --note "Fixed locally and verified."
gh-address-cr session-engine resolve-local-item owner/repo 123 local-finding:<fingerprint> clarify --note "Expected behavior."
gh-address-cr session-engine resolve-local-item owner/repo 123 local-finding:<fingerprint> defer --note "Deferred to a follow-up PR."
```

## Runtime Package Layout

The main logic lives in the Python runtime package under `src/gh_address_cr/`.

- `cli.py`: console entrypoint and runtime command dispatch
- `core/`: session state, workflow transitions, final-gate, and orchestration helpers
- `github/`: GitHub CLI IO and failure diagnostics
- `intake/`: findings parsing and normalization
- `legacy_scripts/`: compatibility surfaces for older direct script invocations

The packaged `skill/scripts/` folder remains in the installed skill payload for compatibility checks and helper shims. New automation should use `gh-address-cr`, not direct `python3 skill/scripts/*.py` paths.

The runtime package requires Python 3.10+ because the implementation uses modern typing syntax such as `list[str]` and `str | None`.

The `gh-address-cr` console script is the stable automation surface. The packaged `skill/scripts/cli.py` path is compatibility-only.

Unified CLI examples:

```bash
gh-address-cr run-once owner/repo 123
gh-address-cr final-gate --no-auto-clean owner/repo 123
gh-address-cr session-engine gate owner/repo 123
gh-address-cr ingest-findings --source local-agent:code-review owner/repo 123 --input findings.json
gh-address-cr review owner/repo 123 --input -
gh-address-cr findings owner/repo 123 --input -
gh-address-cr session-engine resolve-local-item owner/repo 123 local-finding:<fingerprint> fix --note "Fixed locally."
```

## Testing

Run the current automated checks with:

```bash
python3 -m unittest discover -s tests
gh-address-cr --help
gh-address-cr cr-loop --help
```

Current test layout:

- `tests/test_session_engine_cli.py`
  - PR session state machine and gate behavior
- `tests/test_python_wrappers.py`
  - Python entrypoints for GitHub/local-review flows
- `tests/test_aux_scripts.py`
  - helper scripts such as reply generation, batch resolve, and state cleanup
- `tests/helpers.py`
  - shared test harness

## Install with npx skills

```bash
npx skills add https://github.com/RbBtSn0w/gh-address-cr --skill skill
```

## Breaking changes (2026-04-09)

- `gh-address-cr batch-resolve` now requires an approved list format:
  - one thread per line: `APPROVED <thread_id>`
  - empty lines and `#` comments are allowed
  - raw thread-id lines now fail fast
- `gh-address-cr list-threads` now uses the latest thread comment as primary context and emits:
  - `comment_source` (`latest|first|none`)
  - `first_url`, `latest_url`
  - `url`/`body` remain available, now latest-first with fallback

## Update model (official `skills` behavior)

`npx skills update` is driven by the lock file and remote folder hash, not by git tag directly.

- Lock file name: `.skill-lock.json`
- Typical path: `~/.agents/.skill-lock.json`
- Optional path when `XDG_STATE_HOME` is set: `$XDG_STATE_HOME/skills/.skill-lock.json`
- Update comparison key: `skills.<skill-name>.skillFolderHash` (GitHub tree SHA of the skill folder)

### User-side update commands

```bash
# Check whether updates are available
npx skills check

# Update installed skills
npx skills update
```

### Provider-side release policy

- Keep skill identifier stable:
  - `SKILL.md` frontmatter `name` should stay stable
  - skill folder path should stay stable
  - source repo (`owner/repo`) should stay stable
- Publish all releasable changes to `main` so `skillFolderHash` can change and be detected by `check/update`.
- Use semantic version tags + changelog for human-readable release management.

## What this skill provides

- PR-scoped session state for GitHub threads and local findings
- Strict per-item CR handling workflow
- Required evidence format (commit/files/test result)
- Mandatory final gate (`gh-address-cr final-gate`) before completion
- Session-scoped state tracking to avoid duplicate work
- Audit log + trace log + audit summary + summary hash output
- Audit summaries and `final-gate` output preserve machine-readable gate counts and summary hashes for evidence
- Python-first implementation with a single CLI entrypoint
- Module-split automated tests for session, wrappers, and helper scripts

## Repository Layout Model

This git repository is the development and release wrapper around one shipped skill.

- Published skill payload: the entire `skill/` directory
- Repo-level verification harness: `tests/`
- Repo-level release and contributor files: `.github/`, `pyproject.toml`, `CHANGELOG.md`, root `AGENTS.md`, and other top-level metadata

Path convention:

- Repo-level docs and commands that execute runtime workflows use `gh-address-cr`
- Skill-owned docs inside `skill/` use paths relative to the skill root, such as `scripts/cli.py`, `references/...`, and `agents/openai.yaml`

If a rule or instruction must ship with the installed skill, it must live inside `skill/`, not only at repository root.

## Skill folder

- `skill/`
  - `SKILL.md`
  - `agents/openai.yaml`
  - `scripts/*.py`
  - `scripts/cli.py` (compatibility shim)
  - `assets/reply-templates/*`
  - `references/cr-triage-checklist.md`

## Quick usage after installation

```bash
gh-address-cr run-once --audit-id run-YYYYMMDD owner/repo 123
gh-address-cr run-local-review --source local-agent:codex owner/repo 123 ./adapter.sh
gh-address-cr post-reply --repo owner/repo --pr 123 --audit-id run-YYYYMMDD <thread_id> "$GH_ADDRESS_CR_STATE_DIR/owner__repo/pr-123/reply.md"
gh-address-cr resolve-thread --repo owner/repo --pr 123 --audit-id run-YYYYMMDD <thread_id>
gh-address-cr submit-action <loop_request_path> --resolution fix --note "Fixed it" -- <resume_command>
gh-address-cr submit-action <action-request.json> --agent-id codex-fixer-1 --resolution fix --note "Fixed it" --files src/example.py --validation-cmd "python3 -m unittest tests.test_example=passed"
gh-address-cr final-gate --auto-clean --audit-id run-YYYYMMDD owner/repo 123
```

## Operating Modes

This skill supports several distinct operating modes. The session model is the same in all of them, but the required commands differ.

### Mode 1: GitHub Thread Only

Use this when the PR already has remote review threads and there is no local AI review input.

Example:

```bash
gh-address-cr run-once --audit-id run-20260412 owner/repo 123

# inspect one unresolved GitHub thread
gh-address-cr generate-reply --mode fix --severity P2 "$GH_ADDRESS_CR_STATE_DIR/owner__repo/pr-123/reply.md" abc123 "src/app.py" "python3 -m unittest" "passed" "Added the missing guard."
gh-address-cr post-reply --repo owner/repo --pr 123 --audit-id run-20260412 THREAD_ID "$GH_ADDRESS_CR_STATE_DIR/owner__repo/pr-123/reply.md"
gh-address-cr resolve-thread --repo owner/repo --pr 123 --audit-id run-20260412 THREAD_ID

gh-address-cr final-gate --auto-clean --audit-id run-20260412 owner/repo 123
```

Rules:

- GitHub thread items require both `gh-address-cr post-reply` and `gh-address-cr resolve-thread`
- `gh-address-cr resolve-thread` rejects silent resolve attempts when reply evidence is missing
- outdated / `STALE` GitHub threads still count as unresolved until explicitly handled
- `gh-address-cr final-gate` must pass before completion and now fails if a terminal GitHub thread has no reply evidence

### Mode 2: GitHub Thread Clarify / Defer

Use this when the review comment is not accepted as a code change and you need to respond with rationale.

Clarify example:

```bash
gh-address-cr generate-reply --mode clarify "$GH_ADDRESS_CR_STATE_DIR/owner__repo/pr-123/reply.md" "The current control flow is intentional because initialization must stay lazy."
gh-address-cr post-reply --repo owner/repo --pr 123 --audit-id run-20260412 THREAD_ID "$GH_ADDRESS_CR_STATE_DIR/owner__repo/pr-123/reply.md"
gh-address-cr resolve-thread --repo owner/repo --pr 123 --audit-id run-20260412 THREAD_ID
```

Defer example:

```bash
gh-address-cr generate-reply --mode defer "$GH_ADDRESS_CR_STATE_DIR/owner__repo/pr-123/reply.md" "This requires broader refactoring and is deferred to a follow-up PR."
gh-address-cr post-reply --repo owner/repo --pr 123 --audit-id run-20260412 THREAD_ID "$GH_ADDRESS_CR_STATE_DIR/owner__repo/pr-123/reply.md"
gh-address-cr resolve-thread --repo owner/repo --pr 123 --audit-id run-20260412 THREAD_ID
```

Rules:

- even without code changes, GitHub thread items still require reply plus resolve
- defer/clarify should carry rationale, not just a status change
- low-level resolve paths are intentionally blocked until reply evidence exists in the session or the same action posts a fresh reply

### Mode 3: Local Finding Only

Use this when you want to run local AI review without waiting for GitHub or Copilot review comments.

Example:

```bash
gh-address-cr run-local-review --source local-agent:codex owner/repo 123 ./adapter.sh

gh-address-cr session-engine list-items owner/repo 123 --item-kind local_finding --status OPEN
gh-address-cr session-engine update-item owner/repo 123 local-finding:FINGERPRINT ACCEPTED --note "Confirmed locally."
gh-address-cr session-engine update-item owner/repo 123 local-finding:FINGERPRINT FIXED --note "Implemented fix."
gh-address-cr session-engine update-item owner/repo 123 local-finding:FINGERPRINT VERIFIED --note "Validated with targeted tests."
gh-address-cr session-engine close-item owner/repo 123 local-finding:FINGERPRINT --note "Closed after local validation."

gh-address-cr final-gate --no-auto-clean --audit-id run-20260412 owner/repo 123
```

Rules:

- local findings do not require GitHub reply/resolve unless you choose to publish them
- they still participate in the same session gate
- terminal local-item transitions require `--note`

### Mode 4: Mixed Session

Use this when the PR has both remote GitHub threads and local AI findings.

Example:

```bash
gh-address-cr run-once --audit-id run-20260412 owner/repo 123
gh-address-cr run-local-review --source local-agent:codex owner/repo 123 ./adapter.sh

# process GitHub items with reply + resolve
# process local items through gh-address-cr session-engine transitions

gh-address-cr final-gate --no-auto-clean --audit-id run-20260412 owner/repo 123
```

Rules:

- GitHub items need reply plus resolve
- local items need valid state transitions and notes
- the PR is not clear until both session blocking count and unresolved GitHub thread count are zero

### Mode 5: Publish Local Finding Back To GitHub

Use this when a locally discovered issue should become visible in the GitHub PR discussion.

Example:

```bash
gh-address-cr run-local-review --source local-agent:codex owner/repo 123 ./adapter.sh
gh-address-cr session-engine list-items owner/repo 123 --item-kind local_finding --status OPEN

gh-address-cr publish-finding --repo owner/repo --pr 123 local-finding:FINGERPRINT
gh-address-cr run-once --audit-id run-20260412 owner/repo 123
```

What happens:

- the local finding is published as a GitHub review comment
- later GitHub sync can associate the local finding with the resulting thread
- from that point onward, the issue can be handled like a normal GitHub review item

### Mode 6: Direct Session Engine / Unified CLI

Use this when you need low-level session control or when integrating the skill into other automation.

Examples:

```bash
gh-address-cr run-once owner/repo 123
gh-address-cr final-gate --no-auto-clean owner/repo 123
gh-address-cr session-engine list-items owner/repo 123 --item-kind local_finding
gh-address-cr session-engine reclaim-stale-claims owner/repo 123
```

Rules:

- `gh-address-cr` is the preferred and stable automation entrypoint
- `skill/scripts/cli.py` remains compatibility-only for installed skill payloads
- low-level resolve helpers are stricter than before: `resolve-thread` and batch resolve flows refuse resolve-only handling when reply evidence is absent

## Troubleshooting final gate failure

If `gh-address-cr final-gate` fails:

1. Read the pending table in terminal output and the printed audit summary path.
2. Prefer the returned `next_action` and `commands` templates; common recovery starts with `gh-address-cr address <owner/repo> <pr_number> --lean` or `gh-address-cr agent publish <owner/repo> <pr_number>`.
3. For each pending or invalid terminal thread, verify both operations were completed through the runtime: reply evidence and thread resolve.
4. For file-matched stale threads, use `gh-address-cr agent resolve-stale <owner/repo> <pr_number> --commit <sha> --files <paths> --validation <cmd=passed> --match-files`, then publish and rerun final-gate.
5. If the summary reports missing reply evidence, publish the accepted evidence before re-running `gh-address-cr final-gate`.

## Troubleshooting installation and release

- Unsupported Python: use Python 3.10 or newer through `pipx`, `uv tool`, or a local virtual environment.
- Missing PyPI package: `gh-address-cr` may not have been published yet. Use the GitHub-direct runtime validation install for pre-release validation.
- Missing Trusted Publishing: production PyPI publishing must use GitHub OIDC with the PyPI project `gh-address-cr`, repository `RbBtSn0w/gh-address-cr`, workflow `.github/workflows/release.yml`, no GitHub environment constraint, and `id-token: write`.
- Missing Homebrew tap token: production Homebrew publishing requires `HOMEBREW_TAP_TOKEN`, a fine-grained GitHub token with `contents: write` access to `RbBtSn0w/homebrew-tap`.
- Stale artifact version: release-built wheel and sdist metadata must match the semantic-release version. If a publish partially succeeds, inspect PyPI before retrying because uploaded files are immutable.
- Homebrew tap update failure: inspect the `publish-homebrew` job after confirming PyPI upload succeeded. The job renders `Formula/gh-address-cr.rb` from the PyPI sdist, runs `brew update-python-resources`, `brew audit --formula --strict`, `brew install --build-from-source`, and `brew test` before pushing the tap update.
- Installed smoke domain failure: `agent orchestrate status` may report a missing session and `final-gate` may report `Final gate failed to evaluate: error connecting to api.github.com` when GitHub state or network access is unavailable. These are acceptable smoke outcomes only when there is no traceback, missing import, or missing console entrypoint.
- Skill install confusion: `npx skills add ... --skill skill` installs the packaged skill adapter only. It does not install the runtime CLI package.
- Skill-shim migration confusion: if `python3 skill/scripts/cli.py` works from a checkout but `gh-address-cr` is unavailable, install or reinstall the runtime CLI with `pipx` or `uv tool`.

## CI semantic release (tag + changelog)

This repo includes a `semantic-release` workflow:

- Trigger: push to `main`
- Input: Conventional Commits history
- Output: semantic version tag (`vX.Y.Z`) + GitHub Release + `CHANGELOG.md`
- Python package release: `pyproject.toml` and `src/gh_address_cr/__init__.py` are synchronized to the semantic-release version before wheel/sdist build.
- Stable Python package registry: PyPI remains the authoritative Python runtime package registry.
- Homebrew tap: production PyPI releases update `RbBtSn0w/homebrew-tap` after the PyPI sdist is available. Homebrew is the documented macOS/Linuxbrew CLI installation channel.
- GitHub Releases remain release-note, tag, source-archive, and optional provenance surfaces; they are not the primary Python package registry.
- Dry-run/staging validation: use the `workflow_dispatch` `dry-run` or `testpypi` target before enabling production PyPI publishing. These targets build the package and render a local-sdist Homebrew formula but do not write the tap.
- Production PyPI publishing: requires PyPI Trusted Publishing and package-name ownership. It runs without a GitHub deployment environment approval gate; do not use long-lived PyPI API tokens unless a separate explicit release-policy change approves that fallback.
- Production Homebrew publishing: requires `HOMEBREW_TAP_TOKEN` with write access to `RbBtSn0w/homebrew-tap`. The workflow validates the formula with `brew update-python-resources`, `brew audit --formula --strict`, source install, and `brew test` before pushing.
- No-release runs: if semantic-release finds no qualifying commit and does not create a tag, PyPI and Homebrew publishing both skip explicitly.
- Failed or partial publish recovery: inspect the PyPI project state and release artifacts before retrying; immutable package files may require a follow-up semantic-release version.

Commit format examples:

```text
feat: add strict unresolved-thread guard in final gate
fix: avoid duplicate handled-state writes when thread already resolved
docs: clarify npx skills update behavior
```
