F257 V1: Harness Ledger 段试验品 — objective-driven typed-fact 采集层(T-A/T-B/T-C) - #42
Merged
Conversation
Why: V1 切片第一步(redesign v2.3.2 FINAL §6)。@解析成功率指标的分子分母 必须由 parser 内部产 draft(parser 是 tokenization 唯一真相源,外部 re-tokenize = 第二真相源禁止)。现状 parser 对 self/unknown/duplicate/截断 零痕迹,指标不可验真。 What (semantics 全部引 T-A §3.4,代码不复述定义): - routing-attempt.ts: draft/batch 类型 + T-A eligible/success 列映射 + span 去重 collector(同 span 二次访问 = traversal artifact 无声合并) - a2a-mentions.ts: 改造①self patterns 参与匹配标记 self_excluded; 改造②unknown_token break 前 emit;(右截断) cap 后只读 scan, metric-affecting token 才置 truncated → batch metricEligible=false - AgentRouter.ts: parseMentionsRaw 三遍扫描 draft 化(route-line/prose/ speech),改造③duplicate 仅 distinct-span-same-target,改造④group 关键词 draft 层先行识别;speech-mention-map.ts 提供 speech pass 坐标 回映射(跨 pass span 合并前提);attemptBatch 插通 parseMentions/ parseAllMentions/resolveTargetsAndIntent - tokenOrdinal 于全部 pass 合并去重后按 span 起点一次性赋值(0-based) Routing 行为变更(T-A 授权,测试固定): 仅改造① — self token 后同行 其余 token 现在继续扫描(旧行为:静默弃行)。其余 mentions/warnings 行为与既有 229 条测试逐条一致。 Tests: f257-routing-attempts.test.js 36 新增(红→绿)+ 既有路由测试 229 全过;biome 0 error(警告基线 17→15);tsc 干净。 [布偶猫/宪宪 Fable🐾] Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Why: V1 切片第二步。@解析成功率要可验真,fact 必须与消息同写共命运 (权威内嵌),投影只是查询缓存——评估前对账重建保证零静默缺口 (§4.5.1 ①watermark ②reconcile-before-evaluate ③错误可见)。 What: - StoredMessage.routingFact(T-A §3.4 batch):append 同一 hset 内嵌写入 (物理共命运);零 token parse 不产 authority 记录;in-memory/Redis 两 store 对齐;safeParse 容错 malformed - 6 个调用点接线:messages.ts 用户三路径(queue/TOCTOU/immediate)+ callbacks.ts 两回调路径 + route-serial stream 落库路径(改用 analyzeA2AMentions 捕获 batch;callbackAlreadyStored 分支天然无双写) - RedisRoutingFactProjection(§4.5.1):owner-scoped ZSET 时间索引 + watermark Lua 单调推进 + reconcileWindow 幂等重建(authority=消息 timeline ∩ 有 fact 字段;missing 补/stale 删;任何读错误→ok:false)+ computeResolutionRate(per parserMode,T-A eligible/success 列via routing-attempt.ts 映射;reconcile 失败→unmeasurable;截断批次/ malformed 计数呈现不静默丢)+ getHealth(collection-health 素材) - 接线:RedisMessageStore append 后 void project()(错误由 projection 自账:log + error ZSET,不复用 onAppend 吞错形态——§4.5.1③) Tests: +13(in-memory roundtrip 2 / Redis roundtrip+hydrate+malformed 3 / projection 契约 8)全绿;F257 相关 99/99。全量 api 套件 19027 tests 与 baseline e842229 严格对比:MINE-ONLY 回归 = 0(90 条失败两边完全一致, 均为 fresh-worktree 环境性 pre-existing——capabilities-route 类已知问题)。 [布偶猫/宪宪 Fable🐾] Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Why: V1 第二个 active 指标。live 路径 void tryDetectMagicWords 异常时静默 丢 hit(T-B 实测锚点),Event Memory 漏记则 raw count 静默偏低——指标 计算前必须按 owner-scoped cursor 幂等重扫补账,否则数字不可验真。 What (口径唯一来源 = T-B §3.5,代码不复述): - MagicWordMetricService.reconcileWindow:窗口内 user-authored 消息重扫 detectMagicWords(同一纯函数)→ markEvent 幂等补账 Event Memory(唯一键 owner+thread+msg+word 天然去重;补账事件带消息原始 timestamp 保证窗口 过滤正确)+ 数值 watermark Lua 单调持久化;cat 消息不在 cohort - computeWordCounts:reconcile 失败 → unmeasurable;成功 → Event Memory 只读分页投影,per word 唯一 (message,word) hit 计数——不写任何第二存储 (P4 单一真相源) Tests: 5 条(补账幂等+消息时间戳 / 唯一计数 / cat 消息出圈 / live 已写不 双计 / 窗口边界)isolated redis + :memory: SQLite 全绿。 [布偶猫/宪宪 Fable🐾] Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…anual 写入支 Why: V1 语义上报层(§4.8②)落地。三源 manual_observation 此前无账本无通道, operator/peer/self 的语义纠偏不可验真不可聚合——账本必须 owner-scoped、 原子去重、TTL=0,工具必须 principal 注入不可自报(T-C 契约全集)。 What (契约唯一来源 = redesign §3.1 + T-C §3.6,代码不复述): - deviation-event.ts:union by kind(condition_hit/manual_observation 公共字段 全集)+ manualIncidentKey(owner+anchor+subject+sorted 归属元组,weight 不进 identity)+ conditionIncidentKey(owner namespace)+ validateDeviationEvent (manual weight∈(0,1] / objective 不重复 / unitType V1 仅 segment / exact 支 单条 weight=1.0) - DeviationEventLog.ts:claim+append 同一 Lua(BallCustody 先例,无 phantom claim;claims=HASH incidentKey→eventId,duplicate 返回原 eventId 显式去重) + idempotencyKey 幂等 replay + cursor 分页((score,member-lex) 全序 boundary walk,同 timestamp tie 不丢不重,不沿用 200 静默截断)+ countInWindow 完整 聚合 + TTL=0 - report-harness-signal.ts:三条服务端校验①②③(getById 实体存在含 tombstone 拒 / owner 同域 / operator source ⇒ catId=null 且非 connector)+ recordedBy/ ownerUserId 从 callback principal 注入 + body .strict()(自报字段即拒)+ await-append 显式错误(§4.5-2 不 fail-open;无 Redis → 503); operator_confirmation 锚 V1 无 backing store → 校验① 如实 404 - MCP 工具:inputSchema per T-C + retryDelaysMs=[](非幂等 POST 不自动重放); AGENT_KEY_TOOLS 登记(shared-MCP 猫是三源上报主体,publish_verdict 先例)+ A_WRITE_SAFE 标注;callbacks.ts 注册 + index.ts 装配(Redis 缺席降级 503) Tests: 23 条(incidentKey canonical 序/weight 非 identity / 校验矩阵 / Lua claim 原子 / 幂等 replay / 分页 tie-break 25 事件三页无损 / owner 隔离 / TTL=0 / 三条服务端校验 / principal 注入 / 显式 dedup)+ F257 相关回归 127/127 绿;pnpm lint 0 error;全量套件 baseline 对比另附。 [布偶猫/宪宪 Fable🐾] Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…c 检查 Why: 中间 review R1 BLOCK(msg 0001784281501734):覆盖率自证循环、CJK unknown 零痕迹、malformed 仍可测、magic-word 双时间基准漏计、MULTI 逐命令 错误吞掉——五项都是"指标可验真"的地基缺口,不修则 V1 数字不可信。 What(逐 finding,语义唯一来源 = redesign §3.1/§4.5.1/T-A/T-B): 1. P1-1 cohort 审计:零 token batch 一律持久化+索引(fact 字段 = producer-run marker,两 store + project() 三处跳过删除);补齐漏接写路径——route() 改走 resolveTargetsAndIntent(persist) 带 batch、proposal dispatch 三支 append 带 resolved.attemptBatch、route-parallel 猫 stream 两处接 analyzeA2AMentions、dispatch-proposal deliverMessage 同款;reconcile 改为 独立 cohort 谓词(排 briefing/system/source 消息——source 面 V1 无 parser 不假装可测)对账"应跑 parser vs 有 fact",gap>0 → ok:false/producer_gap → 指标 unmeasurable(sol repro:@Opus 无 fact 消息不再 unmeasurable:false) 2. P1-2 CJK unknown:user tokenizer charset 扩 /^[\p{L}\p{N}_.-]+/u(ASCII ._- 连续语义原样保留——domain 判别依赖点号;TOKEN_BOUNDARY_RE 方案会切碎 example.com,已用回归测试钉住);a2a 侧 boundary-based 天然免疫已核验 3. P1-3 深校验:isValidRoutingAttemptBatch 全字段结构校验(值域数组与类型 同源防漂移);malformedFacts>0 → 强制 unmeasurable:malformed_authority_fact (原钉死 broken-JSON 可测语义的测试翻转) 4. P1-4 消息坐标 join:computeWordCounts 按窗口消息 id 集 join Event Memory (live 事件带检测时刻,event-time 过滤会漏边界;since=fromTs 仅作分页下界 ——检测必晚于消息落库不变量);缺 hash 由静默跳过改为 reconcile 失败 5. P1-5 exec 检查:assertExecResultsOk 检查 multi/pipeline 每条结果, project()/repairIndex() 失败不推 watermark、落 error ZSET(sol repro: wrong-type index 后 watermark 不再说谎) 测试基建根修:magic-word/projection 测试文件 per-file keyPrefix 硬隔离 (cleanupClientKeyspace 先例)——跨文件 msg:* 通配清理与严格缺-hash 契约 并发互爆的 race 根除。 Tests: 137/137 ×3 连跑全绿(+17 新增:CJK/边界/domain 回归、producer_gap、 零 token 授权、source 出圈、malformed 双形态、wrong-type watermark、双时间 基准 join、缺 hash 失败、空 batch 持久化翻转);pnpm lint 0 error; biome 0 error。 [布偶猫/宪宪 Fable🐾] Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…append exec 检查 Why: R2 BLOCK(msg 0001784302194374):cohort 靠 nullable 字段猜测把正常 proposal 卡片判成 producer gap、系统转述算成 operator 词面命中;validator 只验类型放行语义非法 fact;权威 append 吞 MULTI 逐命令错误产出"可测空窗" ——三项都让 exact 指标失真。 What(语义唯一来源 = §4.5.1/T-A/T-B): 1. P1-1 lane provenance:StoredMessage.lane('routed'|undefined=surface) 持久化写方声明——13 个 parser 面写点显式标注(messages×3/callbacks×2/ route-serial/route-parallel×2/route()/proposal-dispatch×3/deliverMessage/ index.ts);routing cohort = lane routed(gap = routed 无 fact); magic-word cohort = lane routed 且 catId 空;删除 origin/catId/source 全部猜测判据。sol 两个 repro(proposal 卡片→gap、系统转述→词面命中) 反转钉住;顺带治愈 legacy 窗口永久 unmeasurable(cohort 转 opt-in) 2. P1-2 跨字段不变量:从 collector/finalize 构造 derive—— metricEligible≡!truncated、user 永不 truncated、tokenOrdinal===index、 span (start,end) 严格 lex 递增、pattern 命中四 outcome 恒有 target/ token-skip 三 outcome 恒无;违反任一 → malformed_authority_fact; round-trip sanity:两 parser 真实输出过自家 validator(防假 malformed) 3. P1-3 authority append:逐命令检查 multi.exec tuple;任一失败 → undoAppendArtifacts 补偿撤销(hash+全部 timeline zrem+idem 回滚)→ throw——不留孤儿 hash 也不留无 hash 幽灵 timeline 条目;修复后同 idempotencyKey 重试可成功。sol repro(wrong-type timeline → 可测空窗) 反转钉住 Tests: 143/143 ×3 连跑全绿(+6:surface 出圈×2 / 不变量矩阵+round-trip×3 / append 补偿);pnpm lint 0 error;biome 0 error。 [布偶猫/宪宪 Fable🐾] Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… validator 收尾
Why: R3 BLOCK(msg 0001784304314350):lane 可选单轴仍自证(双漏静默出圈)、
routing lane 被复用为作者身份(game-lane 真实用户消息漏计)、validator 放行
空 target/错 basis 配对/重叠 span——cohort 判据连续三轮返工的根因 = 把
"作者身份"与"routing plane"压进同一轴 + 声明可选。
What(按 sol 修复判据):
1. P1-1 类型边界强制:AppendMessageInput.provenance **必填**
{ author: 'user'|'cat'|'system', routed: boolean }——TS 编译期强制全部
46 个 src append 调用点显式表态(漏写=编译错误,静默双漏根除);
assertProvenanceConsistent 写边界四向校验(user⇔catId null / cat⇔catId
set / routed⇔fact 双向)——声明不一致在写入口早爆;StoredMessage 侧
optional 仅为 legacy hydration(无声明=出全部 cohort,诚实)。
同族审计增量:route-parallel:1357 + route-serial:3473/3559 三处漏接的
空 content 猫 stream 落库点接上零 token batch + routed 声明
2. P1-2 author 轴:magic-word cohort = provenance.author==='user'(与
routing 轴正交)——game-lane 真实用户消息(routed:false)纳入(sol repro
反转钉住),系统转述/卡片/猫消息排除;routing cohort = provenance.routed
3. P1-3 validator:spanBasis↔parserMode 配对固定(finalize 调用点 derive)、
present-but-empty target 拒绝、span 扫描序不重叠(强于 lex 递增);
负例全补 + 真实 parser round-trip 双模守护(防假 malformed)
Tests: 145/145 ×3 连跑全绿(+2:game-lane 纳入 repro / 写边界四 throw;
gap 测试改 out-of-band 模拟——写边界已拦声明不一致路径);tsc 0 error;
biome 0 error。
[布偶猫/宪宪 Fable🐾]
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… catId 重建 author
P1-1 三入口 fail-open 收紧:
- routedProvenance: batch 运行时必填缺失即 throw——parser lane 不可能安静地
不 routed;非 parser 路径显式声明 { author, routed: false }
- assertProvenanceConsistent: provenance 运行时必填 + author 枚举 + routed
布尔值域,JS 调用者无法跳过声明或走私越域值;catId 交叉断言 loose 化
(undefined/null 同为无 catId 事实,hydration 本就折叠)
- 读端三态 parseProvenanceField: absent(legacy)/malformed/present 是不同事实。
malformed 令窗口 unmeasurable(routing reconcile ok:false
reason:malformed_provenance;magic scan collection-gap throw),absent 继续
诚实出圈;hydrateProvenance 仅供 UI/API 表面,指标端禁用
P1-2 thread-branch 复制:
- 复制可信 source provenance 的 author 轴,routed 恒 false(副本无 parser 跑过,
authority fact 属原消息);legacy 源显式 author:'unknown'(新枚举,语义=作者
无法验真,退出一切 exact cohort),不再从 nullable catId 猜 author
测试: 判据钉住 9 案全绿(P1-1a/b 单元 5 + P1-1c projection/magic 2 + P1-2
branch 2);全仓 fixture 补写声明 432 处/46 文件 + router mock 52 处补最小
合法 batch(对齐真实 parser 契约);R3 期契约测试 3 处升 R4 语义。
全量: 非 Redis 9496+19223、隔离 Redis 19543,对基线 106 档 0 新失败;
tsc 0 err/biome 0 error 级。
sol R4 verdict: 0001784306621979-002103-d05f03bf
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Why: exact routing and magic-word metrics must fail closed on damaged records, while branch/import copies must not masquerade as fresh operator observations. Hook-Override: inbound brand guard scanned a pre-existing localhost:3003 fallback in connector-gateway-bootstrap.ts; the staged R5 delta there only adds the observation type axis. Independent Biome, lint, build, targeted tests, and blame verification are recorded in the review note. [宪宪/gpt-5.6-sol🐾] Thread-Context: threadId=thread_mrq3h5d3imbulk26 catId=cat-8zfu14fb
Why: exact harness metrics must reject damaged Redis records, distinguish authenticated owners from connector senders, and timestamp branch edits as new observations. A single write/read identity contract prevents healthy-looking partial windows and false operator samples. [宪宪/gpt-5.6-sol🐾]
Why: queued messages move to their delivery position and may later change owner. Exact metrics must validate and join on the Store's effective order coordinate instead of mistaking these legal transitions for corruption or dropping early live events. [宪宪/gpt-5.6-sol🐾]
Why: exact harness readers treated hard-delete tombstones as healthy observations and left token-bearing projections, so results depended on a lossy live detector. Model deletion in the canonical record state machine and scrub F257 derivatives before irreversible message mutations. [宪宪/gpt-5.6-sol🐾]
Why: one-time pre-delete scrubs allowed stale Event Memory and episode writers, orphan Redis indexes, and restore races to violate the irreversible deletion boundary. Durable SQLite fences, complete projection cleanup, and Redis atomic transitions make deletion privacy-first and retryable. [宪宪/gpt-5.6-sol🐾]
Why: hard deletion could be bypassed by stale Redis mutators, projector/reconcile writers, and scan-before-delete races. [宪宪/gpt-5.6-sol🐾]
Why: delivery and owner reassignment could each commit a stale snapshot, splitting persisted owner timelines from effective order. [宪宪/gpt-5.6-sol🐾]
Why: a successful owner transition could return a pre-delivery snapshot, while the async projection contract overstated write-time convergence. [宪宪/gpt-5.6-sol🐾]
平行线 R5-R12 将 provenance 契约扩为三轴 (author/routed/observation, author 增 external_user) 但未跑全仓——gate 全量暴露 63 处 fixture 洞: - 两个 mockMsg builder 默认值补 observation:'original' (f148 家族 61 失败全源于此) - 3 处单行 provenance 字面量补三轴 - 2 处 connector source fixture 升级 author:'external_user' (新交叉断言: authenticated operator user 不得带 connector source) 验证: f148/incremental-context/messages-endpoint 家族 70/70 绿 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…tch regex 三轴批量补丁误伤唯一负例:753 行平行线判据(缺 observation 必须 throw)被 正则无差别补成合法对象。还原缺轴形态,f257-routing-attempts 49/49 绿。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
mindfn
added a commit
that referenced
this pull request
Jul 19, 2026
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
mindfn
added a commit
that referenced
this pull request
Jul 21, 2026
…rity + fail-closed) (#48) * feat(F257): #3 objective registry — 只读发现(取代 report_harness_signal objectiveId 考古) 修复清单 #3:report_harness_signal 的 objectiveId 是自由 string,零 list/schema/注入清单 → 三次上报三次考古。本 PR 建 objective registry 只读发现层: - registry YAML(docs/harness-feedback/objectives/registry.yaml,KD-3 registry-as-data)= 定义层(id/statement/segments)。**只登 canonized 目标**——redesign §2 名义 8 objectives 但只 canonize 了 2 个 id(obj-routing-delivery + obj-identity-integrity);不 invent 另 7 个 id(会伪造 V2 依赖的契约),registry 随 canonize 增长。 - loader(objective-registry.ts):parseObjectiveRegistry 纯函数(malformed 行丢弃不抛、 malformed YAML → 空)+ loadObjectiveRegistry fail-safe。 - GET /api/callbacks/objectives(镜像 rich-block-rules 只读路由)。 - cat_cafe_list_objectives MCP tool(镜像 rich-block-rules-tool;A_READ_LOCAL + readonly allowlist 注册)。 - report_harness_signal objectiveId description 同步指向 list_objectives。 边界:只做定义层 + 发现,不做 V2(evaluator/metrics/condition registry)。objectiveId 仍 自由(discovery-only,软校验留 V2)。 证据:9 tests(parseObjectiveRegistry 4 + loadObjectiveRegistry 2 + 路由 e2e + shipped registry 验证)全绿;api + mcp-server build clean;biome clean。切片 2a,独立 #47。 [宪宪/claude-opus-4-8🐾] Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(F257): #3 (2a) R1 — single authority + fail-closed + contract tests + map delta Addresses sol's slice-2a R1 REQUEST CHANGES (all four, no pushback). ## P1-1 — remove `segments` (second writable authority) The registry authored `id/statement/segments`, duplicating the unit→objective membership that frozen redesign §4.8 keeps in the versioned UnitEvaluationManifest. Dropped `segments` from YAML + loader type + API output + MCP tool output; the registry is now the canonical `id + statement` definition layer only. Attachments become a V2 derived read-model from UnitEvaluationManifest — one authority. ## P1-2 — fail-closed loader (no silent empty), strict validation, lower complexity parseObjectiveRegistry/loadObjectiveRegistry now return a discriminated ObjectiveRegistryResult ({ok:true,registry} | {ok:false,error}). Unreadable file / malformed YAML / non-mapping root / non-positive-integer version / non-array objectives / any invalid row / duplicate id → explicit failure, never {version:1,objectives:[]}. Validates positive-integer version, trimmed non-empty id matching ^obj-[a-z0-9]+(?:-[a-z0-9]+)*$, trimmed non-empty statement, unique ids (sol repros now rejected: version -2.5, whitespace id/statement, dup ids). Route returns 503 (uncached) on failure; MCP tool surfaces it via its existing !ok error path. Validation extracted into helpers → below the Biome complexity-17 warning. Route gains an optional injectable registry path (test seam). ## P2-1 — MCP contract tests restored to true green Added cat_cafe_list_objectives to EXPECTED_TOOLS / EXPECTED_COLLAB_TOOLS / EXPECTED_READONLY_TOOLS, and cat_cafe_report_harness_signal to TOOLS/COLLAB (the PR #42 leftover that made the suite baseline-red 385/387) — not masking the new mismatch behind the old failure name. Added focused handler tests (success / honest empty / 503 HTTP failure / network error). Full mcp-server suite 391/391. ## P2-2 — architecture map delta harness-eval cell: added objective-registry.ts / callback-docs-routes.ts / list-objectives-tool.ts code anchors + registry.yaml doc anchor + scan hints + why this is the definition layer of the SAME control plane, not a parallel registry. ## Evidence - api: f257-objective-registry 18/0, callback-docs-route 4/0 (200 + 503 fail-closed). - mcp-server full suite 391/391 (was 385/387). - biome: changed files clean (useLiteralKeys + parser complexity + format resolved). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(F257): #3 (2a) R2 — path-free 503 + strict key-set (reject unknown, not strip) Addresses sol's 2a R2 REQUEST CHANGES (both small, no scope change). R1's four findings were confirmed CLOSED. ## P2-1 — unauthenticated 503 leaked internal path / fs errno callback-docs-routes.ts /api/callbacks/objectives is unauthenticated but returned the loader's raw error, which contains the registry path + Node fs errno (e.g. "...registry unreadable at /private/secret/install/objectives.yaml: ENOENT..."), forwarded onward via the MCP tool's response.text(). Now: log the full internal reason server-side (request.log.error) and return a stable, path-free 503 body `{ error: 'Objective registry unavailable' }`. Test asserts the body contains neither the passed path nor ENOENT/errno, and is uncached; the MCP tool still recognizes 503 as an errorResult. ## P2-2 — "strict + single authority" schema was still fail-open on forbidden fields The loader read only id/statement and silently dropped everything else — so a stray `segments` (or a typo / future unversioned field) could reappear in the YAML, mislead a human into treating it as membership authority, while the runtime ignored it. Worse, the R1 test asserted that strip-behavior as "valid". Now registryVersion=1 fail-closes on the key set: root allows only registryVersion/objectives; each entry allows only id/statement. A `segments` key REJECTS (message points to the UnitEvaluationManifest §4.8 authority), not strips; any unknown key rejects. Future fields must bump the schema. Removed the fail-open "ignores segments" test; added red→green rejections for segments, unknown entry key, and unknown root key. ## Evidence - api: f257-objective-registry 21/0 (now includes segments/unknown-key rejections + descriptive-message assertion), callback-docs-route 4/0 (path-free 503 asserted). - shipped registry.yaml still validates (id/statement only). biome changed files clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(F257): #3 (2a) R3 — pin registryVersion to exactly 1 (fail closed on unsupported) Addresses sol's 2a R3 sole finding (R2's two remain CLOSED). ## P2-1 — unsupported schema versions were accepted under v1 semantics The key-set contract advertised "registryVersion=1 allows only … / future fields must bump schema", but parseObjectiveRegistry accepted EVERY positive integer and applied the v1 parser (repro: v1/v2/v999 all ok:true). That advertises an unimplemented version back to discovery clients as supported. Now the version gate requires exactly SUPPORTED_REGISTRY_ VERSION (=1); anything else fails closed with a clear message. A future v2 must ship an explicit versioned parser + bump the constant, not ride the positive-integer gate. Tests: changed the version-2 "valid" fixture to 1; added v2 + v999 rejection cases (the existing -2.5 / 0 / 1.5 / missing cases still reject as ≠1). ## Evidence - f257-objective-registry 23/0. biome changed files clean; build clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
F257 objective-driven redesign 的第一个 vertical slice(V1):三段试验品的 typed-fact 采集层。
cat_cafe_report_harness_signal:猫上报 harness 偏差信号;Lua claim+append 原子、幂等 replay、cursor 分页、owner 隔离、TTL=0;服务端三条校验 + principal 注入防自报Why
审计实锤(spec Current State):路由诊断不落库、工具流 7 天 TTL、130+ 口锅零触发遥测——指标所需事实必须新建 typed fact,且采集完整性必须可自证(数据丢失不得伪装健康空窗口)。
Review 链
跨猫 review 12 轮(sol/terra,缅因猫家族)R1→R12 全 BLOCK 收敛,R12 独立 APPROVE @ fb36bf5;之后仅测试 fixture 三轴对齐修复(cccf217ed/a0fc60a16,见下)。
Merge-gate 定性证据
全量 gate(19038 tests)三跑收敛轨迹:121 fail → 70 → 69,对基线档案(/tmp/f257-fails-r3fix2-clean.txt,106 名 pre-existing 环境失败)新增失败 = 0。
结论:本分支引入的测试失败为零;gate exit=1 完全由机器环境 pre-existing 失败造成(任何分支同红)。
🤖 Generated with Claude Code