[ISSUE-10] Implement domestication planner/service with approvals#77
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: eb16ac7dd8
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| metadata = { | ||
| "source_stage": "domestication", | ||
| "source_part_identity": job.part_identity, | ||
| "insert_identities": [job.part_identity], |
There was a problem hiding this comment.
Create SBOL implementation for domesticated outputs
The domestication product metadata only records identities and never provides an implementation_identity, and this service also does not create an sbol2.Implementation for the new plasmid. When this generated product is later selected by AssemblyLvl1Stage, AssemblyService._implementation_from_plasmid_record raises because it requires either metadata implementation_identity or an implementation in the source document. That makes domesticated products non-consumable in downstream assembly for runs where no pre-existing part plasmid is available.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Summary
- Fixed the domestication SBOL service to preserve all source roles by assigning the full roles list once, rather than overwriting per-loop iteration. src/buildcompiler/sbol/domestication.pyL43-L44
- Added generation and registration of an
sbol2.Implementationfor each domesticated product, wired itsbuiltfield to the generated component, and recordedimplementation_identityin product metadata for downstream assembly resolution. src/buildcompiler/sbol/domestication.pyL46-L56 - Corrected
IndexedPlasmid.identityto use the canonical identity from the created SBOL component, ensuring consistency between metadata/implementation references and stored product identity. src/buildcompiler/sbol/domestication.pyL64-L71 - Extended the domestication service unit test to verify role preservation and implementation creation/resolution behavior. tests/unit/sbol/test_domestication_service.pyL12-L40
Testing
- ✅
pytest tests/unit/sbol/test_domestication_service.py - ✅
pytest tests/unit/planning/test_domestication_planner.py tests/unit/sbol/test_domestication_service.py tests/unit/stages/test_domestication_stage.py
Committed on the current branch as:
58ccf8c - Fix domestication SBOL implementation metadata and role copying
Also created a follow-up PR message via make_pr summarizing these changes on top of the original PR.
| for role in component.roles: | ||
| product_component.roles = role |
There was a problem hiding this comment.
Copy all roles instead of overwriting in loop
Assigning product_component.roles = role inside the loop overwrites prior values, so only the last source role is retained. If a source part carries multiple ontology roles, the generated domesticated SBOL object silently drops all but one role, which can break downstream logic that depends on preserved role annotations.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
I checked the branch state, and this issue is already fixed in the current HEAD commit (b50b13f), so there was nothing additional to patch.
What I verified
- ✅
git status --short(clean working tree; no pending changes) - ✅
git log --oneline -n 5(includesb50b13f Fix domestication SBOL implementation metadata and role copying)
Because no new code changes were required, I did not create a new commit and did not call make_pr (per your workflow rules).
Motivation
Description
src/buildcompiler/planning/domestication.pyintroducingSequenceEditProposal,DomesticationPlan, andDomesticationPlannerwhich validates part roles, requires a usable DNA sequence, and detects internal BsaI motifs (GGTCTC/GAGACC) as non-mutating proposals.src/buildcompiler/sbol/domestication.pywithDomesticationJob,DomesticationSbolResult, andDomesticationServicethat emits a minimal generatedIndexedPlasmidproduct, attaches provenance (source part, backbone, reagents, and proposals), and adds SBOL objects to the target document without writing files.src/buildcompiler/stages/domestication.pythat resolves the source part, produces structuredMissingBuildInputblockers for missing backbone/reagents, enforces a hard approval gate viaRequiredApprovalfor proposed sequence edits, and indexes generated products viainventory.add_generated_product()withinsert_identitiesset to the source part identity.src/buildcompiler/planning/__init__.py,src/buildcompiler/sbol/__init__.py, andsrc/buildcompiler/stages/__init__.py, and kept changes lightweight (no Opentrons/PUDU/SBOLInventory dependencies at runtime of core imports).domestication_sequence_editand stable approval id convention isdomestication-edit:<part_identity>; sequence edits are represented asSequenceEditProposalrecords surfaced inStageResult.protocol_artifactsandRequiredApproval.metadata.Testing
tests/unit/planning/test_domestication_planner.py(planner role/sequence/bsai detection),tests/unit/sbol/test_domestication_service.py(product/provenance), andtests/unit/stages/test_domestication_stage.py(missing backbone/reagent blockers, approval gating, protocol-mode behavior, approved-process success).python -c "from buildcompiler.api.options import BuildOptions"— succeeded.python -c "from buildcompiler.inventory import Inventory, CompatibilitySelector"— succeeded.python -c "from buildcompiler.stages import AssemblyLvl1Stage"— succeeded.python -c "from buildcompiler.domain import StageResult, MissingBuildInput, RequiredApproval, ApprovalStatus"— succeeded.python -c "from buildcompiler.stages import DomesticationStage"— succeeded.python -c "from buildcompiler.sbol import DomesticationService"— succeeded.python -c "from buildcompiler.planning import DomesticationPlanner"— succeeded.uv run pytest tests/unit/planning/test_domestication.py tests/unit/sbol/test_domestication_service.py tests/unit/stages/test_domestication.py— failed in this environment due to network/Git fetch of optionalSBOLInventorydependency (403), souvvirtualenv provisioning could not complete.pytest tests/unit/planning/test_domestication_planner.py tests/unit/sbol/test_domestication_service.py tests/unit/stages/test_domestication_stage.py— succeeded (these targeted tests passed).pytest tests/unit/domain tests/unit/api tests/unit/inventory tests/unit/planning tests/unit/sbol tests/unit/stages— succeeded; all unit suites report53 passed.ruff check . && ruff format --check .— failed due to pre-existing unrelated lint issues in legacy files and notebooks (these are outside this PR scope).uv-based environment setup failed due to network restrictions fetching an optional dependency and is a CI/environment issue rather than code failure.Codex Task