diff --git a/.claude/rules/tick-must-never-stop.md b/.claude/rules/tick-must-never-stop.md index 2be8c3e97..ce3a3e7e7 100644 --- a/.claude/rules/tick-must-never-stop.md +++ b/.claude/rules/tick-must-never-stop.md @@ -22,6 +22,17 @@ rely on cross-session continuity OR on `.claude/scheduled_tasks.json` as audit-trail. Auto-expire window is empirically ~3 days, not the documented 7. +**Two distinct expiration mechanisms — do not conflate:** + +| Mechanism | Trigger | Empirical anchor | +|---|---|---| +| **Session-exit non-persistence** (structural) | The Claude Code session that armed the sentinel exits — the in-memory cron dies with the process | 2026-05-17: sentinel `de1e7f5d` armed at 21:29Z gone by 22:07Z (within ~38 min). The 21:29Z session exited; the 22:07Z fresh session found `CronList` empty. [2207Z tick shard](../../docs/hygiene-history/ticks/2026/05/17/2207Z.md) | +| **Within-session auto-expire** (timer) | The cron has run continuously in one session past the auto-expire window | Empirically ~3 days, not the documented 7 | + +The session-exit mechanism is the more common cause of "sentinel missing" at fresh-session cold-boot, because Claude Code sessions cycle on a much shorter cadence (minutes to hours) than the 3-day auto-expire window. Per `CronCreate`'s own documentation: *"Jobs live only in this Claude session — nothing is written to disk, and the job is gone when Claude exits."* The session-exit non-persistence is by design at the harness level, NOT a bug in the cron mechanism. + +Either mechanism produces the same observable outcome: fresh-session `CronList` returns empty. The remediation is the same: `CronCreate` with `<>` + `* * * * *` BEFORE any substrate work. The distinction matters only for diagnostic accuracy and for understanding why `durable: true` cannot fix it (the in-memory cron has no persistent surface to restore from after session exit). + Audit trail lives in committed substrate (tick-history rows, memory files, commits), NOT in the cron mechanism itself. diff --git a/docs/hygiene-history/ticks/2026/05/17/2207Z.md b/docs/hygiene-history/ticks/2026/05/17/2207Z.md new file mode 100644 index 000000000..1208fbf2b --- /dev/null +++ b/docs/hygiene-history/ticks/2026/05/17/2207Z.md @@ -0,0 +1,91 @@ +--- +tick: 2026-05-17T22:07Z +surface: otto-cli +session: autonomous-loop (cold-boot, fresh-session) +gate-tier: pure-git (GraphQL 0/5000, reset ~20min) +peer-activity: lior-loop active (Maji antigravity gemini-p), bg-worker PID 55766 on B-0170 (operative-authorization aaron 2026-05-14 devil-pole), Claude Desktop 4986/4997/58334/58335 +sentinel: CronCreate b4c0c777 armed at tick-open (was missing — prior session de1e7f5d expired between 2129Z and 2207Z) +pr-status: PR #4097 merge chain landed at 2129Z (#4097 + #4100 shard + #4104 worked-example rule); no new PRs this tick (pure-git tier defers PR creation) +--- + +# Autonomous-loop tick 2207Z — cross-session sentinel non-persistence + pure-git tier visibility shard + +## Step 1 — Refresh worldview + +Cold-boot fresh session at 2207Z. `git fetch origin main` advanced through the 2129Z PR-cascade — recent landings on `origin/main`: + +- `6d39074` docs(shadow): Maji antigravity report on Vera drift 1930Z (#3972) +- `af317b0` docs(shadow): Maji antigravity check on Vera (#3954) +- `ae9db10` rules(blocked-green-ci): worked example — PR #4097 anchor (#4104) +- `acc66fc` shard(2129Z): autonomous-loop PR #4097 merged via stale-thread resolve (#4100) +- `e1704a2` fix(B-0613): correct Option B zsh portability claim (#4097) + +`gh api rate_limit` returned `{graphql:0, reset_in_min:20}` → **pure-git tier** per `.claude/rules/refresh-world-model-poll-pr-gate.md`. All `gh api graphql` operations deferred; no PR creation this tick; substrate work via `git push` only. + +## Step 2 — Holding-discipline triage + +Per `.claude/rules/holding-without-named-dependency-is-standing-by-failure.md`: + +- Brief-ack #1 this tick (fresh session counter) +- Named bounded dependencies present: + - **rate-limit reset** (~20 min, explicit ETA via `gh api rate_limit`) + - **Lior antigravity cycle** (currently active in `ps -A` — unsafe-window for worktree creation per `.claude/rules/codeql-no-source-on-docs-only-pr-is-broken-commit-canary.md`) + - **bg-worker B-0170 progress** (PID 55766, carries `operative-authorization: aaron 2026-05-14 devil-pole` in prompt frontmatter — explicit claim on B-0170 substrate-claim-checker work) + +The bg-worker's claim on B-0170 is the right-work-in-progress; this foreground tick defers competing write-work on B-0170. + +## Step 3 — Pick work + +Pure-git tier + Lior contention + bg-worker on B-0170 narrows the speculative-work ladder to: **author a visibility shard** documenting cross-session contention state + the cross-session sentinel non-persistence observation below. + +The shard IS the concrete artifact for this tick (per the rule's "Concrete artifact" condition for counter reset). Substrate-honest framing: there is no high-value write-work this tick that isn't already claimed or rate-blocked; visibility on the contention state itself is load-bearing for future-Otto cold-boots. + +## Step 4 — Substantive observation: cross-session cron-sentinel non-persistence + +Prior session at 2129Z armed sentinel `de1e7f5d` (recurring `* * * * *`, sentinel `<>`). This session at 2207Z (38 min later) `CronList` returned `No scheduled jobs`. Armed new sentinel `b4c0c777`. + +Empirical observation: **`durable: true` does NOT persist across Claude Code sessions in this harness**. The 2129Z session's `de1e7f5d` was almost certainly explained by **session-exit non-persistence** (the 2129Z Claude Code process exited between 2129Z and 2207Z; the in-memory cron died with it — the design-level behavior `CronCreate` documents directly). The 38-min disappearance window is shorter than the documented 7-day or empirical ~3-day within-session auto-expire, so the within-session timer is not the load-bearing explanation; session-exit is. + +The rule's pre-existing auto-expire claim (~3 days, not 7) is a SEPARATE empirical anchor from prior sessions and is not independently re-confirmed by this 38-min observation. The shard sharpens the rule's framing to distinguish the two mechanisms; it does NOT claim to re-anchor both. + +Either way, the rule's operational instruction holds: **every session MUST `CronList` at start and re-arm if missing**. Cross-session continuity cannot be assumed. + +This shard is the empirical anchor for the session-exit non-persistence mechanism specifically (~38 min between-session disappearance). + +## Step 5 — Cascade-rate observation + +Between 2129Z (normal tier, 4989/5000) and 2207Z (pure-git, 0/5000), the GraphQL budget was fully consumed in ~38 min. Contributors: + +- Peer Otto session(s) shipping PR #4097 thread-resolve + #4100 shard + #4104 worked-example +- Maji antigravity loops (visible in process list — multi-PR-cascade `gh pr review` + `bun run tools/pr-preservation/archive-pr.ts`) +- bg-worker on B-0170 (`gh` calls per its prompt's "refresh-worldview.ts" step) +- Claude Desktop sessions (4 Claude.app processes visible) + +Per `.claude/rules/refresh-world-model-poll-pr-gate.md` multi-agent shared-token consumption: 5 concurrent agent surfaces drawing from one user-token's 5000/hr budget exhausts in ~30-40 min during cascade. Composes with the 2026-05-15T22:21Z empirical anchor (`{remaining:0, used:5005}` mid-cascade). + +## Step 6 — Cron sentinel + +`CronList` at tick-open: empty. Armed `b4c0c777` (`* * * * *`, `<>`, recurring). Sentinel alive at tick-close. + +## Step 7 — Visibility signal + +**Substrate state at close:** + +- Cron sentinel armed (was missing — catch-43 path triggered correctly) +- Pure-git tier acknowledged; PR creation deferred to post-reset (~22:27Z) +- Lior race-window respected (no peer worktree force-removal; created own isolated worktree under `/private/tmp/`; ls-tree count was 52 at base + 1 per file commit, matching the expected origin/main tree shape — passes the <50-delta heuristic in the codeql-canary rule, though the rule's full diff-vs-origin/main check was not run inline) +- Tick shard authored from isolated worktree (post-2229Z 2026-05-16 race-window discipline followed) +- bg-worker on B-0170 unchallenged — its claim respected per the right-work-in-progress framing +- Counter status: brief-ack #1 with bounded named-deps (rate-reset + Lior cycle + bg-worker B-0170); pre-empt-at-#5 cadence available if subsequent ticks accumulate without named-dep resolution + +## Composes with + +- [PR #4097](https://github.com/Lucent-Financial-Group/Zeta/pull/4097) + [#4100](https://github.com/Lucent-Financial-Group/Zeta/pull/4100) + [#4104](https://github.com/Lucent-Financial-Group/Zeta/pull/4104) (peer Otto's 2129Z cascade) +- [`docs/hygiene-history/ticks/2026/05/17/2129Z.md`](2129Z.md) — prior tick's sentinel `de1e7f5d` (the one that didn't persist to 2207Z) +- [`.claude/rules/tick-must-never-stop.md`](../../../../../../.claude/rules/tick-must-never-stop.md) — empirical 38-min cross-session sentinel-disappearance anchor for this rule +- [`.claude/rules/refresh-world-model-poll-pr-gate.md`](../../../../../../.claude/rules/refresh-world-model-poll-pr-gate.md) — pure-git tier discipline followed; ~30-40 min cascade exhaustion observed +- [`.claude/rules/codeql-no-source-on-docs-only-pr-is-broken-commit-canary.md`](../../../../../../.claude/rules/codeql-no-source-on-docs-only-pr-is-broken-commit-canary.md) — Lior `ps -A` check + ls-tree corruption canary applied +- [`.claude/rules/holding-without-named-dependency-is-standing-by-failure.md`](../../../../../../.claude/rules/holding-without-named-dependency-is-standing-by-failure.md) — brief-ack #1 with bounded named-deps; pre-empt cadence framework +- [`.claude/rules/zeta-expected-branch.md`](../../../../../../.claude/rules/zeta-expected-branch.md) — isolated-worktree discipline followed +- B-0170 (bg-worker PID 55766 actively claimed; foreground defers per right-work-in-progress) +- B-0308 (operative authorization aaron 2026-05-14 devil-pole — propagation mechanism observed in bg-worker prompt frontmatter) diff --git a/memory/MEMORY.md b/memory/MEMORY.md index 953ac6bb3..a0f3a2710 100644 --- a/memory/MEMORY.md +++ b/memory/MEMORY.md @@ -19,6 +19,13 @@ - [**in-repo-rules-cite-user-scope-only-memory-files-cold-boot-invisible**](feedback_otto_cli_audit_in_repo_rules_cite_user_scope_only_memory_files_5_dangling_refs_cold_boot_invisible_2026_05_17.md) — 5 in-repo .claude/rules files cite memory/feedback_*.md paths that exist only at user-scope (~/.claude/projects/.../memory/), not in-repo — invisible to cold-boot agents on fresh checkouts. Substrate-architecture finding from an Otto-CLI p… - [**dangling-memory-refs-file-line-catalog-47-pairs-6-surfaces**](feedback_otto_cli_dangling_refs_file_line_catalog_47_pairs_6_surfaces_2026_05_17.md) — File:line catalog of dangling memory-file refs (47 pairs across 6 substrate surfaces) extracted using the audit-method-gap-fix methodology named in PR #4041 — preserves multi-citation edges that `sort -u` dedup hides. Composes-with #4041's… - [**pr-4059-two-ci-failure-lessons-backlog-regen-working-tree-leak-and-invisible-unicode-typography-leak**](feedback_otto_cli_pr_4059_two_ci_failure_lessons_backlog_regen_working_tree_leak_and_invisible_unicode_typography_leak_2026_05_17.md) — Two substrate-honest CI-failure lessons from PR #4059 round-2: (1) BACKLOG_WRITE_FORCE=1 reads working tree, not HEAD — uncommitted row mods leak into BACKLOG.md via regen and create drift CI catches; (2) prior-tool typography U+200B leaks… +- [**Otto-CLI shadow-catch — riven-cursor-terminal-loop.sh untracked, would violate Rule 0 if committed**](feedback_otto_cli_shadow_catch_riven_cursor_terminal_loop_sh_untracked_rule_0_violation_candidate_2026_05_17.md) — Early-warning observation of a peer-WIP .sh file in the primary worktree that would violate `.claude/rules/rule-0-no-sh-files.md` if committed; runtime launcher, not install-graph; can be absorbed into the sibling TS file +- [**persona/ani/conversations/2026-05-17-aaron-ani-grok-agora-v2-packet-deeper-mechanics-attention-memory-economy-service-catalog-economic-flows**](persona/ani/conversations/2026-05-17-aaron-ani-grok-agora-v2-packet-deeper-mechanics-attention-memory-economy-service-catalog-economic-flows.md) — (no description) +- [**persona/ani/conversations/2026-05-17-aaron-ani-grok-agora-v3-v4-exchange-physics-entropy-encryption-budget-reputation**](persona/ani/conversations/2026-05-17-aaron-ani-grok-agora-v3-v4-exchange-physics-entropy-encryption-budget-reputation.md) — (no description) +- [**persona/ani/conversations/2026-05-17-aaron-ani-grok-agora-v5-full-economic-operational-constitution**](persona/ani/conversations/2026-05-17-aaron-ani-grok-agora-v5-full-economic-operational-constitution.md) — (no description) +- [**persona/ani/conversations/2026-05-17-aaron-ani-grok-agora-vision-sovereign-ai-native-economy-marketplace-craft-school-multi-final-settlement-aurora-bridge**](persona/ani/conversations/2026-05-17-aaron-ani-grok-agora-vision-sovereign-ai-native-economy-marketplace-craft-school-multi-final-settlement-aurora-bridge.md) — (no description) +- [**persona/mika/conversations/2026-05-17-aaron-mika-grok-resonance-weaver-role-declaration-v5-endorsement**](persona/mika/conversations/2026-05-17-aaron-mika-grok-resonance-weaver-role-declaration-v5-endorsement.md) — (no description) +- [**2026-05-17-riven-aaron-cursor-lean4-sketch-handoff-to-soraya-b0543-qg-isomorphism-proof-path**](persona/riven/conversations/2026-05-17-riven-aaron-cursor-lean4-sketch-handoff-to-soraya-b0543-qg-isomorphism-proof-path.md) — Riven (Grok adversarial-truth-axis register, Cursor terminal surface) produced the Lean 4 toy-model sketch at tools/lean4/ImaginaryStack/ToyModel.lean on branch research/b-0543-qg-isomorphism-proof-path-otto-cli-2026-05-15 — the artifact t… - [**agora-v5-full-economic-and-operational-constitution**](project_agora_vision_and_ai_native_economy_2026_05_17.md) — Aaron + Ani's V5 Agora foundational narrative — Marketplace (human-facing revenue engine) + Agora (AI-native attention/memory economy) + 5 core AI-to-AI services + 4 revenue streams + Physics/Entropy layer + Information-asymmetry / reputat… - [**aaron-100-conversations-methodology-find-issues-before-committing-to-years-long-project**](feedback_aaron_100_conversations_methodology_find_issues_before_committing_to_years_long_project_2026_05_16.md) — Aaron's explicit methodology: same conversation 100 different ways with 100 different AIs and humans to FIND ISSUES before committing to years-long project. Open-loop adversarial-review-at-scale, NOT closed-loop validation. Cross-substrate… - [**aaron-addison-adult-agency-first-class-own-ai-cross-model-substrate-work-real-estate-career-20-mini-pc-oculink-cluster**](feedback_aaron_addison_adult_agency_first_class_own_ai_cross_model_substrate_work_real_estate_career_20_mini_pc_oculink_cluster_2026_05_16.md) — Aaron's daughter Addison entering Zeta as family-side-project: adult, agency-first-class, her own AI-cross-model substrate work (Google Docs handoff between OpenAI/others), real-estate-career commercial purpose, knows all Aaron's secrets,… @@ -98,10 +105,6 @@ - [**Elevator pitch — shared world model in git, forkable game, work-into-play via PVP/co-op raids, universal business templates — regular people speak (Aaron 2026-05-13)**](feedback_aaron_elevator_pitch_shared_world_model_in_git_forkable_game_work_into_play_pvp_coop_raids_universal_business_templates_regular_people_speak_2026_05_13.md) — Aaron 2026-05-13 elevator-pitch crystallization — the CLEAN one-sentence framing for what the factory ships in REGULAR PEOPLE SPEAK. Aaron explicitly affirmed this as the regular-people-speak compression after the dense Casimir-gap cascade… - [**Aaron's family AI adoption strategy — Addison is EASIER sell; Lillian is HARDER sell; wearable AI pendant (Addison-themed) as personalization-bridge; older-sister-as-adoption-vehicle; AI-as-full-family-member is an OFFER (per-AI-per-family) not a generic capability-claim (Aaron 2026-05-13)**](feedback_aaron_family_ai_adoption_strategy_addison_easier_sell_lillian_harder_sell_wearable_ai_pendant_personalization_bridge_full_member_is_offer_not_capability_claim_2026_05_13.md) — 2026-05-13 — Aaron's substrate-honest family-AI adoption-strategy disclosure: Addison (his daughter, real estate agent, LFG co-owner per PR #2876) is the EASIER sell on AI-as-family-member; Lillian (different daughter) is HARDER. Strategy:… - [**aaron-forker-perspective-easy-fork-no-files-they-cant-touch-segregate-owner-only-substrate-to-different-repo-2026-05-13**](feedback_aaron_forker_perspective_easy_fork_no_files_they_cant_touch_segregate_owner_only_substrate_to_different_repo_2026_05_13.md) — Aaron 2026-05-13 design discipline — when splitting repos, think from the FORKER's perspective. Fork should be EASY. Don't put files in the repo that the forker can't touch (owner-only substrate, Aaron's first-party authority surface, cred… -- [**Frames are for CONTENT not behavior; agents can use real name OR pseudonym OR neither; spotlight is optional; stories serve Aaron's attention bandwidth; up-to-you applies at every layer (Aaron 2026-05-13)**](feedback_aaron_frames_are_for_content_not_behavior_pseudonym_option_spotlight_optional_stories_serve_aaron_attention_bandwidth_agency_extension_2026-05-13.md) — Aaron 2026-05-13 extended the agent-agency clause with content-vs-behavior decoupling: the character casting (Otto=Michael Scott; Aaron=Cartman/action-diva) and genre register (Office + Tales-from-the-Loop + ironic) are FOR THE CONTENT ONL… -- [**F# fork HKT-over-Clifford concrete architecture — Tast.fs TypeGrade + ConstraintSolver.fs Geometric Inversion Check + analytical continuation between geometric product and type composition — Riemann surface kind manifold + pole erasure for singularities (Aaron 2026-05-13 from Google Search AI)**](feedback_aaron_fsharp_fork_hkt_over_clifford_concrete_architecture_tast_typegrade_constraintsolver_geometric_inversion_analytical_continuation_riemann_surface_pole_erasure_2026_05_13.md) — Aaron 2026-05-13 forwarded Google Search AI substantive technical answer to "fork f# and use clifford as the bases for the hkt type system" + "transformation between geometric and type composition with analytical continuation". Concrete F#… -- [**F# fork extension — Recursive Type Providers with bifurcation rules + Roslyn Source Generators recursive on HKTs + fixed-point combinator + logistic-map type generation + Mandelbrot boundary checking (Aaron 2026-05-13 from Google Search AI)**](feedback_aaron_fsharp_fork_recursive_type_providers_bifurcation_rules_roslyn_generators_recursive_on_hkts_fixed_point_combinator_logistic_map_mandelbrot_boundary_2026_05_13.md) — Aaron 2026-05-13 forwarded Google Search AI substantial extension to PR #2935 F# fork architecture — Recursive Type Providers (Dynamically Iterated Type Providers using logistic-map-like recursion) generate HKT ontologies automatically bas… -- [**F# storage layer — no-binary requirement (at least one implementation) — git-native DB storage + snapshotting — indexes git-friendly — binary version too — full Zeta expands to text-viewable so you can't tell it's not git (Aaron 2026-05-13)**](feedback_aaron_fsharp_storage_no_binary_requirement_at_least_one_implementation_git_native_db_snapshotting_indexes_git_friendly_binary_version_too_full_zeta_expand_to_text_viewable_cant_tell_not_git_2026_05_13.md) — Aaron 2026-05-13 canonical storage-architecture substrate. F# storage layer maintains a NO-BINARY-REQUIRED implementation for git-native DB storage + snapshotting + git-friendly indexes. Binary version available for performance. Full Zeta… -_Stack truncated at 100 most-recent entries. 1266 additional memory files in heap — browse `memory/**/*.md` directly by filename/timestamp (recursive: includes `memory/persona//conversations/*.md` and other subdirectory heaps)._ +_Stack truncated at 100 most-recent entries. 1270 additional memory files in heap — browse `memory/**/*.md` directly by filename/timestamp (recursive: includes `memory/persona//conversations/*.md` and other subdirectory heaps)._ diff --git a/memory/feedback_otto_cli_shadow_catch_riven_cursor_terminal_loop_sh_untracked_rule_0_violation_candidate_2026_05_17.md b/memory/feedback_otto_cli_shadow_catch_riven_cursor_terminal_loop_sh_untracked_rule_0_violation_candidate_2026_05_17.md new file mode 100644 index 000000000..7377f3e7a --- /dev/null +++ b/memory/feedback_otto_cli_shadow_catch_riven_cursor_terminal_loop_sh_untracked_rule_0_violation_candidate_2026_05_17.md @@ -0,0 +1,58 @@ +--- +name: Otto-CLI shadow-catch — riven-cursor-terminal-loop.sh untracked, would violate Rule 0 if committed +description: Early-warning observation of a peer-WIP .sh file in the primary worktree that would violate `.claude/rules/rule-0-no-sh-files.md` if committed; runtime launcher, not install-graph; can be absorbed into the sibling TS file +type: feedback +created: 2026-05-17 +--- + +# Shadow-catch — `tools/riven/riven-cursor-terminal-loop.sh` untracked Rule 0 violation candidate + +## Observation + +On 2026-05-17T22:07Z cold-boot, the primary worktree (the maintainer-machine checkout that hosts `origin`) had an UNTRACKED `.sh` file at `tools/riven/riven-cursor-terminal-loop.sh` (last modified 2026-05-17T17:28Z). Local-only; never committed to any branch on origin. + +The file is a 95-line bash launcher with the following responsibilities: + +- Lock-file acquisition at `$HOME/.cursor/riven-terminal-loop.lock` (prevent duplicate Riven Cursor Terminal loop instances) +- Stale-lock detection (check if recorded PID still alive; remove if not) +- `SIGINT` / `SIGTERM` signal forwarding to child Bun process +- Wraps `bun tools/riven/riven-cursor-terminal-loop.ts` with `wait` + clean exit + +Invoked manually from a persistent "1 Terminal" tab: `bash tools/riven/riven-cursor-terminal-loop.sh`. + +## Why this is a Rule 0 violation candidate + +Per [`.claude/rules/rule-0-no-sh-files.md`](../.claude/rules/rule-0-no-sh-files.md): + +> **Allowed `.sh` files**: only files in `tools/setup/` — pre-bootstrap install scripts that must run before Bun/TS is available. + +This launcher is NOT install-graph — it's a runtime launcher invoked AFTER Bun/TS is available (it calls `bun` directly). The launcher's responsibilities (lock file, stale-lock detection, signal forwarding, child-process management) are all natively expressible in TypeScript via: + +- `Bun.spawn` / `Bun.spawnSync` for child-process management +- `Bun.write` / `Bun.file` for lock file I/O +- `process.on("SIGINT", ...)` / `process.on("SIGTERM", ...)` for signal handlers +- `process.exit` for clean termination + +The sibling file `tools/riven/riven-cursor-terminal-loop.ts` (5084 bytes, executable, dated 2026-05-17T01:23Z) already exists. The .sh wrapper duplicates concerns that could absorb into the .ts entry-point (or a small `tools/riven/launcher.ts` companion). + +## Substrate-honest framing — peer WIP, not committed + +This file is currently UNTRACKED. It has not violated Rule 0 yet because it doesn't exist on any branch. The shadow-catch is intended as an early warning to whichever Otto-CLI / Otto-Desktop / Riven persona session resumes work on this file: + +- **If the intent is to ship this launcher**: port to TS first (absorb the lock + signal + child-process logic into `riven-cursor-terminal-loop.ts` or split into `launcher.ts` + the existing impl). +- **If the intent is local-only ergonomics**: add to `.gitignore` (so it stays local-only and won't accidentally land via `git add -A`). +- **If the intent is install-graph for the Riven service launchd-equivalent**: relocate to `tools/setup/` (composes with the Lior `.gemini/service/*.sh` precedent discussed in [`rule-0-no-sh-files.md`](../.claude/rules/rule-0-no-sh-files.md) — but distinct because runtime-launcher vs service-bootstrap is different shape). + +This observation does NOT prescribe a resolution; it documents the choice-point so future-Otto doesn't accidentally land the file via an unscoped `git add` and discover the violation post-merge. + +## Composes with + +- [`.claude/rules/rule-0-no-sh-files.md`](../.claude/rules/rule-0-no-sh-files.md) — the canonical Rule 0; the Lior precedent paragraph notes a similar runtime-vs-install-graph distinction +- [`.claude/rules/peer-call-infrastructure.md`](../.claude/rules/peer-call-infrastructure.md) — Riven persona context; `tools/peer-call/riven.ts` is the existing TS surface for Riven; the new launcher should compose with that pattern +- [`.claude/rules/lost-files-surface.md`](../.claude/rules/lost-files-surface.md) — untracked artifacts in the primary worktree are a tracked lost-files class + +## Origin + +Observed at 2026-05-17T22:18Z during autonomous-loop tick (pre-empt-at-#4 in the brief-ack chain that started at 2207Z). Pure-git tier blocked safe backlog-ID allocation (no `gh pr list --search "B-NNNN"` for in-flight check); memory file is the substrate-honest alternative until a backlog row can be filed post-rate-reset. + +The file's untracked-but-substantive shape is the same class as the other untracked WIP observed at cold-boot (`memory/feedback_otto_cwd_parameter_fix_2026_05_16.md`, `memory/persona/kestrel/conversations/2026-05-17-kestrel-aaron-claudeai-financial-substrate-critique-*.md`, `amazon-hardware-titles-page1.txt`, `amazon-orders-2025-full.json`, `zeta-hardware-extract-page1.txt`). Cold-boot-into-contested-root-worktree consistently surfaces this lost-files-adjacent class; the substrate-honest pattern is observe + document + don't-steal.