blob: a1d07e2e6ce64b5e30f2038009aef8f5b859fd6b [file]
import { execFile, spawn, type ChildProcess } from 'node:child_process';
import { createHash, randomBytes, randomUUID } from 'node:crypto';
import { createReadStream } from 'node:fs';
import {
lstat,
mkdir,
open as openFile,
readFile,
realpath,
rename,
rm,
stat,
} from 'node:fs/promises';
import { dirname, isAbsolute, join, normalize, relative, resolve } from 'node:path';
import { promisify } from 'node:util';
import { withArtifactWriterLock } from './artifact-writer-lock.js';
import { bundledGitEnvironment } from './dugite-native-environment.js';
import { registerManagedBaselineReceiptAuthorityInternal } from './managed-baseline-receipt-authority-internal.js';
const execFileAsync = promisify(execFile);
const GIT_TIMEOUT_MS = 2 * 60 * 1_000;
const GIT_MAX_BUFFER_BYTES = 16 * 1024 * 1024;
const BINDING_SCHEMA_VERSION = 1;
const REPOSITORY_SCHEMA_VERSION = 1;
const EPOCH_ARTIFACT_SCHEMA_VERSION = 1;
const QUARANTINE_INTENT_SCHEMA_VERSION = 1;
const BASELINE_RECEIPT_SCHEMA_VERSION = 1;
const IDENTIFIER_PATTERN = /^(repository|workspace|epoch|instance)_[a-f0-9]{32}$/u;
const SHA256_PATTERN = /^sha256:[a-f0-9]{64}$/u;
const OID_PATTERN = /^(?:[a-f0-9]{40}|[a-f0-9]{64})$/u;
const BINDING_KEYS = [
'schemaVersion',
'protocol',
'repositoryId',
'workspaceId',
'workspaceEpochId',
'workspaceInstanceId',
'sourceRoot',
'sourceGitCommonDir',
'sourceHeadCommitOid',
'sourceTreeOid',
'repositoryPath',
'worktreePath',
'hooksPath',
'baselineCommitOid',
'baselineTreeOid',
'headRef',
'gitRuntimeSha256',
'objectFormat',
'materializationProfileDigest',
'materializationSemantics',
] as const;
const REPOSITORY_KEYS = [
'schemaVersion',
'protocol',
'repositoryId',
'repositoryPath',
'hooksPath',
'gitRuntimeSha256',
'objectFormat',
'repositoryCapabilityDigest',
] as const;
const EPOCH_ARTIFACT_KEYS = [
'schemaVersion',
'protocol',
'repositoryId',
'workspaceId',
'workspaceEpochId',
'sourceRoot',
'sourceGitCommonDir',
'sourceHeadCommitOid',
'sourceTreeOid',
'baselineCommitOid',
'baselineTreeOid',
'baselineRef',
'headRef',
'gitRuntimeSha256',
'objectFormat',
'materializationProfileDigest',
'materializationSemantics',
] as const;
const QUARANTINE_INTENT_KEYS = [
'schemaVersion',
'protocol',
'reason',
'quarantinePath',
'binding',
] as const;
const QUARANTINE_RECORD_KEYS = ['protocol', 'reason', 'binding'] as const;
const BASELINE_RECEIPT_KEYS = [
'schemaVersion',
'protocol',
'binding',
'workspaceVersionId',
'policyVersion',
'policyHash',
'epochOpenedEventId',
'baselineAcceptedEventId',
'treeDeltaDigest',
'changedFileCount',
'deletedFileCount',
] as const;
const MATERIALIZATION_SEMANTICS = 'git_tree_materialized_with_fixed_config_v1';
const MANAGED_BASELINE_POLICY_V1 = {
protocol: 'maka_managed_workspace_baseline_policy_v1',
source: 'source_head_tree',
sourceWorkingTree: 'clean_tracked_and_untracked_except_ignored',
trackedFiles: 'include',
untrackedFiles: 'exclude',
ignoredFiles: 'exclude',
pathEncoding: 'utf8_lossless_roundtrip_required',
caseCollisions: 'reject_nfc_casefold_v1',
symlinks: 'reject',
submodules: 'reject',
attributes: 'reject',
specialModes: 'reject',
materialization: MATERIALIZATION_SEMANTICS,
} as const;
const MANAGED_BASELINE_POLICY_HASH_V1 = hashCanonicalJson(MANAGED_BASELINE_POLICY_V1);
const BASELINE_MESSAGE = 'maka managed workspace baseline v1\n';
const BASELINE_DATE = '2000-01-01T00:00:00Z';
export type GitWorkspaceServiceErrorCode =
| 'git_runtime_unavailable'
| 'git_runtime_integrity_mismatch'
| 'git_workspace_operation_failed'
| 'repository_ineligible'
| 'source_changed_during_baseline_import'
| 'managed_workspace_identity_conflict'
| 'managed_workspace_unavailable'
| 'managed_workspace_drifted';
export class GitWorkspaceServiceError extends Error {
constructor(
readonly code: GitWorkspaceServiceErrorCode,
message: string,
options?: ErrorOptions,
) {
super(message, options);
this.name = 'GitWorkspaceServiceError';
}
}
interface GitRuntimeExecutableIdentity {
readonly executablePath: string;
readonly expectedSha256: `sha256:${string}`;
}
export type VerifiedGitRuntimeInput = GitRuntimeExecutableIdentity &
(
| {
readonly distribution?: undefined;
readonly runtimeIdentitySha256?: undefined;
}
| {
readonly distribution: {
readonly kind: 'dugite_native_v1';
readonly rootPath: string;
};
/** Stable identity of the complete declared distribution. */
readonly runtimeIdentitySha256: `sha256:${string}`;
}
);
export interface CreateGitWorkspaceServiceInput {
readonly storageRoot: string;
readonly gitRuntime: VerifiedGitRuntimeInput;
readonly failpoint?: (point: GitWorkspaceServiceFailpoint) => void | Promise<void>;
}
export type GitWorkspaceServiceFailpoint =
| 'after_repository_record'
| 'after_baseline_ref_created'
| 'after_worktree_materialized'
| 'after_worktree_locked'
| 'after_head_ref_updated'
| 'after_quarantine_intent'
| 'after_quarantine_unlock'
| 'after_quarantine_move'
| 'after_quarantine_binding_removed'
| 'after_quarantine_pruned'
| 'after_baseline_receipt';
export interface ManagedWorkspaceIdentity {
/**
* Identifies the Maka-owned Git object universe. It is not the identity of the
* source checkout; sourceRoot, sourceGitCommonDir, HEAD, and tree OIDs carry
* source provenance and must be validated independently.
*/
readonly repositoryId: string;
readonly workspaceId: string;
readonly workspaceEpochId: string;
readonly workspaceInstanceId: string;
}
export interface CreateManagedWorkspaceFromSourceInput extends ManagedWorkspaceIdentity {
readonly sourceRoot: string;
}
export interface ManagedWorkspaceBinding {
readonly schemaVersion: 1;
readonly protocol: 'git_managed_workspace_v1';
readonly repositoryId: string;
readonly workspaceId: string;
readonly workspaceEpochId: string;
readonly workspaceInstanceId: string;
readonly sourceRoot: string;
readonly sourceGitCommonDir: string;
readonly sourceHeadCommitOid: string;
readonly sourceTreeOid: string;
readonly repositoryPath: string;
readonly worktreePath: string;
readonly hooksPath: string;
readonly baselineCommitOid: string;
readonly baselineTreeOid: string;
readonly headRef: string;
readonly gitRuntimeSha256: `sha256:${string}`;
readonly objectFormat: 'sha1' | 'sha256';
readonly materializationProfileDigest: `sha256:${string}`;
readonly materializationSemantics: typeof MATERIALIZATION_SEMANTICS;
}
export type ManagedWorkspaceInspection =
| {
readonly state: 'ready';
readonly commitOid: string;
readonly treeOid: string;
}
| {
readonly state: 'drifted';
readonly commitOid?: string;
readonly treeOid?: string;
readonly status: string;
};
export interface ManagedWorkspaceQuarantine {
readonly quarantinePath: string;
readonly reason: string;
}
export interface ManagedWorkspaceBaselineReceiptV1 {
readonly schemaVersion: 1;
readonly protocol: 'maka_managed_workspace_baseline_receipt_v1';
readonly binding: ManagedWorkspaceBinding;
readonly workspaceVersionId: string;
readonly policyVersion: 1;
readonly policyHash: `sha256:${string}`;
readonly epochOpenedEventId: string;
readonly baselineAcceptedEventId: string;
readonly treeDeltaDigest: `sha256:${string}`;
readonly changedFileCount: number;
readonly deletedFileCount: 0;
}
export interface GitWorkspaceService {
assertAvailable(): Promise<void>;
createManagedWorkspaceFromSource(
input: CreateManagedWorkspaceFromSourceInput,
): Promise<ManagedWorkspaceBinding>;
openManagedWorkspaceFromBinding(
input: ManagedWorkspaceIdentity,
): Promise<ManagedWorkspaceBinding>;
inspectManagedWorkspace(binding: ManagedWorkspaceBinding): Promise<ManagedWorkspaceInspection>;
quarantineManagedWorkspace(
binding: ManagedWorkspaceBinding,
reason: string,
): Promise<ManagedWorkspaceQuarantine>;
}
export function createGitWorkspaceService(
input: CreateGitWorkspaceServiceInput,
): GitWorkspaceService {
return new GitWorkspaceServiceImpl(input);
}
interface SourceRepositoryInspection {
readonly sourceRoot: string;
readonly gitCommonDir: string;
readonly headCommitOid: string;
readonly treeOid: string;
readonly objectFormat: 'sha1' | 'sha256';
}
interface GitTreeEntry {
readonly mode: string;
readonly objectType: string;
readonly oid: string;
readonly path: string;
readonly pathBytesBase64: string;
}
interface BaselineTreeSummary {
readonly treeDeltaDigest: `sha256:${string}`;
readonly changedFileCount: number;
}
interface ManagedRepositoryRecord {
readonly schemaVersion: 1;
readonly protocol: 'maka_managed_git_repository_v1';
readonly repositoryId: string;
readonly repositoryPath: string;
readonly hooksPath: string;
readonly gitRuntimeSha256: `sha256:${string}`;
readonly objectFormat: 'sha1' | 'sha256';
readonly repositoryCapabilityDigest: `sha256:${string}`;
}
interface ManagedWorkspaceEpochArtifact {
readonly schemaVersion: 1;
readonly protocol: 'maka_managed_workspace_epoch_artifact_v1';
readonly repositoryId: string;
readonly workspaceId: string;
readonly workspaceEpochId: string;
readonly sourceRoot: string;
readonly sourceGitCommonDir: string;
readonly sourceHeadCommitOid: string;
readonly sourceTreeOid: string;
readonly baselineCommitOid: string;
readonly baselineTreeOid: string;
readonly baselineRef: string;
readonly headRef: string;
readonly gitRuntimeSha256: `sha256:${string}`;
readonly objectFormat: 'sha1' | 'sha256';
readonly materializationProfileDigest: `sha256:${string}`;
readonly materializationSemantics: typeof MATERIALIZATION_SEMANTICS;
}
interface ManagedWorkspaceQuarantineIntent {
readonly schemaVersion: 1;
readonly protocol: 'maka_managed_workspace_quarantine_intent_v1';
readonly reason: string;
readonly quarantinePath: string;
readonly binding: ManagedWorkspaceBinding;
}
interface ManagedWorkspaceQuarantineRecord {
readonly protocol: 'maka_managed_workspace_quarantine_v1';
readonly reason: string;
readonly binding: ManagedWorkspaceBinding;
}
interface WorkspaceLayout {
readonly managedRoot: string;
readonly repositoryRoot: string;
readonly repositoryPath: string;
readonly repositoryRecordPath: string;
readonly hooksPath: string;
readonly homePath: string;
readonly epochRoot: string;
readonly epochArtifactPath: string;
readonly instanceRoot: string;
readonly bindingPath: string;
readonly baselineReceiptPath: string;
readonly worktreePath: string;
readonly quarantineRoot: string;
readonly quarantineIntentRoot: string;
readonly quarantineIntentPath: string;
}
class GitWorkspaceServiceImpl implements GitWorkspaceService {
private readonly runtime: VerifiedGitRuntime;
constructor(private readonly input: CreateGitWorkspaceServiceInput) {
if (!isAbsolute(input.storageRoot)) {
throw new GitWorkspaceServiceError(
'managed_workspace_identity_conflict',
'Managed workspace storage root must be absolute',
);
}
this.runtime = new VerifiedGitRuntime(input.gitRuntime);
registerManagedBaselineReceiptAuthorityInternal(this, {
issue: (binding) => this.#createOrReuseManagedWorkspaceBaselineReceipt(binding),
require: (request) => this.#requireManagedWorkspaceBaselineReceipt(request),
verify: (receipt) => this.#verifyManagedWorkspaceBaselineReceipt(receipt),
});
}
async assertAvailable(): Promise<void> {
await this.runtime.verify();
await withArtifactWriterLock(this.input.storageRoot, async () => undefined);
}
async createManagedWorkspaceFromSource(
input: CreateManagedWorkspaceFromSourceInput,
): Promise<ManagedWorkspaceBinding> {
assertOpenIdentity(input);
const runtime = await this.runtime.verify();
return withArtifactWriterLock(this.input.storageRoot, async (canonicalStorageRoot) => {
const layout = workspaceLayout(canonicalStorageRoot, input);
await ensureOwnedDirectory(layout.managedRoot, canonicalStorageRoot);
await ensureOwnedDirectory(layout.quarantineRoot, layout.managedRoot);
await ensureOwnedDirectory(layout.homePath, layout.managedRoot);
await assertOwnedManagedWorkspaceLayout(canonicalStorageRoot, layout);
const quarantined = await this.resumePendingQuarantine(input, layout, runtime.digest);
if (quarantined) {
throw new GitWorkspaceServiceError(
'managed_workspace_unavailable',
`Managed workspace instance was quarantined: ${input.workspaceInstanceId}`,
);
}
const existingBinding = await readBinding(layout.bindingPath);
if (existingBinding) {
assertBindingMatches(existingBinding, input, layout, runtime.digest);
return this.adoptStoredBinding(input, existingBinding, layout);
}
const sourceRoot = await canonicalDirectory(input.sourceRoot, 'repository_ineligible');
const source = await this.inspectSourceRepository(sourceRoot);
const repository = await this.openRepository(input, source, layout, runtime.digest);
const epoch = await this.openEpochArtifact(input, source, repository, layout);
await this.clearIncompleteInstance(input, epoch, layout);
await ensureOwnedDirectory(layout.instanceRoot, layout.managedRoot);
await this.runtime.run(
[
'--git-dir',
repository.repositoryPath,
'worktree',
'add',
'--quiet',
'--detach',
layout.worktreePath,
epoch.baselineCommitOid,
],
layout.homePath,
);
await this.input.failpoint?.('after_worktree_materialized');
await this.runtime.run(
[
'--git-dir',
repository.repositoryPath,
'worktree',
'lock',
'--reason',
worktreeLockReason(input),
layout.worktreePath,
],
layout.homePath,
);
await this.input.failpoint?.('after_worktree_locked');
await this.updateRefCas(
repository.repositoryPath,
epoch.headRef,
epoch.baselineCommitOid,
repository.objectFormat,
layout.homePath,
);
await this.input.failpoint?.('after_head_ref_updated');
const binding: ManagedWorkspaceBinding = {
schemaVersion: BINDING_SCHEMA_VERSION,
protocol: 'git_managed_workspace_v1',
repositoryId: input.repositoryId,
workspaceId: input.workspaceId,
workspaceEpochId: input.workspaceEpochId,
workspaceInstanceId: input.workspaceInstanceId,
sourceRoot: epoch.sourceRoot,
sourceGitCommonDir: epoch.sourceGitCommonDir,
sourceHeadCommitOid: epoch.sourceHeadCommitOid,
sourceTreeOid: epoch.sourceTreeOid,
repositoryPath: repository.repositoryPath,
worktreePath: normalize(layout.worktreePath),
hooksPath: repository.hooksPath,
baselineCommitOid: epoch.baselineCommitOid,
baselineTreeOid: epoch.baselineTreeOid,
headRef: epoch.headRef,
gitRuntimeSha256: runtime.digest,
objectFormat: repository.objectFormat,
materializationProfileDigest: epoch.materializationProfileDigest,
materializationSemantics: MATERIALIZATION_SEMANTICS,
};
const inspection = await this.inspectBinding(binding, layout);
if (inspection.state !== 'ready') {
await this.beginQuarantine(binding, layout, 'initial_materialization_drift');
throw new GitWorkspaceServiceError(
'managed_workspace_drifted',
'Git materialization did not produce a clean managed workspace',
);
}
await atomicWriteJson(layout.bindingPath, binding);
return binding;
});
}
async openManagedWorkspaceFromBinding(
input: ManagedWorkspaceIdentity,
): Promise<ManagedWorkspaceBinding> {
assertOpenIdentity(input);
const runtime = await this.runtime.verify();
return withArtifactWriterLock(this.input.storageRoot, async (canonicalStorageRoot) => {
const layout = workspaceLayout(canonicalStorageRoot, input);
await assertOwnedManagedWorkspaceLayout(canonicalStorageRoot, layout);
const quarantined = await this.resumePendingQuarantine(input, layout, runtime.digest);
if (quarantined) {
throw new GitWorkspaceServiceError(
'managed_workspace_unavailable',
`Managed workspace instance was quarantined: ${input.workspaceInstanceId}`,
);
}
const binding = await readBinding(layout.bindingPath);
if (!binding) {
throw new GitWorkspaceServiceError(
'managed_workspace_unavailable',
`Managed workspace binding is unavailable: ${input.workspaceInstanceId}`,
);
}
assertBindingIdentity(binding, input, layout, runtime.digest);
return this.adoptStoredBinding(input, binding, layout);
});
}
private async adoptStoredBinding(
input: ManagedWorkspaceIdentity,
binding: ManagedWorkspaceBinding,
layout: WorkspaceLayout,
): Promise<ManagedWorkspaceBinding> {
const repository = await this.requireRepository(input, layout);
assertBindingRepository(binding, repository);
const epoch = await this.requireEpochArtifact(input, repository, layout);
assertBindingEpoch(binding, epoch);
const inspection = await this.inspectBinding(binding, layout);
if (inspection.state !== 'ready') {
throw new GitWorkspaceServiceError(
'managed_workspace_drifted',
`Managed workspace contains unaccepted changes: ${binding.worktreePath}`,
);
}
return binding;
}
async inspectManagedWorkspace(
binding: ManagedWorkspaceBinding,
): Promise<ManagedWorkspaceInspection> {
const runtime = await this.runtime.verify();
assertBindingShape(binding);
assertOpenIdentity(binding);
return withArtifactWriterLock(this.input.storageRoot, async (canonicalStorageRoot) => {
const layout = workspaceLayout(canonicalStorageRoot, binding);
await assertOwnedManagedWorkspaceLayout(canonicalStorageRoot, layout);
assertBindingPaths(binding, layout);
const quarantined = await this.resumePendingQuarantine(binding, layout, runtime.digest);
if (quarantined) {
throw new GitWorkspaceServiceError(
'managed_workspace_unavailable',
`Managed workspace instance was quarantined: ${binding.workspaceInstanceId}`,
);
}
const stored = await readBinding(layout.bindingPath);
if (!stored || !sameBinding(stored, binding)) {
throw new GitWorkspaceServiceError(
'managed_workspace_unavailable',
`Managed workspace binding is unavailable: ${binding.workspaceInstanceId}`,
);
}
const repository = await readRepositoryRecord(layout.repositoryRecordPath);
if (!repository) {
throw new GitWorkspaceServiceError(
'managed_workspace_unavailable',
`Managed Git repository record is unavailable: ${binding.repositoryId}`,
);
}
assertBindingRepository(binding, repository);
await this.assertRepositoryArtifact(repository);
const epoch = await this.requireEpochArtifact(binding, repository, layout);
assertBindingEpoch(binding, epoch);
return this.inspectBinding(binding, layout);
});
}
async #requireManagedWorkspaceBaselineReceipt(
input: CreateManagedWorkspaceFromSourceInput,
): Promise<ManagedWorkspaceBaselineReceiptV1> {
const runtime = await this.runtime.verify();
assertOpenIdentity(input);
return withArtifactWriterLock(this.input.storageRoot, async (canonicalStorageRoot) => {
const layout = workspaceLayout(canonicalStorageRoot, input);
await assertOwnedManagedWorkspaceLayout(canonicalStorageRoot, layout);
const receipt = await readBaselineReceipt(layout.baselineReceiptPath);
if (!receipt) {
throw new GitWorkspaceServiceError(
'managed_workspace_unavailable',
'Canonical workspace baseline receipt is unavailable',
);
}
assertBindingMatches(receipt.binding, input, layout, runtime.digest);
const summary = await this.requireVerifiedBaselineContext(
receipt.binding,
layout,
runtime.digest,
);
assertBaselineReceiptMatches(receipt, receipt.binding, summary);
return receipt;
});
}
async #createOrReuseManagedWorkspaceBaselineReceipt(
binding: ManagedWorkspaceBinding,
): Promise<ManagedWorkspaceBaselineReceiptV1> {
const runtime = await this.runtime.verify();
assertBindingShape(binding);
assertOpenIdentity(binding);
return withArtifactWriterLock(this.input.storageRoot, async (canonicalStorageRoot) => {
const layout = workspaceLayout(canonicalStorageRoot, binding);
const summary = await this.requireVerifiedBaselineContext(binding, layout, runtime.digest);
const existing = await readBaselineReceipt(layout.baselineReceiptPath);
if (existing) {
assertBaselineReceiptMatches(existing, binding, summary);
return existing;
}
const identities = deriveBaselineReceiptIdentities(binding);
const receipt: ManagedWorkspaceBaselineReceiptV1 = {
schemaVersion: BASELINE_RECEIPT_SCHEMA_VERSION,
protocol: 'maka_managed_workspace_baseline_receipt_v1',
binding,
workspaceVersionId: identities.workspaceVersionId,
policyVersion: 1,
policyHash: MANAGED_BASELINE_POLICY_HASH_V1,
epochOpenedEventId: identities.epochOpenedEventId,
baselineAcceptedEventId: identities.baselineAcceptedEventId,
treeDeltaDigest: summary.treeDeltaDigest,
changedFileCount: summary.changedFileCount,
deletedFileCount: 0,
};
await atomicWriteJson(layout.baselineReceiptPath, receipt);
await this.input.failpoint?.('after_baseline_receipt');
const durable = await readBaselineReceipt(layout.baselineReceiptPath);
if (!durable) {
throw new GitWorkspaceServiceError(
'managed_workspace_unavailable',
'Managed workspace baseline receipt was not durable',
);
}
assertBaselineReceiptMatches(durable, binding, summary);
return durable;
});
}
async #verifyManagedWorkspaceBaselineReceipt(
receipt: ManagedWorkspaceBaselineReceiptV1,
): Promise<void> {
const runtime = await this.runtime.verify();
assertBaselineReceiptShape(receipt);
assertOpenIdentity(receipt.binding);
await withArtifactWriterLock(this.input.storageRoot, async (canonicalStorageRoot) => {
const layout = workspaceLayout(canonicalStorageRoot, receipt.binding);
const summary = await this.requireVerifiedBaselineContext(
receipt.binding,
layout,
runtime.digest,
);
const durable = await readBaselineReceipt(layout.baselineReceiptPath);
if (!durable || !sameBaselineReceipt(durable, receipt)) {
throw new GitWorkspaceServiceError(
'managed_workspace_identity_conflict',
'Managed workspace baseline receipt does not match its durable artifact',
);
}
assertBaselineReceiptMatches(durable, receipt.binding, summary);
});
}
async quarantineManagedWorkspace(
binding: ManagedWorkspaceBinding,
reason: string,
): Promise<ManagedWorkspaceQuarantine> {
const runtime = await this.runtime.verify();
assertBindingShape(binding);
assertOpenIdentity(binding);
if (!reason.trim()) {
throw new GitWorkspaceServiceError(
'managed_workspace_identity_conflict',
'Managed workspace quarantine reason is required',
);
}
return withArtifactWriterLock(this.input.storageRoot, async (canonicalStorageRoot) => {
const layout = workspaceLayout(canonicalStorageRoot, binding);
await assertOwnedManagedWorkspaceLayout(canonicalStorageRoot, layout);
assertBindingPaths(binding, layout);
const pending = await readQuarantineIntent(layout.quarantineIntentPath);
if (pending) {
assertQuarantineIntentMatches(pending, binding, reason, layout);
await this.assertQuarantineBindingAuthority(binding, layout, runtime.digest);
return this.resumeQuarantineIntent(pending, layout);
}
const stored = await readBinding(layout.bindingPath);
if (!stored || !sameBinding(stored, binding)) {
throw new GitWorkspaceServiceError(
'managed_workspace_unavailable',
`Managed workspace binding is unavailable: ${binding.workspaceInstanceId}`,
);
}
const repository = await readRepositoryRecord(layout.repositoryRecordPath);
if (!repository) {
throw new GitWorkspaceServiceError(
'managed_workspace_unavailable',
`Managed Git repository record is unavailable: ${binding.repositoryId}`,
);
}
assertBindingRepository(binding, repository);
await this.assertRepositoryArtifact(repository);
const epoch = await this.requireEpochArtifact(binding, repository, layout);
assertBindingEpoch(binding, epoch);
return this.beginQuarantine(binding, layout, reason);
});
}
private async requireVerifiedBaselineContext(
binding: ManagedWorkspaceBinding,
layout: WorkspaceLayout,
runtimeDigest: `sha256:${string}`,
): Promise<BaselineTreeSummary> {
assertBindingPaths(binding, layout);
const quarantined = await this.resumePendingQuarantine(binding, layout, runtimeDigest);
if (quarantined) {
throw new GitWorkspaceServiceError(
'managed_workspace_unavailable',
`Managed workspace instance was quarantined: ${binding.workspaceInstanceId}`,
);
}
const stored = await readBinding(layout.bindingPath);
if (!stored || !sameBinding(stored, binding)) {
throw new GitWorkspaceServiceError(
'managed_workspace_unavailable',
`Managed workspace binding is unavailable: ${binding.workspaceInstanceId}`,
);
}
const repository = await this.requireRepository(binding, layout);
assertBindingRepository(binding, repository);
const epoch = await this.requireEpochArtifact(binding, repository, layout);
assertBindingEpoch(binding, epoch);
const inspection = await this.inspectBinding(binding, layout);
if (inspection.state !== 'ready') {
throw new GitWorkspaceServiceError(
'managed_workspace_drifted',
`Managed workspace contains unaccepted changes: ${binding.worktreePath}`,
);
}
return this.readBaselineTreeSummary(binding, layout);
}
private async readBaselineTreeSummary(
binding: ManagedWorkspaceBinding,
layout: WorkspaceLayout,
): Promise<BaselineTreeSummary> {
const entries = parseTreeEntries(
await this.runtime.runBuffer(
['--git-dir', binding.repositoryPath, 'ls-tree', '-r', '-z', binding.baselineCommitOid],
layout.homePath,
),
);
assertSupportedTree(entries);
return baselineTreeSummary(entries);
}
private async inspectSourceRepository(sourceRoot: string): Promise<SourceRepositoryInspection> {
try {
const topLevelRaw = await this.runtime.run([
'-C',
sourceRoot,
'rev-parse',
'--show-toplevel',
]);
const topLevel = await realpath(topLevelRaw.trim());
if (!samePath(topLevel, sourceRoot)) {
throw new GitWorkspaceServiceError(
'repository_ineligible',
'Managed workspace source must be the Git worktree root',
);
}
const status = await this.runtime.run([
'-C',
sourceRoot,
'status',
'--porcelain=v1',
'--untracked-files=all',
'--ignore-submodules=none',
]);
if (status.trim()) {
throw new GitWorkspaceServiceError(
'repository_ineligible',
'Managed workspace source must have no tracked or untracked changes',
);
}
const sparse = await this.runtime.runOptional(
['-C', sourceRoot, 'config', '--bool', '--get', 'core.sparseCheckout'],
1,
);
if (sparse?.trim() === 'true') {
throw new GitWorkspaceServiceError(
'repository_ineligible',
'Sparse Git worktrees are not supported by managed workspace v1',
);
}
const entries = parseTreeEntries(
await this.runtime.runBuffer(['-C', sourceRoot, 'ls-tree', '-r', '-z', 'HEAD']),
);
assertSupportedTree(entries);
const gitCommonDirRaw = (
await this.runtime.run(['-C', sourceRoot, 'rev-parse', '--git-common-dir'])
).trim();
const gitCommonDir = await realpath(resolveGitPath(sourceRoot, gitCommonDirRaw));
await this.assertSourceConfigurationFences(sourceRoot, gitCommonDir);
const [headCommitOid, treeOid, objectFormat] = await Promise.all([
this.runtime.run(['-C', sourceRoot, 'rev-parse', '--verify', 'HEAD']),
this.runtime.run(['-C', sourceRoot, 'rev-parse', '--verify', 'HEAD^{tree}']),
this.runtime.run(['-C', sourceRoot, 'rev-parse', '--show-object-format']),
]);
const normalizedObjectFormat = objectFormat.trim();
if (normalizedObjectFormat !== 'sha1' && normalizedObjectFormat !== 'sha256') {
throw new GitWorkspaceServiceError(
'repository_ineligible',
`Unsupported Git object format: ${normalizedObjectFormat}`,
);
}
return {
sourceRoot: normalize(sourceRoot),
gitCommonDir: normalize(gitCommonDir),
headCommitOid: headCommitOid.trim(),
treeOid: treeOid.trim(),
objectFormat: normalizedObjectFormat,
};
} catch (error) {
if (error instanceof GitWorkspaceServiceError) throw error;
throw new GitWorkspaceServiceError(
'repository_ineligible',
`Unable to inspect managed workspace source: ${sourceRoot}`,
{ cause: error },
);
}
}
private async openRepository(
input: CreateManagedWorkspaceFromSourceInput,
source: SourceRepositoryInspection,
layout: WorkspaceLayout,
runtimeDigest: `sha256:${string}`,
): Promise<ManagedRepositoryRecord> {
const existing = await readRepositoryRecord(layout.repositoryRecordPath);
if (existing) {
assertRepositoryMatches(existing, input, source.objectFormat, layout, runtimeDigest);
await this.assertRepositoryArtifact(existing);
return existing;
}
if (await pathExists(layout.repositoryRoot)) {
await moveToQuarantine(
layout.repositoryRoot,
layout.quarantineRoot,
`${input.repositoryId}-incomplete-repository`,
);
}
await ensureOwnedDirectory(layout.repositoryRoot, layout.managedRoot);
await ensureOwnedDirectory(layout.hooksPath, layout.repositoryRoot);
const stagingRepository = join(
layout.repositoryRoot,
`r.tmp-${randomBytes(6).toString('hex')}`,
);
try {
const templatePath = join(layout.repositoryRoot, 'empty-template');
await mkdir(templatePath, { recursive: true });
await this.runtime.run(
[
'init',
'--quiet',
'--bare',
`--object-format=${source.objectFormat}`,
`--template=${templatePath}`,
stagingRepository,
],
layout.homePath,
);
await this.configureManagedRepository(stagingRepository, layout.hooksPath);
await rename(stagingRepository, layout.repositoryPath);
const record: ManagedRepositoryRecord = {
schemaVersion: REPOSITORY_SCHEMA_VERSION,
protocol: 'maka_managed_git_repository_v1',
repositoryId: input.repositoryId,
repositoryPath: normalize(layout.repositoryPath),
hooksPath: normalize(layout.hooksPath),
gitRuntimeSha256: runtimeDigest,
objectFormat: source.objectFormat,
repositoryCapabilityDigest: repositoryCapabilityDigest(runtimeDigest, source.objectFormat),
};
await this.assertRepositoryArtifact(record);
await atomicWriteJson(layout.repositoryRecordPath, record);
await this.input.failpoint?.('after_repository_record');
return record;
} catch (error) {
await rm(stagingRepository, { recursive: true, force: true });
if (error instanceof GitWorkspaceServiceError) throw error;
throw new GitWorkspaceServiceError(
'git_workspace_operation_failed',
'Unable to create the Maka-owned Git repository',
{ cause: error },
);
}
}
private async assertSourceConfigurationFences(
sourceRoot: string,
gitCommonDir: string,
): Promise<void> {
if (await pathExists(join(gitCommonDir, 'objects', 'info', 'alternates'))) {
throw new GitWorkspaceServiceError(
'repository_ineligible',
'Managed workspace source must not use Git object alternates',
);
}
const unsafeConfig = await this.runtime.runOptional(
['-C', sourceRoot, 'config', '--no-includes', '--local', '--name-only', '--get-regexp', '.*'],
1,
);
const worktreeConfigEnabled = (
await this.runtime.runOptional(
[
'-C',
sourceRoot,
'config',
'--no-includes',
'--local',
'--bool',
'--get',
'extensions.worktreeConfig',
],
1,
)
)?.trim();
const unsafeWorktreeConfig =
worktreeConfigEnabled === 'true'
? await this.runtime.runOptional(
[
'-C',
sourceRoot,
'config',
'--no-includes',
'--worktree',
'--name-only',
'--get-regexp',
'.*',
],
1,
)
: undefined;
const replaceRefs = await this.runtime.run(
['-C', sourceRoot, 'for-each-ref', '--format=%(refname)', 'refs/replace/'],
undefined,
undefined,
[1],
);
if (
hasUnsafeSourceConfig(unsafeConfig) ||
hasUnsafeSourceConfig(unsafeWorktreeConfig) ||
replaceRefs.trim()
) {
throw new GitWorkspaceServiceError(
'repository_ineligible',
'Managed workspace source contains unsupported Git indirection or runtime configuration',
);
}
}
private async openEpochArtifact(
input: CreateManagedWorkspaceFromSourceInput,
source: SourceRepositoryInspection,
repository: ManagedRepositoryRecord,
layout: WorkspaceLayout,
): Promise<ManagedWorkspaceEpochArtifact> {
const existing = await readEpochArtifact(layout.epochArtifactPath);
if (existing) {
assertEpochArtifactMatches(existing, input, source, repository);
await this.assertEpochArtifact(existing, repository, layout);
return existing;
}
const baselineRef = managedBaselineRef(input.workspaceEpochId);
await this.clearIncompleteBaselineRef(repository.repositoryPath, baselineRef, layout.homePath);
await ensureOwnedDirectory(layout.epochRoot, layout.managedRoot);
await this.runtime.importTree(
source.sourceRoot,
source.treeOid,
repository.repositoryPath,
layout.homePath,
);
const importedTree = (
await this.runtime.run(
['--git-dir', repository.repositoryPath, 'rev-parse', `${source.treeOid}^{tree}`],
layout.homePath,
)
).trim();
if (importedTree !== source.treeOid) {
throw new GitWorkspaceServiceError(
'git_workspace_operation_failed',
'Imported baseline tree does not match the source HEAD tree',
);
}
const baselineCommitOid = (
await this.runtime.run(
[
'--git-dir',
repository.repositoryPath,
'commit-tree',
importedTree,
'-m',
BASELINE_MESSAGE.trim(),
],
layout.homePath,
baselineCommitEnvironment(),
)
).trim();
const observedBeforeRef = await this.inspectSourceRepository(source.sourceRoot);
assertSameSourceObservation(source, observedBeforeRef);
await this.updateRefCas(
repository.repositoryPath,
baselineRef,
baselineCommitOid,
repository.objectFormat,
layout.homePath,
);
await this.input.failpoint?.('after_baseline_ref_created');
try {
const observedAgain = await this.inspectSourceRepository(source.sourceRoot);
assertSameSourceObservation(source, observedAgain);
} catch (error) {
await this.deleteRefCas(
repository.repositoryPath,
baselineRef,
baselineCommitOid,
layout.homePath,
);
throw error;
}
const artifact: ManagedWorkspaceEpochArtifact = {
schemaVersion: EPOCH_ARTIFACT_SCHEMA_VERSION,
protocol: 'maka_managed_workspace_epoch_artifact_v1',
repositoryId: input.repositoryId,
workspaceId: input.workspaceId,
workspaceEpochId: input.workspaceEpochId,
sourceRoot: source.sourceRoot,
sourceGitCommonDir: source.gitCommonDir,
sourceHeadCommitOid: source.headCommitOid,
sourceTreeOid: source.treeOid,
baselineCommitOid,
baselineTreeOid: importedTree,
baselineRef,
headRef: managedHeadRef(input.workspaceId, input.workspaceEpochId),
gitRuntimeSha256: repository.gitRuntimeSha256,
objectFormat: repository.objectFormat,
materializationProfileDigest: materializationProfileDigest(
repository.gitRuntimeSha256,
repository.objectFormat,
),
materializationSemantics: MATERIALIZATION_SEMANTICS,
};
await this.assertEpochArtifact(artifact, repository, layout);
await atomicWriteJson(layout.epochArtifactPath, artifact);
return artifact;
}
private async requireRepository(
input: ManagedWorkspaceIdentity,
layout: WorkspaceLayout,
): Promise<ManagedRepositoryRecord> {
const repository = await readRepositoryRecord(layout.repositoryRecordPath);
if (!repository) {
throw new GitWorkspaceServiceError(
'managed_workspace_unavailable',
`Managed Git repository record is unavailable: ${input.repositoryId}`,
);
}
if (
repository.repositoryId !== input.repositoryId ||
!samePath(repository.repositoryPath, layout.repositoryPath) ||
!samePath(repository.hooksPath, layout.hooksPath)
) {
throw new GitWorkspaceServiceError(
'managed_workspace_identity_conflict',
'Managed Git repository does not match the requested repository identity',
);
}
await this.assertRepositoryArtifact(repository);
return repository;
}
private async requireEpochArtifact(
input: Pick<ManagedWorkspaceIdentity, 'repositoryId' | 'workspaceId' | 'workspaceEpochId'>,
repository: ManagedRepositoryRecord,
layout: WorkspaceLayout,
): Promise<ManagedWorkspaceEpochArtifact> {
const epoch = await readEpochArtifact(layout.epochArtifactPath);
if (!epoch) {
throw new GitWorkspaceServiceError(
'managed_workspace_unavailable',
`Managed workspace epoch artifact is unavailable: ${input.workspaceEpochId}`,
);
}
if (
epoch.repositoryId !== input.repositoryId ||
epoch.workspaceId !== input.workspaceId ||
epoch.workspaceEpochId !== input.workspaceEpochId
) {
throw new GitWorkspaceServiceError(
'managed_workspace_identity_conflict',
'Managed workspace epoch artifact does not match the requested identity',
);
}
await this.assertEpochArtifact(epoch, repository, layout);
return epoch;
}
private async assertEpochArtifact(
epoch: ManagedWorkspaceEpochArtifact,
repository: ManagedRepositoryRecord,
layout: WorkspaceLayout,
): Promise<void> {
if (
epoch.repositoryId !== repository.repositoryId ||
epoch.gitRuntimeSha256 !== repository.gitRuntimeSha256 ||
epoch.objectFormat !== repository.objectFormat ||
epoch.materializationProfileDigest !==
materializationProfileDigest(repository.gitRuntimeSha256, repository.objectFormat) ||
epoch.baselineRef !== managedBaselineRef(epoch.workspaceEpochId) ||
epoch.headRef !== managedHeadRef(epoch.workspaceId, epoch.workspaceEpochId)
) {
throw new GitWorkspaceServiceError(
'managed_workspace_identity_conflict',
'Managed workspace epoch artifact does not match its repository capability',
);
}
const [commit, tree, baselineRef] = await Promise.all([
this.runtime.run(
['--git-dir', repository.repositoryPath, 'rev-parse', '--verify', epoch.baselineCommitOid],
layout.homePath,
),
this.runtime.run(
[
'--git-dir',
repository.repositoryPath,
'rev-parse',
'--verify',
`${epoch.baselineCommitOid}^{tree}`,
],
layout.homePath,
),
this.runtime.run(
['--git-dir', repository.repositoryPath, 'rev-parse', '--verify', epoch.baselineRef],
layout.homePath,
),
]);
if (
commit.trim() !== epoch.baselineCommitOid ||
tree.trim() !== epoch.baselineTreeOid ||
baselineRef.trim() !== epoch.baselineCommitOid
) {
throw new GitWorkspaceServiceError(
'managed_workspace_identity_conflict',
'Managed workspace epoch baseline identity changed',
);
}
}
private async updateRefCas(
repositoryPath: string,
ref: string,
desiredOid: string,
objectFormat: string,
homePath: string,
): Promise<void> {
const current = (
await this.runtime.runOptional(
['--git-dir', repositoryPath, 'rev-parse', '--verify', '--quiet', ref],
1,
)
)?.trim();
if (current === desiredOid) return;
if (current) {
throw new GitWorkspaceServiceError(
'managed_workspace_identity_conflict',
`Managed Git ref already points at a different object: ${ref}`,
);
}
const expected = '0'.repeat(objectFormat === 'sha256' ? 64 : 40);
try {
await this.runtime.run(
['--git-dir', repositoryPath, 'update-ref', ref, desiredOid, expected],
homePath,
);
} catch (error) {
throw new GitWorkspaceServiceError(
'managed_workspace_identity_conflict',
`Managed Git ref changed concurrently: ${ref}`,
{ cause: error },
);
}
}
private async deleteRefCas(
repositoryPath: string,
ref: string,
expectedOid: string,
homePath: string,
): Promise<void> {
try {
await this.runtime.run(
['--git-dir', repositoryPath, 'update-ref', '-d', ref, expectedOid],
homePath,
);
} catch (error) {
throw new GitWorkspaceServiceError(
'managed_workspace_identity_conflict',
`Managed Git ref changed before cleanup: ${ref}`,
{ cause: error },
);
}
}
private async clearIncompleteBaselineRef(
repositoryPath: string,
baselineRef: string,
homePath: string,
): Promise<void> {
const current = (
await this.runtime.runOptional(
['--git-dir', repositoryPath, 'rev-parse', '--verify', '--quiet', baselineRef],
1,
)
)?.trim();
if (!current) return;
const commitBody = await this.runtime.run(
['--git-dir', repositoryPath, 'cat-file', 'commit', current],
homePath,
);
if (!isOwnedBaselineCommit(commitBody)) {
throw new GitWorkspaceServiceError(
'managed_workspace_identity_conflict',
`Incomplete managed baseline ref is not owned by this protocol: ${baselineRef}`,
);
}
await this.deleteRefCas(repositoryPath, baselineRef, current, homePath);
}
private async configureManagedRepository(
repositoryPath: string,
hooksPath: string,
): Promise<void> {
const entries: readonly [string, string][] = [
['core.autocrlf', 'false'],
['core.safecrlf', 'true'],
['core.hooksPath', normalize(hooksPath)],
['core.sshCommand', ''],
['credential.helper', ''],
['credential.interactive', 'never'],
['protocol.allow', 'never'],
['gc.auto', '0'],
];
for (const [key, value] of entries) {
await this.runtime.run(
['--git-dir', repositoryPath, 'config', '--local', key, value],
dirname(repositoryPath),
);
}
}
private async assertRepositoryArtifact(record: ManagedRepositoryRecord): Promise<void> {
if (!(await isNonSymlinkDirectory(record.repositoryPath))) {
throw new GitWorkspaceServiceError(
'managed_workspace_unavailable',
`Managed Git repository is unavailable: ${record.repositoryPath}`,
);
}
if (!(await isNonSymlinkDirectory(record.hooksPath))) {
throw new GitWorkspaceServiceError(
'managed_workspace_identity_conflict',
`Managed Git hooks fence is unavailable: ${record.hooksPath}`,
);
}
const objectFormat = (
await this.runtime.run([
'--git-dir',
record.repositoryPath,
'rev-parse',
'--show-object-format',
])
).trim();
if (
objectFormat !== record.objectFormat ||
record.repositoryCapabilityDigest !==
repositoryCapabilityDigest(record.gitRuntimeSha256, record.objectFormat)
) {
throw new GitWorkspaceServiceError(
'managed_workspace_identity_conflict',
'Managed Git repository capability identity changed',
);
}
if (await pathExists(join(record.repositoryPath, 'objects', 'info', 'alternates'))) {
throw new GitWorkspaceServiceError(
'managed_workspace_identity_conflict',
'Managed Git repository must not use object alternates',
);
}
}
private async inspectBinding(
binding: ManagedWorkspaceBinding,
layout: WorkspaceLayout,
): Promise<ManagedWorkspaceInspection> {
assertBindingPaths(binding, layout);
if (
!(await isNonSymlinkDirectory(binding.worktreePath)) ||
!(await isNonSymlinkDirectory(binding.repositoryPath))
) {
throw new GitWorkspaceServiceError(
'managed_workspace_unavailable',
`Managed workspace is unavailable: ${binding.worktreePath}`,
);
}
try {
const commonDirRaw = (
await this.runtime.run(
['-C', binding.worktreePath, 'rev-parse', '--git-common-dir'],
layout.homePath,
)
).trim();
const commonDir = await realpath(resolveGitPath(binding.worktreePath, commonDirRaw));
if (!samePath(commonDir, binding.repositoryPath)) {
throw new GitWorkspaceServiceError(
'managed_workspace_identity_conflict',
'Managed worktree is attached to a different Git repository',
);
}
const [commitRaw, treeRaw, statusRaw, headRefRaw, worktreeListRaw] = await Promise.all([
this.runtime.run(
['-C', binding.worktreePath, 'rev-parse', '--verify', 'HEAD'],
layout.homePath,
),
this.runtime.run(
['-C', binding.worktreePath, 'rev-parse', '--verify', 'HEAD^{tree}'],
layout.homePath,
),
this.runtime.run(
[
'-C',
binding.worktreePath,
'status',
'--porcelain=v1',
'--untracked-files=all',
'--ignored=matching',
],
layout.homePath,
),
this.runtime.run(
['--git-dir', binding.repositoryPath, 'rev-parse', '--verify', binding.headRef],
layout.homePath,
),
this.runtime.run(
['--git-dir', binding.repositoryPath, 'worktree', 'list', '--porcelain'],
layout.homePath,
),
]);
const commitOid = commitRaw.trim();
const treeOid = treeRaw.trim();
const status = statusRaw.trim();
const headRef = headRefRaw.trim();
assertWorktreeRegistrationLocked(
worktreeListRaw,
binding.worktreePath,
worktreeLockReason(binding),
);
if (
commitOid !== binding.baselineCommitOid ||
treeOid !== binding.baselineTreeOid ||
headRef !== binding.baselineCommitOid ||
status
) {
return { state: 'drifted', commitOid, treeOid, status };
}
return { state: 'ready', commitOid, treeOid };
} catch (error) {
if (error instanceof GitWorkspaceServiceError) throw error;
throw new GitWorkspaceServiceError(
'managed_workspace_unavailable',
`Unable to inspect managed workspace: ${binding.worktreePath}`,
{ cause: error },
);
}
}
private async clearIncompleteInstance(
input: ManagedWorkspaceIdentity,
epoch: ManagedWorkspaceEpochArtifact,
layout: WorkspaceLayout,
): Promise<void> {
const registration = findWorktreeRegistration(
await this.runtime.run(
['--git-dir', layout.repositoryPath, 'worktree', 'list', '--porcelain'],
layout.homePath,
),
layout.worktreePath,
);
if (registration) {
if (
registration.headOid !== epoch.baselineCommitOid ||
(registration.lockReason !== undefined &&
registration.lockReason !== worktreeLockReason(input))
) {
throw new GitWorkspaceServiceError(
'managed_workspace_identity_conflict',
'Incomplete managed worktree registration does not match its durable identity',
);
}
// Git cannot unlock a registration after its worktree path has been moved
// (notably on Windows), so unlock only after exact identity validation and
// immediately before quarantining the path under the global writer lock.
if (registration.lockReason !== undefined) {
await this.runtime.run(
['--git-dir', layout.repositoryPath, 'worktree', 'unlock', layout.worktreePath],
layout.homePath,
);
}
}
if (await pathExists(layout.instanceRoot)) {
await moveToQuarantine(
layout.instanceRoot,
layout.quarantineRoot,
`incomplete-${randomUUID()}`,
);
}
await this.runtime.run(
['--git-dir', layout.repositoryPath, 'worktree', 'prune', '--expire=now'],
layout.homePath,
);
const remaining = findWorktreeRegistration(
await this.runtime.run(
['--git-dir', layout.repositoryPath, 'worktree', 'list', '--porcelain'],
layout.homePath,
),
layout.worktreePath,
);
if (remaining) {
throw new GitWorkspaceServiceError(
'managed_workspace_identity_conflict',
'Incomplete managed worktree registration could not be removed safely',
);
}
}
private async resumePendingQuarantine(
input: ManagedWorkspaceIdentity,
layout: WorkspaceLayout,
runtimeDigest: `sha256:${string}`,
): Promise<ManagedWorkspaceQuarantine | undefined> {
await assertOwnedManagedWorkspaceLayout(this.input.storageRoot, layout);
const intent = await readQuarantineIntent(layout.quarantineIntentPath);
if (!intent) return undefined;
assertQuarantineIntentMatches(intent, intent.binding, intent.reason, layout);
assertBindingIdentity(intent.binding, input, layout, runtimeDigest);
await this.assertQuarantineBindingAuthority(intent.binding, layout, runtimeDigest);
return this.resumeQuarantineIntent(intent, layout);
}
private async assertQuarantineBindingAuthority(
binding: ManagedWorkspaceBinding,
layout: WorkspaceLayout,
runtimeDigest: `sha256:${string}`,
): Promise<void> {
assertBindingIdentity(binding, binding, layout, runtimeDigest);
const repository = await this.requireRepository(binding, layout);
assertBindingRepository(binding, repository);
const epoch = await this.requireEpochArtifact(binding, repository, layout);
assertBindingEpoch(binding, epoch);
}
private async beginQuarantine(
binding: ManagedWorkspaceBinding,
layout: WorkspaceLayout,
reason: string,
): Promise<ManagedWorkspaceQuarantine> {
await ensureOwnedDirectory(layout.quarantineIntentRoot, layout.managedRoot);
const existing = await readQuarantineIntent(layout.quarantineIntentPath);
if (existing) {
assertQuarantineIntentMatches(existing, binding, reason, layout);
return this.resumeQuarantineIntent(existing, layout);
}
const intent: ManagedWorkspaceQuarantineIntent = {
schemaVersion: QUARANTINE_INTENT_SCHEMA_VERSION,
protocol: 'maka_managed_workspace_quarantine_intent_v1',
reason,
quarantinePath: join(
layout.quarantineRoot,
`${compactIdentity(binding.workspaceInstanceId)}-${sanitizeReason(reason)}-${randomUUID()}`,
),
binding,
};
assertQuarantineIntentMatches(intent, binding, reason, layout);
await atomicWriteJson(layout.quarantineIntentPath, intent);
await this.input.failpoint?.('after_quarantine_intent');
return this.resumeQuarantineIntent(intent, layout);
}
private async resumeQuarantineIntent(
intent: ManagedWorkspaceQuarantineIntent,
layout: WorkspaceLayout,
): Promise<ManagedWorkspaceQuarantine> {
await assertOwnedManagedWorkspaceLayout(this.input.storageRoot, layout);
const { binding, reason, quarantinePath } = intent;
assertQuarantineIntentMatches(intent, binding, reason, layout);
const registration = findWorktreeRegistration(
await this.runtime.run(
['--git-dir', binding.repositoryPath, 'worktree', 'list', '--porcelain'],
layout.homePath,
),
binding.worktreePath,
);
if (
registration &&
(registration.headOid !== binding.baselineCommitOid ||
(registration.lockReason !== undefined &&
registration.lockReason !== worktreeLockReason(binding)))
) {
throw new GitWorkspaceServiceError(
'managed_workspace_identity_conflict',
'Quarantine worktree registration does not match its durable intent',
);
}
if (registration?.lockReason !== undefined) {
await this.runtime.run(
['--git-dir', binding.repositoryPath, 'worktree', 'unlock', binding.worktreePath],
layout.homePath,
);
}
await this.input.failpoint?.('after_quarantine_unlock');
const sourceExists = await pathEntryExists(binding.worktreePath);
const targetExists = await pathEntryExists(quarantinePath);
if (sourceExists && targetExists) {
throw new GitWorkspaceServiceError(
'managed_workspace_identity_conflict',
'Quarantine source and target both exist',
);
}
if (sourceExists) {
await ensureOwnedDirectory(layout.quarantineRoot, layout.managedRoot);
await assertOwnedManagedWorkspaceLayout(this.input.storageRoot, layout);
await rename(binding.worktreePath, quarantinePath);
} else if (!targetExists) {
throw new GitWorkspaceServiceError(
'managed_workspace_identity_conflict',
'Quarantine intent has neither a source worktree nor a target artifact',
);
}
await assertOwnedDirectoryEntry(quarantinePath, layout.quarantineRoot, true);
if (!samePath(await realpath(dirname(quarantinePath)), await realpath(layout.quarantineRoot))) {
throw new GitWorkspaceServiceError(
'managed_workspace_identity_conflict',
'Quarantine target parent does not match the owned quarantine root',
);
}
await this.input.failpoint?.('after_quarantine_move');
const stored = await readBinding(layout.bindingPath);
if (stored && !sameBinding(stored, binding)) {
throw new GitWorkspaceServiceError(
'managed_workspace_identity_conflict',
'Quarantine binding changed after its durable intent was recorded',
);
}
await rm(layout.bindingPath, { force: true });
await this.input.failpoint?.('after_quarantine_binding_removed');
await this.runtime.run(
['--git-dir', binding.repositoryPath, 'worktree', 'prune', '--expire=now'],
layout.homePath,
);
const remaining = findWorktreeRegistration(
await this.runtime.run(
['--git-dir', binding.repositoryPath, 'worktree', 'list', '--porcelain'],
layout.homePath,
),
binding.worktreePath,
);
if (remaining) {
throw new GitWorkspaceServiceError(
'managed_workspace_identity_conflict',
'Quarantine could not remove the managed worktree registration',
);
}
await this.input.failpoint?.('after_quarantine_pruned');
const record: ManagedWorkspaceQuarantineRecord = {
protocol: 'maka_managed_workspace_quarantine_v1',
reason,
binding,
};
const existingRecord = await readQuarantineRecord(`${quarantinePath}.json`);
if (existingRecord && !sameQuarantineRecord(existingRecord, record)) {
throw new GitWorkspaceServiceError(
'managed_workspace_identity_conflict',
'Quarantine record conflicts with its durable intent',
);
}
if (!existingRecord) await atomicWriteJson(`${quarantinePath}.json`, record);
return { quarantinePath, reason };
}
}
class VerifiedGitRuntime {
constructor(private readonly input: VerifiedGitRuntimeInput) {
if (
!isAbsolute(input.executablePath) ||
!SHA256_PATTERN.test(input.expectedSha256) ||
(input.distribution !== undefined && !SHA256_PATTERN.test(input.runtimeIdentitySha256 ?? ''))
) {
throw new GitWorkspaceServiceError(
'git_runtime_unavailable',
'Managed workspace requires an absolute Git executable and SHA-256 digest',
);
}
if (input.distribution) {
const rootPath = input.distribution.rootPath;
const executableRelativePath = relative(rootPath, input.executablePath);
if (
!isAbsolute(rootPath) ||
executableRelativePath === '' ||
executableRelativePath === '..' ||
executableRelativePath.startsWith(`..${process.platform === 'win32' ? '\\' : '/'}`) ||
isAbsolute(executableRelativePath)
) {
throw new GitWorkspaceServiceError(
'git_runtime_unavailable',
'Bundled Git executable must belong to its declared distribution root',
);
}
}
}
verify(): Promise<{ executablePath: string; digest: `sha256:${string}` }> {
return this.verifyOnce();
}
async run(
args: readonly string[],
homePath?: string,
extraEnv?: NodeJS.ProcessEnv,
acceptedExitCodes: readonly number[] = [],
): Promise<string> {
const runtime = await this.verify();
const hooksPath = homePath ? join(homePath, 'empty-hooks') : dirname(runtime.executablePath);
if (homePath) {
await mkdir(homePath, { recursive: true });
await mkdir(hooksPath, { recursive: true });
}
const env = isolatedGitEnvironment(this.input, homePath ?? dirname(runtime.executablePath));
try {
const { stdout } = await execFileAsync(
runtime.executablePath,
[...fixedGitArguments(hooksPath), ...args],
{
cwd: homePath ?? dirname(runtime.executablePath),
// Operation-scoped values (currently only deterministic commit
// identity) cannot override the hermetic Git execution profile.
env: { ...extraEnv, ...env },
encoding: 'utf8',
maxBuffer: GIT_MAX_BUFFER_BYTES,
timeout: GIT_TIMEOUT_MS,
windowsHide: true,
},
);
return stdout;
} catch (error) {
if (acceptedExitCodes.includes(exitCode(error) ?? -1)) return '';
throw error;
}
}
async runBuffer(
args: readonly string[],
homePath?: string,
extraEnv?: NodeJS.ProcessEnv,
): Promise<Buffer> {
const runtime = await this.verify();
const hooksPath = homePath ? join(homePath, 'empty-hooks') : dirname(runtime.executablePath);
if (homePath) {
await mkdir(homePath, { recursive: true });
await mkdir(hooksPath, { recursive: true });
}
const env = isolatedGitEnvironment(this.input, homePath ?? dirname(runtime.executablePath));
const { stdout } = await execFileAsync(
runtime.executablePath,
[...fixedGitArguments(hooksPath), ...args],
{
cwd: homePath ?? dirname(runtime.executablePath),
env: { ...extraEnv, ...env },
encoding: 'buffer',
maxBuffer: GIT_MAX_BUFFER_BYTES,
timeout: GIT_TIMEOUT_MS,
windowsHide: true,
},
);
return stdout;
}
async runOptional(
args: readonly string[],
acceptedMissingExitCode: number,
): Promise<string | undefined> {
try {
return await this.run(args);
} catch (error) {
if (exitCode(error) === acceptedMissingExitCode) return undefined;
throw error;
}
}
async importTree(
sourceRoot: string,
treeOid: string,
repositoryPath: string,
homePath: string,
): Promise<void> {
const packRuntime = await this.verify();
const hooksPath = join(homePath, 'empty-hooks');
await mkdir(hooksPath, { recursive: true });
const fixed = fixedGitArguments(hooksPath);
const pack = spawn(
packRuntime.executablePath,
[...fixed, '-C', sourceRoot, 'pack-objects', '--stdout', '--revs'],
{
cwd: homePath,
env: isolatedGitEnvironment(this.input, homePath),
stdio: ['pipe', 'pipe', 'pipe'],
windowsHide: true,
},
);
let indexRuntime: Awaited<ReturnType<VerifiedGitRuntime['verify']>>;
try {
// Each Git process is an independent trust decision. Re-check the
// executable immediately before index-pack instead of extending the
// pack-objects verification across a second invocation.
indexRuntime = await this.verify();
} catch (error) {
pack.kill('SIGKILL');
await waitForChildExit(pack).catch(() => undefined);
throw error;
}
const index = spawn(
indexRuntime.executablePath,
[...fixed, '--git-dir', repositoryPath, 'index-pack', '--stdin', '--fix-thin'],
{
cwd: homePath,
env: isolatedGitEnvironment(this.input, homePath),
stdio: ['pipe', 'ignore', 'pipe'],
windowsHide: true,
},
);
if (!pack.stdin || !pack.stdout || !index.stdin) {
pack.kill('SIGKILL');
index.kill('SIGKILL');
throw new Error('Git tree import did not create the required process pipes');
}
const packStderr = collectBoundedStderr(pack.stderr);
const indexStderr = collectBoundedStderr(index.stderr);
index.stdin.on('error', () => {
// The index process exit status/stderr is the authoritative pipeline failure.
});
pack.stdout.pipe(index.stdin);
pack.stdin.end(`${treeOid}\n`);
const timeout = setTimeout(() => {
pack.kill('SIGKILL');
index.kill('SIGKILL');
}, GIT_TIMEOUT_MS);
try {
const [packCode, indexCode] = await Promise.all([
waitForChildExit(pack),
waitForChildExit(index),
]);
if (packCode !== 0 || indexCode !== 0) {
throw new Error(
`Git tree import failed: pack=${packCode} index=${indexCode} ` +
`${await packStderr} ${await indexStderr}`,
);
}
} catch (error) {
pack.kill('SIGKILL');
index.kill('SIGKILL');
throw error;
} finally {
clearTimeout(timeout);
}
}
private async verifyOnce(): Promise<{
executablePath: string;
digest: `sha256:${string}`;
}> {
try {
const executablePath = normalize(await realpath(this.input.executablePath));
const info = await stat(executablePath);
if (!info.isFile()) throw new Error('not a regular file');
const executableDigest = await sha256File(executablePath);
if (executableDigest !== this.input.expectedSha256) {
throw new GitWorkspaceServiceError(
'git_runtime_integrity_mismatch',
`Git executable digest mismatch: ${executablePath}`,
);
}
return {
executablePath,
digest: this.input.runtimeIdentitySha256 ?? executableDigest,
};
} catch (error) {
if (error instanceof GitWorkspaceServiceError) throw error;
throw new GitWorkspaceServiceError(
'git_runtime_unavailable',
`Git runtime is unavailable: ${this.input.executablePath}`,
{ cause: error },
);
}
}
}
function workspaceLayout(
canonicalStorageRoot: string,
identity: Pick<
ManagedWorkspaceIdentity,
'repositoryId' | 'workspaceId' | 'workspaceEpochId' | 'workspaceInstanceId'
>,
): WorkspaceLayout {
const managedRoot = join(canonicalStorageRoot, 'managed-workspaces');
const quarantineIntentRoot = join(managedRoot, 'quarantine-intents');
const repositoryRoot = join(managedRoot, 'r', compactIdentity(identity.repositoryId));
const epochRoot = join(
managedRoot,
'w',
compactIdentity(identity.workspaceId),
'e',
compactIdentity(identity.workspaceEpochId),
);
const instanceRoot = join(epochRoot, 'i', compactIdentity(identity.workspaceInstanceId));
return {
managedRoot,
repositoryRoot,
repositoryPath: join(repositoryRoot, 'repository.git'),
repositoryRecordPath: join(repositoryRoot, 'repository.json'),
hooksPath: join(repositoryRoot, 'hooks'),
homePath: join(managedRoot, 'git-home'),
epochRoot,
epochArtifactPath: join(epochRoot, 'epoch.json'),
instanceRoot,
bindingPath: join(instanceRoot, 'binding.json'),
baselineReceiptPath: join(instanceRoot, 'baseline-receipt.json'),
worktreePath: join(instanceRoot, 'worktree'),
quarantineRoot: join(managedRoot, 'quarantine'),
quarantineIntentRoot,
quarantineIntentPath: join(
quarantineIntentRoot,
`${compactIdentity(identity.workspaceInstanceId)}.json`,
),
};
}
function assertOpenIdentity(input: ManagedWorkspaceIdentity): void {
for (const [name, value] of Object.entries({
repositoryId: input.repositoryId,
workspaceId: input.workspaceId,
workspaceEpochId: input.workspaceEpochId,
workspaceInstanceId: input.workspaceInstanceId,
})) {
if (!IDENTIFIER_PATTERN.test(value)) {
throw new GitWorkspaceServiceError(
'managed_workspace_identity_conflict',
`Invalid ${name}: ${value}`,
);
}
}
}
function assertBindingShape(value: unknown): asserts value is ManagedWorkspaceBinding {
if (!isBinding(value)) {
throw new GitWorkspaceServiceError(
'managed_workspace_identity_conflict',
'Invalid managed workspace binding',
);
}
}
function assertBindingMatches(
binding: ManagedWorkspaceBinding,
input: CreateManagedWorkspaceFromSourceInput,
layout: WorkspaceLayout,
runtimeDigest: `sha256:${string}`,
): void {
assertBindingIdentity(binding, input, layout, runtimeDigest);
if (!samePath(binding.sourceRoot, input.sourceRoot)) {
throw new GitWorkspaceServiceError(
'managed_workspace_identity_conflict',
'Managed workspace binding does not match the requested source provenance',
);
}
}
function assertBindingIdentity(
binding: ManagedWorkspaceBinding,
input: ManagedWorkspaceIdentity,
layout: WorkspaceLayout,
runtimeDigest: `sha256:${string}`,
): void {
assertBindingShape(binding);
assertBindingPaths(binding, layout);
if (
binding.repositoryId !== input.repositoryId ||
binding.workspaceId !== input.workspaceId ||
binding.workspaceEpochId !== input.workspaceEpochId ||
binding.workspaceInstanceId !== input.workspaceInstanceId ||
binding.gitRuntimeSha256 !== runtimeDigest ||
binding.materializationProfileDigest !==
materializationProfileDigest(runtimeDigest, binding.objectFormat) ||
binding.headRef !== managedHeadRef(input.workspaceId, input.workspaceEpochId)
) {
throw new GitWorkspaceServiceError(
'managed_workspace_identity_conflict',
'Managed workspace binding does not match the requested managed identity',
);
}
}
function assertBindingRepository(
binding: ManagedWorkspaceBinding,
repository: ManagedRepositoryRecord,
): void {
if (
binding.repositoryId !== repository.repositoryId ||
!samePath(binding.repositoryPath, repository.repositoryPath) ||
!samePath(binding.hooksPath, repository.hooksPath) ||
binding.gitRuntimeSha256 !== repository.gitRuntimeSha256 ||
binding.objectFormat !== repository.objectFormat ||
repository.repositoryCapabilityDigest !==
repositoryCapabilityDigest(repository.gitRuntimeSha256, repository.objectFormat)
) {
throw new GitWorkspaceServiceError(
'managed_workspace_identity_conflict',
'Managed workspace binding does not match its Git repository record',
);
}
}
function assertBindingEpoch(
binding: ManagedWorkspaceBinding,
epoch: ManagedWorkspaceEpochArtifact,
): void {
if (
binding.repositoryId !== epoch.repositoryId ||
binding.workspaceId !== epoch.workspaceId ||
binding.workspaceEpochId !== epoch.workspaceEpochId ||
!samePath(binding.sourceRoot, epoch.sourceRoot) ||
!samePath(binding.sourceGitCommonDir, epoch.sourceGitCommonDir) ||
binding.sourceHeadCommitOid !== epoch.sourceHeadCommitOid ||
binding.sourceTreeOid !== epoch.sourceTreeOid ||
binding.baselineCommitOid !== epoch.baselineCommitOid ||
binding.baselineTreeOid !== epoch.baselineTreeOid ||
binding.headRef !== epoch.headRef ||
binding.materializationProfileDigest !== epoch.materializationProfileDigest
) {
throw new GitWorkspaceServiceError(
'managed_workspace_identity_conflict',
'Managed workspace binding does not match its epoch artifact',
);
}
}
function assertBindingPaths(binding: ManagedWorkspaceBinding, layout: WorkspaceLayout): void {
if (
!samePath(binding.repositoryPath, layout.repositoryPath) ||
!samePath(binding.worktreePath, layout.worktreePath) ||
!samePath(binding.hooksPath, layout.hooksPath)
) {
throw new GitWorkspaceServiceError(
'managed_workspace_identity_conflict',
'Managed workspace binding escapes its owned storage namespace',
);
}
}
function assertRepositoryMatches(
record: ManagedRepositoryRecord,
input: CreateManagedWorkspaceFromSourceInput,
objectFormat: string,
layout: WorkspaceLayout,
runtimeDigest: `sha256:${string}`,
): void {
if (
record.repositoryId !== input.repositoryId ||
record.gitRuntimeSha256 !== runtimeDigest ||
record.objectFormat !== objectFormat ||
record.repositoryCapabilityDigest !== repositoryCapabilityDigest(runtimeDigest, objectFormat) ||
!samePath(record.repositoryPath, layout.repositoryPath) ||
!samePath(record.hooksPath, layout.hooksPath)
) {
throw new GitWorkspaceServiceError(
'managed_workspace_identity_conflict',
'Managed Git repository does not match the requested repository capability',
);
}
}
async function readBinding(path: string): Promise<ManagedWorkspaceBinding | undefined> {
const value = await readJson(path);
if (value === undefined) return undefined;
assertBindingShape(value);
return value;
}
async function readBaselineReceipt(
path: string,
): Promise<ManagedWorkspaceBaselineReceiptV1 | undefined> {
const value = await readJson(path);
if (value === undefined) return undefined;
assertBaselineReceiptShape(value);
return value;
}
async function readRepositoryRecord(path: string): Promise<ManagedRepositoryRecord | undefined> {
const value = await readJson(path);
if (value === undefined) return undefined;
if (!isRepositoryRecord(value)) {
throw new GitWorkspaceServiceError(
'managed_workspace_identity_conflict',
`Invalid managed Git repository record: ${path}`,
);
}
return value;
}
function assertEpochArtifactMatches(
artifact: ManagedWorkspaceEpochArtifact,
input: CreateManagedWorkspaceFromSourceInput,
source: SourceRepositoryInspection,
repository: ManagedRepositoryRecord,
): void {
if (
artifact.repositoryId !== input.repositoryId ||
artifact.workspaceId !== input.workspaceId ||
artifact.workspaceEpochId !== input.workspaceEpochId ||
!samePath(artifact.sourceRoot, source.sourceRoot) ||
!samePath(artifact.sourceGitCommonDir, source.gitCommonDir) ||
artifact.sourceHeadCommitOid !== source.headCommitOid ||
artifact.sourceTreeOid !== source.treeOid ||
artifact.baselineTreeOid !== source.treeOid ||
artifact.gitRuntimeSha256 !== repository.gitRuntimeSha256 ||
artifact.objectFormat !== repository.objectFormat
) {
throw new GitWorkspaceServiceError(
'managed_workspace_identity_conflict',
'Managed workspace epoch artifact does not match the requested source boundary',
);
}
}
function assertSameSourceObservation(
captured: SourceRepositoryInspection,
current: SourceRepositoryInspection,
): void {
if (
!samePath(captured.sourceRoot, current.sourceRoot) ||
!samePath(captured.gitCommonDir, current.gitCommonDir) ||
captured.headCommitOid !== current.headCommitOid ||
captured.treeOid !== current.treeOid ||
captured.objectFormat !== current.objectFormat
) {
throw new GitWorkspaceServiceError(
'source_changed_during_baseline_import',
'Managed workspace source changed while the baseline was being imported',
);
}
}
async function readEpochArtifact(path: string): Promise<ManagedWorkspaceEpochArtifact | undefined> {
const value = await readJson(path);
if (value === undefined) return undefined;
if (!isEpochArtifact(value)) {
throw new GitWorkspaceServiceError(
'managed_workspace_identity_conflict',
`Invalid managed workspace epoch artifact: ${path}`,
);
}
return value;
}
async function readQuarantineIntent(
path: string,
): Promise<ManagedWorkspaceQuarantineIntent | undefined> {
const value = await readJson(path);
if (value === undefined) return undefined;
if (!isQuarantineIntent(value)) {
throw new GitWorkspaceServiceError(
'managed_workspace_identity_conflict',
`Invalid managed workspace quarantine intent: ${path}`,
);
}
return value;
}
async function readQuarantineRecord(
path: string,
): Promise<ManagedWorkspaceQuarantineRecord | undefined> {
const value = await readJson(path);
if (value === undefined) return undefined;
if (!isQuarantineRecord(value)) {
throw new GitWorkspaceServiceError(
'managed_workspace_identity_conflict',
`Invalid managed workspace quarantine record: ${path}`,
);
}
return value;
}
function assertQuarantineIntentMatches(
intent: ManagedWorkspaceQuarantineIntent,
binding: ManagedWorkspaceBinding,
reason: string,
layout: WorkspaceLayout,
): void {
assertBindingShape(intent.binding);
assertBindingPaths(intent.binding, layout);
if (
!sameBinding(intent.binding, binding) ||
intent.reason !== reason ||
!isPathWithin(intent.quarantinePath, layout.quarantineRoot) ||
!samePath(dirname(intent.quarantinePath), layout.quarantineRoot)
) {
throw new GitWorkspaceServiceError(
'managed_workspace_identity_conflict',
'Managed workspace quarantine intent does not match its binding or owned namespace',
);
}
}
function isBinding(value: unknown): value is ManagedWorkspaceBinding {
if (!isRecord(value)) return false;
return (
hasExactKeys(value, BINDING_KEYS) &&
value.schemaVersion === BINDING_SCHEMA_VERSION &&
value.protocol === 'git_managed_workspace_v1' &&
typeof value.repositoryId === 'string' &&
IDENTIFIER_PATTERN.test(value.repositoryId) &&
typeof value.workspaceId === 'string' &&
IDENTIFIER_PATTERN.test(value.workspaceId) &&
typeof value.workspaceEpochId === 'string' &&
IDENTIFIER_PATTERN.test(value.workspaceEpochId) &&
typeof value.workspaceInstanceId === 'string' &&
IDENTIFIER_PATTERN.test(value.workspaceInstanceId) &&
typeof value.sourceRoot === 'string' &&
isAbsolute(value.sourceRoot) &&
typeof value.sourceGitCommonDir === 'string' &&
isAbsolute(value.sourceGitCommonDir) &&
typeof value.sourceHeadCommitOid === 'string' &&
OID_PATTERN.test(value.sourceHeadCommitOid) &&
typeof value.sourceTreeOid === 'string' &&
OID_PATTERN.test(value.sourceTreeOid) &&
typeof value.repositoryPath === 'string' &&
isAbsolute(value.repositoryPath) &&
typeof value.worktreePath === 'string' &&
isAbsolute(value.worktreePath) &&
typeof value.hooksPath === 'string' &&
isAbsolute(value.hooksPath) &&
typeof value.baselineCommitOid === 'string' &&
OID_PATTERN.test(value.baselineCommitOid) &&
typeof value.baselineTreeOid === 'string' &&
OID_PATTERN.test(value.baselineTreeOid) &&
typeof value.headRef === 'string' &&
value.headRef === managedHeadRef(value.workspaceId, value.workspaceEpochId) &&
typeof value.gitRuntimeSha256 === 'string' &&
SHA256_PATTERN.test(value.gitRuntimeSha256) &&
(value.objectFormat === 'sha1' || value.objectFormat === 'sha256') &&
typeof value.materializationProfileDigest === 'string' &&
SHA256_PATTERN.test(value.materializationProfileDigest) &&
value.materializationSemantics === MATERIALIZATION_SEMANTICS
);
}
function assertBaselineReceiptShape(
value: unknown,
): asserts value is ManagedWorkspaceBaselineReceiptV1 {
if (!isBaselineReceipt(value)) {
throw new GitWorkspaceServiceError(
'managed_workspace_identity_conflict',
'Invalid managed workspace baseline receipt',
);
}
}
function isBaselineReceipt(value: unknown): value is ManagedWorkspaceBaselineReceiptV1 {
if (!isRecord(value)) return false;
return (
hasExactKeys(value, BASELINE_RECEIPT_KEYS) &&
value.schemaVersion === BASELINE_RECEIPT_SCHEMA_VERSION &&
value.protocol === 'maka_managed_workspace_baseline_receipt_v1' &&
isBinding(value.binding) &&
typeof value.workspaceVersionId === 'string' &&
/^version_[a-f0-9]{32}$/u.test(value.workspaceVersionId) &&
value.policyVersion === 1 &&
typeof value.policyHash === 'string' &&
SHA256_PATTERN.test(value.policyHash) &&
typeof value.epochOpenedEventId === 'string' &&
/^[A-Za-z0-9_-]{1,128}$/u.test(value.epochOpenedEventId) &&
typeof value.baselineAcceptedEventId === 'string' &&
/^[A-Za-z0-9_-]{1,128}$/u.test(value.baselineAcceptedEventId) &&
value.epochOpenedEventId !== value.baselineAcceptedEventId &&
typeof value.treeDeltaDigest === 'string' &&
SHA256_PATTERN.test(value.treeDeltaDigest) &&
typeof value.changedFileCount === 'number' &&
Number.isSafeInteger(value.changedFileCount) &&
value.changedFileCount >= 0 &&
value.deletedFileCount === 0
);
}
function assertBaselineReceiptMatches(
receipt: ManagedWorkspaceBaselineReceiptV1,
binding: ManagedWorkspaceBinding,
summary: BaselineTreeSummary,
): void {
const identities = deriveBaselineReceiptIdentities(binding);
if (
!sameBinding(receipt.binding, binding) ||
receipt.workspaceVersionId !== identities.workspaceVersionId ||
receipt.epochOpenedEventId !== identities.epochOpenedEventId ||
receipt.baselineAcceptedEventId !== identities.baselineAcceptedEventId ||
receipt.policyVersion !== 1 ||
receipt.policyHash !== MANAGED_BASELINE_POLICY_HASH_V1 ||
receipt.treeDeltaDigest !== summary.treeDeltaDigest ||
receipt.changedFileCount !== summary.changedFileCount ||
receipt.deletedFileCount !== 0
) {
throw new GitWorkspaceServiceError(
'managed_workspace_identity_conflict',
'Managed workspace baseline receipt does not match its verified Git boundary',
);
}
}
function deriveBaselineReceiptIdentities(binding: ManagedWorkspaceBinding): {
readonly workspaceVersionId: string;
readonly epochOpenedEventId: string;
readonly baselineAcceptedEventId: string;
} {
const identity = {
repositoryId: binding.repositoryId,
workspaceId: binding.workspaceId,
workspaceEpochId: binding.workspaceEpochId,
workspaceInstanceId: binding.workspaceInstanceId,
baselineCommitOid: binding.baselineCommitOid,
baselineTreeOid: binding.baselineTreeOid,
policyVersion: 1,
policyHash: MANAGED_BASELINE_POLICY_HASH_V1,
} as const;
const derive = (purpose: string): string =>
createHash('sha256')
.update(
JSON.stringify({
protocol: 'maka_managed_workspace_baseline_identity_v1',
purpose,
identity,
}),
)
.digest('hex');
return {
workspaceVersionId: `version_${derive('workspace_version').slice(0, 32)}`,
epochOpenedEventId: `workspace_epoch_opened_${derive('epoch_opened').slice(0, 64)}`,
baselineAcceptedEventId: `workspace_baseline_accepted_${derive('baseline_accepted').slice(0, 64)}`,
};
}
function hashCanonicalJson(value: unknown): `sha256:${string}` {
return `sha256:${createHash('sha256').update(JSON.stringify(value)).digest('hex')}`;
}
function isRepositoryRecord(value: unknown): value is ManagedRepositoryRecord {
if (!isRecord(value)) return false;
return (
hasExactKeys(value, REPOSITORY_KEYS) &&
value.schemaVersion === REPOSITORY_SCHEMA_VERSION &&
value.protocol === 'maka_managed_git_repository_v1' &&
typeof value.repositoryId === 'string' &&
IDENTIFIER_PATTERN.test(value.repositoryId) &&
typeof value.repositoryPath === 'string' &&
isAbsolute(value.repositoryPath) &&
typeof value.hooksPath === 'string' &&
isAbsolute(value.hooksPath) &&
typeof value.gitRuntimeSha256 === 'string' &&
SHA256_PATTERN.test(value.gitRuntimeSha256) &&
(value.objectFormat === 'sha1' || value.objectFormat === 'sha256') &&
typeof value.repositoryCapabilityDigest === 'string' &&
SHA256_PATTERN.test(value.repositoryCapabilityDigest)
);
}
function isEpochArtifact(value: unknown): value is ManagedWorkspaceEpochArtifact {
if (!isRecord(value)) return false;
return (
hasExactKeys(value, EPOCH_ARTIFACT_KEYS) &&
value.schemaVersion === EPOCH_ARTIFACT_SCHEMA_VERSION &&
value.protocol === 'maka_managed_workspace_epoch_artifact_v1' &&
typeof value.repositoryId === 'string' &&
IDENTIFIER_PATTERN.test(value.repositoryId) &&
typeof value.workspaceId === 'string' &&
IDENTIFIER_PATTERN.test(value.workspaceId) &&
typeof value.workspaceEpochId === 'string' &&
IDENTIFIER_PATTERN.test(value.workspaceEpochId) &&
typeof value.sourceRoot === 'string' &&
isAbsolute(value.sourceRoot) &&
typeof value.sourceGitCommonDir === 'string' &&
isAbsolute(value.sourceGitCommonDir) &&
typeof value.sourceHeadCommitOid === 'string' &&
OID_PATTERN.test(value.sourceHeadCommitOid) &&
typeof value.sourceTreeOid === 'string' &&
OID_PATTERN.test(value.sourceTreeOid) &&
typeof value.baselineCommitOid === 'string' &&
OID_PATTERN.test(value.baselineCommitOid) &&
typeof value.baselineTreeOid === 'string' &&
OID_PATTERN.test(value.baselineTreeOid) &&
value.baselineRef === managedBaselineRef(value.workspaceEpochId) &&
value.headRef === managedHeadRef(value.workspaceId, value.workspaceEpochId) &&
typeof value.gitRuntimeSha256 === 'string' &&
SHA256_PATTERN.test(value.gitRuntimeSha256) &&
(value.objectFormat === 'sha1' || value.objectFormat === 'sha256') &&
typeof value.materializationProfileDigest === 'string' &&
SHA256_PATTERN.test(value.materializationProfileDigest) &&
value.materializationSemantics === MATERIALIZATION_SEMANTICS
);
}
function isQuarantineIntent(value: unknown): value is ManagedWorkspaceQuarantineIntent {
if (!isRecord(value)) return false;
return (
hasExactKeys(value, QUARANTINE_INTENT_KEYS) &&
value.schemaVersion === QUARANTINE_INTENT_SCHEMA_VERSION &&
value.protocol === 'maka_managed_workspace_quarantine_intent_v1' &&
typeof value.reason === 'string' &&
value.reason.length > 0 &&
typeof value.quarantinePath === 'string' &&
isAbsolute(value.quarantinePath) &&
isBinding(value.binding)
);
}
function isQuarantineRecord(value: unknown): value is ManagedWorkspaceQuarantineRecord {
if (!isRecord(value)) return false;
return (
hasExactKeys(value, QUARANTINE_RECORD_KEYS) &&
value.protocol === 'maka_managed_workspace_quarantine_v1' &&
typeof value.reason === 'string' &&
value.reason.length > 0 &&
isBinding(value.binding)
);
}
function isRecord(value: unknown): value is Record<string, unknown> {
return typeof value === 'object' && value !== null && !Array.isArray(value);
}
function hasExactKeys(value: Record<string, unknown>, expected: readonly string[]): boolean {
const actual = Object.keys(value).sort();
const canonical = [...expected].sort();
return (
actual.length === canonical.length && actual.every((key, index) => key === canonical[index])
);
}
function sameBinding(left: ManagedWorkspaceBinding, right: ManagedWorkspaceBinding): boolean {
return JSON.stringify(left) === JSON.stringify(right);
}
function sameBaselineReceipt(
left: ManagedWorkspaceBaselineReceiptV1,
right: ManagedWorkspaceBaselineReceiptV1,
): boolean {
return JSON.stringify(left) === JSON.stringify(right);
}
function sameQuarantineRecord(
left: ManagedWorkspaceQuarantineRecord,
right: ManagedWorkspaceQuarantineRecord,
): boolean {
return JSON.stringify(left) === JSON.stringify(right);
}
async function readJson(path: string): Promise<unknown | undefined> {
try {
const info = await lstat(path);
if (!info.isFile() || info.isSymbolicLink()) {
throw new Error('control record is not one regular non-symlink file');
}
return JSON.parse(await readFile(path, 'utf8')) as unknown;
} catch (error) {
if ((error as NodeJS.ErrnoException).code === 'ENOENT') return undefined;
throw new GitWorkspaceServiceError(
'managed_workspace_identity_conflict',
`Invalid managed workspace control record: ${path}`,
{ cause: error },
);
}
}
async function atomicWriteJson(path: string, value: unknown): Promise<void> {
await mkdir(dirname(path), { recursive: true });
const temporaryPath = `${path}.tmp-${randomUUID()}`;
try {
const file = await openFile(temporaryPath, 'wx', 0o600);
try {
await file.writeFile(`${JSON.stringify(value, null, 2)}\n`, 'utf8');
await file.sync();
} finally {
await file.close();
}
await rename(temporaryPath, path);
if (process.platform !== 'win32') {
const directory = await openFile(dirname(path), 'r');
try {
await directory.sync();
} finally {
await directory.close();
}
}
} finally {
await rm(temporaryPath, { force: true });
}
}
async function moveToQuarantine(
source: string,
quarantineRoot: string,
label: string,
): Promise<string> {
await mkdir(quarantineRoot, { recursive: true });
const target = join(quarantineRoot, `${sanitizeReason(label)}-${Date.now()}-${randomUUID()}`);
await rename(source, target);
return target;
}
async function canonicalDirectory(
path: string,
code: GitWorkspaceServiceErrorCode,
): Promise<string> {
try {
const canonical = normalize(await realpath(path));
if (!(await stat(canonical)).isDirectory()) throw new Error('not a directory');
return canonical;
} catch (error) {
throw new GitWorkspaceServiceError(code, `Directory is unavailable: ${path}`, { cause: error });
}
}
async function ensureOwnedDirectory(path: string, ownerRoot: string): Promise<void> {
const requested = normalize(resolve(path));
const canonicalOwner = normalize(await realpath(ownerRoot));
const relation = relative(normalize(resolve(ownerRoot)), requested);
if (relation.startsWith('..') || isAbsolute(relation)) {
throw new GitWorkspaceServiceError(
'managed_workspace_identity_conflict',
`Managed workspace control path escapes its owner root: ${path}`,
);
}
let current = normalize(resolve(ownerRoot));
for (const segment of relation.split(/[\\/]/u).filter(Boolean)) {
current = join(current, segment);
try {
await mkdir(current);
} catch (error) {
if ((error as NodeJS.ErrnoException).code !== 'EEXIST') throw error;
}
const info = await lstat(current);
const canonical = normalize(await realpath(current));
if (!info.isDirectory() || info.isSymbolicLink() || !isPathWithin(canonical, canonicalOwner)) {
throw new GitWorkspaceServiceError(
'managed_workspace_identity_conflict',
`Managed workspace control path is not one owned directory: ${current}`,
);
}
}
}
async function assertOwnedManagedWorkspaceLayout(
storageRoot: string,
layout: WorkspaceLayout,
): Promise<void> {
const canonicalStorageRoot = normalize(await realpath(storageRoot));
await assertOwnedDirectoryEntry(layout.managedRoot, canonicalStorageRoot, true);
await assertOwnedDirectoryEntry(layout.quarantineRoot, layout.managedRoot, true);
await assertOwnedDirectoryEntry(layout.homePath, layout.managedRoot, true);
await assertOwnedDirectoryEntry(layout.quarantineIntentRoot, layout.managedRoot, false);
await assertOwnedDirectoryEntry(layout.repositoryRoot, layout.managedRoot, false);
await assertOwnedDirectoryEntry(layout.repositoryPath, layout.repositoryRoot, false);
await assertOwnedDirectoryEntry(layout.hooksPath, layout.repositoryRoot, false);
await assertOwnedDirectoryEntry(layout.epochRoot, layout.managedRoot, false);
await assertOwnedDirectoryEntry(layout.instanceRoot, layout.epochRoot, false);
await assertOwnedDirectoryEntry(layout.worktreePath, layout.instanceRoot, false);
}
async function assertOwnedDirectoryEntry(
path: string,
ownerRoot: string,
required: boolean,
): Promise<void> {
let info;
try {
info = await lstat(path);
} catch (error) {
if (!required && (error as NodeJS.ErrnoException).code === 'ENOENT') return;
throw new GitWorkspaceServiceError(
'managed_workspace_identity_conflict',
`Managed workspace owned directory is unavailable: ${path}`,
{ cause: error },
);
}
let canonicalOwner: string;
let canonicalPath: string;
try {
canonicalOwner = normalize(await realpath(ownerRoot));
canonicalPath = normalize(await realpath(path));
} catch (error) {
throw new GitWorkspaceServiceError(
'managed_workspace_identity_conflict',
`Managed workspace owned directory cannot be canonicalized: ${path}`,
{ cause: error },
);
}
if (
!info.isDirectory() ||
info.isSymbolicLink() ||
!isPathWithin(canonicalPath, canonicalOwner)
) {
throw new GitWorkspaceServiceError(
'managed_workspace_identity_conflict',
`Managed workspace owned directory escaped or changed identity: ${path}`,
);
}
}
async function pathExists(path: string): Promise<boolean> {
try {
await stat(path);
return true;
} catch (error) {
if ((error as NodeJS.ErrnoException).code === 'ENOENT') return false;
throw error;
}
}
async function pathEntryExists(path: string): Promise<boolean> {
try {
await lstat(path);
return true;
} catch (error) {
if ((error as NodeJS.ErrnoException).code === 'ENOENT') return false;
throw error;
}
}
async function isNonSymlinkDirectory(path: string): Promise<boolean> {
try {
const info = await lstat(path);
return info.isDirectory() && !info.isSymbolicLink();
} catch (error) {
if ((error as NodeJS.ErrnoException).code === 'ENOENT') return false;
throw error;
}
}
function resolveGitPath(cwd: string, path: string): string {
return isAbsolute(path) ? path : resolve(cwd, path);
}
function samePath(left: string, right: string): boolean {
const normalizedLeft = normalize(resolve(left));
const normalizedRight = normalize(resolve(right));
return process.platform === 'win32'
? normalizedLeft.toLowerCase() === normalizedRight.toLowerCase()
: normalizedLeft === normalizedRight;
}
function isPathWithin(path: string, root: string): boolean {
const candidate = normalize(resolve(path));
const owner = normalize(resolve(root));
const comparisonCandidate = process.platform === 'win32' ? candidate.toLowerCase() : candidate;
const comparisonOwner = process.platform === 'win32' ? owner.toLowerCase() : owner;
const relation = relative(comparisonOwner, comparisonCandidate);
return relation === '' || (!relation.startsWith('..') && !isAbsolute(relation));
}
function sanitizeReason(value: string): string {
return (
value
.toLowerCase()
.replace(/[^a-z0-9_-]+/gu, '-')
.replace(/^-+|-+$/gu, '')
.slice(0, 64) || 'unknown'
);
}
function hasUnsafeSourceConfig(raw: string | undefined): boolean {
if (!raw) return false;
return raw.split(/\r?\n/u).some((line) => {
const key = line.trim().toLowerCase();
return (
key.startsWith('include.') ||
key.startsWith('includeif.') ||
key === 'extensions.objectformat' ||
key === 'extensions.partialclone' ||
key === 'core.fsmonitor' ||
(key.startsWith('remote.') && key.endsWith('.promisor'))
);
});
}
function compactIdentity(value: string): string {
return createHash('sha256').update(value).digest('hex').slice(0, 20);
}
function managedHeadRef(workspaceId: string, workspaceEpochId: string): string {
return `refs/maka/workspaces/${workspaceId}/epochs/${workspaceEpochId}/head`;
}
function managedBaselineRef(workspaceEpochId: string): string {
return `refs/maka/baselines/${workspaceEpochId}`;
}
function worktreeLockReason(
identity: Pick<ManagedWorkspaceIdentity, 'workspaceInstanceId'>,
): string {
return `maka managed workspace ${identity.workspaceInstanceId}`;
}
function assertWorktreeRegistrationLocked(
porcelain: string,
worktreePath: string,
expectedReason: string,
): void {
const registration = findWorktreeRegistration(porcelain, worktreePath);
if (!registration || registration.lockReason !== expectedReason) {
throw new GitWorkspaceServiceError(
'managed_workspace_identity_conflict',
'Managed worktree registration or Maka ownership lock is unavailable',
);
}
}
interface WorktreeRegistration {
readonly headOid?: string;
readonly lockReason?: string;
}
function findWorktreeRegistration(
porcelain: string,
worktreePath: string,
): WorktreeRegistration | undefined {
for (const block of porcelain.split(/\r?\n\r?\n/u)) {
const lines = block.split(/\r?\n/u);
const pathLine = lines.find((line) => line.startsWith('worktree '));
if (!pathLine || !samePath(pathLine.slice('worktree '.length), worktreePath)) continue;
const headLine = lines.find((line) => line.startsWith('HEAD '));
const lockedLine = lines.find((line) => line === 'locked' || line.startsWith('locked '));
return {
...(headLine ? { headOid: headLine.slice('HEAD '.length) } : {}),
...(lockedLine ? { lockReason: lockedLine.slice('locked'.length).trim() } : {}),
};
}
return undefined;
}
function repositoryCapabilityDigest(
gitRuntimeSha256: `sha256:${string}`,
objectFormat: string,
): `sha256:${string}` {
const capability = JSON.stringify({
protocol: 'maka_managed_git_repository_capability_v1',
gitRuntimeSha256,
objectFormat,
hooks: 'disabled_v1',
credentials: 'disabled_v1',
autoGc: false,
alternates: 'forbidden_v1',
});
return `sha256:${createHash('sha256').update(capability).digest('hex')}`;
}
function materializationProfileDigest(
gitRuntimeSha256: `sha256:${string}`,
objectFormat: string,
): `sha256:${string}` {
const profile = JSON.stringify({
protocol: 'git_materialization_profile_v1',
gitRuntimeSha256,
objectFormat,
platform: process.platform,
autocrlf: false,
safecrlf: true,
attributes: 'reject_v1',
symlinks: 'reject_v1',
submodules: 'reject_v1',
caseCollisions: 'reject_v1',
ignoredInputs: 'exclude_v1',
});
return `sha256:${createHash('sha256').update(profile).digest('hex')}`;
}
function parseTreeEntries(output: Buffer): GitTreeEntry[] {
const entries: GitTreeEntry[] = [];
let start = 0;
while (start < output.length) {
const end = output.indexOf(0, start);
if (end < 0) {
throw new GitWorkspaceServiceError(
'repository_ineligible',
'Git source tree contains an unterminated entry',
);
}
const record = output.subarray(start, end);
start = end + 1;
if (record.length === 0) continue;
const tab = record.indexOf(0x09);
const metadata = tab >= 0 ? record.subarray(0, tab).toString('ascii') : '';
const pathBytes = tab >= 0 ? record.subarray(tab + 1) : Buffer.alloc(0);
const [mode = '', objectType = '', oid = ''] = metadata.split(' ');
let path = '';
try {
path = new TextDecoder('utf-8', { fatal: true }).decode(pathBytes);
} catch {
throw new GitWorkspaceServiceError(
'repository_ineligible',
'Managed workspace v1 requires Git paths to be valid UTF-8',
);
}
if (
!mode ||
!objectType ||
!OID_PATTERN.test(oid) ||
pathBytes.length === 0 ||
!Buffer.from(path, 'utf8').equals(pathBytes)
) {
throw new GitWorkspaceServiceError(
'repository_ineligible',
'Git source tree contains an unreadable entry',
);
}
entries.push({ mode, objectType, oid, path, pathBytesBase64: pathBytes.toString('base64') });
}
return entries;
}
function baselineTreeSummary(entries: readonly GitTreeEntry[]): BaselineTreeSummary {
const manifest = JSON.stringify({
protocol: 'maka_git_empty_tree_delta_v1',
entries: entries.map(({ mode, objectType, oid, pathBytesBase64 }) => ({
mode,
objectType,
oid,
pathBytesBase64,
})),
});
return {
treeDeltaDigest: `sha256:${createHash('sha256').update(manifest).digest('hex')}`,
changedFileCount: entries.length,
};
}
function assertSupportedTree(entries: readonly GitTreeEntry[]): void {
const caseFolded = new Set<string>();
for (const entry of entries) {
if ((entry.mode !== '100644' && entry.mode !== '100755') || entry.objectType !== 'blob') {
throw new GitWorkspaceServiceError(
'repository_ineligible',
'Symlinks, submodules, and special Git modes are not supported by managed workspace v1',
);
}
if (entry.path === '.gitattributes' || entry.path.endsWith('/.gitattributes')) {
throw new GitWorkspaceServiceError(
'repository_ineligible',
'Tracked .gitattributes require a materialization profile not supported by v1',
);
}
const folded = entry.path.normalize('NFC').toLocaleLowerCase('en-US');
if (caseFolded.has(folded)) {
throw new GitWorkspaceServiceError(
'repository_ineligible',
'Case-colliding Git paths are not supported by managed workspace v1',
);
}
caseFolded.add(folded);
}
}
function baselineCommitEnvironment(): NodeJS.ProcessEnv {
return {
GIT_AUTHOR_NAME: 'Maka Workspace Service',
GIT_AUTHOR_EMAIL: 'workspace@maka.invalid',
GIT_AUTHOR_DATE: BASELINE_DATE,
GIT_COMMITTER_NAME: 'Maka Workspace Service',
GIT_COMMITTER_EMAIL: 'workspace@maka.invalid',
GIT_COMMITTER_DATE: BASELINE_DATE,
GIT_WORKSPACE_BASELINE_MESSAGE: BASELINE_MESSAGE,
};
}
function isOwnedBaselineCommit(raw: string): boolean {
const normalized = raw.replace(/\r\n/gu, '\n');
const separator = normalized.indexOf('\n\n');
if (separator < 0) return false;
const headers = normalized.slice(0, separator).split('\n');
const message = normalized.slice(separator + 2).trimEnd();
return (
headers.length === 3 &&
/^tree (?:[a-f0-9]{40}|[a-f0-9]{64})$/u.test(headers[0] ?? '') &&
headers[1] === 'author Maka Workspace Service <workspace@maka.invalid> 946684800 +0000' &&
headers[2] === 'committer Maka Workspace Service <workspace@maka.invalid> 946684800 +0000' &&
message === BASELINE_MESSAGE.trimEnd()
);
}
function isolatedGitEnvironment(
input: VerifiedGitRuntimeInput,
homePath: string,
): NodeJS.ProcessEnv {
const executablePath = input.executablePath;
const env: NodeJS.ProcessEnv = {
HOME: homePath,
XDG_CONFIG_HOME: join(homePath, 'xdg'),
GIT_CONFIG_NOSYSTEM: '1',
GIT_TERMINAL_PROMPT: '0',
GCM_INTERACTIVE: 'never',
GIT_OPTIONAL_LOCKS: '0',
GIT_NO_REPLACE_OBJECTS: '1',
GIT_NO_LAZY_FETCH: '1',
LANG: 'C',
LC_ALL: 'C',
PATH: dirname(executablePath),
};
if (input.distribution?.kind === 'dugite_native_v1') {
Object.assign(
env,
bundledGitEnvironment({
platform: process.platform,
arch: process.arch,
rootPath: input.distribution.rootPath,
executablePath,
}),
);
}
for (const name of ['SystemRoot', 'WINDIR', 'COMSPEC', 'TMP', 'TEMP', 'TMPDIR']) {
if (process.env[name]) env[name] = process.env[name];
}
return env;
}
function fixedGitArguments(hooksPath: string): string[] {
return [
'--no-pager',
'-c',
'core.autocrlf=false',
'-c',
'core.safecrlf=true',
'-c',
'core.fsmonitor=false',
'-c',
'core.longpaths=true',
'-c',
`core.hooksPath=${hooksPath}`,
'-c',
'credential.helper=',
'-c',
'credential.interactive=never',
'-c',
'core.sshCommand=',
'-c',
'protocol.allow=never',
'-c',
'gc.auto=0',
'-c',
'submodule.recurse=false',
];
}
function waitForChildExit(child: ChildProcess): Promise<number | null> {
return new Promise((resolve, reject) => {
child.once('error', reject);
child.once('exit', (code) => resolve(code));
});
}
function collectBoundedStderr(stream: NodeJS.ReadableStream | null): Promise<string> {
if (!stream) return Promise.resolve('');
return new Promise((resolve) => {
let output = '';
stream.on('data', (chunk) => {
if (output.length < 64 * 1024) output += String(chunk);
});
stream.on('end', () => resolve(output.slice(0, 64 * 1024).trim()));
});
}
async function sha256File(path: string): Promise<`sha256:${string}`> {
const hash = createHash('sha256');
for await (const chunk of createReadStream(path)) hash.update(chunk);
return `sha256:${hash.digest('hex')}`;
}
function exitCode(error: unknown): number | undefined {
if (!isRecord(error)) return undefined;
return typeof error.code === 'number' ? error.code : undefined;
}