Skip to content

backlog: Otto-204 PR-resolve-loop skill — close-the-PR cycle automation (active management > ship-and-pray)#356

Merged
AceHack merged 1 commit intomainfrom
backlog/otto-204-pr-resolve-loop-skill
Apr 24, 2026
Merged

backlog: Otto-204 PR-resolve-loop skill — close-the-PR cycle automation (active management > ship-and-pray)#356
AceHack merged 1 commit intomainfrom
backlog/otto-204-pr-resolve-loop-skill

Conversation

@AceHack
Copy link
Copy Markdown
Member

@AceHack AceHack commented Apr 24, 2026

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:

  1. CI-status check → fix failures
  2. Review-thread enumeration → reply-then-resolve (never shortcut)
  3. Name-attribution lint (factory-produced vs audit-trail distinction)
  4. Conversation-preservation hook (writes to artifacts/pr-discussions/)
  5. Auto-merge re-arm
  6. Loop-exit on merge / maintainer-escalation / external-blocker

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

  • NOT auto-merge bypass
  • NOT shortcut around reviewer intent
  • NOT retry-loop on flake
  • NOT opener of new PRs

Placement

P1 CI/DX section line 2469, NOT BACKLOG tail. Single-row add.

Test plan

  • Markdownlint clean
  • Single-location edit; placed away from DIRTY tail
  • BACKLOG-only change

🤖 Generated with Claude Code

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>
Copilot AI review requested due to automatic review settings April 24, 2026 11:05
@AceHack AceHack enabled auto-merge (squash) April 24, 2026 11:05
@AceHack AceHack merged commit 12ae740 into main Apr 24, 2026
12 checks passed
@AceHack AceHack deleted the backlog/otto-204-pr-resolve-loop-skill branch April 24, 2026 11:07
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread docs/BACKLOG.md
Comment on lines +2532 to +2533
`mergeStateStatus: MERGEABLE` (not BEHIND, DIRTY,
or BLOCKED), re-arm `gh pr merge --auto --squash`.
Copy link

Copilot AI Apr 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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).

Suggested change
`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`.

Copilot uses AI. Check for mistakes.
Comment thread docs/BACKLOG.md
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-
Copy link

Copilot AI Apr 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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).

Suggested change
+ resolve operation logs to `artifacts/pr-
and resolve operation logs to `artifacts/pr-

Copilot uses AI. Check for mistakes.
Comment thread docs/BACKLOG.md
Comment on lines +2524 to +2528
+ 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
Copy link

Copilot AI Apr 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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).

Suggested change
+ 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

Copilot uses AI. Check for mistakes.
Comment thread docs/BACKLOG.md

- NOT an auto-merge-bypass. The skill doesn't override
branch protection; it honors the 5 required checks
+ review-resolution gate faithfully.
Copy link

Copilot AI Apr 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 +.

Suggested change
+ review-resolution gate faithfully.
and review-resolution gate faithfully.

Copilot uses AI. Check for mistakes.
Comment thread docs/BACKLOG.md
Comment on lines +2472 to +2473
close-the-PR cycle (CI-failures + review-conversations
+ agent-comment preservation + auto-merge arm) so Otto
Copy link

Copilot AI Apr 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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).

Suggested change
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

Copilot uses AI. Check for mistakes.
AceHack added a commit that referenced this pull request Apr 24, 2026
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>
AceHack added a commit that referenced this pull request Apr 24, 2026
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>
AceHack added a commit that referenced this pull request Apr 24, 2026
…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>
AceHack added a commit that referenced this pull request Apr 24, 2026
…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>
AceHack added a commit that referenced this pull request Apr 24, 2026
…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>
AceHack added a commit that referenced this pull request Apr 24, 2026
…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>
AceHack added a commit that referenced this pull request Apr 24, 2026
…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>
AceHack added a commit that referenced this pull request Apr 24, 2026
…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>
AceHack added a commit that referenced this pull request Apr 24, 2026
…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>
AceHack added a commit that referenced this pull request Apr 24, 2026
…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>
AceHack added a commit that referenced this pull request Apr 25, 2026
…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>
AceHack added a commit that referenced this pull request Apr 25, 2026
…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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants