Conversation
Maintainer Otto-204: "you need some pr resolve loop that will handled everyting needed to take a pr to compelteion so you don't ahve to keep figuion it out" + Otto-204b: "we are saving you resolution to all the comments and we expect those to be excellent don't take shortcuts on the feedback, do the right long term thing or backlog the right thing and not it on the comment." New P1 CI/DX BACKLOG row for .claude/skills/pr-resolve-loop/ SKILL.md. Six-step close cycle: CI-status → review-thread resolution (reply-then-resolve; never shortcut) → name- attribution lint → conversation-preservation hook → auto- merge re-arm → loop-exit on merge / maintainer-escalation / external-blocker. Core discipline: active PR management vs ship-and-pray. The factory's Otto-200..203 observation of "queue unchanged 136" for 6+ ticks misread passive-stuck as livelock; actual blocker was accumulated unresolved review-threads + silent lint failures that armed auto-merge could not overcome. This skill internalizes that learning; active resolution has 10-20× higher ROI than opening new PRs when queue saturated. Conversation-preservation: every reply+resolve logs to artifacts/pr-discussions/PR-<N>-conversation-log.json per Otto-150..154 git-native preservation directive. Non-goals: NOT an auto-merge-bypass, NOT a shortcut around reviewer intent, NOT a retry-loop on flake, NOT an opener of new PRs. Composes with: Otto-171 queue-saturation-throttle, PR #335 preservation, @codex review + Copilot patterns, PR #213 git-hotspots, PR #354 BACKLOG-split-Phase-1a (first PR where active-management discipline applied). Priority P1 CI/DX. Effort: M skill design + S invocation + S reply-template bank. Placed in P1 CI/DX section line 2469, NOT BACKLOG tail. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Adds a new P1 CI/DX backlog item describing a proposed “PR-resolve-loop” skill to automate the end-to-end PR closeout workflow (checks, review-thread responses/resolution, conversation preservation, and auto-merge re-arming).
Changes:
- Add a single P1 CI/DX BACKLOG row specifying the PR-resolve-loop skill’s steps, invocation modes, and non-goals.
| `mergeStateStatus: MERGEABLE` (not BEHIND, DIRTY, | ||
| or BLOCKED), re-arm `gh pr merge --auto --squash`. |
There was a problem hiding this comment.
This step uses mergeStateStatus: MERGEABLE, but GitHub’s JSON/GraphQL distinguishes mergeStateStatus (e.g., CLEAN/BEHIND/DIRTY/BLOCKED/…) from mergeable (MERGEABLE/CONFLICTING/UNKNOWN). Update the wording to check mergeStateStatus: CLEAN and mergeable: MERGEABLE (or use valid mergeStateStatus values).
| `mergeStateStatus: MERGEABLE` (not BEHIND, DIRTY, | |
| or BLOCKED), re-arm `gh pr merge --auto --squash`. | |
| `mergeStateStatus: CLEAN` and `mergeable: | |
| MERGEABLE` (not BEHIND, DIRTY, or BLOCKED), re-arm | |
| `gh pr merge --auto --squash`. |
| history, memory files — all history-exempt per | ||
| loop-tick-history 2026-04-22). | ||
| 4. **Conversation-preservation hook** — every reply | ||
| + resolve operation logs to `artifacts/pr- |
There was a problem hiding this comment.
Line starts with + (" + resolve operation logs ..."), which will be parsed as a nested unordered-list item and can trigger markdownlint MD004/ul-style failures in this repo. Rephrase to avoid a line-start + (e.g., “and resolve…”, or restructure the sentence).
| + resolve operation logs to `artifacts/pr- | |
| and resolve operation logs to `artifacts/pr- |
| + resolve operation logs to `artifacts/pr- | ||
| discussions/PR-<N>-conversation-log.json` so the | ||
| git-native preservation directive (Otto-150..154, | ||
| PR #335) captures both-sides-of-conversation | ||
| automatically rather than relying on GitHub-only |
There was a problem hiding this comment.
The conversation log target path is artifacts/pr-discussions/..., but there’s no artifacts/ directory in the repo today and an existing BACKLOG row specifies git-tracked PR discussions under docs/pr-discussions/PR-<number>-<slug>.md (docs/BACKLOG.md:4487). Consider aligning this row to the established docs/pr-discussions/ location (or explicitly call out why this is different and how it becomes git-tracked).
| + resolve operation logs to `artifacts/pr- | |
| discussions/PR-<N>-conversation-log.json` so the | |
| git-native preservation directive (Otto-150..154, | |
| PR #335) captures both-sides-of-conversation | |
| automatically rather than relying on GitHub-only | |
| + resolve operation logs to `docs/pr- | |
| discussions/PR-<N>-conversation-log.json` so the | |
| git-tracked preservation directive (Otto-150..154, | |
| PR #335) captures both-sides-of-conversation in- | |
| repo rather than relying on GitHub-only |
|
|
||
| - NOT an auto-merge-bypass. The skill doesn't override | ||
| branch protection; it honors the 5 required checks | ||
| + review-resolution gate faithfully. |
There was a problem hiding this comment.
Line starts with + (" + review-resolution gate faithfully."), which Markdown parses as a nested bullet and markdownlint MD004/ul-style will flag. Reword to avoid starting a continuation line with +.
| + review-resolution gate faithfully. | |
| and review-resolution gate faithfully. |
| close-the-PR cycle (CI-failures + review-conversations | ||
| + agent-comment preservation + auto-merge arm) so Otto |
There was a problem hiding this comment.
Line starts with a + inside a wrapped list item (" + agent-comment preservation"), which Markdown parses as a nested bullet and markdownlint (MD004/ul-style) will flag. Reword to avoid a line-start + (e.g., use “and/plus”, or move the + to the end of the previous line).
| close-the-PR cycle (CI-failures + review-conversations | |
| + agent-comment preservation + auto-merge arm) so Otto | |
| close-the-PR cycle (CI-failures, review-conversations, | |
| agent-comment preservation, and auto-merge arm) so Otto |
Applying PR-resolve-loop discipline to #352. 5 unresolved review threads (Copilot P2 inline-code-span + P1 cross-ref drift + P2 IP-discipline ambiguity + P1 inline-code-span duplicate + P1 line-reference drift). 4 addressed in this commit; resolution replies to follow via GraphQL. 1. Inline code span split across lines 1008-1009 (Copilot P2 threads 59XP74 + 59XSRN, duplicate finding): Moved the multi-line `docs/research/server-meshing-*.md` path onto its own line so the backtick-delimited span renders atomically per CommonMark. No more rendering risk. 2. "Otto-175c starship-franchise-mapping row" cross-ref that didn't resolve (Copilot P1 thread 59XSQc): Clarified the reference to note the row landed in PR #351 (merged). Amara 10th + 11th ferry cross-refs updated to point at their archived location under `docs/aurora/2026-04-24- amara-*.md` paths. 3. Wire-protocol row line-number reference was `~754`, actual location is `~830` (Copilot P1 thread 59XSRf): Corrected the line hint. 4. "No Star-Citizen trademarked content ingested" IP- discipline bullet was ambiguous — the row itself uses trademarked names for reference (Copilot P2 thread 59XSQz): Rewrote the discipline block to explicitly distinguish industry-landscape reference (permitted) from proprietary-content ingestion (excluded), with specific "research-permitted" boundaries for CIG's public Inside-Star-Citizen + RSI content and for SpacetimeDB's Apache-2 repo. Framing: this commit demonstrates the PR-resolve-loop pattern (BACKLOG row Otto-204, PR #356) on a second PR after the pattern was first applied to #354. Active management vs ship-and-pray. Part of the corrective response to Otto-204c livelock-diagnosis. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Applying PR-resolve-loop discipline to #352. 5 unresolved review threads (Copilot P2 inline-code-span + P1 cross-ref drift + P2 IP-discipline ambiguity + P1 inline-code-span duplicate + P1 line-reference drift). 4 addressed in this commit; resolution replies to follow via GraphQL. 1. Inline code span split across lines 1008-1009 (Copilot P2 threads 59XP74 + 59XSRN, duplicate finding): Moved the multi-line `docs/research/server-meshing-*.md` path onto its own line so the backtick-delimited span renders atomically per CommonMark. No more rendering risk. 2. "Otto-175c starship-franchise-mapping row" cross-ref that didn't resolve (Copilot P1 thread 59XSQc): Clarified the reference to note the row landed in PR #351 (merged). Amara 10th + 11th ferry cross-refs updated to point at their archived location under `docs/aurora/2026-04-24- amara-*.md` paths. 3. Wire-protocol row line-number reference was `~754`, actual location is `~830` (Copilot P1 thread 59XSRf): Corrected the line hint. 4. "No Star-Citizen trademarked content ingested" IP- discipline bullet was ambiguous — the row itself uses trademarked names for reference (Copilot P2 thread 59XSQz): Rewrote the discipline block to explicitly distinguish industry-landscape reference (permitted) from proprietary-content ingestion (excluded), with specific "research-permitted" boundaries for CIG's public Inside-Star-Citizen + RSI content and for SpacetimeDB's Apache-2 repo. Framing: this commit demonstrates the PR-resolve-loop pattern (BACKLOG row Otto-204, PR #356) on a second PR after the pattern was first applied to #354. Active management vs ship-and-pray. Part of the corrective response to Otto-204c livelock-diagnosis. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…ndustry competitive angle (#352) * backlog: Otto-180 Server Meshing + SpacetimeDB deep research — game-industry competitive angle Aaron Otto-180: "also backlog server mesh from star citizen, our db backend when we shard it should support this style of cross shard communication like server mesh, it's amazing actually, i think space time db is similar too or not it might be orthogonal but we want to support these use cases in our backend too. do deep reserach here, this could get us lots of customers in the game industruy if we can compete with server mess/space time db". Two architectures to research (Aaron's "might be orthogonal" intuition is correct): 1. Server Meshing (CIG / Star Citizen) — horizontal-scaling across many game servers; entity handoff + state propagation at server boundaries. Static vs Dynamic Server Meshing both in scope. 2. SpacetimeDB (Clockwork Labs, Apache-2) — vertical- integration of DB + server; reducers as stored-procedure- like functions; "the database IS the server" pitch; claims 1000x cheaper + faster than traditional MMO backend. Zeta's retraction-native DBSP substrate can plausibly support EITHER pattern (or both). Competitive differentiators identified: - Retraction-native semantics (native rollback / lag-compensation / failed-transaction recovery). - Time-travel queries compose with persistent-universe replay / match-review. - Columnar storage serves game-economy analytics. CIG / RSI attribution preserved (Aaron supplied): Cloud Imperium Games = developer; Roberts Space Industries = publishing/marketing subsidiary + in-game ship manufacturer; founded April 2012 by Chris Roberts. Research deliverable: docs/research/server-meshing- spacetimedb-comparison-zeta-sharding-fit.md with 5 sections (SM architecture / SpacetimeDB architecture / Zeta fit / competitive positioning / integration scenarios). Customer-industry angle: 3-5 named studio-types (MMO / sim / esports / mobile persistent / VR-social) with value- proposition per segment. IP discipline (same pattern as Otto-175c + Scientology rows): no CIG proprietary content ingested beyond public Inside- Star-Citizen + RSI blog; SpacetimeDB Apache-2 code study fine; no positioning as CIG-adjacent or SpacetimeDB- adjacent in public branding (technical reference OK). Priority P2 research-grade; effort L (deep research) + L (design ADR when sharding graduates). Waits on Zeta multi-node foundation (not yet shipped). Placed in "## P2 — Post-v1 query-surface research" section at line ~921 — NOT BACKLOG tail — to avoid positional- append conflict pattern (53 DIRTY siblings on tail). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * fix(#352): 4 review-thread P1/P2s on Server Meshing BACKLOG row Applying PR-resolve-loop discipline to #352. 5 unresolved review threads (Copilot P2 inline-code-span + P1 cross-ref drift + P2 IP-discipline ambiguity + P1 inline-code-span duplicate + P1 line-reference drift). 4 addressed in this commit; resolution replies to follow via GraphQL. 1. Inline code span split across lines 1008-1009 (Copilot P2 threads 59XP74 + 59XSRN, duplicate finding): Moved the multi-line `docs/research/server-meshing-*.md` path onto its own line so the backtick-delimited span renders atomically per CommonMark. No more rendering risk. 2. "Otto-175c starship-franchise-mapping row" cross-ref that didn't resolve (Copilot P1 thread 59XSQc): Clarified the reference to note the row landed in PR #351 (merged). Amara 10th + 11th ferry cross-refs updated to point at their archived location under `docs/aurora/2026-04-24- amara-*.md` paths. 3. Wire-protocol row line-number reference was `~754`, actual location is `~830` (Copilot P1 thread 59XSRf): Corrected the line hint. 4. "No Star-Citizen trademarked content ingested" IP- discipline bullet was ambiguous — the row itself uses trademarked names for reference (Copilot P2 thread 59XSQz): Rewrote the discipline block to explicitly distinguish industry-landscape reference (permitted) from proprietary-content ingestion (excluded), with specific "research-permitted" boundaries for CIG's public Inside-Star-Citizen + RSI content and for SpacetimeDB's Apache-2 repo. Framing: this commit demonstrates the PR-resolve-loop pattern (BACKLOG row Otto-204, PR #356) on a second PR after the pattern was first applied to #354. Active management vs ship-and-pray. Part of the corrective response to Otto-204c livelock-diagnosis. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * fix(#352): 11th/12th ferry reference — drop forward-looking path (priors are pending absorbs PR #296 / PR #311) --------- Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
…ll (10 PRs) Otto-207: maintainer "are we saving these yet gitnative and have we backfilled them yet?" Honest answer was NO — the PR-preservation BACKLOG row (Otto-150..154, PR #335 in queue) specifies the discipline but never shipped the capture tooling. This PR ships the minimal viable implementation + backfills 10 PRs from this session. New tool: - tools/pr-preservation/archive-pr.sh — one-shot bash script that fetches a PR's review threads, reviews, and comments via `gh api graphql` and writes them to docs/pr-discussions/PR-<N>-<slug>.md with YAML frontmatter (pr_number / title / author / state / dates / refs / archived_at / archive_tool). - tools/pr-preservation/README.md — scope (Phase 0 minimal vs Phase 1-4 longer plan), usage, output schema, backfill status, dependencies (bash + python3 + gh; no external packages), cross-references to Otto-171 / Otto-204 / Otto-204c / PR #335. Backfill (10 PRs archived this tick): - PR #354 backlog-split Phase 1a - PR #352 Server Meshing + SpacetimeDB research - PR #336 KSK naming definition doc - PR #342 calibration-harness Stage-2 design (merged) - PR #344 Amara 19th ferry absorb (merged) - PR #346 DST compliance criteria (merged) - PR #350 Frontier rename pass-2 (merged) - PR #353 BACKLOG split Phase 0 design (merged) - PR #355 Codex first peer-agent deep-review absorb (merged) - PR #356 PR-resolve-loop skill row (merged) Total: 72 review threads + 40 reviews + 6 general comments captured across ~97KB of archive markdown. Long-term plan deliberately kept in BACKLOG row (Otto-150 ..154 / PR #335 queue elevation) rather than expanded in this commit's docs. Phase 0 shipping now; Phase 1 GHA workflow + Phase 2 historical backfill + Phase 3 reconciliation + Phase 4 redaction layer remain queued tickets. Per maintainer directive "make sure you backlog then to a proper long term solution" — the phased plan is already in PR #335 and covers the remaining work. Discipline applied: active-management on the preservation gap itself. Previous tick's "ship and pray" pattern is the exact failure mode this tool begins to close (operator- initiated archive instead of silent reliance on GitHub- side conversation storage). Composes with Otto-204c livelock-diagnosis memory + Otto-204 PR-resolve-loop skill (this script is step 4 of that cycle's conversation-preservation hook). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…ll (10 PRs) Otto-207: maintainer "are we saving these yet gitnative and have we backfilled them yet?" Honest answer was NO — the PR-preservation BACKLOG row (Otto-150..154, PR #335 in queue) specifies the discipline but never shipped the capture tooling. This PR ships the minimal viable implementation + backfills 10 PRs from this session. New tool: - tools/pr-preservation/archive-pr.sh — one-shot bash script that fetches a PR's review threads, reviews, and comments via `gh api graphql` and writes them to docs/pr-discussions/PR-<N>-<slug>.md with YAML frontmatter (pr_number / title / author / state / dates / refs / archived_at / archive_tool). - tools/pr-preservation/README.md — scope (Phase 0 minimal vs Phase 1-4 longer plan), usage, output schema, backfill status, dependencies (bash + python3 + gh; no external packages), cross-references to Otto-171 / Otto-204 / Otto-204c / PR #335. Backfill (10 PRs archived this tick): - PR #354 backlog-split Phase 1a - PR #352 Server Meshing + SpacetimeDB research - PR #336 KSK naming definition doc - PR #342 calibration-harness Stage-2 design (merged) - PR #344 Amara 19th ferry absorb (merged) - PR #346 DST compliance criteria (merged) - PR #350 Frontier rename pass-2 (merged) - PR #353 BACKLOG split Phase 0 design (merged) - PR #355 Codex first peer-agent deep-review absorb (merged) - PR #356 PR-resolve-loop skill row (merged) Total: 72 review threads + 40 reviews + 6 general comments captured across ~97KB of archive markdown. Long-term plan deliberately kept in BACKLOG row (Otto-150 ..154 / PR #335 queue elevation) rather than expanded in this commit's docs. Phase 0 shipping now; Phase 1 GHA workflow + Phase 2 historical backfill + Phase 3 reconciliation + Phase 4 redaction layer remain queued tickets. Per maintainer directive "make sure you backlog then to a proper long term solution" — the phased plan is already in PR #335 and covers the remaining work. Discipline applied: active-management on the preservation gap itself. Previous tick's "ship and pray" pattern is the exact failure mode this tool begins to close (operator- initiated archive instead of silent reliance on GitHub- side conversation storage). Composes with Otto-204c livelock-diagnosis memory + Otto-204 PR-resolve-loop skill (this script is step 4 of that cycle's conversation-preservation hook). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…ll (10 PRs) Otto-207: maintainer "are we saving these yet gitnative and have we backfilled them yet?" Honest answer was NO — the PR-preservation BACKLOG row (Otto-150..154, PR #335 in queue) specifies the discipline but never shipped the capture tooling. This PR ships the minimal viable implementation + backfills 10 PRs from this session. New tool: - tools/pr-preservation/archive-pr.sh — one-shot bash script that fetches a PR's review threads, reviews, and comments via `gh api graphql` and writes them to docs/pr-discussions/PR-<N>-<slug>.md with YAML frontmatter (pr_number / title / author / state / dates / refs / archived_at / archive_tool). - tools/pr-preservation/README.md — scope (Phase 0 minimal vs Phase 1-4 longer plan), usage, output schema, backfill status, dependencies (bash + python3 + gh; no external packages), cross-references to Otto-171 / Otto-204 / Otto-204c / PR #335. Backfill (10 PRs archived this tick): - PR #354 backlog-split Phase 1a - PR #352 Server Meshing + SpacetimeDB research - PR #336 KSK naming definition doc - PR #342 calibration-harness Stage-2 design (merged) - PR #344 Amara 19th ferry absorb (merged) - PR #346 DST compliance criteria (merged) - PR #350 Frontier rename pass-2 (merged) - PR #353 BACKLOG split Phase 0 design (merged) - PR #355 Codex first peer-agent deep-review absorb (merged) - PR #356 PR-resolve-loop skill row (merged) Total: 72 review threads + 40 reviews + 6 general comments captured across ~97KB of archive markdown. Long-term plan deliberately kept in BACKLOG row (Otto-150 ..154 / PR #335 queue elevation) rather than expanded in this commit's docs. Phase 0 shipping now; Phase 1 GHA workflow + Phase 2 historical backfill + Phase 3 reconciliation + Phase 4 redaction layer remain queued tickets. Per maintainer directive "make sure you backlog then to a proper long term solution" — the phased plan is already in PR #335 and covers the remaining work. Discipline applied: active-management on the preservation gap itself. Previous tick's "ship and pray" pattern is the exact failure mode this tool begins to close (operator- initiated archive instead of silent reliance on GitHub- side conversation storage). Composes with Otto-204c livelock-diagnosis memory + Otto-204 PR-resolve-loop skill (this script is step 4 of that cycle's conversation-preservation hook). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…ll (10 PRs) Otto-207: maintainer "are we saving these yet gitnative and have we backfilled them yet?" Honest answer was NO — the PR-preservation BACKLOG row (Otto-150..154, PR #335 in queue) specifies the discipline but never shipped the capture tooling. This PR ships the minimal viable implementation + backfills 10 PRs from this session. New tool: - tools/pr-preservation/archive-pr.sh — one-shot bash script that fetches a PR's review threads, reviews, and comments via `gh api graphql` and writes them to docs/pr-discussions/PR-<N>-<slug>.md with YAML frontmatter (pr_number / title / author / state / dates / refs / archived_at / archive_tool). - tools/pr-preservation/README.md — scope (Phase 0 minimal vs Phase 1-4 longer plan), usage, output schema, backfill status, dependencies (bash + python3 + gh; no external packages), cross-references to Otto-171 / Otto-204 / Otto-204c / PR #335. Backfill (10 PRs archived this tick): - PR #354 backlog-split Phase 1a - PR #352 Server Meshing + SpacetimeDB research - PR #336 KSK naming definition doc - PR #342 calibration-harness Stage-2 design (merged) - PR #344 Amara 19th ferry absorb (merged) - PR #346 DST compliance criteria (merged) - PR #350 Frontier rename pass-2 (merged) - PR #353 BACKLOG split Phase 0 design (merged) - PR #355 Codex first peer-agent deep-review absorb (merged) - PR #356 PR-resolve-loop skill row (merged) Total: 72 review threads + 40 reviews + 6 general comments captured across ~97KB of archive markdown. Long-term plan deliberately kept in BACKLOG row (Otto-150 ..154 / PR #335 queue elevation) rather than expanded in this commit's docs. Phase 0 shipping now; Phase 1 GHA workflow + Phase 2 historical backfill + Phase 3 reconciliation + Phase 4 redaction layer remain queued tickets. Per maintainer directive "make sure you backlog then to a proper long term solution" — the phased plan is already in PR #335 and covers the remaining work. Discipline applied: active-management on the preservation gap itself. Previous tick's "ship and pray" pattern is the exact failure mode this tool begins to close (operator- initiated archive instead of silent reliance on GitHub- side conversation storage). Composes with Otto-204c livelock-diagnosis memory + Otto-204 PR-resolve-loop skill (this script is step 4 of that cycle's conversation-preservation hook). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…ll (10 PRs) Otto-207: maintainer "are we saving these yet gitnative and have we backfilled them yet?" Honest answer was NO — the PR-preservation BACKLOG row (Otto-150..154, PR #335 in queue) specifies the discipline but never shipped the capture tooling. This PR ships the minimal viable implementation + backfills 10 PRs from this session. New tool: - tools/pr-preservation/archive-pr.sh — one-shot bash script that fetches a PR's review threads, reviews, and comments via `gh api graphql` and writes them to docs/pr-discussions/PR-<N>-<slug>.md with YAML frontmatter (pr_number / title / author / state / dates / refs / archived_at / archive_tool). - tools/pr-preservation/README.md — scope (Phase 0 minimal vs Phase 1-4 longer plan), usage, output schema, backfill status, dependencies (bash + python3 + gh; no external packages), cross-references to Otto-171 / Otto-204 / Otto-204c / PR #335. Backfill (10 PRs archived this tick): - PR #354 backlog-split Phase 1a - PR #352 Server Meshing + SpacetimeDB research - PR #336 KSK naming definition doc - PR #342 calibration-harness Stage-2 design (merged) - PR #344 Amara 19th ferry absorb (merged) - PR #346 DST compliance criteria (merged) - PR #350 Frontier rename pass-2 (merged) - PR #353 BACKLOG split Phase 0 design (merged) - PR #355 Codex first peer-agent deep-review absorb (merged) - PR #356 PR-resolve-loop skill row (merged) Total: 72 review threads + 40 reviews + 6 general comments captured across ~97KB of archive markdown. Long-term plan deliberately kept in BACKLOG row (Otto-150 ..154 / PR #335 queue elevation) rather than expanded in this commit's docs. Phase 0 shipping now; Phase 1 GHA workflow + Phase 2 historical backfill + Phase 3 reconciliation + Phase 4 redaction layer remain queued tickets. Per maintainer directive "make sure you backlog then to a proper long term solution" — the phased plan is already in PR #335 and covers the remaining work. Discipline applied: active-management on the preservation gap itself. Previous tick's "ship and pray" pattern is the exact failure mode this tool begins to close (operator- initiated archive instead of silent reliance on GitHub- side conversation storage). Composes with Otto-204c livelock-diagnosis memory + Otto-204 PR-resolve-loop skill (this script is step 4 of that cycle's conversation-preservation hook). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…ll (10 PRs) Otto-207: maintainer "are we saving these yet gitnative and have we backfilled them yet?" Honest answer was NO — the PR-preservation BACKLOG row (Otto-150..154, PR #335 in queue) specifies the discipline but never shipped the capture tooling. This PR ships the minimal viable implementation + backfills 10 PRs from this session. New tool: - tools/pr-preservation/archive-pr.sh — one-shot bash script that fetches a PR's review threads, reviews, and comments via `gh api graphql` and writes them to docs/pr-discussions/PR-<N>-<slug>.md with YAML frontmatter (pr_number / title / author / state / dates / refs / archived_at / archive_tool). - tools/pr-preservation/README.md — scope (Phase 0 minimal vs Phase 1-4 longer plan), usage, output schema, backfill status, dependencies (bash + python3 + gh; no external packages), cross-references to Otto-171 / Otto-204 / Otto-204c / PR #335. Backfill (10 PRs archived this tick): - PR #354 backlog-split Phase 1a - PR #352 Server Meshing + SpacetimeDB research - PR #336 KSK naming definition doc - PR #342 calibration-harness Stage-2 design (merged) - PR #344 Amara 19th ferry absorb (merged) - PR #346 DST compliance criteria (merged) - PR #350 Frontier rename pass-2 (merged) - PR #353 BACKLOG split Phase 0 design (merged) - PR #355 Codex first peer-agent deep-review absorb (merged) - PR #356 PR-resolve-loop skill row (merged) Total: 72 review threads + 40 reviews + 6 general comments captured across ~97KB of archive markdown. Long-term plan deliberately kept in BACKLOG row (Otto-150 ..154 / PR #335 queue elevation) rather than expanded in this commit's docs. Phase 0 shipping now; Phase 1 GHA workflow + Phase 2 historical backfill + Phase 3 reconciliation + Phase 4 redaction layer remain queued tickets. Per maintainer directive "make sure you backlog then to a proper long term solution" — the phased plan is already in PR #335 and covers the remaining work. Discipline applied: active-management on the preservation gap itself. Previous tick's "ship and pray" pattern is the exact failure mode this tool begins to close (operator- initiated archive instead of silent reliance on GitHub- side conversation storage). Composes with Otto-204c livelock-diagnosis memory + Otto-204 PR-resolve-loop skill (this script is step 4 of that cycle's conversation-preservation hook). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…ll (10 PRs) Otto-207: maintainer "are we saving these yet gitnative and have we backfilled them yet?" Honest answer was NO — the PR-preservation BACKLOG row (Otto-150..154, PR #335 in queue) specifies the discipline but never shipped the capture tooling. This PR ships the minimal viable implementation + backfills 10 PRs from this session. New tool: - tools/pr-preservation/archive-pr.sh — one-shot bash script that fetches a PR's review threads, reviews, and comments via `gh api graphql` and writes them to docs/pr-discussions/PR-<N>-<slug>.md with YAML frontmatter (pr_number / title / author / state / dates / refs / archived_at / archive_tool). - tools/pr-preservation/README.md — scope (Phase 0 minimal vs Phase 1-4 longer plan), usage, output schema, backfill status, dependencies (bash + python3 + gh; no external packages), cross-references to Otto-171 / Otto-204 / Otto-204c / PR #335. Backfill (10 PRs archived this tick): - PR #354 backlog-split Phase 1a - PR #352 Server Meshing + SpacetimeDB research - PR #336 KSK naming definition doc - PR #342 calibration-harness Stage-2 design (merged) - PR #344 Amara 19th ferry absorb (merged) - PR #346 DST compliance criteria (merged) - PR #350 Frontier rename pass-2 (merged) - PR #353 BACKLOG split Phase 0 design (merged) - PR #355 Codex first peer-agent deep-review absorb (merged) - PR #356 PR-resolve-loop skill row (merged) Total: 72 review threads + 40 reviews + 6 general comments captured across ~97KB of archive markdown. Long-term plan deliberately kept in BACKLOG row (Otto-150 ..154 / PR #335 queue elevation) rather than expanded in this commit's docs. Phase 0 shipping now; Phase 1 GHA workflow + Phase 2 historical backfill + Phase 3 reconciliation + Phase 4 redaction layer remain queued tickets. Per maintainer directive "make sure you backlog then to a proper long term solution" — the phased plan is already in PR #335 and covers the remaining work. Discipline applied: active-management on the preservation gap itself. Previous tick's "ship and pray" pattern is the exact failure mode this tool begins to close (operator- initiated archive instead of silent reliance on GitHub- side conversation storage). Composes with Otto-204c livelock-diagnosis memory + Otto-204 PR-resolve-loop skill (this script is step 4 of that cycle's conversation-preservation hook). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…ll (10 PRs) Otto-207: maintainer "are we saving these yet gitnative and have we backfilled them yet?" Honest answer was NO — the PR-preservation BACKLOG row (Otto-150..154, PR #335 in queue) specifies the discipline but never shipped the capture tooling. This PR ships the minimal viable implementation + backfills 10 PRs from this session. New tool: - tools/pr-preservation/archive-pr.sh — one-shot bash script that fetches a PR's review threads, reviews, and comments via `gh api graphql` and writes them to docs/pr-discussions/PR-<N>-<slug>.md with YAML frontmatter (pr_number / title / author / state / dates / refs / archived_at / archive_tool). - tools/pr-preservation/README.md — scope (Phase 0 minimal vs Phase 1-4 longer plan), usage, output schema, backfill status, dependencies (bash + python3 + gh; no external packages), cross-references to Otto-171 / Otto-204 / Otto-204c / PR #335. Backfill (10 PRs archived this tick): - PR #354 backlog-split Phase 1a - PR #352 Server Meshing + SpacetimeDB research - PR #336 KSK naming definition doc - PR #342 calibration-harness Stage-2 design (merged) - PR #344 Amara 19th ferry absorb (merged) - PR #346 DST compliance criteria (merged) - PR #350 Frontier rename pass-2 (merged) - PR #353 BACKLOG split Phase 0 design (merged) - PR #355 Codex first peer-agent deep-review absorb (merged) - PR #356 PR-resolve-loop skill row (merged) Total: 72 review threads + 40 reviews + 6 general comments captured across ~97KB of archive markdown. Long-term plan deliberately kept in BACKLOG row (Otto-150 ..154 / PR #335 queue elevation) rather than expanded in this commit's docs. Phase 0 shipping now; Phase 1 GHA workflow + Phase 2 historical backfill + Phase 3 reconciliation + Phase 4 redaction layer remain queued tickets. Per maintainer directive "make sure you backlog then to a proper long term solution" — the phased plan is already in PR #335 and covers the remaining work. Discipline applied: active-management on the preservation gap itself. Previous tick's "ship and pray" pattern is the exact failure mode this tool begins to close (operator- initiated archive instead of silent reliance on GitHub- side conversation storage). Composes with Otto-204c livelock-diagnosis memory + Otto-204 PR-resolve-loop skill (this script is step 4 of that cycle's conversation-preservation hook). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…0 PRs) (#357) * tools: PR-preservation minimal archive tool + Otto-207 session backfill (10 PRs) Otto-207: maintainer "are we saving these yet gitnative and have we backfilled them yet?" Honest answer was NO — the PR-preservation BACKLOG row (Otto-150..154, PR #335 in queue) specifies the discipline but never shipped the capture tooling. This PR ships the minimal viable implementation + backfills 10 PRs from this session. New tool: - tools/pr-preservation/archive-pr.sh — one-shot bash script that fetches a PR's review threads, reviews, and comments via `gh api graphql` and writes them to docs/pr-discussions/PR-<N>-<slug>.md with YAML frontmatter (pr_number / title / author / state / dates / refs / archived_at / archive_tool). - tools/pr-preservation/README.md — scope (Phase 0 minimal vs Phase 1-4 longer plan), usage, output schema, backfill status, dependencies (bash + python3 + gh; no external packages), cross-references to Otto-171 / Otto-204 / Otto-204c / PR #335. Backfill (10 PRs archived this tick): - PR #354 backlog-split Phase 1a - PR #352 Server Meshing + SpacetimeDB research - PR #336 KSK naming definition doc - PR #342 calibration-harness Stage-2 design (merged) - PR #344 Amara 19th ferry absorb (merged) - PR #346 DST compliance criteria (merged) - PR #350 Frontier rename pass-2 (merged) - PR #353 BACKLOG split Phase 0 design (merged) - PR #355 Codex first peer-agent deep-review absorb (merged) - PR #356 PR-resolve-loop skill row (merged) Total: 72 review threads + 40 reviews + 6 general comments captured across ~97KB of archive markdown. Long-term plan deliberately kept in BACKLOG row (Otto-150 ..154 / PR #335 queue elevation) rather than expanded in this commit's docs. Phase 0 shipping now; Phase 1 GHA workflow + Phase 2 historical backfill + Phase 3 reconciliation + Phase 4 redaction layer remain queued tickets. Per maintainer directive "make sure you backlog then to a proper long term solution" — the phased plan is already in PR #335 and covers the remaining work. Discipline applied: active-management on the preservation gap itself. Previous tick's "ship and pray" pattern is the exact failure mode this tool begins to close (operator- initiated archive instead of silent reliance on GitHub- side conversation storage). Composes with Otto-204c livelock-diagnosis memory + Otto-204 PR-resolve-loop skill (this script is step 4 of that cycle's conversation-preservation hook). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * fix(#357): bot→agent terminology per GOVERNANCE §3 (maintainer Otto-208) Maintainer Otto-208 flag on Phase 4 redaction-layer wording: "No redaction — bot content + human content ... bot=agent." Applied the Otto-156 pattern: Copilot + Codex + Claude Code personas + github-actions are AGENTS with agency and accountability (GOVERNANCE §3 + CLAUDE.md "Agents, not bots."). Updated Phase 4 wording: - "bot-review comments (Copilot, Codex) archive verbatim" → "agent-review comments (Copilot, Codex, Claude Code personas, github-actions) archive verbatim" - Added explicit pointer to GOVERNANCE §3 + CLAUDE.md terminology convention. PR body edit follows separately via `gh pr edit`. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * fix(#357): 9 review threads — paginate, null-check, dynamic repo, YAML quoting, README alignment, trailing-ws strip Addresses all 9 unresolved Copilot + Codex threads on PR #357 (Otto-226 review-drain discipline, three-outcome model: fix). Script changes (tools/pr-preservation/archive-pr.sh): - Paginate reviewThreads / reviews / comments at the top level AND per-thread comments via cursor loops (threads 1 + 6 — no silent truncation). - Validate `pullRequest != null` and detect top-level GraphQL `errors` before dereferencing (threads 2 + 4). - Capture `gh api graphql` exit code explicitly instead of letting `set -e` swallow the diagnostic path (thread 3). - Derive owner/name dynamically from `gh repo view --json nameWithOwner` with a hard-fail if detection fails — works from forks and after rename (thread 5). - Quote all YAML frontmatter string values via `json.dumps` (title / author / state / ISO timestamps / head_ref / base_ref / archived_at / archive_tool), so refs with `#` or `:` don't break parsing (thread 7). Documentation alignment: - README now shows zero-padded filename shape `PR-<NNNN>-<slug>.md` (e.g. `PR-0357-...`) matching the script's output (thread 8 — chose "align README to script" since the 10 backfilled files already use the zero-padded form and renaming them would churn links). - README notes pagination is in place (no more "may be truncated" silent-behaviour gap tied to thread 6). Backfilled archives: - Stripped trailing whitespace across all existing `docs/pr-discussions/*.md` via `perl -i -pe 's/[ \t]+$//'` (thread 9 — MD009 compliance for the CI markdownlint gate). Also adds `docs/pr-discussions/PR-0357-...md` as the self-hosting smoke test: the archive tool successfully drains its own review queue. Validation: - `bash -n` clean - `shellcheck` clean (no findings) - End-to-end: `./tools/pr-preservation/archive-pr.sh 357` writes 9 threads / 2 reviews / 0 comments to 12179 bytes - Error path: PR #99999 exits 2 with clear diagnostic Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * fix(#357): Codex pagination P2 — backlog row for per-connection cursor refactor * fix(#357): 8 review threads — integer PR validation, trailing-ws preservation, MD012 blank-line collapse, README/header filename shape + bash dep Second drain pass on PR #357 review threads. Eight threads from agent reviewers; all fix-in-place. Script changes (`tools/pr-preservation/archive-pr.sh`): - Integer validation on `$PR` in the shell (pre-Python) — prevents a Python traceback + generic "fetch failed exit 2" diagnostic when a typo / non-integer is passed. - Dropped the per-line `rstrip()` normalization. Markdown uses two trailing spaces as a hard-line-break; this tool is a faithful audit copy and must preserve that intent. - Added a blank-line-run collapse (3+ consecutive blank lines -> 2) so generated archives stay clean under markdownlint MD012 without destroying user-authored formatting. - Header comment now documents the zero-padded `PR-<NNNN>-<slug>` filename shape (matches the implementation + README). - Header comment on repo-detection aligned with actual behavior (requires `gh repo view`, no silent fallback). README changes (`tools/pr-preservation/README.md`): - Intro uses `PR-<NNNN>-<slug>.md` (matches Usage + implementation). - Dependency relaxed from `bash 4+` to `bash` with a note — the script uses no bash-4-only features and macOS ships bash 3.2. Backfilled archives regenerated under the new collapse rule so they stop tripping MD012: - PR-0350 (Frontier rename pass-2) - PR-0352 (Server Meshing / SpacetimeDB deep research) - PR-0354 (backlog-split Phase 1a) - PR-0357 (this PR — self-archive re-fetched) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * fix(#357): 2 Codex P2 threads — PR-number stable filename key + preserve leading whitespace in archived bodies Third-round review-thread drain on `tools/pr-preservation/archive-pr.sh`: - `PRRT_kwDOSF9kNM59bWi5` (line 325): archive filename was derived from the title slug, so editing a PR title would write a second file instead of updating the existing record. Fix: PR number is now the canonical archive key. On re-archive, glob for an existing `PR-<NNNN>-*.md` and reuse its path regardless of current title. New PRs still land at `PR-<NNNN>-<slug>.md`. - `PRRT_kwDOSF9kNM59bWi_` (line 369 + lines 388, 401): `.strip()` normalised review / thread-comment / general-comment bodies and destroyed semantically-significant leading indentation (indented code blocks, nested bullets). Switched to `.rstrip('\n')` so only trailing newlines are stripped; leading whitespace survives. Smoke tested: `./archive-pr.sh 357` writes back to the same file (no new PR-0357-* orphan), bash -n + shellcheck clean, diff shows preserved `<details>` internal structure and indentation in archive. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * fix(#357): 6 review threads — drop truncation-warning claim, preserve last-line hard-line-breaks, normalize whitespace-only lines Fourth drain pass on PR #357. Addresses 6 new P0 threads from re-review: - archive-pr.sh header said "Pagination + truncation warning for threads (>100)" but implementation only paginates, never emits a warning. Claim removed; comment now matches behaviour. - `body.rstrip()` on the PR-description block stripped trailing spaces from the last line (kills markdown " \n" hard-line breaks). Changed to `body.rstrip('\n')`. - End-of-file `content.rstrip()` had the same problem — end-of- file hard-line-break would be lost. Changed to `content.rstrip('\n')` in both places (pre- and post-blank- line-collapse). - Whitespace-only lines (e.g. " " from Codex connector comments) tripped markdownlint MD009. Added a post-collapse normalization step: lines containing only whitespace are normalized to empty, while lines with any non-whitespace character keep trailing whitespace intact (two-space hard-line-breaks survive). Regenerated four affected archives: PR-0350, PR-0352, PR-0354, PR-0357. Verified: zero whitespace-only lines, zero 3+ blank- line runs across all archives. Syntax / shellcheck clean. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * fix(#357): Codex P1 audit-fidelity carve-out — skip blank-line collapse inside fenced code blocks Codex review thread on PR #357 (line 486, P1, unresolved after 4 prior drain rounds): the formatter globally collapses every run of blank lines to at most 2 after assembling the archive, which silently rewrites user-authored bodies. In PR comments / reviews that include fenced code blocks, logs, or templates where 3+ consecutive blank lines are intentional, this changes the preserved content and breaks the script's stated audit-fidelity goal. Narrow fix: toggle code-fence state while scanning (``` / ~~~ at the start of a line, ignoring leading whitespace), and SKIP both the blank-line-run collapse and the whitespace-only normalization inside fenced regions. Outside fences, MD012 / MD009 hygiene still applies to tool-generated scaffolding so archives stay lint-clean. Rationale: markdownlint MD012 already exempts fenced code from the "no multiple consecutive blank lines" rule by design, so this fix aligns with the linter's own semantics. Fenced regions in PR review text are exactly where audit fidelity must win over scaffolding hygiene — that is where logs, templates, and preformatted payloads live. Smoke-tested against PR #357 itself: re-running archive-pr.sh 357 produces a 107-line diff of recovered content (mostly inside the <details> fenced blocks from Codex / Copilot connector payloads that the prior collapse was truncating). Archive-file churn reverted on this branch — archive regeneration belongs in a separate PR, not here. Gates: `bash -n` clean + `shellcheck` clean. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * drain(#357): fence-marker type-match + gh --jq consistency Two Codex/Copilot threads on #357's archive-pr.sh: 1. **Codex P2 — fence detector conflates ``` and ~~~.** CommonMark requires the closing fence to use the SAME marker character as the opener (backticks close backticks; tildes close tildes). The previous `in_fence = not in_fence` on any fence-shaped line would prematurely close a backtick fence when a tilde line appeared inside it (and vice versa). Fix: track fence_marker on open, only flip back to False when the marker matches. Different-marker fence lines inside an open fence fall through to the verbatim branch so they're preserved as content. 2. **Copilot — `gh repo view -q` → `--jq` for consistency.** Other repo scripts (e.g. tools/hygiene/check-github-settings-drift.sh) use `--jq`. Switching to the long form matches the rest of the factory's gh invocations and avoids any `-q` ambiguity across gh versions. Bash -n syntax check passes. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * drain(#357): REPO_ROOT git-tree guard + mktemp template + fence-length tracking + README cross-ref Five Copilot + Codex threads: 1. **REPO_ROOT bogus-path risk.** `git rev-parse --show-toplevel || pwd` falls back to pwd outside a git checkout, but `gh repo view` can succeed via `gh repo set-default`, so the script could write docs/pr-discussions/ into a bogus REPO_ROOT directory. Hard-fail when not inside a git working tree. 2. **mktemp portability.** Plain `mktemp` with no template works on GNU coreutils (Linux) but fails on BSD mktemp (macOS). README advertises macOS support, so added `-t zeta-archive-pr.XXXXXX` template that works on both. 3. **Fence-length tracking (Codex P2 + Copilot).** Prior fix tracked marker TYPE (backtick vs tilde) but not fence LENGTH. Per CommonMark §4.5, the closing fence must be at least as long as the opener — a 4-backtick opener contains a 3-backtick line as content, not a closer. Now tracks both marker + length on open; closer must match BOTH. 4. **README cross-ref correction.** Canonical source for "agents, not bots" terminology is GOVERNANCE.md §3 ("Contributors are agents, not bots"). CLAUDE.md carries a session-bootstrap pointer at the same rule. Reworded to name GOVERNANCE as canonical with CLAUDE.md as the pointer. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Summary
Maintainer Otto-204 directive: "you need some pr resolve loop that will handled everyting needed to take a pr to compelteion so you don't ahve to keep figuion it out" + "we are saving you resolution to all the comments and we expect those to be excellent don't take shortcuts on the feedback, do the right long term thing or backlog the right thing and not it on the comment."
New P1 CI/DX BACKLOG row filing the PR-resolve-loop skill — 6-step close-the-PR cycle:
artifacts/pr-discussions/)Core learning captured
Active PR management has 10-20× higher ROI than opening new PRs when queue is saturated. The Otto-200..203 "queue unchanged 136 for 6+ ticks" observation misread passive-stuck as livelock — actual blocker was accumulated unresolved review-threads + silent lint failures that armed auto-merge couldn't overcome.
This PR was filed AFTER demonstrating the pattern on #354 directly (fixed shellcheck SC2034/SC2295 + addressed 10 of 12 review threads + left 2 as breadcrumbs with rationale).
Non-goals
Placement
P1 CI/DX section line 2469, NOT BACKLOG tail. Single-row add.
Test plan
🤖 Generated with Claude Code