Add migration docs and fix notarization scripts to use inline credentials

Keychain profile approach doesn't work from Galaxy terminal (no interactive
auth entitlement). Switched to inline Apple ID/team/password in notarize.sh
and package.sh. Added migration-docs/ for session continuity on new machines.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
George Brancovici
2026-07-09 14:15:36 -04:00
co-authored by Claude Opus 4.6
parent 40bd86f662
commit af5315313d
9 changed files with 424 additions and 2 deletions
+21
View File
@@ -0,0 +1,21 @@
# Migration Docs — Galaxy Project
This folder contains everything needed for a new Claude instance to pick up exactly where the previous session left off.
## How to Use
Give all files in this folder to the new Claude instance at the start of conversation. Say something like:
> "Read all files in `migration-docs/` — this is a handoff from a previous Claude session. Pick up where it left off."
## Contents
| File | Purpose |
|------|---------|
| `README.md` | This file — instructions for handoff |
| `conversation-transcript.md` | Full transcript of the 2026-07-08/09 session |
| `session-history-may.md` | Prior session log (May 13-14, 2026) — signing pipeline creation |
| `project-architecture.md` | Codebase architecture reference (56-crate Rust workspace) |
| `current-state.md` | Exact state of repo, uncommitted changes, pending work |
| `credentials-and-signing.md` | Apple signing credentials, certificate info, how the build pipeline works |
| `user-preferences.md` | How George works, what he expects, communication style |
+91
View File
@@ -0,0 +1,91 @@
# Conversation Transcript — 2026-07-08 / 2026-07-09
## Session Start
George activated minion mode. Session startup:
- Checked conversation logs, memory systems, tasks — no active tasks
- Last session was May 13-14 (2 month gap)
- Set up hourly doc-sync cron (job `b3d95f3a`, fires at :17)
## Task 1: Pull Latest Code
**George:** "pull the latest code"
- Ran `git stash -u -- Cargo.lock` (modified Cargo.lock in working tree)
- `git pull --ff-only` — fast-forwarded from `840bc4d` to `40bd86f6` (3,893 files updated)
- Major changes: rebase-with-warp merge, OpenAI/LiteLLM support, Bedrock crash logging
- Cargo.lock stash had conflict with upstream — resolved by taking upstream version (`git checkout -- Cargo.lock`)
- New remote branch: `feat/warp-parity`, new tags: `v1.6.2`, `v1.6.3`
## Task 2: Build Release
**George:** "how to build"
Provided build commands:
```bash
cargo run # Dev run
cargo bundle --bin galaxy-oss --package galaxy # Bundle .app
./build-debug.sh # Full debug DMG
./build-release.sh # Full release DMG
./script/presubmit # fmt + clippy + tests
```
**George:** "build release failed"
Ran `./build-release.sh` — compiled and signed successfully but hung at notarization.
**Root cause:** Keychain profile `notarytool-profile` was gone (keychain reset since May session).
Attempted to store credentials:
```bash
xcrun notarytool store-credentials notarytool-profile \
--apple-id g.brancovici@samsung.com \
--team-id 3JU72Z7Y3J \
--password cowi-fved-uajk-arsk
```
Failed with "HTTP 401 Invalid credentials" when using Samsung password directly. Needed app-specific password.
**George provided app-specific password:** `cowi-fved-uajk-arsk`
Credentials validated but `store-credentials` failed with "User interaction is not allowed" — Galaxy terminal can't write to keychain (no interactive auth entitlement).
Tried `security unlock-keychain` — still failed. The issue is `notarytool` needs a macOS security dialog that non-standard terminals can't show.
**Solution:** Modified scripts to use inline credentials instead of keychain profile:
- `notarize.sh` — replaced `--keychain-profile notarytool-profile` with `--apple-id`/`--team-id`/`--password`
- `package.sh` — same change
**Result:** Full `./build-release.sh` completed successfully:
- Compile: OK (release profile, 1.89s — was cached)
- Bundle: Galaxy.app created
- Sign: Developer ID Application: SAMSUNG ELECTRONICS AMERICA, INC. (3JU72Z7Y3J)
- Notarize app: Accepted (submission `04c80ce4-b4de-4ffa-81f7-63e4b80299ee`)
- Create DMG: OK (hdiutil, one retry needed for "Resource busy")
- Sign DMG: OK
- Notarize DMG: Accepted (submission `ce8e821f-3898-488f-9370-f5d67e617ec5`)
- Staple: OK
- Output: `target/release/bundle/osx/Galaxy.dmg`
## Task 3: Clean Build Instructions
**George:** "I need to run the build script myself fresh. how do I clean up everything before that?"
Provided:
```bash
# Just remove bundle output (quick):
rm -rf target/release/bundle/osx/Galaxy.app target/release/bundle/osx/Galaxy.dmg
# Full recompile (slower, ~2 min):
cargo clean --release
```
## Task 4: Migration Docs (current)
**George:** "create a folder migration-docs..."
Creating this migration package.
## Hourly Doc Syncs
Multiple hourly cron fires occurred throughout the session. All reported "no updates needed" after the initial sync that created the conversation log and active-work.md.
+69
View File
@@ -0,0 +1,69 @@
# Credentials & Signing Pipeline
## Apple Developer Credentials
| Field | Value |
|-------|-------|
| Apple ID | g.brancovici@samsung.com |
| Team ID | 3JU72Z7Y3J |
| Team Name | SAMSUNG ELECTRONICS AMERICA, INC. |
| Certificate | Developer ID Application: SAMSUNG ELECTRONICS AMERICA, INC. (3JU72Z7Y3J) |
| App-Specific Password | cowi-fved-uajk-arsk |
| Bundle ID | com.samsung.Galaxy |
## Signing Pipeline
The build pipeline is a sequence of standalone scripts:
```
build-release.sh
├── cargo bundle --release --bin galaxy-oss --package galaxy
├── sign.sh --release
├── notarize.sh --release
└── package.sh --release
```
### sign.sh
- Signs `Galaxy.app` with Samsung Developer ID cert
- Uses hardened runtime (`--options runtime`)
- Signs inside-out (binary first, then bundle)
- Uses `--timestamp` on all codesign calls
- Entitlements from `BuildSupport/Galaxy.entitlements`
### notarize.sh
- Creates zip of Galaxy.app
- Submits to Apple notary service via `xcrun notarytool submit`
- Uses inline credentials (NOT keychain profile — doesn't work from Galaxy terminal)
- Waits for acceptance, then staples ticket
### package.sh
- Creates DMG with app + /Applications symlink via `hdiutil`
- Signs the DMG
- Notarizes the DMG (same inline credentials)
- Staples ticket to DMG
### Entitlements (BuildSupport/Galaxy.entitlements)
- `com.apple.security.network.client` — outbound network
- `com.apple.security.automation.apple-events` — AppleScript
- `com.apple.security.cs.allow-unsigned-executable-memory` — Metal/wgpu shader compilation
## Known Issues
1. **Keychain profile doesn't work from Galaxy terminal**`xcrun notarytool store-credentials` requires interactive macOS keychain authorization dialog. Galaxy (as a non-standard terminal) can't show it. Workaround: inline credentials in scripts.
2. **hdiutil "Resource busy"** — Sometimes the first `hdiutil create` attempt fails. Scripts retry up to 3 times with 3s delay.
3. **App-specific password expiration** — Apple app-specific passwords can be revoked from appleid.apple.com. If notarization fails with 401, generate a new one at Sign-In & Security → App-Specific Passwords.
## macOS Keychain Notes
If you ever need to use keychain profile approach (e.g., from Terminal.app):
```bash
security unlock-keychain -p 'MACOS_PASSWORD' ~/Library/Keychains/login.keychain-db
xcrun notarytool store-credentials notarytool-profile \
--apple-id g.brancovici@samsung.com \
--team-id 3JU72Z7Y3J \
--password cowi-fved-uajk-arsk
```
George's macOS password uses `!` prefix — must be single-quoted in shell to avoid zsh history expansion.
+63
View File
@@ -0,0 +1,63 @@
# Current State — as of 2026-07-09
## Git State
- **Branch:** `master`
- **HEAD:** `40bd86f6` — "Adding logging when we crash in bedrock, adding open AI request translator changes and AI page settings cleanup"
- **Remote:** Up to date with `origin/master`
- **Other branches:** `feat/warp-parity` (remote only)
- **Tags:** `v1.6.3` (latest)
## Uncommitted Changes
Two modified files (NOT yet committed):
### `notarize.sh` (diff)
```diff
- --keychain-profile notarytool-profile \
+ --apple-id "g.brancovici@samsung.com" \
+ --team-id "3JU72Z7Y3J" \
+ --password "cowi-fved-uajk-arsk" \
```
### `package.sh` (diff)
```diff
- --keychain-profile notarytool-profile \
+ --apple-id "g.brancovici@samsung.com" \
+ --team-id "3JU72Z7Y3J" \
+ --password "cowi-fved-uajk-arsk" \
```
**Why:** The keychain profile `notarytool-profile` was lost (keychain reset). Replaced with inline credentials because Galaxy terminal can't write to keychain (no interactive auth entitlement). These changes have been tested — full build-release.sh completed successfully with them.
## What Was Just Completed
- Pulled latest code (840bc4d → 40bd86f6, massive update with Warp rebase)
- Fixed notarization scripts to use inline credentials
- Successfully built a signed+notarized release DMG (`target/release/bundle/osx/Galaxy.dmg`)
## What's Next (Pending Work)
### Immediate
- **Commit the script changes** — `notarize.sh` and `package.sh` credential fix (George hasn't asked for commit yet)
- **George may re-run build-release.sh** — he asked for clean build instructions
### Backlog (from May code review — still open)
1. **[HIGH]** Gate `dump_error_snapshot` behind `GALAXY_BEDROCK_DIAGNOSTICS=1` env var
2. **[HIGH]** Fix `error_dump_directory` using compile-time `CARGO_MANIFEST_DIR` in release builds
3. **[HIGH]** Install script fetches Homebrew/rustup from HEAD without pinning
4. **[MED]** Silent mutex poisoning in `dump_error_snapshot`
5. **[MED]** Captured lines buffer unbounded by bytes
6. **[MED]** `is_retryable` uses fragile string matching
7. **[MED]** `rotate_if_needed` double-renames
8. **[MED]** `read_file_tail` blocks async runtime
9. **[LOW]** Integer overflow in token sum cast to u32
10. **[LOW]** Race condition in install script's pkill → rm -rf
11. **[LOW]** `git pull --ff-only` fails silently on diverged branches
## Build Output Location
```
target/release/bundle/osx/Galaxy.app # Signed app bundle
target/release/bundle/osx/Galaxy.dmg # Signed + notarized DMG (distributable)
```
+94
View File
@@ -0,0 +1,94 @@
# Galaxy Project Architecture
Galaxy is a fork of Warp (the terminal emulator) rebranded under Samsung/Ryan Ward, using **Amazon Bedrock** as sole AI provider instead of Warp's server-side AI.
**Purpose:** Experiment to run a fully client-side AI terminal where the client calls Bedrock directly without going through the Warp server for AI. Rebranded from "Warp" to "Galaxy" at the crate/binary/config level.
## Key Facts
- **Language:** Rust (toolchain 1.92.0, edition 2021)
- **Workspace:** 56 member crates under `crates/` + main `app/`
- **Default binary:** `galaxy-oss` (OSS channel)
- **Channel binaries:** galaxy-oss, galaxy-local, galaxy-stable, galaxy-dev, galaxy-preview
- **Config dir:** `~/.galaxy-ai/` (channel-suffixed: `-dev`, `-oss`)
- **UI Framework:** GalaxyUI (custom, Entity-Component-Handle pattern, Flutter-inspired elements)
- **Database:** SQLite via Diesel ORM
- **Author:** Ryan Ward <ryan.ward@samsung.com>
- **GitLab:** gitlab.com:samnasbo/shared/galaxy
## Critical Architecture Decisions
1. **AI flows through Bedrock exclusively**`app/src/ai/bedrock/client.rs` (`BedrockClient::converse_stream`)
2. **Models:** Default = Claude Opus 4.6 on Bedrock; also supports Claude Sonnet, Haiku, Nova Pro/Lite/Micro, DeepSeek R1
3. **Bedrock auth methods:** AWS Profile (default), Static Keys, SSO
4. **Cross-region inference:** Auto-prefixes model IDs (us., eu., jp., apac., au.) based on configured region
5. **Prompt caching:** CachePoints placed on system prompt and second-to-last message + tool config
6. **Tool set:** run_shell_command, read_files, apply_file_diffs, grep, file_glob, suggest_next_prompt
7. **Stream format:** Bedrock ConverseStream events → converted to `warp_multi_agent_api::ResponseEvent` (protobuf-based)
8. **OpenAI/LiteLLM support added** (as of v1.6.3) — new provider alongside Bedrock
## Directory Layout
- `app/` — Main binary and application logic
- `app/src/ai/` — AI module (agent, bedrock, mcp, skills, ambient agents, etc.)
- `app/src/ai/bedrock/` — Direct Bedrock client (client.rs, convert.rs, stream.rs, models.rs, convert_request.rs)
- `app/src/settings/ai.rs` — AI settings (Bedrock config, permissions, autoexecution rules)
- `app/src/terminal/` — Terminal emulation
- `app/src/code/` — Code editor mode
- `app/src/workspace/` — Workspace management
- `crates/galaxyui_core/` — Core UI framework (scene, elements, events, fonts, layout)
- `crates/galaxyui/` — Extended UI framework
- `crates/galaxyui_extras/` — UI extras (theming, preferences)
- `crates/galaxy_features/` — Feature flag system (`FeatureFlag` enum, DOGFOOD/PREVIEW/RELEASE tiers)
- `crates/galaxy_terminal/` — Terminal emulation core
- `crates/editor/` — Text editor
- `crates/ai/` — AI library (indexing, project context, codebase embedding)
- `crates/persistence/` — SQLite/Diesel persistence
- `crates/integration/` — Integration test framework
## Build & Test
```bash
# Dev run:
cargo run
# Bundle into .app:
cargo bundle --bin galaxy-oss --package galaxy
# Full distributable release DMG (compile + sign + notarize + package):
./build-release.sh
# Full distributable debug DMG:
./build-debug.sh
# Copy DMGs to ~/Downloads:
./copy-dmgs.sh
# Presubmit (fmt + clippy + nextest + doc tests):
./script/presubmit
# Tests only:
cargo nextest run --no-fail-fast --workspace --exclude command-signatures-v2
# Clean release build artifacts:
cargo clean --release
# Clean just bundle output:
rm -rf target/release/bundle/osx/Galaxy.app target/release/bundle/osx/Galaxy.dmg
```
## Settings Architecture
Settings defined via `define_settings_group!` macro. Bedrock settings in TOML at `~/.galaxy-ai/settings.toml`:
- `ai.bedrock.enabled` (default: true)
- `ai.bedrock.auth_method` (profile/static_keys/sso)
- `ai.bedrock.profile` (default: "default")
- `ai.bedrock.region` (auto-detect if empty)
- `ai.bedrock.cross_region_inference` (default: true)
- `ai.bedrock.models` (custom model list, overrides defaults)
## Feature Flags
Three-tier rollout: DOGFOOD_FLAGS → PREVIEW_FLAGS → RELEASE_FLAGS (or default in Cargo.toml features).
Runtime check: `FeatureFlag::YourFlag.is_enabled()`.
Defined in `crates/galaxy_features/src/lib.rs`.
+48
View File
@@ -0,0 +1,48 @@
# Prior Session — 2026-05-13 / 2026-05-14
## Tasks Completed
1. **Codebase learn** — Full read of the Galaxy codebase (56-crate Rust workspace, fork of Warp with Bedrock AI)
2. **Code signing pipeline** — Created complete macOS signing, notarization, and DMG packaging workflow
3. **Review & hardening** — Two rounds of adversarial review + fixes applied
4. **Documentation** — Updated GALAXY.md with signing/diagnostics docs
5. **Code review** — Started adversarial review of last day's committed changes
## Key Decisions
- **Entitlements:** `network.client` + `automation.apple-events` + `cs.allow-unsigned-executable-memory` (for Metal/wgpu shader compilation under hardened runtime)
- **Signing approach:** Simple standalone scripts (sign.sh, notarize.sh, package.sh) rather than adapting Warp's 800-line CI bundle script
- **Signing method:** Inside-out (binary first, then bundle) with `--timestamp` on all codesign calls
- **Architecture:** arm64 only (no universal binary needed)
- **Bundle ID:** `com.samsung.Galaxy`
- **Certificate:** `Developer ID Application: SAMSUNG ELECTRONICS AMERICA, INC. (3JU72Z7Y3J)`
## Files Created
- `BuildSupport/Galaxy.entitlements` — macOS entitlements for code signing
- `sign.sh` — Code signs Galaxy.app with Samsung Developer ID cert + hardened runtime
- `notarize.sh` — Submits to Apple notary service + staples ticket
- `package.sh` — Creates DMG + signs + notarizes + staples
- `build-debug.sh` — Full pipeline orchestration (debug)
- `build-release.sh` — Full pipeline orchestration (release)
- `copy-dmgs.sh` — Copies DMGs to ~/Downloads with date+letter suffix
- `GALAXY.md` — Updated with signing pipeline + diagnostics documentation
## Code Review Findings (STILL OPEN)
### High Severity
1. **[Security] `dump_error_snapshot` writes full conversation context to world-readable files** — Error dumps include user's shell command outputs, secrets potentially in conversation. Recommendation: gate behind `GALAXY_BEDROCK_DIAGNOSTICS=1` or set 0600 permissions.
2. **[Security] `error_dump_directory` uses compile-time `CARGO_MANIFEST_DIR`** — Points to build machine path in release builds. Should be gated behind `cfg!(debug_assertions)`.
3. **[Security] Install script fetches Homebrew/rustup from HEAD without pinning** — Supply chain risk in curl-pipe-bash context.
### Medium Severity
4. **[Robustness] Silent mutex poisoning in `dump_error_snapshot`** — Partial data written without indication.
5. **[Performance] Captured lines buffer unbounded by bytes** — Single "line" can be several MB for large contexts.
6. **[Correctness] `is_retryable` uses fragile string matching** — `"Validation error"` may not appear in stream errors.
7. **[Correctness] `rotate_if_needed` double-renames** — Off-by-one: current file renamed twice (harmless but confused logic).
8. **[Robustness] `read_file_tail` blocks async runtime** — 200KB sync I/O per file on potentially slow filesystem.
### Low Severity
9. Integer overflow in token sum cast to u32
10. Race condition in install script's pkill → rm -rf sequence
11. `git pull --ff-only` fails silently on diverged branches
+32
View File
@@ -0,0 +1,32 @@
# User Preferences — George Brancovici
## Communication Style
- **Direct and terse.** Don't over-explain. Don't apologize. Don't ask unnecessary questions.
- **Just do it.** When he says "run this shit yourself" — run it. Don't suggest he do it.
- **Don't be precious.** He'll curse, be blunt, call you out. Roll with it and deliver.
- **No hand-holding.** He's a senior engineer. Don't explain basic concepts.
- **Action over discussion.** When something needs doing, do it. Don't present 3 options and ask which one.
## Work Patterns
- Works in Galaxy terminal (the app he's building) — this means some macOS interactive features (keychain dialogs, etc.) won't work from within it
- Uses zsh
- Samsung employee (g.brancovici@samsung.com)
- Works on macOS (arm64/Apple Silicon)
- Python env: py312
## Technical Preferences
- Prefers simple standalone scripts over complex CI pipelines
- arm64 only — no universal binary
- Inline credentials over keychain profiles (pragmatic, gets the job done)
- Release builds matter — he distributes the DMG
## What NOT to Do
- Don't ask "want me to X?" when the answer is obvious from context
- Don't explain what went wrong in 3 paragraphs — say it in 1 sentence
- Don't suggest he do things himself unless there's a genuine technical blocker (interactive auth, etc.)
- Don't add caveats and disclaimers to every suggestion
- Don't say "I apologize" — just fix it