Wayfinder / Case study / Recovered specification

Source-derived document; review findings and open questions with the application owner.

States and Transitions

In this document

States and Transitions

The system represents lifecycle state for notification assessments, movements, shipments and financial guarantees. The available evidence shows several state vocabularies and selected transition rules, but does not establish one complete, application-wide state machine. Some states may be hierarchical or represented differently in domain, database, views and reports. Numeric status values are not sufficient evidence of lifecycle order.

Notification assessment lifecycle

Assessment state values represented in the evidence include:

  • NotSubmitted
  • Submitted
  • NotificationReceived
  • AwaitingPayment
  • InAssessment
  • ReadyToTransmit
  • Transmitted
  • DecisionRequiredBy
  • Consented
  • ConsentedUnlock
  • ConsentWithdrawn
  • Unlocked
  • Reassessment
  • Objected
  • Withdrawn
  • UnderProhibition
  • InDetermination
  • FileClosed
  • Resubmitted

The evidence supports the following tested or source-described behaviour:

  • A new assessment starts in NotSubmitted.
  • Submission requires notification progress to be complete.
  • Successful submission changes the assessment to a submitted state and raises status-change and submission events.
  • Duplicate submission is rejected.
  • Receipt is permitted from Submitted and records a received date, resulting in NotificationReceived.
  • Commencement requires NotificationReceived, a payment-received date and a non-empty officer name, and moves the assessment to InAssessment.
  • A tested progression continues from InAssessment to ReadyToTransmit, then Transmitted, and then DecisionRequiredBy.
  • Transmitted or DecisionRequiredBy may be unlocked, producing Unlocked.
  • Consented may be unlocked to ConsentedUnlock.
  • Resubmission from ConsentedUnlock returns to Consented; resubmission from Unlocked moves to Reassessment.
  • From Reassessment, an acknowledgement date may lead to DecisionRequiredBy; a transmitted date without an acknowledgement date may lead to Transmitted; rejected changes return to Unlocked.
  • Consent withdrawal records a date and reason and changes the assessment to a withdrawal-related state.
  • ConsentWithdrawn, Consented, Objected and Withdrawn are reported as able to move to FileClosed.
  • Prohibition can be applied from a listed set of non-prohibition states, including early, reassessment and consent-unlock states. The available evidence does not prove that it is available from every possible state.
  • Lifting prohibition can return an assessment to a prior state, but the complete set of permitted prior states is not established.

Editability is partially evidenced. Editing is permitted in NotSubmitted, Submitted, NotificationReceived, InAssessment and Unlocked, and is rejected in ReadyToTransmit, Transmitted, DecisionRequiredBy and UnderProhibition. Editability for Consented, ConsentWithdrawn, Objected, Withdrawn, FileClosed, Reassessment and ConsentedUnlock is not fully established. Some views describe notifications as read-only after assessment, but the filter and handler enforcement are not supplied.

There is a material state-description ambiguity. One state-machine configuration shows NotificationReceived accepting Submit and moving to AwaitingPayment, while AwaitingPayment is represented as a child or subordinate state beneath Submitted. Other evidence describes submission as moving to Submitted. These descriptions may refer to a hierarchical state and its parent, rather than contradictory persisted values, but the concrete state stored, displayed and reported at runtime is unresolved.

The evidence also does not establish whether each transition is atomic with its date updates, status-history record, domain events, notifications, payment changes and persistence. Event classes and status-change records are present, but event dispatch, consumers, retries, ordering and failure handling are not demonstrated.

Prohibition, withdrawal and closure

Under-prohibition is represented as a state and as a date-bearing status change. Setting prohibition uses the current UTC time in the observed handler path. Removing prohibition uses a prior status change and the current UTC time, then attempts to restore the previous status. A missing assessment or missing prior status may result in false in some handlers; withdrawal paths may instead dereference missing assessments without a visible local check.

