Skip to content

Feat/ivan/pure modules#2469

Draft
leshy wants to merge 125 commits into
mainfrom
feat/ivan/pure-modules
Draft

Feat/ivan/pure modules#2469
leshy wants to merge 125 commits into
mainfrom
feat/ivan/pure-modules

Conversation

@leshy

@leshy leshy commented Jun 11, 2026

Copy link
Copy Markdown
Member

No description provided.

leshy added 2 commits June 11, 2026 18:48
…e + health

A PureModule declares when it runs (one tick() input), how every other
input is sampled at that moment (latest/interpolate/window), and one pure
step() bound to inputs by parameter name. The same class runs live on
pubsub ports (NullStore-bridged, recording = store choice) or offline
over stored memory2 streams via Module.over() — lazy, exact, chainable
into other modules.

Live ticks flow through a selectable BackpressureBuffer (KeepLast
default); every queue in the path is bounded, incl. a max_pending cap so
a dead interpolate() input can't accumulate ticks. Health follows
"drops are metrics, not errors": per-reason drop counters, a 1 Hz
_health stream in the module store, one warmup line comparing observed
vs expected input rates, transition-logged DEGRADED/STALLED contract
messages with throttled reminders, and strict mode for offline replay
determinism.
Executable walkthrough (md-babel) in docs/usage/pure_modules.md: synthetic
recording, first module with interpolation proof, sampler language,
missing-data policy, explicit state, module chaining, live deployment
notes, and a fake-clock health contract demo. Linked from the usage TOC
and the puremodule.md reference.
@codecov

codecov Bot commented Jun 11, 2026

Copy link
Copy Markdown

❌ 20 Tests Failed:

Tests completed Failed Passed Skipped
3500 20 3480 184
View the top 3 failed test(s) by shortest run time
dimos.pure.test_typing_static::test_fixture_expectations[case_config_kwargs.py]
Stack Traces | 0.001s run time
case = 'case_config_kwargs.py'
diagnostics = {'__strays__': [], 'case_arity.py': [], 'case_config_kwargs.py': [], 'case_config_real.py': [], ...}

    @pytest.mark.parametrize("case", CASES)
    def test_fixture_expectations(case, diagnostics):
        exp_errors, exp_reveals = _expected(case)
        act_errors, act_reveals, problems = _actual(case, diagnostics[case])
    
        for line, revealed in sorted(act_reveals.items()):
            want = exp_reveals.pop(line, None)
            if want is None:
                problems.append(f"line {line}: unmarked reveal {revealed!r}")
            elif revealed != want:
                problems.append(f"line {line}: revealed {revealed!r}, marker says {want!r}")
        for line, want in sorted(exp_reveals.items()):
            problems.append(f"line {line}: marker expects reveal {want!r}, mypy emitted none")
    
        for line, (code, msg) in sorted(act_errors.items()):
            want = exp_errors.pop(line, None)
            if want is None:
                problems.append(f"line {line}: unmarked error [{code}] {msg}")
            else:
                want_code, want_sub = want
                if code != want_code:
                    problems.append(f"line {line}: error code [{code}], marker says [{want_code}]")
                if want_sub not in msg:
                    problems.append(f"line {line}: {want_sub!r} not in message {msg!r}")
        for line, (want_code, want_sub) in sorted(exp_errors.items()):
            problems.append(f"line {line}: marker expects [{want_code}] {want_sub!r}, no error emitted")
    
>       assert not problems, f"{case}:\n  " + "\n  ".join(problems)
E       AssertionError: case_config_kwargs.py:
E           line 88: marker expects reveal 'builtins.str', mypy emitted none
E           line 89: marker expects reveal 'builtins.float', mypy emitted none
E           line 90: marker expects reveal 'Grid', mypy emitted none
E           line 93: marker expects reveal 'Go2Connection.Out', mypy emitted none
E           line 95: marker expects [call-arg] 'did you mean "prefix"?', no error emitted
E           line 96: marker expects [arg-type] 'incompatible type', no error emitted
E           line 97: marker expects [call-arg] 'Unexpected keyword argument', no error emitted
E       assert not ["line 88: marker expects reveal 'builtins.str', mypy emitted none", "line 89: marker expects reveal 'builtins.float', mypy emitted none", "line 90: marker expects reveal 'Grid', mypy emitted none", "line 93: marker expects reveal 'Go2Connection.Out', mypy emitted none", 'line 95: marker expects [call-arg] \'did you mean "prefix"?\', no error emitted', "line 96: marker expects [arg-type] 'incompatible type', no error emitted", ...]

