Skip to content

feat(task/controller): TASK_DIR per-vault (required, no default)#22

Merged
bborbe merged 1 commit into
masterfrom
feature/task-dir-per-vault
Jun 15, 2026
Merged

feat(task/controller): TASK_DIR per-vault (required, no default)#22
bborbe merged 1 commit into
masterfrom
feature/task-dir-per-vault

Conversation

@bborbe

@bborbe bborbe commented Jun 15, 2026

Copy link
Copy Markdown
Owner

Vaults follow different folder conventions:

Vault task-dir
openclaw tasks
personal 24 Tasks

Previously the binary defaulted TaskDir to "24 Tasks" but the STS env hard-coded it to 'tasks' for both controllers, so commands routed to agent-task-controller-personal materialized in the wrong directory (Personal vault grew a tasks/ folder instead of using the canonical 24 Tasks/).

Changes

  • task/controller/main.go: TaskDir is now required:"true" with no default. Missing TASK_DIR env now fails fast at startup with a clear validation error instead of silently defaulting to a vault-incorrect path.
  • task/controller/k8s/agent-task-controller-sts.yaml: TASK_DIR env reads {{ "TASK_DIR" | env }} (was hard-coded 'tasks').
  • task/controller/k8s/Makefile: VAULTS tuple gains a third =<task-dir> field. The apply loop exports TASK_DIR per iteration via cut -d'=' -f3-, preserving the space in "24 Tasks".

Migration

After this lands:

  1. BRANCH=dev make apply + BRANCH=prod make apply redeploy with new env wiring
  2. git mv 45 files in bborbe/obsidian-personal from tasks/24 Tasks/ (one-time)
  3. Future ticks land directly in 24 Tasks/; UUID5 prevents duplicates regardless of path

Test plan

  • Local /coding:pr-review loop converged
  • Bot review approves
  • All CI green
  • Apply to dev + prod, verify no regressions on openclaw, verify personal pod's Argument: TaskDir '24 Tasks'

Different vaults follow different folder conventions:
  openclaw → tasks
  personal → 24 Tasks

Previously the binary defaulted TaskDir to '24 Tasks' but the STS env
hard-coded it to 'tasks' for both controllers, so commands targeting
the personal vault materialized in the wrong directory.

Changes:
- main.go: TaskDir field now required:"true" (no default). Missing
  TASK_DIR env now fails fast at startup with a clear error instead of
  silently defaulting.
- k8s/agent-task-controller-sts.yaml: TASK_DIR env reads
  {{ "TASK_DIR" | env }} (was hardcoded 'tasks').
- k8s/Makefile: VAULTS tuple gains a third '=<task-dir>' field. The
  apply loop exports TASK_DIR per iteration via cut -d'=' -f3-, which
  preserves the space in '24 Tasks'.

Deploy migration: existing files in obsidian-personal's 'tasks/' folder
need to be 'git mv'd to '24 Tasks/' once. Future ticks dedup via UUID5
regardless of path, so no double-write.
@bborbe bborbe marked this pull request as ready for review June 15, 2026 20:29

@ben-s-pull-request-reviewer ben-s-pull-request-reviewer Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Based on my review of the 3 changed files, here is my analysis:

Review Findings

Changes Overview

The PR makes TASK_DIR a required field per-vault instead of a global default. This enforces explicit configuration for each vault (openclaw=tasks, personal=24 Tasks).

Analysis by Concern

Concern 1: TaskDir required with no default — crash loop risk

The concern about missing TASK_DIR causing startup failure is valid but intended. The change explicitly moves from a default of "24 Tasks" to required:"true". The agent-task-controller-sts.yaml now uses {{ "TASK_DIR" | env }} which will produce an empty string if unset — combined with required:"true", the binary will fail fast at startup. This is the correct behavior: it forces operators to provide TASK_DIR explicitly rather than silently using a wrong default. Migration path: update k8s manifests to set TASK_DIR before deploying this version.

Concern 2: Helm templating {{ "TASK_DIR" | env }} with unset variable

The helm env function returns the value of the named environment variable at template rendering time. If TASK_DIR is unset, this renders as an empty string (not the literal {{ ... }}). Since main.go now requires this field, the container will fail to start if the variable is missing. This is correct — it's a hard fail rather than silent wrong behavior.

Concern 3: cut -d'=' -f3- parsing with spaces in vault names

No issue found. The command uses -f3- (from 3rd field to end), so 'personal=dwkkgw=24 Tasks' correctly extracts 24 Tasks (preserving the space). The vault name itself (personal) cannot contain = so field splitting is clean.

Must Fix (Critical)

None — the behavior is as intended.

Should Fix (Important)

None.

Nice to Have (Optional)

  • Documentation: The agent-task-controller-sts.yaml comment block could document that TASK_DIR env var must be set by the Helm render pipeline (e.g., via {{ .Values.taskDir }} with a required field), since an unset variable produces an empty string that will crash the container.

{
  "verdict": "approve",
  "summary": "The PR correctly makes TASK_DIR required per-vault with no default. The three-file change (Makefile, STS template, main.go) is internally consistent: the Makefile exports TASK_DIR from the VAULTS tuple, the STS template consumes it via helm env templating, and main.go enforces it as required. Missing TASK_DIR causes fast-fail startup rather than a silent wrong-behavior crash — which is the intended design.",
  "comments": [
    {
      "file": "task/controller/k8s/agent-task-controller-sts.yaml",
      "line": 68,
      "severity": "nit",
      "message": "Consider adding a comment documenting that TASK_DIR must be provided at helm render time (e.g., via Values.taskDir with required=true), since an unset variable renders as empty string and will cause startup failure when combined with main.go's required:true flag."
    }
  ],
  "concerns_addressed": [
    "correctness: TaskDir is now required with no default — the binary fails fast at startup if TASK_DIR is missing, enforcing explicit per-vault configuration rather than silently using a wrong default. This is the intended behavior.",
    "correctness: The helm templating {{ \"TASK_DIR\" | env }} renders as empty string if unset. Combined with required:true in main.go, this causes a clear startup failure rather than silent misbehavior. Correct.",
    "correctness: cut -d'=' -f3- correctly preserves '24 Tasks' (space included) by taking fields 3 onward. No issue with vault names containing spaces."
  ]
}

@bborbe bborbe enabled auto-merge June 15, 2026 20:33
@bborbe bborbe merged commit 62833c6 into master Jun 15, 2026
9 checks passed
@bborbe bborbe deleted the feature/task-dir-per-vault branch June 15, 2026 20:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant