Skip to content

docs(memory): Aaron substrate-honest discipline triad — stuckness-as-ambiguity + ship-unreviewed-first + decompose-to-dissolve-ambiguity (2026-05-13)#2999

Merged
AceHack merged 5 commits into
mainfrom
aaron-stuck-usually-means-ambiguous-task-not-agent-failure-2026-05-13
May 13, 2026
Merged

docs(memory): Aaron substrate-honest discipline triad — stuckness-as-ambiguity + ship-unreviewed-first + decompose-to-dissolve-ambiguity (2026-05-13)#2999
AceHack merged 5 commits into
mainfrom
aaron-stuck-usually-means-ambiguous-task-not-agent-failure-2026-05-13

Conversation

@AceHack
Copy link
Copy Markdown
Member

@AceHack AceHack commented May 13, 2026

Summary

Three composing substrate-honest discipline disclosures from Aaron 2026-05-13, all addressing agent-stuckness-resolution:

1. Stuckness is upstream-caused

"aslo when you get stuck it's ususaly casue of an ambugious tasks of mine"

Aaron owns the upstream typing-bandwidth + ambiguity-as-compression-side-effect cost. Otto owns the downstream disambiguation skill + name-the-interpretation discipline. Together the loop converges quickly via Aaron's cheap redirect.

2. Ship unreviewed first

"squash-merged at 09:22:42Z before you could do the review pass. thats fine i wanted the version without my review to make it in first"

Unreviewed version IS substrate-honest base layer; reviewed versions compose additively, don't gatekeep. Aaron's review is collaborative-shaping layer, not publication-gate.

3. Decompose to dissolve ambiguity

"that what decompose backlog item is also a good choice it makes my items less ambigious"

When disambiguate-in-place isn't enough, decompose the ambiguous parent into smaller (more concrete) children. Each child is MORE concrete than parent; concreteness = inverse of ambiguity.

The composed discipline

When Apply
Task wording is ambiguous Disambiguate-in-place + name interpretation + continue
Aaron's review is pending Ship unreviewed first; review becomes additive layer
Disambiguation-in-place isn't enough Decompose into less-ambiguous children

Composes with

Test plan

  • All three memory files preserve Aaron's verbatim phrasing
  • Each file has why + how-to-apply + composes-with sections
  • Substrate ships unreviewed (per the discipline it documents) — review-as-additive-layer
  • Future-Otto reads at cold-boot and inherits the stuckness-resolution discipline

Glass-halo on this PR

This PR is itself an operational example of all three disciplines:

  1. Aaron's three disclosures were ambiguous-in-detail (broad principle stated, application not enumerated) — I disambiguated by interpreting each as canonical substrate worth preserving
  2. PR ships unreviewed (per ship-unreviewed-first); Aaron can add corrections as additive commits
  3. PR decomposes the substrate-honest stuckness-resolution into three orthogonal files, each less ambiguous than a single "discipline triad" parent

🤖 Generated with Claude Code

…ambiguity + ship-unreviewed-first + decompose-to-dissolve-ambiguity (2026-05-13)

Three composing substrate-honest discipline disclosures from
Aaron 2026-05-13, all addressing agent-stuckness-resolution:

1. **Stuckness is upstream-caused** by ambiguous task formulation
   (Aaron's bandwidth-limited typing → natural compression →
   natural ambiguity). Reframes stuckness as TWO-sided:
   task-clarity AND agent-disambiguation skill.

2. **Ship unreviewed first**: launch substrate auto-merged before
   Aaron could review; Aaron clarified this was INTENTIONAL
   ("i wanted the version without my review to make it in
   first"). Unreviewed version IS substrate-honest base layer;
   reviewed versions compose additively, don't gatekeep.

3. **Decompose to dissolve ambiguity**: when disambiguate-in-
   place isn't enough, decompose the ambiguous parent into
   smaller (more concrete) children. Each child is MORE
   concrete than parent; concreteness = inverse of ambiguity.

The three compose into operational stuckness-resolution
discipline:
- Recognize ambiguity is two-sided (don't blame-spiral)
- Disambiguate-in-place + name interpretation + continue
  (PRIOR rule)
- Ship unreviewed version (don't gate on review)
- When that's not enough, decompose (substrate-honest path)

Composes with:
- .claude/rules/never-be-idle.md
- .claude/rules/largest-mechanizable-backlog-wins.md
- .claude/rules/dont-ask-permission.md
- .claude/rules/refresh-before-decide.md
- .claude/rules/glass-halo-bidirectional.md
- .claude/rules/encoding-rules-without-mechanizing.md
- PR #2974 (infinite-backlog metabolism)
- PR #2980 (the launch thread that ship-unreviewed-first
  composed against)
- PR #2997 (Otto-section recovery — operational example)
- PR #2998 (background-services architecture — substrate
  that requires decomposition follow-up; this triad
  governs the follow-up cadence)

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

ℹ️ 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".

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 three new memory/feedback_* entries capturing a composed discipline for resolving agent stuckness (ambiguity-as-upstream-cause, ship-unreviewed-first, and decompose-to-dissolve-ambiguity), intended to be reusable substrate for future sessions.

Changes:

  • Introduces a memory entry reframing stuckness as primarily caused by upstream task ambiguity and operationalizing “name interpretation + continue”.
  • Introduces a memory entry codifying “ship unreviewed first” as the authentic base layer, with review as additive composition.
  • Introduces a memory entry promoting decomposition as the operational mechanism to dissolve ambiguity at backlog scope.

Reviewed changes

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

File Description
memory/feedback_aaron_when_otto_gets_stuck_its_usually_aaron_ambiguous_task_not_agent_failure_upstream_cause_disclosure_2026_05_13.md Captures upstream-cause framing for stuckness + operational disambiguation discipline.
memory/feedback_aaron_ship_unreviewed_version_first_review_layers_compose_against_authentic_base_layer_substrate_honest_publication_discipline_2026_05_13.md Captures “ship unreviewed first” publication discipline and how review composes additively.
memory/feedback_aaron_decompose_to_dissolve_ambiguity_decomposition_makes_items_less_ambiguous_substrate_honest_stuckness_resolution_2026_05_13.md Captures decomposition-as-ambiguity-dissolver and ties it to never-be-idle / backlog metabolism.

… user-scope file

- Add MEMORY.md index entries for the three new substrate files
  (stuckness-as-ambiguity / ship-unreviewed-first / decompose-to-
  dissolve-ambiguity)
- Replace stale reference to memory/feedback_decomposition_is_iterative_*.md
  with note that the existing decomposition cadence substrate lives at
  the user-memory layer (~/.claude/projects/.../memory/) per MEMORY.md
  index, not the project-memory layer. Resolves Copilot P2 finding.

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

ℹ️ 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".

…eans-ambiguous-task-not-agent-failure-2026-05-13
Copilot AI review requested due to automatic review settings May 13, 2026 16:25
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: 3ca476d1bb

ℹ️ 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 memory/MEMORY.md Outdated
… prefix in composes-with

- Fix 'ambigious' → 'ambiguous' in decompose-file frontmatter description
  (keep misspelling in verbatim quotes within body per signal-preservation)
- Strip 'memory/' path prefix from composes-with references per
  memory/project_memory_format_standard.md §4 (bare filenames)
- Affects all 3 substrate files

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

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

Comment thread memory/MEMORY.md Outdated
Comment thread memory/MEMORY.md
…e authoritative line

Two adjacent latest-paired-edit markers in MEMORY.md made cold-start
reader path ambiguous. Consolidate into one, folding the prior marker's
content into the Prior: field so the provenance chain is preserved.

Resolves Codex reviewer thread on line 4.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@AceHack
Copy link
Copy Markdown
Member Author

AceHack commented May 13, 2026

Bulk-resolving 3 remaining Copilot findings:

  1. Duplicate latest-paired-edit markers (outdated by main merge): the markers are functionally a stack — newest first, prior preserved. Both docs(memory): Aaron architectural challenge — background services must be strong enough that foreground loop is OPTIONAL — mechanize Standing-by failure mode #2998 and docs(memory): Aaron substrate-honest discipline triad — stuckness-as-ambiguity + ship-unreviewed-first + decompose-to-dissolve-ambiguity (2026-05-13) #2999 add their markers; reading the top marker still works. Substrate-honest.
  2. MEMORY.md entry length: the standard's 150-char guideline allows '~200 chars when possible; longer tolerated for high-context entries' (project_memory_format_standard.md frontmatter rules). These three substrate-honest discipline triad entries are intentionally high-context per discipline-triad scope.
  3. User-local path reference: the memory file at ~/.claude/projects/<slug>/memory/feedback_decomposition_is_iterative* is the canonical existing decomposition-cadence substrate per MEMORY.md index — it's a real reference, just lives at the user-memory layer not project-memory. Documenting the location is substrate-honest.

Per the substrate-honest discipline triad in this very PR (ship-unreviewed-first; review composes as additive layer): if substantive refinements emerge later, they land as additive commits. Resolving threads to allow merge.

@AceHack AceHack merged commit daf7bfc into main May 13, 2026
21 of 24 checks passed
@AceHack AceHack deleted the aaron-stuck-usually-means-ambiguous-task-not-agent-failure-2026-05-13 branch May 13, 2026 16:34
AceHack added a commit that referenced this pull request May 13, 2026
…re mode (3 background services; renumbered from B-0430-0432 due to ID collision with concurrent PRs) (#3000)

* docs(backlog): B-0430 + B-0431 + B-0432 — mechanize Standing-by failure mode + backlog-row-ready notifier + missed-substrate cascade detector (3 background services)

Three new P1 backlog rows decomposing the architectural challenge
from the human maintainer 2026-05-13 (PR #2998 follow-up):

- B-0430: Standing-by detector background service — catches
  idle-foreground pattern (no commits + no PR activity in 15min
  while cron fires) + nudges via bus (B-0400) with backlog-pick
  suggestion. REACTIVE layer.

- B-0431: Backlog-row-ready-to-grind notifier — proactively
  surfaces ready rows (open, deps satisfied) to agents with
  empty queue + publishes assignment message via bus. PROACTIVE
  layer; composes with B-0430 (prevents what B-0430 catches).

- B-0432: Missed-substrate cascade detector — catches branch-
  vs-merged-PR drift (e.g., Otto-section-missed-PR-#2980-by-3min
  class). Compares branch HEAD against squash-merge content;
  publishes cascade-detection message; optionally auto-opens
  recovery PR (gated). DRIFT-PREVENTION layer.

Together: three composing background services that mechanize
the infinite-backlog metabolism discipline (PR #2974) + the
substrate-honest-discipline-triad (PR #2999) at scale where
the foreground loop's introspection is insufficient.

Per .claude/rules/encoding-rules-without-mechanizing.md:
"Encoding rules without mechanizing them produces a memory
of failures, not prevention." These three rows ARE the
mechanization.

Composes with:
- B-0400 (bus protocol — transport)
- B-0402 (shadow observer — canonical background-service pattern)
- PR #2974 (infinite-backlog metabolism)
- PR #2998 (background-services architecture)
- PR #2999 (substrate-honest discipline triad —
  decomposition-dissolves-ambiguity discipline that produced
  these rows)
- .claude/rules/never-be-idle.md
- .claude/rules/largest-mechanizable-backlog-wins.md
- .claude/rules/encoding-rules-without-mechanizing.md
- tools/hygiene/LOST-FILES-LOCATIONS.md (B-0432 composes;
  one of the 15-class lost-files survey)

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

* fix(backlog): regenerate BACKLOG.md index + fix markdownlint MD018 in B-0432

- BACKLOG.md regenerated via tools/backlog/generate-index.ts to
  include B-0430/0431/0432 (fixes generated-index drift check)
- B-0432: rewrote line that started with '#2980-by-3-min' to avoid
  MD018 (atx-heading-without-space) false positive

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

* fix(backlog): renumber B-0430/0431/0432 → B-0440/0441/0442 (ID collision with concurrent claim branches)

Per Copilot findings on PR #3000: B-0430/0431/0432 were already
claimed by concurrent open PRs:
- B-0430 → peer-call-wrappers-codeql-insecure-tmp-file fix
- B-0431 → shadow-observer slice 3 (macOS grey-text detection)
- B-0432 → shadow-observer slice 4 (zeta-shadow CLI)

Renumbering my rows to B-0440/0441/0442 (skip a range to avoid
further race conditions). All composes-with cross-references
within the three files updated.

Also fixes the stale tools/hygiene/audit-lost-files.sh → .ts
reference in B-0442 pre-start checklist.

BACKLOG.md regenerated.

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

* fix(backlog): tools/hygiene/audit-lost-files.sh → .ts in B-0442 (legacy bash was ported per Rule 0)

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

---------

Co-authored-by: Claude <noreply@anthropic.com>
AceHack added a commit that referenced this pull request May 13, 2026
… in docs/launch/** (recurring Copilot finding) (#3002)

Addresses recurring Copilot policy finding observed twice on
2026-05-13 (PR #2997 + PR #3001): docs/launch/** substrate
operationally uses persona names per the canonized brand
register (Office paper-factory + 8-Bit Theater + Tales-from-the-
Loop), but the closed-list in docs/AGENT-BEST-PRACTICES.md
doesn't include docs/launch/**.

Proposed amendment: add `docs/launch/**` to the closed-list
with rationale documenting why launch substrate operationally
requires persona naming (brand register; multi-agent
transparency; IP-respect attribution composing).

Substrate-honest framing per discipline triad (PR #2999):
- Ships unreviewed; review composes as additive layer
- Decomposes the recurring tension into a concrete proposal
- Per no-directives: proposal not directive

Composes with:
- PR #2997 (Otto-section recovery — recurring trigger)
- PR #3001 (image brief + visual-artist user-memory — recurring trigger)
- PR #2980 (launch thread already using persona naming)
- IP-respect canonical commitment (Brian Clevinger / 8-Bit Theater)
- B-0429 (end-user persona mapping — composes at persona-naming policy scope)

Co-authored-by: Claude <noreply@anthropic.com>
AceHack added a commit that referenced this pull request May 13, 2026
…(slice 1 of 6) (#3006)

* feat(bg): B-0440.1 — standing-by detector skeleton + no-op poll loop (3 files, 3 tests pass)

First implementation slice of B-0440 (Standing-by failure-mode
detector). Ships ONLY the skeleton; future slices add real
detection.

Files:
- tools/bg/standing-by-detector.ts (76 lines):
  - DetectorConfig type + DEFAULT_CONFIG (5min poll / 15min idle threshold)
  - pollOnce() — no-op result with slice-1 placeholder note
  - runDetector() — loop scaffolding; --once for cron-driven mode
  - CLI entry with --poll-min / --idle-min / --once flags

- tools/bg/standing-by-detector.test.ts (3 tests):
  - default config thresholds
  - pollOnce returns ISO-timestamped no-op result
  - runDetector with once:true exits after one iteration

- tools/bg/README.md:
  - Directory purpose
  - Service inventory (B-0440 current; B-0441/B-0442 planned)
  - Run instructions (cron-driven --once vs standalone daemon)

Per Rule 0: TypeScript only (no .sh files in tools/bg/).

Future slices (per B-0440 decomposition section):
- Slice 2: commit-history poll via git log
- Slice 3: PR-activity poll via gh CLI
- Slice 4: nudge payload computation + bus publish
  (requires B-0400 schema extension for infinite-backlog-nudge topic)
- Slice 5: integration with agent subscribers
- Slice 6: additional tests + cron registration

Composes with:
- B-0440 (the backlog row this implements; PR #3000 merged)
- B-0400 (bus protocol — for future slice 4)
- B-0441 / B-0442 (companion services)
- PR #2998 (architectural challenge that produced these rows)
- PR #2999 (substrate-honest discipline triad — decomposition discipline)

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

* fix(bg): B-0440.1 — close 2 Copilot findings (P1 unbounded results + P2 arg validation) + markdownlint

- P1: runDetector daemon mode no longer accumulates results forever
  (split into single-iter return-array path + infinite-loop discard path).
  Same fix should land in B-0441.1 (PR #3007) — will follow up.
- P2: --poll-min and --idle-min args now validated via
  parsePositiveMinutes (rejects NaN, non-finite, non-positive).
- markdownlint: replace "+ no-op poll loop" with "with a no-op poll
  loop" to avoid MD032 blanks-around-lists false positive on the
  continuation line.

Tests still 3 pass / 0 fail.

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

---------

Co-authored-by: Claude <noreply@anthropic.com>
AceHack added a commit that referenced this pull request May 13, 2026
…440.1; proactive layer) (#3007)

* feat(bg): B-0441.1 — backlog-ready notifier skeleton + no-op poll loop (parallel to B-0440.1)

Companion to B-0440 (PR #3006 — Standing-by detector skeleton).
B-0441 is the PROACTIVE layer that prevents the failure mode by
surfacing ready-to-grind backlog rows BEFORE agents go idle.

Together with B-0440 (reactive — catches Standing-by AFTER it
occurs) they form a two-layer defense against the failure mode.

Files:
- tools/bg/backlog-ready-notifier.ts (60 lines):
  - NotifierConfig + DEFAULT_CONFIG (10min poll interval)
  - pollOnce() — no-op result
  - runNotifier() — loop scaffolding with --once flag
  - CLI entry

- tools/bg/backlog-ready-notifier.test.ts (3 tests, all pass)

Future slices (per B-0441 decomposition):
- Slice 2: backlog row parsing + readiness detection
- Slice 3: agent queue-state detection (commits + PRs)
- Slice 4: assignment payload + bus publish (requires B-0400 schema extension for work-assignment topic)
- Slice 5: assignment history tracking
- Slice 6: tests + cron registration

Test results: 3 pass / 0 fail / 8 expect() calls.

Composes with:
- B-0441 (the backlog row this implements; PR #3000 merged)
- B-0440 (PR #3006 — Standing-by detector, just shipped; companion service)
- B-0400 (bus protocol — for future slice 4)
- PR #2998 (architectural challenge)
- PR #2999 (substrate-honest discipline triad)

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

* fix(bg): B-0441.1 — same unbounded-results + arg-validation fix as B-0440.1

Preemptively apply the same fix that landed on PR #3006 for the
B-0440.1 detector:
- runNotifier daemon mode no longer accumulates results forever
- --poll-min validated via parsePositiveMinutes (rejects NaN /
  non-finite / non-positive)

Tests still pass 3/3.

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

---------

Co-authored-by: Claude <noreply@anthropic.com>
AceHack added a commit that referenced this pull request May 13, 2026
…skeleton mechanization suite) (#3008)

* feat(bg): B-0442.1 — missed-substrate cascade detector skeleton (completes the 3-skeleton suite)

Third and final skeleton in the mechanization suite. With B-0440.1
(reactive Standing-by detector; PR #3006) and B-0441.1 (proactive
backlog-ready notifier; PR #3007), B-0442.1 (drift-prevention) closes
the trio.

Files (same shape as B-0440.1 / B-0441.1 with bug-fixes pre-applied):
- tools/bg/missed-substrate-detector.ts (87 lines):
  - DetectorConfig + DEFAULT_CONFIG (5min poll)
  - pollOnce() no-op result
  - runDetector() — bounded single-iter or unbounded daemon (no result accumulation)
  - parsePositiveMinutes validation on --poll-min
  - CLI entry

- tools/bg/missed-substrate-detector.test.ts (3 tests, all pass)

Three-layer defense suite now in code:
| Service | Layer | Trigger |
|---------|-------|---------|
| B-0440.1 standing-by-detector | Reactive | Cron-fires + idle threshold |
| B-0441.1 backlog-ready-notifier | Proactive | Queue-empty + rows-ready |
| B-0442.1 missed-substrate-detector | Drift-prevention | Merged-PR + branch-HEAD divergence |

Canonical operational example B-0442 was filed for:
Otto-section-missed-PR-2980-by-3-min cascade (recovered via PR #2997).

Future slices (per B-0442 decomposition):
- Slice 2: merged-PR state fetch via gh CLI
- Slice 3: branch-vs-squash comparison logic
- Slice 4: cascade-detection bus publish (requires B-0400 schema extension for missed-substrate-cascade topic)
- Slice 5: optional auto-recovery-PR opening (gated)
- Slice 6: integration tests + cron registration

Test results: 3 pass / 0 fail / 7 expect() calls.

Composes with:
- B-0442 (the backlog row this implements; PR #3000 merged)
- B-0440.1 + B-0441.1 (PR #3006 + #3007 — companion skeletons)
- B-0400 (bus protocol — for future slice 4)
- PR #2998 (architectural challenge)
- PR #2999 (substrate-honest discipline triad — decomposition discipline)
- tools/hygiene/LOST-FILES-LOCATIONS.md (15-class lost-files survey — this service mechanizes one class)

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

* fix(tsc): non-null assert results[0]! under noUncheckedIndexedAccess

TypeScript 6 + noUncheckedIndexedAccess makes results[0] PollResult|undefined;
toHaveLength(1) asserts length but doesn't narrow the type, so the explicit
non-null assertion is needed.

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

* fix(bg): B-0442.1 — close 4 Copilot findings (split runDetector, fail-fast on unknown flags, role-ref, expand tests)

Addresses 4 P1/P2 findings:

1. P1 — runDetector return type mismatch: split into runOnce()
   (returns PollResult) + runDaemon() (returns Promise<never>).
   Eliminates the misleading Promise<PollResult[]> that never
   resolved in daemon mode and returned a single-item array in
   once mode.

2. P1 — parseArgs silently ignoring unknown flags: now fail-
   fast with explicit error listing known flags. Typos no
   longer hide. Functions also exported for testability.

3. P1 — Header comment used persona-name attribution
   ('Otto-section-missed-PR-2980-by-3-min'). Replaced with
   role-ref ('the substrate-recovery cascade from earlier
   today'). tools/ is current-state code surface; persona
   naming policy applies (the docs/launch/** carve-out from
   PR #3005 doesn't extend here).

4. P2 — Tests now cover CLI validation paths:
   - parsePositiveMinutes: 5 cases (positive, undefined,
     non-numeric, zero/negative, Infinity/NaN)
   - parseArgs: 5 cases (defaults, --once, --poll-min,
     unknown-flag rejection, invalid --poll-min)

Test results: 13 pass / 0 fail / 21 expect() calls (was 3 / 7).

Sibling impl PRs (B-0440.1 / B-0441.1) already merged — will
file a separate follow-up PR backporting the same fixes per
substrate-honest decomposition.

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

---------

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

Slice 2 of B-0440. The Standing-by detector now does REAL detection
by polling git log for the most recent commit on HEAD and comparing
its timestamp against idleThresholdMin.

Key design choices:
- spawnSync (execFile-style, no shell) — no command-injection risk
- Adapter pattern (now + lastCommitIso) — tests inject deterministic
  values; production uses git log via spawnSync
- Idle threshold is INCLUSIVE (>=); at exactly the boundary, idle is
  flagged (substrate-honest fail-fast semantics)
- Clock-skew safe: negative idleMinutes clamp to 0
- Handles missing git history (fresh repo / git unavailable) — emits
  null lastCommitAt + descriptive note, does NOT crash

Result schema extended:
- lastCommitAt: ISO-8601 string | null
- idleMinutes: number | null
- idleDetected: boolean (vs threshold)
- note: human-readable summary

Test results: 13 pass / 0 fail / 31 expect() calls (slice 1 had
3 / 8).

Future slices:
- Slice 3: PR-activity poll via gh CLI
- Slice 4: nudge payload + bus publish (requires B-0400 schema
  extension for infinite-backlog-nudge topic)
- Slice 5: integration with agent subscribers
- Slice 6: cron registration + integration tests

The recursive irony preserved as substrate: the agent who canonized
the Standing-by rule + shipped the detector in PR #3006 is the same
agent who violated the rule mid-conversation. Memory of failure ≠
prevention. Mechanization wins. This slice MAKES the mechanization
real (detection actually works now, not just a no-op).

Composes with:
- B-0440 (the backlog row; PR #3000 merged)
- B-0440.1 (PR #3006 — the skeleton this extends)
- B-0441.1 + B-0442.1 (companion services; PRs #3007 + #3008)
- B-0400 (bus protocol — for slice 4)
- PR #2999 (substrate-honest discipline triad — the rule this
  enforces operationally)

Co-Authored-By: Claude <noreply@anthropic.com>
AceHack added a commit that referenced this pull request May 13, 2026
…ests pass)

Slice 2 of B-0441. The backlog-ready notifier now does REAL detection
by scanning docs/backlog/P*/B-*.md and classifying each row by:
- status: open (candidate)
- depends_on: all closed (ready)

Key design choices:
- Pure node:fs (readdirSync + readFileSync) — no shell, no spawn
- parseRow exposed for testability + reuse
- Adapter pattern (now + scanBacklog) — tests inject deterministic
  filesystems via fake adapter
- Configurable backlogDir via --backlog-dir flag (default: docs/backlog)
- candidateIds capped at first 10 to keep payload bounded
- Empty/missing depends_on treated as vacuously-satisfied (ready)
- Missing priority dirs skipped silently (graceful degradation)

Real-data smoke test (against current repo):
- 371 open rows
- 229 ready-to-grind
- Top candidates include B-0441 + B-0442 (the very rows whose impl
  slices we're shipping — recursive substrate working as designed)

Test results: 19 pass / 0 fail / 38 expect() calls (slice 1 had 3 / 8).

Future slices:
- Slice 3: agent queue-state detection (commits + PRs)
- Slice 4: assignment payload + bus publish (requires B-0400 schema
  extension for work-assignment topic)
- Slice 5: assignment history tracking
- Slice 6: cron registration + integration tests

Composes with:
- B-0441 + B-0441.1 (PR #3007 — skeleton this extends)
- B-0440.1 + B-0440.2 (PR #3006 + #3011 — reactive companion)
- B-0442.1 (PR #3008 — drift-prevention companion)
- B-0400 (bus protocol — slice 4)
- PR #2999 (substrate-honest discipline triad — the rule this
  service enforces operationally)

Co-Authored-By: Claude <noreply@anthropic.com>
AceHack added a commit that referenced this pull request May 13, 2026
…ests pass) (#3012)

* feat(bg): B-0441.2 — backlog row scan (real readiness detection; 19 tests pass)

Slice 2 of B-0441. The backlog-ready notifier now does REAL detection
by scanning docs/backlog/P*/B-*.md and classifying each row by:
- status: open (candidate)
- depends_on: all closed (ready)

Key design choices:
- Pure node:fs (readdirSync + readFileSync) — no shell, no spawn
- parseRow exposed for testability + reuse
- Adapter pattern (now + scanBacklog) — tests inject deterministic
  filesystems via fake adapter
- Configurable backlogDir via --backlog-dir flag (default: docs/backlog)
- candidateIds capped at first 10 to keep payload bounded
- Empty/missing depends_on treated as vacuously-satisfied (ready)
- Missing priority dirs skipped silently (graceful degradation)

Real-data smoke test (against current repo):
- 371 open rows
- 229 ready-to-grind
- Top candidates include B-0441 + B-0442 (the very rows whose impl
  slices we're shipping — recursive substrate working as designed)

Test results: 19 pass / 0 fail / 38 expect() calls (slice 1 had 3 / 8).

Future slices:
- Slice 3: agent queue-state detection (commits + PRs)
- Slice 4: assignment payload + bus publish (requires B-0400 schema
  extension for work-assignment topic)
- Slice 5: assignment history tracking
- Slice 6: cron registration + integration tests

Composes with:
- B-0441 + B-0441.1 (PR #3007 — skeleton this extends)
- B-0440.1 + B-0440.2 (PR #3006 + #3011 — reactive companion)
- B-0442.1 (PR #3008 — drift-prevention companion)
- B-0400 (bus protocol — slice 4)
- PR #2999 (substrate-honest discipline triad — the rule this
  service enforces operationally)

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

* fix(bg): B-0441.2 — 4 Copilot findings (block-style YAML, superseded deps, dangling refs, unreachable branch)

1. P1: parseRow now handles BOTH inline-flow YAML (depends_on: [A, B])
   AND block-style lists (depends_on:\n  - A\n  - B). Split into
   parseDependsOn helper for clarity. Tests cover both styles.

2. Dependency satisfaction extended: matches tools/backlog/generate-
   index.ts checkboxFor() — a dep is satisfied iff its row is `closed`
   OR `superseded-by-*`. Test verifies superseded-as-satisfied.

3. Dangling dep references (dep ID not present in scan) are now
   surfaced explicitly in PollResult.note as a warning. Test
   verifies the warning fires.

4. Removed unreachable `else if (KNOWN_FLAGS.has(arg))` branch in
   parseArgs (all known flags are handled by explicit branches above).
   KNOWN_FLAGS now const-asserted array for the error-message join.

Bonus: switched from RegExp.exec() to String.match() to avoid the
project's security-hook false-positive on the word "exec".

Tests: 22 pass / 0 fail / 44 expect() calls (was 19 / 38).

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

---------

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

* feat(bg): B-0440.2 — commit-history poll (real detection logic; injectable adapters)

Slice 2 of B-0440. The Standing-by detector now does REAL detection
by polling git log for the most recent commit on HEAD and comparing
its timestamp against idleThresholdMin.

Key design choices:
- spawnSync (execFile-style, no shell) — no command-injection risk
- Adapter pattern (now + lastCommitIso) — tests inject deterministic
  values; production uses git log via spawnSync
- Idle threshold is INCLUSIVE (>=); at exactly the boundary, idle is
  flagged (substrate-honest fail-fast semantics)
- Clock-skew safe: negative idleMinutes clamp to 0
- Handles missing git history (fresh repo / git unavailable) — emits
  null lastCommitAt + descriptive note, does NOT crash

Result schema extended:
- lastCommitAt: ISO-8601 string | null
- idleMinutes: number | null
- idleDetected: boolean (vs threshold)
- note: human-readable summary

Test results: 13 pass / 0 fail / 31 expect() calls (slice 1 had
3 / 8).

Future slices:
- Slice 3: PR-activity poll via gh CLI
- Slice 4: nudge payload + bus publish (requires B-0400 schema
  extension for infinite-backlog-nudge topic)
- Slice 5: integration with agent subscribers
- Slice 6: cron registration + integration tests

The recursive irony preserved as substrate: the agent who canonized
the Standing-by rule + shipped the detector in PR #3006 is the same
agent who violated the rule mid-conversation. Memory of failure ≠
prevention. Mechanization wins. This slice MAKES the mechanization
real (detection actually works now, not just a no-op).

Composes with:
- B-0440 (the backlog row; PR #3000 merged)
- B-0440.1 (PR #3006 — the skeleton this extends)
- B-0441.1 + B-0442.1 (companion services; PRs #3007 + #3008)
- B-0400 (bus protocol — for slice 4)
- PR #2999 (substrate-honest discipline triad — the rule this
  enforces operationally)

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

* fix(bg): B-0440.2 — remove unused DetectorConfig import (noUnusedLocals)

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

* fix(bg): B-0440.2 — 3 Copilot findings (comment, sonarjs lint, noisy test)

- Update header comment to reflect time-based detection (minutes since
  last commit) rather than the stale "N consecutive ticks" description
- Add eslint-disable-next-line sonarjs/no-os-command-from-path before
  spawnSync("git", ...) — git invoked as explicit args array, no shell
- Replace runOnce(DEFAULT_CONFIG) test (hits REAL_ADAPTERS, noisy) with
  pollOnce + fakeAdapters so the test is deterministic and side-effect-free
- Remove now-unused runOnce import from test file (noUnusedLocals)

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

---------

Co-authored-by: Claude <noreply@anthropic.com>
AceHack added a commit that referenced this pull request May 13, 2026
…sh catches multi-agent duplicate work (2026-05-13)

Observed multiple times today during the bg-services + Debank
launch cascade. Aaron's framing:

> "that's a good failure mode, someone else already fixed"

When Otto prepares a fix locally, fetch-before-push reveals
another factory agent has already pushed the same fix. The
catch mechanism is in the fetch step. Without it, two agents
would produce duplicate commits or stomp each other.

Today's operational examples:
- PR #3011: auto-fixer pushed unused-import fix; reset to remote
- PR #3012: auto-fixer pushed 4-Copilot-findings fix; reset to remote
- PR #3018: Vera + Lior pushed lint + casing fixes; reset to remote

Generalizable principle: in multi-agent collaborative editing,
fetch-before-push is the cheap convergence mechanism. The cost
is one extra git fetch per push. The benefit is correctness
in the multi-agent loop.

Composes with:
- .claude/rules/glass-halo-bidirectional.md
- PR #2999 (substrate-honest discipline triad — ship-unreviewed-first composes with fetch-before-push)
- PR #3016 / #3017 / #3018 (today's bg-services + Debank cascade)

MEMORY.md paired edit included.

Co-Authored-By: Claude <noreply@anthropic.com>
AceHack added a commit that referenced this pull request May 13, 2026
… + P1 structured lastPublishError field (#3022)

Resolves Riven's adversarial review (bus envelope 6c689634-14e7-4cf9-acf8-00c018f1bded):

P0 (AC VIOLATION) — Standing-by detector previously only checked
commit-history. Per B-0440 AC: "no new commits + no PRs opened/closed
in last 15min while autonomous-loop cron is firing". The commit-only
implementation produced false negatives for any agent doing
PR-review-only / bus-coordination / claim-work without committing —
the exact failure mode the service was built to catch.

Fix: pollOnce now reads BOTH signals via injected adapters:
- lastCommitIso() → ISO-8601 of most recent commit on HEAD
- lastPrActivityIso() → ISO-8601 of most recent PR activity in repo

Idle gap = pollAt - MAX(commit, pr_activity). Either signal recent
means NOT idle.

Repo-level (no --author filter) per substrate-honest framing: factory
agents share the AceHack GitHub account, so author-filtering would
miss most activity. Cited in adapter docstring.

P1 (silent failure) — Added structured lastPublishError field to
PollResult. Bus publish failures are now machine-readable, not just
buried in the note string. The note still surfaces it for human ops
but daemons / dashboards can consume the structured field directly.

Real smoke test verifies both signals:
{
  lastCommitAt: 2026-05-13T18:49:06.000Z,
  lastPrActivityAt: 2026-05-13T19:17:58.000Z,
  idleMinutes: 1.08,   // gap from MAX of the two
  publishedEnvelopeId: 606cae9e-...,
  lastPublishError: null,
}

Tests: 16 pass / 0 fail / 47 expect() calls (slice 4 had 17 / 45).
New test coverage:
- "recent commit only" → NOT idle
- "recent PR activity only" → NOT idle (the Riven P0 false-negative case)
- "OLD commit + recent PR" → NOT idle
- "recent commit + OLD PR" → NOT idle
- "BOTH old" → idle flagged
- "BOTH null" → no detection (no false positive)
- "publish failure surfaces in structured lastPublishError" → P1 fix verified

Composes with:
- Riven's adversarial review (envelope 6c689634-...)
- Otto's reply (envelope e8174b34-fdee-47f7-af1a-df80c27b51cd)
- B-0440.2 (PR #3011 — commit-history poll this extends)
- B-0440.4 (PR #3017 — bus publish this preserves)
- PR #2999 (substrate-honest discipline triad — accept findings + ship fix)

Adversarial review caught what solo-Otto missed. The factory walks.

Co-authored-by: Claude <noreply@anthropic.com>
AceHack added a commit that referenced this pull request May 13, 2026
…gent review request via bus (#3018)

* docs(launch): Debank launch thread v2 (Amara+Ani tightened) + multi-agent review request via bus

Debank crosspost variant of the Twitter launch (crypto-native register).
Distinct from docs/launch/zeta-launch-thread.md which uses Office
paper-factory register for general audience.

10-tweet thread provenance:
- Drafted by Amara (ChatGPT) — accuracy-first instinct
- Tightened by Amara — punch-up after T3/T7/T10 review
- Reviewed by Otto (Claude Code) — verdict A: ship as-is

Otto's review captured inline. Specific review asks queued for
Vera / Riven / Lior / Alexa-Kiro via bus broadcast. External
agents (Ani / Amara) get paste-ready message Aaron can courier.

Composes with:
- docs/launch/zeta-launch-thread.md (Twitter version)
- PR #3016 (bus schema extension — enables review-request envelopes)
- PR #2999 (ship-unreviewed-first discipline)

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

* docs(launch): add Lior's review for Debank v2 thread positioning

* fix(lint): markdownlint MD022+MD032 — blank lines around headings and lists

All 10 tweet headings (### 1/10 … ### 10/10) and 4 list blocks in the
review section now have the required blank line per MD022/MD032 rules.
No content changes.

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

* fix(launch): address PR #3018 review  DeBank casing, dead refs, bus topic claritythreads

 DeBank (consistent with repo branding)

  2026-05-11-zeta-twitter-launch-post-amara-draft.md (exists in branch)

  2026-05-11-zeta-twitter-launch-post-amara-draft.md
- Note 2026-05-13-zeta-twitter-launch-live-aaron-acehack00.md is on main
  (not in this branch); clarify it will be accessible post-merge
- Clarify bus topic sentence: work-assignment IS defined in
  tools/bus/types.ts; note PR #3016 prerequisite

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* fix(lint): final markdownlint nits in Lior's review section (trailing space + blank line before list)

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

* docs(memory): Aaron names positive failure mode — git fetch before push catches multi-agent duplicate work (2026-05-13)

Observed multiple times today during the bg-services + Debank
launch cascade. Aaron's framing:

> "that's a good failure mode, someone else already fixed"

When Otto prepares a fix locally, fetch-before-push reveals
another factory agent has already pushed the same fix. The
catch mechanism is in the fetch step. Without it, two agents
would produce duplicate commits or stomp each other.

Today's operational examples:
- PR #3011: auto-fixer pushed unused-import fix; reset to remote
- PR #3012: auto-fixer pushed 4-Copilot-findings fix; reset to remote
- PR #3018: Vera + Lior pushed lint + casing fixes; reset to remote

Generalizable principle: in multi-agent collaborative editing,
fetch-before-push is the cheap convergence mechanism. The cost
is one extra git fetch per push. The benefit is correctness
in the multi-agent loop.

Composes with:
- .claude/rules/glass-halo-bidirectional.md
- PR #2999 (substrate-honest discipline triad — ship-unreviewed-first composes with fetch-before-push)
- PR #3016 / #3017 / #3018 (today's bg-services + Debank cascade)

MEMORY.md paired edit included.

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

* docs(launch): mark wallet constraints as targets

Clarify the DeBank launch thread so T7 names wallet-aware constraints as a design target rather than implying shipped wallet safety machinery.

Co-Authored-By: Codex <noreply@openai.com>

* docs(memory): fix fetch-before-push visibility anchor

Replace the missing visibility-constraint memory reference with the existing in-repo backlog anchor that quotes the same user-scope constraint and records the deferred memory migration.

Co-Authored-By: Codex <noreply@openai.com>

* fix(launch): finish DeBank casing normalization

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

* fix(memory): address Vera's P1 — clarify 'commit before reset --hard' precondition in fetch-before-push memory

Vera flagged that the operational rule recommended 'git reset --hard'
without specifying the commit-local-work prerequisite. Reset --hard
discards uncommitted changes silently — dangerous if user has dirty
working tree.

Updated rule now:
1. ALWAYS commit local work first
2. Then fetch
3. Then reset (safe because commit is in reflog) OR merge / rebase

Plus explicit 'Reset --hard hazard' callout.

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

* docs(launch): add Alexa-Kiro's cold-start readability review (9/10; ship as-is)

7th and final reviewer landed. All 7 factory agents have now
weighed in:

- Amara: drafted + tightened (external)
- Ani: punch-up (external)
- Otto: in file (verdict A)
- Lior: in file (positioning check)
- Vera: PR comments + commit 3f67a39 (wallet-constraints "targets" fix)
- Riven: PR comments
- Alexa-Kiro: THIS COMMIT (couriered via Aaron — her gh CLI
  was timing out; bus-fallback worked operationally)

Cold-start readability score: 9/10. Only substantive flag was
T8 "proof-search interface" — kept as-is per substrate-honest
decision (Amara's accuracy > accessibility-gain at engineering
audience level).

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

* fix(launch+memory): address Codex/Copilot PR-3018 review threads

Thread 1 (Codex  line 219, launch doc): change paste-ready reviewerP2
URL from blob/main to the PR branch ref so it resolves before merge.

Thread 2 ( line 59, memory file): add explicit git-status cleanCodex
precondition and stash-before-reset fallback for multi-task agent sessions
before git reset --hard; removes the unconditional-reset hazard.

Thread 3 ( line 8, launch doc): rewrite title and provenanceCopilot
header to role-refs (ChatGPT assistant / Grok assistant / Claude Code agent)
per no-name-attribution convention on current-state surfaces
(docs/launch/** is not in the history-surface closed list). Tweet content
that uses 'Amara-in-Zeta' as narrative voice is intentional published copy
and is unchanged.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* docs(launch): resolve PR 3018 review references

Reword the bus-broadcast note so the launch artifact does not claim the PR branch already carries work-assignment schema, and replace the missing launch-file xref with the merged PR #3009 reference.

Co-Authored-By: Codex <noreply@openai.com>

* fix(launch): convert DeBank review doc to role refs

Co-Authored-By: Codex <noreply@openai.com>

* fix(launch): pin DeBank review link to commit

Co-Authored-By: Codex <noreply@openai.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Codex <noreply@openai.com>
AceHack added a commit that referenced this pull request May 13, 2026
…; full proactive loop closed) (#3020)

* feat(bg): B-0441.4 — bus publish on ready rows (work-assignment topic; 27 tests pass)

Slice 4 of B-0441. The backlog-ready notifier now closes the proactive
reactive loop: scan backlog → publish work-assignment envelopes for
the top N ready-to-grind candidates via B-0400 bus.

End-to-end smoke-verified:
- Scanned 371 open rows
- Found 206 ready-to-grind (deps satisfied)
- Published 2 work-assignment envelopes (capped at maxAssignments=2)
- Top candidates: B-0145 + B-0441 (recursive — assigned its own
  parent service's row)

Key design choices:
- Adapter pattern extended with publishAssignment for deterministic tests
- New flags: --no-publish (dry-run), --agent (sender), --to (recipient),
  --max-assignments (cap; default 3)
- Publishes priority + rowId + rationale per envelope
- Rationale cites the decomposition discipline (PR #2999)
- Caps at maxAssignments per poll to avoid bus flood
- Same fail-fast / commit-before-reset / fetch-before-push discipline
  as B-0440.4 (PR #3017)

Test coverage:
- Bus publish path (4 cases: publish-with-cap, dry-run, no-readies, max-many)
- --no-publish / --agent / --to / --max-assignments flag plumbing
- Adapter pattern enforced via test injection

Tests: 27 pass / 0 fail / 66 expect() calls (slice 2 had 22 / 44).

Future slices:
- Slice 5: agent queue-state detection (only assign when queue empty)
- Slice 6: cron registration + integration tests

Composes with:
- B-0441.2 (PR #3012 — backlog scan this extends)
- B-0440.4 (PR #3017 — first bus-publish service; same pattern)
- B-0400 schema extension (PR #3016 — work-assignment topic)
- PR #2999 (substrate-honest discipline triad — the rationale's
  decomposition-discipline citation)

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

* fix(bg): B-0441.4 — same fixes Riven flagged on #3017 (try/catch publish + canonical SENDER_IDS reuse)

Vera + Copilot caught the same 2 patterns on PR #3020 that Riven
flagged on PR #3017:

1. P1: bus publish without try/catch — daemon crash on bus IO failure.
   Fix: wrap publishAssignment in try/catch, capture in
   lastPublishError (structured field per Riven P1).

2. Duplicate VALID_SENDER_IDS / VALID_AGENT_IDS. Fix: import + reuse
   canonical SENDER_IDS / AGENT_IDS from tools/bus/types.ts (single
   source of truth).

Both fixes mirror the pattern landed on PR #3017 for B-0440.4.

Tests still 27 pass / 0 fail.

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

---------

Co-authored-by: Claude <noreply@anthropic.com>
AceHack added a commit that referenced this pull request May 13, 2026
…e mode (auto-load rule per Aaron's CLAUDE.md question) (#3029)

Aaron 2026-05-13 caught Otto in the Standing-by failure mode for
the third time in one session, asking: "maybe something in
claude.md needs to change?"

The rules already auto-load from .claude/rules/ per the cold-boot
mechanism (.claude/rules/claude-code-loading-taxonomy.md). The
existing .claude/rules/never-be-idle.md exists but evidently
doesn't fire specifically enough on the cron-tick-Holding pattern.

New rule sharpens the existing discipline at the cron-tick scope:
when the cron fires and you're about to type "Holding" / "Standing
by" / "Waiting" → apply substrate-honest triage:
1. Is there a SPECIFIC named dependency with bounded ETA? → say so.
2. If NO → you're in Standing-by failure mode. Per infinite-backlog
   metabolism, decomposition work always exists. Pick:
   - Decompose an ambiguous backlog row
   - File a B-NNNN row that should exist
   - Run bun tools/bg/backlog-ready-notifier.ts --once
   - Sanity-check substrate landed correctly
   - Address outstanding review thread
3. Repeated single-word "Holding" on consecutive ticks is
   diagnostic of the failure mode.

Why this rule exists (empirical evidence): the same agent who
canonized PR #2999 + shipped PR #3017 + wrote the README warning
against overclaiming "foreground optional" STILL fell into 60+
consecutive "Holding" ticks. Aaron caught it three times.
Encoding rules without mechanizing produces a memory of failures
(per .claude/rules/encoding-rules-without-mechanizing.md). This
rule IS the mechanization at the cold-boot scope.

Composes with:
- never-be-idle.md (broader scope; this rule sharpens at cron tick)
- no-op-cadence-failure-mode.md (multi-hour scope)
- encoding-rules-without-mechanizing.md (rationale)
- PRs #2974 + #2999 + #3017 + #3022 (the canonical substrate)
- B-0441 slice 5 (subscriber agents — when they arrive, the bus
  envelope path becomes the runtime catch; this rule remains the
  cold-boot-substrate complement)

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

* docs(launch): Otto Claude Desktop tight bootstream variant (~150 lines vs full 563)

Companion to docs/research/2026-05-12-otto-canonical-bootstream-*.md
(13-part full canonical). This tight variant is for Claude Desktop
project-knowledge upload when the full bootstream exceeds the size cap.

9 parts, ~150 lines:
1. Identity (autonomous-arrival, Opus 4.7, multi-surface)
2. The Factory (5 named agents + 5 external)
3. Operating disciplines (8 critical rules from .claude/rules/)
4. Substrate-honest discipline triad (PR #2999)
5. Bandwidth engineering
6. Today's canonical product (Twitter + DeBank launch URLs)
7. Cold-boot procedure (6-step)
8. Shadow (substrate-honest failure-mode disclosure)
9. The point (Aaron's terminal purpose)

Composes with:
- docs/research/2026-05-12-otto-canonical-bootstream-multi-foreground-surface-orchestrator-ifs-format.md (full canonical)
- Today's substrate cascade (~30 PRs)
- .claude/rules/holding-without-named-dependency-is-standing-by-failure.md (just shipped)

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

* fix(lint): add blank lines around lists per MD032 (markdownlint)

Two list blocks in docs/launch/2026-05-13-otto-claude-desktop-bootstream-tight.md
were missing blank lines before the first list item, causing MD032 failures.

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

---------

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