* autoresearch iter 23: fail-closed auth guarding for user/message_gateway
Both plugins resolve contracts.AuthService in Apply to build their route
middleware, but declared only DBService in Inject(). The kernel gates a
plugin's Apply solely on declared deps, and cmd/app.go registers user
before auth, so user mounted first, core.Inject failed, and loginMW
silently degraded to a pass-through closure — leaving /api/v1/user
change-password, profile and access-tokens unguarded. message_gateway
was saved only by its later list position.
Declare AuthService in Inject() for both, and pin the property with a
reconcile-level test that mirrors production registration order and
asserts the real auth middleware reaches the route table.
* autoresearch iter 24: make auth middleware fallbacks fail closed
user, message_gateway and admin each fell back to a c.Next() closure when
contracts.AuthService could not be resolved, so a route would be served as
if authenticated. For admin this is reachable at runtime: OnDispose calls
service.ResetServices(), which nils the global the per-request guard reads,
so requests still in flight during dispose bypass authorization entirely.
Add ginutil.AuthUnavailable() and bind every fallback to it, with a test
that drives each plugin's registered guard without an auth service present
and asserts the request is aborted rather than passed through.
* chore(autoresearch): log iter 23 (fail-open auth ordering, proven)
* autoresearch iter 24 follow-up: let staticcheck infer the auth guard type
* docs(autoresearch): log iters 24-25 and lessons 9-11 (declared-dep bug class, gate discipline)
message_gateway scheduled message_gateway:cleanup_pairing_codes every 10
minutes but never registered a task under that pattern, so every dispatch
went to a task type with no handler and expired pairing rows accumulated
forever, even though repository.DeleteExpiredPairingCodes already existed.
Add a test that fails for any schedule whose task pattern is unregistered:
it reports the exact orphan rather than relying on a schedule-exists assert.
- Purify core micro-kernel by removing context hardcoded helpers and reverse dependencies
- Eliminate init() side effects in infra plugins with reversible lifecycle disposal
- Completely isolate plugins by removing cross-plugin imports and using core/contracts
- Introduce TaskService and RiskControlService contracts for unified cross-plugin APIs
- Regenerate Swagger documentation and update developer guide matrix
- Achieve 0 violations in check_cordis_architecture.sh and 100% test pass
- Relocated go.mod and go.sum into backend/ root directory
- Stripped redundant backend/ segments from all Go imports (github.com/Rain-kl/Wavelet/...)
- Unified Makefile, swagger, and build-test to execute in backend/ module context
- Ensured 100% build-test, code-check, format, and swagger pass