Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
119 changes: 36 additions & 83 deletions .agents/skills/ship-pr/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,84 +12,46 @@ One session worktree, one topic branch per plan, many small commits (each
already passed local CI except coverage), required checks green. A plan is
not done until those checks are green. Do not merge unless asked.

Owner facts for tests and coverage stay in [`TESTING.md`](../../../TESTING.md).
Do not copy them here.
When to run which command:
[`docs/how-we-plan.md`](../../../docs/how-we-plan.md#agent-contract).
Suite and budgets: [`TESTING.md`](../../../TESTING.md).
Do not copy those facts here.

## Session worktree

Reuse one worktree per session. Do not add a worktree per PR.

`rearden-grok[bot]` on this operator VM: silo, editor tree, ENOSPC, identity,
and HTTPS push are [`rearden-vm-HOST.md`](../../../rearden-vm-HOST.md). If
you are not that identity, ignore that file; use `$PWD/target/dev`.

```bash
# once per session
git fetch origin
git worktree add /tmp/rbtc-<session> origin/master
cd /tmp/rbtc-<session>
git switch -c <area>/<short-name>
export CARGO_TARGET_DIR="${CARGO_TARGET_DIR:-$PWD/target/dev}"

# next PR in the same session (do not add another worktree)
git fetch origin
git switch -C <area>/<next-short> origin/master
```

| Rule | Detail |
|------|--------|
| Base | Current `origin/master` (or `main`) |
| Branch | Topic name. Never commit the plan onto `master` |
| Worktree | One `/tmp/rbtc-<session>` for the session |
| `CARGO_TARGET_DIR` | `$PWD/target/dev` unless already set. `rearden-grok[bot]`: [`rearden-vm-HOST.md`](../../../rearden-vm-HOST.md) |
| Remotes | Worktrees share `origin`. Never `git remote set-url origin` |

### After merge
One `/tmp/rbtc-<session>` for the session. The next PR is `git switch -C`
from current `origin/master`, not another worktree. Never commit the plan
onto `master`. Worktrees share `origin`. Never `git remote set-url origin`.

Delete the topic branch only. Keep the session worktree until the session ends.
Do not delete a branch that still has an open PR. Do not `git push --delete master`.
`rearden-grok[bot]`: silo, identity, HTTPS `HEAD:<branch>` push, and session
end are [`rearden-vm-HOST.md`](../../../rearden-vm-HOST.md). If you are not
that identity, ignore that file. Use `$PWD/target/dev` and push the topic
branch with ordinary `git push`.

```bash
git fetch origin --prune
git switch -C <area>/<next-short> origin/master
git branch -d <area>/<merged-short>
# rearden-grok[bot]: delete the topic branch over HTTPS (rearden-vm-HOST.md)
```

```bash
# session end
git worktree remove /tmp/rbtc-<session>
git fetch origin --prune
```

`rearden-grok[bot]` session-end extras (test dirs, shared silo):
[`rearden-vm-HOST.md`](../../../rearden-vm-HOST.md). Other identities:
ignore that file.
After merge, delete the topic branch only. Keep the session worktree until
the session ends. Do not delete a branch that still has an open PR. Do not
`git push --delete master`.

## Local tests

From `nix-shell` (CI pins rustc 1.95.0). `CARGO_TARGET_DIR` as in Session
worktree. Same **commands** as the required jobs, not the GitHub Actions
`env:`
(leave `CARGO_INCREMENTAL` unset; that is [`ci.yml`](../../../.github/workflows/ci.yml) only).
When to run which command:
[`docs/how-we-plan.md`](../../../docs/how-we-plan.md) (The cycle).
Suite and budgets: [`TESTING.md`](../../../TESTING.md).
`env:` (leave `CARGO_INCREMENTAL` unset; that is
[`ci.yml`](../../../.github/workflows/ci.yml) only).

| When | Run |
|------|-----|
| Inner loop (Red / Green) | Targeted `cargo test -p <crate> … -- --quiet`. `cargo check -p <crate> --lib`. Not `--tests` after every edit |
| After Green | `cargo test --workspace --quiet` |
| After Refactor, before commit | Local CI except coverage (below) |
| Docs, comments, formatting only | Skip the suite. `cargo fmt` if rustfmt would touch the tree |
| Core functional CI red | [core-functional skill](../core-functional/SKILL.md) |
| Overlay functional CI red | [overlay-functional skill](../overlay-functional/SKILL.md) |
| Never local | `./scripts/coverage.sh`, `nix build .#rbitcoin-musl`, host IBD |

Redirect every command above (stdout and stderr to `/tmp`, print `EXIT`,
search then tail on failure). Do not `tee` or `| tail` as the only sink,
and do not load the log wholesale. Recipe:
[`docs/how-we-plan.md`](../../../docs/how-we-plan.md) (Agent RAM). Do not
copy that snippet here.
Redirect every cargo, clippy, deny, and rustc command (stdout and stderr
to `/tmp`, print `EXIT`, search then tail on failure). Recipe:
[`docs/how-we-plan.md`](../../../docs/how-we-plan.md#agent-ram).

Local CI except coverage:

Expand All @@ -105,12 +67,10 @@ cargo test --workspace --quiet
If the slice changed `flake.nix`, `nix/`, or the NixOS module, also
`nix build .#checks.x86_64-linux.nixos-module-eval --no-link`. Label the PR
`nixos-module-runtime` when systemd deps, users/groups, firewall, or the VM
start argv changed — that runs `nixos-module-runtime` (qemu). Do not wait
out the VM test locally.
start argv changed. Do not wait out the VM test locally.

Coverage and native `windows` / `macos` stay GitHub Actions;
`ci-os-smoke.sh` is the local stand-in. Do not wait out a host IBD or a
coverage run in the agent VM.
`ci-os-smoke.sh` is the local stand-in.

## Push and poll

Expand All @@ -128,9 +88,7 @@ Label `nixos-module-runtime` when the NixOS module VM test should run (not
eval). Poll with `--interest nixos-module-runtime`. It is not a required
check.

`rearden-grok[bot]` fetch/push (`gh-login.sh`, HTTPS `HEAD:<branch>`, never
`git push origin`, no `-u`): [`rearden-vm-HOST.md`](../../../rearden-vm-HOST.md).
If you are not that identity, ignore that file.
Bot fetch and push: [`rearden-vm-HOST.md`](../../../rearden-vm-HOST.md).

```bash
gh pr create --repo reardencode/rbitcoin --head <area>/<short-name> --title "…" --body "…"
Expand All @@ -146,11 +104,10 @@ operator (`security_events` is read). An alert that only fires in `#[cfg(test)]`
or a test module: stop. Do not rename tests or shuffle literals. Ask the
operator to dismiss. Production CodeQL is a real finding — fix it.

**Fail-fast poll.** Do not use `gh pr checks --watch` as the only waiter. It
blocks until every check finishes, including slow `coverage` and CodeQL, even
after a job this change exercises is already red. `./scripts/pr-checks-watch.sh`
exits 1 as soon as any required job fails, and as soon as a `--interest` job
fails. On exit 1: stop polling, fetch that job’s log, and start the fix.
**Fail-fast poll.** `./scripts/pr-checks-watch.sh` exits 1 as soon as any
required job fails, and as soon as a `--interest` job fails. On exit 1:
stop polling, fetch that job’s log, and start the fix. `gh pr checks --watch`
waits out `coverage` and CodeQL after a job this change already failed.

```bash
gh api --allow-escape-sequences repos/reardencode/rbitcoin/actions/jobs/<job-id>/logs
Expand All @@ -159,14 +116,10 @@ gh run view <run-id> --repo reardencode/rbitcoin --job <job-id> --log-failed

**Unmergeable means tests do not run.** If `mergeable` is `CONFLICTING` or
`mergeStateStatus` is `DIRTY` (or `BEHIND` when the branch is not on current
`origin/master`), required `test` CI does not start. Rebase, lease-force the
topic branch, then poll. Do not `gh run rerun` to wake jobs that never queued.

```bash
git fetch origin
git rebase origin/master
# rearden-grok[bot]: lease-force over HTTPS (rearden-vm-HOST.md)
```
`origin/master`), required `test` CI does not start. Rebase onto
`origin/master`, lease-force the topic branch, then poll. Do not `gh run rerun`
to wake jobs that never queued. Bot lease-force:
[`rearden-vm-HOST.md`](../../../rearden-vm-HOST.md).

| Rule | Detail |
|------|--------|
Expand All @@ -185,16 +138,16 @@ When required checks are green locally and CI only needs a re-run:
|----|--------|
| `gh run rerun <id> [--failed]` | Empty commit whose only purpose is to wake Actions |
| GitHub Actions re-run failed or all jobs | Noise commits (`ci: bump`, `trigger`) |
| Amend the tip and `--force-with-lease` the topic branch over HTTPS | Force-push `master` / `main` |
| Amend the tip and `--force-with-lease` the topic branch | Force-push `master` / `main` |

```bash
gh run rerun <run-id> --failed

# If the API rejects: amend the tip (no empty commit) and lease-force the topic branch only
git commit --amend --no-edit
# rearden-grok[bot]: lease-force over HTTPS (rearden-vm-HOST.md)
```

If the API rejects, amend the tip (no empty commit) and lease-force the
topic branch only. Bot lease-force is
[`rearden-vm-HOST.md`](../../../rearden-vm-HOST.md).

If CI `coverage` fails, add a pin and push. Floor: [`TESTING.md`](../../../TESTING.md).

Operator musl binaries are [`docs/releases.md`](../../../docs/releases.md).
Expand Down
55 changes: 24 additions & 31 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
# Agent notes

Documentation map (one owner per fact): [`docs/README.md`](docs/README.md).
Before exploring, read [`docs/ORIENT.md`](docs/ORIENT.md).
This file is the harness-injected hard-rule contract. Design lives in the
owner docs; do not grow a second design book here.
When the task area is unclear, [`docs/ORIENT.md`](docs/ORIENT.md) routes.
Open the one row that matches the change. This file is the harness-injected
hard-rule contract. Design lives in the owner docs; do not grow a second
design book here.

Process playbooks are Agent Skills under [`.agents/skills/`](.agents/skills/).
Read the matching `SKILL.md` when the task needs it. Do not paste bash,
Expand All @@ -15,22 +16,27 @@ If you are acting as `rearden-grok[bot]`, also read
[`rearden-vm-HOST.md`](rearden-vm-HOST.md). If you are not that identity,
ignore that file.

## Language, comments, composition
## Language and shape

Write clear, concrete technical English. Keep Core-aligned terms where we
match Bitcoin Core. Do not inject moralizing or political framing, or soften
consensus and security language. If a rename is not clearer engineering, keep
the existing term.

Comments that restate what, why, or weird are a smell. Prefer names, types,
and structure. Keep `//` only for an invariant, protocol rule, `SAFETY`, or
library quirk. Crate and public rustdoc (`//!` / `///`) is not this rule.
Full text: [`CONTRIBUTING.md`](CONTRIBUTING.md) principle 7.

Prefer composition (has-a) over inheritance; avoid tall trees. Build
immutable structures once, then compose them. If a map needs extra fields,
wrap it on read rather than mutating members in place.
Control flow: principle 10 and [`docs/code-shape.md`](docs/code-shape.md).
Open [`CONTRIBUTING.md`](CONTRIBUTING.md) principles 7–11 and
[`docs/code-shape.md`](docs/code-shape.md) when editing Rust. Short form:

- `//` only for an invariant, protocol rule, `SAFETY`, or library quirk.
Crate and public rustdoc (`//!` / `///`) is not this rule (principle 7).
- Tests assert shipped behavior, not repo text. No `*_for_test` backdoors.
IO pins use session or table stats or on-disk state (principle 8).
- A RAM or CPU trade is named (principle 9).
- Control flow and composition: principle 10 and `docs/code-shape.md`.
- Crate `pub` is the cross-crate graph only. No unused `pub`. No
`dead_code` silence. `#[cfg(test)]` on production items is a smell,
including fuzz-only exports (principle 11).
- One logical change per commit. The message says what and why. Not WIP,
misc, or a drive-by rename mixed with behavior.

## Store and IBD

Expand Down Expand Up @@ -65,8 +71,8 @@ Perf A/B is operator-host only.
One plan step is one Red → Green → Refactor turn, committed before the next
step. Keep `--lib` compiling (wrap the old API, switch one caller). Inner
loop is `cargo test -p <crate> --lib` / `cargo check -p <crate> --lib`.
Do not `cargo check --tests` after every edit. Owner:
[`docs/how-we-plan.md`](docs/how-we-plan.md). Commands:
Do not `cargo check --tests` after every edit. Cycle and Agent RAM:
[`docs/how-we-plan.md`](docs/how-we-plan.md#agent-contract). Commands:
[`.agents/skills/ship-pr/SKILL.md`](.agents/skills/ship-pr/SKILL.md).

**Agent RAM:** never load `cargo test`, clippy, deny, or rustc stdout into
Expand All @@ -81,24 +87,11 @@ identities: ignore that file; use `$PWD/target/dev`.

One production implementation at the lowest crate that owns the concept.
Extract is a move: [`docs/code-shape.md`](docs/code-shape.md). Core-facing
RPC / P2P / Electrum / Esplora: [`COMPAT.md`](COMPAT.md).

Tests assert shipped behavior, not repo text
([`CONTRIBUTING.md`](CONTRIBUTING.md) principle 8). Budgets, no `*_for_test`
backdoors, no production-scale default fixtures: [`TESTING.md`](TESTING.md).
Tests use session or table instance stats or on-disk state, not thread-local
hot-path IO probes.

Crate `pub` is the cross-crate graph only. Unused `pub` is forbidden.
`#[cfg(test)]` on production items is a smell, including fuzz-only exports.
Do not leave dead code or silence `dead_code`. A RAM or CPU trade is named
([`CONTRIBUTING.md`](CONTRIBUTING.md) principle 9).

One logical change per commit. The message says what and why. Not WIP, misc,
or a drive-by rename mixed with behavior.
RPC / P2P / Electrum / Esplora: [`COMPAT.md`](COMPAT.md). Budgets and
fixtures: [`TESTING.md`](TESTING.md).

Before the first edit under `crates/<name>/`, read `crates/<name>/AGENTS.md`
when it exists.
when it exists, and open the read-first row that matches the change.

## Ship, release, Core functional

Expand Down
16 changes: 6 additions & 10 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -246,16 +246,12 @@ digging into a monolithic job log.
Label **`nixos-module-runtime`** to run the NixOS module qemu test (not
eval). That job is not required.

**Agents** implement in **one git worktree per session**, a topic branch per
PR, and **one PR** per plan. Each plan step follows
[`docs/how-we-plan.md`](./docs/how-we-plan.md) and is committed only after
local CI except coverage. Coverage and native `windows` / `macos` stay
GitHub Actions. After merge they delete the topic branch and keep the
session worktree. Never `git remote set-url origin`. Bot push uses an
explicit HTTPS URL (not `git push origin`). Fail-fast poll is
`./scripts/pr-checks-watch.sh`, not `gh pr checks --watch`. Start at
[`docs/ORIENT.md`](./docs/ORIENT.md).
Ship commands: [`.agents/skills/ship-pr/SKILL.md`](./.agents/skills/ship-pr/SKILL.md).
**Agents** open [`docs/ORIENT.md`](./docs/ORIENT.md) when the area is
unclear, follow the agent contract in
[`docs/how-we-plan.md`](./docs/how-we-plan.md#agent-contract), and use
[`.agents/skills/ship-pr/SKILL.md`](./.agents/skills/ship-pr/SKILL.md) to
open or update a pull request. Humans use ordinary git. The bot host file
does not apply to them.

Humans who want the same gates offline (Nix optional; rustup 1.95 is enough):

Expand Down
Loading
Loading