cold-audit catch from 2026-05-24 (round 3) Round-3 P3 docs batch. Two unrelated docs items grouped per IDR cleanup convention (D19/D20/D25 precedent). **F7** — README Environment Variables table drift. Pre-D30 table documented `OLP_HOME` and `OLP_LOG_LEVEL` — neither is read by any code in the repo. The table missed `OLP_CLAUDE_BIN`, `OLP_CODEX_BIN`, `OLP_VIBE_BIN` which the 3 provider plugins DO read to override the path to each provider's CLI binary. `grep -rn "process\.env\.OLP_" server.mjs lib/` returns exactly 4 reads: - `OLP_PORT` (server.mjs:49) - `OLP_CLAUDE_BIN` (anthropic.mjs:69) - `OLP_CODEX_BIN` (codex.mjs:143) - `OLP_VIBE_BIN` (mistral.mjs:240) Fix: README env-vars table now lists exactly these 4 active vars with their actual defaults. `OLP_HOME` + `OLP_LOG_LEVEL` moved to a "📋 Planned (Phase 2)" callout block beneath the table, with honest explanations linking to the actual code state (`loadFallbackConfigSync` hardcodes the config path; `logEvent` writes unconditionally). **F20** — Author docs/openai-spec-pin.md v0.1 baseline. ALIGNMENT.md Authority 2 + Annual Alignment Audit § Scope both referenced `docs/openai-spec-pin.md` as the artifact the annual audit diffs against. Pre-D30 the file didn't exist (D20 marked it 📋 Planned). This left the entry-surface audit without a diff baseline — v0.1 ships with no provable "the OpenAI spec was THIS on the day OLP implemented its entry surface" anchor. Fix: author a 175-line minimal v0.1 baseline. Every field claim is verified against source (openai-to-ir.mjs + ir-to-openai.mjs + server.mjs). Structure: - POST /v1/chat/completions: 14 supported request fields (model, messages + 6 message-level subfields, stream, temperature, max_tokens, top_p, stop, tools, tool_choice, response_format) + 11 NOT-yet-supported fields (n, seed, frequency_penalty, presence_penalty, logit_bias, logprobs, top_logprobs, user, service_tier, parallel_tool_calls, stream_options) - Response shapes: chat.completion (non-stream), chat.completion.chunk (streaming) — verified against irResponseToOpenAINonStream and irChunkToOpenAISSE - `finish_reason` enum: verified against OPENAI_FINISH_REASON_ENUM constant in ir-to-openai.mjs (post-D19 + D26) - Error response shape: HTTP 4xx/5xx + `{error: {message, type}}` — verified against `sendError` in server.mjs - GET /v1/models: verified against handleModels (post-D18 + D27 F15) - Streaming SSE semantics: framing, terminator, post-D26 F19 truncation marker The pin also documents the v0.1 → v1.0 forward-looking expansion plan: the "NOT yet supported" fields are explicit candidates for v1.0+ implementation via openai-to-ir.mjs amendments + ADR 0003 updates. ALIGNMENT.md + README Implementation status table both flip the marker from 📋 Planned to ✅ Shipped (D30) with the 2026-05-24 timestamp. Changes (3 files, +180 / -8): - ALIGNMENT.md +2/-2 (2 markers updated: Authority 2 + Annual Audit) - README.md +11/-6 (env-vars table delta + status table marker flip + Planned callout for OLP_HOME/OLP_LOG_LEVEL) - docs/openai-spec-pin.md (new, 175 lines) Tests: 400/400 unchanged — pure docs change. Authority: - F7 → process.env reads verified by direct grep - F20 → OpenAI Chat Completions spec https://platform.openai.com/docs/api-reference/chat/create https://platform.openai.com/docs/api-reference/chat/streaming https://platform.openai.com/docs/api-reference/chat/object https://platform.openai.com/docs/api-reference/models/list - F20 internal source-of-truth: openai-to-ir.mjs + ir-to-openai.mjs + server.mjs (all field claims traced) - ALIGNMENT.md § Authority 2 + § Annual Alignment Audit - CC 开发铁律 v1.6 § 10.x — Round-3 Cold Audit caught both items Reviewer (Iron Rule v1.6 § 10.x Mode A, fresh-context opus, independent of drafter): APPROVE. Independent verification: - Grep confirmed exactly 4 process.env.OLP_* reads — matches new env vars table - Each new var's default value verified against the plugin code (anthropic.mjs:69 → 'claude'; codex.mjs:143 → 'codex'; mistral.mjs:240 → 'vibe') - All 14 spec-pin supported request fields traced to openAIToIR line references (model L129, messages L45-89, stream L141, temperature L160, max_tokens L152, top_p L168, stop L176, tools L183, tool_choice L187, response_format L191) - All 11 NOT-supported fields confirmed absent via grep - Response shape claims (chat.completion + chat.completion.chunk + /v1/models) all match source code line-by-line - ALIGNMENT.md markers — pure markup flip, no rule changes - 400/400 tests pass 3 non-blocking suggestions noted (function_call finish_reason caveat; README slug rendering; ADR 0003 cross-link in spec-pin) — all cosmetic, not folded. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
6.7 KiB
OpenAI Spec Pin (v0.1 baseline)
- Date pinned: 2026-05-24 (D30)
- Status: v0.1 baseline — annual audit per ALIGNMENT.md § Annual Alignment Audit
- Authority: OpenAI Chat Completions API + Models API
This document is the spec-diff baseline against which OLP's annual audit will compare
future OpenAI spec changes. It enumerates the specific spec sections OLP currently
implements as the entry surface, verified against lib/ir/openai-to-ir.mjs and
lib/ir/ir-to-openai.mjs at the time of pinning.
Endpoints implemented
POST /v1/chat/completions
- Spec section: https://platform.openai.com/docs/api-reference/chat/create
- Retrieval timestamp: 2026-05-24
Request body fields supported (translated into IR by openAIToIR in
lib/ir/openai-to-ir.mjs):
| Field | Type | Required | Notes |
|---|---|---|---|
model |
string | required | Passed through to IR; validated non-empty |
messages |
array | required | Non-empty; each element translated via translateMessage |
messages[i].role |
string | required | system / user / assistant / tool; deprecated function normalized to tool |
messages[i].content |
string|null | required | null normalized to '' |
messages[i].name |
string | optional | Passed through to IR |
messages[i].tool_call_id |
string | optional | Passed through to IR |
messages[i].tool_calls |
array | optional | {id, type:'function', function:{name, arguments}} |
messages[i].function_call |
object | optional | Deprecated field; mapped to a single tool_calls entry |
stream |
boolean | optional | Default false; true triggers SSE path |
temperature |
number | optional | Range [0, 2]; passed to IR |
max_tokens |
integer | optional | Must be a positive integer; passed to IR |
top_p |
number | optional | Range [0, 1]; passed to IR |
stop |
string | array | optional | Passed to IR as-is |
tools |
array | optional | Only type:'function' tools supported; translated via translateTools |
tools[i].function.name |
string | required (in tool) | Passed through |
tools[i].function.description |
string | optional | Passed through if present |
tools[i].function.parameters |
object | optional | Passed through if present |
tool_choice |
'auto'|'none'|'required'|{type:'function',function:{name}} |
optional | Passed to IR verbatim |
response_format |
object | optional | Passed to IR verbatim |
Request body fields NOT yet supported (silently dropped by entry surface — not
read in openAIToIR):
n— multiple completions; OLP is single-completion onlyseed— deterministic samplingfrequency_penalty,presence_penaltylogit_biaslogprobs,top_logprobsuserservice_tierparallel_tool_callsstream_options
Response shape (non-streaming) — object: 'chat.completion'
(assembled by irResponseToOpenAINonStream in lib/ir/ir-to-openai.mjs):
{
"id": "chatcmpl-<base64url>",
"object": "chat.completion",
"created": <unix-epoch-seconds>,
"model": "<model-string-from-request>",
"choices": [{
"index": 0,
"message": {
"role": "assistant",
"content": "<string-or-null>",
"tool_calls": [ ... ]
},
"finish_reason": "<stop|length|tool_calls|content_filter|function_call|null>"
}],
"usage": { ... }
}
usageis included only when the provider surfaces token counts on the final chunk.message.tool_callsis included only when tool calls are present.message.contentisnullwhen there is no text content and tool calls are present.
Response shape (streaming) — object: 'chat.completion.chunk'
(emitted by irChunkToOpenAISSE in lib/ir/ir-to-openai.mjs):
data: {"id":"chatcmpl-...","object":"chat.completion.chunk","created":<ts>,"model":"<m>","choices":[{"index":0,"delta":{"role":"assistant","content":"..."},"finish_reason":null}]}
data: {"id":"chatcmpl-...","object":"chat.completion.chunk","created":<ts>,"model":"<m>","choices":[{"index":0,"delta":{},"finish_reason":"stop"}]}
data: [DONE]
deltacarriesrole(first chunk only),content(text chunks), ortool_calls(tool call chunks).- Final stop chunk has
finish_reasonset and emptydelta. usageis included in the stop chunk only when the provider surfaces token counts.- Stream terminator:
data: [DONE]\n\n.
finish_reason enum honored (normalized by normalizeFinishReason; non-spec values
normalized to 'stop'):
stop— natural completionlength— truncated atmax_tokensor synthesized on truncation (D19/D16)tool_calls— model stopped to emit a tool callcontent_filter— provider-side content filterfunction_call— deprecated; preserved for backwards compatibilitynull— in-progress (streaming delta chunks)
Error response shape:
HTTP 4xx/5xx with body:
{ "error": { "message": "<string>", "type": "<string>" } }
No invented top-level error field on chat.completion objects (per ALIGNMENT.md
Rule 2 — D12 finding). Errors surface exclusively via HTTP status codes with the above
body shape.
GET /v1/models
- Spec section: https://platform.openai.com/docs/api-reference/models/list
- Retrieval timestamp: 2026-05-24
Response shape (handleModels in server.mjs):
{ "object": "list", "data": [ ... ] }
Each entry: { "id": "<model-id>", "object": "model", "created": <ts>, "owned_by": "<provider-key>" } —
no invented fields (per D27 F15). Alias entries are also surfaced as separate list members
(per D27 F15 alias surfacing).
GET /health
OLP-specific endpoint (not in OpenAI spec). Returns:
{ "ok": true, "version": "<semver>", "providers": { "enabled": <n>, "available": <n> } }
Streaming SSE semantics
- MIME:
text/event-stream - Per-chunk framing:
data: <json>\n\n - Terminator:
data: [DONE]\n\n - Truncation marker:
finish_reason: 'length'synthesized when the provider generator exhausts without a natural stop chunk (D26 F19 — mirrors D16 buffered-path semantics) - Response headers on stream:
Content-Type: text/event-stream,Cache-Control: no-cache,Connection: keep-alive,X-Accel-Buffering: noplus OLP diagnostic headers
Audit method
Annual audit (target 2027-05-14): re-fetch each cited URL above, diff against the field
lists above, file an ADR amendment for any newly-shipped OpenAI field or changed semantic
that OLP should implement. Consult lib/ir/openai-to-ir.mjs and lib/ir/ir-to-openai.mjs
as the implementation source of truth.
Scope note: v0.1 baseline
This is a minimal baseline. v1.0+ should expand coverage to include the "NOT yet
supported" fields above where OLP intends to support them (via openAIToIR amendments +
ADR 0003 updates).