Repository navigation
CMUX-37 final push: close five 2026-05-03 smoke-test gaps - #118
Merged
Merged
Conversation
Final-Push Plan section drafted by orchestrator pre-handoff covers all five workstreams (markdown blueprints, manifest layer, diagnostic cleanup, workspace --help routing, C11_SOCKET safety) with commit grouping, parallelization table, acceptance criteria, and Do-NOT-ship list. Delegator phase begins from this state.
Captures the prior delegator session's plan rewrite plus the Lattice state changes (status/comments) that went with it. The plan replaces the older phase-based shape with a single five-workstream close-out PR: 1. Markdown blueprint format 2. Snapshot manifest layer for `--all` 3. Restore diagnostic cleanup 4. `c11 workspace --help` routing fix 5. CLI socket safety (`C11_SOCKET` + auto-discovery breadcrumb) Driven by the 2026-05-03 smoke validation report (/tmp/cmux-37-smoke-report.md) on tagged build cmux-37-smoke. Original ticket Phases 0–5 already shipped via PRs #75 and #79. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…pace <sub> --help` `c11 workspace new --help` previously printed `Unknown command 'workspace'` because the help dispatcher had no entry for `workspace`. Add a `case "workspace":` to subcommandUsage that recognizes the three real subcommands (apply, new, export-blueprint), thread `commandArgs` through so the sub-token resolves, and update dispatchSubcommandHelp to include the resolved subcommand in the header. Top-level usage gains the four workspace lines too. Workstream 4 of the five-workstream close-out (smoke report 2026-05-03). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
New `Sources/WorkspaceBlueprintMarkdown.swift` provides Foundation-only parse/serialise for the operator-approved markdown blueprint format (Obsidian-friendly frontmatter + fenced YAML layout block). A vendored tiny YAML subset parser handles the indented mapping/list grammar the schema needs without an external SwiftPM dependency. `WorkspaceBlueprintStore.read(url:)` and `write(_:to:)` now dispatch on the URL extension: `.md` files round-trip through the new parser, JSON files keep the existing path. `indexEntries` reads the markdown frontmatter to populate name and description (falling back to filename stem when the frontmatter is missing or unparseable), so .md blueprints appear in the picker with their authored titles. Round-trip semantics: name ↔ frontmatter title; description ↔ frontmatter description; workspace.customColor ↔ custom_color; workspace.title falls back to frontmatter title unless `workspace_title` is set explicitly. SurfaceSpec metadata, paneMetadata, and description are dropped on serialise — markdown is the hand-authored, legible form; fully-faithful captures stay on the JSON path. Per-repo and per-user discovery still scan only the legacy `.cmux` paths in this commit; the filesystem rename to `.c11`/`~/.config/c11/blueprints/` lands in the next commit alongside the exporter and CLI integration. Tests cover round-trip equality at the value level (single-leaf, horizontal split, nested split mirroring the operator schema), custom color preservation, separate workspace_title, schema-example parse, and error surface for missing layout section / missing fenced block / unknown surface kind / split without children. Plus a store-level .md round-trip and an updated .md picker test. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…ll read Switch the canonical blueprint write target from ~/.config/cmux/blueprints/<name>.json to ~/.config/c11/blueprints/<name>.md. Markdown is the default format; operators who still want JSON pass --format json (also threaded over the v2 workspace.export_blueprint method as a format param). Per-user discovery now scans both the new and the legacy directory; the new directory ships first so the picker prefers canonical files when both exist. Per-repo discovery walks .c11/blueprints/ alongside .cmux/blueprints/ at each ancestor — .c11/ entries lead the merged list. Legacy JSON envelopes at ~/.config/cmux/blueprints/*.json remain discoverable and applicable; the smoke acceptance criteria require this. runWorkspaceBlueprintNew and workspaceBlueprintPicker now sniff the file extension on --blueprint / picker selection. .md files are routed through a new pure workspace.parse_blueprint v2 method that parses content received in memory and returns the plan dict — keeping the markdown parser inside the app's link surface, not the CLI binary, and not turning the parse path into another arbitrary-file-read. .json files keep the existing in-process JSONSerialization path. Help text under `c11 workspace new --help` and `c11 workspace export-blueprint --help` is updated to name the c11 canonical paths, list both file extensions, document --format, and show an .md example. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Workstream 5 of the CMUX-37 close-out. Closes the wrong-socket footgun the smoke validator hit on 2026-05-03: orchestrator set C11_SOCKET=..., CLI read CMUX_SOCKET_PATH instead, fell through to auto-discovery via last-socket-path, and silently mutated the operator's live workspace. Changes: - Socket-path resolution precedence is now: --socket → C11_SOCKET → CMUX_SOCKET_PATH → CMUX_SOCKET → auto-discovery. Both legacy keys remain accepted for back-compat (no deprecation warning yet — the plan defers that). - Three call sites updated consistently: defaultSocketPath, run()'s env-var loop, claudeTeamsResolvedSocketPath. CLISocketSentryTelemetry also reads C11_SOCKET first so the breadcrumb context is accurate. - After socket.path.autodiscovered fires, c11 now prints one stderr line attributing the resolved socket. CLISocketPathResolver gains a best-effort discoverySourceHint() that names the pointer file (last-socket-path) when the resolver matched it, or the CMUX_TAG=... derivation when matching a tag-derived candidate. Falls back to a generic "(auto-discovered)" suffix when the source is unclear. - C11_QUIET_DISCOVERY=1 (any non-empty, non-"0" value) suppresses the stderr line. A global --quiet flag would touch every command's print loop; that's deferred per the plan's "Out of scope" note. - usage() gains a Socket Path subsection and the Environment block now documents C11_SOCKET, CMUX_SOCKET_PATH, CMUX_SOCKET, and C11_QUIET_DISCOVERY. New String(localized:) keys for the Translator phase: - cli.socket.autoDiscoveredWithSource — "c11: using socket %@ (auto-discovered from %@)" - cli.socket.autoDiscovered — "c11: using socket %@ (auto-discovered)" Build: c11-cli scheme compiles clean against impl-A's commit 7911a41 at HEAD. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Workstream 3 of the CMUX-37 close-out, apply-side / CLI-side. The smoke
validator on 2026-05-03 saw `c11 restore <id>` exit 0 but emit seven
`failure:` lines for behaviors the executor deliberately reports on
every clean round trip — six `metadata_override` (one per surface with
a title) plus one `working_directory_not_applied` for the seed
terminal. Operator framing: stop scaring automation that grep-greps
for `failure:`.
Approach: Option B from the plan (CLI-side reclassification). The
ApplyFailure wire shape stays bit-exact — only the human-readable
print classifies. A future caller with a different opinion can read
the structured payload and ignore the classification.
Changes (CLI/c11.swift):
- Add CMUXCLI.FailureSeverity (.failure | .info) and two static
helpers: failureSeverity(code:message:) and partitionFailures(_:).
partitionFailures preserves the original order for stable output.
- Two codes get reclassified as .info:
- `metadata_override` — fires when SurfaceSpec carries both .title
and metadata["title"]. The capture-side fix (next commit) strips
the dup; this is the belt for the suspenders.
- `working_directory_not_applied` whose message contains
"seed terminal reuse" — fires on every restore whose first
terminal had a captured cwd. The seed shell is already running by
the time the executor sees the spec, so the cwd cannot apply.
Other emission sites (browser/markdown split, in-pane creation)
stay classified as real failures.
- Three print sites updated to partition-then-print:
- runWorkspaceApply (~L2975)
- runWorkspaceBlueprintNew (~L3045)
- runSnapshotRestore (~L3466)
Real failures keep their existing prefix ("failures: N" or
" failure: ..."); info-level entries print under "info: N" or
" info: ...". Format consistency with the existing prefix per
call site is preserved.
- DEBUG-only test hooks (debugFailureSeverityForTesting,
debugPartitionFailuresForTesting) on CMUXCLI for future c11-cli
test infrastructure.
CAUTION: detection of the seed-terminal case relies on the executor's
emitted message containing the substring "seed terminal reuse". If
Sources/WorkspaceLayoutExecutor.swift's
reportWorkingDirectoryNotApplicable call for the seedTerminal context
(around L656) ever changes its `context:` argument, update the matcher
in failureSeverity().
Tests: skipped — CMUXCLI lives in the c11-cli target only; c11Tests
links the c11 module, so unit-testing partitionFailures from there
would require adding c11.swift (~17k LoC) to the test target's build
phase or a new shared file with cross-target build-phase membership.
The classifier is testable via the smoke fixture during the Validate
phase (acceptance criterion: `c11 restore <id>` on the mixed
6-surface fixture prints `failures: 0`). DEBUG hooks are wired so
future c11-cli test infrastructure can exercise the partition.
No new String(localized:) keys. Existing print prefixes (`failures:`,
`failure:`) are not localized in the surrounding code, so the new
`info:` prefix follows that convention.
Build: c11-cli scheme compiles clean.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…erride warnings Workstream 3 of the CMUX-37 close-out, capture-side. Pair to the preceding CLI-side reclassification (3629b31). Together they close the gap where every clean snapshot/restore round trip emitted six bogus `metadata_override` "failure:" lines. Root cause: - Sources/WorkspaceLayoutExecutor.swift has dedicated setters for the canonical `title` (workspace.setPanelCustomTitle) and `description` (a separate write) fields. After they fire, it iterates spec.metadata and re-writes everything via SurfaceMetadataStore in merge mode. When metadata["title"] is also set and spec.title is non-nil, the executor flags this as an override even though the values usually agree — the dup is a round-trip artifact, not a real conflict. - WorkspacePlanCapture reads `surfaceMetadata` (which contains the canonical "title" key, written through SurfaceMetadataStore by setPanelCustomTitle) AND sets SurfaceSpec.title from workspace.panelCustomTitles. Both make it onto the wire; the executor sees both and warns on every restore. Fix: - Add a private strippingRedundantCanonicalFields helper to WorkspacePlanCapture.Walker. It drops metadata["title"] (and metadata["description"]) when the metadata value matches the canonical SurfaceSpec field exactly — preserving the divergent case (operator wrote `set-metadata --key title --value "Foo"` separate from `set-title "Bar"`) where the override warning is a real signal. - Call the helper from walkPane before constructing SurfaceSpec. Description is unconditionally nil from capture today, so the description branch is a no-op for now; the symmetry is intentional for when capture starts promoting description into spec.description. Build: c11 scheme compiles clean against my WS3a commit. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…nifest id `c11 snapshot --all` keeps writing N independent per-workspace files and now ALSO writes a manifest at `~/.c11-snapshots/sets/<set_id>.json` listing the inner ids with set-level metadata (set id, capture time, c11 version, which workspace was selected). The new `WorkspaceSnapshotSetFile` envelope is a pure pointer file — each inner snapshot stays independently restorable through the existing `c11 restore <inner-id>` path; nothing is duplicated. `c11 restore <id>` is now polymorphic. The CLI probes `~/.c11-snapshots/sets/<id>.json` first; when that exists the request goes to the new `snapshot.restore_set` v2 method, which reads the manifest and runs each inner snapshot through `WorkspaceLayoutExecutor` in capture order, re-establishing the selected workspace at the end (subject to the socket focus policy). `--in-place` is rejected for set restores: a set creates several fresh workspaces and there is no single target to replace. Path-on-disk targets are classified by content (`set_id` + `snapshots` → manifest, `snapshot_id` + `plan` → single snapshot) and staged into the matching default location before the v2 call. `c11 list-snapshots` grows two flags: `--sets` switches to the manifest table (SET_ID, CREATED_AT, COUNT, C11_VERSION); `--all` prints both tables back-to-back. The default output is unchanged. New v2 methods: `snapshot.restore_set`, `snapshot.list_sets`. The `sets/` subdirectory is naturally excluded from per-snapshot enumeration (the existing `enumerate(directory:source:)` is non-recursive). New unit test rounds the manifest envelope through Codable, asserts snake_case wire keys, and confirms `selected: false` is wire-omitted on the common case. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
BenevolentFutures
added a commit
that referenced
this pull request
May 5, 2026
Patch release covering two PRs landed since v0.45.1: - #121: socket-handler self-deadlock fix (EXC_BREAKPOINT crash, 4× on 2026-05-04). Routes 99 v1 handlers in TerminalController.swift and 12 in ThemeSocketMethods.swift through v2MainSync / Self.mainSync, which short-circuit when already on main, so they're correct under both pre- and post-C11-26 dispatcher paths. - #118: CMUX-37 final push. Workspace blueprint markdown writer, snapshot --all manifest envelope with polymorphic restore, two-level workspace --help dispatch, CLI honors C11_SOCKET (legacy CMUX_SOCKET still works), redundant restore failure: lines reclassified as info.
BenevolentFutures
added a commit
that referenced
this pull request
May 5, 2026
Lattice ticket task_01KPMTEY4WGECM9MNZ4XARN7Y6 transitions to done after PR #118 ("CMUX-37 final push: close five 2026-05-03 smoke-test gaps") shipped on 2026-05-04. The orchestrator never recorded the merge on the ticket; this catches the bookkeeping up. Archive notes/archive/cmux-37/ preserves five generations of trident review packs (2026-04-24 through 2026-05-04) that drove the ticket and were unique to the cmux-37/* worktrees. Also archives the orphan C11-14 "CMUX-37 Phase 1 follow-up" task record from the cmux-37-phase1 worktree — its work shipped via PR #78 but the Lattice file never reconciled with main, and the C11-14 short_id has since been reassigned to a different ticket. Re-importing it would collide; preserved here as historical record instead. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes the five gaps surfaced by the 2026-05-03 smoke-test of CMUX-37 (
/tmp/cmux-37-smoke-report.md). Phases 0 to 5 already landed via PRs #75, #77, #78, #79; this is the final close-out so the ticket can move review to done.Workstreams (9 commits, 5 substantive + 2 housekeeping)
W1: blueprint markdown parser/writer, default to
~/.config/c11/be80a504blueprint markdown parser + writer7911a41ec11 directory + markdown default; legacy paths still readW2:
snapshot --allwrites a manifest envelope,restorepolymorphic on idaea6eaa8snapshot manifest on --all; restore polymorphic on manifest idW3: silence bogus
failure:lines on clean restore (metadata_override + seed terminal cwd)8fb86dd7capture: drop redundant title metadata3629b310cli: classify expected restore diagnostics as infoW4:
c11 workspace <sub> --helptwo-level dispatcha30e6b8cworkspace --help routingW5: CLI honors
C11_SOCKETd0d85f42cli: honor C11_SOCKET; log auto-discovery to stderrHousekeeping
314f4687refresh plan: five-workstream close-out6c77018bcapture orchestrator handoff plan + lattice stateDiff scope
16 files, +2843/-891. Mostly Swift sources under
Sources/Workspace*plus matching tests inc11Tests/.Test plan
cmux-37/final-push/tmp/cmux-37-smoke-report.md:failure:lines on a clean restoresnapshot --all: one manifest plus inner snapshots;restore <set-id>rebuilds all workspaces~/.config/c11/blueprints/c11 workspace new --helpandc11 workspace export-blueprint --helproute correctlyC11_SOCKET=...is honored by the CLI; legacyCMUX_SOCKETstill works🤖 Generated with Claude Code