Skip to content

Make adaptive refresh agent-aware with explicit local activity consent#2111

Merged
steipete merged 5 commits into
steipete:mainfrom
hhh2210:codex/agent-aware-adaptive-refresh
Jul 17, 2026
Merged

Make adaptive refresh agent-aware with explicit local activity consent#2111
steipete merged 5 commits into
steipete:mainfrom
hhh2210:codex/agent-aware-adaptive-refresh

Conversation

@hhh2210

@hhh2210 hhh2210 commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Problem

#2029 found that the replay-only activity candidate did not improve global p95 menu staleness, so that result did not support a broad production claim. Main now has the local Agent Sessions scanner from #1968, which provides an attributable Codex/Claude activity signal without adding another detector.

This PR has a narrower target: while local coding is active, an unconstrained Adaptive decision should not wait longer than the old 5-minute default. Global p95 remains unchanged.

Consent and upgrade boundary

Adaptive cadence is not permission to inspect local process or session metadata.

  • CodexBar persists a separate undecided, allowed, or declined choice. Only allowed enables Adaptive-only scanning.
  • Fresh installs default to Adaptive, then show a one-time local-activity prompt before the first scan. Declining leaves Adaptive selected and uses menu activity only.
  • Existing Adaptive users also start as undecided after upgrade and perform no Adaptive-only scan until they allow it.
  • The prompt discloses the actual scanner scope: the running-process list, including command lines, plus known Codex/Claude session metadata every 30 seconds. It also states that Adaptive-only mode keeps one latest-activity timestamp in memory, discards paths and identities, sends no activity data, and does not enable remote discovery or SSH.
  • The choice is editable in General settings. Turning it off stops monitoring and clears the in-memory activity timestamp.
  • Agent Sessions remains a separate explicit setting. When enabled, its existing local scan path continues to work independently; remote discovery and SSH still require that setting.
  • Existing installs with no stored cadence retain the 5-minute fallback. Invalid cadence values recover to 5 minutes, and every valid Manual, fixed, or Adaptive choice remains unchanged.

The historical edge case is unchanged: a completely untouched, configless v0.1-v0.3 install left no durable state that can distinguish it from a new install, so that cohort follows the fresh-install default.

Consent UI

Adaptive refresh local activity consent

Use Menu Activity Only also responds to Escape. The same six consent/settings strings are present in all supported app language catalogs.

Packaged runtime proof

Redacted exact-head proof report

The proof bundle came from clean commit 2c0a41479602a8aa804139cbf50bef358e32d3da. Its embedded CodexGitCommit is 2c0a4147; the debug executable SHA-256 is eb3361e2a96e9cae269ce4490e96ed555da09ce9f802268e33af24dfc4712499.

The bundle ran with network access denied, Keychain access disabled, and synthetic HOME / CODEX_HOME data containing one recent fixture rollout. It did not read a real Codex or Claude transcript.

Scenario Initial state Packaged result
Fresh install no config, marker, cadence, or consent persisted adaptive + undecided; showed the prompt; 0 local session scans before a decision
Existing Adaptive config + marker + stored adaptive, consent missing repaired consent to undecided; showed the prompt; 0 local session scans
Legacy unset config + marker, cadence and consent missing persisted fiveMinutes; no prompt; 0 local session scans
Allowed branch same bundle, persisted allowed replayed 3 scanner starts across 65.6 seconds; timer moved from longIdle 1800s to codingActivity 300s; 0 Tailscale/SSH events
Declined branch existing Adaptive config, persisted declined replayed no repeated prompt and 0 scans after crossing a full 30-second interval

The persisted allowed and declined states were replayed on relaunch to isolate the two runtime branches. Focused tests cover setter persistence, reload, invalid-value repair, existing-Adaptive behavior, and the Agent Sessions bypass.

Sustained scan profile

The allowed process produced scanner starts at t+0.000s, t+31.350s, and t+63.336s. The first scan pulled the pending Adaptive timer from 30 minutes to 5 minutes eight milliseconds later. No remote discovery, remote fetch, or SSH subprocess label appeared.

A 65.646-second Time Profiler recording covered the next two scans:

  • 170 running samples at 1.00 ms weight, about 170 ms of sampled CPU time for the whole app, or 0.26% of one core over the window;
  • scanner frames in AgentSessionsStore.refreshLocal, LocalAgentSessionScanner.scan, LocalAgentSessionScanner.processOutput, and SubprocessRunner.run;
  • 0 potential hangs at the template's 250 ms threshold.

The raw trace SHA-256 is be7943ea0588bdb6f60d60d3ddaa3ef65453f65dea5cc505f14cd1badae786a2. The trace stays local because Instruments embeds local paths and environment values. These are sampled runtime figures, not an energy claim.

Policy replay

Agent-aware Adaptive replay

Frozen trace: 1,780 JSONL records, SHA-256 b1e4aa33180b7c177293eb9ed16b45e24e026d259600fba2b1b67b931b904f0b.

Policy Simulated refreshes Per observed 24h Active coding over 5m Menu p50 / p95 Constraints
Agent-aware Adaptive 696 143.88 0 / 145 139s / 1093s pass
Menu-only Adaptive 694 143.47 4 / 145 142s / 1093s pass
Fixed 5m 1383 285.90 0 / 99 150s / 281s 157 violations

Compared with menu-only Adaptive, the activity signal adds 2 simulated refreshes (+0.29%) and removes all 4 observed active-coding delays above 5 minutes. Compared with fixed 5 minutes, it schedules 49.7% fewer simulated refreshes. These are policy-clock results, not observed provider requests.

The trace comes from one machine. Activity covers 462 of 733 decision records, and p95 remains 1093 seconds. It samples activity at reconstructed decision points rather than replaying the 30-second scanner callback; the packaged profile above covers that callback.

Validation

  • make check: pass; SwiftFormat clean and SwiftLint reported 0 violations
  • 67 focused tests passed across settings rollout/consent, Agent Sessions projection, Adaptive timer behavior, and localization
  • The settings suite covers fresh persistence, both prior-launch markers, existing config, String and non-String invalid values, all 7 valid cadence values, consent persistence, and existing-Adaptive opt-in

The released adaptive-activity replay CLI spelling remains a deprecated alias for adaptive, while adaptive-menu-only names the historical baseline.

Copilot AI review requested due to automatic review settings July 13, 2026 02:39

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR makes Adaptive refresh agent-aware by default by feeding recent local Codex/Claude activity into the adaptive cadence decision, while keeping the Agent Sessions UI (and all remote discovery/SSH behavior) explicitly opt-in.

Changes:

  • Extend the shared AdaptiveRefreshPolicyCore decision table with an optional lastCodingActivityAt signal that caps otherwise-slower unconstrained delays at 5 minutes.
  • Make missing/unrecognized refreshFrequency resolve to .adaptive, and enable bounded local session monitoring when Adaptive is effective—without enabling the Agent Sessions UI.
  • Update replay tooling to treat activity-aware Adaptive as production (adaptive), preserve the historical baseline as adaptive-menu-only, and keep adaptive-activity as a CLI alias.

Reviewed changes

Copilot reviewed 30 out of 30 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
Tests/CodexBarTests/SettingsStoreTests.swift Update default/fallback expectations for refresh frequency; add explicit 5m preservation test.
Tests/CodexBarTests/CodexSessionRolloutTests.swift Add bounded-rollout parsing coverage for local scanner limits.
Tests/CodexBarTests/ClaudeSessionMappingTests.swift Add transcript list limiting coverage.
Tests/CodexBarTests/AgentSessionMenuDescriptorTests.swift Cover Adaptive-only monitoring enablement, projection, and constraint pausing.
Tests/CodexBarTests/AdaptiveRefreshTimerTests.swift Add timer pull-forward behavior tests for coding activity; ensure fixed-mode behavior stays in-memory only.
Tests/CodexBarTests/AdaptiveRefreshPolicyTests.swift Verify app adapter forwards coding activity into policy decisions.
Tests/AdaptiveReplayKitTests/MenuOnlyAdaptivePolicyTests.swift Reframe replay tests around production adaptive and the historical menu-only baseline.
Tests/AdaptiveReplayKitTests/AdaptiveRefreshPolicyCoreTests.swift Add core policy tests for coding-activity cap, boundaries, and constraints.
Tests/AdaptiveReplayCLITests/CLIArgumentsTests.swift Ensure adaptive-activity remains accepted and maps to production adaptive.
Sources/CodexBarCore/LocalAgentSessionScanner.swift Bound process/rollout/transcript candidate handling to configured limits.
Sources/CodexBarCore/AgentSession.swift Extend scan config with bounds; add transcript limiting support.
Sources/CodexBar/UsageStore+AdaptiveRefresh.swift Wire lastCodingActivityAt through adaptive decisions and timer advancement behavior.
Sources/CodexBar/UsageStore.swift Track lastCodingActivityAt in-memory; refactor timer restart helper.
Sources/CodexBar/StatusItemController+AgentSessions.swift Forward activity timestamp into adaptive refresh; centralize agent session settings sync.
Sources/CodexBar/StatusItemController.swift Track refresh-frequency changes alongside agent-session settings; use new wiring helpers.
Sources/CodexBar/SettingsStore.swift Change missing/unrecognized refresh-frequency fallback to .adaptive.
Sources/CodexBar/AgentSessionsStore.swift Enable local monitoring under Adaptive without enabling UI; project activity timestamp-only when UI is off.
Sources/CodexBar/AdaptiveRefreshPolicy.swift Thread coding activity input through the production policy adapter into the shared core.
Sources/AdaptiveReplayKit/README.md Update replay docs to reflect production activity-aware Adaptive and historical baseline.
Sources/AdaptiveReplayKit/HistoricalPolicies.swift Add historical menu-only Adaptive baseline policy (adaptive-menu-only).
Sources/AdaptiveReplayKit/CandidatePolicies.swift Remove replay-only activity candidate (now folded into production policy).
Sources/AdaptiveReplayKit/BaselinePolicies.swift Feed coding activity into production replay policy; add helper for omitting the signal.
Sources/AdaptiveReplayCLI/main.swift Update CLI help text and document alias behavior.
Sources/AdaptiveReplayCLI/CLIArguments.swift Replace candidate policy with historical baseline; implement adaptive-activity alias parsing.
Sources/AdaptiveRefreshCore/AdaptiveRefreshPolicyCore.swift Add coding-activity signal, reason, thresholds, and cap behavior to shared decision table.
README.md Update high-level feature description and privacy note for adaptive local scan behavior.
docs/refresh-loop.md Document new default fallback, activity signal, scanner bounds, and pause conditions.
docs/predictive-refresh-policy.md Update decision record to reflect agent-aware adaptive default extension and constraints.
CHANGELOG.md Document default/fallback change, activity cap behavior, and bounded/local-only scan implications.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 162 to +166
self.localRefreshInFlight = true
let sessions = await self.localScanner.scan()
self.localRefreshInFlight = false
guard !Task.isCancelled, self.settings.agentSessionsEnabled else { return }
self.localSessions = sessions
self.lastUpdatedAt = Date()
guard !Task.isCancelled, self.localMonitoringEnabled else { return }
self.applyLocalScanResult(sessions)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed in 04df269. LocalAgentSessionScanner.scan is now @concurrent, so the synchronous ps/lsof work and transcript parsing do not inherit a MainActor caller. I kept structured concurrency instead of using a detached task, which preserves cancellation, priority, and task-local values. The 37 repair-focused tests pass and make check is clean.

@clawsweeper clawsweeper Bot added proof: 📸 screenshot Contributor real behavior proof includes screenshot evidence. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P2 Normal priority bug or improvement with limited blast radius. merge-risk: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. merge-risk: 🚨 security-boundary 🚨 Merging this PR could weaken sandboxing, authorization, credentials, or sensitive data. labels Jul 13, 2026
@clawsweeper

