* arch: decouple HTTP API gateway and MCP gateway via shared schema resolver
- Add gateway/schema: shared registry watcher and endpoint schema parser
used by both gateways, replacing duplicated discovery logic in gateway/mcp
- gateway/mcp: consume schema.Resolver; add NewServer for independent
lifecycle (discovery/watching in NewServer, transport in Serve, shutdown
via Stop)
- gateway/api: remove MCPEnabled/MCPAddress fields and background MCP
spawning; the HTTP gateway no longer starts MCP
- cmd/micro/run and cmd/micro/gateway: instantiate and orchestrate both
gateways explicitly, shutting down together on signal or first exit
- Mark gateway decoupling tickets 01-03 done
* feat(mcp): add streamable-HTTP transport for browser MCP clients
Implement the MCP streamable-HTTP spec at /mcp: POST JSON-RPC (batches,
notifications -> 202), GET SSE stream with heartbeat and session
lifecycle, DELETE session teardown, Mcp-Session-Id minted on initialize,
30-min idle session sweep. Tool dispatch shares invokeTool with the
legacy /mcp/call route; x402 challenge and tool-execution errors surface
as isError results.
Fixes browser-based clients (llama.cpp web UI): CORS preflight allows
mcp-protocol-version, and serveHTTP now shuts down the HTTP server when
the context is canceled so Ctrl-C/SIGTERM terminate cleanly.
* docs(website): document streamable-HTTP MCP transport and gateway decoupling
* fix(gateway): add /api/{service}/{method} HTTP-to-RPC proxy
The gateway only rendered the /api explorer page; any /api/{service}/{endpoint}
path fell through to 404. Add a proxy that resolves the endpoint from the
registry, checks scopes, and forwards the request body to the RPC client.
Accepts both /api/{service}/{method} and /api/{service}/{pkg}/{method} forms.
* fix(readme): old links, add protoc and docs for docker
* test(store): de-flake file store expiry window in first block
The initial record used a 150ms expiry read back immediately after a
bbolt write. Under -race/-cover on a loaded runner, the fsync'd write
or instrumented read can exceed 150ms, so the record has already
expired and Read("Hello") returns ErrNotFound, failing the test early.
Widen the first block to the same 1s expiry / 2s sleep pattern used by
the sibling blocks since #3789/#3828. The pre-expiry read stays well
inside 1s; the post-expiry read comfortably exceeds it.
* fix(website): more uglyURLs on main page
* docs(website): fix contributing doc paths and jekyll references
* docs(website): dedupe duplicate pages, standardize on _index.md sections
Remove duplicate page titles in internal/website/content/en so every
title resolves to a single canonical page. Precedence: directory index
pages with bundled images, then the most complete content; draft copies
were dropped.
Removed duplicates (kept page in parentheses):
- docs/overview/*/index.md (dir index + image) vs docs/*.md for
ai-integration, architecture, config, getting-started, observability
- docs/interfaces/{broker,registry,transport}/index.md (dir index +
image) vs docs/{broker,registry,transport}.md
- docs/interfaces/{plugins,store}.md vs docs/{plugins,store}.md
- docs/contributing.md and docs/guides/contributing.md vs
docs/project/contributing.md
- docs/guides/quickstart.md vs docs/quickstart.md
- docs/overview/performance.md vs docs/performance.md
- docs/project/{roadmap,roadmap-2026}.md vs docs/roadmap.md
- docs/architecture/{index,adr-*}.md (already mirrored and kept in
docs/project/architecture/, whose index now links the available ADRs)
- docs/model.md vs docs/model/index.md
- blog/news/agent-guardrails.md vs docs/guides/agent-guardrails.md
- docs/examples/learn-by-examples/* (near-identical copies) vs
docs/examples/*
- docs/overview/{REFLECTION-EVALUATION-SUMMARY,TLS_SECURITY_UPDATE}.md
(draft copies)
- docs/index.md and docs/examples/index.md symlinks vs their _index.md
Frontmatter tidy: add missing descriptions (store, atlas-cloud, model),
drop weight/draft overrides, consolidate the Architecture Decision
Records index, and remove dead CSS overrides from _styles_project.scss.
Hugo conventions: _index.md is the branch/section bundle for a
directory - it is the landing page for a doc section that lists its
children. index.md is a leaf bundle - a standalone page at the exact
directory URL whose directory bundles its own resources (images, etc.).
The docs site standardizes on _index.md for section landing pages, so
the redundant index.md symlinks were removed and the duplicate
Architecture directory was merged into the project/architecture section.
* refactor(website): merge duplicates
* docs(website): fix relative links and wayfinding tests after Hugo migration
Replace Jekyll-era .html links with .md/index.md targets, fix relative
paths for pages moved into Hugo bundles, restore the ADR files dropped by
the duplicate-merge refactor, and update zero-to-hero-ci docs tests to the
content/en/docs layout.
* test(cmd/micro): expect .md guide links in docs, translate for CLI alignment
* docs(website): drop duplicate h1s, promote titles, backfill descriptions
Auth is a policy of exposure, not of which command you typed. The bind
address decides the default and there is never a default credential.
- Address-based default: loopback (127.0.0.1/localhost/::1) => auth off;
non-loopback (0.0.0.0/routable) => auth on. micro run now binds
127.0.0.1:8080 by default, so the dev loop and localhost MCP clients
work with no login; micro gateway keeps :8080 (exposed => on).
- No default credential: stop creating admin/micro. When auth is on, use
--auth-token / MICRO_AUTH_TOKEN or generate a machine token and print it
once. It is accepted as an admin (constant-time compare) alongside JWTs.
- Token for machines, login for the browser: /api and /mcp accept
Authorization: Bearer and a ?token= query param (for SSE / links).
- Explicit override both ways: --auth/--no-auth and MICRO_AUTH=on|off,
shared by run and gateway via AuthFlags.
- Capability-aware even locally: checkEndpointScopes no longer short-
circuits when auth is off, so a tool with a required scope (actions,
paid) still needs a token+scope on a loopback gateway; read-only tools
stay open.
Adds gateway/auth.go (isExposed, ResolveAuth, static token, AuthFlags)
with tests, updates the run banner and the micro-run guide. Smoke-tested:
loopback /api open (404 no-service, not 401); exposed /api 401 without a
token and authenticated with Bearer or ?token=; no admin/micro created.
Co-authored-by: Claude <noreply@anthropic.com>
Rename `micro server` to `micro gateway` and fold the standalone
micro-mcp-gateway binary into it, so there is one gateway with one name.
- Rename command server -> gateway (package cmd/micro/server ->
cmd/micro/gateway; update the run and main importers).
- `micro gateway` gains the MCP production controls the standalone binary
had: --rate-limit/--rate-burst, --auth, --audit, --scope,
--circuit-breaker[-timeout], and --x402-*. When --mcp-address is set it
runs the full gateway/mcp with those options; registry selection uses
the CLI global --registry/--registry_address flags.
- `micro server` stays as a hidden, deprecated alias that warns and
delegates, so existing invocations keep working.
- Delete cmd/micro-mcp-gateway (binary + Dockerfile). goreleaser only
builds ./cmd/micro, so releases are unaffected.
- Repoint deploy/refs at the micro CLI image: Dockerfile CMD -> gateway;
Helm chart runs `micro gateway --mcp-address` with registry via
MICRO_REGISTRY env, image ghcr.io/micro/go-micro; drop the v6
micro-mcp-gateway vanity entry and rename server -> gateway; update the
docs guides and CLAUDE.md.
Build, vet, gofmt, and the run/gateway/cmd tests pass; `micro gateway`
and the hidden `micro server` alias both resolve.
Co-authored-by: Claude <noreply@anthropic.com>
micro run is the local development inner loop, not a production runtime.
Make that explicit and fix real dev-UX bugs:
- Clean shutdown: the new-service scanner shared the signal channel with
the main wait; a signal goes to one receiver, so it could steal Ctrl-C
and hang teardown. Give background goroutines a dedicated shutdown
channel and guard the services slice with a mutex (also fixes a data
race on that slice during shutdown).
- Hot reload no longer takes a service offline on a compile error: build
into a temp binary first and only swap+restart if the build succeeds;
on failure the previous version keeps serving and the error is printed.
- Raise the log scanner buffer so long lines (JSON logs, stack traces)
no longer overflow it and silently drop a services logs.
- Help text and the micro run guide now state plainly it is a dev tool
with no daemon, and point to systemd/Docker/Kubernetes for production.
Remove the guides fictional micro logs/status/stop commands (no such
commands exist) and describe the real lifecycle (Ctrl-C, log files).
Co-authored-by: Claude <noreply@anthropic.com>
The loop's dispatch is agent-agnostic already — `--agent` just sets the
@mention it posts, so any coding agent that responds to an issue @mention and
opens a PR works. Make that explicit instead of implying Codex-only:
- micro-loop guide: add a "Choosing an agent" section — Codex (default), Claude
Code (via anthropics/claude-code-action responding to @claude), any other
mention-driven agent, and an honest note that assignment-triggered agents
(e.g. Copilot's coding agent) aren't supported by the mention dispatch yet.
- Clarify the `--agent` help text and the CLI README bullet.
No behavior change — the mention model already covers Codex and Claude; this
documents it and scopes the one real gap (an "assign" adapter) honestly.
Claude-Session: https://claude.ai/code/session_01CmdEY7pYmV5zzwCjNJ4ykL
Co-authored-by: Claude <noreply@anthropic.com>
The release action always bumped the PATCH, so genuine features (new providers,
`micro loop`, the security role, agent memory, …) all shipped as patches while
the minor stayed frozen at .3 (now on v6.3.18). By semver, backward-compatible
features are MINOR bumps.
Now the bump reflects what shipped, read from the CHANGELOG [Unreleased] section
(kept current by the coherence role):
- `### Added` / `### Changed` -> MINOR (vX.(M+1).0)
- fixes/docs only -> PATCH (vX.M.(P+1))
- breaking (`### Removed` / a "(breaking)" heading / BREAKING) -> skip the
automated release; a MAJOR stays a human decision.
Applied to both go-micro's loop-release.yml and the generic `micro loop`
template (guards a missing CHANGELOG.md -> patch). Verified against the current
CHANGELOG: next release resolves to v6.4.0 (features present), not v6.3.19.
Claude-Session: https://claude.ai/code/session_01CmdEY7pYmV5zzwCjNJ4ykL
Co-authored-by: Claude <noreply@anthropic.com>
Adds an opt-in `security` role to `micro loop` and wires it into go-micro's own
loop. On a schedule it dispatches the agent to audit the codebase for real,
exploitable vulnerabilities and file them.
Security gets a deliberately more conservative policy than the other roles,
encoded in .github/loop/prompts/security.md:
- NEVER auto-merges a security change (fixes stay human-reviewed).
- NEVER publishes exploit detail / PoC in a public issue — novel exploitable
findings get a concise `security` + `needs-human` issue (class, location,
impact) routed to private disclosure; only known/public dep CVEs get a
bump PR (no auto-merge).
- Weekly by default (`--security-cron`, 0 6 * * 1); tunable.
The go-micro prompt targets its real attack surface: MCP/A2A gateways, x402
payments, JWT/wrapper auth, provider BaseURL SSRF + key leakage, the agent
tool loop (prompt injection / guardrail bypass), TLS defaults, the loop's own
PAT, and dependency CVEs via govulncheck.
Note: an agent review is not a gate. The deterministic companion — govulncheck
as a required CI check — is a recommended follow-up so known-vulnerable deps
can't merge at all.
Claude-Session: https://claude.ai/code/session_01CmdEY7pYmV5zzwCjNJ4ykL
Co-authored-by: Claude <noreply@anthropic.com>
Backstop for the gate: previously loop-triage only fired on Harness (E2E)
failures, so a red lint or test on master (e.g. the misspell that slipped past
because golangci-lint isn't a required check) produced no fix issue. Now triage
watches all the gate workflows.
- micro loop: `--ci-workflow` accepts a comma-separated list of workflow names,
rendered into the triage workflow_run trigger as a YAML array; the issue names
the actual failed workflow via github.event.workflow_run.name. (generic CLI)
- go-micro: regenerate loop-triage.yml to watch "Harness (E2E)", "Lint",
"Run Tests"; generalize the triage prompt beyond the harness (a lint/test
failure on master is a real regression to fix, not a flake to ignore).
- Docs: update CONTINUOUS_IMPROVEMENT.md triage description.
Note: this is defense-in-depth. The primary fix is making golangci-lint a
required status check so red lint can't merge in the first place — that stays
with the human (branch protection).
Claude-Session: https://claude.ai/code/session_01CmdEY7pYmV5zzwCjNJ4ykL
Co-authored-by: Claude <noreply@anthropic.com>
* feat(loop): go-micro now runs on `micro loop` (dogfood its own tool)
Replace go-micro's five hand-written loop workflows with ones generated by
`micro loop init --roles all`, making "go-micro builds itself with micro loop"
literally true rather than aspirational.
- Generate loop-planner/builder/triage/coherence/release.yml via the CLI with
go-micro's cadence and wiring (planner :59, builder :29, coherence 07:00,
release 23:00; CI gate "Harness (E2E)"; token CODEX_TRIGGER_TOKEN; base master;
tag prefix v). The old loop-architect.yml and loop-devrel.yml become
loop-planner.yml and loop-coherence.yml.
- Move the queue to .github/loop/PRIORITIES.md and add .github/loop/NORTH_STAR.md
(a concise steer pointing to internal/docs/THESIS.md), adopting the loop's
convention.
- Preserve go-micro's rich instructions as editable policy in
.github/loop/prompts/{planner,builder,triage,coherence}.md — the architect
founder-lens + adoption steer, the increment builder, harness-failure triage,
and the DevRel changelog/blog pass — faithfully ported from the old inline
prompts. Behavior is preserved; only the mechanism is now generated.
- CLI refinement the migration surfaced: prompts (and NORTH_STAR/PRIORITIES) are
now write-once — `micro loop init --force` refreshes workflow MECHANICS but
never clobbers customized POLICY. Added renderKeep + a test.
- Update internal/docs/CONTINUOUS_IMPROVEMENT.md (renamed workflows, moved queue,
the prompt-file model, and a note that these files are generated by micro loop).
Verified: build, go test ./cmd/micro/loop/..., golangci-lint (0 issues), gofmt;
`micro loop verify` passes; all generated workflows are valid YAML; re-running
init --force is idempotent and preserves policy.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CmdEY7pYmV5zzwCjNJ4ykL
* loop: strip prompt editorial comments before posting to the agent
Verification of the migration surfaced that a dispatch workflow posted the
prompt file's leading <!-- editorial --> header to the agent, and __ISSUE__
inside it got substituted too (e.g. "Keep 4242 literal"). Harmless (invisible
in rendered markdown) but unclean and mildly confusing. The dispatch and triage
body construction now strips <!-- --> blocks with `sed '/<!--/,/-->/d'` before
substituting runtime tokens. Regenerated go-micro's workflows; added a test.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CmdEY7pYmV5zzwCjNJ4ykL
---------
Co-authored-by: Claude <noreply@anthropic.com>
Rework `micro loop` so the workflows are the mechanism and each dispatch role's
instruction is an editable .github/loop/prompts/<role>.md file (the policy).
That split lets any repo — including go-micro itself — customize behavior by
editing prompt files instead of forking the CLI, which is the prerequisite for
go-micro consuming its own tool without losing its richer prompts.
- Add two opt-in roles: `coherence` (README/docs/CHANGELOG alignment) and
`release` (cut the next patch tag on new commits; bakes in the
persist-credentials:false fix so the PAT push isn't clobbered by the
checkout token — the 403 we hit on the live release action).
- `--roles` selects which roles to scaffold (default planner,builder,triage;
`all` for everything); `--tag-prefix`, `--release-cron`, `--coherence-cron`
added. Templates keep the << >> delimiters so GHA ${{ }} passes through;
prompts leave __ISSUE__/__RUNURL__ as runtime tokens the workflow substitutes.
- `micro loop verify` now checks each present role workflow has its prompt.
- README updated with the five roles and a copy-pasteable flag example
(folds in the readability fix from the now-closed #3651).
Verified: build, `go test ./cmd/micro/loop/...`, vet, golangci-lint (0 issues),
gofmt; and an end-to-end `micro loop init --roles all` whose generated
workflows all parse as valid YAML and pass `micro loop verify`.
Claude-Session: https://claude.ai/code/session_01CmdEY7pYmV5zzwCjNJ4ykL
Co-authored-by: Claude <noreply@anthropic.com>
`micro loop init` writes an autonomous improvement loop into any repository —
the same planner/builder/triage loop that maintains go-micro, generalized:
- planner (loop-planner.yml): keeps a ranked queue in .github/loop/PRIORITIES.md
- builder (loop-builder.yml): builds the top open item as a single-concern PR,
auto-merged on green CI
- triage (loop-triage.yml): turns CI failures into scoped fix issues
plus .github/loop/NORTH_STAR.md (direction) and PRIORITIES.md (queue).
The agent adapter is mention-based, not hardcoded to Codex: `--agent @codex`
(or any @mention agent that responds on an issue and can run gh), `--token-secret`,
`--branch`, `--ci-workflow`, and cron flags are the whole config-vs-core boundary.
Templates use << >> delimiters so GitHub Actions' own ${{ }} expressions pass
through untouched. `micro loop verify` checks the wiring and flags the two things
the CLI can't: the token secret and branch protection (the green-CI gate).
Built inside go-micro with the config/core split already drawn, so the workflows
can later be extracted to a standalone reusable-workflows repo without a rewrite.
Claude-Session: https://claude.ai/code/session_01CmdEY7pYmV5zzwCjNJ4ykL
Co-authored-by: Claude <noreply@anthropic.com>
The gateway already serves /mcp/tools on :8080 unconditionally (every
endpoint is an AI-callable tool), but the startup banner only printed an MCP
line when --mcp-address was set — so the live `micro run` experience hid the
harness's signature feature even though it was running, and didn't match the
README. Always advertise MCP Tools on the gateway address; keep the optional
standalone MCP-protocol server (--mcp-address) as a clearly separate line.
No behavior change — banner output only.
Co-authored-by: Claude <noreply@anthropic.com>