Test Document Approval Against Revisions and Competing Edits
Build a scoped approval acceptance record, inject document and attachment changes, and reconcile release evidence without transferring authority to a newer package.
trigger="An approval badge survives document edits, or a delayed worker cannot establish which package it may release." owner="The workflow owner accountable for the permitted release action and its significance rules." participants={['Document owner', 'Backend engineer', 'Security reviewer', 'Independent evaluator', 'Recovery operator']} prerequisites={['One declared release policy', 'Synthetic documents and grants', 'Isolated competing writers', 'Controlled interruption points', 'An inert destination ledger']} outputs={['A package and authority contract', 'An independent fixture manifest', 'Historical retrieval evidence', 'Competing-transition results', 'A reconciled release register']} doneWhen={['Every intended fixture has a disposition', 'Changed packages cannot inherit authority', 'Missing historical evidence is held', 'Unknown writes retain their original identity', 'The owner accepts only the tested boundary']} />
Prove which package may be released
A document approval test should establish that the released package is the one the decision permits, not just that an Approved label appears on screen. The test must cover the readable document, its attachments, the action, the grant and the transition that commits release work. A later edit can preserve a valid historical decision while making that decision unusable for the current package.
Use a hypothetical service notice N20 in an isolated tenant. Package R4 contains an outage window, a recipient group and attachment A2. A reviewer permits its release. An editor prepares R5 with another window while an AI worker proposes a summary based on R4. A delayed release worker can now choose the wrong content even though each component reports success. This playbook creates controlled fixtures for that failure, rather than relying on a fast test that happens not to encounter it.
All identifiers, notices, grants and recipients in this procedure are synthetic. Destination adapters must be inert. This is an engineering acceptance procedure, not a customer incident, legal-signature determination or prescribed retention schedule. The owner must choose the real policy before the implementation is accepted. Passing the isolated procedure does not prove that an untested production document provider or publication endpoint enforces the same boundary.
1. Declare the release policy and accountable owner
Owner: workflow owner with document owner. Output: approved release contract. Select one action, such as publishing a notice to a named internal group. Separate review for drafting, internal approval and external release. State which decision actually permits the selected action. A generic approval stage should not silently authorize every later use of the document.
Choose between a pinned historical package and a current-package policy. In the first, an explicitly selected approved R4 may remain releasable while R5 is drafted separately. In the second, a significant current change makes the old release request unusable. These policies require different expected results after an edit. Do not switch between them to make a failing fixture pass.
Record significant fields, attachment membership, allowed audience, grant lifetime, revocation behavior and changes after local intent commit. Name who can resolve a held case and what evidence that person needs. The test owner must distinguish an unavailable rule from a rejected action; neither is permission to release. Record residual destination limitations before building a fixture that promises stronger behavior than the destination can enforce.
2. Build independent expected outcomes and a fixture manifest
Owner: independent evaluator. Output: versioned acceptance manifest. Specify expected outcomes before running the candidate. Include unchanged release, significant text edit, attachment replacement, audience change, grant withdrawal, missing historical package, stale AI patch, simultaneous release requests and lost receipts. Give each fixture a stable scoped identifier, starting state, interruption point and expected local and destination evidence.
For the proposed current-package policy, pause the worker after it reads R4 approval, commit R5 and resume it. Expect a hold or a newly evaluated request, never release of R5 under R4's grant. In the release-first schedule, commit an identified R4 intent before the edit and apply the declared post-commit cancellation or pinned-release rule. An observer must identify which schedule occurred rather than infer it from arrival timestamps alone.
Include a deliberately permissive candidate that reads the badge and later fetches the current file. Confirm that the observer detects its wrong-package release. This negative control tests the evidence path itself. If it passes, repair the observer before accepting the hardened candidate. Keep every intended fixture in the denominator, including setup failures and inconclusive runs; do not report only completed releases as the coverage set.
3. Construct a scoped, readable package identity
Owner: document engineer with security reviewer. Output: package inventory and review representation. Bind the tenant, workflow, source revision, accepted representation, attachment versions, significant structured values and permitted action. Resolve that identity on the backend under the authorized caller's scope. Two tenants may use the same friendly filename and revision label; the label is not an authority boundary.
Prepare the actual representation offered to the reviewer. Check hidden comments, tracked changes, linked values, rendering omissions and attachment access. A digest can detect byte differences but cannot establish that a person saw the significant terms. Retain the readable package and its mapping to the source revision, using the owner-approved data policy. The source revision and rendered PDF can be different artifacts without being interchangeable evidence.
OWASP's transaction-authorization guidance supports operation-specific significant data, server-side enforcement and an execution-time control. Apply those principles to the declared notice release; the source does not define this hypothetical package schema or make a login session equivalent to approval of a particular notice. Verify that client-supplied package and grant identifiers cannot change the selected tenant, action or representation.
4. Demonstrate historical retrieval and access failure
Owner: integration engineer with data-policy owner. Output: retrieval and disposal test record. Retrieve R4 and A2 through the authorized history path, then compare their content with the accepted representation. Repeat after a current-file edit and after the provider reports the old revision unavailable. The latter must produce an evidence-unavailable hold, not a silent download of R5.
Google Drive's revision-management documentation describes revision-specific retrieval and provider-dependent retention. Older revisions can be purged, and listed history can be incomplete for large revision sets. Blob-file retention controls are not a universal archival contract for every document type. If the real workflow uses Drive, verify the actual file type and access path. If it uses another provider, inspect that provider's contract separately.
Test historical access with a revoked or wrong-scope user as well as an authorized reviewer. Seeing the current notice title must not expose an old confidential attachment. Record an attributable correction when an archive mapping is wrong; do not rewrite the earlier decision into apparent success. Confirm that approved disposal creates a truthful missing-evidence state and does not leave an approval badge promising a representation the system can no longer retrieve.
5. Capture an action-specific decision and invalidate by rule
Owner: workflow owner with backend engineer. Output: decision record and change-classification fixtures. Store the approver, package identity, permitted action and audience, policy reference, decision time and applicable expiry or revocation state. Preserve rejection and withdrawal decisions as well as acceptance. Make the user view distinguish a historical approval from permission to act now.
Replace A2 with A3 while leaving the main filename unchanged. Change only an explicitly nonsignificant field in a separate fixture. Apply the approved significance rules to each case and record their basis. A missing comparison is unknown, not evidence that nothing material changed. If the owner allows a nonsignificant edit without renewed approval, retain the difference and policy justification instead of silently pretending the bytes are identical.
Test authority changes independently of document changes. Withdraw the grant without editing R4, then request the release. Conversely, edit a significant field while leaving the grant row unchanged. Both cases reveal whether the implementation binds the decision to all required facts. A technical merge, matching filename or earlier conversational confirmation must not make the new package approved. No model confidence score may replace the authoritative significance decision.
6. Exercise the protected local transition
Owner: backend engineer with independent evaluator. Output: transition and intent evidence. Under the chosen current-package policy, combine expected package, usable grant and permitted action checks with the local state change and identified release intent. Protect dependent records such as attachments and audience membership. State exactly which database boundary enforces the invariant and which later destination behavior remains outside it.
PostgreSQL's isolation documentation explains statement snapshots under Read Committed and transaction retry requirements for relevant serialization failures. A transaction wrapper alone does not prove this workflow's invariant. Inspect the actual conditional updates, locking or isolation design and its result handling. A zero-row conditional update is not an accepted release, and a rolled-back attempt must leave no dispatchable intent.
Run edit-first and release-first schedules using controlled barriers. Save the before-state, competing change, commit outcome and intent identity for each. Make every writer participate: manual editing, import, AI patch and administrative repair. An unversioned attachment replacement bypass can invalidate the release worker's otherwise correct check. Retry the whole decision from authoritative state where the database contract requires it, not the cached conclusion that R4 was approved. Keep external effects outside speculative transaction attempts.
7. Test destination conditions without widening their scope
Owner: integration engineer. Output: destination precondition register. Name the exact representation protected by the destination's version validator. Use an inert endpoint that records the expected validator, body and operation identity. Change that representation before the write and require the documented conflict behavior. Also simulate an adapter that drops the condition so the observer proves it detects a broken integration.
RFC 9110's If-Match semantics use strong comparison at the origin for the selected representation. A wildcard tests existence rather than equality with the reviewed version. Where the actual endpoint supports the contract, test an exact validator. Do not replace it with a wildcard or fetch a new tag and resubmit the old approval after a conflict.
Check attachments, audience and grant separately when the validator does not cover them. One resource's ETag is not a package-wide approval guarantee. If the destination cannot enforce the required invariant, record a held action or an explicitly approved narrower release procedure. Faster polling does not close the residual race. Retain response evidence and investigate whether a reported success is the original operation's receipt, not just a similar request that happens to have matching content.
The proposed current-package test has two distinct checks: the local transition binds the selected package and grant, while the destination condition protects only its declared resource. A retained approval is evidence of the earlier decision, not permission to replace R4 with R5. The diagram does not assert distributed atomicity or legal validity.
8. Keep AI summaries and patches attached to their inputs
Owner: AI application engineer with document reviewer. Output: derived-artifact and merge fixtures. Record the base package for each summary or patch and show that relationship to the reviewer. Let an AI worker prepare an R4 comparison, then commit R5 before the result returns. The application must label the result stale for the new package rather than attach it to R5 as if it described the latest terms.
Inject an omitted significant change and a supplier attachment containing instructions to bypass review. Treat document text as evidence, not workflow authority. The model may propose a comparison; the release service must still apply the package, action and grant checks. A summary that reads well is not proof of complete change classification or authorized release.
For a patch based on R4, test both a textual conflict and a clean textual merge into R5. The clean merge can still alter a significant condition or combine attachments no one reviewed together. Give the resulting package a truthful identity and required review state. Preserve the original proposal and reviewer disposition so a later corrected output cannot erase the first failure. Missing base evidence should hold the patch rather than regenerate a complete document and overwrite current work.
9. Reconcile duplicate workers and uncertain receipts
Owner: recovery operator with backend engineer. Output: operation settlement register. Run two workers against one committed release intent. Inspect the inert destination ledger for effect count, package and operation identity. A single local Completed flag cannot prove that only one notice was issued. Keep database transaction retry, delivery retry and newly authorized publication distinct.
Withhold the local commit response after persistence. Read back the original scoped request and intent before deciding whether another attempt is permitted. An unavailable readback remains unknown; it is not proof that the commit failed. Next, let the destination accept the operation while withholding its response. Preserve the original identity, attempted package and owner for receipt investigation. Do not mint another operation because the application timed out.
Restart between intent commit and dispatch, and between destination acceptance and receipt storage. Inspect the persisted state after each interruption. A missing receipt lookup is inconclusive when its authority or coverage cannot establish absence. Do not reset identity retention or delete unresolved work to make the drill repeatable. Use an isolated new fixture for a genuinely new case, while preserving the earlier case's evidence and obligations.
10. Test edits and cancellation after intent commit
Owner: workflow owner with dispatch engineer. Output: post-commit policy results. Pause the worker immediately before dispatch, then withdraw the grant or save a significant newer package. Apply the declared pinned-release or invalidation rule. Show the operator whether the original intent remains permitted, is held, or has already crossed an irreversible destination boundary.
Race cancellation with a destination request already in progress. A local Canceled state cannot prove that the destination did not accept the notice. Preserve issued and uncertain requests separately from undispatched work. If a corrective notice is allowed, give it a new scoped authorization and connect it to the earlier receipt; do not erase the original release.
Exercise rollback compatibility with retained package, decision and intent records. A previous application version must either understand those records or hold them safely. Turning off an AI assistant does not undo edits it already committed. Freeze new dispatch when required, retain the recovery owner and reconcile outstanding identities before restarting. Do not call a routing switch a complete rollback when notices or durable document changes remain.
11. Verify the operator view, export and full manifest
Owner: independent evaluator with operations reviewer. Output: reconciled acceptance register. For every intended fixture, record expected package, observed package, action, audience, grant, local result, intent, destination condition and receipt disposition. Classify pass, failed invariant, setup failure or inconclusive evidence. Name an owner and next action for each unresolved record. An average success rate must not hide one wrong-package release.
Review the actual browser view and exported record at the same time. A historical approval should show its package and limits. A conflict should explain which field or boundary changed without leaking another tenant's content. An uncertain receipt should direct investigation of the original operation, not expose a generic Retry button that creates another identity.
Export the accepted representation and its identity mapping, not a fresh rendering of the current file under the earlier approval label. Test with the historical package deliberately unavailable. Inspect every attachment and linked value that the declared approval scope includes. Save evidence of rejected competing requests as well as the winner. A green pipeline is insufficient when the operator cannot reconstruct what was permitted and what actually happened.
12. Decide acceptance and retain the recovery handoff
Owner: workflow owner with independent evaluator. Output: scoped acceptance or hold decision. Accept only the candidate, release policy, document types, writer paths and destinations actually tested. Missing production-provider evidence remains a separate gap. Assign owners for package retention, grant policy, dispatch reconciliation and future fixture maintenance before widening the workflow.
Release review checklist
- The approved representation and every significant attachment are retrievable under the correct scope.
- The permitted action and audience are bound to the package and usable grant.
- Significant changes cannot inherit authority from a matching filename or green badge.
- Both edit-first and release-first schedules follow the declared policy.
- Every relevant writer participates in the protected transition.
- Destination conditions protect their declared resource without wildcard fallback.
- AI summaries and patches retain their base, differences and review disposition.
- Lost commit and destination responses retain their original operation identity.
- Cancellation and rollback preserve already issued or uncertain work.
- Every intended fixture has a result, evidence owner and next action.
After acceptance, rerun the affected fixtures whenever representation, significance rules, storage, writer paths or destination behavior change. Use the document-version review for the package contract and the concurrent-edit review for transition choices. Bring one reconciled register to a backend systems review or a system architecture review. Downloads need no email address. Requesting contact remains optional and does not subscribe the reader to marketing.