Skip to content

Latest commit

 

History

History
367 lines (341 loc) · 29.1 KB

CLAUDE.md

File metadata and controls

367 lines (341 loc) · 29.1 KB

CLAUDE.md

Guidance for Claude (and anyone else) working in this repository.

What this repository is

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:

  1. 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).
  2. 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 the Content (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.

Schema: current vs. what this repo expects

Schema 2.0.0: every Brotli row uses a shared dictionary

As of 2026-08-20 ~/documentation.db reports 2.0.0 in DocumentationDatabaseVersion ("Add CompressionDictionary table", David) — a deliberately incompatible major bump. Every brotli Content row is compressed against the shared 256 KiB raw LZ77 dictionary held in CompressionDictionary (id 1). Measured on that database: 0 of 24 sampled brotli rows decode with plain Brotli; all 24 require brotli -D. A dictionary stream and a plain one are not interchangeable, so anything reading or writing Content has to go through the dictionary.

No Python Brotli binding exposes a custom dictionary (the brotli package has no such parameter; brotlicffi dropped BrotliDecoderSetCustomDictionary in 1.2), so all three writers shell out to the brotli CLI — which therefore has to be installed wherever the pipeline runs. Both workflows install it.

Writer Dictionary handling
ProcessKotlinWebsiteJSON/populate_db.py DictionaryCompressor + load_or_create_dictionary; trains one only if the table is absent/empty, and never retrains.
ProcessKotlinWebsiteJSON/insert_optimized_media.py Reads the existing dictionary via load_dictionary; never creates one.
scripts/sync_kotlin_stdlib_docs/sync_kdoc_json_to_db.py DictionaryBrotli + 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.py recompresses any remaining plain-Brotli rows.

Note also that image/webp (id 26) and video/quicktime (id 28) now exist in ContentTypes, so the workflows' INSERT OR IGNORE ... image/webp step is a no-op against current copies.

Schema 3.0.0: keyed tooltip tables and compressed templates, in the shipped copy only

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 in TooltipButtonDescriptions and TooltipButtonUris. 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 Templates row Brotli-compressed against CompressionDictionary, 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.py and verify_android_json_db.py, and in open PRs minify_text.py (#44), the a/ pages-to-templates step (android_pages_to_templates.py, #49) and hm_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 the a/ 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's remint_dictionary.py --seeds 4 (which recompresses templates too in 3.0.0), then rebuild_database.py --pack Content,TooltipTexts; hm_pages_to_templates.py goes after the i/ 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.py and load_android_json_db.py read 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-studio reads 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 daily docdb-regression-test.yaml run selects TooltipButtons.uri and Tooltips.detail), sync_kdoc_json_to_db.py (step 5 of build-kotlin-docs.yaml) and TooltipManager.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 the brotli CLI on PATH.

In the 3.0 shape Tooltips.id must be unique and name a TooltipTexts row: a writer takes the id its TooltipTexts insert hands out, never one of its own. Nothing enforces it (a UNIQUE (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, what docdb-studio edits, what check-tools/db_health_checker.py validates, and what scripts/TooltipManager.py dumps/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 by scripts/tooltips.py (TooltipDatabase, driven by scripts/import_tooltips.py from SourceDocs/Tooltips/tooltips.xlsx) and by scripts/load_android_data.py (fed by pickle files that scripts/android_tooltips.py / scripts/java_tooltips.py scrape from Android/Java HTML doc trees). ide_tooltip_table does 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).

Repository tour

  • docdb-studio/ — a Flet (Flutter-for-Python) desktop GUI for browsing/editing Tooltips / TooltipCategories / TooltipButtons and importing Content. Has its own CLAUDE.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 outside docdb-studio (and outside this repo, e.g. via plugins — see below), and docdb-studio is expected to catch up after the fact rather than lead. Its AGENTS.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) plus download_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 by publish-doc-db.yaml), TooltipManager.py (CSV ⇄ normalized-Tooltips round-trip), create_empty_database.py, list_database_documents.py, trim_kotlin_json.py (drops what layout.pebble never 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-page index-all.html after pointing every link to it at the split index-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, so rebuild_database.py --pack has to follow it; and the 31 rows its closed UNLINKED list 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 pack Content,TooltipTexts, not Tooltips), minify_text.py (ADFA-6627: minifies the HTML, CSS, JS and SVG rows and the HTML templates without changing what a page shows; run ProcessDocs/ProcessKotlinDocs/ProcessKotlinWebsiteJSON/remint_dictionary.py and verify_remint_dictionary.py straight 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.py renders 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.br books - 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 after svg_images_to_webp.py, before the final dictionary re-mint), and four steps that run in this order before the --before snapshot update_media_references.py diffs against: remove_skin_font_comment.py (cuts Help+Manual's commented-out Google Fonts note out of the i/ 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 in remote_media/adfa-6589/, and points the pages at them; a URL in that folder's existing.tsv is pointed at the row already holding its image instead; ADFA-6589), then remove_remote_loads.py (takes out the markup that makes pages fetch from the internet where no download is needed - a remote srcset beside a stored src, dark-theme <source>s, kotl.in badges, YouTube players - ADFA-6589; after bundle_remote_images.py, because it drops a remote srcset only beside a stored src), and last check_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), and share_skin_sprite.py, which runs before the --before snapshot update_media_references.py diffs against: it replaces the SVG icon sprite Help+Manual's skin copies into the i/ pages with one shared i/js/hm_sprite.js that puts the sprite back as each page loads, until the skin stops inlining it (ADFA-4195); with the ADFA-6589 steps it runs after remove_remote_loads.py and before check_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 removed ide_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 under i/ 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 needs java and the Pebble jars). With --drop-jstopics it also stores helpmanual-jstopic.peb and drops the i/jstopics/ rows the app then builds from the page JSON (ADFA-6618; needs the app side). Run it after every step that edits i/ pages: after remove_skin_font_comment.py, bundle_remote_images.py, remove_remote_loads.py, share_skin_sprite.py, check_remote_loads.py and the media steps (with their snapshot before them), then check_remote_loads.py again, which reads Templates and JSON pages and so works on either side. share_skin_sprite.py comes 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 under a/ (except a/devsite/) as JSON plus android-reference.peb and 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 write a/ pages, drop_unread_rows.py and 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). Following drop_unread_rows.py is 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's ProcessDocs/AndroidDocs/AndroidDocsToJson/load_android_json_db.py converts the same a/android/ and a/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 Python http.server reference implementation that predates WebServer.kt. It queries a differently-cased Documentation.db, doesn't implement Brotli decompression (there's a literal TODO: 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.kt is the real thing.
  • Dokka-plugin-kdoc2json/ — the Dokka JsonRenderer/ModelMapper/LinkPostProcessor plugin, its test suite, and the kotlin-stdlib-docs build scripts, merged to main via fix/ADFA-4514 (4c6b8aef). Consumed by Dokka-plugin-kdoc2json/scripts/kotlin/build-stdlib-json-docs.sh and scripts/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/ (holds android-tooltips.pkl, the pickle consumed by the now-deprecated load_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 the scripts/ingest.py pipeline and releases the resulting .sqlite), docdb-regression-test.yaml (daily cron, downloads the production DB from Google Drive via WIF and runs check-tools/main.py against it), build-kotlin-docs.yaml and its local-filesystem counterpart build-kotlin-docs-local.yaml (manual dispatch, the five-step Kotlin docs pipeline — these two are the only ones with Slack notifications), and python-tests.yaml (push/PR, runs the pytest suites). No workflow runs scripts/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).

Decisions log

Settled with Alex on 2026-08-05, folded into the sections above; recorded here so the reasoning isn't lost:

  • ide_tooltip_table and everything that targets it are dead. Treat as deprecated, not as a gap.
  • Templates/Bookshelf/BookCategories are 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.py is not being extended with Templates/Bookshelf checks 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.