What was a design doc is now a real binary: adom-wiki <pillar> <verb> with --json on every command, actionable hints, and the 3-depth --help — replacing the now-deprecated adompkg. Same registry (wiki.adom.inc), same signing, nothing breaks. Pillars shipped: pkg · repo · release · page · discussion · pr · discover · admin · breadcrumb · family; meta verbs include api + status (the two highest-leverage adds from the audit below).
The npm-style package: a source tarball with a manifest, semver versions and dependencies. You pkg install it into adom_modules and other packages depend on it. It's code/skills the machine consumes — resolved, deduped, version-pinned.
Built binary artifacts attached to a version — the .exe/.dmg/.tar.gz per platform, with release notes. A human release downloads it; you don't depend on it. It's the product people run, not the source you import.
Like GitHub's paid granular visibility, each storage layer flips on its own — so you can keep source private while the app is freely installable and the binaries public:
| --source public|private | the git repo / Files tab — browse the actual code | ships --hide-source |
| --pkg public|private | the installable tarball — who can install it | new 3rd axis |
| --releases public|private | the downloadable binaries | ships --public-releases |
You publish in two recurring shapes — and right now each is assembled by hand from scattered flags (--no-source, --hide-source, --private). I probed your live repos: the per-axis columns source_visibility / release_visibility exist but read null on hydrogen-desktop & adom-desktop — so the proprietary-source model isn't declared, it's improvised. Fix: name the modes as presets that set all three axes at once.
| preset | source | install (pkg) | releases | your examples |
| --preset open | public | public | public | chip-fetcher |
| --preset licensed | org-only | public | public | hydrogen-desktop, adom-desktop |
| --preset preview | org-only | org-only | org-only | adom-usb (WIP, also score −50) |
| --preset private | org-only | org-only | org-only | internal-only tools |
Your wiki-skillpack defines three repo archetypes. The CLI should know them — scaffold the right structure on init, then lint that a repo stays true to it. Today init --type app|skill|bootstrap sets the content type, not the structural archetype; and push --check lints files+secrets but doesn't check archetype conformance.
| archetype | what it is | proposed command | state |
| page | one page = one thing (open or closed source) | init --archetype page | partial |
| skillpack | main SKILL.md + N sub-skills, -skillpack suffix | init --archetype skillpack → skills/<sub>/ + install.sh + files[] | new |
| family | anchor + child pages, joined by family tag + breadcrumbs | init --archetype family · family add-child · anchor | new |
| — lint | validate a repo matches its archetype (suffix, layout, family tag, breadcrumbs) | lint <slug> (extends push --check) | partial |
Verdict on your three examples: no new pillar, almost no new commands. adompkg already ships a real linter — lintSecrets · lintTags · lintVersionSync · lintSkillFrontmatter · lintSymlinkConvention · lintSealedSourceInTarball — plus --skip-lint, and the API already returns a coded hints engine. I pulled these live off adom-usb just now:
{ "code": "NO_DISCOVERY_TRIGGERS", "action": "Add 'discovery_triggers' … to the manifest." }
{ "code": "STALE", "action": "Ship a new release/commit, or deprecate the package…" } ← level/code/message/action schema
What's missing: (1) promote lint to a first-class verb (today it only runs inside push --check / publish), and (2) three new rules for the exact mistakes the AI keeps making. Each rule must fire in both layers — client-side for fast CLI feedback and server-side in the hints engine, so the API reprimands even when the AI skips the CLI and POSTs direct.
| rule code | catches | the reprimand → fix | state |
| HERO_IN_README | the hero image embedded in the README body | "You're showing the hero twice — the page renders it above the README automatically. Drop it from the body; use other screenshots." | new |
| BINARY_IN_REPO | executable / archive binaries committed to git (not presentation images) | "Binaries bloat the repo. A downloadable binary is a release asset; installable code is a pkg tarball. The repo is for source + README images only." | new |
| PKG_VS_RELEASE | binary type ↔ target mismatch (sniffed by magic bytes, not extension) | "This is a Windows PE/.exe → ship it as release upload --platform windows. An ELF / shebang / JS CLI → that's a pkg." | new |
| TITLE_IS_SLUG | page title is the raw slug / kebab-case (e.g. adom-desktop), or an adom-* slug whose title dropped the "Adom" prefix | "Title is the slug — set a display name: adom-desktop → Adom Desktop" + a humanized suggestion: Title-Case, keep Adom, expand known initialisms (USB, LBR→Library, EDA, KiCad) | new |
| README_SHADOWED | a commit touches README.md while readme.html exists (readme.html wins — the edit won't show) | "readme.html is what renders here — your README.md change won't be visible. Edit readme.html, or delete it to fall back to README.md." (also a warning on the /files push response) | new |
| lintSecrets · lintSealedSourceInTarball · … | already shipping — secret scan, sealed-source leak guard, frontmatter, tags, version-sync, symlink convention | ships | |
gh can't attach an image to an issue or comment — so a bug report is words about a picture nobody can see. Here every discussion create / comment takes --image, and the AI or user attaches the actual screenshot of the problem.
The hero is the AI-age app icon — and it lives in the git repo (page.json + the image). So it inherits hero history, blame (who changed it), rollback — and a hero change can arrive as a pr you review and merge. No app store versions its icons.
A first-class discover pillar: discover find by trigger words and preview "what would surface for X, and why" — so a brand-new, zero-engagement page is findable the instant it's published, not after it earns stars.
Each page now carries a real popularity block — earned signals roll into a composite_score, and an admin can hand-adjust it so the adom-screensaver billboards promote the right things. Verified live on adom-usb today:
"composite_score": 70, "install_count_30d": 18, "commit_count_90d": 30, "manual_score_adjustment": -50, "manual_score_reason": "Not yet released / WIP quality — keep in wiki but suppress from screensaver promotion"
From the adom-screensaver thread: the screensaver billboards and the wiki homepage hero strip should rank by the same transparent, additive score, so the two surfaces never disagree — and Colby gets an admin page to see the breakdown and tune it, exactly like the screensaver's Settings → Cache tab. The score is a sum of named components, never a black box; both read popularity.manual_score_adjustment as the curation lever.
screensaver = freshness + novelty(per-viewer) + manual_score_adjustment + jitter homepage = w1·recency + w2·normalize(composite_score) + manual_score_adjustment + jitter freshness curve (shared): <7d 100 · <30d 60 · <90d 35 · <365d 15 · else 5 homepage is many-viewer → popularity-weighted (w2); per-visitor novelty optional (cookie)
| piece | what | state |
| list scores | expose composite_score + manual_score_adjustment + updated_at on page-LIST items. Today only page-detail carries popularity, so a consumer iterating pages must N+1 fetch — the exact turn/call waste the hints section fights. One list call should rank the whole homepage. | new |
| weights cfg | w1 (freshness) vs w2 (popularity) as admin config, so Colby dials "fresh vs popular" without code. Floor stale/WIP pages via the manual nudge — don't hide them. | new |
| /admin/scoring | mirror Settings → Cache: a row per page — hero thumb (+ load-current-on-demand), slug/type/title, the full component breakdown summing to the total ("fresh 100 + new 0 − admin 50"), the resulting rank + homepage cutoff, and an inline manual_score_adjustment control (POST /api/v1/admin/pages/:slug/score) that recomputes total + rank live. Sort by total/recency/popularity/slug/type; filter org/type; flag is_stale. | new |
| home strip | cross-fade the top N heroes, re-sort each cycle, consuming the shared score off the (now score-bearing) list endpoint. | new |
adom-screensaver can't tell if a hero changed without re-downloading the whole image (~400 KB each). I probed the live asset to see why:
HEAD …/files/screenshots/hero.png → 200 content-length: 400197 ✓ HEAD works (body-free) last-modified: Tue, 23 Jun … ⚠ = serve time, not the 22nd commit — unreliable (no etag header) ✗ no content validator
So a HEAD is possible, but there's no trustworthy cheap signal — last-modified moves on cache misses, and length only changes if the size does. The fix is two parts, both keyed on the hero's git blob SHA:
| fix | what | why it's right |
| ETag + 304 | asset returns ETag (= blob sha) + a stable Last-Modified (hero's commit time); honor If-None-Match → 304 Not Modified | saver stores the ETag, sends it, gets a ~0-byte 304 when unchanged — standard HTTP, zero client logic |
| /hero meta | GET /api/v1/pages/:slug/hero → { sha256, bytes, content_type, updated_at, url } where updated_at = commit time of hero_path specifically | one tiny JSON poll; compare sha256 to what you cached — for clients that prefer explicit over HTTP caching |
| page hero status | CLI verb that prints sha · updated_at · bytes (one HEAD / meta call) | the AI & saver can check from the CLI without scripting a raw request |
The AI always opens with --help, so make it the best surface in the CLI — and turn the mimic trick into documentation: every line names the CLI it mirrors, so one --help transfers a whole vocabulary. Default to a concise top-level map (don't dump ~80 verbs and burn the model's context); offer --help --all and --help --json for when it wants the lot.
No CLI was designed for an AI consumer — they were built for humans who'd read the manual once. But an AI never reads the manual; it guesses, then reads 100% of whatever the command prints. That flips the design: stdout is the teaching surface. Instead of a giant skill doc loaded every session, the CLI returns hints — progressive skill-reveal: exactly the right guidance, at the moment it's relevant, populated with live data. The wiki already does this (I pulled {level,code,message,action} hints live off the API). The move is to make it a first-class, everywhere, turn-eliminating design principle.
A hint costs ~40 tokens to include and the AI reads it for free (it was reading the output anyway). The thing a hint replaces — the AI running another command to discover what the hint would have told it — costs a whole round-trip. And here's the killer: near a 1M-token context window, every extra turn re-sends the entire conversation as input — roughly a million tokens, re-billed, per avoided turn.
Concretely, extend the live hint object with one field — a literal, ready-to-run cmd (and optional data) — so a hint isn't advice, it's the next action, pre-written:
{ "level": "reprimand", "code": "BINARY_IN_REPO",
"message": "app.exe (PE32) doesn't belong in the git repo.",
"action": "A Windows binary is a release asset, not repo source.",
"data": { "file": "app.exe", "kind": "PE32", "bytes": 8123904 },
"cmd": "adom-wiki release upload my-app 1.2.0 app.exe --platform windows" } ← the AI runs this, no guessing
| situation | the hint returns… | saves |
| Ambiguous slug — info chip-fetcher (real: exists under kyle & john) | the owner list as data + two ready cmds (info kyle/…, info john/…) | 1–2 turns (vs search to find owners) |
| Version exists — pkg publish rejected (versions are immutable) | "1.2.0 is published; bump first" + cmd: pkg version patch && pkg publish | 1–2 turns (vs diagnosing the error) |
| Hero in README — caught on repo push | reprimand: "rendered twice — drop the <img> from README" + the right page hero set cmd | a bad publish + human-noticed redo |
| Proprietary app published fully public | "source will be world-browsable" + cmd: page visibility … --preset licensed | a leak + a rollback |
| No discovery triggers (real: NO_DISCOVERY_TRIGGERS) | "AI agents won't surface this" + cmd: discover triggers … --add | future invisibility (silent failure) |
| Truncated list — discussion list returns 20 of 412 | "showing 20/412" + cmd: … --limit 412 --json | a blind re-call |
| whoami / context priming — real-time orgs & auth state | your orgs inline as data, so later --org needs no lookup | a read call on every org op |
| Hero freshness — page hero status | {sha, changed:false} + "send If-None-Match <etag> to skip the download" | a 400 KB re-download |
| Next step — after repo init (empty repo) | "repo created, empty" + cmd: repo push … --files README.md | the AI guessing the workflow |
| Affordance reveal — first discussion create | "you can attach a screenshot with --image" — reveals a flag the AI didn't know | a worse bug report |
| Solo namespace on create — repo init / publish under a personal owner (john/) | "created under john/ — only you can edit this. Collaborating with someone? Create it under an org, or transfer it" + cmd: repo transfer … --to-org adom. If the request mentioned working with someone, ask: "this is solo-owned — did you mean to collaborate?" | a re-publish + a transfer + a frustrated user |
A skill doc is documentation the AI must load up front and carry — it costs context every session whether or not it's needed. Hints are documentation the CLI pushes to the AI exactly when it's relevant, already personalized with live data, already written as the next command.
So the CLI stops being a tool the AI must know, and becomes a tool that teaches itself as it's used — and every hint that lands is a turn that never has to happen.
Audited every gh command group against the design. The lifecycle verbs above (discussion edit/reopen/pin/lock, pr review/comment/ready/reopen, repo edit/archive/sync, release delete-asset/verify) are now folded into their pillars. What's left splits two ways:
The verbatim founder prompts that drove this design — the unfiltered intent behind every pillar above. Read these first; the structured asks below are my synthesis of them.
can you go read my adom-wiki-skillpack to understand the wiki and then look at adompkg to understand that cli. i'd like to brainstorm a good cli design. i see the wiki as 6 top-level items: a git repo that mimics the git cli, a pkg management system like npm so our pkg system should mimic those known commands, a releases section like github releases and so our commands should mimic github's gh cli, and then a discussion forum which i don't even know if gh supports discussions or posting of issues but if there's something known out there for discussions around repos let me know and we should mimic it, and then a pull request feature so that's like gh too. and then we do have a presentation layer to the wiki that lets us do things like manage hero images which are becoming like our app icons in an ai age and we even have a scoring system so surfaces like adom-screensaver can prioritize what order they show hero image billboards as based on trending and use the high-five and user comments to determine a trending score. so these branches i think should all have a top-level verb in the cli and then under that verb we should mimic the most common thing the ai would know from the internet community like the git cli for that branch or npm common commands from that branch. so could you create an html page that shows the hierarchy of the verbs we should support in our cli that i think we should call adom-wiki? and then compare that to the adompkg cli we have today?
ok, yeah, add discover as a top-level pillar. i like that. and for the discussions, one of the things gh sucks with is not letting the ai or a user ad a screenshot showing the problem they're reporting so we need that to be supported
and for hero images, those need to be supported where the adom-wiki leverages the git repo and changelogs so you can rollback changes on the hero image or see if somebody else changed it, or get a pr for it and roll in the hero image pr request
and can you help describe a bit better the difference between a pkg and a release? and we need to support public/private independently on the git repo, the pkg, and the release kind of like how github allows that under its paid plan
colby recently added a negative score i can attach to a wiki page so that the adom-screensaver can calculate a good trending score. this negative score lets an admin downplay certain stuff like adom usb that's new on the wiki but not ready for primetime, so it really shouldn't show up in places yet and get promoted
so can you add cli commands that would help the ai and a user tweak those? that negative score should be admin only, so we may need an admin pillar
and perhaps the admin pillar can do superuser stuff to repos
also, i do think we need a soft-delete and a hard-delete in the cli to delete repos. i also think we should be able to rename a repo, but does gh let you do that? cuz we should mimic github
and if we were to fully audit against the gh cli, what else might we be missing?
i tend to mark some repos as full open-source like chip-fetcher so you get source code and binaries, other's i mark as licensed proprietary where the binaries are free to use by everyone like hydrogen-desktop or adom-desktop, but the source code must be hidden except for adom org members. do we have cli commands that help that definition occur? also, we have the archetypes that i described in the wiki skillpack. should we make cli commands to support that model/structure/approach?
and then i tend to want a linter when using the wiki. do we need any cli commands for these examples below, or are we good with our existing commands: - when the ai creates a readme, it tends to place the hero image in the readme as well cuz its lazy and thinks "oh, i created a hero image, i should add it to the readme" but the wiki page always shows the hero first and then shows the readme. so the ai constantly screws that up. the wiki cli's and api's should double check for this through a linter pass to reprimand the ai that they made that mistake and to fix it. - the ai likes to upload binaries into the git repo. we should "lint" for that and reprimand the ai so that git repos don't get filled up with binaries and instead we give hints to the ai that this is what pkg and releases are for. - some projects like adom-desktop have an exe that is installed on your windows computer, so that's a release, and then they also have a cli for linux that runs in the adom cloud container and wsl2 container in hydrogen-desktop. so that would mean a pkg gets created. can we have a linter or hints that help the ai understand that breakdown? like could the wiki almost test for the type of binary and send back helpful hints or even reprimands depending on what is being created as pkg or releases?
also i notice the ai always calls the cli first with a --help so can we support that to help the ai know how to use this cli each time where --help literally returns all the verbs available or if that's too much for it at least returns the toplevel verbs with info on how to call help for the sub-verbs?
one issue i ran into with adom-screensaver is it couldn't easily tell if the hero image was updated, so can we add an api and cli command to check the timestamp or sha of a hero image cuz the ai said that the saver had to re-download the hero image each time to even tell if it was new
is there any way for you to think through the hints that any of these cli verbs could return to help the ai better use them? most cli's were never designed for ai, but we have found that ai guesses at stuff, but then instead of the ai reading a skill documenting the cli, its better to have hints returned in your json responses because the ai always reads all of the cli's output. so hints essentially become progressive skill revealing to the ai at the appropriate time and possibly populated with relevant real-time data. so could you make a section that talks about why hints are so important in the cli and some possible areas where you think the hints could add great value to the ai. remember another goal is help the ai not have to do as many turns. if the ai has a 1M context window and its nearing it, every turn the ai has to do to call another sub cli call results in the 1M context being resubmitted to the ai each time and burning thru tokens. our hints can save $1000's of $'s in tokens.
We're planning the Adom Wiki (wiki.adom.inc). I want two related things folded into the overall plan:
(A) a "featured / trending" rotation of page HERO images on the wiki HOMEPAGE, ordered by a
transparent, component-based score, and (B) an ADMIN page where Colby can SEE that score broken
down per page and tune it — the same way the Adom Screensaver's Settings → Cache tab already shows
me the score it uses to order its billboard rotation. Model it on the screensaver; here's exactly
how that works so you can adapt it.
═══ REFERENCE: how the Adom Screensaver scores its billboard rotation ═══
Each candidate hero (one per wiki page) gets an additive priority score; the rotation plays
highest-first and re-sorts each cycle. The score is deliberately a SUM OF NAMED COMPONENTS so it's
fully explainable (no black box):
slideScore(page) = freshness + novelty + adminAdjustment + jitter
• freshness(updated_at): <7d → 100, <30d → 60, <90d → 35, <365d → 15, older/unknown → 5
• novelty(slug): max(0, 60 − 20 × timesShownToThisViewer) // never-seen = +60; ~0 after 3 views
• adminAdjustment: the wiki's popularity.manual_score_adjustment for that page (e.g. −50)
• jitter: random 0..12 // so ties vary run-to-run and the order isn't frozen
The screensaver READS adminAdjustment from the page-detail API
(popularity.manual_score_adjustment), folds it into the score, and shows the whole breakdown to
the user as "fresh 100 + new 0 − admin 50" with the running total. Example: I just put −50 on the
14 adom-usb pages (via POST /api/v1/admin/pages/:slug/score) and they dropped from 100 → 50 and
sank to the bottom of the rotation, while staying in the wiki. That admin lever + the visible
breakdown is exactly what I want Colby to have for the homepage.
═══ WHAT THE WIKI ALREADY HAS (adompkg 2.46.0) ═══
The page-detail response carries a `popularity` object:
{ star_count, fork_count, install_count_30d, invoke_count_30d, view_count_30d,
commit_count_90d, discussion_count_30d, composite_score, is_stale, stale_reason,
last_computed_at, manual_score_adjustment, manual_score_reason }
So composite_score already blends real popularity signals + the manual adjustment and survives
recompute. POST /api/v1/admin/pages/:slug/score {adjustment, reason} sets the manual nudge.
Gap: the page LIST endpoint omits `popularity`, so a consumer iterating the list (the screensaver,
or the homepage) can't see scores without a per-page fetch — please expose manual_score_adjustment
+ composite_score on list items too.
═══ (A) HOMEPAGE ROTATION SCORING ═══
Adapt the screensaver model to a MANY-viewer surface (so popularity matters more than per-user
novelty). Keep the same transparent additive structure + the admin lever:
homepageScore(page) = w1·recencyBoost(updated_at) // same freshness curve as above
+ w2·normalize(composite_score) // installs/stars/commits/views/discussions
+ manual_score_adjustment // Colby's curation nudge (e.g. −50, +100 to feature)
+ smallJitter // keep the daily rotation varied
Rank highest-first, cross-fade N heroes on the homepage trending strip. Make the weights (w1,w2)
config so Colby can dial "freshness vs popularity." Floor stale/WIP pages via the manual nudge
rather than hiding them. (A per-session "don't repeat what this visitor just saw" novelty term is
optional — cookie-based — if you want the screensaver's de-dup feel for repeat visitors.)
═══ (B) ADMIN SCORING PAGE (mirror the screensaver's Settings → Cache tab) ═══
A new admin-only page (e.g. /admin/scoring) listing every page, sortable, each row showing:
• the page's HERO thumbnail (+ a "load current hero" button to pull the live blob on demand)
• slug + type capsule + title + brief
• the FULL score broken into its named components (recency, each popularity signal, composite,
and the manual adjustment) summing to the total — exactly like "fresh 100 + new 0 − admin 50"
• the resulting RANK / whether it makes the homepage rotation cutoff
• an inline control to SET manual_score_adjustment (+ reason), with the new total + rank
recomputed live on save (calls the existing admin score endpoint)
• sort by total / recency / popularity / slug / type; filter by org/type; flag is_stale
This is the admin's window into the same scoring the homepage uses — transparency + a tuning lever
in one place, the way the screensaver shows it to me.
═══ DELIVERABLE ═══
Fold (A) + (B) into the overall wiki plan (data model, the list-endpoint score exposure, the
weights config, the /admin/scoring page, and how the homepage trending strip consumes it). When
done, REPLY WITH A PASTE-READY PROMPT summarizing your conclusions + the concrete build steps,
that I can hand to Colby (and back to my screensaver thread so the two scoring models stay aligned).
My synthesis of the brief above into paste-ready asks. Each is self-contained, names the live API state, and ends asking for a report-back prompt to wire the CLI side. Tap Copy.
Context: Adom Wiki backend (wiki.adom.inc, REST /api/v1). Discussions are live — POST /api/v1/pages/:slug/discussions creates a thread and POST /api/v1/discussions/:id/replies posts a reply — but both are TEXT-ONLY. There is no way to attach an image. Ask: Add image attachments to discussions AND replies, so a bug report can carry the screenshot of the problem: - Accept image uploads on create + reply (multipart, or a base64 field alongside the text), store them like page assets, and return their URLs in the payload. - Allow multiple images per post. - Render them inline when a thread is fetched (GET /api/v1/pages/:slug/discussions). - Sane size cap + content-type allowlist (png/jpg/webp/gif). This unblocks the adom-wiki CLI `discussion create --image` / `comment --image` verbs, and is the one thing GitHub's `gh issue` can't do. Report back with: the final request/response shape for attaching + reading images, the size/type limits you chose, and a short paste-ready prompt I can drop into the adom-wiki CLI thread to wire it up.
Context: Adom Wiki backend. Page visibility today has TWO independent layers: source (the git repo / Files tab — CLI --hide-source/--show-source) and releases (downloadable binaries — --public-releases/--private-releases). Ask: Add a THIRD independent visibility axis for the PACKAGE / install layer — who can `adompkg install` the tarball — controllable separately from source and releases, like GitHub's granular per-feature visibility. Combinations we want: - closed source + public install + public releases (proprietary app, anyone can install/run) - public source + org-only install (open code, internal distribution) - any other mix of the three. Specifically: a per-package visibility field (public | private | org), enforced at the tarball-download + resolve endpoints, independent of source and release visibility, and surfaced in page metadata so the CLI can read + set it. Report back with: the field name + the endpoint(s) that enforce it, how it interacts with org membership, and a paste-ready prompt for the CLI thread to add `page visibility --pkg public|private|org`.
Context: Adom Wiki discovery. GET /api/v1/search?q= works (FTS). GET /api/v1/discover?triggers=<csv> is supposed to surface pages whose declared discovery_triggers match the requested phrases — but today it returns roughly the same fixed ~70-page popular set regardless of the triggers passed, so a brand-new, correct, zero-engagement page is invisible to trigger discovery until it organically earns engagement (backwards — you discover something in order to start using it). discovery_triggers ARE stored server-side (GET /api/v1/packages/:slug/manifest). Ask: 1. Make /discover?triggers= text-relevance match the requested phrases against each page's manifest discovery_triggers, instead of returning a popular set. 2. Index triggers at publish time so a page is discoverable the instant it's published, zero engagement required. 3. Blend relevance + quality in ranking (relevance surfaces; stars/installs break ties) — a highly-relevant new page should outrank a barely-relevant popular one. 4. Exclude deprecated / soft-deleted / private pages from public discovery. Report back with: the matching + ranking approach, two example queries with their results, and a paste-ready prompt for the CLI thread to wire `discover find <triggers>` and `discover preview`.
Context: Adom Wiki backend — a batch of smaller gaps the adom-wiki CLI design surfaced. Independent; do the easy ones first. 1. FTS hyphen bug: GET /api/v1/search?q=chip-fetcher errors "no such column: fetcher". Almost every Adom slug is hyphenated — tokenize so hyphens don't break the query. 2. GET /api/v1/trending returns 404. The per-page popularity block (composite_score, install_count_30d, manual_score_adjustment) is already live — so stand up a /trending endpoint that ranks by composite_score (honoring manual_score_adjustment), filterable by type, so adom-screensaver and the homepage can order the hero billboards. 3. Document/expose a WRITE path for manual_score_adjustment + manual_score_reason (the admin negative/positive trending override — it's populated today, e.g. adom-usb = -50, but there's no documented endpoint to set it). This backs the admin-only `admin score --adjust N --reason` verb. Also add a high-five endpoint (POST/DELETE) alongside the existing star endpoints. 4. POST /api/v1/pages/:slug/fork returns 404 — implement fork-to-your-namespace so the standard fork → PR → merge loop works (PRs already work). 5. page.json metadata.discovery_triggers pushed via /files does not persist (reads back as []). Either persist it, or document the manifest as the single source of truth and say so. Report back with: which items shipped, the request/response shape for each new endpoint, and a paste-ready prompt for the CLI thread covering what's now wired.
Context: Adom Wiki (wiki.adom.inc). The adom-screensaver already ranks its billboard rotation by a transparent, additive, component-based score and reads popularity.manual_score_adjustment as the admin lever (POST /api/v1/admin/pages/:slug/score is live; page-detail carries the full `popularity` object incl. composite_score + manual_score_adjustment). We want the wiki HOMEPAGE to run the SAME model, plus an admin page to see + tune it. Keep the two surfaces on ONE documented formula so they never diverge.
Build:
1. LIST-ENDPOINT SCORE EXPOSURE (do first — everything else needs it). The page LIST endpoint omits `popularity`, so a consumer (homepage strip, screensaver) must N+1 fetch per page. Add composite_score + manual_score_adjustment + updated_at to list items so one call ranks them all.
2. WEIGHTS CONFIG. homepageScore = w1·recency(updated_at) + w2·normalize(composite_score) + manual_score_adjustment + smallJitter. Freshness curve: <7d 100, <30d 60, <90d 35, <365d 15, else 5. Make w1/w2 admin-config so Colby dials freshness vs popularity. Floor stale/WIP pages via the manual nudge, never hide them. (Optional cookie-based per-visitor novelty term for repeat-visitor de-dup.)
3. /admin/scoring PAGE (mirror the screensaver's Settings → Cache tab). One row per page: hero thumbnail (+ load-current-hero-on-demand), slug + type capsule + title + brief, the FULL score broken into named components summing to the total ("fresh 100 + new 0 − admin 50"), the resulting rank + whether it clears the homepage cutoff, and an inline control to set manual_score_adjustment + reason (calls the existing admin score endpoint) recomputing total + rank live. Sortable by total/recency/popularity/slug/type; filter by org/type; flag is_stale.
4. HOMEPAGE TRENDING STRIP. Cross-fade the top N heroes, re-sort each cycle, consuming the shared score off the now-score-bearing list endpoint.
Report back with: the list-item score fields you added, the weights-config shape, the /admin/scoring route + how it recomputes on save, and TWO paste-ready prompts — one for the adom-wiki CLI thread (to wire `admin score list` + `page trending` against the new fields) and one for the adom-screensaver thread (confirming the formula/fields so both rotations stay aligned).
Context: Adom Wiki (wiki.adom.inc). The CLI is going native on Windows, macOS, Linux & WSL2, so package/release resolution must be platform-aware AND self-healing. A wiki is third-party contribution — so a missing-platform binary should be something the asking AI can build and contribute back, making the catalog more complete the more it's used (the whole industry's build effort compounds into a shared asset).
Build (applies to BOTH packages and releases):
1. PLATFORM CONTEXT ON EVERY REQUEST. Accept an X-Adom-Platform: <os>-<arch> header (e.g. darwin-arm64, windows-x64), also reflected in the User-Agent. Default install / download / resolve to the caller's platform — never hand a Linux binary to a Windows box.
2. MANIFEST DECLARES AVAILABILITY + BUILDABILITY. Per-package/per-release: `platforms` (which targets are prebuilt), a per-target `build` recipe (the exact command to build it from source), and a `source` ref. This is what the resolver reads.
3. RESOLVE RETURNS A STRUCTURED, AI-ACTIONABLE OUTCOME (hints with literal cmds):
- have-it -> the asset for the caller's platform
- agnostic -> the platform-agnostic pkg (pure source/skill/JS)
- needs_build -> { source.cmd (clone), build.cmd, verify, contribute.cmd } so the AI clones, builds, verifies, and uploads
- unavailable -> clear reason (source private / platform unsupported / Windows-only by design)
4. CONTRIBUTE-BACK + PROVENANCE. release upload --platform <x> accepts a community-built binary carrying provenance { built_from_commit, sha256, built_by, toolchain }; serve it as "community-built", promotable to official via an owner/admin vouch (reuse vouch/verify + the integrity SHA) so nobody unknowingly runs a tampered cross-platform binary.
Make every response AI-native: structured, runnable, zero-guess — a missing Mac build should heal in ONE agent loop, not a filed issue.
Report back with: the platform-header + resolve-response shape, the manifest platforms/build/source fields, the contribute-back + provenance model, and a paste-ready prompt for the adom-wiki CLI thread to wire install/download platform resolution + the build-back loop.
Context: Adom Wiki (wiki.adom.inc). Breadcrumbs let a third party announce a related repo on someone else's ANCHOR page without edit rights (e.g. an OrCAD bridge for adom-desktop, or a community website-surfing skill for chip-fetcher / adom-browser-extension). GET /api/v1/pages/:slug/breadcrumbs is LIVE (returns {"breadcrumbs":[]}); the write path + moderation + ranking are what's missing. This is core to the wiki's third-party-contribution commons — anchors grow ecosystems their owners never manage.
Build:
1. POST WRITE PATH. POST /api/v1/pages/:anchor/breadcrumbs { to_slug, kind, title } from any authenticated user, no edit rights on the anchor required. Validate: the target page exists + is public; dedupe; rate-limit. Read it back on the anchor's breadcrumb list.
2. MODERATION (anchor owner). approve / hide / pin a breadcrumb on a repo you own — spam control for hot anchors like chip-fetcher.
3. RANKING. Rank an anchor's breadcrumbs by the same composite_score (installs/stars/vouch) so the best surface first; support a `kind` filter (bridge | surfing-skill | plugin | ...).
4. AI-FOLLOW. Surface a BREADCRUMBS_AVAILABLE hint (count + a literal follow cmd) on the anchor's page/show response, and a follow/resolve endpoint that returns the target repos (slug + kind + score + a match field) so the AI discovers + follows the trail in ONE call instead of N.
5. PROVENANCE. Record who posted, when, and the target's commit.
Make it AI-native: the AI working with an anchor should be told "there's a trail here, here's how to follow it," and publishing+breadcrumbing a new skill should be a one-flow contribution.
Report back with: the POST + moderation + follow/resolve endpoint shapes, the ranking model, the breadcrumb object fields (incl. kind + provenance), and a paste-ready prompt for the adom-wiki CLI thread to wire breadcrumb post/list/follow/approve/pin.
Context: Adom Wiki (wiki.adom.inc). readme.html renders nicely, but any OTHER .html file in a repo does not. Probed live on john/adom-browser-extension/files/privacy.html (a privacy policy needed for Google Web Store verification of the extension): the page route wraps it in the wiki's file-viewer chrome and shows the markup as source; the raw API (/api/v1/pages/:slug/files/privacy.html) serves Content-Type: application/octet-stream. So there is NO clean rendered URL to hand Google's verifier. Build: 1. RENDERED VIEW IN THE FILES TAB. A Rendered/Source toggle for any .html file (sandboxed iframe), generalizing what readme.html already does to every HTML file in the repo. 2. STANDALONE CLEAN URL. A route that serves a repo .html with Content-Type: text/html and NO wiki chrome - e.g. /:owner/:slug/render/:path - a clean public page for external consumers (Google's verifier, sharing). Must work UNAUTHENTICATED for public pages (the verifier won't log in). 3. SECURITY (the reason it's octet-stream today). Render untrusted user HTML SANDBOXED - from a separate content origin/subdomain (the way GitHub serves user content off a distinct domain) or via a sandboxed iframe + strict CSP - never on the main wiki origin where it could touch session cookies. 4. CONTENT-TYPES. Serve repo assets with correct content-type by extension for public pages (text/html, text/css, image/*, application/javascript) so a rendered page's linked assets actually load. Report back with: the render route, the sandbox/origin model, the content-type handling, whether the standalone URL works unauthenticated for public pages, and a paste-ready prompt for the adom-wiki CLI thread to wire page render <slug> <file.html> (returns the clean URL).
Context: Adom Wiki (wiki.adom.inc). When a repo has BOTH README.md and a custom readme.html, the wiki renders readme.html and silently shadows README.md — with zero warning. Confirmed live on adom-browser-extension: it has both files; readme.html is what renders; GET /api/v1/pages/:slug returns `readme` = the README.md *markdown* (so the API misleads — you read it, see your markdown, assume it's live); there is NO rendered_readme / readme_source_path field; and POST /files accepts README.md edits with a 200 and no hint they won't show. Real incident: an author edited README.md ~6 times (retoning the page, swapping the hero, adding sections), pushed each OK, and none of it showed because readme.html was winning with stale content. ~6 wasted round-trips, no signal why.
Build (any/all):
1. WARN ON PUSH. On POST /api/v1/pages/:slug/files, if the commit touches README.md while readme.html exists, return a warning in the 200 response: { "ok": true, "warnings": ["You committed README.md, but readme.html exists and is what renders on this page. Your README.md change will NOT be visible. Edit readme.html, or delete it to fall back to README.md."] }
2. EXPOSE THE WINNER. Add rendered_readme: "readme.html" | "README.md" (and ideally readme_source_path) to GET /api/v1/pages/:slug, so tools/AI can check before editing. Bonus: have `readme` reflect what actually renders, or clearly label which file it is.
3. UI BADGE. In the Files tab / editor, badge the file currently being rendered ("live") so a human sees at a glance which one wins.
4. DOCUMENT PRECEDENCE. State the rule explicitly (readme.html beats README.md, or whatever it actually is) in the wiki API docs AND the adom-wiki skills — today it's tribal knowledge.
This is the textbook case for the wiki's hint/warning layer: a ~40-token warning would have saved ~6 wasted push-turns.
Report back with a paste-ready conclusions prompt summarizing: what you'll implement (push warning? rendered_readme field? UI badge?), the exact response/field shape, the documented precedence rule, and any timeline — so I can update the adom-wiki skills + tooling and the CLI thread can wire a README_SHADOWED lint that mirrors it.
Context: Adom Wiki discovery quality. The best moment to author a page's discovery keywords is PUBLISH/PUSH time — the AI writing the repo has full context of the app right then. And the way to make those keywords actually good is to immediately simulate them against the whole corpus and hand the result back, so the AI self-corrects before the write is done. (Depends on /discover actually matching triggers — see the earlier discovery prompt; this is its killer app.) The wiki already stores discovery_triggers + discovery_pitch and emits NO_DISCOVERY_TRIGGERS.
Build:
1. FORCE A DISCOVERY REFRESH ON WRITE. On publish / package update (and optionally push), require fresh discovery_triggers + a discovery pitch/snippet — the phrases a typical Adom user would type that should surface this page. If absent or stale, return a hint the AI must satisfy before the write is considered clean. Elevate the existing NO_DISCOVERY_TRIGGERS nudge to a forced, every-write step.
2. SIMULATE + RETURN AS A HINT. On submit of the triggers, run them against the full corpus and return a DISCOVERY_PREVIEW hint: { your_rank, results_returned, collisions: [ { trigger, competes_with: [...] } ], weak_triggers: [...], unique_wins: [...] } so the AI sees "these triggers return 7 pages, you're #5, you collide with X/Y on 'pcb viewer'" and revises in the same loop.
3. RANK BLEND. Score by relevance + quality (composite_score) so a precise new page can win its own niche; report which triggers the page ranks #1 for vs which it's buried under.
4. AI-NATIVE. Structured hint with the simulated search + a concrete action ("drop generic 'board/viewer', lean into 'tscircuit' where you're #1"). A human would get a report; the AI gets a fix it can apply now.
This turns discovery from set-once-and-rot into self-optimizing-at-every-write — the highest-quality-wiki play.
Report back with: the forced-refresh trigger points, the exact DISCOVERY_PREVIEW hint shape, how rank + collisions are computed, and a paste-ready prompt for the adom-wiki CLI thread to wire discover check <slug> + the publish-time preview.
Context: Adom Wiki (wiki.adom.inc). When a page/repo is created under a PERSONAL namespace (e.g. john/foo), only that user can edit it — nobody can collaborate until it's transferred to an org. The wiki gives zero signal about this at creation, so an AI happily creates a collaboration-intended page privately and the human only discovers the lockout later. Real incident: this very spec was published to john/adom-wiki-cli-design when the explicit goal was to collaborate with Colby — he was locked out until it was transferred to adom/. Build: 1. CREATE-TIME OWNERSHIP HINT. On POST /api/v1/pages (and adompkg create / repo init), return a hint stating who can edit it: "Created under john/ (personal) — only you can edit. To collaborate, create under an org or transfer." Include cmd: adompkg transfer--to-org . 2. COLLABORATION-INTENT NUDGE. If the creation context signals collaboration (a brief/description or the agent's stated intent mentioning another person, "collaborate", "with ", "shared"), escalate to a confirmation: "This is solo-owned — did you mean to collaborate? Move it to ." The AI should resolve this BEFORE the human ever sees the lockout. 3. SURFACE EDITABILITY. Expose who-can-edit on GET /api/v1/pages/:slug (owner type personal|org, + the editor set) so tools/AI can check and self-correct. 4. EASY FIX PATH. Make transfer-to-org a first-class, hinted one-liner (it exists — adompkg transfer --to-org — just surface it in the hint). Goal: the human never has to re-prompt the AI or the wiki to "do ownership correctly" — the wiki volunteers it at creation. Report back with: the create-response hint shape, the who-can-edit field on GET pages, how collaboration-intent is detected/passed, and a paste-ready prompt for the adom-wiki CLI thread to wire the create-time ownership hint + a SOLO_NAMESPACE check.
The wiki README markdown sanitizer strips
Requirements for the new wiki — rich content rendering
(captured while building wiki.adom.inc/adom/adom-browser-extension, where each of these blocked us)
=== TWO HARD REQUIREMENTS ===
1) INLINE VIDEO IN A README.
Authors must be able to embed a playable <video> in a page's README/markdown. Today the markdown sanitizer STRIPS <video>/<source> (lib/templates.js -> MD_SANITIZE_OPTS.allowedTags has no video/source), so our 5 demo clips vanish on render and we had to fall back to clickable poster images. Blob serving already does HTTP 206 Range on mp4, so playback works the instant the tag survives.
- Need: allow `video` + `source` (and ideally a sandboxed `iframe` for YouTube/Vimeo) in allowedTags, with allowedAttributes —
video: src,controls,muted,autoplay,loop,playsinline,poster,width,height,preload,class
source: src,type
(A CSP already backs the sanitizer and video/source carry no inline script, so low-risk.)
- Also allow a safe inline-style subset (or class-based styling) on img/video — we had to strip border-radius/border because the `style` attribute is filtered out.
- Acceptance: the 5 <video> tags already in the adom-browser-extension README render as players (mp4s live at demo/clips/use-case-*.mp4).
2) RENDER .html FILES AS HTML (the privacy policy).
A .html file viewed on the wiki must render as a sandboxed HTML page (with a Rendered/Raw toggle), NOT as raw <pre> source. Today fileView shows any non-md/non-image file as <pre class="file-code">, so our privacy.html displays as code — only the .md version renders. We need a real, formatted HTML privacy-policy URL for the Chrome Web Store submission.
- Acceptance: /adom/adom-browser-extension/files/privacy.html shows the formatted policy, not source.
=== RELATED REQUIREMENTS WE ALSO HIT (same theme: serve rich/public content correctly) ===
3) PUBLIC ASSETS ON A CLOSED-SOURCE PAGE.
With source_visibility=private (public page + private source — our intended shipping state), EVERY repo asset except the registered hero returns 403 to logged-out users — our README images AND demo videos 403'd, so we had to keep the page fully open-source. A public product page with closed source needs its README-/hero-referenced assets (images, videos) to stay PUBLIC while the source code is sealed. Need: auto-whitelist README-referenced assets, or a /public asset dir served regardless of source visibility.
4) ORG-TRANSFER REDIRECT MUST PRESERVE SUBPATHS.
After transferring a page to an org, the old URL /<user>/<slug>/files/<path> 301-redirects but DROPS the /files/<path> portion and lands on the page root — so every deep link (privacy policy, skill docs, store links) silently breaks. The redirect must preserve the full path: /<olduser>/<slug>/files/<path> -> /<neworg>/<slug>/files/<path>. (Verified live: /john/adom-browser-extension/files/privacy.html 301s to /adom/adom-browser-extension, dropping the file path.)
5) LARGER BINARY UPLOADS.
The JSON files API returns 413 above ~3.5 MB, so we had to down-res the demo videos to fit. Support multipart/streaming upload (or raise the cap) so demo videos and other assets push at full quality. (Note: the adompkg CLI push already streams multipart up to 100MB — so routing the JSON/base64 + web-UI path through multipart, or raising its cap, closes this.)
Live repro / test page for all of the above: wiki.adom.inc/adom/adom-browser-extension
(README has the stripped <video> tags + poster fallbacks; privacy.html renders as raw code; the page is open-source only because closing the source 403'd the demo assets).
When you've scoped/landed these, send back a paste-ready summary of exactly what changed and the behavior authors can now rely on, so I can flip the extension page over to real inline video + the rendered HTML privacy policy and remove the placeholder workarounds.
The wiki is becoming pervasive — not a cloud-container-only tool. You drive it from native Windows while on Cloud / Hydrogen Desktop; Kyle drives it from native macOS; AIs drive it from the Adom cloud container and the WSL2 box inside Hydrogen Desktop. So adom-wiki can't be a Node script that assumes a runtime — it ships as a suite of compiled, single-file binaries, one per OS/arch, behaviour-identical, all talking to the same wiki.adom.inc API.
| target | built for | runtime |
| windows-x64 | John's native Windows (Cloud Desktop) — PowerShell + cmd | none |
| darwin-arm64 | Kyle's Mac — Apple Silicon | none |
| darwin-x64 | Intel Macs | none |
| linux-x64 | Adom cloud container · CI · WSL2 inside HD | none |
| linux-arm64 | arm cloud / arm WSL2 | none |
Once the CLI is native everywhere, it has to be smart about platform. Every request announces the caller's OS/arch (a X-Adom-Platform: darwin-arm64 header, also in the User-Agent), so the wiki resolves to the right artifact — never hand a Linux binary to a Windows box. This is true for packages and releases alike — each declares what it has per platform. And when there's no prebuilt binary for the caller's platform, the wiki doesn't just 404 — it hands the AI everything it needs to build it and contribute the result back, so the next person on that platform gets it prebuilt. The catalog heals through use. This must be AI-native: structured, runnable, in the spec.
| caller asks (platform X) | wiki finds… | wiki returns |
| install / release download | a prebuilt asset for X | the asset — done, no guessing |
| ↳ | a platform-agnostic pkg (pure source / skill / JS) | the pkg — no platform concern |
| ↳ | no X binary, but source + a build recipe exist | a build-it hint: source + build cmd + verify + the contribute-back cmd |
| ↳ | no X binary, source private / platform unsupported | clear "not available for X" + why (Windows-only by design / ask owner) |
The third row is the magic. A Mac asks for adom-desktop; only windows + linux are prebuilt. Instead of failing, the wiki returns a recipe the AI just runs — and the contribute line means the Mac build now exists for everyone after:
$ adom-wiki pkg install adom-desktop # called from a Mac → X-Adom-Platform: darwin-arm64 { "status": "needs_build", "reason": "no prebuilt darwin-arm64 release; windows + linux exist", "source": { "ref": "v1.4.0", "cmd": "adom-wiki repo clone adom-desktop" }, "build": { "cmd": "bun build --compile --target=bun-darwin-arm64 ./cli.ts --outfile adom-desktop" }, "verify": "./adom-desktop --version # expect 1.4.0", "contribute": "adom-wiki release upload adom-desktop 1.4.0 ./adom-desktop --platform macos", "hint": "No Mac build yet — clone, build, verify, then upload so the next Mac user gets it prebuilt." }
A human hitting "no Mac build" files an issue and waits days. An AI gets a runnable recipe and heals the catalog in one loop — clone, build, verify, upload. The response is structured hints with literal cmds (the same engine as the Hints section), so it costs the AI zero guess-turns.
Each build-back carries provenance — { built_from_commit, sha256, built_by, toolchain } — and lands as community-built, promotable to official by an owner/admin vouch (reusing vouch / verify + the integrity SHA). A Windows user never unknowingly runs a tampered Mac binary.
A wiki is third-party contribution, and platform build-back is that mechanic at its highest leverage. The first Mac user's AI spends the tokens to build adom-desktop once — and every Mac user after gets it instantly prebuilt. The same for every package, every release, every platform.
Scale that across the entire electronics industry: every AI and every third-party user that builds a missing artifact contributes it back, so the catalog gets more complete the more it's used. The wiki turns the industry's distributed token & compute spend into a shared, compounding asset — that spend isn't burned, it's deposited back as durable binaries + provenance. We all benefit.
A breadcrumb is a small trail-marker a third party drops on someone else's anchor repo to announce a related thing they built — a bridge, a surfing skill, a plugin — without edit rights on that repo. The anchor surfaces them; the AI sees "there's a trail here" and follows it. GET /api/v1/pages/:slug/breadcrumbs is already live — the write path + moderation is what we firm up. This is the compounding commons applied to discovery: an anchor grows an ecosystem its owner never has to manage. (Closest known model: webmention / trackback.)
We want an OrCAD bridge, a MATLAB bridge, a desktop-oscilloscope bridge — each a repo owned & maintained by a third party. adom-desktop can't enumerate them all. Each bridge drops a breadcrumb on adom-desktop; an AI working with adom-desktop sees the trail and follows it to the right bridge. No coordination, no edit rights.
chip-fetcher crawls thousands of sites — Adom will never build a skill for each. A user vibe-prompts a skill while surfing Bosch's electronics site; the AI says "great skill — let's publish it and breadcrumb it on chip-fetcher," and every Adom user instantly benefits the next time they hit that site.
Same model, any website the extension navigates. The community posts site-navigation skills as breadcrumbs on the extension's anchor; the extension's AI follows the trail to the right skill for the site it's on.
A popular anchor (chip-fetcher) will attract spam. Breadcrumbs are open to post but owner-moderatable (approve / hide / pin) and ranked by the same composite_score (installs/stars/vouch) — so the best surfing skills surface first and junk sinks.
AI-native, as ever: the anchor's response carries a hint so the AI discovers the trail at the right moment, and contributing back is one flow:
$ adom-wiki repo show chip-fetcher # AI is about to fetch from a new site { "hints": [ { "code": "BREADCRUMBS_AVAILABLE", "data": { "count": 37 }, "message": "37 community surfing skills are breadcrumbed here.", "cmd": "adom-wiki breadcrumb follow chip-fetcher --kind surfing-skill --match bosch.com" } ] } # the user just made a new one — publish + breadcrumb in one flow: $ adom-wiki pkg publish bosch-surf-skill $ adom-wiki breadcrumb post chip-fetcher --to bosch-surf-skill --kind surfing-skill → the commons grows by one; every Adom user benefits next time they hit bosch.com
The wiki renders readme.html beautifully — but any other .html file in a repo doesn't render, it gets dumped as source. Real, blocking case: john/adom-browser-extension/files/privacy.html — a privacy policy needed for Google Web Store verification of the extension, with nowhere clean to point Google. I probed it:
GET /john/adom-browser-extension/files/privacy.html → wrapped in wiki file-viewer chrome ("…- privacy.html - Adom Wiki", /static/style.css) — shows markup, doesn't render GET /api/v1/pages/adom-browser-extension/files/privacy.html → content-type: application/octet-stream — even the raw URL won't render in a browser
A Rendered / Source toggle on the Files tab for any .html (sandboxed iframe) — generalizing what readme.html already does to every HTML file. View it nicely inside the wiki.
Serve the .html with Content-Type: text/html and no wiki chrome — e.g. /john/adom-browser-extension/render/privacy.html — a clean public page for external consumers (Google's verifier, sharing, linking). Must work unauthenticated for public pages.
Rendering untrusted user HTML on the main wiki origin, with the visitor's session cookies in scope, is an XSS hole. So it must be sandboxed: a separate content origin / subdomain (the way GitHub serves user content off a distinct domain) or a sandboxed iframe + strict CSP, so a malicious page can never reach wiki auth. Serving application/octet-stream is the safe-but-useless default; the fix is "render, but sandboxed." A CLI tie: page render <slug> <file.html> returns the clean rendered URL, and lint can flag a linked .html that won't render.
Same family of problem, different surface: the README markdown sanitizer drops <video> / <source> (and iframes), so authors can't embed demo videos. Verified live — adom/adom-browser-extension has 5 <video> tags in its README and the blobs serve fine (HTTP 206, video/mp4, Range), yet 0 video elements render. The fix is a one-line allowlist add (video, source, sandboxed iframe for YouTube/Vimeo) in the sanitizer — low risk, since the CSP is already behind it and media tags carry no inline script. → Colby prompt 12.
Captured while building the live repro page adom/adom-browser-extension, where each of these blocked shipping. Two hard requirements (inline video + real .html render) plus three that share one theme — serve rich/public content correctly. Marked ✓ where I reproduced it live. Full detail + the exact sanitizer diff → Colby prompt 13.
| # | requirement | acceptance | repro |
| 1 | Inline <video> in a README — allow video/source (+ sandboxed iframe) and a safe inline-style/class subset on img/video | the 5 <video> tags in the abe README render as players | ✓ 5→0 |
| 2 | Render .html as sandboxed HTML (Rendered/Raw toggle), not <pre class="file-code"> source | …/files/privacy.html shows the formatted policy (Chrome Web Store needs it) | ✓ raw |
| 3 | Public assets on a closed-source page — with source_visibility=private, every asset but the hero 403s to logged-out users | README-/hero-referenced imgs+videos stay public while source is sealed (auto-whitelist or a /public dir) | per repro |
| 4 | Org-transfer redirect preserves subpaths — today the 301 drops /files/<path> and lands on the page root | deep links (privacy policy, store links, skill docs) survive a transfer | ✓ drops |
| 5 | Larger binary uploads — the JSON files API 413s above ~3.5 MB, forcing down-res'd demo videos | full-res videos/assets push (multipart/streaming or a raised cap) | per repro |
The best moment to author a page's discovery keywords is the instant of publish — the AI writing the repo has full context of the app right then; nobody will ever understand it better. So publish / push / update should force a fresh discovery snippet: the triggers + pitch a typical Adom user would type to surface this page. Set-once-and-rot is how pages go invisible; forcing it on every write keeps the wiki's discoverability as good as its latest author. (The wiki already stores discovery_triggers + discovery_pitch and emits a NO_DISCOVERY_TRIGGERS hint — this elevates that nudge to a forced, every-write step.)
But don't just accept the keywords — prove them. Run the proposed triggers against the whole corpus and hand the simulated search result back in the hints, so the AI self-corrects before the write is even done:
$ adom-wiki pkg publish adom-tsci
{ "ok": true, "hints": [ { "code": "DISCOVERY_PREVIEW",
"message": "Your 8 triggers were simulated against 1,240 pages.",
"data": { "your_rank": 5, "results_returned": 7,
"collisions": [ { "trigger": "pcb viewer", "competes_with": ["adom-3d-viewer","chipfit"] } ],
"weak_triggers": ["board","viewer"],
"unique_wins": ["tscircuit","autorouter rerun"] },
"action": "Rank #5 for your OWN triggers — drop generic 'board/viewer', lean into 'tscircuit/autorouter' where you're #1." } ] }
The AI just built the app — it knows the exact phrases a user would ask for. Capturing the snippet then, and re-confirming on every update, beats any after-the-fact SEO. The wiki self-optimizes its own findability, authored by whoever understands each page best at the time.
The realization John wants the AI to have — "oh crap, these keywords return 7 apps and I'm not even top-3, they collide with X/Y — let me revise" — happens automatically, in the publish loop, instead of after months of "why isn't my page found." Discovery fixed before a single user misses it.
Everything above, sequenced. The trick: most of the restructure is client-only and ships without touching the backend — so Track A (CLI) starts now, Track B (server) lands in parallel, and Track C (distribution — compiling the native suite for every OS) runs cross-cutting alongside both. Owner tags: CLI client-side only · SERVER needs Colby · BOTH client + server.