You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 2875a31
Browse filesBrowse the repository at this point in the historyBrowse files
fix(pm): write-pace fails closed on an unrecordable log, and its lock is bounded by attempts
Three things the first draft got wrong, all found by its own new cases:
- an unwritable log threw out of the transport. `paceWrite` now REFUSES with the
distinct exit code and a one-line remedy — a throttle that cannot record cannot
count, so it cannot honestly allow the write either;
- `noteResponse` is the asymmetric half: it runs one line before the caller throws
the platform's own refusal, so it never throws, and reports the consequence
(the marker did not land) instead;
- the lock retry was bounded only by a deadline read from an injected clock. A
recursive mkdir over a path that is a FILE answers EEXIST, the same code
contention answers, so an unusable path read as a busy lock and spun forever
under a clock that does not advance. Bounded by attempts as well, the directory
mkdir moved out of the retry, and both pinned.
Claude-Session: https://claude.ai/code/session_012GcsUbuqFGBibkEDMRC1eE
Co-Authored-By: Claude <noreply@anthropic.com>
'rule ②: the 41st is REFUSED, with a prescription': 8,
635
692
'rule ③: what writes a stop marker, how long it lasts, what it refuses': 10,
636
693
'the prune: the trailing hour for writes, the expiry for markers': 6,
637
-
'the log, --status and the CLI: what lands on disk, and what must never': 9,
694
+
'the log, --status and the CLI: what lands on disk, and what must never': 14,
638
695
'the wiring: both halves, in every write transport, on write verbs only': 7,
639
696
});
640
697
constSELF_TEST_BATTERY_FLOOR=9;
@@ -873,6 +930,27 @@ export async function selfTest() {
873
930
});
874
931
t('the CLI reports a budget nobody has spent yet, at exit 0',spawned.status===0&&spawned.stdout.includes(`budget : 0 of ${DEFAULT_HOURLY_MAX}`),true,JSON.stringify(spawned.stdout));
875
932
t('an unrecognised flag is usage, ⛔ never a silent pass',spawnSync(process.execPath,[SELF,'--paec'],{encoding: 'utf8'}).status,EXIT_USAGE);
933
+
934
+
// An unwritable log: the parent of the path is a FILE, so every mkdir on
935
+
// the way to it fails. The two halves answer this DIFFERENTLY on purpose.
t('⛔ a log it cannot write REFUSES the write — unrecorded is the state this exists to prevent',[unrecordable.verdict,bad.state.exits],['unrecordable',[EXIT_WRITE_PACE_REFUSED]]);
941
+
t('…naming the path and the one-line remedy',bad.text().includes('OS_PM_WRITE_PACE_FILE'));
t('⛔ but `noteResponse` does NOT throw — it runs one line before the caller throws the platform\'s own error',[noted.recorded,noted.why],[false,'HTTP 429']);
944
+
945
+
// ⛔ THE case the attempt bound exists for, found by the case above: a
946
+
// lock somebody else holds, plus a clock that does not advance. The
947
+
// deadline can then never fire, so only the attempt bound ends the wait.
0 commit comments