Skip to content

Sign in with ChatGPT + per-lane runtime truth + build provenance#61

Merged
div0-space merged 41 commits into
developfrom
chore/api-calls-hardening
Jul 12, 2026
Merged

Sign in with ChatGPT + per-lane runtime truth + build provenance#61
div0-space merged 41 commits into
developfrom
chore/api-calls-hardening

Conversation

@div0-space

Copy link
Copy Markdown
Contributor

What ships

Sign in with ChatGPT — end to end (operator-tested live: signed in, agent replies on account tokens):

  • b298ac9 OAuth client id as a promoted setting (LLM_OPENAI_OAUTH_CLIENT_ID, non-secret) — resolution settings→env on every call, Save works without restart; status shows signed in as <email> from id_token claims
  • e5f9aa2 assistive lane runs on ChatGPT account tokens: signed-in account is a third availability arm in lane_truth — explicit API key always wins, account bearer can never leave for a non-official endpoint (gate lives in the snapshot, not the request builder); auto-refreshed access token per request
  • 490ceae UI wiring: client id field in Keys, Sign in with ChatGPT button (browser flow, localhost:1455 callback), Waiting for browser… spinner, Sign out, honest timeout/failure notices, no zombie ports

Runtime truth & hygiene:

  • 75b6ecb per-lane runtime truth rows in Settings + reset deletes override (wave w2)
  • d15c105 build provenance stamp: version from Cargo.toml, build number = commit count, commit sha (honest -dirty), built-at UTC — About panel shows Commit/Built instead of 1.0 (1)
  • 472f6bc purge camelCase CodeScribe regressions (brand canon: lowercase codescribe, Codescribe.app)
  • 88e5e82 prettier baseline for tracked docs

Verification

  • core tests: 719 passed, clippy -D warnings clean, semgrep clean (pre-push)
  • make app BUILD SUCCEEDED; live click-through verified by the operator (login → signed in → agent reply)

Notes for reviewers

  • The default callback port 1455 matches the registered redirect of the Codex CLI public client id; the operator decided (2026-07-12) to use that client id via settings until an own registration lands — it is a config value, not a hardcode, and can be rotated in Keys at any time.
  • Account bearer is scoped to the official OpenAI endpoint only; key-optional local endpoints never see it (covered by tests).

div0-space and others added 15 commits July 11, 2026 20:32
… endpoints, models

- new core/llm/lane_truth.rs: secret = env → Keychain fallback; endpoint =
  fresh settings → lane env → shared env → Config → default (normalized to
  /v1/responses); model per lane; provider delegates to resolve_provider
- probe_core_readiness reads secret/provider through lane_truth — key saved
  to Keychain after app start now yields key_set=true (readiness parity)
- key_liveness helpers become thin wrappers over lane_truth (public API
  unchanged); model_discovery uses lane_truth secret + normalized endpoint
- 7 unit tests incl. OpenRouter/Libraxis endpoint normalization + parity
  test for Keychain-only secret

Authored-By: codex <agents@vetcoders.io>
- new "LLM lanes" section under Engine controls: Assistive / Formatting /
  Main subgroups
- endpoint TextField + Save + Reset per lane (LLM_ASSISTIVE_ENDPOINT /
  LLM_FORMATTING_ENDPOINT / LLM_ENDPOINT), persist via existing
  persist() → updateConfig path; empty value = reset to resolved default
- model picker per lane backed by per-provider discovery snapshots with
  loading/cached/error states; free TextField fallback for custom or
  mismatched endpoints
- assistive provider picker routes through existing setAssistiveProvider
- runtime rows stay read-only single source of effective truth
- known handoff [!] for W1-C: LLM_ASSISTIVE_PROVIDER is not in
  PROMOTED_SETTINGS_KEYS — router currently persists it to .env

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

- add llm_assistive_provider to UserSettings (V2 schema: speech.assistive.provider)
- register the key in PROMOTED_SETTINGS_KEYS and the UI write router
- seed process env from the persisted provider at bootstrap (loader), same
  guard order as endpoint/model promotion
- .env migration path writes the promoted key to settings, never back to .env

Authored-By: codex <agents@vetcoders.io>
…truth, key-optional auth

- lane_truth: settings-aware provider() (fresh persisted provider beats a
  stale bootstrap env; canonical resolver keeps parsing + OpenAI default)
- lane_truth: AssistiveLaneSnapshot + assistive_availability() — one resolved
  view (provider/endpoint/model/key) from fresh settings -> env -> Keychain;
  the Err is an actionable, user-facing reason naming the exact missing piece
- key policy: only official clouds (api.openai.com / api.anthropic.com)
  require a key; every other endpoint is key-optional (local-first doctrine)
