fix(#2136): route operator-facing date fields through local clock day
clock.today() derived the calendar day by slicing a UTC ISO instant
(nowIso().split('T')[0]), so in any negative-UTC-offset zone during UTC's early
hours last_activity named a day the operator had not reached yet — ahead of
last_updated's local date, written by the same call.
- Add Clock.localToday(): host-local YYYY-MM-DD via getMonth/getDate/
getFullYear, honoring the same GSD_NOW_MS pin as today()/nowIso().
- Route operator-facing date-only fields through localToday(): last_activity
(state-transition ×7, state.cts), roadmap 'completed <date>' (phase.cts,
roadmap.cts), milestone completion date (milestone.cts), todo/scaffold
completion (commands.cts — now threaded through the realClock seam).
- Leave today() (UTC) as the source for internal/cosmetic stamps.
Closes #2136
This commit is contained in:
@@ -42,6 +42,7 @@ const { extractFrontmatter } = frontmatter;
|
||||
import modelProfiles = require('./model-profiles.cjs');
|
||||
const { MODEL_PROFILES, VALID_PHASE_TYPES } = modelProfiles;
|
||||
import { formatGsdSlash, resolveRuntime } from './runtime-slash.cjs';
|
||||
import { realClock } from './clock.cjs';
|
||||
|
||||
// ─── Types ────────────────────────────────────────────────────────────────────
|
||||
|
||||
@@ -1418,7 +1419,7 @@ function cmdTodoComplete(cwd: string, filename: string | undefined, raw: boolean
|
||||
|
||||
// Read, add completion timestamp, move
|
||||
let content = fs.readFileSync(sourcePath, 'utf-8');
|
||||
const today = new Date().toISOString().split('T')[0];
|
||||
const today = realClock.localToday();
|
||||
content = `completed: ${today}\n` + content;
|
||||
|
||||
platformWriteSync(path.join(completedDir, filename as string), content);
|
||||
@@ -1430,7 +1431,7 @@ function cmdTodoComplete(cwd: string, filename: string | undefined, raw: boolean
|
||||
function cmdScaffold(cwd: string, type: string, options: ScaffoldOptions, raw: boolean): void {
|
||||
const { phase, name } = options;
|
||||
const padded = phase ? normalizePhaseName(phase) : '00';
|
||||
const today = new Date().toISOString().split('T')[0];
|
||||
const today = realClock.localToday();
|
||||
|
||||
// Find phase directory
|
||||
const phaseInfo = phase ? findPhaseInternal(cwd, phase) as Record<string, unknown> | null : null;
|
||||
|
||||
Reference in New Issue
Block a user