Skip to content

Commit 34ec274

Browse files
okohlbacherclaude
andcommitted
fix(v2.0): Codex R16 — SmilesParser adoption + missing tests + bond-prop doc; 282/282
R16 reviewed Track B Cluster B; verdict NEEDS-FIXES with 3 [BUG]s. All addressed before v2.0.0-rc3 tag. # C-B1 [BUG]: SmilesParser adoption order Pre-fix: smilesParser.C inserted empty Molecule into System first, then tried to single-atom-adopt bonded orphan atoms one by one. K0's canAdopt() rejects every such call (partners still in orphan). Net countAtoms()=0 for every SMILES input. Fix: build the Molecule off-system, insert atoms into it (no adopt triggered), THEN insert populated Molecule into System → adoptSubtree handles batched bonded migration. SmilesParser_test WILL_FAIL quarantine removed. # C-B4 [BUG]: 3 CORE_ONLY tests silently dropped FragmentDB_test, DefaultProcessors_test, NormalizeNamesProcessor_test were listed only in BALL_KERNEL_TESTS, not BALL_STRUCTURE_TESTS. The CB-3 dedupe removed them from BALL_CORE_KERNEL_TESTS expecting BALL_STRUCTURE_TESTS to cover them — but it didn't. CORE_ONLY silently dropped 3 tests. Fix: added to BALL_STRUCTURE_TESTS in test/cmake/BALLTestExecutables.cmake. # C-B7 [BUG] → DOCUMENTED: Bond PropertyManager bag not in JSON K0.6 JSON serialises BondRecord (a, b, order, type, flags) but not the Bond *handle's* PropertyManager bag. Affected: MMFF94SBMB, MMFF94RBL, VIRTUAL__BOND, HBondProcessor annotations. Most BALL workloads don't persist bond properties (set ephemerally during force-field setup, recomputed on load). Shipping rc3 with the gap documented is acceptable. V21-BOND-PROPERTY-JSON filed as v2.1 backlog. Implementation needs bond_back_ptr_[i] exposure in writer + Bond handle lookup in reader. # Documentation .planning/RELEASE-NOTES-v2.0.md: new 'Bond PropertyManager bag' known-gaps subsection. .planning/v2.x/K0-CODEX-REVIEW-ROUND16.md: full R16 review record. # Verification - CORE_ONLY ctest: 282/282 PASS (was 279/279 at Cluster B close; +3 from C-B4 restoration). - 0 WILL_FAIL, 0 disabled. - MoleculeStore_test 100-run stress: 0/100. - Heap-System repro: exit 0. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 73a640a commit 34ec274

5 files changed

Lines changed: 141 additions & 17 deletions

File tree

