Skip to content

feat: reimplementement dropped features (reload, health, tenant guard)#193

Closed
intel352 wants to merge 13 commits intoCrisisTextLine:mainfrom
GoCodeAlone:feat/reimplementation
Closed

feat: reimplementement dropped features (reload, health, tenant guard)#193
intel352 wants to merge 13 commits intoCrisisTextLine:mainfrom
GoCodeAlone:feat/reimplementation

Conversation

@intel352
Copy link

@intel352 intel352 commented Mar 9, 2026

Summary

Reimplements 3 of the 4 features dropped during the CrisisTextLine/modular upstream reset:

Dynamic Reload Manager

  • Reloadable interface for modules that support live config reloading
  • ReloadOrchestrator with buffered request queue, atomic CAS single-flight, circuit breaker (exponential backoff), and rollback on partial failure
  • ConfigDiff with change tracking, prefix filtering, sensitive field redaction
  • 4 reload lifecycle events via CloudEvents observer pattern
  • 10 tests including concurrency and rollback verification

Aggregate Health Service

  • HealthProvider interface with HealthStatus enum (Unknown/Healthy/Degraded/Unhealthy)
  • AggregateHealthService with concurrent fan-out, panic recovery, TTL cache (250ms), force-refresh context key
  • Separate readiness (non-optional only) vs health (all providers) aggregation
  • Temporary error detection (→ Degraded vs Unhealthy)
  • 3 provider adapters: Simple, Static, Composite
  • 17 tests including panic recovery and cache behavior

TenantGuard Enforcement

  • TenantGuard interface with ValidateAccess() for 3 modes: Strict (block), Lenient (log), Disabled (no-op)
  • Ring buffer for bounded violation history (default 1000 entries, FIFO eviction)
  • Whitelist support for explicit cross-tenant access
  • ViolationType and Severity enums
  • Builder integration: WithTenantGuardMode(), WithTenantGuardConfig()
  • 13 tests including concurrent access (100 goroutines)

Revised Plans

  • Gap analysis for all 4 features against existing codebase
  • BDD/Contract Testing plan updated — 65% already exists, remaining items depend on reload + health

Test plan

  • go build ./... passes
  • go vet ./... passes
  • All 40 new tests pass with -race flag
  • No modifications to existing interfaces (additive only)

🤖 Generated with Claude Code

Copilot AI and others added 13 commits March 6, 2026 21:31
…ests

Co-authored-by: intel352 <77607+intel352@users.noreply.github.com>
Co-authored-by: intel352 <77607+intel352@users.noreply.github.com>
…ategies

Co-authored-by: intel352 <77607+intel352@users.noreply.github.com>
… fix MakeJSONResponse status format

Co-authored-by: intel352 <77607+intel352@users.noreply.github.com>
Reset GoCodeAlone/modular to CrisisTextLine/modular main (v1.11.11+16 commits).
Changed all module paths from CrisisTextLine to GoCodeAlone.
Merged CrisisTextLine#192 (composite route strategies).
Added reimplementation plans for previously GoCodeAlone-specific features:
- TenantGuard framework
- Dynamic Reload Manager
- Aggregate Health Service
- BDD/Contract Testing framework

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Update all sub-modules to reference GoCodeAlone/modular v1.12.0.
Add replace directive for eventbus mocks resolution.
Fix letsencrypt httpserver dependency version.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The eventbus/v2 go.mod had a require + replace for the v1 eventbus
module path (for mocks). The replace directive doesn't propagate to
consumers, causing 'unknown revision' errors when downstream modules
run go mod tidy.

Fix: change test imports from .../eventbus/mocks to .../eventbus/v2/mocks
(the correct v2 import path) and remove the v1 require/replace.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Analyzed existing codebase against all 4 plans:
- TenantGuard: ~50% exists (context, service, config, decorators)
- Dynamic Reload: ~25% exists (observer, field tracking, config providers)
- Aggregate Health: ~15% exists (reverseproxy health checker)
- BDD/Contract Testing: ~65% exists (121 tests, contract CLI, CI)

Revised checklists to only cover remaining work.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… emission

Implements HealthProvider interface, HealthReport/AggregatedHealth types,
provider adapters (simple, static, composite), and AggregateHealthService
with fan-out evaluation, panic recovery, cache TTL, temporary error
detection, and CloudEvent emission on status changes. 17 tests including
concurrency and race-detector verified.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Introduces TenantGuard interface and StandardTenantGuard implementation
with strict/lenient/disabled modes, whitelist support, ring buffer
violation tracking, and CloudEvents emission on violations.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…and rollback

Add Reloadable interface to module.go for modules that support runtime
config reloading. Implement ReloadOrchestrator with single-flight
execution, exponential backoff circuit breaker, reverse-order rollback
on partial failure, and CloudEvents emission for reload lifecycle.

New files:
- reload.go: ChangeType, ConfigChange, FieldChange, ConfigDiff, ReloadTrigger types
- reload_orchestrator.go: ReloadOrchestrator with queue, circuit breaker, rollback
- reload_test.go: comprehensive tests (ConfigDiff, orchestrator, rollback, circuit breaker, concurrency)

Also fix pre-existing WithLogger name collision in health_service.go -> WithHealthLogger.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings March 9, 2026 22:29
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot wasn't able to review this pull request because it exceeds the maximum number of files (300). Try reducing the number of changed files and requesting a review from Copilot again.

@intel352 intel352 closed this Mar 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants