Skip to content

tools: PR-preservation minimal archive + Otto-207 session backfill (10 PRs)#357

Merged
AceHack merged 10 commits intomainfrom
tools/pr-preservation-phase-2-minimal
Apr 25, 2026
Merged

tools: PR-preservation minimal archive + Otto-207 session backfill (10 PRs)#357
AceHack merged 10 commits intomainfrom
tools/pr-preservation-phase-2-minimal

Conversation

@AceHack
Copy link
Copy Markdown
Member

@AceHack AceHack commented Apr 24, 2026

Summary

Maintainer Otto-207: "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 elevating to P1 + phased plan) specifies the discipline but never shipped capture tooling. This PR ships Phase 0 minimal viable implementation + backfills 10 PRs from this session.

Tool

tools/pr-preservation/archive-pr.sh — one-shot bash script:

  • Fetches review threads + reviews + comments via gh api graphql
  • Writes docs/pr-discussions/PR-<N>-<slug>.md with YAML frontmatter
  • Sections: PR description · Reviews · Review threads (with resolved/unresolved) · General comments
  • No external deps beyond gh + python3 stdlib + bash 4+

Backfill (10 PRs this session)

PR Status Threads Reviews Comments
#354 backlog-split Phase 1a OPEN 20 16 1
#352 Server Meshing research OPEN 6 8 0
#336 KSK naming doc OPEN 8 8 1
#342 calibration-harness design MERGED 5 1 1
#344 Amara 19th ferry absorb MERGED 8 1 1
#346 DST compliance criteria MERGED 5 1 1
#350 Frontier rename pass-2 MERGED 4 2 0
#353 BACKLOG split design MERGED 6 1 0
#355 Codex peer-review absorb MERGED 5 1 1
#356 PR-resolve-loop row MERGED 5 1 0

Total: 72 threads + 40 reviews + 6 comments across ~97KB markdown.

Long-term plan (per maintainer directive)

Remaining phases kept in the PR-preservation BACKLOG row (PR #335 in queue):

  • Phase 1 — GHA workflow on merge (automatic archive)
  • Phase 2 — historical backfill (all merged PRs)
  • Phase 3 — reconciliation (drift detection)
  • Phase 4 — redaction layer (privacy-pass for human-reviewer comments)

Scope out of this PR per maintainer "make sure you backlog then to a proper long term solution".

Composes with

Test plan

🤖 Generated with Claude Code

Copilot AI review requested due to automatic review settings April 24, 2026 11:23
@AceHack AceHack enabled auto-merge (squash) April 24, 2026 11:23
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: cc217ae031

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread tools/pr-preservation/archive-pr.sh Outdated
Comment thread tools/pr-preservation/archive-pr.sh Outdated
AceHack added a commit that referenced this pull request Apr 24, 2026
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>
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 minimal, git-tracked PR-conversation preservation tool (tools/pr-preservation/archive-pr.sh) and backfills 10 PR discussion archives into docs/pr-discussions/, aligning with the project’s “git-native preservation” direction.

Changes:

  • Add a one-shot bash + gh api graphql + Python-stdlib script to export PR metadata, reviews, review threads, and general comments into markdown files under docs/pr-discussions/.
  • Add usage + output-schema documentation for the preservation tool.
  • Commit 10 backfilled PR archive markdown files for this session.

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
tools/pr-preservation/README.md Documents scope, usage, and the intended archive schema/location for PR preservation.
tools/pr-preservation/archive-pr.sh Implements the PR fetch + markdown archive writer via GitHub GraphQL + Python formatting.
docs/pr-discussions/PR-0356-backlog-otto-204-pr-resolve-loop-skill-close-the-pr-cycle-au.md Backfilled archive for PR #356 discussion content.
docs/pr-discussions/PR-0355-ferry-codex-first-completed-peer-agent-deep-review-absorb-4.md Backfilled archive for PR #355 discussion content.
docs/pr-discussions/PR-0354-tools-backlog-split-phase-1a-generator-schema-example-row-aa.md Backfilled archive for PR #354 discussion content.
docs/pr-discussions/PR-0353-docs-backlog-md-split-design-phase-0-aaron-otto-181-3rd-ask.md Backfilled archive for PR #353 discussion content.
docs/pr-discussions/PR-0352-backlog-otto-180-server-meshing-spacetimedb-deep-research-ga.md Backfilled archive for PR #352 discussion content.
docs/pr-discussions/PR-0350-docs-frontier-rename-pass-2-hindu-ff7-egyptian-greek-norse-s.md Backfilled archive for PR #350 discussion content.
docs/pr-discussions/PR-0346-docs-dst-compliance-criteria-dst-held-foundationdb-grade-bar.md Backfilled archive for PR #346 discussion content.
docs/pr-discussions/PR-0344-ferry-amara-19th-absorb-dst-audit-5-5-corrections-10-tracked.md Backfilled archive for PR #344 discussion content.
docs/pr-discussions/PR-0342-docs-calibration-harness-stage-2-design-amara-18th-ferry-b-f.md Backfilled archive for PR #342 discussion content.
docs/pr-discussions/PR-0336-docs-ksk-naming-definition-doc-canonical-expansion-locked-ot.md Backfilled archive for PR #336 discussion content.

Comment thread tools/pr-preservation/archive-pr.sh Outdated
Comment thread tools/pr-preservation/archive-pr.sh Outdated
Comment thread tools/pr-preservation/archive-pr.sh Outdated
Comment thread tools/pr-preservation/archive-pr.sh Outdated
Comment thread tools/pr-preservation/archive-pr.sh Outdated
Comment thread tools/pr-preservation/README.md Outdated
@AceHack AceHack force-pushed the tools/pr-preservation-phase-2-minimal branch from cfbda45 to 66e48f0 Compare April 24, 2026 13:21
AceHack added a commit that referenced this pull request Apr 24, 2026
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>
AceHack added a commit that referenced this pull request Apr 24, 2026
…L 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>
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 66e48f0630

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread tools/pr-preservation/archive-pr.sh
Copilot AI review requested due to automatic review settings April 24, 2026 13:41
@AceHack AceHack force-pushed the tools/pr-preservation-phase-2-minimal branch from 66e48f0 to dfc8ef5 Compare April 24, 2026 13:41
AceHack added a commit that referenced this pull request Apr 24, 2026
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>
AceHack added a commit that referenced this pull request Apr 24, 2026
…L 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>
AceHack added a commit that referenced this pull request Apr 24, 2026
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: dfc8ef554f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread tools/pr-preservation/archive-pr.sh Outdated
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

Copilot reviewed 14 out of 14 changed files in this pull request and generated 7 comments.

Comment thread tools/pr-preservation/archive-pr.sh Outdated
Comment thread tools/pr-preservation/archive-pr.sh
Comment thread tools/pr-preservation/archive-pr.sh
Comment thread tools/pr-preservation/README.md Outdated
Comment thread tools/pr-preservation/README.md Outdated
Comment thread tools/pr-preservation/archive-pr.sh Outdated
@AceHack AceHack force-pushed the tools/pr-preservation-phase-2-minimal branch from dfc8ef5 to a5331f7 Compare April 24, 2026 14:38
AceHack added a commit that referenced this pull request Apr 24, 2026
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>
AceHack added a commit that referenced this pull request Apr 24, 2026
…L 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>
AceHack added a commit that referenced this pull request Apr 24, 2026
AceHack added a commit that referenced this pull request Apr 24, 2026
…ervation, 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>
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a5331f79e5

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread tools/pr-preservation/archive-pr.sh Outdated
Comment thread tools/pr-preservation/archive-pr.sh Outdated
Copilot AI review requested due to automatic review settings April 24, 2026 14:50
@AceHack AceHack force-pushed the tools/pr-preservation-phase-2-minimal branch from a5331f7 to 549369f Compare April 24, 2026 14:50
AceHack added a commit that referenced this pull request Apr 24, 2026
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>
AceHack added a commit that referenced this pull request Apr 24, 2026
…L 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>
AceHack added a commit that referenced this pull request Apr 24, 2026
AceHack added a commit that referenced this pull request Apr 24, 2026
…ervation, 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>
AceHack added a commit that referenced this pull request Apr 24, 2026
AceHack added a commit that referenced this pull request Apr 24, 2026
…ervation, 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>
AceHack added a commit that referenced this pull request Apr 24, 2026
…rve 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>
AceHack added a commit that referenced this pull request Apr 24, 2026
… 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>
AceHack added a commit that referenced this pull request Apr 24, 2026
…se 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>
AceHack added a commit that referenced this pull request Apr 25, 2026
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>
Copilot AI review requested due to automatic review settings April 25, 2026 02:26
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

Copilot reviewed 14 out of 14 changed files in this pull request and generated 4 comments.

Comment thread tools/pr-preservation/archive-pr.sh Outdated
Comment thread tools/pr-preservation/archive-pr.sh Outdated
Comment thread tools/pr-preservation/README.md Outdated
Comment thread tools/pr-preservation/archive-pr.sh Outdated
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9143752655

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread tools/pr-preservation/archive-pr.sh
AceHack added a commit that referenced this pull request Apr 25, 2026
…tion/** as verbatim-preservation archives

The pr-preservation archive (Otto-250) + session-backfill pr-discussions
files are verbatim preservation of PR bodies + review-thread content.
Output carries the input markdown structure unchanged — duplicate
"Pull request overview" headings from GitHub's auto-preamble, blank-line
spacing from the source, etc.

Reformatting archive output to satisfy MD032 (blanks-around-lists),
MD024 (no-duplicate-heading), MD012 (no-multiple-blanks) would violate
the verbatim-preservation contract (same principle that exempted
docs/amara-full-conversation/ from lint). Archive-generated files are
not author-controlled prose.

The scripts that generate these archives already ship their own hygiene
pass (tools/pr-preservation/archive-pr.sh). Markdownlint's job is to
catch authoring-class issues; preservation-class is a different contract.

Unblocks #357 markdownlint failure on the 10-PR session-backfill it
carries. Composes with Otto-250 pr-preservation discipline + Otto-279
pr-preservation-is-history-surface policy.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
AceHack added a commit that referenced this pull request Apr 25, 2026
…ise.toml + bump 0.18.1→0.22.1

Two tightly-related fixes bundled:

1. **Ignore preservation archives.** docs/pr-discussions/** and
   docs/pr-preservation/** are verbatim preservation of PR bodies
   + review-thread content. Archive output carries the input markdown
   structure unchanged — duplicate "Pull request overview" headings
   from GitHub's auto-preamble, blank-line spacing from the source,
   etc. Reformatting would violate the verbatim-preservation
   contract (Otto-250 + Otto-279). Adds these paths to
   .markdownlint-cli2.jsonc's existing ignores list alongside
   docs/amara-full-conversation/ which follows the same pattern.

2. **Declarative version pin.** Per Aaron's 2026-04-24 directive
   *"need to update declarativly everywhere"*, moved
   markdownlint-cli2 from hardcoded npm install in
   .github/workflows/gate.yml to .mise.toml using the
   `npm:markdownlint-cli2` backend (confirmed supported by mise-
   versions.jdx.dev). gate.yml now uses the same three-way-parity
   pattern as shellcheck and actionlint: `./tools/setup/install.sh`
   to install, then `mise exec -- markdownlint-cli2 ...` to run.
   Single source of truth — same version on dev laptops + CI runners.

3. **Version bump 0.18.1 → 0.22.1.** Old pin was stale (4+ minor
   versions behind). Verified 0.22.1 is npm latest as of 2026-04-24
   (published hours ago per npmjs.com). shellcheck 0.11.0 and
   actionlint 1.7.12 confirmed already current; no bump needed
   there.

Unblocks #357 markdownlint failure on the 10-PR session-backfill
it carries. Composes with Otto-247 version-currency-always-search-
first, GOVERNANCE §24 three-way-parity, Otto-250 pr-preservation.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
AceHack added a commit that referenced this pull request Apr 25, 2026
…ise.toml + bump 0.18.1→0.22.1 (#409)

Two tightly-related fixes bundled:

1. **Ignore preservation archives.** docs/pr-discussions/** and
   docs/pr-preservation/** are verbatim preservation of PR bodies
   + review-thread content. Archive output carries the input markdown
   structure unchanged — duplicate "Pull request overview" headings
   from GitHub's auto-preamble, blank-line spacing from the source,
   etc. Reformatting would violate the verbatim-preservation
   contract (Otto-250 + Otto-279). Adds these paths to
   .markdownlint-cli2.jsonc's existing ignores list alongside
   docs/amara-full-conversation/ which follows the same pattern.

2. **Declarative version pin.** Per Aaron's 2026-04-24 directive
   *"need to update declarativly everywhere"*, moved
   markdownlint-cli2 from hardcoded npm install in
   .github/workflows/gate.yml to .mise.toml using the
   `npm:markdownlint-cli2` backend (confirmed supported by mise-
   versions.jdx.dev). gate.yml now uses the same three-way-parity
   pattern as shellcheck and actionlint: `./tools/setup/install.sh`
   to install, then `mise exec -- markdownlint-cli2 ...` to run.
   Single source of truth — same version on dev laptops + CI runners.

3. **Version bump 0.18.1 → 0.22.1.** Old pin was stale (4+ minor
   versions behind). Verified 0.22.1 is npm latest as of 2026-04-24
   (published hours ago per npmjs.com). shellcheck 0.11.0 and
   actionlint 1.7.12 confirmed already current; no bump needed
   there.

Unblocks #357 markdownlint failure on the 10-PR session-backfill
it carries. Composes with Otto-247 version-currency-always-search-
first, GOVERNANCE §24 three-way-parity, Otto-250 pr-preservation.

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
AceHack and others added 10 commits April 24, 2026 22:39
…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>
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>
…L 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>
…ervation, 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>
…rve 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>
… 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>
…se 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>
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>
…h 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>
@AceHack AceHack force-pushed the tools/pr-preservation-phase-2-minimal branch from 9143752 to 737192b Compare April 25, 2026 02:41
@AceHack AceHack merged commit 9c325c0 into main Apr 25, 2026
13 checks passed
@AceHack AceHack deleted the tools/pr-preservation-phase-2-minimal branch April 25, 2026 02:43
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 737192b479

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread tools/pr-preservation/archive-pr.sh
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