Skip to content

docs(memory): Aaron architectural challenge — background services must be strong enough that foreground loop is OPTIONAL — mechanize Standing-by failure mode#2998

Merged
AceHack merged 3 commits into
mainfrom
aaron-background-services-must-be-strong-enough-foreground-loop-optional-mechanize-standing-by-failure-mode-2026-05-13
May 13, 2026
Merged

docs(memory): Aaron architectural challenge — background services must be strong enough that foreground loop is OPTIONAL — mechanize Standing-by failure mode#2998
AceHack merged 3 commits into
mainfrom
aaron-background-services-must-be-strong-enough-foreground-loop-optional-mechanize-standing-by-failure-mode-2026-05-13

Conversation

@AceHack
Copy link
Copy Markdown
Member

@AceHack AceHack commented May 13, 2026

Summary

Aaron 2026-05-13 substrate-honestly challenged Otto's 'Standing-by' failure-mode pattern with an architectural disclosure:

"you need to imagine how would you survive without this foreground loop and you background should be strong enough to do that"

"this is something background services should walk"

The foreground loop (this Claude Code Otto conversation) was operating as the load-bearing substrate-engineering driver. That's wrong by design. Background services should be the load-bearing layer. Foreground is the operator interface, not the factory itself.

Thought experiment

If Otto-foreground died right now — session terminated, context compacted, no replacement — would the factory keep operating?

  • Would PRs continue landing? — only if background agents (Vera's foreground loop counts as background relative to Otto) keep operating
  • Would the backlog get decomposed? — only if backlog-grind is mechanized via cron / launchd / scheduled work
  • Would substrate-engineering rules be applied? — only if rules are mechanized in CI / hooks / pre-commit / razor-cadence workflow
  • Would the "Standing-by" failure mode get caught? — only if a background service detects idle-foreground + nudges or reassigns work

Gaps surfaced (for backlog decomposition)

  • No idle-foreground detection + nudge service — the Standing-by failure mode was caught by Aaron in real time; should be caught by a background service
  • No backlog-decomposition surfacing service — no service proactively surfaces backlog rows when foreground agent is idle
  • No backlog row ready-to-grind notification — backlog audits exist but agents must run them on-demand
  • No missed-substrate cascade detector — e.g., my Otto-section-missed-PR-docs(launch): Zeta launch thread — final polish (production-minded + receipts) #2980-by-3-min could've been caught by a service watching for branch-vs-merged-PR drift

Composes with

Test plan

  • Memory file lands with full architectural framing + gap inventory + design sketch
  • Follow-up B-NNNN backlog rows file for: Standing-by detector, backlog-row-ready-to-grind notifier, missed-substrate cascade detector
  • Future-Otto reads this at cold-boot and recognizes the foreground-load-bearing failure mode

🤖 Generated with Claude Code

…ound services must be strong enough that foreground loop is OPTIONAL — imagine surviving without foreground — mechanize the Standing-by failure mode

Aaron 2026-05-13 substrate-honestly challenged Otto's
'Standing-by' failure-mode pattern with an architectural
disclosure:

> "you need to imagine how would you survive without this
> foreground loop and you background should be strong enough
> to do that"

> "this is something background services should walk"

The foreground loop (this Claude Code Otto conversation) was
operating as the load-bearing substrate-engineering driver.
That's wrong by design. Background services should be the
load-bearing layer. Foreground is the operator interface, not
the factory itself.

Captures: thought experiment (would the factory keep operating
if Otto-foreground died right now?); current background-service
landscape inventory; gaps (no idle-foreground detector, no
backlog-ready notifier, no missed-substrate cascade detector);
hypothetical Standing-by detector design sketch; deeper
architectural framing (foreground = visitors; substrate +
background = residents); proposed backlog rows for follow-up.

Composes with: PR #2974 (infinite-backlog metabolism — the
rule this mechanizes), .claude/rules/encoding-rules-without-
mechanizing.md (direct composition), .claude/rules/never-be-
idle.md, .claude/rules/largest-mechanizable-backlog-wins.md,
PR #2997 (Otto-section recovery — concrete artifact recovered
from the foreground-load-bearing failure).

Co-Authored-By: Claude <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings May 13, 2026 16:01
@AceHack AceHack enabled auto-merge (squash) May 13, 2026 16:01
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds a new memory/feedback_*.md entry capturing an architectural challenge: background services should be robust enough that the interactive “foreground loop” is optional, and the “Standing-by” failure mode should be mechanized rather than relying on agent introspection.

