ChildrenDao.reorder: now requires a complete permutation — partial lists, unknown ids and duplicates are rejected with ValueError before any write (inside the transaction + connection lock, so check and write are atomic). The two DAO tests encoding the old silent-no-op semantics updated to the new contract.
children.py reorder_children: Feature 09-facing wrapper; rejects non-integer ids up front.
Tests: round-trip via the active list, partial/unknown/duplicate/non-int rejections with order-unchanged proofs, empty-list rejection, inactive children keep positions.
Verification
uv run pytest: 866 passed.
Closes task 31e80e1a (Feature 03).
Task 3 of Feature 03.
## Delivered
- **ChildrenDao.reorder**: now requires a complete permutation — partial lists, unknown ids and duplicates are rejected with ValueError before any write (inside the transaction + connection lock, so check and write are atomic). The two DAO tests encoding the old silent-no-op semantics updated to the new contract.
- **children.py reorder_children**: Feature 09-facing wrapper; rejects non-integer ids up front.
- **Tests**: round-trip via the active list, partial/unknown/duplicate/non-int rejections with order-unchanged proofs, empty-list rejection, inactive children keep positions.
## Verification
uv run pytest: 866 passed.
Closes task 31e80e1a (Feature 03).
- ChildrenDao.reorder now requires a COMPLETE permutation of the
children table: partial lists (missing an existing child), unknown
ids and duplicates are rejected with ValueError before any write,
inside the existing transaction and connection lock (check and
write atomic). Empty list is the maximally partial reorder against
a non-empty table; against an empty table it stays a no-op. The two
DAO tests that encoded the old permissive semantics (silent no-op
on empty/unknown) are updated to the new contract.
- children.py gains reorder_children: the Feature 09-facing wrapper,
which additionally rejects non-integer ids up front (bools and
floats would silently compare against stored integer ids at the SQL
layer).
- Business tests: round-trip (active list returns new order), partial/
unknown/duplicate/non-int rejections with order-unchanged proofs,
empty-list rejection, and inactive children keeping positions in a
whole-table permutation. Suite: 866 passed.
Review round 1 (Codex gpt-5.6-terra): SQLite binds bools as integers,
so edit_child(True, ...) would silently edit child 1 and
set_child_active had the same hole (reorder already validated its
list). A shared _validate_child_id guard now runs before lookup in
edit_child, set_child_active and reorder_children's list scan, with a
coercible-id test matrix for both call shapes (True/False/1.0/"1"/
None) asserting the refused call leaves the profile untouched. Suite:
875 passed.
Round 1 — CHANGES_REQUIRED (2 MEDIUM): SQLite binds bools as integers, so edit_child(True, ...) would silently edit child 1 and set_child_active had the same id-coercion hole. Fixed in 5fe6cb7: shared _validate_child_id guard before lookup on all three calls (edit, set_active, reorder list), coercible-id test matrix asserting untouched profiles.
Round 2 — APPROVED (zero findings). Full suite verified by the reviewer: 876 passed.
## Independent review — Codex gpt-5.6-terra
**Round 1 — CHANGES_REQUIRED (2 MEDIUM):** SQLite binds bools as integers, so edit_child(True, ...) would silently edit child 1 and set_child_active had the same id-coercion hole. *Fixed in 5fe6cb7:* shared _validate_child_id guard before lookup on all three calls (edit, set_active, reorder list), coercible-id test matrix asserting untouched profiles.
**Round 2 — APPROVED (zero findings).** Full suite verified by the reviewer: 876 passed.
dev_agent
merged commit b7f7e092a0 into feature/4f802471-1de1-4c35-844f-eebf3bea0de5-children-registry-admin-allowlist2026-09-15 16:47:45 -04:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Task 3 of Feature 03.
Delivered
Verification
uv run pytest: 866 passed.
Closes task 31e80e1a (Feature 03).
Independent review — Codex gpt-5.6-terra
Round 1 — CHANGES_REQUIRED (2 MEDIUM): SQLite binds bools as integers, so edit_child(True, ...) would silently edit child 1 and set_child_active had the same id-coercion hole. Fixed in
5fe6cb7: shared _validate_child_id guard before lookup on all three calls (edit, set_active, reorder list), coercible-id test matrix asserting untouched profiles.Round 2 — APPROVED (zero findings). Full suite verified by the reviewer: 876 passed.