From 6df580f3f8ff674bcf107c05a09c24594ce04d80 Mon Sep 17 00:00:00 2001 From: EHotwagner Date: Sat, 3 Oct 2026 21:25:06 +0200 Subject: [PATCH] Bind selected stock pairing diagnostics to the owned capture --- .../barc-01.5f-pairing-observability-20261003.md | 4 ++++ .../Broker.NativeProof/tactical-native-journey.spec.js | 2 +- .../tactical-native-readiness.test.mjs | 10 ++++++++-- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/docs/roadmaps/evidence/barc-01.5f-pairing-observability-20261003.md b/docs/roadmaps/evidence/barc-01.5f-pairing-observability-20261003.md index a5b16b2..240bd8d 100644 --- a/docs/roadmaps/evidence/barc-01.5f-pairing-observability-20261003.md +++ b/docs/roadmaps/evidence/barc-01.5f-pairing-observability-20261003.md @@ -19,3 +19,7 @@ PR 31 initially had no native checks because the existing RuntimeEvidence workfl Pipeline preflight is static: this is one linear job with no matrix, shared artifacts, reuse, or publication. A custom model would add maintenance without an interaction to check. The assessment is limited to configuration, trigger coverage, shell syntax, and exact test selection; reuse is expected on later changes to the same inputs, with a ten-minute assessment cap and a ten-minute hosted timeout. Local workflow commands passed: build with zero warnings, fourteen JavaScript tests, and three exact compiled tests. Result-refusal controls and compiled reflection of preserved union tags 0–14 also passed. Native exact-head acceptance remains pending; historical cause remains Unknown and useful native play remains 0/6. Native run `37145445532` at head `ab81ef61eaf43571b3ddc7aba4619f8c6b778328` passed the JavaScript controls, then failed during protobuf generation: pinned `grpc-fsharp` 0.2.0 targets .NET 6 while the runner has .NET 8/9/10. Compiled controls were skipped and do not qualify that head. The build step now supplies `DOTNET_ROLL_FORWARD=LatestMajor`, matching the existing generator policy in `specs/001-tui-grpc-broker/readiness/feature-baseline.md` and `us1-progress.md`, through the step environment. No package runtimeconfig or dependency pin is changed. An isolated .NET-10-only setup control reproduced exit 150 without the setting and returned exit 0 with it using the unchanged generator and empty protobuf request. YAML, environment scope, preserved steps/pins, and shell syntax passed static checks; the repaired native run remains pending. + +PR 31 subsequently merged as `742e73caa4413ded82e65fcc6c712ab9e1084902`, tree `80c15c7a1fbcc0fd034a734507c14ecc4cd1dec9`, after native run `37146325321` passed the fourteen JavaScript and three synthetic compiled controls at exact head `c0add113363af5d84ee18242220157cd4c554e78`. Unified progress PR 4163 records that source delivery. Read-only artifact tracing then found the selected stock route omitted `outputPath` from its pairing context, although the new sidecar writer requires it. The selected context now binds `outputPath` to its existing admitted `capturePath`, alongside the unchanged arm-failure destination. + +The existing sidecar control now executes the exact selected-stock context initializer with synthetic handoff/environment values and a journal stub, then invokes the actual diagnostic writer under an owned temporary mode-0700 parent. Before this fix it failed at the writer; after the fix all fourteen JavaScript controls pass. It checks the exact capture-derived sidecar and arm-failure destinations, rejects a foreign capture path before journal construction, and retains private/exclusive publication, payload omission, bounded bytes and unsafe-parent refusal. JavaScript syntax and diff checks pass. No browser, game, build, grant, protected activation or genuine capture was run for this JavaScript-only repair. Native qualification of the successor source remains pending; the historical cause and missing READY/raw-map observations stay Unknown, with useful native play 0/6. diff --git a/tests/Broker.NativeProof/tactical-native-journey.spec.js b/tests/Broker.NativeProof/tactical-native-journey.spec.js index 3ffe742..1569e93 100644 --- a/tests/Broker.NativeProof/tactical-native-journey.spec.js +++ b/tests/Broker.NativeProof/tactical-native-journey.spec.js @@ -180,7 +180,7 @@ test.describe("actual tactical BAR receiver",()=>{test.skip(!enabled,"requires p test.describe("selected stock Count1 smoke",()=>{ test.skip(!stockEnabled,"requires root-admitted selected stock smoke handoff"); test("uses the production browser path and retains exact stock trace joins",async({page})=>{ - const h=stockHandoff,capturePath=process.env.BARC_STOCK_SMOKE_CAPTURE,releasePath=process.env.BARC_STOCK_SMOKE_RELEASE;if(capturePath!==h.paths.capture)throw new Error("authenticated capture path changed");const journal=captureJournal(capturePath,releasePath,h.runId,h.source),j={receiverUrl:h.connection.receiverUrl,gatewayUrl:h.connection.gatewayUrl,allowedOrigin:h.connection.allowedOrigin,expectedSessionId:h.connection.sessionId,credential:h.connection.credential,bundledGuestSha256:h.artifacts.guest.sha256,armFailurePath:`${capturePath}.arm-failure.json`}; + const h=stockHandoff,capturePath=process.env.BARC_STOCK_SMOKE_CAPTURE,releasePath=process.env.BARC_STOCK_SMOKE_RELEASE;if(capturePath!==h.paths.capture)throw new Error("authenticated capture path changed");const journal=captureJournal(capturePath,releasePath,h.runId,h.source),j={receiverUrl:h.connection.receiverUrl,gatewayUrl:h.connection.gatewayUrl,allowedOrigin:h.connection.allowedOrigin,expectedSessionId:h.connection.sessionId,credential:h.connection.credential,bundledGuestSha256:h.artifacts.guest.sha256,outputPath:capturePath,armFailurePath:`${capturePath}.arm-failure.json`}; try{const rows=await capture(page,journal),live=await pair(page,j,"Manual guest",rows);await expect.poll(()=>latest(rows)?.basis?.stateSequence??null,{timeout:30000}).not.toBeNull();await select(page,live,"pointer",[h.actors.factory]);const initial=queue(latest(rows),h.actors.factory,"QUEUE_DOMAIN_FACTORY_PRODUCTION");expect(initial?.complete).toBe(true);expect(initial?.evidenceScheme).toBe("NATIVE_QUEUE_EVIDENCE_SCHEME_STOCK_LUA_SUPPORTED_FIELDS_V1");expect(initial?.entries?.length).toBeGreaterThan(0); await target(live,h.setup.positions.rally);await live.getByLabel("Action").selectOption("setRally");await trigger(page,live,rows,"pointer","stockSmokeRally");await live.getByLabel("Action").selectOption("factoryProduce");await live.getByLabel("Definition").selectOption(String(h.setup.productDefinitionId));await live.getByLabel("Count").fill("1");await live.getByLabel("Queue policy").selectOption("TACTICAL_QUEUE_POLICY_APPEND");const append=await trigger(page,live,rows,"pointer","stockSmokeAppend1");expect(plannedChildCount(append.submit.intent)).toBe(1); const beforeReplace=rows.filter(row=>row.kind==="submit").length;await live.getByLabel("Queue policy").selectOption("TACTICAL_QUEUE_POLICY_REPLACE");await live.getByRole("button",{name:"Send tactical command"}).click();await expect(live.locator(".result")).toContainText("No Append fallback");await page.waitForTimeout(250);expect(rows.filter(row=>row.kind==="submit")).toHaveLength(beforeReplace);journal.append("ui-refusal",{action:"factoryProduce",queuePolicy:"TACTICAL_QUEUE_POLICY_REPLACE",submitCountBefore:beforeReplace,submitCountAfter:beforeReplace,detail:"No Append fallback"}); diff --git a/tests/Broker.NativeProof/tactical-native-readiness.test.mjs b/tests/Broker.NativeProof/tactical-native-readiness.test.mjs index c95d94d..2e19ef7 100644 --- a/tests/Broker.NativeProof/tactical-native-readiness.test.mjs +++ b/tests/Broker.NativeProof/tactical-native-readiness.test.mjs @@ -125,8 +125,14 @@ test("exact client close observer forwards original once and contains diagnostic }); test("pairing sidecar publishes exclusive private bounded bytes and refuses unsafe parents",async()=>{ const dir=await mkdtemp(resolve(tmpdir(),"bar-pairing-projection-"));try{ - chmodSync(dir,0o700);const j={outputPath:resolve(dir,"capture")},state=pairing.pairingState();state.secret="PRIVATE";pairing.notePairing(state,"socket"); - pairing.writePairingDiagnostic(j,state,null);const path=j.outputPath+".pairing-diagnostic.json",text=await readFile(path,"utf8"),pin=await stat(path);assert.equal(pin.mode&0o777,0o600);assert.equal(pin.nlink,1);assert.ok(Buffer.byteLength(text)<=4096);assert.equal(text.includes("PRIVATE"),false); + chmodSync(dir,0o700);const capturePath=resolve(dir,"capture.jsonl"),releasePath=resolve(dir,"release"); + const start=spec.indexOf("const h=stockHandoff,capturePath=");assert.ok(start>=0); + const end=spec.indexOf("\n try{const rows=await capture(page,journal)",start);assert.ok(end>start); + const selectedStockSetup=spec.slice(start,end);let journals=0; + const context={stockHandoff:{paths:{capture:capturePath},runId:"controlled",source:{},connection:{receiverUrl:"http://example.invalid/",gatewayUrl:"ws://example.invalid/",allowedOrigin:"http://example.invalid",sessionId:"controlled",credential:"PRIVATE"},artifacts:{guest:{sha256:"0".repeat(64)}}},process:{env:{BARC_STOCK_SMOKE_CAPTURE:capturePath,BARC_STOCK_SMOKE_RELEASE:releasePath}},captureJournal:(path,release)=>{assert.equal(path,capturePath);assert.equal(release,releasePath);journals++;return{}}}; + const j=vm.runInNewContext(`${selectedStockSetup};j`,context),state=pairing.pairingState();assert.equal(journals,1);state.secret="PRIVATE";pairing.notePairing(state,"socket"); + pairing.writePairingDiagnostic(j,state,null);assert.equal(j.outputPath,capturePath);assert.equal(j.armFailurePath,capturePath+".arm-failure.json");const path=capturePath+".pairing-diagnostic.json",text=await readFile(path,"utf8"),pin=await stat(path);assert.equal(pin.mode&0o777,0o600);assert.equal(pin.nlink,1);assert.ok(Buffer.byteLength(text)<=4096);assert.equal(text.includes("PRIVATE"),false); + assert.throws(()=>vm.runInNewContext(selectedStockSetup,{...context,process:{env:{BARC_STOCK_SMOKE_CAPTURE:resolve(dir,"foreign"),BARC_STOCK_SMOKE_RELEASE:releasePath}}}),/authenticated capture path changed/);assert.equal(journals,1); assert.throws(()=>pairing.writePairingDiagnostic(j,state,null),/private pairing diagnostic refused/);assert.equal(await readFile(path,"utf8"),text); chmodSync(dir,0o755);assert.throws(()=>pairing.writePairingDiagnostic({outputPath:resolve(dir,"world")},state,null),/private pairing diagnostic refused/);chmodSync(dir,0o700); const link=dir+"-link";symlinkSync(dir,link);try{assert.throws(()=>pairing.writePairingDiagnostic({outputPath:resolve(link,"linked")},state,null),/private pairing diagnostic refused/)}finally{unlinkSync(link)}