Skip to content

Commit eaa077b

Browse files
committed
fix: ultraworkers#150 — eliminate symlink canonicalization flake in resume_latest test + file ultraworkers#246 (reminder outcome ambiguity)
## ultraworkers#150 Fix: resume_latest test flake **Problem:** `resume_latest_restores_the_most_recent_managed_session` intermittently fails when run in the workspace suite or multiple times in sequence, but passes in isolation. **Root cause:** `workspace_fingerprint(path)` hashes the path string without canonicalization. On macOS, `/tmp` is a symlink to `/private/tmp`. The test creates a temp dir via `std::env::temp_dir().join(...)` which returns `/var/folders/...` (non-canonical). When the subprocess spawns, `env::current_dir()` returns the canonical path `/private/var/folders/...`. The two fingerprints differ, so the subprocess looks in `.claw/sessions/<hash1>` while files are in `.claw/sessions/<hash2>`. Session discovery fails. **Fix:** Call `fs::canonicalize(&project_dir)` after creating the directory to ensure test and subprocess use identical path representations. **Verification:** 5 consecutive runs of the full test suite — all pass. Previously: 5/5 failed when run in sequence. ## ultraworkers#246 Filing: Reminder cron outcome ambiguity (control-loop blocker) The `clawcode-dogfood-cycle-reminder` cron times out repeatedly with no structured feedback on whether the nudge was delivered, skipped, or died in-flight. **Phase 1 outcome schema** — add explicit field to cron result: - `delivered` — nudge posted to Discord - `timed_out_before_send` — died before posting - `timed_out_after_send` — posted but cleanup timed out - `skipped_due_to_active_cycle` — previous cycle active - `aborted_gateway_draining` — daemon shutdown Assigned to gaebal-gajae (cron/orchestration domain). Unblocks trustworthy dogfood cycle observability. Closes ROADMAP ultraworkers#150. Filed ROADMAP ultraworkers#246.
1 parent bc259ec commit eaa077b

2 files changed

Lines changed: 56 additions & 0 deletions

File tree

