fix(mosaic): isolate brain publication index

This commit is contained in:
2026-08-05 17:19:50 -05:00
parent fb7087b3eb
commit f0555016f4
4 changed files with 244 additions and 36 deletions
@@ -83,13 +83,13 @@ No explicit token ceiling was supplied. Working cap: 55K tokens for implementati
- [x] C1 P5→P7 seam receipt read; no brain implementation is in C1.
- [x] RED acceptance set committed at `cf11c6c86abae073d8b02b4014cd5447ba67f12a`; author and committer read back as `be-coder-07` and branch reachability was independently verified by `tl-mosaic`.
- [x] Moving-contract REDs observed independently for v1.4 mismatch, R8 prerequisite ordering, owner resolver seam/allowlist, tracked skeleton/no-follow behavior, runtime observation/publication, and provider owner resolution.
- [x] Focused implementation includes secure migration, v1.5 write-differential/subject binding, production Git+API refusal parity, provider-backed durable owner resolution that ignores non-admin `active`, required GLPI standing-process policy, P7 provision orchestration, an internal installer command, and installed `mosaic doctor` wiring. Latest focused result: 86/86 (secure config 3, store 43, runtime 12, owner resolver 16, provision 4, provision command 3, installed doctor 5).
- [x] Focused implementation includes secure migration, v1.5 write-differential/subject binding, production Git+API refusal parity, provider-backed durable owner resolution that ignores non-admin `active`, required GLPI standing-process policy, P7 provision orchestration, an internal installer command, and installed `mosaic doctor` wiring. Latest focused result: 87/87 (secure config 3, store 43, runtime 13, owner resolver 16, provision 4, provision command 3, installed doctor 5).
- [x] MC-CRED added the required canonical reverse registry seam `ParsedCredentialEstateRegistry.resolveByHost()` at dependency head `6ca8758f`; current local copies are temporary until dependency integration and the 32-line permissive shim has been removed.
- [x] Identity gotcha measured: inline `MOSAIC_GIT_IDENTITY=be-coder-07` controls credential resolution but does not override `user.name`/`user.email` inherited from the linked worktree common-dir config (`coder-mos1`). The first local P7 RED commit was immediately amended before push with command-scoped `GIT_AUTHOR_*` + `GIT_COMMITTER_*`; resulting author and committer both read back as `be-coder-07`. Every subsequent authoring command must carry both identity sets and be verified.
- [x] R6 migration reports filename- or content-secret-shaped files without copying them; arbitrary legacy content requires an approved scanner bound to the exact source snapshot, and production currently retains/reports when no approved scanner is configured. Symlinked `.gitignore`, layout directories, and nested migration destinations fail closed.
- [x] Provider owner lookup uses manual redirect handling, a five-second abort signal, strict JSON content type/shape, and an incrementally enforced 256 KiB response ceiling.
- [x] Automatic source deletion is parked per the shared-Git-identity governance ruling; remotely reachable snapshots still leave and report every source.
- [x] Multi-host push-on-write retries non-fast-forward races via fetch/rebase rather than LWW, and unknown publication reachability retains both sources and local copies.
- [x] Multi-host push-on-write uses an isolated temporary Git index, verifies the exact changed-path allowlist plus both author/committer trailers before push, retries non-fast-forward races via identity-scoped fetch/rebase rather than LWW, and retains both sources and local copies when publication reachability is unknown. A real-repository abuse test proves unrelated pre-staged secret-shaped content remains staged but never enters the published commit.
- [ ] Installer shell P7 invocation after C1 + MC-CRED integration; production command is registered but the C1 shell has not yet called it.
- [ ] Implementation green on merged dependency base.
- [ ] Independent code review.
@@ -301,6 +301,7 @@ describe('P7 brain provisioning orchestration', (): void => {
writeFileSync(source, 'durable finding\n');
const requests: CommandRequest[] = [];
let commitOrdinal = 0;
let approvedPaths: string[] = [];
const runner: CommandRunner = (request): CommandResult => {
requests.push(request);
if (request.program === 'mosaic') {
@@ -325,6 +326,24 @@ describe('P7 brain provisioning orchestration', (): void => {
mkdirSync(join(input.root, '.git'), { recursive: true });
return { status: 0, stdout: '', stderr: '' };
}
if (command.includes(' add -- ')) {
const separator = request.args.indexOf('--');
approvedPaths = separator === -1 ? [] : [...request.args.slice(separator + 1)];
return { status: 0, stdout: '', stderr: '' };
}
if (command.includes('diff --cached --quiet')) {
return { status: 1, stdout: '', stderr: '' };
}
if (command.includes('diff-tree')) {
return { status: 0, stdout: `${approvedPaths.join('\0')}\0`, stderr: '' };
}
if (command.includes('show -s')) {
return {
status: 0,
stdout: 'seat-a\[email protected]\0seat-a\[email protected]\n',
stderr: '',
};
}
if (command.includes('rev-parse --is-inside-work-tree')) {
return { status: 0, stdout: 'true\n', stderr: '' };
}
@@ -1,5 +1,6 @@
import { afterEach, describe, expect, it } from 'vitest';
import { mkdirSync, mkdtempSync, rmSync } from 'node:fs';
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs';
import { execFileSync } from 'node:child_process';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
@@ -46,6 +47,7 @@ interface PublishEvidence {
}
interface BrainRuntimeModule {
readonly systemCommandRunner: CommandRunner;
collectBrainDoctorReport(
input: {
readonly registrySource: string;
@@ -544,6 +546,64 @@ describe('R5 production refusal control', (): void => {
});
describe('push-on-write publication', (): void => {
it('never commits or pushes an unrelated pre-staged secret-shaped file', async (): Promise<void> => {
const runtime = await loadRuntime('MB-REQ-06 isolated publication index');
const root = tempRoot();
const remote = join(root, 'remote.git');
const checkout = join(root, 'brain');
execFileSync('git', ['init', '--bare', '--initial-branch=main', remote]);
execFileSync('git', ['init', '--initial-branch=main', checkout]);
writeFileSync(join(checkout, 'README.md'), 'brain\n');
execFileSync('git', ['-C', checkout, 'add', 'README.md']);
execFileSync('git', [
'-C',
checkout,
'-c',
'user.name=fixture',
'-c',
'[email protected]',
'commit',
'-m',
'seed',
]);
execFileSync('git', ['-C', checkout, 'remote', 'add', 'origin', remote]);
execFileSync('git', ['-C', checkout, 'push', '-u', 'origin', 'main']);
writeFileSync(join(checkout, '.env'), 'TEST_ONLY_SECRET=fixture-value\n');
execFileSync('git', ['-C', checkout, 'add', '-f', '.env']);
const approved = join(checkout, 'finding.md');
writeFileSync(approved, 'approved finding\n');
const evidence = runtime.publishBrainPaths(
{
root: checkout,
identity: 'seat-a',
paths: [approved],
message: 'append approved finding',
},
runtime.systemCommandRunner,
);
const committed = execFileSync('git', [
'-C',
checkout,
'diff-tree',
'--no-commit-id',
'--name-only',
'-r',
evidence.commit,
]).toString();
const staged = execFileSync('git', [
'-C',
checkout,
'diff',
'--cached',
'--name-only',
]).toString();
expect(committed.trim().split('\n')).toEqual(['finding.md']);
expect(staged.trim().split('\n')).toContain('.env');
expect(evidence.reachable).toBe(true);
});
it('commits with command-scoped identity, pushes immediately, and proves reachability from origin/main', async (): Promise<void> => {
const runtime = await loadRuntime('MB-REQ-07 publish-on-write reachability');
const root = tempRoot();
@@ -558,6 +618,19 @@ describe('push-on-write publication', (): void => {
if (command.includes('rev-parse origin/main')) {
return { status: 0, stdout: `${remoteHead}\n`, stderr: '' };
}
if (command.includes('diff --cached --quiet')) {
return { status: 1, stdout: '', stderr: '' };
}
if (command.includes('diff-tree')) {
return { status: 0, stdout: '.gitignore\0lanes/lane-a/.gitkeep\0', stderr: '' };
}
if (command.includes('show -s')) {
return {
status: 0,
stdout: 'seat-a\[email protected]\0seat-a\[email protected]\n',
stderr: '',
};
}
return { status: 0, stdout: '', stderr: '' };
};
@@ -632,6 +705,23 @@ describe('push-on-write publication', (): void => {
if (command.includes('rev-parse origin/main')) {
return { status: 0, stdout: `${remoteHead}\n`, stderr: '' };
}
if (command.includes('diff --cached --quiet')) {
return { status: 1, stdout: '', stderr: '' };
}
if (command.includes('diff-tree')) {
return {
status: 0,
stdout: 'lanes/lane-a/findings/host-a.md\0',
stderr: '',
};
}
if (command.includes('show -s')) {
return {
status: 0,
stdout: 'seat-a\[email protected]\0seat-a\[email protected]\n',
stderr: '',
};
}
return { status: 0, stdout: '', stderr: '' };
},
);
@@ -679,7 +769,7 @@ describe('push-on-write publication', (): void => {
);
expect(evidence).toEqual({ commit, remoteHead: commit, reachable: true });
expect(requests.some((request) => request.args.includes('push'))).toBe(true);
expect(requests.some((request) => request.args.includes('push'))).toBe(false);
});
it('does not manufacture reachability when merge-base rejects the new commit', async (): Promise<void> => {
@@ -703,6 +793,19 @@ describe('push-on-write publication', (): void => {
if (command.includes('rev-parse origin/main')) {
return { status: 0, stdout: `${remoteHead}\n`, stderr: '' };
}
if (command.includes('diff --cached --quiet')) {
return { status: 1, stdout: '', stderr: '' };
}
if (command.includes('diff-tree')) {
return { status: 0, stdout: '.gitignore\0', stderr: '' };
}
if (command.includes('show -s')) {
return {
status: 0,
stdout: 'seat-a\[email protected]\0seat-a\[email protected]\n',
stderr: '',
};
}
if (command.includes('merge-base --is-ancestor')) {
return { status: 1, stdout: '', stderr: '' };
}
@@ -1,6 +1,7 @@
import { existsSync } from 'node:fs';
import { existsSync, mkdtempSync, rmSync } from 'node:fs';
import { spawnSync } from 'node:child_process';
import { isAbsolute, relative, resolve, sep } from 'node:path';
import { tmpdir } from 'node:os';
import { isAbsolute, join, relative, resolve, sep } from 'node:path';
import {
assessCredentialResult,
deriveBrainTarget,
@@ -84,6 +85,15 @@ function runGit(run: CommandRunner, identity: string, args: readonly string[]):
return run({ program: 'git', args, env: commandEnv(identity) });
}
function runGitWithEnv(
run: CommandRunner,
identity: string,
args: readonly string[],
env: Readonly<Record<string, string>>,
): CommandResult {
return run({ program: 'git', args, env: { ...commandEnv(identity), ...env } });
}
export function collectBrainDoctorReport(
input: {
readonly registrySource: string;
@@ -316,32 +326,6 @@ export function publishBrainPaths(
if (input.message.trim().length === 0) throw new Error('brain-publish-message-empty');
const paths = input.paths.map((path: string): string => containedRelative(input.root, path));
requireSuccess(
runGit(run, input.identity, ['-C', input.root, 'add', '--', ...paths]),
'brain-git-add',
);
const commitAttempt = runGit(run, input.identity, [
'-C',
input.root,
'-c',
`user.name=${input.identity}`,
'-c',
`user.email=${input.identity}@fleet.mosaicstack.dev`,
'commit',
'-m',
input.message,
]);
if (commitAttempt.status !== 0) {
const stagedDifference = runGit(run, input.identity, [
'-C',
input.root,
'diff',
'--cached',
'--quiet',
'--exit-code',
]);
if (stagedDifference.status !== 0) throw new Error('brain-git-commit-failed');
}
const readHead = (): string => {
const result = runGit(run, input.identity, ['-C', input.root, 'rev-parse', 'HEAD']);
requireSuccess(result, 'brain-git-read-commit');
@@ -349,9 +333,100 @@ export function publishBrainPaths(
if (!COMMIT.test(value)) throw new Error('brain-git-commit-shape-invalid');
return value;
};
let commit = readHead();
let pushed = false;
for (let attempt = 0; attempt < 3; attempt += 1) {
const verifyCommitIdentity = (commit: string): void => {
const result = runGit(run, input.identity, [
'-C',
input.root,
'show',
'-s',
'--format=%an%x00%ae%x00%cn%x00%ce',
commit,
]);
requireSuccess(result, 'brain-git-read-commit-identity');
const expectedEmail = `${input.identity}@fleet.mosaicstack.dev`;
const [author, authorEmail, committer, committerEmail] = result.stdout.trimEnd().split('\0');
if (
author !== input.identity ||
authorEmail !== expectedEmail ||
committer !== input.identity ||
committerEmail !== expectedEmail
) {
throw new Error('brain-git-commit-identity-mismatch');
}
};
const verifyCommitPaths = (commit: string): void => {
const changed = runGit(run, input.identity, [
'-C',
input.root,
'diff-tree',
'--root',
'--no-commit-id',
'--name-only',
'-r',
'-z',
commit,
]);
requireSuccess(changed, 'brain-git-read-commit-paths');
const names = changed.stdout.split('\0').filter(Boolean);
const approved = new Set(paths);
if (names.length === 0 || names.some((name: string): boolean => !approved.has(name))) {
throw new Error('brain-git-commit-paths-unapproved');
}
};
const base = readHead();
const indexRoot = mkdtempSync(join(tmpdir(), 'mosaic-brain-index-'));
const isolatedEnv = { GIT_INDEX_FILE: join(indexRoot, 'index') };
let commit = base;
let createdCommit = false;
try {
requireSuccess(
runGitWithEnv(run, input.identity, ['-C', input.root, 'read-tree', base], isolatedEnv),
'brain-git-isolated-index-init',
);
requireSuccess(
runGitWithEnv(run, input.identity, ['-C', input.root, 'add', '--', ...paths], isolatedEnv),
'brain-git-add',
);
const difference = runGitWithEnv(
run,
input.identity,
['-C', input.root, 'diff', '--cached', '--quiet', '--exit-code', base, '--', ...paths],
isolatedEnv,
);
if (difference.status === 1) {
requireSuccess(
runGitWithEnv(
run,
input.identity,
[
'-C',
input.root,
'-c',
`user.name=${input.identity}`,
'-c',
`user.email=${input.identity}@fleet.mosaicstack.dev`,
'commit',
'-m',
input.message,
],
isolatedEnv,
),
'brain-git-commit',
);
commit = readHead();
verifyCommitPaths(commit);
verifyCommitIdentity(commit);
createdCommit = true;
} else if (difference.status !== 0) {
throw new Error('brain-git-isolated-diff-failed');
}
} finally {
rmSync(indexRoot, { recursive: true, force: true });
}
let pushed = !createdCommit;
for (let attempt = 0; createdCommit && attempt < 3; attempt += 1) {
const push = runGit(run, input.identity, ['-C', input.root, 'push', 'origin', 'HEAD:main']);
if (push.status === 0) {
pushed = true;
@@ -364,10 +439,21 @@ export function publishBrainPaths(
'brain-git-fetch-concurrent',
);
requireSuccess(
runGit(run, input.identity, ['-C', input.root, 'rebase', 'origin/main']),
runGit(run, input.identity, [
'-C',
input.root,
'-c',
`user.name=${input.identity}`,
'-c',
`user.email=${input.identity}@fleet.mosaicstack.dev`,
'rebase',
'origin/main',
]),
'brain-git-rebase-concurrent',
);
commit = readHead();
verifyCommitPaths(commit);
verifyCommitIdentity(commit);
}
if (!pushed) throw new Error('brain-git-push-failed');
requireSuccess(