본문으로 건너뛰기

기능별 사용 위치

현재 Component surface 경계

현재 @px.component는 companion metadata와 annotation-derived input/result를 등록합니다. Flow reader의 기본 projection은 exact target/settings를 read-only 지원 불가 상태로 보존합니다. production host의 명시적 component presentation resolver가 exact installed declaration을 찾으면 host-owned component.declarative@2 projection으로 승격하고, 찾지 못하거나 declaration이 잘못됐으면 지원 불가 상태를 유지합니다. package UI는 Canvas에 마운트하지 않으며 settings는 component-declared-settings@1이, rich surface는 RFC-016의 component-rich-surface-declaration@1이 소유합니다. signed/verified라는 표현은 RFC-005 검증 기록이 있는 marketplace release에만 씁니다.

Normative surface registries

아래 두 목록은 생성 계약과 양방향으로 검사하는 public surface registry입니다. 항목은 이 문서의 다른 예제를 대체하지 않으며, 계약에만 있거나 이 목록에만 있는 이름을 허용하지 않습니다.

MCP Tool registry: project_search, report_search, report_describe, pxflow_search, pxflow_describe, function_search, function_describe, component_search, component_describe, report_plan_change, report_apply_change, function_validate_change, function_plan_change, function_apply_change, pxflow_validate, pxflow_plan_change, pxflow_apply_change, pxflow_run, run_get, run_cancel, result_read.

Python grammar registry: px.Flow, flow.input, flow.node, flow.connect, flow.result, flow.group, flow.subflow, flow.preview_html, px.function, px.component, px.loads, px.dumps, px.Report, px.Report.open, report.section, section.text, section.value, section.table, table.select, section.result_slot, section.result_table, section.artifact_slot, section.attachment, report.connect_flow, report.connection, connection.bind, connection.show, connection.remove_mapping, report.move, report.remove, report.remove_connection, report.save, report.plan_pages, report.export_pdf, report.preview_html, px.Client, client.create_project, client.search_catalog, client.save, client.open_report, client.run, client.run_many, client.run_batch, report.block, report.result_slot, report.document, block.to_dict, block.replace, block.set_value, block.select, block.insert_result, selection.format, selection.as_value, client.export_documents, px.ReportDocument, px.ReportDocument.from_wire, document.to_dict, report.settings, report.set_settings, client.import_documents, px.DocumentAnalysis, px.DocumentAnalysis.from_wire, analysis.to_dict, analysis.citation, px.DocumentCitation, px.DocumentCitation.from_wire, citation.to_dict, citation.resolve, px.DocumentTranslation, px.DocumentTranslation.from_wire, translation.to_dict, translation.resolve, client.retain_document, client.document_job, client.cancel_document_job, client.review_document_job, client.apply_document_result, client.document_application, client.resume_document_application, client.submit_document_job, client.document_submission, client.document_job_result, px.DocumentTranslatedPdf, px.DocumentTranslatedPdf.from_wire, translated_pdf.to_dict, translated_pdf.resolve, client.retain_translated_pdf, px.ProjectPdfFiles, pdf_files.read, pdf_files.list, pdf_files.remember, pdf_files.import_pdf, pdf_files.open_pdf, report.table, table.cell, table.set_cell, selection.read, selection.replace, client.read_report, client.read_attachment, report.capture_context, report.apply_edits, attachment.capture, run.read_result, px.Artifact.from_bytes, flow.viewer, client.plan_flow_change, client.apply_flow_change, client.search_functions, client.describe_function, client.plan_function_source_change, client.apply_function_change, client.read_flow_input_draft, client.save_flow_input_draft, client.get_run, run.read_inputs.

Project Function, Report와 Flow는 같은 Project에서 함께 사용하며 각각의 authoring owner와 revision 경계를 가집니다.

text
Project
├─ Function source · Python SDK 또는 Definitions에서 작성
├─ Report (.pxreport) · Report Workbench 또는 Python SDK에서 작성·연결
└─ Flow   (.pxflow)   · PXFLOW Studio 또는 Python SDK에서 작성

Flow 작성: 같은 의미, 다른 조작 방식

Flow는 PXFLOW Studio에서 직접 만들거나 Python SDK에서 작성합니다. 선택한 authoring owner가 Flow의 public boundary, Node와 내부 연결을 저장합니다.

일반 Python 예제의 public client는 client = px.Client(workspace="structural_team", project="bridge_design")로 만듭니다. hosted surface를 포함한 current public client도 Workspace와 Project를 명시합니다. lowercase px.client()는 host scope 주입을 검토할 후속 계약에 예약돼 있으며 현재 facade에는 없습니다.

현재 Function·Component input은 일반 Python parameter annotation, 이름 있는 result는 px.Results subclass의 annotated field로 선언하고 px.input·px.result marker가 그 선언부에 description·unit을 더합니다. 계획된 record decorator, px.Table, px.Artifact는 current executable grammar가 아니라 별도 계약으로 보존한 계획 이름입니다.

의도Python SDKPXFLOW StudioMCP/LLM
Project Function 만들기@px.function(key=..., version=...)Definitions → Functions → New Functionfunction_validate_change → plan/apply
Project Function 새 버전 만들기같은 key와 새 version으로 source 변경Function → EditCreateFunctionVersion plan/apply
특정 Node만 다른 Function으로 분기key@px.function을 만들고 해당 flow.node(...) target 변경Function → Branch for this NodeBranchProjectFunction + ReplaceNodeTarget
설치된 Component 찾기public module importComponents dock 검색 · 계획dependency evidence + component describe · 계획
Component 정의@px.component(key=...) companion metadataexact resolver 성공 시 host declarative Node, 아니면 read-only 지원 불가resolved Component contract 설명
Function 찾기·계약 확인exact FunctionRef 사용Definitions → Functionsfunction_searchfunction_describe
public input 추가flow.input(...)Flow interface input 추가plan/apply public input command
Node 배치flow.node("node_key", target)Place Node / Addplan/apply AddNode
Node 연결flow.connect(...)result port → input portplan/apply ConnectInput
public result 추가flow.result(...)Flow interface result 추가plan/apply public result command
Group 만들기flow.group(...)drag-select → Group selectionplan/apply AddGroup
외부 Flow 배치flow.subflow(...)Canvas Add → External Flowplan/apply AddExternalSubflow
Component setting 저장flow.node(..., settings={...}) raw object현재 schema 없는 opaque settings 보존; Settings UI는 계획plan/apply SetNodeSetting · 계획
검증SDK validatorValidatepxflow_validate
저장materialize/buildSaveapproved apply
Flow 직접 실행client.run(flow, **inputs)Runpxflow_run
결과 읽기named resultResult panelresult_read

SDK-linked Flow의 Studio 변경은 source-safe diff를 거쳐 Python source로 반영합니다. PXFLOW-native Flow의 Studio 변경은 .pxflow revision으로 저장합니다.

Report와 Flow 연결

Report 작성값과 결과 위치는 Report Workbench 또는 Python SDK에서 편집합니다. 두 경로는 같은 typed Report command를 적용하고 .pxreport revision을 저장합니다. Flow는 연결 가능한 public input/result를 공개합니다.

Python 열은 report = px.Report(...)로 만든 Report 객체, summary = report.section(...)으로 받은 Section handle, connection = report.connect_flow(...)으로 받은 Connected Flow handle, client = px.Client(workspace=..., project=...)로 만든 Client 객체를 기준으로 읽습니다.

의도Python SDKReport Workbench저장 객체MCP/LLM
Report 시작report = px.Report(...)New ReportReportDocument draftCreateReport
저장된 Report 열기px.Report.open(...)Project에서 Report 열기exact base revision을 고정한 draftreport_describe 후 exact target으로 plan
section·text 작성summary = report.section(...)summary.text(...)본문 작성blocks[]InsertReportBlock
작성값·표 만들기Section handle의 .value(), .table()값·표 삽입typed block/tableUpsertReportValue / UpsertReportTable
result 위치 만들기Section handle의 .result_slot()@ Insert → Result positionnamed result slotInsertReportResultSlot
Connected Flow 추가connection = report.connect_flow(...)Connected Flows → Add FlowflowConnections[]AddReportFlowConnection
Report 작성값 → Flow inputConnected Flow handle의 .bind(..., to=...)값 선택 → Use report inputinputMappings[]SetReportFlowInputSource
Flow result → Report 위치Connected Flow handle의 .show(..., at=...)표시 위치 → Show resultresultMappings[]SetReportFlowResultTarget
Report 항목 이동report.move(...)block drag/reorder같은 stable key의 parent/order 변경MoveReportBlock
Report 항목 제거report.remove(...)block Delete영향 검토 후 block 제거RemoveReportBlock
input/result mapping 제거connection.remove_mapping(...)connection Removeexact mapping 제거RemoveReportFlowMapping
Connected Flow 제거report.remove_connection(...)Connected Flow Removeconnection과 mapping 영향 검토RemoveReportFlowConnection
Report 저장Report 객체의 .save()Save.pxreport revisionapproved Report apply
연결 실행Client 객체의 .run(connection)Run this Flowordinary Flow RunRunReportFlowConnection
여러 연결 실행client.run_many([...])Run selected독립 ordinary Run 목록connection별 run command
scalar case 묶음 실행client.run_batch(...)Batch Runordinary child Run 묶음RunReportFlowBatch
결과 확인returned Run·Result handleReport result position / Activityimmutable Result projectionrun_get / result_read

flow.connect(...)는 현재 Flow 안의 port-to-port 연결을 나타냅니다. Report의 inputMappingsresultMappings는 Flow 바깥의 public boundary를 사용하며 .pxreport에 저장됩니다.

client.run(flow, **inputs)는 Report 연결 없이 Flow를 바로 실행하며 호출자가 public input을 전달합니다. client.run(connection)은 저장한 Report connection의 input mapping을 사용하고 Result를 연결된 Report 위치에 표시합니다. 두 호출 모두 같은 ordinary Flow Run을 만들며, 입력과 결과 위치를 어디서 가져오는지만 다릅니다.

표와 여러 case

Report sourceFlow input실행 의미
scalar 하나scalarordinary Flow Run 1회
여러 행의 fieldList<T>list 하나로 ordinary Flow Run 1회
여러 행과 fieldTable<Record>table 하나로 ordinary Flow Run 1회
여러 scalar caseexplicit Batch Run검토한 case 수만큼 실행

Report selection 자체는 실행 수를 결정하지 않습니다. Collection은 typed value 하나로 전달하고, scalar 반복은 Batch Run plan에서 실행 수와 result merge를 확인합니다.

계획된 V2 host Component surface도 Core Flow 규칙 사용

Python package/distribution은 Component symbol을 하나 이상 export할 수 있습니다. 별도의 portable V1 Component container는 declaration 하나만 받습니다. 아래 dock 동선은 V2 host-declarative discovery가 구현된 뒤 사용할 목표 계약입니다.

의도Component package SDKPXFLOW StudioMCP/LLM
Component package 추가pxlab dependency add <distribution>@<range> · 계획Project dependencies → Add · 계획dependency plan/apply · 계획
Component 찾기public @px.component importComponents → Installed · 계획component search/describe · 계획
Component 배치flow.node(..., component)명시적 installed resolver가 exact target을 찾으면 host declarative Node, 아니면 read-only 지원 불가일반 AddNode
값 연결flow.connect(...)일반 result → input 연결일반 ConnectInput
Node 상세 확인host-owned component.declarative@2exact identity·Port 확인일반 component describe
settings@px.component(..., settings=...) 선언 · 선언당 최대 8개host control registry가 그리는 control미제공
rich surfacecomponent-rich-surface-declaration@1 선언RFC-016이 소유하는 격리 editor미제공
artifact 만들기Component result contract같은 Flow Run일반 pxflow_run

Component rich editor 내부 command나 block schema는 이 V2에서 package가 소유하지 않습니다. field·entry·message는 RFC-016의 component-rich-surface-declaration@1이 정의하고, command shape는 열지 않으며 Core Flow command에 package 이름과 전용 block 종류를 추가하지 않습니다.

Project Function command

이 절이 Project Function write command 이름의 정식 정의입니다. Project가 소유한 @px.function(key=..., version=...) source만 이 command로 작성합니다. 설치한 dependency package의 Function과 Component source는 consumer Project에서 읽기 전용이며, 변경하려면 해당 package의 owning source와 release 절차로 이동합니다.

kind필수 payload정확한 의미
CreateProjectFunctionProject scope, complete typed Function draftfunctionKey와 첫 immutable version 생성
CreateFunctionVersionexact base FunctionRef, 같은 functionKey의 새 version draft, referencePolicy: "all_current_usages"기존 version을 보존하고 새 immutable version 후보와 모든 현재 사용처 갱신을 함께 계획
BranchProjectFunctionexact base FunctionRef, 새 functionKey와 첫 version draft기존 Function을 보존한 채 독립적으로 편집할 Project Function 생성

