@plot-pm/board 0.14.0 → 0.14.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/board-server.mjs +106 -103
- package/package.json +1 -1
- package/plot-deliver.sh +66 -0
- package/plot-dispatch.sh +496 -41
- package/plot-host.sh +285 -29
- package/plot-plan-meta.sh +75 -0
- package/plot-worker-state.sh +201 -2
package/package.json
CHANGED
package/plot-deliver.sh
CHANGED
|
@@ -419,6 +419,64 @@ decide_transition() { # $1=file → prints "<Phase>\t<record>\t<write|already>"
|
|
|
419
419
|
# writes — and appending a second is how one plan came to hold two `Delivered:`
|
|
420
420
|
# lines (2026-09-01). The domain returns the written record unchanged in that
|
|
421
421
|
# case, so the phase still flips and nothing is inserted.
|
|
422
|
+
# Would the PARSER read this phase out of the file we are about to land?
|
|
423
|
+
#
|
|
424
|
+
# THE WRITE SUCCEEDING IS NOT THE OUTCOME HOLDING, and that gap is #924. A plan
|
|
425
|
+
# carrying BOTH front matter and a `## Status` block was delivered in a project
|
|
426
|
+
# repo: `flip_phase` wrote `Delivered` into the block, `mv` landed it, the
|
|
427
|
+
# summary said `phase=flipped`, and `plot-plan-meta.sh` went on answering
|
|
428
|
+
# `approved` — because it prefers front matter wherever it exists and reads the
|
|
429
|
+
# block only in the `else if` below. The write took effect on bytes nobody
|
|
430
|
+
# reads.
|
|
431
|
+
#
|
|
432
|
+
# `flip_phase`'s awk matches only inside `section == "status"`. That one guard
|
|
433
|
+
# IS the defect: on a front-matter plan it edits the block and leaves the front
|
|
434
|
+
# matter untouched, and returns 0 for having changed something.
|
|
435
|
+
#
|
|
436
|
+
# SO THE TEST IS WHAT THE PARSER ANSWERS, NEVER WHETHER AWK CHANGED A LINE.
|
|
437
|
+
# Refusing on `flipped=0` would break every re-run of a correct delivery — a
|
|
438
|
+
# plan already carrying `Delivered` flips nothing and is fine. This asks the one
|
|
439
|
+
# question that distinguishes them: read the scratch copy the way every later
|
|
440
|
+
# consumer will read the plan, and compare.
|
|
441
|
+
#
|
|
442
|
+
# IT RUNS ON THE SCRATCH COPY, BEFORE THE `mv`, and the caller passes whichever
|
|
443
|
+
# file that arm is about to land — `$a` on the `recorded=yes` arm, `$b` on the
|
|
444
|
+
# other. Parsing `$a` on the record arm would check content that never reaches
|
|
445
|
+
# the plan. After the `mv` is too late twice over: the script's own header
|
|
446
|
+
# documents exit 0 as *"the plan is Delivered on the default branch"*, so
|
|
447
|
+
# refusing there would exit 1 on a run meeting the documented success
|
|
448
|
+
# condition — and `runAutoDeliver` spawns this detached, logging a non-zero exit
|
|
449
|
+
# to nobody while the plan sits delivered on main.
|
|
450
|
+
#
|
|
451
|
+
# AN UNREADABLE SCRATCH COPY REFUSES. `decide_transition` already takes that
|
|
452
|
+
# line — *"refusing rather than guessing"* — and a file the parser cannot read
|
|
453
|
+
# is exactly the state this gate exists to keep off the plan.
|
|
454
|
+
phase_would_read() { # $1=scratch file $2=expected phase (lowercase) → 0 agrees, 1 refuses
|
|
455
|
+
local scratch="$1" want="$2" m got
|
|
456
|
+
m=$(bash "$script_dir/plot-plan-meta.sh" "$scratch" 2>/dev/null) || m=""
|
|
457
|
+
if [ -z "$m" ]; then
|
|
458
|
+
echo "plot-deliver: $rel — the written file does not parse, so the delivery was not landed." >&2
|
|
459
|
+
echo " Nothing was written. Re-run after fixing the file." >&2
|
|
460
|
+
return 1
|
|
461
|
+
fi
|
|
462
|
+
got=$(printf '%s' "$m" | jq -r '.phase // ""')
|
|
463
|
+
[ "$got" = "$want" ] && return 0
|
|
464
|
+
|
|
465
|
+
# THE REFUSAL NAMES BOTH VALUES AND THE FILE. A message saying only "delivery
|
|
466
|
+
# failed" throws away the half a person acts on: which phase was written, and
|
|
467
|
+
# which one the parser still reads. The cause is named too, because the file
|
|
468
|
+
# holding two records of one fact is the thing to fix — and which format ought
|
|
469
|
+
# to win is a decision this gate deliberately leaves to a person.
|
|
470
|
+
echo "plot-deliver: $rel — wrote phase '$want', but the parser still reads '$got'." >&2
|
|
471
|
+
echo " The plan states its phase in TWO places and they disagree: the write" >&2
|
|
472
|
+
echo " landed in the '## Status' block while front matter takes precedence," >&2
|
|
473
|
+
echo " so the delivery would have reported a success it did not achieve." >&2
|
|
474
|
+
echo " Nothing was written — the plan is unchanged. Remove one of the two" >&2
|
|
475
|
+
echo " records (front matter, or the '## Status' block) and re-run." >&2
|
|
476
|
+
echo " See what the parser reads: $script_dir/plot-plan-meta.sh $rel" >&2
|
|
477
|
+
return 1
|
|
478
|
+
}
|
|
479
|
+
|
|
422
480
|
write_transition() { # $1=file $2=record $3=recorded(yes|no) → sets phase_report record_report
|
|
423
481
|
local f="$1" record="$2" recorded="$3" a="$1.plot-phase" b="$1.plot-record" flipped=0
|
|
424
482
|
|
|
@@ -428,6 +486,11 @@ write_transition() { # $1=file $2=record $3=recorded(yes|no) → sets phase_repo
|
|
|
428
486
|
[ -s "$a" ] || { rm -f "$a"; echo "plot-deliver: could not read $rel" >&2; return 1; }
|
|
429
487
|
|
|
430
488
|
if [ "$recorded" = "yes" ]; then
|
|
489
|
+
# THE DRY RUN, on the file this arm is about to land. A refusal discards the
|
|
490
|
+
# scratch copy and leaves the plan byte-identical — and never reaches
|
|
491
|
+
# `record_state_receipt`, which would otherwise license a commit of a state
|
|
492
|
+
# that was refused.
|
|
493
|
+
phase_would_read "$a" delivered || { rm -f "$a"; return 1; }
|
|
431
494
|
mv "$a" "$f" || { rm -f "$a"; return 1; }
|
|
432
495
|
record_report="already"
|
|
433
496
|
else
|
|
@@ -438,6 +501,9 @@ write_transition() { # $1=file $2=record $3=recorded(yes|no) → sets phase_repo
|
|
|
438
501
|
echo " with no record is invisible to the scan. Fix the section and re-run." >&2
|
|
439
502
|
return 1
|
|
440
503
|
fi
|
|
504
|
+
# `$b` AND NOT `$a`: this arm lands the file carrying the record, so `$a`
|
|
505
|
+
# is content that never reaches the plan.
|
|
506
|
+
phase_would_read "$b" delivered || { rm -f "$a" "$b"; return 1; }
|
|
441
507
|
mv "$b" "$f" || { rm -f "$a" "$b"; return 1; }
|
|
442
508
|
rm -f "$a"
|
|
443
509
|
record_report="written"
|