Guidance for Claude (and anyone else) working in this repository.
App Dev For All builds Code on the Go, an Android IDE aimed at users with no or limited internet access (code: appdevforall/CodeOnTheGo). To support that, Java/Kotlin/Android API documentation is bundled into the app as a single SQLite file — the documentation database — rather than fetched from the web.
The documentation database serves two distinct features in the IDE:
- Tooltips (Tier 1/2). When a user selects a keyword/symbol in the code editor, a dialog
shows short (Tier 1) and detailed (Tier 2) tooltip text if the selection matches an entry in
the DB. This lookup happens elsewhere in the CodeOnTheGo Android code (not in this repo, and
not in
WebServer.kt— see below). - Content pages (Tier 3). From a tooltip, the user can click through to a full documentation
page. Those pages (and other static content — HTML, images, PDFs) are served over HTTP by
WebServer.kt(CodeOnTheGo/app/src/main/java/com/itsaky/androidide/localWebServer/WebServer.kt), which runs inside the app and reads directly from theContent(and, as of recently,Templates/Bookshelf/BookCategories) tables of the same database.
This repository (OfflineDocumentationTools) is the collection of offline tools that build and
edit that database — it contains no part of the production Android app itself.
Alex's standing caveat, worth repeating at the top of every session: nothing in this repository is guaranteed to work against the current production database. The schema has moved forward (in the app / by hand) faster than the tooling in this repo has been updated. See "Schema: current vs. what this repo expects" below — that gap is the most important thing to understand before making changes here.
As of 2026-08-20
~/documentation.dbreports 2.0.0 inDocumentationDatabaseVersion("Add CompressionDictionary table", David) — a deliberately incompatible major bump. EverybrotliContent row is compressed against the shared 256 KiB raw LZ77 dictionary held inCompressionDictionary(id 1). Measured on that database: 0 of 24 sampled brotli rows decode with plain Brotli; all 24 requirebrotli -D. A dictionary stream and a plain one are not interchangeable, so anything reading or writingContenthas to go through the dictionary.No Python Brotli binding exposes a custom dictionary (the
brotlipackage has no such parameter;brotlicffidroppedBrotliDecoderSetCustomDictionaryin 1.2), so all three writers shell out to thebrotliCLI — which therefore has to be installed wherever the pipeline runs. Both workflows install it.
Writer Dictionary handling ProcessKotlinWebsiteJSON/populate_db.pyDictionaryCompressor+load_or_create_dictionary; trains one only if the table is absent/empty, and never retrains.ProcessKotlinWebsiteJSON/insert_optimized_media.pyReads the existing dictionary via load_dictionary; never creates one.scripts/sync_kotlin_stdlib_docs/sync_kdoc_json_to_db.pyDictionaryBrotli+load_compression_dictionary; falls back to plain Brotli only for pre-2.0.0 databases.Retraining an existing dictionary would orphan every row already compressed against the old one, which is why all three only ever read what is already stored.
migrate_content_to_dictionary_brotli.pyrecompresses any remaining plain-Brotli rows.Note also that
image/webp(id 26) andvideo/quicktime(id 28) now exist inContentTypes, so the workflows'INSERT OR IGNORE ... image/webpstep is a no-op against current copies.
scripts/migrate_tooltip_schema.py(ADFA-3305) rewrites the tooltip tables and declares 3.0.0:Tooltips(id, categoryId, tag)WITHOUT ROWID, keyed on(categoryId, tag);TooltipTexts(id AUTOINCREMENT, summary, detail);TooltipButtons(tooltipId, buttonNumberId, descriptionId, uriId)WITHOUT ROWID, keyed on(tooltipId, buttonNumberId); and each button string once inTooltipButtonDescriptionsandTooltipButtonUris. Code On The Go from CodeOnTheGo #2163 on reads only these tables, and refuses tooltips from a database declaring less.The same step stores every
Templatesrow Brotli-compressed againstCompressionDictionary, with no per-row marker: in 3.0.0 all templates are compressed, and the app always decodes them. Every other tool that reads or writes Templates expects them plain:populate_db.py,sync_javadoc_json_to_db.py,ProcessDocs/AndroidDocs/AndroidDocsToJson/load_android_json_db.pyandverify_android_json_db.py, and in open PRsminify_text.py(#44), thea/pages-to-templates step (android_pages_to_templates.py, #49) andhm_pages_to_templates.py(#43). On the master the templates stay plain. Some of these run on the copy that ships as well (the minify and thea/step do), so there every one of them runs before the migration. The order on that copy is: minify, row drops, Kotlin trim,a/pages-to-templates,migrate_tooltip_schema.py, PR #48'sremint_dictionary.py --seeds 4(which recompresses templates too in 3.0.0), thenrebuild_database.py --pack Content,TooltipTexts;hm_pages_to_templates.pygoes after thei/page steps it lists, before the migration like every other Templates writer. PR #48 has to merge no later than this step's PRs (#45, #50): the re-mint and verifier before it handle Content only, so they refuse a database declaring 3.0.0.
populate_db.py,sync_javadoc_json_to_db.pyandload_android_json_db.pyread and write both (ADFA-6740): below 3.0.0 they write plain templates, from it compressed ones (brotli -D -w 24, checked by decoding back, never large-window), and they leave a 3.x file at the version it declares. They refuse a major above 3, a format they do not know, before writing anything.docdb-studioreads and writes both shapes too (tooltips through the keyed tables, templates decoded and re-encoded with the dictionary), choosing by the declared major.The other tools still read and write only the 2.x shape:
check-tools(whose dailydocdb-regression-test.yamlrun selectsTooltipButtons.uriandTooltips.detail),sync_kdoc_json_to_db.py(step 5 ofbuild-kotlin-docs.yaml) andTooltipManager.py. Until they catch up the step runs on the copy that ships, after all of them, and never on the master database they edit; nothing converts 3.0 back. It needs thebrotliCLI on PATH.In the 3.0 shape
Tooltips.idmust be unique and name aTooltipTextsrow: a writer takes the id itsTooltipTextsinsert hands out, never one of its own. Nothing enforces it (aUNIQUE (id)index would cost about the 613 pages the conversion saves), and two rows sharing an id share one text, so deleting either key's text deletes the other's.
The schema below is what ~/documentation.db (Alex's current production copy) actually contains,
as of 2026-08-05 — predating the 2.0.0 bump described above, which additionally adds the
CompressionDictionary and DocumentationDatabaseVersion tables:
CREATE TABLE Languages (id INTEGER PRIMARY KEY AUTOINCREMENT, value TEXT NOT NULL UNIQUE);
CREATE TABLE ContentTypes (id INTEGER PRIMARY KEY AUTOINCREMENT, value TEXT NOT NULL UNIQUE, compression TEXT NOT NULL);
CREATE TABLE TooltipCategories (id INTEGER PRIMARY KEY, category TEXT NOT NULL);
CREATE TABLE TooltipButtonNumbers (id INTEGER UNIQUE); -- manually assigned display order
CREATE TABLE Content (
id INTEGER PRIMARY KEY AUTOINCREMENT, path TEXT NOT NULL, languageID INTEGER NOT NULL,
content BLOB NOT NULL, contentTypeID INTEGER NOT NULL, templateId INTEGER NOT NULL DEFAULT 0,
FOREIGN KEY (languageID) REFERENCES Languages(id), FOREIGN KEY (contentTypeID) REFERENCES ContentTypes(id),
UNIQUE('path')
);
CREATE TABLE Tooltips (
id INTEGER PRIMARY KEY AUTOINCREMENT, categoryId INTEGER NOT NULL, tag TEXT NOT NULL,
summary TEXT NOT NULL, detail TEXT NOT NULL, UNIQUE (categoryId, tag),
FOREIGN KEY(categoryId) REFERENCES TooltipCategories(id)
);
CREATE TABLE TooltipButtons (
tooltipId INTEGER, buttonNumberId INTEGER, description TEXT, uri TEXT,
FOREIGN KEY(tooltipId) REFERENCES Tooltips(id), FOREIGN KEY(buttonNumberId) REFERENCES TooltipButtonNumbers(id)
);
CREATE TABLE LastChange (documentationSet TEXT, changeTime TIMESTAMP DEFAULT CURRENT_TIMESTAMP, who TEXT);
CREATE TABLE Templates (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, content BLOB NOT NULL, UNIQUE('name'));
CREATE TABLE BookCategories (id INTEGER PRIMARY KEY AUTOINCREMENT, category STRING, description STRING DEFAULT '', UNIQUE('category'));
CREATE TABLE Bookshelf (contentID INTEGER NOT NULL, title STRING DEFAULT '', description STRING DEFAULT '',
bookCategoryID INTEGER, FOREIGN KEY (bookCategoryID) REFERENCES BookCategories(id), UNIQUE(title, bookCategoryId));
-- Triggers keep Bookshelf in sync when a .pdf row is added to/removed from Content.
CREATE TABLE PUCC_Students (...), PUCC_Classes (...), PUCC_Sections (...), PUCC_Professors (...),
PUCC_StudentAssignments (...), PUCC_ProfessorAssignments (...)
-- Unrelated to documentation tooling (confirmed by Alex) — ignore, leave as-is, do not
-- document or maintain further in this repo.Templates, BookCategories, and Bookshelf are not documentation cruft — WebServer.kt
actively depends on them. Its /pr/bs endpoint builds a JSON "bookshelf" payload straight from
Content + Bookshelf + BookCategories, looks up a template named 'bookshelf' in Templates,
and renders it with the Pebble template engine. More generally, any Content row with a non-zero
templateId gets its stored (decompressed) content run through the matching row in Templates as
a Pebble template before being served. This is a real, current feature of the shipped server, not
a placeholder.
In a database whose newest DocumentationDatabaseVersion row declares major 3 or later, every
Templates row is stored Brotli-compressed against the shared dictionary, with no per-row marker
(ADFA-3305). Only the ship-time copy is converted; the master database the tools here edit keeps
plain templates. remint_dictionary.py and verify_remint_dictionary.py read the version the way
the app does: from major 3 on they sample, recompress and verify the templates together with the
Content rows, and below it they leave the templates exactly as stored.
remint_dictionary.py trains a 768 KiB dictionary on up to 3,600 rows within 128 MiB by default
(ADFA-3305), where the first mint keeps 256 KiB on up to 900 rows within 32 MiB. On the 2026-10-19
ship-time database that saved 1.66 MB of file and 1.92 MB of .br; a large dictionary needs the
larger sample (with the small one, two of four 768 KiB seeds stored more than 256 KiB). Nothing that
ships re-mints yet: CodeOnTheGo's release compresses the master as it is, so today's release keeps the
master's 256 KiB dictionary. The new default applies to a re-mint run by hand and to the ship-time
pipeline once one exists. Of the workflows here, only the Android docs pair calls the re-mint, and #49
removes it. Measurements are in its docstring.
This repo writes Templates, but not Bookshelf or BookCategories. populate_db.py
(page.peb, nav.peb), sync_javadoc_json_to_db.py (javadoc.peb) and load_android_json_db.py
(the android-*.peb templates) write rows there and point the pages they write at them via
templateId; verify_android_json_db.py reads them; migrate_tooltip_schema.py compresses
every one for 3.0.0; and remint_dictionary.py and verify_remint_dictionary.py recompress and
compare them from 3.0.0 on (above).
insert_optimized_media.py reads and writes templateId too.
Bookshelf and BookCategories come from App Dev For All's plugin system, which writes into the
documentation database - the bookshelf feature from
appdevforall/bookshelf-plugin, now archived on
GitHub. Nothing here writes them, except that Content's AddBook trigger adds a Bookshelf row
for each .pdf path inserted (see migrate_content_to_dictionary_brotli.py). Concretely, relative
to the schema above:
| Piece | What it thinks the schema is | Consequence |
|---|---|---|
scripts/DocumentationDatabase.py (used by scripts/ingest.py, and hence by .github/workflows/publish-doc-db.yaml) |
Content / Languages / ContentTypes only, plus an optional ide_tooltip_table. Its constructor explicitly raises ValueError if it opens a DB containing any table outside that whitelist. |
This will refuse to open the current production documentation.db at all — it will list Tooltips, TooltipCategories, TooltipButtons, TooltipButtonNumbers, LastChange, Templates, BookCategories, Bookshelf, and every PUCC_* table as "unexpected." This is the single biggest blocker to reusing this script as-is. |
docdb-studio/SCHEMA.md / AGENTS.md (states the schema is "locked," no migrations) |
Content (no templateId, no UNIQUE(path)), Tooltips, TooltipButtons, TooltipCategories, TooltipButtonNumbers, LastChange (with a different shape: documentationSet/changeTime/who — this part does match current), plus a legacy ide_tooltip_table. Missing templateId, Templates, BookCategories, Bookshelf, PUCC_*. |
Closest of the three documented schemas to reality, but still out of date. docdb_studio.py's own "never change the schema" policy is itself now stale, since the live schema has already changed underneath it. |
check-tools/README.md's embedded schema (and by extension the mental model behind check-tools/db_health_checker.py) |
Content (no templateId, no UNIQUE(path)), Tooltips, TooltipButtons, TooltipCategories, TooltipButtonNumbers, and a third variant of LastChange (now/who). No Templates/Bookshelf/BookCategories/PUCC_*. |
The health checker's required-table check still passes (it only checks that its known tables exist, not that no others do). Since Bookshelf/BookCategories are written outside this repo (see above) and check-tools reads no Templates, this is not being treated as something to fix right now. |
There also appear to be two unrelated tooltip storage formats in this repo's history, and it's worth being deliberate about which one is current:
- The normalized format (
Tooltips+TooltipCategories+TooltipButtons+TooltipButtonNumbers) — this is what's in the live schema above, whatdocdb-studioedits, whatcheck-tools/db_health_checker.pyvalidates, and whatscripts/TooltipManager.pydumps/rebuilds via CSV. - A legacy flat format, a single
ide_tooltip_table(tooltipCategory, tooltipTag, tooltipSummary, tooltipDetail, tooltipButtons)table (button data packed as a JSON string in one column) — written byscripts/tooltips.py(TooltipDatabase, driven byscripts/import_tooltips.pyfromSourceDocs/Tooltips/tooltips.xlsx) and byscripts/load_android_data.py(fed by pickle files thatscripts/android_tooltips.py/scripts/java_tooltips.pyscrape from Android/Java HTML doc trees).ide_tooltip_tabledoes not exist in the current production schema at all.
ide_tooltip_table is officially dead (confirmed by Alex). That means the entire chain that
targets it — scripts/tooltips.py, scripts/import_tooltips.py, scripts/android_tooltips.py,
scripts/java_tooltips.py, scripts/android_html_page.py, and scripts/load_android_data.py — is
deprecated legacy code. It's left in the repo for reference/history, but none of it should be
extended or relied on, and none of it writes to a table the shipped app or docdb-studio actually
uses. Any future Android/Java tooltip work should target the normalized Tooltips /
TooltipCategories / TooltipButtons / TooltipButtonNumbers tables instead (the same ones
docdb-studio and scripts/TooltipManager.py already use for Kotlin tooltips), in their 2.x
shape: every tool here reads and writes that, and only the shipped copy holds the 3.0.0 shape, after
migrate_tooltip_schema.py (see "Schema 3.0.0" above).
docdb-studio/— a Flet (Flutter-for-Python) desktop GUI for browsing/editingTooltips/TooltipCategories/TooltipButtonsand importingContent. Has its ownCLAUDE.md,AGENTS.md,SCHEMA.md, and a real pytest suite. Actively maintained (most recent commits in the repo touch this tool), but per the table above, its documented schema is behind the live one. That's an accepted state, not an active problem: schema evolution happens outsidedocdb-studio(and outside this repo, e.g. via plugins — see below), anddocdb-studiois expected to catch up after the fact rather than lead. ItsAGENTS.md/SCHEMA.md"never migrate the schema" language should be read as "don't migrate it from in here," not as a claim that the schema never changes.check-tools/—db_health_checker.py(schema/integrity/referential checks against the old normalized schema) plusdownload_database.py, a working Google Drive downloader authenticated via GCP Workload Identity Federation (no long-lived keys). Wired into.github/workflows/docdb-regression-test.yaml, which runs it daily against the production DB on Drive.scripts/— the original CLI toolbox. Live/current:DocumentationDatabase.py(Content ingestion — see whitelist issue above),ingest.py(thin CLI over it, used bypublish-doc-db.yaml),TooltipManager.py(CSV ⇄ normalized-Tooltips round-trip),create_empty_database.py,list_database_documents.py,trim_kotlin_json.py(drops whatlayout.pebblenever shows from the Kotlin API pages' JSON; its T03 cuts member summaries to their first paragraph, which changes pages, and T02 drops per-platform text no page shows; no dictionary re-mint needed after it),drop_unread_rows.py(deletes Content rows nothing reads - javadoc Use pages, pdf.js CMaps, pdf.js fallbacks and scripting sandbox, x/ placeholders - after checking that nothing kept refers to them, before or after the schema-3 migration, whose templates it decodes; it also drops javadoc's 23 MB one-pageindex-all.htmlafter pointing every link to it at the splitindex-files/pages, and merges byte-identical media copies other than SVGs (mostly Help+Manual zoom images, ADFA-6645 item 2) after pointing their links at the kept copy; both rewrites loosen a packed file, sorebuild_database.py --packhas to follow it; and the 31 rows its closedUNLINKEDlist names, each with why nothing reads it),clear_repeated_tooltip_detail.py(empties a tooltip detail that repeats its summary),migrate_tooltip_schema.py(ADFA-3305: converts to documentation schema 3.0.0, which Code On The Go reads from 3.0.0 on: the WITHOUT ROWID, lookup-table tooltip shape, and every template Brotli-compressed against the dictionary; run it on the copy that ships, after every step that writes tooltips or templates, since they all write the old shape and plain templates, never on the master they edit; re-mint afterwards, then packContent,TooltipTexts, notTooltips),minify_text.py(ADFA-6627: minifies the HTML, CSS, JS and SVG rows and the HTML templates without changing what a page shows; runProcessDocs/ProcessKotlinDocs/ProcessKotlinWebsiteJSON/remint_dictionary.pyandverify_remint_dictionary.pystraight after it, or the minified rows compress worse than before),svg_images_to_webp.py(ADFA-3305: re-encodes the raster images SVG rows embed as data: URIs as WebP, image by image, by a quality rule; run on the shipped copy before the final dictionary re-mint;compare_svg_renders.pyrenders each changed SVG before and after in headless Chrome, through<img>and<object>, as its visual check),optimize_pdfs.py(ADFA-6629: rewrites the PDF rows - and, with--file, the Bookshelf plugin's.pdf.brbooks - losslessly so the Brotli around them compresses them better: streams other than images stored plain, Flate-wrapped JPEGs stored bare, Flate images PNG-predicted; every rewrite checked object by object against the original; run on the shipped copy aftersvg_images_to_webp.py, before the final dictionary re-mint), and four steps that run in this order before the--beforesnapshotupdate_media_references.pydiffs against:remove_skin_font_comment.py(cuts Help+Manual's commented-out Google Fonts note out of thei/pages until the skin fix, ADFA-6609, ships; first - its docstring says why),bundle_remote_images.py(stores the 19 diagrams API reference pages load from developer.android.com, kept with their sources and licenses inremote_media/adfa-6589/, and points the pages at them; a URL in that folder'sexisting.tsvis pointed at the row already holding its image instead; ADFA-6589), thenremove_remote_loads.py(takes out the markup that makes pages fetch from the internet where no download is needed - a remotesrcsetbeside a storedsrc, dark-theme<source>s, kotl.in badges, YouTube players - ADFA-6589; afterbundle_remote_images.py, because it drops a remotesrcsetonly beside a storedsrc), and lastcheck_remote_loads.py(reads every page, template and tooltip, and fails the build, naming each, if anything would still load from off the device; it writes nothing - ADFA-6589), andshare_skin_sprite.py, which runs before the--beforesnapshotupdate_media_references.pydiffs against: it replaces the SVG icon sprite Help+Manual's skin copies into thei/pages with one sharedi/js/hm_sprite.jsthat puts the sprite back as each page loads, until the skin stops inlining it (ADFA-4195); with the ADFA-6589 steps it runs afterremove_remote_loads.pyand beforecheck_remote_loads.py, which reads scripts without searching them, so this step refuses a sprite that names anything outside the page. Deprecated/dead (target the removedide_tooltip_table— see above, kept for reference only):tooltips.py,import_tooltips.py,android_tooltips.py,java_tooltips.py,android_html_page.py,load_android_data.py.scripts/hm_pages_to_templates.py- stores the Help+Manual topic pages underi/as JSON plus one Pebble template derived from the pages themselves (helpmanual-topic.peb), after rendering every page back byte for byte with the app's engine (scripts/hm_render_check/, which needsjavaand the Pebble jars). With--drop-jstopicsit also storeshelpmanual-jstopic.peband drops thei/jstopics/rows the app then builds from the page JSON (ADFA-6618; needs the app side). Run it after every step that editsi/pages: afterremove_skin_font_comment.py,bundle_remote_images.py,remove_remote_loads.py,share_skin_sprite.py,check_remote_loads.pyand the media steps (with their snapshot before them), thencheck_remote_loads.pyagain, which reads Templates and JSON pages and so works on either side.share_skin_sprite.pycomes with PR #42 (ADFA-4195) and the other four with PR #41 (ADFA-6589); this step ships after both. A media rollback (--restore-originals) cannot undo its pages: start the rollback from this step's pre-run backup, keep that backup with the rollback bundle, and run this step again afterwards.scripts/android_pages_to_templates.py- stores the Android reference pages undera/(excepta/devsite/) as JSON plusandroid-reference.peband one shared include per inherited-member block header (android-inherited-<n>.peb), with every text of 32 or more characters that 5 or more pages hold (link holes excepted) stored once in a shared-text bundle (android-text-<n>.peb, at most 8,000 bytes of source each, texts grouped by the pages that use them), after rendering every page back byte for byte with the app's engine (scripts/hm_render_check/, as above); a page that does not render back, or is over the app's render limit, stays HTML (ADFA-3305). Run it on the ship-time copy only, never on the master: after the steps that writea/pages,drop_unread_rows.pyand the Kotlin trim, before the 3.0.0 migration (which compresses every template; the app reads compressed templates from documentation schema 3.0.0, CodeOnTheGo stacked on #2163) and the final dictionary re-mint. It refuses a database that already holds its templates, or that declares documentation version 3 or later (whose templates are compressed, so its plain ones would not render). Followingdrop_unread_rows.pyis an exception to that step's "after every page-writing step" rule, and safe: every converted page renders back byte for byte, so it links to nothing the row drops did not already check. ADFA-5548'sProcessDocs/AndroidDocs/AndroidDocsToJson/load_android_json_db.pyconverts the samea/android/anda/androidx/pages its own way. This step is the one that ships: the workflows that ran that pipeline on the master (build-android-docs.yaml,build-android-docs-local.yaml) were retired in ADFA-3305, never having run, since after it this step would convert almost nothing.scripts/myServer.py— a minimal Pythonhttp.serverreference implementation that predatesWebServer.kt. It queries a differently-casedDocumentation.db, doesn't implement Brotli decompression (there's a literalTODO: Replace this function with Brotli decompression), and knows nothing about compression-aware content types, templates, or fragmentation. This is not what ships in the app — treat it as historical/reference only, not as documentation of current server behavior.WebServer.ktis the real thing.Dokka-plugin-kdoc2json/— the DokkaJsonRenderer/ModelMapper/LinkPostProcessorplugin, its test suite, and thekotlin-stdlib-docsbuild scripts, merged tomainviafix/ADFA-4514(4c6b8aef). Consumed byDokka-plugin-kdoc2json/scripts/kotlin/build-stdlib-json-docs.shandscripts/sync_kotlin_stdlib_docs/sync_kdoc_json_to_db.py(ADFA-4739) to generate and load kotlin-stdlib/-reflect/-test JSON docs.ProcessDocs/— HTML-processing pipelines that predate the "build docs as JSON" goal:ProcessKotlinDocs/(turns Kotlin's HTML doc export into a self-contained HTML set + table of contents, used by.github/workflows/automate-kotlin.yaml),ProcessAndroidDevSite/,AndroidDocs/(holdsandroid-tooltips.pkl, the pickle consumed by the now-deprecatedload_android_data.py),ProcessPDFs/.SourceDocs/— raw inputs:KotlinDocs/html,JavaDocs/html+java_keywords.html,Tooltips/tooltips.xlsx,KotlinDocs/kotlin-spec.pdf.DocumentationAnalysis/,DocAnalysis/,png_optimization/,androidxtooltips/— Jupyter notebooks and one-off scripts for doc-set size analysis, image/PNG compression experiments, and a one-time AndroidX tooltip import (ADFA-1419). Not part of the critical build path..github/workflows/—automate-kotlin.yaml(tag-triggered, builds the Kotlin HTML doc bundle as a GitHub release asset),publish-doc-db.yaml(tag-triggered, runs thescripts/ingest.pypipeline and releases the resulting.sqlite),docdb-regression-test.yaml(daily cron, downloads the production DB from Google Drive via WIF and runscheck-tools/main.pyagainst it),build-kotlin-docs.yamland its local-filesystem counterpartbuild-kotlin-docs-local.yaml(manual dispatch, the five-step Kotlin docs pipeline — these two are the only ones with Slack notifications), andpython-tests.yaml(push/PR, runs the pytest suites). No workflow runsscripts/trim_kotlin_json.py: the pipeline's last step,sync_kdoc_json_to_db.py, rewrites every k/ row, so the trim, like the other ADFA-3305 size-reduction steps, is run by hand on the pipeline's output (after the dictionary re-mint).
Settled with Alex on 2026-08-05, folded into the sections above; recorded here so the reasoning isn't lost:
ide_tooltip_tableand everything that targets it are dead. Treat as deprecated, not as a gap.Templates/Bookshelf/BookCategoriesare populated by App Dev For All's plugin system (e.g. bookshelf-plugin), not by this repo. Not a gap to fill here.PUCC_*tables are unrelated to documentation tooling. Ignore; leave as-is.docdb-studio's schema is expected to lag the live schema and catch up after the fact; that's fine, no urgent update needed.check-tools/db_health_checker.pyis not being extended withTemplates/Bookshelfchecks right now — deliberately out of scope for the moment.
The one piece of this document that still describes an active problem rather than a settled
scope boundary is scripts/DocumentationDatabase.py's hard failure on unrecognized tables (see the
table above) — that will need to be addressed before scripts/ingest.py /
publish-doc-db.yaml can run against a current-schema database.