feat(11-A): schema additive — Span, SpanStatus, python_source, spans #15

Merged
timur merged 1 commit from feat/11-phase-a-schema-additive into development 2026-05-05 12:16:48 +00:00
Owner

Summary

Phase A of hero_logic#11. Schema-only, additive. Old DAG flows still work; new Python flows get their data model.

Added Purpose
SpanStatus enum pending|running|ok|failed|timed_out|cancelled — finer-grained than ExecutionStatus
Span type One row per flow.step / flow.span / instrumented RPC call
WorkflowVersion.python_source @flow-decorated source. Empty = DAG mode
Play.spans Span tree, populated incrementally from the per-Play socket
Play.parent_span_id When this play is a sub-flow, the parent span owning it

Nothing removed. Existing rows stay valid. Method count unchanged at 25 — new RPCs land in Phase C.

Phase plan (#11 split)

  • A — this PR — schema additive
  • B — hero_tracing.py SDK (decorator, step/span context, instrument, JSONL UDS protocol)
  • C — executor rewrite + 4 new RPCs + Tier 0 sandbox + SSE
  • D — migration tool + delete legacy DAG types/files

Each phase is independently mergeable. Old DAG path keeps running through C; D is the destructive removal.

Test plan

  • cargo build --workspace clean
  • cargo test --workspace --lib green
  • Generated openrpc.json contains Span, SpanStatus, Play.spans, Play.parent_span_id, WorkflowVersion.python_source
  • Existing DAG fields (Play.node_runs, WorkflowVersion.{nodes,edges}) still present

Implementation note

Array fields don't support = [] defaults in OSchema's parser (verified: parser rejects spans: [Span] = []), so Play.spans and Play.node_runs are listed without defaults — same convention as the existing tags: [str] and versions: [str] fields.

🤖 Generated with Claude Code

## Summary Phase A of hero_logic#11. Schema-only, additive. Old DAG flows still work; new Python flows get their data model. | Added | Purpose | |---|---| | `SpanStatus` enum | `pending\|running\|ok\|failed\|timed_out\|cancelled` — finer-grained than `ExecutionStatus` | | `Span` type | One row per `flow.step` / `flow.span` / instrumented RPC call | | `WorkflowVersion.python_source` | `@flow`-decorated source. Empty = DAG mode | | `Play.spans` | Span tree, populated incrementally from the per-Play socket | | `Play.parent_span_id` | When this play is a sub-flow, the parent span owning it | Nothing removed. Existing rows stay valid. Method count unchanged at 25 — new RPCs land in Phase C. ## Phase plan (#11 split) - **A — this PR** — schema additive - B — `hero_tracing.py` SDK (decorator, step/span context, instrument, JSONL UDS protocol) - C — executor rewrite + 4 new RPCs + Tier 0 sandbox + SSE - D — migration tool + delete legacy DAG types/files Each phase is independently mergeable. Old DAG path keeps running through C; D is the destructive removal. ## Test plan - [x] `cargo build --workspace` clean - [x] `cargo test --workspace --lib` green - [x] Generated `openrpc.json` contains `Span`, `SpanStatus`, `Play.spans`, `Play.parent_span_id`, `WorkflowVersion.python_source` - [x] Existing DAG fields (`Play.node_runs`, `WorkflowVersion.{nodes,edges}`) still present ## Implementation note Array fields don't support `= []` defaults in OSchema's parser (verified: parser rejects `spans: [Span] = []`), so `Play.spans` and `Play.node_runs` are listed without defaults — same convention as the existing `tags: [str]` and `versions: [str]` fields. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Phase A of hero_logic#11. Schema-only change. Adds the new Python-flow
execution model alongside the existing DAG model — nothing is removed,
existing rows stay valid, all existing CRUD methods continue to work.

Schema additions:

- SpanStatus enum (pending|running|ok|failed|timed_out|cancelled).
- Span type — span_id, parent_id, name, start_ms, end_ms, status, tags
  (JSON), logs, error, rpc_service, rpc_method, child_play_sid. Tags and
  logs default to empty so a minimally-decorated flow stays valid.
- WorkflowVersion.python_source — empty ⇒ DAG mode (existing path);
  populated ⇒ Python flow (Phase C). Coexists with nodes/edges so the
  same Workflow can hold both kinds of versions during migration.
- Play.spans — populated incrementally for python_source plays as the
  executor consumes JSONL events from the per-Play span socket.
- Play.parent_span_id — non-empty when this play is a sub-flow launched
  via play_run_async; the child's root span uses it as its parent so the
  parent flow's tree shows the sub-flow nested correctly.

Generated artifacts: types_generated.rs (+79 lines), types_wasm_generated.rs
(+68), openrpc.json (+87), osis_server_generated.rs (+46), JS SDK
types (+184). Method count unchanged at 25 — schema additive only,
no new RPC methods land here (those come in Phase C).

DAG types (Node, Edge, NodeRun, NodeType, ExecutionStatus,
EdgeCondition, NodeConfig, DataMapping, Mapping, NodeRunResult) stay
intact and used. They get deleted in Phase D once the executor + UI
have migrated.

Refs hero_logic#11 (Story 1: Foundation), hero_logic#10 (epic).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
timur merged commit cf2a6d85bd into development 2026-05-05 12:16:48 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
lhumina_code/hero_logic!15
No description provided.