@@ -466,6 +466,79 @@ Body.
466466 // Missing / malformed phases array
467467 // ---------------------------------------------------------------------------
468468
469+ // ---------------------------------------------------------------------------
470+ // Phase claimed_at field parsing
471+ // ---------------------------------------------------------------------------
472+
473+ it ( 'parses claimed_at as ISO string into claimedAt epoch ms' , ( ) => {
474+ const planPath = writeFile ( 'claimed-iso/plan.md' , `---
475+ epic: claimed-iso
476+ phases:
477+ - id: 1
478+ title: "Phase"
479+ persona: eng
480+ status: IN_PROGRESS
481+ claimed_at: "2026-04-06T10:00:00Z"
482+ ---
483+ Body.
484+ ` )
485+
486+ const epic = parsePlanFile ( planPath , 'P' , '/p' ) !
487+ expect ( epic . phases [ 0 ] . claimedAt ) . toBe ( Date . parse ( '2026-04-06T10:00:00Z' ) )
488+ } )
489+
490+ it ( 'parses claimed_at as epoch ms number' , ( ) => {
491+ const ts = 1743933600000 // some known epoch ms
492+ const planPath = writeFile ( 'claimed-ms/plan.md' , `---
493+ epic: claimed-ms
494+ phases:
495+ - id: 1
496+ title: "Phase"
497+ persona: eng
498+ status: IN_PROGRESS
499+ claimed_at: ${ ts }
500+ ---
501+ Body.
502+ ` )
503+
504+ const epic = parsePlanFile ( planPath , 'P' , '/p' ) !
505+ expect ( epic . phases [ 0 ] . claimedAt ) . toBe ( ts )
506+ } )
507+
508+ it ( 'parses claimed_at as epoch seconds (auto-converts to ms)' , ( ) => {
509+ const secs = 1743933600 // < 1e12, treated as seconds
510+ const planPath = writeFile ( 'claimed-secs/plan.md' , `---
511+ epic: claimed-secs
512+ phases:
513+ - id: 1
514+ title: "Phase"
515+ persona: eng
516+ status: IN_PROGRESS
517+ claimed_at: ${ secs }
518+ ---
519+ Body.
520+ ` )
521+
522+ const epic = parsePlanFile ( planPath , 'P' , '/p' ) !
523+ expect ( epic . phases [ 0 ] . claimedAt ) . toBe ( secs * 1000 )
524+ } )
525+
526+ it ( 'omits claimedAt when claimed_at is absent' , ( ) => {
527+ const planPath = writeFile ( 'no-claimed/plan.md' , `---
528+ epic: no-claimed
529+ phases:
530+ - id: 1
531+ title: "Phase"
532+ persona: eng
533+ status: IN_PROGRESS
534+ ---
535+ Body.
536+ ` )
537+
538+ const epic = parsePlanFile ( planPath , 'P' , '/p' ) !
539+ expect ( epic . phases [ 0 ] . claimedAt ) . toBeUndefined ( )
540+ } )
541+
469542 it ( 'treats missing phases key as an empty phases array' , ( ) => {
470543 // No phases: key at all — should produce a valid epic with zero phases
471544 const planPath = writeFile ( 'no-phases-key/plan.md' , `---
0 commit comments