recurring-task-creator

command module
v0.0.2 Latest Latest
Warning

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

Go to latest
Published: Jun 17, 2026 License: BSD-2-Clause Imports: 26 Imported by: 0

README

Recurring Task Creator

Go Reference CI Go Report Card Ask DeepWiki

Publishes task.CreateCommand events to Kafka on a fixed schedule so a downstream task-controller materializes recurring tasks (daily / weekly / weekday / monthly / quarterly / yearly) as Obsidian vault .md files.

Task definitions live as Kubernetes Schedule Custom Resources — adding / editing / removing a recurring task is kubectl apply, not a code release.

How it works

kubectl apply -f schedule.yaml          ← operator
        │
        ▼
   K8s API server  (Schedule CRD, group task.benjamin-borbe.de/v1)
        │ watch
        ▼
   recurring-task-creator pod  ← installs the CRD at boot,
                                 runs an informer in its own pod
                                 namespace, hourly tick reads from
                                 the cache
        │ task.CreateCommand
        ▼
   Kafka  ← topic per vault (e.g. task-command-personal)
        │
        ▼
   agent-task-controller pod  ← consumes the topic,
                                writes the markdown file
        │
        ▼
   Obsidian vault git remote  ← committed by the controller

Identifiers are deterministic: UUID5("recurring-<slug>-<period-token>"), where the period token is YYYY-MM-DD (daily), YYYYWww (weekly), YYYYWww-<3-letter-weekday> (weekday), YYYY-MM (monthly), YYYYQN (quarterly), YYYY (yearly). The downstream controller dedups on identifier → safe to re-publish every tick, safe to manual /trigger?date=YYYY-MM-DD replay, safe to crash-restart.

Define a schedule

See k8s/apis/task.benjamin-borbe.de/v1/testdata/example.yaml for the canonical shape:

apiVersion: task.benjamin-borbe.de/v1
kind: Schedule
metadata:
  name: weekly-review              # frozen — UUID5 input
  namespace: default               # the recurring-task-creator pod watches its own namespace
spec:
  vault: default                   # routes to agent-task-controller-<vault>
  title: Weekly Review             # Go text/template; period token suffixed by publisher
  schedule:
    recurrence: Weekday            # Daily | Weekly | Weekday | Monthly | Quarterly | Yearly
    weekday: Saturday              # required iff recurrence == Weekday (Monday..Sunday)
  template:
    body: |
      Reflect on the past week.
      Plan the next.
    frontmatter:                   # YAML frontmatter stamped onto the generated task file
      priority: 2
      status: in_progress
      page_type: task
      assignee: bborbe

The CRD's OpenAPI schema enforces the recurrence enum, the weekday enum, and a CEL rule that requires weekday iff recurrence == "Weekday".

Build + deploy

make test                          # ginkgo specs + coverage
BRANCH=dev  make buca              # build, push image, apply STS + RBAC to dev
BRANCH=prod make buca              # same for prod

make buca is a small chain (make build && make upload && make apply). The applied tree is the binary deployment only — StatefulSet, Service, KafkaUser, Role + RoleBinding for namespace-scoped Schedule watch, and ClusterRole + ClusterRoleBinding for the CRD self-install.

Schedule CRs themselves live in a separate (typically private) repository — they reference the deployed image but are operator-owned data, not part of the binary. The repo deployer applies them with kubectl apply -k <overlay> (kustomize) or any GitOps mechanism of choice.

RBAC

The pod's ServiceAccount needs:

  • apiextensions.k8s.io/customresourcedefinitions get / create / update / patch at cluster scope — for the boot-time CRD install
  • task.benjamin-borbe.de/schedules get / list / watch in the pod's own namespace — for the informer

Manifests: k8s/recurring-task-creator-{sa,clusterrole,clusterrolebinding,role,rolebinding}.yaml.

Local smoke-test

DRY_RUN=true ./recurring-task-creator-run-once -logtostderr -v=2

Skips Kafka init entirely (uses a noop sender); logs every (slug, date, identifier) triple the publisher would send. Use to verify a Schedule's behavior before deploying.

Repo layout

Path Purpose
main.go + cmd/run-once/main.go Long-lived service entry point + one-tick smoke binary
pkg/k8s_connector.go Self-installing CRD (SetupCustomResourceDefinition) — get-or-create-or-update on every binary boot, 30s timeout
pkg/k8s_connector_schema.go The Go-built JSONSchemaProps (vault regex, recurrence enum, weekday enum, CEL rule)
pkg/store Informer-backed ScheduleStore — the only source of truth at tick time
pkg/publisher Builds task.CreateCommand, computes the period-anchored UUID5, sends via injected sender
pkg/tick Hourly cron loop + Prometheus metrics
pkg/handler HTTP — /healthz, /trigger?date=YYYY-MM-DD, /setloglevel/{n}, /metrics
pkg/factory Composition root — Create* constructors that wire everything
pkg/schedule Internal types — Date, RecurrenceKind, TaskDefinition, TasksForDate
k8s/apis/task.benjamin-borbe.de/v1/ CRD Go types (hand-written) + zz_generated.deepcopy.go
k8s/client/ Generated typed clientset + informers + listers + applyconfiguration
k8s/recurring-task-creator-*.yaml Binary deployment manifests (STS + RBAC)
hack/update-codegen.sh Wraps kube_codegen.sh for the client tree
mocks/ Counterfeiter mocks
specs/, prompts/ dark-factory development history (specs → prompts → daemon-executed code)

License

BSD-2-Clause. See LICENSE.

Documentation

The Go Gopher

There is no documentation for this package.

Directories

Path Synopsis
cmd
run-once command
Command recurring-task-creator-run-once runs a single tick (compute today's task set and publish each via Kafka) then exits.
Command recurring-task-creator-run-once runs a single tick (compute today's task set and publish each via Kafka) then exits.
k8s
apis/task.benjamin-borbe.de/v1
Package v1 is the v1 API for the Schedule custom resource definition.
Package v1 is the v1 API for the Schedule custom resource definition.
client/clientset/versioned/fake
This package has the automatically generated fake clientset.
This package has the automatically generated fake clientset.
client/clientset/versioned/scheme
This package contains the scheme of the automatically generated clientset.
This package contains the scheme of the automatically generated clientset.
client/clientset/versioned/typed/task.benjamin-borbe.de/v1
This package has the automatically generated typed clients.
This package has the automatically generated typed clients.
client/clientset/versioned/typed/task.benjamin-borbe.de/v1/fake
Package fake has the automatically generated clients.
Package fake has the automatically generated clients.
Code generated by counterfeiter.
Code generated by counterfeiter.
pkg

Jump to

Keyboard shortcuts

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