diff --git a/.planning/phases/01-framework-kernel-foundation/01-CONTEXT.md b/.planning/phases/01-framework-kernel-foundation/01-CONTEXT.md
new file mode 100644
index 0000000..3955b1c
--- /dev/null
+++ b/.planning/phases/01-framework-kernel-foundation/01-CONTEXT.md
@@ -0,0 +1,119 @@
+# Phase 1: Framework kernel foundation - Context
+
+**Gathered:** 2026-09-16
+**Status:** Ready for planning
+
+
+## Phase Boundary
+
+Phase 1 delivers the framework kernel in `summercms.go` only: config (`compass`), plugin descriptor and registry with the generated import list and `summer build` (`party`), typed event bus (`festival`), app container and service registry (`backpack`), console command framework with rich output (`bonfire`), and a dev watch loop. It is built only as far as Phase 3's `GET /_fonoteka/api/v1/genres` slice will need, per the interleaved-not-sequential rule. No HTTP router (`surf`), no ORM (`lagoon`), no auth (`bouncer`), no i18n (`phrasebook`) and no scaffolding beyond what `summer build` and the `examples/hello` testbed require. Requirements: KERN-01 through KERN-09 and CLI-01.
+
+
+
+
+## Implementation Decisions
+
+### Binary and repo layout
+- **D-01:** Two binaries, xcaddy-style. `summer` is a framework tool installed once (`go install git.golem15.com/golem15/summercms/cmd/summer`) providing `make:plugin`, `plugin:add`, `build` and `dev`. It generates `main.go` and `plugins.gen.go` in an app repo and runs `go build` there. The app binary (for example `fonoteka`) embeds the framework's runtime commands plus plugin commands. The framework never links an app.
+- **D-02:** One command kernel, two entry points. The framework exposes a `bonfire` kernel function that builds the root cobra command with runtime commands (`serve`, `migrate:*`, `queue:work` as later phases add them). The `summer` tool wraps that kernel plus the build and scaffold commands; the generated app `main.go` calls the same kernel. No duplicated command wiring.
+- **D-03:** The Phase 1 testbed is `examples/hello`, kept permanently: a tiny real app inside the framework repo with its own `go.mod`, linked through a root `go.work`, containing two or three trivial plugins (enough to prove Register-before-Boot, `Requires()` ordering and an optional capability interface). `summer build` and `summer dev` are exercised against it, it is the template source for `make:plugin`, and integration tests run it.
+- **D-04:** Canonical module path is `git.golem15.com/golem15/summercms` (go.mod as committed; origin added and master pushed). Research docs that say `github.com/golem15/summercms` get a one-line correction. Apps require this path and use `go.work` or a local `replace` during development.
+- **D-05:** Pin the toolchain: add `toolchain go1.27.x` to go.mod so every developer and agent builds with the same compiler. Generated app `go.mod` files copy the same line.
+
+### Config layout and keys
+- **D-06:** Plugin config keys use the bare plugin ID as namespace: `golem15.fonoteka.posts_per_page`. App-level sections (`app`, `database`) stay top-level. Rule: a top-level key containing a dot-separated vendor prefix is a plugin namespace. This follows the summer-compass design and reads like WinterCMS's `golem15.fonoteka::key`; STACK.md's `plugins..*` sketch is superseded.
+- **D-07:** File layout follows summer-compass: `config/.yaml` for base config, `config/env//.yaml` for environment overlays, filename becomes the section key. Plugins ship `config/*.yaml` inside their module (embedded FS via the `HasConfig` capability) and are loaded under their namespace. Deep merge, not top-level replace.
+- **D-08:** Environment variables use the `SUMMER_` prefix with `__` as the path separator: `SUMMER_DATABASE__HOST` maps to `database.host`, `SUMMER_GOLEM15__FONOTEKA__POSTS_PER_PAGE` maps to `golem15.fonoteka.posts_per_page`. Single underscores stay literal so snake_case leaf keys are unambiguous. A `.env` file in the app root is loaded when present and never overrides variables already set in the real environment.
+- **D-09:** The full compass override surface is carried over: in-memory `Set` (highest priority), `Persist` writing `config/env//overrides.yaml`, and `Reload` that clears runtime overrides and re-reads disk. Priority, highest wins: runtime Set, persisted overrides, env vars, env overlay file, base file, plugin defaults.
+
+### Plugin lifecycle and events
+- **D-10:** A plugin whose `Requires()` names an unregistered plugin fails boot with an error naming both the plugin and the missing dependency; the binary exits non-zero. Cycles in `Requires()` fail the same way. No warn-and-disable behavior.
+- **D-11:** Optional integration (KERN-05) has two mechanisms, both free of imports of the optional plugin's package: `app.HasPlugin("golem15.translate")` for coarse checks mirroring PHP `class_exists` guards, and a typed lookup on the `backpack` container returning `(value, ok)` for interface-based integration where the optional plugin publishes a service under a `pact` interface.
+- **D-12:** Event listeners have an optional integer priority, default 0. Higher priority runs first; ties keep registration order (stable). Both a plain `Listen` and a priority-taking variant exist. This makes fire-until-handled deterministic and lets ported PHP listeners keep their priorities.
+- **D-13:** Listener error handling per dispatch mode. Fire-and-forget: run every listener, return the joined errors (`errors.Join`). Fire-and-collect: run every listener, return the partial merged payload together with the joined error. Fire-until-handled: the first error stops dispatch and is returned. Panics inside a listener are recovered and wrapped as an error carrying the listener's owning plugin ID.
+
+### CLI and dev loop
+- **D-14:** Rich output widgets are hand-rolled on the standard library plus `golang.org/x/term` for TTY detection and raw mode: braille spinner, gradient progress bar, box-drawing table, ask/confirm/choice/secret prompts, with the non-TTY degradation table from the bonfire plan (static `[...]` line, `[N/M] pct%` updates, tab-separated tables, stdin prompts, `NO_COLOR`/`FORCE_COLOR`/`TERM=dumb` respected). No Charm stack, no pterm.
+- **D-15:** Command names are colon-style like WinterCMS/Artisan: `summer fonoteka:reindex`, `summer make:plugin`, `summer migrate:rollback`. Plugin commands must carry a namespace prefix; kernel commands use their group prefix. cobra accepts colons in `Use`.
+- **D-16:** The dev watch loop is built into the tool as `summer dev` using `fsnotify`: watch the app workspace (Go sources, config, plugin manifests), run the same build step as `summer build`, restart the app binary with a debounce, and print the measured rebuild latency after every cycle. No dependency on an external `air` install; STACK.md's air recommendation is superseded for this purpose.
+- **D-17:** Plugins implement a `bonfire.Command` interface (name, description, flag and argument definition, `Run(ctx, Input, Output) error`). The kernel wraps each into a `cobra.Command`. Output is an injected value so tests capture it and non-TTY degradation is decided once, not per command.
+
+### Claude's Discretion
+- Event identity: typed Go struct events (generic `Listen[T]`), as sketched in ARCHITECTURE.md Pattern 3a; no string-named events. Dispatch is synchronous on the caller's goroutine; async fan-out is a listener's own concern.
+- The event bus and the service registry are fields of the app instance, not package globals, so tests build isolated apps. Only `party`'s `init()` self-registration uses a package-level ordered slice, drained into the app at boot.
+- Plugin IDs are lowercase `vendor.plugin` (`golem15.fonoteka`); matching is exact.
+- Environment detection reads `SUMMER_ENV`, defaulting to `production` as compass did; an explicit constructor argument overrides it.
+- Typed section loading uses koanf's `Unmarshal` into a struct with a `koanf` tag; dot-path getters mirror the compass API (`String`, `Int`, `Bool`, `Has`, plus a `Lookup` returning ok).
+- `plugins.gen.go` is regenerated from an explicit ordered manifest (a `summer.yaml` or the `go.work` use list), never from a map, per the init-order pitfall. `summer build` measures and prints build time.
+- What `make:plugin` scaffolds in Phase 1: the minimum that compiles and registers (go.mod, plugin.go with the required interface, an empty config dir). Model, migration, controller and command stubs belong to Phase 4 (CLI-02).
+- Package layout follows ARCHITECTURE.md's list (`pact`, `towel`, `compass`, `festival`, `backpack`, `party`, `bonfire`, `cmd/summer`, `examples/hello`); `internal/` is used for build codegen helpers not meant as public API.
+
+
+
+
+## Canonical References
+
+**Downstream agents MUST read these before planning or implementing.**
+
+### Kernel architecture and pitfalls
+- `.planning/research/ARCHITECTURE.md` §Component Responsibilities, §Recommended Project Structure, §Pattern 1, §Pattern 2, §Pattern 3, §Anti-Patterns, §Framework vs Application Repo Boundary, §Suggested Build Order — plugin interface sketch, capability interfaces, generated import list, container usage rules, package names. Note: it says `github.com/golem15/summercms` and `cmd/summer` lives in the app repo; D-01, D-02 and D-04 supersede those two points.
+- `.planning/research/PITFALLS.md` §Pitfall 1 (bottom-up kernel), §Pitfall 2 (globals vs context), §Init-order plugin registration nondeterminism, §Dev rebuild loop friction, §Pitfall-to-Phase Mapping — the tests and acceptance criteria Phase 1 must include (`go test -race`, reordered-input test, measured rebuild latency).
+- `.planning/research/SUMMARY.md` §Architecture Approach, §Phase 1, §Research Flags — kernel phase is flagged as safe to plan without deep research.
+- `.planning/research/STACK.md` §Core Technologies (koanf, cobra, goccy/go-yaml versions), §Config: koanf + YAML — the `plugins..*` sketch there is superseded by D-06; air for the watch loop is superseded by D-16.
+- `.planning/research/go-ecosystem.md` §2 Plugin architecture — the Caddy/xcaddy verdict and the hand-rolled event bus verdict.
+
+### Design carry-overs from the Scala modules
+- `../modules/summer-compass/README.md` — config file layout, environment layering priority, plugin namespaces, set/persist/reload API and thread-safety notes; port the design, not the code.
+- `../modules/summer-bonfire/README.md` and `../modules/summer-bonfire/PLAN.md` §Input trait, §Output trait, §Command trait, §CommandRunner, §Non-TTY Graceful Degradation — the command and output interfaces and the degradation table to port.
+- `../IDEA_LIB_NAMES.md` — Go package names (backpack, compass, festival, party, bonfire, pact, towel).
+
+### Project-level decisions
+- `.planning/PROJECT.md` §Constraints, §Key Decisions — stdlib-first rule, two-repo split, compiled plugins only.
+- `.planning/REQUIREMENTS.md` KERN-01..KERN-09, CLI-01 — the phase's requirement text.
+- `.planning/notes/why-go-not-scala.md` — the bottom-up failure mode this phase must not repeat.
+- `CLAUDE.md` (repo root) §GSD workflow rules — lean planning, plan-count checkpoint, unit tests as the last plan, `go vet` and `go test ./...` green at every commit.
+
+
+
+
+## Existing Code Insights
+
+### Reusable Assets
+- No Go code exists yet; the repo holds `go.mod` (module `git.golem15.com/golem15/summercms`, `go 1.27.0`), `README.md`, `CLAUDE.md` and `.planning/`. Everything in Phase 1 is greenfield.
+- Design assets to port: summer-compass (config layering, namespaces, overrides) and summer-bonfire (command interfaces, widgets, degradation table). Their READMEs are the spec; their Scala code is not ported.
+
+### Established Patterns
+- Stdlib-first: new dependencies in Phase 1 are limited to koanf v2 with its file, env and confmap providers and yaml parser, goccy/go-yaml, cobra, golang.org/x/term, fsnotify, and testify for tests. Anything else needs a decision note.
+- Request state travels only in `context.Context` with unexported struct key types and exported accessor functions.
+- Container used only at Register and Boot for constructor injection; application code holds typed fields.
+
+### Integration Points
+- `examples/hello` is the first consumer of every kernel package and the target of `summer build` and `summer dev`.
+- Phase 3 will add `surf`, `lagoon` and `bouncer` on top of `backpack` and `party`; the capability interfaces they need (`HasRoutes`, `HasModels`, `HasMigrations`) may be declared in `pact` now but must not be implemented before Phase 3 pulls them.
+- Phase 2's parity harness has no dependency on Phase 1 and runs in parallel.
+
+
+
+
+## Specific Ideas
+
+- "It should feel like WinterCMS's drop-in loop": `summer dev` prints rebuild latency every cycle so the friction pitfall is visible, and the phase's acceptance includes a measured rebuild time for a single-plugin change in `examples/hello`.
+- Command spelling must let ported PHP commands keep their names (`fonoteka:reindex`, `fonoteka:oauth-client`).
+- The user asked whether `__` is common in Go; answer recorded: single underscore is more common in Go libraries but ambiguous with snake_case keys, `__` is the cross-ecosystem convention (ASP.NET Core, Rust config, dynaconf) and was chosen deliberately.
+
+
+
+
+## Deferred Ideas
+
+- Scaffolding of model, migration, command, job and admin-controller stubs by `make:*` commands — Phase 4 (CLI-02). Phase 1's `make:plugin` produces only the compiling minimum.
+- Admin config editor consuming `Persist` overrides — later admin phase; Phase 1 only provides the API.
+- Extraction of shared stack plugins into their own repos — only when a second app (keios.eu) needs one.
+- One-line corrections to research docs (module path, air, `plugins.` sketch) — do as a docs commit alongside Phase 1 planning, not as code.
+
+
+
+---
+
+*Phase: 01-framework-kernel-foundation*
+*Context gathered: 2026-09-16*
diff --git a/.planning/phases/01-framework-kernel-foundation/01-DISCUSSION-LOG.md b/.planning/phases/01-framework-kernel-foundation/01-DISCUSSION-LOG.md
new file mode 100644
index 0000000..1402ef6
--- /dev/null
+++ b/.planning/phases/01-framework-kernel-foundation/01-DISCUSSION-LOG.md
@@ -0,0 +1,170 @@
+# Phase 1: Framework kernel foundation - 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-16
+**Phase:** 01-framework-kernel-foundation
+**Areas discussed:** Binary and repo layout, Config layout and keys, Plugin lifecycle & events, CLI and dev loop
+
+---
+
+## Binary and repo layout
+
+| Option | Description | Selected |
+|--------|-------------|----------|
+| Two binaries, xcaddy-style | `summer` tool (make:plugin, plugin:add, build, dev) generates main.go + plugins.gen.go in the app repo; app binary embeds runtime and plugin commands | ✓ |
+| One binary per app, named summer | Each app builds its own `summer` in cmd/summer; chicken-and-egg bootstrap | |
+| One binary, framework ships it | Framework ships the runnable binary, apps are plugin sets linked in | |
+
+**User's choice:** Two binaries, xcaddy-style
+
+| Option | Description | Selected |
+|--------|-------------|----------|
+| examples/hello app, kept permanently | Tiny real app in the framework repo, go.work-linked, two or three trivial plugins; build/dev target and make:plugin template | ✓ |
+| internal/testplugin fixtures only | Throwaway plugins only in test packages | |
+| Bootstrap fonoteka.go now | Start the app repo in Phase 1 | |
+
+**User's choice:** examples/hello app, kept permanently
+
+| Option | Description | Selected |
+|--------|-------------|----------|
+| git.golem15.com/golem15/summercms | Keep go.mod as is; research docs corrected | ✓ |
+| github.com/golem15/summercms | Switch go.mod to GitHub | |
+
+**User's choice:** git.golem15.com/golem15/summercms
+**Notes:** User added the origin remote and pushed the current master during the discussion.
+
+| Option | Description | Selected |
+|--------|-------------|----------|
+| Shared bonfire command set, two entry points | Framework exposes a kernel root command; tool and generated app main both call it | ✓ |
+| Tool and runtime fully separate | Runtime commands in a separate package assembled by each app main | |
+
+**User's choice:** Shared bonfire command set, two entry points
+
+| Option | Description | Selected |
+|--------|-------------|----------|
+| Pin toolchain go1.27.x in go.mod | Same compiler everywhere; generated app go.mod copies it | ✓ |
+| Leave floating | Only the minimum go directive | |
+
+**User's choice:** Pin toolchain go1.27.x in go.mod
+
+---
+
+## Config layout and keys
+
+| Option | Description | Selected |
+|--------|-------------|----------|
+| Bare plugin ID: golem15.fonoteka.key | Compass design, WinterCMS-like | ✓ |
+| Prefixed: plugins.golem15.fonoteka.key | STACK.md confmap sketch | |
+
+**User's choice:** Bare plugin ID
+
+| Option | Description | Selected |
+|--------|-------------|----------|
+| Compass layout: config/.yaml + config/env// | Filename becomes section key; plugins ship config/*.yaml | ✓ |
+| Single file plus overlays | base.yaml + .yaml | |
+
+**User's choice:** Compass layout
+
+| Option | Description | Selected |
+|--------|-------------|----------|
+| SUMMER_ prefix, __ for dots, .env loaded when present | Automatic mapping, .env never overrides real env | ✓ |
+| Explicit ${VAR} references in YAML | Laravel-like declared references | |
+| Both | Explicit references plus automatic mapping | |
+
+**User's choice:** SUMMER_ prefix, __ for dots, .env loaded when present
+**Notes:** User first asked "is __ commonly used in Go?". Answer given: single underscore is more common in Go (koanf docs, viper replacer) but ambiguous with snake_case keys; `__` is the cross-ecosystem convention (ASP.NET Core, Rust config crate, dynaconf, nconf); explicit references is the Laravel model. User then chose `__`.
+
+| Option | Description | Selected |
+|--------|-------------|----------|
+| Drop persist, keep in-memory Set | Persistence deferred to the admin phase | |
+| Keep full set/persist/reload | Complete carry-over of the compass surface | ✓ |
+| No runtime overrides at all | Immutable config after boot | |
+
+**User's choice:** Keep full set/persist/reload
+
+---
+
+## Plugin lifecycle & events
+
+| Option | Description | Selected |
+|--------|-------------|----------|
+| Fail boot with a clear error | Missing or cyclic Requires exits non-zero | ✓ |
+| Warn and skip the dependent plugin | WinterCMS-style disable and continue | |
+
+**User's choice:** Fail boot with a clear error
+
+| Option | Description | Selected |
+|--------|-------------|----------|
+| Both: HasPlugin(id) and typed service lookup | Coarse ID check plus (value, ok) interface lookup via pact | ✓ |
+| Service lookup only | Only interface resolution | |
+| HasPlugin(id) only | ID check plus hard import | |
+
+**User's choice:** Both
+
+| Option | Description | Selected |
+|--------|-------------|----------|
+| Optional priority, default 0, registration order within ties | Listen and a priority variant | ✓ |
+| Registration order only | Boot order decides | |
+
+**User's choice:** Optional priority
+
+| Option | Description | Selected |
+|--------|-------------|----------|
+| Errors collected, panics recovered and converted | Joined errors for forget/collect, first error stops until-handled | ✓ |
+| First error aborts every mode | Any error stops dispatch | |
+| Listeners cannot return errors | Log-only listeners | |
+
+**User's choice:** Errors collected, panics recovered and converted
+
+---
+
+## CLI and dev loop
+
+| Option | Description | Selected |
+|--------|-------------|----------|
+| Hand-rolled widgets, stdlib plus x/term | Port bonfire widget designs; full control of degradation | ✓ |
+| charmbracelet lipgloss + huh + bubbles | Charm stack | |
+| pterm | Single library with fallbacks | |
+
+**User's choice:** Hand-rolled widgets
+
+| Option | Description | Selected |
+|--------|-------------|----------|
+| Colon style: summer fonoteka:reindex | WinterCMS/Artisan spelling | ✓ |
+| Nested subcommands: summer fonoteka reindex | Idiomatic cobra tree | |
+
+**User's choice:** Colon style
+
+| Option | Description | Selected |
+|--------|-------------|----------|
+| Built-in summer dev using fsnotify | Watch, rebuild, restart, print latency | ✓ |
+| External air with generated .air.toml | Shell out to air | |
+| Both | Built-in default with --air | |
+
+**User's choice:** Built-in summer dev using fsnotify
+
+| Option | Description | Selected |
+|--------|-------------|----------|
+| Bonfire Command interface wrapped into cobra | Injected Input/Output, cobra adapter | ✓ |
+| Plain cobra commands | Plugins return []*cobra.Command | |
+
+**User's choice:** Bonfire Command interface wrapped into cobra
+
+---
+
+## Claude's Discretion
+
+- Typed struct events, synchronous dispatch; bus and registry live on the app instance
+- Plugin ID casing (lowercase `vendor.plugin`), `SUMMER_ENV` default `production`
+- Typed section loading via koanf Unmarshal; compass-like dot-path getters
+- Ordered manifest as the source for `plugins.gen.go`; build time printed by `summer build`
+- Minimum `make:plugin` scaffold in Phase 1; package layout per ARCHITECTURE.md
+
+## Deferred Ideas
+
+- Full `make:*` scaffolding (model, migration, command, job, admin controller) — Phase 4
+- Admin config editor on top of `Persist` — later admin phase
+- Stack plugin extraction to own repos — when keios.eu needs one
+- Research doc corrections (module path, air, plugins. sketch) — docs commit