clawsweeper Bot commented Jul 13, 2026

Copy link
Copy Markdown

Codex review: needs real behavior proof before merge. Reviewed July 17, 2026, 3:49 PM ET / 19:49 UTC.

Summary
The branch adds a separate consent-gated agent-aware Adaptive refresh mode that consumes local Codex/Claude activity to cap slower refresh decisions, plus settings, scanner bounds, localization, documentation, replay support, and focused tests.

Reproducibility: not applicable. This PR introduces a new refresh mode and consent flow rather than fixing a reproducible existing defect. The supplied earlier-head packaged run is useful behavioral evidence but does not reproduce a bug on current main.

Review metrics: 2 noteworthy metrics.

  • Patch surface: 63 files; 1,608 additions; 232 deletions. The branch spans runtime policy, persisted settings, local scanning, documentation, tests, and 21 localization catalogs, so a current-main merge refresh is material.
  • Proof revision gap: 1 packaged proof head behind current head. The available runtime report is pinned to 2c0a4147, while current code is 6865744a and changes the reviewed behavior boundary.

Merge readiness
Overall: 🦐 gold shrimp
Proof: 🦐 gold shrimp
Patch quality: 🐚 platinum hermit
Result: blocked until stronger real behavior proof is added.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • Record the owner decision for the fresh-install and markerless-legacy contract.
  • Rebase on current main, resolve the localization-tail conflicts, and rerun required checks.
  • Attach a redacted exact-head packaged runtime report; redact private paths, IP addresses, tokens, and non-public endpoints.

Proof guidance:

  • [P1] Needs stronger real behavior proof before merge: The PR contains unusually detailed redacted packaged-app proof, but it is pinned to earlier head 2c0a4147; current head 6865744a changes the opt-in boundary and blocker fixes, so submit a redacted exact-head packaged run before merge. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.

Risk before merge

  • [P1] Merging changes the fresh-install cadence from the prior five-minute default to plain Adaptive, while markerless v0.1–v0.3 installations remain indistinguishable from fresh installs; this upgrade contract needs an explicit owner decision.
  • [P1] The current head has no exact-head packaged runtime proof for the revised opt-in mode, post-modal notification authorization, scanner bounds, and future-mtime behavior.
  • [P1] The branch needs a current-main merge refresh because the maintainer found conflicts in 23 localization catalog tails; green results must be rerun for the resolved head.

Maintainer options:

  1. Confirm contract, then refresh the branch (recommended)
    Record approval of the fresh-install and markerless-legacy behavior, resolve the localization-tail merge conflicts, and rerun checks plus exact-head packaged proof before merge.
  2. Keep the prior default
    Restore five-minute fresh-install behavior while retaining an explicitly selected, consent-gated agent-aware option if avoiding the legacy ambiguity is more important than changing the default.
  3. Pause the policy rollout
    Do not merge the default or agent-aware cadence behavior until the owner wants to sponsor the production policy with broader evidence.

Next step before merge

  • [P1] An owner must confirm the user-facing default/legacy contract, and the remaining proof and rebase work cannot be safely delegated as an automated repair.

Maintainer decision needed

  • Question: Should CodexBar ship plain Adaptive as the fresh-install default while retaining the documented markerless v0.1–v0.3 ambiguity, with local activity scanning available only through the separate explicitly consented agent-aware mode?
  • Rationale: The latest owner-authored commit narrows the privacy boundary, but the owner’s July 17 review required an explicit decision on the production policy and the legacy-default tradeoff; automated review cannot choose that user-facing contract.
  • Likely owner: steipete — The owner wrote the blocking contract review and authored the latest commit implementing the narrowed direction.
  • Options:
    • Approve the documented contract (recommended): Keep plain Adaptive as the fresh-install default, preserve five minutes for identifiable legacy-unset installs, and accept the documented markerless legacy ambiguity after exact-head proof and merge refresh.
    • Preserve five minutes by default: Keep the separate opt-in agent-aware mode but restore five minutes as the fresh-install default to eliminate the ambiguous legacy behavior change.
    • Park the cadence change: Retain only independently useful scanner hardening or consent groundwork and defer both Adaptive default and agent-aware policy rollout.

