mirror of
https://github.com/dtzp555-max/ocp.git
synced 2026-07-21 21:15:09 +00:00
The cache key hashed model + keyId + sampling params + raw messages, but the ANSWER also depends on boot-time server config that shapes the composed prompt and tool surface: CLAUDE_SYSTEM_PROMPT (newly load-bearing since #175), OCP_SYSTEM_PROMPT_WRAPPER, CLAUDE_ALLOWED_TOOLS, and CLAUDE_NO_CONTEXT. The cache store is SQLite-backed and survives restarts, so an operator who changed any of these and restarted kept serving answers composed under the OLD config until TTL expiry (found by the #175 independent reviewer). Fix: server.mjs computes CONFIG_EPOCH once at boot — a 16-hex sha256 digest of the four values — and passes it to cacheHash, which folds `ce:<epoch>|` into the key. Any config change = instant whole-cache invalidation (the honest behavior). Callers that omit configEpoch (tests, any older path) hash byte-identically to before — asserted by test. Runtime-mutable settings (maxPromptChars via the settings API) are deliberately excluded: a const epoch cannot track them, and truncation drops context rather than changing the instruction set (noted in the code comment). One-time side effect on upgrade: existing cache entries no longer match (keys now carry the epoch). Cache is off by default and TTL-bounded; a one-time miss storm is the cost of never serving stale-config answers again. ALIGNMENT.md Rule 2: no cli.js citation applies — cache-key composition is OCP-internal (Class B); no endpoint, header, or wire field changes. Tests: +2, mutation-proven (dropping the fold fails both). Suite 343/0. Closes #176 Co-authored-by: dtzp555 <dtzp555@gmail.com> Co-authored-by: Claude <claude-opus-4-8> <noreply@anthropic.com>
This commit is contained in:
@@ -355,6 +355,11 @@ export function cacheHash(model, messages, opts = {}) {
|
||||
if (opts.temperature != null) h.update(`t:${opts.temperature}`);
|
||||
if (opts.max_tokens != null) h.update(`mt:${opts.max_tokens}`);
|
||||
if (opts.top_p != null) h.update(`tp:${opts.top_p}`);
|
||||
// #176: fold the server's boot-config epoch into the key, so a config change that shapes
|
||||
// answers (operator system prompt, wrapper text, allowed tools, NO_CONTEXT) invalidates
|
||||
// the persistent cache instead of serving answers composed under the old config. Callers
|
||||
// that omit it (older paths, tests) hash byte-identically to before.
|
||||
if (opts.configEpoch != null) h.update(`ce:${opts.configEpoch}|`);
|
||||
for (const m of messages) {
|
||||
h.update(m.role || "");
|
||||
h.update(typeof m.content === "string" ? m.content : JSON.stringify(m.content));
|
||||
|
||||
Reference in New Issue
Block a user