hamza.khyari
45c15bcc1a
fix(migration): chain m6_004 after m7_001_repo_indexing_tables to resolve multiple heads
...
CI / benchmark-publish (pull_request) Has been skipped
CI / lint (pull_request) Successful in 15s
CI / build (pull_request) Successful in 17s
CI / quality (pull_request) Successful in 17s
CI / security (pull_request) Successful in 34s
CI / typecheck (pull_request) Successful in 37s
CI / unit_tests (pull_request) Successful in 2m35s
CI / integration_tests (pull_request) Successful in 3m7s
CI / docker (pull_request) Successful in 40s
CI / coverage (pull_request) Successful in 4m56s
CI / benchmark-regression (pull_request) Successful in 31m53s
m6_004_resource_type_inherits and m7_001_repo_indexing_tables both had
down_revision='m6_003_async_jobs_table', creating two Alembic heads.
Chain m6_004 after m7_001 so the migration graph is linear.
2026-03-10 04:10:58 +00:00
hamza.khyari
135481f9a6
fix(resource): address PR #618 review findings (round 1)
...
CI / benchmark-publish (pull_request) Has been skipped
CI / lint (pull_request) Successful in 14s
CI / quality (pull_request) Successful in 18s
CI / build (pull_request) Successful in 16s
CI / unit_tests (pull_request) Failing after 25s
CI / security (pull_request) Successful in 34s
CI / typecheck (pull_request) Successful in 36s
CI / docker (pull_request) Has been skipped
CI / coverage (pull_request) Failing after 25s
CI / integration_tests (pull_request) Failing after 2m19s
CI / benchmark-regression (pull_request) Has been cancelled
- P2-1: Add field_validator('inherits') on ResourceTypeSpec
- P2-2: Remove 'properties' from _COLLECTION_FIELDS (scalar override)
- P2-3: Add behave scenarios for exception rollback paths
- P2-4: Add ordering comment to BUILTIN_TYPES
- P2-5: Define RegistryHost Protocol, remove type:ignore on mixins
- P2-6: Add if_not_exists=True on migration index creation
- P3-1: Use deque.popleft() in get_ancestors for O(1) BFS
- P3-2: Filter private attrs in _to_dict vars() fallback
- P3-3: Replace _handler_cache import with clear_handler_cache()
- P3-4: Add migration downgrade test for m6_004
- P3-5: Extract ResourceDagMixin to _resource_registry_dag.py
All files remain under 500-line CONTRIBUTING limit.
Lint, typecheck, and 85 behave scenarios pass.
2026-03-10 04:06:02 +00:00
hamza.khyari
ab4da7804d
test(resource): add diff-coverage BDD scenarios for inheritance service and resolver
...
CI / benchmark-publish (pull_request) Has been skipped
CI / lint (pull_request) Successful in 15s
CI / build (pull_request) Successful in 16s
CI / quality (pull_request) Successful in 22s
CI / unit_tests (pull_request) Failing after 26s
CI / security (pull_request) Successful in 35s
CI / typecheck (pull_request) Successful in 37s
CI / docker (pull_request) Has been skipped
CI / coverage (pull_request) Failing after 23s
CI / integration_tests (pull_request) Failing after 2m19s
CI / benchmark-regression (pull_request) Has been cancelled
Add 21 scenarios covering uncovered paths in:
- resource_registry_service.py: register_type inherits validation,
remove_type guards, resolve_chain, is_subtype_of (76% -> 95%)
- resolver.py: import error, instantiation, protocol check,
polymorphic chain walk (77% -> 98%)
- _resource_registry_ops.py: exact filter, child type mismatch,
tree type_filter (95% -> 98%)
- inheritance.py: _merge_dict, resolve_fields gap (96% -> 99%)
Overall project coverage holds at 97%.
2026-03-10 03:39:32 +00:00
hamza.khyari
bebe91e0a7
fix(resource): add defensive copies for capabilities/auto_discovery/equivalence in as_cli_dict
...
Complete F24 fix: capabilities, auto_discovery, and equivalence dicts
were returned as direct references. Now wrapped with dict() to
prevent callers from mutating internal state.
2026-03-10 03:39:32 +00:00
hamza.khyari
ce1536c4c4
refactor(resource): split resource_registry_service into 3 modules (<500 LOC each)
...
Extract data helpers (_resource_registry_data.py, 389 lines) and
operation mixins (_resource_registry_ops.py, 497 lines) from the
1247-line resource_registry_service.py, reducing it to 467 lines.
All three modules stay under the 500-line CONTRIBUTING limit.
Backward-compat aliases (_spec_to_db, _db_to_spec) are re-exported
from the main module so existing test imports continue to work.
Addresses review finding F8 for PR #618 .
2026-03-10 03:39:32 +00:00
hamza.khyari
23d8a53f6a
fix(resource): address review findings for resource type inheritance
...
Fix 25 of 27 review findings from PR #618 code review:
P1 (Must Fix):
- F3: Fix silent data corruption in _merge_collection for properties
dict fields (was falling through to string list merge)
- F1: Split 1023-line step file into 3 files + helper module (all <500)
- F4: Add SELECT FOR UPDATE lock on parent type in register_type to
prevent TOCTOU race in concurrent registrations
- F6: Fix docs claiming exceptions inherit from CleverAgentsError
(they inherit from ValueError)
- F7: Fix docs incorrectly describing validate_chain return type
P2 (Should Fix):
- F9: Replace dict[str, Any] with TypeRegistryMap type alias
- F10: Replace import logging with structlog in inheritance.py
- F11: Add __all__ to inheritance.py
- F13: Fix _load_type_registry to derive built_in from namespace column
- F14: Add warning log for unregistered types in resolve_inheritance_chain
- F15: Return defensive copies from resolve_fields
- F16: Add chain validation to bootstrap_builtin_types
- F17: Narrow except Exception to specific types in step files
- F18: Add side-effect verification scenarios after error cases
- F19: Always include inherits key in JSON output for consistent schema
- F20: Log actual exception instead of hardcoded string in CLI
P3 (Nit):
- F21: Reject whitespace-only inherits values in validate_chain
- F23: Wrap chain errors in HandlerResolutionError in resolver
- F24: Return defensive copies from as_cli_dict
- F25: Replace tautological assertion with ResourceHandler isinstance
- F26: Add whitespace inherits test scenario
- F27: Fix find_subtypes docstring to note it excludes ancestor_name
Deferred:
- F2: type: ignore in step files — pyright only checks src/, matches
existing project pattern (91 occurrences in resource_dag_steps.py)
- F5: CLI integration tests require full DI container setup
- F8: resource_registry_service.py size is pre-existing (971 on master)
- F12: Coverage boost file changes are test adaptations, not scope creep
- F22: FK constraint intentionally omitted per docs (SQLite compat)
2026-03-10 03:39:32 +00:00
hamza.khyari
bb8175aa11
feat(resource): add resource type inheritance and polymorphic tool matching
...
Implement ADR-042 single-inheritance for resource types with polymorphic
tool and handler resolution.
Core changes:
- Add `inherits` field to ResourceTypeConfigSchema, ResourceTypeSpec, and
ResourceTypeModel with chain depth validation (max 5), circular
inheritance detection, and built-in-from-custom guard
- New inheritance.py module (390 lines): resolve_inheritance_chain(),
validate_chain(), is_subtype_of(), resolve_fields(), find_subtypes()
- Wire inheritance into ResourceRegistryService: chain validation on
register_type(), resolve_type_inheritance_chain(), is_subtype_of()
- Add find_tools_for_resource() to ToolRegistry with polymorphic matching
that walks the inheritance chain
- Add resolve_handler_polymorphic() to handler resolver
- Alembic migration m6_004_resource_type_inherits adds inherits column
and index to resource_types table
CLI changes:
- `agents resource type list` shows Inherits column
- `agents resource type show` displays inheritance chain
Tests:
- 30 BDD scenarios in resource_type_inheritance.feature (all pass)
- 18 Robot Framework test cases
- 14 ASV benchmark timing methods across 4 suites
Docs:
- docs/reference/resource_type_inheritance.md (full reference)
- Updated docs/schema/resource_type.schema.yaml
- CHANGELOG entry for #513
ISSUES CLOSED : #513
2026-03-10 03:39:32 +00:00