The text can stay the same while its facts change
A reviewed application pack can still point to an older profile or CV. Checking its text digest alone would miss a later correction to those underlying facts. The service recomputes the stored pack digest, matches the job and selected revision, then uses assertPackFresh to require the latest pack, profile and CV.
Approval also has a limited lifetime. Its expiry must be in the future and no more than thirty minutes beyond trustedNow from the service clock. An expired approval can be replaced through an explicit transition; an active approval cannot simply be overwritten.
Use approval and record the attempt together
Starting an attempt repeats the freshness and expiry checks. It also looks for candidate/job and candidate/destination identities already marked STARTED, SUBMITTED or UNKNOWN. An uncertain earlier outcome blocks a new attempt just as a known submission does, until reconciliation establishes what happened.
CareerStore then creates the STARTED record, consumes approval and updates the pack in one mutation of its cloned state. A hash-chained audit event and idempotency receipt accompany the save. An exact retry returns digest metadata without making those changes twice; changed input under the same key is rejected.
Local acceptance isn't an employer receipt
This path changes local records. It doesn't fill a form or contact an employer. Receipt references are supplied by the caller, so passing schema validation says nothing about whether an employer issued them. Similarly, authenticated encryption detects tampering but cannot detect restoration of an older valid store after restart.
The integration tests define stale-revision, expiry, single-use, replay and UNKNOWN-reconciliation cases; they weren't rerun for this review. Independent receipt validation and an external rollback anchor remain necessary before the approval record can control external submission.
Digest-bound approval consumption inside the local store
Revision, expiry and duplicate checks gate the mutation that consumes approval. No external form action follows in this version.
Versioned records
Service checks
Mutation and capability boundary
Scroll or drag the background to move. Use the zoom buttons to resize.Arrow keys move between components. Enter selects.
Choose a component to explore
Select a numbered component on the map or use the component menu. Its details and connections will appear here.
No component selected.
All connections (10)
- 02 · Approval request → 03 · Digest and freshness gateValidate exact approval · Direct call
- 01 · Current pack and references → 03 · Digest and freshness gateStored revision references · Direct call
- 03 · Digest and freshness gate → 04 · Refused local transitionDigest, revision or time mismatch · Blocked / denied
- 03 · Digest and freshness gate → 05 · ACTIVE approvalCreate ACTIVE record · Direct call
- 05 · ACTIVE approval → 06 · Begin-attempt gateSingle-use request · Direct call
- 06 · Begin-attempt gate → 07 · Candidate/destination checkCompare consequential identities · Direct call
- 06 · Begin-attempt gate → 04 · Refused local transitionStale or expired · Blocked / denied
- 07 · Candidate/destination check → 04 · Refused local transitionExisting active or ambiguous attempt · Blocked / denied
- 07 · Candidate/destination check → 08 · One local state mutationNo duplicate; consume approval · Direct call
- 08 · One local state mutation → 09 · Employer form actionNo external capability · Blocked / denied