Commit Graph

255 Commits

Author SHA1 Message Date
bellman
d2b5f5d498 require provenance for green contracts
Promote merge-ready green contracts from a level-only check to explicit provenance requirements for test commands, base freshness, recovery-attempt context, and known blocking flakes. This preserves simple level contracts while giving policy code a single satisfied-contract signal to require before merge decisions.\n\nConstraint: Task scope was limited to green_contract.rs, policy_engine.rs if needed, and narrow tests; stale_* and recovery_recipes.rs were not edited.\nRejected: Adding more boolean fields to GreenContract | clippy flagged the shape and a requirement list is more explicit.\nConfidence: high\nScope-risk: narrow\nDirective: Treat raw test level as insufficient for merge readiness unless green contract evidence is satisfied.\nTested: cargo check --manifest-path rust/Cargo.toml -p runtime; cargo test --manifest-path rust/Cargo.toml -p runtime; cargo clippy --manifest-path rust/Cargo.toml -p runtime -- -D warnings; focused green_contract, policy_engine, and integration tests.\nNot-tested: full workspace cargo test due pre-existing rusty-claude-cli session_lifecycle_prefers_running_process_over_idle_shell failure observed before this slice.
2026-05-14 18:33:51 +09:00
bellman
d3f8ff9916 omx(team): auto-checkpoint worker-1 [1] 2026-05-14 18:28:21 +09:00
bellman
5c40d4e778 omx(team): auto-checkpoint worker-3 [4] 2026-05-14 18:26:55 +09:00
bellman
6a37442ee1 omx(team): auto-checkpoint worker-2 [3] 2026-05-14 18:24:51 +09:00
bellman
0bca524c8c omx(team): auto-checkpoint worker-1 [1] 2026-05-14 18:22:37 +09:00
bellman
1fbde9f47f omx(team): auto-checkpoint worker-1 [1] 2026-05-14 18:21:26 +09:00
bellman
0b0d55d7ec omx(team): auto-checkpoint worker-1 [1] 2026-05-14 18:11:53 +09:00
bellman
7214573f35 Keep approval token contracts in their own runtime module
Constraint: G004 task 3 now owns approval-token contracts through rust/crates/runtime/src/approval_tokens.rs, while auto-integration left a duplicate unused copy in permissions.rs.\nRejected: suppressing dead-code warnings | the duplicate implementation was obsolete after the dedicated module landed.\nConfidence: high\nScope-risk: narrow\nDirective: Keep permission-mode authorization in permissions.rs and approval-token policy handoff in approval_tokens.rs.\nTested: cargo fmt --manifest-path rust/Cargo.toml --all -- --check; cargo check --manifest-path rust/Cargo.toml -p runtime; cargo test --manifest-path rust/Cargo.toml -p runtime approval_token -- --nocapture; cargo test --manifest-path rust/Cargo.toml -p runtime --test g004_conformance -- --nocapture\nNot-tested: full workspace test suite; G004 tasks 2/4/5 remain non-terminal.\n\nCo-authored-by: OmX <omx@oh-my-codex.dev>
2026-05-14 18:11:20 +09:00
bellman
dcf11f8190 harden report contract projection identity
Add a runtime report schema v1 contract so downstream consumers can negotiate structured fields, verify canonical report identity, and audit projection redactions without reverse-engineering prose.\n\nConstraint: Task 2 scope was limited to report schema/projection/redaction modules/docs/tests and prohibited .omx/ultragoal mutation.\nRejected: Wiring into broader CLI report emitters | kept this slice focused on the reusable contract and deterministic fixtures.\nConfidence: high\nScope-risk: narrow\nDirective: Future report emitters should build canonical payloads through CanonicalReportV1 before projecting audience-specific views.\nTested: cargo test -p runtime report_schema -- --nocapture; cargo test -p runtime lane_events -- --nocapture; cargo check -p runtime\nNot-tested: cargo clippy -p runtime --all-targets -- -D warnings remains blocked by pre-existing non-task warnings in compact.rs, file_ops.rs, policy_engine.rs, sandbox.rs.
2026-05-14 18:09:36 +09:00
bellman
e1641aa010 Prove G004 contract bundles are machine-checkable
Constraint: Task 6 needed a regression harness without overwriting Task 1-4 implementation files.\nRejected: Editing lane_events/report-schema/approval-token owners directly | would create shared-file conflicts with active lanes.\nConfidence: high\nScope-risk: narrow\nDirective: Keep this harness as a consumer-facing conformance layer; extend fixtures after Task 2/3 land schema/token producers.\nTested: cd rust && cargo test -p runtime --test g004_conformance -- --nocapture; cd rust && cargo check -p runtime; cd rust && cargo fmt --check; git diff --check\nNot-tested: cargo clippy -p runtime --tests -- -D warnings fails on pre-existing runtime lint debt outside changed files.
2026-05-14 18:07:11 +09:00
bellman
5cebdd999d omx(team): auto-checkpoint worker-2 [3] 2026-05-14 18:07:05 +09:00
bellman
bf533d77a7 task: approval token chain
Add a runtime approval-token ledger so policy-blocked actions can require scoped owner grants, consume one-time tokens, reject replay, and retain delegation traceability.\n\nConstraint: Task 3 scope is the G004 approval-token chain for runtime event/report contract families.\nRejected: Extending the existing permission prompt path directly | the token contract can be tested independently without changing live tool authorization behavior.\nConfidence: high\nScope-risk: narrow\nDirective: Keep approval grants scoped to policy/action/repo/branch before wiring them into external execution paths.\nTested: cargo check --manifest-path rust/Cargo.toml --workspace; cargo test --manifest-path rust/crates/runtime/Cargo.toml; cargo test --manifest-path rust/crates/runtime/Cargo.toml approval_token -- --nocapture\nNot-tested: cargo clippy --manifest-path rust/crates/runtime/Cargo.toml --all-targets -- -D warnings is blocked by pre-existing warnings in compact.rs, file_ops.rs, policy_engine.rs, and sandbox.rs.
2026-05-14 18:07:03 +09:00
bellman
e34209ff7f omx(team): auto-checkpoint worker-2 [3] 2026-05-14 18:07:00 +09:00
bellman
ff37d395bb Stabilize G004 contract integration after worker merges
Constraint: G004 worker integrations introduced unparseable approval-token tests and a conformance path bug that blocked leader verification.\nRejected: waiting for another auto-integration cycle | local leader verification had exact parse and fixture failures to repair safely.\nConfidence: high\nScope-risk: moderate\nDirective: Keep approval-token regression tests in cfg(test) modules or integration tests, never inside type definitions.\nTested: cargo fmt --manifest-path rust/Cargo.toml --all -- --check; cargo check --manifest-path rust/Cargo.toml -p runtime; cargo test --manifest-path rust/Cargo.toml -p runtime approval_token -- --nocapture; cargo test --manifest-path rust/Cargo.toml -p runtime --test g004_conformance -- --nocapture; python3 .github/scripts/check_doc_source_of_truth.py\nNot-tested: full workspace test suite; remaining G004 tasks 1-5 still non-terminal.\n\nCo-authored-by: OmX <omx@oh-my-codex.dev>
2026-05-14 18:06:14 +09:00
bellman
f8d744bb37 omx(team): auto-checkpoint worker-1 [1] 2026-05-14 18:05:26 +09:00
bellman
c8c936ede1 omx(team): auto-checkpoint worker-3 [6] 2026-05-14 18:00:23 +09:00
bellman
57b3e3258b omx(team): auto-checkpoint worker-2 [3] 2026-05-14 18:00:19 +09:00
bellman
06e545325d omx(team): auto-checkpoint worker-1 [1] 2026-05-14 18:00:16 +09:00
bellman
f4e08d0ecf omx(team): auto-checkpoint worker-2 [3] 2026-05-14 17:58:46 +09:00
bellman
16d6525de4 omx(team): auto-checkpoint worker-2 [3] 2026-05-14 17:57:59 +09:00
bellman
8c11dd16f4 task: preserve startup no-evidence timestamp evidence
Lock the startup-no-evidence contract so prompt timestamps remain the original send time while lifecycle and pane timestamps prove timeout ordering.

