Skip to content

feat(snapshot): move scope into presentation - #1855

Merged
thymikee merged 10 commits into
mainfrom
codex/1797-step3-scope
Aug 20, 2026
Merged

feat(snapshot): move scope into presentation#1855
thymikee merged 10 commits into
mainfrom
codex/1797-step3-scope

Conversation

@thymikee

@thymikee thymikee commented Aug 18, 2026

Copy link
Copy Markdown
Member

Summary

Move snapshot scope selection into each platform's presentation boundary.

  • keep iOS acquisition broad, apply contribution-aware scope and relative depth once in Swift presentation, and treat a missing scope as a healthy empty projection
  • preserve Android's contribution-aware presentation policy and pin Swift and TypeScript to the same golden table, including decorative-first and dropped-container cases
  • remove daemon/backend-specific iOS scope interpretation and accept an empty simulator result only when an active scope carries a structured non-sparse runner verdict
  • update the snapshot command reference and ADR 0004 to name the presentation-owned contract

Part of #1797.

Validation

Evidence head: 85ac56681b51c0f1a71a7a090e5e879c440f03ae.

  • pnpm check:affected --run
  • pnpm build
  • pnpm check:xctest-selection — 156 declared methods; 0 unreachable
  • AGENT_DEVICE_XCUITEST_INCLUDE_UNIT_TESTS=1 pnpm build:xcuitest:macos
  • pnpm build:xcuitest:ios
  • focused TypeScript suites across the shared scope table, Android and desktop projections, daemon ownership boundary, and Apple interactor
  • red proof: restoring first-raw-match selection makes the decorative-first parity case fail (1 !== 2); before the scoped-empty interactor fix, the production-boundary regression throws XCTest snapshot returned 0 nodes on iOS simulator
  • live iOS Simulator at production-identical 70ef0b6d (the final commit changes only the test-size ratchet), Settings on iPhone 17 Pro: snapshot --actions -s General -d 0 --json selected private-ax and returned only the re-rooted General root; -s zzzz-no-match-token returned success: true with nodes: [] and the structured private-AX verdict; close succeeded

Scope: 30 files, 594 additions / 221 deletions, with no expansion beyond snapshot scope ownership, parity evidence, and command documentation. Of that, 332 additions / 124 deletions are the Swift runner policy, presentation move, and XCTest evidence; TypeScript production is 71 additions / 46 deletions; the remainder is tests, the shared fixture, workflow ownership, and docs. CI Size reports +225 B raw JS / +121 B gzip / +3.9 kB npm unpacked. The unpacked-size review trigger was examined: the new Swift policy and presentation seam are the necessary cross-process twin of the TypeScript contract, while keeping scope in the daemon would duplicate the invariant. A tightening pass removed 537 lines of unrelated provider-scenario churn before publication.

@thymikee

Copy link
Copy Markdown
Member Author

Exact bd59d47e is DIRTY and stale-stacked. Current main already contains #1850 eligibility and #1846 contribution-aware Android scope. This branch reintroduces raw-tree first-match scope in TypeScript and Swift, so a decorative first match later removed by eligibility can yield empty output despite a later contributing match.

Rebase, drop the merged eligibility commit, preserve the first-preorder-match-whose-presented-subtree-contributes contract, and add decorative-first/later-contributing parity plus production-boundary regressions.

The PR body is only stack boilerplate, full CI did not run, and the required live iOS tree/private-AX plus Android evidence is absent.

@thymikee
thymikee force-pushed the codex/1797-step3-scope branch from bd59d47 to 8b1c813 Compare August 18, 2026 17:58
@thymikee thymikee changed the title codex/1797 step3 scope feat(snapshot): move scope into presentation Aug 18, 2026
@github-actions

github-actions Bot commented Aug 18, 2026

Copy link
Copy Markdown

Size Report

Metric Base Current Diff
JS raw 2.33 MB 2.33 MB +225 B
JS gzip 764.9 kB 765.1 kB +121 B
npm tarball 888.6 kB 889.7 kB +1.1 kB
npm unpacked 3.10 MB 3.10 MB +3.9 kB

Startup median (7 runs, lower is better):

Scenario Base Current Diff
CLI --version 19.3 ms 19.3 ms +0.0 ms
CLI --help 47.5 ms 48.3 ms +0.8 ms

