Sign in with ChatGPT + per-lane runtime truth + build provenance#61
Conversation
… 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>
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
… 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>
… + 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.
What ships
Sign in with ChatGPT — end to end (operator-tested live: signed in, agent replies on account tokens):
b298ac9OAuth 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 claimse5f9aa2assistive lane runs on ChatGPT account tokens: signed-in account is a third availability arm inlane_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 request490ceaeUI wiring: client id field in Keys, Sign in with ChatGPT button (browser flow,localhost:1455callback), Waiting for browser… spinner, Sign out, honest timeout/failure notices, no zombie portsRuntime truth & hygiene:
75b6ecbper-lane runtime truth rows in Settings + reset deletes override (wave w2)d15c105build provenance stamp: version from Cargo.toml, build number = commit count, commit sha (honest-dirty), built-at UTC — About panel shows Commit/Built instead of1.0 (1)472f6bcpurge camelCaseCodeScriberegressions (brand canon: lowercasecodescribe,Codescribe.app)88e5e82prettier baseline for tracked docsVerification
-D warningsclean, semgrep clean (pre-push)make appBUILD SUCCEEDED; live click-through verified by the operator (login → signed in → agent reply)Notes for reviewers