feat(core): workflow abstraction update #2

Merged
fnoble merged 17 commits from feat/workflow into master 2026-08-25 12:46:51 +00:00
Owner
No description provided.
- add_edge gains into= for named-slot fan-in; recorded ops carry it
- rule 3b at import time: multi-parent targets must fit named-slot form
  (required fields covered exactly once, source output_type fits the slot)
  or collected form (exactly one list[<model>] field, arity within its
  min_length/max_length); humans stay single-parent; mixing static parents
  with conditional dispatch is rejected as ambiguous
- validation now builds once against a throwaway StateGraph; the recording-
  sink double-build determinism check is replaced by a static lint over
  build()'s source rejecting environment/clock/random reads, mutation of
  self or module globals, and iteration over sets
refactor(core): precise composite boundary agreement via START pseudo-source
Some checks failed
/ ci (push) Has been cancelled
/ ci (pull_request) Has been cancelled
0727ac3a60
Rule 4 now reuses rule 3b's machinery instead of a second type-checking
notion: entry edges treat START as a pseudo-source whose output_type is
the composite's input_type, so a plain entry edge only requires the child
to accept that input (issubclass) and an into= entry edge requires the
slot to exist and accept it. Terminals are checked with one issubclass
per terminal against the composite output, so early-exit paths may emit
subtypes but never unrelated models. START delivers the run input rather
than a state-keyed parent dump, so it never counts toward fan-in forms,
parent counts, or static/dispatch assembly ambiguity.
@ -449,0 +472,4 @@
source_output, source_desc = cls.input_type, "the composite input"
else:
source_output, source_desc = w.nodes[source].output_type, f"{source}.output_type"
if not (isinstance(source_output, type) and issubclass(source_output, ann)):
Author
Owner

This can be done with pydantic more cleanly

This can be done with pydantic more cleanly
Replace three hand-rolled model_fields/issubclass inspection sites
(_check_slot_fit, the START entry whole-input check, the terminal
output_type check in _check_topology) with one _accepts helper that
probes a TypeAdapter with an unvalidated source-model instance.

Widened coverage: scalar, literal, and union into= slots are now checked
at import time instead of silently skipped; slots that no model output
can satisfy fail at import rather than surfacing as runtime DataErrors.
Container annotations stay exempt: a model instance iterates its fields,
so pydantic would coerce it into list[...] even though the runtime port
delivers a dict; collected fan-in covers list slots structurally.

New tests: union slot fan-in passes; scalar slot mismatch fails.
main.sh runs deps, lint, test, build; each stage is also its own
standalone script. complexity.sh is advisory and ranks functions over
the cyclomatic ceiling (CX_THRESHOLD to override). fmt.sh exists but
stays out of main until the tree is formatted.
Checkout, install uv, then run scripts/main.sh so local and CI checks
stay identical.
Ceiling set above the current worst offender (_check_fanin, 20) so CI
is green now; tighten as the workflow.py linter functions get refactored.
chore: gate ruff format in main.sh now that tree is formatted
All checks were successful
CI / test (push) Successful in 33s
54132bce91
complexity-check.sh fails when any function exceeds the ceiling from
ruff.toml, or CX_THRESHOLD if set. The old report-only script becomes
complexity-audit.sh under scripts/util/.
Gating checks live in scripts/ci (deps, lint, complexity-check, test,
build), developer helpers in scripts/util (format, format-check,
complexity-audit). check.sh runs all checks, keeps going past failures,
prints a FAILED summary and exits nonzero; stage names can be passed to
run a subset. Adds ci/deps.sh and util/format.sh.
Run each CI check as its own step with always() and JUnit report
All checks were successful
CI / check (push) Successful in 27s
a747771f42
Each check is a separate step so the failing step is immediately
visible. Independent steps use if: always() so all failures show in one
run. Tests write test-report.xml, uploaded as an artifact.
fnoble force-pushed feat/workflow from a747771f42
All checks were successful
CI / check (push) Successful in 27s
to 30bea5036e
All checks were successful
CI / check (push) Successful in 19s
2026-08-25 12:27:44 +00:00
Compare
test(ci): restyle HTML report with a readable theme
All checks were successful
CI / check (push) Successful in 22s
144437c2d7
Merge remote-tracking branch 'origin/master' into feat/workflow
All checks were successful
CI / check (push) Successful in 21s
e1cb52c643
fnoble merged commit 4c7531575f into master 2026-08-25 12:46:51 +00:00
fnoble deleted branch feat/workflow 2026-08-25 12:46:52 +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
neurogenesis/ngen-weave!2
No description provided.