Report, Flow와 Component의 시스템 모델
이 문서는 기술 참조입니다
제품을 처음 사용한다면 처음 보는 용어와 처음 시작하기를 먼저 읽으세요. 계산 흐름은 PXFLOW Studio, 문서와 계산 입력·결과 배치는 Report Workbench에서 편집합니다.
현재 Component 화면 범위
현재 production Flow reader는 Component package UI를 실행하거나 ComponentDescriptor 전체를 Canvas에 불러오지 않습니다. 기본 projection은 .pxflow에 저장된 exact target과 settings를 읽기 전용 unsupported 상태로 보존합니다. production host가 명시적으로 연결한 component presentation resolver가 같은 exact installed declaration을 찾으면 label·presentation과 port view를 host-owned component.declarative@2 Node로 투영하며, declaration이 없거나 잘못됐으면 unsupported 상태를 유지합니다. package UI는 마운트하지 않고 settings는 component-declared-settings@1이, rich surface는 RFC-016의 component-rich-surface-declaration@1이 소유합니다. 이 경계는 Node presentation과 third-party UI 계약이 소유합니다. Component contribution과 worker의 exact ProjectScope data-path isolation은 구현됐지만, 요청 Project와 authenticated principal의 권한 결속 및 execution-trust closure는 닫히지 않았습니다. 안전한 inactive quarantine도 없습니다. authorization·execution-trust closure가 모두 닫힐 때까지 production third-party Component install admission과 activation은 계약상 모두 차단합니다.
두 작성 제품이 public port로 연결됩니다
Project 안에서 Report와 Flow는 나란히 저장되는 문서입니다. Report Workbench 또는 Python SDK의 px.Report는 .pxreport를, PXFLOW Studio 또는 px.Flow는 .pxflow를 작성합니다.
Report는 본문, 작성값·표, Flow connection과 result 표시 위치를 소유합니다. Flow는 public input/result, Node와 내부 연결을 소유합니다. Runtime은 exact Flow revision을 실행하고 immutable Result를 만듭니다.
같은 Flow를 여러 곳에서 사용합니다
Function은 재사용 정의로 등록하고, @px.component는 installed Component와 대조할 companion metadata를 등록합니다. Flow는 px.Flow 아래에 실제 Node와 연결을 구성합니다. Function은 Studio·Runtime·MCP가 같은 descriptor를 읽습니다. Component는 명시적 resolver가 installed exact declaration을 찾았을 때 host-owned presentation과 port view로 투영되고, resolver가 없거나 일치하지 않으면 exact Component target을 read-only 지원 불가 상태로 보존합니다. 이 경계는 자동 폴더 탐색이나 package UI 실행을 뜻하지 않습니다.
현재 @px.function과 명시적으로 resolve한 imported @px.component를 flow.node(...) target으로 배치할 수 있습니다. Component placement는 exact installed declaration과 Project scope를 사용하며 자동 탐색하지 않습니다. 계획된 decorator 기반 record 문법은 contract_only typed schema이고 현재 collection은 지원되는 원소 annotation의 list[T]를 사용합니다. 현재 record schema 문법은 Python SDK 문법이 소유합니다. flow.connect(...)가 배치된 Node의 exact result와 input을 연결합니다.
Component Node bridge는 exact installed declaration을 host-owned component.declarative@2 registry로 투영합니다. 외부 data·artifact·codec·standalone app surface를 연결할 때만 SDK Adapter 체계를 사용합니다. Flow 실행 의미는 PXFLOW가, Report 작성과 public port mapping은 Report가 소유합니다. V2 settings는 component-declared-settings@1이 소유하고 rich UI는 RFC-016의 component-rich-surface-declaration@1이 소유합니다.
따라서 사용자는 Studio용, Component용, AI용 Flow를 따로 만들지 않습니다. Component는 같은 Flow input·result 계약을 사용합니다.
사용자가 하는 일과 기술 객체의 관계
| 사용자가 하는 일 | 화면에서 찾는 곳 | 구현 문서에서 보는 이름 |
|---|---|---|
| 재사용할 계산 기능 만들기 | Definitions → Functions | FunctionDescriptor |
| Component target 추가하기 | Components dock | SDK의 @px.component와 ComponentDescriptor; exact resolver 성공 시 host projection, 실패 시 unsupported |
| Node를 놓고 연결해 계산 흐름 만들기 | PXFLOW Studio Canvas | FlowDocument |
| Component package에서 기능 고르기 | Components → Installed | installed Component catalog; local signature는 없거나 아직 검증되지 않았을 수 있음 |
| Report 값·표를 Flow에 연결하기 | Report Workbench → @ Insert · PXFLOW | ReportFlowConnection |
| Flow result를 Report에 표시하기 | Report Workbench → result 위치 → @ Insert · PXFLOW | ReportFlowConnection.resultMappings |
| 계산 실행과 저장된 결과 확인하기 | Run·Result, Project Activity | Run, ResultSnapshot |
| 읽기 전용 결과를 외부에 전달하기 | Share → Publish / Embed | Publication, EmbedDelivery |
아래 표는 이 동작을 SDK·API·저장소 수준에서 구현할 때 필요한 객체를 설명합니다. 객체 이름 자체를 화면에서 찾아 편집하는 것이 아니라, 마지막 열의 화면 동작으로 만들거나 확인합니다.
core 객체
첫 열의 객체명을 누르면 SDK·CLI·API에서 만드는 방법과 제품 화면에서 보이는 형태를 함께 설명하는 전용 위치로 이동합니다. 아래 마지막 열은 raw 객체를 편집하는 관리 화면이 아니라, 사용자가 실제로 선언·생성하는 동작과 확인하는 화면을 구분합니다. Runtime·control plane이 만드는 객체는 실제 생성 command를 보여 주며, 기존 기록을 덮어쓰지 않습니다.
예를 들어 FunctionDescriptor 링크는 Flow 화면 설명만 여는 링크가 아닙니다. 이동한 한 절에서 @px.function으로 Function을 정의하는 코드, flow.node(...)로 현재 Flow에 배치하는 코드, Definitions → Functions에서 확인하는 위치와 Canvas의 Function Reference Node를 순서대로 볼 수 있습니다. 다른 객체 링크도 같은 원칙을 따릅니다. 단, Run·Publication처럼 SDK decorator로 선언하지 않는 기록은 실제 Run 버튼·CLI·application command와 확인 화면을 함께 설명합니다.
작성하고 편집하는 객체
| 객체 | SDK·명령 → 제품 화면 | 무엇을 저장하는가 |
|---|---|---|
FunctionDescriptor | @px.function → build/materialize → Definitions → Functions → flow.node(...) 또는 Place Node로 Function Reference Node 배치 | 재사용 Function의 version·typed input/result·실행 계약. exact package/registry identity가 소유 |
ComponentDescriptor | @px.component companion symbol → installed release resolve → flow.node(...)로 Node 배치 | 현재 SDK가 생성하는 label·description·category와 typed input/result metadata. setting·presentation·executor는 포함하지 않으며 decorator에서 package declaration/executor로 만드는 bridge도 아직 없음 |
FlowDocument | flow = px.Flow(...) 또는 New Flow → 같은 Flow를 PXFLOW Studio에서 열어 Validate·Save·Run | Flow input/result, Node, connection, Group과 presentation. .pxflow에 저장 |
FlowGroup | flow.group(...) 또는 Canvas Group selection → editable Subflow · Group | 같은 Flow의 member nodeKey 목록. flow.groups에 저장되며 멤버의 실행 관계를 유지 |
ReportDocument | px.Report(...) 또는 Report Workbench의 New Report → report.save() 또는 Save | Report structure와 Flow connection. .pxreport에 저장 |
ReportFlowConnection | report.connect_flow(...) 또는 Workbench의 Connected Flows → Add Flow | exact Flow revision, input source mapping과 result target mapping. .pxreport.flowConnections에 저장 |
연결하고 실행할 때 생기는 객체
| 객체 | SDK·명령 → 제품 화면 | 무엇을 저장하는가 |
|---|---|---|
SemanticTarget family | SDK symbol·port binding → AI plan·breadcrumb에서 exact target 확인 | Flow·Node·input/result를 찾는 semantic 주소. 별도 편집 객체가 아님 |
Run | Studio Run 또는 px.Client(workspace=..., project=...)의 client.run(flow, **inputs) / client.run(connection) → Run·Result / Project Activity | pinned Flow revision·input digest·상태·audit. runtime ledger가 생성 |
ResultSnapshot | usable result가 있고 snapshot assembly가 완료된 terminal Run이 생성 → Result panel에서 선택·근거 확인 | 변경되지 않는 typed result와 provenance. Succeeded뿐 아니라 usable partial result도 가능하며 object store/CAS와 ledger가 소유 |
Diagnostic | SDK px.InputError, Validate 또는 Runtime issue → Node·연결·문서 위치의 inline issue와 Run detail | code·path·expected/current·복구 동작을 담는 response/event. 사용자가 직접 저장하지 않음 |
Component와 Extension별 객체
현재 V1 Component container reader와 내부 fixture는 미리 작성한 declaration·Python executor bytes를 읽고 형식 호환성을 검사할 수 있습니다. 이 internal/test wire probe는 production 설치 또는 실행 권한이 아닙니다. 현재 installer는 trust authority 없이 signed Component를 기록하지 않으며, 명시적으로 수용한 unsigned container만 absent·not-checked로 저장합니다. 이 저장 evidence도 install admission이 아닙니다. authorization·execution-trust P0가 닫힐 때까지 production caller는 third-party Component install·run 경로를 노출하거나 호출하지 않습니다. 전용 editor 문서와 artifact, rich renderer를 Component V2 package contribution으로 열지 않습니다. rich surface는 RFC-016의 component-rich-surface-declaration@1이 소유합니다. Marketplace에서 publisher signature와 revocation을 실제로 검증한 경우에만 이를 verified release라고 부릅니다.
계획 중인 전달 기능 · V2
| 객체 | 목표 명령 → 목표 화면 | 무엇을 저장하는가 |
|---|---|---|
Publication | pxlab publication ... 또는 Share → Publish | V2 계획: 읽기 전용 게시 단위와 현재 활성 version |
PublicationVersion | publication publish 또는 Publish version → version history | exact Flow revision·공개 결과·dependency를 고정한 변경 불가능한 전달본 |
DeploymentRevision | @px.app/Builder → Deploy request → deployment history | V2 계획: 검증된 PXFLOW App 배포 상태와 immutable revision |
EmbedDelivery | pxlab embed plan/apply 또는 Share → Embed | exact Publication Version 또는 Deployment Revision, 접근 방식과 허용 site |
execution target, Node와 Report mapping
- Project가 소유하는 Python 계산도 explicit stable key가 있는
@px.function(key=...)으로 정의합니다.@px.function은 Function,@px.component는 Component를 정의합니다. flow.node(...)는 Function target과 명시적으로 resolve한 exact Component target을 배치합니다. Component reader는 production host의 installed-presentation resolver가 같은 target을 찾으면 host-ownedcomponent.declarative@2로 투영하고, 찾지 못하면 read-only unsupported로 보존합니다.- 별도 module이 export한 Flow는
flow.subflow(...)로 배치하며 현재 Flow에서는 읽기 전용 nested Canvas로 엽니다. - Group은 같은 Flow의 기존 Node를 접어 탐색·편집하는 membership이며 target, 실행 Node나 독립 Flow가 아닙니다.
- Report source와 result 위치는 Flow의 public input/result에만 연결하며
.pxreport가 mapping을 소유합니다. - Python local variable은 target·Node·mapping의 identity가 아닙니다.
| SDK source | Flow 구성 문법 | Studio 표현 | 편집 원본 |
|---|---|---|---|
Project 또는 package의 @px.function(key=...) | flow.node("key", function_target) | Function Reference Node | Project Definitions 또는 package의 Function 원본; Node에서는 읽기 전용 |
imported @px.component · explicit resolver 경로 | flow.node("key", component) | exact resolver 성공 시 host declarative Node, 실패 시 read-only unsupported | exact target/settings와 installed declaration; Canvas는 host-owned projection only |
imported px.Flow object | flow.subflow("key", imported_flow) | Subflow · External reference | 현재 Flow에서는 읽기 전용, Edit source Flow로 원본 이동 |
| 같은 Flow의 기존 Node | flow.group("key", members=[...]) | Subflow · Group | nested Canvas에서 멤버 Node를 직접 편집 |
current internal/test compatibility primitive에서는 imported @px.component target의 flow.node(..., settings={...})가 그 placement의 raw instance setting object를 저장할 수 있습니다. 이는 production third-party 절차가 아니며 production reader는 이미 저장된 raw settings만 round-trip합니다. 현재 ComponentDescriptor는 setting schema를 선언하거나 이 값을 검증하지 않습니다. @px.function placement에는 instance setting을 만들지 않습니다. SDK의 flow.connect(...) 한 호출은 Studio의 result port → input port 연결 한 개에 대응합니다.
Report는 독립 authoring root이며 .pxreport로 저장합니다. production Flow reader는 host가 명시적으로 연결한 installed declaration resolver를 사용하며, 자동 package 탐색은 하지 않습니다. Report는 materialize된 Flow public port 계약만 참조합니다.
Component package manual은 현재 template schema나 application 동작을 정의할 수 없습니다. Component template과 packTemplate은 별도 versioned settings/template contract, RFC-014와 Project/trust P0 closure 전까지 예약된 후속 용어입니다. Canvas에는 새 package target을 배치하지 않으며, 이미 저장된 exact @px.component target만 unsupported Node로 나타납니다.
host Component Node projection
명시적 resolution 경계
다음 bridge는 production에 구현돼 있습니다. exact installed declaration을 resolver가 제공하지 못하면 reader는 기존 unsupported projection으로 되돌아갑니다.
exact ComponentRef
→ admitted installed declaration
→ host component.declarative@2 registry
└─ host-owned declarative Canvas bodynode-presentation V2는 이 host-declarative Canvas body까지만 소유합니다. settings를 component-declared-settings@1로 선언당 최대 8개까지 받고 host control registry가 그립니다. rich editor의 field·entry·message shape는 RFC-016의 component-rich-surface-declaration@1이 정의합니다. core host는 특정 Component package 이름을 제품 route나 App Surface format으로 hard-code하지 않습니다. Standalone app surface, data source, artifact codec 같은 contribution만 별도 Adapter category를 사용합니다.
Report와 Flow의 public boundary mapping
이 mapping은 Flow의 Canvas 연결과 다른 저장 객체입니다. flow.connect(...)는 Flow 내부 port-to-port 관계를, .pxreport.flowConnections는 Report와 public port의 관계를 소유합니다. 정확한 schema와 실행 규칙은 Report와 Flow 공개 포트 연결을 따릅니다.
Report를 편집하는 방식
| 모드 | 편집 원본 | Report Workbench에서 저장할 때 |
|---|---|---|
reportNative | .pxreport direct object | typed Report command로 새 revision 저장 |
readOnly | pinned Report revision/package | 변경 불가; 명시적 사본 생성 가능 |
Report mapping을 저장할 때 SDK-linked Flow source나 PXFLOW-native .pxflow를 수정하지 않습니다. Flow public port 계약이 바뀌면 새 Flow revision과 연결된 Report의 영향 범위를 함께 검토합니다.
Component rich editing 경계
현재 production Flow reader와 후속 V2에는 Component rich editor가 없습니다. V2 settings를 component-declared-settings@1로 선언당 최대 8개까지 받고 host control registry가 그립니다. rich editing의 entry와 message shape는 RFC-016의 component-rich-surface-declaration@1이 소유하며, package manual이나 ComponentDescriptor가 그 mode나 command를 정의하지 않습니다.
Flow를 편집하는 방식
Flow를 여는 방식에 따라 편집 원본이 정해집니다. 같은 Flow에 서로 다른 원본 두 개를 만들지 않습니다.
| 모드 | 편집 원본 | Studio에서 저장할 때 |
|---|---|---|
sdkLinked | Python SDK source + lock | source-safe diff를 Apply한 뒤 rematerialize |
pxflowNative | .pxflow direct object | typed Flow edit command를 revision으로 저장 |
readOnly | pinned revision/package | 변경 불가; 명시적 사본 생성 가능 |
SDK로 작성한 Flow와 Studio에 보이는 같은 Flow를 Recent에서 두 개의 문서처럼 표시하지 않습니다. 하나의 Flow 항목에서 Python 원본과 마지막 저장 상태를 함께 확인합니다.
실행할 때 저장 상태가 고정됩니다
Run을 시작하면 현재 Flow와 입력을 변경할 수 없는 revision으로 고정합니다. 실행 도중 캔버스나 Python 파일을 수정해도 이미 시작한 Run의 계산 내용은 바뀌지 않습니다.
저장된 Node position presentation은 direct object의 일부이므로 semanticDigest에는 포함되지만 executionDigest에는 포함하지 않습니다. 여기서 presentation.position은 의미 경로를 설명하는 이름이며 exact physical nesting을 뜻하지 않습니다. 그 위치는 RFC-001 schema가 승인하기 전까지 고정하지 않습니다. viewport, selection과 panel open state는 artifact에 저장하지 않으며 어느 digest에도 넣지 않습니다.
화면 표시와 저장 데이터는 다릅니다
다음 항목은 같은 계산 구조를 보여 주거나 전달하는 방법이며, Flow의 별도 복사본이 아닙니다.
- Studio 캔버스의 Node와 연결선
- Report Workbench의 public port 연결 표시와 팝오버
- SDK가 보여 주는 Python 객체
- MCP 응답과 AI에 전달되는 작업 문맥
화면 표시를 다시 해석해 Flow를 복원하지 않습니다. 모든 화면은 저장된 같은 Flow와 resolved target 설명을 읽습니다.
공유·게시·외부 삽입
같은 PXFLOW를 전달하는 방법도 사용 목적에 따라 분리합니다.
PXFLOW immutable revision
├─ Share → 권한이 있는 사람이 같은 원본을 계속 조회
├─ Publication Version → 바뀌지 않는 읽기 전용 PXFLOW Viewer
│ └─ View Embed → 외부 HTML의 읽기 전용 iframe
└─ App Candidate → Deployment Revision
└─ App Embed → 외부 HTML의 입력·실행 화면Publication은 항상 읽기 전용입니다. 새 실행 가능한 외부 화면은 Active Deployment Revision을 고정하고 이후 명시적으로 전환하기 전까지 그 exact servable revision을 사용합니다. EmbedDelivery.target.kind가 두 화면을 구분하므로 별도의 readOnly, runnable 또는 mode 값을 중복 저장하지 않습니다.
공유 URL, token, ACL, 허용 사이트와 게시·배포 상태는 .pxflow에 들어가지 않습니다. 자세한 필드와 상태 규칙은 게시·Embed 전달 계약을 따릅니다.
Flow·Project 템플릿으로 새 작업 만들기
템플릿은 같은 원본을 함께 편집하는 Share와 다릅니다. 이 V2 계획은 exact Flow 또는 Project source를 TemplateRelease로 고정하고, 사용 권리가 확인되면 새 identity와 lineage를 가진 Flow/Project를 만드는 경계만 다룹니다. publication-sharing profile은 availability: contract_only이고 TemplateRelease의 전체 persisted shape도 아직 blocker이므로, 아래 동선은 현재 활성 기능이나 승인된 serialization을 뜻하지 않습니다.
목록에 보임, 무료·유료 획득, 조직 배정, 승인과 destination 생성 권한은 각각 따로 판정합니다. 가격·주문·조직 배정은 .pxflow, .pxproject와 SDK 문법에 저장하지 않습니다.
profile의 packTemplate row는 미래 vocabulary 예약일 뿐 현재 Component template target이 아닙니다. settings/template application, renderer·preview asset, install 또는 execution을 열지 않습니다. 후속 Component template은 별도 versioned settings/template contract와 RFC-014 admission을 승인하고 exact ProjectScope isolation과 execution-trust P0를 모두 닫은 뒤 새 contract version으로 정의해야 합니다.
자세한 사용 흐름과 정확한 객체·상태는 Template Marketplace·Organization Library 계약을, Component 후속 경계는 Component container V2와 서드파티 Node UI를 따릅니다.