2. Write service.json
service.json is the only manifest Service Lasso should need to acquire, configure, start, monitor, and update a service.
Minimum Manifest Contract
Every release-backed service manifest should define:
idnamedescriptionversionenabledartifact.kind: "archive"artifact.source.type: "github-release"artifact.source.repoartifact.source.tagartifact.platforms.<platform>.assetNameartifact.platforms.<platform>.archiveTypeartifact.platforms.<platform>.commandwhen the archive exposes an executable
Use service.json Reference for field-level detail.
Add Runtime Behavior
Managed services usually also need:
endpoints[]for named network interfaces and theirautomatic/preferred/fixedport policiesurlsfor operator-facing linkshealthchecks[]for process, HTTP, TCP, file, or variable readinessenvfor service-local runtime valuesglobalenvfor values other services can consumedepend_onfor startup orderinginstall.filesorconfig.fileswhen Service Lasso must write config filessetup.stepswhen the service must run one-shot setup commands after install/config
Provider services usually need:
role: "provider"globalenventries that expose installed tool paths- a cheap probe/version command where useful
- setup steps when the provider must generate local files, install trust material, or prepare a tool cache
- no long-running daemon healthcheck item unless the provider truly starts a process
Add Setup Steps When Needed
Use setup.steps for work that must execute locally after install/config but should not be supervised as a long-running daemon. Common examples include generating local certificates, installing service-local Python dependencies, creating a database schema, or loading sample data.
This is Service Lasso's first-class one-shot job contract. Use One-shot Jobs for CLI/API behavior, dependency ordering, provider-backed execution, rerun policy, and persisted setup history.
Use Startup Endpoint Allocation
to distinguish author proposals from resolved runtime selectors. Generated
files, command lines, URLs, and health checks should reference
${endpoint.<id>.<field>} instead of copying numeric defaults.
Use Setup Helper Conventions when a setup step is better maintained as service-owned helper code instead of a long inline command.
Use Legacy Setup Migration when
converting donor-era execconfig.setup arrays or punctuation-prefixed setup
lines into setup.steps.
{
"setup": {
"steps": {
"generate-cert": {
"description": "Generate local development certificates.",
"cwd": "${SERVICE_ROOT}",
"commandline": {
"win32": "mkcert.exe -key-file \"${SERVICE_DATA_PATH}\\mkcert.key\" -cert-file \"${SERVICE_DATA_PATH}\\mkcert.pem\" *.localhost",
"default": "mkcert -key-file \"${SERVICE_DATA_PATH}/mkcert.key\" -cert-file \"${SERVICE_DATA_PATH}/mkcert.pem\" *.localhost"
},
"timeoutSeconds": 60,
"rerun": "ifMissing"
}
}
}
}
Rules:
- No
execservicemeans the setup command runs directly. execserviceruns the setup step through a provider such as@node,@python, or@java.cwdoptionally picks the working directory for the setup command. It uses the same variable selectors ascommandlineandenv, defaults to the service root, and must resolve to an existing directory inside the service root.commandline.win32,commandline.linux, andcommandline.darwinoverridecommandline.default.rerun: "ifMissing"is the default bootstrap-friendly behavior. Declarecreateswhen the step should skip only while those files or directories still exist.rerun: "ifChanged"reruns when declaredfingerprintinputs or the installed artifact release tag change. Setup state stores a hash only, never the resolved values.rerun: "manual"is for destructive or sample/demo steps that should only run when explicitly requested.
Keep setup steps visible in the manifest even when the implementation delegates to scripts/lasso-<service>.mjs or platform scripts under scripts/setup/. The manifest remains the operator-readable contract; helper code owns the detailed orchestration, idempotence checks, readiness polling, exit codes, logging, and sensitive-value handling.
Pin the Release
The manifest must point to a real release asset:
{
"artifact": {
"kind": "archive",
"source": {
"type": "github-release",
"repo": "service-lasso/lasso-example",
"tag": "2026.4.29-abc1234"
},
"platforms": {
"win32": {
"assetName": "lasso-example-win32.zip",
"archiveType": "zip",
"checksum": {
"algorithm": "sha256",
"assetName": "SHA256SUMS.txt"
}
}
}
}
}
The release tag uses yyyy.m.d-<shortsha>. Artifact names should include the exact upstream service, runtime, framework, or tool version.
For release-backed services, declare checksum verification per platform whenever the release publishes a checksum. Use either a direct SHA-256 checksum.value or a release checksum asset such as checksum.assetName: "SHA256SUMS.txt". Service Lasso verifies the archive before extraction or install state mutation and fails closed on missing, malformed, unsupported, or mismatched checksum evidence.
Exit Criteria
Move to step 3 only when:
service.jsoncan identify the exact GitHub release asset to download- release-backed archive checksums are declared when the release publishes them
- commands, env, dependencies, ports, and health checks match the planned service shape
- the manifest can be copied into
services/<service-id>/service.jsonwithout needing a second hidden metadata file