Skip to content

gbrain dream silently drops --source flag, breaking cycle_freshness loop doctor recommends #1452

@Mr-B-1

Description

@Mr-B-1

Version: v0.40.8.0

Repro

# Run the command doctor explicitly recommends:
gbrain dream --source default --dir /data/brain
# Wait for completion (full 16-phase cycle, exit 0).
gbrain doctor --json | jq '.checks[] | select(.name=="cycle_freshness")'
# Still reports "Source 'default' has never completed a full cycle"

psql $DATABASE_URL -c "SELECT id, config->>'last_full_cycle_at' FROM sources;"
# NULL for all sources

Root cause

src/commands/dream.ts:36-44 DreamArgs interface has no source field:

interface DreamArgs {
  json: boolean;
  dryRun: boolean;
  pull: boolean;
  phase: CyclePhase | null;
  dir: string | null;
  // ... no source field
}

dream.ts:278-288 calls runCycle() without propagating sourceId:

const report = await runCycle(engine, {
  brainDir,
  dryRun: opts.dryRun,
  pull: opts.pull,
  phases,
  // ← MISSING: sourceId: opts.source ?? undefined
  synthInputFile: opts.inputFile ?? undefined,
  // ...
});

cycle.ts:1738 gates the per-source marker write on opts.sourceId truthy:

if (opts.sourceId && engine && !dryRun && (status === 'ok' || 'clean' || 'partial')) {
  await engine.updateSourceConfig(opts.sourceId, { last_full_cycle_at: new Date().toISOString() });
}

With opts.sourceId = undefined, the write is silently skipped (no warning, by design — best-effort).

Why this matters

Doctor at src/commands/doctor.ts:2067 recommends Run 'gbrain dream --source <id>' for each stale source as the fix. Following the recommendation has no effect. Users either accept a persistent warn forever or install gbrain autopilot as a daemon — but no autopilot.service ships in the repo.

gbrain sync --source <id> accepts and propagates the flag correctly. Dream is the odd one out — likely missed during the v0.38 per-source cycle tracking refactor.

Suggested fix (~15 lines, src/commands/dream.ts)

// 1. Add to DreamArgs interface
interface DreamArgs {
  // ... existing fields
  source: string | null;   // per-source cycle tracking
}

// 2. Add to args initialization
const args: DreamArgs = { ..., source: null };

// 3. Add to argv parser
} else if (arg === '--source') {
  args.source = argv[++i] ?? null;
}

// 4. Pass to runCycle (line 278)
const report = await runCycle(engine, {
  brainDir,
  dryRun: opts.dryRun,
  pull: opts.pull,
  phases,
  sourceId: opts.source ?? undefined,    // ← new line
  synthInputFile: opts.inputFile ?? undefined,
  // ...
});

// 5. Update docstring (line 12-18) to document --source <id>

Happy to PR if helpful.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions