Project¶
The Project custom resource is the top-level grouping unit in tatara. One Project maps to a single SCM owner (a GitHub organization, a GitLab group, or a personal account), owns the per-project memory stack, and drives all scheduled activity: issue scans, MR reviews, brainstorm cycles, health checks, and incident handling.
Every Repository CR must reference a Project. Every Task is born inside a Project.
API group / version: tatara.dev/v1alpha1
Kind: Project
Scope: Namespaced
Spec¶
Top-level fields¶
| Field | Type | Default | Required | Description |
|---|---|---|---|---|
scmSecretRef | string | - | yes | Name of the Secret in the same namespace holding the SCM token. Key token is the bot PAT or GitLab project access token. |
triggerLabel | string | tatara | no | Issue label that causes the operator to react. An issue must carry this label (or be authored by the bot) to enter the tatara lifecycle. |
maxConcurrentTasks | int | 3 | no | Maximum number of simultaneously running Task pods for this project. Also sets the default queue.capacity when queue is omitted. |
agent | AgentSpec | see below | no | Configuration for the claude-code-wrapper agent session that every Task runs. |
memory | MemorySpec | see below | no | Size of the per-project memory stack (Postgres + Neo4j). |
scm | ScmSpec | - | no | SCM provider binding, labels, cron schedules, and merge policy. |
grafana | GrafanaSpec | disabled | no | Optional Grafana integration for incident-response tasks. |
queue | QueueSpec | derived | no | Fine-grained admission queue tuning. |
tokenBudget | TokenBudgetSpec | nil (inherits operator default, off) | no | Token-budget admission gate: pauses proactive and/or incident work once usage crosses a percentage threshold. |
deployBudgetSeconds | int | 3300 | no | Deploying-phase deadline (seconds) for a push-CD cascade along the longest path to a tatara-helmfile apply (2 tag-cut hops, e.g. cli -> wrapper -> helmfile). Exceeding it parks the Task recoverable with reason deploy-timeout. |
deploySingleHopBudgetSeconds | int | 2100 | no | Tighter Deploying-phase deadline for artifacts one hop from tatara-helmfile (operator, memory, ingester, chat) with no intermediate parent rebuild. Deploy-supervision picks this over deployBudgetSeconds for single-hop artifacts. |
Deprecated: maxOpenTasks
maxOpenTasks is no longer enforced. The queue bounds concurrency, not event creation; events above capacity wait in Queued phase. The field is retained for backward compatibility and silently ignored.
maxConcurrentTasks: 0 fully pauses a project
Setting maxConcurrentTasks to 0 admits no new Tasks: every scan, brainstorm, and webhook-triggered event queues but nothing spawns. This is the pause lever for a project (see Tuning).
AgentSpec¶
Controls every agent pod spawned by this project.
| Field | Type | Default | Description |
|---|---|---|---|
model | string | operator default | Claude model ID (e.g. claude-opus-4-8 project-wide, tiered down per kind to claude-sonnet-5). When empty the wrapper's own default applies. |
image | string | operator default | Fully-qualified container image for the claude-code-wrapper pod. When empty the operator's compiled-in default is used. |
permissionMode | string | bypassPermissions | Claude Code permission mode. bypassPermissions disables interactive approval prompts inside the agent. |
maxTurnsPerTask | int | 50 | Hard ceiling on the number of agent turns per task. The task is failed when this limit is reached. |
turnTimeoutSeconds | int | 1800 | Inactivity window per turn in seconds. A turn is killed only after this many seconds of no streaming output -- a turn actively producing output is never killed mid-work regardless of wall-clock age. |
contextWindowTokens | int | 200000 | Context window budget passed to the wrapper. Controls when the agent initiates a handover. |
handoverThresholdPercent | int | 25 | When the last-turn input token count exceeds this percentage of contextWindowTokens, the next pod receives a compacted handover text instead of the full conversation replay. Below the threshold the full transcript is replayed. |
maxLifecycleIterations | int | 10 (min 3) | Maximum times a lifecycle task can restart (crash-resume cycles) before the operator marks it terminal. |
effort | string | xhigh | Reasoning-effort level forwarded to the wrapper as the EFFORT env var. Maps to Claude's extended thinking intensity. One of: low, medium, high, xhigh, max. |
maxTaskTokens | int64 | 0 (disabled) | Per-Task cumulative output-token ceiling for the otherwise turn-uncapped kinds (implement, issueLifecycle): a runaway backstop, not a cost lever. 0 disables it. When status.cumulativeTokens crosses it the Task fails with reason TokenBudgetExceeded. |
modelByKind | map[string]string | {} | Per-Task.Spec.Kind override of model. Keys limited to implement, review, triageIssue, brainstorm, issueLifecycle, incident, selfImprove, refine, healthCheck (max 9 entries). healthCheck is a pseudo-key: healthCheck Tasks carry Kind=brainstorm but resolve against this key first, falling back to the brainstorm entry when absent - lets healthCheck be tiered separately from brainstorm. Values must start with claude- (max 64 chars). A missing/empty entry falls back to model. |
effortByKind | map[string]string | {} | Per-kind override of effort. Same keys and healthCheck pseudo-key semantics as modelByKind. Values must be one of low, medium, high, xhigh, max. A missing/empty entry falls back to effort. |
skillsRef | string | main | Git ref (branch, tag, or SHA) of the tatara-agent-skills repo the wrapper clones at boot. Pin to a SHA to avoid drift from main. |
hooks | LifecycleHooks | - | Optional shell commands run at fixed points in the session. |
extraEnvs | []EnvVar | - | Additional environment variables appended to the wrapper container after the operator's required variables. A stray extra cannot shadow an operator-required variable. |
extraEnvsFrom | []EnvFromSource | - | ConfigMap or Secret refs whose keys are bulk-loaded into the wrapper container's environment. |
extraVolumeMounts | []VolumeMount | - | Additional volume mounts appended to the wrapper container. |
extraVolumes | []Volume | - | Additional volumes appended to the agent pod's volume list. |
extraSidecarContainers | []Container | - | Additional containers appended after the wrapper in the agent pod. Useful for MCP servers or local proxies. |
extraInitContainers | []Container | - | Init containers added to the agent pod. Run to completion before the wrapper starts. |
LifecycleHooks¶
Each field is a shell command string passed to sh -c. An empty field is skipped. Hook failures are logged and counted as metrics but never abort the agent session.
| Field | Trigger point | Arguments available |
|---|---|---|
preClone | Before each repository clone | Repo URL as positional arg $1 |
postClone | After each successful clone and checkout | Clone destination directory as $1 |
conversationStart | Once, after the agent session boots | Task context from pod env (TATARA_TASK, TATARA_PROJECT) |
conversationRestart | Each time the session is relaunched after a crash (--continue path) | Same as conversationStart |
agentTurnFinished | After each agent turn (after work is committed and pushed) | Same as conversationStart |
conversationFinished | Once, during session teardown | Same as conversationStart |
MemorySpec¶
Governs the per-project memory stack: a CNPG-managed Postgres cluster (LightRAG backing store) and a Neo4j single-node instance (graph traversal).
| Field | Type | Default | Description |
|---|---|---|---|
pgInstances | int | 1 | Number of Postgres instances in the CNPG cluster. Set to 3 for HA. |
pgStorage | string | 10Gi | Persistent volume size for each Postgres instance. |
neo4jStorage | string | 10Gi | Persistent volume size for Neo4j. |
Production sizing
Scale pgInstances to 3 to avoid single-node crash-recovery wedges. pgStorage is per-instance; total cluster storage is pgInstances x pgStorage.
GrafanaSpec¶
Enables an operator-provisioned grafana-mcp sidecar and an alert-webhook receiver for incident-response tasks. The feature is entirely inert when enabled: false.
| Field | Type | Default | Description |
|---|---|---|---|
enabled | bool | false | Master switch. Must be true for any other field to take effect. |
url | string | - | Grafana base URL that grafana-mcp queries (non-sensitive). |
secretRef | string | - | Name of the Secret holding Grafana credentials. Must contain two keys: serviceAccountToken (Grafana Viewer SA token mounted into grafana-mcp) and webhookSecret (static bearer token the alert webhook must present). |
Deprecated: cooldownSeconds
cooldownSeconds (default 3600) is retained for API compatibility but has no effect. The per-alert-group refire window was replaced by admission-time idempotency.
QueueSpec¶
Fine-grained control over the in-operator admission queue. Omit this section entirely if the defaults derived from maxConcurrentTasks are sufficient.
| Field | Type | Default | Description |
|---|---|---|---|
capacity | int | value of maxConcurrentTasks, else 3 | Maximum concurrently admitted normal-class events. Events above this limit wait in Queued phase until a slot frees. |
alertCapacity | int | 1 | Reserved concurrent slots for alert-class events (incident webhooks from Grafana). Kept separate so a burst of normal tasks cannot starve incident response. |
queuedAutonomousCap | int | value of maxOpenTasks, else 3 | Deprecated, no longer enforced. Retained for CRD backward-compatibility; ignored. |
Queue vs concurrency
The queue bounds running concurrency, not the total number of events. Any number of events can be created; they accumulate in Queued state and are admitted FIFO as capacity frees.
TokenBudgetSpec¶
Configures the per-Project token-budget admission gate: pauses proactive work (brainstorm, implement, review, ...) at proactivePercent and incident work (the alert pool) at emergencyPercent of the measured usage window. Off by default at every level: the operator-wide default Config is the zero value (enabled: false), and a Project inherits that default verbatim unless it sets its own tokenBudget block - the presence of the block, not any single field, is what turns the gate on for that Project.
| Field | Type | Default | Description |
|---|---|---|---|
enabled | bool | false | Turns the gate on for this project. Authoritative once the block is present - it is not inherited from the operator-wide default. |
mode | string | customWindow | customWindow meters the operator's own per-turn token accounting against tokenLimit within a cron-anchored reset window. claudeSubscription gates on the wrapper-reported Claude 5h/weekly usage percentages instead. |
proactivePercent | int (0-100) | 50 | Pauses the normal pool at this percentage of the window. |
emergencyPercent | int (0-100) | 80 | Pauses the alert pool (incidents) at this percentage. Ordered >= proactivePercent at evaluation; a lower value is raised to match. |
resetSchedule | string | - | 5-field cron marking each window reset boundary. customWindow mode only; empty disables the custom window. |
windowDuration | string | - | Declared window length as a Go duration (e.g. "5h", "168h"). Bounds the reset-boundary search; pair with resetSchedule. |
tokenLimit | int64 | - | Absolute total-token budget per window. customWindow mode only. |
claudeSubscription mode: present in the API, not yet load-bearing
mode: claudeSubscription and the corresponding status.tokenBudget.fiveHourPercent / weeklyPercent fields exist in the current CRD but are inert until a wrapper snapshot with a future reset time is reported (an unknown or past reset is ignored so the gate can never wedge on a stale snapshot). Neither live Project (tatara, infrastructure) currently sets a tokenBudget block, so the gate is fully disabled fleet-wide today. A follow-on per-kind admission gate (fleet-wide account-usage poller + per-kind spawn-ceiling ladder, superseding this per-project snapshot mechanism) is in development on a feature branch and has not merged to main; it is not part of this reference until it lands.
ScmSpec¶
Binds the project to an SCM provider and configures the full set of operational knobs: bot identity, approval gates, merge policy, labels, and cron schedules.
Identity¶
| Field | Type | Default | Required | Description |
|---|---|---|---|---|
provider | string | - | yes | SCM provider. One of github or gitlab. |
owner | string | - | yes | GitHub organization or user name, or GitLab group/user path. All enrolled repositories must live under this owner. |
botLogin | string | - | yes | SCM username of the bot account. Used to distinguish bot comments from human comments and to gate autoapprove. |
botEmail | string | - | no | Git commit author email for agent commits. When empty the wrapper's default identity applies. |
Approval gates¶
| Field | Type | Default | Description |
|---|---|---|---|
maintainerLogins | []string | [] | Trusted human maintainer accounts. Together with botLogin they form the "trusted insider" set for autoapprove. When non-empty, a thread comment is only treated as a human approval if its author appears in this list. When empty, any non-bot human reply releases the self-approve hold. Overridable per-repository via RepositorySpec.maintainerLogins. |
reporterLogins | []string | [] | Allowlist of accounts whose issues and issue comments the operator will act on. When non-empty, issues or comments from any account not in this list (and not a bot or maintainer) are silently dropped at intake. Prevents unknown third parties from driving the lifecycle via prompt injection. When empty, any author is accepted. Overridable per-repository via RepositorySpec.reporterLogins. |
Prompt-injection defense
Set reporterLogins in any project exposed to untrusted contributors. Without it, anyone who can open an issue can drive agent behavior.
Merge and review policy¶
| Field | Type | Default | Enum | Description |
|---|---|---|---|---|
mergePolicy | string | afterApproval | afterApproval, autoMergeOnGreenCI | When afterApproval, the operator merges when the agent signals pr_outcome=merge (the agent infers human intent from the PR/issue thread; SCM review state is not independently verified). When autoMergeOnGreenCI, the bot merges as soon as CI is green. |
prReactionScope | string | (empty) | labeledOrMentioned, all | Controls which PRs/MRs trigger bot review. Empty (the default) is the historical open behavior: reviews every open human PR/MR. labeledOrMentioned restricts reviews to PRs carrying triggerLabel or @-mentioning the bot, so unlabeled/un-mentioned MRs are not re-reviewed every scan cycle. all is an explicit synonym for the empty/open default. The default is deliberately not labeledOrMentioned: a defaulted value would be indistinguishable from an explicit opt-in, silently gating every project. |
Enable labeledOrMentioned to stop repeat re-reviews
Both live projects (tatara, infrastructure) set prReactionScope: labeledOrMentioned explicitly. Leaving it empty means every mrScan cycle re-reviews every open PR/MR regardless of prior review state.
Operational tuning¶
| Field | Type | Default | Description |
|---|---|---|---|
guidance | string | - | Free-form project charter text appended verbatim to the brainstorm and healthCheck goal context. Use to steer agent proposals toward project-specific priorities. |
babysitDeadlineMinutes | int | 60 | Minutes after task creation that the babysit controller starts checking for stuck tasks. |
conversationIdleMinutes | int | 60 | Minutes of inactivity after which the operator considers a conversation stale and triggers recovery. |
Board integration¶
Configure board to enable project-board synchronization.
| Field | Type | Default | Description |
|---|---|---|---|
board.githubProjectNumber | int | - | GitHub Projects (V2) project number. |
board.gitlabBoardId | int | - | GitLab board ID. |
board.statusField | string | Status | Name of the board field the operator writes task phase into. |
Cron schedules¶
All cron fields use standard 5-field cron syntax (minute hour dom month dow). An empty schedule disables that activity.
scm.cron.mrScan, scm.cron.issueScan, and scm.cron.cdScan¶
All three activities share the CronActivity shape.
| Field | Type | Default | Description |
|---|---|---|---|
schedule | string | - | 5-field cron expression. Empty disables the activity. |
maxPerRepo | int | 1 | Maximum in-progress tasks of this type per repository (per-repo lane throttle). A repository whose lane is full is skipped until the in-flight task completes. |
cdScan is the push-CD deploy-supervision backstop: it sweeps Deploying Tasks whose cascade has stalled past 1.5x the applicable deploy budget (deployBudgetSeconds / deploySingleHopBudgetSeconds) with no live watcher, and rerolls them - parks recoverable Tasks, re-implements orphans. It is a peer of mrScan/issueScan, project-scoped. Empty schedule disables it.
scm.cron.brainstorm¶
Opt-in self-driven issue-proposal cycle. Disabled unless enabled: true.
| Field | Type | Default | Description |
|---|---|---|---|
enabled | bool | false | Must be true to activate. |
schedule | string | - | 5-field cron expression. |
maxOpenProposals | int | 5 | If the total number of open, unapproved agent proposals across all repos in the project meets or exceeds this value, the brainstorm cycle is skipped entirely. Controls backlog pressure. |
staleProposalDays | int | 0 (reaper off) | Opts in the staleness reaper: a positive value auto-closes bot-authored proposals with no human engagement (no human comment, no live work) for at least that many days, clearing dead proposals out of the maxOpenProposals backlog. <=0 (the unset default) disables the reaper entirely. This is an explicit opt-in sentinel, not a kubebuilder default - "unset" must never be indistinguishable from an active value. |
sources | []string | - | Knowledge sources the brainstorm agent may consult. Allowed values: docs, memory, internet. An empty list uses only repository contents. |
One brainstorm per project per cycle
maxPerCycle is deprecated and ignored. The controller hard-caps brainstorm at one task per project per cycle.
scm.cron.healthCheck¶
Periodic project-health survey. Proposes one targeted discovery issue per cycle via the tatara-health-check skill. Disabled unless enabled: true.
| Field | Type | Default | Description |
|---|---|---|---|
enabled | bool | false | Must be true to activate. |
schedule | string | - | 5-field cron expression. |
maxOpenProposals | int | 5 | Same semantics as brainstorm: cycle is skipped when open proposals meet this cap. |
sources | []string | - | Same allowed values as brainstorm: docs, memory, internet. |
scm.cron.refine¶
Pre-step that fires automatically before each scan and brainstorm cycle. No independent schedule; it is a mandatory barrier, not a standalone cron.
| Field | Type | Default | Description |
|---|---|---|---|
closedLookbackDays | int | 30 | How far back (in days) closed issues are loaded for already-implemented detection. Zero uses the default of 30. |
Label set¶
The operator projects a set of SCM labels onto issues to communicate task phase. All labels are configurable; the table shows the defaults.
Field (scm.*) | Default value | Semantics |
|---|---|---|
brainstormingLabel | tatara-brainstorming | Issue is in triage or discussion (pre-approval). Applied by the triage agent. |
approvedLabel | tatara-approved | Issue is approved for implementation. Set when a maintainer approves the proposal thread. |
implementationLabel | tatara-implementation | Implementation is in flight. Applied when the implement task starts. |
declinedLabel | tatara-declined | Issue was declined before implementation (triage reject). |
incidentLabel | tatara-incident | Issue originated from an incident investigation. Applied additively alongside brainstormingLabel; never swept by the phase-label reconciler. |
priorityLabel | (empty) | Optional priority tag. When set, the operator applies it to high-priority tasks. |
Deprecated label fields
approvalLabel, ideaLabel, and rejectedLabel are deprecated aliases retained for migration tooling only. Do not set them in new projects; they have no effect on operator behavior.
Status¶
The operator writes observed state back to .status. All fields are read-only.
Top-level status fields¶
| Field | Type | Description |
|---|---|---|
webhookURL | string | The operator-provisioned inbound webhook URL for this project. Register this URL in your SCM provider to receive push events. Populated after the first reconciliation. |
conditions | []Condition | Standard Kubernetes conditions reflecting overall Project readiness. |
memory.phase | string | Observed phase of the memory stack (Pending, Running, Degraded). |
memory.endpoint | string | In-cluster HTTP URL of the tatara-memory service for this project. Used by agent pods and the operator. |
memory.externalEndpoint | string | External URL of the memory service when exposed outside the cluster (optional). |
grafana.phase | string | Observed phase of the grafana-mcp deployment. Empty when grafana.enabled is false. |
grafana.endpoint | string | In-cluster URL of the grafana-mcp instance. |
tokenBudget | TokenBudgetStatus | Token-budget accumulator/snapshot (see TokenBudgetSpec). |
Last-run timestamps¶
All timestamps are RFC 3339 and reflect the last time the corresponding activity completed successfully.
| Field | Activity |
|---|---|
lastMRScan | MR/PR review scan |
lastIssueScan | Issue scan |
lastBrainstorm | Brainstorm cycle |
lastHealthCheck | Health check cycle |
lastCDScan | Push-CD deploy-supervision backstop scan |
lastRefine | Refine pre-step |
TokenBudgetStatus¶
| Field | Type | Description |
|---|---|---|
windowStart | metav1.Time | When the current custom-window opened (the most recent reset boundary). customWindow mode. |
windowTokens | int64 | Total tokens spent in the current custom window so far. |
fiveHourPercent | int (0-100) | Wrapper-reported Claude usage percentage for the rolling 5h window. claudeSubscription mode. |
fiveHourReset | metav1.Time | Reset time for the 5h window snapshot. A nil or past value means "not reported" and the gate ignores it. |
weeklyPercent | int (0-100) | Wrapper-reported Claude usage percentage for the rolling weekly window. claudeSubscription mode. |
weeklyReset | metav1.Time | Reset time for the weekly window snapshot. Same nil/past-ignored semantics as fiveHourReset. |
Annotated example¶
apiVersion: tatara.dev/v1alpha1
kind: Project
metadata:
name: my-platform
namespace: tatara
spec:
# (1)!
scmSecretRef: my-platform-scm-token
triggerLabel: tatara
maxConcurrentTasks: 5
# (10)!
deployBudgetSeconds: 3300
deploySingleHopBudgetSeconds: 2100
agent:
# (2)!
model: claude-opus-4-8
permissionMode: bypassPermissions
maxTurnsPerTask: 60
turnTimeoutSeconds: 1800
contextWindowTokens: 200000
handoverThresholdPercent: 25
maxLifecycleIterations: 10
effort: high
# (11)!
maxTaskTokens: 3000000
modelByKind:
triageIssue: claude-sonnet-5
review: claude-sonnet-5
effortByKind:
triageIssue: low
review: medium
skillsRef: 395713a0ef849fde8df5e27121840e043276eccf
hooks:
# (3)!
postClone: "mise install --quiet"
conversationFinished: |
echo "Task ${TATARA_TASK} finished in project ${TATARA_PROJECT}"
extraEnvs:
- name: CUSTOM_REGISTRY
value: harbor.example.com
memory:
# (4)!
pgInstances: 3
pgStorage: 20Gi
neo4jStorage: 20Gi
grafana:
# (5)!
enabled: true
url: https://grafana.example.com
secretRef: grafana-tatara-credentials
queue:
# (6)!
capacity: 5
alertCapacity: 2
# (12)!
tokenBudget:
enabled: true
mode: customWindow
proactivePercent: 50
emergencyPercent: 80
resetSchedule: "0 0 * * *"
windowDuration: "24h"
tokenLimit: 50000000
scm:
provider: github
owner: my-org
# (7)!
botLogin: my-org-bot
botEmail: my-org-bot@users.noreply.github.com
# (8)!
maintainerLogins:
- alice
- bob
reporterLogins:
- alice
- bob
- charlie
mergePolicy: afterApproval
prReactionScope: labeledOrMentioned
guidance: |
This project runs the platform team's infrastructure repos.
Prefer Kubernetes-native approaches. Avoid new external dependencies.
board:
githubProjectNumber: 42
statusField: Status
cron:
mrScan:
# (9)!
schedule: "*/15 * * * *"
maxPerRepo: 1
issueScan:
schedule: "0 * * * *"
maxPerRepo: 1
# (13)!
cdScan:
schedule: "*/30 * * * *"
maxPerRepo: 1
brainstorm:
enabled: true
schedule: "0 9 * * 1"
maxOpenProposals: 8
# (14)!
staleProposalDays: 14
sources:
- memory
- docs
healthCheck:
enabled: true
schedule: "0 10 * * 1"
maxOpenProposals: 8
sources:
- memory
refine:
closedLookbackDays: 14
scmSecretRefis the only required field. TheSecretmust exist in the same namespace and contain atokenkey with the bot PAT.- Agent defaults are production-ready out of the box. Override
modelandimageto pin specific versions. - Hooks run via
sh -c. A non-zero exit is logged and counted but never aborts the session. - Set
pgInstances: 3for HA. A single instance is acceptable for non-critical projects but is vulnerable to crash-recovery wedges on CephFS-backed storage. - Grafana integration provisions a
grafana-mcpsidecar for incident-response tasks. ThesecretRefSecret must containserviceAccountTokenandwebhookSecretkeys. capacityoverrides themaxConcurrentTasksdefault for queue admission.alertCapacityreserves dedicated slots so incident tasks are never starved by a backlog of normal tasks.botLoginmust match the SCM account whose token is inscmSecretRef. Mismatches cause the operator to misidentify its own comments as human input.maintainerLogins+reporterLoginsform the security perimeter. At minimum setmaintainerLoginsto restrict who can approve proposals.- MR scan every 15 minutes, issue scan hourly, brainstorm and health check weekly on Monday morning.
- Deploy budgets bound how long a
Deploying-phase Task can wait for its push-CD cascade to reach atatara-helmfileapply before parking recoverable.deployBudgetSecondscovers the longest 2-hop path (e.g. cli -> wrapper -> helmfile);deploySingleHopBudgetSecondsis tighter for single-hop artifacts (operator, memory, ingester, chat). maxTaskTokensis a runaway backstop for the turn-uncappedimplement/issueLifecyclekinds, not a cost lever.modelByKind/effortByKindtier specific kinds down (heretriageIssue/reviewdrop to Sonnet at lower effort) while the project-widemodel/effortfallback stays high-end for everything else.skillsRefpins the agent-skills clone to a SHA to avoidmaindrift.tokenBudgetis off unless this block is present withenabled: true.customWindowmode meters absolute tokens againsttokenLimitinside the cron-anchoredresetSchedule/windowDurationwindow;claudeSubscriptionmode gates on wrapper-reported Claude usage percentages instead (see TokenBudgetSpec).cdScanis the push-CD deploy-supervision backstop: it sweeps stalledDeployingTasks past 1.5x the deploy budget and rerolls them. Emptyscheduledisables it.staleProposalDays: 14opts in the brainstorm staleness reaper: bot proposals with no human engagement for 14+ days are auto-closed, keeping themaxOpenProposalsbacklog from clogging with dead proposals. Omit or set<=0to keep the reaper off.