What v1 is and the names it fixes
What v1 is
The core loop and nothing else: a scan previews stacks and writes the dashboard, a person ticks a box, exactly that stack deploys, and the row returns to in sync or shows why it failed.
Names fixed for v1
Collected here so nobody has to search the records. The record in the last column is the authority.
Action inputs and outputs
| Name | Kind | Modes | Default | Meaning | Record |
|---|---|---|---|---|---|
mode |
input | all | required | scan, resolve, apply, settle or check |
0003, 0042 |
concurrency |
input | scan |
4 |
Size of the preview pool | 0012 |
preview-timeout |
input | scan, apply |
10 |
Time limit for one preview, whole minutes | 0012, 0035 |
github-token |
input | all | the workflow token | Always the workflow’s own GITHUB_TOKEN |
0017, 0035 |
deployment-id |
input | apply |
required there | The deployment record to deploy | 0035 |
dry-run |
input | apply |
false |
A rehearsal: everything up to the hash check, then no deploy. The record ends as inactive, “rehearsed, nothing was deployed” |
0051 |
job-id |
input | scan, apply |
${{ job.check_run_id }} |
The id of the running job, for links to its log. Never set by hand | 0044 |
matrix |
output | resolve, scan |
[] |
[{ stack, environment, deployment }]. A scan sets one entry only after a merge from the dashboard |
0035, 0054 |
dashboard-url |
output | scan, apply, settle |
none | Web address of the dashboard issue | 0041 |
pending |
output | scan |
0 |
Number of pending stacks after this scan | 0041 |
preview-failed |
output | scan |
0 |
Number of stacks whose preview failed | 0041 |
in-sync |
output | scan |
0 |
Number of stacks in sync | 0041 |
dashboard-changed |
output | scan |
false |
true when this scan wrote a different body, so a notify step can stay quiet otherwise |
0041 |
outcome |
output | apply |
none | deployed, in-sync (nothing to deploy), rehearsed (dry-run), refused (the change moved, the record was not open, or deploys: false) or failed |
0041, 0051 |
stack |
output | apply |
none | The stack id this job handled | 0041 |
result-file |
output | scan, apply |
none | Path under RUNNER_TEMP of a JSON file with what the summary holds: no values, none of the tool’s words |
0041 |
sluiceway.yaml
The file is optional and sits at the repo root. Unknown keys are an error, because a typo in tickers would change who can deploy.
| Key | Default | Meaning | Record |
|---|---|---|---|
dashboard.title |
Sluiceway dashboard |
Issue title | brief |
dashboard.label |
sluiceway |
Label the dashboard is found by | 0009, 0017 |
dashboard.pin |
true |
Pin the issue, best effort | Actions research |
dashboard.redact |
false |
Keep names out of the issue | 0023 |
dashboard.personality |
true |
Header image and the voice | 0034 |
dashboard.readOnly |
false |
No boxes: pending rows have none, there is no rescan box, and the line under the Pending heading says so. For a workflow that only scans (onboarding log, hurdle 16) | 0045 |
dashboard.showValues |
[] |
Property paths whose old and new value may appear, as old → new after the path. Exact paths, * for part of one name. Never a value the tool marks secret, none with redact on. The hash covers a shown value (0008) |
0052 |
tickers |
write |
Default tick rule: write, maintain, admin or a list of usernames |
0018 |
deploys |
true |
false stops every deploy: resolve clears every ticked box with a note, apply ends before the tool runs |
0051 |
ignore |
[] |
Globs matched against the stack id. An entry is a glob, or { glob, reason }, and a stack left out with a reason is listed with it under In sync |
0010, 0051 |
scan.unrelated |
[] |
Globs for files that claim nothing and force nothing | 0010 |
scan.logDiff |
false |
Print the tool’s own diff of every pending stack, values included, in that stack’s group of the job log and nowhere else | 0048 |
drift.enabled |
false |
Check every stack for drift in each scan that a schedule starts or a person starts with Run workflow, and in a push’s scan only for the stacks whose row showed drift. There is no drift.schedule: the loader says the cron goes in the workflow |
0055 |
stacks[].path |
required per entry | Directory of the stack, relative to the repo root | 0006 |
stacks[].name |
none | Name of the stack. Without it the entry covers every stack in path |
0006 |
stacks[].tool |
none | opentofu: the entry declares a stack of that tool at path, because files alone cannot name one |
0053 |
stacks[].environment |
sluiceway |
Label on the deployment record, and the GitHub Environment where one is used | 0003 |
stacks[].tickers |
the top level value | Tick rule for this stack | 0018 |
stacks[].inputs |
[] |
Extra globs this stack claims | 0010 |
stacks[].previewTimeout |
the input | Time limit for this stack, whole minutes | 0012, 0035 |
stacks[].dependsOn |
none | Stack ids this stack depends on. A tick waits while one of them is pending and not ticked, ticks in one chain deploy one layer per run (slice 4.4) | 0056 |
stacks[].options |
{} |
Named adapter options, only with tool. OpenTofu: workspace and varFiles |
0006, 0015, 0053 |
mergeAndDeploy.authors |
[] |
Logins whose green pull requests that one stack claims are listed to merge and deploy with one tick. Empty turns it off | 0054 |
Rules for config loading:
- A
stacks[]entry adds settings to stacks that discovery found. It never creates a stack, except an entry withtool, which declares one (0053). An entry that matches no discovered stack is a config error. - A
tickersentry with a slash fails with the message that teams are not supported yet (0018). stacks[].driftfails with a message that says it is not in this version yet. It is never ignored. (dependsOndid too until slice 4.4, 0056, and a top leveldriftuntil slice 4.3, 0055.)- The JSON schema is generated from the Zod schema into
schema/sluiceway.schema.json, committed, and checked in CI the waydist/is.
Fixed strings and numbers
| What | Value | Record |
|---|---|---|
| Bot | github-actions[bot], type Bot |
0017 |
Deployment task |
sluiceway:<stack id> |
0003 |
| Deployment payload | { "v": 1, "hash", "ticker", "run" }, plus "drift": true when the approved hash covers drift |
0003, 0055 |
| Default environment label | sluiceway |
0003 |
| Concurrency groups | sluiceway-scan, sluiceway-resolve, sluiceway-apply-<stack id> |
0004, 0025, 0035 |
| Marker version | 1 |
0009 |
| Row states | pending, deploying, in-sync, preview-failed, queued since slice 4.4, and drift since slice 4.3, with the marker key drift="true" on a row whose hash covers drift |
0009, 0055, 0056 |
| Diff hash | SHA-256 of the canonical document, first 16 hex characters | 0008 |
| Body target, hard limits | 58,000 characters, 65,536 characters, 262,144 bytes | 0028 |
| Summary budget | 1,000,000 bytes | 0037 |
| Preview page | A check run named sluiceway / <stack id>, completed, neutral, its text cut on a line at 65,535 bytes. Needs checks: write |
0050 |
| Write loop | at most 3 tries | 0004 |
| Lookback, names on a row, recently deployed | 100 commits, 5, 10 | 0026, 0029 |
| Minimum Pulumi CLI | v3.229.0 | 0001 |
| Minimum OpenTofu CLI | v1.11.0 | 0053 |
| Minimum self-hosted runner | v2.328.0, no ARM32 | Actions research |
| API budget | 1,000 requests per hour per repo | 0017 |