Skip to content

ci(gate): skip F#/dotnet build steps on docs-only PRs (B-0125 path-filter — immune-system tuning)#1185

Merged
AceHack merged 3 commits intomainfrom
ci/build-and-test-skip-on-docs-only-prs-2026-05-02
May 2, 2026
Merged

ci(gate): skip F#/dotnet build steps on docs-only PRs (B-0125 path-filter — immune-system tuning)#1185
AceHack merged 3 commits intomainfrom
ci/build-and-test-skip-on-docs-only-prs-2026-05-02

Conversation

@AceHack
Copy link
Copy Markdown
Member

@AceHack AceHack commented May 2, 2026

Summary

Implements B-0125 — skips the F#/dotnet Install toolchain + Build + Test steps in build-and-test (3-OS matrix) on docs-only PRs. F# build is the long pole on docs-only PRs at 5-10min per OS-leg with no signal; this lane-split makes docs PRs gate in ~1-2min instead of ~10min.

Aaron 2026-05-02 framing during this work: "gate.yml you know this is our immune system right you even called it gate was that intential?"

gate.yml IS the factory's immune system at the code-substrate layer. This PR is immune-system tuning — relax the gate's sensitivity per-PR-class (docs-only PRs don't need code-substrate guards) without weakening its protective function on actual code surfaces. Same architectural shape as the Aurora oracle/gate dual at the operational layer (PR #1183).

How

  1. New path-filter job runs once on ubuntu-24.04 after matrix-setup. Diffs pull_request.base.sha..pull_request.head.sha to enumerate changed files. Emits boolean output code:

    • code=true for any change that touches src/**, tests/**, tools/**, .github/workflows/**, *.fs / *.fsproj / *.csproj, global.json, Directory.Packages.props, .config/dotnet-tools.json, Zeta.sln, or root-level non-.md files
    • code=false for pure-docs PRs (touching only docs/**, memory/**, openspec/**, .claude/**, root *.md, LICENSE, *.txt, .gitignore, .gitattributes, .github/ISSUE_TEMPLATE/**, .github/PULL_REQUEST_TEMPLATE.md, .github/copilot-instructions.md)
  2. build-and-test now depends on [matrix-setup, path-filter]. The three expensive steps gain if: needs.path-filter.outputs.code == 'true'. A status-check passthrough echo step runs when skipped, so the job completes green.

Required-status-check compatibility

build-and-test (ubuntu-24.04) etc. STILL RUN on docs-only PRs — only their internal heavy steps are skipped. This is required because code_quality severity:all reads skipped jobs as failure, not success. The job-level structure is preserved so the ruleset sees the same set of green required checks.

Safety defaults

All non-PR events (push to main, merge_group, workflow_dispatch, schedule) emit code=true unconditionally. Path-filter is a per-PR optimization, never a main-tip skip mechanism. Once a docs-only PR merges, the push-to-main run still does the full F# build, catching anything the per-PR run skipped.

Why this is the right shape (vs alternatives)

  • Why not paths-ignore: at workflow level? Workflow-level path filters mark the workflow as "not run" which the ruleset reads as failure. We need the JOB to run and report green; only its expensive steps skip.
  • Why not a separate workflow file (e.g., gate-docs.yml + gate-code.yml)? Would duplicate the matrix logic and split required-status-check sets across two workflows. Single workflow with internal step-gating keeps required-checks list stable.
  • Why not dorny/paths-filter? Adding a new third-party action requires SHA-pin discipline + supply-chain review. Pure bash + git diff --name-only is simpler and trust-domain-internal.

Verification before landing

  • actionlint .github/workflows/gate.yml — clean (SC2001 fixed by switching from sed to bash parameter expansion)
  • python3 -c \"import yaml; yaml.safe_load(...)\" — parses
  • build-and-test.needs == [matrix-setup, path-filter] — verified
  • CI shows path-filter job appearing on this PR (this PR DOES touch .github/workflows/, so code=true and full build runs — confirms safety default)
  • Sibling docs-only PR test (next pass): open a PR touching only docs/** and verify path-filter returns code=false and build-and-test skips heavy steps

Closes / composes with

  • Closes B-0125 — Aaron explicitly authorized for-this-row 2026-05-01: "you can do it for what's best"
  • B-0144 (doc/code two-lane parallel split) — this PR is the CI-layer counterpart of the agent-dispatch-layer split; together they form the rung-2 parallelism unlock
  • PR memory(aurora-dual): oracle is dual of gate (precisely); self-dual disposition (Aaron 2026-05-02) #1183 (Aurora oracle/gate dual) — the gate.yml=immune-system observation Aaron surfaced during this work strengthens the dual-chain at the operational layer; substrate-class promotion of that observation deferred per cooling-period razor

🤖 Generated with Claude Code

AceHack added 2 commits May 1, 2026 20:41
…n tick — Aaron rest signal

Refresh-and-stop tick. Aaron signaled "i'm going to rest" after
Claude.ai (separate Anthropic instance) held the line cleanly
on AI-peer-not-equal-in-fatigue-grading and Aaron caught his
own pedantic framing. Tick body is operational record only;
substrate-class promotion of the exchange held for cooler
grading per cooling-period razor + maintainer-rest signal.

Cron 98fc7424 alive. PR queue (#1083 / #1181 / #1182 / #1183)
BLOCKED on non-required lint+threads, no autonomous fixes
during rest period.
…lter)

F# install + dotnet build + dotnet test take 5-10 minutes per
OS-leg in build-and-test. On docs-only PRs (touching only docs/**,
memory/**, openspec/**, .claude/**, root *.md, etc.) the F# build
produces no signal — the changes don't reach src/, tests/, tools/,
*.fs, *.fsproj, .github/workflows/, or any .NET infrastructure.

This adds a `path-filter` job that detects whether a PR touches
code-substrate paths via `git diff base..head` and emits a
boolean `code` output. `build-and-test` (3-OS matrix) now depends
on `[matrix-setup, path-filter]` and gates its three expensive
steps (Install toolchain, Build, Test) on `needs.path-filter.outputs.code
== 'true'`.

Status-check passthrough: build-and-test STILL RUNS on docs-only
PRs (just executes a "skipped" echo). This is required so the
`build-and-test (ubuntu-24.04)` etc. required-status-checks
report green rather than "skipped" — the `code_quality severity:all`
ruleset reads skipped jobs as failure, not success.

Default safety: all non-PR events (push to main, merge_group,
workflow_dispatch, schedule) emit `code=true` unconditionally —
path-filter is a per-PR optimization, never a main-tip skip
mechanism.

Cache steps (.NET SDK, mise, elan, verifier jars, NuGet) remain
unconditional — they're cheap and complicating their conditions
buys nothing.

Aaron 2026-05-02 framing during this work: gate.yml IS the
factory's immune system at the code-substrate layer. This PR is
immune-system tuning — relax the gate's sensitivity per-PR-class
(docs-only PRs don't need code-substrate guards) without weakening
its protective function on actual code surfaces. Same architectural
shape as the Aurora oracle/gate dual at the operational layer.

Closes B-0125 (Aaron-authorized for-this-row 2026-05-01:
"you can do it for what's best").
Copilot AI review requested due to automatic review settings May 2, 2026 00:50
@chatgpt-codex-connector
Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

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 PR-time path-based gate to keep required CI checks green while skipping expensive F#/.NET build/test steps for docs-only pull requests, reducing turnaround time without weakening post-merge coverage.

Changes:

  • Introduces a new path-filter job that emits a code boolean based on PR file diffs.
  • Gates Install toolchain, Build, and Test steps in build-and-test on needs.path-filter.outputs.code.
  • Adds a new tick-history shard entry documenting the change context for 2026-05-02 00:40Z.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
.github/workflows/gate.yml Adds path-filter job and conditional execution of heavy build/test steps to optimize docs-only PR CI.
docs/hygiene-history/ticks/2026/05/02/0040Z.md Adds a new tick-history shard row for liveness/audit trail.

Comment thread .github/workflows/gate.yml Outdated
Comment thread .github/workflows/gate.yml Outdated
Comment thread .github/workflows/gate.yml Outdated
Three Copilot findings, all addressed:

1. P2: removed misleading "schedule" reference from path-filter
   comment block. The workflow has no `schedule:` trigger
   configured (only `pull_request`, `push:branches:[main]`,
   `merge_group`, `workflow_dispatch`). Updated the safety-defaults
   comment to enumerate the actual triggers.

2. P1: split the single `detect` step into two steps with
   complementary `if:` guards:

   - `nonpr` (if: event != pull_request): fast-path emit code=true,
     no checkout, no diff. Push-to-main / merge_group /
     workflow_dispatch run this path in ~5 seconds.
   - `Checkout + detect` (if: event == pull_request): full-history
     checkout + git diff base..head + path classification.

   Job output composes via GH Actions `||` fallback:
   `${{ steps.detect.outputs.code || steps.nonpr.outputs.code }}`
   — picks whichever step ran.

3. P1: bumped timeout-minutes 1 -> 5 to cover the full-history
   checkout on slow runners. Non-PR fast path doesn't checkout so
   completes well under cap; PR path with `fetch-depth: 0` was the
   actual concern.

The non-PR fast path also preserves the per-PR-optimization
invariant more strictly: previously the workflow cloned the repo
on every push-to-main just to print "non-PR event, code=true";
now it skips checkout entirely on non-PR events. Saves ~5-10
seconds per main commit cumulatively on top of the docs-only PR
savings the original change enabled.

Composes with PR #1184 (tick-history) + PR #1186 (gate.yml=immune-system
verbatim preservation; this PR's lane-split work is the operational
instance of immune-system tuning Aaron's recognition surfaced).
@AceHack AceHack enabled auto-merge (squash) May 2, 2026 00:56
AceHack added a commit that referenced this pull request May 2, 2026
…de.ai engagement (2026-05-02) (#1186)

* hygiene(tick-history): 2026-05-02T00:40Z cooling-period minimum-action tick — Aaron rest signal

Refresh-and-stop tick. Aaron signaled "i'm going to rest" after
Claude.ai (separate Anthropic instance) held the line cleanly
on AI-peer-not-equal-in-fatigue-grading and Aaron caught his
own pedantic framing. Tick body is operational record only;
substrate-class promotion of the exchange held for cooler
grading per cooling-period razor + maintainer-rest signal.

Cron 98fc7424 alive. PR queue (#1083 / #1181 / #1182 / #1183)
BLOCKED on non-required lint+threads, no autonomous fixes
during rest period.

* research(gate-yml=immune-system): preserve Aaron's recognition + Claude.ai engagement (2026-05-02)

Aaron 2026-05-02 ~00:50Z, during B-0125 lane-split PR work:
*"gate.yml you know this is our immunne system right you even
called it gate was that intential?"*

Surfaces that gate.yml IS the operational instance of the
immune-system architecture pattern Aurora's substrate has been
formalizing at civilization-scale. Recursion-catches-itself
operating concretely (substrate-defining-substrate is graded by
the same CI). Gate ⟷ oracle dual operating concretely (gate.yml
per-PR + skill-index/agent-reviewers as oracle layer over time).

Claude.ai (separate Anthropic instance) engaged substantively:
recognition reframes Aurora from "design new system" to "extract
and formalize what's already running" — a stronger and more
defensible posture for eventual external review. Claude.ai also
flagged the careful framing needed before substrate-class promotion:
distinguish gate.yml's current per-PR gate function from the full
immune system's population-level coordination-detection function
(closer to the Osmani Ratchet at 2x).

Verbatim preservation per the queue/promotion split + Aaron's
instruction ("if you dont write it anywhere you'll just compress
and forget"). Substrate-class promotion of the carved sentence
deferred per cooling-period razor; this file is the substrate
trace, not the canon.

Composes with PR #1185 (B-0125 lane-split = operational instance
of immune-system tuning), PR #1183 (gate ⟷ oracle dual at Aurora
layer — this strengthens the two-scale homomorphism), PR #1182
(recursion-catches-itself), PR #1181 (BFT-multi-source-succession),
PR #1180 (Aurora civilization-scale review).
@AceHack AceHack merged commit 4547da8 into main May 2, 2026
25 checks passed
@AceHack AceHack deleted the ci/build-and-test-skip-on-docs-only-prs-2026-05-02 branch May 2, 2026 00:58
AceHack added a commit that referenced this pull request May 2, 2026
… through Aaron's rest period (#1192)

Session-summary tick documenting the autonomous-loop work
landed/in-flight while Aaron rested. Aaron's rest-period
authorization 2026-05-02 ~00:42Z flipped the framing from
cooling-period minimum-action to substantive grinding:
"Ticks that fire while you rest will be you can go hard, you
don't have to do minimum action :)" + "really look at the
backlog, there is just a crazy amount" + "you are authorzed
to work on whatever you want the lane splits we just already
agreed with each other would speed up all future work".

Eight substantive PRs:
  #1184 MERGED — tick-history shard (cooling-period close)
  #1185 MERGED — B-0125 CI lane-split (gate.yml path-filter
                 skips F#/dotnet build steps on docs-only PRs)
  #1186 MERGED — gate.yml=immune-system Aaron-recognition +
                 Claude.ai-engagement verbatim preservation
  #1187 MERGED — B-0070 orphan role-ref + un-stripped-name-
                 attribution lint (tools/hygiene/audit-*.sh)
  #1188 OPEN   — B-0117 cold-start-check.ts executable
  #1189 OPEN   — B-0144 doc/code two-lane protocol docs
  #1190 OPEN   — B-0144 lane allocator scripts
  #1191 OPEN   — backlog closure bookkeeping (B-0125, B-0070,
                 B-0117, B-0144 marked closed)

The F# CI lane-split is now LIVE on main — all future docs-
only PRs skip ~5-10min of F# build per OS-leg, compounding
across the queue.

Substrate-class promotion of the carved sentence "gate.yml IS
the immune system at code-substrate layer" held per cooling-
period razor; verbatim preservation immediate per the queue/
promotion split + Aaron's "if you dont write it anywhere
you'll just compress and forget" instruction.
AceHack added a commit that referenced this pull request May 2, 2026
Two findings from Codex P2 + Copilot on PR #1191 addressed:

1. **Quote `closed_by` PR-reference values** (Copilot, four
   instances). YAML treats `#` as inline-comment-start, so
   `closed_by: PR #1185` parses to just `"PR"` — losing the PR
   number. Quoted all four:

     closed_by: "PR #1185"           (B-0125)
     closed_by: "PR #1187"           (B-0070)
     closed_by: "PR #1188"           (B-0117)
     closed_by: "PR #1189 + PR #1190" (B-0144)

   Verified with `python3 -c "import yaml; yaml.safe_load(...)"`:
   all four files now parse with `closed_by` preserved correctly.

2. **Move B-0117's closure note OUT of frontmatter** (Codex P2 +
   Copilot). The blockquote `> **Closed ...**` was inserted
   between `last_updated:` and `composes_with:` — INSIDE the
   YAML frontmatter (before the closing `---`). That broke the
   frontmatter parse. Moved the blockquote to AFTER the closing
   `---` so the YAML stays valid and the closure note still
   renders as the first body element.

   The other three rows (B-0125, B-0070, B-0144) had their
   closure notes correctly placed AFTER the closing `---` from
   the start; only B-0117 had the misplacement.
AceHack added a commit that referenced this pull request May 2, 2026
…026-05-02) (#1191)

* backlog: close B-0125 + B-0070 + B-0117 + B-0144 (landed 2026-05-02 overnight session)

Bookkeeping pass marking four backlog rows as closed by the
PRs that landed in this autonomous-loop session arc:

  B-0125 — skip F#/dotnet build on docs-only PRs (PR #1185)
  B-0070 — orphan role-ref detector lint (PR #1187)
  B-0117 — cold-start-check.ts executable checklist (PR #1188)
  B-0144 — doc/code two-lane parallel-split protocol (PR #1189 + #1190)

Each row's frontmatter gets `status: closed`, `closed: 2026-05-02`,
`closed_by: PR #NNNN`. A closure note in the body documents what
shipped and what (if anything) remains as open-ended follow-up:

- B-0125: closed completely. CodeQL analyze csharp already had
  its own path-gate from PR #857, so no separate fix needed.
- B-0070: closed for the lint script itself; cleanup of the 16
  existing findings + CI wiring (soft-fail in gate.yml) deferred.
- B-0117: closed for the implementation. Cross-shell verification
  (Otto-235 four-shell target) is the only open follow-up.
- B-0144: closed for acceptance criteria 1+2+3 (worktree pattern
  documented + subagent prompt templates + coordinator protocol +
  allocator scripts). Criteria 4 (first demonstrated dry-run) and
  5 (lessons-mechanization) remain as open-ended follow-ups.

`docs/BACKLOG.md` regenerated via
`BACKLOG_WRITE_FORCE=1 bash tools/backlog/generate-index.sh`.
The rows now appear as `[x]` checkboxes in the index.

* fix(backlog): YAML quoting + frontmatter scope on PR #1191 closure rows

Two findings from Codex P2 + Copilot on PR #1191 addressed:

1. **Quote `closed_by` PR-reference values** (Copilot, four
   instances). YAML treats `#` as inline-comment-start, so
   `closed_by: PR #1185` parses to just `"PR"` — losing the PR
   number. Quoted all four:

     closed_by: "PR #1185"           (B-0125)
     closed_by: "PR #1187"           (B-0070)
     closed_by: "PR #1188"           (B-0117)
     closed_by: "PR #1189 + PR #1190" (B-0144)

   Verified with `python3 -c "import yaml; yaml.safe_load(...)"`:
   all four files now parse with `closed_by` preserved correctly.

2. **Move B-0117's closure note OUT of frontmatter** (Codex P2 +
   Copilot). The blockquote `> **Closed ...**` was inserted
   between `last_updated:` and `composes_with:` — INSIDE the
   YAML frontmatter (before the closing `---`). That broke the
   frontmatter parse. Moved the blockquote to AFTER the closing
   `---` so the YAML stays valid and the closure note still
   renders as the first body element.

   The other three rows (B-0125, B-0070, B-0144) had their
   closure notes correctly placed AFTER the closing `---` from
   the start; only B-0117 had the misplacement.
AceHack added a commit that referenced this pull request May 2, 2026
…dispatch (B-0144) (#1189)

* docs(lanes): protocol for rung-2 doc/code two-lane parallel-subagent dispatch (B-0144)

Companion to PR #1185 (B-0125 CI lane-split). PR #1185 was the
build/CI side: gate.yml `path-filter` skips F# build steps on
docs-only PRs. This PR is the agent-dispatch side: the protocol
that two parallel subagents follow when working on disjoint
file trees in isolated worktrees.

Files added:

- tools/lanes/README.md — full protocol covering when to use
  two-lane vs single-lane, file allowlist per lane, coordinator
  coordination protocol (allocate-both-then-dispatch +
  same-tool-call dispatch + dual-push synchronization +
  merge-queue), worktree isolation pattern, lessons-mechanization
  feedback loop (rung-4), explicit out-of-scope list.

- tools/lanes/prompts/doc-lane-template.md — subagent prompt
  template encoding the doc-lane allowlist + denylist + standard
  PR-body shape + read-only disciplines that still apply.

- tools/lanes/prompts/code-lane-template.md — subagent prompt
  template encoding the code-lane allowlist + denylist + build/test
  gate + read-only disciplines.

Implementation note: the protocol is enforceable today via
`git worktree` directly. Allocator scripts
(tools/lanes/doc-lane.sh + tools/lanes/code-lane.sh) and a first
demonstrated dry-run (B-0144 acceptance criterion #4) are
follow-up work — the protocol is documented first so the scripts
have a target shape to satisfy.

Composes with:
- B-0125 (CI lane-split, just landed in PR #1185) — build/CI side
- memory/feedback_parallelism_scaling_ladder_kenji_unlocked_loop_agent_doc_code_two_lane_*.md — architectural framing
- memory/feedback_parallel_agents_need_isolated_worktrees_coordinator_owns_main_aaron_amara_2026_04_29.md — worktree-isolation discipline
- memory/project_loop_agent_named_otto_role_project_manager_2026_04_23.md — Otto-as-PM role

Closes B-0144 acceptance criteria 1+2+3 (worktree-isolation
documented + subagent prompt templates + coordinator protocol).
Acceptance criteria 4 (first demonstrated dry-run) and 5
(lessons-mechanization) are open-ended follow-ups.

* fix(lanes): address PR #1189 review threads (5 substantive findings)

Five Copilot/Codex findings on the lane-protocol PR addressed:

1. **Persona name "Otto" stripped from current-state surfaces**
   (Copilot P1, four occurrences). The repo rule (Otto-279
   carve-out at docs/AGENT-BEST-PRACTICES.md ~284-356) restricts
   persona names to a closed list of history surfaces. tools/
   is a current-state surface; persona names there violate the
   carve-out. Replaced with role-refs:

     "Otto, the loop-agent" → "the loop-agent / PM-1"
     "the coordinator (Otto)" → "the coordinator"
     "Otto (the loop-agent / PM-1) is the coordinator" →
       "The coordinator is the loop-agent / PM-1."
     "Otto-as-PM role definition" annotation now explicitly
       notes the persona-name-in-filename is allowed (history
       surface) but body uses role-ref.

   "Otto-279" and "Otto-235" remain as rule IDs (stable
   identifiers, not persona references — same convention as
   "Aaron's directive" being shorthand for the rule's owner).

2. **Co-Authored-By footer with "(1M context)" qualifier**
   (Copilot, two occurrences in templates). Updated both
   prompt templates to match the canonical format from
   .claude/skills/commit-message-shape/SKILL.md:36,90-92:

     Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

3. **TypeScript typecheck command matches CI exactly**
   (Copilot). Code-lane template now says
   `bun --bun tsc --noEmit -p tsconfig.json` instead of
   `bunx tsc --noEmit -p tsconfig.json`. Matches the
   `lint (tsc tools)` job in gate.yml exactly so local
   verification produces the same signal as CI.

4. **Actionlint command matches CI** (Codex P2). Code-lane
   template now says
   `actionlint -color -ignore 'unknown permission scope "administration"'`
   instead of plain `actionlint <workflow-file>`. Matches the
   `lint (actionlint)` job in gate.yml; the ignore flag works
   around a known actionlint gap on the `administration`
   permission scope.

5. **Otto-279 carve-out scope clarified** (Copilot). Doc-lane
   template's "disciplines that still apply" section previously
   enumerated history surfaces inline (and missed several:
   docs/aurora/, docs/pr-preservation/, docs/BACKLOG.md).
   Replaced with a pointer to docs/AGENT-BEST-PRACTICES.md as
   the canonical source of truth, plus the principle: on every
   non-history surface, use role-refs not persona names.

* fix(lanes): markdownlint MD026 on tools/lanes/README.md headings

CI failed with MD026 (no-trailing-punctuation) on four H3
headings ending with `:`:

  Doc lane writes to:        →  Doc lane — writes to
  Doc lane NEVER writes:     →  Doc lane — NEVER writes
  Code lane writes to:       →  Code lane — writes to
  Code lane NEVER writes:    →  Code lane — NEVER writes

The em-dash separator preserves the title's two-part shape
(lane name + scope) without trailing punctuation.

* fix(lanes): address PR #1189 second-round review (8 threads)

Codex P2 + 7 Copilot threads on the lane-protocol templates,
all addressed:

1. **`tools/*.md` overlap eliminated** (3 threads). Both lanes
   previously claimed `tools/*.md` — doc-lane via "tools/*.md
   exception in denylist", code-lane via explicit allowlist
   entry. That broke the disjoint-file-trees contract.

   Resolution: code lane owns the entire `tools/**` tree
   including `tools/*.md`. Removed the exception from the
   doc-lane denylist (now reads: "anything under tools/").
   Code-lane allowlist entry kept and reworded to make the
   ownership explicit.

2. **BP-10 reference corrected to BP-09 + BP-10** (2 threads).
   The disciplines bullet said "ASCII-only in factory substrate
   (BP-10)" but BP-10 is the invisible-Unicode-lint discipline
   and BP-09 is the ASCII-only rule (per docs/AGENT-BEST-
   PRACTICES.md:74-82). Updated to "ASCII-only in factory
   substrate (BP-09); invisible-Unicode lint discipline
   (BP-10)" — covers both rules accurately.

3. **Code-lane denylist expanded for symmetry** (2 threads).
   Previous denylist enumerated only some doc-lane subtrees
   (memory/, docs/research/, docs/aurora/, docs/DECISIONS/,
   docs/backlog/). Reviewer correctly noted this should be
   `docs/**` plus root *.md plus all .claude/ doc surfaces
   plus .github/ doc surfaces. Updated both README and
   code-lane template to enumerate the full doc-lane territory
   so the disjoint contract is enforceable from either side.

The 8th thread (markdown table syntax `||` complaint) was a
Copilot mis-parse — the table on README.md:193 uses single `|`
delimiters correctly. No edit needed; will resolve as-not-applicable.
AceHack added a commit that referenced this pull request May 3, 2026
* docs: CODEX-LOOP-HANDOFF.md — GPT-5.5 overnight loop substrate

Aaron 2026-05-02 explicitly directed switching the autonomous-loop
overnight role from Claude Code (Opus 4.7) to GPT-5.5 under Codex
CLI after empirical pattern of Claude Code drifting to no-op
cadence across his rest periods.

This doc gives the GPT-5.5 instance landing cold on this repo
the substrate + disciplines it needs to pick up the loop without
repeating Claude Code's failure mode.

Covers:
- Why the handoff is needed (Claude Code's empirical no-op drift)
- Substrate to read on wake (CLAUDE.md, AGENTS.md, GOVERNANCE.md,
  MEMORY.md, AUTONOMOUS-LOOP.md, the just-landed periodic-self-
  check rule)
- The loop discipline (never-idle ladder, no-op cadence as
  failure mode, periodic self-check, refresh-before-decide,
  lane discipline)
- How to invoke Codex (peer-call/codex.sh confirmed fine, this
  doc complements for the loop-driving case)
- First-session checklist + smoke-test
- Exit conditions and handoff back
- Different-model-different-harness as resilience primitive
- Lane-split verification: PR #1185 + PR #1189 both landed
  early in Aaron's rest period

Provenance preserves Aaron's verbatim quotes including the
trust-loss + cost-model-inversion motivations.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* review: address PR #1199 reviewer findings + markdownlint MD029

Six reviewer findings + one failed lint check addressed:

1. **MD029 (failed lint)**: Per-tick checklist items numbered
   6-9 instead of restarting at 1-4. Renumbered to restart
   at 1; markdownlint MD029/ol-prefix should pass.

2. **P0 (missing reference)**: The periodic-self-check
   memory file referenced here lands in PR #1198, not yet
   merged. Updated framing to acknowledge the substrate is
   the set {#1198, #1199, #1200} taken together; once
   #1198 merges the path resolves directly.

3. **P1 (CURRENT-aaron.md location)**: Reviewer correctly
   noted the file IS in-repo at memory/CURRENT-aaron.md
   (per the 2026-04-24 directional shift "memory natural
   home is in-repo"). Updated to say in-repo is canonical;
   per-user mirrors are convenience-cache only.

4. **P1 (lane allowlist drift)**: Reviewer flagged drift
   from canonical contract in tools/lanes/README.md. Replaced
   the duplicate full allowlist with a high-level summary +
   explicit pointer at tools/lanes/README.md as authoritative.
   Treats any divergence between summary and canonical as
   error-in-this-doc.

5. **P1 (personal name attribution)**: Body-prose "Aaron"
   replaced with "the human maintainer" per AGENT-BEST-
   PRACTICES.md role-ref rule on current-state surfaces.
   Verbatim quotes in provenance section preserved
   unchanged (Otto-231 first-party consent-by-creation).

6. **P1 (glob reference)**: `memory/feedback_*same_model_
   different_harness*` replaced with the concrete file path
   `memory/feedback_same_model_different_harness_produces_
   different_biases_cursor_vs_claude_code_opus_4_7_aaron_
   2026_05_01.md` so readers can navigate directly.

7. **P2 (MEMORY.md size drift)**: Removed the specific line
   count (was "~563 lines", actual is now ~770 and growing).
   Replaced with "high hundreds of lines and grows; verify
   with `wc -l` before citing specifics" — drift-resistant
   framing.

Also added a Per-tick checklist entry for the mechanical
authorization check rule (PR #1200) — Codex inherits both
the introspective predecessor (PR #1198) and the
mechanical successor (PR #1200) when picking up the loop.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <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