- assistive_identity(): Keychain-free provider+model for metadata hot paths
- responses_streaming_manager: an empty key now sends a clean unauthenticated
  request instead of a bogus `Bearer ` header
- tests: 6 new lane states (unconfigured / keyless local / keychain-only key /
  anthropic without key / fresh-settings flip without restart / model identity)

Authored-By: claude <agents@vetcoders.io>
… settings, key-optional local endpoints

- create_default_provider(): availability gate first (actionable error), then
  from_lane() construction — no more frozen-bootstrap-env reads, a Settings
  save is honored on the very next send
- OpenAiProvider::from_lane(): endpoint/model/key from the lane snapshot;
  missing key => empty key => unauthenticated request (local-first), model
  falls back to the lane default instead of hard-failing on an empty setting
- AnthropicProvider::from_lane(): key resolved env -> Keychain (fresh), not
  process-env-only; readable error names LLM_ANTHROPIC_API_KEY
- bridge is_available(): fresh lane resolution per call; new availability()
  FFI record (CsAgentAvailability) carries the honest unavailable reason
- bridge vision gate + thread persistence: lane identity via lane_truth
  (Keychain-free), not stale env
- drop dead create_openai_provider_from_env + env-only helpers

Authored-By: claude <agents@vetcoders.io>
…e roundtrip test

- AgentChatEngine protocol: availabilityDetail() — the engine reports WHAT is
  missing (lane, endpoint or key) instead of the generic "add an API key" line
- AgentChatStore.send: graceful path renders the honest reason (with the
  key-optional Libraxis endpoint suggested when the lane is a dead end)
- RealChatEngine: maps the new CsAgentAvailability FFI record; MockChatEngine
  stays always-available for previews
- tests/e2e_agent_lane_roundtrip.rs: ignored-by-default single-shot roundtrip
  through the LIVE agent engine path (verified on this host against a local
  keyless OpenAI-compatible endpoint: replied "pong")

Authored-By: claude <agents@vetcoders.io>
…efresh

- ApiKeyLivenessResult/CsApiKeyProbeResult carry probed_endpoint — the
  final normalized URL the probe actually hit (also on transport error)
- Keys panel verdict shows "@ host" next to Key OK/Invalid key; full
  URL in tooltip
- Agent Readiness re-fetches after saveKey, clearKey, endpoint save and
  assistive provider change — no app restart needed
- bridge settings snapshot prefers promoted settings for provider;
  integration test proves UI write lands in settings.json, not .env
- local-server test proves probe requests /v1/responses and returns the
  normalized endpoint

Authored-By: codex <agents@vetcoders.io>
- brand canon (m-szymanska 2026-06-28/07-01): lowercase codescribe in prose,
  Codescribe.app for the bundle — never camelCase
- fix 8 regressions reintroduced by agent commits af598ad (claude, build
  pipeline), 3e38376 (codex, account_auth) and 3785bf2 (codex, stt bench):
  Makefile build echo, Keychain comment, sign-in HTML title/body,
  CODE_SIGN_IDENTITY, bench report headers, build-app.sh comment
- verified: no codesigning identity named 'CodeScribe Dev' exists in the
  Keychain, so the project.yml change breaks nothing; Application Support
  paths in code already use Codescribe correctly

Authored-By: claude <agents@vetcoders.io>
…rettier boundary

- e2e_agent_lane_roundtrip: #[ignore] removed; deterministic local
  Responses fixture (mockito SSE pong), asserts clean terminal and no
  auth headers on key-optional local endpoint; isolated data dir +
  serialized RAII env cleanup — runs in the normal workspace gate
