Independently gated default flips: artifact absence, bound Web settings, mind maps, download prefetch

Author: teng-linCreated Sep 6, 2026Updated Sep 6, 2026
Labelsenhancementdo-not-implement-yetP2

Parent: #2376.

These are behavior-default / signature-removal changes with their own notice windows. Additive APIs already exist on main (after #2375). This issue is only the later flip.

They are not authorized just because v1.0.0 ships. If their notices have not been in a stable release for one MINOR, keep the 0.x default and schedule a later breaking release.

Committed ledger: docs/deprecations.md “Independent C3/C4/C5 migration rows” (the section title is historical; implement from the row text below).

1. Artifact exact lookup: stop treating an incomplete read as “missing”

0.x today

  • artifacts.lookup() / list_with_status() already distinguish FOUND / MISSING / UNKNOWN and listing completeness.
  • First-party CLI get/download use lookup.
  • Public get() / get_or_none() still project an incomplete no-hit as ArtifactNotFoundError / None and emit artifact_ambiguous_absence only when note-backed mind maps were unavailable. Complete misses and hits stay silent.
  • Android get_prompt(..., require_complete=False) (the default) still goes through that legacy get_or_none path, so a notes outage can look like “no such artifact.” require_complete=True is already strict. Web get_prompt reads Studio directly and already raises on a real miss; it must not grow a redundant aggregate preflight.

Flip (after the warning ships)

  • get() / get_or_none() delegate fully to authoritative lookup: incomplete no-hit is not absence (UNKNOWN → existing RPCError with a sanitized incomplete-read message, not 404)
  • Android get_prompt default becomes require_complete=True (or the default path becomes the strict one)
  • Studio-only polling (poll_status, wait_for_completion) stays Studio-only; do not introduce a notes dependency there

Registry key: artifact_ambiguous_absence. Source-registered; not in a published release.

2. Web request settings: freeze at construction instead of rereading the environment

0.x today

  • WebBackendConfig.request=WebRequestOptions(...) is additive. Omitting it (None) keeps dynamic per-lookup environment resolution (NOTEBOOKLM_BASE_URL, language, build label, transport, recovery command/shell). Documented in docs/configuration.md.
  • First-party CLI/MCP/REST factories already opt in to bound policy.
  • Two bound clients with different endpoints/recovery commands must not share cold-refresh flights or treat another policy’s success as their own.

Flip (after a stable preview/notice — this row has no Python DeprecationWarning today)

  • Default (omitted request=) captures process defaults when NotebookLMClient(...) / from_storage(...) is called, not on every RPC
  • Bound clients inject that host/language/transport/recovery policy into homepage, refresh, batchexecute, streamed chat, upload, asset downloads, and notebook/share URL formatting
  • Do not freeze live cookies/account state; dispatch still uses a fresh auth snapshot
  • Android primary config stays independent; do not invent a sidecar bound-request mode if the sidecar is being deleted (#2378)

If this notice has not shipped, keep dynamic defaults through v1.0.0.

3. Web interactive mind maps: raise on FAILED/REMOVED instead of hydrating

0.x today

  • mind_maps.generate(..., failure_policy="raise"|"legacy") exists. Default "legacy": Web continues hydration after a waited FAILED/REMOVED completion and warns mind_map_legacy_terminal_hydration only when it actually does that. Android already raises in legacy mode.
  • First-party waited interactive generation already passes "raise".
  • Completed, non-waited, note-backed, and explicit strict calls stay silent.

Flip

  • Default failure_policy becomes "raise"ArtifactNotReadyError on FAILED/REMOVED before hydration
  • Do not silently start rejecting the Web interactive language option. Web still accepts it and does not encode it; Android encodes it. A future “reject ignored options” change needs its own concrete row. None is approved.

Registry: mind_map_legacy_terminal_hydration. Source since=0.9.0; unshipped.

4. Raw download-prefetch keywords

0.x today

  • Typed path: artifacts.prepare_downloads(request) then artifacts.download(selection, path). Selections are bound to client/notebook/generation and do not carry raw rows, protobufs, or signed URLs.
  • Nine public download_* methods still accept unused raw-prefetch kwargs artifacts_data, artifacts, mind_maps. Supplying a non-None value warns artifact_raw_download_prefetch. First-party callers stopped using them.

Flip

  • Remove those keywords from the public signatures (one API-compat allowance per method/keyword the audit reports)

Registry: artifact_raw_download_prefetch. Unshipped.

Out of scope

  • Re-implementing lookup, WebRequestOptions, failure_policy="raise", or prepared downloads
  • Treating “ignored Web mind-map language” as something this issue may start rejecting
  • MCP/REST verb parity
  • Combining these flips with #2377 / #2378 just to share a version number if their gates are unmet