Where to pick up
Written 2026-09-24 at commit 7e211697 on main; updated 2026-09-25, 2026-09-26 and 2026-09-27. On 2026-09-26 the code moved to github.com/retail-cortex/blitz with a fresh history (initial commit 53f8c53): the commit hashes below, and the python-final and v0.1.0 tags, exist only in the former repository, rmcguinness/code_puppy. Read this first when resuming. the roadmap has the detail behind each finished item, and Manual verification has the checks that need a person.
CI: green on bcc06f7 (run 36848932128: Linux, macOS, reproducible), after the fixes below; before them, green on 8c31870. The run on 904a46a failed on a data race the race detector caught once in TestRemoteTaskRequests (a published task event pointed at a variable then reused, pkg/engine/runtime/tasks.go); fixed in 8017779. The run on that failed on macOS: a test hung because the REPL’s prompt-time Ctrl+C watcher, stopped as a turn started, could still take the Ctrl+C meant for the turn (cancelOnSignal now waits for its watcher to go); fixed in the commit after this line. Check the latest with gh run list --branch main --workflow ci --limit 3 and gh run view <id> --log-failed. Since 2026-09-30:
- Coverage went from 76.5% to 94.9% of the Go code on Linux, with the floor at 94%, and the page’s TypeScript is measured (17% of lines and branches; floor in
vite.config.ts). The work found and fixed about twenty bugs, logged in the commits and, for the security ones, in the security log. - Tests pass without an OS sandbox (
configtest.RunTools,BLITZ_SANDBOX_SHELL=autoin.bazelrc), with test sizes that fit and the big Go suites in shards. - Security: the sandbox is required on Linux,
blitz security fix-apparmorand the desktop’s Allow bubblewrap lift AppArmor’s restriction for bwrap alone, ADC is shared with commands only on request, theantsign-in is hidden, and a sandbox escape through the ADC copies’ sweep is fixed (SEC-2026-08). - Desktop: the
.debdepends onbubblewrap; install theblitzcommand from Settings, make a folder a git repository from Changes, a readable “/” menu, a white tray bolt, no maximum window size.
Tested by the owner (2026-10-01): the Linux sandbox checks (a, b and c in their note: blitz security fix-apparmor, the desktop’s notice and Allow bubblewrap, against a real AppArmor) on an Ubuntu instance.
Next, in order:
- The same on a Chromebook (ChromeOS’s Linux container, Debian): whether bubblewrap runs there at all (
blitz security), and the.debinstall (manual verification, The sandbox required on Linux and Fixing it; Chromebooks). - Pin the Linux jobs to
ubuntu-24.04before GitHub movesubuntu-latestto Ubuntu 26 (2026-10-19). - The security log’s open items, SEC-2026-O1 (
fix-apparmorpiping the profile to root) first. - Tests for the page’s components (its coverage is 17%), and Go branch coverage (gobco), suggested but not set up.
- Smaller:
blitz workers runs <unknown>says “hasn’t run yet” rather than that there’s no such worker;TestEngineCapsParallelToolCallsnow compares the unlimited run with the one-at-a-time run instead of a fixed 1.1 s, which failed on a loaded machine.
Picking this up on another machine. Everything is in the repository; nothing lives only on the machine it was done on.
- Clone
git@github.com:retail-cortex/blitz.git, then follow building: Bazelisk asbazel, and on Linuxgit bubblewrap. On Ubuntu 24.04,blitz security fix-apparmor(or thesysctlthere, for the gVisor tests too) lets the sandbox tests run; without it they skip, and everything else passes (BLITZ_SANDBOX_SHELL=autoin.bazelrc). gh auth loginto read CI’s logs (gh run view <id> --log-failed): the API won’t give them anonymously.- Commits since 2026-09-30 are unsigned (the owner’s GPG key couldn’t be unlocked from the agent’s shell);
commit.gpgsignis unchanged. - A local
.debis version0.0.0: install it withsudo apt install --reinstall ./blitz-desktop_amd64.deb. - Before a commit:
tools/check_format.sh, andtools/coverage.sh --config=raceas CI runs it (floor 94%); the page has its own floor (bazel test //apps/desktop/web:coverage). Docs-only commits carry[skip ci], and go before the code commit when pushed together, since CI runs on the last commit only. - Security problems go in the security log.
The first release candidate, v0.1.0-rc.1, is ready to tag but blocked on GitHub billing.
mainis at1930d13. Both CI build jobs passed on it (tests, coverage 78.6% on Linux against the 78% floor, every check), and the Linux and macOS archive checksums are identical. Only thereproduciblejob (run36369532092) failed, twice, without starting: “recent account payments have failed or your spending limit needs to be increased”. Every workflow is blocked until the organization’s Settings › Billing & plans is fixed.- Checked locally with a throwaway tag: the stamp reads
0.1.0-rc.1inblitz,blitzdandInfo.plist; each archive holdsblitz,blitzd,blz, README, LICENSE, NOTICE and THIRD_PARTY_NOTICES;sign_macos.shbuilds the unsigned disk image (95 MB). - Tag signing is off for this repository only (
git config --local tag.gpgSign false; the owner’s global setting signs, and needs a pinentry prompt).
Next, in order:
- Once billing is fixed: re-run the failed job (
gh run rerun 36369532092 --failed), thengit tag -a v0.1.0-rc.1 -m "Blitz 0.1.0-rc.1" 1930d13 && git push origin v0.1.0-rc.1. The release workflow makes a draft release: five archives with SBOMs, signedchecksums.txt, the macOS disk image (ad hoc signed: no Apple Developer ID yet; the owner has applied), and.debs for x86-64 and ARM, each with a cosign bundle. - Check the draft against the README:
cosign verify-blobandsha256sum -c, archive contents, versions. The owner tests the Linux binary; send them the download-and-verify commands and what to try (--version,license,doctor, a short session). - Pin the Linux jobs to
ubuntu-24.04: GitHub movesubuntu-latestto Ubuntu 26 from 2026-10-19 (WebKitGTK 4.1, user namespaces for the sandbox). sign_macos.sh:hdiutil createis deprecated in favour ofdiskutil image.- The owner may enable private vulnerability reporting (Settings › Security);
docs/CONTRIBUTING.mdalready points reporters there. - proto-gen-md-diagrams (the owner maintains it): upstream fixes for escaping comments, skipping the license header and optional front matter would let
docs/api_pages.shgo. The owner is checking the repository’s state first. - Coverage: see Resume here (2026-10-01) above.
Roadmap items 1–22 are done and committed, and item 23 (the desktop app) is in progress; each has its own commit:
| Commit | Change |
|---|---|
383ab847 |
Per-file locks for parallel edits; refuse to write a file that changed during approval |
ae509e39 |
Earlier work: Anthropic provider, workspace-scoped sessions, /compact, MCP prefixes/agents, saved forged tools, web search, pricing, i18n, images |
bd0a0bb5 |
slog diagnostic log + opt-in OpenTelemetry (content stripped), chained turn traces |
04bd68dc |
post_tool hooks on an ordered background worker |
b13ba38d |
Retries for every provider, stall timeouts, MCP stdio restart + circuit breaker, parallel tool cap |
72acd1c4 |
Steering a running turn (type or Ctrl+T) |
4d1f31c5 |
!cmd, enforced /plan and --plan, /tools, /show |
042263dd |
Ordered model fallback across providers; Ollama base-URL fix |
7a06b7a6 |
Default Gemini model → gemini-3.8-flash |
7e211697 |
Per-agent models ([agent_models], /pin_model, /unpin) |
b652f263 |
Per-model settings ([model_settings], /model_settings) |
36c2758b |
Removed the committed editor swap file; *.swp ignored |
957c08b9 |
Named session snapshots (/session save, /session load <name>, --resume=<name>) |
9eeab5e6 |
Google search via Gemini grounding; /search web, /search session |
155d595b, a5f34180, e2f02959 |
Item 22: Castor skill definitions and [skills.policy]; the gVisor/OS script sandbox; environments, run_skill_script, /envs |
(the commit removing python/) |
Go-only repository: Python removed (tag python-final), Go at the root, workflows ci.yml and release.yml, Apache 2.0 with NOTICE, planning docs in .agents/ |
1370b80f |
Side questions (/btw) |
56a870a4, dce9baa9, c239dfb8, f318498d |
Dependabot and a macOS release note; pinned release tools, GOTOOLCHAIN=local, a cross-host reproducibility check; project-layout with code in internal/; actions upgraded (checkout v7, setup-go v7, Node 24) |
8ce5c642 |
ROADMAP item 23, phase 2: engine.Open and engine.Workspace replace cmd’s buildEnv |
75630f18 |
Phase 3: Workspace.Run and Steer, one turn lifecycle for the REPL and one-shot runs |
e657a7bd |
Phase 4, agents and models: typed operations for /agents, /agent, /model, /pin_model, /unpin, /model_settings, /set |
ef91966a |
Phase 4, sessions: /session list/new/load/save, /resume, /rename |
8bbe0b94 |
Phase 4, checkpoints and approvals: /undo, /checkpoints, /diff, /approvals |
5bf56f4c |
Phase 4, skills, envs, MCP and tools: /skills, /envs, /mcp, /tools |
4ddbb783 |
Phase 4, the rest: /cost, /context, /compact, /memory, /locale, /sandbox, /attach, /paste, /search; tui.App reduced to the workspace and terminal state |
900c1b96 |
ROADMAP item 23 replanned: one service per user, CLI attaches, Connect + buf |
3fb181cd, af7cad97 |
Phase 5: api.Event instead of ADK events for every client; the prompt is recorded before steering can start |
42aaf41b |
Phase 5b: per-workspace state, no dependence on the working directory |
f9a6e7bf |
ROADMAP item 24 planned: workers |
d8c08d91 |
Phase 6: the service API as protos, buf, generated Go and Connect code |
2e4cb2c0, a6ed23d6, a926faa6 |
Phase 7: apps/service/internal/server, approvals over the stream, blitz serve, the workspace lock |
26e261cd, d969c75f, d5562753 |
Phase 8: api.Backend, pkg/client, the CLI attaching to the service, --local |
31531764, (the commit adding pkg/engine/workers.go) |
Item 24a–b: worker definitions, schedules, permissions (ApprovalRequest.Targets); enabling pinned to the hash, [workers.policy] |
(the commit adding pkg/engine/session/title_test.go) |
Session names from the first prompt, /rename, terminal title, resume hint on exit |
bazel test --config=race //... passes (vet and staticcheck run in every compile), and so does bazel run //tools:check_deps.
- Gemini 3.8 Flash price (handled). The introductory $0.75 / $3.75 / $0.075 per 1M tokens ends on 2026-12-31.
config.PriceChangesswitchesgemini-3.8-flashto $1.50 / $7.50 / $0.15 from 2027-01-01 (UTC) when the configuration loads, so no code change is due then; a long-runningblitz servepicks it up at its next restart. Before a release in 2027, check https://ai.google.dev/gemini-api/docs/pricing and fold the change intoDefaultPricing.
Priority (2026-09-26, owner’s decision): close feature gaps before adding new features. The gaps are specified as requirements in specs/spec_backlog_026.md (Blitz’s own) and specs/spec_parity_027.md (against Claude Code, Antigravity CLI and Antigravity; §14 gives the order; §12 records the five conflicts with earlier decisions, decided below). Specs 001–025 describe current behaviour; move requirements into them as gaps close.
-
Release readiness is done (roadmap item 27): licensing, comments, specs, this site, the README, contributing, owners, and coverage in CI. Coverage’s weakest packages (see coverage) are where tests are most needed; raise
tools/coverage/floor.txtas it rises. -
ROADMAP item 23 is done in a first version: the per-user service (
blitzd,service install), the proto API, the CLI attaching to it, workers (item 24), and the desktop app (now the Electron app,bazel build //:mac-app). Next, in order: run MANUAL_VERIFICATION sections 36–37 (the service, workers and the app need a person, and some checks are 💲); then the known gap of workers’ edits joining/undo(ROADMAP 24c). An attached CLI’s process list and!cmdaudit are done (2026-09-29, CL-04). The app’s slash commands, Markdown, images, notifications, translation and release job are done (2026-09-27, branchdesktop-polish); its signing is item 3. -
Manual verification (needs a person). Nothing in
MANUAL_VERIFICATION.mdhas been run yet. It covers real providers (💲 = paid calls), terminal behavior, the macOS and Linux sandboxes, MCP, steering, fallback and pinning. Record results in the file; any failure becomes the next task. -
Name the release archives’ macOS binaries (spec_monorepo_028 §5): they have their own UUIDs but are signed
a.outby Go’s linker; build them on the macOS runner andcodesign --identifier, or sign with rcodesign on Linux, keeping the archives reproducible. -
Sign and notarize the desktop app (needs an Apple Developer Program membership). The release job (
release.ymldesktop, spec_release_025 REL-20–26) signs ad hoc and warns until these repository secrets exist (Settings › Secrets and variables › Actions):MACOS_CERTIFICATE: a Developer ID Application certificate with its private key, exported from Keychain Access as.p12, thenbase64 -i cert.p12 | pbcopy;MACOS_CERTIFICATE_PASSWORD: the.p12’s export password;DESKTOP_SIGN_IDENTITY: the certificate’s name,Developer ID Application: <name> (<TEAMID>)(security find-identity -v -p codesigning);NOTARY_KEY: an App Store Connect API key (Users and Access › Integrations › Team Keys, role Developer), the.p8file’s text;NOTARY_KEY_IDandNOTARY_ISSUER: that key’s ID and the issuer ID shown on the same page.
To try it locally first: with the certificate in your keychain and the
.p8on disk,bazel build --config=release //apps/electron/packaging:Blitz_arm64.app(orBlitz_x64.app), thenDESKTOP_SIGN_IDENTITY=… NOTARY_KEY_PATH=… NOTARY_KEY_ID=… NOTARY_ISSUER=… apps/electron/packaging/sign_macos.sh "$(bazel cquery --config=release --output=files //apps/electron/packaging:Blitz_arm64.app)" <version> Blitz.dmg. Then tag a release and run MANUAL_VERIFICATION §18’s desktop checks. Neither the signed path nor the release job has run yet; ifgh release uploadcan’t find the draft release by its tag, pass the release’s ID instead.The CLI archives stay unnotarized (the release job could sign their macOS binaries with the same certificate and key, and notarize them in a zip); until then the release notes (
.github/release-footer.md) and the README explain clearing the quarantine flag. Dependabot (.github/dependabot.yml) keeps the pinned action SHAs current.~/.gnupg/gpg-agent.confnow points at GPG Suite’spinentry-mac; the next tag will show whether tag signing works. -
Skill scripts, follow-ups (ROADMAP item 22 is done: Castor definitions,
[skills.policy], the gVisor/OSScriptBox, environments,run_skill_script,/envs):- TypeScript scripts;
- scripts that write the workspace directly, with snapshots;
requires-pythonwith uv-managed interpreters;storage_uriand resources;- running the opt-in real-install tests in CI (
BLITZ_PYENV_TESTS=1); - adding a network field to Castor’s proto, instead of
custom_hints.network.
-
Optional: reasoning settings per model. Python’s
/model_settingsalso setsreasoning_effort, extended thinking and budgets. The Go wrapper (pkg/engine/runtime/settings.go) is where they’d go, mapped to genaiThinkingConfig, which each adapter translates differently. -
Optional, from the Antigravity review (ROADMAP, “Antigravity CLI review”):
/copy(last reply to the clipboard, with OSC 52 over SSH),--add-dir <path>at startup,/grill-me(the agent interviews you before coding), and/fork [n](branch a new session from an earlier turn).
-
The product is Blitz (2026-09-26), renamed from Code Puppy: binary
blitz(withblzas a symlink), modulegithub.com/retail-cortex/blitz, proto packageblitz.v1,~/.blitz,.blitz/in workspaces,BLITZ.md,BLITZ_*variables, the[blitz]config section, the default agentblitz,Blitz.app(dev.blitz.desktop), the login itemdev.blitz.service/blitz.service. A clean break: nothing under the old name is read or migrated.NOTICEanddocs/content/about/history.mdkeep the attribution to Mike Pfaffenberger’s Code Puppy. The repository moved toretail-cortex/blitz(2026-09-26); the remote, the README’s and.goreleaser.yaml’s cosign identity now name it, and releases made before the move verify against the former repository’s identity. The tone pass is done (no mascot; status marks ✓ ✗ ! ↳ only; a one-line banner andagent ›prompt; persona-free agent prompts;qa-kittenisqa;puppy_name/owner_nameand the legacypuppy.cfgloader removed). A deliberate proto break is declared with aBreaking-API: <why>line in the commit message, which CI’sbuf breakingstep honours.blitz exec <prompt>is the explicit one-shot form (flags shared with the root command; no prompt is a usage error), and the README opens with the Blitz lore, with claims kept to what exists. Not done: ablz refactorcommand (to be designed), and the Sam Walton line, left out pending a source (his famous bird dog was Ol’ Roy). -
No shared event bus. Considered for steering and dropped: audit, hooks and traces are fed from engine callbacks, and steering didn’t need a bus.
-
Steering rides on tool results (
message_from_user), because ADK model callbacks can’t add session events (Session()returns nil there). -
Each turn is its own trace root. Turns are linked to the previous turn and tagged
gen_ai.conversation.id; the previous turn’s traceparent is kept in session metadata aslast_turn. A session is never one long trace. -
Content is never exported by default. The ADK puts tool arguments and results on every
execute_toolspan, sopkg/observabilityfilters them before export. OTel providers are built here, not withadk/telemetry.New, which adds its own unfiltered exporter. -
The Python implementation is gone (2026-09-26): the Go code is the repository root, and
python-finaltags the last commit with Python (in the former repository’s history). Don’t reintroduce a second implementation. -
Not ported from Python:
/truncate(use/compact) and/tutorial. Reasons are in ROADMAP item 14. (/cdwas also left out then; it is now planned, see below.) -
Parity decisions (2026-09-26, owner), replacing earlier rejections; details in specs/spec_parity_027.md §12:
bypasspermission mode instead of--dangerously-skip-permissions: entered only with--permission-mode bypass, and it refuses to run unless the OS sandbox is active; deny rules and blocked paths still apply.blitz.auto_approvebecomes this mode. Prompt fatigue is mainly addressed byaccept-editsand a reviewing-modelautomode./cdis adopted: it closes the workspace and reopens the target throughengine.Open(lock, roots, sandbox, memory, MCP, project config) and moves the session; nothing is patched mid-session.- Project configuration is adopted in layers:
.blitz/settings.tomlmay tighten without asking; anything that runs code or loosens policy loads only after trust pinned to the workspace path and a content hash; credentials, endpoints, telemetry targets and sandbox loosening are never read from a project. This replaces “configuration only from trusted locations” as the rule for project files; user configuration still loads only from trusted locations. - The REPL stays line-based, with inline arrow-key pickers; full-screen views go in the desktop app.
/boostand agent teams are deferred until background sub-agents and worktrees exist.
-
fallback_modelsswitches only before any output and never on cancellation. Breakers are asked just before each attempt (regression tests guard this). -
Model settings are applied per built model, not per agent.
newProviderModelwraps every model, so each member of a fallback chain uses its own[model_settings]. Applying them innewLLMAgentwould give fallbacks the primary’s settings. -
Snapshots are never continued in place. Loading one (by name or ID,
/session load,/resume,--resume=) copies it to a new session, as Python’s/load_contextdoes, and--continueskips snapshots. -
No Anthropic server-side web search (dropped by the user). No Google Custom Search JSON API: it shuts down on 2027-01-01, so
googlemeans Gemini grounding. -
/search webpre-approves exactly the URLs it hands over, for that turn only (tools.WithFetchGrants); everything else the agent fetches still asks. -
Telemetry and OTel need one provider per process: the ADK binds its tracer to the first global provider.
-
Bazel, in a monorepo (2026-09-27, owner’s decision; reverses “No Bazel” of 2026-09-26). The engine had bled into the front ends; the repository is now three apps over shared packages (
apps/,pkg/,pkg/engine/), and Bazel 9.2 builds and tests everything: Go, the desktop page, the protos (generated, never committed) and the packages. The service is its own program,blitzd. Make, GoReleaser and the tools module are gone; tools come through Bazel, and host tools are a last resort (bazel run //tools:tidyfor dependencies). The Linux desktop build uses the system’s GTK through pkg-config, deliberately not hermetic. specs/spec_monorepo_028.md. -
Superseded 2026-09-27 by the monorepo decision above. Layout follows golang-standards/project-layout (2026-09-26):
apps/cli(CLI/TUI, pure Go) andapps/desktop(Wails, cgo, built on each OS); code ininternal/,pkg/only for deliberately public APIs; frontend inapps/desktop/web, packaging inbuild/. Slash-command logic moves fromtuito a UI-agnosticpkg/engineshared by both UIs. -
One engine service per user (2026-09-26, replacing “a process per tab”): the service (
blitz serve; since 2026-09-27 its own program,blitzd) hosts every workspace over Connect on a Unix socket; the CLI attaches when it’s running, else runs in-process. Scheduled workers (item 24) run in it. See ROADMAP item 23. -
The module path is
github.com/retail-cortex/blitz, matching the repository.
Conventions, layout and commands: Development.