Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ output/
.env.*
!.env.example
# Operator-filled miner secrets for docker-compose fleet mode (#5177); the .example is committed.
.gittensory-miner.env
!.gittensory-miner.env.example
.loopover-miner.env
!.loopover-miner.env.example
!.env.selfhost.example
# Docker Compose secret files: the actual secret VALUES an operator drops into
# secrets/<name>.txt for the native `secrets:` mount (docker-compose.yml), read via the existing generic
Expand Down
8 changes: 4 additions & 4 deletions .gittensory-ams.yml.example → .loopover-ams.yml.example
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# ============================================================================
# .gittensory-ams.yml - operator execution policy (EXAMPLE)
# .loopover-ams.yml - operator execution policy (EXAMPLE)
# ============================================================================
# This is the OPERATOR's own execution-risk policy for their autonomous miner
# (AMS) -- a deliberate structural sibling to `.gittensory-miner.yml`
# (AMS) -- a deliberate structural sibling to `.loopover-miner.yml`
# (MinerGoalSpec), but answering a different question. MinerGoalSpec is what a
# TARGET REPO wants from being mined (paths, labels, whether it's minable at
# all). This file is how aggressive the OPERATOR wants their own agent to be
Expand All @@ -11,7 +11,7 @@
# willing to do -- see below for why.
#
# OPERATOR-LOCAL ONLY: the miner reads this file from the operator's local
# gittensory-miner config dir. It intentionally does not fetch a target repo's
# loopover-miner config dir. It intentionally does not fetch a target repo's
# checked-in AMS policy, because untrusted repo content must not loosen
# operator-side budget, turn, slop, or submission controls.
#
Expand All @@ -20,7 +20,7 @@
# ignored, and a single malformed field falls back to its default with a
# warning.
#
# Copy to `.gittensory-ams.yml` and edit. YAML or JSON are both accepted.
# Copy to `.loopover-ams.yml` and edit. YAML or JSON are both accepted.

# Whether a real attempt is allowed to actually submit (open a PR), or only
# compute + log its decision. "observe" still runs every real signal/decision
Expand Down
14 changes: 7 additions & 7 deletions .gittensory-miner.env.example → .loopover-miner.env.example
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# gittensory-miner — starter env file
# loopover-miner — starter env file
#
# Copy this to `.gittensory-miner.env` (gitignored), fill in GITHUB_TOKEN, then either `source` it or
# Copy this to `.loopover-miner.env` (gitignored), fill in GITHUB_TOKEN, then either `source` it or
# point docker-compose / systemd at it — see packages/loopover-miner/DEPLOYMENT.md:
#
# cp .gittensory-miner.env.example .gittensory-miner.env
# cp .loopover-miner.env.example .loopover-miner.env
#
# Every value below is a SAMPLE placeholder — never commit real secrets. For the generated,
# always-current table of every miner env var and its default, see
Expand Down Expand Up @@ -31,13 +31,13 @@ GITHUB_TOKEN=ghp_your_token_here
# 3. Optional overrides — defaults are fine for a single-machine install
# =============================================================================
# By default all local state lives under LOOPOVER_MINER_CONFIG_DIR (else $XDG_CONFIG_HOME, else
# ~/.config), in a gittensory-miner/ subdirectory. Set the base dir, or any individual store path,
# ~/.config), in a loopover-miner/ subdirectory. Set the base dir, or any individual store path,
# only to relocate state (e.g. onto a dedicated volume).
# LOOPOVER_MINER_CONFIG_DIR=/var/lib/gittensory-miner
# LOOPOVER_MINER_CONFIG_DIR=/var/lib/loopover-miner

# Repo clones and git worktrees created during attempts:
# LOOPOVER_MINER_REPO_CLONE_DIR=/var/lib/gittensory-miner/clones
# LOOPOVER_MINER_WORKTREE_DIR=/var/lib/gittensory-miner/worktrees
# LOOPOVER_MINER_REPO_CLONE_DIR=/var/lib/loopover-miner/clones
# LOOPOVER_MINER_WORKTREE_DIR=/var/lib/loopover-miner/worktrees

# Per-store SQLite file overrides (each defaults to a file under the config dir above):
# LOOPOVER_MINER_CLAIM_LEDGER_DB=
Expand Down
10 changes: 5 additions & 5 deletions .gittensory-miner.yml.example → .loopover-miner.yml.example
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
# ============================================================================
# .gittensory-miner.yml - per-repo miner configuration (EXAMPLE)
# .loopover-miner.yml - per-repo miner configuration (EXAMPLE)
# ============================================================================
# A repo owner drops this file in to tell an autonomous Gittensory miner what to
# look for and how to behave when targeting their repo. It is the MINER-side
# analogue of `.gittensory.yml` (the review-side focus manifest).
# analogue of `.loopover.yml` (the review-side focus manifest).
#
# Every field is OPTIONAL and has a safe default (shown as "Default: X" below).
# The file is parsed tolerantly: an unknown key is ignored, and a single
# malformed field falls back to its default with a warning - a broken file never
# hard-fails the miner, it just falls back to the defaults.
#
# Discovery order (first match wins):
# .gittensory-miner.yml -> .github/gittensory-miner.yml
# -> .gittensory-miner.json -> .github/gittensory-miner.json
# .loopover-miner.yml -> .github/loopover-miner.yml
# -> .loopover-miner.json -> .github/loopover-miner.json
#
# Copy to `.gittensory-miner.yml` and edit. YAML or JSON are both accepted.
# Copy to `.loopover-miner.yml` and edit. YAML or JSON are both accepted.

# Whether this repo permits autonomous miners at all. Explicit OPT-OUT: a public
# repo with no file is still minable. Set false to halt all miner targeting.
Expand Down
12 changes: 6 additions & 6 deletions packages/loopover-engine/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -630,7 +630,7 @@ module defines the storage contract only — it does not wire into live governor

## MinerGoalSpec

`MinerGoalSpec` is the type surface for a repo's `.gittensory-miner.yml` (miner-side analogue of `.loopover.yml`).
`MinerGoalSpec` is the type surface for a repo's `.loopover-miner.yml` (miner-side analogue of `.loopover.yml`).
`DEFAULT_MINER_GOAL_SPEC` is the safe default a repo with no file behaves as — minable (`minerEnabled: true`, an
explicit opt-out), no path/label preferences, one concurrent claim, `neutral` discovery.

Expand All @@ -639,13 +639,13 @@ never throw on malformed JSON/YAML; instead they return `{ present, spec, warnin
safe defaults and `warnings` explains any dropped or invalid fields.

`discoverMinerGoalSpecPath(exists)` returns the first present file in the documented order (`MINER_GOAL_SPEC_FILENAMES`:
`.gittensory-miner.yml` → `.github/gittensory-miner.yml` → the `.json` variants). It is IO-free — the caller injects
`.loopover-miner.yml` → `.github/loopover-miner.yml` → the `.json` variants). It is IO-free — the caller injects
the existence check — so a caller reads the returned path and feeds its content to `parseMinerGoalSpecContent`. See
`.gittensory-miner.yml.example` for the documented fields.
`.loopover-miner.yml.example` for the documented fields.

## AmsPolicySpec

`AmsPolicySpec` is the type surface for `.gittensory-ams.yml` — the OPERATOR's own execution-risk policy for
`AmsPolicySpec` is the type surface for `.loopover-ams.yml` — the OPERATOR's own execution-risk policy for
their miner (`submissionMode`, `slopThreshold`, `capLimits`, `convergenceThresholds`, `maxIterations`,
`maxTurnsPerIteration`), a deliberate structural sibling to `MinerGoalSpec` but answering a different question: `MinerGoalSpec` is what the target repo wants
from being mined; `AmsPolicySpec` is how aggressive the operator wants their own agent to be. No field on this
Expand All @@ -656,11 +656,11 @@ submission mode (computes real decisions but never actually submits) and a `"low
`parseAmsPolicySpec(raw)` / `parseAmsPolicySpecContent(content)` are the same tolerant-parser pair shape as
`MinerGoalSpec`'s — never throw, return `{ present, spec, warnings }`.

Unlike `MinerGoalSpec`, this package does not resolve `.gittensory-ams.yml` from the filesystem itself (this
Unlike `MinerGoalSpec`, this package does not resolve `.loopover-ams.yml` from the filesystem itself (this
package is IO-free) — `packages/loopover-miner/lib/ams-policy.js`'s `resolveAmsPolicy` is the real caller.
That resolver reads only the operator's local policy and otherwise uses safe defaults; it intentionally does not
fetch a target repo's checked-in AMS policy, because untrusted repo content must not loosen operator-side budget,
turn, slop, or submission controls. See `.gittensory-ams.yml.example`.
turn, slop, or submission controls. See `.loopover-ams.yml.example`.

## Repo map builder

Expand Down
20 changes: 10 additions & 10 deletions packages/loopover-engine/src/ams-policy-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import { parse as parseYaml } from "yaml";

import { DEFAULT_PORTFOLIO_CONVERGENCE_THRESHOLDS, type PortfolioConvergenceThresholds } from "./portfolio/non-convergence.js";

// AmsPolicySpec (#5132, Wave 3.5 follow-up). The type surface for `.gittensory-ams.yml` -- the OPERATOR's own
// AmsPolicySpec (#5132, Wave 3.5 follow-up). The type surface for `.loopover-ams.yml` -- the OPERATOR's own
// execution-risk policy for their miner (AMS: the autonomous mining system this file's fields configure), as
// opposed to `.gittensory-miner.yml` / MinerGoalSpec (this file's direct structural sibling), which is the
// opposed to `.loopover-miner.yml` / MinerGoalSpec (this file's direct structural sibling), which is the
// TARGET REPO's own preferences about being mined at all. That distinction is deliberate and load-bearing: a
// target repo's own checked-in file legitimately gets to say "don't mine me" or "focus on these paths" --
// but it must NEVER get to say "let the operator's agent spend more budget" or "submit live instead of
Expand All @@ -13,7 +13,7 @@ import { DEFAULT_PORTFOLIO_CONVERGENCE_THRESHOLDS, type PortfolioConvergenceThre
// repo could use to loosen what an operator's agent is willing to do.
//
// Resolution deliberately stays operator-local: packages/loopover-miner/lib/ams-policy.js reads only the
// operator's own local `.gittensory-ams.yml` (in their `gittensory-miner` config dir) and otherwise uses safe
// operator's own local `.loopover-ams.yml` (in their `loopover-miner` config dir) and otherwise uses safe
// defaults. It does not fetch a target repo's checked-in file, because that would let untrusted repo content
// loosen operator-side budget, turn, slop, or submission controls.

Expand All @@ -36,7 +36,7 @@ export type AmsCapLimits = {
elapsedMs: number;
};

/** Per-operator AMS execution policy parsed from `.gittensory-ams.yml`. See {@link DEFAULT_AMS_POLICY_SPEC}. */
/** Per-operator AMS execution policy parsed from `.loopover-ams.yml`. See {@link DEFAULT_AMS_POLICY_SPEC}. */
export type AmsPolicySpec = {
/** Whether a real attempt may actually submit. Default: "observe" (deny-by-default). */
submissionMode: AmsSubmissionMode;
Expand All @@ -53,15 +53,15 @@ export type AmsPolicySpec = {
maxTurnsPerIteration: number;
};

/** The tolerant parser result for `.gittensory-ams.yml`. Mirrors `ParsedMinerGoalSpec`'s present/warnings shape. */
/** The tolerant parser result for `.loopover-ams.yml`. Mirrors `ParsedMinerGoalSpec`'s present/warnings shape. */
export type ParsedAmsPolicySpec = {
present: boolean;
spec: AmsPolicySpec;
warnings: string[];
};

/**
* The safe defaults applied when a field is absent from `.gittensory-ams.yml` (or the file itself is
* The safe defaults applied when a field is absent from `.loopover-ams.yml` (or the file itself is
* missing). Deep-frozen: a shared singleton, clone before layering overrides on top.
*/
export const DEFAULT_AMS_POLICY_SPEC: Readonly<AmsPolicySpec> = Object.freeze({
Expand Down Expand Up @@ -183,7 +183,7 @@ function utf8ByteLength(value: string): number {
}

/**
* Tolerantly normalize an already-parsed `.gittensory-ams.yml` object into a {@link ParsedAmsPolicySpec}.
* Tolerantly normalize an already-parsed `.loopover-ams.yml` object into a {@link ParsedAmsPolicySpec}.
* Never throws: malformed shapes degrade to safe defaults and accumulate warnings.
*/
export function parseAmsPolicySpec(raw: unknown): ParsedAmsPolicySpec {
Expand Down Expand Up @@ -218,7 +218,7 @@ export function parseAmsPolicySpec(raw: unknown): ParsedAmsPolicySpec {
}

/**
* Parse raw `.gittensory-ams.yml` file content (JSON or YAML). Malformed content degrades to an absent
* Parse raw `.loopover-ams.yml` file content (JSON or YAML). Malformed content degrades to an absent
* policy spec with a warning rather than throwing, mirroring `parseMinerGoalSpecContent`.
*/
export function parseAmsPolicySpecContent(content: string | null | undefined): ParsedAmsPolicySpec {
Expand All @@ -241,5 +241,5 @@ export function parseAmsPolicySpecContent(content: string | null | undefined): P
return parseAmsPolicySpec(parsed);
}

/** The documented `.gittensory-ams` file-discovery order (first match wins), mirroring `MINER_GOAL_SPEC_FILENAMES`. */
export const AMS_POLICY_SPEC_FILENAMES = [".gittensory-ams.yml", ".github/gittensory-ams.yml", ".gittensory-ams.json", ".github/gittensory-ams.json"] as const;
/** The documented `.loopover-ams` file-discovery order (first match wins), mirroring `MINER_GOAL_SPEC_FILENAMES`. */
export const AMS_POLICY_SPEC_FILENAMES = [".loopover-ams.yml", ".github/loopover-ams.yml", ".loopover-ams.json", ".github/loopover-ams.json"] as const;
2 changes: 1 addition & 1 deletion packages/loopover-engine/src/fleet-run-manifest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { parse as parseYaml } from "yaml";

// FleetRunManifest (#4299). The top-level config a *fleet operator* authors to run the miner across many repos:
// which repos are in scope for a fleet run, and how a finite worktree/concurrency budget is split between them.
// This is the OPERATOR-side analogue of, and deliberately NOT the same file as, `.gittensory-miner.yml` (see
// This is the OPERATOR-side analogue of, and deliberately NOT the same file as, `.loopover-miner.yml` (see
// miner-goal-spec.ts): that one is authored by a *target repo's maintainer* to say how their one repo wants to be
// approached. Same tolerant-parser convention (every field optional, unknown keys ignored, malformed input
// degrades to a documented default with a warning rather than throwing); opposite author and direction of intent.
Expand Down
2 changes: 1 addition & 1 deletion packages/loopover-engine/src/focus-manifest.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* Focus-manifest parse/compile core (#2280). Extracted to `@loopover/engine` so the maintainer
* review stack and the miner's goal-spec parser share identical, versioned manifest logic instead of drifting
* apart. This is the MINER-side parse-pattern template for {@link MinerGoalSpec} (`.gittensory-miner.yml`) —
* apart. This is the MINER-side parse-pattern template for {@link MinerGoalSpec} (`.loopover-miner.yml`) —
* same tolerant-parser shape: typed config + safe defaults + warnings, never throws.
*
* App-local resolver/guidance functions (`resolveEffectiveSettings`, `buildFocusManifestGuidance`, etc.) remain
Expand Down
2 changes: 1 addition & 1 deletion packages/loopover-engine/src/governor/action-mode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export function isGlobalMinerLiveModeOptIn(env: Record<string, string | undefine
/**
* Resolve the miner's overall action mode. Precedence (safest wins, mirroring `resolveAgentActionMode`):
* 1. Kill-switch active (either scope, #2341) -> `"paused"` -- always wins, regardless of any live-mode opt-in.
* 2. BOTH the operator's global env config AND the target repo's own `.gittensory-miner.yml`
* 2. BOTH the operator's global env config AND the target repo's own `.loopover-miner.yml`
* (`MinerGoalSpec.execution.liveModeOptIn`) explicitly opt in -> `"live"`. The repo field is a repo-side
* allowance, not an operator-authored authorization to execute writes under the miner's credentials.
* 3. Otherwise -> `"dry_run"`. No config anywhere, either side omitted, or a malformed/partial config that fails
Expand Down
2 changes: 1 addition & 1 deletion packages/loopover-engine/src/governor/kill-switch.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Governor kill-switch (#2341): the emergency-halt primitive every write-adjacent governor decision consults
// FIRST, before any other calculator. Two independent triggers compose into one scope: a GLOBAL env-level
// switch that halts every repo at once, and a PER-REPO switch (from `.gittensory-miner.yml`'s MinerGoalSpec
// switch that halts every repo at once, and a PER-REPO switch (from `.loopover-miner.yml`'s MinerGoalSpec
// `killSwitch.paused` field) that halts only its own repo's queue while leaving the rest of the fleet running.
// Mirrors `src/settings/agent-execution.ts`'s `isGlobalAgentPause` truthy-string idiom for the review-stack's
// own kill-switch (#776) — a parallel mechanism for the miner's own local runtime, not the same one.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export type SelfReputationThresholds = {
minCadenceFactor: number;
};

/** Conservative built-in defaults; a `.gittensory-miner.yml` override is merged over these. */
/** Conservative built-in defaults; a `.loopover-miner.yml` override is merged over these. */
export const DEFAULT_SELF_REPUTATION_THRESHOLDS: SelfReputationThresholds =
Object.freeze({
minSampleSize: 5,
Expand Down Expand Up @@ -64,7 +64,7 @@ function round3(value: number): number {
}

/**
* Merge a partial (e.g. `.gittensory-miner.yml`-sourced) threshold config over the conservative defaults,
* Merge a partial (e.g. `.loopover-miner.yml`-sourced) threshold config over the conservative defaults,
* normalizing every field so a malformed value can never produce a NaN/negative/out-of-range decision. The
* throttle band is kept well-formed: `floorAtRatio` is pulled to at least `throttleAtRatio` so the interpolation
* span is never negative.
Expand Down
2 changes: 1 addition & 1 deletion packages/loopover-engine/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -607,7 +607,7 @@ export {
type ContributorCalibrationSignal,
} from "./predicted-gate.js";
// Focus-manifest parse/compile core (#2280): shared by the maintainer review stack and the miner's
// `.gittensory-miner.yml` goal-spec parser (see miner-goal-spec.ts for the parallel surface).
// `.loopover-miner.yml` goal-spec parser (see miner-goal-spec.ts for the parallel surface).
export {
compileFocusManifestPolicy,
contentLaneConfigToJson,
Expand Down
Loading