spec: 证据账本判定层 schema v1(standards/evidence/,W1-B1 前半) - #429
Conversation
四类判定事件(gate/cost/approval/decision)统一记录 schema:链式 hash、 tenant 必填、payload ≤4KB 硬执法、payload_ref 轨迹层指针(W1-B3)。 字段命名对齐 OTel gen_ai.* 语义约定(映射表见同目录 README.md)。 Card: #406
|
Warning Review limit reachedNext included review available in 3 minutes. View limit detailsLimit details: You’ve used all 10 included reviews currently available. Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. Review configuration: ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
Comment |
PR Summary by Qodo定义证据账本判定记录 Schema v1
AI Description
Diagram
High-Level Assessment
Files changed (2)
|
Code Review by Qodo
1. Payload limit bypass via ref
|
| payload_ref: | ||
| type: | ||
| - "null" | ||
| - object |
There was a problem hiding this comment.
1. Payload limit bypass via ref 🐞 Bug ≡ Correctness
Because payload_ref does not reject unknown properties, a schema-valid record can place arbitrarily large inline content in a field such as payload_ref.data, bypassing the stated rule that Git stores only the pointer and that inline payload is capped at 4096 UTF-8 bytes. A writer that enforces only the documented payload check will therefore admit the exact large trace data this three-layer split is intended to keep out of Git.
Agent Prompt
## Issue description
`payload_ref` currently permits arbitrary extra properties, allowing large inline trace data to bypass the `payload` size guard and Git-storage discipline.
## Issue Context
JSON Schema's root `additionalProperties: false` does not apply recursively to nested objects.
## Fix Focus Areas
- standards/evidence/record.schema.yaml[103-118]
Add `additionalProperties: false` to `payload_ref` and tests proving unknown/inline-content fields are rejected.
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| prev_hash: | ||
| type: | ||
| - "null" | ||
| - string | ||
| description: "链前记录 hash(首条为 null;断链=红,fail-closed)" |
There was a problem hiding this comment.
2. Malformed chain links validate 🐞 Bug ≡ Correctness
prev_hash accepts any string and allows null at every sequence number, so records such as `seq: 2, prev_hash: null or prev_hash: x` pass the v1 schema despite not being valid SHA-256 chain links. This allows malformed ledger records through contract validation before the later verifier can detect them.
Agent Prompt
## Issue description
`prev_hash` accepts malformed strings and permits null on non-first records, contrary to the documented chain invariant.
## Issue Context
The schema can enforce the local constraints even though equality with the preceding record remains verifier responsibility.
## Fix Focus Areas
- standards/evidence/record.schema.yaml[119-127]
- standards/evidence/record.schema.yaml[17-18]
Require non-null values to match 64 lowercase hexadecimal characters, and add an `if`/`then` constraint making `prev_hash` null exactly when `seq` is 1.
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| ts: | ||
| type: string | ||
| pattern: "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}(\\.[0-9]+)?Z$" | ||
| description: "ISO 8601 UTC(gen_ai 事件时间戳语义)" |
There was a problem hiding this comment.
3. Invalid timestamps pass schema 🐞 Bug ≡ Correctness
The ts regex checks only digit placement, so impossible values such as 2026-99-99T99:99:99Z validate even though the field is declared to be an ISO 8601 UTC timestamp. This undermines chronological queries and the spec's planned timestamp property tests.
Agent Prompt
## Issue description
The timestamp regex accepts impossible calendar and clock values.
## Issue Context
The schema declares draft 2020-12 and the repository's event schema already uses `format: date-time`; UTC-only semantics still need the `Z` restriction.
## Fix Focus Areas
- standards/evidence/record.schema.yaml[24-27]
Use `format: date-time` with a validator configured to assert formats, retain an explicit UTC-only constraint, and add negative tests for invalid dates and times.
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| inputs_digest: | ||
| type: string | ||
| # 校验执法在写入器(write_evidence.py):必须为 64 位十六进制 sha256 | ||
| description: "判定输入摘要 sha256(provenance 锚点;witness 不可伪造性由链 hash 承担)" |
There was a problem hiding this comment.
4. Provenance digest accepts garbage 🐞 Bug ≡ Correctness
inputs_digest is only typed as a string, so values such as not-a-digest pass schema validation despite the field being defined as a 64-character SHA-256 provenance anchor. Invalid provenance identifiers can consequently enter the ledger and cannot be used to correlate or verify decision inputs.
Agent Prompt
## Issue description
`inputs_digest` accepts arbitrary strings instead of the documented SHA-256 representation.
## Issue Context
The intended 64-character hexadecimal rule is already stated in the adjacent comment and can be expressed directly in JSON Schema.
## Fix Focus Areas
- standards/evidence/record.schema.yaml[91-94]
Add the same `^[0-9a-f]{64}$` pattern used by the other SHA-256 fields and add positive/negative schema fixtures.
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| - "null" | ||
| - object | ||
| description: "轨迹层指针(W1-B3 协议):blob sha256+保留策略字段;git 侧零 payload 本体" | ||
| required: [sha256, store] |
There was a problem hiding this comment.
5. Retention policy can be omitted 🐞 Bug ☼ Reliability
payload_ref.required omits retention, so a trajectory pointer without any retention policy validates even though both the three-layer contract and INV-06 define the pointer as SHA-256 plus location plus retention policy. Such records leave lifecycle enforcement unable to determine how long referenced evidence must remain available.
Agent Prompt
## Issue description
A non-null `payload_ref` can omit the required retention-policy declaration.
## Issue Context
The README and governing spec define retention as part of every trajectory-layer pointer.
## Fix Focus Areas
- standards/evidence/record.schema.yaml[103-118]
Add `retention` to the nested `required` list and constrain it to the vocabulary that W1-B3 consumers will implement.
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| hash: | ||
| type: string | ||
| pattern: "^[0-9a-f]{64}$" | ||
| description: "本记录内容 hash(sha256,canonical JSON 序列化后计算——不含自身字段)" |
There was a problem hiding this comment.
6. Hash bytes are undefined 🐞 Bug ☼ Reliability
The schema says to hash “canonical JSON” but defines neither a canonicalization standard nor the exact UTF-8 bytes, leaving property ordering, number rendering, Unicode escaping, and omitted-versus-null handling ambiguous. Independent writers and verifiers can therefore derive different hashes for the same logical record and falsely report a broken chain.
Agent Prompt
## Issue description
The hash protocol does not define the exact byte representation to hash, so independent implementations need not produce the same digest.
## Issue Context
BEH-02 requires an independent verifier to recompute the chain from archived records.
## Fix Focus Areas
- standards/evidence/record.schema.yaml[124-127]
- standards/evidence/README.md[30-38]
Normatively select a canonicalization algorithm such as RFC 8785, specify UTF-8 encoding and exclusion of only the top-level `hash` member, and provide golden record/byte/digest vectors.
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
Card: #406
变更(C1 路径,ADR-0103)
standards/evidence/record.schema.yaml:判定层记录 schema v1(cloudbird/evidence-standard/record@1)standards/evidence/README.md:三层纪律 + OTel gen_ai.* 映射表 + 写入/验证执法面说明要点
kind: gate/cost/approval/decisionsubject.tenant必填(宪法 §14a 多租户计量分离,AC-3c)payload_ref轨迹层指针占位(W1-B3 协议承接)后续(本卡内下一 PR)
archive 仓
evidence/载体 +write_evidence.py/verify_evidence.py+ 月度 checkpoint(AC-3a 负向实测、AC-3b 断链红)。ADR: ADR-0103