Skip to content

Commit e33fd2d

Browse files
refactor(sync): require explicit home directory
1 parent 660fe92 commit e33fd2d

7 files changed

Lines changed: 19 additions & 8 deletions

File tree

docs/intentional-architecture-rewrite-2026-06-27/status.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ Branch: `codex/intentional-architecture-rewrite`
55

66
## Current State
77

8-
The branch has 195 committed rewrite commits past `dev`. The worklog records 149 production slices so far.
8+
The branch has 196 committed rewrite commits past `dev`. The worklog records 150 production slices so far.
99

1010
The diff is broad: 350 files changed, with about 20.4k insertions and 10.6k deletions.
1111

@@ -36,9 +36,9 @@ This is no longer a small cleanup branch. It is a real ownership rewrite.
3636

3737
## Latest Checkpoint
3838

39-
The latest slice made setup instruction home-directory ownership explicit. The setup command already receives `homeDir` from CLI edges; the guide-install step now passes it into setup services, and `src/services/setup/instructions.ts` no longer defaults to `homedir()`.
39+
The latest slice made sync home-directory ownership explicit. The sync CLI edge now passes `homeDir`; `src/cli/commands/sync.ts` and `src/services/sync/types.ts` require it, and `src/services/sync/sync.ts` no longer defaults to `homedir()`.
4040

41-
Verification passed: `npm run lint`, focused setup/uninstall/CLI/boundary tests, full `npm test` with 655 tests, `npm run build`, `git diff --check`, `node dist/codealmanac.js --version`, and `node dist/codealmanac.js automation status`.
41+
Verification passed: `npm run lint`, focused sync/CLI/boundary tests, full `npm test` with 655 tests, `npm run build`, `git diff --check`, `node dist/codealmanac.js --version`, `node dist/codealmanac.js sync status --json`, and `node dist/codealmanac.js automation status`.
4242

4343
## Immediate Next Work
4444

docs/intentional-architecture-rewrite-2026-06-27/worklog.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -995,3 +995,9 @@ One-hundred-forty-ninth production slice:
995995
- Made setup instruction installation require an explicit `homeDir` instead of defaulting to `homedir()` inside `src/services/setup/instructions.ts`.
996996
- Threaded the existing setup command `homeDir` through the guide-install step into the setup service.
997997
- Added boundary guards so setup instruction services cannot reintroduce ambient home-directory ownership.
998+
999+
One-hundred-fiftieth production slice:
1000+
1001+
- Made sync workflow options require an explicit `homeDir` instead of defaulting to `homedir()` inside `src/services/sync/sync.ts`.
1002+
- Threaded `homeDir` from `src/edges/cli/register-sync-commands.ts` through `src/cli/commands/sync.ts` into the sync service.
1003+
- Added boundary guards so sync services cannot reintroduce ambient home-directory ownership.

src/cli/commands/sync.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ export interface SyncCommandOptions {
1212
using?: string;
1313
json?: boolean;
1414
now?: Date;
15-
homeDir?: string;
15+
homeDir: string;
1616
configPath?: string;
1717
startBackground?: SyncWorkflowOptions["startBackground"];
1818
workerProgram: SyncWorkflowOptions["workerProgram"];

src/edges/cli/register-sync-commands.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { Command } from "commander";
2+
import { homedir } from "node:os";
23

34
import { currentCliNodeProgram } from "./current-cli.js";
45
import { emit } from "./helpers.js";
@@ -24,6 +25,7 @@ export function registerSyncCommands(program: Command): void {
2425
quiet: opts.quiet,
2526
using: opts.using,
2627
json: opts.json,
28+
homeDir: homedir(),
2729
workerProgram: currentCliNodeProgram(),
2830
workerEnvironment: process.env,
2931
pid: process.pid,
@@ -54,6 +56,7 @@ export function registerSyncCommands(program: Command): void {
5456
from: opts.from ?? parentOpts.from,
5557
quiet: opts.quiet ?? parentOpts.quiet,
5658
json: opts.json ?? parentOpts.json,
59+
homeDir: homedir(),
5760
workerProgram: currentCliNodeProgram(),
5861
workerEnvironment: process.env,
5962
pid: process.pid,

src/services/sync/sync.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import { homedir } from "node:os";
2-
31
import * as operations from "../../operations/index.js";
42
import * as sync from "../../sync/index.js";
53
import { readConfig } from "../../config/index.js";
@@ -31,7 +29,7 @@ export async function runSyncWorkflow(
3129
await sync.sweep({
3230
candidates: await sync.discoverCandidates({
3331
apps: sources.value,
34-
home: options.homeDir ?? homedir(),
32+
home: options.homeDir,
3533
}),
3634
syncSince: await readSyncSince(options.configPath),
3735
quietMs: quiet.ms,

src/services/sync/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ export interface SyncWorkflowOptions {
99
quiet?: string;
1010
using?: string;
1111
now?: Date;
12-
homeDir?: string;
12+
homeDir: string;
1313
configPath?: string;
1414
startBackground?: StartBackgroundJob;
1515
workerProgram: JobWorkerProgram;

test/architecture-boundaries.test.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -591,6 +591,7 @@ describe("architecture boundaries", () => {
591591
expect(existsSync(join(ROOT, "src/cli/commands/sync-render.ts"))).toBe(true);
592592
expect(syncCommand).not.toContain("import type { CommandResult }");
593593
expect(syncCommand).not.toContain("extends SyncWorkflowOptions");
594+
expect(syncCommand).toContain("homeDir: string");
594595
expect(syncCommand).toContain("toSyncWorkflowOptions");
595596
expect(syncCommand).not.toContain("renderOutcome");
596597
expect(syncCommand).not.toContain("renderError");
@@ -1254,7 +1255,10 @@ describe("architecture boundaries", () => {
12541255
expect(syncServiceIndex).not.toContain("../../sync");
12551256
expect(syncService).not.toContain("interface SyncWorkflowOptions");
12561257
expect(syncService).not.toContain("interface SyncWorkflowSummary");
1258+
expect(syncService).not.toContain("homedir");
12571259
expect(syncServiceTypes).toContain("interface SyncWorkflowOptions");
1260+
expect(syncServiceTypes).toContain("homeDir: string");
1261+
expect(syncServiceTypes).not.toContain("homeDir?: string");
12581262
expect(syncServiceTypes).toContain("interface SyncWorkflowSummary");
12591263
expect(syncService).not.toContain("export type SyncWorkflowSummary = sync.SyncSummary");
12601264
expect(syncService).not.toContain(

0 commit comments

Comments
 (0)