This issue records a decision so it doesn't get lost. Don't start on it until a consumer needs live config reload.
Decision (2026-10-27)
There's no config manager in corestack; see standards#9. Live reload is mostly domain-specific: applying a change safely is different for every component. Rebuilding a DB pool, re-binding a listener and swapping a log level have nothing in common, so no config library can do it generically.
The generic part is small, and lifecycle already owns signals:
The hook. Modules may optionally implement Reload(ctx) error.
The trigger. On SIGHUP, lifecycle calls Reload on those modules in registration order and logs any errors. A reload failure doesn't stop the process.
The app's part. The app re-reads and validates its config, then publishes it with atomic.Pointer[Config]. If validation fails, it keeps the old config.
This adds no dependencies and no config abstraction.
Trigger
The first consumer that needs to change config without a restart. The candidates are the Lark Relay daemons and the hosting control panel. Shape the API from that consumer.
Follow-up in corestack/standards
Once the hook ships, add a Go rule to skills/scaffold-project/templates/rules/go.md (and the example backend AGENTS.md): implement live reload, when needed, per module through lifecycle's reload hook, not in a config library. This rule was left out of standards#12 because the hook doesn't exist yet.
Kickoff prompt (once triggered)
Use the feature-delivery skill to resolve corestack/go#12 (the issue body is the spec).
Repo ~/Projects/corestack/go, base main, branch feat/lifecycle-reload. Read AGENTS.md,
the accepted ADRs and the lifecycle package first. The signal source is already
injectable; extend it for SIGHUP without breaking existing callers. Shape it from this
consumer: <describe what needs reloading>. Independent review before the PR.
This issue records a decision so it doesn't get lost. **Don't start on it** until a consumer needs live config reload.
## Decision (2026-10-27)
There's no config manager in corestack; see standards#9. Live reload is mostly domain-specific: applying a change safely is different for every component. Rebuilding a DB pool, re-binding a listener and swapping a log level have nothing in common, so no config library can do it generically.
The generic part is small, and `lifecycle` already owns signals:
- **The hook.** Modules may optionally implement `Reload(ctx) error`.
- **The trigger.** On SIGHUP, lifecycle calls `Reload` on those modules in registration order and logs any errors. A reload failure doesn't stop the process.
- **The app's part.** The app re-reads and validates its config, then publishes it with `atomic.Pointer[Config]`. If validation fails, it keeps the old config.
This adds no dependencies and no config abstraction.
## Trigger
The first consumer that needs to change config without a restart. The candidates are the Lark Relay daemons and the hosting control panel. Shape the API from that consumer.
## Follow-up in corestack/standards
Once the hook ships, add a Go rule to `skills/scaffold-project/templates/rules/go.md` (and the example backend `AGENTS.md`): implement live reload, when needed, per module through lifecycle's reload hook, not in a config library. This rule was left out of standards#12 because the hook doesn't exist yet.
<details>
<summary>Kickoff prompt (once triggered)</summary>
```text
Use the feature-delivery skill to resolve corestack/go#12 (the issue body is the spec).
Repo ~/Projects/corestack/go, base main, branch feat/lifecycle-reload. Read AGENTS.md,
the accepted ADRs and the lifecycle package first. The signal source is already
injectable; extend it for SIGHUP without breaking existing callers. Shape it from this
consumer: <describe what needs reloading>. Independent review before the PR.
```
</details>
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
This issue records a decision so it doesn't get lost. Don't start on it until a consumer needs live config reload.
Decision (2026-10-27)
There's no config manager in corestack; see standards#9. Live reload is mostly domain-specific: applying a change safely is different for every component. Rebuilding a DB pool, re-binding a listener and swapping a log level have nothing in common, so no config library can do it generically.
The generic part is small, and
lifecyclealready owns signals:Reload(ctx) error.Reloadon those modules in registration order and logs any errors. A reload failure doesn't stop the process.atomic.Pointer[Config]. If validation fails, it keeps the old config.This adds no dependencies and no config abstraction.
Trigger
The first consumer that needs to change config without a restart. The candidates are the Lark Relay daemons and the hosting control panel. Shape the API from that consumer.
Follow-up in corestack/standards
Once the hook ships, add a Go rule to
skills/scaffold-project/templates/rules/go.md(and the example backendAGENTS.md): implement live reload, when needed, per module through lifecycle's reload hook, not in a config library. This rule was left out of standards#12 because the hook doesn't exist yet.Kickoff prompt (once triggered)