mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-10-26 21:47:20 +00:00
Bind isolated presentation fixtures without an unmounted Git read
The source-bound static preview failed before browser startup because its copied worktree has no Git store. Accept an explicit, validated source-owner attribution for that isolated copy, label it separately from an actual Git read, and preserve every source and artifact hash check. Default Git failures still fail closed; regression cases reject malformed attribution and implicit fallback. Contract-Neutral: Browser fixture preparation and its tests only; no product runtime, API, shared primitive, security or subsystem contract delta. Change-source: pulse-maintainer
This commit is contained in:
@@ -81,6 +81,13 @@ own-parent and final-content receipts still require a real browser pass. No
|
||||
native guest-agent, thaw, filesystem-write, installed or publication acceptance
|
||||
is established by compiling these synthetic fixtures.
|
||||
|
||||
The isolated browser copy has no Git store. When preparing its preview there,
|
||||
pass `--source-sha <full SHA>` with the source owner's externally checked HEAD.
|
||||
The binding marks this as `supplied-for-isolated-copy`, not a Git observation.
|
||||
The default remains an actual Git HEAD read, with no silent fallback. Verify
|
||||
the binding's source and artifact hashes against the assigned tree before using
|
||||
the preview as evidence; a supplied SHA alone establishes no source identity.
|
||||
|
||||
## CI and release evidence
|
||||
|
||||
These standalone runners are manual qualification commands: the current GitHub
|
||||
|
||||
@@ -8,6 +8,7 @@ import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
import { execFileSync } from 'node:child_process';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import sourceIdentity from './publication-fixture-source.cjs';
|
||||
import {
|
||||
entryPaths,
|
||||
harnessPaths,
|
||||
@@ -21,7 +22,9 @@ const outDir = path.resolve(root, '../tmp/publication-final-static');
|
||||
const started = Date.now();
|
||||
const binding = {
|
||||
version: 1,
|
||||
source_sha: execFileSync('git', ['rev-parse', 'HEAD'], { cwd: root, encoding: 'utf8' }).trim(),
|
||||
...sourceIdentity.publicationSourceIdentity(process.argv.slice(2), () =>
|
||||
execFileSync('git', ['rev-parse', 'HEAD'], { cwd: root, encoding: 'utf8' }),
|
||||
),
|
||||
graph: hash(fs.readFileSync(path.join(root, 'package-lock.json'))),
|
||||
entries: entryPaths,
|
||||
sources: {},
|
||||
|
||||
@@ -20,6 +20,7 @@ const entryPaths = [
|
||||
'browser-tests/patrol-rule-removal.html',
|
||||
];
|
||||
const harnessPaths = [
|
||||
'browser-tests/publication-fixture-source.cjs',
|
||||
'browser-tests/build-publication-fixtures.mjs',
|
||||
'browser-tests/publication-fixture-server.cjs',
|
||||
'browser-tests/guest-disk-provenance.cjs',
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
// The browser's isolated source copy does not mount the worktree's Git store.
|
||||
// A supplied SHA is an attribution supplied by the source owner, not a Git read
|
||||
// or execution authority. Imported source and served bytes remain hash-bound.
|
||||
const assert = require('node:assert/strict');
|
||||
|
||||
function publicationSourceIdentity(args, readHead) {
|
||||
if (args.length === 0) {
|
||||
const source_sha = readHead().trim();
|
||||
assert.match(source_sha, /^[a-f0-9]{40}$/, 'invalid Git source identity');
|
||||
return { source_sha, source_identity: 'git-head' };
|
||||
}
|
||||
assert.equal(args.length, 2, 'expected only --source-sha <full SHA>');
|
||||
assert.equal(args[0], '--source-sha', 'unknown fixture preparation argument');
|
||||
assert.match(args[1], /^[a-f0-9]{40}$/, 'expected a full lowercase source SHA');
|
||||
return { source_sha: args[1], source_identity: 'supplied-for-isolated-copy' };
|
||||
}
|
||||
|
||||
module.exports = { publicationSourceIdentity };
|
||||
@@ -0,0 +1,37 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import source from './publication-fixture-source.cjs';
|
||||
|
||||
const sha = 'a'.repeat(40);
|
||||
describe('publication fixture source attribution', () => {
|
||||
it('reads the actual Git head by default', () => {
|
||||
expect(source.publicationSourceIdentity([], () => sha + '\n')).toEqual({
|
||||
source_sha: sha,
|
||||
source_identity: 'git-head',
|
||||
});
|
||||
});
|
||||
it('never silently substitutes a supplied identity after a failed Git read', () => {
|
||||
expect(() =>
|
||||
source.publicationSourceIdentity([], () => {
|
||||
throw new Error('Git unavailable');
|
||||
}),
|
||||
).toThrow('Git unavailable');
|
||||
});
|
||||
it('explicitly attributes an isolated copy without trying to access an unmounted Git store', () => {
|
||||
expect(
|
||||
source.publicationSourceIdentity(['--source-sha', sha], () => {
|
||||
throw new Error('must not read outside the isolated copy');
|
||||
}),
|
||||
).toEqual({ source_sha: sha, source_identity: 'supplied-for-isolated-copy' });
|
||||
});
|
||||
it.each([
|
||||
[],
|
||||
['--source-sha'],
|
||||
['--source-sha', 'a'.repeat(39)],
|
||||
['--source-sha', 'A'.repeat(40)],
|
||||
['--source-sha', 'main'],
|
||||
['--source-sha', sha, '--extra'],
|
||||
['--unknown', sha],
|
||||
])('rejects malformed identity or arguments %j', (...args) => {
|
||||
expect(() => source.publicationSourceIdentity(args, () => 'main')).toThrow();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user