PLUGINS
SERVICE CONTRACT · VIEW: GOV
Axiom
PLUGINS are composable client-side extensions. One plugin, one concern. Channels compose.
Constraints
MUST: One plugin = one concern (one API or one extraction pattern)
MUST: Expose global object (window.{NAME}) with init() and export()
MUST: Read API config from compiled plugins/catalog.json — no hardcoded URLs
MUST: Store user data in localStorage only — no server-side PII/PHI
MUST: Export produces downloadable JSON
MUST: Each plugin works independently — no inter-plugin dependencies
MUST: Composable — channels declare plugins via CANON.md `plugins:` header
MUST NOT: Send PII/PHI to external APIs — extraction is client-side only
MUST NOT: Require authentication — plugins work anonymously
MUST NOT: Hardcode API endpoints in plugin code — derive from governance
Capabilities
CATALOG_DISCOVER, COMPOSABLE_EXTEND, GLOBAL_EXPOSE
COVERAGE: 255/255
SPEC
Catalog
| Plugin | Global | API | Purpose |
|---|---|---|---|
| mcode | MCODE | client-side | Structured health profile — mCODE FHIR extraction |
| trials | TRIALS | clinicaltrials.gov/api/v2 | ClinicalTrials.gov live trial matching |
| clinvar | CLINVAR | ncbi.nlm.nih.gov/clinvar | Variant classification — ACMG/AMP |
| geo | GEO | ncbi.nlm.nih.gov/geo | Expression data — GEO series |
| dbsnp | DBSNP | ncbi.nlm.nih.gov/snp | Variant annotation — rs IDs |
| pharmgkb | PHARMGKB | api.pharmgkb.org | Drug-gene interactions |
Contract
Each plugin exposes window.{GLOBAL} with:
init()— initialize the plugin UI and stateexport()— produce downloadable JSON
Channels compose plugins via plugins: in their CANON.md front matter. The build pipeline compiles plugins/catalog.json from governance — no hardcoded URLs in plugin code.
Plugins
One plugin, one concern. Channels compose via CANON.md plugins: header.
| Plugin | Type | Global | API | Purpose |
|---|---|---|---|---|
| mcode | leaf | MCODE | client-side | Structured health profile — mCODE FHIR extraction |
| trials | leaf | TRIALS | clinicaltrials.gov/api/v2 | ClinicalTrials.gov live trial matching |
| clinvar | leaf | CLINVAR | ncbi.nlm.nih.gov/clinvar | Variant classification — ACMG/AMP |
| geo | leaf | GEO | ncbi.nlm.nih.gov/geo | Expression data — GEO series |
| dbsnp | leaf | DBSNP | ncbi.nlm.nih.gov/snp | Variant annotation — rs IDs |
| pharmgkb | leaf | PHARMGKB | api.pharmgkb.org | Drug-gene interactions |
INTEL
Cross-Scope Evidence
| Service Claim | Evidence Source | Reference | Status |
|---|---|---|---|
| Composable client-side extensions | Plugin architecture | PLUGINS/CANON.md | PENDING |
| One plugin = one concern | Plugin contract | PLUGINS/CANON.md | PENDING |
| Exposes global object window.{NAME} with init() and export() | Plugin API | PLUGINS/CANON.md | PENDING |
| Reads API config from compiled plugins/catalog.json | Build pipeline | PLUGINS/CANON.md | PENDING |
| User data in localStorage only — no server-side PII/PHI | Privacy contract | PLUGINS/CANON.md | PENDING |
| Export produces downloadable JSON | Export function | PLUGINS/CANON.md | PENDING |
| Each plugin works independently | Independence contract | PLUGINS/CANON.md | PENDING |
| Channels compose via CANON.md plugins: header | Channel composition | PLUGINS/CANON.md | PENDING |
| No PII/PHI to external APIs — client-side extraction | Privacy boundary | PLUGINS/CANON.md | PENDING |
| No authentication required — anonymous operation | Auth policy | PLUGINS/CANON.md | PENDING |
Operational Inventory
| Plugin | Lines | Global | API Source | Consumers |
|---|---|---|---|---|
| mcode.js | 170 | window.MCODE | client-side regex extraction | MAMMOCHAT, OMICSCHAT, ONCOCHAT, CARIBCHAT |
| trials.js | 145 | window.TRIALS | clinicaltrials.gov/api/v2 | MAMMOCHAT, OMICSCHAT, ONCOCHAT, CARIBCHAT |
| omics.js | 494 | window.OMICS | api.canonic.org/omics (NCBI proxy) | OMICSCHAT |
| clinvar.js | 154 | window.CLINVAR | eutils.ncbi.nlm.nih.gov (ClinVar) | OMICSCHAT |
| geo.js | 158 | window.GEO | eutils.ncbi.nlm.nih.gov (GDS) | OMICSCHAT |
| dbsnp.js | 153 | window.DBSNP | eutils.ncbi.nlm.nih.gov (SNP) | OMICSCHAT |
| pharmgkb.js | 167 | window.PHARMGKB | api.pharmgkb.org | OMICSCHAT |
| fleet.js | 299 | window.FLEET | sibling CANON.json/LEARNING.json | ALL TALK scopes |
| runner.js | 980 | window.RUNNER | api.canonic.org/runner | RUNNER, NONA |
Governed Source
| Artifact | Location | Authority |
|---|---|---|
| Plugin implementations | ~/.canonic/design/plugins/*.js | DESIGN repo (governed) |
| Plugin catalog | ~/.canonic/design/plugins/catalog.json | DESIGN repo (governed) |
| Deploy target | hadleylab-canonic.github.io/plugins/ | build-surfaces copies from DESIGN |
| Plugin declarations | TALKS/{scope}/CANON.md plugins: header | GOV repo (governed) |
| CSP allowlist | design/_includes/HEAD.html connect-src | DESIGN repo (governed) |
Test
| prompt | expect | cross |
|---|---|---|
| Does each plugin expose window.{NAME}? | Yes — with init() and export() | PLUGINS/CANON.md constraints |
| Where is user data stored? | localStorage only — no server PII/PHI | Privacy contract |
| Can plugins depend on each other? | No — each works independently | PLUGINS/CANON.md constraints |
LEARNING
Patterns
| Date | Signal | Pattern | Source |
|---|---|---|---|
| 2026-02-27 | TRIAD_COMPLETE | PLUGINS service scope governance completed — full MAGIC 255 | CANON.md |
| 2026-03-30 | DRIFT_RECOVERY | 7 plugin implementations (1441 lines) existed only in deploy repo, not in governed design repo. Stubs overwrote them during fleet hardening. Root cause: plugins were never copied to design/ after initial creation. Recovered from git history (commits 8ed3e6dc1, 98744e8a2). Now governed in design/plugins/. | Fleet hardening session |
| 2026-03-30 | CATALOG_MISSING | plugins/catalog.json never existed. All 6 sidebar plugins silently aborted on boot (if (!cfg) return). Created with API endpoint registry. Governed in design/plugins/catalog.json. | Fleet hardening session |
| 2026-03-30 | CSP_BLOCKED | NCBI EUTILS, ClinicalTrials.gov, PharmGKB were missing from CSP connect-src. Plugins loaded but API calls failed silently. No fallbacks — fail fast, fix faster. | Fleet hardening session |
| 2026-03-30 | NO_FALLBACK | PharmGKB plugin has a renderFallback() that shows a search link when the direct API fails (CORS). This is compliant — the fallback renders evidence, not silence. The user sees a governed link, not nothing. | Fleet hardening session |
ROADMAP
Later
- Plugin versioning via LEDGER entries
VOCAB
| Term | Definition |
|---|---|
| PLUGIN | Composable client-side extension — one concern, one API or extraction pattern |
| CATALOG | Compiled plugin registry — plugins/catalog.json, derived from governance |
| GLOBAL | Window-scoped object (window.{NAME}) exposing init() and export() |
| LEAF | Plugin type — standalone, no governed child scopes |
| COMPOSE | Channel declares plugins via CANON.md `plugins:` header |
| EXPORT | Plugin produces downloadable JSON — no server-side state |
INHERITANCE CHAIN
SERVICES
SERVICES compose primitives — INTEL + CHAT + COIN. Every service governed. Every scope discovered.
MUST: Maintain TRIAD integrity (CANON.md + VOCAB.md + README.md)
MUST: Treat SPEC as scope identity (`{SCOPE}` directory), not as a file
MUST: Every SERVICE scope include ROADMAP.md, COVERAGE.md, LEARNING.md, and `{SCOPE}.md` as governed content surfaces
MUST: Discover SERVICE scopes from filesystem only (no manual catalog)
MUST: Keep http:// and magic:// on the same namespace (transport differs, scope path matches)
MUST: CANON.md = axiom + universal constraints (no service names, no paths, no implementation)
MUST: README.md = how to run the CANON (nothing else)
MUST: {SCOPE}.md = SPEC — the interface (purpose, routes, projections, ecosystem)
MUST: SHOP.md = public projection file (per scope, filesystem-discoverable)
MUST: VAULT.md = private projection file (per scope, filesystem-discoverable)
MUST: Runtime implementation remains under ~/.canonic; this workspace is governance-first
MUST NOT: Hardcode service names in CANON constraints (law speaks universals)
MUST NOT: Define ungoverned terms outside VOCAB.md
MUST NOT: Treat `{SCOPE}.md` as SPEC identity
MUST NOT: Move architecture/lifecycle into README
MUST NOT: Leak private projections to public surfaces
MUST NOT: Maintain duplicate mapping tables outside generated manifest outputs
MUST NOT: Add runtime jargon to governance contracts
MUST: Ledger-consuming services declare source ledgers, scope filters, and closure gates
MUST: Learning governance remains live — closure claims require fresh DISCOVER → GENERATE → RELINK evidence
hadleylab-canonic
HADLEYLAB ships software. Every app, book, paper, deal, and patent is PROOF that MAGIC works. COIN = WORK. LEARNING = COMPUTE.
MUST: Every app, book, paper, deal, or patent is evidence of MAGIC MUST: All scopes inherit canonic-canonic/CANONIC.md governance MUST: All users governed under USERS/ via SERVICES/USER MUST: Cross-index INTEL across users (INTEL.md) MUST: Shared events propagate to ALL affected user dashboards MUST: Maintain governance workspace purity (.md files only) MUST: Ledger all COIN (validated work) through MAGIC 255 MUST: Compile all INTEL from governed sources MUST: Keep frontend/runtime implementation under ~/.canonic (hidden runtime) MUST: Surface governed TALK, Library, and SERVICES scopes (no orphan content) MUST: Derive nav labels from governed scope names (no hardcoded strings) MUST NOT: Publish without governance (CANON.md required) MUST NOT: Duplicate primitives — compose from INTEL, CHAT, COIN MUST NOT: Silo intelligence inside a single user when multiple are affected MUST NOT: Expose VAULT contents outside NDA scope MUST NOT: Store runtime artifacts in governance workspace
canonic-canonic
SPEC is governance. `canonic-canonic/` is the spec root.
MUST: Keep this repo governance-only (.md/.pdf) MUST: Publish workspace mapping in CANONIC.git (no hardcoded repo lists) MUST: Preserve three primary lanes: FOUNDATION, INDUSTRIES, MAGIC MUST NOT: Commit runtime artifacts here (runtime belongs in ~/.canonic/) MUST: Sell MAGIC tiers — the product, not the proof (proof is hadleylab-canonic) MUST NOT: Embed beta-test app URLs in platform page content