gardenbundle

package
v0.53.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 8, 2026 License: Apache-2.0 Imports: 13 Imported by: 0

Documentation

Overview

Package gardenbundle is the garden bundle -- one default-on fold over the repo's read-only gardening passes.

fak already measures itself with several orchestrators, each folding a different slice of repo health, and each run by hand or in CI but never as ONE thing:

  • tools/scorecard_control_pane.py folds the scorecard family into one portfolio total_debt with a pinned-baseline ratchet (--check).
  • tools/fresh_status.py folds the four top-level domains (git, benchmarks, work, industry) into one cross-domain snapshot.
  • tools/fleet_control_pane.py loop-audit runs the gardening loop catalog and buckets each loop healthy / action / broken.

This is the fold over those folds -- the single read-only "is the garden tended?" verdict, so "run the gardening" is one command instead of three. It is deliberately READ-ONLY: it runs each member (which stay grandfathered Python tools), reads each member's control-pane JSON payload, and folds one schema/ok/verdict/finding/reason/next_action envelope. It mutates nothing and fixes nothing -- auto-fix is a later, witness-gated rung.

--check is the bundle's CI contract: it exits non-zero when any gating member reports a hard regression (today only the scorecard ratchet gates; fresh-status and loop-audit are advisory panes that surface conditions without failing the bundle). A member that fails to RUN (errored) always trips the gate, so a silently-broken pass can't masquerade as a clean garden.

The bundle is skipped entirely when FAK_GARDEN is set to an off value (0/off/false/no/disable/disabled) -- the env-side half of the governor brake.

The pure, tested surface is Interpret (fold one member payload into a uniform row), Fold (fold member rows into one envelope) and CheckGate (the CI gate decision over a folded payload). The live runner shells out to python3 tools/<x>.py exactly as the Python version did.

Beyond the read-only fold, two ACT-side passes share this package:

  • tick.go (PlanTick) acts at the MEMBER level: it turns a member's surfaced stale-work condition into a documented, idempotent remediation (reap an expired lease, surface an orphan worklist) on a recurring cadence.
  • walk.go (PlanWalk) acts at the ITEM level: it walks the HUNDREDS of individual items a member surfaces (today the open-issue backlog) and folds them into a resource-aware, worst-first, budget-bounded worklist — skipping the in-progress/fresh/healthy items so a 300-item set yields a bounded proposal, not 300 reports. Both are pure and tested; the cmd verb performs the side effects and ledgers the run.

Full design: docs/notes/GARDENING-BUNDLE-DEFAULT-ON-2026-06-25.md.

Index

Constants

View Source
const Schema = "fak-garden-bundle/1"

Schema is the stable control-pane schema identifier for the bundle envelope.

View Source
const WalkSchema = "fak.garden-walk.v1"

Schema identifiers for the walk envelope.

Variables

View Source
var DeepMember = Member{
	Key:   "loop_audit",
	Label: "fleet loop-audit",
	Argv: []string{"tools/fleet_control_pane.py", "loop-audit",
		"--names", strings.Join(loopAuditNames, ","), "--json"},
	Gates: false,
	Kind:  "loop_audit",
}

DeepMember is the opt-in deep member (added by --deep). Non-gating advisory. It goes through fleet_control_pane's per-loop orchestration, which carries enough overhead that it doesn't belong on the default tick.

