Adds contract-focused regression coverage for the Electron HTTP server, remote-control events, settings events, and managed download paths, and makes Tier A coverage fail closed when instrumentation fails or a runtime-owning production file disappears from a project or from the merged Istanbul report. The old `coverage:ci` exited 0 despite a `Failed to collect coverage` diagnostic: libs/m3u-state/src/lib/effects.ts was simply absent from the merged map. All 30 Tier A reports are now required, the merged map covers 710 files, and effects.ts is reported as 0/159 instead of silently disappearing. Also fixes remote static-file path containment for encoded, malformed, NUL, POSIX and Win32-style traversal inputs, with behavior-preserving testability seams. Statements 69.27% -> 69.54%; http-server.ts 0% -> 90.21%, remote-control.events.ts 0% -> 96.55%, settings.events.ts 59.25% -> 96.29%.
59 KiB
Coverage Integrity And Electron Runtime Boundaries Implementation Plan
For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (
- [ ]) syntax for tracking.
Goal: Make Tier A coverage fail closed and add meaningful regression coverage for the HTTP server, remote control, settings, and download-file Electron boundaries.
Architecture: A shared pure Node module classifies runtime-owning TypeScript, validates per-project Istanbul reports, scans child output for collection failures, and evaluates aggregate/per-file ratchets. Existing Electron contracts stay unchanged except for the TDD-backed rejection of a discovered static-path traversal escape; tests use real loopback/filesystem behavior where practical and mock only process, persistence, or native-shell boundaries.
Tech Stack: Node.js ESM and node:test, TypeScript compiler API, Istanbul coverage maps, Jest/ts-jest, Electron main-process IPC, Node HTTP streams, Angular Jest configuration, Nx, Playwright.
Execution note (2026-07-26): The branch was rebased onto
origin/master commit 7e8c2ccce16b71d72a64c45f1d96dd090dc8e077
before the final ratchet run. A real-loopback HTTP regression exposed a Windows
double-leading-slash traversal escape; the implementation adds a tested pure
resolver and a user-facing Electron fix note. A final integrity follow-up also
validates the merged Istanbul map itself before evaluating its recomputed
summary and ratchets.
Scope And File Map
Create:
tools/coverage/coverage-integrity.mjs— shared source classification, report validation, output scanning, and ratchet evaluation.tools/coverage/coverage-integrity.test.mjs— deterministic Node tests using temporary source/report fixtures.apps/electron-backend/src/app/server/http-server.spec.ts— real loopback and temporary-directory HTTP server contracts.apps/electron-backend/src/app/events/remote-control.events.spec.ts— registered HTTP handler, IPC, status, validation, and size-limit contracts.
Modify:
tools/coverage/run-tier-a-coverage.mjs— stream child output, detect collection failures, require complete project reports.tools/coverage/merge-coverage.mjs— reject missing/invalid Tier A inputs before touching merged output.tools/coverage/coverage-health.mjs— independently validate completeness and ratchets.tools/coverage/coverage-policy.json— store achieved aggregate and critical-file ratchets.package.json— run coverage-tool unit tests insidecoverage:ci.libs/m3u-state/tsconfig.spec.json— use bundler resolution and include the shared Electron window declaration soeffects.tsinstruments.apps/electron-backend/src/app/server/http-server.ts— optional static-root and server-factory seam, port0support for loopback tests, and a tested static-root containment resolver.apps/electron-backend/src/app/events/remote-control.events.ts— export the class for isolated instances while preserving the default singleton.apps/electron-backend/src/app/events/settings.events.spec.ts— persistence, normalization, remote-control reconciliation, and redaction contracts.apps/electron-backend/src/app/events/database/downloads.events.spec.ts— managed-path checks before native shell access.docs/architecture/validation-map.md— canonical fail-closed and ratchet maintenance workflow.docs/superpowers/specs/2026-07-25-coverage-integrity-runtime-boundaries-design.md— retain the corrected Istanbul-rounded baseline values.
Do not modify:
apps/electron-backend/src/app/workers/database.worker.ts;- workspace dashboard or Stalker search production code;
- type-only/shared-interface source for percentage gain;
AGENTS.mdorCLAUDE.md, unless execution discovers that the implemented commands contradict text already present there.
Task 0: Rebase And Bootstrap Immediately Before Implementation
Files:
-
Verify only:
package.json -
Verify only:
pnpm-lock.yaml -
Verify only:
tools/coverage/coverage-policy.json -
Step 1: Load the execution skills
Read completely before code changes:
using-superpowers
executing-plans
test-driven-development
electron-pro
typescript
angular-testing
iptvnator-nx-architecture
Use systematic-debugging before changing code in response to any unexpected
failure, and verification-before-completion, release-notes, and
github-pr during the final tasks.
- Step 2: Confirm a clean branch and rebase onto fresh master
Run:
git status --short --branch
git fetch origin master --prune
git rebase origin/master
git status --short --branch
git log -2 --oneline --decorate
Expected: the branch is agent/coverage-integrity-runtime-boundaries, the
rebase exits 0, and only the committed design/plan are ahead of the latest
origin/master. If master changed a scoped source, spec, Jest config, or
coverage tool, re-run the baseline checks below and update this plan's numeric
seed before implementation rather than resolving by assumption.
- Step 3: Refresh locked dependencies and Nx discovery
Run:
pnpm install --frozen-lockfile
pnpm nx show projects
pnpm nx show projects --withTarget test
Expected: all commands exit 0; the project list contains
electron-backend, electron-backend-e2e, and m3u-state; the lockfile stays
unchanged.
- Step 4: Reconfirm the fresh baseline
Run even when Step 2 reports no new master commits:
NX_SKIP_NX_CACHE=true pnpm run coverage:ci
Expected on unchanged
7e8c2ccce16b71d72a64c45f1d96dd090dc8e077: the command exits 0 while printing
Failed to collect coverage for libs/m3u-state/src/lib/effects.ts, and the
30 project reports merge 709 files while omitting that runtime-owning source.
The aggregate remains 69.27/58.92/67.44/69.57, with HTTP and remote control at
0%, settings at 16 / 27 (59.25%), and downloads at 69 / 147 (46.93%). Record
the fresh aggregate and selected-file values. If master changed them, replace
the numeric ratchet seed in Task 3; do not lower a baseline already present on
newer master.
Task 1: Build And Unit-Test The Shared Coverage Integrity Module
Files:
-
Create:
tools/coverage/coverage-integrity.test.mjs -
Create:
tools/coverage/coverage-integrity.mjs -
Step 1: Write the failing source-classification and output-scanner tests
Create tools/coverage/coverage-integrity.test.mjs with Node built-ins and
these contracts:
import assert from 'node:assert/strict';
import { mkdtempSync, mkdirSync, rmSync, writeFileSync } from 'node:fs';
import { tmpdir } from 'node:os';
import path from 'node:path';
import { afterEach, describe, it } from 'node:test';
import {
createCoverageOutputScanner,
evaluateCoverageRatchets,
hasRuntimeOwnedStatement,
validateProjectCoverage,
validateRequiredProjectReports,
} from './coverage-integrity.mjs';
const temporaryRoots = [];
afterEach(() => {
for (const root of temporaryRoots.splice(0)) {
rmSync(root, { recursive: true, force: true });
}
});
describe('hasRuntimeOwnedStatement', () => {
it('excludes type-only, import-only, and pure re-export source', () => {
assert.equal(
hasRuntimeOwnedStatement(
'import type { Settings } from "./settings";'
),
false
);
assert.equal(
hasRuntimeOwnedStatement('interface Settings { enabled: boolean }'),
false
);
assert.equal(
hasRuntimeOwnedStatement('export type Mode = "live" | "vod";'),
false
);
assert.equal(
hasRuntimeOwnedStatement('export { value } from "./value";'),
false
);
assert.equal(
hasRuntimeOwnedStatement('declare const injected: string;'),
false
);
});
it('includes emitted declarations and executable statements', () => {
assert.equal(
hasRuntimeOwnedStatement('export const enabled = true;'),
true
);
assert.equal(
hasRuntimeOwnedStatement(
'export class RuntimeBoundary { start() {} }'
),
true
);
assert.equal(hasRuntimeOwnedStatement('console.log("runtime");'), true);
});
});
describe('createCoverageOutputScanner', () => {
it('detects an ANSI-colored marker split across chunks', () => {
const scanner = createCoverageOutputScanner(128);
scanner.push('\u001b[31mFailed to collect');
scanner.push(' coverage from /workspace/effects.ts\u001b[39m');
assert.equal(scanner.collectionFailed, true);
});
it('keeps only a bounded rolling tail', () => {
const scanner = createCoverageOutputScanner(32);
scanner.push('x'.repeat(256));
assert.equal(scanner.tail.length, 32);
assert.equal(scanner.collectionFailed, false);
});
});
- Step 2: Add failing temporary-report tests
In the same file, add helpers that write one runtime source plus a synthetic Istanbul entry:
function makeProjectFixture() {
const workspaceRoot = mkdtempSync(
path.join(tmpdir(), 'iptvnator-coverage-integrity-')
);
temporaryRoots.push(workspaceRoot);
const sourceRoot = 'libs/example/src';
const projectRoot = 'libs/example';
const sourcePath = path.join(workspaceRoot, sourceRoot, 'runtime.ts');
const reportPath = path.join(
workspaceRoot,
'coverage',
projectRoot,
'coverage-final.json'
);
mkdirSync(path.dirname(sourcePath), { recursive: true });
mkdirSync(path.dirname(reportPath), { recursive: true });
writeFileSync(sourcePath, 'export const runtime = true;\n');
const project = {
name: 'example',
root: projectRoot,
sourceRoot,
};
return { project, reportPath, sourcePath, workspaceRoot };
}
function coverageEntry(filePath, hits = [0]) {
const statementMap = Object.fromEntries(
hits.map((_, index) => [
index,
{
start: { line: index + 1, column: 0 },
end: { line: index + 1, column: 28 },
},
])
);
const statementHits = Object.fromEntries(
hits.map((hit, index) => [index, hit])
);
return {
path: filePath,
statementMap,
fnMap: {},
branchMap: {},
s: statementHits,
f: {},
b: {},
};
}
describe('validateProjectCoverage', () => {
it('accepts a report containing every runtime-owning file', () => {
const fixture = makeProjectFixture();
writeFileSync(
fixture.reportPath,
JSON.stringify({
[fixture.sourcePath]: coverageEntry(fixture.sourcePath),
})
);
const result = validateProjectCoverage(fixture);
assert.deepEqual(result.errors, []);
assert.equal(result.report?.project.name, 'example');
});
it('reports a runtime-owning source omitted from a valid report', () => {
const fixture = makeProjectFixture();
writeFileSync(fixture.reportPath, '{}');
const result = validateProjectCoverage(fixture);
assert.equal(result.errors.length, 1);
assert.match(result.errors[0], /runtime\.ts/);
});
it('reports missing and invalid project reports', () => {
const missing = makeProjectFixture();
const invalid = makeProjectFixture();
writeFileSync(invalid.reportPath, '{ invalid json');
assert.match(
validateProjectCoverage(missing).errors[0],
/did not produce/
);
assert.match(
validateProjectCoverage(invalid).errors[0],
/invalid JSON/
);
});
it('requires every configured Tier A report', () => {
const fixture = makeProjectFixture();
const result = validateRequiredProjectReports({
projects: [fixture.project],
workspaceRoot: fixture.workspaceRoot,
});
assert.equal(result.reports.length, 0);
assert.match(result.errors[0], /example/);
});
});
- Step 3: Add failing aggregate and critical-file ratchet tests
Add:
describe('evaluateCoverageRatchets', () => {
it('reports aggregate percentage regression', () => {
const errors = evaluateCoverageRatchets({
coverageData: {},
mergedSummary: {
statements: { covered: 68, total: 100, pct: 68 },
branches: { covered: 57, total: 100, pct: 57 },
functions: { covered: 67, total: 100, pct: 67 },
lines: { covered: 69, total: 100, pct: 69 },
},
ratchet: {
merged: {
statements: 68.86,
branches: 58.66,
functions: 67.19,
lines: 69.2,
},
criticalFiles: [],
},
workspaceRoot: '/workspace',
});
assert.equal(errors.length, 4);
assert.match(errors[0], /statements.*68.*68\.86/);
});
it('requires both covered statements and percentage for a critical file', () => {
const workspaceRoot = '/workspace';
const filePath = path.join(workspaceRoot, 'apps/runtime.ts');
const errors = evaluateCoverageRatchets({
coverageData: {
[filePath]: coverageEntry(filePath, [1, 0]),
},
mergedSummary: {
statements: { covered: 1, total: 1, pct: 100 },
branches: { covered: 0, total: 0, pct: 100 },
functions: { covered: 0, total: 0, pct: 100 },
lines: { covered: 1, total: 1, pct: 100 },
},
ratchet: {
merged: {
statements: 0,
branches: 0,
functions: 0,
lines: 0,
},
criticalFiles: [
{
path: 'apps/runtime.ts',
statements: {
minimumCovered: 2,
minimumPercent: 75,
},
},
],
},
workspaceRoot,
});
assert.equal(errors.length, 2);
assert.match(errors[0], /apps\/runtime\.ts/);
});
it('reports a critical file missing from merged coverage', () => {
const errors = evaluateCoverageRatchets({
coverageData: {},
mergedSummary: {
statements: { covered: 0, total: 0, pct: 100 },
branches: { covered: 0, total: 0, pct: 100 },
functions: { covered: 0, total: 0, pct: 100 },
lines: { covered: 0, total: 0, pct: 100 },
},
ratchet: {
merged: {
statements: 0,
branches: 0,
functions: 0,
lines: 0,
},
criticalFiles: [
{
path: 'apps/missing.ts',
statements: {
minimumCovered: 1,
minimumPercent: 0,
},
},
],
},
workspaceRoot: '/workspace',
});
assert.match(errors[0], /missing from merged coverage/);
});
});
- Step 4: Run the Node tests to verify RED
Run:
node --test tools/coverage/coverage-integrity.test.mjs
Expected: FAIL with ERR_MODULE_NOT_FOUND for
tools/coverage/coverage-integrity.mjs.
- Step 5: Implement source classification and the bounded scanner
Create tools/coverage/coverage-integrity.mjs. Use unknown-equivalent
runtime validation rather than trusting parsed JSON shapes. The core
classification and scanner must follow:
import { createRequire } from 'node:module';
import { existsSync, readFileSync, readdirSync, statSync } from 'node:fs';
import path from 'node:path';
import ts from 'typescript';
const require = createRequire(import.meta.url);
const { createCoverageMap } = require('istanbul-lib-coverage');
export const COVERAGE_COLLECTION_FAILURE = 'Failed to collect coverage';
const ANSI_ESCAPE = /\u001b\[[0-?]*[ -/]*[@-~]/g;
function toPosix(filePath) {
return filePath.split(path.sep).join('/');
}
function hasDeclareModifier(statement) {
const modifiers = ts.canHaveModifiers(statement)
? (ts.getModifiers(statement) ?? [])
: [];
return modifiers.some(
(modifier) => modifier.kind === ts.SyntaxKind.DeclareKeyword
);
}
export function hasRuntimeOwnedStatement(sourceText, fileName = 'source.ts') {
const source = ts.createSourceFile(
fileName,
sourceText,
ts.ScriptTarget.Latest,
true
);
return source.statements.some((statement) => {
if (hasDeclareModifier(statement)) {
return false;
}
return !(
ts.isImportDeclaration(statement) ||
ts.isImportEqualsDeclaration(statement) ||
ts.isInterfaceDeclaration(statement) ||
ts.isTypeAliasDeclaration(statement) ||
ts.isExportDeclaration(statement) ||
ts.isEmptyStatement(statement)
);
});
}
export function createCoverageOutputScanner(maxCharacters = 4096) {
let tail = '';
let collectionFailed = false;
return {
get collectionFailed() {
return collectionFailed;
},
get tail() {
return tail;
},
push(chunk) {
tail = `${tail}${String(chunk).replace(ANSI_ESCAPE, '')}`.slice(
-maxCharacters
);
if (tail.includes(COVERAGE_COLLECTION_FAILURE)) {
collectionFailed = true;
}
},
};
}
Add recursive enumeration with exactly these exclusions:
function isExcludedSource(filePath) {
const file = toPosix(filePath);
return (
/\.(spec|test)\.ts$/.test(file) ||
file.endsWith('.d.ts') ||
file.endsWith('/test-setup.ts') ||
file.includes('/test-stubs/') ||
/\.generated\./.test(file) ||
file.includes('/environments/') ||
file.endsWith('/index.ts')
);
}
runtimeOwningSourceFiles(workspaceRoot, sourceRoot) must recursively read
only .ts files, apply isExcludedSource, parse the file, and return sorted
absolute paths whose source has a runtime-owned statement.
- Step 6: Implement report validation
Implement these stable return shapes:
// validateProjectCoverage(...)
{
errors: string[],
report: undefined | {
data: Record<string, object>,
path: string,
project: object,
},
}
// validateRequiredProjectReports(...)
{
errors: string[],
reports: Array<{
data: Record<string, object>,
path: string,
project: object,
}>,
}
validateProjectCoverage({ workspaceRoot, project }) must:
- resolve
coverage/<project.root>/coverage-final.json; - report a missing file using the project name and relative report path;
- parse JSON and reject arrays,
null, and invalid JSON; - normalize report keys with
path.resolve; - compare them to
runtimeOwningSourceFiles; and - emit one diagnostic per missing source, including project and relative source path.
validateRequiredProjectReports must call it for every project and preserve
policy order in reports.
- Step 7: Implement ratchet evaluation
evaluateCoverageRatchets must:
- compare each merged metric with its numeric minimum;
- build an Istanbul map from
coverageData; - require every critical path to exist;
- obtain
fileCoverage.toSummary().toJSON().statements; - compare both
coveredandpct; and - return diagnostics rather than exiting.
Use messages of the form:
Merged statements coverage regressed: observed 68%, required at least 68.86%.
Critical coverage apps/runtime.ts statements covered regressed: observed 1, required at least 2.
Critical coverage apps/runtime.ts statements percent regressed: observed 50%, required at least 75%.
- Step 8: Run the module tests to verify GREEN
Run:
node --test tools/coverage/coverage-integrity.test.mjs
Expected: all classification, marker, report, and ratchet tests pass.
- Step 9: Commit the pure integrity module
Run:
git add \
tools/coverage/coverage-integrity.mjs \
tools/coverage/coverage-integrity.test.mjs
git commit -m "test(coverage): add integrity primitives"
Expected: one commit containing only the pure module and its Node tests.
Task 2: Wire The Gate And Fix The Real m3u-state Instrumentation Failure
Files:
-
Modify:
tools/coverage/run-tier-a-coverage.mjs -
Modify:
tools/coverage/merge-coverage.mjs -
Modify:
tools/coverage/coverage-health.mjs -
Modify:
package.json -
Modify:
libs/m3u-state/tsconfig.spec.json -
Step 1: Replace synchronous inherited child output with streamed scanning
In run-tier-a-coverage.mjs, replace spawnSync with spawn, import
createCoverageOutputScanner and validateProjectCoverage, and add:
async function runCoverageProject(project) {
const args = buildNxArgs(project);
console.log(`\n==> Collecting coverage for ${project.name}`);
console.log(`pnpm ${args.join(' ')}`);
const scanner = createCoverageOutputScanner();
const child = spawn('pnpm', args, {
cwd: workspaceRoot,
env: {
...process.env,
CI: process.env.CI ?? 'true',
NX_TASKS_RUNNER_DYNAMIC_OUTPUT: 'false',
},
stdio: ['inherit', 'pipe', 'pipe'],
});
for (const [stream, destination] of [
[child.stdout, process.stdout],
[child.stderr, process.stderr],
]) {
stream.on('data', (chunk) => {
scanner.push(chunk);
destination.write(chunk);
});
}
const result = await new Promise((resolve, reject) => {
child.once('error', reject);
child.once('close', (code, signal) => resolve({ code, signal }));
});
if (result.code !== 0 || result.signal) {
return result.code ?? 1;
}
if (scanner.collectionFailed) {
console.error(
`Coverage collection failed while testing ${project.name}.`
);
return 1;
}
const validation = validateProjectCoverage({
project,
workspaceRoot,
});
for (const error of validation.errors) {
console.error(`Error: ${error}`);
}
return validation.errors.length === 0 ? 0 : 1;
}
Replace the final spawnSync loop with top-level awaited sequential calls.
Exit immediately after a nonzero project result so later projects cannot hide
the failed owner.
- Step 2: Make merge input fail closed before output mutation
In merge-coverage.mjs, remove the .filter(existsSync) construction. Call:
const validation = validateRequiredProjectReports({
projects: policy.unitCoverage.tierA,
workspaceRoot,
});
if (validation.errors.length > 0) {
for (const error of validation.errors) {
console.error(`Error: ${error}`);
}
process.exit(1);
}
const coverageInputs = validation.reports;
Perform this before rmSync(outputDir, ...). Merge each input.data instead
of reopening its path. Log coverageInputs.length, which must be exactly 30
on the current policy.
- Step 3: Add independent health validation
In coverage-health.mjs:
- import
evaluateCoverageRatchets,validateMergedCoverage,validateProjectCoverage, andvalidateRequiredProjectReports; - under
--require-report, validate every Tier A report and append all diagnostics toerrors; - without
--require-report, validate only report files that actually exist, treating invalid JSON or missing runtime source in a present report as an error rather than printing 30 missing-report warnings; - after loading merged
coverage-summary.json, load and independently validate mergedcoverage-final.jsonfor every runtime-owning Tier A file; - recompute the aggregate summary from the validated merged map, compare it
with the serialized summary, and evaluate
policy.reporting.coverageRatchetwhen the policy has one.
Do not change existing source-root/spec ownership checks, E2E tag warnings, or changed-file warnings.
- Step 4: Run targeted
m3u-statecoverage to verify the real RED
Run:
node --test tools/coverage/coverage-integrity.test.mjs
pnpm run coverage:unit:ci -- --projects=m3u-state
Expected:
- Node tests PASS.
- Targeted coverage exits nonzero after relaying the existing TypeScript
diagnostics and reports
Coverage collection failed while testing m3u-state.
This is the real regression proof: before the runner wiring, the same Jest failure exited 0.
- Step 5: Align the
m3u-statespec compiler configuration
Replace libs/m3u-state/tsconfig.spec.json with:
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "../../dist/out-tsc",
"module": "preserve",
"target": "es2016",
"types": ["jest", "node"],
"moduleResolution": "bundler"
},
"files": ["src/test-setup.ts", "../../global.d.ts"],
"include": [
"jest.config.ts",
"src/**/*.test.ts",
"src/**/*.spec.ts",
"src/**/*.d.ts"
]
}
This matches the working Angular services test compiler mode, lets TypeScript
honor Angular Material package exports, and includes the shared
Window.electron contract. Do not add a local fake Material declaration to
m3u-state.
- Step 6: Add coverage-tool tests to
coverage:ci
In package.json, add:
"coverage:tools:test": "node --test tools/coverage/coverage-integrity.test.mjs"
Change coverage:ci so it starts with:
"coverage:ci": "pnpm run coverage:tools:test && pnpm run coverage:policy:check && pnpm run coverage:unit:ci && pnpm run coverage:merge && node tools/coverage/coverage-health.mjs --require-report"
- Step 7: Verify targeted instrumentation is GREEN and complete
Run:
pnpm run coverage:tools:test
pnpm nx test m3u-state --skip-nx-cache --runInBand
pnpm run coverage:unit:ci -- --projects=m3u-state
node --input-type=module -e 'import fs from "node:fs"; import path from "node:path"; const report=JSON.parse(fs.readFileSync("coverage/libs/m3u-state/coverage-final.json","utf8")); const target=path.resolve("libs/m3u-state/src/lib/effects.ts"); if (!report[target]) throw new Error(`${target} missing`); console.log("effects.ts present");'
Expected: all commands exit 0, no Failed to collect coverage appears, and
the final command prints effects.ts present.
- Step 8: Commit the fail-closed runner and instrumentation fix
Run:
git add \
package.json \
tools/coverage/run-tier-a-coverage.mjs \
tools/coverage/merge-coverage.mjs \
tools/coverage/coverage-health.mjs \
libs/m3u-state/tsconfig.spec.json
git commit -m "fix(coverage): fail on incomplete instrumentation"
Expected: one commit with the gate wiring and the real effects.ts fix.
Task 3: Establish A Real Failing Critical-File Ratchet
Files:
-
Modify but do not yet commit:
tools/coverage/coverage-policy.json -
Step 1: Add the provisional ratchet
Under reporting, add:
"coverageRatchet": {
"merged": {
"statements": 68.86,
"branches": 58.66,
"functions": 67.19,
"lines": 69.2
},
"criticalFiles": [
{
"path": "apps/electron-backend/src/app/server/http-server.ts",
"statements": {
"minimumCovered": 1,
"minimumPercent": 0
}
},
{
"path": "apps/electron-backend/src/app/events/remote-control.events.ts",
"statements": {
"minimumCovered": 1,
"minimumPercent": 0
}
},
{
"path": "apps/electron-backend/src/app/events/settings.events.ts",
"statements": {
"minimumCovered": 17,
"minimumPercent": 59.25
}
},
{
"path": "apps/electron-backend/src/app/events/database/downloads.events.ts",
"statements": {
"minimumCovered": 70,
"minimumPercent": 46.93
}
}
]
}
The existing files use their fresh master percentage and require one additional covered statement. The two 0% files require one covered statement. These are minimal progress probes, not final thresholds.
- Step 2: Verify the critical acceptance test is RED
Use the fresh baseline reports from Task 0:
pnpm run coverage:merge
node tools/coverage/coverage-health.mjs --require-report
Expected: merge succeeds with exactly 30 reports; health exits nonzero and
names all selected files still below the provisional ratchet. In particular,
http-server.ts and remote-control.events.ts report zero covered
statements.
- Step 3: Keep the provisional policy change unstaged
Run:
git status --short
Expected: only tools/coverage/coverage-policy.json is intentionally dirty.
Do not stage it in Tasks 4–7; it remains the real red acceptance test until
the behavioral suites raise the observed values.
Task 4: Cover The HTTP Server Through Real Loopback And Filesystem Contracts
Files:
-
Create:
apps/electron-backend/src/app/server/http-server.spec.ts -
Modify:
apps/electron-backend/src/app/server/http-server.ts -
Step 1: Write the complete HTTP contract suite before the seam exists
The spec must:
- create a temporary static directory with
index.html,app.js,styles.css,data.json, and an unknown-extension asset; - inject a real
http.createServerwrapper that captures the Node server; - call
start(0), awaitlistening, and request127.0.0.1:<assigned-port>; - stop and remove the temporary tree in
afterEach.
Use these test helpers:
interface HttpResponseSnapshot {
body: Buffer;
contentType: string | undefined;
statusCode: number;
}
function request(
port: number,
requestPath: string,
method = 'GET'
): Promise<HttpResponseSnapshot> {
return new Promise((resolve, reject) => {
const req = http.request(
{
host: '127.0.0.1',
method,
path: requestPath,
port,
},
(res) => {
const chunks: Buffer[] = [];
res.on('data', (chunk: Buffer) => chunks.push(chunk));
res.on('end', () =>
resolve({
body: Buffer.concat(chunks),
contentType: res.headers['content-type'],
statusCode: res.statusCode ?? 0,
})
);
}
);
req.once('error', reject);
req.end();
});
}
Add assertions for:
/returns the exact index body astext/html;.js,.css,.json, and an unknown extension return the expected MIME;- a client route falls back to the exact index body;
- missing index returns plain-text 404;
- a registered API handler receives the request and bypasses static serving;
- unknown
/api/remote-control/...returns JSON 404; /../../outside-secret.txtnever returns an outside file;- duplicate
startcreates/listens once; - disable stops the server; and
- an enabled port change stops then starts once with the new port.
- Step 2: Run the focused spec to verify RED
Run:
pnpm nx test electron-backend \
--testPathPattern=http-server.spec.ts \
--runInBand
Expected: FAIL at TypeScript compilation because HttpServer does not yet
accept the injected distPath and createServer options, and start(0)
currently ignores port zero.
- Step 3: Add the minimal constructor seam
In http-server.ts, add flat types:
type HttpServerFactory = (requestListener: http.RequestListener) => http.Server;
interface HttpServerOptions {
createServer?: HttpServerFactory;
distPath?: string;
}
Add a factory field and constructor:
private readonly createServer: HttpServerFactory;
constructor(options: HttpServerOptions = {}) {
this.createServer =
options.createServer ??
((requestListener) => http.createServer(requestListener));
this.distPath = options.distPath ?? null;
}
Replace:
if (port) {
with:
if (port !== undefined) {
and replace the direct http.createServer call with this.createServer.
Leave the production singleton as:
export const httpServer = new HttpServer();
No production caller passes port zero or constructor options, so normal runtime behavior stays unchanged.
- Step 4: Run HTTP tests and Electron coverage
Run:
pnpm nx test electron-backend \
--testPathPattern=http-server.spec.ts \
--runInBand
pnpm run coverage:unit:ci -- --projects=electron-backend
pnpm run coverage:merge
node tools/coverage/coverage-health.mjs --require-report
Expected:
-
the focused suite PASSes;
-
http-server.tsis nonzero; -
health remains RED only for the not-yet-expanded selected boundaries and any aggregate dip caused by adding
effects.ts. -
Step 5: Commit only the HTTP slice
Run:
git add \
apps/electron-backend/src/app/server/http-server.ts \
apps/electron-backend/src/app/server/http-server.spec.ts
git commit -m "test(electron): cover remote HTTP server"
Expected: the provisional policy remains unstaged.
Task 5: Cover Remote-Control HTTP, IPC, And Renderer Dispatch
Files:
-
Create:
apps/electron-backend/src/app/events/remote-control.events.spec.ts -
Modify:
apps/electron-backend/src/app/events/remote-control.events.ts -
Step 1: Write the isolated remote-control suite
Mock only:
BrowserWindow.getAllWindows;ipcMain.handleandipcMain.on;httpServer.registerRemoteControlHandlerandhttpServer.start; andstore.get.
Import a named RemoteControlEvents class and instantiate it in each test.
Capture registered handlers in maps. Use a PassThrough request for JSON body
tests and a response recorder with typed writeHead/end methods.
Use this complete exchange helper:
interface ResponseSnapshot {
body: string;
headers: Record<string, string>;
statusCode: number;
}
function createExchange(method: string) {
const requestStream = new PassThrough();
Object.defineProperty(requestStream, 'method', { value: method });
let resolveResponse!: (snapshot: ResponseSnapshot) => void;
const snapshot: ResponseSnapshot = {
body: '',
headers: {},
statusCode: 0,
};
const completed = new Promise<ResponseSnapshot>((resolve) => {
resolveResponse = resolve;
});
const response = {
writeHead(statusCode: number, headers: Record<string, string>) {
snapshot.statusCode = statusCode;
snapshot.headers = headers;
return response;
},
end(body?: string) {
snapshot.body = body ?? '';
resolveResponse(snapshot);
return response;
},
};
return {
completed,
request: requestStream as unknown as http.IncomingMessage,
requestStream,
response: response as unknown as http.ServerResponse,
};
}
function getHttpHandler(path: string) {
const handler = mockRegisteredHttpHandlers.get(path);
if (!handler) {
throw new Error(`Expected remote-control HTTP handler for ${path}`);
}
return handler;
}
Add exact contract cases:
it.each([
['/api/remote-control/channel/up', 'CHANNEL_CHANGE', { direction: 'up' }],
[
'/api/remote-control/channel/down',
'CHANNEL_CHANGE',
{ direction: 'down' },
],
[
'/api/remote-control/volume/up',
'REMOTE_CONTROL_COMMAND',
{ type: 'volume-up' },
],
[
'/api/remote-control/volume/down',
'REMOTE_CONTROL_COMMAND',
{ type: 'volume-down' },
],
[
'/api/remote-control/volume/toggle-mute',
'REMOTE_CONTROL_COMMAND',
{ type: 'volume-toggle-mute' },
],
] as const)(
'dispatches POST %s to the first renderer',
async (path, channel, payload) => {
const exchange = createExchange('POST');
getHttpHandler(path)(exchange.request, exchange.response);
exchange.requestStream.end();
const response = await exchange.completed;
expect(response.statusCode).toBe(200);
expect(response.body).toBe(JSON.stringify({ success: true }));
expect(mockWebContentsSend).toHaveBeenCalledWith(channel, payload);
}
);
Also test:
-
all seven endpoint paths are registered;
-
stored enabled/port starts HTTP once; disabled does not;
-
GET on POST-only handlers and POST on status return 405 without dispatch;
-
select-number accepts
7.9and sends integer7; -
missing, zero, negative,
Infinity, and nonnumeric values return 400; -
malformed JSON returns 400 and sends nothing;
-
a 10,241-byte body returns 413, destroys the request, and sends nothing;
-
partial status IPC updates merge with previous state and refresh
updatedAt; -
GET status returns that merged state; and
-
no BrowserWindow logs a warning but does not throw.
-
Step 2: Run the focused spec to verify RED
Run:
pnpm nx test electron-backend \
--testPathPattern=remote-control.events.spec.ts \
--runInBand
Expected: FAIL because RemoteControlEvents is not exported as a named class.
- Step 3: Export the existing class without changing its singleton
Change:
class RemoteControlEvents {
to:
export class RemoteControlEvents {
Keep:
export default new RemoteControlEvents();
Do not change endpoint names, methods, payloads, body limit, stored defaults,
or renderer channels unless a correct regression assertion exposes an actual
defect. If that happens, invoke systematic-debugging, keep the failing test,
and document the separately justified behavior fix.
- Step 4: Verify remote-control behavior and coverage
Run:
pnpm nx test electron-backend \
--testPathPattern=remote-control.events.spec.ts \
--runInBand
pnpm run coverage:unit:ci -- --projects=electron-backend
pnpm run coverage:merge
node tools/coverage/coverage-health.mjs --require-report
Expected: the focused suite PASSes, remote-control.events.ts is nonzero, and
health no longer reports either formerly 0% selected file.
- Step 5: Commit only the remote-control slice
Run:
git add \
apps/electron-backend/src/app/events/remote-control.events.ts \
apps/electron-backend/src/app/events/remote-control.events.spec.ts
git commit -m "test(electron): cover remote control events"
Expected: the provisional policy remains unstaged.
Task 6: Expand Settings Runtime Reconciliation Coverage
Files:
-
Modify:
apps/electron-backend/src/app/events/settings.events.spec.ts -
Verify only:
apps/electron-backend/src/app/events/settings.events.ts -
Step 1: Make the existing test harness deterministic
Keep real normalizeExternalPlayerArguments. Add stable mocks:
type SettingsUpdateHandler = (
event: unknown,
settings: Record<string, unknown>
) => void;
const mockStoreGet = jest.fn();
const mockStoreSet = jest.fn();
const mockUpdateSettings = jest.fn();
let handler: SettingsUpdateHandler;
Include every imported key in the store mock:
EMBEDDED_MPV_FRAME_COPY: 'embeddedMpvFrameCopy',
MPV_PLAYER_ARGUMENTS: 'mpvPlayerArguments',
MPV_REUSE_INSTANCE: 'mpvReuseInstance',
VLC_PLAYER_ARGUMENTS: 'vlcPlayerArguments',
VLC_REUSE_INSTANCE: 'vlcReuseInstance',
store: {
get: mockStoreGet,
set: mockStoreSet,
},
In beforeEach, clear the handler map, reset modules and mocks, silence
console.log, import ./settings.events, and retrieve the registered
SETTINGS_UPDATE handler. Preserve both existing credential-redaction tests.
- Step 2: Confirm the provisional settings ratchet is RED before new cases
Run:
node tools/coverage/coverage-health.mjs --require-report
Expected: settings reports fewer than the provisional 17 covered statements or less than its retained 59.25% floor.
- Step 3: Add normalization and defined-only persistence assertions
Add:
it('normalizes player arguments and preserves explicit false reuse flags', () => {
handler(
{},
{
mpvPlayerArguments: [' --screen=1 ', '', ' --hwdec=auto-safe '],
mpvReuseInstance: false,
vlcPlayerArguments: ' --fullscreen \n\n --no-video-title-show ',
vlcReuseInstance: false,
}
);
expect(mockStoreSet).toHaveBeenCalledWith(
'mpvPlayerArguments',
'--screen=1\n--hwdec=auto-safe'
);
expect(mockStoreSet).toHaveBeenCalledWith('mpvReuseInstance', false);
expect(mockStoreSet).toHaveBeenCalledWith(
'vlcPlayerArguments',
'--fullscreen\n--no-video-title-show'
);
expect(mockStoreSet).toHaveBeenCalledWith('vlcReuseInstance', false);
});
it('does not persist undefined settings', () => {
handler({}, {});
expect(mockStoreSet).not.toHaveBeenCalled();
expect(mockUpdateSettings).not.toHaveBeenCalled();
});
it('coerces the frame-copy startup preference to boolean', () => {
handler({}, { embeddedMpvFrameCopy: 1 });
expect(mockStoreSet).toHaveBeenCalledWith('embeddedMpvFrameCopy', true);
});
- Step 4: Add partial remote-control reconciliation assertions
Add two tests:
it('uses the stored port when only remote-control enabled changes', () => {
mockStoreGet.mockImplementation((key: string) =>
key === 'remoteControlPort' ? 9988 : undefined
);
handler({}, { remoteControl: true });
expect(mockStoreSet).toHaveBeenCalledWith('remoteControl', true);
expect(mockStoreSet).not.toHaveBeenCalledWith(
'remoteControlPort',
expect.anything()
);
expect(mockUpdateSettings).toHaveBeenCalledWith(true, 9988);
});
it('uses stored enabled state when only the remote-control port changes', () => {
mockStoreGet.mockImplementation((key: string) =>
key === 'remoteControl' ? true : undefined
);
handler({}, { remoteControlPort: 9123 });
expect(mockStoreSet).toHaveBeenCalledWith('remoteControlPort', 9123);
expect(mockStoreSet).not.toHaveBeenCalledWith(
'remoteControl',
expect.anything()
);
expect(mockUpdateSettings).toHaveBeenCalledWith(true, 9123);
});
- Step 5: Run settings tests and refresh Electron coverage
Run:
pnpm nx test electron-backend \
--testPathPattern=settings.events.spec.ts \
--runInBand
pnpm run coverage:unit:ci -- --projects=electron-backend
pnpm run coverage:merge
node tools/coverage/coverage-health.mjs --require-report
Expected: all settings tests PASS; settings covered statements and percentage are above the fresh master baseline. These are characterization tests for unchanged behavior, so no production edit is expected.
- Step 6: Commit only the settings spec
Run:
git add apps/electron-backend/src/app/events/settings.events.spec.ts
git commit -m "test(electron): cover settings runtime updates"
Expected: the provisional policy remains unstaged.
Task 7: Expand Download Managed-Path Security Coverage
Files:
-
Modify:
apps/electron-backend/src/app/events/database/downloads.events.spec.ts -
Verify only:
apps/electron-backend/src/app/events/database/downloads.events.ts -
Step 1: Add filesystem and shell spies to the existing harness
Add:
const mockExistsSync = jest.fn();
const mockOpenPath = jest.fn();
const mockShowItemInFolder = jest.fn();
Return the two shell spies from the existing Electron mock. Reset them in
beforeEach; make mockOpenPath resolve an empty string by default.
Before importing downloads.events, register:
jest.doMock('node:fs', () => ({
existsSync: mockExistsSync,
}));
Add a database helper whose limit(1) returns either [{ id: 42 }], [], or
rejects:
function mockManagedPath(result: 'managed' | 'unmanaged' | 'error') {
const limit =
result === 'error'
? jest.fn().mockRejectedValue(new Error('database unavailable'))
: jest
.fn()
.mockResolvedValue(result === 'managed' ? [{ id: 42 }] : []);
mockGetDatabase.mockResolvedValue({
select: jest.fn(() => ({
from: jest.fn(() => ({
where: jest.fn(() => ({ limit })),
})),
})),
});
}
- Step 2: Confirm the provisional downloads ratchet is RED
Run:
node tools/coverage/coverage-health.mjs --require-report
Expected: downloads is below the provisional 70-covered-statement target or its retained 46.93% floor.
- Step 3: Add the managed-path rejection cases
For both DOWNLOADS_REVEAL_FILE and DOWNLOADS_PLAY_FILE, assert:
it.each(['DOWNLOADS_REVEAL_FILE', 'DOWNLOADS_PLAY_FILE'])(
'%s rejects a path not owned by a download row',
async (channel) => {
mockManagedPath('unmanaged');
mockExistsSync.mockReturnValue(true);
await expect(
getHandler(channel)(null, '/tmp/unmanaged.mp4')
).resolves.toEqual({
error: 'File not found',
success: false,
});
expect(mockShowItemInFolder).not.toHaveBeenCalled();
expect(mockOpenPath).not.toHaveBeenCalled();
}
);
it.each(['DOWNLOADS_REVEAL_FILE', 'DOWNLOADS_PLAY_FILE'])(
'%s rejects a managed path missing on disk',
async (channel) => {
mockManagedPath('managed');
mockExistsSync.mockReturnValue(false);
await expect(
getHandler(channel)(null, '/downloads/missing.mp4')
).resolves.toEqual({
error: 'File not found',
success: false,
});
expect(mockShowItemInFolder).not.toHaveBeenCalled();
expect(mockOpenPath).not.toHaveBeenCalled();
}
);
- Step 4: Add the authorized shell and database-failure cases
Add one reveal success, one play success, and a parameterized database failure:
it('reveals only a managed file that exists', async () => {
mockManagedPath('managed');
mockExistsSync.mockReturnValue(true);
await expect(
getHandler('DOWNLOADS_REVEAL_FILE')(null, '/downloads/movie.mp4')
).resolves.toEqual({ success: true });
expect(mockShowItemInFolder).toHaveBeenCalledWith('/downloads/movie.mp4');
});
it('opens only a managed file that exists', async () => {
mockManagedPath('managed');
mockExistsSync.mockReturnValue(true);
await expect(
getHandler('DOWNLOADS_PLAY_FILE')(null, '/downloads/movie.mp4')
).resolves.toEqual({ success: true });
expect(mockOpenPath).toHaveBeenCalledWith('/downloads/movie.mp4');
});
For the database-error cases, silence console.error, use
mockManagedPath('error'), expect the existing structured not-found response,
and assert neither shell spy ran.
- Step 5: Run download tests and refresh Electron coverage
Run:
pnpm nx test electron-backend \
--testPathPattern=downloads.events.spec.ts \
--runInBand
pnpm run coverage:unit:ci -- --projects=electron-backend
pnpm run coverage:merge
node tools/coverage/coverage-health.mjs --require-report
Expected: all existing destructive cleanup/pause/resume tests and all new managed-path tests PASS. Downloads covered statements and percentage exceed the fresh master values.
- Step 6: Commit only the downloads spec
Run:
git add \
apps/electron-backend/src/app/events/database/downloads.events.spec.ts
git commit -m "test(electron): cover managed download paths"
Expected: the provisional policy remains the only unstaged source change.
Task 8: Record Achieved Ratchets And Document The Integrity Contract
Files:
-
Modify:
tools/coverage/coverage-policy.json -
Modify:
docs/architecture/validation-map.md -
Modify:
docs/superpowers/specs/2026-07-25-coverage-integrity-runtime-boundaries-design.md -
Modify:
docs/superpowers/plans/2026-07-25-coverage-integrity-runtime-boundaries.md -
Create:
.changes/electron-remote-static-paths.md -
Step 1: Generate a complete fresh candidate report
Run:
NX_SKIP_NX_CACHE=true pnpm run coverage:ci
Expected: 30 Tier A reports, no Failed to collect coverage, no missing
runtime-owning files, and all four aggregate metrics at or above the fresh
master baseline. If any metric is lower, do not lower the baseline. Inspect
the approved boundary cases for a missing meaningful assertion, add that
failing assertion, and rerun the directly affected suite before repeating this
command.
- Step 2: Print exact achieved aggregate and per-file values
Run:
node --input-type=module <<'NODE'
import { createRequire } from 'node:module';
import fs from 'node:fs';
import path from 'node:path';
const require = createRequire(import.meta.url);
const { createCoverageMap } = require('istanbul-lib-coverage');
const data = JSON.parse(
fs.readFileSync('coverage/merged/coverage-final.json', 'utf8')
);
const map = createCoverageMap(data);
const targets = [
'apps/electron-backend/src/app/server/http-server.ts',
'apps/electron-backend/src/app/events/remote-control.events.ts',
'apps/electron-backend/src/app/events/settings.events.ts',
'apps/electron-backend/src/app/events/database/downloads.events.ts',
];
const criticalFiles = targets.map((file) => {
const statements = map
.fileCoverageFor(path.resolve(file))
.toSummary()
.toJSON().statements;
return {
path: file,
statements: {
minimumCovered: statements.covered,
minimumPercent: statements.pct,
},
};
});
const summary = map.getCoverageSummary().toJSON();
console.log(
JSON.stringify(
{
merged: {
statements: summary.statements.pct,
branches: summary.branches.pct,
functions: summary.functions.pct,
lines: summary.lines.pct,
},
criticalFiles,
},
null,
4
)
);
NODE
Expected: a complete coverageRatchet value with nonzero HTTP/remote values
and settings/download values no lower than their baseline. Copy this exact
JSON object over the provisional reporting.coverageRatchet; do not round
manually or retain the provisional one-statement probes.
- Step 3: Verify the achieved ratchet passes and rejects regressions
Run:
pnpm run coverage:health -- --require-report
node --test tools/coverage/coverage-integrity.test.mjs
Expected: both exit 0. The synthetic Node tests still prove below-ratchet metrics, missing critical files, missing reports, and collection markers fail.
- Step 4: Update the canonical validation map
Under ## Coverage Tiers in docs/architecture/validation-map.md, add:
Tier A coverage is fail-closed. `coverage:unit:ci` relays Jest output but exits
nonzero on `Failed to collect coverage`, a missing/invalid project report, or
a runtime-owning production TypeScript file absent from that report.
`coverage:merge` requires every configured Tier A report before replacing the
merged output, and `coverage:health --require-report` repeats completeness plus
aggregate and critical-file ratchets.
Runtime-owning files are discovered from the TypeScript AST. Specs, declarations,
test setup/stubs, generated/environment files, `index.ts`, type-only files, and
pure re-export shims do not count as executable coverage inputs.
Ratchets live under `reporting.coverageRatchet` in
`tools/coverage/coverage-policy.json`. Update them only from a fresh full
`coverage:ci` report when every value stays level or rises; never lower a
ratchet to accept a regression. The only exception is a reviewed production
source shrink: `minimumCovered` may follow a lower statement total when the PR
identifies the removed executable statements and fresh coverage proves that
the file percentage, aggregate ratchets, and remaining behavioral coverage do
not decrease.
Also include pnpm run coverage:tools:test in the local coverage command block.
- Step 5: Confirm documentation and release-note decisions
Because the real-loopback regression exposed and fixed an observable Windows
static-path traversal escape, add .changes/electron-remote-static-paths.md:
---
type: fix
area: electron
---
The desktop remote-control server now blocks crafted static paths from escaping
bundled web files on Windows.
Run:
pnpm exec prettier --check \
docs/architecture/validation-map.md \
docs/superpowers/specs/2026-07-25-coverage-integrity-runtime-boundaries-design.md \
docs/superpowers/plans/2026-07-25-coverage-integrity-runtime-boundaries.md \
.changes/electron-remote-static-paths.md
pnpm run release:notes:validate
Expected: both pass. The release note records the narrow user-visible security
fix; do not apply no-release-note in Task 10.
- Step 6: Commit ratchets and docs
Run:
git add \
tools/coverage/coverage-policy.json \
docs/architecture/validation-map.md \
docs/superpowers/specs/2026-07-25-coverage-integrity-runtime-boundaries-design.md \
docs/superpowers/plans/2026-07-25-coverage-integrity-runtime-boundaries.md \
.changes/electron-remote-static-paths.md
git commit -m "ci(coverage): ratchet runtime boundaries"
Expected: the provisional policy is replaced by achieved values, the security fix has a valid release note, and the worktree becomes clean.
Task 9: Run Fresh Validation And Audit The Final Diff
Files:
-
Verify only: all changed files
-
Verify only:
apps/electron-backend-e2e/src/downloads.e2e.ts -
Verify only:
apps/electron-backend-e2e/src/remote-control.e2e.ts -
Verify only:
apps/electron-backend-e2e/src/settings.e2e.ts -
Step 1: Run targeted unit, lint, and type checks
Run:
pnpm run coverage:tools:test
pnpm nx test electron-backend --skip-nx-cache --runInBand
pnpm nx test m3u-state --skip-nx-cache --runInBand
pnpm nx lint electron-backend --skip-nx-cache
pnpm nx lint m3u-state --skip-nx-cache
pnpm run typecheck:backend
Expected: every command exits 0; no Jest suite, lint rule, or backend type check fails.
- Step 2: Run the three existing Electron E2E contracts
Run:
pnpm nx run electron-backend-e2e:e2e-ci--src/downloads.e2e.ts --skip-nx-cache
pnpm nx run electron-backend-e2e:e2e-ci--src/remote-control.e2e.ts --skip-nx-cache
pnpm nx run electron-backend-e2e:e2e-ci--src/settings.e2e.ts --skip-nx-cache
Expected: all targets PASS. These prove the real packaged-style Electron IPC, native folder/download flow, remote loopback server, renderer command, and settings persistence contracts beyond unit mocks.
- Step 3: Build the production Electron target
Run:
pnpm nx build electron-backend \
--configuration=production \
--skip-nx-cache
Expected: exit 0, including worker, web, and remote-control-web dependencies.
- Step 4: Run final full coverage from scratch
Run:
NX_SKIP_NX_CACHE=true pnpm run coverage:ci
Expected:
-
all coverage-tool tests PASS;
-
policy sees 30 Tier A projects;
-
all 30 project reports are merged;
-
effects.tsis present; -
no collection marker or runtime-owning source omission is reported;
-
achieved aggregate and critical-file ratchets PASS.
-
Step 5: Inspect exact metrics and scoped diff
Run:
git diff origin/master...HEAD --check
git diff --stat origin/master...HEAD
git diff --name-only origin/master...HEAD
git status --short --branch
Expected:
-
no whitespace errors;
-
only the files in this plan appear;
-
no database worker, dashboard, Stalker search, type-only interface, lockfile, AGENTS, or CLAUDE changes appear;
-
the worktree is clean.
-
Step 6: Apply verification-before-completion
Read and follow verification-before-completion. Record, without paraphrasing
away failures:
- exact unit suite/test counts;
- exact E2E results;
- lint/typecheck/build exit results;
- 30/30 Tier A report integrity;
- aggregate before/after;
- all selected-file before/after values;
- docs and release-note decisions.
Do not claim completion from cached or earlier output.
Task 10: Recheck Master, Push, And Open The Draft PR
Files:
-
Verify only: current branch history and GitHub PR metadata
-
Step 1: Recheck master before publication
Run:
git fetch origin master --prune
git log --oneline HEAD..origin/master
Expected: no output. If master advanced, rebase, rerun dependency bootstrap and all of Task 9, then refresh ratchets only upward before publication.
- Step 2: Review conventional history
Run:
git log --oneline origin/master..HEAD
git status --short --branch
Expected: concise conventional commits, including the design and plan docs, with a clean worktree.
- Step 3: Push the agent branch
Run:
git push -u origin agent/coverage-integrity-runtime-boundaries
Expected: push succeeds and sets the upstream.
- Step 4: Create a draft PR
Read and follow github-pr. Create a draft targeting master with title:
test(electron): harden runtime coverage integrity
The body must contain:
- fresh baseline commit and aggregate metrics;
- exact after metrics;
- selected-file before/after table;
- behavioral contracts for HTTP, remote control, settings, and downloads;
- the two behavior-preserving production seams;
- the
effects.tscompiler/instrumentation correction; - runner, merge, health, and ratchet behavior;
- exact validation commands/results;
- docs update;
- the Electron fix release note for Windows static-path containment; and
- deferred
database.worker.ts, dashboard rails, and Stalker search.
Use:
gh pr create \
--draft \
--base master \
--head agent/coverage-integrity-runtime-boundaries \
--title "test(electron): harden runtime coverage integrity" \
--body-file -
Provide the fully populated body on standard input; do not leave metric or validation placeholders.
- Step 5: Verify release-note metadata
Run:
gh pr view --json url,isDraft,headRefName,baseRefName,labels,files,commits,statusCheckRollup
Expected: the PR is draft, head/base are correct,
.changes/electron-remote-static-paths.md is included, no-release-note is
absent, and the command prints the PR URL.
- Step 6: Return the exact handoff
Return:
- draft PR URL;
- branch;
- final commit SHA;
- aggregate and selected-file before/after metrics;
- exact command results and any explicit environment-only skip;
- docs updated (
docs/architecture/validation-map.md); - release note added (
.changes/electron-remote-static-paths.md) with nono-release-notelabel; - deferred zero-coverage follow-ups.