Skip to content

test: malformed-template fixture uses an unbalanced group - #51

Closed
JarbasAl wants to merge 1 commit into
devfrom
fix/malformed-template-fixture
Closed

JarbasAl wants to merge 1 commit into
devfrom
fix/malformed-template-fixture

Conversation

@JarbasAl

@JarbasAl JarbasAl commented Sep 8, 2026

Copy link
Copy Markdown
Member

🤖 Auto-generated by Claude Fable 5.1 (claude-fable-5-1) via Claude Code — NOT human-reviewed. Verify before acting.

What changed. Three tests in TestMalformedTemplateTolerance fail on dev. Their fixture line estou cansad(e) was chosen as a malformed template, but ovos-spec-tools since 1.10.7a1 (its PR #131) folds a single-branch group to its bare branch under OVOS-INTENT-1 §3.6, so the line now expands to estou cansade and never reaches the literal-line fallback in IntentContainer._expand_or_literal. The fallback itself is untouched and still works.

  • The tolerance tests use estou cansad(e (unbalanced group), which ovos-spec-tools still rejects as MalformedTemplate.
  • One new test asserts the fold: estou cansad(e) registers as estou cansade.
  • The ovos-spec-tools floor moves to >=1.10.7a1, the first release with the fold, so the new test cannot pass by accident on an older resolver pick.
  • The _expand_or_literal docstring names the unbalanced example.

Verified (model re-check, not human review). Fresh clone of origin/dev at afc4bf1, fresh venv, ovos-spec-tools 1.11.1a1: 3 failed, 3 passed in the class before; 156 passed, 2 skipped for the full suite after. The new fold test is a spec-conformance guard, not a regression test: it passes on dev code too, because nothing in nebulento/ changes here. The three red tests are the red-before.

Unblocks #50, whose red CI is exactly these three failures.

ovos-spec-tools folds a single-branch group to its bare branch
(OVOS-INTENT-1 §3.6), so "cansad(e)" expands to "cansade" and no longer
exercises the literal-line fallback. The tolerance tests use the unbalanced
"cansad(e" instead, one test asserts the fold, and the ovos-spec-tools floor
moves to the release that folds.
@coderabbitai

coderabbitai Bot commented Sep 8, 2026

Copy link
Copy Markdown

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Sep 8, 2026

Copy link
Copy Markdown

Ping! I've got your results right here. 🛎️

I've aggregated the results of the automated checks for this PR below.

🔍 Lint

Here's the latest update from the automation pipeline. 🏗️

ruff: issues found — see job log

📋 Repo Health

Checking the pulse of the repository's maintenance. 💓

✅ All required files present.

Latest Version: 0.10.3a1

nebulento/version.py — Version file
README.md — README
LICENSE.md — License file (consider renaming to LICENSE)
pyproject.toml — pyproject.toml
⚠️ setup.py — setup.py
🗑️ requirements.txt — legacy: pyproject.toml is present; this file is no longer needed
CHANGELOG.md — Changelog
nebulento/version.py has valid version block markers

🔌 Skill Tests (ovoscope)

Testing the skill's response time and accuracy. ⏱️

8/20 passed, 12 failed

❌ **TestDetach** — 0/2
Test Result
test_detach_skill_removes_all_its_intents ❌ failed
test_detach_intent_prevents_match ❌ failed

test_detach_skill_removes_all_its_intents failure:

thon/3.11.16/x64/bin/python

self = <test_ovoscope_e2e.TestDetach testMethod=test_detach_skill_removes_all_its_intents>

    def test_detach_skill_removes_all_its_intents(self):
>       self._register_intent(f"{self.SKILL_ID}:hello", _HELLO_SAMPLES)

test/test_ovoscope_e2e.py:94: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <test_ovoscope_e2e.TestDetach testMethod=test_detach_skill_removes_all_its_intents>
name = 'test_skill_nebulento:hello'
samples = ['hello', 'hi', 'hey', 'greetings', 'good morning']

    def _register_intent(self, name, samples):
>       register_padatious_intent(self.bus, name, samples)
E       TypeError: register_padatious_intent() missing 1 required keyword-only argument: 'skill_id'

test/test_ovoscope_e2e.py:49: TypeError

test_detach_intent_prevents_match failure:

/opt/hostedtoolcache/Python/3.11.16/x64/bin/python

self = <test_ovoscope_e2e.TestDetach testMethod=test_detach_intent_prevents_match>

    def test_detach_intent_prevents_match(self):
>       self._register_intent(f"{self.SKILL_ID}:hello", _HELLO_SAMPLES)

test/test_ovoscope_e2e.py:86: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <test_ovoscope_e2e.TestDetach testMethod=test_detach_intent_prevents_match>
name = 'test_skill_nebulento:hello'
samples = ['hello', 'hi', 'hey', 'greetings', 'good morning']

    def _register_intent(self, name, samples):
>       register_padatious_intent(self.bus, name, samples)
E       TypeError: register_padatious_intent() missing 1 required keyword-only argument: 'skill_id'

test/test_ovoscope_e2e.py:49: TypeError
❌ **TestEntityExtraction** — 0/1
Test Result
test_entity_slot_captured_in_match ❌ failed

test_entity_slot_captured_in_match failure:

on 3.11.16 /opt/hostedtoolcache/Python/3.11.16/x64/bin/python

self = <test_ovoscope_e2e.TestEntityExtraction testMethod=test_entity_slot_captured_in_match>

    def test_entity_slot_captured_in_match(self):
>       self._register_entity("item", ["milk", "bread", "eggs", "cheese"])

test/test_ovoscope_e2e.py:111: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <test_ovoscope_e2e.TestEntityExtraction testMethod=test_entity_slot_captured_in_match>
name = 'item', samples = ['milk', 'bread', 'eggs', 'cheese']

    def _register_entity(self, name, samples):
>       register_padatious_entity(self.bus, name, samples)
E       TypeError: register_padatious_entity() missing 1 required keyword-only argument: 'skill_id'

test/test_ovoscope_e2e.py:52: TypeError
❌ **TestHierarchicalRouting** — 0/2
Test Result
test_routes_to_correct_domain ❌ failed
test_detach_skill_removes_domain ❌ failed

test_routes_to_correct_domain failure:

lcache/Python/3.11.16/x64/bin/python

self = <test_ovoscope_e2e.TestHierarchicalRouting testMethod=test_routes_to_correct_domain>

    def test_routes_to_correct_domain(self):
>       self._register_intent(f"{self.SKILL_ID}:play", _HELLO_SAMPLES)

test/test_ovoscope_e2e.py:154: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <test_ovoscope_e2e.TestHierarchicalRouting testMethod=test_routes_to_correct_domain>
name = 'media_skill_nebulento:play'
samples = ['hello', 'hi', 'hey', 'greetings', 'good morning']

    def _register_intent(self, name, samples):
>       register_padatious_intent(self.bus, name, samples)
E       TypeError: register_padatious_intent() missing 1 required keyword-only argument: 'skill_id'

test/test_ovoscope_e2e.py:149: TypeError

test_detach_skill_removes_domain failure:

on/3.11.16/x64/bin/python

self = <test_ovoscope_e2e.TestHierarchicalRouting testMethod=test_detach_skill_removes_domain>

    def test_detach_skill_removes_domain(self):
>       self._register_intent(f"{self.SKILL_ID}:hello", _HELLO_SAMPLES)

test/test_ovoscope_e2e.py:166: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <test_ovoscope_e2e.TestHierarchicalRouting testMethod=test_detach_skill_removes_domain>
name = 'media_skill_nebulento:hello'
samples = ['hello', 'hi', 'hey', 'greetings', 'good morning']

    def _register_intent(self, name, samples):
>       register_padatious_intent(self.bus, name, samples)
E       TypeError: register_padatious_intent() missing 1 required keyword-only argument: 'skill_id'

test/test_ovoscope_e2e.py:149: TypeError
❌ **TestLegacyStillConsumed** — 0/1
Test Result
test_legacy_template_registration_still_matches ❌ failed

test_legacy_template_registration_still_matches failure:

[gw2] linux -- Python 3.11.16 /opt/hostedtoolcache/Python/3.11.16/x64/bin/python

self = <test_intent4_consume_e2e.TestLegacyStillConsumed testMethod=test_legacy_template_registration_still_matches>

    def test_legacy_template_registration_still_matches(self):
        from ovoscope import register_padatious_intent
>       register_padatious_intent(self.bus, f"{self.SKILL_ID}:bye", _BYE)
E       TypeError: register_padatious_intent() missing 1 required keyword-only argument: 'skill_id'

test/end2end/test_intent4_consume_e2e.py:109: TypeError
✅ **TestNegativeKeywordTopic** — 1/1
❌ **TestRegisteredIntentMatch** — 1/5
Test Result
test_best_intent_selected_among_multiple ❌ failed
test_utterance_field_preserved ❌ failed
test_no_match_unrelated_utterance ❌ failed
test_exact_utterance_dispatches_intent ❌ failed
test_no_match_when_no_intents_registered ✅ passed

test_best_intent_selected_among_multiple failure:

self = <test_ovoscope_e2e.TestRegisteredIntentMatch testMethod=test_best_intent_selected_among_multiple>

    def test_best_intent_selected_among_multiple(self):
>       self._register_intent(f"{self.SKILL_ID}:hello", _HELLO_SAMPLES)

test/test_ovoscope_e2e.py:71: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <test_ovoscope_e2e.TestRegisteredIntentMatch testMethod=test_best_intent_selected_among_multiple>
name = 'test_skill_nebulento:hello'
samples = ['hello', 'hi', 'hey', 'greetings', 'good morning']

    def _register_intent(self, name, samples):
>       register_padatious_intent(self.bus, name, samples)
E       TypeError: register_padatious_intent() missing 1 required keyword-only argument: 'skill_id'

test/test_ovoscope_e2e.py:49: TypeError

test_utterance_field_preserved failure:

/Python/3.11.16/x64/bin/python

self = <test_ovoscope_e2e.TestRegisteredIntentMatch testMethod=test_utterance_field_preserved>

    def test_utterance_field_preserved(self):
>       self._register_intent(f"{self.SKILL_ID}:hello", _HELLO_SAMPLES)

test/test_ovoscope_e2e.py:78: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <test_ovoscope_e2e.TestRegisteredIntentMatch testMethod=test_utterance_field_preserved>
name = 'test_skill_nebulento:hello'
samples = ['hello', 'hi', 'hey', 'greetings', 'good morning']

    def _register_intent(self, name, samples):
>       register_padatious_intent(self.bus, name, samples)
E       TypeError: register_padatious_intent() missing 1 required keyword-only argument: 'skill_id'

test/test_ovoscope_e2e.py:49: TypeError

test_no_match_unrelated_utterance failure:

.11.16/x64/bin/python

self = <test_ovoscope_e2e.TestRegisteredIntentMatch testMethod=test_no_match_unrelated_utterance>

    def test_no_match_unrelated_utterance(self):
>       self._register_intent(f"{self.SKILL_ID}:hello", _HELLO_SAMPLES)

test/test_ovoscope_e2e.py:67: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <test_ovoscope_e2e.TestRegisteredIntentMatch testMethod=test_no_match_unrelated_utterance>
name = 'test_skill_nebulento:hello'
samples = ['hello', 'hi', 'hey', 'greetings', 'good morning']

    def _register_intent(self, name, samples):
>       register_padatious_intent(self.bus, name, samples)
E       TypeError: register_padatious_intent() missing 1 required keyword-only argument: 'skill_id'

test/test_ovoscope_e2e.py:49: TypeError
❌ **TestSessionBlacklist** — 0/2
Test Result
test_blacklisted_intent_is_skipped ❌ failed
test_blacklisted_skill_is_skipped ❌ failed

test_blacklisted_intent_is_skipped failure:

thon/3.11.16/x64/bin/python

self = <test_ovoscope_e2e.TestSessionBlacklist testMethod=test_blacklisted_intent_is_skipped>

    def test_blacklisted_intent_is_skipped(self):
>       self._register_intent(f"{self.SKILL_ID}:hello", _HELLO_SAMPLES)

test/test_ovoscope_e2e.py:124: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <test_ovoscope_e2e.TestSessionBlacklist testMethod=test_blacklisted_intent_is_skipped>
name = 'test_skill_nebulento:hello'
samples = ['hello', 'hi', 'hey', 'greetings', 'good morning']

    def _register_intent(self, name, samples):
>       register_padatious_intent(self.bus, name, samples)
E       TypeError: register_padatious_intent() missing 1 required keyword-only argument: 'skill_id'

test/test_ovoscope_e2e.py:49: TypeError

test_blacklisted_skill_is_skipped failure:

/Python/3.11.16/x64/bin/python

self = <test_ovoscope_e2e.TestSessionBlacklist testMethod=test_blacklisted_skill_is_skipped>

    def test_blacklisted_skill_is_skipped(self):
>       self._register_intent(f"{self.SKILL_ID}:hello", _HELLO_SAMPLES)

test/test_ovoscope_e2e.py:132: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <test_ovoscope_e2e.TestSessionBlacklist testMethod=test_blacklisted_skill_is_skipped>
name = 'test_skill_nebulento:hello'
samples = ['hello', 'hi', 'hey', 'greetings', 'good morning']

    def _register_intent(self, name, samples):
>       register_padatious_intent(self.bus, name, samples)
E       TypeError: register_padatious_intent() missing 1 required keyword-only argument: 'skill_id'

test/test_ovoscope_e2e.py:49: TypeError
✅ **TestSpecDeregister** — 2/2 ✅ **TestSpecDisableEnable** — 2/2 ✅ **TestSpecTemplateConsumed** — 2/2

🚌 Bus Coverage

Checking the structural integrity of our bus tests. 🏗️

⚠️ Bus coverage report unavailable — check the job log.

🔨 Build Tests

Checking the blueprint against the actual construction. 📐

✅ All versions pass

Python Build Install Tests
3.10
3.11
3.12
3.13
3.14

🔌 Plugin Detection

Evaluating the impact of this plugin on the ecosystem. 📉

Plugin Status: ERRORS (1)

Plugin Info:

  • Name: nebulento
  • Description: dead simple fuzzy matching intent parser

OPM Detection:

Plugin Type Wheel Editable
pipeline

Entry Point Validation:

Entry Point Type Import Interface
ovos-nebulento-hierarchical-pipeline-plugin pipeline
ovos-nebulento-pipeline-plugin pipeline ✅ 563ms

⊘ No settingsmeta.json
requires-python >=3.10 — running Python 3.11

Issues:

  • ❌ Import time for ovos-nebulento-pipeline-plugin exceeds 500ms (563ms)
  • ⚠️ No settingsmeta.json found
  • ⚠️ No settingsmeta.json found

⚖️ License Check

I've checked the compatibility of dual-licensed code. 🌓

✅ No license violations found.

Policy: Apache 2.0 (universal donor). StrongCopyleft / NetworkCopyleft / WeakCopyleft / Other / Error categories fail. MPL allowed.

🏷️ Release Preview

The roadmap for the future just got clearer. 🗺️

Current: 0.10.3a1Next: 0.10.3a2

Signal Value
Label (none)
PR title test: malformed-template fixture uses an unbalanced group
Bump alpha

✅ PR title follows conventional commit format.


🚀 Release Channel Compatibility

Predicted next version: 0.10.3a2

Channel Status Note Current Constraint
Stable Not in channel -
Testing Not in channel -
Alpha Not in channel -

Automating the path to a better future 🌈

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