AI Decision System
Replayable, offline-verifiable records for AI-assisted go/no-go decisions: experiment promotions, typed model answers and human-approved actions.
README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
📖 Documentation — getting
started, every rule, and the full reference.
decolint is a linter for Dev Container configuration
files: devcontainer.json, devcontainer-feature.json, and
devcontainer-template.json. It reports mistakes, container privileges, and
unpinned versions that the Dev Container tooling itself accepts without a word.
Take a devcontainer.json that opens cleanly in VS Code and builds without
complaint:
console
GOEXPERIMENT=jsonv2 go install github.com/bare-devcoREADME 전문 보기 ↗📖 Documentation — getting started, every rule, and the full reference.
decolint is a linter for Dev Container configuration
files: devcontainer.json, devcontainer-feature.json, and
devcontainer-template.json. It reports mistakes, container privileges, and
unpinned versions that the Dev Container tooling itself accepts without a word.
Take a devcontainer.json that opens cleanly in VS Code and builds without
complaint:
// .devcontainer/devcontainer.json
{
"name": "api",
"image": "mcr.microsoft.com/devcontainers/go:latest",
"features": {
"ghcr.io/devcontainers/features/docker-in-docker": {}
},
"runArgs": ["--privileged"],
"mounts": [
"source=/var/run/docker.sock,target=/var/run/docker.sock,type=bind"
],
"forwardPorts": ["db:5432"]
}
$ decolint .
Config: .decolint.jsonc
Linted 1 file:
.devcontainer/devcontainer.json (devcontainer)
.devcontainer/devcontainer.json:1:1: error: "ALL" is not set via "runArgs", leaving the container with its default Linux capabilities (require-cap-drop-all)
.devcontainer/devcontainer.json:1:1: error: "no-new-privileges" is not set via "securityOpt" or "runArgs", allowing container processes to gain additional privileges (require-no-new-privileges)
.devcontainer/devcontainer.json:1:1: error: neither "remoteUser" nor "containerUser" is set, so the container defaults to running as root (require-non-root)
.devcontainer/devcontainer.json:3:12: error: image "mcr.microsoft.com/devcontainers/go:latest" uses the "latest" tag; pin a specific version (no-image-latest)
.devcontainer/devcontainer.json:3:12: error: image "mcr.microsoft.com/devcontainers/go:latest" is not pinned by digest; add an "@sha256:..." digest (pin-image-digest)
.devcontainer/devcontainer.json:5:5: error: feature "ghcr.io/devcontainers/features/docker-in-docker" has no explicit version; pin a specific version (pin-feature-version)
.devcontainer/devcontainer.json:7:15: error: "runArgs" contains "--privileged", disabling the container's isolation from the host (no-privileged-container)
.devcontainer/devcontainer.json:9:5: error: "mounts" entry bind-mounts the Docker socket, which grants the container root-equivalent control over the host (no-docker-socket-mount)
.devcontainer/devcontainer.json:11:20: error: "forwardPorts" entry "db:5432" uses "host:port" format; Codespaces only supports a bare port number (no-host-port-format)
Found 9 errors and 0 warnings.
That run has every category and both target platforms enabled; the defaults are quieter. See Set up your project.
devcontainer.json is container runtime configuration, and nobody
reviews it that way. --privileged and a bind-mounted Docker socket read
like ordinary setup lines, and they ship to every teammate and every CI run
that rebuilds the container.bind mounts and rejects host:port entries without
reporting anything; the container just comes up wrong.Your devcontainer.json is only part of the configuration. The Features it
references and the base image it names contribute their own, and the tooling
merges all of it before the container starts. Take a file that is careful about
everything visible in it — pinned by digest, capabilities dropped, no new
privileges:
// .devcontainer/devcontainer.json
{
"name": "api",
"image": "mcr.microsoft.com/devcontainers/go:1.24@sha256:8de3d5b3a3ce235671c7649f0b910414158a220d18cbd2714a4446cc0cc6acd3",
"runArgs": ["--cap-drop=ALL"],
"securityOpt": ["no-new-privileges"]
}
Nothing in it is wrong. The problems are in what it pulls in:
$ decolint --merge .
Downloading image metadata(mcr.microsoft.com/devcontainers/go:1.24@sha256:8de3d5b3a3ce235671c7649f0b910414158a220d18cbd2714a4446cc0cc6acd3)
Config: .decolint.jsonc
Linted 1 file:
.devcontainer/devcontainer.json (devcontainer)
.devcontainer/devcontainer.json:3:3: error: "securityOpt" overrides the default seccomp profile (no-seccomp-override)
.devcontainer/devcontainer.json:3:3: error: "securityOpt" contains "seccomp=unconfined", disabling the container's syscall filtering (no-seccomp-unconfined)
.devcontainer/devcontainer.json:3:3: error: extension "golang.Go" has no explicit version; pin a specific version (pin-extension-version)
.devcontainer/devcontainer.json:3:3: error: extension "dbaeumer.vscode-eslint" has no explicit version; pin a specific version (pin-extension-version)
Found 4 errors and 0 warnings.
Not one of those is in the file above. The base image disables seccomp and installs two unpinned VS Code extensions, and that configuration reaches the container whether or not anyone reads it. decolint reports each finding at the property that pulled it in.
Turn it on with --merge, or "merge": true in your config; see Lint what
actually
runs
for what gets resolved and what does not.
Run it against your own repository, without installing anything:
docker run --rm -v "$PWD:/workspace" ghcr.io/bare-devcontainer/decolint
Download a signed binary from the releases page, or build from source:
GOEXPERIMENT=jsonv2 go install github.com/bare-devcontainer/decolint/cmd/decolint@latest
GOEXPERIMENT=jsonv2 is required because decolint uses the still experimental
encoding/json/v2 standard library package. The container image is published for
linux/amd64 and linux/arm64. See Getting
started
for the image tags available and how to verify a release artifact.
Every rule belongs to one category, which sets its severity. Only correctness
runs without configuration; the rest are off until you enable them:
| Category | Default | Rules |
|---|---|---|
correctness | error | 13 |
security | off | 11 |
reproducibility | off | 5 |
style | off | 2 |
Rules are plain Go code and new ones are easy to add; see CONTRIBUTING.md for the development workflow and a walkthrough of adding a rule.