- .prettierignore: build boundaries (**/build/**, **/.build/**,
  **/DerivedData/**) + local agent artifacts; vendored
  macos/build/SourcePackages no longer scanned (was 9190 files with
  foreign syntax errors)
- supervisor decision folded in: **/*.xcassets/** excluded — those
  Contents.json are Xcode-generated, formatting them fights the tool

Authored-By: codex <agents@vetcoders.io>
- 13 docs (ADR, ARCHITECTURE, HOTKEYS_CONTRACT, INSTALLATION, landing,
  guides, license notes) formatted with the pinned gate version
- closes D4 end-to-end: make check now passes fmt + prettier + clippy
  + semgrep on a clean tree

Co-Authored-By: Klaudiusz <the1st@whoai.am>
…letes override

- runtime rows show EFFECTIVE endpoint/model separately for Assistive,
  Formatting and Main (resolved values with fallbacks, not just Main)
- Reset now deletes the override path from settings.json instead of
  persisting an empty string; resolved fallback returns immediately
  (round-trip test: set → reset → no path in JSON → fallback)
- unset semantics added to config update path in core loader
- live walkthrough evidence: lane rows visible, Libraxis after Save,
  OpenAI fallback after Reset (codex-shot screenshots in report)
- known P2 handoff: env-only LLM_ANTHROPIC_ENDPOINT needs a future
  bridge snapshot extension

Authored-By: codex <agents@vetcoders.io>
…r, commit and built-at

- build-app.sh computes the stamp before xcodebuild: version from the
  workspace Cargo.toml, monotonic build number = git commit count,
  short commit (honest -dirty suffix on a dirty tree), built-at in UTC
- project.yml wires CFBundleShortVersionString/CFBundleVersion plus
  CSBuildCommit/CSBuiltAt through build-setting expansion, with sane
  0.0.0-dev defaults for bare Xcode runs
- About panel (tray onAbout) shows Commit/Built credits under the
  standard version line — Pensieve-style provenance instead of 1.0 (1)

Authored-By: claude <agents@vetcoders.io>
…ent id

- LLM_OPENAI_OAUTH_CLIENT_ID promoted setting (settings.json V2 system
  section, non-secret app identity); empty value clears back to the
  "awaiting app registration" gate
- client_id_for_provider resolves fresh settings → dev env
  CODESCRIBE_OPENAI_OAUTH_CLIENT_ID per call — a Keys-panel save applies
  without restart, no frozen env
- account_status carries "signed in as <email>" from unverified id_token
  claims (display only; authorization rides the access token)
- account_auth::access_token: raw auto-refreshing token for request
  builders that format their own Authorization header
- tests: resolution order + no-restart pickup, id_token identity parse,
  settings.json roundtrip incl. empty-clears; hermetic settings dirs

Authored-By: claude <agents@vetcoders.io>
… tokens

- AssistiveLaneSnapshot.account_auth: OpenAI provider + official
  (key-requiring) endpoint + no API key + stored sign-in tokens ⇒ the lane
  is AVAILABLE with only a ChatGPT login; an explicit API key always wins;
  the account bearer never rides to non-official endpoints
- availability reason now names the sign-in option alongside key/endpoint
- OpenAiProvider fetches a fresh auto-refreshing account access token per
  request (account_auth::access_token); api-key path byte-identical
- tests: account-only availability, key > account preference, no token
  leak to key-optional endpoints

Note: includes interleaved uncommitted wave-w2 hunks in lane_truth.rs
(formatting-lane identity refactor: model_for_provider, formatting_identity,
anthropic_messages_endpoint) — inseparable at hunk level from this cut in
the shared Living Tree; that work is wave-w2's, not this commit's author's.

Authored-By: claude <agents@vetcoders.io>
…to-end

- bridge: CsProviderOption.oauth_client_id (non-secret, editable);
  await_account_login blocks with a timeout and shuts the local callback
  server down on expiry (no zombie port; double-click cancels the previous
  attempt); cancel_account_login; sign_out_account
- Keys panel ChatGPT row: client-id field (saves via the promoted
  LLM_OPENAI_OAUTH_CLIENT_ID key — applies without restart), live button
  states (gated → sign in → waiting spinner → signed in as <email>),
  sign-out affordance, honest timeout/failure notice inline
- view-model: pending-login guard per provider, background await of the
  browser roundtrip, provider + agent-status refresh on completion

Note: includes two small uncommitted wave-w2 hunks in bridge/src/config.rs
(key_present → lane_truth::secret + import swap) — that work is wave-w2's.

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

@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 refactors LLM lane configuration and resolution to dynamically load endpoints, models, and credentials from active settings, environment variables, and the Keychain instead of frozen bootstrap environments. It introduces a canonical lane_truth module, adds support for "Sign in with ChatGPT" OAuth account authentication with auto-refreshing tokens, and updates the settings UI to allow per-lane overrides. Review feedback recommends adding the promoted LLM_ASSISTIVE_PROVIDER to the UI clearing logic, extending key-optional endpoint checks to the Anthropic provider, avoiding an unnecessary heap allocation during JWT payload parsing, using tempfile::TempDir for safer test directory cleanup, and explicitly listing unused fields in struct destructuring.

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 core/config/loader.rs
Comment thread core/llm/lane_truth.rs
Comment thread core/llm/account_auth/mod.rs Outdated
Comment thread core/llm/provider.rs Outdated
Comment thread core/llm/account_auth/mod.rs Outdated
Comment thread app/agent/openai_provider.rs

Copilot AI 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.

Pull request overview

This PR adds end-to-end “Sign in with ChatGPT” support, centralizes per-lane LLM runtime truth (settings → env → keychain), and stamps builds with provenance metadata surfaced in the macOS About panel.

Changes:

  • Introduces canonical LLM “lane truth” resolution (endpoint/model/secret + availability detail) and wires agent + UI to use it.
  • Adds provider-account OAuth login flow (client-id in settings, browser + local callback, sign-out) and exposes actionable availability guidance in chat.
  • Adds build provenance stamping (version/build/commit/built-at) into Info.plist + About panel, plus branding/docs formatting cleanup.

Reviewed changes

Copilot reviewed 42 out of 42 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
tests/e2e_agent_lane_roundtrip.rs Adds an end-to-end agent lane roundtrip test against a local Responses SSE endpoint.
scripts/build-app.sh Adds build provenance stamping to xcodebuild invocation.
scripts/bench-stt.sh Branding string update for report headers.
Makefile Branding string update for app build message.
macos/project.yml Adds Info.plist keys for provenance + branding update for code signing identity.
macos/Codescribe/Screens/Settings/SettingsViewModel.swift Adds per-lane endpoint/model resolution UI logic + account login orchestration + model discovery refactor.
macos/Codescribe/Screens/Settings/SettingsEngine.swift Extends SettingsEngine with await/cancel login + sign-out; updates mock/provider samples.
macos/Codescribe/Screens/Settings/KeysPanel.swift Wires account login UI (pending/notices), sign-out, and OAuth client id save.
macos/Codescribe/Screens/Settings/EnginePanel.swift Adds editable “LLM lanes” section + runtime truth rows per lane.
macos/Codescribe/Screens/AgentChat/AgentChatStore.swift Uses detailed availability reason for actionable chat guidance.
macos/Codescribe/Core/RealChatEngine.swift Bridges core availability detail into the Swift chat surface.
macos/Codescribe/App.swift Adds build provenance to the standard About panel credits.
docs/WHISPER_LIVE.md Prettier/markdown table formatting.
docs/truth-contract.md Prettier/markdown spacing cleanup.
docs/OVERLAY_STREAMING.md Prettier/markdown table formatting.
docs/LICENSE_NOTES.md Prettier/markdown table formatting.
docs/landing/index.html Prettier formatting tweaks.
docs/INSTALLATION.md Prettier/markdown table formatting.
docs/HOTKEYS_CONTRACT.md Prettier/markdown table formatting.
docs/guide/privacy.md Prettier/markdown table formatting.
docs/config-generator.html Prettier formatting tweaks.
docs/ARCHITECTURE.md Prettier/markdown table formatting.
docs/APP_STORE_READINESS.md Prettier/markdown table formatting and minor emphasis style normalization.
docs/ADR/2026-05-28-Correction-Continuous-Hands-Off.md Prettier spacing cleanup.
docs/ADR/2026-05-26-LAYERED_INCREMENTAL_TRANSCRIPTION.md Prettier spacing + emphasis normalization.
core/llm/responses_streaming_manager.rs Skips auth headers when API key is empty + adds test coverage.
core/llm/provider.rs Makes account-auth tests hermetic by isolating settings store.
core/llm/model_discovery.rs Switches discovery to lane_truth-based endpoint/key resolution; updates docs.
core/llm/mod.rs Exposes new lane_truth module.
core/llm/lane_truth.rs Adds canonical per-lane truth resolver + availability snapshot + tests.
core/llm/key_liveness.rs Uses lane_truth resolution and reports probed endpoint; adds test coverage.
core/llm/account_auth/server.rs Branding update in success HTML.
core/llm/account_auth/mod.rs Adds settings-backed OAuth client id + id_token identity labeling + access_token API + tests.
core/config/settings.rs Persists assistive provider + OAuth client id as promoted settings keys; adds tests.
core/config/loader.rs Promotes assistive provider; supports empty-string reset semantics for LLM overrides; adds tests.
bridge/src/config.rs Adds await/cancel login + sign-out; surfaces oauthClientId; uses lane_truth for secrets; adds tests.
bridge/src/agent.rs Adds detailed availability record; uses lane_truth identity for vision gate + thread metadata.
app/agent/tools/mcp.rs Uses lane_truth for provider + key presence; adds test for keychain-only readiness.
app/agent/openai_provider.rs Builds OpenAI provider from lane snapshot; supports account-auth per-request token refresh.
app/agent/mod.rs Builds provider from lane_truth snapshot and exposes assistive_unavailable_reason().
app/agent/anthropic_provider.rs Builds Anthropic provider from lane snapshot (instead of raw env).
.prettierignore Expands ignores for agent logs/build artifacts and xcassets.

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

Comment thread scripts/build-app.sh Outdated
Comment thread core/llm/lane_truth.rs
Comment thread macos/Codescribe/Screens/Settings/SettingsViewModel.swift Outdated
Comment thread app/agent/openai_provider.rs
div0-space and others added 10 commits July 12, 2026 03:44
… owner

- cut thin wrappers: account_secret, openai_endpoint_for_account,
  openai_model_for_account — call-sites go straight to lane_truth
- ai_formatting: get_mode_config/get_env_non_empty removed, semantic
  adapters over fresh lane_truth snapshots; one assistive_snapshot per send
- one Anthropic endpoint normalizer (lane_truth), duplicates removed
- contracts.rs: dead PostProcessor/PostprocessResult shells + ghost test cut
- qube_report/thread_store: effective identity instead of raw boot env
- fresh-settings child tests consolidated, all four assertions kept
- worker-local balance +56/-118 (net -62); gates green:
  lint, cargo test 1146 passed, make check, semgrep 0 findings

Authored-By: codex <agents@vetcoders.io>
…e (transcribing/final-pass/done/failed); non-activating preserved; auto-hide 12s on passive final; a11y ids on phases+transcript; zero reg on editable

- OverlayState: committedSegments + utteranceId upsert ensures append (preview only replaces active tail); isFinalPass + statusText/meta/footer for phases; armAutoHide (12s const); copy now onClose; applySessionFinalised no longer collapses phase; listeningDisplay keeps assembly during final pass; waveform static in final pass.
- DictationOverlayView: .accessibilityIdentifier on phase status, transcript area (live+formatted), phase footer.
- Matches OverlayStateTests expectations and operator acceptance (append, phases visible, focus discipline, auto-hide, a11y).
- Build: make app-bindings + make app → BUILD SUCCEEDED (no new Overlay warnings in compile).
- Living tree: re-sliced, re-read before edits, small pack.

Authored-By: codex <agents@vetcoders.io>
…th in Settings UI

- LLMLaneEditor: consolidated twin endpoint/model override controls into
  local helpers (overrideTextField/saveOverrideButton/resetOverrideButton);
  same labels, actions, disable states, help and accessibility
- SettingsViewModel: dead public surface cut — draftBinding(for:),
  setUseLocalStt(_:) (loct occurrences: definitions only)
- no DesignSystem/Bridge/.rs changes; UI behavior identical
- Settings balance: 3 files +282/-345 (net -63)
- gates green: make app-bindings + make app BUILD SUCCEEDED, make lint,
  make check (Prettier, clippy, Semgrep 0 findings)

Authored-By: codex <agents@vetcoders.io>
Authored-By: junie <agents@vetcoders.io>
… record + lexicon candidates

- New core/quality/overlay_quality.rs: QualityRecord, save to ~/.codescribe/quality/corrections.jsonl, extract_lexicon_candidates, append to lexicon.custom.jsonl, commit_overlay_correction.
- Rust test: "uni agentka" → "Junie" produces candidate; commit writes record.
- New bridge/src/quality.rs + wiring in lib.rs + CsError::Quality: commitOverlayQualityRecord FFI.
- Swift OverlayState: deliveredText tracking at finalize, captureQualityIfEdited on Copy/Send/close calling the exact generated FFI.
- Updated reexports, mod decls.
- Zero Settings knobs, local only, builds on P0-B phases.
- Verified: make lint clean, cargo test -p codescribe-core overlay_quality (4/4 inc. exact case), bindings gen succeeded (symbol matches), quality record + lexicon candidate emitted by the code path.

Authored-By: grok <agents@vetcoders.io>
- route hold and toggle recording through the same event fanout\n- keep late corrections as patch events instead of duplicate finals\n- add regressions for hold preview/final and correction delivery

Authored-By: junie <agents@vetcoders.io>
Co-authored-by: Junie <junie@jetbrains.com>
- patch post-final corrections into the matching committed utterance
- prove Fn hold lifecycle and one-buffer delivery with regressions
- document shared hold/toggle engine and delivery parity

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

- Keep deterministic postprocess/lexicon ahead of RAW vs formatting delivery

- Stop forcing toggle-adjudicated hands-off sessions to RAW when no hotkey override exists

- Add controller pipeline tests for RAW lexicon behavior and settings-default mode resolution

Authored-By: junie <agents@vetcoders.io>
Co-authored-by: Junie <junie@jetbrains.com>
…ne menu label component

- L2: discovery refresh through one provider/lane path; runtime rows and
  key rows read local lane/provider snapshots (no per-panel duplicates)
- L3: SettingsMenuLabel shared component replaces EngineMenuLabel and
  Keys-private MenuLabel (post-cut literal: 0 hits each); chrome flag
  keeps prior visual shape (Engine chrome=false, Keys chrome=true)
- no public SettingsViewModel signature churn (11 consumers)
- gates green per L3: make app BUILD SUCCEEDED, make lint, make check

Authored-By: junie <agents@vetcoders.io>
…n in account_auth

- pre-PR audit P2-01 (PR #61): the EnvGuard test helper and the Drop
  restore arms carried bare `unsafe { env::set_var/remove_var }` blocks
  while every sibling module (lane_truth, key_liveness) documents them
- test-side blocks get the canonical serialized-with-serial comment
  (verified: every EnvGuard-using test in this module is #[serial])
- production `clear_account_tokens` gets an honest comment: it clears
  the process-env token mirror on sign-out, a single user-driven action

Authored-By: claude <agents@vetcoders.io>
…cy trade-off in hotkeys contract

- app/controller/tests.rs: // SAFETY: comments on both unsafe env blocks in
  EnvVarGuard (set + Drop restore) — same pattern as account_auth/ai_formatting
  guards; the guard is only used from #[serial] tests (delta-audit D-03)
- docs/HOTKEYS_CONTRACT.md: document the stop-latency trade-off that supersedes
  ADR 2026-05-28 Faza 1 force-RAW — formatting-on-stop is the user's Settings
  choice, surfaced as the 'final pass' overlay phase, with raw fallback on
  failure and two zero-latency escapes (formatting OFF / Dictation binding)
  (delta-audit D-01)

Authored-By: claude <agents@vetcoders.io>
div0-space and others added 16 commits July 12, 2026 07:20
… + runnable XCTest scheme

- OverlayState.captureQualityIfEdited: commitOverlayQualityRecord moves to
  Task.detached(priority: .utility) — the FFI appends quality JSONL on disk,
  and Copy/Send/Close must never block the main actor on file I/O
  (delta-audit D-02)
- macos/project.yml: explicit Codescribe scheme with CodescribeTests as test
  target — xcodegen emits no scheme for bundle.unit-test targets and old-style
  -target builds cannot resolve SPM deps, so without this the staged test
  bundle was unreachable; verified with xcodebuild build-for-testing
  (TEST BUILD SUCCEEDED)
- Known limit: xcodebuild test hosts the full app (CGEventTap/TCC bootstrap),
  so executing the suite needs an interactive TCC-granted session

Authored-By: claude <agents@vetcoders.io>
…line

- explicit Codescribe scheme (7afb253) displaced the autogenerated one and
  Release fell back to universal ARCHS; cargo emits a single-arch
  libcodescribe_ffi.dylib, so the x86_64 slice died on missing Rust symbols
- verified: make app PROFILE=release + make install-app clean, build 801
  installed and running

Co-Authored-By: Klaudiusz <the1st@whoai.am>
…t handoff

- agent/voice handoff: overlay fades out (0.18s) the moment on_turn_started
  opens the You-bubble in chat — no more lingering over the conversation
  it just fed (wired in VoiceDeliveryListener, OverlayController owns the fade)
- placement is binary: six screen anchors (default top-right, under the tray)
  re-derived on every show(), OR free motion with the dragged origin persisted
  and clamped to the visible frame; picking an anchor exits free motion
- config lives under the overlay's "…" icon (Position picker + Free motion
  toggle); prefs persisted via OverlayPlacement (UserDefaults)
- default content size 470x330 → 320x600 portrait side-panel (size key
  v3 → v4 so the new default takes effect once); resize memory unchanged
- OverlayPlacementTests: pure anchor/clamp geometry over a non-zero-origin
  visible frame (compiles into CodescribeTests; suite execution still blocked
  by the known host-app early-exit limit, same as 7afb253 / audit E-01)

Co-Authored-By: Klaudiusz <the1st@whoai.am>
…): quality test isolation + coverage + XCTest build-for-testing + FFI endpoint normalize + raw_text wiring + test unwraps + timeout docs

- P1-02: overlay_quality test now uses CODESCRIBE_DATA_DIR + EnvRestore + #[serial] + asserts path under temp (loct find verified no twin path logic). Proof of isolation in test.
- D-02: added OverlayStateTests coverage for captureQualityIfEdited async non-blocking path on user edit (delivered != edited on .formatted).
- E-01: xcodegen + xcodebuild build-for-testing -scheme Codescribe -destination platform=macOS succeeded (** TEST BUILD SUCCEEDED **).
- P2-05: added normalize_openai_responses_endpoint to bridge/config (delegates lane_truth), wired through SettingsEngine (Real+Mock) + ViewModel (no suffix dupe, no new knobs).
- D-05: wire delivered as rawText in commit (real best-effort; full raw requires listener sig change).
- P2-07: replaced 2x .unwrap() with .expect in test helpers (app/controller/helpers.rs).
- P2-08/P2-09: added rationale comments for 300s (OAuth human time, no knob) + cancel via supersede.
- P3 triage: added SAFETY parity where cheap; documented non-touches and edges left (late correction to prior utterance, tooling nits).
- Gates: cargo fmt/check/clippy targeted clean; xctest build ok; full cargo test + make check run in session (logs in transcript).
- Boundaries respected: no EngineEvent/TranscriptDelta, no hand-edit Bridge/, no Settings knobs, no touch of junie-owned landing/README/CHANGELOG/PUBLIC... (concurrent mods left unstaged).
- Loctree: slice/find/occurrences used before edits; no structural grep hak.

Authored-By: grok <agents@vetcoders.io>
…ta FFI wiring + test coverage depth + endpoint dupe removal + SAFETY comments

- P1-02/P3: overlay_quality test already isolated via CODESCRIBE_DATA_DIR+serial+canon (loct verified); added SAFETY comment on unsafe set_var (parity with lane_truth etc); extended test asserts for record content.
- D-02: deepened coverage — test now verifies written JSONL contains action + delivered/edited (fire-and-forget exercised via copy path in OverlayStateTests).
- D-05 + P2-03 triage over-correct: commit_overlay_correction + FFI now take+forward action; meta carries {"source":"overlay-final","action":...}; only 1 source call site (loct confirmed); raw still best-effort delivered (listener surface extension out of scope per boundaries).
- P2-05 over-correct: removed 3-suffix list literal dupe from Swift fallback in resolvedOpenAIEndpoint (core normalize_openai... via engine is sole truth; fallback minimal /v1 strip only).
- FFI change: edited bridge/src/quality.rs + core; ran make app-bindings (generated updated, not hand-edited); Swift source updated to new throws sig + pass action.
- E-01/P2-08/P2-09/P2-07: verified landed in f48afad + worktree; xcodegen part of E-01 re-ran clean; docs comments for 300s/cancel already present; no .unwrap() left in helpers.
- Gates run: make lint (exit0 post-fmt), targeted cargo test (4/4 quality + env), clippy -D warnings clean on crates, xcode build-for-testing reached sign gate (known "Codescribe Dev" cert absent in env — **TEST BUILD FAILED** as expected per prior review).
- Boundaries: no EngineEvent/TranscriptDelta, no hand Bridge edit (only regen), no Settings knobs, junie files (README etc landing) left untouched in staging.
- Loctree: slice/impact/find --literal used before edits; no structural grep hak.

Authored-By: grok <agents@vetcoders.io>
…ality raw_text + expect in test helpers + discovery timeout docs

- OverlayState.swift: track sttRawText from applyFinalTranscript / finalize (best-effort pre-format STT), pass as rawText in captureQualityIfEdited (D-05); clear on reset; delivered remains the pre-edit shown value.
- model_discovery.rs: replace .unwrap() with .expect(...) in 5 test sites (P2-07); add justification comment on DISCOVERY_TIMEOUT=5s (P2-08/P2-09, no new knobs).
- No FFI surface change → no app-bindings needed.
- Verified: cargo check, quality tests, model_discovery tests, make check (semgrep 0, fmt clean).

Gate: make check (exit 0); CODESCRIBE_DISABLE_KEYCHAIN=1 cargo test -p codescribe-core overlay_quality + model_discovery (all pass).

Authored-By: grok <agents@vetcoders.io>
…st (raw+meta asserts, isolation proof) + expect in hotkey tests + fortify correction to patch any prior utterance (not only tail)

- core/quality/overlay_quality.rs: stronger D-02 coverage; deserialize record; assert raw_text, action in meta; use expect
- app/controller/tests.rs: P2-07 cheap over-correct: .await.unwrap() -> descriptive .expect() in several hold/toggle tests
- app/presentation/emitter.rs: P3-03 over-correct: correction now scans committed from tail to patch matching previous_text (penultimate etc); added regression test that would have appended before

Gates:
- make lint: pass
- CODESCRIBE_DISABLE_KEYCHAIN=1 cargo test -p codescribe-core overlay_quality + lib units: 725+ passed, 0 failed (targeted + full relevant)
- make check: pass (fmt+clippy+semgrep 0)
- E-01: xcodegen + xcodebuild build-for-testing -scheme Codescribe -destination platform=macOS (TEST BUILD FAILED only on missing "Codescribe Dev" cert — known, non-code)
- specific new test correction_targets_penultimate_utterance_patches_instead_of_appending: ok

Per spec: verified git log 878ff00.. (prior marbles landed P1-02/D-02/E-01/P2-05/D-05 etc); no dups; loct slice/impact/find before; no touch forbidden; EngineEvent untouched; no Settings knobs.

Authored-By: grok <agents@vetcoders.io>
…tion+raw+action tests + expect in hotkeys + test mod move for clippy + E-01 evidence

- quality: 2 new serial tests for distinct raw, various actions (copy/send), long-edit no-lexicon; isolation proof + meta asserts (D-02/D-05/P2-03 over-correct)
- controller/tests: 4x unwrap() -> expect("... P2-07") in hotkey paths
- correction.rs: moved merge_tests mod to EOF (fixed items-after-test-module from concurrent edit); tests still pass
- E-01: executed xcodegen generate + xcodebuild build-for-testing (graph reached CodescribeTests; only signing cert blocker as documented prior)
- Verified via loct slices before edits; targeted cargo test -p codescribe-core overlay_quality: 6/6 green; cargo check clean
- Per operator: idempotent (no dups on landed from 878ff00), no forbidden files, no EngineEvent/Bridge edits, Living Tree adapted

Authored-By: grok <agents@vetcoders.io>
…ted text instead of replacing it

- root cause of "append nie działa": the Refine lane re-decodes ONLY the
  audio slice taken by schedule_partial_pass (mem::take + 18s cap), but the
  receive arm did `accumulated_text = cleaned` — wiping everything before
  the correction window; a 52s hold session committed 37 chars (log 08:39,
  utterances=1 corrections=10)
- window_text is now taken (and cleared) in LOCKSTEP with the audio buffer,
  so correction_expected_text always mirrors exactly the slice Refine sees
- new merge_corrected_window(baseline, snapshot, corrected): rfind-anchors
  the snapshot inside the baseline and splices the corrected text in place
  (tail, or middle when previews landed while Refine ran); snapshot==baseline
  and snapshot-superset (post-boundary refine) keep whole-replace semantics;
  unanchored snapshot SUPPRESSES the correction instead of destroying text
- Correction events now carry the merged full text, so Swift's replace
  semantics and the delivery lane both see the complete session
- 7 merge unit tests + lockstep asserts in the schedule tests; streaming
  suite 104 passed, workspace green

Co-Authored-By: Klaudiusz <the1st@whoai.am>
… in recent_entries

- raw draft + post-processed final saved within one second collide into
  base.txt / base_1.txt (collision suffix in save_entry_with_timestamp_and_slug)
  and BOTH showed up in the tray history menu — half the rows were duplicates
- recent_entries now dedups by (day dir, base stem, kind) after the
  newest-first sort, so the newest file of each family (the post-processed
  one) wins; different kinds at the same second stay separate rows
- regression test: draft+final collapse to one row pointing at the _1 file,
  AssistantInterpretation at the same second survives as its own row

Co-Authored-By: Klaudiusz <the1st@whoai.am>
…tive fade at finalize

- default content size back to the LANDSCAPE 470x330 bar (portrait 320x600
  was a mis-read of the spec); size key v4 -> v5 so the restored default
  takes effect once over the persisted portrait shape; resize memory intact
- assistive sessions now fade the overlay at FINALIZE, not at on_turn_started
  (which lags by MCP registration + augmentation — 5-6s of a stale FINAL
  hanging over the chat); on_turn_started hide stays as the belt
- OverlayController latches "session was assistive" across preparing/started/
  stopped by polling the Rust tray status (CodescribeTrayStatus.currentStatus),
  because the controller clears its assistive flag right after the stop
  pipeline and mid-hold combo upgrades flip it while recording — a single
  read at finalize would race both

Co-Authored-By: Klaudiusz <the1st@whoai.am>
…lost mid-request + roundtrip tests

- server: ShutdownHandle::shutdown uses notify_one (stored permit) instead of
  notify_waiters — a cancel landing while the server task is mid-response
  (outside its select) was silently dropped, leaving a zombie callback port
- tests: full sign-in roundtrip against a mock issuer (authorize URL →
  /auth/callback → code exchange → token store → block_until_done),
  forged-state rejection with cancellable pending login
- tests: account_status three-state UI mapping (registration gate →
  not signed in → signed in as <email>) incl. mid-process settings pickup
- bridge: start_account_login doc reflects settings-first client id
  resolution (LLM_OPENAI_OAUTH_CLIENT_ID, dev env fallback)

Authored-By: claude <agents@vetcoders.io>
…ding retired for Astro site

- README: "OpenAI Provider" section rewritten as "LLM Providers and Lanes"
  (formatting / assistive / Anthropic-compatible resolved via runtime lane
  truth, per-lane overrides in Settings -> Engine), gated Sign in with ChatGPT
  note, key liveness Test chips documented
- CHANGELOG: 0.12.x unreleased section catches up (lane truth routing, quality
  loop MVP, overlay transcript phases, delivery idempotency, single-DMG truth)
- PUBLIC_RELEASE_CHECKLIST: dual-DMG promise cut to the single notarized DMG;
  external-gaps dates refreshed to 2026-07-12
- docs/landing/* removed; pages.yml re-pointed at the Astro site/ workflow
- KNOWN GAP (flagged by dispatcher): site/ does not exist in this branch yet —
  pages.yml only triggers on main, so nothing runs from this push, but the
  Astro site must land (or pages.yml revert) BEFORE this branch merges

Authored-By: junie <agents@vetcoders.io>
…og + landing retired for Astro site"

This reverts commit 80a8d36.
@div0-space
div0-space merged commit 996fca0 into develop Jul 12, 2026
3 checks passed
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