Files
summercms/.planning/phases/01-framework-kernel-foundation/01-DISCUSSION-LOG.md
2026-09-16 12:03:21 +02:00

171 lines
7.2 KiB
Markdown

# 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/<section>.yaml + config/env/<env>/ | Filename becomes section key; plugins ship config/*.yaml | ✓ |
| Single file plus overlays | base.yaml + <env>.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.<name> sketch) — docs commit