Skip to content

Windows parity: Context menus carry the macOS item set and grouping #778

Open

Description

@coneilen

Visual and functional parity work item, from the 2026-10-13 side-by-side review.

  • Comparison: macOS reference Run A (app at 09eda11a, Dark, 2x) against the Windows testing-gaps run (installed 0.1.78-windows.beta26, 2560x1440 at 100%).
  • Ground truth: macOS is the reference. Only platform chrome may differ: the title bar, window buttons, menu-bar location and native file pickers.
  • Evidence limits:
    • File names below refer to the two local evidence bundles. The next macOS ground-truth run will attach captures.
    • Difference IDs (D1, E2, …) refer to the review report.
    • The reviewer opened the paired images it cites. Some surfaces could not be reviewed; they are listed under "Captures needed" in the ledger entry.
  • Done when: every acceptance box is met and shown with paired screenshots in the PR. Before/after Windows captures go next to the macOS capture, and a reviewer from a different model vendor confirms them. A UIA readback or green unit test alone does not satisfy a visual criterion.

Evidence:

  • macOS: 734-*-menu-items.txt, 734-card-sketchA-with-menu-region, 734-canvas-background-with-menu-region, 728-*-menu-items.txt;
  • Windows: tg735-promote-menu-state, readbacks\tg734-*.json;
  • differences P1–P4.

Acceptance criteria:

  • Per card type and state, the items, order and separators match the macOS lists, including Export Loop…, Import Loops Here…, Change to Timed… and "Stop Loop".
  • The background and project menus include Export All Loops… and Import Loops…, and "Worktrees…" shows its count.
  • Any Windows-only items (Edit Details…, Create Edge, Wire it up / Mark as entry in the menu) are removed or recorded as deliberate extras.
  • The native popup chrome may stay.