Archive-reference assignment is reported as invalid until file closure has occurred. File closure, withdrawal, objection and consent dates are represented separately, but their complete ordering and conditional-requiredness are unresolved. The relationship between Withdrawn, ConsentWithdrawn, Objected, UnderProhibition and any corresponding decision enums is not fully defined.

Movement lifecycle

Movement states represented in the evidence include:

  • New
  • Captured
  • Submitted
  • Received
  • PartiallyRejected
  • Completed
  • Rejected
  • Cancelled

Observed or tested transitions include:

  • New or Captured to Submitted.
  • Captured to Received, Rejected, Cancelled or PartiallyRejected.
  • Submitted to Received, Rejected, Cancelled or PartiallyRejected.
  • Received to Completed, Rejected, Cancelled or PartiallyRejected.
  • PartiallyRejected to Completed.

Rejected and Cancelled appear terminal in the inspected state-machine configuration because no outgoing transitions were shown. Other application or database code may still update such records, so terminality cannot be generalized across the system.

Movement creation or capture records movement identifiers, movement number, movement date, creator and creation time. Captured movement creation rejects a disabled-prenotification flag when a prenotification date is supplied. Creation checks are reported to include movement date validity, consent status, shipment limits, active loads, remaining quantity, an approved financial guarantee, consent-period validity and movement-number generation. The evidence does not establish that these checks and creation are atomic or concurrency-safe.

Receipt and completion have separate external and internal paths:

  • External receipt requires a non-default file identifier, a date, and a quantity.
  • Internal receipt requires a date and quantity and rejects dates later than the current UTC date; it does not require a file identifier.
  • External completion requires a completion date and file identifier.
  • Internal completion rejects future completion dates and completion dates earlier than the recorded receipt date.

The ordering rule for completion is therefore directly supported for the internal path only. It is not established that external completion applies the same receipt-date guard.

Rejection and partial rejection create corresponding records and may clear receipt data when the prior movement was Received. However, the evidence conflicts on whether the receive methods themselves clear receipt data: one account reports that rejection and partial rejection clear the receipt, while another reports that the inspected receive methods do not show this behaviour. This contradiction remains unresolved.

Partial rejection can subsequently transition to Completed. If rejection or partial rejection has cleared the receipt, internal completion may encounter a missing receipt when it reads the receipt date. An omitted invariant or another persistence path may prevent this state, but that prevention is not evidenced. The partial-rejection reason check rejects null or empty text but does not reject whitespace-only text in the cited implementation.

Repeated completion is also unresolved. One completion path checks for an existing completed receipt, while other evidence describes a completion operation that does not visibly reject an existing receipt. It is therefore not established whether completion is idempotent, whether duplicate receipt records can be created, or which layer enforces uniqueness.

Shipment, receipt and quantity state

Shipment and movement data carries overlapping flags and dates, including received, rejected, partially rejected, completed, cancelled, recovered and disposed indicators. Several mappers use precedence rules rather than rejecting contradictory data. For example, receipt data may be selected before rejection data, while another path gives partial-rejection data precedence over standard receipt data. A summary may classify a movement as received before considering partial rejection.

These mappings can produce different displayed outcomes when multiple flags or related records coexist. The evidence does not establish a universal invariant requiring the flags to be mutually exclusive, nor whether inconsistent combinations are rejected during persistence.

Quantity and date rules include:

  • Received quantities must comply with applicable quantity and unit rules.
  • Partial rejected quantity must be positive and, in the cited implementation, strictly less than actual quantity.
  • Some paths reject quantities greater than actual quantity rather than equality, creating a boundary difference between implementations or descriptions.
  • Receipt and recovery dates must satisfy path-specific ordering rules.
  • Future dates are rejected in several receipt, recovery and completion paths.
  • Movement dates must fall within consent periods and, in some paths, no more than 30 days in the future.
  • A separate prenotification rule is described as allowing up to 60 days after prenotification, while resource text states 30 days. The effective rule is unresolved.

Financial-guarantee lifecycle