act_errors = {}
act_reveals = {}
case       = 'case_config_kwargs.py'
diagnostics = {'__strays__': [], 'case_arity.py': [], 'case_config_kwargs.py': [], 'case_config_real.py': [], ...}
exp_errors = {95: ('call-arg', 'did you mean "prefix"?'), 96: ('arg-type', 'incompatible type'), 97: ('call-arg', 'Unexpected keyword argument')}
exp_reveals = {88: 'builtins.str', 89: 'builtins.float', 90: 'Grid', 93: 'Go2Connection.Out'}
line       = 97
problems   = ["line 88: marker expects reveal 'builtins.str', mypy emitted none", "line 89: marker expects reveal 'builtins.float',...u mean "prefix"?\', no error emitted', "line 96: marker expects [arg-type] 'incompatible type', no error emitted", ...]
want       = 'Go2Connection.Out'
want_code  = 'call-arg'
want_sub   = 'Unexpected keyword argument'

dimos/pure/test_typing_static.py:173: AssertionError
dimos.pure.test_typing_static::test_fixture_expectations[case_config_real.py]
Stack Traces | 0.001s run time
case = 'case_config_real.py'
diagnostics = {'__strays__': [], 'case_arity.py': [], 'case_config_kwargs.py': [], 'case_config_real.py': [], ...}

    @pytest.mark.parametrize("case", CASES)
    def test_fixture_expectations(case, diagnostics):
        exp_errors, exp_reveals = _expected(case)
        act_errors, act_reveals, problems = _actual(case, diagnostics[case])
    
        for line, revealed in sorted(act_reveals.items()):
            want = exp_reveals.pop(line, None)
            if want is None:
                problems.append(f"line {line}: unmarked reveal {revealed!r}")
            elif revealed != want:
                problems.append(f"line {line}: revealed {revealed!r}, marker says {want!r}")
        for line, want in sorted(exp_reveals.items()):
            problems.append(f"line {line}: marker expects reveal {want!r}, mypy emitted none")
    
        for line, (code, msg) in sorted(act_errors.items()):
            want = exp_errors.pop(line, None)
            if want is None:
                problems.append(f"line {line}: unmarked error [{code}] {msg}")
            else:
                want_code, want_sub = want
                if code != want_code:
                    problems.append(f"line {line}: error code [{code}], marker says [{want_code}]")
                if want_sub not in msg:
                    problems.append(f"line {line}: {want_sub!r} not in message {msg!r}")
        for line, (want_code, want_sub) in sorted(exp_errors.items()):
            problems.append(f"line {line}: marker expects [{want_code}] {want_sub!r}, no error emitted")
    
>       assert not problems, f"{case}:\n  " + "\n  ".join(problems)
E       AssertionError: case_config_real.py:
E           line 50: marker expects reveal 'builtins.str', mypy emitted none
E           line 51: marker expects reveal 'builtins.float', mypy emitted none
E           line 52: marker expects reveal 'dimos.pure.config.PureModuleConfig', mypy emitted none
E           line 53: marker expects reveal 'builtins.dict[builtins.str, Any]', mypy emitted none
E           line 55: marker expects [call-arg] 'did you mean "prefix"?', no error emitted
E           line 56: marker expects [arg-type] 'incompatible type', no error emitted
E           line 57: marker expects [call-arg] 'Unexpected keyword argument "LIMIT"', no error emitted
E           line 58: marker expects [misc] 'Too many positional arguments', no error emitted
E           line 59: marker expects [call-arg] 'Missing named argument "robot_ip"', no error emitted
E           line 63: marker expects [misc] 'is read-only', no error emitted
E           line 64: marker expects [misc] 'is read-only', no error emitted
E       assert not ["line 50: marker expects reveal 'builtins.str', mypy emitted none", "line 51: marker expects reveal 'builtins.float', mypy emitted none", "line 52: marker expects reveal 'dimos.pure.config.PureModuleConfig', mypy emitted none", "line 53: marker expects reveal 'builtins.dict[builtins.str, Any]', mypy emitted none", 'line 55: marker expects [call-arg] \'did you mean "prefix"?\', no error emitted', "line 56: marker expects [arg-type] 'incompatible type', no error emitted", ...]

act_errors = {}
act_reveals = {}
case       = 'case_config_real.py'
diagnostics = {'__strays__': [], 'case_arity.py': [], 'case_config_kwargs.py': [], 'case_config_real.py': [], ...}
exp_errors = {55: ('call-arg', 'did you mean "prefix"?'), 56: ('arg-type', 'incompatible type'), 57: ('call-arg', 'Unexpected keyword argument "LIMIT"'), 58: ('misc', 'Too many positional arguments'), ...}
exp_reveals = {50: 'builtins.str', 51: 'builtins.float', 52: 'dimos.pure.config.PureModuleConfig', 53: 'builtins.dict[builtins.str, Any]'}
line       = 64
problems   = ["line 50: marker expects reveal 'builtins.str', mypy emitted none", "line 51: marker expects reveal 'builtins.float',...u mean "prefix"?\', no error emitted', "line 56: marker expects [arg-type] 'incompatible type', no error emitted", ...]
want       = 'builtins.dict[builtins.str, Any]'
want_code  = 'misc'
want_sub   = 'is read-only'

dimos/pure/test_typing_static.py:173: AssertionError
dimos.pure.test_typing_static::test_fixture_expectations[case_graph_apply.py]
Stack Traces | 0.001s run time
case = 'case_graph_apply.py'
diagnostics = {'__strays__': [], 'case_arity.py': [], 'case_config_kwargs.py': [], 'case_config_real.py': [], ...}

    @pytest.mark.parametrize("case", CASES)
    def test_fixture_expectations(case, diagnostics):
        exp_errors, exp_reveals = _expected(case)
        act_errors, act_reveals, problems = _actual(case, diagnostics[case])
    
        for line, revealed in sorted(act_reveals.items()):
            want = exp_reveals.pop(line, None)
            if want is None:
                problems.append(f"line {line}: unmarked reveal {revealed!r}")
            elif revealed != want:
                problems.append(f"line {line}: revealed {revealed!r}, marker says {want!r}")
        for line, want in sorted(exp_reveals.items()):
            problems.append(f"line {line}: marker expects reveal {want!r}, mypy emitted none")
    
        for line, (code, msg) in sorted(act_errors.items()):
            want = exp_errors.pop(line, None)
            if want is None:
                problems.append(f"line {line}: unmarked error [{code}] {msg}")
            else:
                want_code, want_sub = want
                if code != want_code:
                    problems.append(f"line {line}: error code [{code}], marker says [{want_code}]")
                if want_sub not in msg:
                    problems.append(f"line {line}: {want_sub!r} not in message {msg!r}")
        for line, (want_code, want_sub) in sorted(exp_errors.items()):
            problems.append(f"line {line}: marker expects [{want_code}] {want_sub!r}, no error emitted")
    
>       assert not problems, f"{case}:\n  " + "\n  ".join(problems)
E       AssertionError: case_graph_apply.py:
E           line 69: marker expects reveal 'Mapper.Out', mypy emitted none
E           line 70: marker expects reveal 'Grid', mypy emitted none
E           line 74: marker expects reveal 'Grid', mypy emitted none
E           line 77: marker expects reveal 'typing.Iterator[Any]', mypy emitted none
E           line 94: marker expects reveal 'Cloud', mypy emitted none
E           line 95: marker expects reveal 'Grid', mypy emitted none
E           line 101: marker expects reveal 'Nav.Out', mypy emitted none
E           line 102: marker expects reveal 'dimos.pure.graph.GraphRun[Nav.Out]', mypy emitted none
E           line 107: marker expects [arg-type] 'expected "Grid"', no error emitted
E       assert not ["line 69: marker expects reveal 'Mapper.Out', mypy emitted none", "line 70: marker expects reveal 'Grid', mypy emitted none", "line 74: marker expects reveal 'Grid', mypy emitted none", "line 77: marker expects reveal 'typing.Iterator[Any]', mypy emitted none", "line 94: marker expects reveal 'Cloud', mypy emitted none", "line 95: marker expects reveal 'Grid', mypy emitted none", ...]

act_errors = {}
act_reveals = {}
case       = 'case_graph_apply.py'
diagnostics = {'__strays__': [], 'case_arity.py': [], 'case_config_kwargs.py': [], 'case_config_real.py': [], ...}
exp_errors = {107: ('arg-type', 'expected "Grid"')}
exp_reveals = {69: 'Mapper.Out', 70: 'Grid', 74: 'Grid', 77: 'typing.Iterator[Any]', ...}
line       = 107
problems   = ["line 69: marker expects reveal 'Mapper.Out', mypy emitted none", "line 70: marker expects reveal 'Grid', mypy emitte...94: marker expects reveal 'Cloud', mypy emitted none", "line 95: marker expects reveal 'Grid', mypy emitted none", ...]
want       = 'dimos.pure.graph.GraphRun[Nav.Out]'
want_code  = 'arg-type'
want_sub   = 'expected "Grid"'

dimos/pure/test_typing_static.py:173: AssertionError
dimos.pure.test_typing_static::test_fixture_expectations[case_infer_async.py]
Stack Traces | 0.001s run time
case = 'case_infer_async.py'
diagnostics = {'__strays__': [], 'case_arity.py': [], 'case_config_kwargs.py': [], 'case_config_real.py': [], ...}

    @pytest.mark.parametrize("case", CASES)
    def test_fixture_expectations(case, diagnostics):
        exp_errors, exp_reveals = _expected(case)
        act_errors, act_reveals, problems = _actual(case, diagnostics[case])
    
        for line, revealed in sorted(act_reveals.items()):
            want = exp_reveals.pop(line, None)
            if want is None:
                problems.append(f"line {line}: unmarked reveal {revealed!r}")
            elif revealed != want:
                problems.append(f"line {line}: revealed {revealed!r}, marker says {want!r}")
        for line, want in sorted(exp_reveals.items()):
            problems.append(f"line {line}: marker expects reveal {want!r}, mypy emitted none")
    
        for line, (code, msg) in sorted(act_errors.items()):
            want = exp_errors.pop(line, None)
            if want is None:
                problems.append(f"line {line}: unmarked error [{code}] {msg}")
            else:
                want_code, want_sub = want
                if code != want_code:
                    problems.append(f"line {line}: error code [{code}], marker says [{want_code}]")
                if want_sub not in msg:
                    problems.append(f"line {line}: {want_sub!r} not in message {msg!r}")
        for line, (want_code, want_sub) in sorted(exp_errors.items()):
            problems.append(f"line {line}: marker expects [{want_code}] {want_sub!r}, no error emitted")
    
>       assert not problems, f"{case}:\n  " + "\n  ".join(problems)
E       AssertionError: case_infer_async.py:
E           line 43: marker expects reveal 'Captioner.Out', mypy emitted none
E           line 44: marker expects reveal 'builtins.str', mypy emitted none
E           line 58: marker expects reveal 'AsyncSkipping.Out', mypy emitted none
E           line 78: marker expects reveal 'AwaitableReturner.Out', mypy emitted none
E       assert not ["line 43: marker expects reveal 'Captioner.Out', mypy emitted none", "line 44: marker expects reveal 'builtins.str', mypy emitted none", "line 58: marker expects reveal 'AsyncSkipping.Out', mypy emitted none", "line 78: marker expects reveal 'AwaitableReturner.Out', mypy emitted none"]

act_errors = {}
act_reveals = {}
case       = 'case_infer_async.py'
diagnostics = {'__strays__': [], 'case_arity.py': [], 'case_config_kwargs.py': [], 'case_config_real.py': [], ...}
exp_errors = {}
exp_reveals = {43: 'Captioner.Out', 44: 'builtins.str', 58: 'AsyncSkipping.Out', 78: 'AwaitableReturner.Out'}
line       = 78
problems   = ["line 43: marker expects reveal 'Captioner.Out', mypy emitted none", "line 44: marker expects reveal 'builtins.str', ...l 'AsyncSkipping.Out', mypy emitted none", "line 78: marker expects reveal 'AwaitableReturner.Out', mypy emitted none"]
want       = 'AwaitableReturner.Out'

dimos/pure/test_typing_static.py:173: AssertionError
dimos.pure.test_typing_static::test_fixture_expectations[case_infer_fold.py]
Stack Traces | 0.001s run time
case = 'case_infer_fold.py'
diagnostics = {'__strays__': [], 'case_arity.py': [], 'case_config_kwargs.py': [], 'case_config_real.py': [], ...}

    @pytest.mark.parametrize("case", CASES)
    def test_fixture_expectations(case, diagnostics):
        exp_errors, exp_reveals = _expected(case)
        act_errors, act_reveals, problems = _actual(case, diagnostics[case])
    
        for line, revealed in sorted(act_reveals.items()):
            want = exp_reveals.pop(line, None)
            if want is None:
                problems.append(f"line {line}: unmarked reveal {revealed!r}")
            elif revealed != want:
                problems.append(f"line {line}: revealed {revealed!r}, marker says {want!r}")
        for line, want in sorted(exp_reveals.items()):
            problems.append(f"line {line}: marker expects reveal {want!r}, mypy emitted none")
    
        for line, (code, msg) in sorted(act_errors.items()):
            want = exp_errors.pop(line, None)
            if want is None:
                problems.append(f"line {line}: unmarked error [{code}] {msg}")
            else:
                want_code, want_sub = want
                if code != want_code:
                    problems.append(f"line {line}: error code [{code}], marker says [{want_code}]")
                if want_sub not in msg:
                    problems.append(f"line {line}: {want_sub!r} not in message {msg!r}")
        for line, (want_code, want_sub) in sorted(exp_errors.items()):
            problems.append(f"line {line}: marker expects [{want_code}] {want_sub!r}, no error emitted")
    
>       assert not problems, f"{case}:\n  " + "\n  ".join(problems)
E       AssertionError: case_infer_fold.py:
E           line 45: marker expects reveal 'Batcher.Out', mypy emitted none
E           line 46: marker expects reveal 'Scan', mypy emitted none
E       assert not ["line 45: marker expects reveal 'Batcher.Out', mypy emitted none", "line 46: marker expects reveal 'Scan', mypy emitted none"]

act_errors = {}
act_reveals = {}
case       = 'case_infer_fold.py'
diagnostics = {'__strays__': [], 'case_arity.py': [], 'case_config_kwargs.py': [], 'case_config_real.py': [], ...}
exp_errors = {}
exp_reveals = {45: 'Batcher.Out', 46: 'Scan'}
line       = 46
problems   = ["line 45: marker expects reveal 'Batcher.Out', mypy emitted none", "line 46: marker expects reveal 'Scan', mypy emitted none"]
want       = 'Scan'

dimos/pure/test_typing_static.py:173: AssertionError
dimos.pure.test_typing_static::test_fixture_expectations[case_infer_mealy.py]
Stack Traces | 0.001s run time
case = 'case_infer_mealy.py'
diagnostics = {'__strays__': [], 'case_arity.py': [], 'case_config_kwargs.py': [], 'case_config_real.py': [], ...}

    @pytest.mark.parametrize("case", CASES)
    def test_fixture_expectations(case, diagnostics):
        exp_errors, exp_reveals = _expected(case)
        act_errors, act_reveals, problems = _actual(case, diagnostics[case])
    
        for line, revealed in sorted(act_reveals.items()):
            want = exp_reveals.pop(line, None)
            if want is None:
                problems.append(f"line {line}: unmarked reveal {revealed!r}")
            elif revealed != want:
                problems.append(f"line {line}: revealed {revealed!r}, marker says {want!r}")
        for line, want in sorted(exp_reveals.items()):
            problems.append(f"line {line}: marker expects reveal {want!r}, mypy emitted none")
    
        for line, (code, msg) in sorted(act_errors.items()):
            want = exp_errors.pop(line, None)
            if want is None:
                problems.append(f"line {line}: unmarked error [{code}] {msg}")
            else:
                want_code, want_sub = want
                if code != want_code:
                    problems.append(f"line {line}: error code [{code}], marker says [{want_code}]")
                if want_sub not in msg:
                    problems.append(f"line {line}: {want_sub!r} not in message {msg!r}")
        for line, (want_code, want_sub) in sorted(exp_errors.items()):
            problems.append(f"line {line}: marker expects [{want_code}] {want_sub!r}, no error emitted")
    
>       assert not problems, f"{case}:\n  " + "\n  ".join(problems)
E       AssertionError: case_infer_mealy.py:
E           line 41: marker expects reveal 'Mapper.Out', mypy emitted none
E           line 42: marker expects reveal 'builtins.int', mypy emitted none
E           line 61: marker expects reveal 'AlwaysEmits.Out', mypy emitted none
E       assert not ["line 41: marker expects reveal 'Mapper.Out', mypy emitted none", "line 42: marker expects reveal 'builtins.int', mypy emitted none", "line 61: marker expects reveal 'AlwaysEmits.Out', mypy emitted none"]

act_errors = {}
act_reveals = {}
case       = 'case_infer_mealy.py'
diagnostics = {'__strays__': [], 'case_arity.py': [], 'case_config_kwargs.py': [], 'case_config_real.py': [], ...}
exp_errors = {}
exp_reveals = {41: 'Mapper.Out', 42: 'builtins.int', 61: 'AlwaysEmits.Out'}
line       = 61
problems   = ["line 41: marker expects reveal 'Mapper.Out', mypy emitted none", "line 42: marker expects reveal 'builtins.int', mypy emitted none", "line 61: marker expects reveal 'AlwaysEmits.Out', mypy emitted none"]
want       = 'AlwaysEmits.Out'

dimos/pure/test_typing_static.py:173: AssertionError
dimos.pure.test_typing_static::test_fixture_expectations[case_infer_optional.py]
Stack Traces | 0.001s run time
case = 'case_infer_optional.py'
diagnostics = {'__strays__': [], 'case_arity.py': [], 'case_config_kwargs.py': [], 'case_config_real.py': [], ...}

    @pytest.mark.parametrize("case", CASES)
    def test_fixture_expectations(case, diagnostics):
        exp_errors, exp_reveals = _expected(case)
        act_errors, act_reveals, problems = _actual(case, diagnostics[case])
    
        for line, revealed in sorted(act_reveals.items()):
            want = exp_reveals.pop(line, None)
            if want is None:
                problems.append(f"line {line}: unmarked reveal {revealed!r}")
            elif revealed != want:
                problems.append(f"line {line}: revealed {revealed!r}, marker says {want!r}")
        for line, want in sorted(exp_reveals.items()):
            problems.append(f"line {line}: marker expects reveal {want!r}, mypy emitted none")
    
        for line, (code, msg) in sorted(act_errors.items()):
            want = exp_errors.pop(line, None)
            if want is None:
                problems.append(f"line {line}: unmarked error [{code}] {msg}")
            else:
                want_code, want_sub = want
                if code != want_code:
                    problems.append(f"line {line}: error code [{code}], marker says [{want_code}]")
                if want_sub not in msg:
                    problems.append(f"line {line}: {want_sub!r} not in message {msg!r}")
        for line, (want_code, want_sub) in sorted(exp_errors.items()):
            problems.append(f"line {line}: marker expects [{want_code}] {want_sub!r}, no error emitted")
    
>       assert not problems, f"{case}:\n  " + "\n  ".join(problems)
E       AssertionError: case_infer_optional.py:
E           line 40: marker expects reveal 'Gate.Out', mypy emitted none
E           line 41: marker expects reveal 'builtins.float', mypy emitted none
E           line 52: marker expects reveal 'Never', mypy emitted none
E       assert not ["line 40: marker expects reveal 'Gate.Out', mypy emitted none", "line 41: marker expects reveal 'builtins.float', mypy emitted none", "line 52: marker expects reveal 'Never', mypy emitted none"]

act_errors = {}
act_reveals = {}
case       = 'case_infer_optional.py'
diagnostics = {'__strays__': [], 'case_arity.py': [], 'case_config_kwargs.py': [], 'case_config_real.py': [], ...}
exp_errors = {}
exp_reveals = {40: 'Gate.Out', 41: 'builtins.float', 52: 'Never'}
line       = 52
problems   = ["line 40: marker expects reveal 'Gate.Out', mypy emitted none", "line 41: marker expects reveal 'builtins.float', mypy emitted none", "line 52: marker expects reveal 'Never', mypy emitted none"]
want       = 'Never'

dimos/pure/test_typing_static.py:173: AssertionError
dimos.pure.test_typing_static::test_fixture_expectations[case_infer_stateless.py]
Stack Traces | 0.001s run time
case = 'case_infer_stateless.py'
diagnostics = {'__strays__': [], 'case_arity.py': [], 'case_config_kwargs.py': [], 'case_config_real.py': [], ...}

    @pytest.mark.parametrize("case", CASES)
    def test_fixture_expectations(case, diagnostics):
        exp_errors, exp_reveals = _expected(case)
        act_errors, act_reveals, problems = _actual(case, diagnostics[case])
    
        for line, revealed in sorted(act_reveals.items()):
            want = exp_reveals.pop(line, None)
            if want is None:
                problems.append(f"line {line}: unmarked reveal {revealed!r}")
            elif revealed != want:
                problems.append(f"line {line}: revealed {revealed!r}, marker says {want!r}")
        for line, want in sorted(exp_reveals.items()):
            problems.append(f"line {line}: marker expects reveal {want!r}, mypy emitted none")
    
        for line, (code, msg) in sorted(act_errors.items()):
            want = exp_errors.pop(line, None)
            if want is None:
                problems.append(f"line {line}: unmarked error [{code}] {msg}")
            else:
                want_code, want_sub = want
                if code != want_code:
                    problems.append(f"line {line}: error code [{code}], marker says [{want_code}]")
                if want_sub not in msg:
                    problems.append(f"line {line}: {want_sub!r} not in message {msg!r}")
        for line, (want_code, want_sub) in sorted(exp_errors.items()):
            problems.append(f"line {line}: marker expects [{want_code}] {want_sub!r}, no error emitted")
    
>       assert not problems, f"{case}:\n  " + "\n  ".join(problems)
E       AssertionError: case_infer_stateless.py:
E           line 44: marker expects reveal 'typing.Iterator[Tagger.Out]', mypy emitted none
E           line 46: marker expects reveal 'Tagger.Out', mypy emitted none
E           line 47: marker expects reveal 'builtins.str', mypy emitted none
E           line 48: marker expects reveal 'builtins.float', mypy emitted none
E       assert not ["line 44: marker expects reveal 'typing.Iterator[Tagger.Out]', mypy emitted none", "line 46: marker expects reveal 'Tagger.Out', mypy emitted none", "line 47: marker expects reveal 'builtins.str', mypy emitted none", "line 48: marker expects reveal 'builtins.float', mypy emitted none"]

act_errors = {}
act_reveals = {}
case       = 'case_infer_stateless.py'
diagnostics = {'__strays__': [], 'case_arity.py': [], 'case_config_kwargs.py': [], 'case_config_real.py': [], ...}
exp_errors = {}
exp_reveals = {44: 'typing.Iterator[Tagger.Out]', 46: 'Tagger.Out', 47: 'builtins.str', 48: 'builtins.float'}
line       = 48
problems   = ["line 44: marker expects reveal 'typing.Iterator[Tagger.Out]', mypy emitted none", "line 46: marker expects reveal 'T...xpects reveal 'builtins.str', mypy emitted none", "line 48: marker expects reveal 'builtins.float', mypy emitted none"]
want       = 'builtins.float'

dimos/pure/test_typing_static.py:173: AssertionError
dimos.pure.test_typing_static::test_fixture_expectations[case_invalid_self.py]
Stack Traces | 0.001s run time
case = 'case_invalid_self.py'
diagnostics = {'__strays__': [], 'case_arity.py': [], 'case_config_kwargs.py': [], 'case_config_real.py': [], ...}

    @pytest.mark.parametrize("case", CASES)
    def test_fixture_expectations(case, diagnostics):
        exp_errors, exp_reveals = _expected(case)
        act_errors, act_reveals, problems = _actual(case, diagnostics[case])
    
        for line, revealed in sorted(act_reveals.items()):
            want = exp_reveals.pop(line, None)
            if want is None:
                problems.append(f"line {line}: unmarked reveal {revealed!r}")
            elif revealed != want:
                problems.append(f"line {line}: revealed {revealed!r}, marker says {want!r}")
        for line, want in sorted(exp_reveals.items()):
            problems.append(f"line {line}: marker expects reveal {want!r}, mypy emitted none")
    
        for line, (code, msg) in sorted(act_errors.items()):
            want = exp_errors.pop(line, None)
            if want is None:
                problems.append(f"line {line}: unmarked error [{code}] {msg}")
            else:
                want_code, want_sub = want
                if code != want_code:
                    problems.append(f"line {line}: error code [{code}], marker says [{want_code}]")
                if want_sub not in msg:
                    problems.append(f"line {line}: {want_sub!r} not in message {msg!r}")
        for line, (want_code, want_sub) in sorted(exp_errors.items()):
            problems.append(f"line {line}: marker expects [{want_code}] {want_sub!r}, no error emitted")
    
>       assert not problems, f"{case}:\n  " + "\n  ".join(problems)
E       AssertionError: case_invalid_self.py:
E           line 66: marker expects reveal 'StepAndFold.Out', mypy emitted none
E           line 37: marker expects [misc] 'Invalid self argument', no error emitted
E           line 47: marker expects [misc] 'Invalid self argument', no error emitted
E       assert not ["line 66: marker expects reveal 'StepAndFold.Out', mypy emitted none", "line 37: marker expects [misc] 'Invalid self argument', no error emitted", "line 47: marker expects [misc] 'Invalid self argument', no error emitted"]

act_errors = {}
act_reveals = {}
case       = 'case_invalid_self.py'
diagnostics = {'__strays__': [], 'case_arity.py': [], 'case_config_kwargs.py': [], 'case_config_real.py': [], ...}
exp_errors = {37: ('misc', 'Invalid self argument'), 47: ('misc', 'Invalid self argument')}
exp_reveals = {66: 'StepAndFold.Out'}
line       = 47
problems   = ["line 66: marker expects reveal 'StepAndFold.Out', mypy emitted none", "line 37: marker expects [misc] 'Invalid self argument', no error emitted", "line 47: marker expects [misc] 'Invalid self argument', no error emitted"]
want       = 'StepAndFold.Out'
want_code  = 'misc'
want_sub   = 'Invalid self argument'

dimos/pure/test_typing_static.py:173: AssertionError
dimos.pure.test_typing_static::test_fixture_expectations[case_override.py]
Stack Traces | 0.001s run time
case = 'case_override.py'
diagnostics = {'__strays__': [], 'case_arity.py': [], 'case_config_kwargs.py': [], 'case_config_real.py': [], ...}

    @pytest.mark.parametrize("case", CASES)
    def test_fixture_expectations(case, diagnostics):
        exp_errors, exp_reveals = _expected(case)
        act_errors, act_reveals, problems = _actual(case, diagnostics[case])
    
        for line, revealed in sorted(act_reveals.items()):
            want = exp_reveals.pop(line, None)
            if want is None:
                problems.append(f"line {line}: unmarked reveal {revealed!r}")
            elif revealed != want:
                problems.append(f"line {line}: revealed {revealed!r}, marker says {want!r}")
        for line, want in sorted(exp_reveals.items()):
            problems.append(f"line {line}: marker expects reveal {want!r}, mypy emitted none")
    
        for line, (code, msg) in sorted(act_errors.items()):
            want = exp_errors.pop(line, None)
            if want is None:
                problems.append(f"line {line}: unmarked error [{code}] {msg}")
            else:
                want_code, want_sub = want
                if code != want_code:
                    problems.append(f"line {line}: error code [{code}], marker says [{want_code}]")
                if want_sub not in msg:
                    problems.append(f"line {line}: {want_sub!r} not in message {msg!r}")
        for line, (want_code, want_sub) in sorted(exp_errors.items()):
            problems.append(f"line {line}: marker expects [{want_code}] {want_sub!r}, no error emitted")
    
>       assert not problems, f"{case}:\n  " + "\n  ".join(problems)
E       AssertionError: case_override.py:
E           line 50: marker expects reveal 'Shape.Out', mypy emitted none
E           line 58: marker expects [override] 'Return type', no error emitted
E           line 63: marker expects [override] 'incompatible with supertype', no error emitted
E       assert not ["line 50: marker expects reveal 'Shape.Out', mypy emitted none", "line 58: marker expects [override] 'Return type', no error emitted", "line 63: marker expects [override] 'incompatible with supertype', no error emitted"]

act_errors = {}
act_reveals = {}
case       = 'case_override.py'
diagnostics = {'__strays__': [], 'case_arity.py': [], 'case_config_kwargs.py': [], 'case_config_real.py': [], ...}
exp_errors = {58: ('override', 'Return type'), 63: ('override', 'incompatible with supertype')}
exp_reveals = {50: 'Shape.Out'}
line       = 63
problems   = ["line 50: marker expects reveal 'Shape.Out', mypy emitted none", "line 58: marker expects [override] 'Return type', no error emitted", "line 63: marker expects [override] 'incompatible with supertype', no error emitted"]
want       = 'Shape.Out'
want_code  = 'override'
want_sub   = 'incompatible with supertype'

dimos/pure/test_typing_static.py:173: AssertionError
dimos.pure.test_typing_static::test_fixture_expectations[case_param_names.py]
Stack Traces | 0.001s run time
case = 'case_param_names.py'
diagnostics = {'__strays__': [], 'case_arity.py': [], 'case_config_kwargs.py': [], 'case_config_real.py': [], ...}

    @pytest.mark.parametrize("case", CASES)
    def test_fixture_expectations(case, diagnostics):
        exp_errors, exp_reveals = _expected(case)
        act_errors, act_reveals, problems = _actual(case, diagnostics[case])
    
        for line, revealed in sorted(act_reveals.items()):
            want = exp_reveals.pop(line, None)
            if want is None:
                problems.append(f"line {line}: unmarked reveal {revealed!r}")
            elif revealed != want:
                problems.append(f"line {line}: revealed {revealed!r}, marker says {want!r}")
        for line, want in sorted(exp_reveals.items()):
            problems.append(f"line {line}: marker expects reveal {want!r}, mypy emitted none")
    
        for line, (code, msg) in sorted(act_errors.items()):
            want = exp_errors.pop(line, None)
            if want is None:
                problems.append(f"line {line}: unmarked error [{code}] {msg}")
            else:
                want_code, want_sub = want
                if code != want_code:
                    problems.append(f"line {line}: error code [{code}], marker says [{want_code}]")
                if want_sub not in msg:
                    problems.append(f"line {line}: {want_sub!r} not in message {msg!r}")
        for line, (want_code, want_sub) in sorted(exp_errors.items()):
            problems.append(f"line {line}: marker expects [{want_code}] {want_sub!r}, no error emitted")
    
>       assert not problems, f"{case}:\n  " + "\n  ".join(problems)
E       AssertionError: case_param_names.py:
E           line 47: marker expects reveal 'Renamed.Out', mypy emitted none
E           line 64: marker expects reveal 'RenamedMealy.Out', mypy emitted none
E           line 68: marker expects [call-arg] 'Unexpected keyword argument', no error emitted
E       assert not ["line 47: marker expects reveal 'Renamed.Out', mypy emitted none", "line 64: marker expects reveal 'RenamedMealy.Out', mypy emitted none", "line 68: marker expects [call-arg] 'Unexpected keyword argument', no error emitted"]

act_errors = {}
act_reveals = {}
case       = 'case_param_names.py'
diagnostics = {'__strays__': [], 'case_arity.py': [], 'case_config_kwargs.py': [], 'case_config_real.py': [], ...}
exp_errors = {68: ('call-arg', 'Unexpected keyword argument')}
exp_reveals = {47: 'Renamed.Out', 64: 'RenamedMealy.Out'}
line       = 68
problems   = ["line 47: marker expects reveal 'Renamed.Out', mypy emitted none", "line 64: marker expects reveal 'RenamedMealy.Out', mypy emitted none", "line 68: marker expects [call-arg] 'Unexpected keyword argument', no error emitted"]
want       = 'RenamedMealy.Out'
want_code  = 'call-arg'
want_sub   = 'Unexpected keyword argument'

dimos/pure/test_typing_static.py:173: AssertionError
dimos.pure.test_typing_static::test_fixture_expectations[case_ports.py]
Stack Traces | 0.001s run time
case = 'case_ports.py'
diagnostics = {'__strays__': [], 'case_arity.py': [], 'case_config_kwargs.py': [], 'case_config_real.py': [], ...}

    @pytest.mark.parametrize("case", CASES)
    def test_fixture_expectations(case, diagnostics):
        exp_errors, exp_reveals = _expected(case)
        act_errors, act_reveals, problems = _actual(case, diagnostics[case])
    
        for line, revealed in sorted(act_reveals.items()):
            want = exp_reveals.pop(line, None)
            if want is None:
                problems.append(f"line {line}: unmarked reveal {revealed!r}")
            elif revealed != want:
                problems.append(f"line {line}: revealed {revealed!r}, marker says {want!r}")
        for line, want in sorted(exp_reveals.items()):
            problems.append(f"line {line}: marker expects reveal {want!r}, mypy emitted none")
    
        for line, (code, msg) in sorted(act_errors.items()):
            want = exp_errors.pop(line, None)
            if want is None:
                problems.append(f"line {line}: unmarked error [{code}] {msg}")
            else:
                want_code, want_sub = want
                if code != want_code:
                    problems.append(f"line {line}: error code [{code}], marker says [{want_code}]")
                if want_sub not in msg:
                    problems.append(f"line {line}: {want_sub!r} not in message {msg!r}")
        for line, (want_code, want_sub) in sorted(exp_errors.items()):
            problems.append(f"line {line}: marker expects [{want_code}] {want_sub!r}, no error emitted")
    
>       assert not problems, f"{case}:\n  " + "\n  ".join(problems)
E       AssertionError: case_ports.py:
E           line 49: marker expects reveal 'dimos.pure.typing.InPorts[Tagger.In]', mypy emitted none
E           line 50: marker expects reveal 'dimos.pure.typing.OutPorts[Tagger.Out]', mypy emitted none
E           line 51: marker expects reveal 'dimos.pure.typing.InPort[Any]', mypy emitted none
E           line 52: marker expects reveal 'dimos.pure.typing.OutPort[Any]', mypy emitted none
E           line 59: marker expects reveal 'tuple[builtins.str, builtins.str]', mypy emitted none
E           line 67: marker expects reveal 'dimos.pure.typing.InPort[Any]', mypy emitted none
E           line 70: marker expects reveal 'dimos.pure.typing._InAccessor', mypy emitted none
E           line 86: marker expects reveal 'dimos.pure.typing.OutPorts[AsyncMod.Out]', mypy emitted none
E           line 87: marker expects reveal 'dimos.pure.typing.InPorts[AsyncMod.In]', mypy emitted none
E           line 104: marker expects reveal 'dimos.pure.typing.InPorts[StatefulMod.In]', mypy emitted none
E           line 105: marker expects reveal 'dimos.pure.typing.OutPorts[StatefulMod.Out]', mypy emitted none
E           line 119: marker expects reveal 'dimos.pure.typing.InPorts[FoldMod.In]', mypy emitted none
E           line 120: marker expects reveal 'dimos.pure.typing.OutPorts[FoldMod.Out]', mypy emitted none
E           line 63: marker expects [misc] 'read-only', no error emitted
E       assert not ["line 49: marker expects reveal 'dimos.pure.typing.InPorts[Tagger.In]', mypy emitted none", "line 50: marker expects reveal 'dimos.pure.typing.OutPorts[Tagger.Out]', mypy emitted none", "line 51: marker expects reveal 'dimos.pure.typing.InPort[Any]', mypy emitted none", "line 52: marker expects reveal 'dimos.pure.typing.OutPort[Any]', mypy emitted none", "line 59: marker expects reveal 'tuple[builtins.str, builtins.str]', mypy emitted none", "line 67: marker expects reveal 'dimos.pure.typing.InPort[Any]', mypy emitted none", ...]

act_errors = {}
act_reveals = {}
case       = 'case_ports.py'
diagnostics = {'__strays__': [], 'case_arity.py': [], 'case_config_kwargs.py': [], 'case_config_real.py': [], ...}
exp_errors = {63: ('misc', 'read-only')}
exp_reveals = {49: 'dimos.pure.typing.InPorts[Tagger.In]', 50: 'dimos.pure.typing.OutPorts[Tagger.Out]', 51: 'dimos.pure.typing.InPort[Any]', 52: 'dimos.pure.typing.OutPort[Any]', ...}
line       = 63
problems   = ["line 49: marker expects reveal 'dimos.pure.typing.InPorts[Tagger.In]', mypy emitted none", "line 50: marker expects ...ns.str]', mypy emitted none", "line 67: marker expects reveal 'dimos.pure.typing.InPort[Any]', mypy emitted none", ...]
want       = 'dimos.pure.typing.OutPorts[FoldMod.Out]'
want_code  = 'misc'
want_sub   = 'read-only'

dimos/pure/test_typing_static.py:173: AssertionError
dimos.pure.test_typing_static::test_fixture_expectations[case_resources.py]
Stack Traces | 0.001s run time
case = 'case_resources.py'
diagnostics = {'__strays__': [], 'case_arity.py': [], 'case_config_kwargs.py': [], 'case_config_real.py': [], ...}

    @pytest.mark.parametrize("case", CASES)
    def test_fixture_expectations(case, diagnostics):
        exp_errors, exp_reveals = _expected(case)
        act_errors, act_reveals, problems = _actual(case, diagnostics[case])
    
        for line, revealed in sorted(act_reveals.items()):
            want = exp_reveals.pop(line, None)
            if want is None:
                problems.append(f"line {line}: unmarked reveal {revealed!r}")
            elif revealed != want:
                problems.append(f"line {line}: revealed {revealed!r}, marker says {want!r}")
        for line, want in sorted(exp_reveals.items()):
            problems.append(f"line {line}: marker expects reveal {want!r}, mypy emitted none")
    
        for line, (code, msg) in sorted(act_errors.items()):
            want = exp_errors.pop(line, None)
            if want is None:
                problems.append(f"line {line}: unmarked error [{code}] {msg}")
            else:
                want_code, want_sub = want
                if code != want_code:
                    problems.append(f"line {line}: error code [{code}], marker says [{want_code}]")
                if want_sub not in msg:
                    problems.append(f"line {line}: {want_sub!r} not in message {msg!r}")
        for line, (want_code, want_sub) in sorted(exp_errors.items()):
            problems.append(f"line {line}: marker expects [{want_code}] {want_sub!r}, no error emitted")
    
>       assert not problems, f"{case}:\n  " + "\n  ".join(problems)
E       AssertionError: case_resources.py:
E           line 61: marker expects reveal 'Grid', mypy emitted none
E           line 62: marker expects reveal 'VLM', mypy emitted none
E           line 63: marker expects reveal 'Grid', mypy emitted none
E           line 64: marker expects reveal 'dimos.pure.resources.Resource[Grid]', mypy emitted none
E           line 66: marker expects [call-arg] 'Unexpected keyword argument', no error emitted
E       assert not ["line 61: marker expects reveal 'Grid', mypy emitted none", "line 62: marker expects reveal 'VLM', mypy emitted none", "line 63: marker expects reveal 'Grid', mypy emitted none", "line 64: marker expects reveal 'dimos.pure.resources.Resource[Grid]', mypy emitted none", "line 66: marker expects [call-arg] 'Unexpected keyword argument', no error emitted"]

act_errors = {}
act_reveals = {}
case       = 'case_resources.py'
diagnostics = {'__strays__': [], 'case_arity.py': [], 'case_config_kwargs.py': [], 'case_config_real.py': [], ...}
exp_errors = {66: ('call-arg', 'Unexpected keyword argument')}
exp_reveals = {61: 'Grid', 62: 'VLM', 63: 'Grid', 64: 'dimos.pure.resources.Resource[Grid]'}
line       = 66
problems   = ["line 61: marker expects reveal 'Grid', mypy emitted none", "line 62: marker expects reveal 'VLM', mypy emitted none"...ource[Grid]', mypy emitted none", "line 66: marker expects [call-arg] 'Unexpected keyword argument', no error emitted"]
want       = 'dimos.pure.resources.Resource[Grid]'
want_code  = 'call-arg'
want_sub   = 'Unexpected keyword argument'

dimos/pure/test_typing_static.py:173: AssertionError
dimos.pure.test_typing_static::test_fixture_expectations[case_rows_required.py]
Stack Traces | 0.001s run time
case = 'case_rows_required.py'
diagnostics = {'__strays__': [], 'case_arity.py': [], 'case_config_kwargs.py': [], 'case_config_real.py': [], ...}

    @pytest.mark.parametrize("case", CASES)
    def test_fixture_expectations(case, diagnostics):
        exp_errors, exp_reveals = _expected(case)
        act_errors, act_reveals, problems = _actual(case, diagnostics[case])
    
        for line, revealed in sorted(act_reveals.items()):
            want = exp_reveals.pop(line, None)
            if want is None:
                problems.append(f"line {line}: unmarked reveal {revealed!r}")
            elif revealed != want:
                problems.append(f"line {line}: revealed {revealed!r}, marker says {want!r}")
        for line, want in sorted(exp_reveals.items()):
            problems.append(f"line {line}: marker expects reveal {want!r}, mypy emitted none")
    
        for line, (code, msg) in sorted(act_errors.items()):
            want = exp_errors.pop(line, None)
            if want is None:
                problems.append(f"line {line}: unmarked error [{code}] {msg}")
            else:
                want_code, want_sub = want
                if code != want_code:
                    problems.append(f"line {line}: error code [{code}], marker says [{want_code}]")
                if want_sub not in msg:
                    problems.append(f"line {line}: {want_sub!r} not in message {msg!r}")
        for line, (want_code, want_sub) in sorted(exp_errors.items()):
            problems.append(f"line {line}: marker expects [{want_code}] {want_sub!r}, no error emitted")
    
>       assert not problems, f"{case}:\n  " + "\n  ".join(problems)
E       AssertionError: case_rows_required.py:
E           line 64: marker expects reveal 'Image', mypy emitted none
E           line 65: marker expects reveal 'builtins.float', mypy emitted none
E           line 67: marker expects [call-arg] 'Missing named argument "image"', no error emitted
E           line 68: marker expects [call-arg] 'Missing named argument "ts"', no error emitted
E           line 69: marker expects [arg-type] 'incompatible type', no error emitted
E           line 70: marker expects [call-arg] 'Unexpected keyword argument', no error emitted
E           line 71: marker expects [misc] 'Too many positional arguments', no error emitted
E       assert not ["line 64: marker expects reveal 'Image', mypy emitted none", "line 65: marker expects reveal 'builtins.float', mypy emitted none", 'line 67: marker expects [call-arg] \'Missing named argument "image"\', no error emitted', 'line 68: marker expects [call-arg] \'Missing named argument "ts"\', no error emitted', "line 69: marker expects [arg-type] 'incompatible type', no error emitted", "line 70: marker expects [call-arg] 'Unexpected keyword argument', no error emitted", ...]

act_errors = {}
act_reveals = {}
case       = 'case_rows_required.py'
diagnostics = {'__strays__': [], 'case_arity.py': [], 'case_config_kwargs.py': [], 'case_config_real.py': [], ...}
exp_errors = {67: ('call-arg', 'Missing named argument "image"'), 68: ('call-arg', 'Missing named argument "ts"'), 69: ('arg-type', 'incompatible type'), 70: ('call-arg', 'Unexpected keyword argument'), ...}
exp_reveals = {64: 'Image', 65: 'builtins.float'}
line       = 71
problems   = ["line 64: marker expects reveal 'Image', mypy emitted none", "line 65: marker expects reveal 'builtins.float', mypy e...le type', no error emitted", "line 70: marker expects [call-arg] 'Unexpected keyword argument', no error emitted", ...]
want       = 'builtins.float'
want_code  = 'misc'
want_sub   = 'Too many positional arguments'

dimos/pure/test_typing_static.py:173: AssertionError
dimos.pure.test_typing_static::test_fixture_expectations[case_state.py]
Stack Traces | 0.001s run time
case = 'case_state.py'
diagnostics = {'__strays__': [], 'case_arity.py': [], 'case_config_kwargs.py': [], 'case_config_real.py': [], ...}

    @pytest.mark.parametrize("case", CASES)
    def test_fixture_expectations(case, diagnostics):
        exp_errors, exp_reveals = _expected(case)
        act_errors, act_reveals, problems = _actual(case, diagnostics[case])
    
        for line, revealed in sorted(act_reveals.items()):
            want = exp_reveals.pop(line, None)
            if want is None:
                problems.append(f"line {line}: unmarked reveal {revealed!r}")
            elif revealed != want:
                problems.append(f"line {line}: revealed {revealed!r}, marker says {want!r}")
        for line, want in sorted(exp_reveals.items()):
            problems.append(f"line {line}: marker expects reveal {want!r}, mypy emitted none")
    
        for line, (code, msg) in sorted(act_errors.items()):
            want = exp_errors.pop(line, None)
            if want is None:
                problems.append(f"line {line}: unmarked error [{code}] {msg}")
            else:
                want_code, want_sub = want
                if code != want_code:
                    problems.append(f"line {line}: error code [{code}], marker says [{want_code}]")
                if want_sub not in msg:
                    problems.append(f"line {line}: {want_sub!r} not in message {msg!r}")
        for line, (want_code, want_sub) in sorted(exp_errors.items()):
            problems.append(f"line {line}: marker expects [{want_code}] {want_sub!r}, no error emitted")
    
>       assert not problems, f"{case}:\n  " + "\n  ".join(problems)
E       AssertionError: case_state.py:
E           line 37: marker expects reveal 'builtins.int', mypy emitted none
E           line 38: marker expects reveal 'Counter', mypy emitted none
E           line 39: marker expects reveal 'Counter', mypy emitted none
E           line 41: marker expects [call-arg] 'Unexpected keyword argument "bogus"', no error emitted
E           line 42: marker expects [arg-type] 'incompatible type', no error emitted
E           line 43: marker expects [misc] 'Too many positional arguments', no error emitted
E           line 44: marker expects [call-arg] 'Missing named argument "seed"', no error emitted
E           line 47: marker expects [misc] 'is read-only', no error emitted
E       assert not ["line 37: marker expects reveal 'builtins.int', mypy emitted none", "line 38: marker expects reveal 'Counter', mypy emitted none", "line 39: marker expects reveal 'Counter', mypy emitted none", 'line 41: marker expects [call-arg] \'Unexpected keyword argument "bogus"\', no error emitted', "line 42: marker expects [arg-type] 'incompatible type', no error emitted", "line 43: marker expects [misc] 'Too many positional arguments', no error emitted", ...]

act_errors = {}
act_reveals = {}
case       = 'case_state.py'
diagnostics = {'__strays__': [], 'case_arity.py': [], 'case_config_kwargs.py': [], 'case_config_real.py': [], ...}
exp_errors = {41: ('call-arg', 'Unexpected keyword argument "bogus"'), 42: ('arg-type', 'incompatible type'), 43: ('misc', 'Too many positional arguments'), 44: ('call-arg', 'Missing named argument "seed"'), ...}
exp_reveals = {37: 'builtins.int', 38: 'Counter', 39: 'Counter'}
line       = 47
problems   = ["line 37: marker expects reveal 'builtins.int', mypy emitted none", "line 38: marker expects reveal 'Counter', mypy e...ible type', no error emitted", "line 43: marker expects [misc] 'Too many positional arguments', no error emitted", ...]
want       = 'Counter'
want_code  = 'misc'
want_sub   = 'is read-only'

dimos/pure/test_typing_static.py:173: AssertionError
dimos.pure.test_typing_static::test_fixture_expectations[case_tagger_floor.py]
Stack Traces | 0.001s run time
case = 'case_tagger_floor.py'
diagnostics = {'__strays__': [], 'case_arity.py': [], 'case_config_kwargs.py': [], 'case_config_real.py': [], ...}

    @pytest.mark.parametrize("case", CASES)
    def test_fixture_expectations(case, diagnostics):
        exp_errors, exp_reveals = _expected(case)
        act_errors, act_reveals, problems = _actual(case, diagnostics[case])
    
        for line, revealed in sorted(act_reveals.items()):
            want = exp_reveals.pop(line, None)
            if want is None:
                problems.append(f"line {line}: unmarked reveal {revealed!r}")
            elif revealed != want:
                problems.append(f"line {line}: revealed {revealed!r}, marker says {want!r}")
        for line, want in sorted(exp_reveals.items()):
            problems.append(f"line {line}: marker expects reveal {want!r}, mypy emitted none")
    
        for line, (code, msg) in sorted(act_errors.items()):
            want = exp_errors.pop(line, None)
            if want is None:
                problems.append(f"line {line}: unmarked error [{code}] {msg}")
            else:
                want_code, want_sub = want
                if code != want_code:
                    problems.append(f"line {line}: error code [{code}], marker says [{want_code}]")
                if want_sub not in msg:
                    problems.append(f"line {line}: {want_sub!r} not in message {msg!r}")
        for line, (want_code, want_sub) in sorted(exp_errors.items()):
            problems.append(f"line {line}: marker expects [{want_code}] {want_sub!r}, no error emitted")
    
>       assert not problems, f"{case}:\n  " + "\n  ".join(problems)
E       AssertionError: case_tagger_floor.py:
E           line 90: marker expects reveal 'Image', mypy emitted none
E           line 92: marker expects reveal 'Tagger.Out', mypy emitted none
E           line 95: marker expects reveal 'Tagger.Out', mypy emitted none
E           line 96: marker expects reveal 'builtins.str', mypy emitted none
E           line 97: marker expects reveal 'dimos.pure.typing.InPorts[Tagger.In]', mypy emitted none
E           line 98: marker expects reveal 'dimos.pure.typing.OutPorts[Tagger.Out]', mypy emitted none
E           line 101: marker expects [call-arg] 'Missing named argument "pose"', no error emitted
E           line 102: marker expects [call-arg] 'Unexpected keyword', no error emitted
E       assert not ["line 90: marker expects reveal 'Image', mypy emitted none", "line 92: marker expects reveal 'Tagger.Out', mypy emitted none", "line 95: marker expects reveal 'Tagger.Out', mypy emitted none", "line 96: marker expects reveal 'builtins.str', mypy emitted none", "line 97: marker expects reveal 'dimos.pure.typing.InPorts[Tagger.In]', mypy emitted none", "line 98: marker expects reveal 'dimos.pure.typing.OutPorts[Tagger.Out]', mypy emitted none", ...]

act_errors = {}
act_reveals = {}
case       = 'case_tagger_floor.py'
diagnostics = {'__strays__': [], 'case_arity.py': [], 'case_config_kwargs.py': [], 'case_config_real.py': [], ...}
exp_errors = {101: ('call-arg', 'Missing named argument "pose"'), 102: ('call-arg', 'Unexpected keyword')}
exp_reveals = {90: 'Image', 92: 'Tagger.Out', 95: 'Tagger.Out', 96: 'builtins.str', ...}
line       = 102
problems   = ["line 90: marker expects reveal 'Image', mypy emitted none", "line 92: marker expects reveal 'Tagger.Out', mypy emitt... mypy emitted none", "line 98: marker expects reveal 'dimos.pure.typing.OutPorts[Tagger.Out]', mypy emitted none", ...]
want       = 'dimos.pure.typing.OutPorts[Tagger.Out]'
want_code  = 'call-arg'
want_sub   = 'Unexpected keyword'

dimos/pure/test_typing_static.py:173: AssertionError
dimos.pure.test_typing_static::test_fixture_expectations[case_twin.py]
Stack Traces | 0.001s run time
case = 'case_twin.py'
diagnostics = {'__strays__': [], 'case_arity.py': [], 'case_config_kwargs.py': [], 'case_config_real.py': [], ...}

    @pytest.mark.parametrize("case", CASES)
    def test_fixture_expectations(case, diagnostics):
        exp_errors, exp_reveals = _expected(case)
        act_errors, act_reveals, problems = _actual(case, diagnostics[case])
    
        for line, revealed in sorted(act_reveals.items()):
            want = exp_reveals.pop(line, None)
            if want is None:
                problems.append(f"line {line}: unmarked reveal {revealed!r}")
            elif revealed != want:
                problems.append(f"line {line}: revealed {revealed!r}, marker says {want!r}")
        for line, want in sorted(exp_reveals.items()):
            problems.append(f"line {line}: marker expects reveal {want!r}, mypy emitted none")
    
        for line, (code, msg) in sorted(act_errors.items()):
            want = exp_errors.pop(line, None)
            if want is None:
                problems.append(f"line {line}: unmarked error [{code}] {msg}")
            else:
                want_code, want_sub = want
                if code != want_code:
                    problems.append(f"line {line}: error code [{code}], marker says [{want_code}]")
                if want_sub not in msg:
                    problems.append(f"line {line}: {want_sub!r} not in message {msg!r}")
        for line, (want_code, want_sub) in sorted(exp_errors.items()):
            problems.append(f"line {line}: marker expects [{want_code}] {want_sub!r}, no error emitted")
    
>       assert not problems, f"{case}:\n  " + "\n  ".join(problems)
E       AssertionError: case_twin.py:
E           line 74: marker expects [arg-type] 'incompatible type', no error emitted
E       assert not ["line 74: marker expects [arg-type] 'incompatible type', no error emitted"]

act_errors = {}
act_reveals = {}
case       = 'case_twin.py'
diagnostics = {'__strays__': [], 'case_arity.py': [], 'case_config_kwargs.py': [], 'case_config_real.py': [], ...}
exp_errors = {74: ('arg-type', 'incompatible type')}
exp_reveals = {}
line       = 74
problems   = ["line 74: marker expects [arg-type] 'incompatible type', no error emitted"]
want_code  = 'arg-type'
want_sub   = 'incompatible type'

dimos/pure/test_typing_static.py:173: AssertionError
dimos.pure.test_typing_static::test_fixture_expectations[case_variance.py]
Stack Traces | 0.001s run time
case = 'case_variance.py'
diagnostics = {'__strays__': [], 'case_arity.py': [], 'case_config_kwargs.py': [], 'case_config_real.py': [], ...}

    @pytest.mark.parametrize("case", CASES)
    def test_fixture_expectations(case, diagnostics):
        exp_errors, exp_reveals = _expected(case)
        act_errors, act_reveals, problems = _actual(case, diagnostics[case])
    
        for line, revealed in sorted(act_reveals.items()):
            want = exp_reveals.pop(line, None)
            if want is None:
                problems.append(f"line {line}: unmarked reveal {revealed!r}")
            elif revealed != want:
                problems.append(f"line {line}: revealed {revealed!r}, marker says {want!r}")
        for line, want in sorted(exp_reveals.items()):
            problems.append(f"line {line}: marker expects reveal {want!r}, mypy emitted none")
    
        for line, (code, msg) in sorted(act_errors.items()):
            want = exp_errors.pop(line, None)
            if want is None:
                problems.append(f"line {line}: unmarked error [{code}] {msg}")
            else:
                want_code, want_sub = want
                if code != want_code:
                    problems.append(f"line {line}: error code [{code}], marker says [{want_code}]")
                if want_sub not in msg:
                    problems.append(f"line {line}: {want_sub!r} not in message {msg!r}")
        for line, (want_code, want_sub) in sorted(exp_errors.items()):
            problems.append(f"line {line}: marker expects [{want_code}] {want_sub!r}, no error emitted")
    
>       assert not problems, f"{case}:\n  " + "\n  ".join(problems)
E       AssertionError: case_variance.py:
E           line 76: marker expects [arg-type] 'incompatible type', no error emitted
E           line 77: marker expects [arg-type] 'incompatible type', no error emitted
E       assert not ["line 76: marker expects [arg-type] 'incompatible type', no error emitted", "line 77: marker expects [arg-type] 'incompatible type', no error emitted"]

act_errors = {}
act_reveals = {}
case       = 'case_variance.py'
diagnostics = {'__strays__': [], 'case_arity.py': [], 'case_config_kwargs.py': [], 'case_config_real.py': [], ...}
exp_errors = {76: ('arg-type', 'incompatible type'), 77: ('arg-type', 'incompatible type')}
exp_reveals = {}
line       = 77
problems   = ["line 76: marker expects [arg-type] 'incompatible type', no error emitted", "line 77: marker expects [arg-type] 'incompatible type', no error emitted"]
want_code  = 'arg-type'
want_sub   = 'incompatible type'

dimos/pure/test_typing_static.py:173: AssertionError
dimos.pure.test_typing_static::test_gate_excludes_fixtures
Stack Traces | 0.112s run time
def test_gate_excludes_fixtures():
        """Recursive discovery (what the gate does) must not see the fixtures.
    
        If this fails, the deliberate type errors in test_typing_fixtures/ are
        about to break the repo mypy gate: the dir no longer matches the
        `.*/test_.` exclude in pyproject.toml.
        """
        proc = _run_mypy([FIXTURES_REL])
        out = proc.stdout + proc.stderr
>       assert proc.returncode == 2 and "no .py[i] files" in out, out
E       AssertionError: .../dimos/dimos/.venv/bin/python: No module named mypy
E         
E       assert (1 == 2)
E        +  where 1 = CompletedProcess(args=['.../dimos/dimos/.venv/bin/python', '-m', 'mypy', '--config-file', 'pyproject.toml', '--cache-dir', '/tmp/dimos-pure-typing-fixtures.mypy_cache', '--no-error-summary', '--no-color-output', 'dimos/pure/test_typing_fixtures'], returncode=1, stdout='', stderr='.../dimos/dimos/.venv/bin/python: No module named mypy\n').returncode

out        = '.../dimos/dimos/.venv/bin/python: No module named mypy\n'
proc       = CompletedProcess(args=['.../dimos/dimos/.venv/bin/python', '-m', 'mypy', '--config-file', 'pyproject.tom...g_fixtures'], returncode=1, stdout='', stderr='.../dimos/dimos/.venv/bin/python: No module named mypy\n')

dimos/pure/test_typing_static.py:190: AssertionError
dimos.pure.test_typing_static::test_fixture_expectations[case_arity.py]
Stack Traces | 0.117s run time
case = 'case_arity.py'
diagnostics = {'__strays__': [], 'case_arity.py': [], 'case_config_kwargs.py': [], 'case_config_real.py': [], ...}

    @pytest.mark.parametrize("case", CASES)
    def test_fixture_expectations(case, diagnostics):
        exp_errors, exp_reveals = _expected(case)
        act_errors, act_reveals, problems = _actual(case, diagnostics[case])
    
        for line, revealed in sorted(act_reveals.items()):
            want = exp_reveals.pop(line, None)
            if want is None:
                problems.append(f"line {line}: unmarked reveal {revealed!r}")
            elif revealed != want:
                problems.append(f"line {line}: revealed {revealed!r}, marker says {want!r}")
        for line, want in sorted(exp_reveals.items()):
            problems.append(f"line {line}: marker expects reveal {want!r}, mypy emitted none")
    
        for line, (code, msg) in sorted(act_errors.items()):
            want = exp_errors.pop(line, None)
            if want is None:
                problems.append(f"line {line}: unmarked error [{code}] {msg}")
            else:
                want_code, want_sub = want
                if code != want_code:
                    problems.append(f"line {line}: error code [{code}], marker says [{want_code}]")
                if want_sub not in msg:
                    problems.append(f"line {line}: {want_sub!r} not in message {msg!r}")
        for line, (want_code, want_sub) in sorted(exp_errors.items()):
            problems.append(f"line {line}: marker expects [{want_code}] {want_sub!r}, no error emitted")
    
>       assert not problems, f"{case}:\n  " + "\n  ".join(problems)
E       AssertionError: case_arity.py:
E           line 57: marker expects [arg-type] 'incompatible type', no error emitted
E           line 58: marker expects [arg-type] 'incompatible type', no error emitted
E       assert not ["line 57: marker expects [arg-type] 'incompatible type', no error emitted", "line 58: marker expects [arg-type] 'incompatible type', no error emitted"]

act_errors = {}
act_reveals = {}
case       = 'case_arity.py'
diagnostics = {'__strays__': [], 'case_arity.py': [], 'case_config_kwargs.py': [], 'case_config_real.py': [], ...}
exp_errors = {57: ('arg-type', 'incompatible type'), 58: ('arg-type', 'incompatible type')}
exp_reveals = {}
line       = 58
problems   = ["line 57: marker expects [arg-type] 'incompatible type', no error emitted", "line 58: marker expects [arg-type] 'incompatible type', no error emitted"]
want_code  = 'arg-type'
want_sub   = 'incompatible type'

dimos/pure/test_typing_static.py:173: AssertionError

To view more test analytics, go to the Test Analytics Dashboard
📋 Got 3 mins? Take this short survey to help us improve Test Analytics.

leshy added 16 commits June 11, 2026 19:26
…module

MarkerDetectionPureModule sits next to MarkerDetectionStreamModule
(untouched): the per-frame TF lookup becomes a declared
interpolate(tolerance=0.5) camera_pose input, QualityWindow/SpeedLimit
config knobs become upstream stream composition, and the
emit_empty_frames sentinel plumbing reduces to step() returning the
(possibly empty) Detection3DArray. smoothing_window is deliberately out
of scope — it is recurrent state and maps to an explicit Mealy state
parameter. Also: PureModule.offline() now returns Self.
Runnable Navigator example in the gentle intro (two Out ports, partial
emission, slicing one output back out of the offline dict rows) and a
proper Outputs section in the reference covering single/multi/None/
partial semantics, where outputs land per mode, and the dict-row vs
per-port asymmetry as a known open point. Also fixes a map_data misuse
hiding in a skip block — the callable receives the observation, not data.
docs/usage/pure_modules.md is now the single user-facing document:
runnable tutorial followed by a Reference part with the exact rules
(declaration/binding, alignment semantics, outputs, over(), deployment
knobs, health). dimos/memory2/puremodule.md shrinks to design notes —
the why behind ticks/backpressure/health, replay fidelity under drops,
the state persistence journal plan, the run-handle plan, and the
deferred list. No more duplicated tables; architecture.md links both.
The detached HealthMonitor in the contracts section looked like it was
monitoring something; say explicitly that modules construct their own
from config at start() (module.health_monitor), and the demo hand-feeds
one to show the messages a deployed Follower would produce.
…iter

Health contracts gain scale-free forms: max_drop_ratio (the step keeps
up, independent of deployment rates), max_missing_ratio (the hardcoded
>50% staleness rule made configurable), and max_tick_latency_s over a
new end-to-end latency metric — trigger arrival to outputs published,
covering queue wait + alignment + buffer + step. Latency is the felt
consequence of queue growth under any backpressure policy, so queue
depth stays a diagnostic gauge rather than a contract. Ratio contracts
evaluate only above ratio_min_samples: tiny windows are noise and zero
traffic passes vacuously, so the absolute contracts remain the liveness
floor.

Multi-output ergonomics: the reserved `out` writer parameter on step —
assignment emits, skipping a port stays quiet, unknown ports raise at
the assignment line, last write wins. With `out`, stateless steps return
None and stateful steps return just new_state (no more (state, dict)
tuple). The dict return stays as the low-level equivalent; single-output
bare return is unchanged. Outputs is exported for annotation and is the
seam for typed Out bundles later — design notes record the agreed
bundle/structural-wiring direction, the flat-syntax-as-anonymous-bundle
compatibility rule, and the contracts-on-inputs-vs-outputs rationale.

Docs: health/contracts section rewritten from the deployment perspective
around a captured log transcript; contracts table in the reference;
Navigator example switched to the writer form.
Usage doc gains the second captured transcript — a heavy step that keeps
the absolute 10 Hz contract while drop-ratio and tick-latency catch it —
plus ratio/latency examples in the deployment block and recompute
semantics for projected multi-output streams. Design notes: the agreed
nested In/Out bundle design (annotation injection, nested-XOR-flat rule,
binding by annotation, tick-row synergy, stated trade-offs).
- mypy-exclude puremodule_api_sketch.py and ignore it in blueprint
  scanning (incl. the name-closure, which its Captioner collision was
  poisoning with every VL model); exclude PureModule as a framework base
- commit pure_modules_dag.svg referenced by docs/usage/pure_modules.md
- drop __all__, mark re-exports with the 'as' form, delete dead
  logging.getLogger in tick.py
- regenerate all_blueprints.py (adds marker-detection-pure-module)
- scrub stale deployment-override docstrings and doc drift
…ency

- stop() drains and joins the tick threads before super().stop() disposes
  the store; store disposable registered after the input subscriptions so
  a recording store outlives ingest and the final flush (new
  test_stop_records_the_tail proves the tail survives a mid-flow stop)
- HealthMonitor report path and state/latest properties now hold the lock;
  sink runs outside it
- tick latency measured from trigger arrival (_arrival_ts stamp), so
  latency contracts stay meaningful when input_sources feed a recording
- MarkerDetectionPureModule.camera_info is required; width mismatch warns
  once instead of per-frame debug; NDArray annotations
- drop dead TickMachine.end_of_stream, warn on unresolvable step() hints,
  complete the spec re-export (Outputs, contract), scrub stale health.py
  docstrings and change-history narration, test Bounded/DropNew.clone()
@github-actions

Copy link
Copy Markdown
Contributor

This pull request has been automatically marked as stale because it has not had recent activity. It will be closed in 7 days if no further activity occurs.

@github-actions github-actions Bot added the stale label Jul 18, 2026
leshy added 9 commits July 19, 2026 18:19
Sketch 3 (+rpc variant) as source of truth for the pure-modules layer,
dimos/pure/tasks/index.md with per-task boundaries + status pipeline;
mypy exclude widened to cover all design-sketch files.
Sketch 3 (+rpc) is the source of truth; older iterations only confuse
planning agents.
Protocols (Stateless/AsyncStateless/Mealy/Fold, positional-only data
params), EngineSurface with the over() overload set, m.i/m.o port
accessor descriptors, and a mypy-under-pytest harness: 15 marker-driven
fixtures + 4 guard tests, one batched mypy run, gate-invisible by
layout. Spec in dimos/pure/tasks/t4-typing.md.
leshy added 16 commits July 20, 2026 18:01
Implement PureGraph.blueprint() (§7.2): lower a built GraphPlan onto the
existing coordinator via the T8 legacy bridge. Each member deploys through
legacy_blueprint (one process); the graph's explicit edges GENERATE the
wiring — interior producers path-qualify their topic and consumers join it,
name-crossing edges become .remappings entries, rim In/Out stay exposed
(bare) to link by the autoconnect (name,type) convention. tf edges ride the
shared tf rail. Composes with autoconnect/.namespace/.remappings, no fork.

Add TwistUnstamp (§0.4): TwistStamped -> Twist translator so a stamped pure
command drives a legacy In[Twist] sink without covariant matching.

Tests: NavStack §7.3 structural lowering, combined GO2+NavStack blueprint
(name+type link, no conflicts), translator row-level + bridgeability, a
scaled-down live graph-beside-legacy coordinator deploy (test_legacy), and a
data-gated/CI-skipped GO2 --replay grounding deploy. Regenerate all_blueprints
for TwistUnstamp. mypy --strict clean; 538 pure tests pass.
_lower_blueprint generates coordinator wiring from the plan's explicit edges:
each member via legacy_blueprint (one worker), rim In/Out exposed bare, interior
edges path-qualified, name-crossing edges -> remappings, tf edges ride the tf
rail — reusing autoconnect().remappings().namespace(expose=). TwistUnstamp
translator (TwistStamped->Twist, §0.4). Grounding: live cross-worker deploy
proven (echo graph + legacy pinger, data both directions); full GO2 --replay
deploys+wires (5 workers) but end-to-end costmap emit deferred (rim/replay
timing, not the lowering). 539 passed, mypy clean.
Planner/NavStack take a bare point goal (goal_point: PointStamped, e.g. a rerun
click) instead of a PoseStamped goal; step converts to Vector3 for A*. New
dimos/pure/modules/go2_nav.py: GO2Connection + go2 rerun renderer + click server
+ NavStack graph, autoconnected, runnable live or --replay (clicked_point remaps
onto goal_point). example_hk_nav/tests updated. 539 passed, mypy clean.
… bug)

The go2_hongkong_office recording carries a Go2-firmware-corrupt lidar scan
stamped ~75 days in the future. The aligner accepted it (it passed the
monotonic gate as a forward jump), latching the tick port's frontier to the
garbage ts; every subsequent correctly-timed scan then failed `ts <= last_ts`
and was dropped forever, starving the fold — the pure NavStack /map died
mid-run in the multiprocess deployment while delivery kept flowing. Legacy
replay was immune (no monotonic gate).

Add a forward-outlier gate in Aligner.__next__: a sample jumping more than
_FUTURE_TS_OUTLIER_S (3600s) past a finite port frontier is dropped WITHOUT
advancing the frontier, with a warning naming the firmware bug. Marked
TEMPORARY — remove once recordings/firmware carry sane stamps.
Adds run_pure(): mem2 db -> NavStack.over(...) -> NavRerunSink via .save(),
so the recorded lidar/odom drive the graph in-process with no wall clock in
the data path — the DAG computes once and map/costmap/path fan into a single
pure rerun consumer at native rates (verified ~23x realtime on
go2_hongkong_office). --pure needs --replay; --sink chooses grpc/spawn.
Deploy mode (coordinator) unchanged.
Switch the graph's mapper to the VoxelMapper2 respelling; trim a device comment.
…criptions

Two invisibility bugs that between them hid a dead costmap for hours.

drivers/resources used bare logging.getLogger(), which in a forkserver worker
resolves to an unconfigured root logger (WARNING, no handler) and drops every
line. Switch to setup_logger() — the pattern align.py and pubsubrpc.py already
use — so driver errors and resource warmup/teardown failures actually surface,
in the CLI and the worker's own jsonl.

_connect_streams now warns once, at build, listing consumer streams with no
producer in the blueprint. Autoconnect matches by a runtime (name, type) string
convention, so a renamed producer silently leaves its consumer subscribed to a
dead topic and mypy cannot see it. Non-fatal: viewers legitimately subscribe to
optional topics.
…ontrol=True)

Two live-path bugs that together killed /costmap and goal clicks in the
coordinator deploy, while --pure (in-process) worked fine.

1. A live OPTIONAL secondary parked the whole session. rim's _LiveFeed blocks in
   __next__ until data or stop, so a port wired to a real-but-silent topic never
   returned — the tick never fired and the module emitted nothing, with no error.
   PureCostMapper.merged_map is exactly that: optional, subscribed, never
   published. Add _LiveFeed.pull_nowait() and use it for optional secondaries:
   they resolve from newest/default instead of holding. The tick still blocks
   (that IS the pacing) and REQUIRED secondaries still hold (spec §5). Plain
   iterators have no pull_nowait, so offline over() keeps its deterministic
   blocking merge.

2. latest(control=True) for out-of-band control input. A click is stamped with
   the browser's wall clock; under replay that is ~75 days past the data clock,
   so it is never the merge minimum, never promoted to newest, and resolves to
   its default forever — silently. Control ports are re-stamped to the tick
   frontier on arrival (payload untouched, only the merge key). Planner.goal_point
   uses it. Measurements are unaffected: the flag is opt-in.

Also remap the go2 renderer's global_costmap onto NavStack's costmap export —
same type, drifted name, so the viewer was subscribed to a dead topic.
…pure modules

A bridged pure module with a REQUIRED pm.tf() port drops every tick silently:
legacy.py binds only In bundle fields, and tf is a synthetic stream port, so
m.i.tf is never bound, the TfBuffer is never fed, and _fire drops each tick as
unresolved. That is why Planner emits no path in the coordinator (its position
port is required) while VoxelMapper2 maps fine (its pose port is optional) and
--pure works throughout (over() wires odom_tf.tf in-graph).

Spec records the diagnosis with line pointers and Ivan's direction: consume
TFMessage as an ordinary subscribed stream rather than via the PubSubTF service.
…2_nav --pgo

The map IS the keyframes: body clouds registered at ISAM2-optimized poses,
full grid rebuild + immediate emit per accepted loop closure. Reuses the
offline _PGOState core (new public accessors: n_keyframes/n_loops/
correction/keyframe_world_clouds) and a new VoxelGrid.reset(). Exports
correction (world_corrected <- world_raw) + GraphNodes3D/LineSegments3D
debug viz. NavStackPGO subclass (graph outputs must be wired ports, so a
subclass, not a flag); NavRerunSink moves example_hk_nav.py -> rerunsink.py
(sink only, demo runners deleted). Also: silent-CPU device fix
("GPU:0" -> "CUDA:0"), VoxelMapper2 startup log ungated.

hk office full run: 40 loop closures, 14 scans/s vs ~8 Hz live, final map
0.77/0.91 within 1/2 voxels of the offline two-pass reference.
T15 (debugrec.py): per-module flight recorder + deterministic replay.
Decisions/rows/state layers into one mem2 debug.db per run (module-path-
dotted streams; validate_identifier relaxed to allow dots, all SQL sites
audited); bounded ring on the tick path, drained inline per tick-attempt
batch under over() and by the pacer live; reader with summary()/drops()/
replay()/fixture(); pm.Debug/debug_load/debug_latest; `dimos pure debug`
CLI. Silent zero-rows runs now warn unconditionally at teardown.

T9 (health.py): live-liveness-only Health — wall-stamped row carrying the
data-time frontier_ts watermark (lag = ts - frontier_ts is the stall
signature; joins on frontier only). HealthCounters is the single
aggregation shared with ModuleDebug.summary() (post-hoc == live by
construction). Rim-owned HealthPacer absorbs T15's ring drain (interim
pacer retired); flat wire row + full-fidelity HealthRecord storage split;
legacy HealthPlaceholder swapped for the real type; health_hz on
PureModuleConfig. Off under over(): eval perf is a T15 query (step_ms
distribution + data-time contract cadence).

Aligner robustness (found building PGO): the required-tf hold is bounded
at tick_ts + horizon (one pre-tf-stream tick used to drain the ENTIRE tf
stream into eviction and silently starve every later tick); tf ingestion
gets the ports' >1h future-ts guard (one corrupt stamp latched the
frontier forever and expired the edge history). Both now warn.

Task docs: t15 (done, incl. field-found drain-cadence + test-isolation
fixes), t9 (done), t16 run-dirs design (GO, unimplemented), pure
retrospective + scalar-output design notes.
Optional Mealy-only `def finish(self, s: State) -> Out | None`, called
exactly once on graceful exhaustion (never on early close, error unwind,
or an empty stream), stamped from the last consumed tick's ts — the tail
emission fold always had. stepspec classifies + validates it
([finish-not-mealy]/[finish-params]/[finish-state]/[finish-return]...);
drive_mealy owns the call, so over(), graph terminal drives, and the live
rim all deliver the tail through the normal out-row path (T15 records it
in the OUT layer under the last tick's seq; no TickDecision; replay does
not re-fire it).

VoxelMapper2.finish flushes the trailing partial batch — fold vs Mealy is
now FULLY parity (hk slice: both emit the 298 tail, voxel-identical),
which also un-sticks test_over_matches_hand_chaining. PGOVoxelMapper
.finish emits the final corrected map + viz unless the last cadence tick
already did.
…symlink

