What you’ll take away
- Bind a review decision to the actual proposal, relevant context, intended target and operation.
- A changed proposal and changed supporting facts are separate reasons an old decision may no longer apply.
- Approve, edit, reject and pending status carry different meanings; define what an edit does before execution.
- First-response and everyone-must-approve policies can finish differently even with the same possible judgments.
- A saved workflow can resume without proving that its review is still current or that its side effects cannot repeat.
- Keep approval separate from confirmed execution, failure or an unresolved outcome.
An approval needs an identifiable object
A reviewer reads an event announcement and approves it. An editor then changes the starting time. The dashboard still shows a green approval badge. What that badge proves depends on which announcement the reviewer actually saw and what the workflow did with the later change.
Human review is useful only when the decision has a clear object. That object might be a proposed document, a change to an existing record or a particular action. LangChain documents a configurable step that pauses selected AI tool calls for decisions such as approval, editing or rejection [2]. The pause creates an opportunity to review; it does not tell us whether the displayed evidence was complete or the decision still applies.
We will follow an invented event listing through revisions, two reviewers and a delayed execution. The people, text and responses are teaching examples, not results from an AI service or a human study. The aim is to understand what information must stay attached to a review so that an approval continues to mean something precise.
A review decision is a relation between a reviewer, a defined proposal and the conditions under which the proposal was assessed. An unqualified approved flag loses that relation when a proposal is edited, its supporting facts change or the action is applied to another target.
LangChain’s documented human-in-the-loop middleware can intercept tool calls according to configured policy and collect a decision before the relevant action proceeds [2]. This is a control-flow mechanism. It does not, by itself, establish the substantive adequacy of the review, the reviewer’s authority or the freshness of external evidence.
The original model in this article concerns publication of one fictional event listing. We stipulate an authorized service caller and two required review roles, then examine proposal identity, context identity, decision aggregation and execution evidence. These are explicit teaching rules, not defaults asserted for every framework. No model, human participant, publishing endpoint or external messaging service was exercised. The useful outcome is a review record whose meaning can be reconstructed after the proposal has moved through the workflow.
Show the proposed listing beside the facts that support it
Our fictional event is Light and Lenses, identified as E17. Its first schedule record, C1, says East Room, 14:00, capacity 24. Proposed listing P1 reads: Light and Lenses begins at 14:00 in the East Room. The room capacity is 24. The intended action is to publish that text as the public listing for E17.
The reviewer needs both the proposal and its supporting schedule. A polished preview alone does not show whether 14:00 came from the current record, an old draft or an unsupported guess. Put the event identity, intended destination and relevant source facts beside the exact proposed text. The same sentence copied into an announcement for another event would be a different proposed action.
Our two roles have different jobs. The facts reviewer checks the announcement against the schedule; the copy reviewer checks the wording against the stated editorial rules. The workflow requires both decisions on the same proposal and context. This is an invented division of work, not a claim that two reviewers always outperform one. It makes each decision’s scope visible.
Define event E17, context C1=(East Room, 14:00, capacity 24), proposal P1 containing those facts, and target T=the public listing for E17. The proposed operation is publication to T. The fixture excludes additional event records or hidden conditions; these named fields are the relevant context for the examples.
A review packet should expose the exact payload, target, operation and supporting context together. A content identifier can distinguish P1 from later payloads, while a context identifier distinguishes C1 from a changed schedule. These identifiers describe recorded artifacts. They are not evidence that the schedule is truthful or that a human inspected every field.
Let the required roles be facts and copy. Each role records its own decision against the same packet. This separates responsibility from aggregation: the facts role assesses agreement with C1, while the copy role assesses a declared wording criterion. Requiring two roles is a chosen policy for this fixture, not an empirically validated accuracy improvement. The model’s authorization premise remains separate; matching a review record cannot grant an otherwise unauthorized caller permission to publish.
Keep approval, an edit and a rejection distinct
An approval says to proceed with the proposal as reviewed. An edit changes the proposal. A rejection declines it. Those three responses should not collapse into one green state called reviewed. LangChain’s documented action decisions make this distinction: approve retains the proposed arguments, edit substitutes arguments, and reject skips the call [2].
In our example, the copy reviewer might replace begins with starts. That creates P2, even though the event facts remain the same. The facts reviewer might instead reject an announcement because its time disagrees with the schedule. A note asking for the missing schedule is neither an approval nor proof that the announcement is wrong; it leaves the required judgment unresolved.
The interface should show what the person’s response will do. An Edit and publish control would express a different action from Save an edited draft for review. Our teaching workflow uses the latter: an edit creates a candidate to assess again. This is an explicit product choice. A different system may authorize a reviewer to edit and execute in one decision, provided that the executed version and the person’s authority are clear.
Separate response semantics from the mere presence of a response. In the documented LangChain action workflow, approve preserves the proposed arguments, edit supplies replacement arguments and reject prevents that proposed call from executing [2]. Its additional respond decision serves a different input-oriented purpose and should not be interpreted as rejection.
For the original listing workflow, define editing as creation of a new proposal revision. Approval, rejection and pending status then apply to a specific revision; requesting additional evidence leaves the review pending. This differs deliberately from a combined edit-and-execute policy. Neither choice should be inferred from an ambiguous reviewed flag.
The distinction also affects records returned to an AI assistant. If a reviewer changes begins to starts, the resulting artifact is P2. Reporting only that P1 was approved would erase the actual intervention. If an action is rejected, reporting a generic success would misrepresent its disposition. The article does not supply a middleware adapter or request schema; it specifies the information that a chosen interface and its execution path need to preserve.
A small wording change still creates a new proposal
Suppose both reviewers approve P1 against C1. The editor then changes begins to starts, producing P2. All three schedule facts remain unchanged. Under our deliberately simple rule, the earlier approvals remain in the history but do not count as approvals of P2. The workflow asks the required reviewers to assess the revised packet.
That rule is conservative: a real organization might permit a narrower review of certain changes. It would need to define which changes qualify and record what was checked. Calling a change small does not itself establish that it preserved meaning. Changing 14:00 to 15:00 is only a one-character substitution, yet it changes the event information.
GitHub provides a concrete software-review example of configurable stale-approval handling when a pull request’s changes differ from what was approved [3]. Our event workflow is an analogy, not an implementation of GitHub’s branch rules. The shared idea is to preserve the relationship between the review and the reviewed revision, while making any policy for carrying decisions forward explicit.
Let the two approved records bind to (P1,C1,T). Replacing begins with starts produces P2, so a record naming P1 no longer exactly matches the candidate payload. The original policy invalidates review eligibility on any proposal revision. It preserves the old records as historical evidence rather than rewriting them to name P2.
Exact revision matching is not a semantic comparison. It cannot establish that a change is harmful, and a mismatch need not imply that every fact became wrong. It establishes only that the stored decision concerns another artifact. A more selective policy would require an additional, defined judgment about the changed material and retained assumptions.
GitHub documents configurable dismissal of stale approvals and a separate option requiring review of the most recent reviewable push [3]. These options should not be collapsed into a universal reset rule. Our strict fixture chooses a simpler behavior to make its consequence inspectable. Character count is not the criterion: a one-character change to the hour can alter meaning more than a longer stylistic substitution.
Unchanged text can become outdated when its supporting facts change
Now keep P1 exactly as it was, including 14:00. The event organizer changes the schedule from C1 to C2: the start is now 15:00, while East Room and capacity 24 remain unchanged. The announcement file has not changed, but its starting time no longer agrees with the current schedule.
An approval tied only to the announcement’s text would miss this change. Our record therefore names both the proposal and the relevant context. The decision for P1 with C1 remains an accurate history of what was reviewed. It is not a current approval for P1 with C2. The next candidate, P3, changes the announcement to 15:00 and must be reviewed against C2.
This does not mean every unrelated edit anywhere must reopen every review. Our fixture has identified the event schedule as a dependency because it supplies the announcement’s facts. A practical review record should name the dependencies that can change its conclusion. Otherwise a new timestamp may give the appearance of freshness while the underlying information remains old.
Context freshness is independent of payload identity. Define C2 by changing the start from 14:00 to 15:00, with the room and capacity preserved. The bytes of P1 can remain identical while the factual agreement predicate changes from true under C1 to false under C2.
The original record therefore binds a proposal revision and a context revision. Equality of a stored content hash is insufficient to establish current suitability when a relevant external dependency has changed. A cryptographic digest can identify bytes; it cannot prove those bytes still describe the world. Likewise, changing a timestamp without checking the dependency does not restore the missing relation.
P3 is the candidate whose time matches C2. Its new reviews must refer to that pair. This is an original design inference from the defined fixture, not a claim that a named framework automatically monitors external schedules. Dependency selection needs judgment: an unrelated page change need not affect this conclusion, while the start-time change plainly does. Record the dependency and the reason it matters instead of treating all updates as equivalent.
The rule for combining decisions changes the outcome
Imagine the copy reviewer approves at the first decision point, while the facts reviewer has not answered. At a later point, the facts reviewer would reject because the time is wrong. A first-response rule completes with approval at the first point. An everyone-must-approve rule is still waiting then and completes with rejection when the facts decision arrives.
Microsoft documents this difference for its named Power Automate approval types: the everyone-must-approve type requires all assigned approvals, but one rejection can finish it; first-to-respond finishes with the first approval or rejection [4]. An everybody-must-respond rule is a different concept. Waiting for every response regardless of outcome is not necessary for the documented rejection behavior.
Our listing uses everyone-must-approve because both stated roles are required. That choice does not prove either reviewer is correct. It determines which judgments the workflow waits for. With two people who can each be pending, approve or reject, there are nine possible pairs of states: one fully approved pair, five containing a rejection and three still waiting without a rejection. These counts describe logical combinations, not probabilities or measured reviewer performance.
Aggregation policy must be distinguished from individual decisions. For a two-role everyone-must-approve policy, classify the joint state as rejected if either role rejects; approved if both approve; otherwise pending. This gives one approved state, five rejected states and three pending states in the nine-element product of {pending, approve, reject} with itself.
The five rejected states follow by counting all nine pairs and removing the four pairs containing only pending or approve. Of those four, one is approve/approve; the other three remain pending. No equal-probability assumption is made, so 5/9 is not a predicted rejection rate.
Power Automate documents the all-approvals-or-one-rejection behavior separately from its first-to-respond type [4]. In the original ordered example, copy approval at t1 would complete first-response processing before the hypothetical facts rejection at t2. The everyone policy waits at t1 and rejects at t2. This compares completion rules, not measured waiting times, human reliability or a guarantee that additional reviewers improve decisions. The second judgment need not even be collected after a first-response workflow has completed.
A reviewer’s edit needs its own clear decision
Suppose the copy reviewer corrects a misspelling while the facts reviewer is still checking P1. In our workflow, that correction creates a revised proposal rather than silently changing the object under the second reviewer’s screen. The pending request should now identify the new version or be replaced by a new request.
The person who made the edit may also be allowed to approve it, depending on the stated policy. That permission should be deliberate. Our simple fixture still requires both roles on the current proposal. It does not treat authorship of an edit as an automatic substitute for either review. If the editor’s role permits a combined edit-and-approve action, the recorded decision must name the resulting text.
This prevents a misleading history in which one person approved an earlier version and another person changed it, but the interface presents their actions as two approvals of the final text. Preserve the older decisions, the change and the new judgments separately. The record becomes more informative without pretending that every edit requires an entirely new organization-wide process.
Concurrent review introduces a revision-consistency requirement. If the copy role edits P1 while the facts role is assessing it, the facts decision may arrive after the candidate has changed. Arrival time alone does not change the object of that decision: a late response to P1 still refers to P1.
Our teaching policy requires two current role decisions on the candidate revision. Whether the editing reviewer may supply one of those decisions is a separate role-policy choice. The model does not implement separation-of-duties rules or assert that an editor is universally prohibited from approving an edit. It requires only that the decision accurately identify the final artifact and the capacity in which it was made.
A useful history therefore preserves the original proposal, the edit, the new proposal and each role’s decision binding. This is stronger evidence than a total review count detached from revisions. Two historical approvals of different objects do not logically imply two approvals of the current object. That conclusion follows from the defined records, without making a claim about any particular review platform’s interface or observed failure rate.
Resume the right question with the right answer
A review can take longer than the process that originally requested it. LangGraph documents saved checkpoints and a thread identifier that lets an interrupted workflow resume with the corresponding response [1]. Think of this as keeping the work’s place, together with the question that was waiting for an answer.
Keeping the place is different from proving that the answer belongs to the current proposal. In our example, an answer for the E17 listing should not be applied to another event just because both requests display an Approve button. If P1 has been replaced by P3, an old response cannot be silently retitled as a decision about P3.
Several waiting actions also need distinct identities. A response to the first item should not drift to the second when the interface sorts the list. The documented LangChain modes either associate a response with an interrupt identifier or use the request’s specified order [2]. Follow the actual mode’s association rule. A saved identifier helps locate the waiting work; it does not prove who is entitled to answer it.
Persisted continuation and review validity are separate concerns. LangGraph’s interrupt mechanism uses a checkpointer and thread identity to retain state across a pause; resumption supplies a value to the relevant interrupt [1]. This gives the workflow continuity but does not establish that its application-level evidence remains current.
For the original fixture, preserve a review-request identity alongside (proposal, context, target, operation). Resolving an old request must retain that binding even if the display list has been reordered or a newer proposal exists. An identifier is an association mechanism, not an authentication credential or a grant of publication authority.
When multiple actions are awaiting decisions, the response structure must preserve their association. The cited LangChain snapshot distinguishes per-call interrupt identifiers from ordered decisions in batched mode [2]. The article does not choose a framework mode or execute either API. The transferable requirement is that the answer reaches the question that was actually presented, and that the application checks whether that question is still eligible to advance the current candidate.
A resumed step can run some work again
A pause does not always behave like stopping a video at one frame. LangGraph explains that the containing node starts again when an interrupt resumes, including work placed before the pause [1]. That detail matters if the earlier work changes something outside the saved workflow.
Consider an invented trace: append a review-opened entry to an external list, then pause. On the first visit the list gains one entry. On resumption, the same append runs again, so the list now contains two entries for one review request. This is a logical example based on two visits to the step, not a recorded framework test. A second entry does not prove that two people reviewed the proposal.
Putting the proposed publication after the approval check prevents it from running before approval in this design. It does not solve every retry problem. The documentation also distinguishes later retries after a side effect has already committed [1]. The execution service needs an appropriate way to recognize repeated work or reconcile its outcome. A green review badge cannot provide that property on its own.
LangGraph documents node-level replay on interrupt resumption: code preceding the interrupt is executed again [1]. A non-idempotent external operation placed there can therefore be repeated even though the application considers the work one review request.
The original trace starts with an empty external append-only list. Visit one appends opened(R17) and pauses; visit two appends opened(R17) again before consuming the saved response. The final list length is two, with one distinct review identity. This finite trace is independently reproducible as a list operation; it is not an execution of LangGraph, a performance result or a statement that every storage operation duplicates data.
The cited documentation separately warns that a post-approval side effect can repeat if it commits and the node then fails before completion [1]. Gate placement and retry handling solve different problems. A service might use a stable operation identity and an atomic deduplication mechanism, but merely naming an idempotency key does not implement those guarantees. Our fixture preserves the distinction without providing a complete distributed transaction protocol.
A decision to publish is different from evidence that publication happened
Both reviewers approve P3 against C2, and the workflow attempts to publish the current 15:00 announcement. There are now two separate questions: was this publication approved, and what happened when the service tried to perform it? The approval record answers the first. A matching execution result is needed for the second.
If the service returns a clear failure before publication, the article is approved but unpublished. If the connection ends without a clear result, the outcome may be unknown. It would be inaccurate to mark that case as published simply because the reviewers said yes. It would also be inaccurate to assume nothing happened and create a second independent operation without checking the first.
Our proposed record assigns the attempted publication its own identity and retains the target, payload revision and observed result. A later check can reconcile that identity with the service’s stored outcome. This is a design requirement for the teaching example, not a claim that an identifier alone prevents duplicates. The review record and the execution receipt describe different events and should remain separately inspectable.
Separate decision state from execution state. An approval for (P3,C2,T,publish) establishes eligibility under the stipulated review policy. It does not establish that an execution request was delivered, committed or acknowledged by the destination service.
The original outcome model distinguishes confirmed success, confirmed failure and unresolved outcome. A transport interruption can leave the caller without evidence sufficient to choose between success and failure. Recording unknown preserves that uncertainty. Inferring success from approval, or failure from a missing acknowledgement, would add information the observation does not contain.
Bind an execution attempt to a stable operation identity, the approved artifact and the destination, then retain the service’s result or reconciliation evidence. Effective deduplication requires the destination’s actual semantics, including how concurrent or repeated requests are handled. This article makes no exactly-once claim and does not implement that service. The important boundary is evidential: a review decision describes what may proceed; an execution receipt describes what the destination reports occurred for the identified operation.
Keep enough history to explain the decision without overstating it
A useful final record can answer a concrete question: which version was reviewed, against which schedule, by which required roles, under which decision rule, and what happened afterward? For E17, that means keeping the relationship between P3, C2, the two decisions and the publication result. A total such as two reviews is much less informative on its own.
Preserve disagreements and revisions as well as the final status. A rejected older draft can explain why the time changed. A pending response can explain why publication waited. Neither should be rewritten as an earlier approval of the final listing. Record the source of the decision honestly, including when a check was automated rather than performed by a person.
Even a complete record does not prove every judgment was correct. Two people could both overlook a mismatch, and a faithfully stored source could itself be wrong. The record makes the process inspectable and supports correction; it does not turn human involvement into a guarantee. The practical goal is a decision that remains attached to the actual proposal, relevant evidence and observed outcome.
A review history should preserve identity, scope and transitions rather than merely accumulating success counts. In the fixture, retain the candidate revision, relevant context revision, target and operation, role-specific decisions, aggregation rule, subsequent edits and execution evidence. These fields describe the particular review model; they are not a universal audit schema or a legal compliance certification.
An unresolved decision must remain distinguishable from rejection, and a historical approval must remain distinguishable from a current one. Likewise, automated validation, an AI-assisted critique and a human judgment are different processes. Recording their provenance avoids claiming that a person performed a review that was actually computed by software.
The record can demonstrate that the configured process was followed for specified artifacts. It cannot by itself demonstrate factual truth, reviewer competence or the absence of all downstream defects. Those require their own evidence. Within this article’s scope, the improvement is precise: the final approved status can be traced back to current decisions on a known proposal and context, and it remains separate from what happened when the approved action was executed.
Sources & further reading
Explore the references behind this guide. External pages may change after our review.
- Interrupts - Docs by LangChainLangChain · Accessed 7 Nov 2026
- Human-in-the-loop - Docs by LangChainLangChain · Accessed 7 Nov 2026
- About protected branches - GitHub DocsGitHub · Accessed 7 Nov 2026
- Create an approval flow that requires everyone to approve - Power Automate | Microsoft LearnMicrosoft · Accessed 7 Nov 2026
Article updated 7 Nov 2026.
Found something we should revisit?
Good explanations get better with thoughtful feedback.