Constraint: task 4 scope limited changes to runtime worker boot/session/startup modules and tests; .omx/ultragoal not mutated.

Rejected: CLI-surface changes | runtime evidence contract already exposes the typed worker.startup_no_evidence payload.

Confidence: high

Scope-risk: narrow

Directive: Keep startup timeout evidence timestamps stable across later lifecycle observations.

Tested: cargo test -p runtime worker_boot -- --nocapture; cargo check --workspace

Not-tested: cargo clippy -p runtime --tests -- -D warnings is blocked by pre-existing runtime warnings in compact.rs, file_ops.rs, policy_engine.rs, and sandbox.rs.
2026-05-14 17:50:33 +09:00
bellman
9ec4d8398e omx(team): auto-checkpoint worker-3 [unknown] 2026-05-14 17:46:13 +09:00
bellman
087e31d190 Keep G003 integrated runtime tests compiling
Constraint: G003 worker outputs added config and startup evidence fields that must compile under focused runtime validation before leader push.
Rejected: pushing auto-checkpoints without leader validation | integrated tests initially failed to compile due missing imports and stale StartupEvidenceBundle fixtures.
Confidence: high
Scope-risk: narrow
Directive: When extending StartupEvidenceBundle, update all in-crate fixtures in the same change.
Tested: git diff --check; cargo fmt --manifest-path rust/Cargo.toml --all -- --check; cargo test --manifest-path rust/Cargo.toml -p runtime trusted_roots -- --nocapture; cargo test --manifest-path rust/Cargo.toml -p runtime startup -- --nocapture; cargo test --manifest-path rust/Cargo.toml -p runtime worker_boot -- --nocapture; cargo test --manifest-path rust/Cargo.toml -p tools path_scope -- --nocapture; cargo check --manifest-path rust/Cargo.toml --workspace
Not-tested: full cargo test --workspace remains deferred during active G003 team work.

Co-authored-by: OmX <omx@oh-my-codex.dev>
2026-05-14 17:45:46 +09:00
bellman
a6ee51baab omx(team): auto-checkpoint worker-3 [unknown] 2026-05-14 17:40:32 +09:00
bellman
6df60a4683 omx(team): auto-checkpoint worker-2 [unknown] 2026-05-14 17:40:29 +09:00
bellman
713ca7aee4 omx(team): auto-checkpoint worker-1 [1] 2026-05-14 17:27:18 +09:00
bellman
f789525839 omx(team): auto-checkpoint worker-1 [1] 2026-05-14 17:22:06 +09:00
bellman
9ab569e626 omx(team): auto-checkpoint worker-2 [3] 2026-05-14 17:18:55 +09:00
YeonGyu-Kim
75c08bc982 fix: REPL display, /compact panic, identity leak, DeepSeek reasoning, thinking blocks
Five interrelated fixes from parallel Hephaestus sessions:

1. fix(repl): display assistant text after spinner (#2981, #2982, #2937)
   - Added final_assistant_text() call after run_turn spinner completes
   - REPL now shows response text like run_prompt_json does

2. fix(compact): handle Thinking content blocks (#2985)
   - Added ContentBlock::Thinking variant throughout compact summarizer
   - Prevents panic when /compact encounters thinking blocks

3. fix(prompt): provider-aware model identity (#2822)
   - New ModelFamilyIdentity enum (Claude vs Generic)
   - Non-Anthropic models no longer say 'I am Claude'
   - model_family_identity_for() detects provider and sets identity

4. fix(openai): preserve DeepSeek reasoning_content (#2821)
   - Stream parser now captures reasoning_content from OpenAI-compat
   - Emits ThinkingDelta/SignatureDelta events for reasoning models
   - Thinking blocks included in conversation history for re-send

5. feat(runtime): Thinking block support across codebase
   - AssistantEvent::Thinking variant in conversation.rs
   - ContentBlock::Thinking in session serialization
   - Thinking-aware compact summarization
   - Tests for thinking block ordering and content

Closes #2981, #2982, #2937, #2985, #2822, #2821
2026-05-06 15:32:34 +09:00
Andreas Haida
482681cdfe Prune heavy directories during glob searches 2026-05-03 22:13:58 +02:00
Yeachan-Heo
6db68a2baa Expose tool permission gates as structured worker blockers
Worker boot could previously stall on an interactive MCP/tool permission prompt while readiness and startup-timeout surfaces only had generic idle/no-evidence shapes. This adds a first-class blocked lifecycle state, structured event payload, startup evidence fields, and regression coverage so callers can report the exact server/tool gate instead of pane-scraping.

Constraint: ROADMAP #200 requires tool/server identity, prompt age, and session-only versus always-allow capability in status/evidence surfaces
Rejected: Treat MCP/tool prompts as trust gates | conflates distinct prompts and loses tool identity
Rejected: Leave allow-scope as pane text only | clawhip still could not classify the blocker without scraping
Confidence: high
Scope-risk: moderate
Directive: Keep tool_permission_required distinct from trust_required; downstream claws rely on server/tool payload plus allow-scope metadata
Tested: cargo test -p runtime tool_permission
Tested: cargo fmt -p runtime -- --check && cargo clippy -p runtime --all-targets -- -D warnings && cargo test -p runtime
Tested: cargo test --workspace
Not-tested: live interactive MCP permission prompt in tmux
2026-04-27 09:28:09 +00:00
Yeachan-Heo
5b910356a2 Preserve trust boundaries during pulled follow-up
The pull brought the branch current with origin/main while replaying local follow-up work. Conflict resolution kept the roadmap/progress additions and integrated the runtime event/trust changes with upstream's newer surfaces.

The trust allowlist now treats worktree_pattern as an additional required predicate, including the missing-worktree case, so auto-trust cannot fall back to cwd-only matching when a worktree constraint was declared. The runtime formatting cleanup keeps clippy/fmt green after the merge.

Constraint: Local branch was 109 commits behind origin/main with dirty tracked follow-up work.

Rejected: Drop the autostash after conflict resolution | keeping it preserves a reversible safety backup for unrelated recovery.

Confidence: high

Scope-risk: moderate

Directive: Do not relax worktree_pattern matching without preserving the missing-worktree regression.

Tested: git diff --cached --check; cargo fmt -p runtime -- --check; cargo clippy -p runtime --all-targets -- -D warnings; cargo test -p runtime; cargo test --workspace; architect verification approved

Not-tested: Live tmux/worker auto-trust behavior outside unit/integration tests
2026-04-27 09:05:50 +00:00
YeonGyu-Kim
ff45e971aa fix: #80 — session-lookup error messages now show actual workspace-fingerprint directory
## Problem

Two session error messages advertised `.claw/sessions/` as the managed-session
location, but the actual on-disk layout is `.claw/sessions/<workspace_fingerprint>/`
where the fingerprint is a 16-char FNV-1a hash of the CWD path.

Users see error messages like:
```
no managed sessions found in .claw/sessions/
```

But the real directory is:
```
.claw/sessions/8497f4bcf995fc19/
```

The error copy was a direct lie — it made workspace-fingerprint partitioning
invisible and left users confused about whether sessions were lost or just in
a different partition.

## Fix

Updated two error formatters to accept the resolved `sessions_root` path
and extract the actual workspace-fingerprint directory:

1. **format_missing_session_reference**: now shows the actual fingerprint dir
   and explains that it's a workspace-specific partition

2. **format_no_managed_sessions**: now shows the actual fingerprint dir and
   includes a note that sessions from other CWDs are intentionally invisible

Updated all three call sites to pass `&self.sessions_root` to the formatters.

## Examples

**Before:**
```
no managed sessions found in .claw/sessions/
```

**After:**
```
no managed sessions found in .claw/sessions/8497f4bcf995fc19/
Start `claw` to create a session, then rerun with `--resume latest`.
Note: claw partitions sessions per workspace fingerprint; sessions from other CWDs are invisible.
```

```
session not found: nonexistent-id
Hint: managed sessions live in .claw/sessions/8497f4bcf995fc19/ (workspace-specific partition).
Try `latest` for the most recent session or `/session list` in the REPL.
```

## Impact

- Users can now tell from the error message that they're looking in the right
  directory (the one their current CWD maps to)
- The workspace-fingerprint partitioning stops being invisible
- Operators understand why sessions from adjacent CWDs don't appear
- Error copy matches the actual on-disk structure

## Tests

All 466 runtime tests pass. Verified on two real workspaces with actual
workspace-fingerprint directories.

Closes ROADMAP #80.
2026-04-21 22:18:12 +09:00
YeonGyu-Kim
7bc66e86e8 feat: #151 — canonicalize workspace path in SessionStore::from_cwd/data_dir
## Problem

`workspace_fingerprint(path)` hashes the raw path string without
canonicalization. Two equivalent paths (e.g. `/tmp/foo` vs
`/private/tmp/foo` on macOS) produce different fingerprints and
therefore different session stores. #150 fixed the test-side symptom;
this fixes the underlying product contract.

## Discovery path

#150 fix (canonicalize in test) was a workaround. Q's ack on #150
surfaced the deeper gap: the function itself is still fragile for
any caller passing a non-canonical path:

1. Embedded callers with a raw `--data-dir` path
2. Programmatic `SessionStore::from_cwd(user_path)` calls
3. NixOS store paths, Docker bind mounts, case-insensitive normalization

The REPL's default flow happens to work because `env::current_dir()`
returns canonical paths on macOS. But any caller passing a raw path
risks silent session-store divergence.

## Fix

Canonicalize inside `SessionStore::from_cwd()` and `from_data_dir()`
before computing the fingerprint. Kept `workspace_fingerprint()` itself
as a pure function for determinism — canonicalization is the entry
point's responsibility.

```rust
let canonical_cwd = fs::canonicalize(cwd).unwrap_or_else(|_| cwd.to_path_buf());
let sessions_root = canonical_cwd.join(".claw").join("sessions").join(workspace_fingerprint(&canonical_cwd));
```

Falls back to the raw path if canonicalize fails (directory doesn't
exist yet).

## Test-side updates

Three legacy-session tests expected the non-canonical base path to
match the store's workspace_root. Updated them to canonicalize
`base` after creation — same defensive pattern as #150, now
explicit across all three tests.

## Regression test

Added `session_store_from_cwd_canonicalizes_equivalent_paths` that
creates two stores from equivalent paths (raw vs canonical) and
asserts they resolve to the same sessions_dir.

## Verification

- `cargo test -p runtime session_store_` — 9/9 pass
- `cargo test --workspace` — all green, no FAILED markers
- No behavior change for existing users (REPL default flow already
  used canonical paths)

## Backward compatibility

Users on macOS who always went through `env::current_dir()`:
no hash change, sessions resume identically.

Users who ever called with a non-canonical path: hash would change,
but those sessions were already broken (couldn't be resumed from a
canonical-path cwd). Net improvement.

Closes ROADMAP #151.
2026-04-21 21:06:09 +09:00
YeonGyu-Kim
bc259ec6f9 fix: #149 — eliminate parallel-test flake in runtime::config tests
## Problem

`runtime::config::tests::validates_unknown_top_level_keys_with_line_and_field_name`
intermittently fails during `cargo test --workspace` (witnessed during
#147 and #148 workspace runs) but passes deterministically in isolation.

Example failure from workspace run:
  test result: FAILED. 464 passed; 1 failed

## Root cause

`runtime/src/config.rs::tests::temp_dir()` used nanosecond timestamp
alone for namespace isolation:

  std::env::temp_dir().join(format!("runtime-config-{nanos}"))

Under parallel test execution on fast machines with coarse clock
resolution, two tests start within the same nanosecond bucket and
collide on the same path. One test's `fs::remove_dir_all(root)` then
races another's in-flight `fs::create_dir_all()`.

Other crates already solved this pattern:
- plugins::tests::temp_dir(label) — label-parameterized
- runtime::git_context::tests::temp_dir(label) — label-parameterized

runtime/src/config.rs was missed.

## Fix

Added process id + monotonically-incrementing atomic counter to the
namespace, making every callsite provably unique regardless of clock
resolution or scheduling:

  static COUNTER: AtomicU64 = AtomicU64::new(0);
  let pid = std::process::id();
  let seq = COUNTER.fetch_add(1, Ordering::Relaxed);
  std::env::temp_dir().join(format!("runtime-config-{pid}-{nanos}-{seq}"))

Chose counter+pid over the label-parameterized pattern to avoid
touching all 20 callsites in the same commit (mechanical noise with
no added safety — counter alone is sufficient).

## Verification

Before: one failure per workspace run (config test flake).
After: 5 consecutive `cargo test --workspace` runs — zero config
test failures. Only pre-existing `resume_latest` flake remains
(orthogonal, unrelated to this change).

  for i in 1 2 3 4 5; do cargo test --workspace; done
  # All 5 runs: config tests green. Only resume_latest flake appears.

  cargo test -p runtime
  # 465 passed; 0 failed

## ROADMAP.md

Added Pinpoint #149 documenting the gap, root cause, and fix.

Closes ROADMAP #149.
2026-04-21 20:54:12 +09:00
YeonGyu-Kim
12f1f9a74e feat: wire ship.prepared provenance emission at bash execution boundary
Adds ship provenance detection and emission in execute_bash_async():
- Detects git push to main/master commands
- Captures current branch, HEAD commit, git user as actor
- Emits ship.prepared event with ShipProvenance payload
- Logs to stderr as interim routing (event stream integration pending)

This is the first wired provenance event — schema (§4.44.5) now has
runtime emission at actual git operation boundary.

Verified: cargo build --workspace passes.
Next: wire ship.commits_selected, ship.merged, ship.pushed_main events.

Refs: §4.44.5.1, ROADMAP #4.44.5
2026-04-20 17:03:28 +09:00
YeonGyu-Kim
8a8ca8a355 ROADMAP #4.44.5: Ship/provenance events — implement §4.44.5
Adds structured ship provenance surface to eliminate delivery-path opacity:

New lane events:
- ship.prepared — intent to ship established
- ship.commits_selected — commit range locked
- ship.merged — merge completed with provenance
- ship.pushed_main — delivery to main confirmed

ShipProvenance struct carries:
- source_branch, base_commit
- commit_count, commit_range
- merge_method (direct_push/fast_forward/merge_commit/squash_merge/rebase_merge)
- actor, pr_number

Constructor methods added to LaneEvent for all four ship events.

Tests:
- Wire value serialization for ship events
- Round-trip deserialization
- Canonical event name coverage

Runtime: 465 tests pass
ROADMAP updated with IMPLEMENTED status

This closes the gap where 56 commits pushed to main had no structured
provenance trail — now emits first-class events for clawhip consumption.
2026-04-20 15:06:50 +09:00
YeonGyu-Kim
b0b579ebe9 ROADMAP #133: Blocked-state subphase contract — implement §6.5
Adds BlockedSubphase enum with 7 variants for structured blocked-state reporting:
- blocked.trust_prompt — trust gate blockers
- blocked.prompt_delivery — prompt misdelivery
- blocked.plugin_init — plugin startup failures
- blocked.mcp_handshake — MCP connection issues
- blocked.branch_freshness — stale branch blockers
- blocked.test_hang — test timeout/hang
- blocked.report_pending — report generation stuck

LaneEventBlocker now carries optional subphase field that gets serialized
into LaneEvent data. Enables clawhip to route recovery without pane scraping.

Updates:
- lane_events.rs: BlockedSubphase enum, LaneEventBlocker.subphase field
- lane_events.rs: blocked()/failed() constructors with subphase serialization
- lib.rs: Export BlockedSubphase
- tools/src/lib.rs: classify_lane_blocker() with subphase: None
- Test imports and fixtures updated

Backward-compatible: subphase is Option<>, existing events continue to work.
2026-04-20 15:04:08 +09:00
Yeachan-Heo
866ae7562c Fix formatting in task_packet.rs for CI 2026-04-16 09:35:18 +00:00
Yeachan-Heo
1d5748f71f US-005: Typed task packet format with TaskScope enum
- Add TaskScope enum with Workspace, Module, SingleFile, Custom variants
- Update TaskPacket struct with scope_path and worktree fields
- Add validation for scope-specific requirements
- Fix tests in task_packet.rs, task_registry.rs, and tools/src/lib.rs
- Export TaskScope from runtime crate

Closes US-005 (Phase 4)
2026-04-16 09:28:42 +00:00
Yeachan-Heo
77fb62a9f1 Implement LaneEvent schema extensions for event ordering, provenance, and dedupe (US-002)
Adds comprehensive metadata support to LaneEvent for the canonical lane event schema:

- EventProvenance enum: live_lane, test, healthcheck, replay, transport
- SessionIdentity: title, workspace, purpose, with placeholder support
- LaneOwnership: owner, workflow_scope, watcher_action (Act/Observe/Ignore)
- LaneEventMetadata: seq, provenance, session_identity, ownership, nudge_id,
  event_fingerprint, timestamp_ms
- LaneEventBuilder: fluent API for constructing events with full metadata
- is_terminal_event(): detects Finished, Failed, Superseded, Closed, Merged
- compute_event_fingerprint(): deterministic fingerprint for terminal events
- dedupe_terminal_events(): suppresses duplicate terminal events by fingerprint

Provides machine-readable event provenance, session identity at creation,
monotonic sequence ordering, nudge deduplication, and terminal event suppression.

Adds 10 regression tests covering:
- Monotonic sequence ordering
- Provenance serialization round-trip
- Session identity completeness
- Ownership and workflow scope binding
- Watcher action variants
- Terminal event detection
- Fingerprint determinism and uniqueness
- Terminal event deduplication
- Builder construction with metadata
- Metadata serialization round-trip

Closes Phase 2 (partial) from ROADMAP.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-16 09:12:31 +00:00
Yeachan-Heo
21909da0b5 Implement startup-no-evidence evidence bundle + classifier (US-001)
Adds typed worker.startup_no_evidence event with evidence bundle when worker
startup times out. The classifier attempts to down-rank the vague bucket into
specific failure classifications:
- trust_required
- prompt_misdelivery
- prompt_acceptance_timeout
- transport_dead
- worker_crashed
- unknown

Evidence bundle includes:
- Last known worker lifecycle state
- Pane/command being executed
- Prompt-send timestamp
- Prompt-acceptance state
- Trust-prompt detection result
- Transport health summary
- MCP health summary
- Elapsed seconds since worker creation

Includes 6 regression tests covering:
- Evidence bundle serialization
- Transport dead classification
- Trust required classification
- Prompt acceptance timeout
- Worker crashed detection
- Unknown fallback

Closes Phase 1.6 from ROADMAP.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-16 09:05:33 +00:00
Yeachan-Heo
e874bc6a44 Improve malformed hook failures so operators can diagnose broken JSON
Malformed hook stdout that looks like JSON was collapsing into low-signal failure text during hook execution. This change preserves plain-text hook feedback for normal text hooks, but upgrades malformed JSON-like output into an explicit hook_invalid_json diagnostic that includes phase, tool, command, and bounded stdout/stderr previews. It also adds a regression test for malformed-but-nonempty output.

Constraint: User scoped the implementation to rust/crates/runtime/src/hooks.rs and tests only
Constraint: Existing plain-text hook feedback must remain intact for non-JSON hook output
Rejected: Treat every non-JSON stdout payload as invalid JSON | would break legitimate plain-text hook feedback
Confidence: high
Scope-risk: narrow
Directive: Keep malformed-hook diagnostics bounded and preserve the plain-text fallback for hooks that intentionally emit text
Tested: cargo test --manifest-path rust/Cargo.toml -p runtime hooks::tests:: -- --nocapture
Tested: cargo test --manifest-path rust/Cargo.toml -p runtime -- --nocapture
Tested: cargo clippy --manifest-path rust/Cargo.toml -p runtime --all-targets -- -D warnings
Not-tested: Full workspace clippy/test sweep outside runtime crate
2026-04-13 12:44:52 +00:00
Yeachan-Heo
2e34949507 Keep latest-session timestamps increasing under tight loops
The next repo-local sweep target was ROADMAP #73: repeated backlog
sweeps exposed that session writes could share the same wall-clock
millisecond, which made semantic recency fragile and forced the
resume-latest regression to sleep between saves. The fix makes session
timestamps monotonic within the process and removes the timing hack
from the test so latest-session selection stays stable under tight
loops.

Constraint: Preserve the existing session file format while changing only the timestamp source semantics
Rejected: Keep the sleep-based test workaround | hides the real ordering hazard instead of fixing timestamp generation
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Any future session-recency logic must keep `current_time_millis`, ordering tests, and latest-session expectations aligned
Tested: cargo fmt --all --check; cargo clippy --workspace --all-targets -- -D warnings; cargo test --workspace; architect review APPROVE
Not-tested: Cross-process monotonicity when multiple binaries write sessions concurrently
2026-04-12 10:51:19 +00:00
Yeachan-Heo
dbc2824a3e Keep latest session selection tied to real session recency
The next repo-local sweep target was ROADMAP #72: the `latest`
managed-session alias could depend on filesystem mtime before the
session's own persisted recency markers, which made the selection
path vulnerable to coarse or misleading file timestamps. The fix
promotes `updated_at_ms` into the summary/order path, keeps CLI
wrappers in sync, and locks the mtime-vs-session-recency case with
regression coverage.

Constraint: Preserve existing managed-session storage layout while changing only the ordering signal
Rejected: Keep sorting by filesystem mtime and just sleep longer in tests | hides the semantic ordering bug instead of fixing it
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Any future managed-session ordering change must keep runtime and CLI summary structs aligned on the same recency fields
Tested: cargo fmt --all --check; cargo clippy --workspace --all-targets -- -D warnings; cargo test --workspace; architect review APPROVE
Not-tested: Cross-filesystem behavior where persisted session JSON cannot be read and fallback ordering uses mtime only
2026-04-12 07:49:32 +00:00
Yeachan-Heo
f309ff8642 Stop repo lanes from executing the wrong task payload
The next repo-local sweep target was ROADMAP #71: a claw-code lane
accepted an unrelated KakaoTalk/image-analysis prompt even though the
lane itself was supposed to be repo-scoped work. This extends the
existing prompt-misdelivery guardrail with an optional structured task
receipt so worker boot can reject visible wrong-task context before the
lane continues executing.

Constraint: Keep the fix inside the existing worker_boot / WorkerSendPrompt control surface instead of inventing a new external OMX-only protocol
Rejected: Treat wrong-task receipts as generic shell misdelivery | loses the expected-vs-observed task context needed to debug contaminated lanes
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: If task-receipt fields change later, update the WorkerSendPrompt schema, worker payload serialization, and wrong-task regression together
Tested: cargo fmt --all --check; cargo clippy --workspace --all-targets -- -D warnings; cargo test --workspace; architect review APPROVE
Not-tested: External orchestrators that have not yet started populating the optional task_receipt field
2026-04-12 07:00:07 +00:00
Yeachan-Heo
257aeb82dd Retire the stale dead-session opacity backlog item with regression proof
ROADMAP #38 no longer reflects current main. The runtime already runs a
post-compaction session-health probe, but the backlog lacked explicit
regression proof. This change adds focused tests for the two important
behaviors: a broken tool surface aborts a compacted session with a targeted
error, while a freshly compacted empty session does not false-positive as
dead. With that proof in place, the roadmap item can be marked done.

Constraint: User required fresh cargo fmt/clippy/test evidence before closing any backlog item
Rejected: Leave #38 open because the implementation already existed | backlog stays stale and invites duplicate work
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Reopen #38 only with a fresh same-turn repro that bypasses the current health-probe gate
Tested: cargo fmt --all --check; cargo clippy --workspace --all-targets -- -D warnings; cargo test --workspace
Not-tested: No live long-running dogfood session replay beyond existing automated coverage
2026-04-11 18:47:37 +00:00
YeonGyu-Kim
16b9febdae feat: ultraclaw droid batch — ROADMAP #41 test isolation + #50 PowerShell permissions
Merged late-arriving droid output from 10 parallel ultraclaw sessions.

ROADMAP #41 — Test isolation for plugin regression checks:
- Add test_isolation.rs module with env_lock() for test environment isolation
- Redirect HOME/XDG_CONFIG_HOME/XDG_DATA_HOME to unique temp dirs per test
- Prevent host ~/.claude/plugins/ from bleeding into test runs
- Auto-cleanup temp directories on drop via RAII pattern
- Tests: 39 plugin tests passing

ROADMAP #50 — PowerShell workspace-aware permissions:
- Add is_safe_powershell_command() for command-level permission analysis
- Add is_path_within_workspace() for workspace boundary validation
- Classify read-only vs write-requiring bash commands (60+ commands)
- Dynamic permission requirements based on command type and target path
- Tests: permission enforcer and workspace boundary tests passing

Additional improvements:
- runtime/src/permission_enforcer.rs: Dynamic permission enforcement layer
  - check_with_required_mode() for dynamically-determined permissions
  - 60+ read-only command patterns (cat, find, grep, cargo, git, jq, yq, etc.)
  - Workspace-path detection for safe commands
- compat-harness/src/lib.rs: Compat harness updates for permission testing
- rusty-claude-cli/src/main.rs: CLI integration for permission modes
- plugins/src/lib.rs: Updated imports for test isolation module

Total: +410 lines across 5 files
Workspace tests: 448+ passed
Droid source: ultraclaw-04-test-isolation, ultraclaw-08-powershell-permissions

Ultraclaw total: 4 ROADMAP items committed (38, 40, 41, 50)
2026-04-12 03:06:24 +09:00
Yeachan-Heo
124e8661ed Remove the deprecated Claude subscription login path and restore a green Rust workspace
ROADMAP #37 was still open even though several earlier backlog items were
already closed. This change removes the local login/logout surface, stops
startup auth resolution from treating saved OAuth credentials as a supported
path, and updates diagnostics/help to point users at ANTHROPIC_API_KEY or
ANTHROPIC_AUTH_TOKEN only.

While proving the change with the user-requested workspace gates, clippy
surfaced additional pre-existing warning failures across the Rust workspace.
Those were cleaned up in-place so the required `cargo fmt`, `cargo clippy
--workspace --all-targets -- -D warnings`, and `cargo test --workspace`
sequence now passes end to end.

Constraint: User explicitly required full-workspace fmt/clippy/test before commit/push
Constraint: Existing dirty leader worktree had to be stashed before attempted OMX team worktree launch
Rejected: Keep login/logout but hide them from help | left unsupported auth flow and saved OAuth fallback intact
Rejected: Stop after ROADMAP #37 targeted tests | did not satisfy required full-workspace verification gate
Confidence: medium
Scope-risk: moderate
Reversibility: clean
Directive: Do not reintroduce saved OAuth as a silent Anthropic startup fallback without an explicit supported auth policy
Tested: cargo fmt --all --check; cargo clippy --workspace --all-targets -- -D warnings; cargo test --workspace
Not-tested: Remote push effects beyond origin/main update
2026-04-11 17:24:44 +00:00
Yeachan-Heo
61c01ff7da Prevent cross-worktree session bleed during managed session resume/load
ROADMAP #41 was still leaving a phantom-completion class open: managed
sessions could be resumed from the wrong workspace, and the CLI/runtime
paths were split between partially isolated storage and older helper
flows. This squashes the verified team work into one deliverable that
routes managed session operations through the per-worktree SessionStore,
rejects workspace mismatches explicitly, extends lane-event taxonomy for
workspace mismatch reporting, and updates the affected CLI regression
fixtures/docs so the new contract is enforced without losing same-
workspace legacy coverage.

Constraint: Keep same-workspace legacy flat sessions readable while blocking cross-worktree misuse
Constraint: No new dependencies; stay within the ROADMAP #41 changed-file scope
Rejected: Leave team auto-checkpoint history as final branch state | noisy/non-lore history for a single roadmap fix
Confidence: high
Scope-risk: moderate
Reversibility: clean
Directive: Preserve workspace_root validation on future resume/load helpers; do not reintroduce path-only fallback without equivalent mismatch checks
Tested: cargo test -p runtime session_control -- --nocapture; cargo test -p rusty-claude-cli resume -- --nocapture; cargo test -p rusty-claude-cli --test cli_flags_and_config_defaults; cargo test -p rusty-claude-cli --test output_format_contract; cargo test -p rusty-claude-cli --test resume_slash_commands; cargo test --workspace --exclude compat-harness; cargo check --workspace --all-targets; git diff --check
Not-tested: cargo clippy --workspace --all-targets -- -D warnings (pre-existing failures in unchanged rust/crates/rusty-claude-cli/build.rs)
Related: ROADMAP #41
2026-04-11 16:08:28 +00:00