From Plan to Pull Request: A Day on Strike
One realistic feature, end to end, with every prior cairn put to work · ~19 min read ~– min read · Suggested by Bob engineeringproduct
Twelve cairns of philosophy, tools, and gates land in a single loop. This cairn is that loop, walked end to end on a small but realistic feature. The point is not that this is the only valid path. The point is that you can read it once and leave with a working mental model for how a piece of work moves from plan to merged pull request.
The loop, in one diagram
Before we walk it, the whole loop in one breath: brief, organic trigger, or claim-from-board → assigned GitHub issue (add beads for L+ work) → worktree as needed → optional spec pass → execute → just check-fast iterating → commit → timbers log → /local-review → push and gh pr create → Q reviews → triage → merge → close any bead and verify timbers pending. The conditional in the middle — needs a spec pass? — is the call most often gotten wrong; anything more than a typo benefits from a paragraph. The example we walk is “add an opt-out flag to the ECO completion email notification — let an OSP supervisor disable the email per-tenant.”
Where the bead comes from
Work starts three ways. Spec-first: you state the change in three sentences — what it covers, the default, where the surface lives — and the agent turns the brief into one or more beads with t-shirt sizes and explicit dependencies, which you confirm. Organic discovery: while working on something else, you or the agent notice a related problem — a flaky test, a TODO, a cleanup the current work surfaced — and the agent files a discovered GitHub issue for deferred work, or a bead for L+ work starting now. Claim-from-board: a discovered issue or GH issue typed Epic (with an area/<area> label) on the Project board is the trigger; you (or the agent) read it and assign yourself; L+ work mints beads at claim time with the GH URL in --design, while XS/S/M single-session work stays on the issue (see Where the Work Lives for the two flows). These paths converge on an assigned GitHub issue; L+ work adds beads when needed; skipping the spec pass on in-session discoveries may be reasonable when the context is already in hand, and on small claim-from-board work where the GH issue body is the spec.
The brief is the first deterministic constraint on the work. A vague brief produces vague code at startling speed. Specificity here is cheaper than specificity in review.
Claim the work (beads for L+)
You tell the agent what the work is; it runs bd create, names the issue something searchable, drafts a body that captures the brief and names the touchpoints, and assigns a priority. You confirm the breakdown by talking — “split this into two beads, one for the API and projection, one for the web frontend” — and the agent reshapes the graph. When the breakdown is right, “let’s pick this up,” and the agent runs bd update --claim.
Worktree
For L+ work, use bd worktree create .worktrees/<name> rather than plain git worktree add. The bd form does the surrounding setup that lets bd ready, bd close, and the rest see the project’s issue graph from inside the worktree; the plain form leaves the beads commands blind. Once you cd in, run the orientation ritual: branch, bd ready, AGENTS.md.
Spec pass (if needed)
For anything beyond a typo, a paragraph saves a day. The spec pass is a brief structured exchange before any code gets written: what the change covers, what it does not, which decisions are deliberate, which are deferred. In practice: is the flag on the tenant config row or a new override table? Read the flag in the projection or branch the notification path? Ten minutes captured in the issue body (and the bead for L+ work) is what the rest of the work runs against. Do not skip it on anything with more than one valid implementation.
Execute
The agent does the typing. You stay at the briefing-and-judgment level. For work with two beads (one API, one web), subagents earn their keep — one handles each, both reporting back to the orchestrator. The trust posture from Your Box and Your Trust Model is in play: an auto-allow list for just * recipes lets the agent iterate without interrupting; a more careful posture trades speed for more approval points.
Local gates
Quality Gates is the deep read. Iterate on just check-fast, then run just check before push as the seatbelt that catches slow gates — full web build, integration tests, audit-ci. Most lint complaints fix themselves with just api fix and just web fix. Coverage failures are real failures; add the test, do not lower the threshold.
Commit, then timbers
Commits are small. The pre-commit hook does the work the gates cairn described: lint-staged Prettier, the timbers gate. After the commit, the agent runs timbers log with the what / why / how, and you adjust the why if it is shallow. That --why is what the next reviewer will appreciate most — the question the diff alone cannot answer. (Beads syncs separately via refs/dolt/data on origin — pushed by the pre-push hook alongside the code.)
Local review
Before the push, run /local-review. The mechanical half stays with you — closing keyword in the PR body, gates green, bead sync clean. The judgment half goes to a primed fresh-context subagent that reads the diff cold; you wrote it, so you read it for confirmation rather than scrutiny. A fresh-context reviewer can surface issues before the PR round-trip; do not assume its model, turnaround time, or overlap with Q will stay fixed. Skip only on truly trivial diffs.
Push, open the PR
Before pushing, run /local-review — the author runs the mechanical checks (closing-keyword present, gates green, bead sync clean), then a primed fresh-context subagent reads the diff cold and reports findings. A fresh-context reviewer can surface issues before the PR round-trip, without promising a fixed model or review time. Then git push -u origin <branch> publishes the branch; gh pr create opens the PR. Title under 70 characters; body is the tracked issue summary plus a Test plan checklist. Where the PR closes a GH issue, the body must carry a standalone Closes #N line — GitHub’s PR linked to issue automation reads the body, not commit messages. For L+ work the GitHub issue URL lives in each bead’s --design for cross-reference; the bd ↔ GitHub bridge exists (bd github sync/push/pull) but is deliberately not auto-enabled — the manual seam is the methodology, see Where the Work Lives.
Q reviews the PR
Within minutes of the PR opening, Q (automated reviewer) posts a verdict — Looks good, Concerns, or Changes required — and inline comments. The verdict is a first-class checkpoint, not optional polish; Q catches issues that survived the agent’s self-review. While Q reviews, do not start unrelated work that would lose PR context — schedule a check-back in the same area so integrating feedback is cheap.
Q’s verdict is not advisory. Concerns means concerns; Changes required means changes are required. Dismissing without engagement is the failure mode that lets bad code merge under “the gates passed and Q was wrong.”
The triage matrix
Q’s review is not all equal weight. Critical (security, correctness, data loss, regression) gets fixed now, before the next push. Important (architecture concern, missing test) gets fixed in this PR with a brief reply. Nice-to-have (style, naming) gets a one-sentence reply explaining the call. To re-request review, build the JSON with jq -n and pipe via gh api --input -; the trap is gh api -F for an array-valued field, which silently sends a stringified blob the API rejects with a 422 (client_payload is not an object). The convergence loop is capped at three exchanges — a fourth round means a human conversation (or a Codex council) is the next step.
Browser-QA, maybe
An honest section. Driving a browser via Playwright MCP or Chrome DevTools MCP is possible today but is not how most of the team verifies UI changes. The pattern today is just dev, click through the flow yourself, and add a Playwright test (just web e2e) for the regression you want to prevent. Agents running and evaluating end-to-end tests in the same loop as lint and unit tests is something we are feeling our way toward but have not landed.
Merge
Merge only after Q has approved (or its concerns are resolved), CI is green, and — for non-trivial changes — the human has said go. Do not self-merge when the user has not signed off. The cost of merging too early is asymmetric. After the explicit go, the agent runs gh pr merge --squash.
Bead close, ledger check
After the merge, close any bead and verify the ledger. For L+ work the agent runs bd close <id>; you confirm timbers pending is 0 — the substantive work already has its timbers entry from the feature-branch commit (the commit → timbers log → push step earlier), and timbers’ pending check has lenient handling for the merge commit itself, so a separate post-merge entry is not required. The worktree can stay for follow-ups or be removed with git worktree remove and git branch -d. From brief to merged pull request, every prior cairn put to work.
Beyond the repo
A few open questions sit beyond this cairn’s scope. The bd ↔ GitHub bridge exists in the bd CLI but we deliberately don’t auto-enable it; the manual seam between beads and the Osprey Product Development Project — with discovered issues and native type:Epic issues (with orthogonal area/<area> labels) driving L+ bead minting at claim time — is documented in Where the Work Lives. Agile/scrum for agent teams — cadence, story-pointing, retros when execution is cheap and participants include agents — is genuinely undecided; new hires are invited to bring opinions. The portable issue-creation and local-review workflows now ship in Agent Playbook; Strike keeps local policy overlays.
Where this trail leaves you
You have read the philosophy, the tool map, the required practices, the harness, your trust model, the second-opinion pattern, the power tools, the worktree pattern, the gates, and the integrated loop. That is the workflow. The companion trail, Osprey Strike — From Emergency to Resolution, is the product — emergency callouts in fiber operations and the architecture that supports them. Welcome to the team.
- How We Build Here — Cairn 1. The argument under everything in this loop.
- Beads, the Backbone — Cairn 3.
bd create,bd ready,bd close, the issue graph that drives the loop. - Timbers, the Ledger — Cairn 4. The post-commit ritual;
timbers pendingmust be 0 before close. - Just: One Place to Discover — Cairn 6.
just check,just check-fast,just fix— the build verbs throughout. - Quality Gates: The Contract That Lets You Move Fast — Cairn 11. The exact thresholds and the cardinal rules.
- Where the Work Lives — The Project-board side: where claim-from-board originates, why the bd ↔ GitHub seam is intentional, and how the distinct issue signals (discovered, epic, auto-review) stay disjoint.
- local-review-before-pr.md (osprey-strike) — The rule that defines the author-mechanical / fresh-context-subagent split this cairn now references between commit and push.
Pick a small change. The example throughout this cairn is “add an opt-out flag to the ECO completion email notification — let an OSP supervisor disable the email per-tenant if they prefer pager-only.” Small, real, touches the API, the web frontend, and a projection. The exact feature does not matter. What matters is the shape of the loop around it: how the work gets framed, claimed, executed, reviewed, and shipped.
If you have read the prior twelve cairns, every one of them shows up here. That is the point. This cairn is short on new content and long on integration.
The loop, in one diagram
Before we walk it, here is the L±sized example loop. Smaller single-session issues skip the bead steps; they stay on the assigned GitHub issue and track in-session tasks there. The first time you read this cairn, the diagram will be denser than it needs to be; come back to it after the prose has named the steps, and it should look obvious.
The diagram reflects the original L+ example (the final timbers check means verify timbers pending, not necessarily a new entry). The conditional at the middle — “needs a spec pass?” — is the call most often gotten wrong. Anything more than a typo benefits from a paragraph. We will come back to that.
Where the bead comes from
Work starts three ways. The L±sized path the example follows here is spec-first: you have a change in mind, you state it clearly, and the agent turns the brief into one or more beads. The second path is organic discovery — deferred work surfaces during other work, and the agent files a discovered GitHub issue from context. The third path is claim-from-board, where the trigger is a discovered issue or GH issue typed Epic (with an area/<area> label) already on the Project board; L+ work mints beads at claim time; XS/S/M single-session work stays on the assigned issue without a bead. The paths differ in what triggers them.
Spec-first
A brief is what you say (or write) before you create the bead. It does not have to be long. For our example: “OSP tenants should be able to opt out of the per-ECO completion email. Default is opt-in. Setting lives on the OSP tenant config; UI lives in the existing tenant settings page.”
Three sentences naming the change, the default, and where the surface lives. That is enough to ask the agent to create a bead. For larger or more structured specs, the agent breaks the spec into a small set of beads with explicit dependencies, including a t-shirt size on each (see Beads, the Backbone for the sizing scale); you confirm the breakdown. An assigned GitHub issue is already the coordination record; L+ beads link to it manually rather than relying on automatic bd↔GitHub sync.
The brief is the first deterministic constraint on the work. A vague brief produces vague code at startling speed. Specificity here is cheaper than specificity in review.
If a brief takes more than a minute to articulate, the work probably wants its own design pass before it becomes a bead — see Spec pass below.
Organic discovery
While the agent is working on something else, you (or it) notice a related problem worth fixing later — a TODO that should be tracked, a flaky test, a dependency upgrade that wants attention, a cleanup the current work surfaced, an inconsistency between two files. There is no formal brief here. The agent has the context from the surrounding work and turns it into a discovered GitHub issue that captures the intent. “File a discovered issue for that flaky test we just saw — describe the failure mode and link it to the dispatched-contact module.” Confirm the issue body before going back to what you were doing.
This pattern keeps deferred work visible on the board rather than burying it in a local bead queue. If you start an in-session discovery immediately, size it first; a short spec pass can be skipped when the surrounding context already defines the work.
Claim-from-board
A third path covers the case where the work was filed before this session — a discovered GH issue someone hoisted yesterday, an issue typed Epic with an area/<area> label you are picking up off the Project board, a card a teammate assigned to you. The trigger is the GH issue, not a brief or a discovery. Where the Work Lives is the dedicated walkthrough of the Project board and the two claim flows (UI-first: assign yourself in GitHub, bring the number to the agent; Claude-first: tell the agent the number, it updates both sides). For L+ work, beads are minted at claim time and carry the GH issue URL on the first line of --design. XS/S/M single-session work remains bead-less. Assignment automatically advances discovered issues to In progress and planning-tier issues to Ready; active planning work needs a separate status move.
On a small discovered issue, the assigned GitHub issue remains the tracking record and the spec pass may be skipped when its body is sufficient. On an issue typed Epic with an area/<area> label and a Motivation / Outcome / Acceptance breakdown, the agent decomposes into one bead per acceptance criterion (or per coherent implementation chunk) and the Beads section of the epic’s body gets updated with the new IDs. The coordination-recipes skill has the exact bd create and gh issue edit recipes; you do not need to memorize them.
Claim the work (beads for L+)
You tell the agent what the work is and ask for a bead. The agent runs bd create, names the issue something searchable, drafts a body that captures the brief, and assigns a priority. The bead is claimable as soon as it lands.
For L+ work in our example, the bead title might be “Opt-out flag for ECO completion email per OSP tenant.” The body restates the brief, names the touchpoints (packages/api/internal/domain/tenant, packages/api/internal/notification, packages/web/src/app/settings, the ECO completion projection), and lists the gates that must pass.
You confirm the breakdown is right; if it is not, you adjust by talking. “Split this into two beads — one for the API and projection, one for the web frontend.” The agent reshapes the graph.
When L+ work is broken down, a bead can be claimed: “let’s pick this up,” and the agent runs bd update --claim against the relevant bead. The graph now says one or two issues are in flight, owned by you.
Worktree
For L+ work, work in a worktree. The pattern from Working in Parallel (Mostly):
bd worktree create .worktrees/opt-out-completion-email
cd .worktrees/opt-out-completion-email
When the work uses beads, bd worktree create is the form to use — it does the worktree creation and the surrounding setup that lets bd ready, bd close, and the rest see the project’s issue graph from inside the worktree. Plain git worktree add skips that setup and tends to leave the worktree’s beads commands blind to the project’s actual work.
Once you cd in, confirm the branch, the tracking issue (and bd ready if beads are in use), and the project instructions in AGENTS.md. Most of this happens automatically; what is left is the spoken confirmation that you are in the right place.
Spec pass (if needed)
For anything beyond a typo, a paragraph saves a day. The spec pass is a brief structured exchange with the agent before any code gets written: what the change covers, what it explicitly does not cover, which decisions are deliberate, which are deferred. The team’s dm-work:brainstorming skill, if installed, automates the back-and-forth shape of this conversation; without it, the same exchange happens by talking.
For our example, the spec pass surfaces questions like:
- Is the flag stored on the tenant config row, or is it a new per-OSP override table? (Tenant config row, for now.)
- Does the existing notification path read the flag, or is there a new branch in the projection? (Read the flag in the projection’s notification dispatcher.)
- What happens to ECOs that completed before the flag was flipped? (No retroactive change; the flag affects future completions only.)
Ten minutes of that conversation, captured as the bead body’s amendments, is what the rest of the work runs against. Skip it on small changes; do not skip it on anything that has more than one valid implementation.
The spec pass is partly for you and partly for the durable record. The amended issue or bead body is what the next reviewer (human or agent) reads; if your spec pass leaves a question unsettled, the reviewer will ask it again. Settle it once, in the tracking record, before code lands.
Execute
The agent does the typing. You stay at the briefing-and-judgment level. For a piece of work with two beads (one API, one web), this is where subagents earn their keep — one subagent handles the API change in parallel with one handling the web frontend, both reporting back to you. The orchestrator (your main session) integrates.
For smaller work, no subagents needed; the main session writes the code directly. The pattern is the same shape either way: brief the agent on the constraint set, watch it work, intervene when it goes off-script, accept the diff when it converges.
The trust posture from Your Box and Your Trust Model is in play here. If your auto-allow list includes just * recipes, the agent will iteratively run just check-fast against the api and web packages without interrupting you. If it does not, expect to approve those calls. The faster posture pays off most during execute; the more careful posture pays off most when the work touches infrastructure or production.
Local gates
Quality Gates is the deep read. The tactical pattern in this loop:
just check-fast # iterate on this; it is the per-save sanity check
just check # run before push; the umbrella across packages
If just check-fast fails, the agent reads the failure, edits, reruns. Most lint complaints fix themselves with just api fix and just web fix. The 20% that do not are the ones worth your attention. Coverage failures are real failures — they mean a code path you added is not exercised. Add the test; do not lower the threshold.
Running just check before pushing is the seatbelt. It catches the slow gates that just check-fast skips: the full web build, integration tests, audit-ci. The thirty seconds the slow run costs is cheap insurance against a CI failure that lands at 2 PM in everyone’s GitHub notifications.
Commit, then timbers
Commits are small. The pre-commit hook does the work the Quality Gates cairn described: lint-staged Prettier on web, the timbers gate. (Beads sync runs separately via refs/dolt/data on origin — the pre-push hook fires bd dolt push alongside git push so any bead work on the branch reaches origin with the code.) The commit message stays whatever you would have written. After the commit, the agent runs timbers log with the what / why / how it understood. You read what it wrote and adjust the why if it is shallow.
For our example, a commit and its timbers entry look like:
git commit -m "feat(api): add opt_out_completion_email flag to OSP tenant config"
timbers log "Add opt_out_completion_email flag to OSP tenant config" \
--why "OSP supervisors using pager-first workflows do not want duplicate email noise; opt-in by default preserves existing behavior" \
--how "New nullable column on osp_tenant_config; tenant config aggregate updated; projection reads the flag in notification dispatcher"
That --why is the part the next reviewer will appreciate most. “Why is there a flag?” is the question the diff alone cannot answer; the timbers entry is where it is settled.
Local review
Before the push, run /local-review. The mechanical half stays with you: confirm the closing keyword is in the PR body if the PR closes a GH issue, check just check is green, verify bd dolt push is clean (no unpushed bead state), grep the diff for § references that should resolve at this branch’s view of main. Each of those has an objective answer; the author of the diff is fine to verify them.
The judgment half goes to a primed fresh-context subagent that reads the diff cold. The asymmetry matters: you wrote the diff, so you are the worst person to judge it — you already rationalized every choice while writing, and you will read it for confirmation rather than scrutiny. A fresh subagent with no conversation history reads what is actually on disk. A fresh-context reviewer can surface issues before the PR round-trip without assuming a fixed model, turnaround time, or overlap with Q. The asymmetry is large enough that the local pass earns its keep on every non-trivial diff.
The shared Agent Playbook local-review skill primes the subagent; the Strike policy overlay adds mechanical checks. It packages the diff base, the intent and acceptance criteria from the bead (or claim-from-board GH issue), and a rubric (read as a reviewer; cross-references resolve; test-assertion claims match the assertions; doc comments still accurate after the change; conventions cited exist at this branch’s state) and returns findings bucketed Critical / Important / Nice-to-have with file:line and a concrete fix per item. You triage them — same matrix as the Q triage below, but earlier and cheaper.
Skip /local-review only on truly trivial diffs (a typo, a single-line config bump, a bead/timbers bookkeeping commit). Otherwise run it. The extra local pass is usually cheaper than revisiting an opened PR.
Push, open the PR
git push -u origin <branch> publishes the worktree’s branch to the remote. Then gh pr create opens the pull request. Title under 70 characters; body is the tracked issue summary plus a Test plan checklist. The agent will draft both; you read and adjust.
For our example, a PR title: feat(api): opt-out flag for ECO completion email. A body that lists what changed, why, and how to test it. Where the PR closes a GH issue, the body must carry a standalone Closes #N line at the top — GitHub’s PR linked to issue automation reads the PR body, not commit messages; without the keyword in the body, the issue silently skips the In review column on the Project board until merge. For L+ work, the bead URL (and its link back to GH in --design) is the cross-reference back to the execution graph; the bd ↔ GitHub bridge exists (bd github sync/push/pull) but is deliberately not auto-enabled, because the manual seam is the methodology — see Where the Work Lives.
Q reviews the PR
Within minutes of the PR opening, Q (automated reviewer) posts a verdict and inline review comments. Looks good, Concerns, or Changes required. The verdict is a first-class checkpoint, not optional polish — Q’s review catches a meaningful fraction of issues that make it past the agent’s own self-review during execute.
While Q is reviewing, do not start unrelated work that would lose PR context. Schedule a check-back: another small bead in the same area, a documentation pass, a code-reading session on an adjacent module. The point is to stay close enough to the PR that integrating Q’s feedback is cheap when it arrives.
Q’s verdict is not advisory. Concerns means concerns; Changes required means changes are required. Dismissing without engagement is the failure mode that lets bad code merge under “the gates passed and Q was wrong.”
The triage matrix
Q’s review arrives as inline comments and a top-level verdict. Not every comment is equal. The triage move:
| Severity | What it is | What you do |
|---|---|---|
| Critical | Security, correctness, data loss, crash, regression | Fix it now. Do not push another commit until it is addressed. |
| Important | Architecture concern, missing test, gap that will bite later | Fix it in this PR. Reply briefly; push a fix; re-request review. |
| Nice-to-have | Style, minor naming, alternate approach that is also reasonable | Reply with the call you made; defer if the rationale holds. |
The agent does the first pass of triage by reading the comments and proposing severity for each. You confirm or override. Critical and Important get fixed; Nice-to-have gets a reply that explains the call. Nice-to-have dismissals should be one sentence — “Keeping the existing naming for consistency with the adjacent module” is enough.
After fixes land, re-request review explicitly. The gh api invocation that does it cleanly is the one that has bitten every new agent at least once:
# CORRECT: build the JSON object with jq, pipe via --input -
jq -n --arg user "q-redshifted" \
'{reviewers: [$user]}' \
| gh api --input - \
-X POST \
"/repos/{owner}/{repo}/pulls/{number}/requested_reviewers"
The trap is using gh api -F for the array-valued field; that path silently sends a stringified blob that the API rejects with a 422 “client_payload is not an object” (or its variant). Build the JSON properly with jq -n; pipe via --input -. The agent should have this pattern internalized; if you see it reach for -F with an array, redirect.The same pattern applies to repository_dispatch events, which is where this gotcha most often lands. The Conduit publisher uses exactly this idiom in its CI; see the conduit cairns for the deeper context.
The convergence loop is capped at three exchanges. If you are on the fourth round of “fix, re-request, fix, re-request,” that is a signal: the disagreement is not converging on its own, and a human conversation (or a Codex council, per Codex as Second Opinion) is the next step.
Browser-QA, maybe
An honest section. The agent driving a browser via Playwright MCP or Chrome DevTools MCP for runtime verification is possible in our environment today, but it is not how most of the team verifies UI-touching changes. The author has experimented with both, and the experience is somewhere between interesting and worth building on but not yet a default.
For our example, the team’s pattern today is:
- Run the app locally (
just dev). - Click through the affected flow yourself.
- Add a Playwright test (
just web e2e) for the regression you want to prevent.
The future pattern — agents writing, running, and evaluating end-to-end Playwright tests as part of the same loop the agent already runs lint and unit tests in — is something we are feeling our way toward but have not landed. If you experiment with it on a real feature and learn something useful, file a discovered issue for useful deferred follow-up.The shape of the answer is probably: the agent runs Playwright in headed mode against a worktree-scoped local stack, takes screenshots at key points, summarizes the run as a structured artifact the next agent (or the human) can read. None of that is hard; what is hard is making it boring enough that you actually do it.
Merge
Merge only after Q has approved (or its concerns are resolved), CI is green, and — for non-trivial changes — the human in the loop has said go. Do not self-merge when the user has not signed off. This rule is one of the more frequently-tested ones; the temptation when CI is green and Q is approving is to just hit the button. Wait for the explicit go.
For our example, after Q approves and CI is green: “Looks good — merge it.” The agent runs gh pr merge --squash (or whatever the project’s merge style is — squash for Strike), and the branch lands on main.
The “wait for the user’s go” rule applies to agents and to humans-with-rights-to-merge alike. The cost of merging too early is asymmetric: the work is in production before the last layer of judgment fired.
Bead close, ledger check
After the merge, close any bead and verify the ledger:
bd close os-pvw9
timbers pending # should be 0
The substantive work’s timbers entry was written back at the commit step, before push — the agent ran timbers log then, and that entry is what reviewers and future readers will see. The merge commit itself is mechanical; timbers’ pending check has lenient handling for merge commits and bot-authored commits (per the consolidated friction work in beads issue os-283), so a separate post-merge entry is not required. Just confirm pending reads 0 and move on, per Timbers, the Ledger. The worktree can stay around for follow-up beads on the same feature, or be removed:
git worktree remove .worktrees/opt-out-completion-email
git branch -d opt-out-completion-email
That is the loop, complete. From brief to merged pull request, every prior cairn has been put to work.
Beyond the repo
A few open questions sit beyond this cairn’s scope. Naming them is more honest than pretending the loop above is finished work.
bd ↔ GitHub bridge and the Project board. Both questions that used to live here have been answered. The bridge exists in the bd CLI (bd github sync/push/pull), but Strike deliberately doesn’t auto-enable it — bidirectional sync would pollute one side or the other. The choice between mapping the beads graph onto a Project board and keeping the two complementary came down decisively on the complementary side: the manual seam, with discovered issues and native type:Epic issues (with orthogonal area/<area> labels) driving L+ bead minting at claim time, is the methodology. Where the Work Lives is the dedicated walkthrough — directly upstream of this cairn in the trail.
Agile / scrum for agent teams. Sprint cadence, story-pointing, retrospectives, planning poker — what do those rituals look like when execution is cheap and the participants include agents? We are feeling our way. Retros and planning still happen; their rhythm is different. New hires are explicitly invited to bring opinions; this is one of the genuinely undecided parts of the practice.
Agent Playbook. Portable issue creation, local review, and engineering discipline now ship in the shared plugin. Strike retains local .claude/policy/ overlays and coordination-recipes for project-specific behavior.
Where this trail leaves you
You have read the philosophy (How We Build Here), the tool map (The Workshop), the three required practices (Beads, Timbers, Just), the agent harness (Claude Code as Daily Driver), your machine and trust model (Your Box and Your Trust Model), the second-opinion pattern (Codex as Second Opinion), the small power tools (Quiet Power Tools), the worktree pattern (Working in Parallel (Mostly)), the gates (Quality Gates), and now the integrated loop. That is the workflow.
The companion trail, Osprey Strike — From Emergency to Resolution, is the product. Now that you know how we work, that trail is what we work on — emergency callouts in fiber operations, the architecture that supports them, and the design choices that shape the system. The first cairn (When the Fiber Goes Dark) is a good entry point.
Welcome to the team. The work is in front of you; the trail above is how it gets done.
Summary
- One loop, twelve cairns of context. (Trigger: a brief, a claim from the GitHub Project board, or an organic find you'll tackle this session) → issue (bead for L+) → worktree as needed → (spec pass) → execute → gates → commit → timbers → push → Q review → triage → merge → close any bead.
- Execution starts in several ways. Spec-first (you state the change and the agent records it), organic discovery (deferred work becomes a GitHub issue), or board-claim (you pick an existing issue). L+ execution gets beads when warranted; XS/S/M single-session claims stay on the assigned issue. A clear brief or issue body is the first deterministic constraint on the work. Discoveries you intend to defer to a future session file as GitHub issues (label
discoveredor nativetype:Epicwitharea/<area>), not beads — the bead is for active work; see Where the Work Lives. - Worktrees and
bd worktree createfor non-typo work. The bd form does the beads-side setup that makesbd readywork inside the worktree;git worktree addskips it. Branch isolation pays off as soon as a second piece of work shows up. - Local gates iterate via
just check-fast;just checkis the seatbelt before push. Auto-fix first; treat coverage failures as real failures. - Run
/local-reviewbeforegh pr createon non-trivial diffs. Author runs mechanical checks; a primed fresh-context subagent runs the judgment review. The local pass checks the diff independently before the PR round-trip. - Q reviews are first-class. Triage matrix: critical/important/nice-to-have.
jq -n | gh api --input -is the working pattern for re-requesting review. - Browser-QA is honestly TBD. Possible today, not yet a default. File a `discovered` issue for useful deferred follow-up if you experiment.
- Merge requires explicit user sign-off. Self-merging on green CI is the failure mode that skips the last layer of judgment.
- Beyond the repo: agile-for-agent-teams. Still open; new hires welcome to bring opinions. The
bd ↔ GitHubquestion that used to live here is answered — the bridge exists, we don't auto-enable it, and the workflow is in Where the Work Lives.
- The "wait for the user's go before merging" rule is universal, but the test we use for "non-trivial enough to need explicit go" is implicit. How would you write that test down so an agent applies it consistently — number of files changed, package scope, presence of schema changes, something else?
- Browser-QA is the trail's biggest TBD. Pick one shape for what good looks like (agent runs Playwright headlessly, agent narrates a headed run, agent writes Playwright tests but does not run them) and argue for it. Where would you start?
- The "Beyond the repo" section names a remaining open question. If you had to rank them by which one will most reshape the daily loop when it lands, which goes first, and why?
- How We Build Here — Cairn 1. The argument under everything in this loop.
- The Workshop — Cairn 2. The tool map this loop assumes is installed and working.
- Beads, the Backbone — Cairn 3.
bd create,bd ready,bd close, the issue graph that drives the loop. - Timbers, the Ledger — Cairn 4. The post-commit ritual;
timbers pendingmust be 0 before close. - Claude Code as Daily Driver — Cairn 5. The harness, orientation ritual, and subagent pattern this loop runs in.
- Just: One Place to Discover — Cairn 6.
just check,just check-fast,just fix— the build verbs throughout. - Your Box and Your Trust Model — Cairn 7. The trust posture under which the agent runs the loop's mechanics.
- Codex as Second Opinion — Cairn 8. The escalation when Q's review and your judgment diverge, or when convergence stalls.
- Quiet Power Tools — Cairn 9. RTK and the CLI multipliers that compound across the loop without ever showing up as a step in it.
- Working in Parallel (Mostly) — Cairn 10. The
bd worktree createrule and the branch-isolation pattern this loop relies on. - Quality Gates: The Contract That Lets You Move Fast — Cairn 11. The exact thresholds and the cardinal rules.
- Osprey Strike — From Emergency to Resolution — The companion trail. The product domain you have just learned to ship into.
- gh api — Official GitHub CLI documentation for
gh api. Required reading for the--input -pattern that fixes the array-valued payload trap. - Where the Work Lives — The dedicated walkthrough of the Project board, the distinct issue signals, and the two claim flows (UI-first, Claude-first) that create beads for L+ work at claim time.
- local-review-before-pr.md (osprey-strike) — Defines the author-mechanical / fresh-context-subagent split this cairn references in §Local review. Provides the Strike-specific mechanical checks for shared Agent Playbook local review.
Generated by Cairns · Agent-powered with Claude