7.2 KiB
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/ |
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_ENVdefaultproduction - Typed section loading via koanf Unmarshal; compass-like dot-path getters
- Ordered manifest as the source for
plugins.gen.go; build time printed bysummer build - Minimum
make:pluginscaffold 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