Skip to content

docs(rules): add ID allocation discipline section to otto-channels reference card#3153

Merged
AceHack merged 2 commits into
mainfrom
otto-channels-id-allocation-discipline-redo-2026-05-14
May 14, 2026
Merged

docs(rules): add ID allocation discipline section to otto-channels reference card#3153
AceHack merged 2 commits into
mainfrom
otto-channels-id-allocation-discipline-redo-2026-05-14

Conversation

@AceHack
Copy link
Copy Markdown
Member

@AceHack AceHack commented May 14, 2026

Summary

Yesterday's B-0449 collision empirically validated a gap in the otto-channels reference rule: agents pick monotonically-increasing IDs (B-NNNN backlog row numbers) by checking on-disk state but NOT in-flight PRs — race-mode manifests when peer Otto is filing concurrently.

Adds new section "ID allocation discipline (multi-surface)" to .claude/rules/otto-channels-reference-card.md requiring BOTH:

  1. On-disk check (`find docs/backlog → grep B-[0-9]+ → tail`)
  2. In-flight check (`gh pr list --state all --search "B-NNNN"`)

The on-disk check shows merged state; the in-flight check shows what peer Otto is filing concurrently. Skip either and the race manifests.

Empirical anchor

2026-05-13 collision:

Substrate-honest takeaway

The `refresh-before-decide` invariant (`.claude/rules/refresh-before-decide.md`) applies at the per-ID-allocation scope, not just per-tick. The "highest on disk + 1" heuristic is incomplete; PRs in flight are also state.

Why now

This PR is the re-authoring of work that was lost in 2026-05-13 session crash (the original was on `/tmp/zeta-otto-desktop` which got cleaned up during the gap). The substrate gap is still real, the empirical anchor still holds, the rule update is still valuable.

Composition

Test plan

  • CI passes (markdownlint + memory frontmatter checks)
  • Future Otto cold-boots read the new section at session start
  • Next ID allocation across Ottos exercises the discipline (will surface if successful)

🤖 Generated with Claude Code

…ference card

Yesterday's B-0449 collision empirically validated a gap in the channels
reference rule: agents pick monotonically-increasing IDs (B-NNNN backlog
row numbers) by checking on-disk state but not in-flight PRs, race-condition
manifests when peer Otto is filing concurrently.

Adds new section "ID allocation discipline (multi-surface)" after Lane
discipline, requiring BOTH:

1. On-disk check (find docs/backlog → grep B-[0-9]+ → tail)
2. In-flight check (gh pr list --search "B-NNNN")

Empirical anchor: 2026-05-13 collision where Otto on Desktop picked B-0449
for PR #3052, but Otto on CLI had B-0449 in flight via PR #3046 (bg-services
slice 5). Resolved by PR #3053 renumber to B-0450 + PR #3054 shadow lesson log.

Also adds:
- Item 7 to Operational discipline list pointing at new section
- Composes-with entries for PR #3053, PR #3054, refresh-before-decide.md
- /tmp/zeta-otto-id-alloc as example task-specific worktree path

Re-authoring of work lost in yesterday's session crash (was on /tmp/zeta-otto-desktop
which got cleaned up). The substrate gap is still real; the empirical anchor still
holds; the rule update is still valuable.

Co-Authored-By: Claude <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings May 14, 2026 18:11
@AceHack AceHack enabled auto-merge (squash) May 14, 2026 18:11
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: 0d4d0e1218

ℹ️ 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 .claude/rules/otto-channels-reference-card.md Outdated
The on-disk check in the ID allocation discipline section used 'find -printf'
which is GNU-only and fails on BSD find (macOS default). Replaced with the
portable pattern: 'find ... -type f | grep -oE "B-[0-9]+"' — the B-NNNN
pattern only appears once per filename in practice, so extracting from full
paths is equivalent.

Verified portable: ran the new command, output matches expected (top 3 row IDs).

Co-Authored-By: Claude <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

Updates the Otto inter-surface communication reference card to codify ID allocation discipline across local backlog state and GitHub PR state, addressing the B-0449 collision scenario described in the PR.

Changes:

  • Adds ID allocation as an operational discipline item.
  • Adds a new multi-surface ID allocation section with on-disk and in-flight PR checks.
  • Adds composition links to the collision-resolution PRs and refresh-before-decide rule.

Comment thread .claude/rules/otto-channels-reference-card.md
@AceHack
Copy link
Copy Markdown
Member Author

AceHack commented May 14, 2026

This concern was already addressed in commit 1636908 (pushed before this review) — find -printf was replaced with portable find ... -type f | grep -oE "B-[0-9]+" per Codex P2 thread PRRT_kwDOSF9kNM6CJju2 (resolved). Same finding, different reviewer. Resolving thread.

