Decision records
Each record explains one decision about Sluiceway and why it was made. A later record can amend or supersede an earlier one, and the last column says which.
| Record | Decision | Amended or superseded |
|---|---|---|
| 0001 | Drive Pulumi through the CLI, not the Automation API | Amended by 0055 |
| 0002 | Sluiceway renders the diff itself from the normalized diff | |
| 0003 | Deploy facts live in GitHub’s Deployments API | Amended by 0096; Amended by 0051; Amended by 0056; Amended by 0054; Amended by 0062; Amended by 0095; Amended by 0102; Amended by 0104; Amended by 0109 |
| 0004 | The issue body is a cache of row blocks, written without a lock | Amended by 0119; Amended by 0113; Amended by 0108; Amended by 0011 |
| 0005 | Every tick keeps its own event, and nothing deploys without a named ticker | Superseded by 0025 |
| 0006 | “Stack” is Sluiceway’s own word, and a stack’s id is derived, never chosen | Amended by 0053; Amended by 0058; Amended by 0060 |
| 0007 | A change says what happens to the real object and, separately, what happens to the tool’s record of it | Amended by 0046; Amended by 0052; Amended by 0053; Amended by 0055; Amended by 0058; Amended by 0060; Amended by 0079 |
| 0008 | The diff hash covers exactly what the row shows, no more and no less | Amended by 0055; Amended by 0111; Amended by 0023; Amended by 0052; Amended by 0046; Amended by 0102 |
| 0009 | Three marker kinds, a trailing row marker, and a body that is regenerated around its row blocks | Amended by 0120, 0121; Amended by 0117; Amended by 0110; Amended by 0108; Amended by 0096; Amended by 0086; Amended by 0083; Amended by 0075; Amended by 0059; Amended by 0054; Amended by 0055; Amended by 0027; Amended by 0056; Amended by 0102; Amended by 0106 |
| 0010 | Push scans are narrowed by a claim rule that fails open | Amended by 0051; Amended by 0064 |
| 0011 | A narrowed scan swaps its own rows, and every scan ends with one row per discovered stack | |
| 0012 | A scan is one job that previews through a bounded pool, not a matrix of jobs | Amended by 0120; Amended by 0117; Amended by 0085 |
| 0013 | The workflow prepares the environment, and Sluiceway never wraps or hooks the tool | Amended by 0103; Amended by 0100; Amended by 0099; Amended by 0106 |
| 0014 | “Never hold credentials” is five promises that can be checked | Amended by 0103; Amended by 0105; Amended by 0100; Amended by 0078; Amended by 0077; Amended by 0102 |
| 0015 | No generic tool arguments, only named adapter options | Amended by 0055 |
| 0016 | Deploys outside Sluiceway are legal and not detected | Amended by 0073 |
| 0017 | The bot is always the workflow’s own token | Amended by 0120; Amended by 0119; Amended by 0108; Amended by 0086; Amended by 0025; Amended by 0050; Amended by 0054; Amended by 0077 |
| 0018 | A tick is authorized by one live rule that only narrows, and only a person can tick | Amended by 0083; Amended by 0025; Amended by 0051; Amended by 0054; Amended by 0095 |
| 0019 | Apply runs only on an open deployment record, so a fresh tick is the only retry | Amended by 0025 |
| 0020 | The tick is always a gate, and GitHub Environments make it a stronger one | Amended by 0093 |
| 0021 | No property value ever leaves the adapter | Amended by 0059; Amended by 0037; Amended by 0046; Amended by 0048; Amended by 0050; Amended by 0052; Amended by 0102; Amended by 0106 |
| 0022 | The tool’s own words stay in the job log, and nothing is masked by guessing | Amended by 0117; Amended by 0110; Amended by 0048; Amended by 0051; Amended by 0056; Amended by 0106; Amended by 0107 |
| 0023 | Redact strips the issue, not the summary, and the hash still covers the whole diff | Amended by 0052 |
| 0024 | A replace or delete gets a guaranteed place on the row, not more data | |
| 0025 | The edit history names the ticker, and the event is only a wake-up | Amended by 0123; Amended by 0119; Amended by 0108; Amended by 0083; Amended by 0054; Amended by 0077; Amended by 0095 |
| 0026 | Attribution names the pull requests a stack claims and only counts the rest | Amended by 0037; Amended by 0054; Amended by 0072 |
| 0027 | Deletes and replaces sit open under the row, everything else is folded | Amended by 0114; Amended by 0113; Amended by 0112; Amended by 0089; Amended by 0044; Amended by 0062; Amended by 0063; Amended by 0106 |
| 0028 | The size budget shortens the biggest rows first, gives back what fits, and never lists half the destroys | Amended by 0084 |
| 0029 | The body puts pending first and folds away only rows that need nothing | Amended by 0117, 0118; Amended by 0114; Amended by 0108; Amended by 0089; Amended by 0086; Amended by 0076; Amended by 0073; Amended by 0040; Amended by 0051; Amended by 0055; Amended by 0062; Superseded by 0063; Amended by 0120 |
| 0030 | The mascot is the gate itself, and its name is Penny | Amended by 0038 |
| 0031 | The header has six states, bad news wins, and any delete or replace turns it plain | Amended by 0118; Amended by 0117; Amended by 0038, 0039; Amended by 0043; Amended by 0055 |
| 0032 | The voice lives in two lines and stops at the first sign of trouble | Amended by 0075; Amended by 0043 |
| 0033 | The state images are twelve small files named by role, served from the exact release tag | Amended by 0039, 0040; Amended by 0043; Amended by 0055; Amended by 0063; Amended by 0066 |
| 0034 | dashboard.personality: false removes the image and the voice | Amended by 0043 |
| 0035 | resolve hands apply a deployment record, and settle finds its own | Amended by 0123; Amended by 0113; Amended by 0056; Amended by 0054; Amended by 0077; Amended by 0111; Amended by 0109 |
| 0036 | A change that touches only a stack’s outputs is not shown in v1 | Amended by 0079 |
| 0037 | The summary has a budget too, and the job log holds what does not fit | Amended by 0117; Amended by 0044 |
| 0038 | Penny stands mid-channel on a wide quay, and failing is a jam | Amended by 0047; Amended by 0043 |
| 0039 | Pending has three pictures, picked from the pending count, which makes sixteen files of 880 by 160 | Superseded in part by 0047; Amended by 0043 |
| 0040 | The header and the two lines under it are centered, and every count has a dot | Amended by 0117; Amended by 0043 |
| 0041 | Observability is outputs and a result file, and Sluiceway sends nothing | Amended by 0096; Superseded by 0078; Amended by 0051; Amended by 0055; Amended by 0061 |
| 0042 | A check mode validates a setup with no credentials and no tool | Amended by 0099; Amended by 0074; Amended by 0065; Amended by 0061; Amended by 0077 |
| 0043 | The header always shows the real state, and a destroy adds a sign to the same picture | Amended by 0075; Amended by 0047; Amended by 0055; Amended by 0066 |
| 0044 | A row’s link lands on the page that holds the stack, and the summary has an index | Amended by 0048; Amended by 0050 |
| 0045 | A read-only dashboard draws no boxes | Amended by 0083 |
| 0046 | A key is a property path, and a row shortens it without ever showing a value | |
| 0047 | Pending shows one crate per pending stack up to twelve, and the destroy sign stands on a pole | Amended by 0075; Amended, 2026-09-22; Amended by 0066 |
| 0048 | The tool’s own diff may reach the job log, when a repo asks for it | Amended by 0050 |
| 0050 | A pending row links to a preview page: a check run with the stack’s diff | Amended by 0059; Amended by 0052; Amended by 0106 |
| 0051 | A team can stop, rehearse and explain, and an empty fresh preview is not a failure | Amended by 0083; Amended by 0111; Amended by 0102 |
| 0052 | A repo may list the property paths whose values appear, and nothing is guessed | Amended by 0111; Amended by 0102 |
| 0053 | OpenTofu stacks are declared in sluiceway.yaml, initialised one directory at a time, and deployed from the plan that was hashed | Amended by 0105; Amended by 0058; Amended by 0092; Amended by 0068 |
| 0054 | One tick merges a listed update, and the scan after the merge hands its diff to apply | Amended by 0064; Amended by 0071; Amended by 0081; Amended by 0095; Amended by 0119 |
| 0055 | Drift is checked by a scheduled scan, shown on the stack’s own row, and repaired by a tick | Amended by 0121; Amended by 0059; Amended by 0066; Amended by 0069; Amended by 0070; Amended by 0084; Amended by 0102 |
| 0056 | A stack waits only on the stacks it names, and a chain deploys one layer per run | Amended by 0059; Amended by 0067; Amended by 0091; Amended by 0095; Amended by 0104; Amended by 0109 |
| 0058 | Helm releases are declared in sluiceway.yaml, previewed with the diff plugin, and deployed only as the fresh preview rendered them | Amended by 0069 |
| 0059 | A stack may read its dependencies from its stack references, and drift is set per stack | Amended by 0066; Amended by 0067; Amended by 0091 |
| 0060 | Kubernetes manifests are declared in sluiceway.yaml, diffed server-side, and deployed as the one rendered set the preview saw | Amended by 0090; Amended by 0070 |
| 0061 | The check reads the workflow files, and the result file has a published schema | Amended by 0099; Amended by 0096; Amended by 0074; Amended by 0077; Amended by 0093; Amended by 0095 |
| 0062 | The trail lists every deploy that ended, and a caution block names pending destroys | Amended by 0114; Amended by 0076; Amended by 0073; Amended by 0072; Amended by 0075 |
| 0063 | Deploying sits at the top, and its rows start with a spinner | Amended by 0114; Amended by 0098 |
| 0064 | The scan after a merge narrows, and the merge method is read as Renovate reads it | Amended by 0071 |
| 0065 | Init writes a starter workflow and config into the checkout, and commits nothing | Amended by 0077; Amended by 0094 |
| 0066 | The failing and deploying pictures show one crate per pending stack too | Amended by 0118; Amended by 0075 |
| 0067 | A stack may name its phase, and depends on every stack of every earlier phase | |
| 0068 | Terraform, Terragrunt and CDK for Terraform are the OpenTofu adapter with another binary or a wrapper in front | |
| 0069 | Helm drift is what the three-way diff finds beyond the plain one, and the deploy’s flags follow the helm it runs | |
| 0070 | Kubernetes manifests stacks prune from an inventory of their own and read drift from the managed fields | |
| 0071 | An update may be previewed on its branch, claimed by several stacks, and merged with presets from other repos | |
| 0072 | The trail says what a deploy shipped, and a row names its changes outside behind a fold | |
| 0073 | A full scan lists deploys made outside the dashboard from the tool’s own history | Amended by 0076 |
| 0074 | The check suggests inputs, asks the backend on request, and reads the rest of the workflow | Amended by 0123; Amended by 0077; Amended by 0107 |
| 0075 | The header tells a delete from a replace, counts to twenty and shows a queue | |
| 0076 | A later deploy clears the failure line, outside deploys included | |
| 0077 | One step picks its own mode, and the workflow is one job | Amended by 0120; Amended by 0104; Amended by 0109 |
| 0078 | Sluiceway sends opt-in notifications to Slack, Telegram and a webhook | Amended by 0105 |
| 0079 | The root stack resource is not a change, unless it is the only work a deploy has | |
| 0081 | An update that waits on its checks gets a line with no box | Amended by 0119 |
| 0083 | Deploy all is a bulk box and a confirm box, and the confirm box is a tick on each row | Amended by 0114; Amended by 0106 |
| 0084 | The shortened note names every section it cut, and an empty optional input is its default | Amended by 0085 |
| 0085 | The preview pool follows the cores of the machine | |
| 0086 | A run that waits long for a runner gets a line under the scan line | Amended by 0120; Amended by 0108; Amended by 0089 |
| 0087 | Resolve keeps the checkout, and says where its time goes | |
| 0088 | The example dashboard is made up, published at a release tag, and written on the release pull request | Amended by 0114; Amended by 0110; Amended by 0097 |
| 0089 | The dashboard shows times in the repo’s own zone | |
| 0090 | A kubectl recording that raced a write is taken again | |
| 0091 | A queued drift repair is started as a drift repair, and a repair that found nothing says drift gone | Amended by 0095; Amended by 0104 |
| 0092 | OpenTofu and Terraform root modules are found when the repo’s own files say so | |
| 0093 | A tick asks, an environment decides, and the check says which one decides | |
| 0094 | init and the check run as npx sluiceway, from a second bundle published by trusted publishing | Amended by 0116 |
| 0095 | A stack may deploy on merge, and the default stays a tick | Amended by 0105; Amended by 0104; Amended by 0106; Amended by 0115 |
| 0096 | What Sluiceway writes for machines is documented, versioned, and kept small | Amended by 0110 |
| 0097 | The README example keeps its picture open and breaks its lines as an issue does | |
| 0098 | A queued row starts with the crate standing still | |
| 0099 | The check says which credentials each stack needs, and which the workflow does not give it | |
| 0100 | The env-file input loads the file a step names, masks every value, and promise 2 is amended | Amended by 0103 |
| 0101 | A pull request is previewed for its reviewer, and never deployed from | |
| 0102 | A tick covers the values it does not show, through a value fingerprint | |
| 0103 | A stack may name the env file its tool gets, so a repo that spans clouds loads each stack’s credentials for that stack alone | |
| 0104 | A tick outside the deploy window waits for it instead of going out | Amended by 0109; Amended by 0115 |
| 0105 | A row shows what a change costs, and a threshold turns a merge back to a tick | |
| 0106 | Policies run against the preview, and a hard failure takes the box off the row | |
| 0107 | A Pulumi stack that its files name and the backend lacks is created by the scan, when its entry asks | |
| 0108 | The dashboard says a scan is running, from the scan’s first write | Amended by 0120 |
| 0109 | A resolve that no issue edit started hands on the open records that name its own run | Amended by 0122; Amended by 0115 |
| 0110 | The row marker carries its counts and what a queued row waits behind, and the example dashboard is data | |
| 0111 | apply refuses as moved when the branch moved under the stack after its checkout | |
| 0112 | A #, an @ and a web address in a name stay plain text | |
| 0113 | settle writes the row of a deploy it ended, with the failure line | |
| 0114 | The dashboard layout is a set of keys that move and hide, and never drop a row block | Amended by 0117; Amended by 0115 |
| 0115 | A deploy freeze holds every deploy until it ends, and nothing passes it | |
| 0116 | The command line talks to the app with the person’s token, and never to GitHub | |
| 0117 | A preview that fails is tried once more, a stack whose lock is held is busy, and the job log shows the tool’s last lines | |
| 0118 | The failing header names what failed, and the Preview failed section says what comes next | |
| 0119 | A write that went over an edit writes it back, and the walk looks through it | |
| 0119 | The open pull requests are read with pull-requests: read alone, and a list that fails is a warning | |
| 0120 | A run that failed says so under the scan line, and the next scan counts the runs that failed | |
| 0121 | A row whose drift check failed says drift not checked | |
| 0122 | A record writer is the login the site writes, and a record left alone for its writer is a warning | |
| 0123 | A dispatched resolve waits in line, and settle ends the records of a cancelled one |