ReviewStateValidator does not enforce the schema's date-time format on any timestamp field #474
Labels
No labels
agent-ready
bug
contract
documentation
duplicate
enhancement
good first issue
help wanted
invalid
needs-human
needs-input
question
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
iterative-works/iw-cli#474
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Found triaging IW-437 (raised in phase 3 code review; pre-existing, deliberately not fixed there).
schemas/review-state.schema.json declares format: "date-time" for the card's timestamp fields, ci_wait_started included (schemas/review-state.schema.json:98-103).
ReviewStateValidator.validate (core/model/ReviewStateValidator.scala:274-281) only checks that the field is present and is a string. It never parses it. So "not-a-date" passes validation, and the schema's declared format is documentation that nothing checks.
SCOPE. This is a pre-existing pattern shared by every timestamp field on the card, last_updated included. It is not specific to ci_wait_started and was not introduced by IW-437.
WHY IT NOW MATTERS MORE. ci_wait_started gates a safety timeout. An unparseable value there does not fail loudly at validation - it silently resets the CI wait budget on every resumed invocation, so a capped wait becomes unbounded. See #473 for that fallback's semantics. Enforcing the format here is what stops a bad value reaching startOfWait through an ordinary write rather than through file corruption.
PROPOSED FIX. Parse and reject on failure in ReviewStateValidator, for every field the schema declares as date-time - not only ci_wait_started.
Kept separate from #473 deliberately: different file, different scope (all timestamp fields vs one field's fallback semantics), and either can be fixed or deferred independently of the other.
Fixed in PR #501 (merge
d1eba9c4).ReviewStateValidatornow parses every field the schema declaresformat: date-timewithjava.time.Instant.parseand rejects on failure, naming the field. This is the route that let a badci_wait_startedreachstartOfWait(#473).