Initial push

This commit is contained in:
2026-06-13 08:09:39 -04:00
parent d2d2a4d596
commit b8750e50c5
5 changed files with 587 additions and 21 deletions

View File

@@ -0,0 +1,191 @@
# DSC-01 Renderer Spec — Diagnostic Surface Categories
**Version:** 1.0
**Companion to:** VS-RENDERER-SPEC.md (Vital Signs)
**Source taxonomy:** DSC-development-map.md
---
## 1. Purpose
dsc01 presents the ten Active Diagnostic Surface Categories (DSC-01 through
DSC-10) as a **homeowner-applied checklist** attached to a case record. It is
architecturally distinct from vs01:
| | vs01 (Vital Signs) | dsc01 (Categories) |
|---|---|---|
| Cardinality | One record per association | Many records per association (one per case) |
| Authored by | Operator defines schema; participants/professionals/operator fill perspectives | Operator defines taxonomy only; homeowner selects |
| Record shape | Per-VS-code form submission | Single record: multi-select DSC codes + narrative |
| Mutability | Public-record perspective may be immutable after submit | Each case record is its own append-only entry |
| Storage | vs01 spool → orchestrator | dsc01 spool → orchestrator (separate receiver/records file) |
The ten DSC schema files under `diagnostic-categories/` are **read-only
reference data** to the renderer. Homeowners never create, edit, or remove
DSC codes, fields, or categories — that is operator-only, done by editing
the schema JSON files and pushing through the standard tarball workflow.
---
## 2. Schema file shape
Each `diagnostic-categories/DSC-0X-*.json` contains a single `_meta` block:
```json
{
"_meta": {
"code": "DSC-01",
"title": "Assessments",
"cai_reference": "Assessments",
"homeowner_relevance": "Critical",
"development_status": "Active",
"summary": "...",
"vital_sign_dependencies": [
{ "code": "VS-01", "relevance": "..." }
],
"diagnostic_questions": [ "...", "..." ]
}
}
```
No `fields`, `perspectives`, or `_meta.form` keys — there is nothing for a
homeowner to fill in per category. The `diagnostic_questions` array is
**homeowner-facing**: shown inline in the checklist UI to help a homeowner
decide whether a category applies to their situation.
---
## 3. Record shape (dsc01 spool envelope)
One record represents one homeowner's self-assessment for one case. It is
a standalone record type — it does **not** embed into or extend a vs01
record. It carries a reference back to the relevant association's VS
profile via `association_slug`, the same slug key used in
`vs01/config.json`.
```json
{
"addon": "dsc01",
"contract_version": "1.0",
"association_slug": "kingsrow-wdca",
"association_channel_id": "123",
"submitted_at": "2026-06-13T00:00:00+00:00",
"standing": "participant",
"dsc_codes": ["DSC-01", "DSC-07"],
"narrative": "Free-text description of the homeowner's situation."
}
```
Field notes:
- `dsc_codes` — array of selected DSC-0X codes, in any order, at least one
required.
- `narrative` — single free-text field for the whole record (not per-code).
Optional but encouraged.
- `standing` — result of `dsc01_access_state()` at submission time
(`operator` / `participant` / `professional` / `public`), recorded for
provenance. Public submissions are rejected before reaching the spool
(see Access section below).
- `association_slug` / `association_channel_id` — pulled from
`vs01/config.json`, same as vs01's envelope. This is the cross-reference
that lets the corpus place a DSC record against the association's VS
profile without embedding one record type inside the other.
---
## 4. Access model
dsc01 reuses `vs01_access_state()`'s logic by reading the same
`vs01/config.json` associations/groups config — already implemented in
`dsc01_access_state()`. No separate access config file for dsc01.
- **public** — may read the category list, diagnostic questions, and the
checklist UI, but POST submissions are rejected (access wall shown,
same pattern as vs01's `vs01_access_wall()`).
- **participant** — may submit a DSC record for the association they're a
Privacy Group member of.
- **professional** — read access; submission behavior TBD (not blocking for
v1; treat as participant for now unless told otherwise).
- **operator** — full access, plus (future) a manage/review view over
submitted records, mirroring vs01's `vs01_render_manage()` stub.
---
## 5. Routes
- `/dsc01` — index. Lists the ten DSC categories with title + one-line
summary, similar to vs01's `vs01_render_index()` association list, but
here listing categories rather than associations.
- `/dsc01/{association_slug}` — landing page for that association. Shows
the checklist form (all 10 categories, each with diagnostic questions
expandable/inline) plus the narrative field and submit button.
- `/dsc01/{association_slug}` (POST) — submission handler. Validates
`dsc_codes` (at least one selected), builds the envelope (Section 3),
POSTs to orchestrator via `dsc01_post_to_orchestrator()`.
- `/dsc01/{association_slug}/manage` — operator-only, future. Review queue
for submitted DSC records (mirrors vs01's TMP-review stub).
No per-code routes (no `/dsc01/{slug}/DSC-01`) — unlike vs01, there is no
per-category form to navigate to.
---
## 6. Checklist UI
For each of the 10 categories, in DSC-01..10 order:
```html
<div class="dsc01-category">
<label>
<input type="checkbox" name="dsc_codes[]" value="DSC-01">
<strong>DSC-01</strong> — Assessments
</label>
<details class="dsc01-questions">
<summary>Diagnostic questions</summary>
<ul>
<li>Was the assessment properly authorized by the Board...?</li>
...
</ul>
</details>
</div>
```
After the 10 categories, a single `<textarea name="narrative">` for the
free-text case description, then submit.
`vital_sign_dependencies` are **not** shown in the homeowner checklist UI in
v1 — they are reference data for professional/operator views (future:
cross-link from a DSC record back to the association's VS profile to show
which VS conditions are most relevant given the selected DSC codes).
---
## 7. Spool / orchestrator
`dsc01_spool.php` mirrors `vs01_spool.php`'s `*_post_to_orchestrator()`
pattern:
- Reads `receiver_url` / `node_token` from `dsc01/config.json` (separate
config keys from vs01 — see `config.json.template`).
- POSTs the JSON envelope (Section 3) via curl, same header shape
(`Content-Type: application/json`, `X-Node-Token`).
- On success, shows a confirmation with a link back to the association
landing (`vs01/{slug}` or `dsc01/{slug}`, TBD which is more useful as the
"return to" target — likely `vs01/{slug}` since that's the association's
primary page).
- On failure, shows the same alert-danger pattern as vs01.
`records_file` (host-only, heredoc-created, never committed) is reserved
for a future local append-only log if the orchestrator round trip needs a
local fallback/cache — not required for v1 if the orchestrator receiver is
reliable. Document only; do not implement unless requested.
---
## 8. Out of scope for this pass
- Per-DSC-code detail pages.
- Operator manage/review UI (stub only, mirroring vs01's placeholder).
- Cross-linking rendered VS dependencies into the UI.
- Incubator (DSC-11..16, DSC-24) and Monitor categories — not represented
as schema files until promoted to Active per DSC-development-map.md.