Financial guarantees represent statuses including:

  • AwaitingApplication
  • ApplicationReceived
  • ApplicationComplete
  • Approved
  • Refused
  • Released
  • Superseded

The described progression is generally:

ApplicationReceived → ApplicationComplete → Approved or Refused

and:

Approved → Released or, in some replacement scenarios, Superseded.

Approval requires a completed application and, in the cited validation, a nonblank reference. Refusal requires completion, a decision date and a non-null, non-empty reason. Release is reported as available for approved guarantees and not for completed, received or refused guarantees. A direct ApplicationComplete → Released transition is not evidenced.

When a new approval uses the same reference as an existing approved guarantee, the existing guarantee may be superseded. When the reference differs, the existing guarantee may be released. The evidence does not establish whether self-replacement is prevented, whether more than one approved guarantee can exist, or whether database uniqueness enforces the apparent single-approved-guarantee invariant. One path uses SingleOrDefault when locating an approved guarantee, so multiple approved records may produce an exception.

Decision and status changes may update the guarantee and raise status-change events. Approval, refusal and release may then create or persist separate decision or history records. The evidence does not establish atomicity between the aggregate transition, decision record, release date, status history and event dispatch. A failure after the transition but before the associated record is persisted is therefore an unresolved consistency path.

Transition failures and evidence limits

Observed failure paths include rejection of duplicate submission, invalid transitions, missing assessments, missing movements, missing receipts, unsupported enum or status values, duplicate related records, invalid dates, invalid quantities, absent required officers or reasons, and missing or malformed identifiers. Depending on the path, failures may be represented by false, null, a validation error, InvalidOperationException, ArgumentException, ArgumentNullException, ArgumentOutOfRangeException, or a null-reference failure.

The evidence does not establish one consistent failure contract across controllers, handlers, domain methods, repositories, stored procedures and database constraints. Some handlers catch broad exceptions and return null or a generic result, while others allow exceptions to propagate. The mapping between domain failures and HTTP or user-visible responses is therefore incomplete.

Overall, the supplied material supports multiple related state models and a number of selected transitions, particularly for assessment submission and movement receipt/completion. It does not establish a single complete transition graph, definitive persisted state values, universal authorization or editability enforcement, concurrency behavior, transaction boundaries, event delivery, or the final production semantics of contradictory paths.

Content quality review

Advisory; not approval. Review status: advisory.

Overall assessment

The draft is broadly relevant to states.md and is unusually careful about uncertainty. It correctly avoids presenting the material as one authoritative state machine, distinguishes several vocabularies, preserves the 30/60-day and receipt-clearing contradictions, and identifies major gaps around persistence, authorization, transactions, events, and concurrency. Its treatment of numeric statuses as non-ordering evidence is appropriate.

The main weakness is not a major factual error but scope and evidential traceability. The draft often compresses source observations, tests, state-machine configuration, database procedures, mappers, and secondary analyses into “the evidence supports” without identifying which layer supports each statement. Given the supplied evidence’s conflicting coverage and provenance, several assertions should be narrowed or explicitly attributed.

Relevance and structure

The lifecycle sections are relevant, but the document sometimes moves from state semantics into general implementation review. For example, exception-type inventories, mapper precedence, report classifications, file persistence, and broad failure-contract discussion are useful only where they affect lifecycle interpretation. Consider retaining them as short “implementation implications” subsections or moving them to a separate risks/evidence-limits document.

The draft would be easier to use if each lifecycle had a compact transition matrix with columns such as:

  • source or persisted vocabulary;
  • observed transition;
  • trigger or operation;
  • preconditions;
  • dates or records changed;
  • event or audit effects;
  • evidence type;
  • unresolved aspects.

The current prose is comprehensive but makes it difficult to distinguish a tested transition from a state-machine declaration, a handler observation, a database-side update, or a secondary interpretation.

Claims that need narrower wording

The opening assessment-state list combines values from several evidence contexts. The evidence establishes that these names are represented somewhere, but not necessarily that they belong to one runtime enum or one persisted vocabulary. The list should be introduced as “values appearing across the supplied evidence” rather than “assessment state values represented in the evidence,” followed by a warning that some may be from different models or layers.

“Successful submission changes the assessment to a submitted state and raises status-change and submission events” is supported by tests or source descriptions, but “successful” may imply durable completion. A safer wording is: “The cited test or source path expects submission to set Submitted and raise the two events; durable persistence and event delivery are not established.”

“Consent withdrawal records a date and reason and changes the assessment to a withdrawal-related state” should name the exact state only if the evidence does so. Otherwise it should say that the operation records the supplied values and changes status according to an unresolved withdrawal-related mapping.

“Archive-reference assignment is reported as invalid until file closure has occurred” is acceptable, but should be attributed to a domain rule or observed method rather than presented as a system-wide rule. The same applies to “setting prohibition uses the current UTC time” and “removing prohibition uses a prior status change”: these are path-specific observations, not necessarily universal semantics.

The movement statement that “creation checks are reported to include …” is appropriately qualified, but the list combines factory checks, handler checks, and perhaps tests. It should identify whether each check is factory-level, handler-level, controller-level, or database-side. In particular, number generation and uniqueness should not be presented together as one atomic creation rule.

The statement that Rejected and Cancelled “appear terminal” is well qualified. It would be stronger to say “no outgoing transitions were shown in the inspected state-machine configuration,” because terminality is not established even within the whole domain without the complete configuration.

The financial-guarantee paragraph says the described progression is “generally” a sequence. This is reasonable, but ApplicationReceived → ApplicationComplete may be a declared or tested progression rather than an observed production path. The wording should distinguish “state-machine/test-described progression” from “runtime progression.”

Contradictions and evidence handling

The draft correctly records the central NotificationReceived/AwaitingPayment/Submitted ambiguity. It should make explicit that the apparent contradiction may be between a hierarchical state-machine destination and a parent state, not necessarily between two persisted values. It already suggests this, but the correction should be elevated as the principal unresolved question.

The movement receipt-clearing contradiction is correctly preserved. However, the sentence “If rejection or partial rejection has cleared the receipt, internal completion may encounter a missing receipt” is a derived scenario, not directly evidenced as reachable. Label it as a conditional consequence: “If both behaviours occur on the same path and the movement can then reach completion, a missing-receipt dereference is possible.”

Similarly, the partial-rejection/completion concern is plausible but not established. The draft should avoid implying that a partial rejection “can subsequently transition to Completed” necessarily means the same record can have its receipt cleared and then be completed through the same path. The transition and data-clearing observations may come from different layers or operations.

The quantity section says that “some paths reject quantities greater than actual quantity rather than equality.” This wording is potentially misleading because a rule rejecting only > allows equality, whereas another rule requiring “strictly less than actual” rejects equality. State this explicitly as a boundary difference: “One path appears to permit equality by rejecting only >, while another rejects equality by requiring <.”

The prenotification rule is correctly identified as unresolved, but the draft should distinguish the executable 60-day comparison, the 30-day message, the 30-day resource text, and any 60-day resource/property naming. They are not all equal-strength evidence.

Missing behaviours

Although the draft lists many evidence gaps, the following lifecycle behaviours are not sufficiently explicit:

  • The initiating actor and authorization requirement for each transition.
  • Whether transitions are idempotent, retryable, or rejected when repeated.
  • Whether stale pages, duplicate posts, replayed API calls, or concurrent updates are handled.
  • Whether dates are transition guards, historical facts, or merely denormalized display values.
  • Whether state changes are reversible, and under which actor or decision conditions.
  • Whether parent and child states are both persisted, and which state is used by search, reporting, and authorization.
  • Whether status-history records are mandatory for every transition or only selected operations.
  • Whether state changes can occur through direct SQL or stored procedures independently of domain methods.
  • How invalid or unsupported enum values are handled at persistence and read boundaries.
  • Whether movement terminal states are enforced by the database, domain methods, handlers, or only the inspected state-machine configuration.
  • Whether financial-guarantee replacement is scoped by notification, reference, authority, or another business key.
  • Whether multiple approved guarantees are prohibited, tolerated, or merely cause SingleOrDefault failures.
  • Whether prohibition is orthogonal to the underlying assessment state or replaces it as the persisted state.

Some of these are mentioned indirectly, but a lifecycle document should state them as explicit unresolved behaviours rather than leaving them dispersed through the prose.

Evidence gaps and attribution

The supplied evidence contains many second-opinion summaries, inconsistent source ranges, omitted files, and notes saying that some claims are characterization candidates rather than executed tests. The draft should use stronger attribution labels such as:

  • “test-described”;
  • “state-machine configuration shows”;
  • “handler path shows”;
  • “database procedure shows”;
  • “mapper or view inference”;
  • “secondary analysis reports.”

This is especially important for:

  • assessment editability;
  • prohibition transitions;
  • financial-guarantee release eligibility;
  • movement creation preconditions;
  • external/internal completion differences;
  • archive-reference validity;
  • event raising;
  • status-history creation;
  • duplicate completion handling.

The document currently says “tested or source-described behaviour” in places, which helps, but the distinction should be maintained at individual bullet or paragraph level.

  1. Replace the assessment-state list introduction with:
    “The following values occur across the supplied assessment-related state machines, enums, tests, database descriptions, views, and reports. The evidence does not establish that they form one enum or persisted vocabulary.”

  2. Change “successful submission changes the assessment…” to:
    “The cited submission test or source path expects the assessment status to become Submitted and raises submission/status-change events; durable persistence and delivery are not shown.”

  3. Change “Rejected and Cancelled appear terminal” to:
    “The inspected state-machine configuration shows no outgoing transitions from Rejected or Cancelled; this supports terminality only within that configuration.”

  4. Mark the receipt-clearing and repeated-completion passages as conditional scenarios, not implied reachable defects.

  5. Separate movement creation checks into their evidence layers: controller validation, factory/domain checks, repository/database checks, and unverified assumptions about atomicity.

  6. Clarify all boundary contradictions using the operators (<, <=, >, >=) rather than describing them only as “boundary differences.”

  7. Add a short explicit subsection titled “Persisted versus hierarchical state unresolved,” covering Submitted, AwaitingPayment, parent/child state, displayed state, report state, and database state.

  8. Add a short explicit subsection titled “Transition authority and enforcement unresolved,” stating that no complete actor-to-operation-to-state matrix is evidenced.

  9. Reduce repeated general caveats about transactions, authorization, events, and production behaviour. State them once globally, then identify only the lifecycle-specific consequence in each section.

Unresolved questions that should remain prominent

  • Is AwaitingPayment a persisted state, a child state, a view state, or a reporting projection beneath Submitted?
  • What exact state is stored after receipt and after commencement?
  • Are state changes and associated dates/history/events committed atomically?
  • Are domain events persisted, dispatched synchronously, queued, retried, or discarded?
  • Which actor and permission are required for each assessment, movement, guarantee, prohibition, withdrawal, and closure transition?
  • Are state and decision enums separate dimensions or competing representations of the same lifecycle?
  • Are external and internal movement completion paths intentionally different?
  • Does partial rejection require an existing receipt before completion?
  • Can a movement have receipt, rejection, partial-rejection, cancellation, recovery, and completion records simultaneously?
  • Is equality permitted for all quantity boundaries?
  • Is the effective prenotification limit 30 or 60 days, and is it calendar-day or working-day based?
  • Is there a database constraint preventing duplicate movement numbers, completed receipts, approved guarantees, or related status rows?
  • Which layer defines the user-visible failure contract for invalid transitions?

Overall, the draft is a strong cautious synthesis, but it should be made more auditable by attributing each transition to its evidence layer and by separating established observations from derived reachability scenarios. It should not be treated as a definitive state machine or as evidence that the unresolved behaviours are defects.