Skip to content

Consolidation + de-privatization for public release (stacked on #7)#8

Merged
Szowesgad merged 125 commits into
fix/pr6-audit-fixesfrom
chore/deprivatize
Jul 10, 2026
Merged

Consolidation + de-privatization for public release (stacked on #7)#8
Szowesgad merged 125 commits into
fix/pr6-audit-fixesfrom
chore/deprivatize

Conversation

@m-szymanska

@m-szymanska m-szymanska commented Jun 29, 2026

Copy link
Copy Markdown

Consolidation + pre-public de-privatization (stacked on #7)

Scope correction (this body was stale): this branch grew well beyond the original 4-commit naming scrub. It is now a consolidation of ~68 commits (+4845/−718, 75 files) carrying both feature work and the full de-privatization hygiene. Stacked on fix/pr6-audit-fixes (#7); retarget to main once #7 merges. Do not merge automatically — depends on #7.

Feature blocks (on top of #7)

  • Editor stability — typewriter steady on same-line typing; per-keystroke viewport/find-highlight fixes (block vanish/reflow); gutter anti-ghosting; async viewport sync; save-on-close flush before teardown.
  • Window/tab lifecycle — durable empty state; never reap the last/visible window; reopen launcher on last close; shared tabbing identifier (Merge All Windows); default click opens in place vs explicit tab gesture.
  • Multi-root workspace — per-root index keying; N-root cache/identity/fingerprint (N=1 identical); cold-path trace breadcrumbs.
  • Preview themes — open-licensed reading-surface skins (Vercel/Themeable/Glass/Notion/Vista/MLA/Jamstatic) + editor status bar.
  • Agent dispatch UI — sheet-based picker (run_id confirm, no double-fire); full fleet seeding; Agent→Path→workflow popover with Terminal launch.
  • Sidebar / release / find — Open Files mirrors the live tab group; release-local --no-dmg; find-bar fixes; mic/tafla permission + cold-start launcher hardening.

De-privatization (complete — text + binary, certified clean)

  • camelCase brand → Vetcoders/Vibecrafted; personal names removed; home paths scrubbed (/Users/maciejgad/ → neutral in test fixtures).
  • FFI vendor scripts: dropped $HOME/vc-workspace/LibraxisAI default (operator-machine fingerprint) → neutral default + VISTA_KERNEL_ROOT override.
  • Vendored dylib re-vendored with --remap-path-prefix — removed 1007 builder-home strings baked into __TEXT by rustc panic-location (strip could not). Verified 0 builder-username occurrences in the binary.
  • fix(security): charset guard on agent/runID before Terminal injection.
  • Intentionally kept (not leaks): LibraxisAI (parent company / Licensor), Satoshi Iwaki heritage credit (original CSS kept), CodeScribe cross-repo vista-kernel path.

Before merge (operator)

🤖 Generated with Claude Code

m-szymanska and others added 4 commits June 28, 2026 17:56
Remove docs/specs/2026-05-22-pensieve-design.md — a frozen vc-scaffold
planning snapshot (dated filename, approved-for-implementation status,
personal author line, internal codenames). Internal/stale artifact that
should not ship in a public repo. No inbound links.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Collapse founder/agent names to vetcoders per brand naming rules and
remove a leaked dev home path:

- README/CONTRIBUTING/LEGACY: drop personal credit lines, fix camelCase
  VetCoders -> Vetcoders brand orthography.
- Tests: replace real home path /Users/maciejgad/ with /Users/tester/,
  generalise a code-comment name reference, neutralise a wikilink
  fixture target.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Drop the "Tailscale" infra fingerprint from the .gitignore comment
describing how internal docs sync between machines; keep the functional
rsync explanation intact.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Apply the lowercase brand convention (camelCase brand names do not exist):
VetCoders -> Vetcoders / vetcoders and CodeScribe -> codescribe across
prose, headings, LICENSE licensor, Info.plist copyright, the docs site
footer, and the BSL/agent docs. HTMLEmitterTests updated on both the
markdown input and the expected HTML assertion (test-coupled).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review

This pull request focuses on anonymizing personal names and normalizing the brand name 'VetCoders' to 'Vetcoders' or 'vetcoders' across documentation, tests, and configuration files, alongside removing an outdated design document. The review feedback consistently points out several instances where the brand name was left in lowercase ('vetcoders') and suggests capitalizing it as 'Vetcoders' to maintain uniform branding throughout the repository.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread CODE_OF_CONDUCT.md Outdated
## Enforcement

Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at VetCoders. All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident.
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at vetcoders. All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

The brand name is capitalized as Vetcoders in titles and copyright notices (e.g., # Vetcoders Code of Conduct), but here it is written in lowercase as vetcoders. To maintain consistent branding throughout the repository, especially for a public release, please capitalize it as Vetcoders.

Suggested change
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at vetcoders. All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident.
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at Vetcoders. All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident.

Comment thread CONTRIBUTING.md Outdated
Welcome to the 𝚅𝚒𝚋𝚎𝚌𝚛𝚊𝚏𝚝𝚎𝚍. forge.

We build software differently here at VetCoders. We value *product truth* over local elegance, and *runtime truth* over theoretical correctness. If you want to contribute, please understand our core stance.
We build software differently here at vetcoders. We value *product truth* over local elegance, and *runtime truth* over theoretical correctness. If you want to contribute, please understand our core stance.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

To ensure consistent brand capitalization across the public release, please capitalize vetcoders as Vetcoders.

Suggested change
We build software differently here at vetcoders. We value *product truth* over local elegance, and *runtime truth* over theoretical correctness. If you want to contribute, please understand our core stance.
We build software differently here at Vetcoders. We value *product truth* over local elegance, and *runtime truth* over theoretical correctness. If you want to contribute, please understand our core stance.

Comment thread README.md Outdated
Native macOS markdown writing app. File-first. Source-first.
Not Notion. Not Obsidian. Not an unwieldy monolith.
A beautiful, fast, local markdown *pisak* — crafted for Maciej and Monika, and anyone who appreciates the pure joy of typing.
A beautiful, fast, local markdown *pisak* — crafted for vetcoders, and anyone who appreciates the pure joy of typing.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

Please capitalize vetcoders to Vetcoders to maintain consistent branding across all documentation.

Suggested change
A beautiful, fast, local markdown *pisak* — crafted for vetcoders, and anyone who appreciates the pure joy of typing.
A beautiful, fast, local markdown *pisak* — crafted for Vetcoders, and anyone who appreciates the pure joy of typing.

Comment thread README.md Outdated

---
Created by Maciej (operator), Monika (vision), and Klaudiusz (synthesis). No newline at end of file
Created by vetcoders. No newline at end of file

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

Please capitalize vetcoders to Vetcoders for consistent brand representation.

Suggested change
Created by vetcoders.
Created by Vetcoders.

Comment thread SECURITY.md Outdated
## Reporting a Vulnerability

Security is a top priority for VetCoders. If you discover a security vulnerability within Pensieve, please report it via private email to `security@vetcoders.com` or use the GitHub Security Advisory feature.
Security is a top priority for vetcoders. If you discover a security vulnerability within Pensieve, please report it via private email to `security@vetcoders.com` or use the GitHub Security Advisory feature.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

Please capitalize vetcoders to Vetcoders to align with the brand normalization guidelines.

Suggested change
Security is a top priority for vetcoders. If you discover a security vulnerability within Pensieve, please report it via private email to `security@vetcoders.com` or use the GitHub Security Advisory feature.
Security is a top priority for Vetcoders. If you discover a security vulnerability within Pensieve, please report it via private email to `security@vetcoders.com` or use the GitHub Security Advisory feature.

m-szymanska and others added 3 commits June 30, 2026 07:06
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: dae2b8bd47

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread AGENTS.md Outdated
- "Doubt" w wyborze tool = anti-pattern. Albo loctree to znajdzie,
albo nie umie i wtedy hak + fallback.
- Sfabrykowane doctriny ("CodeScribe grep-first", "szybciej grepem",
- Sfabrykowane doctriny ("codescribe grep-first", "szybciej grepem",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Revert the inline doctrine edit

This change is inside the loctree doctrine block, but AGENTS.md says the “doctrine block above is operator-managed” and “should not be edited inline — use --revert + re-apply to refresh it.” Because this PR hand-edits that protected block, the managed scan process can overwrite it and the change violates the repo’s instructions; please revert this line or regenerate the block through the documented script.

Useful? React with 👍 / 👎.

Szowesgad and others added 21 commits June 30, 2026 07:42
- Introduce `DebugTrace` for runtime tracing of window and document flow issues, activated via the `PENSIEVE_TRACE=1` environment flag.
- Implement `DocumentWindowFactory` to create AppKit-backed document windows with proper lifecycle handling, tab management, and SwiftUI hosting.
- Prevent retain cycles and window leaks during tab closure with deferred cleanups.
- Add support for bridging SwiftUI toolbars and titles into AppKit windows on macOS 14+.
Cargo bakes the builder's absolute checkout path into the dylib id, so
binaries linked against it fail dlopen on every other machine -- CI
included; swift test could never pass on a runner. Repoint the vendored
binary to @rpath (Package.swift already adds the matching -rpath) and
make build-ffi.sh apply the same fix on every future sync.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ocuments

With in-window routing a window swaps its displayed document constantly,
but windowsByDocumentID kept every document the window had EVER shown.
Open in New Window for any previously-viewed document then hit the
existing-window path and silently activated the current window instead
of spawning one. A window hosts exactly one document: attach now drops
the window's other mappings. The context menu also hides Open in New
Window for the currently selected document, where one-window-per-
document makes the gesture a designed no-op.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…Mappings decl

Commit 8abd0d1 landed two identical declarations of
releaseStaleDocumentMappings(for:keeping:) in DocumentWindowRegistry,
breaking the release build with "invalid redeclaration" and failing
make install-app. The two bodies are identical except the first carries
the DebugTrace.log line from e986484; the second is a stale duplicate
(likely a merge/rebase artifact). Remove the duplicate, keep the traced
version. All three callers (lines 144/206/234) bind to the survivor;
swift build is green again.

Authored-By: claude <agents@vetcoders.io>
session_id: 7514fc80-6f90-4f9c-bda4-c1343e53e0b3
date: 2026-06-11T12:04:26 MST
runtime: claude
…bedding qube-ffi dylib

make release died with "Filesize limit exceeded" / Error 153 (SIGXFSZ) at the
cp that embeds the vendored qube-ffi dylib into the .app's Frameworks dir. The
launching shell carried an inherited ulimit -f of 65336 blk (31 MiB); the
dylib is ~68 MiB, so cp wrote past the cap and the kernel killed it with
SIGXFSZ — after swift build, 341 tests, signing identity, and bundle layout
had all succeeded. Same SIGXFSZ class as vibecrafted 5c6c439. Lift
ulimit -f unlimited once near the top of the script so the whole build's
process tree is uncapped. Proven: subshell repro at cap 65336 → cp exit 153;
with the lift → exit 0, full 68M copied.

Authored-By: claude <agents@vetcoders.io>
session_id: 7514fc80-6f90-4f9c-bda4-c1343e53e0b3
date: 2026-06-11T13:53:47 MST
runtime: claude
…ithout rebuilding the .app

make release failed at the DMG step on ENOSPC after the .app was already
built, signed, notarized and stapled. Re-running the full pipeline to retry
only the DMG wastefully rebuilds and re-submits the .app to Apple for a
second notarization. Add --dmg-only: it reuses the existing
dist/Pensieve.app (guarded — must exist and pass codesign --verify --strict),
skips the build/sign/notarize-app block, and runs only the DMG
create/sign/notarize/staple section. The whole-script ulimit -f lift (added
earlier this session) covers the hdiutil copy of the ~68 MiB dylib. Pairs
with the fix that the .app, signed+notarized+stapled, must be copied with a
lifted ulimit -f or it truncates on SIGXFSZ — same root as the build cp.

Authored-By: claude <agents@vetcoders.io>
session_id: 7514fc80-6f90-4f9c-bda4-c1343e53e0b3
date: 2026-06-11T14:06:50 MST
runtime: claude
…packaging of built artifacts

make release DMG_ONLY=1 does not work: the Makefile release target doesn't
forward an env var into build-release.sh, and the script takes a --dmg-only
flag, not a variable. Add a first-class 'make notarize' target that wraps
build-release.sh --dmg-only. It deliberately carries NO 'gates' prerequisite
(unlike release/release-local/release-clean) because it operates exclusively
on the already-built, signed, notarized + stapled dist/Pensieve.app: it only
packages, signs, notarizes and staples the DMG around it. The script's
--dmg-only guard still verifies the .app exists and passes
codesign --verify --strict before packaging.

Authored-By: claude <agents@vetcoders.io>
session_id: 7514fc80-6f90-4f9c-bda4-c1343e53e0b3
date: 2026-06-11T14:21:33 MST
runtime: claude
…clear yellow highlights

Three find-bar UX gaps the operator hit, all in the already-present find
machinery (search + nav + replace existed; the surface even tracked
findMatches/activeFindMatchIndex — it just never reached the UI, and the
shading was barely visible):

1. ⌘F now lands focus in the query field. The bar mounts on demand, so a
   fresh NSSearchField must claim first responder when it appears; the
   focusToken alone is swallowed by the freshly-built coordinator. Added a
   focusOnAppear path (deferred makeFirstResponder) and set it on the find
   field only (Replace keeps its own focus).
2. Match count is plumbed surface -> AppState (findMatchCount /
   findActiveMatchIndex, deduped to avoid re-render loops) and rendered in
   the bar: "3 of 12" / "12 found" / "No results".
3. Find highlights now read as a clear yellow wash (active match orange)
   instead of an accent tint at 0.18 alpha that was easy to miss.

Verified: swift build clean; swift test 341/341 pass (incl. find-nav
coordinator tests). GUI behavior (focus jump, yellow shade, live count) is
visual — needs an operator eyeball in the running app.

Authored-By: claude <agents@vetcoders.io>
session_id: ae21346a-dfc6-4515-8fcf-77ba4168b96b
date: 2026-06-13T15:42:33 MST
runtime: interactive
Generalize Vibecrafted dispatch to workflow/agent/prompt-or-file payloads and expose the curated workflow list through AppController.

Add a toolbar Dispatch to Agent menu for the active document and sidebar context-menu dispatch for per-file workflows.

Verify argv assembly for file payloads and keep transcription dispatch routed through the generalized launcher.

Authored-By: codex

Session-Id: cb7eaa63-aee0-4649-aa9a-82e4b1655393

Date: 2026-06-13

Runtime: headless
The preview rendered a leading YAML frontmatter block as body content (the
closing fence even became a setext heading). Strip a document-leading YAML
frontmatter block before rendering — Jekyll/Hugo/Obsidian/gray-matter
convention — so writing skills (SKILL.md name/description) previews clean.

Only a fence that is the VERY FIRST line and has a matching close counts; a
delimiter anywhere else stays a real thematic break / setext heading (correct
CommonMark), and an unclosed opening fence is left as an hr. Strip lives in
MarkdownRenderer.render (preview-only path; the editor still shows raw text).
8 unit tests incl. mid-doc, BOM, no-close, whole-doc edges. Full suite 350/350.

Authored-By: claude <agents@vetcoders.io>
session_id: 91779397-45e4-48f1-a1bd-93886f2ea483
date: 2026-06-13T21:04:20 MST
runtime: interactive
…very keystroke

In Focus mode (typewriterScrollEnabled), centerCaretLineIfNeeded() re-scrolled the
editor to re-center the caret line on EVERY textDidChange — including same-line
typing where the caret's vertical position (and thus the scroll target) never
moved. The unconditional scroll(to:) + reflectScrolledClipView made the document
visibly jump on each typed character. Add the missing "IfNeeded" guard: skip the
re-center when targetY already matches the current scroll offset (within 0.5pt);
a real vertical caret move (new line, wrap) still re-centers as before.

Authored-By: claude <agents@vetcoders.io>
session_id: 35f18c86-a482-4802-a188-c62c9bc1ecbb
date: 2026-06-14T02:51:16 MST
runtime: interactive
… uv-core vibecrafted

The toolbar "Dispatch to Agent" menu was effectively a no-op: resolveExecutablePath
preferred the legacy bash command-deck (~/.local/share/vibecrafted/.../scripts/vibecrafted),
which targets an interactive terminal/zellij session and produces no usable run when
spawned from this GUI Process (no TTY). Prefer the canonical ~/.local/bin/vibecrafted
(uv-core) entry, which is headless-friendly and prints the parseable launch receipt
(run_id / report path) that AgentDispatchMetadata.parse already expects. Args are
unchanged ([workflow, agent, --file|--prompt, value]) and match the uv-core surface.

Authored-By: claude <agents@vetcoders.io>
session_id: 35f18c86-a482-4802-a188-c62c9bc1ecbb
date: 2026-06-14T20:02:51 PDT
runtime: interactive
…tops bleeding the document

The find bar used a flat controlBackgroundColor fill that let the document text show
through behind the search field. Switch to the native .bar material (Safari / TextEdit
find-bar look) — an opaque, blurred backing that reads as a real macOS find bar.

Authored-By: claude <agents@vetcoders.io>
session_id: 35f18c86-a482-4802-a188-c62c9bc1ecbb
date: 2026-06-14T20:02:51 PDT
runtime: interactive
…oolbar (experimental)

EXPERIMENTAL native-look pass: the editor scroll view's SwiftUI top safe-area inset
held the document text below the toolbar while the line-number ruler already ran under
it. .ignoresSafeArea(.container, edges: .top) lets the text slide under the translucent
unified toolbar (Finder look). Unverified visually (headless); revert this commit alone
if the find bar overlaps the toolbar when open.

Authored-By: claude <agents@vetcoders.io>
session_id: 35f18c86-a482-4802-a188-c62c9bc1ecbb
date: 2026-06-14T20:15:02 PDT
runtime: interactive
…e flicker in normal/split mode

Two coupled symptoms, one root: NSClipView copy-on-scroll. (1) The line-number
NSRulerView kept a stale copy of the numbers at the old offset while drawing new ones
on top — the doubled/ghosted gutter. (2) updateNSView re-pinned the viewport on EVERY
keystroke via scroll(to:)+reflectScrolledClipView even when nothing moved, posting a
redundant bounds-change → gutter redraw → the text flicker in normal/split mode.

Fixes:
- scrollView.contentView.copiesOnScroll = false → full clean redraw on scroll (no ghost).
- guard the viewport re-pin to only fire when surface.update() actually drifted the origin.

Authored-By: claude <agents@vetcoders.io>
session_id: 35f18c86-a482-4802-a188-c62c9bc1ecbb
date: 2026-06-14T20:16:31 PDT
runtime: interactive
… live discovery + Terminal launch

Replaces the toolbar ✈ workflow-only menu with a configured dispatch popover:
- Agent picker populated dynamically from `vibecrafted doctor` (agent-stream:<name>),
  not a hardcoded "codex".
- Path picker = WHERE the agent runs (--root), default = workspace folder, NSOpenPanel
  to change. The PLAN is always the currently-open document (--file).
- Workflow picker from the vibecrafted deck.
- Summary + explicit Dispatch (confirmation) before anything fires.
- Launches into a visible Terminal (`vibecrafted <wf> <agent> --file <doc> --root <where>`)
  so the run is observable; Terminal takes focus, then focus returns to Pensieve after ~10s.

The sidebar per-file dispatch keeps the existing headless path (now also routed to uv-core).

Authored-By: claude <agents@vetcoders.io>
session_id: 35f18c86-a482-4802-a188-c62c9bc1ecbb
date: 2026-06-14T23:03:24 PDT
runtime: interactive
…iscovery test + swift-format pass

- Gutter ghosting: copiesOnScroll=false (24d1b68) was a NO-OP — NSClipView.copiesOnScroll
  is deprecated since macOS 11 ("setting this property has no effect"), and it emitted a
  deprecation warning. Replace with the real lever: LineNumberGutter overrides
  wantsDefaultClipping=false, so drawHashMarksAndLabels fills + repaints the FULL ruler
  bounds instead of being clipped to the scroll's minimal dirty rect — no stale numbers.
- discovery: extract AppController.agentStreamNames(in:) as a pure, testable function;
  add AgentDiscoveryTests (order, dedup, empty) — 353 tests green.
- swift-format pass over all files touched this session; my files now lint clean.

Authored-By: claude <agents@vetcoders.io>
session_id: 35f18c86-a482-4802-a188-c62c9bc1ecbb
date: 2026-06-14T23:22:12 PDT
runtime: interactive
…roup (registry-sourced)

Each tab is a separate DocumentWindow with its own per-window AppState, so the
sidebar "Open Files" only showed the current window's working set, never the full
tab chain (operator: "separate life ongoing"). Make the window registry the single
source of truth:

- DocumentWindowRegistry is now ObservableObject with @published openTabDocumentIDs,
  kept in lockstep with windowsByDocumentID via recordOpenDocument/forgetOpenDocument
  (both contains-guarded) at open/attach/dead-drop/stale-release.
- Sidebar reads it via @ObservedObject; openTabDocuments resolves each URL through the
  shared store, falling back to a synthesized ad-hoc ref so an evicted-but-open tab
  never silently drops; .onMove removed (tab order is AppKit's).
- Window-agnostic close reconciliation: a process-wide willCloseNotification observer
  calls reconcileClosedWindow (forget WITHOUT tombstone) so closing a state-restored
  WindowGroup scene tab (no onClose hook) still drops its row; tombstoning stays in
  DocumentWindow.onClose (never-reused factory windows).
- Close/Clear route through the registry (close the tab) and keep the dirty-session
  save guard (untitled Save/Discard/Cancel, existing force-save) so the sidebar close
  never loses unsaved edits; Clear-button gate + empty-state share the registry source;
  Close offered for all tabs; openDocumentWindow resolves evicted-but-open tabs so their
  clicks activate; dead reorderOpenFiles removed.

Designed + adversarially verified across 3 workflow rounds against the P0 window/tab
invariants (re-entrancy, deferred teardown, phantom-tab resurrection, modal gating,
leaks). 353 tests green, swift-format clean.

Authored-By: claude <agents@vetcoders.io>
session_id: 35f18c86-a482-4802-a188-c62c9bc1ecbb
date: 2026-06-15T00:49:59 PDT
runtime: interactive
…survives, run_id confirms, no double-fire

The toolbar ✈ dispatch popover lost the chosen folder (a transient popover was
dismissed by NSOpenPanel.runModal) and gave no signal whether a run fired. Rework:
- ContentView .popover → .sheet; DispatchPopover runs the folder chooser via
  NSOpenPanel.beginSheetModal(for: the sheet's window) — a WindowReader resolves
  that window, runModal is only a pre-attach fallback — so the sheet stays mounted
  and the chosen rootURL persists and shows in the summary.
- Dispatch is headless via the canonical uv-core launcher
  (AppController.dispatchOpenDocument async → DocumentDispatchOutcome with parseable
  run_id); a Phase machine shows Dispatching… → "Dispatched ✓ run: <id>" with Reveal
  report + Observe in Terminal (user-triggered) + Done, so the user always knows it
  fired. Removed the old fire-and-forget Terminal launch + 10s focus-return.
- Synchronous re-entry guard on the Dispatch button so one intent never spawns two runs.

Designed + adversarially verified (sheet/panel survival, concurrency, re-entrancy).
353 tests green, swift-format clean.

Authored-By: claude <agents@vetcoders.io>
session_id: 35f18c86-a482-4802-a188-c62c9bc1ecbb
date: 2026-06-15T01:17:42 PDT
runtime: interactive
…oise in two files

swift-format lint flagged 5 hand-written residual warnings: a single-element
trailing comma in WorkspaceMetadataStore.swift (TrailingComma) and a 4-line
over-indented multiline string literal in IndexDatabaseBacklinksTests.swift
(Indentation). Applied swift-format format -i to both; both now lint clean.
The test's multiline string VALUE is unchanged — swift-format shifted the
closing delimiter and the content together, so the stripped string is identical.

Authored-By: claude <agents@vetcoders.io>
session_id: 85b77214-2fa1-4ad1-8386-24c0ec9f35d6
date: 2026-06-15T03:12:36 PDT
runtime: interactive
… edit before window/tab teardown

Closing a document window/tab within the 1.5s autosave debounce silently
dropped the unsaved edit: the red close button, the tab "×", the sidebar
"Close from Open Files", and ⌘W falling through to a native window close all
tore the window (and its per-window AppState) down before the scheduled save
fired. There was no windowShouldClose / save-on-close hook for document
windows — a real data-safety gap surfaced by verify.

The fix flushes synchronously at the window-lifecycle level:
- DocumentStore.savePendingChangesOnClose(appState:) mirrors the autosave
  closure exactly (titled -> write to disk, untitled -> recovery draft) but
  runs NOW and cancels the pending timer; no blocking prompt (the window is
  already closing); clean buffers are a no-op.
- AppController.savePendingChangesOnClose() routes to the current window's
  session.
- DocumentWindowRootView (the single root shared by factory-built document
  tabs AND state-restored WindowGroup scenes) observes
  NSWindow.willCloseNotification filtered to its own currentWindow, so the
  guard is app-wide and per-window without touching the SwiftUI-owned delegate.

Editor text already syncs to documentSession.text per keystroke, so the flush
writes the latest content — verified by 3 tests: titled doc reaches disk under
a 60s debounce only via the close-flush, untitled persists a recovery draft,
and a clean buffer triggers zero writes.

Authored-By: claude <agents@vetcoders.io>
session_id: c4cc9660-3b8b-4f95-a36e-4150a730e143
date: 2026-06-15T03:19:34 PDT
runtime: interactive
Szowesgad added 29 commits July 5, 2026 18:53
…cycle + completion contract guards

Marbles L3: sealed the uncommitted trash-flow cut sitting in the tree and
guarded its async tail. AppController.moveItemToTrash now closes the selected
buffer and every open document tab whose ID is the trashed URL or a descendant
BEFORE NSWorkspace.recycle fires, through injectable seams
(AppController.documentWindowRegistry, FolderManager.recycleItems) so the flow
is testable without touching the real Trash. Added WorkspaceTrashTests covering
open-file, closed-file and folder-descendant trash, plus two new completion
guards the tree was missing: recycle success removes the openFiles reference,
recycle failure surfaces lastError and keeps the reference because the file is
still on disk.

Gate: pass
Tests: swift build; swift test --filter 'WorkspaceTrashTests|WorkspaceOpenActivityTests' (8/8); make lint
Regressions: 0

Authored-By: claude <agents@vetcoders.io>
session_id: e182bcc2-e1f0-4173-9ede-c2cfd72ce04c
time: 2026-07-05T18:52:55-07:00
runtime: claude
Operator-driven version bump for the appstore-v1 ship tail; consumed by
scripts/build-release.sh (APP_VERSION -> Info.plist marketing version).

Authored-By: claude <agents@vetcoders.io>
session_id: 423065c1-dd92-4b7e-a078-d544c5e86a46
time: 2026-07-05T19:42:35-07:00
runtime: claude
…menu; floating bar clamped out of chrome

Cut 5-1R after the operator bounce (18:20/18:47 evidence): the raw B/S/I/quote/
code/link/list cluster leaves the titlebar and lives behind one Aa (textformat)
Menu in the principal slot that iterates MarkdownFormat.allCases — the same
single source of truth the floating selection bar and editor context menu
render, so the surfaces cannot drift. The rich-markdown toggle (the old
misleading bare Aa button) relocates into that menu. Trailing side reduced to
daily drivers share/appearance/reload (+dispatch in ContentView); tafla,
scroll-sync and auto-reload fold into one ellipsis overflow menu. The floating
formatter now clamps to visibleRect ∩ window.contentLayoutRect (chrome truth):
static accessoryOrigin/clampedAccessoryOrigin are pure and tested, re-pinned on
every bounds/layout tick and during grip drags, so the bar pins at the toolbar
edge instead of ghosting under the translucent chrome. Regression suite
EditorToolbeltFloatingClampTests pins the seam; EditorToolbeltTests pins the
shared allCases order.

Authored-By: claude <agents@vetcoders.io>
session_id: 27e19f58-fb6b-4e94-aaea-c75305a25dc3
time: 2026-07-05T19:53:50-07:00
runtime: claude
…nt-seam suite swept into the lane

Concurrent shared work landed mid-cut: VoiceOver accessibilityLabels on the
toolbelt buttons/menus and FormattingAccessoryPlacementTests — 10 tests over
accessoryOrigin/clampedAccessoryOrigin (flipped + unflipped + degenerate) and
a real fullSizeContentView NSWindow proving accessoryAllowedRect excludes the
titlebar band. Verified green together with the Cut 5-1R suites (48/48).

Authored-By: claude <agents@vetcoders.io>
session_id: 27e19f58-fb6b-4e94-aaea-c75305a25dc3
time: 2026-07-05T19:55:34-07:00
runtime: claude
…to EditorToolbeltTests

Peer consolidation swept into the lane: FormattingAccessoryPlacementTests.swift
folds into EditorToolbeltTests.swift as FormattingAccessoryChromeTruthTests —
unflipped branches, full origin→clamp pin path, and the real
fullSizeContentView window proof for accessoryAllowedRect — deduped against
EditorToolbeltFloatingClampTests. Extended filter green 43/43.

Authored-By: claude <agents@vetcoders.io>
session_id: 27e19f58-fb6b-4e94-aaea-c75305a25dc3
time: 2026-07-05T19:57:22-07:00
runtime: claude
…ar seam + toolbelt a11y labels

Marbles L1 on the Cut 5-1R surface: the pure clamp suite pinned the flipped
geometry but left three blind spots — the unflipped accessoryOrigin branch,
the full origin→clamp pin path, and accessoryAllowedRect against a REAL
window.contentLayoutRect under .fullSizeContentView (the actual chrome truth
the pure tests only model). FormattingAccessoryChromeTruthTests covers all
three. The image-only toolbar controls (share, appearance, reload, Aa edit
menu, overflow) also gain explicit accessibilityLabel: VoiceOver had no
accessible name for them, only tooltips and identifiers.

Gate: pass
Tests: swift test --filter 'EditorToolbelt|FormattingAccessory' (19 green), make lint clean
Regressions: 0

Authored-By: claude <agents@vetcoders.io>
session_id: 42efe5dc-9c8f-4990-8e61-e98feace15f4
time: 2026-07-05T19:57:47-07:00
runtime: claude
…d from the vendored banner

Polarize L2 cycle-2 cut, continuing L1's 'version speaks once' axis onto
component versions. The Mermaid version claim had two hand-written
producers that silently outlive an upgrade of the vendored runtime:
the Info.plist template (with an explicit test exemption hiding it) and
a hardcoded literal in scripts/build-release.sh:270. Now the banner of
mermaid.min.js (line 1) is the ONLY producer: the release script extracts
the version at stamp time and dies hard when extraction fails; the
template drops to the 0.0.0 placeholder like every other component; the
placeholder test loses its Mermaid exemption; and a new guard pins the
extraction contract (banner must carry 'Mermaid v<x.y.z>').

Gates: swift build green, swift test --filter
'BuildIdentityTests|PreviewPipelineTests' 21/21 green, make lint green,
bash -n + shellcheck -S warning clean, sed extraction verified against
the real vendored file (yields 11.15.0, byte-identical to the removed
literal).

Authored-By: claude <agents@vetcoders.io>
session_id: 6c0285e5-588c-4cda-9058-ece881adc796
time: 2026-07-05T20:16:49-07:00
runtime: claude
Add the 0.3.0 release note, source-trial install path, and social/crawler metadata for the public representation surface.

This stays local-lane honest: MAS submission, signing identities, push, and LFS/provenance decisions remain operator-gated.

Authored-By: codex <agents@vetcoders.io>

session_id: ce64cf14-7eb4-4eed-b6b9-d373672262a2

time: 2026-07-06T01:15:58-07:00

runtime: codex
Orphaned claude-marbles lane left the directory-routing fix in the Living Tree without a commit after the 2026-07-06 spend-limit stop.

Codex verified the full diff, Loctree slice and literal context, swift build, the requested filtered tests, and make lint, then committed the existing fix as the routing unit.

Directory URLs entering openFile(url:) now dispatch through openFolder(url:) before document registry and markdown rejection so Finder, Dock drop, and open -a workspace opens do not surface unsupported-file errors.

Authored-By: codex <agents@vetcoders.io>

session_id: 232dc134-5b70-4370-9773-33f702af911d

time: 2026-07-06T01:48:45-07:00

runtime: codex
…downFormat

Orphaned claude-marbles lane left this formatter-completeness latch in the Living Tree beside the directory-routing fix after the 2026-07-06 spend-limit stop.

Codex verified the full diff, Loctree context, swift build, the requested filtered tests, and make lint, then committed the existing test-only latch as a separate unit.

The wrapper-string expectations now assert parity with MarkdownFormat.allCases so future enum additions force an explicit Format-menu coverage decision.

Authored-By: codex <agents@vetcoders.io>

session_id: 232dc134-5b70-4370-9773-33f702af911d

time: 2026-07-06T01:49:06-07:00

runtime: codex
Move contextual wrapping-toggle semantics into MarkdownFormatter.formatSelection so shared toolbar, menu, and floating-bar paths stop double-wrapping selections that already sit inside bold, italic, strike, or code spans.

Selections exactly covering a wrapping span now unwrap the span. Selections inside the span content also unwrap the whole span. Partially overlapping selections no-op because the requested toggle crosses delimiter boundaries and preserving Markdown structure is safer than producing malformed mixed markup.

EditorView now applies the formatter's explicit edit range/replacement instead of wrapping the selected substring directly. EditorToolbelt and FloatingFormatBar UI surfaces are untouched.

Verified: cd Pensieve && swift build

Verified: cd Pensieve && swift test --filter 'MarkdownFormatter|EditorToolbelt'

Verified: make lint

Authored-By: codex <agents@vetcoders.io>

session_id: 07d5cca5-2a56-4e3c-a953-ec9d3d99ee9a

time: 2026-07-06T02:05:59-07:00

runtime: codex
Move preview heading sizing into appearanceCSS so vendored flavor px rules cannot flatten H1-H6 when --vc-font-size grows.

Set the shared heading rhythm to em-based sizes, 1.25 line-height, and relative margins. Raise Vercel headings to 700 for dark-surface readability; leave Vista at its existing 600 overlay because the contract allows conscious skin overrides at 600+ and this cut diagnosed Vercel specifically.

Add CSS string coverage for default, vercel, and paper skins, including 16px/24px body-font checks that keep heading scale in em units.

Vibecrafted-Trail: cut-7-4

Owner-Agent: codex/vc-ownership

Verification: swift build; swift test --filter 'Preview|DocumentExport'; make lint; semgrep --config auto --quiet touched files

Authored-By: codex <agents@vetcoders.io>

session_id: 019f36fd-8c78-7c21-9050-156288805390

time: 2026-07-06T04:02:26-07:00

runtime: terminal
Replace the Aa dropdown menu with an inline horizontal formatting toolbelt in the titlebar. The row keeps MarkdownFormat.allCases as the single action source, routes every format through controller.applyMarkdownFormat, and keeps Rich Markdown as the final toolbar toggle.

State is per-window chrome state owned by ContentView and resets on launch and when the editable buffer identity changes, so the expansion does not persist across documents.

Gates:
- cd Pensieve && swift build
- cd Pensieve && swift test --filter 'Toolbelt|EditorToolbelt'
- make lint

Authored-By: codex <agents@vetcoders.io>
session_id: 77e30457-3190-481a-9a07-ad142acbb695
time: 2026-07-08T20:47:22-07:00
runtime: codex
Non-markdown preview requests now render escaped preformatted text instead of entering the markdown renderer, while known markdown extensions keep the existing HTML path. Shebangs force the plain path so scripts with comment lines no longer become headings.

Tests cover .sh/.txt shebang plain output and the .md markdown regression path.

Gates:
- cd Pensieve && swift build
- cd Pensieve && swift test --filter 'Preview|DocumentExport'
- make lint
- wrapper visual: /private/tmp/PensieveCut76.app with /private/tmp/vibecrafted-rescue.txt screenshot inspected

Vibecrafted-Skill: vc-ownership
Vibecrafted-Cut: 7-6
Vibecrafted-Report: /Users/maciejgad/.vibecrafted/artifacts/vetcoders/pensieve/2026_0708/reports/ownership/2026-07-08_codex_cut-7-6_report.md

Authored-By: codex <agents@vetcoders.io>

session_id: 019f44f6-5594-7472-a79d-2fef68dd819f

time: 2026-07-08T20:59:12-07:00

runtime: terminal
Move titlebar glass height and chrome-clipped content rect truth into WindowChromeRecipe, then route PreviewTitlebarGlassController and editor accessory geometry through it. Pin preview top padding to the shared chrome recipe instead of responsive 3vw drift, reset the first preview child margin, and keep horizontal/bottom preview padding responsive.

Measurements: baseline split preview was about 24.5-25pt lower than editor; final split, resize, and fullscreen screenshots measure 0.5pt delta.

Verification: cd Pensieve && swift build; cd Pensieve && swift test --filter 'Preview|Chrome|Toolbelt'; make lint.

Vibecrafted-Run: owne-260708-204025-26000

Vibecrafted-Report: /Users/maciejgad/.vibecrafted/artifacts/vetcoders/pensieve/2026_0708/reports/ownership/2026-07-08_codex_cut-7-7_report.md

Authored-By: codex <agents@vetcoders.io>

session_id: 019f44f7-0012-7d50-abf8-cd83afc98ab7

time: 2026-07-08T21:03:27-07:00

runtime: terminal
Korekta polityki operatora po 7-5: keep the 911b77d horizontal formatting row, but remove the artificial expand/collapse policy around the Aa opener.

Format actions now render directly in the principal toolbar for editable source, split, and focus buffers. Preview-only and empty buffers hide the row. Rich Markdown becomes the last icon in the row, with no separate Aa opener, because fewer controls beats ceremony.

Verification: cd Pensieve && swift build; cd Pensieve && swift test --filter 'Toolbelt|EditorToolbelt'; make lint; wrapper-.app live proof with screenshots in /Users/maciejgad/.vibecrafted/artifacts/vetcoders/pensieve/2026_0708/live-proof/cut-7-5b.

Vibecrafted-Run: owne-260708-205330-46000

Vibecrafted-Report: /Users/maciejgad/.vibecrafted/artifacts/vetcoders/pensieve/2026_0708/reports/ownership/2026-07-08_codex_cut-7-5b_report.md

Authored-By: codex <agents@vetcoders.io>

session_id: f9e4d05c-2beb-42f8-a4c8-2f2730840d89

time: 2026-07-08T21:19:17-07:00

runtime: terminal
…uth over preview

Cut 7-9: over the preview pane the titlebar glass composited WKWebView's
default underPageBackgroundColor (a light warm system gray), so in dark
chrome the strip right of the split divider read as a lighter sepia-tinted
patch while the strip over the editor drank the neutral editor surface.
Root cause proven on a live wrapper-app rig: seam pixels measured
(44,42,39) warm over preview vs (30,30,30) flat over editor, position-
independent. Fix pins the under-page backing to the same surface truth the
editor feeds the chrome — textBackgroundColor — owned by WindowChromeRecipe
as titlebarGlassBackingColor and wired in PreviewWebView. Post-fix rig
measurements: strip uniform across the divider in dark (paper + code skins),
light mode unchanged, fullscreen bands identical both sides, editor/preview
content start delta 0.0pt (no 7-7 regression).

Verification: cd Pensieve && swift build; swift test --filter 'Preview|Chrome' (83/0); make lint.

Authored-By: claude <agents@vetcoders.io>
session_id: 8c3fe192-8ec7-4358-b642-cae3961f7f93
time: 2026-07-08T22:03:49-07:00
runtime: claude
Rework the macOS toolbar so the native title leads after the sidebar toggle, then share and dispatch sit before the always-on edit row, with modes, appearance, reload, and overflow trailing.

Keep dispatch presentation state and sheet ownership in ContentView while exposing the button through the toolbelt composition.

Add EditorToolbelt identifier-order tests for the new titlebar contract while preserving the MarkdownFormat.allCases guard.

Vibecrafted-Cut: 7-8

Vibecrafted-Report: ~/.vibecrafted/artifacts/vetcoders/pensieve/2026_0708/reports/ownership/2026-07-08_codex_cut-7-8_report.md

Verification: cd Pensieve && swift build

Verification: cd Pensieve && swift test --filter 'Toolbelt|EditorToolbelt'

Verification: make lint

Authored-By: codex <agents@vetcoders.io>

session_id: 019f4546-26f3-7b61-a998-8875271730b4

time: 2026-07-08T22:19:04-07:00

runtime: terminal
Separate share and dispatch into their own native principal toolbar group, then start the edit row with the existing Rich Markdown Aa toggle before the unchanged MarkdownFormat action order.

Gates: swift build; swift test --filter 'Toolbelt|EditorToolbelt'; make lint.

Authored-By: codex <agents@vetcoders.io>
session_id: 960421b1-4c64-42fc-9647-414940054d02
time: 2026-07-08T22:52:26-07:00
runtime: codex
…view the editor's glass glide

Cut 7-10: both panes now treat the chrome boundary the same way the
editor text view does (the post-7-7/7-9 pattern).

- LineNumberGutter clips fill + separator + numbers to
  WindowChromeRecipe.chromeClippedVisibleRect, so the ruler stops painting
  into the titlebar and across the window title; the anti-ghosting
  full-bounds repaint contract survives inside the clipped region
  (fast-scroll probe: no stale numbers).
- PreviewWebView zeroes WKWebView.obscuredContentInsets (macOS 26 public
  API) and re-asserts on window moves/layout, because WebKit re-adopts the
  safe area on window attach; the automatic pocket was the hard mid-glyph
  cut of scrolled preview content at the toolbelt. Body top padding now
  rides on the measured glass-height CSS var.
- PreviewTitlebarGlassController KVO-observes window.contentLayoutRect:
  SwiftUI attaches the toolbar after the preview joins the window, which
  changes the chrome height without any resize notification or web-view
  layout pass — the stale mid-construction measurement (88px vs real 52px)
  both parked the page start a band below the editor's and painted the 7-9
  light-mode underlay stripe, which is gone now.

Verified on a live wrapper build (5-1R rig): seam editor/preview 0.5 pt
(baseline -0.5), titlebar tint identical per-pixel both sides in dark and
light, gutter line/background end at the chrome edge, fullscreen clean,
120/120 filtered tests, make lint exit 0.

Authored-By: claude <agents@vetcoders.io>
session_id: 3b2e449f-9e04-4852-82b7-f243e5ebb90a
time: 2026-07-08T23:29:54-07:00
runtime: claude
… titlebar glass like the editor does

Cut 7-12 (follow-up to 7-10's glide parity): the strip above the preview
now dissolves gliding content the way the editor's scroll-edge effect
does, instead of letting sharp glyphs ride between the toolbelt buttons.

- Measured platform limit (probe app + live rig): CSS backdrop-filter is
  implemented via Core Animation backdrop capture, and CA refuses nested
  capture under the native titlebar glass — the identical rule blurs fine
  in a plain window and below the glass line, but under the glass it
  silently drops the whole effect including its mask. Native knob for
  WebKit's own scroll-edge blur stays private (7-10), and a non-zero
  obscuredContentInsets would re-introduce the hard-clip pocket. So the
  parity is the closest achievable approximation: a masked dissolve veil.
- appearanceCSS gains a fixed body::after band owned by the measured
  glass-height var, painted in the native glass backing colour and
  mask-faded (black 50% -> 0.35 residual at the band edge, hidden in the
  chrome seam), pointer-events: none, zero layout impact.
- The veil colour is plumbed by PreviewTitlebarGlassController alongside
  the height: WindowChromeRecipe.titlebarGlassBackingCSSColor resolves the
  one backing truth (textBackgroundColor) through the window's effective
  appearance to a concrete sRGB value, and viewDidChangeEffectiveAppearance
  re-plumbs on dark/light flips (same height, different colour — the guard
  tracks both).

Verified on a live wrapper build (5-1R rig): dark + light scrolled show
zero sharp glyphs in the band and class parity with the editor's fade;
at-rest band is per-pixel identical to the native backing (30,30,30 dark)
so the 7-9 stripe class stays dead, paper skin keeps its clean seam, glide
and content start unchanged. 90/90 filtered tests, make lint exit 0.

Authored-By: claude <agents@vetcoders.io>
session_id: 36a46027-2e59-4086-9fe3-a7b517d19949
time: 2026-07-09T01:02:26-07:00
runtime: claude
Widen the native principal spacer between the share/dispatch group and the editor formatting group so the toolbar reads as two distinct islands instead of one continuous edit strip.

Pin the spacer rhythm in EditorToolbeltTests while preserving the titlebar identifier order and MarkdownFormat allCases contract.

Gates: swift build; swift test --filter 'Toolbelt|EditorToolbelt'; make lint.

Authored-By: codex <agents@vetcoders.io>

session_id: d546f5cd-fbe7-4315-b11d-652500b0a7bc

time: 2026-07-09T01:05:00-07:00

runtime: codex
Move share and dispatch out of the principal toolbar strip and into their own automatic ToolbarItemGroup so macOS can render a separate native capsule next to the file title.

Replace the old spacer-width regression pin with an explicit toolbar island order contract covering share/dispatch, edit, and trailing clusters while preserving the existing identifier order and MarkdownFormat allCases guard.

Loctree-Recon: context atlas read; slice/impact EditorToolbelt; literal checks for ToolbarItemGroup/shareEditIslandGap/Color.clear

Gates: swift build; swift test --filter 'Toolbelt|EditorToolbelt'; make lint; semgrep changed Swift files

Screenshots: wide-open.png; narrow-open.png

Authored-By: codex <agents@vetcoders.io>

session_id: 019f45f2-cba3-76f2-9c3a-1b628cac2014

time: 2026-07-09T01:24:58-07:00

runtime: terminal
…ts across the whole glass band

Cut 7-12b (correction of 7-12's veil): the operator's screenshot showed
two defects in the dissolve band — a solid plate directly under the
toolbar buttons and the ghost zone hanging tens of pixels below them.
Row-probe measurement (5-1R rig, dark, split, scroll) found a single
root: the 7-12 mask ('black 50% -> 0.35') made the upper half of the
band 100% opaque, compressing all transmission into the bottom quarter.
The editor's native scroll-edge effect transmits ghosts across the WHOLE
band instead: ~9% at the window edge, ~15% mid-band, ~38% at 80%, ~55%
just above the chrome seam.

- Geometry hypothesis falsified by measurement: a diagnostic red-band
  build showed the veil footprint at exactly 0..52pt == frame minus
  contentLayoutRect, in BOTH window variants (direct file open and
  in-place open from a workspace root) — the veil never painted below
  the seam; no var fix needed.
- The mask is now a 4-stop gradient tracking the measured editor profile
  (alpha = 1 - transmission): 0.92 0%, 0.86 45%, 0.62 80%, 0.42 100% —
  no fully-opaque stop anywhere.
- Test pin updated and extended: the veil mask must never carry a 'black'
  stop (the solid-plate failure class), with the measurement rationale in
  a comment.

Verified pre-lock on the live rig (dark, scroll, max-over-5-scroll-offsets
row probe): preview transmission 0.08/0.12/0.15-0.25/0.41-0.55 vs editor
0.09/0.12/0.15-0.17/0.46-0.53 at matching band depths; ghosts start at the
same top edge in both panes, zero solid segment, zero dissolve below the
seam. At-rest dark band per-pixel uniform with the native backing (mean
30.0, var 0.0 outside static chrome). 90/90 filtered tests, make lint 0.
Light/sepia at-rest eyeball check blocked by session screen-lock mid-rig;
structural argument and follow-up noted in the cut report.

Authored-By: claude <agents@vetcoders.io>
session_id: 373cd437-c4cb-4dc0-a50c-6b9d73ad498d
time: 2026-07-09T01:53:03-07:00
runtime: claude
…ly owner of the veil mask profile

Polarize L1, cut A: the last chrome number living outside WindowChromeRecipe
was the preview veil's measured transmission profile (cut 7-12b row probe),
hardcoded twice — in PreviewWebView's appearanceCSS gradient and again as a
string literal in PreviewThemeTests. Move the stops into
WindowChromeRecipe.titlebarGlassVeilMaskStops with a CSS-emitting accessor;
the veil rule and its regression pins now both consume the Recipe, and new
WindowChromeRecipeTests pin the measured curve, the no-opaque-stop
constraint, and the downward-only dissolve. After this cut every chrome
number, colour, and profile has exactly one home.

Gates: swift build; swift test --filter 'Preview|Chrome|Toolbelt|Editor' (128 passed); make lint

Authored-By: claude <agents@vetcoders.io>
session_id: b1738e62-d46d-4c45-98c4-94a33e998270
time: 2026-07-09T12:58:29-07:00
runtime: claude
…oolbar layout truth

Polarize L1, cut B: the 7-14 island split relied on mixing an .automatic
share/dispatch group with a .principal edit island — a per-window system
heuristic that rendered the capsule beside the title on one rig and to the
RIGHT of the edit island on the operator's window (screenshot 12:41). Kill
both placement modes: every group now uses the default placement, so the
system renders TITLE, SHARE/DISPATCH, EDIT, MODES/THEMES strictly in
declaration order. Island separation comes from native ToolbarSpacer(.fixed)
behind #available(macOS 26.0, *) (the 7-14 SDK probe), and
ToolbarSpacer(.flexible) keeps the trailing cluster on the window edge.
Verified live on the installed /Applications build, dark + split: capsule
order matches the operator contract.

Gates: swift build; swift test --filter 'Preview|Chrome|Toolbelt|Editor' (128 passed); make lint

Authored-By: claude <agents@vetcoders.io>
session_id: b1738e62-d46d-4c45-98c4-94a33e998270
time: 2026-07-09T12:58:52-07:00
runtime: claude
…chrome geometry event

Polarize L2: the preview's chrome offset still had TWO competing runtime
truths. Pixel measurement on the operator-class window (evidence pair,
scrolled minus at-rest) showed the editor ghosting 3-7/255 through the whole
52pt glass band while the preview transmitted EXACTLY 0/255, with content
hard-clipped and WebKit's own fade at ~63-77pt and the page start parked
~50pt below the editor's — the double offset (WebKit pocket + CSS glass
var). Root cause: WebKit re-adopts obscuredContentInsets on chrome geometry
changes that give the container no layout pass (SwiftUI attaches the toolbar
after the preview joins the window, shrinking contentLayoutRect silently);
enforceFullBleedViewport only ran on layout()/viewDidMoveToWindow, and the
7-10 KVO channel refreshed the CSS var but never the insets. Fix: viewport
enforcement now rides the glass controller's geometry channel — every event
that funnels into apply() (attach, window notifications, contentLayoutRect
KVO, navigation finish) re-zeroes the pocket first, even when the script
guard short-circuits. Two new pins: controller runs the enforcer on every
apply; integration probe simulates the silent re-adoption and drives the
notification path back to zero insets.

Gates: swift build; swift test --filter 'Preview|Chrome|Toolbelt|Editor' (130 passed); make lint

Authored-By: claude <agents@vetcoders.io>
session_id: 35ec1bf7-4697-48fb-91d8-7bf1ab50a28b
time: 2026-07-09T13:19:35-07:00
runtime: claude
…S pocket on both panes

Polarize L3 verdict from rig measurement: WebKit's auto-adopted
obscuredContentInsets pocket renders the SAME native scroll-edge ghosts
as the editor band (2-12/255 vs 3-11/255), while zeroing it painted
scrolled text crisp through the window title (192/255). The pocket is
the one chrome truth on macOS 26 for both panes — AppKit automatic
content insets for the editor, the WebKit pocket for the preview.
Dead mechanisms removed: viewport zeroing (L2 enforcer), the masked
backing veil (7-12/7-12b) and its Recipe mask profile, the backing CSS
variable and its plumbing. The glass controller survives only as the
explicit pre-macOS-26 fallback for the CSS offset variable (0px default
on 26). Verified on operator-class rig windows: dark/light, split,
preview-only, tab bar (pocket auto-adapts 52->88pt), live resize.

Authored-By: claude <agents@vetcoders.io>
session_id: 45d7ed93-53cc-4206-97aa-af1d15a58f85
date: 2026-07-09T14:11:48 PDT
runtime: claude

time: 2026-07-09T14:11:54-07:00
…s into the Recipe

Polarize L4 residual cut: PreviewTitlebarGlassController carried two
static forwards (titlebarGlassHeight(frameHeight:contentLayoutHeight:)
and titlebarGlassHeight(for:)) that re-exported WindowChromeRecipe's
glass arithmetic under a second name, and PreviewThemeTests duplicated
WindowChromeRecipeTests' delta test byte-for-byte against that shim
(loct twins flagged the pair). One number, one name, one pinned test:
the controller now consumes WindowChromeRecipe.titlebarGlassHeight
directly and the duplicate test dies. No behavior change - the fallback
path evaluates the identical function.

Authored-By: claude <agents@vetcoders.io>
session_id: 5cf8dff1-04da-46e8-9857-9631fb5ef190
date: 2026-07-09T14:29:56 PDT
runtime: claude

time: 2026-07-09T14:29:56-07:00
@Szowesgad Szowesgad merged commit 2eb53ce into fix/pr6-audit-fixes Jul 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants