feat(mcp): scaffold tool, config/env conventions, and scaffold-hygiene rules #2

Merged
Rene Nochebuena merged 1 commits from feat/app-scaffold into main 2026-08-07 12:22:14 -06:00
Owner

Summary

The MCP documented the wiring conventions but not the config half of a project, and its example main.go omitted the godotenv autoload — so an AI assistant starting an Einherjar service from zero still hand-rolled main.go and the launcher, and got config wrong. This release adds a first-class get_scaffold tool, completes the config / .env.example conventions in the synthetic wire module, and adds three rules that catch the "mess in main.go" pattern. The MCP reaches v1.0.0, aligned with the v1.0.0 framework.


Type of change

  • Bug fix — non-breaking change that resolves an issue
  • New feature — non-breaking addition of functionality
  • Breaking change — alters existing behavior or public API
  • Documentation update
  • Test improvement

Description

Problem. The synthetic wire builtin documented main.go, wire.go's Run(), and the feature-hook pattern, but never internal/config — so an assistant scaffolding a project had no template for the config package and improvised it. Worse, the documented main.go dropped the _ "github.com/joho/godotenv/autoload" import, producing a main that never loaded .env; and the builtin documented migrations and seeding as if they were framework conventions when they are developer choices. Net effect: a project started from zero got a messy main.go, a hand-rolled launcher, and a config that didn't load. The badge and serverVersion were also stale at v0.1.0 while the framework had reached v1.0.0.

Solution.

  • get_scaffold tool (internal/tools/scaffold.go) — the canonical minimum scaffold as ready-to-write files (clean main.go, internal/wire/wire.go, a composed internal/config/config.go, a health hook, .env.example), import paths filled from a module argument. Registered in tools.go.
  • Three validate_snippet rules (internal/rules/scaffold_rules.go) — main.dirty, main.no-godotenv-autoload, config.raw-getenv — with a rules test suite (scaffold_rules_test.go; the package had none).
  • wire builtin rewrite (internal/index/builtins/README.md) — added the Config section (compose framework component configs + caarlos0/env + APP_*/EINHERJAR_*) and the Config & .env.example discipline; fixed main.go to include the godotenv autoload; renamed the assembly file launcher.gowire.go; removed migrations and seeding; re-synced against iron-dough-api / pei-api.
  • Version aligned to v1.0.0 (README badge + serverVersion).

Additive and backward-compatible: the existing ten tools and their behaviour are unchanged; tools go 10 → 11 and validation rules 8 → 11; the index schema is unchanged.


Test plan

  • go build ./...
  • go test ./...internal/index and the new internal/rules suite green
  • go vet ./internal/tools/
  • Redeploy and smoke-test get_scaffold from a live MCP client