.planning/RELEASE-NOTES-v2.0.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,20 @@ build-time concept.
360360
- **Tighter perf gates** — JSON I/O test gates (30s save / 30s load)
361361
are tripwires, not regression-pins. v2.1 should calibrate against
362362
CI machine variance.
363+
- **Bond PropertyManager bag — not in K0.6 JSON** (Codex R16 C-B7,
364+
2026-05-19): the K0.6 JSON persistence path serialises the
365+
per-atom + per-molecule + per-system PropertyManager bags, plus
366+
the BondRecord `(a, b, order, type, flags)` tuple. The Bond
367+
*handle's* `PropertyManager` bag (used by MMFF94 for `MMFF94SBMB`,
368+
`MMFF94RBL`, MMFF94 bond-type discriminator; `VIRTUAL__BOND`
369+
marker; HBondProcessor annotations) is NOT serialised. Most BALL
370+
workloads don't use bond properties — they're set ephemerally
371+
during force-field setup and computed fresh on every load. v2.1
372+
backlog item: V21-BOND-PROPERTY-JSON. Implementation requires
373+
exposing bond_back_ptr_[i] in the writer and finding the Bond
374+
handle for property restore in the reader (Bond handle isn't
375+
stored in the store; it's heap-owned by the AtomContainer
376+
hierarchy).
363377
364378
## Things deferred to v2.1
365379
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
# Track B Cluster B — Codex CLI Round 16 (2026-05-19)
2+
3+
**Status:** Complete. Verdict: **NEEDS-FIXES → 2/3 [BUG]s fixed,
4+
1 documented → GO for v2.0.0-rc3**.
5+
6+
**Reviewer:** Codex CLI 0.128.0 (`codex exec`).
7+
**Subject:** Track B Cluster B (commits `2d6a820e3` + `73a640a80`) —
8+
QSAR + STRUCTURE restore + MOLMEC AMBER/MMFF94 + SCORING
9+
COMPONENTS/FUNCTIONS + SOLVATION + DOCKING + remaining FORMAT.
10+
Cluster B brought CORE_ONLY ctest from 174/174 (rc2) to 279/279 (+105).
11+
12+
---
13+
14+
## Verdict (Codex, verbatim)
15+
16+
> Final: NEEDS-FIXES
17+
>
18+
> Minimum rc3 blockers: fix SmilesParser adoption order, restore the
19+
> three missing CORE_ONLY tests into `BALL_STRUCTURE_TESTS`, and either
20+
> implement bond-property JSON persistence or explicitly downgrade
21+
> the K0.6 persistence claim before tagging.
22+
23+
## Probe answers
24+
25+
| # | Probe | Verdict | Status |
26+
|---|---|---|---|
27+
| C-B1 | SmilesParser_test failure root cause | [BUG] — K0 adoption-order break in public parser, not a harmless WILL_FAIL | **Fixed** (build off-system, insert populated) |
28+
| C-B2 | scoringComponent.C un-ifdef'd back-transform | OK with caveat ||
29+
| C-B3 | scoringFunction.C un-ifdef'd SideChainOptimizer | OK ||
30+
| C-B4 | Test dedupe silently lost 3 CORE_ONLY tests | [BUG] — FragmentDB/DefaultProcessors/NormalizeNamesProcessor missing | **Fixed** (added to BALL_STRUCTURE_TESTS) |
31+
| C-B5 | AssignBondOrderProcessor_test2 quarantine gate | OK ||
32+
| C-B6 | Lock ordering / thread-safety regressions | OK; residual Bond::setOrder data race documented ||
33+
| C-B7 | Bond-property JSON persistence | [BUG] — MMFF94/HBond bond annotations don't round-trip | **Documented** (v2.1 backlog V21-BOND-PROPERTY-JSON) |
34+
| C-B8 | sizeof(Atom)/sizeof(Bond) unchanged | OK — Sizeof_test still pins 360 B / 288 B ||
35+
| C-B9 | Ship rc3 with SmilesParser WILL_FAIL? | [BUG] No — fix before tagging | **Fixed** via C-B1 |
36+
37+
## Fixes applied this commit
38+
39+
### C-B1 fix — SmilesParser adoption order
40+
41+
`source/STRUCTURE/smilesParser.C` line 158-163:
42+
43+
Pre-fix:
44+
```cpp
45+
Molecule* molecule = new Molecule;
46+
system_.insert(*molecule); // empty molecule into system FIRST
47+
for (atom : all_atoms_) molecule->insert(*atom); // single-atom adopt rejected
48+
// by canAdopt — partners in orphan
49+
```
50+
51+
Post-fix:
52+
```cpp
53+
Molecule* molecule = new Molecule;
54+
for (atom : all_atoms_) molecule->insert(*atom); // off-system: no adopt
55+
system_.insert(*molecule); // triggers adoptSubtree
56+
// which migrates bonded atoms
57+
// in a single batched pass
58+
```
59+
60+
SmilesParser_test WILL_FAIL quarantine removed in test/CMakeLists.txt.
61+
62+
### C-B4 fix — Restore 3 CORE_ONLY tests into BALL_STRUCTURE_TESTS
63+
64+
`test/cmake/BALLTestExecutables.cmake`: added FragmentDB_test,
65+
DefaultProcessors_test, NormalizeNamesProcessor_test to
66+
BALL_STRUCTURE_TESTS. They had been listed only in BALL_KERNEL_TESTS,
67+
so when the CB-3 dedupe removed them from BALL_CORE_KERNEL_TESTS the
68+
CORE_ONLY build silently dropped them. Net: +3 tests.
69+
70+
### C-B7 — Bond-property JSON gap documented (v2.1)
71+
72+
`.planning/RELEASE-NOTES-v2.0.md`: new "Known gaps" subsection
73+
explicitly stating that Bond's `PropertyManager` bag is NOT
74+
serialised in K0.6 JSON. Affected: MMFF94 bond-type properties
75+
(MMFF94SBMB, MMFF94RBL), VIRTUAL__BOND markers, HBondProcessor
76+
annotations. Most workloads don't persist bond properties (they're
77+
ephemeral during force-field setup), so shipping rc3 with the gap
78+
documented is acceptable.
79+
80+
V21-BOND-PROPERTY-JSON filed as v2.1 backlog item. Implementation
81+
needs: writer exposes `bond_back_ptr_[i]` to find Bond handle,
82+
serialises its PropertyManager bag inline with the bond record;
83+
reader finds the Bond handle after restore (Bond is heap-owned by
84+
the AtomContainer hierarchy, not in the store).
85+
86+
## Verification
87+
88+
- CORE_ONLY ctest: **282/282 PASS** (was 279 at Cluster B close;
89+
+3 from C-B4 restoration; +0 from C-B1 since SmilesParser_test
90+
was already counted but WILL_FAIL'd; net +3).
91+
- MoleculeStore_test 100-run stress: 0/100 fails.
92+
- Heap-System repro: exit 0.
93+
- 0 WILL_FAIL tests in CORE_ONLY mode. 0 disabled tests.
94+
95+
## v2.0.0-rc3 readiness
96+
97+
All R16 blocker items are either fixed (C-B1, C-B4) or explicitly
98+
documented with v2.1 backlog (C-B7). Cluster B closure is clean.
99+
100+
**Verdict: GO for v2.0.0-rc3 tag.**

source/STRUCTURE/smilesParser.C

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -154,14 +154,23 @@ namespace BALL
154154
// fill up empty valences with hydrogens
155155
addMissingHydrogens();
156156

157-
// Transfer all atoms into a new molecule.
157+
// 2026-05-19 (Codex R16 C-B1 fix): build the molecule
158+
// OFF-system first, then insert the populated molecule INTO
159+
// the system. The AtomContainer::insert(AtomContainer&) path
160+
// triggers System::adoptSubtree which handles bonded multi-
161+
// atom migration correctly. Pre-fix, this code inserted an
162+
// empty molecule into the system first and then tried to
163+
// single-Atom-adopt each bonded orphan atom one by one;
164+
// K0's canAdopt() rejects every such call because each
165+
// atom's bond partners are still in the orphan store. Net
166+
// result was countAtoms()=0 on the parsed System.
158167
Molecule* molecule = new Molecule;
159-
system_.insert(*molecule);
160168
for (Position i = 0; i < all_atoms_.size(); i++)
161169
{
162-
molecule->insert(*all_atoms_[i]);
170+
molecule->insert(*all_atoms_[i]); // off-system insert: no adopt
163171
}
164-
172+
system_.insert(*molecule); // triggers adoptSubtree
173+
165174
// Clean up the pointers to these atoms.
166175
all_atoms_.clear();
167176
}

test/CMakeLists.txt

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -269,19 +269,13 @@ ENDIF()
269269
# Previously WILL_FAIL'd in full builds. CB-3 brought rotamerLibrary.C
270270
# into CORE_ONLY too, and re-tested — passes in both modes.
271271
#
272-
# SmilesParser_test — QUARANTINED (2026-05-19, TEST-SMILES-PARSER)
273-
# getSystem().countAtoms() returns 0 instead of 5 for all SMILES
274-
# inputs (line 76, 114). The SMILES parser produces no atoms —
275-
# likely a v2.0 kernel interaction (Atom auto-adopt path from
276-
# temporary parser-internal containers differs from v1.x).
277-
# Files: source/STRUCTURE/smilesParser.C + smilesParserParser.C.
278-
# SmartsParser_test PASSES with shared parser infrastructure, so
279-
# the issue is SMILES-specific. Filed as v2.0.x backlog
280-
# (TEST-SMILES-PARSER).
281-
SET_TESTS_PROPERTIES (
282-
SmilesParser_test
283-
PROPERTIES WILL_FAIL TRUE
284-
)
272+
# SmilesParser_test — QUARANTINE LIFTED (Codex R16 C-B1, 2026-05-19)
273+
# Root cause: smilesParser.C built atoms in orphan store with bonds,
274+
# inserted empty molecule into system FIRST, then tried to adopt
275+
# bonded orphan atoms one-by-one — K0's canAdopt() rejected each
276+
# (partners still in orphan). Fix: build molecule off-system, insert
277+
# atoms into it, THEN insert populated molecule into system →
278+
# adoptSubtree handles the bonded multi-atom migration correctly.
285279

286280
IF (BALL_HAS_VIEW)
287281
FOREACH(test ${VIEW_TESTS})

test/cmake/BALLTestExecutables.cmake

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,13 @@ SET(BALL_STRUCTURE_TESTS
262262
AtomBijection_test
263263
BinaryFingerprintMethods_test
264264
BindingPocketProcessor_test
265+
# Cluster B step 3 (Codex R16 C-B4 fix): moved here from
266+
# BALL_KERNEL_TESTS — the 3 STRUCTURE tests had been listed only
267+
# in KERNEL group, so when CB-3 dedupe removed them from
268+
# BALL_CORE_KERNEL_TESTS the CORE_ONLY build silently dropped them.
269+
DefaultProcessors_test
270+
FragmentDB_test
271+
NormalizeNamesProcessor_test
265272
ConnectedComponentsProcessor_test
266273
DisulfidBondProcessor_test
267274
Enumerator_test

0 commit comments

Comments
 (0)