Implement parseMinerGoalSpec(raw: unknown, source?) / parseMinerGoalSpecContent(content: string | null | undefined) following the EXACT same shape as src/signals/focus-manifest.ts's parseFocusManifest/parseFocusManifestContent: tolerant of a missing file (returns DEFAULT_MINER_GOAL_SPEC), tolerant of unknown/malformed keys (drops them with a warning, never throws), validates each field against its declared type/enum and falls back to the default on a type mismatch, and returns a warnings: string[] array alongside the parsed spec so a CLI can surface "your .gittensory-miner.yml had problems" without hard-failing the miner run.
Deliverables
References
src/signals/focus-manifest.ts parseFocusManifest/parseFocusManifestContent (lines 995-1142) — THE pattern to mirror, per the phase brief's explicit instruction.
.gittensory.yml.example (full file, 10679 bytes) — the doc-comment style/structure to mirror for the new .gittensory-miner.yml.example.
packages/gittensory-engine/src/miner-goal-spec.ts (or wherever the sibling types issue placed it) — the type contract this parser fills.
Implement
parseMinerGoalSpec(raw: unknown, source?)/parseMinerGoalSpecContent(content: string | null | undefined)following the EXACT same shape assrc/signals/focus-manifest.ts'sparseFocusManifest/parseFocusManifestContent: tolerant of a missing file (returnsDEFAULT_MINER_GOAL_SPEC), tolerant of unknown/malformed keys (drops them with a warning, never throws), validates each field against its declared type/enum and falls back to the default on a type mismatch, and returns awarnings: string[]array alongside the parsed spec so a CLI can surface "your.gittensory-miner.ymlhad problems" without hard-failing the miner run.Deliverables
parseMinerGoalSpec(raw: unknown, source?: "repo_file" | "user_supplied")andparseMinerGoalSpecContent(content: string | null | undefined)implementing YAML-then-JSON fallback parsing (mirrorparseFocusManifestContent's try-YAML-then-JSON approach) and per-field validation with warnings-not-throws on any single bad field..gittensory-miner.yml→.github/gittensory-miner.yml→.gittensory-miner.json→.github/gittensory-miner.json, first match wins (mirroring.gittensory.yml's own documented discovery order).gittensory-miner status(from the earlier CLI-entry-point issue) gains a line reporting whether a goal-spec file was found and any parse warnings, wiring this parser into the CLI end-to-end.focus-manifest's own tolerance for genuinely unknown keys vs. known-but-malformed ones — confirm which conventionfocus-manifest.tsactually uses and match it exactly, citing the specific line)..gittensory-miner.yml.exampledocumentation file at the repo root, matching the header-comment style and per-field "Default: X" convention of.gittensory.yml.example.References
src/signals/focus-manifest.tsparseFocusManifest/parseFocusManifestContent(lines 995-1142) — THE pattern to mirror, per the phase brief's explicit instruction..gittensory.yml.example(full file, 10679 bytes) — the doc-comment style/structure to mirror for the new.gittensory-miner.yml.example.packages/gittensory-engine/src/miner-goal-spec.ts(or wherever the sibling types issue placed it) — the type contract this parser fills.