Open questions¶
Two lists: Spikes (facts to verify by running something; each has a copy-pasteable command and states what changes depending on the answer) and Decisions (preferences only you can settle). Spike results go to docs/spikes/<topic>.md; close the item here with a link.
Spikes¶
S1 — Does headless agy -p expose an image-generation tool? — closed, see docs/spikes/antigravity.md¶
- Verify:
agy -p "reply with the single word ok" --output-format stream-json | jq -r 'select(.event=="init") | .init.tools[]' - Result: yes —
generate_image, one of 57 tools listed in theinitevent (agy 1.2.6).AntigravityProvideris viable, so ADR 0013 moves to Accepted and P3.4 is unblocked.
S2 — Output path control — closed, see docs/spikes/antigravity.md¶
- Verify: prompt the tool to save to an exact absolute path under
--add-dir, then inspect that directory and~/.gemini/antigravity-cli/scratch. - Result: not controllable.
generate_imagetakes no path parameter; the image lands in~/.gemini/antigravity-cli/brain/<conversation_id>/<ImageName>_<epoch_ms>.jpg. The--add-dirtarget andscratch/both stayed empty, so the third-party "scratch" report is wrong for 1.2.6. The path is still deterministic because the envelope returnsconversation_id, so the adapter globs that directory and copies into the asset store.
S3 — Output format and size — closed, see docs/spikes/antigravity.md¶
- Verify: generate with and without aspect-ratio wording, then read
Image.open(...).format/.size. - Result: always JPEG. The words "16:9 widescreen" reliably give 1376×768 (5 of 5); stating exact pixels changes nothing; omitting the ratio gives an unpredictable size (1024×1024 and 1264×848 both seen), so the wrapper must always state the ratio.
1376/768 = 1.792, slightly wider than true 16:9, so a small crop is always needed. Confirms the native size D2 anticipated: reaching the 1920×1080 default needs a 1.40× upscale inimaging/fit.py.
S4 — Reference images — closed, see docs/spikes/antigravity.md¶
- Verify: name a reference image's absolute path in the prompt with
--add-dir, then inspect.step_update.tool_info.parameters. - Result: prose only. The agent
view_files the reference and describes it into thePrompt;generate_imagehas no image parameter, so the bytes never reach the image model. Palette transfer is nonetheless good (reference(250,240,20)→ generated dominant(246,233,14)), but there is no image-to-image conditioning and two runs will not be pixel-consistent.supports_reference_image = False; batch consistency rests on prompt-only style anchors, which strengthens ADR 0008.
S5 — Permissions — closed, see docs/spikes/antigravity.md¶
- Verify: run an image generation without
--dangerously-skip-permissionsand with nopermissions.allowentry. - Result: no grant needed. Exit 0,
SUCCESS, empty stderr, no soft-deny notice. Supersedes D4:providers.antigravity.skip_permissionsdefaults tofalseand nopermissions.allowrule is required.
S6 — Exit codes and status matrix — closed (except 6a), see docs/spikes/antigravity.md¶
- Verify: (a) unauthenticated profile; (b)
--model does-not-exist; (c)--print-timeout 1s. - Result: (b) exit
1with a cleanERRORenvelope naming the available models. (c) exit0withstatus: SUCCESS, an emptyresponse, zerousageand a stderr notice — a timeout reports success, so it must map toProviderTimeoutError(retryable) before the "SUCCESS but file missing" row, or every long generation permanently fails its batch item. (a) not verified: overridingUSERPROFILE/HOMEdid not isolate the cached credentials, and confirming it would mean signing the maintainer out of Antigravity. Theauthentication requiredbehaviour stays documentation-only andProviderAuthErroris mapped defensively.
S7 — Rate limits / quota — closed, see docs/spikes/antigravity.md¶
- Verify: five sequential generations, then two in parallel; then
agy -p "/usage". - Result: no throttling. Five sequential and two concurrent runs all succeeded; the concurrent pair finished in ~17 s each versus 32–40 s sequentially, so forcing
max_concurrency = 1costs wall-clock time without protecting a limit. Seven generations moved the five-hour quota99% → 98%and left the weekly figure unchanged at71%./usagereturns a parsable tab-separated report with reset timestamps.
S8 — Cost / usage fields — closed, see docs/spikes/antigravity.md¶
- Verify: compare
usagefor a text-only run against an image run; look for a credit field. - Result: tokens only. Five keys, no credit/price/currency.
total_tokens = input + output;cache_read_tokensis excluded from the total. An image run costs ~3.5× a trivial text run (67,706 vs 19,246 total tokens).Costcan record tokens andduration_secondsonly, so the P8.4 report is limited to tokens plus the/usagepercentages.
S9 — graphify on Windows with uv — closed, see docs/spikes/graphify.md¶
- Verify:
uv tool install graphifyy && graphify extract . --code-only && graphify cluster-only . --no-label - Result: working seamlessly under Windows with uv; generated
graphify-out/committed to repo.
S10 — terminal image preview with rich-pixels in Windows Terminal — closed (except legibility in Windows Terminal), see docs/spikes/terminal-preview.md¶
- Verify (run in Windows Terminal, the primary development terminal):
Replace the synthetic fill with a real thumbnail once one exists. The tile is sized to half the terminal width, which is what one cell of the
uv run --with rich --with rich-pixels --with pillow python -c "from PIL import Image; from rich.console import Console; from rich_pixels import Pixels; c=Console(); Image.new('RGB',(1920,1080),(200,40,40)).save('preview.png'); w=max(c.width//2-2,20); c.print(Pixels.from_image_path('preview.png',resize=(w,w*9//16)))"--columns 2grid gets. Confirm the block-character output is legible — that the title and overall composition are recognisable, not that it is pixel-accurate. Note thatrich.columns.Columnsdid not lay twoPixelstiles side by side in a smoke test, so P5.4 must verify the real grid layout rather than assume it. - Changes: the
_render.preview()helper and P5.4. If unusable,previewprints the asset paths plus thethumb exporthint andthumb showfalls back to a table (ADR 0002). - Result: tiles render, and
Table.gridgives a real two-column grid. Under a Linux pty at 100 columns (not Windows Terminal) the command above printed 14 lines × 48 columns of▄in truecolor (38;2;200;40;40;48;2;200;40;40).preview()with a red and a blue tile printed 14 pixel lines shared by both colours plus a caption line, whilerich.columns.Columnsstacked the same tiles (red lines 0–13, blue 14–27), so the grid usesTable.grid. The path-table fallback with thethumb exporthint was confirmed underTERM=dumb NO_COLOR=1. Not verified: legibility of a real thumbnail in Windows Terminal; that stays the manualthumb showacceptance check (Phase 5 spec, P6.x).
S11 — yt-dlp flat playlist fields under extract_flat — closed, see docs/spikes/ytdlp.md¶
- Verify:
uv run --with yt-dlp python -c "import yt_dlp,json; print(sorted(yt_dlp.YoutubeDL({'extract_flat':'in_playlist','quiet':True}).extract_info('<playlist url>', download=False)['entries'][0]))" - Result:
id,title,duration,channel_id,channel,url,thumbnails,view_countare always present (183/183 entries).playlist_indexis absent — this spike assumed it would be there — soPlaylistItemMeta.positioncomes from enumeration order.descriptionis likewise absent from every entry, whiletimestamp,availabilityandlive_statusare present but alwaysNone— so a flat extract cannot filldescriptionorpublished_at; those need a per-video full extract.
S12 — Python 3.15 GA timing¶
- Verify: python.org release page; GA expected October 2026.
- Changes: add
3.15to the CI matrix after GA;requires-pythonstays>=3.14.
S13 — prettier via pre-commit on Windows — closed, see docs/spikes/tooling.md¶
- Verify:
pre-commit try-repo https://github.com/pre-commit/mirrors-prettier prettier --files README.md; confirm Node bootstraps without a repopackage.json; pick the pinnedrev. - Changes: if the mirror is archived or fails, fall back to
mdformat(uv run --with mdformat mdformat) for Markdown only and drop YAML/JSON formatting.
S14 — zensical build of the ADR/spec tree — closed, see docs/spikes/tooling.md¶
- Verify:
uv add --dev zensical && uv run zensical build; confirm mermaid fences render (check whether apymdownx.superfencescustom fence is required inzensical.toml); record the exact version. - Changes:
zensical.tomlcontents indocs/specs/phase-0-infra.md.
Decisions¶
All decided 2026-09-19 by the maintainer, taking the recommended option in each case.
| ID | Decision |
|---|---|
| D1 | Tool name thumbforge (package, command, repo khiladisngh/thumbforge). |
| D2 | Default output size 1920×1080; imaging/fit.py upscales from the provider's native 16:9 when smaller. S3 measured that native size as 1376×768, so the upscale is 1.40× and a small crop is needed (1.792 vs 1.778). |
| D3 | Type checker pyright, strict on src/. |
| D4 | ~~Antigravity runs with --dangerously-skip-permissions by default~~ — superseded by spike S5, which measured generate_image succeeding with neither the flag nor a permissions.allow rule. providers.antigravity.skip_permissions now defaults to false. The decision's premise (that the image tool is permission-gated) did not hold. |
| D5 | GitHub khiladisngh/thumbforge, CODEOWNERS @khiladisngh, MIT license, PyPI trusted publishing (release.yml, environment pypi; publisher to be configured on PyPI before the first tag). Docs on GitHub Pages at https://khiladisngh.github.io/thumbforge/. |
| D6 | Overlay default: bold-title = title only; series-parts = title + "Part N" badge. Bundled font Inter (OFL). |
| D7 | YouTube Data API source kept as the Phase 8 optional extra thumbforge[api]. |