Security
Cleared: The supplied latest diff adds no dependency, upload, analytics, URL, or remote-discovery path for adaptive-only activity; it gates the sensitive local scan behind separate persisted consent and keeps remote Agent Sessions behavior separate.

Review details

Best possible solution:

Record the owner’s acceptance or rejection of the fresh-install/legacy contract, rebase onto current main while resolving localization tails, then provide a redacted exact-head packaged-app run covering plain Adaptive, opt-in agent-aware consent, same-launch notification authorization, bounded scanning, and future timestamps.

Do we have a high-confidence way to reproduce the issue?

Not applicable: this PR introduces a new refresh mode and consent flow rather than fixing a reproducible existing defect. The supplied earlier-head packaged run is useful behavioral evidence but does not reproduce a bug on current main.

Is this the best way to solve the issue?

Unclear: separating agent-aware scanning from plain Adaptive is the narrowest privacy-preserving shape in the supplied diff, but only the owner can approve the fresh-install default and markerless-legacy upgrade contract.

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against cfb7b8036087.

Label changes

Label changes:

  • add status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs stronger real behavior proof before merge: The PR contains unusually detailed redacted packaged-app proof, but it is pinned to earlier head 2c0a4147; current head 6865744a changes the opt-in boundary and blocker fixes, so submit a redacted exact-head packaged run before merge. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
  • remove proof: sufficient: Current real behavior proof status is insufficient, not sufficient.
  • remove status: ⏳ waiting on author: Current PR status label is status: 📣 needs proof.

Label justifications:

  • P2: This is a substantial but bounded refresh-policy feature with unresolved owner contract and proof/merge-refresh work, not an active service outage.
  • merge-risk: 🚨 compatibility: Fresh installs move to plain Adaptive and markerless legacy installs cannot be distinguished from fresh installs during upgrade.
  • merge-risk: 🚨 security-boundary: The feature adds periodic inspection of local process command lines and session metadata, making consent and scope isolation merge-critical.
  • rating: 🦐 gold shrimp: Overall readiness is 🦐 gold shrimp; proof is 🦐 gold shrimp and patch quality is 🐚 platinum hermit.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs stronger real behavior proof before merge: The PR contains unusually detailed redacted packaged-app proof, but it is pinned to earlier head 2c0a4147; current head 6865744a changes the opt-in boundary and blocker fixes, so submit a redacted exact-head packaged run before merge. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
Evidence reviewed

What I checked:

  • Latest head addresses prior review blockers: The latest branch commit 6865744a is authored by steipete and its supplied diff adds a separate adaptiveAgentAware frequency, consent gating, scanner directory/process bounds, future-mtime clamping, and notification authorization after the consent modal; CHANGELOG.md is not among the 63 changed paths. (Sources/CodexBar/SettingsStore.swift:10, 6865744ab217)
  • Maintainer review establishes the remaining contract: The owner’s July 17, 2026 review explicitly required a decision on production agent-aware policy and the fresh-install Adaptive default, and identified scan bounds, same-launch notifications, future mtimes, and release-owned changelog handling as blockers. The supplied latest diff materially addresses the mechanical blockers but does not provide a later explicit contract comment. (2c0a41479602)
  • Exact-head behavior proof is stale: The linked packaged-app proof identifies clean commit 2c0a41479602a8aa804139cbf50bef358e32d3da, while the current PR head is 6865744ab2179eb735ad0db5146bde56da5b3667; the later head changes the mode/default boundary and implements the blocker fixes, so the older proof cannot fully prove this exact revision. (6865744ab217)
  • Current branch needs merge refresh: The maintainer review reports the branch is dirty against main and that a merge-tree rehearsal conflicts in 23 localization catalog tails; the supplied check state is also still queued or in progress for the current revision. (Sources/CodexBar/Resources/en.lproj/Localizable.strings:736, 6865744ab217)
  • Related merged feature history: The local Agent Sessions substrate was merged through the owner-authored implementation at 8106e7d3, and the shared adaptive replay core was merged through fe753940; this branch builds on both rather than duplicating either feature. (Sources/CodexBar/AgentSessionsStore.swift:44, 8106e7d3cc31)

