본문으로 건너뛰기

결과 셀의 코멘트 anchor

결과표의 새 셀은 table key, 안정적인 row key 또는 Batch case key, fieldKey에 연결된 opaque blockAnchor를 받습니다. 헤더는 row 대신 별도 header identity를 사용합니다. 열의 위치나 표시 문구는 셀 identity가 아닙니다.

같은 셀의 결과를 갱신하거나 행·열을 재정렬할 때는 기존 anchor를 그대로 보존합니다. 이 규칙은 과거에 발급된 anchor에도 적용됩니다. 행을 삭제한 뒤 같은 row/case와 fieldKey로 다시 생성하면 새 incarnation을 발급합니다. 이전 셀의 코멘트 origin은 바뀌지 않으며 새 셀에 자동으로 연결되지 않습니다. 현재 revision에 원본 anchor가 없으면 orphaned로 표시하고, 원본 revision을 조회하면 원래 셀을 가리킵니다. orphaned는 조회 시 계산하는 상태이며 저장된 open/resolved 상태를 변경하지 않습니다.

Python SDK의 section.result_table(...)도 최초 헤더를 작성할 때 이 규칙을 적용합니다. incarnation token은 작성 시 한 번 생성해 draft에 보존합니다. 같은 draft의 반복 직렬화·명령 재시도는 같은 bytes를 사용하지만, 독립적으로 새로 작성한 표의 헤더는 서로 다른 incarnation이므로 문서·명령 bytes가 달라질 수 있습니다.

발급 인코딩은 UTF-8 compact JSON 배열 [table, row-or-null, fieldKey]의 SHA-256 소문자 hex와 16-byte incarnation token의 소문자 hex를 result_<digest>_<token>으로 조합합니다. JSON tuple은 구분자와 Unicode를 손실 없이 구별하고, null row는 실제 문자열 row와 구별됩니다. 하나의 생성 작업이 여러 셀에 token을 공유해도 각 셀은 서로 다른 tuple을 사용합니다. token 발급은 issuer별로 다릅니다: SDK 저작은 운영체제 entropy로 token을 한 번 생성해 draft에 보존하고, Runtime 투영은 최초 투영 명령 identity의 domain-separated compact JSON tuple ["report-result-incarnation-v1", workspaceRef, projectRef, reportKey, runRef, requestDigest]의 SHA-256 앞 16 byte로 token을 파생합니다. 따라서 commit 전 동일 투영 명령의 재시도는 같은 token을 다시 계산하고, 새 run/intent identity나 재생성은 이전 token을 다시 발급하지 않습니다. Core는 동일 입력에 대해 동일한 문자열을 만드는 공통 함수를 소유합니다. 소비자는 이 문자열을 분해하거나 직접 만들지 않고 정확히 보존합니다.

이 규칙은 모든 SemanticKey와 opaque anchor를 하나의 문법으로 합치는 규칙이 아닙니다. 새 발급값은 기존 comment record의 키 검증도 통과하지만, 기존 opaque anchor를 변환하거나 과거 revision·CommentThread origin을 다시 쓰지 않습니다. Report bodyDocument schemaVersion 1.0.0과 comment 저장소는 그대로 유지됩니다.

계약 원본은 comment profile, 공유 검증 벡터는 공유 anchor fixture입니다.