View Source
var Members = []Member{
	{
		Key:   "scorecard",
		Label: "scorecard control pane",
		Argv:  []string{"tools/scorecard_control_pane.py", "--check", "--json"},
		Gates: true,
		Kind:  "envelope",
	},
	{
		Key:   "propagation_scorecard",
		Label: "propagation scorecard",
		Argv:  []string{"fak", "propagation-scorecard", "--json"},
		Gates: false,
		Kind:  "envelope",
		Exec:  "command",
	},
	{
		Key:   "fresh_status",
		Label: "fresh status",
		Argv:  []string{"fak", "fresh-status", "--json"},
		Gates: false,
		Kind:  "envelope",
		Exec:  "command",
	},
	{

		Key:   "guard_route",
		Label: "guard-session route",
		Argv:  []string{"fak", "guard-verdict-rsi", "route", "--no-issues", "--json"},
		Gates: false,
		Kind:  "envelope",
		Exec:  "command",
	},
	{

		Key:   "sessions_learn",
		Label: "sessions learn",
		Argv:  []string{"fak", "sessions", "learn", "--corpus", "experiments/sessionobs/corpus.jsonl", "--json"},
		Gates: false,
		Kind:  "envelope",
		Exec:  "command",
	},
	{

		Key:   "orphaned_runs",
		Label: "orphaned runs",
		Argv:  []string{"fak", "loop", "recover", "--control-pane"},
		Gates: false,
		Kind:  "envelope",
		Exec:  "command",
	},
	{

		Key:   "release_staleness",
		Label: "release staleness",
		Argv:  []string{"fak", "release-staleness", "--json"},
		Gates: true,
		Kind:  "envelope",
		Exec:  "command",
	},
	{

		Key:          "stale_leases",
		Label:        "stale leases",
		Argv:         []string{"fak", "leaseref", "audit"},
		Gates:        false,
		Kind:         "envelope",
		Exec:         "command",
		ActOnVerdict: true,
	},
	{

		Key:   "windowgate",
		Label: "no desktop popups",
		Argv:  []string{"fak", "windowgate", "--json"},
		Gates: true,
		Kind:  "envelope",
		Exec:  "command",
	},
	{

		Key:   "growthgate",
		Label: "unbounded ledger growth",
		Argv:  []string{"fak", "growthgate", "--json"},
		Gates: false,
		Kind:  "envelope",
		Exec:  "command",
	},
}

Members is the DEFAULT bundle: the two fast, canonical folds that already speak the same control-pane envelope -- the scorecard control pane and fresh-status. It is deliberately small so a scheduled tick is fast and host-safe.

Functions

func AttentionTriageLine added in v0.38.0

func AttentionTriageLine(p WalkPlan) string

AttentionTriageLine renders the decenter split for a walk plan as one readout line: of the emitted worklist, how many genuinely wait on a person vs how many the fleet drives. Returns "" when nothing was emitted (an empty or all-skipped walk has no attention to split). Rendered only under FAK_GARDENWALK_TRIAGE_GATE=enforce.

func CheckGate

func CheckGate(p Payload) (int, string)

CheckGate is the CI gate decision over a folded payload (pure: exit code + message).

0  garden tended (clear or advisory-only)
1  a gating member regressed, or a member failed to run

func CollectBounded added in v0.44.0

func CollectBounded(root string, opt CollectOptions) ([]MemberResult, CollectProgress)

CollectBounded runs a checkpointed suffix of the member list. Collection used to run every member sequentially with a full per-member timeout, before the tick's phase budget even began. With ten members, that made a 900-second timeout an hours-scale aggregate allowance. This function instead:

  • never starts a member after the whole-tick budget is spent;
  • caps each member to min(per-member timeout, global time remaining);
  • checkpoints after every returned member; and
  • resumes at the first member not yet checkpointed.

A member killed by RunMember's timeout returns an errored row and collection advances best-effort. If the OUTER watchdog kills RunMember itself, the checkpoint remains on that member and the next tick retries it.

func DecisionNeedsHuman added in v0.38.0

func DecisionNeedsHuman(d WalkDecision) bool

DecisionNeedsHuman reports whether an emitted decision genuinely waits on a person — the enforce-mode replacement for "DispReview == needs you". True only for a real priority/policy/release authority; a ready-command act and a knowable classification review both return false even though PlanWalk emits the latter under DispReview.

func DefaultPython

func DefaultPython() string

DefaultPython is the exported form of defaultPython, so sibling packages (e.g. cadencereport) can share this one resolver instead of copying it.

func GardenOff

func GardenOff() bool

GardenOff reports whether FAK_GARDEN names an off value (the env-side governor brake).

func GardenWalkTriageEnforced added in v0.38.0

func GardenWalkTriageEnforced(mode string) bool

GardenWalkTriageEnforced reports whether the decenter split is active for the given mode string. Only "enforce" (case-insensitive) turns it on; "", "warn" and anything else leave the walk's worklist byte-for-byte unchanged so the fold can soak. Mirrors every other decenter seam's enforce/warn switch.

func HeadCommit

func HeadCommit(root string) string

HeadCommit returns the short HEAD commit of root, or "unknown".

func Render

func Render(p Payload) string

Render produces the human snapshot, mirroring the Python render().

func RunMember

func RunMember(root string, member Member, python string, timeout time.Duration) (map[string]any, int, string)

RunMember runs one member and parses its JSON stdout. A default ("" / "python") member runs Argv[0] as a repo python script under the interpreter; a "command" member runs Argv[0] as a direct executable. A "command" member whose Argv[0] is the bare token "fak" is rewritten to the CURRENTLY-RUNNING executable (os.Executable), so a Go-native member re-invokes the same built binary -- never `go run`, which would recompile the whole tree and so error whenever a peer's uncommitted edit leaves cmd/fak uncompilable on the shared trunk. It returns the parsed payload (nil on any failure), the process exit code, and an error string (empty on success).

func TriageDecision added in v0.38.0

func TriageDecision(d WalkDecision) choicetriage.Verdict

TriageDecision folds one emitted walk decision into its choicetriage disposition. The Signal is built from the decision's own fields — the ready Command is the strongest TAKE_OBVIOUS signal, and the Reason (the condition tags, e.g. "needs-area, likely-dup") carries the authority test: a reason naming priority/policy/release routes to HUMAN_RESIDUAL, everything else to FRESH_CONTEXT. Source is the neutral "garden" — never a token choicetriage reads as authority.

func TriageSelfcheck added in v0.38.0

func TriageSelfcheck() error

TriageSelfcheck is the deterministic, no-I/O proof of the walk fold: a ready-command act is the fleet's to run, a needs-area / needs-kind / likely-dup review is the fleet's to drive in a fresh context, and only an unset-priority review genuinely waits on a person. It is the witness the CLI surfaces as the walk's triage selfcheck.

Types

type ActDecision

type ActDecision struct {
	Key     string  `json:"key"`
	Label   string  `json:"label"`
	State   string  `json:"state"`
	Act     ActKind `json:"act"`
	Perform bool    `json:"perform"`
	Mode    string  `json:"mode"` // "act" or "dry-run"
	Reason  string  `json:"reason"`
	Detail  string  `json:"detail"`
}

ActDecision is one member's tick decision: which remediation applies, whether the tick will Perform it (false under --dry-run, or when the member is ok), and a human Reason. The cmd verb reads Perform+Act to do the side effect; Detail carries the member's own surfaced reason for the tick's witness record.

type ActKind

type ActKind string

ActKind is the closed set of remediations the garden tick can take. It is the per-member action policy from the ticket made into a typed value.

const (
	// ActNone: the member is ok, or has no registered remediation — nothing to do.
	ActNone ActKind = "none"
	// ActReap: an expired cross-machine lease lingers — delete the reapable
	// records (the `fak leaseref reap` remediation). Idempotent: a second reap of
	// an already-gone lease is a no-op.
	ActReap ActKind = "reap"
	// ActSurface: orphaned/unwitnessed runs exist — surface the recovery worklist
	// as a witnessed tick event so the operator can re-dispatch/re-verify
	// (re-dispatch stays gated, never automatic). Idempotent: one bounded event.
	ActSurface ActKind = "surface"
	// ActAdvisory: the member surfaced a condition whose remediation is owned
	// elsewhere (release_staleness -> #1367). Reported, never auto-acted by the tick.
	ActAdvisory ActKind = "advisory"
	// ActGrowthReap: an oversized, COLD, disposable log crossed its growthgate
	// budget — collect (reap) the reapable set. The growthgate detector already
	// runs on the tick, but its ACTION verdict was reported and never acted; this
	// binds it to the collector. Idempotent: an os.Remove of an already-gone file
	// is a no-op. Deletes stay default-off (ledger-only) until the soak opt-in
	// flips them on, so a surfaced verdict inherits surfacing + dry-run untouched.
	ActGrowthReap ActKind = "growth-reap"
)

type CollectOptions added in v0.44.0

type CollectOptions struct {
	Python           string
	PerMemberTimeout time.Duration
	Budget           time.Duration
	Start            time.Time
	Deep             bool
	// Next names the next member to run. Empty starts a fresh collection.
	Next string
	// Prior is the already-checkpointed prefix from previous ticks.
	Prior []MemberResult
	Now   func() time.Time
	Run   MemberRunner
	// Checkpoint is called after each returned member with the accumulated prefix
	// and the key of the next member (empty when collection completed).
	Checkpoint func(next string, results []MemberResult) error
}

CollectOptions makes member collection part of the tick's GLOBAL budget.

type CollectProgress added in v0.44.0

