Deferred: SIGHUP reload hook in lifecycle #12

Open
opened 2026-10-27 11:57:38 -07:00 by end · 0 comments
Owner

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>
Sign in to join this conversation.
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: corestack/go#12