design(app-creator): S6 — forfatt ios-app referanse-domain-pack + start claude-code-plugin-pakke

- domain-packs/ios-app/: komplett referanse-pakke (8 komponenter) — pack.json med
  components-map, conventions.md, 4 patterns/, gotchas.md, checklist.md splittet i 3
  (App Store-submission + security-privacy/MASVS 2.1 + accessibility/WCAG 2.2 AA),
  3 scaffold/-maler (PrivacyInfo.xcprivacy-plist, NSUsageDescription-inventar,
  ASC-metadata), eksempel-feature-brief i Voyage strict-mode-format, glossary.md.
  Hver teknisk påstand verifisert mot Apple Developer / W3C WAI / OWASP MAS.
- domain-packs/claude-code-plugin/: stub — pack.json + conventions.md + gotchas.md
  + checklist.md + glossary.md ferdige (ekstrahert fra ktg-privat-konvensjoner);
  patterns/scaffold/examples er stubs.
- docs/domain-pack-spec.md: § D2/D3/D4/D7 + restrisiko oppdatert — pack.json
  components-felt, core/supplementary låst til manifestet, checklist-splitt-konvensjon,
  snapshot-materialiserings-mekanikk presisert, iOS-versjons-korreksjon (iOS 26, ikke
  "iOS 18/19"), D7 → "forfattet i S6".
- prototype-run/friksjon.md: #9 (Akashic-briefen refererer "iOS 19" som ikke finnes —
  rettes i S7) + S6-prosessnotater (checklist-splitt bekreftet nødvendig, components-gap
  fylt, verifiserings-asymmetri ios-app vs claude-code-plugin notert).
- CLAUDE.md: peker til domain-packs/ under § Status.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Kjell Tore Guttormsen 2026-05-12 14:06:54 +02:00
commit 2011507ea1
27 changed files with 1059 additions and 17 deletions

View file

@ -1,8 +1,8 @@
# Domain-pack-spec (app-creator)
<!-- Skrevet: 2026-05-11 (S5) -->
<!-- Status: FØRSTEUTKAST. Domene-nøytral spec. Referanse-pakkene (ios-app, claude-code-plugin) forfattes i S6 — kun skissert her (§ 7). Spec-en er hypotese inntil den første referanse-pakken faktisk er bygget og konsumert av en pipeline-fase. -->
<!-- Begrunnelse / research-grunnlag: prototype-run/research/research-brief.md § 5 (D1D7), prototype-run/research/C-domain-packs.md § 5, friksjon #5 og #7. -->
<!-- Skrevet: 2026-05-11 (S5). Revidert: 2026-05-12 (S6) — pack.json `components`-felt + status; core/supplementary-merking låst til pack.json; checklist-splitt-konvensjon; D7 oppdatert (pakkene forfattet); iOS-versjons-korreksjon (iOS 26, ikke "iOS 18/19"); restrisiko-lista oppdatert. -->
<!-- Status: ANDREUTKAST. Domene-nøytral spec. Referanse-pakkene (ios-app komplett, claude-code-plugin som stub) er forfattet i `../domain-packs/` (S6). Spec-en er fortsatt hypotese inntil den første referanse-pakken faktisk er konsumert av en pipeline-fase (S8+). -->
<!-- Begrunnelse / research-grunnlag: prototype-run/research/research-brief.md § 5 (D1D7), prototype-run/research/C-domain-packs.md § 5, friksjon #5, #7, #9. -->
## D1 — Hva en domain pack er
@ -35,7 +35,7 @@ Hver komponent er en dedikert fil eller katalog under en `domain-pack/`-rot. Sek
| 7 | Reference impl | `examples/` | Eksempel-briefer, eksempel-artefakter — konsumeres av brief-generator i fase 6/7 som "slik ser en god feature-brief ut i dette domenet". | supplementary |
| 8 | Glossary | `glossary.md` | Domene-vokabular — lastes selektivt (fase 1 ved behov, ved oppslag). | supplementary |
**Hard lengde-grense per fil:** ~500 ord / én skjerm der mulig. Lange filer er usynlige for agenten (Cursor-erfaringen: regler ignoreres når de blir for lange). Hvis en pattern-fil eller checklist sprenger grensen: del den i flere filer under `patterns/` eller seksjoner i `checklist.md` som lastes uavhengig. `examples/`-filer er unntatt grensen (de er referanse-materiale, ikke instruksjon).
**Hard lengde-grense per fil:** ~500 ord / én skjerm der mulig. Lange filer er usynlige for agenten (Cursor-erfaringen: regler ignoreres når de blir for lange). Hvis en pattern-fil eller checklist sprenger grensen: del den i flere filer `patterns/{a}.md`, `patterns/{b}.md`, eller `checklist.md` + `checklist-{tema}.md` (som i `ios-app`: `checklist.md` = App Store-submission + index, `checklist-security-privacy.md` = MASVS + privacy-manifest, `checklist-accessibility.md` = WCAG 2.2 AA — hver lastes uavhengig). Hver split-fil får sin egen `components`-oppføring i `pack.json`. `examples/`-filer er unntatt grensen (referanse-materiale, ikke instruksjon).
**Katalog-layout:**
```
@ -43,7 +43,7 @@ domain-pack/ ({name}/)
├── pack.json
├── conventions.md
├── gotchas.md
├── checklist.md
├── checklist.md # + valgfri checklist-{tema}.md-splitt
├── glossary.md
├── patterns/
│ ├── {pattern-a}.md
@ -64,10 +64,17 @@ Minimalt JSON-manifest. Ingen npm-semantikk, ingen build-step, ingen lock-fil.
"schema": "domain-pack/v1",
"name": "ios-app",
"version": "0.1.0",
"domain": "iOS-app-utvikling (Swift/SwiftUI)",
"description": "Domene-kunnskap for iOS-app-utvikling med Swift/SwiftUI",
"domain": "iOS-app-utvikling (Swift/SwiftUI, App Store-distribusjon)",
"description": "Domene-kunnskap for iOS-app-utvikling: HIG/Liquid Glass, Swift/SwiftUI, offline-first, App Store-submission, MASVS 2.1, WCAG 2.2 AA, privacy manifest.",
"phases": [1, 3, 4, 5, 6, 7],
"verified": { "date": "2026-05-11", "against": "iOS 18, HIG WWDC2025, MASVS 2.1, WCAG 2.2" }
"verified": { "date": "2026-05-12", "against": "iOS 26 (gjeldende SDK), HIG/Liquid Glass (WWDC 2025), deployment-baseline iOS 1718, OWASP MASVS 2.1.0, WCAG 2.2 AA", "note": "kildebelegg inline i pack-filene" },
"components": {
"conventions.md": "core",
"gotchas.md": "core",
"checklist.md": "core",
"patterns/offline-first-swiftdata.md": "supplementary",
"scaffold/PrivacyInfo.xcprivacy": "supplementary"
}
}
```
@ -79,7 +86,9 @@ Minimalt JSON-manifest. Ingen npm-semantikk, ingen build-step, ingen lock-fil.
| `domain` | string | ja | Menneskelesbar domene-beskrivelse. |
| `description` | string | ja | Én-linjes formålsbeskrivelse. |
| `phases` | number[] | ja | Hvilke pipeline-faser som *kan* laste fra pakken (17). En fase som ikke er i lista laster ikke pack-filer. |
| `verified` | object | ja | `{ "date": "YYYY-MM-DD", "against": "..." }` — sist-verifisert-dato + mot hvilken versjon av domenet (iOS-versjon, HIG-utgave, standard-versjoner). Gjør at man ser når en pakke er i ferd med å råtne. |
| `verified` | object | ja | `{ "date": "YYYY-MM-DD", "against": "...", "note"?: "..." }` — sist-verifisert-dato + mot hvilken versjon av domenet (iOS-versjon, HIG-utgave, standard-versjoner) + valgfri kilde-note. Gjør at man ser når en pakke er i ferd med å råtne. |
| `components` | object | ja | Map fra hver pack-fil-sti (relativt pakke-roten) til `"core"` eller `"supplementary"`. **Dette er den autoritative core/supplementary-merkingen** (S6-beslutning — sentralt i manifestet, ikke spredt i fil-headere; en kort `<!-- core/supplementary -->`-kommentar i toppen av hver fil er kun en menneske-leselig redundans). `core`-filene materialiseres sammenslått inn i `00-context/domain-pack-{name}.md`; `supplementary` lastes on-demand. |
| `status` | string | nei | Fritekst om pakkens modenhet (f.eks. "stub — kun core-filene ferdige"). Kun for pakker under arbeid. |
Ingenting i `pack.json` er menneske-leselig *innhold* — alt innhold lever i markdown-filene. Manifestet er kun maskinlesbart metadata.
@ -102,7 +111,7 @@ Ingenting i `pack.json` er menneske-leselig *innhold* — alt innhold lever i ma
**Materialisert snapshot i `00-context/`.** Ved init av app-creator-instansen (eller når en pack legges til) materialiseres et snapshot av pakken — versjonen appen bruker — inn i `{app-creator-instance-dir}/00-context/domain-pack-{name}.md`. Snapshotet er en sammenslått, lesbar form av pakkens core-komponenter (conventions + gotchas + checklist + de patterns appen faktisk bruker), med pack-versjonen innskrevet i toppen. Begrunnelse: embedding slår linking for AI-konsum (BMAD-prinsippet) — fase 7-`context.md` embedder utdrag fra dette snapshotet, ikke pekere til en ekstern pakke som kan ha endret seg. (Copier-mønsteret: den genererte appen "kjenner" sin egen versjon av kilden.)
**core vs supplementary-merking.** Hver pack-fil merkes `core` (alltid relevant for de fasene den gjelder) eller `supplementary` (lastes kun ved eksplisitt behov). Snapshotet i `00-context/` inkluderer core-komponentene; supplementary lastes on-demand fra `domain-packs/{name}/` direkte.
**core vs supplementary-merking (S6-beslutning).** Hver pack-fil merkes `core` (alltid relevant for de fasene den gjelder) eller `supplementary` (lastes kun ved eksplisitt behov). **Merkingen ligger sentralt i `pack.json` under `components`** — ikke spredt i fil-headere; en kort `<!-- domain-pack: {name} · component: {type} · core/supplementary -->`-kommentar i toppen av hver fil er kun menneske-leselig redundans, ikke kilden. Snapshotet i `00-context/` inkluderer core-komponentene; supplementary lastes on-demand fra `domain-packs/{name}/` direkte. (Begrunnelse: én autoritativ kilde for hva som er core, og maskinlesbar — en snapshot-generator kan lese `components` direkte uten å parse fil-headere.)
**Ingen runtime-framework.** Hele mekanikken er: fase-agent leser `state.json` → finner `domain_pack`-verdien → resolver stien (`domain-packs/{name}/` i plugin-roten) → leser den/de fil(ene) fase-prompten ber om → bruker `00-context/`-snapshotet for embedding i fase 7. Matcher filsystem-som-state-invarianten. Zero eksterne verktøy.
@ -144,13 +153,13 @@ Når en feature-brief overleveres til Voyage (fase 7):
Praktisk: når fase 7 skriver `context.md`, henter den relevante avsnitt fra `00-context/domain-pack-{name}.md`-snapshotet (med `pack-overrides.md` anvendt), parafraserer/utdrag-er dem inn under `## Domain-pack-utdrag`-seksjonen som *bare kontekst* — uten metadata om hvor det kom fra.
## D7 — Referanse-pakkene (skisse — S6 forfatter dem)
## D7 — Referanse-pakkene (forfattet i S6)
app-creator shipper to referanse-pakker som eksempel-implementasjoner. Fork-and-own-brukere lager egne. **Disse skisseres her, ikke spesifiseres — S6 er forfatter-sesjonen.**
app-creator shipper to referanse-pakker som eksempel-implementasjoner i [`../domain-packs/`](../domain-packs/). Fork-and-own-brukere lager egne. **Skissen under er beholdt for kontekst; den realiserte tilstanden er i `domain-packs/`.** S6 (2026-05-12) forfattet `ios-app` komplett (alle 8 komponenter; `checklist.md` splittet i 3); `claude-code-plugin` som stub (`pack.json` + `conventions.md` + `gotchas.md` + `checklist.md` + `glossary.md` ferdige). **Korreksjon under verifisering (S6):** "iOS 18 / HIG WWDC2025" i skissen var basert på prototype-data — den verifiserte tilstanden er at gjeldende iOS er **iOS 26** (Liquid Glass, WWDC 2025; iOS 1925 finnes ikke — Apple gikk fra iOS 18 til iOS 26), deployment-target-baseline iOS 1718, MASVS **2.1.0**, WCAG 2.2 AA (W3C Rec 2023-10-05). `ios-app/pack.json` `verified` reflekterer dette. (Akashic-`01-app-brief.md`s "iOS 19" rettes i S7 — se `prototype-run/friksjon.md` #9.)
### `ios-app`-pakke (fra Akashics reelle behov)
- **`pack.json`:** `name: "ios-app"`, `version: "0.1.0"`, `phases: [1, 3, 4, 5, 6, 7]`, `verified` mot iOS 18 / HIG WWDC2025 / MASVS 2.1 / WCAG 2.2.
- **`pack.json`:** `name: "ios-app"`, `version: "0.1.0"`, `phases: [1, 3, 4, 5, 6, 7]`, `verified` mot iOS 26 / HIG/Liquid Glass (WWDC 2025) / deployment-baseline iOS 1718 / OWASP MASVS 2.1.0 / WCAG 2.2 AA; `components`-map merker core/supplementary.
- **`conventions.md`:** HIG-regler (navigasjon, layout, "Liquid Glass"-konformans-notat); Swift/SwiftUI-konvensjoner; MVVM-vs-TCA-veiledning (når hva); min-iOS-versjon-policy; guardrails-underseksjon (App Store-constraints du ikke avviker fra; GDPR-håndtering).
- **`patterns/`:** `offline-first-swiftdata.md`, `local-notifications.md`, `widget-live-activities-shared-model.md` (deling av datamodell mellom app/widget/Live Activity), `current-location-regeneration.md` (current-location-basert beregning + fallback ved nektet permission).
- **`gotchas.md`:** required-reason-API-deklarasjon (manglende = avvisning); ATS-unntak uten begrunnelse; `NSUsageDescription` manglende = umiddelbar App Store-avvisning; vanlige App Store Review-avvisnings-triggere.
@ -172,10 +181,13 @@ app-creator shipper to referanse-pakker som eksempel-implementasjoner. Fork-and-
## Åpne spørsmål / restrisiko
- **Snapshot-materialiserings-mekanikk.** Nøyaktig hvordan `00-context/domain-pack-{name}.md` genereres fra `domain-packs/{name}/` (hvilke filer slås sammen, i hvilken rekkefølge, hvor mye trimmes) — låses når den første pakken faktisk materialiseres i S7. Inntil da: "core-komponentene, sammenslått, pack-versjon innskrevet".
- **`pack.md` med YAML-frontmatter som alternativ til `pack.json`.** Thread C nevnte begge. S5-valg: `pack.json` (rent maskinlesbart, ingen risiko for at noen putter innhold i frontmatter). Revurderes hvis det viser seg upraktisk.
- **Når en fase trenger en `patterns/`-fil som ikke er i `phases`-lista.** Skal pakken da utvides, eller skal fasen klare seg uten? Sannsynlig: utvid pakken (en pattern relevant for en fase hører i pakken) — men det er en S6+-beslutning per konkret tilfelle.
- **Pakke-deling på tvers av repos.** Hvis app-creator-instanser i ulike repos vil dele samme `ios-app`-pakke: da må lagrings-stedet flyttes til `~/.claude/domain-packs/` eller eget repo. Ikke et problem så lenge forfatteren er eneste konsument med pakkene i plugin-roten.
- **Snapshot-materialiserings-mekanikk.** Nøyaktig hvordan `00-context/domain-pack-{name}.md` genereres fra `domain-packs/{name}/` — låses når den første pakken faktisk materialiseres i **S7**. S6-presisering: generatoren leser `pack.json``components`, slår sammen alle `"core"`-filene i den rekkefølgen `components` lister dem (`conventions.md`, `gotchas.md`, `checklist.md` + evt. `checklist-{tema}.md`), skriver pack-navn + `version` + materialiserings-dato i toppen, anvender `00-context/pack-overrides.md` på slutten. `supplementary` tas *ikke* med — lastes on-demand. Eksakt trimming/seksjonering avgjøres i S7 mot den faktiske `ios-app`-pakken.
- **`core` vs `supplementary`-merking — LÅST (S6).** Ligger i `pack.json``components` (map fil-sti → `"core"`/`"supplementary"`). Fil-headere har en redundant kommentar for menneske-lesere, men `components` er kilden. Se § D2 / § D3 / § D4.
- **`pack.md` med YAML-frontmatter som alternativ til `pack.json` — LUKKET (S5/S6).** `pack.json` valgt og brukt; ingen grunn til å revurdere. Tatt ut av risiko-lista.
- **Når en fase trenger en `patterns/`-fil som ikke er i `phases`-lista.** Skal pakken da utvides, eller skal fasen klare seg uten? Sannsynlig: utvid pakken (en pattern relevant for en fase hører i pakken) — men det er en per-tilfelle-beslutning. Ikke truffet i S6 (ingen fase ble kjørt).
- **`pack.json` `verified` håndheves ikke automatisk.** Ingen mekanisme sjekker at `verified.date` ikke er for gammel; det er en menneskelig disiplin. Hvis pakker råtner i praksis: vurder en lett validator (`.mjs`) som flagger gamle `verified`-datoer. YAGNI inntil bevist behov.
- **Pakke-deling på tvers av repos.** Hvis app-creator-instanser i ulike repos vil dele samme `ios-app`-pakke: lagrings-stedet må flyttes til `~/.claude/domain-packs/` eller eget repo. Ikke et problem så lenge forfatteren er eneste konsument med pakkene i plugin-roten.
- **Domene-versjons-drift (iOS spesielt).** `ios-app`-pakken er verifisert mot iOS 26 / WCAG 2.2 / MASVS 2.1.0 per 2026-05-12. iOS 27 kommer høst 2026 — da må `conventions.md`, `gotchas.md`, `checklist*.md` og `pack.json` `verified` revideres, minor- eller major-bump avhengig av om noe brytende endres. Logget mønster, ikke et åpent designspørsmål.
## Kilder
@ -184,3 +196,4 @@ app-creator shipper to referanse-pakker som eksempel-implementasjoner. Fork-and-
- `prototype-run/research/D-feature-artifacts.md` § 2 — BMAD-prinsippet (embedding slår linking for AI-konsum) som begrunner `00-context/`-snapshot framfor ekstern peker.
- `prototype-run/friksjon.md` #5 (flat layout antok ikke domain-pack-kontekst), #7 (tre sjekkliste-grupper uten eierfase — løses av `checklist.md`-komponenten).
- `phase-design-draft.md` — fase-seksjonene som konsumerer pakkene; `CLAUDE.md` — verktøy-agnostisk- og Voyage-agnostisk-invariantene D6 respekterer.
- **S6-verifiseringskilder for `ios-app`-pakken** (per-påstand inline i pack-filene): Apple Developer (developer.apple.com — privacy-manifest, required-reason API, App Store Connect screenshot specs, Upcoming Requirements, ATT/ATS, UNUserNotificationCenter, Live Activities, Liquid Glass/HIG, App Store Review Guidelines); W3C WAI (w3.org/WAI — WCAG 2.2 What's New + W3C Recommendation 2023-10-05); OWASP MAS (mas.owasp.org — MASVS 2.1.0, 8 kontroll-grupper). `claude-code-plugin`-pakken: ekstrahert fra ktg-privat `CLAUDE.md` + `.claude/rules/{plugin-convention,hook-format}.md` (intern konvensjon) — plattform-detaljer (hooks-API, `${CLAUDE_PLUGIN_ROOT}`, auto-discovery) bør re-verifiseres mot offisiell Claude Code-dokumentasjon ved neste oppdatering (ikke gjort uttømmende i S6 — pakken er en stub).