epic-3/story-4: Add entity lookup helpers - #36
Conversation
There was a problem hiding this comment.
Code Review
This pull request implements read-only configuration entity lookup functionality (Story 3.4 / FR28) for the Convert Python SDK, adding precomputed indexes to ConfigSnapshot and new lookup methods to Context. Feedback on the changes suggests using List instead of list in get_config_entities for type-hinting consistency, and adding a TODO comment in resolve_entities to future-proof the unresolved key filtering when _no_result() is updated to return a non-None object in a future story.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| if entity is not None: | ||
| resolved.append(entity) |
There was a problem hiding this comment.
The current implementation of resolve_entities uses if entity is not None: to filter out unresolved keys. However, the design of _no_result() (as described in its docstring) is intended to allow Story 4.2 to replace None with a typed-reason result object (which will be a non-None object). If _no_result() is changed to return a non-None object, entity is not None will evaluate to True for unresolved keys, causing the reason objects to be incorrectly appended to the resolved list instead of being skipped.
To ensure future-proofing and maintain the contract of skipping unresolved keys, consider adding a TODO comment or a helper function to ensure this check is updated when _no_result() is modified.
| if entity is not None: | |
| resolved.append(entity) | |
| if entity is not None: # TODO(Story 4.2): Update this check if _no_result() returns a non-None reason object | |
| resolved.append(entity) |
| def get_config_entities( | ||
| self, entity_type: str, keys: list[str] | ||
| ) -> list[Mapping[str, Any]]: |
There was a problem hiding this comment.
For consistency with the rest of the file (which uses capital List from typing, e.g., List[ExperienceResult]), please use List instead of the lowercase list generic type in the signature of get_config_entities.
| def get_config_entities( | |
| self, entity_type: str, keys: list[str] | |
| ) -> list[Mapping[str, Any]]: | |
| def get_config_entities( | |
| self, entity_type: str, keys: List[str] | |
| ) -> List[Mapping[str, Any]]: |
e29bd5f to
231dc35
Compare
456e2fc to
9d4e32d
Compare
Beads: ai-driven-product-dev-fiak Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…GREEN) Beads: ai-driven-product-dev-fiak Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… (RED) Beads: ai-driven-product-dev-p66d Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ation (GREEN) Beads: ai-driven-product-dev-p66d Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…GREEN) Beads: ai-driven-product-dev-uabk Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Beads: ai-driven-product-dev-1apb Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
9d4e32d to
663c22b
Compare
F-066 propagation (rebase onto remediated 3-3)Rebased onto the remediated
|
|
Superseded — all commits already in main (bc76b64). Closing without merge as part of post-sprint cleanup. |
Story 3.4 — Add Entity Lookup Helpers (FR28)
Adds the read-only entity-lookup surface over the Story 1.2 immutable indexed
ConfigSnapshot. Part of sprintsprint/2026-04-06-convert-python-sdk.What was built
Context.get_config_entity(entity_type, key),get_config_entities(entity_type, keys),get_config_entity_by_id(entity_type, entity_id)— Pythonic snake_case public lookup methods returning typed domain entities (never raw transport dicts),None/empty on miss.evaluation/entity_lookup.py(NEW, L2) — dedicated resolver with a single localized_no_result()decision point so Story 4.2 can swapNone→ the FR50 typed-reason result without changing the hit return.Contextstays a thin orchestrator delegating to it.domain/config_snapshot.py— reused Story 1.2's by-key index; added only the missing_goals_by_id,_segments_by_key,_segments_by_idat construction time (no parallel index, no per-lookup rebuild).SUPPORTED_ENTITY_TYPESvocabulary; unknown/unsupportedentity_typeyields the sameNone/empty no-result (never a crash, never a sentinel string).Scope discipline
EntityTypeenum introduced).Tests — zero regressions
tests/test_layering.py(import-linter not installed):entity_lookup.pyL2 clause +config_snapshot.pyL0-clean clause.Beads
Epic
ai-driven-product-dev-d09w; tasks-fiak(SDK-1 indexes),-p66d(SDK-2 resolver),-uabk(SDK-3 Context surface),-1apb(SDK-4 layering+integration) — all closed.Readiness & review
Readiness PASS 9/10, 0 auto-delegations (well-formed standalone story, no audit findings). Code review clean round 1.
Stacked on epic-3/story-3 (#35 → #34 → #33 chain).
🤖 Generated with Claude Code