docs(10.1): capture phase context
This commit is contained in:
@@ -0,0 +1,167 @@
|
||||
# Phase 10.1: Runtime admin extension point - Discussion Log
|
||||
|
||||
> **Audit trail only.** Do not use as input to planning, research, or execution agents.
|
||||
> Decisions are captured in CONTEXT.md — this log preserves the alternatives considered.
|
||||
|
||||
**Date:** 2026-09-28
|
||||
**Phase:** 10.1-runtime-admin-extension-point
|
||||
**Areas discussed:** Acceptance target, Widget contract, Partials and custom toolbar actions, Asset load and CSP
|
||||
|
||||
---
|
||||
|
||||
## Acceptance target
|
||||
|
||||
| Option | Description | Selected |
|
||||
|--------|-------------|----------|
|
||||
| Fixture plugin | Framework test plugin ships widget + partial + custom button | |
|
||||
| Wait for a real plugin | Seams only; first consumer is user/media | |
|
||||
| Fixture now, real consumer later | Fixture proves contract; real plugin is a later port | |
|
||||
| Other: fonoteka statistics + Discogs widget | Real Albums list stats strip and Albums form Discogs widget | ✓ |
|
||||
|
||||
**User's choice:** Add a statistics partial to the fonoteka plugin above the list, and a custom `fields.yaml` widget that is a button to load data from Discogs (stub until Phase 14).
|
||||
**Notes:** “Above the list” is list chrome, not `type: partial` in `fields.yaml`. Screens locked to Albums list + Albums form.
|
||||
|
||||
| Option | Description | Selected |
|
||||
|--------|-------------|----------|
|
||||
| Click hits a stub endpoint | Enabled button, POST, Phase 14 replaces stub | ✓ |
|
||||
| Visible but disabled | No request until Phase 14 | |
|
||||
| Click only runs widget JS | No new backend action | |
|
||||
|
||||
**User's choice:** Stub endpoint.
|
||||
|
||||
| Option | Description | Selected |
|
||||
|--------|-------------|----------|
|
||||
| Albums list + Albums form | One controller owns both proofs | ✓ |
|
||||
| Collections list + Albums form | Two controllers load different assets | |
|
||||
| You decide | Planner picks screens | |
|
||||
|
||||
**User's choice:** Albums list + Albums form.
|
||||
|
||||
| Option | Description | Selected |
|
||||
|--------|-------------|----------|
|
||||
| Defer custom toolbar | create/delete only until a real third action | |
|
||||
| Add one Albums list action now | Third button, stub POST | ✓ |
|
||||
| Fixture-only custom action | No Płytarium toolbar change | |
|
||||
|
||||
**User's choice:** Add one Albums list action now.
|
||||
|
||||
---
|
||||
|
||||
## Widget contract
|
||||
|
||||
| Option | Description | Selected |
|
||||
|--------|-------------|----------|
|
||||
| SPA owns HTTP | CustomEvent; FieldRenderer POSTs with CSRF | ✓ |
|
||||
| Tiny same-origin helper | SummerAdmin.request() | |
|
||||
| Widget fetch() itself | Widget must remember X-Requested-With | |
|
||||
|
||||
**User's choice:** SPA owns HTTP.
|
||||
|
||||
| Option | Description | Selected |
|
||||
|--------|-------------|----------|
|
||||
| Patch declared fields | YAML `fill` keys; fixture payload allowed | ✓ |
|
||||
| Toast only | Form unchanged | |
|
||||
| Only this field’s value | Widget bound as one field | |
|
||||
|
||||
**User's choice:** Patch declared fields.
|
||||
|
||||
| Option | Description | Selected |
|
||||
|--------|-------------|----------|
|
||||
| Winter-shaped type: widget | tag/path, action, fill; unknown keys fail boot | ✓ |
|
||||
| type + path only | Action and fill live in Go | |
|
||||
| You decide | Planner picks keys | |
|
||||
|
||||
**User's choice:** Winter-shaped `type: widget`.
|
||||
|
||||
| Option | Description | Selected |
|
||||
|--------|-------------|----------|
|
||||
| Attributes + fill snapshot | record-id, field, locale, current fill values | ✓ |
|
||||
| record-id only | Widget cannot see current name/year | |
|
||||
| You decide | Planner picks attributes | |
|
||||
|
||||
**User's choice:** Attributes + fill snapshot.
|
||||
|
||||
---
|
||||
|
||||
## Partials and custom toolbar actions
|
||||
|
||||
| Option | Description | Selected |
|
||||
|--------|-------------|----------|
|
||||
| List-header only | Leave form `type: partial` as a boot error | |
|
||||
| List-header and form type: partial | Both in this phase | ✓ |
|
||||
| You decide | Planner scopes it | |
|
||||
|
||||
**User's choice:** Both.
|
||||
|
||||
| Option | Description | Selected |
|
||||
|--------|-------------|----------|
|
||||
| Curated view model | Typed struct from controller; auto-escaped | ✓ |
|
||||
| Record map + extras | More Winter-like; leak risk | |
|
||||
| You decide | Planner picks data shape | |
|
||||
|
||||
**User's choice:** Curated view model.
|
||||
|
||||
| Option | Description | Selected |
|
||||
|--------|-------------|----------|
|
||||
| config_list.yaml slot | e.g. headerPartial names the template | ✓ |
|
||||
| Controller Go API only | No YAML key | |
|
||||
| You decide | Planner picks declaration | |
|
||||
|
||||
**User's choice:** YAML slot.
|
||||
|
||||
| Option | Description | Selected |
|
||||
|--------|-------------|----------|
|
||||
| Named action + stub POST | toolbar.buttons string list; controller registers extras | ✓ |
|
||||
| Inline map in YAML | strings or {action, label, confirm} | |
|
||||
| You decide | Planner picks YAML | |
|
||||
|
||||
**User's choice:** Named action + stub POST.
|
||||
|
||||
---
|
||||
|
||||
## Asset load and CSP
|
||||
|
||||
| Option | Description | Selected |
|
||||
|--------|-------------|----------|
|
||||
| On controller open | Winter addJs/addCss timing | ✓ |
|
||||
| All registered assets at login | Simpler, more JS in the admin origin | |
|
||||
| Per widget/partial only | Finest grain, define() timing issues | |
|
||||
|
||||
**User's choice:** On controller open.
|
||||
|
||||
| Option | Description | Selected |
|
||||
|--------|-------------|----------|
|
||||
| Embed only | air / summer watch rebuilds; no disk-in-prod | ✓ |
|
||||
| Dev-mode disk override | Original 10.1 note; rejected | |
|
||||
| You decide | Planner picks | |
|
||||
|
||||
**User's choice:** Embed only.
|
||||
|
||||
| Option | Description | Selected |
|
||||
|--------|-------------|----------|
|
||||
| Under admin prefix, script-src 'self' | No unsafe-inline, no extra hosts | ✓ |
|
||||
| Allow nonce inline for widgets | Weaker than current hygiene | |
|
||||
| You decide | Planner picks URL layout | |
|
||||
|
||||
**User's choice:** Prefix + `script-src 'self'`.
|
||||
|
||||
| Option | Description | Selected |
|
||||
|--------|-------------|----------|
|
||||
| Go method on the controller | addJs/addCss; new interface name | ✓ |
|
||||
| YAML asset list | js:/css: in config | |
|
||||
| You decide | Planner picks Go vs YAML | |
|
||||
|
||||
**User's choice:** Go method.
|
||||
|
||||
---
|
||||
|
||||
## the agent's Discretion
|
||||
|
||||
- Exact YAML key names, JS/CSS interface name, stub payload/toast copy, stats numbers, form-partial proof vehicle, custom-element tag naming, create vs update for the widget, asset URL layout, PartialHost vs T-10-16, toolbar action identifier.
|
||||
|
||||
## Deferred Ideas
|
||||
|
||||
- Phase 14: real Discogs client and non-stub payloads
|
||||
- Dev-mode disk override (rejected for v1)
|
||||
- WASM extension API (v2)
|
||||
- Phase 10 leftovers: Ctrl+K, badge columns, Playwright, user/media nav
|
||||
Reference in New Issue
Block a user