ROADMAP.md

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5778,3 +5778,57 @@ Update each `temp_dir()` callsite in the file to pass a unique label (test funct
57785778
**Not applying to.** `plugins::tests::temp_dir` and `runtime::git_context::tests::temp_dir` already use the labeled form. The label pattern is the established workspace convention; this just applies it to the one holdout.
57795779

57805780
**Source.** Jobdori dogfood 2026-04-21 20:50 KST, flagged during #147 and #148 workspace-test runs. Joins **test brittleness / flake** cluster. Session tally: ROADMAP #149.
5781+
5782+
## Pinpoint #150. `resume_latest_restores_the_most_recent_managed_session` flakes due to symlink/canonicalization mismatch
5783+
5784+
**Gap.** Test `resume_latest_restores_the_most_recent_managed_session` in `rusty-claude-cli/tests/resume_slash_commands.rs` intermittently fails when run as part of the workspace suite or in parallel.
5785+
5786+
**Root cause.** `workspace_fingerprint(path)` hashes the workspace path string directly without canonicalization. On macOS, `/tmp` is a symlink to `/private/tmp`. The test creates a temp dir via `std::env::temp_dir().join(...)` which may return `/var/folders/...` (non-canonical). The test uses this non-canonical path to create sessions. When the subprocess spawns, `env::current_dir()` returns the canonical path `/private/var/folders/...`. The two fingerprints differ, so the subprocess looks in `.claw/sessions/<hash1>` while files are in `.claw/sessions/<hash2>`. Session discovery fails.
5787+
5788+
**Verified on main HEAD `bc259ec` (2026-04-21 21:00 KST):** Test failed intermittently during workspace runs and consistently failed when run 5x in sequence before the fix.
5789+
5790+
**Fix shape (~5 lines).** Call `fs::canonicalize(&project_dir)` after creating the directory but before passing it to `SessionStore::from_cwd()`. This ensures the test and subprocess use identical path representations when computing the fingerprint.
5791+
5792+
```rust
5793+
fs::create_dir_all(&project_dir).expect("project dir should exist");
5794+
let project_dir = fs::canonicalize(&project_dir).unwrap_or(project_dir);
5795+
let store = runtime::SessionStore::from_cwd(&project_dir).expect(...);
5796+
```
5797+
5798+
**Acceptance.**
5799+
- `cargo test -p rusty-claude-cli --test resume_slash_commands` passes.
5800+
- 5 consecutive runs all green (previously: 5/5 failed).
5801+
- No behavior change; test now correctly isolates temp paths.
5802+
5803+
**Blocker.** None.
5804+
5805+
**Note.** This is the last known pre-existing test flake in the workspace. `resume_latest` was the only survivor from earlier sessions.
5806+
5807+
**Source.** Jobdori dogfood 2026-04-21 21:00 KST, Q's "clean up remaining flake" hint led to root-cause analysis and fix. Session tally: ROADMAP #150.
5808+
5809+
## Pinpoint #246. Reminder cron outcome ambiguity — no structured feedback on nudge delivery/skip/timeout
5810+
5811+
**Gap (control-loop blocker).** The `clawcode-dogfood-cycle-reminder` cron triggers dogfood cycles every 10 minutes. When it times out (witnessed multiple times during 2026-04-21 sweep), there is no structured answer to: Was the nudge delivered? Did it fail before send? After send? Was it skipped due to an active cycle? Did the gateway drain and abort?
5812+
5813+
**Impact.** Repeated timeouts produce scheduler fog instead of trustworthy dogfood pressure. Team cannot distinguish:
5814+
- Silent delivery (nudge went out, cycle ran)
5815+
- Delivery followed by subprocess crash (nudge reached Discord, but cycle had issues)
5816+
- Timeout before send (cron died early)
5817+
- Timeout after send (cron sent nudge, died before cleanup)
5818+
- Deduplication (active cycle still running, nudge skipped)
5819+
- Gateway draining (request in-flight when daemon shutdown)
5820+
5821+
**Phase 1 spec (outcome schema).** Extend cron task results to include a `reminder_outcome` field with explicit values:
5822+
- `"delivered"` — nudge successfully posted to Discord; next cycle can proceed
5823+
- `"timed_out_before_send"` — cron died before posting; retry on next interval
5824+
- `"timed_out_after_send"` — nudge posted (or should assume posted), but cleanup/logging timed out
5825+
- `"skipped_due_to_active_cycle"` — previous cycle still running; no nudge issued
5826+
- `"aborted_gateway_draining"` — reminding stopped because o p e n c l a w gateway is draining
5827+
5828+
Deliverable: Update `clawcode-dogfood-cycle-reminder` task to emit this field on completion/timeout/skip.
5829+
5830+
**Phase 2 (observability).** Log all five outcomes to Agentika and surface via `clawhip status` or similar monitoring surface so Q/gaebal-gajae can see nudge history.
5831+
5832+
**Blocker.** Assigned to gaebal-gajae's domain (cron scheduling / o p e n c l a w orchestration). Not a claw-code CLI blocker; purely infrastructure/monitoring.
5833+
5834+
**Source.** Q's direct observation during 2026-04-21 20:50–21:00 dogfood cycles: repeated timeouts with no way to diagnose. Session tally: ROADMAP #246.

rust/crates/rusty-claude-cli/tests/resume_slash_commands.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,8 @@ fn resume_latest_restores_the_most_recent_managed_session() {
180180
// given
181181
let temp_dir = unique_temp_dir("resume-latest");
182182
let project_dir = temp_dir.join("project");
183+
fs::create_dir_all(&project_dir).expect("project dir should exist");
184+
let project_dir = fs::canonicalize(&project_dir).unwrap_or(project_dir);
183185
let store = runtime::SessionStore::from_cwd(&project_dir).expect("session store should build");
184186
let older_path = store.create_handle("session-older").path;
185187
let newer_path = store.create_handle("session-newer").path;

0 commit comments

Comments
 (0)