mint_run_dir(label): global counter claimed race-safely via
mkdir(exist_ok=False) retry, slugged label, set_run_log_dir routing
(main.jsonl + DIMOS_RUN_LOG_DIR for forkserver workers), and an
atomically-repointed logs/latest symlink. GlobalConfig.run_dir overrides
(absolute / relative-to-LOG_DIR / append-into-existing). Minting from
`dimos run` (dir gets the counter name; DIMOS_RUN_ID watchdog tag keeps
its own format — never parsed, only environ-matched) and go2_nav main()
in both --pure and deploy modes. debugrec's last-resort fallback now
mints a run dir instead of a shared debug.db — cross-run stream mixing
(same replay ts twice into one stream) is structurally gone;
pm.debug_latest() resolves latest -> highest-NNN -> legacy mtime.
… graphs

Graph edges deliver a member's nested field payload, and downstream
aligners align on the payload's OWN ts — but only the Out row is engine-
stamped from the tick. A payload with a wall-clock ts (Planner's Path via
min_cost_astar's time.time() default) pinned an off-scale future head and
starved the planner to 1 output over a full recording; PGOVoxelMapper's
global_map carried the grid's cached snapshot ts, which runs BACKWARDS on
a loop-closure rebuild, so the cost mapper dropped exactly the immediate
closure refreshes as nonmonotonic. The tee/round-robin distribution was
verified faithful — the currency was mis-stamped, not the delivery.

_carry_row_ts in _project (one choke point for _RunInstance exports and
_TerminalRun.save) stamps payload.ts = row.ts when they differ; rim
sources keep true acquisition ts. T13 §0.6 amendment (BINDING). Four
regression tests (frozen payload ts, wall-clock latest, burst chain,
store recording); hongkong eval: cost mapper 243/243 fired 0 dropped
(was 168 fired / 73 nonmonotonic), planner 243 attempts (was 1).

Follow-up noted in t13 §0.6: stamp Path/global_map correctly at the
producing modules too (belt and suspenders).
"tick dropped: required tf unresolvable" and the future-ts guards now
carry bundle= (the In-bundle path, e.g. ...PGOVoxelMapper.In) / owner=
(the tf claim owner) — a drop log line was previously unattributable
when two modules share a field name like 'pose'.
@mintlify

mintlify Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
dimensional 🟢 Ready View Preview Jul 22, 2026, 5:11 AM

💡 Tip: Enable Workflows to automatically generate PRs for you.

@mintlify

mintlify Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
dimensional 🟡 Building Jul 22, 2026, 5:10 AM

💡 Tip: Enable Workflows to automatically generate PRs for you.

leshy added 3 commits July 22, 2026 11:10
…cone

A graph member that ticks without emitting now yields Progress(ts) frontier
markers on its interior edges (run_over(progress=True), MEALY/STATELESS).
The aligner refill treats a marker as frontier-advance-without-sample and
stops pulling a covered latest port, so a silent producer (planner with no
reachable goal) no longer drives its upstream cone to exhaustion on the
first sink tick — the rerun burst-at-end incident. Markers never cross the
rim; save-to-store drains skip them; the module sink is now debug-recorded.
The T4 os.devnull rationale (<1 s cold) went stale once the typing fixtures
grew to import the real production graph: the cold batched mypy hit 34.8 s,
54% of the pure suite's wall time. A dedicated cache dir (isolated from the
gate's .mypy_cache) brings the harness to ~3 s warm; assertions unchanged.
…save()

save()/record= now resolve rim input names (the source stream tees a record
branch), so NavRerunSink drives on the raw scan stream: lidar-rate frames,
map/costmap/path demoted to change-detected latest logging (each distinct
sample logged once — re-presenting the newest map 30x per emission would
bloat the recording). village3: 701 scan frames rendered vs 43 before.
@github-actions github-actions Bot removed the stale label Jul 23, 2026
leshy added 2 commits July 23, 2026 15:14
…mory2

The v1 PureModule (memory2/puremodule.py + tick.py + health.py) was the
earlier sketch of this architecture; dimos/pure supersedes it end to end,
including deployment (rim + the legacy_actor bridge). Nothing in dimos/pure
ever imported it — only memory2's store/stream, which are untouched.

Removed with its dependents: the spec re-export shim, the marker-detection
experiment that ran parallel to the stream module, and docs/usage/pure_modules.md
(it documents the v1 API — class-attr inputs, Outputs, window() — none of which
survive on the pm surface). New-architecture docs land separately.

Moved puremodule_api_sketch3_rpc.py to dimos/pure — it is forward design for
the un-built RPC wave, so it belongs beside the other pure sketches.

memory2 keeps exactly one change, the one the new engine needs: dot-separated
stream names, so debugrec can namespace by module path (<path>.raw.<port>).

buffer.clone() goes too — only the v1 tick buffer ever called it.

all_blueprints loses every dimos.pure.modules entry: those were an artifact of
v1's `class PureModule(Module)` seeding the generator's AST closure. The pure
modules are not dimos.core Modules (mro: PureModule -> EngineSurface), so they
were never deployable through the registry; graph blueprint() lowering is
Phase B. Regenerated, so the file now matches main.
leshy added 4 commits July 23, 2026 16:15
The pure engine was opted out of six repo-wide checks. Conform instead of
exempting.

The pm surface moves from dimos/pure/__init__.py to dimos/pure/pm.py: a plain
module, so importing a submodule no longer drags the whole surface in, and the
package becomes a namespace package. Callers say `from dimos.pure import pm`;
every `pm.X` reference is untouched. Re-exports take the `X as X` form (two
renamed ones carry noqa: F401), which is also what lets other modules import
names from it.

dimos/pure/modules/__init__.py is deleted outright — its lone re-export had no
importers; the two consumers already import the submodules directly.

__all__ goes from 25 files. Two tests read it as their surface lock: pm's now
computes the public namespace (equivalent, since every binding is a re-export),
and T4's spells its ten names out.

test_costmapper built the legacy CostMapper via __new__ to dodge its ctor. The
ctor takes flat config kwargs and works fine — it just spins up transport
threads, so the parity helper now disposes it. test_graph's Phase-C stub test
used object.__new__(PureGraph) with a "no subclass is definable pre-impl"
comment that stale-dated itself; _Fan is right there in the file.

`_ = expr` side-effect probes become bare accesses with noqa: B018.

Also unstales the NavStack lowering tests: they still expected the member name
voxel_mapper, but the graph derives names from the class and NavStack wires
VoxelMapper2 — so nav_stack/voxel_mapper2 is what lowering correctly produces.

mypy clean; suite 3741 passed. The one remaining failure, test_no_sections, is
290 markers inside the untracked dimos-viewer/ checkout — no tracked file.
11.4k lines of internal working specs across 16 files. They're the drafting
notes the engine was built from, not a deliverable, so they stay out of the PR
and live on untracked in the working tree.

Nothing reads them at runtime — every remaining reference is docstring prose
("Spec: dimos/pure/tasks/t8-rim.md §11"), and no markdown links point in, so
doclinks stays clean. Those pointers now name files the branch doesn't ship;
the text still identifies which spec section a module implements.
puregraph_api_sketch.py and puremodule_api_sketch3_rpc.py are non-functional
design drafts — the graph one is superseded by the landed dimos/pure/graph.py,
the RPC one is forward design for a wave that isn't built. Both stay untracked
in the working tree; nothing imports either.

With the RPC sketch gone the blueprint generator needs no special-casing, so
both accommodations revert to main: its IGNORED_FILES entry and the
IGNORED_FILES filter in _build_module_class_set. Regeneration is unchanged
either way — all_blueprints.py does not churn.

That leaves one real change in the generator: test-named directories are not
production module files, so dimos/pure/test_typing_fixtures/ stops registering
its fixture classes.
api_improvements.md (field notes from the PGOVoxelMapper session) and
number_problem.md (scalars-to-rerun, implementation not started) are working
notes like the task specs and API sketches before them. Untracked, still on
disk.

The three code references are docstring prose — health.py and stepspec.py cite
them for why a design is shaped the way it is — and nothing links to them, so
doclinks stays clean.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant