Begin portable TORCH fleet rewrite

This commit is contained in:
thePR0M3TH3AN committed 2026-09-27 15:39:12 -04:00
1 parent a46832314f
commit cce059fc3a
16 files changed
+2258 -613

No files matched your search

+87
View File
@@ -0,0 +1,87 @@
import { existsSync, readFileSync } from 'node:fs';
import { extname } from 'node:path';
import { trackedFiles } from './git.mjs';
const LANGUAGE_BY_EXTENSION = new Map([
['.js', 'JavaScript'], ['.mjs', 'JavaScript'], ['.cjs', 'JavaScript'],
['.ts', 'TypeScript'], ['.tsx', 'TypeScript'], ['.jsx', 'JavaScript'],
['.py', 'Python'], ['.rs', 'Rust'], ['.go', 'Go'], ['.java', 'Java'],
['.c', 'C'], ['.h', 'C/C++'], ['.cc', 'C++'], ['.cpp', 'C++'],
['.cs', 'C#'], ['.rb', 'Ruby'], ['.php', 'PHP'], ['.swift', 'Swift'],
['.kt', 'Kotlin'], ['.sh', 'Shell'], ['.bash', 'Shell'], ['.ps1', 'PowerShell'],
['.html', 'HTML'], ['.css', 'CSS'], ['.scss', 'CSS'], ['.vue', 'Vue'],
['.svelte', 'Svelte'], ['.sol', 'Solidity'],
]);
const MANIFESTS = [
'package.json', 'pyproject.toml', 'requirements.txt', 'Cargo.toml', 'go.mod',
'pom.xml', 'build.gradle', 'Makefile', 'CMakeLists.txt', 'Dockerfile',
];
export function analyzeRepository(repository) {
const files = trackedFiles(repository.root);
const languageCounts = new Map();
const topLevel = new Set();
for (const file of files) {
const language = LANGUAGE_BY_EXTENSION.get(extname(file).toLowerCase());
if (language) languageCounts.set(language, (languageCounts.get(language) ?? 0) + 1);
const first = file.split('/')[0];
if (file.includes('/')) topLevel.add(first);
}
const languages = [...languageCounts.entries()]
.map(([name, files]) => ({ name, files }))
.sort((a, b) => b.files - a.files || a.name.localeCompare(b.name));
const manifests = MANIFESTS.filter((file) => files.includes(file));
const operations = files.filter((file) =>
/(^|\/)(\.github\/workflows|Dockerfile|docker-compose|vercel\.json|systemd|deploy|release|cron)/i.test(file));
const testFiles = files.filter((file) => /(^|\/)(test|tests|spec|e2e)(\/|\.|$)/i.test(file));
const docs = files.filter((file) => /(^|\/)(docs?|README)(\/|\.|$)/i.test(file));
const sharedCandidates = files.filter((file) =>
/(^|\/)(package(-lock)?\.json|[^/]*config[^/]*|schema|schemas|types|shared)(\/|\.|$)/i.test(file));
const checks = [];
const packagePath = `${repository.root}/package.json`;
if (existsSync(packagePath)) {
try {
const pkg = JSON.parse(readFileSync(packagePath, 'utf8'));
for (const [name, command] of Object.entries(pkg.scripts ?? {})) {
if (/test|check|lint|type|build|verify|audit/i.test(name)) checks.push({ name, command });
}
} catch {
// The analyzer reports observable repository shape. Invalid manifests are
// surfaced later by doctor and should not make read-only analysis mutate.
}
}
const scarceResources = [];
const joined = files.join('\n').toLowerCase();
if (/playwright|puppeteer|cypress|browser/.test(joined)) scarceResources.push('browser');
if (/cuda|gpu|webgl|three\.js|threejs/.test(joined)) scarceResources.push('gpu');
if (/postgres|mysql|sqlite|database/.test(joined)) scarceResources.push('database');
return {
generatedAt: new Date().toISOString(),
repository: {
root: repository.root,
name: repository.name,
branch: repository.branch,
head: repository.head,
hasRemote: repository.remotes.length > 0,
},
inventory: {
trackedFileCount: files.length,
languages,
manifests,
topLevelDirectories: [...topLevel].sort(),
testFileCount: testFiles.length,
documentationFileCount: docs.length,
operations: operations.slice(0, 100),
sharedSurfaceCandidates: sharedCandidates.slice(0, 100),
checks,
scarceResources,
},
mutationPerformed: false,
};
}
+55
View File
@@ -0,0 +1,55 @@
import { existsSync, readFileSync } from 'node:fs';
import { join } from 'node:path';
import { fileHash } from './files.mjs';
import { projectStatePath } from './paths.mjs';
function parseJsonYaml(path) {
return JSON.parse(readFileSync(path, 'utf8'));
}
export function diagnoseProject({ repository, env = process.env }) {
const trackedRoot = join(repository.root, '.torch');
const configPath = join(trackedRoot, 'torch.yaml');
const manifestPath = join(trackedRoot, 'install-manifest.json');
const findings = [];
if (!existsSync(configPath)) {
return { status: 'not-installed', healthy: false, findings: [{ severity: 'error', code: 'CONFIG_MISSING', path: configPath }] };
}
if (!existsSync(manifestPath)) {
return { status: 'broken', healthy: false, findings: [{ severity: 'error', code: 'MANIFEST_MISSING', path: manifestPath }] };
}
let config;
let manifest;
try { config = parseJsonYaml(configPath); } catch (error) {
findings.push({ severity: 'error', code: 'CONFIG_INVALID', message: error.message });
}
try { manifest = parseJsonYaml(manifestPath); } catch (error) {
findings.push({ severity: 'error', code: 'MANIFEST_INVALID', message: error.message });
}
if (manifest) {
for (const record of manifest.created ?? []) {
const path = join(repository.root, record.path);
if (!existsSync(path)) findings.push({ severity: 'error', code: 'OWNED_FILE_MISSING', path: record.path });
else if (fileHash(path) !== record.sha256) findings.push({ severity: 'info', code: 'OWNED_FILE_MODIFIED', path: record.path });
}
const stateRoot = projectStatePath(manifest.projectId, env);
if (!existsSync(stateRoot)) findings.push({ severity: 'error', code: 'LOCAL_STATE_MISSING', path: stateRoot });
}
if (config?.project?.id && manifest?.projectId && config.project.id !== manifest.projectId) {
findings.push({ severity: 'error', code: 'PROJECT_ID_MISMATCH' });
}
if (repository.dirtyEntries.length) {
findings.push({ severity: 'info', code: 'WORKTREE_DIRTY', count: repository.dirtyEntries.length });
}
return {
status: findings.some((finding) => finding.severity === 'error') ? 'broken' : 'ok',
healthy: !findings.some((finding) => finding.severity === 'error'),
projectId: config?.project?.id ?? null,
findings,
};
}
+16
View File
@@ -0,0 +1,16 @@
export class TorchError extends Error {
constructor(message, { code = 'TORCH_ERROR', details = undefined } = {}) {
super(message);
this.name = 'TorchError';
this.code = code;
this.details = details;
}
}
export function asErrorRecord(error) {
return {
error: error?.code ?? 'UNEXPECTED_ERROR',
message: error instanceof Error ? error.message : String(error),
...(error?.details === undefined ? {} : { details: error.details }),
};
}
+24
View File
@@ -0,0 +1,24 @@
import { createHash } from 'node:crypto';
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
import { dirname } from 'node:path';
import { TorchError } from './errors.mjs';
export function sha256(content) {
return createHash('sha256').update(content).digest('hex');
}
export function writeNewFile(path, content) {
if (existsSync(path)) {
throw new TorchError(`Refusing to overwrite existing path: ${path}`, {
code: 'PATH_ALREADY_EXISTS',
details: { path },
});
}
mkdirSync(dirname(path), { recursive: true });
writeFileSync(path, content, { encoding: 'utf8', mode: 0o600, flag: 'wx' });
return { path, sha256: sha256(content) };
}
export function fileHash(path) {
return sha256(readFileSync(path));
}
+57
View File
@@ -0,0 +1,57 @@
import { execFileSync } from 'node:child_process';
import { realpathSync } from 'node:fs';
import { basename } from 'node:path';
import { TorchError } from './errors.mjs';
function git(cwd, args, { optional = false } = {}) {
try {
return execFileSync('git', ['-C', cwd, ...args], {
encoding: 'utf8',
stdio: ['ignore', 'pipe', 'pipe'],
}).trim();
} catch (error) {
if (optional) return '';
throw new TorchError(`Git command failed: git ${args.join(' ')}`, {
code: 'GIT_COMMAND_FAILED',
details: error.stderr?.toString().trim() || undefined,
});
}
}
export function inspectRepository(cwd = process.cwd()) {
const rootText = git(cwd, ['rev-parse', '--show-toplevel'], { optional: true });
if (!rootText) {
throw new TorchError(`Not a Git repository: ${cwd}`, { code: 'NOT_GIT_REPOSITORY' });
}
const root = realpathSync(rootText);
const branch = git(root, ['branch', '--show-current'], { optional: true }) || null;
const head = git(root, ['rev-parse', 'HEAD'], { optional: true }) || null;
const initialCommit = head
? git(root, ['rev-list', '--max-parents=0', 'HEAD'], { optional: true }).split('\n')[0] || null
: null;
const status = git(root, ['status', '--porcelain=v1', '--untracked-files=all'], { optional: true });
const remotesText = git(root, ['remote', '-v'], { optional: true });
const remotes = remotesText
? remotesText.split('\n').map((line) => {
const [name, url, kindText = ''] = line.split(/\s+/);
return { name, url, kind: kindText.replace(/[()]/g, '') || 'unknown' };
})
: [];
return {
root,
name: basename(root),
branch,
head,
initialCommit,
dirtyEntries: status ? status.split('\n') : [],
remotes,
canonicalRemote: remotes.find((remote) => remote.name === 'origin' && remote.kind === 'fetch') ?? null,
};
}
export function trackedFiles(root) {
const output = git(root, ['ls-files', '-z'], { optional: true });
return output ? output.split('\0').filter(Boolean) : [];
}
+203
View File
@@ -0,0 +1,203 @@
import { randomUUID } from 'node:crypto';
import {
existsSync, mkdirSync, readFileSync, readdirSync, rmSync, writeFileSync,
} from 'node:fs';
import { dirname, join, relative, resolve, sep } from 'node:path';
import { TorchError } from './errors.mjs';
import { fileHash, writeNewFile } from './files.mjs';
import { projectStatePath } from './paths.mjs';
const TRACKED_DIR = '.torch';
function jsonYaml(value) {
return `${JSON.stringify(value, null, 2)}\n`;
}
function initialFiles({ repository, projectId, createdAt }) {
const config = {
schema: 'torch.dev/v1alpha1',
project: {
id: projectId,
name: repository.name,
main_branch: repository.branch || 'main',
},
paths: { tracked_state: TRACKED_DIR, worktree_parent: '~/TORCHWorktrees' },
repository: repository.canonicalRemote
? { canonical: { type: 'remote', remote: repository.canonicalRemote.name } }
: { canonical: { type: 'unconfigured' } },
forge: { provider: 'none' },
git: {
branch_prefix: 'torch/', convergence: 'merge', allow_rebase: false,
allow_force_push: false, allow_bare_stash: false,
},
synchronization: { strategy: 'dispatcher-managed', auto_merge_worktrees: false },
session_manager: { id: 'session-manager', start_last: true },
domains: [],
};
const roster = {
schema: 'torch.dev/roster/v1alpha1',
areas: [{
id: 'session-manager', title: 'TORCH Session Manager',
scope: ['routing', 'priority', 'ownership rulings', 'fleet health'],
not_scope: ['project feature implementation by default'],
neighbours: ['all'],
}],
};
return new Map([
['torch.yaml', jsonYaml(config)],
['roster.yaml', jsonYaml(roster)],
['decisions.md', '# TORCH decisions\n\nNo project decisions recorded yet.\n'],
['RESUME-BRIEF.md', '# TORCH resume brief\n\nFleet not started yet.\n'],
['prompts/COMMON.md', '# Common fleet rules\n\nRepository state outranks conversation memory. Query ownership before crossing a domain boundary.\n'],
['prompts/session-manager.md', '# TORCH Session Manager\n\nRoute owner requests, establish ownership and priority, and keep routine coordination inside the fleet.\n'],
['backlog/.gitkeep', ''],
['INSTALLATION.md', `# TORCH installation\n\nInstalled ${createdAt}. Run \`torch doctor\` before starting the fleet.\n`],
]);
}
function manifestPath(root) {
return join(root, TRACKED_DIR, 'install-manifest.json');
}
function readManifest(root) {
const path = manifestPath(root);
if (!existsSync(path)) {
throw new TorchError(`No TORCH ownership manifest at ${path}`, { code: 'NOT_INSTALLED' });
}
try {
return JSON.parse(readFileSync(path, 'utf8'));
} catch (error) {
throw new TorchError(`Invalid TORCH ownership manifest: ${path}`, {
code: 'INVALID_INSTALL_MANIFEST', details: error.message,
});
}
}
function safeProjectPath(root, relativePath) {
const target = resolve(root, relativePath);
const prefix = `${resolve(root)}${sep}`;
if (!target.startsWith(prefix)) {
throw new TorchError(`Manifest path escapes project root: ${relativePath}`, {
code: 'UNSAFE_MANIFEST_PATH', details: { relativePath },
});
}
return target;
}
export function planInstall({ repository, env = process.env }) {
const trackedRoot = join(repository.root, TRACKED_DIR);
return {
action: 'install',
projectRoot: repository.root,
trackedRoot,
stateParent: join(projectStatePath('<new-project-id>', env), '..'),
wouldCreateTrackedState: !existsSync(trackedRoot),
mutationPerformed: false,
};
}
export function installProject({
repository,
env = process.env,
projectId = randomUUID(),
now = () => new Date(),
} = {}) {
const trackedRoot = join(repository.root, TRACKED_DIR);
if (existsSync(trackedRoot)) {
throw new TorchError(`Refusing to replace existing ${trackedRoot}`, {
code: 'ALREADY_INSTALLED', details: { trackedRoot },
});
}
const createdAt = now().toISOString();
const stateRoot = projectStatePath(projectId, env);
if (existsSync(stateRoot)) {
throw new TorchError(`Refusing to replace existing TORCH state: ${stateRoot}`, {
code: 'STATE_ALREADY_EXISTS', details: { stateRoot },
});
}
const created = [];
try {
for (const [path, content] of initialFiles({ repository, projectId, createdAt })) {
const absolute = join(trackedRoot, path);
const record = writeNewFile(absolute, content);
created.push({ path: relative(repository.root, record.path), sha256: record.sha256 });
}
mkdirSync(dirname(stateRoot), { recursive: true });
mkdirSync(stateRoot, { recursive: false });
for (const dir of ['sessions', 'messages', 'locks', 'leases', 'checks', 'integration', 'logs']) {
mkdirSync(join(stateRoot, dir));
}
writeFileSync(join(stateRoot, 'project.json'), jsonYaml({
schema: 'torch.dev/local-project/v1alpha1', projectId,
root: repository.root, createdAt, detachedAt: null,
}), { encoding: 'utf8', mode: 0o600, flag: 'wx' });
const manifest = {
schema: 'torch.dev/install-manifest/v1alpha1',
installationId: randomUUID(),
projectId,
createdAt,
created,
patched: [],
external: [{ type: 'local-state', path: stateRoot }],
};
writeNewFile(manifestPath(repository.root), jsonYaml(manifest));
return { projectId, trackedRoot, stateRoot, manifest, mutationPerformed: true };
} catch (error) {
if (existsSync(trackedRoot)) rmSync(trackedRoot, { recursive: true, force: true });
if (existsSync(stateRoot)) rmSync(stateRoot, { recursive: true, force: true });
throw error;
}
}
function nonEmptyEntries(path) {
if (!existsSync(path)) return [];
return readdirSync(path, { recursive: true, withFileTypes: true })
.filter((entry) => entry.isFile() && entry.name !== 'project.json')
.map((entry) => entry.name);
}
export function planUninstall({ repository, purge = false }) {
const manifest = readManifest(repository.root);
const problems = [];
for (const record of manifest.created) {
const path = safeProjectPath(repository.root, record.path);
if (!existsSync(path)) problems.push({ type: 'missing', path: record.path });
else if (fileHash(path) !== record.sha256) problems.push({ type: 'modified', path: record.path });
}
for (const entry of manifest.external ?? []) {
if (entry.type === 'local-state') {
const extras = nonEmptyEntries(entry.path);
if (extras.length) problems.push({ type: 'local-state-not-empty', path: entry.path, entries: extras });
}
}
return {
action: purge ? 'purge' : 'detach', manifest, problems,
canProceed: !purge || problems.length === 0,
mutationPerformed: false,
};
}
export function uninstallProject({ repository, purge = false, dryRun = false }) {
const plan = planUninstall({ repository, purge });
if (dryRun || !purge) return plan;
if (!plan.canProceed) {
throw new TorchError('TORCH purge stopped because managed state changed', {
code: 'UNSAFE_TO_PURGE', details: plan.problems,
});
}
for (const record of [...plan.manifest.created].reverse()) {
rmSync(safeProjectPath(repository.root, record.path));
}
rmSync(manifestPath(repository.root));
rmSync(join(repository.root, TRACKED_DIR), { recursive: true });
for (const entry of plan.manifest.external ?? []) {
if (entry.type === 'local-state' && existsSync(entry.path)) rmSync(entry.path, { recursive: true });
}
return { ...plan, mutationPerformed: true };
}
+11
View File
@@ -0,0 +1,11 @@
import { homedir } from 'node:os';
import { join } from 'node:path';
export function torchDataHome(env = process.env) {
const dataHome = env.XDG_DATA_HOME || join(homedir(), '.local', 'share');
return join(dataHome, 'torch');
}
export function projectStatePath(projectId, env = process.env) {
return join(torchDataHome(env), 'projects', projectId);
}