Top changed chunks:

Chunk Raw diff Gzip diff
dist/src/internal/daemon.js -135 B -38 B
dist/src/snapshot.js +6 B +15 B

@thymikee

Copy link
Copy Markdown
Member Author

Re-reviewed exact 8b1c8130: the rebase/stack issue is fixed, and current-main eligibility plus Android’s contribution-aware scope policy are preserved.

P1 remains on Swift: applyScope selects the first raw semantic match before presentedNodes applies eligibility. A decorative first match whose subtree contributes nothing can therefore produce an empty projection and suppress a later contributing match, contrary to the shared contract and Android implementation. Make Swift selection contribution-aware, then add decorative-first/later-contributing and dropped-container/contributing-child parity plus production-route regressions.

Coverage is red only from inherited #1860 ratchet drift. The body also still needs the required 24-file scope disclosure and specific live private-AX production evidence.

Use one preorder label/identifier/value policy across Swift and TypeScript, keep scoped iOS acquisition conservative, and remove the daemon's second scope pass.

Non-vacuity: label-only matching failed identifier/value parity fixtures; Android pass-through failed its boundary test; disconnecting Swift applyScope produced eight scope/depth/projection failures.
@thymikee
thymikee force-pushed the codex/1797-step3-scope branch from 8b1c813 to 70ef0b6 Compare August 20, 2026 06:48
@github-actions

github-actions Bot commented Aug 20, 2026

Copy link
Copy Markdown
PR Preview Action v1.8.1
Preview removed because the pull request was closed.
2026-08-20 08:30 UTC

@thymikee thymikee added the ready-for-human Valid work that needs human implementation, judgment, or maintainer merge label Aug 20, 2026
@thymikee

Copy link
Copy Markdown
Member Author

Finished and re-reviewed exact head 70ef0b6d53a202fee90bbb6b6b58a9df4ad69b91: code-clean. Scope selection now lives at each platform presentation boundary, skips an earlier semantic match when its projected subtree contributes nothing, and retains a dropped matching container when its child contributes. The shared golden cases make the former first-match implementation red; XCTest, Android, and the shared TypeScript range owner agree.

The exact-head live iOS Settings route also exposed and fixed the simulator's healthy-empty boundary: a scoped empty capture is accepted only with an active scope plus a structured non-sparse runner verdict; unscoped, sparse, and legacy empty captures still fail closed. Live private-AX evidence covers General with relative depth 0 and a missing scope returning success: true, nodes: []; session cleanup succeeded.

pnpm check:affected --run is green (4,758 tests; changed-line coverage 100%), the branch is mergeable, CI Size is +225 B raw JS / +121 B gzip / +3.9 kB unpacked, and the body now itemizes the justified growth and tightening. Exact-head CI is green so far with Android/iOS Smoke, Coverage, and FreeRange still running. Marked ready-for-human.

@thymikee thymikee removed the ready-for-human Valid work that needs human implementation, judgment, or maintainer merge label Aug 20, 2026
@thymikee

Copy link
Copy Markdown
Member Author

Follow-up at 85ac56681b51c0f1a71a7a090e5e879c440f03ae: the prior Coverage failure was PR-owned and fixed. This branch removes 14 lines from src/daemon/handlers/__tests__/find.test.ts; its shrink-only pin still named 1,237, so CI correctly required lowering it to the measured 1,223. The focused ratchet test and the full chained pnpm check:affected --run pass (4,762 tests, 100% changed-line coverage). Readiness stays off until the new exact-head CI run confirms the fix.

@thymikee thymikee added the ready-for-human Valid work that needs human implementation, judgment, or maintainer merge label Aug 20, 2026
@thymikee

Copy link
Copy Markdown
Member Author

Exact-head update: Coverage is now green on 85ac56681b51c0f1a71a7a090e5e879c440f03ae, confirming the lowered 1,223-line ratchet pin. Every completed exact-head check passes, the branch is mergeable, and only iOS Smoke remains in progress with no failure evidence. Restored ready-for-human; merge readiness awaits that final lane.

@thymikee
thymikee merged commit 9ce1ef7 into main Aug 20, 2026
30 checks passed
@thymikee
thymikee deleted the codex/1797-step3-scope branch August 20, 2026 08:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready-for-human Valid work that needs human implementation, judgment, or maintainer merge

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant