본문으로 건너뛰기

Engineering Paper Extension 개발

현재 구현과 목표 surface

이 문서의 editor, template contribution, settings schema와 presentation resource는 contract_only 목표입니다. 현재 @px.component는 companion metadata와 annotation-derived port만 등록하고 production Canvas에서는 read-only unsupported로 표시됩니다. portable V1 container는 content/component.json 선언 하나만 받습니다. 다중 선언과 host presentation은 Node presentation과 third-party UI를 따르며 decorator-to-package build bridge는 아직 없습니다. successor V2 Canvas는 host-owned component.declarative@2만 허용합니다. rich editor·renderer와 non-empty settings는 RFC-014와 별도 versioned settings contract가 모두 승인되기 전에는 선언하거나 활성화하지 않습니다.

Engineering Paper는 선택 설치형 Component package가 제공할 목표 Component입니다. Engineering Paper Extension 계약은 Component target, Node에서 열 editor, template contribution, Document/PDF artifact와 versioned manual을 함께 정의합니다.

정식 registry의 component.engineering-paper@1과 기본 즐겨찾기는 현재 host code로 제공되는 legacy first-party built-in/oracle입니다. package contribution이나 successor V2 activation 결과가 아니므로, package 개발자가 이 renderer id·paper body·기본 즐겨찾기를 custom rich UI admission으로 재사용할 수 없습니다.

committed engineering-paper-package.v1.pxpkgpipelinexlab/engineering_paper@2.0.0, requiredContractVersion: 1, content/component.json을 사용하는 executable local V1 test fixture입니다. Runtime gate가 user-accepted local install, describe, resolve와 execution materialization을 실행합니다. 이 fixture는 published successor V2 release나 package-provided rich UI가 아닙니다.

successor V2 artifact bytes는 아직 없습니다. 따라서 현재의 7-field ComponentRef는 member order만 승인된 contract-only non-resolvable shape이며, concrete packageDigest· releaseByteDigest나 exact ref 생성·설치·admission을 의미하지 않습니다.

먼저 확장 지점을 고릅니다

추가하려는 기능사용할 계약
여러 Flow에서 재사용할 계산core @px.function
Package Component의 Canvas 표시@px.component declaration → host component.declarative@2 projection
재사용할 문서 기본 구조Extension @px.paper template contribution
section·formula·evidence 표현Component editor element contribution
가져오기·내보내기 형식versioned document-codec contribution
Flow에 배치할 기능package @px.component export + flow.node(...) placement

@px.component는 package-owned executable UI 진입점이 아닙니다. successor V2 Canvas는 declaration을 host component.declarative@2로만 표시합니다. 별도 rich editor/viewer는 기존 legacy first-party built-in과도 분리하며, 향후 RFC-014와 versioned settings contract를 모두 통과한 격리 surface만 사용할 수 있습니다.

목표 Engineering Paper surface가 Flow에 공개할 Canvas Component는 engineering_paper 하나입니다. Formula block과 Evidence table은 계획된 editor 내부 요소입니다.

연결 규칙

Engineering Paper Component 실행은 일반 typed input으로 계산값을 받습니다. 계획된 editor 요소는 현재 Node input이나 그 field를 안정적인 문서 block에 표시합니다.

Runtime은 typed input binding을 실행하고 editor는 그 값을 안정적인 문서 block에 표시합니다.

실행은 current Flow의 typed input binding과 Run을 사용합니다. editor extension은 현재 Node input의 문서 projection을 담당하며, current Flow와 Runtime이 실행 의미를 소유합니다.

Component와 template 예제

아래 document.input(...)과 non-empty template setting은 별도 versioned settings + port-projection 계약 뒤의 candidate authoring입니다. 초기 successor V2는 declaration-fixed ports와 absent 또는 {} settings만 허용하며 Node instance에서 port를 추가하지 않습니다.

python
from pipelinexlab import px
from engineering_paper import components as paper_components


@px.paper(version="1.0.0", title="Bearing check document")
def bearing_document(document: px.Paper):
    utilization = document.input("utilization", float, unit="1")
    summary = document.section("summary", title="Check summary")
    summary.result("utilization", utilization)


flow = px.Flow(
    "bearing_review",
    label="Bearing review",
    description="Checks a bearing and prepares its design document.",
)
load = flow.input(
    "load",
    float,
    unit="kN",
    description="Factored bearing load.",
)
check = flow.node("bearing_check", bearing_check)
paper = flow.node(
    "design_document",
    paper_components.engineering_paper,
    settings={"template": bearing_document},
)

flow.connect(load, check.inputs.load)
flow.connect(check.results.utilization, paper.inputs.utilization)
flow.result("paper_document", paper.results.document)

Component의 public result member는 paper.results.document입니다. 반환 artifact가 Document이므로 SDK author와 사용자가 보는 이름도 document로 맞춥니다. report는 독립 제품인 Report와 충돌하므로 사용하지 않습니다. 이 member는 기존 immutable Document artifact reference를 그대로 노출해 결과 payload를 복제하지 않으며, PDF 생성은 명시적 export로 남아 Run마다 렌더링 비용을 추가하지 않습니다.

Template은 Component input과 문서 위치를 선언합니다. flow.node(...)가 Canvas Node를 만들고 flow.connect(...)가 upstream result를 input에 연결합니다.

계획된 Editor element contribution

새 element는 RFC-014와 별도 versioned settings contract가 승인된 뒤의 target 계약입니다. 다음 정보를 현 V2 declaration이나 verified contribution index에 넣어 활성화해서는 안 됩니다.

항목목적
semantic key·version저장·migration identity
title·descriptionComponents manual과 editor picker 설명
input schemacurrent Node input/field와의 type compatibility
editor rendererauthoring UI
read-only rendererResult·Review UI
print rendererDocument/PDF 출력
command schemainsert·update·remove transaction
manual reference같은 release의 사용 안내

계획된 Element는 current Node input에서 계산 결과를 읽고, 문서 상태는 Engineering Paper Node setting에 저장합니다. 실행 순서와 Result 저장은 current Flow와 Runtime이 맡습니다.

Formula element payload는 version 1 FormulaExpressionTree입니다. closed node kind는 source, decimal, expression이고 exact engineering_paper@1.0.0 release가 binary div와 binary maximum만 제공합니다. source 값은 새 input wire 없이 ordinary Node.inputBindings가 해석한 typed value를 사용합니다. Runtime은 existing RepositoryAdapterPort<ReadFlow>로 saved revision을 읽고 FlowRevisionExecutor의 claimed attempt마다 formula evaluator를 한 번 실행합니다. 같은 category의 div만 dimensionless result를 만들고 maximum은 operand category를 유지하며, implicit unit conversion은 하지 않습니다. 각 root는 512 node와 depth 32로 제한하고 모든 refusal은 선언된 diagnostic vocabulary로 fail closed합니다 — formula 전용 다섯 code(PX_FORMULA_REFERENCE_NOT_FOUND, PX_FORMULA_OPERATOR_UNSUPPORTED, PX_FORMULA_SHAPE_INCOMPATIBLE, PX_FORMULA_DOMAIN_ERROR, PX_FORMULA_COMPLEXITY_LIMIT)와 기존 PX_UNIT_INCOMPATIBLE, PX_RESOURCE_LIMIT입니다.

계획된 저장 contract와 command

current V1 legacy EngineeringPaperNodeSetting은 canonical V1 schema와 Rust codec에 따라 contractSnapshot · document를 필수로 저장하고 읽을 때 snapshot을 검증합니다. snapshot의 ComponentRef는 Node target과 같아야 합니다. 이 persisted full snapshot은 V1 전용 호환 권위이며 generic Component recovery 또는 successor V2 settings 권위가 아닙니다. successor V2의 document-only setting은 승인·활성화된 형상이 아니라 후보입니다. presentation resource와 element contribution을 포함한 non-empty settings는 RFC-014 및 별도 versioned settings contract 뒤로 deferred되며 현재 V2 settings는 absent 또는 빈 object만 허용합니다. generic reader는 exact target/raw settings와 usage-derived 일부 port만 보존하며 last-verified snapshot은 저장하지 않습니다. original package bytes는 package artifact owner가 실제로 retained한 경우에만 recovery evidence이며 Flow 상태에서 추론하지 않습니다. input 실행 wire를 새로 만들지 말고 .pxflowNode.inputBindings와 RFC-003 TypeDescriptor를 사용합니다.

초기 successor V2 port는 component declaration.inputs에 고정합니다. 향후 deterministic Paper compiler가 document.input(...)을 publish/materialization 시점의 fixed declaration input으로 낮추는 경로는 별도 승인 뒤의 후보이며 Node-instance port가 아닙니다. Engineering Paper inventory는 engineering_paper 정확히 하나이므로 input contract가 다른 template은 versioned settings + port-projection contract 전까지 unsupported입니다. 일반 package의 1:N 기능은 이 inventory를 넓히지 않습니다. 화면 Add input과 instance-port materialization도 같은 계약 전까지 차단합니다.

document는 version 1의 schemaVersion · templateRef · generation · elements object입니다. 각 element는 elementKey · elementType · elementVersion · revision · parentKey? · payload를 보존합니다. 설치한 release가 elementType을 모르는 경우에도 payload를 다른 type으로 바꾸거나 삭제하지 않습니다. version 1 이외의 document는 원본 bytes를 유지한 read-only recovery로 열고, 자동 migration하지 않습니다. Document limit은 16 MiB, element 10000개, nesting/payload depth 32입니다.

Command schema는 다음 closed union을 구현합니다.

kindpayload
insertexpectedDocumentGeneration, optional afterElementKey, full element
updateexpectedDocumentGeneration, elementKey, expectedElementRevision, replacementPayload
removeexpectedDocumentGeneration, elementKey, expectedElementRevision

Command는 1 MiB 이하이며 generation/revision precondition, unique element key, existing parent, same-parent anchor와 depth 32를 통과한 뒤에만 Document를 한 번에 변경합니다.

불변 artifact 저장

Runtime이 반환하는 paper.results.documentartifactKey · contentDigestEngineeringPaperArtifactRef 하나이며 Document payload를 복제하지 않습니다. Document artifact는 version 1 Document와 sourceFlowRevision · nodeKey · evaluatorRelease · inputDigest provenance를 함께 고정하고, evaluatorRelease는 exact ComponentRef를 사용합니다.

PDF export DTO는 schemaVersion · artifactRef · sourceDocumentRef · exportProfileDigest만 보존합니다. PDF bytes는 storage operation에만 전달합니다. Document 저장에는 artifact.create, PDF 저장에는 artifact.createartifact.export, 읽기에는 artifact.read와 active exact-project AccessGrant가 필요합니다. local adapter는 공통 FilesystemCas의 reachability가 유지되는 동안 bytes를 보존하고 같은 ref의 교체를 거부합니다. Report PDF repository나 .pxreport를 재사용하지 않습니다.

Package layout

text
engineering-paper-extension/
├─ pyproject.toml
├─ src/<package>/
│  ├─ components.py
│  └─ templates.py
├─ editor/
│  ├─ package.json
│  └─ src/index.ts
├─ docs/
│  ├─ ko/
│  └─ en/
└─ tests/

계획된 public marketplace release는 Component declaration, Python content closure, manifest와 digest를 함께 고정하고 RFC-005 channel matrix에서 verified 상태여야 합니다. unsigned local install은 명시적 수락·경고·audit, unsigned admin-attached install은 명시적 수락·audit가 필요합니다. present-unverified·invalid·revoked·stale/unavailable verification evidence는 모든 channel에서 거부하며 renderer id나 signature 존재만으로 실행 권한을 만들지 않습니다. rich editor, template, codec, element, viewer, print와 manual entry는 RFC-014가 소유하며 별도 settings contract와 함께 admission을 통과한 뒤에만 exact ComponentRef에서 resolve할 수 있습니다.

공용 manifest의 packageKindcomponent, mimetype은 application/vnd.pipelinexlab.component+zip입니다. package-envelope profile이 허용하는 member는 schemaVersion, packageKind, publisher, packageKey, packageVersion, requiredFeatures, requiredContractVersion, capabilities, pythonDependencies, projectSnapshot, entries입니다. Component는 projectSnapshot을 금지하고 빈 capability/dependency는 생략 또는 빈 배열로 읽습니다. successor V2 declaration은 requiredContractVersion: 2를 요구하므로 현재 V1 installer가 거부합니다. committed V1 test fixture와 달리, 이 successor V2 declaration을 담은 signed/published release artifact는 아직 없습니다.

현재 V2가 계약으로 받아들이는 closure는 declaration과 그 declaration의 executorEntry가 정확히 가리키는 manifested Python source뿐입니다.

rolepath
Component declarationcontent/components/engineering_paper.json
Component executorcontent/engineering_paper.py

Rich content entry는 현재 manifest에 없으며 serialize하지 않습니다 (absent-pending-rfc-014). editor·template·codec·element·viewer·print·manual의 entry role, 경로, message shape는 이 문서에서 미리 고정하지 않습니다. RFC-014와 별도 versioned settings contract가 모두 승인되면 그 후속 authority가 exact entry 형상과 package 배치를 정합니다.

Contract-only 배포 전 확인

  • [ ] Engineering Paper가 Components의 Component 하나로 보입니다.
  • [ ] Formula block·Evidence table은 editor 내부 요소로만 보입니다.
  • [ ] Node는 normal import + flow.node(...)로 배치됩니다.
  • [ ] editor는 current Node input만 mapping합니다.
  • [ ] editor instance는 Flow target + nodeKey로 구분됩니다.
  • [ ] Generic/successor V2에서 Component package가 없을 때 current reader가 무조건 보존하는 범위는 exact ComponentRef, raw settings와 usage-derived partial ports뿐입니다. original package bytes는 package artifact owner가 실제로 retained한 경우에만 recovery evidence로 사용하며 Flow 상태에서 추론하지 않습니다. 이 branch에는 full 또는 last-verified contract snapshot owner가 없습니다.
  • [ ] Current V1 legacy Engineering Paper setting은 contractSnapshot · document를 필수로 보존·검증하되, 이를 generic Component recovery나 successor V2 settings 권위로 사용하지 않습니다.
  • [ ] Document·PDF를 Extension artifact로 설명합니다.
  • [ ] public marketplace contribution manual은 같은 verified release에 포함하고, local/admin channel은 공용 수락·경고·audit matrix를 따릅니다.

함께 읽기