diff --git a/agents/darkwing/work/queue-273/BUILD.md b/agents/darkwing/work/queue-273/BUILD.md index d07f6448e..417c27b55 100644 --- a/agents/darkwing/work/queue-273/BUILD.md +++ b/agents/darkwing/work/queue-273/BUILD.md @@ -62,7 +62,11 @@ live in the node tests and test-release.sh runs unchanged. - T2 and T4 usage: every forbidden pairing and verb, checked against the full usage text. - T3: from an `--sso --send` pointer, `--no-sso` on the same copy gives back the pre-`--sso` ExecStart line byte for byte, without `--send`. A second case walks past a `--no-send` re-pin that ran with - `--sso` and keeps the pointer's tester port (7334), which differs from the set's (7333). + `--sso` and keeps the pointer's tester port (7334), which differs from the set's (7333). A third + (sage-2305 a) turns `--sso` on, then re-pins twice with `--send` and `--no-send`, so the two newest + sets both hold `--sso`. `--no-sso` then gives back the arrival's ExecStart line byte for byte. +- T4 (sage-2305 b): two sets, both edited or written to hold `--sso` with sums intact, refuse + `sso-off-flags` through `refused()`. - T4: `sso-not-on`; a set that fails its sums, ran with `--sso`, has no argv or is missing; a log with no set. Each runs through `refused()`, so nothing stops and nothing else changes. - T5: stack-release-external.test.mjs adds `--send` and `--no-sso` to the row 232 usage list. diff --git a/packages/cli/tests/stack-release.test.mjs b/packages/cli/tests/stack-release.test.mjs index 37bf143d3..83421b793 100644 --- a/packages/cli/tests/stack-release.test.mjs +++ b/packages/cli/tests/stack-release.test.mjs @@ -1807,6 +1807,37 @@ test('T58 row 273: activate --send and --no-sso',async(t)=>{ r=await prun(e,'status','acme');assert.equal(r.code,0,r.err);assert.match(r.out,/unit flags: match the pointer/); await noLeak(e); }); + await t.test('T3 (sage-2305 a): after --sso, two later re-pins that carry it, then --no-sso restores the flags from before --sso byte for byte',async(t)=>{ + const e=await mk(t),base=await seedPreview(e,undefined,['--tester-port','7333']);await ssoConfig(e); + let r=await prun(e,'activate',C1,'acme');assert.equal(r.code,0,r.out+r.err); + const pre=conExec(e);assert.ok(pre.endsWith(` ${base.join(' ')}`),pre); + r=await prun(e,'activate',C1,'acme','--sso');assert.equal(r.code,0,r.out+r.err); + const set=setOf(e,pointer(e).activation); + // Two same-copy re-pins carry --sso, so the two newest sets both hold a Console with it. + r=await prun(e,'activate',C1,'acme','--send');assert.equal(r.code,0,r.out+r.err); + r=await prun(e,'activate',C1,'acme','--no-send');assert.equal(r.code,0,r.out+r.err); + const acts=logLines(e).filter((l)=>l.result==='ok'&&l.op==='activate').map((l)=>l.activation).slice(-2); + for(const a of acts)assert.match(readFileSync(join(setOf(e,a),SHOW),'utf8'),/ --sso /); + const out=await planOnly(e,0,'activate',C1,'acme','--no-sso'); + assert.deepEqual(ssoLines(out),[OFF_PLAN(set,base.slice(0,-2).join(' '))]); + r=await prun(e,'activate',C1,'acme','--no-sso');assert.equal(r.code,0,r.out+r.err); + assert.deepEqual(pointer(e).console,base);assert.equal(conExec(e),pre); + r=await prun(e,'status','acme');assert.equal(r.code,0,r.err);assert.match(r.out,/unit flags: match the pointer/); + await noLeak(e); + }); + await t.test('T4 (sage-2305 b): a log in which every set holds a Console with --sso refuses before any unit stops',async(t)=>{ + const e=await mk(t);await seedPreview(e,undefined,['--send']);await ssoConfig(e); + let r=await prun(e,'activate',C1,'acme','--sso');assert.equal(r.code,0,r.out+r.err); + const first=setOf(e,pointer(e).activation); + r=await prun(e,'activate',C1,'acme','--no-send');assert.equal(r.code,0,r.out+r.err); + assert.match(readFileSync(join(setOf(e,pointer(e).activation),SHOW),'utf8'),/ --sso /); + // The set of the activation that turned --sso on now claims its Console ran with it too, sums intact. + setEdit(first,SHOW,' --public-host ',' --sso --public-host '); + const why=OFF_MSG(`the Console in ${join(first,SHOW)} already ran with --sso, and the log names no earlier activation`); + await refused(e,['activate',C1,'acme','--no-sso'],'sso-off-flags',why); + assert.deepEqual((await planOnly(e,3,'activate',C1,'acme','--no-sso')).filter((l)=>l.startsWith('refuses ')),[`refuses sso-off-flags: ${why}`]); + await noLeak(e); + }); await t.test('T4: --no-sso refuses before any stop on a pointer without --sso, a tampered or missing set, a set that ran with --sso, and a log with no set',async(t)=>{ const e=await mk(t);await seedPreview(e,undefined,['--send']); await refused(e,['activate',B,'acme','--no-sso'],'sso-not-on',NOT_ON_MSG);