Report a published node that has no code of its own

The store answers the new-node template when nothing was ever written for a
node, so such a node ran — returning {} on every call, reporting active and
ok, and saying nothing anywhere. Unreachable through `fluksio sync`, which
writes every body before it publishes; the editor end was open.

A run of a flow holding one is now refused, and the flow carries a
missing_source issue so it is visible before anybody runs it. A draft is
exempt: a node being written legitimately has no published body yet.

The generated client is regenerated for the new issue code, which also
catches up the drift left by earlier backend work (resources, code_digest,
idempotency_key).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-26 22:55:11 +02:00
co-authored by Claude Opus 5
parent 69fc0ceeb5
commit 4f3eaf950c
8 changed files with 275 additions and 8 deletions
+19
View File
@@ -317,6 +317,25 @@ def test_a_rate_limited_port_cannot_be_run_as_a_batch():
assert not batch_issues(double_flow())
def test_a_node_with_no_stored_code_cannot_be_run():
"""The store answers a template for one, and a template publishes nothing."""
class Store:
def __init__(self, *, written: bool):
self.written = written
def has_node_source(self, flow, node_id, draft=False):
return self.written
flow = double_flow()
(issue,) = batch_issues(flow, Store(written=False))
assert "no stored code" in issue
assert not batch_issues(flow, Store(written=True))
# A shared node runs the library's copy, so it is not this node's to have.
flow.nodes[0].source_ref = "shared"
assert not batch_issues(flow, Store(written=False))
def test_a_streaming_port_may_thin_itself_out():
flow = double_flow()
flow.nodes[0].provides = [spec("loss", interval=0.5, stream=True)]