const { spawnSync } = require('node:child_process'); const fs = require('node:fs'); const path = require('node:path'); const projectRoot = path.resolve(__dirname, '..'); const sourceWrapperPath = path.join(__dirname, 'playtest-stockade-stances-blocking.cjs'); const sourceWrapper = fs.readFileSync(sourceWrapperPath, 'utf8'); const runtimeWrapperPath = path.join(__dirname, `.playtest-stockade-spell-blocking-${process.pid}.cjs`); function replaceExactlyOnce(source, marker, replacement, label) { const count = source.split(marker).length - 1; if (count !== 1) throw new Error(`${label} must occur exactly once; found ${count}.`); return source.replace(marker, replacement); } function transformSpellCampaignHarness(source) { const replaceOnce = (marker, replacement, label) => { const count = source.split(marker).length - 1; if (count !== 1) throw new Error(`${label} must occur exactly once in the campaign source; found ${count}.`); source = source.replace(marker, replacement); }; const replaceEvery = (marker, replacement, label) => { const count = source.split(marker).length - 1; if (!count) throw new Error(`${label} marker was not found in the campaign source.`); source = source.replaceAll(marker, replacement); }; replaceOnce( `async function runCampaignBossRoute(page, route, entryState, profile) { const guidance = readNavigationGuidance(route.id);`, `async function runCampaignBossRoute(page, route, entryState, profile) { if (!entryState.dungeonRun?.id && !entryState.dungeonRun?.biteSizedSelection) { const selectionDeadline = Date.now() + 8_000; while (Date.now() < selectionDeadline && !entryState.dungeonRun?.id && !entryState.dungeonRun?.biteSizedSelection) { await page.waitForTimeout(250); entryState = await readLiveState(page, true); } } const fullStockadeGuidance = readNavigationGuidance(FULL_STOCKADE_DUNGEON_ID); const sourceBossObjectives = fullStockadeGuidance.objectives; const observedBossesAtEntry = entryState.mobs.filter((mob) => mob.boss && !mob.dead && sourceBossObjectives.some((objective) => objective.name === mob.name)); if (observedBossesAtEntry.length > 1) { throw new Error(\`Bite-Sized Stockade exposed multiple source bosses at entry: \${JSON.stringify(observedBossesAtEntry.map((mob) => ({ id: mob.id, name: mob.name, serverEntry: mob.serverEntry })))}.\`); } const selectedRunBoss = entryState.dungeonRun?.biteSizedSelection?.boss ?? null; const runId = entryState.dungeonRun?.id ?? null; const observedSelectedBoss = observedBossesAtEntry[0] ?? null; const runIdSelectedObjective = runId ? (() => { let hash = 2_166_136_261; for (let index = 0; index < runId.length; index += 1) { hash ^= runId.charCodeAt(index); hash = Math.imul(hash, 16_777_619); } return sourceBossObjectives[(hash >>> 0) % sourceBossObjectives.length]; })() : null; const selectedSourceObjective = selectedRunBoss ? sourceBossObjectives.find((objective) => objective.name === selectedRunBoss.name && objective.id === selectedRunBoss.objectiveId) : runIdSelectedObjective ?? sourceBossObjectives.find((objective) => objective.name === observedSelectedBoss?.name); if (!selectedSourceObjective) { throw new Error(\`Bite-Sized Stockade selected boss was not present in run selection or a live entry mob: selection=\${JSON.stringify(selectedRunBoss)}, observed=\${JSON.stringify(observedBossesAtEntry.map((mob) => ({ id: mob.id, name: mob.name, serverEntry: mob.serverEntry })))}.\`); } if (observedSelectedBoss && observedSelectedBoss.name !== selectedSourceObjective.name) { throw new Error('The live entry boss name disagrees with the seeded dungeon-run selection.'); } const cellblockAnchor = sourceBossObjectives.find((objective) => objective.name === 'Targorr the Dread'); if (!selectedSourceObjective || !cellblockAnchor) { throw new Error('The observed seeded boss or reviewed central-cell navigation anchor is missing from the source guide.'); } const expectedBiteSizedBossRoom = [-159.582, -25.6062, 1.2531]; if (!Array.isArray(cellblockAnchor.position) || cellblockAnchor.position.some((coordinate, index) => coordinate !== expectedBiteSizedBossRoom[index])) { throw new Error(\`Targorr guide anchor \${JSON.stringify(cellblockAnchor.position)} does not exactly match the Bite-Sized boss room \${JSON.stringify(expectedBiteSizedBossRoom)}.\`); } const biteWaypoints = fullStockadeGuidance.waypoints.slice(0, cellblockAnchor.waypointIndex + 1); const biteDistance = biteWaypoints.slice(1).reduce((sum, waypoint, index) => sum + distance3(biteWaypoints[index], waypoint), 0); const selectedObjective = { ...selectedSourceObjective, position: cellblockAnchor.position, waypointIndex: cellblockAnchor.waypointIndex }; const selectedBossIdentity = { name: selectedSourceObjective.name, sourceSpawnId: selectedSourceObjective.id, entityId: selectedRunBoss?.entityId ?? null, sourceDungeonId: selectedRunBoss?.sourceDungeonId ?? null, runId, liveActorId: observedSelectedBoss?.id ?? null, serverEntry: observedSelectedBoss?.serverEntry ?? null, selectionEvidence: selectedRunBoss ? 'read-only biteSizedSelection.boss from normal dungeon-run progress' : runIdSelectedObjective ? 'source seededBossIndex FNV-1a selection reconstructed from read-only dungeon-run id' : 'the one live source boss mob observed at normal Bite-Sized Stockade entry', }; const guidance = { ...fullStockadeGuidance, dungeonId: route.id, objective: selectedObjective.name, objectiveId: selectedObjective.id, objectivePosition: selectedObjective.position, objectives: [selectedObjective], waypoints: biteWaypoints, waypointCount: biteWaypoints.length, expectedNavigationDistance: Number(biteDistance.toFixed(2)), };`, 'dynamic seeded one-boss navigation guide', ); replaceOnce( ' objective: { name: guidance.objective, position: guidance.objectivePosition },', ' objective: { name: guidance.objective, position: guidance.objectivePosition },\n selectedBossIdentity,', 'selected boss identity in campaign result', ); replaceOnce( ' dungeonRun: dungeonRunProgress ? {\n dungeonId: dungeonRunProgress.dungeonId,', ' dungeonRun: dungeonRunProgress ? {\n id: dungeonRunProgress.id ?? null,\n biteSizedSelection: dungeonRunProgress.biteSizedSelection ?? null,\n dungeonId: dungeonRunProgress.dungeonId,', 'read-only seeded boss run selection', ); replaceOnce( ' const playerToBoss = liveBoss ? distance3(current.player.position, liveBoss.position) : bossDistance;', ' if (liveBoss) {\n selectedBossIdentity.liveActorId = liveBoss.id;\n selectedBossIdentity.serverEntry = liveBoss.serverEntry ?? selectedBossIdentity.serverEntry;\n }\n const playerToBoss = liveBoss ? distance3(current.player.position, liveBoss.position) : bossDistance;', 'late live seeded boss identity confirmation', ); replaceOnce( ' result.pageErrors = [];\n result.consoleErrors = [];\n result.frozenBuildAssetUrls = moduleUrls.map((url) => new URL(url, page.url()).href);', ' const selectedBossMobObservation = [...entryState.mobs, ...current.mobs,\n ...result.samples.flatMap((sample) => sample.mobs ?? [])]\n .find((mob) => mob.name === selectedBossIdentity.name && mob.id);\n const selectedBossDeathObservation = [...observedDeadMobs].find(([, name]) => name === selectedBossIdentity.name);\n if (selectedBossMobObservation) {\n selectedBossIdentity.liveActorId = selectedBossMobObservation.id;\n selectedBossIdentity.serverEntry = selectedBossMobObservation.serverEntry ?? selectedBossIdentity.serverEntry;\n } else if (selectedBossDeathObservation) selectedBossIdentity.liveActorId = selectedBossDeathObservation[0];\n result.pageErrors = [];\n result.consoleErrors = [];\n result.frozenBuildAssetUrls = moduleUrls.map((url) => new URL(url, page.url()).href);', 'final selected live boss actor identity', ); replaceOnce( ` const initialEventKeys = new Set(entryState.events.map((event) => [event.occurredAt, event.sourceActorId, event.targetActorId, event.abilityId, event.kind, event.effectiveAmount].join('|'))); const seenEventKeys = initialEventKeys;`, ` const eventKey = (event) => event.id != null ? \`event:\${event.id}\` : JSON.stringify(event); const initialEventKeys = new Set(entryState.events.map(eventKey)); const seenEventKeys = initialEventKeys;`, 'stable source event identity key', ); replaceEvery( ` const key = [event.occurredAt, event.sourceActorId, event.targetActorId, event.abilityId, event.kind, event.effectiveAmount].join('|');`, ' const key = eventKey(event);', 'stable sampled-event deduplication key', ); replaceOnce( " if (lastCombatResult?.outcome === 'block') {\n const latestDamageEvent = [...snapshot.events].reverse().find((event) => event.kind === 'damage');\n const matchedLatestBlockEvent = latestDamageEvent?.outcome === 'block'\n && Number(latestDamageEvent.rawAmount) === Number(lastCombatResult.rawDamage)\n ? latestDamageEvent : null;", " if (lastCombatResult?.blocked === true || lastCombatResult?.outcome === 'block') {\n const latestDamageEvent = [...snapshot.events].reverse().find((event) => event.kind === 'damage'\n && (event.blocked === true || Number(event.blockedAmount) > 0 || event.outcome === 'block'));\n const matchedLatestBlockEvent = latestDamageEvent\n && Number(latestDamageEvent.rawAmount) === Number(lastCombatResult.rawDamage)\n ? latestDamageEvent : null;", 'crit-with-block last result sampling', ); replaceOnce( ' school: attack.school ?? null, castTimeMs: attack.castTimeMs ?? 0,', ' school: attack.school ?? null, wowSpellDefense: attack.wowSpellDefense ?? null,\n effects: attack.effects ?? [], castTimeMs: attack.castTimeMs ?? 0,', 'source NPC spell metadata projection', ); replaceOnce( ' playerAtEntry: entryState.player, partyAtEntry: entryState.party,', ' playerAtEntry: entryState.player, partyAtEntry: entryState.party,\n sourceSpellAbilityMetadata: (entryState.abilities ?? [])\n .filter((ability) => ability.wowSpellDefense || ability.ranks?.some((rank) => rank.wowSpellDefense))\n .map((ability) => ({ ...ability, ranks: (ability.ranks ?? []).filter((rank) => rank.wowSpellDefense) })),', 'read-only ability source metadata', ); return source; } function summarizeSpellBlockingEvidence(route) { const events = route.observedCombatEvents ?? []; const partyActorIds = new Set(['__player__', ...(route.partyAtEntry ?? []).map((actor) => actor.id)]); for (const sample of route.samples ?? []) { for (const member of sample.party ?? []) partyActorIds.add(member.id); } const hostileActorIds = new Set((route.samples ?? []).flatMap((sample) => (sample.mobs ?? []) .map((mob) => mob.id).filter(Boolean))); const resultByEventId = new Map((route.observedBlockResultObservations ?? []) .filter((observation) => observation.event?.id != null) .map((observation) => [observation.event.id, observation])); const blockedDamageEvents = events.filter((event) => event.kind === 'damage' && (event.blocked === true || Number(event.blockedAmount) > 0 || event.outcome === 'block')) .map((event) => { const result = resultByEventId.get(event.id)?.combatResult ?? null; return { ...event, blockDirection: hostileActorIds.has(event.sourceActorId) && partyActorIds.has(event.targetActorId) ? 'hostile-attack-blocked-by-party' : partyActorIds.has(event.sourceActorId) && hostileActorIds.has(event.targetActorId) ? 'party-attack-blocked-by-hostile' : 'actor-team-unresolved', blocked: event.blocked ?? result?.blocked ?? (event.outcome === 'block'), blockedAmount: event.blockedAmount ?? result?.blockedAmount ?? null, sampledCombatResult: result, }; }); const mobSamples = (route.samples ?? []).flatMap((sample) => (sample.mobs ?? []).map((mob) => ({ observedAt: sample.at ?? sample.now ?? null, id: mob.id ?? null, name: mob.name ?? null, serverEntry: mob.serverEntry ?? null, attacks: mob.attacks ?? [], auras: mob.auras ?? [], combatAuraTelemetry: mob.combatAuraTelemetry ?? [], }))); return { definitions: { blockedDamageEvents: 'Read-only StructuredCombatEvent values retained verbatim from sampled combatEvents snapshots when blocked is true, blockedAmount is positive, or outcome is block; crit outcomes remain crit.', eventSampling: 'The source snapshots take the latest 200 events from the store ring; polling plus ID deduplication can miss events that age out between snapshots.', blockDirection: 'Party and hostile sides are determined only from sampled party/mob actor IDs; unresolved IDs retain an explicit unresolved direction.', blockedAmount: 'Prefers the event field; otherwise uses a sampled lastCombatResult only when correlated by event id.', npcSources: 'Mob attack definitions, source aura lists, and combatStore aura telemetry copied from read-only campaign snapshots.', abilityMetadata: 'Source spell metadata is recorded only when the entry ability or rank supplied wowSpellDefense.', negativeEvidence: 'No observed blocked event is not evidence that a spell cannot be blocked; this route samples ordinary live UI snapshots.', }, counts: { rawCombatEvents: events.length, blockedDamageEvents: blockedDamageEvents.length, blockedDamageEventsWithAmount: blockedDamageEvents.filter((event) => event.blockedAmount !== null).length, critAndBlockedDamageEvents: blockedDamageEvents.filter((event) => event.outcome === 'crit' && (event.blocked === true || Number(event.blockedAmount) > 0)).length, hostileAttacksBlockedByParty: blockedDamageEvents.filter((event) => event.blockDirection === 'hostile-attack-blocked-by-party').length, partyAttacksBlockedByHostile: blockedDamageEvents.filter((event) => event.blockDirection === 'party-attack-blocked-by-hostile').length, actorTeamUnresolvedBlockEvents: blockedDamageEvents.filter((event) => event.blockDirection === 'actor-team-unresolved').length, sourceNpcSamples: mobSamples.length, sourceNpcAuraSamples: mobSamples.filter((mob) => mob.auras.length || mob.combatAuraTelemetry.length).length, sourceSpellAbilityMetadata: route.sourceSpellAbilityMetadata?.length ?? 0, }, selectedBossIdentity: route.selectedBossIdentity ?? null, blockedDamageEvents, sourceNpcSamples: mobSamples, sourceSpellAbilityMetadata: route.sourceSpellAbilityMetadata ?? [], rawCombatEvents: events, }; } function makeBiteSizedWrapper() { let source = sourceWrapper; source = replaceExactlyOnce(source, 'const {\n FULL_STOCKADE_DUNGEON_ID,', 'const {\n DEFAULT_TEST_DUNGEON_ID,\n DEFAULT_TEST_DUNGEON_TITLE,\n FULL_STOCKADE_DUNGEON_ID,', 'bite-sized defaults import'); source = source.replaceAll('stockade-stances-blocking', 'stockade-spell-blocking'); source = replaceExactlyOnce(source, 'function main() {\n const instrumentedHarness = createInstrumentedHarness();', `${transformSpellCampaignHarness.toString()}\n\n${summarizeSpellBlockingEvidence.toString()}\n\nfunction main() {\n const instrumentedHarness = transformSpellCampaignHarness(createInstrumentedHarness());`, 'spell-specific campaign transformation'); source = replaceExactlyOnce(source, " if (!process.argv.includes('--full-stockade')) {\n throw new Error('This source-specific full-campaign harness requires explicit --full-stockade opt-in.');\n }", " if (!process.argv.includes('--bite-sized-stockade')) {\n throw new Error('This source-specific Bite-Sized Stockade harness requires explicit --bite-sized-stockade opt-in.');\n }", 'explicit Bite-Sized route opt-in'); source = replaceExactlyOnce(source, ' dungeon: { id: FULL_STOCKADE_DUNGEON_ID, title: FULL_STOCKADE_DUNGEON_TITLE },', " dungeon: { id: DEFAULT_TEST_DUNGEON_ID, title: DEFAULT_TEST_DUNGEON_TITLE },\n routeScope: 'Bite-Sized Cellblock Rush; one seeded source boss, ordinary UI traversal, 900-second hard bound',", 'Bite-Sized route record'); source = replaceExactlyOnce(source, ' entryAndPlay: \'normal full Stockade picker and Discipline healer-role entry; campaign harness ordinary WASD, target selection, attack/support healing/party commands; no Boss Testing, teleport, collision bypass, enemy/damage/aura/health/cast seeding, or combat store writes\',', " entryAndPlay: 'normal Bite-Sized Stockade picker and Discipline healer-role entry; ordinary WASD, target selection, attack/support healing/party commands; no Boss Testing, teleport, collision bypass, enemy/damage/aura/health/cast seeding, or combat store writes',", 'normal Bite-Sized entry description'); source = replaceExactlyOnce(source, " instrumentation: ['active enemy-source aura applications for spells 7164/7165/3419 with owner, target, apply/expiry, and stack fields',\n 'raw observed combat events with block outcomes and actor direction',\n 'read-only lastCombatResult block amount snapshots correlated to matching damage events',\n 'read-only live-state progress.json snapshots at 30-second intervals'],\n requestedMaximumCampaignSeconds: 1800,", " instrumentation: ['sampled read-only StructuredCombatEvent ring snapshots (latest 200), retaining blocked and blockedAmount fields; crit-plus-block stays visible',\n 'read-only source NPC attacks, auras, and combatAuraTelemetry',\n 'source spell metadata only where wowSpellDefense is present on an entry ability/rank',\n 'actual seeded boss identity plus one-objective native clear result',\n 'complete content manifest JSON before and after and hash-addressed objects actually served'],\n requestedMaximumCampaignSeconds: 900,", 'spell run instrumentation record'); source = replaceExactlyOnce(source, " const contentManifestBefore = collectContentManifestSnapshot();", " const contentManifestBefore = collectContentManifestSnapshot();", 'baseline content manifest location'); source = replaceExactlyOnce(source, " const child = spawnSync(process.execPath, [runtimeHarnessPath,\n '--campaign-boss-route', `--route=${FULL_STOCKADE_DUNGEON_ID}`, '--max-campaign-seconds=1800'], {", " const child = spawnSync(process.execPath, [runtimeHarnessPath,\n '--campaign-boss-route', `--route=${DEFAULT_TEST_DUNGEON_ID}`, '--max-campaign-seconds=900'], {", 'bounded Bite-Sized campaign route'); source = replaceExactlyOnce(source, ' timeout: 2_100_000,', ' timeout: 900_000,', '900-second child hard bound'); source = replaceExactlyOnce(source, ' ? path.join(campaignDirectory, `${FULL_STOCKADE_DUNGEON_ID}-campaign-boss-route.json`) : null;', ' ? path.join(campaignDirectory, `${DEFAULT_TEST_DUNGEON_ID}-campaign-boss-route.json`) : null;', 'Bite-Sized route result path'); source = replaceExactlyOnce(source, ' ? path.join(campaignDirectory, `${FULL_STOCKADE_DUNGEON_ID}-route.json`) : null;', ' ? path.join(campaignDirectory, `${DEFAULT_TEST_DUNGEON_ID}-route.json`) : null;', 'Bite-Sized summary result path'); source = replaceExactlyOnce(source, " const evidence = route ? summarizeStanceBlockingEvidence(route) : null;\n if (evidence) writeJson(path.join(outputDirectory, 'stances-blocking-evidence.json'), evidence);", " const evidence = route ? summarizeSpellBlockingEvidence(route) : null;\n if (route && evidence?.selectedBossIdentity) {\n const selectedBossSample = evidence.sourceNpcSamples.find((mob) => mob.name === evidence.selectedBossIdentity.name && mob.id);\n if (selectedBossSample) {\n const observedIdentity = { ...route.selectedBossIdentity, liveActorId: selectedBossSample.id,\n serverEntry: selectedBossSample.serverEntry ?? null };\n route.selectedBossIdentity = observedIdentity;\n evidence.selectedBossIdentity = observedIdentity;\n writeJson(routePath, route);\n }\n }\n if (evidence) writeJson(path.join(outputDirectory, 'spell-blocking-evidence.json'), evidence);", 'spell-blocking evidence output'); source = replaceExactlyOnce(source, ' runRecord.stanceBlockingEvidenceCounts = evidence?.counts ?? null;', ' runRecord.spellBlockingEvidenceCounts = evidence?.counts ?? null;', 'spell-blocking evidence count field'); source = replaceExactlyOnce(source, "specializationId: 'priest:discipline', role: 'healer', level: 30,", "specializationId: 'priest:discipline', role: 'healer', level: 30,\n preEntryLevelPreparation: 'UI-created profile advanced through isolated shell.saveActiveProgression(30, 0, talentRanks) before dungeon entry; no combat-state writes during play',", 'explicit isolated pre-entry progression setup'); source = replaceExactlyOnce(source, " if (route && !evidence?.counts.stanceAuraApplications) {\n runRecord.statusNotes.push('No live application of Defensive Stance 7164 or Battle Stance 7165 was captured; aura outcomes are not observed in this run.');\n }\n if (route && !evidence?.counts.improvedBlockingAuraApplications) {\n runRecord.statusNotes.push('No live Improved Blocking 3419 application was captured; aura outcomes are not observed in this run.');\n }\n if (route && !evidence?.counts.rawBlockEvents) {\n runRecord.statusNotes.push('No damage event with outcome=block was captured; intermittent live sampling limits negative conclusions.');\n } else if (route && evidence?.counts.matchedBlockedAmountEvents < evidence?.counts.rawBlockEvents) {\n runRecord.statusNotes.push(`${evidence.counts.rawBlockEvents - evidence.counts.matchedBlockedAmountEvents} block outcome event(s) had no matching sampled lastCombatResult amount; the outcome is retained without inferring a blocked amount.`);\n }\n if (route && evidence?.counts.actorTeamUnresolvedBlockEvents) {\n runRecord.statusNotes.push(`${evidence.counts.actorTeamUnresolvedBlockEvents} block event(s) could not be assigned to party-versus-hostile direction from sampled actor IDs.`);\n }", " if (route && !evidence?.counts.blockedDamageEvents) {\n runRecord.statusNotes.push('No block-indicated damage event was captured in sampled combat-event snapshots; this does not establish that a spell cannot be blocked.');\n } else if (route && evidence?.counts.blockedDamageEventsWithAmount < evidence?.counts.blockedDamageEvents) {\n runRecord.statusNotes.push(`${evidence.counts.blockedDamageEvents - evidence.counts.blockedDamageEventsWithAmount} block-indicated event(s) had no correlated numeric blocked amount; missing amounts remain unknown.`);\n }\n if (route && evidence?.counts.actorTeamUnresolvedBlockEvents) {\n runRecord.statusNotes.push(`${evidence.counts.actorTeamUnresolvedBlockEvents} block-indicated event(s) could not be assigned to party-versus-hostile direction from sampled actor IDs.`);\n }", 'spell-appropriate sampled block status notes'); source = replaceExactlyOnce(source, ' const fiveRequiredBossesVerified = expectedBossIds.length === 5\n && expectedBossIds.every((bossId) => killedBossIds.has(bossId));', " const selectedBossIdentity = route?.selectedBossIdentity ?? null;\n const supportedSeededBossNames = new Set(['Targorr the Dread', 'Kam Deepfury', 'Hamhock', 'Bazil Thredd', 'Dextren Ward']);\n const oneSelectedBossVerified = expectedBossIds.length === 1\n && killedBossIds.has(expectedBossIds[0])\n && selectedBossIdentity?.sourceSpawnId === expectedBossIds[0]\n && supportedSeededBossNames.has(selectedBossIdentity?.name);", 'single selected boss result verification'); source = replaceExactlyOnce(source, ' && fiveRequiredBossesVerified);', ' && oneSelectedBossVerified);', 'single boss native clear assertion'); source = replaceExactlyOnce(source, ' runRecord.requiredBossIds = expectedBossIds;\n runRecord.killedBossIds = [...killedBossIds];', ' runRecord.requiredBossIds = expectedBossIds;\n runRecord.killedBossIds = [...killedBossIds];\n runRecord.selectedBossIdentity = selectedBossIdentity;', 'actual boss identity in run record'); source = replaceExactlyOnce(source, ' runRecord.contentSourceResponseCounts = contentSourceEvidence.counts;', ' runRecord.contentSourceResponseCounts = contentSourceEvidence.counts;\n runRecord.contentObjectsActuallyLoaded = contentSourceEvidence.counts.successfulManifestResponses > 0\n && contentSourceEvidence.counts.verifiedHashAddressedObjects > 0\n && contentSourceEvidence.counts.objectIntegrityFailures === 0;\n runRecord.contentObjectsActuallyLoadedRequirement = \'At least one successful manifest response and one served hash-addressed content object whose bytes match its address; zero integrity failures.\';', 'loaded hash-addressed content verification'); source = replaceExactlyOnce(source, " if (!runRecord.fullClearVerified && runRecord.executionStatus === 'complete' && route) {\n runRecord.statusNotes.push('Campaign process exited successfully, but results UI plus all five required boss IDs were not verified; this remains a partial live attempt.');\n }", " if (!runRecord.fullClearVerified && runRecord.executionStatus === 'complete' && route) {\n runRecord.statusNotes.push('Campaign process exited successfully, but the native result UI plus the one seeded boss ID were not verified; this remains a partial live attempt.');\n }\n if (!runRecord.contentObjectsActuallyLoaded && runRecord.executionStatus === 'complete') {\n runRecord.statusNotes.push('The run did not prove that hash-addressed content objects were served from the recorded manifest; content provenance remains unverified.');\n }", 'single boss and content-provenance notes'); source = replaceExactlyOnce(source, " runRecord.status = runRecord.executionStatus === 'complete' && route\n ? runRecord.fullClearVerified ? 'complete' : 'partial-full-clear-unverified' : 'failed';", " runRecord.status = runRecord.executionStatus === 'complete' && route\n ? runRecord.fullClearVerified && runRecord.contentObjectsActuallyLoaded ? 'complete'\n : 'partial-spell-blocking-run-unverified' : 'failed';", 'final route status requires content provenance'); source = source.replaceAll('Stockade stance/blocking QA', 'Stockade spell-blocking QA'); source = source.replaceAll('Prepared scoped Stockade stance/blocking harness', 'Prepared scoped Bite-Sized Stockade spell-blocking harness'); source = source.replaceAll('all five required boss IDs', 'the one seeded boss ID'); source = source.replaceAll('contentManifestSha256: contentManifestBefore.manifestSha256,', 'contentManifestSha256: contentManifestBefore.manifestSha256,\n contentManifestJsonIncluded: true,'); source = replaceExactlyOnce(source, ' manifestVersion: manifest.version ?? null,', ' manifest,\n manifestVersion: manifest.version ?? null,', 'full source content manifest JSON'); source = replaceExactlyOnce(source, 'function collectLoadedContentObjectEvidence(responses) {', 'function collectLoadedContentObjectEvidence(responses, manifest) {', 'manifest-backed content object evidence'); source = replaceExactlyOnce(source, " return uniqueObjects.map((response) => {\n const relativeObjectPath = decodeURIComponent(response.pathname.slice('/content/'.length));", " return uniqueObjects.map((response) => {\n const manifestReferences = Object.entries(manifest?.files ?? {})\n .filter(([, entry]) => [entry.url, entry.download?.url].includes(response.pathname))\n .map(([logicalPath, entry]) => ({ logicalPath, sha256: entry.download?.sha256 ?? entry.sha256 ?? null }));\n const manifestReferencedLogicalPaths = manifestReferences.map((entry) => entry.logicalPath);\n const relativeObjectPath = decodeURIComponent(response.pathname.slice('/content/'.length));", 'content object manifest membership'); source = replaceExactlyOnce(source, 'return { ...response, localObjectPath: null, localBytes: null, localSha256: null,\n objectIntegrity:', 'return { ...response, manifestReferencedLogicalPaths, manifestReferenceCount: manifestReferences.length,\n localObjectPath: null, localBytes: null, localSha256: null,\n objectIntegrity:', 'unsafe content object manifest telemetry'); source = replaceExactlyOnce(source, 'return { ...response, localObjectPath: path.relative(projectRoot, absoluteObjectPath),\n localBytes: null, localSha256: null, objectIntegrity:', 'return { ...response, manifestReferencedLogicalPaths, manifestReferenceCount: manifestReferences.length,\n localObjectPath: path.relative(projectRoot, absoluteObjectPath),\n localBytes: null, localSha256: null, objectIntegrity:', 'missing content object manifest telemetry'); source = replaceExactlyOnce(source, ' return {\n ...response,\n localObjectPath: path.relative(projectRoot, absoluteObjectPath),', ' return {\n ...response,\n manifestReferencedLogicalPaths,\n manifestReferenceCount: manifestReferences.length,\n localObjectPath: path.relative(projectRoot, absoluteObjectPath),', 'verified content object manifest telemetry'); source = replaceExactlyOnce(source, ' const loadedContentObjects = collectLoadedContentObjectEvidence(contentSourceResponses);', ' const loadedContentObjects = collectLoadedContentObjectEvidence(contentSourceResponses, contentManifestBefore.manifest);', 'captured-manifest object verification'); source = replaceExactlyOnce(source, " verifiedHashAddressedObjects: loadedContentObjects.filter((object) => object.objectIntegrity === 'served-file-matches-hash-address').length,", " verifiedHashAddressedObjects: loadedContentObjects.filter((object) => object.objectIntegrity === 'served-file-matches-hash-address').length,\n verifiedManifestReferencedHashAddressedObjects: loadedContentObjects.filter((object) => object.objectIntegrity === 'served-file-matches-hash-address'\n && object.manifestReferenceCount > 0).length,", 'manifest reference match count'); source = replaceExactlyOnce(source, ' && contentSourceEvidence.counts.verifiedHashAddressedObjects > 0\n && contentSourceEvidence.counts.objectIntegrityFailures === 0;', ' && contentSourceEvidence.counts.verifiedHashAddressedObjects > 0\n && contentSourceEvidence.counts.verifiedManifestReferencedHashAddressedObjects > 0\n && contentSourceEvidence.counts.objectIntegrityFailures === 0;', 'manifest-backed object success gate'); return source; } function main() { const wrapper = makeBiteSizedWrapper(); fs.writeFileSync(runtimeWrapperPath, wrapper, 'utf8'); try { const syntax = spawnSync(process.execPath, ['--check', runtimeWrapperPath], { cwd: projectRoot, encoding: 'utf8', windowsHide: true, }); if (syntax.status !== 0) throw new Error(`Generated Stockade wrapper syntax check failed: ${syntax.stderr || syntax.error}`); const args = process.argv.slice(2); const run = spawnSync(process.execPath, [runtimeWrapperPath, ...args], { cwd: projectRoot, stdio: 'inherit', windowsHide: true, }); if (run.error) throw run.error; process.exitCode = run.status ?? 1; } finally { fs.rmSync(runtimeWrapperPath, { force: true }); } } try { main(); } catch (error) { fs.rmSync(runtimeWrapperPath, { force: true }); console.error(error.stack ?? error.message); process.exitCode = 1; }