# Addon Skeleton Specification **Project:** kane-diagnostics **Version:** 1.0 **Prerequisite reading:** README.md, DSC-development-map.md, HANDOFF.md, CODING-GUIDELINES.md --- ## Purpose This document specifies the three addon skeletons to be created as the baseline for the kane-diagnostics project. It is a handoff document — the incoming Assistant reads this, reads the repos, and then works with the operator to build each skeleton before any functional code is written. A skeleton is not a working addon. It is the correct structure, the correct conventions, the correct file layout, and the correct configuration — with placeholder content where the logic will go. A skeleton that compiles and loads without errors is a skeleton that is ready to develop. **Nothing in this document should be built without the operator's input and confirmation at each step.** --- ## The Three Addons ### vs01 — Vital Signs **Purpose:** Present the ten structural preconditions of an HOA association. Public-facing — readable without authentication. This is the first thing a participant reads and the first thing an attorney reads. **Route:** `/vs01` **Access:** Public read. No authentication required to view. HOA_MEMBER standing required to submit a Vital Signs record for a specific association. **What it does:** - Presents each of the ten Vital Signs in plain language - Explains why each one matters to the homeowner - Provides public record lookup guidance for each Vital Sign (Recorder of Deeds, Secretary of State, IDFPR, etc.) - Allows a verified participant to submit a Vital Signs record for their association - Stores the record via the orchestrator spool **What it does not do:** - It does not present scenarios - It does not present case law - It does not manage attorney listings --- ### dsc01 — Diagnostic Surface Categories **Purpose:** Present the Diagnostic Surface Categories — the legal surfaces where HOA governance disputes manifest — organized from the homeowner's perspective. Browsable publicly. Case law entries require HOA_MEMBER standing to submit. **Route:** `/dsc01` **Access:** Public read. HOA_MEMBER standing required to submit a diagnostic record or case law entry. **What it does:** - Presents the ten Active DSC categories with their diagnostic questions - Presents the Vital Sign dependencies for each category - Presents case law entries organized by DSC category - Connects each DSC category to the relevant Vital Signs - Allows verified participants to submit accounts under a specific DSC category - Stores records via the orchestrator spool **What it does not do:** - It does not present scenarios - It does not manage the Vital Signs record - It does not manage attorney listings --- ### scn01 — Scenarios **Purpose:** The participant intake surface. A verified participant reads diagnostic scenarios, writes their account in their own words, and submits. The account is the record. **Route:** `/scn01` **Access:** HOA_MEMBER standing required. Public visitors see the access wall with SASE instructions. **What it does:** - Presents the scenario carousel — browse only, no selection required - Accepts the participant's account in their own words - Writes the submission to the orchestrator spool as a TMP record - Provides an operator-only `/scn01/manage` interface for scenario management and TMP review **What it does not do:** - It does not present Vital Signs - It does not present case law - It does not manage attorney listings **Relationship to pilot:** The pilot `ds01` addon in `caselaw-document-access` is the functional prototype for this addon. The new `scn01` is a clean rebuild on the complete foundation — not a port of the pilot code. The pilot is reference, not source. --- ## Skeleton File Structure Each addon skeleton follows this structure. Files marked `[placeholder]` contain the correct structure but no functional logic. ``` hubzilla/addon/{addon}/ {addon}.php — main addon file: hooks, load/unload, content routing {addon}.apd — app descriptor mod_{addon}.pdl — PDL layout: aside, content, right_aside config.json.template — all config fields documented, no secrets Widget/ {Addon}.php — sidebar widget: navigation, resources, status view/ css/ {addon}.css — all presentation styles, no inline styles anywhere js/ {addon}.js — all behavior, no inline scripts anywhere contracts/ spool-v1.json — the spool envelope contract this addon produces README.md — one paragraph: what this addon does and does not do ``` --- ## Skeleton Content Requirements ### {addon}.php Must contain, in order: 1. **File header** — addon name, description, version, min/max Hubzilla version 2. **Hook registration** — `{addon}_load()` and `{addon}_unload()` with PDL and Widget hooks 3. **PDL loader** — `{addon}_load_pdl()` following the established convention 4. **Helper** — `{addon}_h()` — the HTML escape function 5. **Access state** — `{addon}_access_state()` — returns `'public'`, `'participant'`, or `'operator'` 6. **Access wall** — `{addon}_access_wall()` — plain language, SASE link 7. **Content router** — `{addon}_content()` — loads CSS/JS, checks access, routes by path and method 8. **Config loader** — `{addon}_load_config()` 9. **CSRF token and verify** — standard pattern 10. **Placeholder content functions** — one per route, each returning a `// TODO` string with a plain description of what goes here No functional logic in the skeleton. No database calls. No file I/O. No orchestrator calls. Those come after the skeleton is confirmed. ### {addon}.apd ``` version: 2 url: $baseurl/{addon} requires: local_channel name: {Descriptive name} photo: icon:{bootstrap-icon-name} categories: Civic Diagnostics desc: {One sentence — what this addon does.} ``` ### mod_{addon}.pdl ``` [template]default[/template] [region=aside] [widget={addon}][/widget] [/region] [region=content] $content [/region] [region=right_aside] [widget=notifications][/widget] [widget=newmember][/widget] [/region] ``` ### config.json.template Every field the addon reads from `config.json` must appear here with a descriptive comment and a placeholder value. No field should ever be read from `config.json` that does not first appear in `config.json.template`. ```json { "_note": "Copy to config.json. Do not commit config.json — it contains secrets.", "receiver_url": "REPLACE — orchestrator receiver endpoint", "node_token": "REPLACE — shared secret for node-to-orchestrator auth", "corpus_builder_group_id": 0 } ``` ### Widget/{Addon}.php Must contain: - Correct namespace: `namespace Zotlabs\Widget;` - Class name matching filename exactly: `class {Addon}` - `widget($arr)` method returning sidebar HTML - `current_step()` or `current_route()` for navigation state - Sidebar navigation showing current location - Resources panel using `data-{addon}-resource` attributes — no navigation links ### contracts/spool-v1.json The JSON contract this addon produces and POSTs to the orchestrator. Must contain: - `_header` block with all required fields documented - `_payload` block with the addon-specific fields - `_meta` block describing the contract version and purpose This file is the contract. When the payload structure changes, the version increments and a new file is created (`spool-v2.json`). The old contract is never deleted — it documents what the orchestrator must remain able to consume. ### {addon}.css Skeleton contains: - File header comment with addon name and version - Section comments for each visual area: layout, header, content, sidebar, resources, manage - No rules yet — just the section comments as placeholders ### {addon}.js Skeleton contains: - IIFE wrapper - `initResourcePanels()` function — complete, this is the same in every addon - One placeholder function per interactive area with a `// TODO` comment - `init()` calling all functions - DOMContentLoaded guard The `initResourcePanels()` function is shared behavior. It is the same in every addon. Copy it exactly from the pilot — it is proven. --- ## Build Sequence The operator will direct which addon to build first. The expected sequence based on the DSC development map is: 1. `vs01` — Vital Signs — because it is the entry point for both participants and attorneys 2. `dsc01` — DSC Categories — because it is the primary reference surface 3. `scn01` — Scenarios — because it depends on both Vital Signs and DSC context being established **Each skeleton must be confirmed working — loading without errors, displaying the access wall or placeholder content correctly — before the next skeleton begins.** --- ## What the Operator Will Decide Before Each Skeleton Is Built Before writing any skeleton file, discuss and confirm with the operator: 1. The exact route — the operator may have a different preference than what is proposed here 2. The access model — which privacy group gates participant access for this addon 3. The sidebar content — what resources and navigation the Widget shows 4. The config fields — whether any addon-specific configuration is needed beyond the standard fields 5. The spool contract — what the payload block contains for this addon's submissions Do not assume these decisions are made because they appear in this document. This document proposes. The operator decides. --- ## What Not To Do - Do not port the pilot `ds01` code. Read it as reference. Write the skeleton fresh. - Do not add functional logic to the skeleton. Placeholders only. - Do not generate all three skeletons at once. One at a time, confirmed working before the next begins. - Do not create files that already exist in the repo. Read the repo first. - Do not hardcode any value that belongs in `config.json`. - Do not write inline styles or inline scripts. - Do not exceed 500 lines in any PHP file. The skeleton should be well under that — if it is approaching 300 lines before any logic is added, something is wrong.