Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions DECISIONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,8 @@ Select which sleeve(s) activate first and final initial capital split/account ma
| KD-002 | Claude API key not provisioned — NOT required under default posture: ADR-029/030 gateway-or-rules with `DirectApiFallbackEnabled=false` means zero metered spend (gateway bearer key provisioned via S5-004). Becomes relevant only if the owner explicitly enables the metered fallback | Conditional — regime integration shipped, degrades to deterministic rules | 2026-02-16 |
| KD-003 | Backtest pipeline paths use Python (not .NET) | Must install Python + deps separately for backtesting | 2026-04-07 |
| KD-004 | ✅ RESOLVED 2026-05-29 (S3-001, PR #70). ~~CachingMarketDataService.cs ~360 lines, exceeds 300-line architecture-fitness threshold (grew across S2-001/003/005/006)~~ — decomposed into a 125-line facade + new 280-line MarketRegimeProvider (internal composition, no DI change, zero behavior change) per ADR-017 | Maintainability — closed | 2026-05-29 |
| KD-005 | **ApplicationInsights 2.x→3.x upgrade gate (S5-004r).** `Microsoft.ApplicationInsights.WorkerService` is pinned to the classic 2.x line (2.23.0): AI 3.x is OTel-based and removed classic API types (`ITelemetryInitializer`) that `Microsoft.Azure.Functions.Worker.ApplicationInsights` 2.50.0 is compiled against — pairing them crashes the isolated worker at DI bootstrap with `TypeLoadException`. Upgrade is BLOCKED until the Functions Worker AI package ships a 3.x-compatible release; when unblocking, re-evaluate the OpenTelemetry.Api pin removed in S5-004r (see comment in `TradingSystem.Functions.csproj`) and clear KD-006 in the same change | Stuck on classic 2.x telemetry SDK; no OTel-native pipeline. Boot-blocking if upgraded prematurely | 2026-06-10 |
| KD-006 | **discord.com URI-redaction gate before enabling App Insights (S5-004r).** AI 2.x *dependency* telemetry records the full request URL of outbound HTTP calls — for the Discord named clients that URL IS the token-bearing webhook URL. This path bypasses the `System.Net.Http.HttpClient` ILogger filter in `Program.cs` (that filter only covers log telemetry) and is dormant solely because `APPLICATIONINSIGHTS_CONNECTION_STRING` is unset everywhere. Do NOT set that variable until a telemetry processor/initializer that redacts or drops discord.com dependency URLs is in place (or AI 3.x with OTel redaction supersedes it — KD-005) | Secret-leak risk into App Insights if telemetry is ever enabled without redaction | 2026-06-10 |

---

Expand Down
8 changes: 7 additions & 1 deletion docs/paper-validation-runbook.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,13 @@ Run this check each trading morning **before 5:00 AM PT in winter (PST) / 6:00 A
classification (ADR-029/ADR-030) — **this is expected behavior, not an incident**.
Restart the gateway (`D:\Source\claude-gateway`) when convenient.
3. **Functions worker** started (`func start` per section 1).
4. **Startup-log smoke check:** the worker banner lists both timer functions —
4. **Host boot smoke:** after `func start`, the function-list banner must appear with **no
`TypeLoadException`** (or repeated "worker process" restarts) in the startup output.
The banner proves the isolated worker process actually loaded its DI graph — a
package-version mismatch (S5-004r) can pass the full unit suite yet crash the worker
at bootstrap, because tests never load the Functions host. Run this check first: the
function list in step 5 is meaningless until the worker has provably booted.
5. **Startup-log smoke check:** the worker banner lists both timer functions —
`DailyOrchestrator_PreMarket` and `DailyOrchestrator_EndOfDay`. If either is missing,
the build is broken or the wrong project started; do not assume the day will run.

Expand Down
23 changes: 20 additions & 3 deletions src/TradingSystem.Functions/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,12 @@
context.Configuration.GetSection("TradingSystem"));
services.Configure<TacticalConfig>(
context.Configuration.GetSection("TradingSystem:Tactical"));
// S5-004r: OptionsSleeveManager takes the bare TacticalConfig (its siblings take
// IOptions<TacticalConfig>), so the bare type must be resolvable or the worker dies
// at DI validation on boot. This was masked by the AI-package TypeLoadException —
// the unit suite never builds the full host graph, only the real `func start` does.
services.AddSingleton(sp =>
sp.GetRequiredService<Microsoft.Extensions.Options.IOptions<TacticalConfig>>().Value);
services.Configure<IBKRConfig>(
context.Configuration.GetSection("IBKR"));
services.Configure<LocalStorageConfig>(
Expand All @@ -53,7 +59,12 @@
services.Configure<ReportingConfig>(
context.Configuration.GetSection("Reporting"));

// Application Insights
// Application Insights — registration is inert until APPLICATIONINSIGHTS_CONNECTION_STRING
// is set (it is NOT set in local.settings.json or any deployed config today): with no
// connection string the SDK builds a disabled TelemetryConfiguration and sends nothing.
// Before ever setting that variable, the discord.com URI-redaction gate in DECISIONS.md
// (Known Debt KD-005/KD-006) must be satisfied — AI 2.x dependency telemetry records full
// request URLs, which for the Discord named clients are token-bearing webhook URLs.
services.AddApplicationInsightsTelemetryWorkerService();
services.ConfigureFunctionsApplicationInsights();

Expand Down Expand Up @@ -124,8 +135,14 @@
builder.SetMinimumLevel(LogLevel.Information);
// S5-004 (review): IHttpClientFactory's LogicalHandler logs the full request URI at
// Information on every send — for Discord named clients that URI IS the token-bearing
// webhook URL. Warning+ only for the HttpClient categories keeps the secret out of
// console/App Insights logs while preserving error visibility.
// webhook URL. Warning+ for every "System.Net.Http.HttpClient.*" ILogger category
// keeps the secret out of console logs and out of App Insights *log* telemetry while
// preserving error visibility. Scope note (S5-004r review): this filter governs only
// ILogger output — it does NOT cover App Insights *dependency* telemetry, which the
// AI 2.x SDK emits with the full request URL outside the logging pipeline. That path
// is dormant solely because APPLICATIONINSIGHTS_CONNECTION_STRING is unset (see the
// enablement-gate comment at the App Insights registration above and DECISIONS.md
// Known Debt).
builder.AddFilter("System.Net.Http.HttpClient", LogLevel.Warning);
});
})
Expand Down
20 changes: 12 additions & 8 deletions src/TradingSystem.Functions/TradingSystem.Functions.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,21 @@
<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Http" Version="3.3.0" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Timer" Version="4.3.1" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Sdk" Version="1.16.2" />
<PackageReference Include="Microsoft.ApplicationInsights.WorkerService" Version="3.0.0" />
<!-- S5-004r: MUST stay on the classic 2.x line. AI 3.x is OTel-based and REMOVED classic
API types (e.g. ITelemetryInitializer) that Functions.Worker.ApplicationInsights is
built against — pairing 3.x with it makes the isolated worker crash at DI bootstrap
with TypeLoadException and the host recycles until the worker-restart cap. -->
<PackageReference Include="Microsoft.ApplicationInsights.WorkerService" Version="2.23.0" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.ApplicationInsights" Version="2.50.0" />
<PackageReference Include="Azure.Identity" Version="1.18.0" />
<PackageReference Include="Azure.Extensions.AspNetCore.Configuration.Secrets" Version="1.5.0" />
<!-- Transitive lift: GHSA-g94r-2vxg-569j (OpenTelemetry.Api < 1.15.3, excessive memory
allocation parsing propagation headers). Pulled in at 1.15.0 via
Microsoft.ApplicationInsights.WorkerService 3.0.0 -> Azure.Monitor.OpenTelemetry.Exporter.
Pinned to the first patched version; remove once ApplicationInsights.WorkerService ships
a patched chain. Tests and SmokeTest inherit this pin via their project reference to
Functions — if either drops that reference, it needs its own pin. -->
<PackageReference Include="OpenTelemetry.Api" Version="1.15.3" />
<!-- S5-004r: the S5-005 OpenTelemetry.Api 1.15.3 pin that used to live here was REMOVED,
not lost. The vulnerable transitive chain it patched (GHSA-g94r-2vxg-569j, via
ApplicationInsights.WorkerService 3.0.0 -> Azure.Monitor.OpenTelemetry.Exporter) does
not exist on the classic 2.23.0 line above — a transitive vulnerability scan
(dotnet list package, vulnerable + include-transitive) is clean without it. If
WorkerService is ever upgraded back to 3.x (see DECISIONS.md Known Debt),
re-evaluate whether an OTel pin is needed. -->
</ItemGroup>

<ItemGroup>
Expand Down