Likely related people:

  • steipete: Authored the merged Agent Sessions implementation, posted the detailed owner review, and authored the current PR-head commit that narrows the feature to opt-in agent-aware refresh. (role: feature owner and recent area contributor; confidence: high; commits: 8106e7d3cc31, 6865744ab217; files: Sources/CodexBar/AgentSessionsStore.swift, Sources/CodexBar/SettingsStore.swift, Sources/CodexBarCore/LocalAgentSessionScanner.swift)
  • hhh2210: Authored the merged replay tooling that established the shared adaptive policy surface and supplied the initial consent-gated implementation and detailed packaged proof for this branch. (role: prior adaptive replay contributor; confidence: medium; commits: fe75394076f3, 2c0a41479602; files: Sources/AdaptiveRefreshCore/AdaptiveRefreshPolicyCore.swift, Sources/AdaptiveReplayKit/AgentAwarePolicies.swift)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.
Review history (6 earlier review cycles)
  • reviewed 2026-07-13T03:01:14.993Z sha e393deb :: needs real behavior proof before merge. :: [P1] Preserve unset users or add a fresh-install migration
  • reviewed 2026-07-13T04:18:55.172Z sha 04df269 :: needs real behavior proof before merge. :: [P1] Preserve the scan boundary for existing Adaptive users
  • reviewed 2026-07-13T04:25:16.211Z sha 04df269 :: needs real behavior proof before merge. :: [P1] Preserve the scan boundary for existing Adaptive users
  • reviewed 2026-07-13T05:50:21.369Z sha 2c0a414 :: needs real behavior proof before merge. :: [P3] Remove the release-owned changelog edit
  • reviewed 2026-07-13T06:00:07.930Z sha 2c0a414 :: found issues before merge. :: [P1] Preserve ambiguous legacy installs before changing the default | [P2] Request notification authorization during the same launch | [P3] Remove the release-owned changelog entry
  • reviewed 2026-07-13T06:11:43.418Z sha 2c0a414 :: found issues before merge. :: [P1] Preserve ambiguous legacy installs before changing the default | [P2] Request notification authorization during the same launch | [P3] Remove the release-owned changelog entry

@hhh2210 hhh2210 changed the title Make adaptive refresh agent-aware by default Make adaptive refresh agent-aware on fresh installs Jul 13, 2026
@hhh2210

hhh2210 commented Jul 13, 2026

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

The two current-head blockers are fixed in 04df269a:

  • Adaptive is now the fresh-install default. Existing config or either prior-launch marker keeps an unset cadence at 5 minutes; invalid values also recover to 5 minutes. All valid stored choices remain unchanged. The resolved value is persisted immediately.
  • LocalAgentSessionScanner.scan is @concurrent, so process and transcript parsing cannot inherit MainActor execution.

The new settings suite covers fresh persistence, both launch markers, existing config, String and non-String invalid values, and all 7 valid cadence values across fresh and marked states. The PR body now states the only historical ambiguity: a completely untouched, configless v0.1-v0.3 install left no durable signal that differs from a new install.

make check is clean, and 37 repair-focused tests pass on this head. The replay screenshot, frozen-trace hash, coverage limits, and scanner cost measurements remain in the PR body.

@clawsweeper

clawsweeper Bot commented Jul 13, 2026

Copy link
Copy Markdown

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

Re-review progress:

@hhh2210 hhh2210 changed the title Make adaptive refresh agent-aware on fresh installs Make adaptive refresh agent-aware with explicit local activity consent Jul 13, 2026
@hhh2210

hhh2210 commented Jul 13, 2026

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

Head 2c0a4147 addresses the authorization finding and adds the requested packaged-app proof.

  • Adaptive cadence no longer authorizes local scanning. A separate persisted undecided / allowed / declined preference gates the Adaptive-only scanner. Fresh and existing Adaptive installs both stay at 0 scans until the user chooses Allow Local Activity.
  • The consent screenshot discloses the running-process/command-line and session-metadata scope, 30-second cadence, in-memory retention, no activity-data upload, no remote/SSH work, and the menu-only decline path.
  • The redacted exact-head report covers fresh install, existing Adaptive, legacy unset, allowed, declined, timer pull-forward, and sustained scanning from one clean packaged bundle. It used synthetic HOME / CODEX_HOME, disabled Keychain access, and denied network access.
  • The 65.646-second Time Profiler run covered two recurring scans after the immediate scan. The allowed process started scans at 0.000s, 31.350s, and 63.336s, logged codingActivity delay=300s, emitted no remote/SSH event, and had 0 potential hangs at the 250 ms threshold.
  • make check passes, along with 67 focused consent/settings/timer/localization tests.

The PR body now puts this blocker-resolution matrix before the older policy replay and states the proof limits explicitly.

@clawsweeper

clawsweeper Bot commented Jul 13, 2026

Copy link
Copy Markdown

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

Re-review progress:

@clawsweeper clawsweeper Bot added proof: sufficient Contributor real behavior proof is sufficient. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. and removed proof: 📸 screenshot Contributor real behavior proof includes screenshot evidence. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Jul 13, 2026
@steipete

Copy link
Copy Markdown
Owner

Maintainer review: needs owner decision; not merging this head.

Thanks @hhh2210 — the implementation and proof here are unusually thorough. I read the full 62-file diff plus the adjacent scanner, timer, settings, and onboarding paths.

The privacy boundary itself looks credible:

  • Adaptive-only scanning does not start before explicit allowed consent.
  • The consent copy discloses process-list inspection (including command lines), known Codex/Claude session metadata, and the 30-second cadence.
  • With Agent Sessions hidden, the scan projects only the newest local activity timestamp into memory and clears session details.
  • Remote/Tailscale/SSH discovery remains behind the separate Agent Sessions setting.
  • I found no new upload, analytics, URL, dependency, or other network path for local activity.

I am parking the PR for these blockers:

  1. Product contract / owner decision. Peter's merge verification on feat: add offline adaptive-refresh replay tooling #2029 explicitly concluded that the same one-machine replay did not support a default or production-policy change: feat: add offline adaptive-refresh replay tooling #2029 (comment). This PR does both. It needs explicit owner decisions on two separate questions: (a) ship activity-aware production Adaptive policy at all, and (b) make Adaptive the fresh-install default while accepting that markerless v0.1-v0.3 installs are indistinguishable from fresh installs and would change from 5m.
  2. Scanner bounds. The Codex/Claude caps are applied after complete directory enumeration, mtime reads, and sorting. Content parsing is capped, but the 30-second metadata scan still scales with the full directory. Either bound that work before enumeration/sort, or get explicit performance/contract acceptance and avoid describing the entire scan as bounded.
  3. First-launch notification authorization. When the consent modal is shown, notification authorization is skipped until a later app launch. A long-running menu-bar first launch may therefore never enable adaptive notifications in that process lifetime. Request authorization after the modal completes in the same launch.
  4. Future mtimes. A future-dated session timestamp produces a negative age and remains active; newer-only retention can then pin the 5m cadence until wall time catches up. Clamp or reject future activity timestamps.
  5. Changelog workflow. Remove the CHANGELOG.md edit; maintainers batch that separately.

Verification performed on PR head 2c0a41479602a8aa804139cbf50bef358e32d3da:

  • Focused Swift test run: 100 tests across 10 suites passed (adaptive policy/timer, settings default, CLI, session descriptors/mapping/rollouts, localization).
  • make check: passed; SwiftFormat reported 0 files requiring formatting, SwiftLint reported 0 violations, and repository/package/localization gates passed.
  • git diff --check origin/main...HEAD: clean.
  • Full maintainer autoreview: five accepted findings, matching the owner/default, scan-bound, notification, and future-timestamp blockers above.
  • Existing exact-head CI is green, but the branch is now DIRTY against main. A merge-tree rehearsal found conflicts limited to the 23 localization catalog tails.

Recommended next step: owner decides both product questions. If approved, fix the code blockers, merge current origin/main without force-pushing, resolve the locale tails, and rerun exact-head CI. If not approved, narrow or park the policy/default portions while preserving the consent work.

@clawsweeper clawsweeper Bot added status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. and removed proof: sufficient Contributor real behavior proof is sufficient. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. labels Jul 17, 2026
@steipete
steipete merged commit 0844c87 into steipete:main Jul 17, 2026
8 checks passed
@steipete

Copy link
Copy Markdown
Owner

Merged with the owner-decided opt-in shape. Plain Adaptive remains the fresh-install default. Adaptive (agent-aware) is a separate picker choice and requires explicit consent.

Privacy and safety verification:

  • No process or session-directory observation occurs before both agent-aware mode selection and allowed consent.
  • After consent, the process list identifies Codex or Claude; adaptive-only metadata enumeration starts only when an agent process is present.
  • Hidden Agent Sessions state retains only the latest in-memory timestamp. Future mtimes use one path-free, stable clamp anchor.
  • Scan limits are 64 processes, 128 Codex rollouts, 64 Claude transcripts per project, and a shared 512-entry, depth-1, 250 ms directory budget.
  • Notification authorization is requested in the same launch after consent resolution.
  • All five strings were added across 23 locale catalogs. No CHANGELOG edit remains.

Verification:

  • swift test --filter 'ClaudeSessionMappingTests|CodexSessionRolloutTests|ClaudeProbeWorkingDirectoryTests|SettingsStoreRefreshDefaultTests|AgentSessionMenuDescriptorTests|AdaptiveRefreshTimerTests|AdaptiveReplayModeTests': 63 tests in 7 suites passed.
  • make check: locale, package, docs, and release gates passed; SwiftFormat clean; SwiftLint reported 0 violations in 1,535 files.
  • Final autoreview of the exact PR diff: no accepted or actionable findings.
  • Exact-head CI on 6865744ab2179eb735ad0db5146bde56da5b3667: GitGuardian, lint, both Linux builds, and both full macOS shards passed. The macOS shards completed in 24m49s and 21m55s.
  • Local make test discovered 697 selections but stopped in BoundedChildProcessProofTests: the PTY 1.1 MB proof completed without triggering its output limit. That code and test are unchanged versus main; exact-head CI's full macOS shards passed.

Merge commit: 0844c878a9bcce85b431c6b3f35fbad9b5f8e47b.

Thanks @hhh2210 for the original agent-aware design and diagnosis. The contribution is preserved in the merge history.

@steipete

Copy link
Copy Markdown
Owner

Follow-up CPU-budget coverage landed in #2276 as 86d3e2d4e26a7542379c6e643de3cb97dd8623bf.

The new normal-suite tests cover the agent-aware Adaptive path from #2111: a synthetic capped 512-entry/depth-1 session tree must complete below 250 ms and never visit beyond the cap, while plain Adaptive plus undecided/declined consent must make zero local scan calls through a spy seam. The implementation now gives adaptive metadata enumeration a 150 ms internal deadline and stops Codex parsing after all live working directories are matched.

Verification: 24 focused tests passed; make check passed with SwiftFormat clean and SwiftLint at 0 violations; exact head d6c01579c0e7e2fad3c34f7c99cc4ed1c3fb9bcf passed all 8 GitHub checks, including both macOS test shards and both Linux builds.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merge-risk: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. merge-risk: 🚨 security-boundary 🚨 Merging this PR could weaken sandboxing, authorization, credentials, or sensitive data. P2 Normal priority bug or improvement with limited blast radius. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants