docs: make the plugin hub-ready and self-explanatory for operators - #9
Merged
Conversation
The hub does not store this manifest, it PROJECTS it. `parsePublish`
(omadia-hub/lib/manifest.ts:113-231) keeps identity, compat.core,
setup.fields, setup.guide, provides/requires/depends_on and permissions,
and throws away everything else — including `optional_requires` and every
comment in the file. So the four capabilities this plugin is designed to
survive the absence of, and the degradation it takes for each, were
invisible to anyone deciding whether to install it.
manifest.yaml
- setup.guide (en + de) now carries what the registry cannot: the two
operator grants and how to perform them, the runner backends, the
ledger handoff dry-run, and a degradation table for each optional
capability. The German guide was three sections behind; it is at parity.
- Every setup.fields entry gets label + help as `{ en, de }` maps, the
shape core normalises through manifestLocalized.normalizeLocalized
(byte5ai/omadia#602). 21 fields, both locales.
- compat.core `>=1.0 <2.0` -> `>=1.5 <2.0`. Each of C4/C6/C7/C9/C11 is
traced to the core PR that shipped it; C11 is newest, and it landed in
@omadia/plugin-api 1.5.0. Core never semver-compares compat_core
(manifestLoader.ts:503 and registryClient.ts:415 only carry the string
through to the store view), which is precisely why it has to be honest
rather than permissive: on a 1.4.0 core `ctx.sql.seedLedger` is
undefined and the handoff silently does not happen.
- A header comment recording the kept/stripped split with file:line, so
the next operator-facing block does not get added somewhere that is
discarded at publish time.
The SQL grant has no UI. `pluginSqlGrants.ts` says so twice in its own
source — nothing in core's `src/` calls `grant()`, and the bundled ramp
covers four bundled plugins this one is not among. Documented as the
manual INSERT it currently is, rather than left as "grant the SQL
permission" with no way to do it. The public-path grant does have a
shipped surface and is documented as the endpoint it is.
packages/plugin/README.md ships INSIDE the ZIP and still described 0.1.0:
"Nothing yet", "no routes", "Permissions: none declared". It is the first
thing an operator reads after unzipping. Rewritten for what 0.3.0 does.
Also: docs/OPERATOR-GUIDE.md (the runbook the READMEs link to), a root
README rewritten from "Status: P0 - scaffold" to the current release with
an architecture diagram, CHANGELOG entries for 0.1.0 and 0.2.0
reconstructed from the history plus an Unreleased section, and a
CONTRIBUTING section on keeping the four operator-facing documents in
step.
Verified: typecheck, build, 1269 tests and `npm run package` all pass;
version unchanged at 0.3.0 so the drift guard still agrees. The cut ZIP
was run through the hub's own parsePublish to confirm every gate passes
and to check what the index actually ends up holding.
Weegy
force-pushed
the
docs/hub-annotations
branch
from
August 21, 2026 06:55
48640f6 to
b7e9121
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
The hub does not store
manifest.yaml— it projects it.parsePublish(
omadia-hub/lib/manifest.ts:113-231) lifts a fixed set of fields into theregistry index and discards everything else. Two of the discards matter:
optional_requiresis never read (:221-223nameprovides,requiresand
depends_on, and nothing else). The four capabilities this plugin iswritten to survive the absence of — and the degradation it takes for each —
were invisible to anyone deciding whether to install it.
parseYamlkeeps values, not trivia. All thecareful rationale in this manifest is for whoever edits it, never for an
operator.
Meanwhile
packages/plugin/README.md, which ships inside the ZIP and is thefirst thing an operator reads after unzipping, still described 0.1.0: "Nothing
yet… contributes no routes… Permissions: none declared."
What changed
packages/plugin/manifest.yamlsetup.guide(en + de) now carries what the registry cannot: the twooperator grants and how to perform each, the Fly-vs-Docker runner choice, the
ledger-handoff dry run, and a degradation table for every optional
capability. The German guide was three sections behind English; it is now at
parity.
setup.fields: all 21 entries getlabelandhelpas{ en, de }maps — the shape core normalises through
manifestLocalized.normalizeLocalized(OM-17/15: Google Workspace plugin manifest needs format validation, German labels, and prerequisites on the card omadia#602).
compat.core>=1.0 <2.0→>=1.5 <2.0(reasoning below).identity.descriptionrewritten for the storefront card;categoriesextended with
automationandgithub.omadia-hubfile:line, so the next operator-facing block does not get added somewhere that
is discarded at publish time.
The SQL grant has no UI, and the guide now says so
middleware/src/platform/pluginSqlGrants.tsrecords it twice in its own source— "
plugin_sql_grantsstill has no shipped grant surface — nothing insrc/calls
grant()" (:79-81,:184-185). The hardcoded ramp(
LEGACY_SQL_GRANTS_2026_08_20) covers four bundled plugins; this one isinstalled, not bundled.
So rather than leaving "grant the SQL permission" with no way to do it, the
guide documents the manual
INSERTit currently is. The public-path grantdoes have a shipped surface and is documented as the endpoint it is:
PUT /api/v1/admin/runtime/installed/:id/public-paths.compat.corereasoningpublic_pathspermissions.sqlgateoptional_requires+getOptionalctx.sql.seedLedgerC15 (
permissions.sql.handoff, added by #8) wants plugin-api 1.6.0 and doesnot raise the floor, because it degrades cleanly: an older core ignores the
unknown key and the
activate()seedLedgercall remains the thing thatperforms the handoff. The floor tracks what this plugin cannot run without, not
what it would prefer.
C11 is newest, so 1.5.0 is the floor. Core never semver-compares
compat_core—manifestLoader.ts:503andregistryClient.ts:415only carrythe string through to the store view — which is exactly why it has to be honest
rather than permissive: on a 1.4.0 core
ctx.sql.seedLedgerisundefined, thehandoff silently does not happen, and the migrations re-run against a schema
core already created.
Documentation
docs/OPERATOR-GUIDE.md(new) — install, the two grants, credentials,runner backends, migration handoff (with the real
--plan/--applyCLIcontract), uninstall/purge, troubleshooting, known issues.
README.md— rewritten from "Status: P0 — scaffold / Nothing has movedyet" to the current release, with a mermaid architecture diagram. 269 lines.
packages/plugin/README.md— the in-ZIP operator README, rewritten.CHANGELOG.md— 0.1.0 and 0.2.0 reconstructed from the history, 0.2.0expanded from three lines, plus an
Unreleasedsection for 0.3.1.CONTRIBUTING.md— a section on keeping the four operator-facingdocuments in step, and the two rules that are easy to get wrong.
Verification
No version bump of its own — rebased onto #8, so the artifact is 0.3.1 and
the drift guard still agrees with
package.json.The cut ZIP was additionally run through the hub's own
parsePublish(realfflate+yaml, real gates) to confirm it publishes cleanly and to check whatthe index actually ends up holding:
That last line is the whole reason for this PR.
Notes for review
permissions.sql.handoffkey and the0.3.1 CHANGELOG section are preserved intact; this PR's documentation work is
folded in under the same 0.3.1 heading. The only conflict was in
CHANGELOG.md;manifest.yamlmerged cleanly.README and manifest all record that the fix needs plugin-api 1.6.0 and that
the gap persists below it.
SetupRowprintslabelthroughasText, whichJSON.stringifys a non-string(
app/p/[...id]/page.tsx:243-259), so the{en,de}maps render as raw JSONin the storefront's setup-fields table. Core's install wizard — the surface
where an operator actually fills these in — resolves them correctly. The fix
is one line in
omadia-hub; the maps are deliberately not flattened back tobare English strings to work around it, since that would take German away from
the wizard to protect a display bug.