feat(miner): add .gittensory-ams.yml operator execution-policy config (#5132) - #5249
Merged
Conversation
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
gittensory-ui | b927588 | Commit Preview URL Branch Preview URL |
Jul 12 2026, 11:39 AM |
Advances #5132 runMinerAttempt needs submissionMode/slopThreshold/capLimits/ convergenceThresholds, none of which had any config or env backing anywhere in the codebase -- pure policy dials that would otherwise get hardcoded with no way to tune them. Adds AmsPolicySpec (engine package, structural sibling to MinerGoalSpec) and resolveAmsPolicy (miner package), mirroring .gittensory.yml's own established self-host precedent: a target repo may propose a .gittensory-ams.yml default, but the operator's own local copy (in their gittensory-miner config dir), when present, fully REPLACES it -- never a field-by-field merge. A repo's own file can only ever propose a fallback default for an unconfigured operator; it can never loosen what an operator's agent is willing to do against that same repo. Deny-by-default: submissionMode defaults to "observe" (computes real decisions, never actually submits), slopThreshold to "low" (strict).
JSONbored
force-pushed
the
feat/ams-policy-spec-5132
branch
from
July 12, 2026 11:38
9a1d1fb to
b927588
Compare
Contributor
|
Superagent did not find any vulnerabilities or security issues in this PR. |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #5249 +/- ##
==========================================
- Coverage 94.34% 94.26% -0.09%
==========================================
Files 473 474 +1
Lines 39982 40043 +61
Branches 14576 14598 +22
==========================================
+ Hits 37722 37747 +25
- Misses 1585 1609 +24
- Partials 675 687 +12
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
JSONbored
added a commit
that referenced
this pull request
Jul 12, 2026
Advances #5132 #5249 merged with AmsPolicySpec at 40.98% patch coverage: Codecov only sees packages/gittensory-engine files through a root test/unit/*.test.ts that actually imports and exercises them -- the engine package's own node:test suite is a completely separate, Codecov-invisible measurement. test/unit/miner-ams-policy.test.ts only exercised resolveAmsPolicy's own call path, leaving most of parseAmsPolicySpec's field-level branches (submissionMode/slopThreshold rejection, capLimits/convergenceThresholds validation, malformed/oversized content) uncovered from Codecov's perspective. Adds a root-level mirror of the engine's own parser test, matching the established miner-goal-spec-parser.test.ts pattern -- 100% statement/branch/line coverage on ams-policy-spec.ts confirmed locally.
3 tasks
JSONbored
added a commit
that referenced
this pull request
Jul 12, 2026
#5253) Advances #5132 #5249 merged with AmsPolicySpec at 40.98% patch coverage: Codecov only sees packages/gittensory-engine files through a root test/unit/*.test.ts that actually imports and exercises them -- the engine package's own node:test suite is a completely separate, Codecov-invisible measurement. test/unit/miner-ams-policy.test.ts only exercised resolveAmsPolicy's own call path, leaving most of parseAmsPolicySpec's field-level branches (submissionMode/slopThreshold rejection, capLimits/convergenceThresholds validation, malformed/oversized content) uncovered from Codecov's perspective. Adds a root-level mirror of the engine's own parser test, matching the established miner-goal-spec-parser.test.ts pattern -- 100% statement/branch/line coverage on ams-policy-spec.ts confirmed locally.
10 tasks
JSONbored
added a commit
that referenced
this pull request
Jul 12, 2026
Closes #5132 The final assembly: attempt-cli.js now fetches a real SelfReviewContext (#5145), builds a real coding-task spec (#5239, blocking on an infeasible verdict), resolves the real AmsPolicySpec execution policy (#5249, extended here with maxIterations/maxTurnsPerIteration -- the same operator-risk-policy gap capLimits/submissionMode/slopThreshold already covered), assembles the real IterateLoopInput + Governor chokepoint context, and calls runMinerAttempt for real -- the first point in this epic where a real coding agent actually executes rather than every path ending in a reported block. New attempt-input-builder.js holds the two pure composers (buildAttemptGovernorContext, buildAttemptLoopInput) so the assembly logic is independently unit-tested, mirroring coding-task-spec.js's own precedent. Real outcomes now surface distinct exit codes: 0 (submitted), 7 (abandon), 8 (stale), 9 (blocked by submission gate), 10 (governed), plus the existing 4 (blocked_infeasible, repurposed from the old blocked_missing_prerequisite placeholder), 5 (rejection_signaled), 6 (worktree_preparation_failed). The worktree is cleaned up on submission, retained on any other real outcome for post-mortem inspection (cleanupAttemptWorktree's own retention policy). KNOWN, DOCUMENTED GAPS (not fabricated -- see attempt-input-builder.js and attempt-cli.js's own header comments): - governor.killSwitchRepoPaused only checks the GLOBAL env-var kill switch; a real per-repo .gittensory-miner.yml pause needs miner-goal-spec.js (#5255, open) wired in as a fast-follow. - governor.convergenceInput is an honest first-attempt-shaped literal, not a real per-issue attempt-history query -- attempt-log.js's schema has no repo+issue index, and reenqueue counts aren't tracked anywhere yet (non-convergence.ts's own header: that belongs on the portfolio-queue table once it grows attempt-history columns, a real separate schema change). This closes #5132 for the core attempt pipeline; #5135 (the autonomous supervising loop) remains as separate, explicitly-flagged safety-critical follow-up work.
JSONbored
added a commit
that referenced
this pull request
Jul 12, 2026
Closes #5132 The final assembly: attempt-cli.js now fetches a real SelfReviewContext (#5145), builds a real coding-task spec (#5239, blocking on an infeasible verdict), resolves the real AmsPolicySpec execution policy (#5249, extended here with maxIterations/maxTurnsPerIteration -- the same operator-risk-policy gap capLimits/submissionMode/slopThreshold already covered), assembles the real IterateLoopInput + Governor chokepoint context, and calls runMinerAttempt for real -- the first point in this epic where a real coding agent actually executes rather than every path ending in a reported block. New attempt-input-builder.js holds the two pure composers (buildAttemptGovernorContext, buildAttemptLoopInput) so the assembly logic is independently unit-tested, mirroring coding-task-spec.js's own precedent. Real outcomes now surface distinct exit codes: 0 (submitted), 7 (abandon), 8 (stale), 9 (blocked by submission gate), 10 (governed), plus the existing 4 (blocked_infeasible, repurposed from the old blocked_missing_prerequisite placeholder), 5 (rejection_signaled), 6 (worktree_preparation_failed). The worktree is cleaned up on submission, retained on any other real outcome for post-mortem inspection (cleanupAttemptWorktree's own retention policy). KNOWN, DOCUMENTED GAPS (not fabricated -- see attempt-input-builder.js and attempt-cli.js's own header comments): - governor.killSwitchRepoPaused only checks the GLOBAL env-var kill switch; a real per-repo .gittensory-miner.yml pause needs miner-goal-spec.js (#5255, open) wired in as a fast-follow. - governor.convergenceInput is an honest first-attempt-shaped literal, not a real per-issue attempt-history query -- attempt-log.js's schema has no repo+issue index, and reenqueue counts aren't tracked anywhere yet (non-convergence.ts's own header: that belongs on the portfolio-queue table once it grows attempt-history columns, a real separate schema change). This closes #5132 for the core attempt pipeline; #5135 (the autonomous supervising loop) remains as separate, explicitly-flagged safety-critical follow-up work.
JSONbored
added a commit
that referenced
this pull request
Jul 12, 2026
…5261) * feat(miner): wire the real runMinerAttempt call into attempt-cli.js Closes #5132 The final assembly: attempt-cli.js now fetches a real SelfReviewContext (#5145), builds a real coding-task spec (#5239, blocking on an infeasible verdict), resolves the real AmsPolicySpec execution policy (#5249, extended here with maxIterations/maxTurnsPerIteration -- the same operator-risk-policy gap capLimits/submissionMode/slopThreshold already covered), assembles the real IterateLoopInput + Governor chokepoint context, and calls runMinerAttempt for real -- the first point in this epic where a real coding agent actually executes rather than every path ending in a reported block. New attempt-input-builder.js holds the two pure composers (buildAttemptGovernorContext, buildAttemptLoopInput) so the assembly logic is independently unit-tested, mirroring coding-task-spec.js's own precedent. Real outcomes now surface distinct exit codes: 0 (submitted), 7 (abandon), 8 (stale), 9 (blocked by submission gate), 10 (governed), plus the existing 4 (blocked_infeasible, repurposed from the old blocked_missing_prerequisite placeholder), 5 (rejection_signaled), 6 (worktree_preparation_failed). The worktree is cleaned up on submission, retained on any other real outcome for post-mortem inspection (cleanupAttemptWorktree's own retention policy). KNOWN, DOCUMENTED GAPS (not fabricated -- see attempt-input-builder.js and attempt-cli.js's own header comments): - governor.killSwitchRepoPaused only checks the GLOBAL env-var kill switch; a real per-repo .gittensory-miner.yml pause needs miner-goal-spec.js (#5255, open) wired in as a fast-follow. - governor.convergenceInput is an honest first-attempt-shaped literal, not a real per-issue attempt-history query -- attempt-log.js's schema has no repo+issue index, and reenqueue counts aren't tracked anywhere yet (non-convergence.ts's own header: that belongs on the portfolio-queue table once it grows attempt-history columns, a real separate schema change). This closes #5132 for the core attempt pipeline; #5135 (the autonomous supervising loop) remains as separate, explicitly-flagged safety-critical follow-up work. * fix(miner): use a real FocusManifest fixture in attempt-cli tests CI's typecheck (not caught by an earlier stale local tsc run -- incremental cache silently no-op'd) correctly failed: the hand-rolled {present, settings, gate, warnings} manifest fixture doesn't satisfy FocusManifest's real shape (source, wantedPaths, preferredLabels, linkedIssuePolicy, and 8 more required fields). Uses the engine's own parseFocusManifest(undefined) to build a genuinely valid absent manifest instead, and drops the `as never` cast in miner-attempt-input-builder.test.ts that was silently working around the same gap there. * fix(miner): use a real RepositoryRecord shape in attempt-cli test fixtures CI's typecheck (again not caught locally -- verified this time with a genuinely fresh tsc run, all .tsbuildinfo caches cleared) correctly failed: the hand-rolled repo fixture used the wrong field names entirely (private/ownerLogin) instead of RepositoryRecord's real shape (isPrivate/owner, plus required isInstalled/isRegistered).
This was referenced Jul 14, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Advances #5132
runMinerAttemptrequiressubmissionMode/slopThreshold/capLimits/convergenceThresholds, none of which had any config or env backing anywhere in the codebase -- pure policy dials that would otherwise get hardcoded with no way to tune them.Adds
AmsPolicySpec(engine package, a structural sibling toMinerGoalSpec) andresolveAmsPolicy(miner package), mirroring.gittensory.yml's own established self-host precedent (src/selfhost/private-config.ts'smakeLocalManifestReader, whose own doc comment says the operator's local file "takes priority over -- and fully REPLACES -- the public.gittensory.yml"): a target repo may propose a.gittensory-ams.ymldefault, but the operator's own local copy (in theirgittensory-minerconfig dir), when present, fully replaces it -- never a field-by-field merge.This boundary is deliberate:
MinerGoalSpec(.gittensory-miner.yml) is what a target repo wants from being mined (paths, labels, opt-out) -- that's legitimately the repo's own call.AmsPolicySpecis how aggressive the operator wants their own agent to be (budget, submission mode, slop threshold) -- a repo's own checked-in file must never get to loosen what an operator's agent is willing to do against that same repo, since that would let a malicious/compromised repo talk an operator's miner into raising its own risk tolerance. A repo's file can only ever propose a fallback default for an unconfigured operator.Deny-by-default:
submissionModedefaults to"observe"(computes real decisions, never actually submits) andslopThresholdto"low"(strict), matching the codebase's own stated deny-by-default conventions (src/settings/autonomy.ts'sAUTONOMY_LEVELS).Test plan
node --test packages/gittensory-engine/test/ams-policy-spec-parser.test.ts-- 9/9 (missing/malformed input, every field's normalization + rejection, JSON/YAML parsing, oversized content)node --test packages/gittensory-engine/test/*.test.ts-- full engine suite, 519/519 passingnpx vitest run test/unit/miner-ams-policy.test.ts-- 9/9 (config-path precedence, defaults-when-neither-exists, repo-file fallback, local-fully-replaces-repo regression, never-fetches-once-local-found, malformed-local-file, malformed-repoFullName, network-error,.github/+.jsoncandidate paths)npm run test:engine-paritynode --check packages/gittensory-miner/lib/ams-policy.jsnpm run --prefix packages/gittensory-miner build(addedams-policy.jsto the check list)