Report 출력과 외부 전달
px.Report 또는 Report Workbench에서 저장한 .pxreport revision이 출력의 원본입니다. Report에 연결된 Flow Result는 exact Result snapshot을 읽기 전용으로 표시하며, Preview와 PDF는 이 저장 상태를 같은 방식으로 렌더링합니다.
서로 다른 작업
| 작업 | source | result | durable |
|---|---|---|---|
| Report Save | current Report draft | 새 .pxreport revision | 예 |
| Flow Run | Report connection이 고정한 Flow revision과 input | immutable Result snapshot | 예 |
| Preview | exact Report revision + Result refs + render profile | expiring resource | 아니요 |
| Save PDF to Project | exact Report revision + Result refs + render profile | immutable PDF artifact revision | 예 |
| Download PDF | exact PDF render | 사용자가 선택한 OS file | Project 밖 |
| exact Report render | host print dialog | 아니요 | |
| Publish | exact Report 또는 PDF revision | immutable Publication Version | V2 |
Report Save는 계산을 실행하지 않습니다. Flow Run은 Report 본문을 수정하거나 PDF를 자동으로 생성하지 않습니다. 연결한 결과 위치는 Result snapshot의 값을 계속 읽고, 출력은 그 상태를 고정해 렌더링합니다.
출력 source 불변식
모든 출력은 다음을 고정합니다.
- source Report revision ref
- 각 result projection이 가리키는 Flow Run과 Result snapshot ref
- Report의 block·table·artifact slot key
- renderer, font, locale와 page setup
- 포함할 attachment와 provenance policy
현재 열려 있는 draft, mutable Flow head와 latest result를 렌더링 시점에 다시 선택하지 않습니다.
입력·결과의 글자 서식
문서의 첫 제목과 설명은 같은 저장 revision의 metadata.title과 metadata.description에서 읽습니다. 편집기와 Typst Preview/PDF에 함께 표시하며, 출력을 위해 본문에 제목을 복사하거나 block·연결 key를 추가하지 않습니다. 긴 제목과 설명도 조판 엔진이 줄과 페이지를 나눕니다. 매 페이지 반복하는 머리말과는 별개입니다.
본문의 text, field, placement: inline인 resultProjection은 같은 marks 배열을 저장합니다. 승인된 10종 글자 서식과 textStyle의 글꼴·크기·줄 간격을 사용하며, 문장을 굵게 바꾸어도 입력·결과가 일반 텍스트로 바뀌거나 연결 key가 달라지지 않습니다. 블록 결과와 문단·표 같은 컨테이너에는 인라인 marks를 붙이지 않습니다.
편집기와 읽기 화면은 저장된 서식을 표시하고 Typst는 같은 revision의 실제 값을 읽은 뒤 그 서식을 적용합니다. 화면의 @ 표시와 연결 영역 강조는 문서 서식이 아니므로 인쇄하지 않습니다. 인라인 참조의 서식을 거부하던 이전 Runtime과 새 편집기를 혼합 배포하지 않습니다.
Media type allowlist
Report 본문에 그리는 attachment와 계산 결과를 내려받는 artifact slot은 서로 다른 versioned allowlist를 사용합니다.
| 위치 | version | 승인된 media type |
|---|---|---|
| attachment | 1.0.0 | application/pdf, image/png, image/jpeg, image/svg+xml |
| artifact slot | 1.0.0 | application/pdf, image/png, image/jpeg, image/svg+xml, text/csv, application/json, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet |
본문에 그리는 attachment는 renderer가 감당할 수 있는 형식이어야 화면과 출력물이 같아집니다. Flow 계산이 만든 Artifact는 본문에 그리지 않고 내려받으므로 renderer 제약을 받지 않으며, resultProjection.attrs.declaration.accepts에 artifact-slot 목록의 non-empty subset을 기록합니다.
두 목록은 각자 version을 가지며 이후 변경은 additive 확장만 허용합니다. 새 version은 media type을 추가할 수 있지만 이미 승인한 member를 제거하거나 다른 의미로 재정의할 수 없습니다.
Page setup
{
"pageSize": "A4",
"orientation": "portrait",
"margins": {
"top": "18",
"right": "16",
"bottom": "18",
"left": "16"
}
}Page setup은 Report마다 하나씩 가지는 durable setting이며 stable workspaceKey + projectKey + reportKey 주소의 page_setup key가 소유합니다. Report revisionRef는 이 주소에 포함하지 않습니다. pageSize, orientation, margins는 모두 required이고 이 세 member 밖의 값은 허용하지 않습니다. Flow와 Node의 실행 계약에는 Report page field를 추가하지 않습니다.
Store read는 accepted value와 non-empty opaque version을 함께 반환하거나 아직 값이 없으면 null을 반환합니다. Write는 그 read version을 expectedVersion으로 보내는 compare-and-set만 허용하며 blind overwrite는 금지합니다. Version conflict가 나면 현재 stored value와 사용자의 draft를 모두 그대로 보존하고, 사용자가 충돌을 명시적으로 해결한 뒤에만 다시 write합니다.
pageSize | portrait 물리 크기 | 상태 |
|---|---|---|
A4 | 210 × 297 mm | closed enum · default |
Letter | 215.9 × 279.4 mm | closed enum |
pageSize는 closed enum A4 | Letter이며 V1은 이 둘만 지원합니다. orientation은 closed enum portrait | landscape이고 portrait이 default입니다. landscape는 표의 width와 height를 바꿉니다. 다른 용지나 방향을 비슷한 값으로 대체하지 않습니다.
margins는 top, right, bottom, left 순서의 closed object입니다. 각 값은 millimetre 길이를 나타내는 RFC-003 decimal이며 JSON number가 아니라 exponent 없는 canonical decimal string으로 저장합니다. Decimal precision은 최대 38, scale은 0 이상 18 이하이고 각 margin은 0 이상 105 mm 이하여야 합니다. 0은 음수 margin을 열지 않으면서 full-page body를 허용하는 최솟값입니다. 105는 지원 용지 중 가장 작은 edge인 A4 210 mm의 절반입니다. 이 값은 임의의 printer preset이 아니며, 서로 마주 보는 두 margin이 각각 최댓값일 때 별도의 body-area 검사가 실제로 0 mm 경계를 거부할 수 있게 하는 가장 작은 파생 상한입니다.
Default margins는 top: "18", right: "16", bottom: "18", left: "16"입니다. 공개 출력 사양에서 사용자가 이미 보던 값을 보존하기 위해 이 default를 선택했습니다. 15 mm는 더 이상 production 상수가 아니며 네 margin에서 사용자가 선택할 수 있는 유효한 값 하나입니다.
Orientation을 적용한 page width와 height에서 left + right와 top + bottom을 각각 뺀 body width와 height는 모두 0보다 커야 합니다. 하나라도 0 이하이면 전체 Page setup을 PX_RESOURCE_LIMIT으로 거부하고 diagnostic path는 /pageSetup/margins로 둡니다. 이 code는 RFC-003 core registry의 기존 code이며 RFC-008용 새 PX_ code가 아닙니다. Renderer와 UI는 margin을 clamp하거나 default로 되돌리거나 다른 용지로 바꾸지 않습니다. Unknown pageSize, unknown orientation, non-canonical decimal, 범위 밖 margin도 저장·preview·output 전에 전체를 거부합니다.
고정된 두 page size, 두 orientation과 네 margin은 validation을 O(1)로 유지합니다. RFC-003의 precision 38/scale 18 상한은 각 decimal 연산과 입력 자릿수를 bounded하게 하고, 105 mm 상한은 입력과 diagnostic 크기를 더 좁게 제한합니다. 하지만 좁은 유효 body는 줄바꿈과 page 수를 크게 늘릴 수 있습니다. 따라서 이 상한과 default geometry는 처리량 보장이 아니며 production pagination은 생성된 page 수에 비례하는 resource budget을 적용하고 초과 시 fail closed해야 합니다.
Report Workbench Page setup surface
Report Workbench는 Report setting을 편집하는 Page setup surface를 제공합니다. 이 surface는 printable page 안이 아니라 Report chrome에서 시작하는 modal dialog이고, pageSize, orientation, 네 margins를 위 contract 순서로 편집합니다. A4/Letter와 portrait/landscape는 closed choice control로, margin은 mm suffix와 연결된 decimal field로 표시합니다. 현재 저장값, default와 body width/height validation 결과를 text로 함께 보여 주며 색만으로 오류를 알리지 않습니다.
Apply는 완전하고 유효한 Page setup 하나를 Report setting update intent로 내보낼 때만 가능하고, Cancel과 Escape는 원래 값을 보존합니다. 첫 오류로 focus를 옮기고 dialog를 연 exact trigger로 focus를 돌려줍니다. 좁은 화면에서는 같은 field 순서와 44 px minimum target을 유지합니다. Apply는 위 page_setup 주소와 마지막 read version으로 compare-and-set하며 conflict가 draft를 지우거나 stored value를 덮어쓰지 않습니다. Design token, control density, overlay, focus와 error state는 PXFLOW design-system catalog가 소유합니다. React implementation과 실제 command wiring은 별도 implementation gate 전에는 완료된 기능으로 간주하지 않습니다.
수치 정밀도와 표기
{
"computationScale": "12",
"displayScale": "3",
"smallValueNotation": "engineering"
}수치 정밀도도 Report마다 하나씩 가지는 setting이며 Page setup과 같은 per-report-setting입니다. computationScale, displayScale, smallValueNotation은 모두 required이고 이 세 member 밖의 값은 허용하지 않습니다. Page setup과 마찬가지로 이 setting은 Page setup 안에 들어가는 네 번째 member가 아니라 그 옆에 서는 별도 record입니다.
computationScale과 displayScale은 서로 다른 두 setting이며 lifetime이 다릅니다. computationScale은 저장되고 따라서 digest되는 값을 바꾸고, displayScale은 화면이 보여 주는 것만 바꿉니다. 한쪽을 다른 쪽 자리에 쓰는 구현은 fail closed로 거부하며 두 값을 하나로 합치지 않습니다.
| member | default | 바꾸는 것 |
|---|---|---|
computationScale | 12 | 저장되는 값과 그 digest |
displayScale | 3 | 화면 표시만 |
smallValueNotation | engineering | 화면 표시만 |
두 scale은 decimal place 개수이며 RFC-003 int64 serialization을 따라 leading zero 없는 base-10 string으로 저장합니다. JSON number로 저장하지 않습니다. float로 도착한 scale은 canonical decimal grammar가 지키려는 성질을 이미 잃은 값입니다. 두 scale은 0 이상 18 이하이며 18은 RFC-003이 이미 고정한 decimal scaleMax입니다. 새 precision 값을 도입하지 않습니다.
computationScale이 12여도 0이 아닌 값이 0으로 rounding되지는 않습니다. scale 12가 0을 만들 경우 유효숫자가 살아남을 때까지 scale이 커지며 그 상한은 같은 scaleMax 18입니다. 따라서 저장된 scale은 크기에 따라 달라지지만, canonical decimal은 trailing zero를 금지하므로 한 값에 두 spelling이 생기지 않고 digest는 그대로 정의됩니다.
smallValueNotation은 closed enum engineering | scientific | e-notation이며 engineering이 default입니다.
smallValueNotation | 예시 | 규칙 |
|---|---|---|
engineering | 123.4 × 10⁻⁹ | exponent가 항상 3의 배수여서 nano·micro·milli·kilo·mega와 맞습니다 |
scientific | 1.234 × 10⁻⁷ | mantissa가 1 이상 10 미만인, 문서가 인쇄하는 형태입니다 |
e-notation | 1.234e-7 | 같은 값을 ASCII로 적어 복사와 export에서 살아남습니다 |
Notation은 presentation 전용입니다. RFC-003 canonical decimal grammar에는 exponent form이 아예 없고 그 rejectedSpellings가 이미 "1.0"과 ".5" 같은 형태를 거부하므로, 화면이 어떤 notation을 쓰든 저장되는 값은 exponent 없는 canonical decimal string입니다. Notation을 바꾸는 것은 어떤 digest도 바꾸지 않습니다. Exponent를 가진 string이 저장·digest·wire 경로에 도달하면 그것은 defect이며 PX_TYPE_INCOMPATIBLE로 거부합니다. 범위를 벗어난 scale은 PX_RESOURCE_LIMIT으로 거부하고 diagnostic path는 /numericPrecisionAndNotation으로 둡니다. 두 code 모두 RFC-003 core registry의 기존 code이며 RFC-008용 새 PX_ code가 아닙니다.
Setting scope는 personal-global과 per-report 둘이며 Report setting이 personal global setting을 이깁니다. 이는 정밀도만의 규칙이 아니라 이 제품의 일반 규칙입니다. Report가 값을 소유하고 한 문서가 하나의 digest를 유지하려면 Report는 항상 명시적인 값을 들고 있어야 하므로, global setting은 Report를 만들 때 Report 안으로 복사되고 그 뒤로는 Report가 소유합니다. 이후 global setting 변경은 새로 만드는 Report에만 영향을 줍니다. Report를 비워 두고 읽는 사람의 global setting으로 fallback하는 대안은 두 조건을 동시에 깨뜨립니다. 이 결과는 선택한 것이 아니라 두 조건에서 유도한 것입니다.
세 member, 두 정수 scale과 세 값짜리 notation enum은 validation을 O(1)로 유지합니다. 크기에 따라 커지는 scale도 accepted scaleMax 안에 머무르므로 decimal 연산이 bounded합니다. Notation formatting은 순수 string projection이며 저장·digest·wire 비용을 더하지 않습니다.
아직 승인되지 않은 것이 다섯 있습니다. personal global setting을 어디에 저장하는지를 정한 authority가 없습니다. SDK가 이 세 값을 어디서 정하는지도 열려 있습니다. 문서에 쓰는 것과 실행마다 넘기는 것은 다르며, 후자는 한 문서를 두 번 실행해 서로 다른 digest 둘을 만들 수 있습니다. Report의 displayScale과 smallValueNotation을 바꾸는 것이 새 revision을 만드는지도 아직 정해지지 않았습니다. 어떤 크기부터 값을 exponent form으로 보여 주는지, 그리고 displayScale이 notation의 mantissa에 어떻게 적용되는지도 정해진 authority가 없습니다. 이 다섯은 값을 고르지 않고 승인되지 않은 결정으로 기록합니다.
Report Workbench 수치 정밀도 surface
Report Workbench는 이 세 setting을 편집하는 surface를 제공하며 두 scope 모두에 닿을 수 있어야 합니다. 하나는 사용자의 personal global setting이고 다른 하나는 지금 Report의 override입니다. Surface는 어느 scope를 편집하는지 항상 text로 보여 주고, Report가 global 값을 override하고 있으면 그 사실과 원래 global 값을 함께 보여 줍니다. 색만으로 상태를 알리지 않습니다.
두 scale은 decimal places 단위가 붙은 정수 field로, notation은 세 값을 모두 보여 주는 closed choice control로 표시합니다. Notation control은 선택마다 지금 값의 실제 표기 예시를 함께 보여 줍니다. Apply는 완전하고 유효한 setting 하나를 update intent로 내보낼 때만 가능하며, Cancel과 Escape는 원래 값을 보존하고 focus를 exact trigger로 돌려줍니다. 범위 밖 scale이나 canonical하지 않은 값에서는 Apply를 막고 해당 field를 이름으로 지목하며 값을 clamp하지 않습니다.
Report의 computationScale을 바꾸는 것은 저장되는 값을 바꾸므로 document edit이며 새 revision을 만듭니다. 따라서 누가 언제 결과의 정밀도를 바꿨는지 history에 남습니다. displayScale과 smallValueNotation의 revision 효과는 위에 적은 대로 아직 승인되지 않았습니다. Design token, control density, overlay, focus와 error state는 PXFLOW design-system catalog가 소유합니다.
페이지 나눔
- Section의 keep-with-next와 explicit page break를 우선합니다.
- table row, equation, figure와 code block은 가능한 한 중간에서 자르지 않습니다.
- 한 page보다 큰 element는 정의된 continuation renderer를 사용합니다.
- header/footer, footnote와 page number는 renderer가 deterministic하게 배치합니다.
- 같은 Report revision, Result refs와 RenderProfile은 같은 semantic PDF output을 만듭니다.
RenderProfile
{
"profileKey": "report_pdf",
"profileVersion": "0.1.0",
"rendererVersion": "0.15.1",
"fontBundleDigest": "sha256:...",
"locale": "ko-KR",
"pageSetup": {}
}Remote font, current time, random과 host별 system font를 암묵적으로 사용하지 않습니다.
The version-owned report_pdf / 0.1.0 preset is fixed by report-output-profile.v1.json#/paginationAndTemplates/runtimeRenderPreset. It owns the body font order, point sizes, ink, heading/table defaults and the body/header-to-Typst mapping. Changing that mapping or a preset default requires a new preset version. The common Runtime resolves the actual bundled font file digest and Typst engine version; ko-KR maps explicitly to Typst language ko and region KR. It never reads a host locale or discovers system fonts.
report.plan_pages() and report.export_pdf(path) select the document's settings once and send the complete {value, version} as settingsSnapshot. An explicit page_setup overrides only the render page box and retains the selected document snapshot. No render re-reads latest settings. Legacy pageSetup-only product requests remain an explicit page selection, with settingsSnapshot: null and settingsSelection: "explicit-page-only"; they do not invent a settings version. Snapshot requests use document-settings or explicit-page-override.
A supplied settingsSnapshot is recognized only when it matches the Report's stored settings at output-request admission. A version the store does not hold answers PX_GENERATION_STALE; the stored version with a different value answers PX_REQUEST_SHAPE_INVALID on /settingsSnapshot. The accepted snapshot is copied into the resolved render input, so a settings change during typesetting does not move the accepted input, and reproducing an archived output uses its archived resolved snapshot without re-checking current settings. settingsSelection is the closed enum fixed by report-output-profile.v1.json#/paginationAndTemplates/settingsSelection.
Both outputs carry provenance.renderProfile, its six-member JCS renderProfileDigest, sourceRevisionRef, fontBundleDigest, engine, settingsSnapshot and settingsSelection. PagePlan.to_dict()["provenance"] and PdfExport.provenance / PdfExport.to_dict()["provenance"] expose the frozen inputs without asking authors to enter a profile hash. Output provenance is separate from Report revision JCS; retained Result refs remain in that exact source revision. Unsupported caller profile/locale/font members are refused rather than silently claimed by this preset. Changing page geometry computes a different profile digest. Numeric notation rendering is a separate formatter boundary; this preset does not claim C7 implementation.
Preview
Preview는 짧은 수명의 permission-checked resource입니다.
- Project artifact나 Publication을 만들지 않습니다.
- Preview URL을 durable Report field에 저장하지 않습니다.
- Report revision, Result ref 또는 permission이 바뀌면 다시 발급합니다.
- Download/Print 권한을 자동으로 부여하지 않습니다.
PDF artifact
Save PDF to Project는 새 immutable artifact revision을 만듭니다.
{
"artifactKind": "pdf",
"sourceReportRef": "report:girder_review@sha256:...",
"sourceResultRefs": ["result:run_..."],
"renderProfileDigest": "sha256:...",
"contentDigest": "sha256:..."
}같은 이름으로 다시 저장해도 기존 bytes를 덮어쓰지 않고 새 revision을 만듭니다. Download PDF는 trusted host가 발급한 exact destination handle에 씁니다.
저장할 bytes가 선언된 contentDigest와 다르면 CAS 보존 등록과 revision 생성 전에 거절합니다. 이미 저장된 같은 bytes는 이 거절로 삭제하지 않습니다.
CAS 보존 등록, PDF revision과 head는 하나의 저장 transaction에서 확정됩니다. 파일 준비 후 저장이 실패하거나 프로세스가 중단되면 아직 참조되지 않는 파일이 남을 수 있지만, 이 저장으로 새 보존 등록이나 읽을 수 있는 revision이 따로 생기지는 않습니다. 다시 저장할 때 검증된 파일을 재사용하며, 기존에 보존된 파일과 revision은 유지합니다.
Print
Print는 exact Report revision, Result refs와 RenderProfile에서 frozen render를 만든 뒤 사용자 gesture로 host print dialog를 엽니다. Print 자체는 Project artifact나 Publication을 만들지 않습니다.
OutputBuild
큰 출력은 durable OutputBuild task로 처리할 수 있습니다.
OutputBuild는 source Report revision, Result refs, RenderProfile digest, caller permission scope와 destination kind를 고정합니다. Retry가 새 source나 latest Result를 선택하지 않습니다.
Report Publication profile
V2 Publication은 exact Report 또는 PDF revision을 읽기 전용으로 전달합니다.
- Publication은 Flow Run 기능을 추가하지 않습니다.
- source Report를 편집할 수 없습니다.
- 공개할 attachment, Result와 provenance closure를 사전에 검사합니다.
- suspend/withdraw는 delivery를 중지하고 source revision은 보존합니다.
- HTML Embed는 이 profile의 read-only viewer를 사용합니다.
입력과 Run을 제공하는 화면은 별도 PXFLOW App Deployment로 배포합니다.
권한
| 동작 | 최소 확인 |
|---|---|
| Preview | Report revision과 포함된 Result read |
| Save PDF to Project | source read + destination create |
| Download PDF | PDF read + trusted file destination |
| source read + user gesture | |
| Publish | source read + publication capability + closure review |
허용된 Report revision을 읽는 권한과 source Flow를 편집하는 권한은 분리합니다. 출력에서 Open source Flow를 선택할 때는 Flow read/edit 권한을 별도로 확인합니다.
Local과 Cloud
Local과 Cloud는 같은 Report revision, Result refs와 render 계약을 사용합니다. 달라지는 것은 storage adapter, worker 배치와 destination handle입니다. Local absolute path, Cloud bucket key와 signed URL을 portable artifact identity로 저장하지 않습니다.
진단
| code | 의미 | recovery |
|---|---|---|
PX_REPORT_REVISION_REQUIRED | 출력할 저장 Report revision을 선택하지 않음 | Report 저장 |
PX_REPORT_RESULT_STALE | 연결 source 뒤에 Result가 바뀌었거나 만료됨 | mapping 검토 후 Flow 다시 실행 |
PX_RENDER_PROFILE_INVALID | page/font/renderer 계약 불일치 | profile 검토 |
PX_OUTPUT_PERMISSION_DENIED | source 또는 destination 권한 부족 | access 검토 |
PX_OUTPUT_DESTINATION_CONFLICT | 선택 file과 충돌 | 새 이름 또는 명시적 교체 |
PX_OUTPUT_RESOURCE_MISSING | 포함할 attachment 또는 Result를 찾지 못함 | Report connection과 retention 확인 |
구현 불변식
- Report 출력은 exact
.pxreportrevision에서 시작합니다. - result projection은 immutable Result snapshot ref를 유지합니다.
- PDF는 사용자가 시작하는 명시적 export입니다.
- output이 source Report, Flow 또는 Node를 수정하지 않습니다.
- Preview, Project PDF, Download, Print와 Publication은 각각 별도 operation입니다.
- 선택 Component의 document artifact와 core Report revision을 같은 객체로 저장하지 않습니다.
이어서 보기
First V1 Report storage closure (2026-09-08)
report-output-profile.v1.json#/storageV1 and report-storage.v1.schema.json own Report semantic attribute, authored numeric and portable setting shapes. pxflow-core validates them; SDKs, web clients, Flow projections and PDF consumers do not define alternate persisted shapes. The body discriminator remains bodyDocument.schemaVersion1.0.0 for this first production freeze.
connectedTable.declaration is null, {rowKeyField}, or the closed {kind: "resultTable", version: 1, fieldKeys} declaration. A result slot declaration is null or {accepts} using the approved artifact media list. Table presentation is null or one current provenance watermark plus connectionKey, rowKeys, fieldKeys, and resultProvenance. Each retained region has those same eight members without recursion. valueRef is a PublicDigestRef, snapshotRef is an opaque nonempty handle, and mapping, port, connection and field keys use SemanticKey. Row keys preserve source identity. Coverage denotes the Cartesian product of row and field keys, contains no duplicates or overlapping regions, and names existing cells. An empty row set represents an empty result. The latest watermark must also occur in the retained regions. Unknown semantic members, invalid references or coverage are refused; result payloads remain governed by their result type rather than an arbitrary metadata closure. A pre-region table watermark preserves its original bytes for read-only recovery; neither coverage inference nor history rewriting is allowed.
page_setup and numeric_precision_and_notation are explicit document-owned settings, addressed by workspace/project/report and updated with an opaque-version compare-and-set. They remain outside revision root. Report.settings() and Report.set_settings(value, expected_version=...) are the SDK boundary. A setting update advances only the setting version, never re-rounds stored history, and supplies computation scale for subsequent decimal authoring. Main defaults only initialize new documents; rendering never falls back to workspace, project or reader preferences. Export carries the exact settings snapshot, and import/copy restores it as part of that operation; existing conflicting settings require explicit resolution. C3 freezes that snapshot with RenderProfile.
Python int authoring uses canonical int64 text, Decimal uses canonical decimal text, float preserves float64 JSON-number semantics, and raw str remains string. Canonical negative zero is zero. Numeric settings do not stringify coordinates, indices or booleans, and displayScale does not round execution values. RFC-003 bounds, JCS and the CanonicalQuantity/PresentationQuantity separation continue to apply.
New authored table cells use the same closed {kind, value, unit} union as scalar registries. Their row identity stays a canonical string; legacy primitive cells remain readable without rewriting their stored bytes. A finite Python decimal.Decimal is normalized by the Core tuple codec, then rounded half-even using the document's current computationScale; small nonzero values retain significance through bounded scale growth. Decimal precision/scale bounds are checked before rounding. New int64 values cover the complete signed 64-bit range as text.
product.report.read_revision includes a Core-derived displayBodyDocument beside report and freshness. It extracts canonical scalar content for readers and is never saved, hashed, or passed back as authoring content. The stored revision remains the editing source. Typst uses the same Core scalar reader. This does not implement C7 display notation or a new formatter.
문서 처리 JSON 첨부
attachment 미디어 계약 1.1.0은 application/json을 추가합니다. 분석·인용·번역의 canonical JSON은 기존 첨부파일의 이름·미디어 타입·크기 표현을 사용하며 JSON 내용을 본문 문장으로 렌더링하지 않습니다. typed 보존 여부와 부모 관계는 별도 Core 문서 보존 계약으로 검증합니다. 기존 PDF·이미지 미디어의 의미와 Report revision 형식은 바꾸지 않습니다.