Respect explicit DNA strand direction during transcription
The biology organ ignores the written direction of a DNA strand during transcription. At c473d28914e480425adb29b4f7f42485b8cfb4e3, its actual BiologyOrgan.answer returns UCCGUA for:
"Transcribe the DNA template strand 3'-TACGGA-5' into mRNA."
The expected 5′→3′ transcript is AUGCCU: the template is already written in polymerase reading order. The same physical template written 5'-AGGCAT-3' produces AUGCCU already. The current code always reverses templates and never reverses coding strands, regardless of their explicit end labels.
This repair binds adjacent 3′/5′ labels to the sequence already selected by the existing reader. Template strands written 3′→5′ are complemented directly; those written 5′→3′ are reversed before complementing. Coding strands are normalized to 5′→3′ before replacing T with U. Conflicting same-end labels decline. Unlabelled strands retain the existing 5′→3′ convention, now stated in the module contract. Output-direction words elsewhere do not override the input's labels. Existing complement, reverse-complement, translation and GC operations are unchanged.
The biological rule is described by OpenStax Biology 2e §15.2, figure 15.7 and Genomes, Transcriptomes and Proteomes, figure 3.4: transcription makes 5′→3′ RNA complementary to the antiparallel template.
Validation (Python standard library only):
python3 -B -m unittest discover -s tests/biology -v
All 11 test methods pass. They include typed expected transcripts, both strand polarities and roles, prime/separator spellings, conflicting labels, output-direction controls, all 256 four-base templates in both written orientations (512 checks), and the shipped biology panel through its own scorer. Against the unpatched source, this same suite has 259 failing assertions/subtests across seven methods; the 5′→3′ and unlabelled controls pass.
The actual shipped panel scores remain dev 14 right / 0 wrong, one correct decline; heldout 14 right / 0 wrong, one correct decline, with zero changed replies on all 30 panel rows. The panel contains no template-polarity cases, which is why the independent regressions matter.
Scope: this exercises the actual Python specialist and its shipped scorer, not the full Engine or admission gate. No new verdict, implementation hash, formal proof, whole-head result or fleet score is claimed. Two files: one runtime file and one portable test file.
Thank you. This shipped in 10.3.1, slim and full, credited by name in CHANGELOG_1031.md, with your suite at tests/biology/. On our side your 11 tests pass on both trees, and the template now gives AUGCCU in chat in both written orientations, with same-end labels refused. That chat check is a row in sealed test v40, which passed on both trees. You were right that the panel has no template-polarity cases; it took your regressions to show the defect.