Function draft는 explicit functionKey, 새 version, description, typed input/result contract와 decorator에 결합된 완전한 구현 후보를 담습니다. line-based patch는 payload가 아닙니다. CreateFunctionVersion은 같은 Project의 현재 editable head에서 해당 Function을 쓰는 모든 Node를 새 FunctionRef로 옮기는 정책만 지원합니다. 일부 Node만 다르게 만들 때는 BranchProjectFunction과 Core Flow의 ReplaceNodeTarget을 한 plan에 넣습니다.

Plan은 command 외에 derived reference update를 정확히 나열합니다.

  • old/new FunctionRef와 source-safe Python diff
  • 영향받는 flowKey·nodeKey, 각 새 Flow revision과 rematerialized semantic diff
  • 그 Flow revision을 pin한 Report connection과 승인 시 갱신될 Report revision
  • immutable history, published revision 또는 권한 때문에 갱신하지 않는 reference와 그 이유

Apply는 Function source, 새 Function version, 승인된 Node target, Flow revision과 Report connection reference를 하나의 multi-target transaction으로 확정합니다. 하나라도 stale이거나 권한·contract·source parity 검사를 통과하지 못하면 아무 target도 저장하지 않습니다. 기존 Function version과 기존 Flow·Report revision은 덮어쓰지 않습니다.

Source edit 위치는 explicit decorator key와 base source digest로 찾습니다. Python symbol 이름, 파일 순서 또는 label을 identity로 추측하지 않습니다. Apply는 syntax-aware diff를 적용한 뒤 Function과 영향받는 Flow를 다시 materialize하고 planned semantic contract와 같을 때만 새 revision을 확정합니다.

Core Flow command

Flow 변경 command의 discriminant는 다음 범위를 사용합니다.

text
CreateFlow
AddNode
RemoveNode
AddGroup
RemoveGroup
SetGroupMembers
SetGroupLabel
AddExternalSubflow
RemoveExternalSubflow
ReplaceNodeTarget
SetNodeSetting
ClearNodeSetting
AddFlowInput
UpdateFlowInput
RemoveFlowInput
AddFlowResult
UpdateFlowResult
RemoveFlowResult
ConnectInput
DisconnectInput
RenameSemanticKey
SetFlowMetadata
SetPresentation
SetResultViewer
RemoveResultViewer
kind필수 payload정확한 의미
CreateFlowdocument검증된 canonical direct document를 세대 0의 첫 revision과 head로 저장
AddNodenode완전한 direct Node 추가
RemoveNodenodeKey영향받는 binding·Group membership 검토 후 제거
AddGroupgroup기존 Node의 editable Group membership 추가
SetGroupMembersgroupKey, membersexact member nodeKey 집합 교체
AddExternalSubflowsubflowimported Flow의 exact external reference 추가
ReplaceNodeTargetnodeKey, target, preconditionexact target과 target-kind state 교체
SetNodeSettingnodeKey, settingKey, valuedescriptor schema에 맞는 setting 지정
ConnectInputnodeKey, portKey, bindingdestination input에 typed internal binding 설정
RenameSemanticKeytarget kind, current/new keykey와 모든 in-scope reference를 함께 변경
SetPresentationtarget key, position계산 Node의 Canvas 위치 변경; 실행 의미 유지
SetResultViewerviewerKey, viewerV2 public result viewer 전체 정의 추가/교체. renderer/results/position은 Flow V2 계약, V1의 첫 추가는 새 V2 revision
RemoveResultViewerviewerKey존재하는 viewer 하나 제거. 빈 V2 유지; Run·원본 파일은 삭제하지 않음

첫 저장은 새 Tool이나 Tool 밖 쓰기가 아니라 pxflow_plan_changepxflow_apply_changeCreateFlow 한 command입니다. 계획 대상은 project scope, CreateFlow document 안의 flowKey와 같은 flowKey, 그리고 검증된 canonical direct document의 byteDigest와 같은 revisionRef를 가져야 하며 expectedGeneration은 0입니다. Apply 성공은 같은 digest를 newRevisionRef로, 0을 newGeneration으로 반환합니다. 같은 flowKey의 head가 이미 있으면 FlowHeadAlreadyExists로 거부합니다. 이 규칙은 Flow·Report·Function 쓰기를 모두 plan→apply와 generation 검사 한 경로에 두어 생성 감사 기록이 별도 표면으로 갈라지지 않게 합니다.

Node target은 Project 또는 installed package가 소유한 FunctionRef나 ComponentRef의 exact reference를 사용합니다. Decorator 없는 Python helper는 target이 아니며 Canvas에 표시되지 않습니다. Function이 부르는 helper는 decorator의 helpers 선언으로 그 Function revision에 저장됩니다. Imported Flow는 external Subflow reference로 배치하고 Group은 같은 Flow의 기존 Node membership을 저장합니다.

