feat(ports): typed Ports base classes, ADR-0044, BTND-03-009–011, validate_report pilot - #1827
Conversation
…idate_report pilot - Add DataLayerConditionWithPorts and DataLayerActionWithPorts to helpers.py - Import NoDataAvailable; narrow except clause to NoDataAvailable - Migrate 4 validate_report nodes to typed Ports base classes - Add ADR-0044 and update ADR index; add ADR to mkdocs nav - Add BTND-03-009 through BTND-03-011 to specs/behavior-tree-node-design.yaml (fix YAML with folded scalars for statements containing inline mappings) - Add 6-step migration recipe to notes/py-trees-ports-adoption.md - Add 25-test test_typed_ports.py covering base contracts and pilot nodes - Correct NoDataAvailable timing: surfaces in initialise(), not setup() Closes #1808 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…, ADR-0044, BTND-03-009–011, validate_report pilot Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…tialise(), not setup() - NoDataAvailable is raised by get_input() in initialise(), not by setup_ports() - 'Early error detection' means at the start of the first tick, not pre-tick - Initial BTND-03-011 spec and ADR-0044 both stated 'at setup time' — incorrect - Corrected before PR opened; recording here so future spec/test authors don't repeat the mistake Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
sei-ahouseholder
left a comment
There was a problem hiding this comment.
PR Triage — 1827
5 findings (all IMPROVE / fix-now); CI is still pending.
Phase 3 — PR Body Format
IMPROVE phase3-closes-at-bottom-0 — Closes #1808 is at the bottom of the body (before the Claude footer). The PR body guide requires closing references at the top of the body, one per bullet line, before ## Summary.
IMPROVE phase3-pr-body-missing-changes-section-0 — The body uses ### What changed (a sub-heading under ## Summary) rather than the template's standalone ## Changes section.
Phase 9 — Notes Currency
IMPROVE phase9-notes-status-draft-0 — notes/py-trees-ports-adoption.md still has status: draft. The implementation is complete (not just planned), so the status should advance to status: active.
notes/py-trees-ports-adoption.mdline 3
Phase 10 — Test Coverage
IMPROVE phase10-sender-actor-id-untested-0 — CheckRMStateValid and CheckRMStateReceivedOrInvalid both accept sender_actor_id which overrides the blackboard actor_id (ADR-0022 single-BT pattern). No test exercises this branch — the path self.sender_actor_id if self.sender_actor_id else self.actor_id is only tested with sender_actor_id=None (default).
test/core/behaviors/report/nodes/test_typed_ports.pytest classTestCheckRMStateValidPorts- Fix: add a BTTestScenario test passing a non-None
sender_actor_idthat differs from the blackboardactor_id.
IMPROVE phase10-transition-rm-failure-untested-0 — TransitionRMtoValid has only one happy-path test. The _require_datalayer() FAILURE guard and the actor_id is None check have no test coverage.
test/core/behaviors/report/nodes/test_typed_ports.pyclassTestTransitionRMtoValidPorts- Fix: add a test that runs
TransitionRMtoValidwithoutdatalayeron the blackboard and asserts FAILURE.
Not findings
- Legacy
DataLayerCondition/DataLayerActionnodes remaining inconditions.pyandrm_transitions.py(e.g.EvaluateReportCredibility,TransitionRMtoInvalid) are pre-existing nodes — BTND-03-009 says "new BT nodes" so the full sweep is correctly scoped to follow-on #1809. ✅ behavior-tree-integration.yamlnot updated — BTBridge still writes the same flat keys; only the reading mechanism changed. AC-3 qualifier "where the bridge/blackboard contract changes" is satisfied by no change needed. ✅- Test count accurate: 25 new tests in
test_typed_ports.py, 618 total in the tested subdirectories. ✅ - Co-authored-by trailers present in all 3 commits. ✅
- ADR-0044 format, mkdocs nav, and spec entries all correct. ✅
CI
All linters (black, flake8, mypy, pyright) and CodeQL passed. Tests, docs-build, and demo integration are still pending.
- phase3-closes-at-bottom-0 — moved Closes #1808 to top of PR body as bullet - phase3-pr-body-missing-changes-section-0 — renamed ### What changed to ## Changes (top-level) - phase9-notes-status-draft-0 — advanced notes/py-trees-ports-adoption.md status draft → active - phase10-sender-actor-id-untested-0 — added sender_actor_id ADR-0022 path test for CheckRMStateValid - phase10-transition-rm-failure-untested-0 — added FAILURE guard path test for TransitionRMtoValid Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
sei-ahouseholder
left a comment
There was a problem hiding this comment.
PR Execute — 1827
All 5 triage findings resolved. CI green. Tests passing.
Findings addressed (commit 07e3ca81)
| ID | Outcome | Notes |
|---|---|---|
phase3-closes-at-bottom-0 |
✅ fixed | Moved - Closes #1808 to the first line of the PR body |
phase3-pr-body-missing-changes-section-0 |
✅ fixed | Renamed ### What changed → ## Changes (top-level) |
phase5-btnd03009-legacy-nodes-conditions-0 |
✅ no change needed | BTND-03-009 scopes to "new BT nodes"; pre-existing nodes → follow-on #1809 |
phase5-btnd03009-legacy-nodes-rm-0 |
✅ no change needed | Same — pre-existing nodes deferred to #1809 |
phase10-sender-actor-id-untested-0 |
✅ fixed | Added test_sender_actor_id_checked_instead_of_blackboard_actor (ADR-0022 path) |
phase10-transition-rm-failure-untested-0 |
✅ fixed | Added test_failure_when_datalayer_not_available (FAILURE guard path) |
phase9-notes-status-draft-0 |
✅ fixed | notes/py-trees-ports-adoption.md status: draft → active |
CI (07e3ca81)
| Check | Status |
|---|---|
| Python application | ✅ success |
| Spec Check | ✅ success |
| Docs Build and Link Check | ✅ success |
| Demo Integration | ✅ success |
| Lint Markdown | ✅ success |
Test suite
Full local suite: 5797 passed, 265 skipped, 2 xfailed — no regressions.
New test count in test_typed_ports.py: 27 (up from 25).
🤖 Generated with Claude Code
sei-ahouseholder
left a comment
There was a problem hiding this comment.
PR Verify — 1827 ✅ READY-TO-MERGE
All findings confirmed at HEAD. CI green. No gaps.
Finding verification
| ID | Severity | Outcome | Verdict |
|---|---|---|---|
phase3-closes-at-bottom-0 |
IMPROVE | fixed | ✅ CONFIRMED |
phase3-pr-body-missing-changes-section-0 |
IMPROVE | fixed | ✅ CONFIRMED |
phase5-btnd03009-legacy-nodes-conditions-0 |
IMPROVE | no_change_needed | ✅ NOTED — BTND-03-009 scopes to new nodes; pre-existing deferred to #1809 |
phase5-btnd03009-legacy-nodes-rm-0 |
IMPROVE | no_change_needed | ✅ NOTED — same; deferred to #1809 |
phase10-sender-actor-id-untested-0 |
IMPROVE | fixed | ✅ CONFIRMED |
phase10-transition-rm-failure-untested-0 |
IMPROVE | fixed | ✅ CONFIRMED |
phase9-notes-status-draft-0 |
IMPROVE | fixed | ✅ CONFIRMED |
CI (commit 07e3ca81)
| Check | Status |
|---|---|
| Python application | ✅ success |
| Spec Check | ✅ success |
| Docs Build and Link Check | ✅ success |
| Demo Integration | ✅ success |
| Lint Markdown | ✅ success |
Overall verdict
READY-TO-MERGE — all findings resolved, CI green, full test suite clean (5797 passed).
🤖 Generated with Claude Code
Summary
Implements issue #1808 — adopt py_trees 2.5.0 typed Ports for BT node blackboard contracts.
Changes
vultron/core/behaviors/helpers.py— addsDataLayerConditionWithPortsandDataLayerActionWithPortsbase classes. Each declaresinput_ports()/output_ports(),calls
setup_ports()with BTBridge flat-key remappings insetup(), and reads injectedvalues via
get_input()ininitialise(). ImportsNoDataAvailablefor the optionaltrigger_activity_factoryguard.validate_reportnodes migrated fromDataLayerCondition/DataLayerActionto the new bases:CheckRMStateValid,CheckRMStateReceivedOrInvalid,EnsureEmbargoExists(conditions.py);TransitionRMtoValid(rm_transitions.py).docs/adr/0044-py-trees-typed-ports-adoption.md— new ADR extending ADR-0008; recordsdecision, alternatives, constructor-vs-remapping tension, and known consequence (XML authoring
deferred to spike Spike: assess BehaviorTree XML authoring/export feasibility for Vultron BTs via py_trees Ports #1810).
specs/behavior-tree-node-design.yaml— adds BTND-03-009, BTND-03-010, BTND-03-011(typed port declarations, setup_ports remappings, get_input usage). Uses
>folded scalarsto avoid YAML parse errors from inline
{key: value}remapping examples.notes/py-trees-ports-adoption.md— adds 6-step migration recipe with code examples.test/core/behaviors/report/nodes/test_typed_ports.py— 27 new tests: base-classcontract tests, isolated
NoDataAvailabledetection tests,BTTestScenariointegrationtests for all four pilot nodes, sender_actor_id ADR-0022 path, and FAILURE guard path.
mkdocs.yml— adds ADR-0044 to nav (required byadr-index-synchook).Key design decisions
{"datalayer": "/datalayer", "actor_id": "/actor_id"}bridge the Portsnamespace to the flat keys
BTBridge.setup_tree()writes — no changes to BTBridge required.trigger_activity_factoryis declared asrequired=False; absence caught narrowly viaexcept NoDataAvailable(not broadexcept Exception).NoDataAvailablesurfaces ininitialise()at the start of the first tick, not duringsetup()— ADR and spec corrected to reflect this (pre-PR review finding).Deferred
Test plan
uv run black vultron/ test/ && uv run flake8 vultron/ test/— cleanuv run mypy— no issues in 1114 source filesuv run pyright— 0 errors, 0 warningsuv run pytest test/core/behaviors/report/ test/metadata/specs/— 620 passedadr-index-sync)🤖 Generated with Claude Code