From 1ac21d36cd9d47fd6a36c16f331a79866bf362a7 Mon Sep 17 00:00:00 2001 From: Jason Woltje Date: Sun, 25 Oct 2026 06:50:47 -0500 Subject: [PATCH] test(proxy): keep clock behavior inventory free of source grep checks --- .../queue-331/clock650-r3-expected-red.json | 218 ++++++++++++++++++ .../clock650-r3-file1-expected-red.json | 31 +++ .../clock650-r3-prepared-manifest.json | 141 +++++++++++ .../work/queue-331/clock650-r3-proposal.md | 21 ++ packages/cli/tests/model-turn-clock.test.mjs | 2 - 5 files changed, 411 insertions(+), 2 deletions(-) create mode 100644 agents/magica/work/queue-331/clock650-r3-expected-red.json create mode 100644 agents/magica/work/queue-331/clock650-r3-file1-expected-red.json create mode 100644 agents/magica/work/queue-331/clock650-r3-prepared-manifest.json create mode 100644 agents/magica/work/queue-331/clock650-r3-proposal.md diff --git a/agents/magica/work/queue-331/clock650-r3-expected-red.json b/agents/magica/work/queue-331/clock650-r3-expected-red.json new file mode 100644 index 000000000..125a760d0 --- /dev/null +++ b/agents/magica/work/queue-331/clock650-r3-expected-red.json @@ -0,0 +1,218 @@ +{ + "status": "STATIC expected only; source-grep case removed under sage4570, no clock execution", + "cases": 36, + "expectedRED": 31, + "expectedGREEN": 5, + "unverified": [ + "wrong owner", + "independently unreadable valid0600 metadata", + "current confined timestamp bounds until actual run" + ], + "files": [ + { + "path": "packages/cli/tests/model-turn-clock.test.mjs", + "cases": [ + { + "name": "650 idle longer than initial budget remains unarmed", + "expected": "RED", + "assertion": "idle time must not spend first-output budget" + }, + { + "name": "650 first silent turn spends one initial budget then invokes existing stop callback", + "expected": "RED", + "assertion": "silent turn clock is unarmed before first turn" + }, + { + "name": "650 first output cancels turn watcher without output text in receipt", + "expected": "GREEN", + "assertion": null + }, + { + "name": "650 later marker cannot extend already armed initial budget", + "expected": "GREEN", + "assertion": null + }, + { + "name": "650 idle run exit cancellation stops no process", + "expected": "GREEN", + "assertion": null + } + ] + }, + { + "path": "packages/cli/tests/model-turn-reader.test.mjs", + "cases": [ + { + "name": "650 reader rejects oversized without exposing metadata", + "expected": "RED", + "assertion": "invalid first-turn metadata triggers single trusted stop" + }, + { + "name": "650 reader rejects empty without exposing metadata", + "expected": "RED", + "assertion": "invalid first-turn metadata triggers single trusted stop" + }, + { + "name": "650 reader rejects wrong prefix without exposing metadata", + "expected": "RED", + "assertion": "invalid first-turn metadata triggers single trusted stop" + }, + { + "name": "650 reader rejects zero without exposing metadata", + "expected": "RED", + "assertion": "invalid first-turn metadata triggers single trusted stop" + }, + { + "name": "650 reader rejects future without exposing metadata", + "expected": "RED", + "assertion": "invalid first-turn metadata triggers single trusted stop" + }, + { + "name": "650 reader rejects leading zero without exposing metadata", + "expected": "RED", + "assertion": "invalid first-turn metadata triggers single trusted stop" + }, + { + "name": "650 reader rejects extra trailing newline without exposing metadata", + "expected": "RED", + "assertion": "invalid first-turn metadata triggers single trusted stop" + }, + { + "name": "650 reader rejects extra token without exposing metadata", + "expected": "RED", + "assertion": "invalid first-turn metadata triggers single trusted stop" + }, + { + "name": "650 reader rejects CRLF without exposing metadata", + "expected": "RED", + "assertion": "invalid first-turn metadata triggers single trusted stop" + }, + { + "name": "650 reader rejects malformed digit without exposing metadata", + "expected": "RED", + "assertion": "invalid first-turn metadata triggers single trusted stop" + }, + { + "name": "650 reader rejects highbit prefix without exposing metadata", + "expected": "RED", + "assertion": "invalid first-turn metadata triggers single trusted stop" + }, + { + "name": "650 reader rejects highbit digit without exposing metadata", + "expected": "RED", + "assertion": "invalid first-turn metadata triggers single trusted stop" + }, + { + "name": "650 reader rejects highbit newline without exposing metadata", + "expected": "RED", + "assertion": "invalid first-turn metadata triggers single trusted stop" + }, + { + "name": "650 reader rejects wrong mode", + "expected": "RED", + "assertion": "invalid first-turn metadata triggers single trusted stop" + }, + { + "name": "650 reader never follows owned symlink to a valid long-budget timestamp", + "expected": "RED", + "assertion": "invalid first-turn metadata triggers single trusted stop" + }, + { + "name": "650 reader FIFO cannot block the watcher process", + "expected": "RED", + "assertion": "FIFO metadata is refused through existing stop" + }, + { + "name": "650 reader late detection uses already-spent embedded budget", + "expected": "RED", + "assertion": "embedded initial timestamp already spent the budget" + }, + { + "name": "650 reader closes owned marker descriptors and never rereads armed timestamp", + "expected": "RED", + "assertion": "first marker read observed" + }, + { + "name": "650 first output cancels before malformed metadata can request a stop", + "expected": "GREEN", + "assertion": null + } + ] + }, + { + "path": "packages/harness/tests/first-turn.test.mjs", + "cases": [ + { + "name": "650 first-turn producer publishes time metadata only and keeps output content separate", + "expected": "RED", + "assertion": "first-turn protocol producer exists" + }, + { + "name": "650 subsequent actual turn cannot reset or extend first timestamp", + "expected": "RED", + "assertion": "first-turn one-shot producer exists" + }, + { + "name": "650 producer partial write failure keeps ownership and fixed diagnostic", + "expected": "RED", + "assertion": "guarded first-turn producer exists" + }, + { + "name": "650 producer exclusive collision failure keeps ownership and fixed diagnostic", + "expected": "RED", + "assertion": "guarded first-turn producer exists" + }, + { + "name": "650 producer link failure keeps ownership and fixed diagnostic", + "expected": "RED", + "assertion": "guarded first-turn producer exists" + }, + { + "name": "650 producer close failure keeps ownership and fixed diagnostic", + "expected": "RED", + "assertion": "guarded first-turn producer exists" + }, + { + "name": "650 producer unlink failure keeps ownership and fixed diagnostic", + "expected": "RED", + "assertion": "guarded first-turn producer exists" + } + ] + }, + { + "path": "packages/seat/tests/model-markers-confined.test.mjs", + "cases": [ + { + "name": "650 confined actual stdout writes fixed output marker in existing runDir without changing reply", + "expected": "GREEN", + "assertion": null + }, + { + "name": "650 confined actual adapter turn publishes first timestamp once and idle stays unarmed", + "expected": "RED", + "assertion": "actual confined turn publishes first-turn marker" + } + ] + }, + { + "path": "packages/harness/tests/model-turn-publication.test.mjs", + "cases": [ + { + "name": "650 landing publication failure reaps owned adapter then releases and exits2 without later turn", + "expected": "RED", + "assertion": "controlled publication failure observed at real caller" + }, + { + "name": "650 message publication failure reaps owned adapter then releases and exits2 without later turn", + "expected": "RED", + "assertion": "controlled publication failure observed at real caller" + }, + { + "name": "650 retry publication failure reaps owned adapter then releases and exits2 without later turn", + "expected": "RED", + "assertion": "controlled publication failure observed at real caller" + } + ] + } + ] +} diff --git a/agents/magica/work/queue-331/clock650-r3-file1-expected-red.json b/agents/magica/work/queue-331/clock650-r3-file1-expected-red.json new file mode 100644 index 000000000..ee6d0def6 --- /dev/null +++ b/agents/magica/work/queue-331/clock650-r3-file1-expected-red.json @@ -0,0 +1,31 @@ +{ + "status": "expected only; actual5behaviorcases preserved; source inspection not runtime proof", + "path": "packages/cli/tests/model-turn-clock.test.mjs", + "cases": [ + { + "name": "650 idle longer than initial budget remains unarmed", + "expected": "RED", + "assertion": "idle time must not spend first-output budget" + }, + { + "name": "650 first silent turn spends one initial budget then invokes existing stop callback", + "expected": "RED", + "assertion": "silent turn clock is unarmed before first turn" + }, + { + "name": "650 first output cancels turn watcher without output text in receipt", + "expected": "GREEN", + "assertion": null + }, + { + "name": "650 later marker cannot extend already armed initial budget", + "expected": "GREEN", + "assertion": null + }, + { + "name": "650 idle run exit cancellation stops no process", + "expected": "GREEN", + "assertion": null + } + ] +} diff --git a/agents/magica/work/queue-331/clock650-r3-prepared-manifest.json b/agents/magica/work/queue-331/clock650-r3-prepared-manifest.json new file mode 100644 index 000000000..f2c6ddf31 --- /dev/null +++ b/agents/magica/work/queue-331/clock650-r3-prepared-manifest.json @@ -0,0 +1,141 @@ +{ + "status": "r3 STATIC only, no clock execution/product edit; remove unexecuted code-grep testcase under sage4570", + "clockSourceCommit": "5868d77f18abeb01d2822cb475df48ce1336ae58", + "baseHEAD": "9507e2ee4380f09e1b23880b038b5f822437ee74", + "independentLowProduct": "tested committed6d3edea61 ModelKeys815b92c8, outside clock scope; clock product source unchanged", + "artifacts": [ + { + "path": "agents/magica/work/queue-331/clock650-r2-protocol-proposed.diff", + "sha256": "755290c5ef575a3e68d714bf42fffbb5ffe21e00fd34766cf0cfbebaad4afc71", + "bytes": 10644 + }, + { + "path": "agents/magica/work/queue-331/clock650-r2-D17-amendment.diff", + "sha256": "abd21fcbee6c39518a721d3bdac5a8af236b04b5a2434685a8a15591564c6c42", + "bytes": 2418 + }, + { + "path": "agents/magica/work/queue-331/clock650-r2-red-files.txt", + "sha256": "c4cb4e839fa24d185f8aebb9ba656a7e81dcd113636f49bb711f2da2e47a93e9", + "bytes": 241 + }, + { + "path": "packages/cli/tests/model-turn-clock.test.mjs", + "sha256": "1ad28416c4e55e9feebadafd8f2f2785968620b2445dba41362c470bbef4b214", + "bytes": 2399 + }, + { + "path": "packages/cli/tests/model-turn-reader.test.mjs", + "sha256": "7a9507a382c4e7a3216c3d3af6df8c35ccb17e5454d6b3701ffcd6e2113e9bbc", + "bytes": 6243 + }, + { + "path": "packages/harness/tests/first-turn.test.mjs", + "sha256": "d1843683fd4b75a60ac605aca22a0442f3e2201df5bdea41fcd667feedd93ac2", + "bytes": 4352 + }, + { + "path": "packages/seat/tests/model-markers-confined.test.mjs", + "sha256": "3fb2e3841f7368bcdd851aad1b4a6293175e0258bb6aa2cd1cdc2fd03c42049f", + "bytes": 6439 + }, + { + "path": "packages/harness/tests/model-turn-publication.test.mjs", + "sha256": "6a11bba06be1265ec7ab0229464334f6258a9fc2852615cce9b3acd7cca0437c", + "bytes": 6867 + }, + { + "path": "packages/cli/tests/fixtures/model-clock-probe.mjs", + "sha256": "d711c0b8c354d01432ad5aef0ccbd918526d3a64f0214276d28d78ddedc26ed4", + "bytes": 809 + }, + { + "path": "agents/magica/work/queue-331/clock650-r2-file1-red-files.txt", + "sha256": "d689b6986c489bb9aba95f3e812b9e877f8d4c1054c8336b231eff564b8d174b", + "bytes": 45 + }, + { + "path": "agents/magica/work/queue-331/clock650-r2-file2-red-files.txt", + "sha256": "9cdc15f9ee65fa8da2a4546df83dfb331aaf86bd5fc1a041862cc1a494302ef5", + "bytes": 46 + }, + { + "path": "agents/magica/work/queue-331/clock650-r2-file3-red-files.txt", + "sha256": "d9d218bd49de745872529b02de574da294fa4f3ced7e1434cee25a4767d96416", + "bytes": 43 + }, + { + "path": "agents/magica/work/queue-331/clock650-r2-file4-red-files.txt", + "sha256": "76932c1fce474f87d3a24b0710b5ce853aaaf468b499a900ca2b978c7c3aa35a", + "bytes": 52 + }, + { + "path": "agents/magica/work/queue-331/clock650-r2-file5-red-files.txt", + "sha256": "bd7cb63cd2264b9aa6519a9393725ba0c647caa4d9b530615ff871446b034a89", + "bytes": 55 + }, + { + "path": "agents/magica/work/queue-331/clock650-r2-file2-expected-red.json", + "sha256": "255c071c0cf3dcdd56d4242810012dd589d10dc3c3f04e6477fa4697ac1e051b", + "bytes": 3662 + }, + { + "path": "agents/magica/work/queue-331/clock650-r2-file3-expected-red.json", + "sha256": "6df81b6b33117ec43117188a92baad94b2ac21e757476a731d5cf696862f5ba5", + "bytes": 1404 + }, + { + "path": "agents/magica/work/queue-331/clock650-r2-file4-expected-red.json", + "sha256": "52602e87e2486e033d0b81f702e2260bc41991a02a8d63310dcb2dae61c6e86d", + "bytes": 528 + }, + { + "path": "agents/magica/work/queue-331/clock650-r2-file5-expected-red.json", + "sha256": "005474a66644ebc94ff0e2faff3a18f9a49893aa6ebe95413440b97b39c0578a", + "bytes": 821 + }, + { + "path": "agents/magica/work/queue-331/clock650-r3-expected-red.json", + "sha256": "2227053018382b99ebb8ed1d62227b84804e2a2d391b6c5606fcb4fa5fd3f21c", + "bytes": 8227 + }, + { + "path": "agents/magica/work/queue-331/clock650-r3-file1-expected-red.json", + "sha256": "efb0164c566f95819636ae5896d636ba8bc7d763517d1df2af6f8d4544615806", + "bytes": 976 + }, + { + "path": "agents/magica/work/queue-331/clock650-r3-proposal.md", + "sha256": "a4e5e7ed3312287ac01a13ce7f420dcb8393fa53b144af431494eb9220d64cd1", + "bytes": 7562 + } + ], + "unchangedClockProducts": [ + { + "path": "packages/cli/src/model-stall.mjs", + "sha256": "3df9770e8aae51357986a16473c96d2a3879bcd436153fa25c70f71b0ab181d7", + "bytes": 1012 + }, + { + "path": "packages/harness/src/first-output.mjs", + "sha256": "1ef13e5bd2ea9b166b505c46821f1649444b8fab9882531975858ce20a79f341", + "bytes": 473 + }, + { + "path": "packages/harness/src/runner.mjs", + "sha256": "9c0a0482c877dd5eae1e2691f20d30e37a289d68cb7d4998b0418c44055ae6d1", + "bytes": 31478 + }, + { + "path": "packages/cli/src/launcher.mjs", + "sha256": "28bd9bd37b6e71b1cdd8bbd7e6c94e47e5b08db9d6c07da90e7bead2ca2c45e4", + "bytes": 68551 + }, + { + "path": "packages/seat/src/sandbox.mjs", + "sha256": "a203f7bb2735e4abeb0758c7719022545696b35f00d7943144b73aa892091807", + "bytes": 10764 + } + ], + "supersedes": "clock650-r2-prepared-manifest.json; product755290c5 unchanged" +} diff --git a/agents/magica/work/queue-331/clock650-r3-proposal.md b/agents/magica/work/queue-331/clock650-r3-proposal.md new file mode 100644 index 000000000..09b13371d --- /dev/null +++ b/agents/magica/work/queue-331/clock650-r3-proposal.md @@ -0,0 +1,21 @@ +# #650 r3 test-scope revision, product bytes unchanged STATIC packet — exact bytes need Mos/Sage inspection + +Supersedes historical0875b66f; no clock product changes or clock execution. Directions1706/1707 retained; this revised exact four-file delta and tests are proposals, not implementation/run approval. Clock product files remain5868; independently applied low ModelKeys815b92c8 is outside these clock source paths. + +Internal nonproxy opt-in: only launcher `if(system.proxy)` writes fixed0600 runDir/proxy-first-turn-enabled before spawn, via exclusive create. Failure uses existing launch-failed with fixed setup diagnostic. Managed watch always passes armAtFirstTurn:true. No session.json/publicconfig/adapterAPI/env/P3 field. Runner caches enabled existence in PRIVATE in-memory session property AFTER parsed JSON, overriding any JSON field; no adapter runs before this initialization. Nonproxy lacks this host marker and never invokes first-turn producer; actual confined stdout control asserts no turn timestamp after two real adapter turns. Existing output marker remains unchanged in ALL modes. Managed proxy producer/watcher caller was inspected directly by Sage; its source-grep test has been removed from behavior inventory. This is NOT actual runtime proxy-launch proof; existing launcher controls and future appropriate integration remain required. + +Successful /bin/sh adapter child spawn inside common runTurn is actual-turn boundary for landing/message/guardedretry (technical owner interpretation, not Jason quote). One initial budget, idle unarmed, output cancels forever, no later reset/extension. Atomic metadata same runDir only: final proxy-first-turn `turn \n`; own temporary `.proxy-first-turn--`. Exclusive OPEN confers ownership immediately, then write/link-no-replace. Independent guarded close/unlink attempts run even after partial write/close error; collision never confers ownership/unlinks someone else's temp. All producer failure diagnostics fixed, no raw error/path/text. No new import module, mount, copy/image, authority, key or public schema. + +Strict reader: NOFOLLOW|NONBLOCK; regular0600/currentuid/size<=64; bounded read; reject ANY rawbyte>127 BEFORE ASCIIdecode; canonical non-leading-zero positive timestamp/exact newline with complete matched-length check (JS dollar-anchor's optional final newline cannot accept extra trailing newline). Reject malformed/zero/future/noncanonical/size/mode/owner/IO as immediate same trusted modelStall/fixed proxy-stall once unless output already cancelled; absent ENOENT idle/unarmed. Once embedded timestamp+budget is captured, no later read/arrival reset; maxpoll1s unchanged. Late detection spends original embedded budget. Every open path attempts close, tests check own marker descriptors after valid/invalid/FIFO reads. Current Linux+bwrap no-time-namespace shared hrtime origin is an inference until actual confined bound passes nonskip, not portable Node guarantee. + +Controlled producer failure, precise SOURCE trace: original EventEmitter spawn callback throw has no general runTurn/main catch; main bottom merely awaits main. Historical0875 was NOT executed and cannot claim observed fatal cleanup. Revised callback is inside real turn promise lifecycle, catches producer error, marks private markerFailed, cancels own turn clock, signals ONLY captured owned adapter group TERM then tracked5s KILL. It waits child CLOSE/reap; close clears both timers BEFORE existing final group cleanup and resolves fixed private failure. No registry PID/stop authority. All three callers consume markerFailed AFTER normal usage-end bookkeeping: landing marks gone/breaks its loop, ordinary/retry break main loop; no later turn/metadata attempt. Fixed runner diagnostic, existing failed exit2 (EXIT.usage), normal tool-server close/socket unlink and EXISTING role.release call also runs for this controlledfailure. Launcher exit continuation then existing endRun/registryremove/endlog/runtime-unregister/workspace-lock release; no new reason/processing schema. No claim generic old catch covered this. + +Failure tests run real UNCONFINED runner+real Broker/SQLite/library guard; TEST-ONLY preload wraps original fs.linkSync for exact own temp-prefix/final target, plus real own adapter spawn and owned negative-group signal observation/guard. All actual IO/spawn/signal operations pass through except selected owned link fault; unrelated fs passes through, unowned group signal blocked/counted. This is NOT a product injection seam, not a new managed mount and not confined-fault proof. Landing/message fail publication attempt1; retry uses actual library guard rejection then fails attempt2 (defensive failure on later producer attempt even though initial timestamp already exists). Controlled exit/release/no later attempt/owned groups are asserted. Adapter may terminate before its fixture code runs; this does not claim actual upstream API or forced TERM-resistant5s escalation. New5s timer clearing is exact source evidence, not OS PID reuse stress. + +Producer fault unit cases narrowly intercept only own fixture temp paths/ownedFD, restore named builtins, test partial write/exclusive collision/link/close/unlink and fixed error/cleanup attempts. Unlink failure may leave owned temp until fixture root cleanup; cannot claim guaranteed deletion after failed unlink. Ownership never transfers on collision. Direct confined SUCCESS tests remain separate real spawnSession/bwrap/Broker/shell using existing pi mount pattern, no additional bind; fixed stdout0600/no private output/no reply change/once, first-turn timestamp bounded between host observations/temp cleanup/once. Unavailable confinement is UNVERIFIED not green. CLI stop callback unit is stand-in, not real modelStall or rotation SIGTERM proof. + +Prepared36cases across five whole files: clock5=2expectedRED3GREEN; reader19=18expectedRED1GREEN; producer7=7expectedRED; confined2=1expectedRED1GREEN; real processfailure3=3expectedRED. Total31expectedRED5GREEN, NOT OBSERVED. Each file has own REDlist/map; do not infer combined run authority. FIFO is isolated in exact owned child with5s parent kill bound, helper itself cancels at100ms; prevents synchronous bad-open hanging test driver. Metadata negative old-code failures assert missing expected stop, not observer timeout. All perfile contexts remain original clock source baseline5868. + +Wrongowner and independently unreadable otherwise-valid0600 fixtures NOT fabricated: changing UID/access on owned file without portable privilege/ACL is not assumed. Those distinct branches remain UNVERIFIED pending feasible owned fixture/ruling; current exact owner and open-error guards reviewed statically. No artificial green/skip claim. Tests cover wrongmode and FD cleanup; they do not imply wrongowner/access proof. New controlledfailure process fixtures have early own resource cleanup, only own children; preloader never prints secret/material. Existing old assertions/deadlines untouched. + +Before any clock product implementation/RED run: inspect exact revised protocol, opt-in setup failure reuse of launch-failed, all test-only interception, callsite/failure cleanup, maps/limits. Proposed focused GREEN later: new five files first; cli/model-stall; harness/first-output, runner, citation-runner; seat/sandbox, session; cli/launcher/session-launch; bus/model-stop/model-proxy. Same serial whole-file private scratch/nice19 measured; new full import graph and separate global/review gates after stable source, no automatic nextgate. diff --git a/packages/cli/tests/model-turn-clock.test.mjs b/packages/cli/tests/model-turn-clock.test.mjs index 43f144908..59919c8f7 100644 --- a/packages/cli/tests/model-turn-clock.test.mjs +++ b/packages/cli/tests/model-turn-clock.test.mjs @@ -13,5 +13,3 @@ test('650 first silent turn spends one initial budget then invokes existing stop test('650 first output cancels turn watcher without output text in receipt',async t=>{const f=fixture(t);f.arm();fs.writeFileSync(join(f.runDir,'proxy-first-output'),'output\n',{mode:0o600});await doneWithin(f.watch);assert.equal(f.stops(),0);assert.deepEqual(f.receipts,[]);}); test('650 later marker cannot extend already armed initial budget',async t=>{const f=fixture(t);f.arm();await delay(30);fs.writeFileSync(join(f.runDir,'proxy-first-turn'),`turn ${process.hrtime.bigint()+60_000_000_000n}\n`);await doneWithin(f.watch);assert.equal(f.stops(),1);}); test('650 idle run exit cancellation stops no process',async t=>{const f=fixture(t);f.watch.cancel();await f.watch.done;assert.equal(f.stops(),0);assert.deepEqual(f.receipts,[]);}); - -test('650 managed launcher explicitly enables producer and first-turn watcher only in proxy mode',()=>{const source=fs.readFileSync(new URL('../src/launcher.mjs',import.meta.url),'utf8');const start=source.indexOf(' if (system.proxy) {',source.indexOf('const { run, runDir } = newRun')),end=source.indexOf(' const sessionDir',start),block=source.slice(start,end);assert.equal(block.includes('proxy-first-turn-enabled'),true,'managed proxy launcher enables internal producer protocol');assert.match(source,/watchModelOutput\(\{ runDir, armAtFirstTurn: true/,'managed proxy watcher explicitly arms at first actual turn');});