Changes:

  • Introduces a feedback memory file documenting the foreground-vs-background robustness thesis and a concrete “Standing-by detector” design sketch.
  • Enumerates current background-service inventory and identifies mechanization gaps to drive follow-up backlog decomposition.

AceHack and others added 2 commits May 13, 2026 12:12
…ate file

Adds the index entry for feedback_aaron_background_services_must_be_strong_enough_*.md
to satisfy the MEMORY.md paired-edit CI check.

Also updates the latest-paired-edit marker.

Co-Authored-By: Claude <noreply@anthropic.com>
…-to-apply section

- P1 fix: reference_otto_launchd_services_*.md lives at user-memory
  layer (~/.claude/projects/.../memory/), not project-memory. Updated
  two pointers in the substrate file to clarify location.
- P2 fix: rename 'Operational implications' to 'How to apply' per
  memory/project_memory_format_standard.md format standard.

Co-Authored-By: Claude <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings May 13, 2026 16:16
@AceHack AceHack merged commit b237daa into main May 13, 2026
25 of 26 checks passed
@AceHack AceHack deleted the aaron-background-services-must-be-strong-enough-foreground-loop-optional-mechanize-standing-by-failure-mode-2026-05-13 branch May 13, 2026 16:20
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 2 out of 2 changed files in this pull request and generated 2 comments.

Comments suppressed due to low confidence (2)

memory/feedback_aaron_background_services_must_be_strong_enough_foreground_loop_optional_imagine_surviving_without_foreground_mechanize_standing_by_failure_mode_2026_05_13.md:54

  • This references a “user-memory” file at ~/.claude/projects/<slug>/memory/reference_otto_launchd_services_mac_background_infrastructure_2026_05_08.md, but that reference file doesn’t appear to exist in the repo under memory/. If this is meant to be durable substrate for others, consider adding the reference_*.md file to the repo (and linking it relatively), or rewording this row to avoid a non-portable local path.
| `com.zeta.claude-loop` launchd service | Operational per user-memory `~/.claude/projects/<slug>/memory/reference_otto_launchd_services_mac_background_infrastructure_2026_05_08.md` | Heartbeat/gate 60s |

memory/feedback_aaron_background_services_must_be_strong_enough_foreground_loop_optional_imagine_surviving_without_foreground_mechanize_standing_by_failure_mode_2026_05_13.md:176

  • This again cites ~/.claude/projects/<slug>/memory/reference_otto_launchd_services_mac_background_infrastructure_2026_05_08.md, but there’s no corresponding memory/reference_otto_launchd_services_mac_background_infrastructure_2026_05_08.md in the repository. Consider either committing that reference file under memory/ and linking it, or removing the local-path citation to keep the composes-with list repository-resolvable.
- Otto-329 launchd-services (existing background-services
  substrate; user-memory `~/.claude/projects/<slug>/memory/reference_otto_launchd_services_mac_background_infrastructure_2026_05_08.md`)

Comment thread memory/MEMORY.md
> discipline yet; that's heap state. Architectural fix tracked at
> `docs/backlog/P1/B-0423-memory-md-serialization-point-2026-05-12.md`.

- [**Background services must be strong enough that foreground loop is OPTIONAL — imagine surviving without foreground — mechanize Standing-by failure mode (2026-05-13)**](feedback_aaron_background_services_must_be_strong_enough_foreground_loop_optional_imagine_surviving_without_foreground_mechanize_standing_by_failure_mode_2026_05_13.md) — Aaron's substrate-honest architectural challenge: background services must be strong enough that Otto-foreground dying doesn't break the factory. Mechanize Standing-by failure mode (see B-0430/0431/0432).
| Service | Status | What it does |
|---------|--------|--------------|
| `autonomous-loop` cron (CronCreate sentinel) | Operational; every-minute heartbeat | Fires `<<autonomous-loop>>` ticks; lifecycle bounded to session |
| `tools/shadow/shadow-observer.ts` (B-0402) | Slice 1 + 2 shipped on main; slice 3 + 4 pending | Polls grey-text from CLI; can invoke `--detect-cmd` external detector |
AceHack added a commit that referenced this pull request May 13, 2026
…ambiguity + ship-unreviewed-first + decompose-to-dissolve-ambiguity (2026-05-13) (#2999)

* docs(memory): Aaron substrate-honest discipline triad — stuckness-as-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>

* fix(memory): MEMORY.md paired edit + correct stale cross-reference to 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>

* fix(memory): resolve Copilot findings — typo in description + memory/ 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>

* fix(memory): collapse duplicate latest-paired-edit markers into single 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>

---------

Co-authored-by: Claude <noreply@anthropic.com>
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
…(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>
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