type CollectProgress struct {
	Total           int      `json:"total"`
	Completed       int      `json:"completed"`
	Ran             []string `json:"ran"`
	Deferred        []string `json:"deferred"`
	Next            string   `json:"next,omitempty"`
	Complete        bool     `json:"complete"`
	Exhausted       bool     `json:"exhausted"`
	Millis          int64    `json:"millis"`
	CheckpointError string   `json:"checkpoint_error,omitempty"`
}

CollectProgress is the typed resume account for one bounded collection pass.

type GardenIssue added in v0.37.0

type GardenIssue struct {
	Key           string `json:"key"`
	RecurrenceKey string `json:"recurrence_key"`
	MemberKey     string `json:"member_key"`
	Label         string `json:"label"`
	State         string `json:"state"`
	Verdict       string `json:"verdict"`
	Gates         bool   `json:"gates"`
	Severity      int    `json:"severity"`
	Debt          int    `json:"debt"`
	Detail        string `json:"detail,omitempty"`
	NextAction    string `json:"next_action"`
}

GardenIssue is the stable, deduplicable work item projected from one garden member. RecurrenceKey is intentionally deterministic: if the same member keeps surfacing the same class of condition across runs, downstream issue filers and ratchets can update one item instead of opening a fresh "garden red" note.

type GardenScore added in v0.37.0

type GardenScore struct {
	Score     int
	Debt      int
	TopIssues []GardenIssue
}

GardenScore is the scoreboard view of a garden payload. Score is 100 when the garden is clear and falls as debt rises; Debt is the additive unit used for trend/ratchet comparisons; TopIssues is bounded so the envelope stays small.

func ScoreResults added in v0.37.0

func ScoreResults(results []MemberResult) GardenScore

ScoreResults folds member rows into a deterministic score and a bounded worst-first worklist. It is deliberately pure: same member rows in, same score out, so scheduled runs can compare score/debt over time.

type Member

type Member struct {
	Key   string
	Label string
	Argv  []string
	Gates bool
	Kind  string // "envelope" or "loop_audit"
	// Exec selects how Argv is run. "" / "python" (the default) runs Argv[0] as a
	// repo python script under the resolved interpreter -- the shape every original
	// member uses. "command" runs Argv[0] as a direct executable with Argv[1:] as
	// its args (e.g. `go run ./cmd/fak ...`), so a Go-native member can join the
	// bundle without a python shim.
	Exec string
	// ActOnVerdict opts this member into VERDICT-DRIVEN state (#5003). A READ-ONLY
	// detector reports `ok: true` unconditionally -- reporting IS the pass working --
	// and carries its finding in `verdict: ACTION`. Interpret derives State from `ok`
	// alone, so such a member folds to "ok" no matter what it found and PlanTick, which
	// acts only on "action"/"red", can never reach its registered remediation. With
	// this set, an ok=true payload whose verdict is ACTION folds to State "action"
	// while OK stays true -- the condition becomes actionable without gating the
	// garden red. It is OPT-IN PER MEMBER on purpose: a blanket promotion would newly
	// arm file-deleting remediations (growthgate) off an advisory verdict.
	ActOnVerdict bool
}

Member binds a label to the argv that produces its control-pane payload and whether a RED verdict from that member GATES the bundle (--check exits non-zero). The scorecard ratchet is the only hard gate today; the others are advisory panes whose ACTION verdict is a surfaced condition, not a broken garden.

func CollectionMembers added in v0.44.0

func CollectionMembers(deep bool) []Member

CollectionMembers returns a copy of the ordered member list one collection cycle must visit. Callers may safely append or slice the result.

type MemberResult

type MemberResult struct {
	Key      string `json:"key"`
	Label    string `json:"label"`
	Gates    bool   `json:"gates"`
	ExitCode int    `json:"exit_code"`
	State    string `json:"state"`
	OK       bool   `json:"ok"`
	Verdict  string `json:"verdict"`
	Detail   string `json:"detail"`
	// Counts carries the loop-audit bucket counts; nil for envelope members.
	Counts map[string]int `json:"counts,omitempty"`
}

MemberResult is the bundle's normalization of one member into a uniform row. State is one of:

  • "ok" -- the member ran and reports nothing to do
  • "action" -- the member ran and surfaces a real condition (advisory)
  • "red" -- the member's gate tripped (a hard regression)
  • "errored" -- the member could not run / produced no usable payload

func Collect

func Collect(root, python string, timeout time.Duration, deep bool) []MemberResult

Collect runs every member (plus the deep member when deep is set) and folds each into a MemberResult.

func Interpret

func Interpret(member Member, payload map[string]any, exitCode int, err string) MemberResult

Interpret folds one member's raw payload into a uniform member-result row. payload is nil when the member produced no usable payload.

func (MemberResult) MarshalJSON

func (r MemberResult) MarshalJSON() ([]byte, error)

MarshalJSON emits the same field set and order as the Python member row.

type MemberRunner added in v0.44.0

type MemberRunner func(root string, member Member, python string, timeout time.Duration) (map[string]any, int, string)

MemberRunner is the injectable RunMember seam used by CollectBounded tests.

type Payload

type Payload struct {
	OK          bool
	Verdict     string
	Finding     string
	Reason      string
	NextAction  string
	Workspace   string
	Commit      string
	Members     []MemberResult
	MemberCount int
	Gating      []string
	Skipped     bool
	// contains filtered or unexported fields
}

Payload is one folded garden-bundle control-pane envelope.

func Fold

func Fold(results []MemberResult, workspace, commit string) Payload

Fold folds member results into one garden-bundle control-pane payload.

func SkippedPayload

func SkippedPayload(workspace, commit string) Payload

SkippedPayload is the well-formed payload for an FAK_GARDEN=off skip (still ok=True).

func (Payload) MarshalJSON

func (p Payload) MarshalJSON() ([]byte, error)

MarshalJSON emits the same field set and order as the Python payload.

func (Payload) WithGate

func (p Payload) WithGate(code int, message string) Payload

WithGate returns a copy of the payload reconciled to a CheckGate decision, for the --check --json envelope.

type TickPlan

type TickPlan struct {
	DryRun    bool          `json:"dry_run"`
	Decisions []ActDecision `json:"decisions"`
	// ToReap / ToSurface count the members the tick WILL act on (0 under dry-run).
	ToReap    int `json:"to_reap"`
	ToSurface int `json:"to_surface"`
	// Advisory counts members surfacing a condition acted on elsewhere.
	Advisory int `json:"advisory"`
}

TickPlan is the folded act-pass plan: the per-member decisions plus the summary counts the verb and its witness event report.

func PlanTick

func PlanTick(results []MemberResult, dryRun bool) TickPlan

PlanTick folds member results into the act-pass plan. It is pure: same results + dryRun in, same plan out, no I/O. dryRun=true forces every decision to Perform=false / Mode="dry-run" (acts on nothing).

func (TickPlan) Acted

func (p TickPlan) Acted() bool

Acted reports whether the plan performed any real side effect (false under dry-run, or when every member was ok). The verb uses it to decide whether to stamp a "tick acted" vs "tick clean" witness summary.

type WalkDecision added in v0.37.0

type WalkDecision struct {
	ID          int             `json:"id"`
	Title       string          `json:"title"`
	Score       int             `json:"score"`
	IdleDays    int             `json:"idle_days"`
	Disposition WalkDisposition `json:"disposition"`
	Action      string          `json:"action,omitempty"`
	Command     string          `json:"cmd,omitempty"`
	Perform     bool            `json:"perform"`
	Reason      string          `json:"reason,omitempty"`
}

WalkDecision is one budgeted item's outcome: which handling applies, whether the walk would Perform it (act + not dry-run), and the ready command.

func WalkAttentionSplit added in v0.38.0

func WalkAttentionSplit(p WalkPlan) (needHuman, fleetDrives []WalkDecision)

WalkAttentionSplit partitions the plan's emitted worklist into the decisions that genuinely wait on a person and the ones the fleet drives itself. Deterministic: it walks plan.Decisions in their already-sorted worst-first order.

type WalkDisposition added in v0.37.0

type WalkDisposition string

WalkDisposition is the closed set of per-item outcomes the walk assigns.

const (
	// DispAct: a concrete, low-judgment gardening action with a ready command
	// (close a dormant question, mark a stale issue). Eligible to Perform.
	DispAct WalkDisposition = "act"
	// DispReview: the item surfaces a condition that needs human judgment
	// (needs-area / needs-kind / likely-dup). Surfaced, never auto-performed.
	DispReview WalkDisposition = "review"
	// DispSkip: nothing to do — the item is healthy (no condition) or fresh
	// (touched within the freshness window). Counted, never emitted in detail.
	DispSkip WalkDisposition = "skip"
)

type WalkItem added in v0.37.0

type WalkItem struct {
	ID       int
	Title    string
	Score    int
	IdleDays int
	// InProgress marks an item already being actively worked (the source's own
	// "someone is on it" signal, e.g. the in-progress label). The cheapest, most
	// reliable resource pre-filter: re-surfacing an item under active work is waste,
	// and unlike IdleDays it is immune to bot churn bumping the timestamp.
	InProgress bool
	// Disposition is the source's classification BEFORE the resource policy: act,
	// review, or skip (healthy). PlanWalk may downgrade act/review to skip when the
	// item is fresh or in-progress, but never upgrades a skip.
	Disposition WalkDisposition
	// Action is the action kind (e.g. "mark-stale"); Command is the ready-to-run
	// shell command for an act (empty for review/skip). Reason explains the tags.
	Action  string
	Command string
	Reason  string
}

WalkItem is one classified garden item handed to the pure planner. The caller (the cmd verb) does the source-specific classification (the issue gardener's tags/score/action) and fills these fields; PlanWalk decides per-item handling and applies the resource policy. Source-agnostic on purpose: an issue, a trajectory turn, or an orphaned run all reduce to (id, score, idle, disposition).

type WalkPlan added in v0.37.0

type WalkPlan struct {
	Schema     string         `json:"schema"`
	Source     string         `json:"source"`
	DryRun     bool           `json:"dry_run"`
	Budget     int            `json:"budget"`
	Total      int            `json:"total"`     // items walked
	Active     int            `json:"active"`    // cheap-skipped: actively in-progress
	Fresh      int            `json:"fresh"`     // cheap-skipped: idle < SkipFreshDays
	Healthy    int            `json:"healthy"`   // skipped: no condition
	Attention  int            `json:"attention"` // act+review needing follow-up (pre-budget)
	Acted      int            `json:"acted"`     // act decisions emitted (Perform under !dry-run)
	Review     int            `json:"review"`    // review decisions emitted
	Deferred   int            `json:"deferred"`  // attention items beyond budget -> next pass
	Decisions  []WalkDecision `json:"decisions"` // budgeted, worst-first
	OK         bool           `json:"ok"`
	Verdict    string         `json:"verdict"`
	Finding    string         `json:"finding"`
	Reason     string         `json:"reason"`
	NextAction string         `json:"next_action"`
}

WalkPlan is the folded walk: the resource counts plus the bounded, worst-first worklist. It carries the control-pane envelope fields so it speaks the same schema/ok/verdict/reason/next_action language as the rest of the garden and can join the bundle as a member later.

func PlanWalk added in v0.37.0

func PlanWalk(source string, items []WalkItem, policy WalkPolicy) WalkPlan

PlanWalk folds a classified item set into the resource-aware walk plan. It is pure: same items + policy in, same plan out, no I/O. The order of operations is the resource policy:

  1. skip-fresh — drop items idle fewer than SkipFreshDays (cheap pre-filter), counting them Fresh, before anything else looks at them.
  2. partition the rest into attention (act/review) vs healthy (skip).
  3. sort attention worst-first by score (tie: lower id first, stable).
  4. take the first Budget as the emitted worklist; the rest are Deferred.

type WalkPolicy added in v0.37.0

type WalkPolicy struct {
	// Budget caps how many attention items (act + review) earn a follow-up
	// decision, worst-first. <= 0 means unbounded.
	Budget int
	// SkipFreshDays skips any item idle FEWER than this many days, regardless of its
	// tags (a recently-touched item is left alone). <= 0 disables the freshness skip.
	// NOTE: keyed on the item's update timestamp, so it is only meaningful where that
	// timestamp tracks real work — on a bot-churned tracker it bumps constantly and
	// the filter over-skips, which is why the cmd default is off.
	SkipFreshDays int
	// SkipInProgress skips any item the source marks actively-in-progress — the cheap
	// pre-filter that genuinely fires even when timestamps are unreliable.
	SkipInProgress bool
	// DryRun forces every decision's Perform=false: the plan proposes, never acts.
	DryRun bool
}

WalkPolicy is the resource-awareness knob set. Zero values mean: no freshness skip, unbounded budget, act for real (not dry-run) — but the cmd defaults are resource-safe (a freshness window, a finite budget, dry-run on).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL