You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
.gittensory-miner.yml already has a real, tolerant parser and type — MinerGoalSpec (packages/gittensory-engine/src/miner-goal-spec.ts:14-52) currently covers six fields (minerEnabled, wantedPaths, blockedPaths, preferredLabels, blockedLabels, maxConcurrentClaims, issueDiscoveryPolicy); none of them govern the feasibility gate. parseMinerGoalSpec/parseMinerGoalSpecContent in the same file (lines 193-257) never throw — a malformed field degrades to DEFAULT_MINER_GOAL_SPEC (lines 72-80) plus a warning string. This is the canonical implementation: it's re-exported from the package entrypoint (packages/gittensory-engine/src/index.ts:190-198) and it's what the one real caller in the miner package actually uses (packages/gittensory-miner/lib/opportunity-ranker.js:57, parseMinerGoalSpecContent(content).spec).
Caution for whoever picks this up: there is a second, differently-behaved parseMinerGoalSpec function in a sibling file, packages/gittensory-engine/src/miner-goal-spec-parse.ts (110 lines, its own MinerGoalSpecParseResult return type, different limits — 200 list entries / 300 chars vs. the canonical file's 100 / 256). It is not exported from index.ts and has no caller anywhere in the repo outside its own test files (packages/gittensory-engine/test/miner-goal-spec-parse.test.ts, miner-goal-spec-discovery.test.ts). Extend miner-goal-spec.ts — that's the one every real consumer depends on; changing the other file would have zero effect on actual miner behavior.
The JSON Schema mirror, packages/gittensory-miner/schema/miner-goal-spec.schema.json, has "additionalProperties": true (line 7) and repeats the same six fields 1:1, so adding a feasibilityGate property is additive and non-breaking to the schema. packages/gittensory-miner/docs/miner-goal-spec.md documents the same six fields and will need the new one too.
This item is naturally paired with #4270 (wiring buildFeasibilityVerdict into an MCP tool + CLI command) — this issue is what would let a repo maintainer actually tune that gate's behavior per-repo — but the two can be built independently since this only touches the config-parsing surface, not the composer or its callers.
Deliverables
Add a feasibilityGate field to MinerGoalSpec in packages/gittensory-engine/src/miner-goal-spec.ts — type + an entry in DEFAULT_MINER_GOAL_SPEC (lines 72-80) + a normalize* helper mirroring the existing ones (e.g. normalizeIssueDiscoveryPolicy, lines 138-150)
Wire the new field through parseMinerGoalSpec (lines 193-231) and hasConfiguredGoalFields (lines 176-186, so a spec with only this field set is still correctly detected as present: true)
Do NOT extend miner-goal-spec-parse.ts for this — it's a second, non-exported implementation with no real caller (see caution above)
Update packages/gittensory-miner/schema/miner-goal-spec.schema.json with the new property
Tests in packages/gittensory-engine/test/miner-goal-spec*.test.ts covering present/absent/malformed cases for the new field, mirroring the existing per-field test coverage
.gittensory-miner.ymlalready has a real, tolerant parser and type —MinerGoalSpec(packages/gittensory-engine/src/miner-goal-spec.ts:14-52) currently covers six fields (minerEnabled,wantedPaths,blockedPaths,preferredLabels,blockedLabels,maxConcurrentClaims,issueDiscoveryPolicy); none of them govern the feasibility gate.parseMinerGoalSpec/parseMinerGoalSpecContentin the same file (lines 193-257) never throw — a malformed field degrades toDEFAULT_MINER_GOAL_SPEC(lines 72-80) plus a warning string. This is the canonical implementation: it's re-exported from the package entrypoint (packages/gittensory-engine/src/index.ts:190-198) and it's what the one real caller in the miner package actually uses (packages/gittensory-miner/lib/opportunity-ranker.js:57,parseMinerGoalSpecContent(content).spec).Caution for whoever picks this up: there is a second, differently-behaved
parseMinerGoalSpecfunction in a sibling file,packages/gittensory-engine/src/miner-goal-spec-parse.ts(110 lines, its ownMinerGoalSpecParseResultreturn type, different limits — 200 list entries / 300 chars vs. the canonical file's 100 / 256). It is not exported fromindex.tsand has no caller anywhere in the repo outside its own test files (packages/gittensory-engine/test/miner-goal-spec-parse.test.ts,miner-goal-spec-discovery.test.ts). Extendminer-goal-spec.ts— that's the one every real consumer depends on; changing the other file would have zero effect on actual miner behavior.The JSON Schema mirror,
packages/gittensory-miner/schema/miner-goal-spec.schema.json, has"additionalProperties": true(line 7) and repeats the same six fields 1:1, so adding afeasibilityGateproperty is additive and non-breaking to the schema.packages/gittensory-miner/docs/miner-goal-spec.mddocuments the same six fields and will need the new one too.This item is naturally paired with #4270 (wiring
buildFeasibilityVerdictinto an MCP tool + CLI command) — this issue is what would let a repo maintainer actually tune that gate's behavior per-repo — but the two can be built independently since this only touches the config-parsing surface, not the composer or its callers.Deliverables
feasibilityGatefield toMinerGoalSpecinpackages/gittensory-engine/src/miner-goal-spec.ts— type + an entry inDEFAULT_MINER_GOAL_SPEC(lines 72-80) + anormalize*helper mirroring the existing ones (e.g.normalizeIssueDiscoveryPolicy, lines 138-150)parseMinerGoalSpec(lines 193-231) andhasConfiguredGoalFields(lines 176-186, so a spec with only this field set is still correctly detected aspresent: true)miner-goal-spec-parse.tsfor this — it's a second, non-exported implementation with no real caller (see caution above)packages/gittensory-miner/schema/miner-goal-spec.schema.jsonwith the new propertypackages/gittensory-miner/docs/miner-goal-spec.mdbuildFeasibilityVerdictavoid/raise reasons per-repo, or just tune thresholds — coordinating loosely with feat(miner-plan): wire the feasibility gate into a new MCP tool + miner CLI command #4270 since that issue is the gate's actual consumerpackages/gittensory-engine/test/miner-goal-spec*.test.tscovering present/absent/malformed cases for the new field, mirroring the existing per-field test coverageReferences
packages/gittensory-engine/src/miner-goal-spec.ts:14-52(MinerGoalSpectype)packages/gittensory-engine/src/miner-goal-spec.ts:72-80(DEFAULT_MINER_GOAL_SPEC)packages/gittensory-engine/src/miner-goal-spec.ts:193-231(parseMinerGoalSpec)packages/gittensory-engine/src/miner-goal-spec.ts:176-186(hasConfiguredGoalFields)packages/gittensory-engine/src/index.ts:190-198(public export — the canonical module)packages/gittensory-engine/src/miner-goal-spec-parse.ts(the non-exported, uncalled sibling — do not extend this one)packages/gittensory-miner/lib/opportunity-ranker.js:57(the one real caller ofparseMinerGoalSpecContent)packages/gittensory-miner/schema/miner-goal-spec.schema.json:7("additionalProperties": true)packages/gittensory-miner/docs/miner-goal-spec.md