Contract and implementation
oren init worker my-task --template shellGenerates the contract, the implementation, the worker and a pipeline to exercise it. If you only want to use existing tasks, the path is a different one — see First pipeline.
The line
Section titled “The line”It is Oren’s central decision, and the easiest one to get wrong.
| Belongs to the Task | Belongs to the Implementation |
|---|---|
| “I need a git repository” | “I mount it at /source” |
| “I will write to it” | — |
| “I need a GCP credential” | “it goes to /keys/gcp-credential.json” |
“I take defaultChange, I return change” |
“I read from /oren/input.json” |
| — | “I use the image ghcr.io/...” |
| — | “and I need the Docker socket” |
Note the last row. The build-docker-image contract does not require a
Docker daemon: building an image without one is possible (kaniko, buildah).
Requiring it is a decision of whoever implemented it — and one that costs
critical privilege.
Floor and delta
Section titled “Floor and delta”The Task declares the floor: what any implementation will need. The Implementation declares what it adds.
Two implementations of the same contract are only comparable because the floor is identical — what is left is an engineering choice. That is what the catalogue ranks.
They version independently
Section titled “They version independently”- The Task version describes the contract. Removing an output or making an input required is major. Adding an optional input is minor.
- The Implementation version describes the worker, and evolves on its own.
It declares the contract range it satisfies (
^1.0.0).
The test, when in doubt
Section titled “The test, when in doubt”If I swap implementation and this value disappears, does the output change?
If it changes, it is contract. If it does not — a cacheKey, a verbosity level
— it is implementation configuration.