fix: Phase 2-3 DB isolation + Gate 3 data layer real connection (AGENTS.md v16.0)

**DB Isolation (P0):**
- Test connection string: kartselldb → kartselldb_test (prevents accidental production truncates)
- Production Host appsettings unchanged (kartselldb is correct for operations)

**Gate 3 Data Layer (P1):**
- Remove StubKrxDataService from ModelOperationsModule DI
- Register real KrxDataService as typed HttpClient in Program.cs
- KrxDataService already has built-in fallback to stub data when KRX_API_KEY is missing
- No behavior change for local dev (key missing → stub data); production ready (key present → real API)

**Tech Debt Registration (AGENTS.md no undocumented magic):**
- DEBT-009: PBO/Sharpe calculation simplified (needs proper CSCV methodology)
- DEBT-010: Model prediction uses fixed quantities (needs real position-sizing)
- DEBT-011: Cost 2x simulation uses linear formula (needs full re-simulation)
- DEBT-012: False-exit analysis unimplemented (always returns 0)
- DEBT-013: Plaintext DB password in appsettings.json (security debt)
- DEBT-014: Duplicate/reconciliation detection placeholders (infrastructure debt)

Gate 3 marked "rehearsal ready" (real KRX data, simplified analytics).
See TECH_DEBT_REGISTER.md for full impact/effort estimates.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-08-02 21:09:15 +09:00
parent 0bf3bc3c75
commit ca85a2c902
5 changed files with 28 additions and 9 deletions
@@ -71,24 +71,27 @@ public class MetricsSql
public async Task<(int Detected, int Resolved, DateTime LastCheck)?> GetDuplicateDetectionAsync(CancellationToken cancellationToken = default)
{
// Placeholder: outbox duplicate detection (table not yet in migrations)
// Returns null until outbox-duplicate-detection feature is implemented
// Placeholder: building_blocks.outbox_message table exists (0000_building_blocks.sql).
// Duplicate detection logging (via operation_audit_trail or dedicated table) not yet implemented.
// Returns null until OutboxPollerJob hooks duplicate tracking (see DEBT-014).
await Task.CompletedTask; // Async compliance
return null;
}
public async Task<(int Detected, int Resolved, List<string> Pending)?> GetReconciliationBreaksAsync(CancellationToken cancellationToken = default)
{
// Placeholder: Reconciliation break detection requires outbox/inbox log correlation
// Returns null until full audit trail correlation is implemented
// Placeholder: Reconciliation break detection requires outbox/inbox log correlation.
// Requires audit trail showing Evidence version mismatches. Not yet implemented.
// Returns null until operation_audit_trail is populated by job consumers (see DEBT-014).
await Task.CompletedTask; // Async compliance
return null;
}
public async Task<(decimal Baseline, decimal Current)?> GetModelDriftAsync(CancellationToken cancellationToken = default)
{
// Placeholder: Model drift calculation requires baseline comparison from shadow_run metrics
// Returns null until full OOS metrics are integrated from model_operations.shadow_run
// Placeholder: Model drift calculation requires baseline/current sharpe comparison from shadow_run results.
// Returns null until Gate 3 rehearsal populates model_operations.shadow_run with real metrics.
// Once shadow_run results exist, baseline/current sharpe can be calculated and compared (see DEBT-009).
await Task.CompletedTask; // Async compliance
return null;
}
+5
View File
@@ -117,6 +117,11 @@ builder.Services.AddSingleton<RateLimiterService>();
builder.Services.AddSingleton<CircuitBreakerPolicyFactory>();
builder.Services.AddHttpClient<ResilientHttpClient>();
// KRX Data Service (real API, with KRX_API_KEY; fallback to stub data if key missing)
builder.Services.AddHttpClient<KArtSell.Modules.ModelOperations.ShadowRun.Services.KrxDataService>();
builder.Services.AddScoped<KArtSell.Modules.ModelOperations.ShadowRun.IKrxDataService>(sp =>
sp.GetRequiredService<KArtSell.Modules.ModelOperations.ShadowRun.Services.KrxDataService>());
// Observability Metrics
builder.Services.AddScoped<MetricsPolicy>();
builder.Services.AddScoped<MetricsSql>();
@@ -17,7 +17,7 @@ public static class ModelOperationsModule
services.AddScoped<IModelOperationRequestRepository, DapperModelOperationRequestRepository>();
services.AddScoped<IModelOperationRequestService, ModelOperationRequestService>();
services.AddSingleton<IMarketCalendarService, MarketCalendarService>();
services.AddScoped<IKrxDataService, StubKrxDataService>();
// KrxDataService registered in Host.Program.cs as typed HttpClient
services.AddScoped<IObservabilityService, StubObservabilityService>();
return services;
}