Job module
Source: modules/job/.
At a glance
Section titled “At a glance”| CLI | shc job |
| Subcommands | 6 |
| HTTP endpoints | see the route reference |
| Events emitted | see the event reference |
| Error codes | see the error code reference |
| Service classes | JobLoader, JobExecutor, JobService |
| Cross-module deps | app, network, node, stack |
Source layout
Section titled “Source layout”modules/job/├── command.go├── errors.go├── events.go├── models.go├── registration.go├── router.go├── service.go├── tasks.go├── types.go├── utils.go├── commands/└── contexts/CLI entry points
Section titled “CLI entry points”shc job— manage jobs
HTTP API
Section titled “HTTP API”Routes are listed in the generated route reference; request/response notes live in the API reference.
Errors
Section titled “Errors”Typed errors are catalogued in the error code reference with HTTP statuses and message templates.
Responsibilities
Section titled “Responsibilities”The job module owns user-defined jobs — short-lived, named
operations that an app exposes alongside its stack. Jobs live in
*.job.yaml files inside an app directory and can be invoked manually
(shc job run), on a cron (shc schedule add), or from lifecycle hooks
(pre_install, post_install, etc.).
The module has three collaborating types in service.go:
JobLoader— reads*.job.yamlfiles from a stack’s app directory and parses them intoJobDefinitionGo structs. OneJobLoaderper (tenant, stack, environment). Errors:X400010INVJOB,X400011JOBMNG,X404001JOBNFD.JobExecutor— takes aJobDefinition, resolves secrets viaref+vault://...references (vars.ResolveSecretReferences), renders the job’s templated command with Go templating (sharing filters with theapptemplate machinery), dispatches to the correct context executor (container, host, remote, etc. — seecontexts/), and returns a structured result.JobService— the public API. Lists, runs, and tracks jobs throughJobModel/JobRunModeltables. Each invocation creates aJobRunModelrow with status, start/end time, stdout/stderr, and the POSIX exit code.
What the job module does not own: scheduling (that is
schedule, which inserts rows into ScheduleModel that
reference a job by name), queueing for async execution (that is the
task module), or the shell/container primitives
themselves (those live in the per-context executors, modules/job/context_*.go).
A job run’s lifecycle: JobService.run → creates JobRunModel →
delegates to JobExecutor.execute → dispatches to a context executor
→ captures exit/stdout → updates the run row → emits audit event.