Passante A Passante publication

En Passante

In Passing
Field Kit

The button finished before the process did

Return when the promised result is ready, while keeping concurrency protection for the full lifetime of unfinished work.

What happened

A dashboard timed out after 240.4 seconds while waiting for unrelated trailing work; polling its actual result reduced the recorded response to 28.2 seconds while the concurrency lock still protected the running process.

2026-09-12 Node.js · detached process · result file measured: Historical response time and lock lifetime
2 prompts, in order
  1. Identify the promised result A refresh button times out although its status report has already changed.
  2. Check the result and lock independently The request now polls a fresh result and returns before unrelated work ends.

1Identify the promised result

Run it when
A refresh button times out although its status report has already changed.
It asks you for
The button promise, child-process stages, result freshness field, lock file and timing observations.
You get back
The correct completion observation and the distinct lifetime of the concurrency lock.
It refuses if
Do not keep raising a timeout without checking whether it measures the work the button promises.
copy this into a model
<stance>
Your job is to separate an observed failure from a convincing explanation that has never been checked. Keep the reader's actual system in view. A result is useful when another person can repeat the observation and get a different answer if the proposed repair is wrong.
</stance>

<inputs>
Ask for these before drawing a conclusion. Wait for anything essential that is missing.
1. The button promise, child-process stages, result freshness field, lock file and timing observations.
2. The exact user-visible symptom, including the original output and the time it was observed.
3. The implementation and launch conditions responsible for that output. Read the relevant source in full.
4. What may be changed safely, and which actions require the owner's approval.
5. Any existing verification that could distinguish the proposed cause from the alternatives.
</inputs>

<method>
1. Read what the button promises to refresh and which exact result it displays. Capture the result's freshness marker before starting the child process.
2. Follow the child through every stage. Identify work that writes the promised result and trailing work that serves a different consumer. Compare their completion times with the observed HTTP response.
3. Define success as a new valid result for this operation, while preserving a separate owner for the child process. An existing old report must never satisfy the new request.
4. Keep the concurrency lock until the real process ends. Returning early to the interface must not release protection and allow a second click to corrupt the first process's observations. Define the early-exit failure separately.
</method>

<deliver>
- OBSERVED: the behavior actually established, with the output that supports it.
- EXPLANATION: what the observation settles and what remains unknown.
- NEXT ACTION: one bounded action, its owner, and its expected result.
- PROOF: the observation that would establish success, plus the result that would disprove it.
</deliver>

<refuse>
Do not keep raising a timeout without checking whether it measures the work the button promises.
Do not invent measurements, defaults, source contents, or a successful run. Keep historical results separate from today's observations. Never transmit private inputs or perform a paid or external action just to complete this check. If access or authorization is missing, stop and name the exact missing condition.
</refuse>

2Check the result and lock independently

Run it when
The request now polls a fresh result and returns before unrelated work ends.
It asks you for
The existing result-polling tests, process exit handling, concurrency marker and actual returned status.
You get back
Fresh-result success, early-exit failure and proof that overlapping work stays protected.
It refuses if
Do not call a changed timestamp proof that every background stage finished.
copy this into a model
<stance>
Your job is to separate an observed failure from a convincing explanation that has never been checked. Keep the reader's actual system in view. A result is useful when another person can repeat the observation and get a different answer if the proposed repair is wrong.
</stance>

<inputs>
Ask for these before drawing a conclusion. Wait for anything essential that is missing.
1. The existing result-polling tests, process exit handling, concurrency marker and actual returned status.
2. The exact user-visible symptom, including the original output and the time it was observed.
3. The implementation and launch conditions responsible for that output. Read the relevant source in full.
4. What may be changed safely, and which actions require the owner's approval.
5. Any existing verification that could distinguish the proposed cause from the alternatives.
</inputs>

<method>
1. Use the existing isolated action tests to run a child that writes the promised result and continues its trailing work. Record when the caller returns and whether the marker still exists.
2. Attempt an overlapping request before the original child exits. It must be refused while the original work remains protected, even though the first caller already received its result.
3. Exercise a child that exits without producing a fresh report and one that never produces it. The first should report early exit; the second should expire with a statement about the missing result.
4. Read cleanup after actual process termination. The marker must disappear at that lifetime boundary, and the returned success must stay limited to the promised report rather than claim completion of all trailing work.
</method>

<deliver>
- OBSERVED: the behavior actually established, with the output that supports it.
- EXPLANATION: what the observation settles and what remains unknown.
- NEXT ACTION: one bounded action, its owner, and its expected result.
- PROOF: the observation that would establish success, plus the result that would disprove it.
</deliver>

<refuse>
Do not call a changed timestamp proof that every background stage finished.
Do not invent measurements, defaults, source contents, or a successful run. Keep historical results separate from today's observations. Never transmit private inputs or perform a paid or external action just to complete this check. If access or authorization is missing, stop and name the exact missing condition.
</refuse>
How you know it worked

Check the lock separately. The requested result must become fresh before success is returned, and a second request must remain refused while the original process is still running. A process that exits without a fresh result must report that failure instead of waiting out the entire deadline.

from a real incident, 2026-09-12 · stack Node.js · detached process · result file · verified by Historical response time and lock lifetime · concurrencyautomationperformance

← every Field Kit