## Summary The MCP documented the wiring conventions but not the config half of a project, and its example `main.go` omitted the godotenv autoload — so an AI assistant starting an Einherjar service from zero still hand-rolled `main.go` and the launcher, and got config wrong. This release adds a first-class `get_scaffold` tool, completes the config / `.env.example` conventions in the synthetic `wire` module, and adds three rules that catch the "mess in main.go" pattern. The MCP reaches **v1.0.0**, aligned with the v1.0.0 framework. --- ## Type of change - [ ] Bug fix — non-breaking change that resolves an issue - [x] New feature — non-breaking addition of functionality - [ ] Breaking change — alters existing behavior or public API - [x] Documentation update - [x] Test improvement --- ## Description **Problem.** The synthetic `wire` builtin documented `main.go`, `wire.go`'s `Run()`, and the feature-hook pattern, but never `internal/config` — so an assistant scaffolding a project had no template for the config package and improvised it. Worse, the documented `main.go` dropped the `_ "github.com/joho/godotenv/autoload"` import, producing a `main` that never loaded `.env`; and the builtin documented migrations and seeding as if they were framework conventions when they are developer choices. Net effect: a project started from zero got a messy `main.go`, a hand-rolled launcher, and a config that didn't load. The badge and `serverVersion` were also stale at `v0.1.0` while the framework had reached v1.0.0. **Solution.** - **`get_scaffold` tool** (`internal/tools/scaffold.go`) — the canonical minimum scaffold as ready-to-write files (clean `main.go`, `internal/wire/wire.go`, a composed `internal/config/config.go`, a health hook, `.env.example`), import paths filled from a `module` argument. Registered in `tools.go`. - **Three `validate_snippet` rules** (`internal/rules/scaffold_rules.go`) — `main.dirty`, `main.no-godotenv-autoload`, `config.raw-getenv` — with a rules test suite (`scaffold_rules_test.go`; the package had none). - **`wire` builtin rewrite** (`internal/index/builtins/README.md`) — added the Config section (compose framework component configs + `caarlos0/env` + `APP_*`/`EINHERJAR_*`) and the Config & `.env.example` discipline; fixed `main.go` to include the godotenv autoload; renamed the assembly file `launcher.go` → `wire.go`; removed migrations and seeding; re-synced against `iron-dough-api` / `pei-api`. - **Version aligned to `v1.0.0`** (README badge + `serverVersion`). Additive and backward-compatible: the existing ten tools and their behaviour are unchanged; tools go 10 → 11 and validation rules 8 → 11; the index schema is unchanged. --- ## Test plan - [x] `go build ./...` - [x] `go test ./...` — `internal/index` and the new `internal/rules` suite green - [x] `go vet ./internal/tools/` - [ ] Redeploy and smoke-test `get_scaffold` from a live MCP client
Rene Nochebuena added 1 commit 2026-08-07 12:22:07 -06:00
Major release to v1.0.0, aligned with the v1.0.0 framework. The MCP documented
the wiring conventions but not the config half of a project, and its example
main.go omitted the godotenv autoload — so an assistant starting a service from
zero still hand-rolled main.go and the launcher, and got config wrong. This adds
a first-class scaffold, completes the config/.env.example conventions, and adds
rules that catch the "mess in main" pattern.

internal/tools:
- New get_scaffold: returns the canonical minimum application scaffold as
  ready-to-write files (main.go with godotenv autoload + wire.Run(), wire.go,
  a composed config.go, a health hook, .env.example), with import paths filled
  from a `module` argument. Registered in tools.go.

internal/rules:
- Three new validate_snippet rules, appended in scaffold_rules.go: main.dirty
  (launcher/components built in main instead of internal/wire),
  main.no-godotenv-autoload (a wire-convention main that never loads .env), and
  config.raw-getenv (an EINHERJAR_* var read via os.Getenv instead of composing
  the component Config; EINHERJAR_LOG_* stays with logz.direct-env-read).
- scaffold_rules_test.go — internal/rules had no tests; asserts each new rule
  fires and that a clean main is not flagged.

internal/index (builtins):
- The synthetic wire module gains a Config section (compose the framework's
  component configs, load with caarlos0/env, APP_* app fields / EINHERJAR_*
  framework fields) and a Config & .env.example discipline (every env var the
  config reads is documented in .env.example, kept in lock-step).
- main.go now shows the `_ "github.com/joho/godotenv/autoload"` blank import,
  previously omitted. The assembly file is renamed launcher.go -> wire.go.
- Migrations and seeding removed from the documented scaffold — developer
  choices, not framework conventions. Re-synced against iron-dough-api / pei-api.

Version:
- Badge and serverVersion const were stale at v0.1.0; both now v1.0.0.

Docs:
- README (eleven tools, eleven validation rules) and CHANGELOG updated.

No new dependencies. The wire conventions are embedded at build time
(//go:embed builtins/README.md) and the new tool and rules are compiled in, so a
deployment must be rebuilt to serve them; a server still running the v0.2.0
binary keeps serving the old conventions until redeployed.
Rene Nochebuena requested review from CoreDevelopers 2026-08-07 12:22:07 -06:00
Rene Nochebuena requested review from Agents 2026-08-07 12:22:07 -06:00
Rene Nochebuena merged commit a0b803cb40 into main 2026-08-07 12:22:14 -06:00
Rene Nochebuena deleted branch feat/app-scaffold 2026-08-07 12:22:14 -06:00
Sign in to join this conversation.
No Reviewers
einherjar/CoreDevelopers
einherjar/Agents
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: einherjar/mcp#2