Validation Checklist
For an extension that declares modelRecommendations, first follow the end-to-end procedure in Model recommendations.
Packaging:
- Run the extension root
npm run build. - Confirm
dist/<id>.isax/extension.jsonexists. - Confirm
dist/<id>.isax/payload.tar.xzexists. - Confirm the distribution
payloadSha256matches the packaged payload. - If the source requests
mod, confirm the package-root manifest contains the normalizedpermissionsand exactmodEntry, and confirm the payload contains that module. - Confirm
payload.tar.xzdoes not containextension.json. - For local dashboard registration, select the final
.isaxdirectory with Browse and confirm it contains regularextension.jsonandpayload.tar.xzfiles. Confirm a package with either file missing, a wrong suffix, a payload digest mismatch, links, traversal entries, or an invalid install manifest is rejected before upload. - Confirm the local flow uploads the payload as an artifact with resource type
extensionand that installation resolves a fresh permission-checked signed link rather than persisting one. - If the source manifest has
modelRecommendations, confirm the validatedschemaVersion: 1block is present inline in the distributionextension.json. - Confirm recommendations use unique portable keys, supported model types, valid source/location combinations, HTTPS or loopback URLs, safe relative output paths, and no credential fields.
- Confirm
normalHttp.autoDownloadis absent orfalseand everyopenAICompatibleAPIsource omitsapiKey.
Before shipping an extension or documenting a new capability, verify:
- Manifest parses and the entry file exists.
- Declared native assets exist.
- Only required permissions are requested.
- A
modextension has one existing safe relativemodEntry; a non-mod extension has nomodEntry. - The mod script registers its exact extension ID exactly once, synchronously, and keeps the iframe entry usable when activation is declined.
- Mod styles, roots, direct DOM state, and listeners are removed after reload, close, update, activation failure, and replacement.
- Helper-created host contributions use
appendStyle,appendRoot, oraddEventListener; every remaining direct host mutation has registered or returned cleanup. - Automatic installation leaves the host module inert until an interactive activation acknowledgement.
- Normal bridge traffic cannot invoke the host loader, access the parent document, or create host contributions.
- Host mod UI uses documented mount points, does not hide the host warning/status, and has usable light, dark, hover, focus, active, and disabled states.
- Implemented APIs match the real host dispatcher.
get_app_infoadvertises the filesystem commands the extension uses.- Extension storage uses
ensureGroupFolder()only when group-shared storage is needed. - Existing workspace files are accessed only after
openWorkspaceFile()oropenWorkspaceFolder()returns a local grant. - Read-only grants reject upload, replacement, and delete.
- Syncable files are written below the returned extension group folder with
metadata.syncable = "true". - The extension does not implement its own offline sync for syncable files.
- Dashboard-backed project files follow the project-sync standard, omit
metadata.syncableunless offline editing is an explicit requirement, and reconcile incoming canonical changes while mounted. - Canonical inventory preserves unavailable/invalid outcomes and never treats them as confirmed remote deletion.
- Local grants can be revoked in Settings and access stops after revocation.
- Project pickers check
get_app_info.projects.commands; archive and restore are shown only whenprojects_set_archivedis advertised. - The default project list hides archived projects. Archive management calls
projects_listwithincludeArchived: trueand distinguishesarchivedprojects from deleted or unknown ids. - Project archive and restore are idempotent, preserve the stable project id, and never delete, move, or orphan extension-owned project files.
- Audio extensions request
audio_capture, survive iframe minimization, and expose a working host-level stop control. - The extension checks
get_app_info.audioCaptureandget_app_info.transcriptionbefore showing media actions. - The microphone grant is host-owned and revocable; revocation stops an active recording for that extension.
- Audio responses, events, shared files, logs, and project metadata contain no audio bytes or local audio paths.
- Missing launch groups and empty speech-to-text provider lists produce clear unavailable states without a workspace-wide model fallback.
- First-use local model download handles only
transcription_model_downloadingas retryable waiting;transcription_model_not_downloadedis surfaced. - The job ID is persisted immediately, restored views call
transcription_get, and event listeners are removed when the view is disposed. failed,cancelled, andinterruptedjobs are handled, active jobs are cancelled before deletion, and only terminal jobs are deleted.- Remote transcription requires host confirmation for every job and never trusts iframe-provided consent, endpoint, or API-key values.
- Speech-to-text models are resolved only from the exact launch group; there is no workspace-wide fallback.
- Transcript/project persistence succeeds durably before local audio cleanup.
- Light and dark themes both work.
- One notification centre is mounted at the extension root and imports the shared
isa-extension-notifications.jsand.csscontracts. - Operational messages appear only in the root notification centre; contextual validation, progress, empty, and durable status remain inline.
- The same outcome is not duplicated inline and in a notification, notification history is bounded/deduplicated, and keyed conditions update in place.
- Error notifications pass caught values through
normalizeExtensionError; known error codes are translated and serialized JSON is never primary copy. - Notifications support individual dismiss, clear-all, timeout countdown, recovery actions, mobile/safe-area layout, and reduced motion.
- Error notifications use alert semantics; all other tones use polite status semantics and appearing notifications do not steal focus.
- Email payloads use the documented contract only.
- Dashboard distribution metadata and disclosure are complete if the extension is intended for distribution.
- Required model recommendations cannot be deselected; recommended items can be toggled individually and selected together.
- Existing recommendation matching uses exact HTTP URL/output or API base URL/provider-model identity plus compatible model types, never display name.
- Selected missing models are created in workspace inventory with no implicit group links.
- API keys entered during recommendation review never appear in extension metadata, stored manifest JSON, logs, or subsequent UI state.
- A required model failure prevents extension creation, leaves the review retryable, and a retry reuses models created by an earlier partial attempt.
- Adding a
normalHttprecommendation does not start a model-byte download; device download and group assignment remain separate actions. - Recommendation keys are not used as runtime model IDs; the extension discovers only models authorized for its exact launch context.
- The extension remains usable or shows a clear setup state when no recommendation is linked to the launch group.
- Documentation tells existing administrators that recommendation changes in an update are not provisioned automatically and uninstall leaves models in workspace inventory.