@AceHack AceHack merged commit 056c09f into main May 14, 2026
21 checks passed
@AceHack AceHack deleted the otto-channels-id-allocation-discipline-redo-2026-05-14 branch May 14, 2026 18:16
AceHack added a commit that referenced this pull request May 14, 2026
…to find-portability fix) (#3154)

Aaron-authored PR #3153 (ID-allocation discipline section) had a Codex P2 thread flagging
`find ... -printf` as GNU-only (fails on BSD/macOS). Investigation found another agent had
already pushed commit 1636908 with the portable-find fix (Aaron + Co-Authored-Claude); the
thread was still open.

Otto-CLI's contribution: verified the portable command works on this BSD-find macOS
environment + closed the thread via GraphQL resolveReviewThread mutation.

PR #3153 now wait-ci (6/7 required ok, 1 in-progress, threads:0, autoMerge armed).

Also cleaned up stale /private/tmp/zeta-otto-id-alloc worktree (4h-old leftover from
yesterday's session crash; PR body confirms original session was lost).

Co-authored-by: Claude <noreply@anthropic.com>
AceHack added a commit that referenced this pull request May 14, 2026
…rd (#3156)

* chore(backlog): B-0506 — stale-worktree prune cadence mechanization (P3 friction-reducer)

Otto-CLI 2026-05-14T18:13Z empirically observed 23 stale /private/tmp/zeta-* worktree
entries left over from yesterday's session crash. The accumulation creates a recurring
lockout pattern: 'git checkout <branch>' fails with "already used by worktree at <path>"
even when <path> no longer exists on disk.

Manual cleanup at 18:17Z: 'git worktree prune --expire=now -v' cleared all 23 entries.

This row proposes mechanizing the prune via a small TypeScript audit tool that:
1. Enumerates worktrees + checks directory existence
2. Reports stale entries
3. With --prune flag, runs git worktree prune --expire=now

Wire-up candidates: per-tick in autonomous-loop, or daily GitHub Actions cron.

Filed as P3 backlog row (not implemented this tick) because the manual command works
and the per-tick value of a new file + PR + CI cycle is less than the row capture.

Composes with B-0400 (bus protocol), B-0444 (claim worktree field),
claim-acquire-before-worktree-work rule, encoding-rules-without-mechanizing rule.

Co-Authored-By: Claude <noreply@anthropic.com>

* shard(tick): 1817Z — stale-worktree cleanup (23 pruned) + B-0506 mechanization row filed

Pruned 23 stale /private/tmp/zeta-* worktree admin entries via 'git worktree prune
--expire=now -v'. The accumulation creates a recurring "branch already used by
worktree at <path>" lockout pattern that hit on prior tick (PR #3153 thread fix).

Filed B-0506 (P3 friction-reducer) to mechanize the prune via a small TypeScript
audit tool + per-tick or daily cadence wire-up.

Side observation captured in shard: long-standing prior-session stash auto-popped
during 'git stash push <untracked>' workflow, introducing conflict markers in
tools/bus/claim.{ts,test.ts}. Reset both to origin/main; stash content discarded
(alternative SHA-256 lock-path variant; if needed, derivable via decision archaeology).

Composes with: claim-acquire-before-worktree-work rule, encoding-rules-without-
mechanizing rule, B-0400, B-0444.

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
AceHack added a commit that referenced this pull request May 14, 2026
…d (MEMORY.md bloat) (#3204)

(renumbered from B-0516 due to multi-Otto ID collision — a parallel Otto had
also claimed B-0516 in chore/b-0516-gates-ecc-physical-compression-research-
direction-2026-05-14 in-flight; B-0517 is the next safe ID)

Razor-cadence item 5 (MEMORY.md index audit) investigation:

- User-scope MEMORY.md: 242 lines / 66KB / 237 entries
- Cold-boot loads first 200 lines only → ~37 lines (15%) unreachable
- Average entry size 275 chars vs 200-char guidance
- ~100-130 entries exceed limit; top 5 are 500-620 chars

Root cause: paragraph-length entries duplicate content already in topic file
frontmatter description: field.

B-0517 two-phase plan:
- Phase 1: bulk cleanup of ~130 entries (trim index; full detail stays in
  topic files)
- Phase 2: mechanize via tools/hygiene/audit-user-scope-memory-index.ts
  (parallel to PR #3202's audit-rule-cross-refs.ts)

Composes with B-0006, PR #3202, razor-cadence #3128, B-0506.

Side observation: multi-Otto ID-collision recurred despite PR #3153's ID-
allocation discipline (on-disk + in-flight check). Both Ottos extracted top
B-0515 from on-disk and incremented; in-flight check missed because the
parallel Otto's branch had a non-standard name (chore/b-0516-gates-ecc-*)
that didn't match the search heuristic. Substrate-honest acknowledgment;
discipline holds but search-heuristic needs widening to catch this case.

Co-authored-by: Claude <noreply@anthropic.com>
AceHack added a commit that referenced this pull request May 14, 2026
…3307)

New section "Worktree force-remove guard" between "When this rule applies"
and "Composes with other rules" addressing an empirical failure mode
that manifested 2026-05-14T18:13Z:

Otto-CLI checked out Otto-Desktop's PR #3153 branch to investigate a
Codex thread, hit "fatal: already used by worktree at /private/tmp/zeta-otto-id-alloc",
and force-removed the worktree to take over. The PR-thread-resolution
DOES-NOT-APPLY clause covered the WHY (legitimate cross-Otto work);
it did not cover the HOW (force-remove vs new-path).

Three operational alternatives now documented:
1. Create new worktree at distinct task-tagged path (cheap, default)
2. Use gh api / GraphQL for branch-state ops requiring no checkout
3. Bus-mediated worktree handoff for rare must-checkout cases

Empirical anchor preserved in commit message + docs/hygiene-history/ticks/2026/05/14/1813Z.md

Co-authored-by: Claude <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