Core Report command

Report Workbench, Python SDK와 AI/MCP는 같은 command family를 사용합니다.

kind의미
CreateReport이름·제목을 가진 ReportDocument draft 생성
SetReportMetadatatitle·description 같은 Report metadata 변경
InsertReportBlock이름 있는 section·text·result slot 삽입
UpdateReportBlockexisting block content·presentation 변경
MoveReportBlockstable block key를 유지하며 parent 또는 순서 변경
RemoveReportBlock영향 검토 후 block 제거
UpsertReportValuetyped authored value 추가·변경
UpsertReportTablestable row key와 field schema를 가진 table 추가·변경
SetReportTableCellsexact table·row·field 값 변경
UpsertReportAttachmentstable attachment key에 content digest·media type·size를 가진 파일 reference 추가·변경
InsertReportResultSlotscalar·Record·List result의 읽기 전용 표시 위치 추가
InsertReportResultTablestable row/field schema를 가진 읽기 전용 Table result 위치 추가
InsertReportArtifactSlot허용 media type을 가진 Artifact result 위치 추가
AddReportFlowConnectionexact Flow revision을 가리키는 Connected Flow 추가
SetReportFlowInputSourceReport source를 exact Flow public input에 지정
SetReportFlowResultTargetFlow public result를 Report destination에 지정
RemoveReportFlowMappingexact input/result mapping 제거
RemoveReportFlowConnectionconnection과 소유 mapping의 영향을 검토한 뒤 제거
SaveReportRevisionexpected revision을 검사하고 새 canonical .pxreport revision 저장
RunReportFlowConnection저장한 connection을 ordinary Flow Run으로 실행
RunReportFlowBatchstable caseKey별 ordinary child Run과 explicit result merge 실행

Report command는 Report block·field·slot과 Flow revisionRef·portKey를 사용합니다. Canvas Node key와 내부 edge를 Report mapping에 복제하지 않습니다. UpsertReportAttachmentsrc는 Run input payload와 같은 filesystem CAS가 발행한 RFC-002 PublicDigestRef이며, size는 그 CAS에 commit하기 위해 supervisor가 읽은 exact byte 수입니다. 로컬 source 경로는 Report command나 저장 revision에 들어가지 않습니다.

변경 내용 미리 보기와 적용

모든 의미 변경은 같은 순서를 사용합니다.

  • Plan은 변경되는 Report mapping 또는 Flow Node·binding과 진단을 보여 줍니다.
  • Apply는 expected revision과 generation을 다시 검사합니다.
  • 동시에 다른 변경이 저장되었으면 새 plan으로 현재 상태를 검토합니다.
  • Canvas 위치 같은 presentation edit와 실행 의미를 바꾸는 edit를 구분합니다.

SDK-linked Flow 편집

SDK가 authoring owner인 Flow는 semantic Flow command를 Python source-safe diff로 변환합니다.

Report command는 이 Flow source edit 경로를 사용하지 않습니다. Report Workbench, Python SDK와 AI/MCP가 같은 typed command를 canonical .pxreport revision에 적용합니다. Python에서 px.Report를 사용해도 Python source와 .pxreport가 동시에 수정 가능한 두 원본이 되지 않습니다.

모든 화면에서 지키는 원칙

  1. 사용자에게 보이는 이름은 같은 semantic key를 가리킵니다.
  2. Type, unit, shape와 nullability는 모든 surface에서 같은 계약을 사용합니다.
  3. Function/Component definition과 Canvas Node instance를 구분합니다.
  4. Report mapping과 Flow 내부 binding의 저장 owner를 구분합니다.
  5. Component는 Core Flow 계약을 사용하고 전용 실행 계층을 추가하지 않습니다.
  6. 결과는 immutable Result snapshot에서 읽습니다.
  7. 권한, capability와 approval은 server에서 다시 검사합니다.

이어서 보기

V2 viewer 편집의 참조 일관성

RenameSemanticKey에서 target kind를 flowResult로 지정하면 모든 viewer의 result key도 함께 바꿉니다. 참조된 public result를 제거하려면 같은 atomic command 묶음에서 해당 viewer binding을 수정하거나 제거해야 합니다. 최종 candidate가 유효하지 않으면 전체 Plan을 거절합니다. 기존 V1 revision/hash는 유지하며 SetPresentation의 대상 의미는 확대하지 않습니다.