# 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