Give check_env struct-level granularity. It could only be told which modules an app composes, so it couldn't flag a var that lives on one struct of a multi-struct module — e.g. EINHERJAR_SERVER_CORS_ORIGINS is on web.Config, and an app that composes web/server.Config never reads it, yet modules: ["web"] treated it as composed. Adds a composes input taking exact module/subpackage/Struct selectors.
Type of change
New feature — non-breaking addition (new optional input)
Breaking change
Description
composes input on check_env: struct selectors like web/server/Config, db-postgres/Config, core/logz/Config. Two-segment module/Struct targets a module-root config.
not-composed now reasons over the union of composed vars (from modules via envspec.ForModule and from composes via envspec.FindStruct), instead of a module set. This is what lets it catch struct-level dead vars.
Backward compatible: modules still works and keeps its coarse behavior; composes is additive.
Version → v1.1.1.
Test plan
go build ./... and go test ./...
New test: EINHERJAR_SERVER_CORS_ORIGINS flagged not-composed with composes: ["web/server/Config"], and NOT flagged with modules: ["web"] (documents the two granularities)
New test: malformed selector (web) and non-existent struct (web/server/Nope) both error
Redeploy and exercise check_env with composes from a live MCP client
## Summary
Give `check_env` struct-level granularity. It could only be told which *modules* an app composes, so it couldn't flag a var that lives on one struct of a multi-struct module — e.g. `EINHERJAR_SERVER_CORS_ORIGINS` is on `web.Config`, and an app that composes `web/server.Config` never reads it, yet `modules: ["web"]` treated it as composed. Adds a `composes` input taking exact `module/subpackage/Struct` selectors.
---
## Type of change
- [x] New feature — non-breaking addition (new optional input)
- [ ] Breaking change
---
## Description
- **`composes` input** on `check_env`: struct selectors like `web/server/Config`, `db-postgres/Config`, `core/logz/Config`. Two-segment `module/Struct` targets a module-root config.
- **`not-composed`** now reasons over the union of composed vars (from `modules` via `envspec.ForModule` and from `composes` via `envspec.FindStruct`), instead of a module set. This is what lets it catch struct-level dead vars.
- Backward compatible: `modules` still works and keeps its coarse behavior; `composes` is additive.
Version → v1.1.1.
---
## Test plan
- [x] `go build ./...` and `go test ./...`
- [x] New test: `EINHERJAR_SERVER_CORS_ORIGINS` flagged `not-composed` with `composes: ["web/server/Config"]`, and NOT flagged with `modules: ["web"]` (documents the two granularities)
- [x] New test: malformed selector (`web`) and non-existent struct (`web/server/Nope`) both error
- [ ] Redeploy and exercise `check_env` with `composes` from a live MCP client
Patch to v1.1.1. check_env could only reason at module granularity, so a var
that lives on one struct of a multi-struct module (e.g. EINHERJAR_SERVER_CORS_ORIGINS
on web.Config, not web/server.Config) couldn't be flagged dead when the app
composes the sibling struct. Adds struct-level selectors to close that gap.
internal/tools (check_env):
- New `composes` input: exact config structs as module/subpackage/Struct selectors
(e.g. web/server/Config, db-postgres/Config, core/logz/Config), alongside or
instead of the coarse `modules` list.
- not-composed now reasons over the union of composed vars (from modules AND
struct selectors), so it surfaces struct-level dead vars. Coarse modules:["web"]
keeps the prior behavior.
- parseStructSelector helper; errors on malformed or non-existent selectors.
Tests: struct-level dead-var catch (CORS flagged with web/server/Config but not
with module web), bad-selector errors; existing calls updated to the new arg.
Version bumped to v1.1.1 (badge + serverVersion). No dependency changes.
Rene Nochebuena
requested review from CoreDevelopers 2026-08-07 19:39:02 -06:00
Rene Nochebuena
requested review from Agents 2026-08-07 19:39:02 -06:00
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.
Summary
Give
check_envstruct-level granularity. It could only be told which modules an app composes, so it couldn't flag a var that lives on one struct of a multi-struct module — e.g.EINHERJAR_SERVER_CORS_ORIGINSis onweb.Config, and an app that composesweb/server.Confignever reads it, yetmodules: ["web"]treated it as composed. Adds acomposesinput taking exactmodule/subpackage/Structselectors.Type of change
Description
composesinput oncheck_env: struct selectors likeweb/server/Config,db-postgres/Config,core/logz/Config. Two-segmentmodule/Structtargets a module-root config.not-composednow reasons over the union of composed vars (frommodulesviaenvspec.ForModuleand fromcomposesviaenvspec.FindStruct), instead of a module set. This is what lets it catch struct-level dead vars.modulesstill works and keeps its coarse behavior;composesis additive.Version → v1.1.1.
Test plan
go build ./...andgo test ./...EINHERJAR_SERVER_CORS_ORIGINSflaggednot-composedwithcomposes: ["web/server/Config"], and NOT flagged withmodules: ["web"](documents the two granularities)web) and non-existent struct (web/server/Nope) both errorcheck_envwithcomposesfrom a live MCP client