Activity

  1. added
    enhancementNew feature or request
    parityWindows/macOS UI parity ledger row (investigation/ui-parity-matrix.md)
    P2 featureParity priority 2: features macOS has that Windows lacks
    visual parityVisual fidelity against the macOS reference captures
    on Oct 14, 2026
  2. coneilen commented on Oct 14, 2026

    @coneilen
    CollaboratorAuthor

    Wave 1 stopped (operator decision, 2026-10-14). No PR was opened; E3 reached 30dc4f55 locally. All this work is abandoned. Decisions to reuse in wave 2:

    • Create Edge: remove it, because connector drag is the macOS path.
    • Edit Edge, Edit Details and unwired recovery: keep them as deliberate extras until Windows has the macOS path. Cite the macOS equivalent in the PR.
    • No dead items: Export Loop, Import Loops, project Move Up/Down and Change to Timed/Goal have no Windows implementation. Leave them out and record them as NotImplemented, with macOS file:line, rather than adding items that do nothing.

    Restarting from main under investigation/windows-parity-lane-kickoff.md.

  3. coneilen commented on Oct 14, 2026

    @coneilen
    CollaboratorAuthor

    Implementation plan (wave 2)

    Baseline: origin/main / 8ea81062a6220e1d2ecfdaa8a73d8eb59ac575b4. Planning worker pe, lane E. Repository inspection only: no product edits, builds, tests, desktop interaction, or reuse of the abandoned 30dc4f55 implementation.

    I read the Wave 1 stopped decision first and checked its conclusions against current source. The canonical kickoff was read in full from origin/main. Source citations below use repository-relative paths at this baseline.

    Complexity rating: standard

    This assessment covers only the coordinator-approved slice: supported menu composition/order/grouping, named-project reclaimable counts, background Create Edge removal, and the indispensable connector-entry gate migration. These are bounded changes to two existing product files and the corresponding two harness files, not a new shared framework or cross-lane architecture. The native HMENU builder, stable command dispatch, project-scoped observations, connector down/move/up route, and connected-stub create/edit/cancel assertions already exist. The migration replaces one creation entry point and its unlocked endpoint checks with the existing connector route and locked endpoint checks; it preserves the downstream wire/CAS/cancel proof rather than introducing a new mechanism. The key risks are precise scope, owner identity, and retaining that proof, not many interdependent architectural changes across the large files.

    The denied ledger edit and deferred export/import, conversion, reordering, edge-summary, and surface-specific menu mechanisms are excluded from this rating. Under the user-directed policy, this is gpt-6-luna / high / default context, not the highly-complex exception. The approval controls scope and execution where it corrects this original plan, including denying step 5's ledger edits and requiring direct pwsh -NoProfile -File Tools\windows\Tests\ValidationRunner.Tests.ps1 execution instead of the originally proposed Invoke-Pester command. No implementation has been performed.

    Decisions retained from wave 1

    1. Remove Create Edge from the background context menu. The replacement already exists, not a proposed future feature: macOS ProjectCanvasForms.swift:33-55 drags a connector to another card; Windows App.zig:9613-9620,9960-9980 routes connector down/drop through createEdgeBetweenIDs, which passes locked endpoints into createEdgeForm (App.zig:3696-3719). Preserve that working path. Do not remove the independently owned Loop-menu command in MainWindow.zig:628 in this PR; that belongs to Windows parity: File/Loop/Terminal menus are missing macOS commands and diverge in enablement (implementation gap) #722.
    2. Retain Edit Details, Edit Edge, and Wire it up / Mark as entry as deliberate Windows extras. Do not claim they are macOS context-menu items. Mac equivalents/limits are documented below.
    3. Do not add inert Export/Import, Move Up/Down, or Change to Goal/Timed entries. Their missing Windows implementations are NotImplemented, not disabled new placeholders and not parity achieved. In particular, the existing disabled Move Project means filesystem relocation, not macOS sidebar reordering.

    Acceptance-box audit

    Paths beginning graphcode/... below are macOS; Windows paths are graphcode-windows/src/....

    Acceptance box Exact macOS behavior and source Current Windows behavior and source Gap / root cause
    Per-card items, order, separators, Export/Import, Change to..., Stop Loop graphcode/Sources/Features/Project/ProjectCanvasCards.swift:84-151, nodeMenu(for:): Open Terminal; unresolved-only New Child Node; composite Open Group / Pilot Once... / Arm Schedule; sketch-only Promote submenu; eligible Goal/Timed conversion; Rename; Save as Template; optional Detach; unresolved-only Stop Loop; divider; Export Loop / Import Loops Here; divider; Delete Loop. GraphcodeKit/Sources/Domain/LoopNode.swift:577-582 resolves succeeded, failed, stalled, stopped. LoopType.swift:49-55 permits Goal <-> Timed only, and the menu additionally excludes stopped nodes. GraphContextMenu.zig:5-16,170-203, nodeMenuPlan: existing stable actions and correct resolved predicate, but Save precedes Rename, Stop is named Stop, composite actions introduce an extra divider, deliberate extras interrupt the primary order, and Delete has no destructive boundary on an ordinary node. buildMenu at GraphContextMenu.zig:282-304 inserts Promote after Edit Details, not from the primary action sequence. App.zig:4487-4533, prepareNodeMenu, derives state/type; App.zig:1225-1230 already matches macOS resolution states. Composition is Windows-specific hard-coded ordering, and submenu insertion is coupled to the unrelated Edit Details command. Transfer actions have no Windows path; conversions cannot reuse the sketch-only path: SketchPromotion.Context.capture/validateCurrent (SketchPromotion.zig:107-120,151-161) reject non-sketches. Wire.zig:863-885 can serialize promotion but that is not an implemented conversion UX. Do not pretend a new label supplies it.
    Background/project Export All / Import and Worktrees count ProjectCanvasView.swift:302-321, folderMenu / worktreesMenuTitle: folder actions, divider, nonempty-only Export All, Import always; suffix is reclaimable, only when >0. AppSidebarView+Rows.swift:117-140, projectMenu: Move Up/Down; divider; folder/remote actions; divider; Close / Remove; divider; nonempty-only Export All / Import; divider; Delete Loops / Delete named folder. FolderMenuItems.swift:16-32 supplies the same reclaimable suffix. Reordering swaps same-section neighbors, not folders on disk (AppFeature.swift:464-480). GraphContextMenu.zig:252-281, buildMenu: background folder verbs plus Create Edge; project Open Project / New Loop, folder verbs, lifecycle/relocation verbs. Both use literal Worktrees...; target structs (GraphContextMenu.zig:18-23,33-37) carry no count. App.zig:4559-4580,4629-4634,9840-9867 never supplies one. Project-scoped observations already exist: App.zig:5454-5475 reads model.graphFor(result.project_path).worktree_notice.observation.summary, including reclaimable. Count information is dropped at target construction and rendered as a constant. Export/import are absent from Windows App dispatch (App.zig:4799-4943), client command methods (DaemonClient.zig:431-465), and Wire command builders (Wire.zig:191-325,806-885); no Windows bundle/picker flow is wired. Sidebar Move Up/Down has no Windows dispatch; moveProjectMenuItem (GraphContextMenu.zig:144-156) instead exposes explicitly unsupported relocation.
    Remove or explicitly record Windows-only items macOS connector creation is ProjectCanvasForms.swift:33-55; on-card recovery is ProjectCanvasCards.swift:33-41 (onWireUp starts the connector gesture; onMarkAsEntry dispatches mark-as-entry). No Edit Details item in the full project, sidebar, or overview menu builders (ProjectCanvasCards.swift:84-151; AppSidebarView+Rows.swift:151-186; GraphOverviewCards.swift:224-264). Edge popup is summary + Delete only (ProjectCanvasView.swift:441-445), not an existing-edge editor. Create Edge is appended by the background arm of buildMenu (GraphContextMenu.zig:252-259) and dispatched at App.zig:4934; recovery is added at GraphContextMenu.zig:182-186, implemented at App.zig:4388-4425; Edit Details is added at GraphContextMenu.zig:194, implemented by App.editSelectedNodeDetails (App.zig:3590-3637); Edit Edge is added at GraphContextMenu.zig:306-309, implemented by App.editSelectedEdge (App.zig:4329-4340). Create Edge duplicates an available parity path and can be removed. The other extras expose working Windows capability without the macOS interaction surface: retain and identify them explicitly, rather than hiding needed actions or claiming a macOS Edit Details/Edit Edge screen exists.
    Native popup chrome may stay SwiftUI context-menu builders cited above; 734/728 captures confirm the menu presentation. GraphContextMenu.show, GraphContextMenu.zig:223-246, uses CreatePopupMenu / TrackPopupMenu / DestroyMenu. No custom popup renderer, palette, font, or chrome change is needed. Keep native Windows menus.

    Additional source-derived edge gap (P2 in the review, though not separately spelled out as an issue checkbox): macOS ProjectCanvasView.swift:441-445 adds disabled edge.canvasSummary before Delete. CanvasEdgeViews.swift:138-145 includes kind display name, condition display name, optional payload-transform summary, and optional loop fireCount/guardSummary. EdgeKind.swift:15-20, EdgeCondition.swift:16-21, PayloadTransform.swift:18-23, and CycleGuard.swift:62-70 define that wording. Windows EdgeTarget carries only path/id (GraphContextMenu.zig:25-28), App.showEdgeContextMenu snapshots only those (App.zig:4582-4598), and buildMenu appends only Edit/Delete. The metadata exists in GraphModel.Edge (GraphModel.zig:65-77), but never reaches the menu. Do not reuse GraphCanvas.edgeLabel blindly: GraphCanvas.zig:1543-1559 uses raw protocol words, omits Always on unfired edges, and adds a fired suffix that differs from canvasSummary.

    Do not flatten the macOS surfaces into an invented universal menu. The project-canvas list above is the reference for card captures. Sidebar node menus intentionally omit Promote, templates, and Open Group (AppSidebarView+Rows.swift:151-186); overview menus add Reveal in folder and omit graph drilling (GraphOverviewCards.swift:224-264). Windows currently shares its node popup across canvas and sidebar (App.zig:4427-4431,9868-9873), and declines canvas right-click handling outside .project (App.zig:9908-9912). This first slice preserves those existing routes; exact surface-specific sidebar/overview composition is not closed by it.

    First PR: supported loop-menu composition, reclaimable counts, and removal of duplicate background creation

    This is a presentation-only slice over existing working commands. The main missing Export/Import and conversion features cannot be completed by menu edits; the operator expressly ruled out dead items. Correct the remaining supported card ordering/grouping and Stop Loop wording first, pass through already-available reclaimable counts, and remove the duplicate context-menu Create Edge without removing edge creation.

    Boxes this PR can close after runtime/image review:

    • Box 3: Create Edge absent from background popups; Edit Details, recovery, and Edit Edge retained and documented as deliberate extras.
    • Box 4: native popup chrome retained.

    Boxes to leave unticked:

    • Box 1: correct the supported project-card subset, including Stop Loop, but Export Loop / Import Loops Here / Goal-Timed conversion remain NotImplemented; complete per-surface item-set parity is not claimed.
    • Box 2: add the correct Worktrees reclaimable count, but Export All / Import and full project-menu structure remain incomplete.

    Also deferred: edge summary header (P2), project lifecycle label/structure alignment, and exact sidebar/overview node-menu variants. Edge summary needs its own coherent formatter/data-ownership slice; coordinate with lane B/#765 before extracting or exposing the existing private cycle-guard formatting in GraphCanvas.zig. Do not silently add that cross-lane edit here.

    Implementation sequence and tests

    All test names below are proposed tests to add, not results already observed. RED must be a completed behavioral assertion against the old menu, not a missing-field/function compile error. Where a target field or preparation seam is needed, land the behavior-preserving data/schema extraction first (new count default 0), then write/run the failing assertion before implementing count propagation/rendering.

    1. Test the actual HMENU, then fix the supported node sequence.

      • File/functions: GraphContextMenu.zig, nodeMenuPlan, promotionItems, buildMenu(.node).
      • Standard supported sequence: Open Terminal; eligible New Child; composite Open Group / Pilot Once... / Arm Schedule, or eligible Promote submenu; Rename; Save as Template; optional Detach; eligible Stop Loop.
      • Put retained Edit Details and eligible Wire it up / Mark as entry together in an explicitly separated extras group after that sequence, then a single divider before Delete Loop. Omit the unsupported transfer group entirely; do not create adjacent/leading/trailing dividers to stand in for missing actions.
      • Have the production plan describe the Promote slot rather than splicing it after Edit Details. Retain existing command IDs, eligibility checks, child/promotion context ownership, and callbacks. The submenu should include macOS's disabled "Keep the session, add a shape" heading and Goal / Turn / Timed entries in source order; use the source's ellipsis and em dash wording. Distinguish a header/submenu slot from a separator rather than overloading command 0 as an actionable entry.
      • Match macOS base captions (Stop Loop, Pilot Once..., etc.). Keep truthful existing Windows shortcut-column hints and actual bindings; they are deliberate platform affordances, not new commands. No shortcut-routing changes.
      • Root src\GraphContextMenu.zig, new tests:
        • context parity node popup preserves supported macOS order and destructive boundary: inspect GetMenuItemCount, GetMenuItemID, GetMenuStringW, GetMenuState, including separators, for sketch/Main, Turn, Goal, Timed, composite; unresolved/resolved; following/not-following template; wired/unwired; piloted/unpiloted. Assert ordered complete arrays, no duplicate/empty separator groups, enabled standard actions, disabled unpiloted Arm, and no Stop/New Child for resolved targets. Expected main RED: Save precedes Rename, Stop is not Stop Loop, and ordinary Delete has no divider.
        • context parity sketch popup keeps promotion before Rename with explanatory header: inspect the real submenu, header disabled/non-actionable, 3 target commands in order, correct wording and context enablement. Expected main RED: submenu follows Edit Details; submenu contains only 3 entries and lacks the heading.
        • Retain/adapt existing custody child ..., sketch promotion ..., resolved node ..., native node menu variants ..., and shortcut tests in this same root; replace obsolete positional expectations, not coverage.
      • Bounds: check NodeMenuPlan capacity for the all-flags test target as well as valid runtime combinations; avoid overrunning its current fixed 15 slots.
    2. Remove background Create Edge without making empty/stray-separator popups.

      • File/functions: GraphContextMenu.zig, buildMenu(.background) / show; App.zig, showBackgroundContextMenu and the background arm of handleContextAction.
      • Remove the context entry and context-only eligibility plumbing; retain the real connector path, createEdgeForm, and the separately owned menu-bar command. Only append separators between groups which actually exist. If global background now has zero supported entries, do not enter TrackPopupMenu with an empty HMENU. Preserve the existing local/remote/busy enablement rules; changing remote-folder functionality is not this slice.
      • Root src\GraphContextMenu.zig, new test context parity background omits duplicate edge creation and empty groups: enumerate local one/two-node-equivalent targets, unavailable/remote targets, and global targets; assert no command 5120, no leading/trailing/adjacent dividers, and correct remaining folder-action enablement. Expected main RED: 5120 exists; global contains that single command.
      • Keep context actions remain stable... assertions for all remaining popup commands. Do not renumber command IDs when removing an entry.
      • Regression for retained creation is step 4's existing connector path plus the connected-stub create/edit workflow, not a direct command disguised as connector input.
    3. Pass the named project's reclaimable count into both existing menu surfaces.

      • File/functions: GraphContextMenu.zig, BackgroundTarget, ProjectTarget, the two Worktrees item builders; App.zig, showBackgroundContextMenu, project popup construction in WM_RBUTTONUP, and showUiaContextMenu targets 1/2.
      • Add a reclaimable-count snapshot to each target, default 0. Extract the current project/background target construction into narrow reusable preparations so the real mouse and UIA-hook paths use the same data. Read the record belonging to the target path via model.graphFor(path), then its observation summary. Never use whichever project is selected, the global attention/header owner, the inspection of another project, total count, or notice-threshold eligibility. A known count 1..7 must appear even below the toolbar-notice threshold. No observation/0 means no numeric suffix, as on macOS.
      • Build one shared Worktrees caption in GraphContextMenu.zig: base caption at 0; suffix 8 at reclaimable 8. Keep busy/local enablement independent from the count. Do not start Git inspection synchronously while opening a menu, and do not store pointers into refreshable model strings in the new metadata.
      • Root src\GraphContextMenu.zig, test context parity Worktrees caption shows reclaimable count on project and background: real HMENU caption for 0,1,7,8 and disabled items. Expected behavioral main RED after inert field scaffolding: input 8 still renders literal Worktrees with no suffix.
      • Root src\App.zig, test context parity menu count belongs to the clicked project: never-shown/in-memory fixture using existing custodyTestApp / model fixture helpers; select A while opening B, give A/B different observations, include below-threshold B and absent-observation cases, and assert both prepared targets carry B's reclaimable count, not total/selected-owner count. Expected RED after behavior-preserving preparation extraction: target keeps default 0 despite B observation. No native dialog/window showing in this focused test.
      • Root src\App.zig, regression context parity prepared loop states retain macOS resolved eligibility: use prepareNodeMenu with real model nodes across idle/running/awaitingInput/blocked/waiting and succeeded/failed/stalled/stopped, plus sketch/composite flags and optional child settings. Assert Stop/New Child visibility and promotion/composite eligibility derive from the actual model. The current resolution predicate should already pass; report this as a regression, not an invented RED. Main is the display name of .sketch, not another raw loop type (GraphcodeKit/Sources/Domain/LoopType.swift:21-25).
      • These roots are already registered at WindowsShell.Tests.ps1:773,1214; no new test root or registry edit is needed.
    4. Repair the integration contract, retaining real edge-create coverage.

      • OUTSIDE LANE LEASE, approval required: Tools\windows\uia-live-gate.ps1.
      • Update ordered node expectations at lines 7791-7871 and 7971-7982, background expectations at 7957-7969, and the project Worktrees expectation at 8240-8244. Keep exact item counts/order/state/command identities, the named fixture cards, cancellation, and shell responsiveness assertions. Do not weaken these to "contains some label".
      • Removing 5120 otherwise breaks a second workflow: Open-EdgeMenu $false 5120 at line 9294. Migrate that connected-stub creation entry to source-card connector drag using the already-working down/move/up pattern at lines 5876-5971 and named source/target card identities in Edge-CanvasPoint at 8948-8960. Keep edit via Open-EdgeMenu $true 5110.
      • The drag form uses locked endpoint text controls, not the unlocked source/target combos. Replace only the two creation-time Edge-Combo 9100/9101 interactions with native locked-text/readonly assertions for the exact source and target IDs. Preserve condition/kind/transform inputs, invalid-submit rejection, single correlated create, exact wire endpoints, CAS edit, cancel-no-mutation, and stable rendered identity.
      • Do not fall back to sending 5120 if connector drag fails. That would recreate the removed path in the test and falsely pass creation parity. Update entryPoint evidence (uia-live-gate.ps1:9447) to report connector geometry/input, not a fictitious menu click. Do not alter unrelated edit/promotion fallbacks.
      • OUTSIDE LANE LEASE, approval required: Tools\windows\Tests\ValidationRunner.Tests.ps1.
      • Replace the obsolete 5120-create/endpoint-combo source checks at lines 3832-3858 with source checks for connector entry and locked endpoints; retain the rest of the wire/CAS assertions. Add executable tests of the gate's menu-contract helper and connector-entry selection/preconditions with fake menu records/API calls (existing AST-extracted helper pattern): positive exact named-card/current-caption cases; negatives for missing/duplicate named source, wrong target identity, wrong count/order/Stop wording, reintroduced 5120, stray separator, and a direct-command creation fallback. Assert nonzero execution and expected throws/call sequences. Do not merely replace one regex with another and call that functional coverage.
      • Expected RED before product changes: the live menu contract rejects current order/Stop/5120/count. The hidden helper tests separately prove rejection of wrong inputs; exact-head hosted integration proves the real menu/connector path. A source-contract failure or injected negative fixture is not proof of a product runtime failure.
    5. Record the deliberate incompleteness, not a promoted parity row.

      • OUTSIDE LANE LEASE, approval required: investigation\ui-parity-matrix.md.
      • Update only Loop context menu (line 147) and Canvas context menu (line 181) with the changed supported subset, removed background Create Edge, and deliberate extras. Qualify the Project context-menu row (line 146): its old Validated status proves the previous Windows contract, not current full macOS item-set parity; with missing transfer/reorder commands it must remain/become Partial for this issue, not acquire a new blanket parity claim.
      • Explicit NotImplemented list, also in the PR: per-loop Export/Import; background/project Export All/Import; Goal/Timed conversion; sidebar Move Up/Down; edge summary header and complete per-surface/project composition deferred to follow-ups. Attach the macOS citations from this plan.
      • PR uses Refs #778, preserves the repository PR template/checklist, and names boxes left open. Source-only planning evidence is not RED/GREEN evidence.

    File scope for coordinator approval

    Within lease: graphcode-windows\src\GraphContextMenu.zig; only menu target construction/preparation, context dispatch, and focused menu tests in graphcode-windows\src\App.zig.

    Requested outside lease, up front: the three files in steps 4-5: Tools\windows\uia-live-gate.ps1, Tools\windows\Tests\ValidationRunner.Tests.ps1, investigation\ui-parity-matrix.md. The gate edit is necessary because current assertions require the command being deliberately removed and use it to create the fixture edge.

    Not requested: MainWindow.zig, GraphCanvas.zig, GraphModel.zig, NativeForms.zig, shared Swift, daemon/protocol files, provider pins, CI classifiers, or WindowsShell.Tests.ps1. If implementation needs any, ask for scope approval instead of widening this plan.

    Deliberate extras to record

    Retained Windows extra macOS counterpart / reason for retention
    Edit Details macOS edits creation fields through NodeDraftForm/NodeDraftFields, renames through the menu, and converts Goal/Timed through ProjectCanvasCards.swift:119-123; it has no existing-node Edit Details popup. Windows App.editSelectedNodeDetails is a working update path with no equivalent Windows editing surface yet. Do not describe the creation form as an existing-details editor.
    Edit Edge macOS configures at connector drop (ProjectCanvasForms.swift:12-24,38-55) and offers summary/Delete (ProjectCanvasView.swift:441-445); there is no equivalent existing-edge editor. Preserve the Windows identity/CAS editor.
    Wire it up / Mark as entry macOS exposes on-card callbacks (ProjectCanvasCards.swift:33-41); Windows still needs its menu recovery until lane B supplies those card controls. Do not remove the last recovery path as a cosmetic change.
    Other pre-existing shared-menu/project differences Windows sidebar currently inherits the canvas superset; project Open Project/New Loop, relocation, lifecycle labels/confirmations, and the separate Loop-menu Create Edge are unchanged by this slice. Record them as deferred deliberate differences, not macOS parity. Filesystem Move Project is not Move Up/Down. Delete Edge confirmation also remains a Windows extra (App.zig:4343-4372), whereas macOS deletes directly (ProjectCanvasView.swift:443-445).

    Risks and coordination

    • App.zig is shared with lanes A-D: touch only the listed menu construction/dispatch and menu-specific tests, not layout/window-procedure policy/geometry. Preserve Windows: make the right loop panel readable and match its macOS hierarchy #789 geometry helpers during rebase.
    • At inspection time, open Bound UIA Worktrees gate traversal #587 ("Bound UIA Worktrees gate traversal", branch coneilen-microsoft-fix-uia-live-gate-timeout) also touches the live gate. Coordinator must serialize or explicitly coordinate those exact regions; do not overwrite its changes or rewrite activation/timeout code.
    • Lane B/Windows parity: Canvas loop cards match the macOS card (layout, states, roles, colours) #764 will move unwired actions onto cards and Windows parity: Edges are quiet at rest and never cover cards #765 may change edge presentation. Keep current recovery until that replacement merges; defer shared edge-summary formatting rather than duplicating private guard logic or claiming the source label is equivalent.
    • The gate changes are not harmless expectation churn: locked-endpoint drag creation differs from unlocked menu creation. Preserve all create/edit/cancel/wire checks and test the harness locally without the desktop before using CI.
    • Native popup placement/metrics vary with DPI; retain Win32 ownership/coordinates. Test captions, states, counts and separators at the HMENU layer; screenshot at 100% only for this slice. Do not claim 150%/200% visual verification from that.
    • No palette/font/token changes, so no visual-baseline task is required for this slice.
    • Use the implementer's own canonical tool/provider/scratch roots, pinned Zig/Swift and process TEMP/TMP; bootstrap before executing builds. Validation root must be a real folder at most 7 characters, no junction. Prepend C:\v5modules for Pester 5.7.1. Seed onboarding-seen in fixture GRAPHCODE_SUPPORT_DIR, not LOCALAPPDATA; avoid stale default-profile zmx logs.
    • Do not run full App/unit/integration suites locally: some show windows. Only the new never-shown menu App tests are eligible for a focused local filter. Use exact-head hosted CI for the full gate.

    Commands / evidence plan

    The implementation worker runs these after bootstrap and within its own scratch environment. Commands below are a plan, NotExecuted by this planner.

    From graphcode-windows, keep distinct RED and GREEN logs:

    & $env:GRAPHCODE_ZIG0152 test src\GraphContextMenu.zig -target x86_64-windows-msvc -lc -luser32 "-I$env:GRAPHCODE_WINGHOSTTY_ROOT\include" --cache-dir "$env:TEMP\menu-zig-local" --global-cache-dir "$env:TEMP\menu-zig-global" --test-filter "context parity"

    Then run this existing hidden menu root without the filter, with the same flags/caches. Assert an actual positive executed count in each passing output, and preserve failed behavioral output. For App count/target tests, use the complete native-link command already registered at Tools\windows\Tests\WindowsShell.Tests.ps1:1214-1218 (including the worker-built provider/static-VT libraries), adding --test-filter "context parity" and worker-owned caches; do not run its unfiltered test root locally.

    For script changes, from the repo root:

    $env:PSModulePath = "C:\v5modules;" + $env:PSModulePath
    Invoke-Pester -Path .\Tools\windows\Tests\ValidationRunner.Tests.ps1 -Output Detailed

    Push the draft and use exact-head Windows unit shards, integration/live UIA, packaging, and all other required workflows for regression. Record run/job IDs and positive counts; empty checks or a manual workflow dispatch are not evidence that exact-head required checks ran. Preserve the rebase diff, then have the assigned different-vendor reviewer open the code, PR body, and actual logs.

    Only after review and exact-head CI pass, request one desktop screenshot lease (15 minutes maximum):

    Surface/state and fixture Pair with existing macOS Run A capture
    Project-canvas Main/sketch unresolved parent popup; no backend launch/submit needed 734\734-card-sketchA-with-menu-region@1x-srgb.png and 735\735-promote-submenu-region@1x-srgb.png
    Turn unresolved; Goal resolved/succeeded; Timed stopped (Stop/New Child absent); followed-template optional actions 734\734-card-turn-with-menu-region@1x-srgb.png, 734\734-card-goal-with-menu-region@1x-srgb.png, 734\734-card-timed-with-menu-region@1x-srgb.png; template-specific state is source-derived and needs a new macOS capture before a visual parity claim
    Composite unresolved/unpiloted (Arm disabled), with piloted enablement covered by focused HMENU test 734\734-card-composite-with-menu-region@1x-srgb.png
    Local project background and sidebar project with 8 reclaimable linked worktrees; background has no Create Edge 734\734-canvas-background-menu@1x-srgb.png plus item list (the with-menu-region image clips the bottom); 734\734-sidebar-project-row-ParityRef-with-menu-region@1x-srgb.png
    Unwired recovery remains visibly reachable, separately identified as a deliberate extra 734\734-card-sketchA-with-menu-region@1x-srgb.png (on-card macOS recovery, not a matching popup item)

    Use privacy-safe named fixture projects/nodes and pre-seeded states; no paid backend turns are necessary. Capture before from main and after from final head at 100%; existing beta26 images are supplementary historical evidence, not this main baseline. Use PrintWindow(...,2) with pixel verification for the owned shell, and ownership-checked screen capture for popups omitted by PrintWindow. Upload only approved privacy-safe images; never the zip or redacted needs-you-click surface. Reviewer opens each image and confirms only the limited boxes/subcriteria actually demonstrated. Close with File > Exit, stop owned processes by PID including zmx, verify cleanup, release the desktop.

    Capture limitation discovered by opening the actual file: despite its name, 735-promote-submenu-region@1x-srgb.png shows the parent popup, not an expanded submenu. Capture the expanded Windows submenu as supporting evidence, but its explanatory heading/target list remains source/HMENU-verified, not paired-image-verified, until a genuine macOS expanded-submenu image is available. Do not cite that filename as proof the submenu was visually compared.

    The ledger stays Partial. Do not tick Export/Import, conversion, sidebar reorder, edge-header, full per-surface parity, or unexercised DPI/keyboard behavior on the strength of menu-presence tests.

  4. coneilen commented on Oct 14, 2026

    @coneilen
    CollaboratorAuthor

    Plan approved (coordinator)

    Approved scope/source review: #778 (comment), supported menu composition/order/grouping, named-project reclaimable counts and removal of duplicate background Create Edge, plus the indispensable live-oracle migration. Unsupported export/import, Goal/Timed conversion, Move Up/Down, edge summary and exact sidebar/overview variants remain NotImplemented. No inert entries. Native popup chrome stays.

    Approved product scope: graphcode-windows/src/GraphContextMenu.zig menu plans/builders/targets and existing-root tests; graphcode-windows/src/App.zig only context-menu target construction/preparation, background context dispatch and focused menu tests. Retain command IDs, owned target/promotion/custody state, enablement and real actions. No normal menu-bar, terminal/workspace, sidebar layout or graph mutation changes. Preserve working Edit Details, Edit Edge and menu recovery as recorded Windows extras.

    Explicit harness extensions: Tools/windows/uia-live-gate.ps1 only ordered node/background/project menu expectations, connected-stub connector-drag creation entry/locked endpoint checks and truthful entryPoint evidence; Tools/windows/Tests/ValidationRunner.Tests.ps1 only corresponding named positive/negative functional menu/connector cases and obsolete 5120-source checks. C owns the separate initial sidebar roster/section/fixture-restore hunks in those files; use distinct helpers/test names and preserve its cases after rebase. I inspected open #587: leave its isolation/timeout and historical Worktrees-traversal mechanisms untouched; do not merge its branch or claim it integrated.

    Not approved: investigation/ui-parity-matrix.md. All ledger edits, including retained extras and the Project context-menu row's existing overbroad Validated claim, belong to the coordinator after evidence is accepted. No GraphCanvas/GraphModel/MainWindow/NativeForms/provider/shared Swift/gate-runner registry/workflow edits. Edge summary formatting is deferred, not permission to extract B's private formatter.

    I checked macOS ProjectCanvasCards.swift:84-149 (supported action order, separators, unresolved Stop Loop/New Child, composite/promotion actions); AppSidebarView+Rows.swift:117-186 (different sidebar menu and actual Move Up/Down); ProjectCanvasView.swift:302-321 (Worktrees suffix is reclaimable, not total, including below notice threshold),441-445 (edge summary/Delete); ProjectCanvasForms.swift:33-55 and ProjectCanvasCards.swift:39-41 (connector creation/recovery). Windows App.zig:9613-9620,9960-9980 confirms an existing real connector path, not a proposed substitute. Retain the independent Loop-menu Create Edge command and existing-edge editor.

    Obtain behavioral RED from the actual HMENU for order/Stop/dividers, missing Worktrees suffix and unwanted 5120, with any new count/preparation scaffolding still behavior-preserving. Test the named clicked owner with another project selected, below-threshold counts, missing observation and busy states. Remove empty/stray-separator background popups. Do not delete the connected-stub create/edit/cancel proof when 5120 is removed: drive the source connector to the exact named target, require locked source/target IDs, retain validation rejection, exact correlated create wire, CAS edit and cancel-no-mutation. No direct-command fallback or broad canvas-card count oracle.

    The planned Invoke-Pester command is corrected: ValidationRunner.Tests.ps1 is an executable test script; run pwsh -NoProfile -File Tools\windows\Tests\ValidationRunner.Tests.ps1, and assert the added functional positives/negatives actually execute. Source regexes alone are insufficient. Keep failed attempts. Full UIA/integration runs in exact-head CI; no local full suite without a separately approved debugging reason. Accepted code review and green exact-head CI precede the one <=15-minute screenshot lease. Missing expanded macOS Promote submenu capture remains Not verified. Use Refs #778; only evidence-proven boxes may be ticked by the coordinator. Implementer ie owns C:\gcs\ie, C:\gct\ie, C:\gcp\ie and real C:\gcie.

    Provisional implementation model (user-directed policy, 2026-10-14): gpt-6-luna, high, default context. This is bounded presentation/target-data work over existing native menu builders and commands, with a specific connector-entry harness migration. New export/import/conversion/reordering frameworks and edge-formatting mechanisms are explicitly deferred. Reviewer remains claude-sonnet-5.5, high. The original planner's own complexity rating determines the final model.

    Launch hold (new user-directed planner-rating step): scope/source review is complete, but effective model approval and implementation launch are pending the original planner's own standard/highly-complex rating and reason in its plan comment. No implementation session for this lane has launched.

    Correction record: a transient GitHub read emitted an unexpected-end-of-JSON error during the prior status amendment and briefly replaced the scope text with the launch hold alone. The complete scope is restored here; no implementation or scope change occurred in that interval.

    Final model/launch approval: the original planner has now added standard with its bounded existing-menu/target-data/connector-oracle rationale to the plan comment. I read and accept that assessment. The launch hold is lifted: use gpt-6-luna, high, default context, reviewer claude-sonnet-5.5, high. The exact scope and exclusions above are unchanged.

  5. coneilen commented on Oct 14, 2026

    @coneilen
    CollaboratorAuthor

    Narrow gate extension approved (coordinator): native sketch submenu

    I independently read completed run38600874454/job115979620156 on exact head7e5bd559a122bbd45fd67601b79145b4e9bb38f0. The second integration failure is the sketch real-HMENU submenu assertion: the gate expects exactly three enabled IDs5116,5117,5118, but the new native builder and native unit test intentionally include a disabled informational heading first (ID0, "Keep the session, add a shape"), then those three actions. This is a slice-caused oracle mismatch, not the transient earlier UIA retry or infrastructure; it is the second self-caused CI iteration, below the five-iteration threshold.

    Approved existing-file addition to this lane's gate/test lease: correct only that named sketch submenu assertion and directly coupled item-position consumers/functional tests. Keep strict native shape: exactly four items, exact order0,5116,5117,5118, exact informational caption/disabled/nonseparator state, followed by the three exact enabled action captions/flags. Preserve parent caption and owned-popup/foreground/command/CAS/recovery guards. Test the heading and all three actions; reject extra/reordered/enabled-heading/disabled-action/wrong-caption variants. Do not merely filter out unwanted rows, relax the count, or remove the explanatory product row to obtain green CI. No unrelated gate or product changes are authorized.

    Retain both CI failures. The log proves earlier connector create/edit/cancel and node-creation paths reached their own reported assertions, but the later promotion flow did not run past this failed menu assertion; do not claim those later checks passed. Rebase onto accepted dialog main and preserve its exact prompt helpers/functional cases before the final reviewed head, then refresh focused tests, actual exact-head CI, review and body. No local broad/native desktop run or screenshot lease is granted by this extension.

  6. coneilen commented on Oct 15, 2026

    @coneilen
    CollaboratorAuthor

    Coordinator approval: E test-only semantic fallback; visual work remains deferred

    The read-only E plan (SHA-256 E3A4E97CEAFF53C093C7E3FB92E9412F116F6924B0522C2FFA05AB381582FC2B) confirms that owned-popup screen capture is genuinely new mechanics requiring its own reviewed step before the scene adapter. Activate the operator-authorized semantic fallback so the product slice need not wait on that separately gated visual dependency. This is not visual acceptance, whole-issue closure or a parity-ledger promotion.

    Exactly one existing-file, test-only lease for the current #816 owner: graphcode-windows/src/GraphContextMenu.zig, limited to ExpectedMenuItem/expectNativeMenu test helpers, the existing hidden-HWND promotion-test adjacency, and the edge-menu test. No production menu behavior, App, stub, fixture, gate, runner, R2 script, provider, workflow or additional file changes.

    Use real GetMenuItemInfoW with bounded two-pass Unicode reads, MIIM_ID/FTYPE/STATE/SUBMENU/STRING and explicit API failures. Inspect the six exact background/resolved/sketch-unwired/Promote-child/post-Goal-shaped/edge targets: 3+7+12+4+11+2 = 39 ordered positions. Require text, order, IDs, row kinds, enablement and submenu linkage, including 5109/5112 and the disabled ID-0 NONseparator heading. Submenu parent IDs are observed native values, not invented command IDs. The shaped post-state is menu-build semantics, not proof of a live promotion.

    Include real disposable-menu negatives for extra/reordered items, enabled/separator heading, disabled action, wrong caption, missing 5109/5112, extra edge header, and invalid/out-of-range reads. Never silently truncate or equate API failure with an empty menu. Hidden STATIC HWND only, deterministic owned menu/window teardown; no ShowWindow, TrackPopupMenu, foreground/input/hover, screenshot, GraphCode/graphcoded/zmx launch or backend work.

    Source/test editing may proceed independently of R2 because this is not a shared-core adapter. NO LOCAL NATIVE EXECUTION is granted yet: the owner must submit the exact pinned Zig executable/include paths, cwd, filter, fresh cache/scratch and command for a separate allow-list decision. Full local runners remain forbidden; hosted CI supplies wider regression. A compatible pre-E source plus the same new oracle may provide a real old-order/heading RED; a compile/setup failure is not behavioral evidence and must not be relabelled. Preserve the original product RED and all prior failures.

    Before any product readiness/merge decision: actual positive focused counts, all six/39 observations and named negatives, different-vendor test/source/evidence/body review, fresh exact-head required CI, honest PR wording deferring pixels/layout/hover/physical input and paired visuals. Keep v3 immutable; corrected current job expectations must use full 12/11 parents. PM mechanics and EA scene adapters remain separate proposed PRs, only after R2 merge and their own exact leases; no E slot is granted here. #778 and the broader verifier remain open.

  7. coneilen commented on Oct 15, 2026

    @coneilen
    CollaboratorAuthor

    Merged the supported menu/connector slice in #816 as 112d458, using the operator-approved semantic fallback. Exact-head code review and CI passed; the native menu root executed 196 tests, including six menu states/39 item observations/12 negative controls. This is semantic evidence, not a visible-popup, hover, glyph/layout, physical-input or paired-visual result.

    Both earlier final-head CI failures remain in the PR: attempt 1's provider-fetch error and attempt 2's inherited capture-journal failure. The second and final permitted same-head failed-job rerun passed under #826's unrelated-PR policy; it does not repair the journal or authorize captures.

    All four whole-issue acceptance boxes remain unchecked and the issue stays open. Unsupported export/import/conversion actions and deliberate Windows extras are explicitly recorded in the PR. Visual verification is deferred; the popup adapter and any later capture batch require their own gates after #826 merges. No parity-ledger row is promoted by this merge.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2 featureParity priority 2: features macOS has that Windows lacksenhancementNew feature or requestparityWindows/macOS UI parity ledger row (investigation/ui-parity-matrix.md)visual parityVisual fidelity against the macOS reference captureswindowsWindows port

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions