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 bce074a
Browse filesBrowse the repository at this point in the historyBrowse files
pm(signature): issue-create and the dispatch door refuse unsigned bodies; pins on every first-line reader; one skill line
issue-create refuses an unsigned card body beside the stamp-token rule;
fleet-write/dispatch refuses an unsigned comment_edit / issue_patch body
in a seat's actions file (the roster's generated body exempt by its
imported marker). record-recognisers pins every named first-line reader
with and without a leading signature; label-write pins its two readers.
seat-post-protocol.md states the signature in one line, paid by the
standing-liveness line whose content lives in dispatch-runbook.md.
Claude-Session: https://claude.ai/code/session_01QSeKYmhU5KEj1nukYhp1Tg
Co-authored-by: Claude <noreply@anthropic.com>
if(!body)errors.push('the body is empty — a card names its evidence');
203
-
elseif(STAMP_TOKEN.test(body))errors.push('the body carries a {{NOW}} / {{WAS:…}} token — those are post-stamped.mjs\'s contract for comments; a new card is dated by the platform');
209
+
else{
210
+
if(STAMP_TOKEN.test(body))errors.push('the body carries a {{NOW}} / {{WAS:…}} token — those are post-stamped.mjs\'s contract for comments; a new card is dated by the platform');
211
+
// The signature (#27113), judged beside the token rule so a body breaking both hears both.
212
+
constunsigned=signatureRefusal(body);
213
+
if(unsigned!==null)errors.push(`the body carries no signature line — ${unsigned.why}; its first line reads \`${unsigned.line}\`. Write ${SEAT_SIGNATURE_SHAPE} as the FIRST line; nothing inserts it for you`);
214
+
}
204
215
}
205
216
206
217
constlabels=dedupe(opts.labels);
@@ -421,13 +432,14 @@ export async function relayMissProbe({ route, send, pace }) {
421
432
constSELF_TEST_BATTERIES=Object.freeze({
422
433
'the arguments: files not argv for prose, exactly one title source, a repo shape': 10,
423
434
'the payload: title trimmed to one line, labels and assignees de-duplicated, nothing invented': 5,
435
+
"the signature: a card body opens with the seat's signature line, or the plan is refused before any request": 8,
424
436
'the transport: a fake platform, and what each answer does to the exit code': 9,
425
437
'dry-run: no request leaves, and the plan is printed': 3,
426
438
'the wiring: both halves around the one POST, on the write verb only': 4,
427
439
'the relay transport: ONE dispatch carrying the create, the card found by title since the dispatch, and an accepted dispatch with no run UNCONFIRMED under auto too — never the direct POST': 9,
428
440
"the relay annotation: the number the relay run's annotation carries is read first — the card read back at it with NO list; absent, the title finds it as before; the read-back still judges the annotated card": 5,
429
441
});
430
-
constSELF_TEST_BATTERY_FLOOR=7;
442
+
constSELF_TEST_BATTERY_FLOOR=8;
431
443
constUNATTRIBUTED_BATTERY='(unattributed)';
432
444
433
445
constbatteryCases=newMap();
@@ -450,7 +462,18 @@ export async function selfTest() {
450
462
const{ tmpdir }=awaitimport('node:os');
451
463
const{ join }=awaitimport('node:path');
452
464
453
-
constfiles={'title.txt': ' A card with `backticks` and $HOME in it \n','body.md': 'Evidence: a repro.\n\n- step one\n','empty.md': ' \n','stamped.md': 'Reading time {{NOW}}\n'};
465
+
// Every body a seat hands this door opens with the seat's signature (#27113), so the fixtures that must plan do too.
'second-line.md': 'Evidence: a repro.\n\ndomain:skills#2 · os-justin · session_01ABCDEFGHJKMNPQRSTVWXYZ\n',
476
+
};
454
477
constread=(p)=>{
455
478
if(!(pinfiles))thrownewError('ENOENT');
456
479
returnfiles[p];
@@ -486,6 +509,32 @@ export async function selfTest() {
486
509
t('a body carrying a stamp token is refused — that is post-stamped\'s contract',planFrom(parseArgs(['--title','x','--body-file','stamped.md']),{ read, env }).errors.some((e)=>e.includes('{{NOW}}')));
487
510
}
488
511
512
+
// ── the signature ─────────────────────────────────────────────────────────
513
+
battery('the signature: a card body opens with the seat\'s signature line, or the plan is refused before any request');
t('an unsigned body is refused — the plan is not ok',unsigned.ok,false);
518
+
t('…and the refusal names the shape to write and the line it read',unsigned.errors.some((e)=>e.includes('no signature line')&&e.includes('LANE#N · ACCOUNT · SESSION')&&e.includes('`Evidence: a repro.`')));
519
+
t('a signed body plans, and the signature is SENT as written — nothing stripped, nothing inserted',[plan('body.md').ok,plan('body.md').payload.body.split('\n')[0]],[true,SIG]);
520
+
t('a near miss (hyphens for the ` · ` separator) is refused, and named as one',plan('near-miss.md').errors.some((e)=>e.includes('reads like a signature and is not one')));
521
+
t('⛔ a signature on a LATER line is not a signature: the first non-empty line decides',plan('second-line.md').ok,false);
522
+
constboth=plan('unsigned-stamped.md').errors;
523
+
t('a body breaking BOTH rules hears both, in one refusal',[both.some((e)=>e.includes('{{NOW}}')),both.some((e)=>e.includes('no signature line'))],[true,true]);
524
+
t('an empty body is told it is empty, once — not also unsigned',plan('empty.md').errors.filter((e)=>e.includes('body is empty')||e.includes('signature')).length,1);
t('⛔ the CLI refuses an unsigned body on a DRY RUN too — usage, nothing printed as sent, nothing paced',[cli.status,cli.stdout.includes('NOTHING was sent'),existsSync(join(dir2,'pace.jsonl'))],[EXIT_USAGE,false,false],cli.stderr.slice(-300));
'the remaining exits: refusal, mismatch, the ONE-OF block and the dry run': 5,
1564
1564
'the CLI: what a typo must never be allowed to mean': 8,
1565
1565
'the relay transport: ONE dispatch carrying the whole stroke, the same read-back, and an accepted dispatch with no run UNCONFIRMED under auto too — never a direct write': 14,
1566
-
'the release: a silent claim reclaimed in ONE relay stroke — Release: comment → pm:queue on → pm:dispatched off → unassign — on the knock\'s SERVER-clock age, RELAY-ONLY, never a direct write': 30,
1566
+
'the release: a silent claim reclaimed in ONE relay stroke — Release: comment → pm:queue on → pm:dispatched off → unassign — on the knock\'s SERVER-clock age, RELAY-ONLY, never a direct write': 32,
1567
1567
});
1568
1568
constSELF_TEST_BATTERY_FLOOR=11;
1569
1569
constUNATTRIBUTED_BATTERY='(unattributed)';
@@ -1819,6 +1819,10 @@ export async function selfTest() {
t('the release text is judged by the owning `Release:` reader on its FIRST line, and may not pre-write the resume line',[releaseTextRefusal(RELEASE_TEXT),typeofreleaseTextRefusal('Released: x'),typeofreleaseTextRefusal('note\nRelease: x'),typeofreleaseTextRefusal('Release: x\nResume-from: a@b'),typeofreleaseTextRefusal('')],[null,'string','string','string','string']);
1822
+
// One leading signature line (#27113) stands ABOVE the first-line key, never in its place.
t('a signed knock reads by the key on the line after its signature; a key on a later line, or under a near-miss signature, still does not',[isRecheckComment(`${SIG}\nOwned-24h re-check: x`),isRecheckComment(`${SIG}\n\n## Owned-24h re-check: x`),isRecheckComment(`${SIG}\nTriage\nOwned-24h re-check: x`),isRecheckComment('domain:skills#2 - os-justin - session_01ABCDEFGHJKMNPQRSTVWXYZ\nOwned-24h re-check: x')],[true,true,false,false]);
1825
+
t('…and a signed release text is judged by its `Release:` line: accepted signed as unsigned, refused when no `Release:` line follows the signature',[releaseTextRefusal(`${SIG}\n${RELEASE_TEXT}`)===releaseTextRefusal(RELEASE_TEXT),typeofreleaseTextRefusal(`${SIG}\nnote\nRelease: x`)],[true,'string']);
1822
1826
1823
1827
// The fixture card the protocol names, younger than the clock.
'the decision facets: a decision analysis carries its marker, and a delta, a record or a quotation is not one': 22,
4068
4070
'the relay transport: the same act as one op, the comment found on the board, the exit register kept apart': 13,
4069
4071
"the size route: over the relay's body cap under auto THIS write goes direct with one line naming bytes, cap and identity; at or under it the relay; explicit dispatch refuses naming the bytes; nothing else re-routes": 13,
4072
+
'the signature: every body opens with LANE#N · ACCOUNT · SESSION or is refused, beside the stamp contract; one leading signature changes no reading': 11,
4070
4073
});
4071
-
constSELF_TEST_BATTERY_FLOOR=17;
4074
+
constSELF_TEST_BATTERY_FLOOR=18;
4072
4075
constUNATTRIBUTED_BATTERY='(unattributed)';
4073
4076
4074
4077
letselfTestReachedVerdict=false;
@@ -5521,6 +5524,40 @@ export function selfTest() {
5521
5524
t('⛔ the proxy re-exec at the entrypoint is UNCONDITIONAL — a dry run resolves the route, which is a read, so it re-execs too',entrySource.includes('rearmThroughProxy(process.argv.slice(2))')&&/--dry-run'\)\s*\?\s*null\s*:\s*rearmThroughProxy/.test(entrySource)===false);
5522
5525
}
5523
5526
5527
+
// ── the signature (#27113) ─────────────────────────────────────────────────
5528
+
battery('the signature: every body opens with LANE#N · ACCOUNT · SESSION or is refused, beside the stamp contract; one leading signature changes no reading');
t('a signed body has no refusal row; an unsigned one has one naming the line it read',signatureRefusal(`${SIG}\nbody`)===null&&signatureRefusal('Hello\nbody')?.line==='Hello');
5532
+
t('the refusal text prints the shape to write and says nothing was written',signatureRefusalText(signatureRefusal('Hello'),{tool: 'post-stamped'}).includes('LANE#N · ACCOUNT · SESSION')&&signatureRefusalText(signatureRefusal('Hello'),{tool: 'post-stamped'}).includes('Nothing was written'));
5533
+
t('⛔ the positional stamp rule still reads the ACT\'s line: a bare stamp on the claim line under a signature is refused',kinds(`${SIG}\nClaim: seat 2026-09-10T06:37Z`,NOW_MS).join()==='positional');
5534
+
t('…and `{{NOW}}` there is accepted, the signature sent as written above it',renderBody(`${SIG}\nClaim: seat {{NOW}}`,NOW_MS).ok&&renderBody(`${SIG}\nClaim: seat {{NOW}}`,NOW_MS).body.split('\n')[0]===SIG);
5535
+
constPLAIN=['Decision record: who lands the gate','','- **A**: the seat lands it','- **B**: the maintainer lands it','','This seat recommends **A**.'].join('\n');
5536
+
t('a decision analysis framed on its plain OPENING line is refused unsigned and signed alike — the frame is the line after the signature',decisionFacetRefusals(PLAIN).length===1&&decisionFacetRefusals(`${SIG}\n${PLAIN}`).length===1);
t('⭐ the CLI refuses an unsigned COMMENT on a dry run: exit 2, the signature refusal on stderr, nothing on stdout',comment.status===EXIT_REFUSED&&comment.stderr.includes('opens with no signature line')&&comment.stdout==='');
5545
+
constbody=run(['--dry-run','--body=1','--repo=o/r'],'**This post is the single authoritative registration.**\n');
5546
+
t('⭐ …and an unsigned card BODY too — both modes, the seat post above all',body.status===EXIT_REFUSED&&body.stderr.includes('opens with no signature line'));
t('a body breaking the stamp contract AND unsigned hears BOTH, under one exit',both.status===EXIT_REFUSED&&both.stderr.includes('stamp-contract problem')&&both.stderr.includes('opens with no signature line'));
t('an empty body is told it is empty, once — not also unsigned',empty.status===EXIT_REFUSED&&empty.stderr.includes('the body is empty')&&!empty.stderr.includes('signature'));
5551
+
}finally{
5552
+
rmSync(dir,{recursive: true,force: true});
5553
+
}
5554
+
// The slice the size-route battery takes: main, up to the self-test's banner.
5555
+
constownText=readFileSync(SELF_PATH,'utf8');
5556
+
constmainSource=ownText.slice(ownText.indexOf('async function main(argv)'),ownText.indexOf('// --self-test — offline'));
5557
+
t('structural: the signature is judged on BOTH modes, before the keyed lines and before the route is resolved',/constunsigned=rendered\.kind==='empty'\?null:signatureRefusal\(input\);/u.test(mainSource)&&mainSource.indexOf('signatureRefusal(input)')<mainSource.indexOf('claimKeyedLineRefusals(')&&mainSource.indexOf('signatureRefusal(input)')<mainSource.indexOf('await resolveRoute('));
5558
+
t('the usage says it, with the shape',USAGE.includes('signature')&&USAGE.includes(SEAT_SIGNATURE_SHAPE));
5559
+
}
5560
+
5524
5561
// The floor, evaluated last: a battery that stops running names itself here.
0 commit comments