cold-audit catch from 2026-05-24
Final round-2 cold-audit cleanup batch. 8 small P3 items, batched per
Iron Rule 11 IDR cleanup-batch convention (precedent: D19 / D20). No
item exceeds ~35 lines; only F9 is a code change, the rest are docs +
registry updates.
Changes (7 files, +140 / -10):
1. ALIGNMENT.md (+8 / -2)
- **F7**: Authority pin rows for anthropic / codex / mistral updated
from "TBD on Phase-1 spawn" to the actual citations cited in each
plugin's header:
· anthropic — @anthropic-ai/claude-code v2.1.89 (OCP fork audit pin)
· openai — https://developers.openai.com/codex/cli/reference + features URL
· mistral — https://docs.mistral.ai/mistral-vibe/terminal/quickstart + config URL
Plugins remain Candidate (per Provider Inventory) — D25 just removes the
`TBD` marker; Enabled transition still requires Phase audit.
- **F6**: New 3rd entry in § One-shot Triggered Audits — "OpenAI Codex ToS
formal pin (trigger: Phase 2 E2E enable for Codex, OR 2026-12-31)".
Closes the cross-reference from ADR 0006 § Decision table.
2. README.md (+4 / -2)
- **F5**: Cache-key bullet (Architecture section) replaced the stale
7-tuple with a link to ADR 0005 § Cache key composition + the
post-D15 11-field tuple inlined.
- **D22 follow-up**: "328-test suite" → "Comprehensive test suite
covering IR, cache, fallback, and integration paths" (version-less
to prevent re-drift on every D-day).
3. docs/adr/0002-plugin-architecture.md (+4 / -2) — **F11**: Amendment 1
wording corrected. The original Authority line + maxSpawnTimeMs
description said "fallback engine's spawn-timeout enforcement loop"
— but the enforcement actually lives in each provider plugin's
`_spawnAndStream` (setTimeout + proc.kill + reject pattern). The
fallback engine merely treats SPAWN_TIMEOUT as a hard trigger per
ADR 0004 § Trigger taxonomy bullet 4. Both wording sites updated.
4. docs/adr/0005-cache-cross-provider.md (+1) — **F13**: Amendment 2
gains a "Note on null-coalescing collisions" paragraph documenting
that the `?? null` serialization treats undefined / null / [] as
equivalent cache keys for array-typed fields. Intentional — both
`tools: []` and `tools` omitted semantically mean "no tools." If a
future provider distinguishes empty-array vs absent, the serialization
needs revision.
5. models-registry.json (+35) — **F10**: 5 candidate entries added for
the providers ALIGNMENT.md names but registry omitted. All five with
`candidate: true`, `models: []`, tier per ALIGNMENT.md inventory:
· grok / kimi → Tier C
· minimax / glm / qwen → Tier B
Closes the release_kit overlay's "Supported Providers from
models-registry.json" claim. alignment.yml KNOWN_PROVIDERS validation
array already includes all 8 names, so registry → workflow validation
continues to pass.
6. server.mjs (+20 / -6) — **F9**: Streaming success path now distinguishes
stop-terminated vs exhausted-without-stop. Pre-D25 code unconditionally
cached after the for-await loop ended, treating any exhaustion as
"completed." Now: only cache if `lastChunk?.type === 'stop'`. If the
generator exhausts without emitting stop (truncation), log
`streaming_no_stop_chunk` warn event and do NOT persist. Mirrors
D16's buffered-path semantics ("response completed successfully (no
truncation, no error mid-stream)") with the simpler skip-write
pattern (streaming path doesn't use getOrCompute → no singleflight
eviction needed). D23's cacheableForFirstHop guard preserved as the
outer condition.
7. test-features.mjs (+78) — F9 test 15e in Suite 15:
- Mock provider whose spawn yields delta chunks then implicit-returns
without stop (provider-injection pattern same as 15d — the real
plugins synthesize a stop on clean proc exit so __setSpawnImpl can't
simulate this case)
- Asserts response succeeds AND second identical request triggers
fresh spawn (proves no caching happened) AND X-OLP-Cache: miss on
both responses
Tests: 348 → 349 (+1 from 15e). All pass on Node 20.
Authority:
- F5 → ADR 0005 § Cache key composition (post-D15 Amendment 2)
- F6 → ALIGNMENT.md self + ADR 0006 self-reference
- F7 → plugin headers (verified during D25 implementation)
- F9 → ADR 0005 § Cache write conditions item 1 + D16 truncation precedent
- F10 → ALIGNMENT.md § Provider Inventory tier classification
- F11 → ADR 0004 § Trigger taxonomy bullet 4 (the actual SPAWN_TIMEOUT
hard-trigger documentation)
- F13 → ADR 0005 Amendment 2 (extends with the null-coalescing note)
- D22 fu → no spec authority; version-less framing prevents future drift
- CC 开发铁律 v1.6 § 10.x — Round-2 Cold Audit caught all 8 items
Reviewer (Iron Rule v1.6 § 10.x Mode A, fresh-context opus, independent
of drafter): APPROVE. Independently verified F7 citations against
plugin headers (anthropic.mjs:5-6, codex.mjs:23/31, mistral.mjs:26/32);
F10 tier classifications against ALIGNMENT.md § Provider Inventory;
F6 cross-reference now self-consistent (ADR 0006 → ALIGNMENT.md);
alignment.yml workflow validation passes; F9 truncation semantics
mirror D16 buffered-path; test 15e correctly uses provider-injection
since real plugin synthesizes stop on clean exit.
Three non-blocking suggestions noted (README cache-key bullet slightly
verbose with both link + inline list; F9 could optionally synthesize
a finish_reason: 'length' stop chunk for client-visible truncation
observability; test 15e single-delta variant could be extended to
multi-delta). None folded in — all genuine polish, not correctness
gaps.
---
**Round-2 cold-audit cleanup complete.** 5 D-days (D21-D25 minus the
already-completed D24) closed all 13 round-2 findings (P2: F1/F2/F3/F4
in D21/D22/D23/D24; P3: F5-F13 distributed across D25 + earlier issues
#2/#3). v0.1 is one cold-audit-round-3 away from being ready to tag.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Architecture Decision Records — OLP
This directory holds the OLP Architecture Decision Records (ADRs) — short documents that capture the why behind structural choices.
Read these before proposing governance, plug-in contract, IR, fallback, cache, or provider-inclusion changes.
Numbering
ADRs in OLP start at 0001 (the project's founding decision). OLP did not inherit the 0001 placeholder convention OCP used; the project starts on a fresh numbering line.
New ADRs increment from the highest existing number. Filenames are NNNN-<short-slug>.md.
Index
| ADR | Title | What it covers |
|---|---|---|
| 0001 | Project Founding | Why OLP exists (the 2026-06-15 Anthropic billing-split trigger), mission + non-mission boundaries, explicit supersession of OCP ADR 0005 "No Multi-Provider". |
| 0002 | Plugin Architecture for Providers | The lib/providers/<name>.mjs plug-in model, the Provider contract (name / models / auth / spawn / estimateCost / quotaStatus / healthCheck / hints), static in-tree registry, why-not full external plugin discovery. |
| 0003 | Intermediate Representation (IR) Design | The OLP-internal canonical request/response shape between the OpenAI-compat entry surface and each provider plugin. v1.0 IR fields, IR-vs-OpenAI-vs-native-provider three-shape model, IR is not exposed externally. |
| 0004 | Fallback Engine Semantics & Safety | Trigger taxonomy (Hard / Soft / Deterministic-deferred / Cost-aware-deferred), idempotent-failure safety (first-chunk rule), chain advancement one-at-a-time, observability headers. |
| 0005 | Cache Layer Cross-Provider Design | Cache key composition over (provider, model, messages, …), per-model isolation, D1+D2+D3+D4 port from OCP v3.13.0, cross-provider fallback cache behaviour (correct miss). |
| 0006 | Provider Inclusion / Exclusion + Risk-Tier Framework | The 4-tier classification (A excluded by default / B explicit consent / C opt-in / D eligible-for-default-enabled), Candidate-vs-Enabled distinction, current v0.1 candidate inventory (0 Enabled), Antigravity exclusion rationale (named prohibition + no cost advantage + reinstatement friction; pending primary-source pin), consent UX, future provider addition procedure. |
When to write a new ADR
Open one whenever:
- A structural rule is being added or changed (e.g., new IR field, new trigger type, new cache-key composition).
- A new provider plugin is being proposed (per ADR 0002 + ADR 0006 — ADR is a hard prerequisite for plugin merge).
- A decision encodes a lesson from an external event (provider policy change, drift incident).
- A future contributor reading the code alone could plausibly undo or re-litigate the choice.
Skip ADRs for routine implementation choices (algorithm pick, naming) — those belong in commit messages.
Format
Keep ADRs short — Context / Decision / Consequences / Alternatives is the standard skeleton. Cite incidents, PRs, or commits where useful. Length per ADR ~150–250 lines; longer than that, split.