-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmise.toml
More file actions
232 lines (198 loc) · 9.26 KB
/
Copy pathmise.toml
File metadata and controls
232 lines (198 loc) · 9.26 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
# Root mise config: monorepo task discovery + shared tools.
# See https://mise.jdx.dev/tasks/monorepo.html
#
# Cedar engine parity contract (see docs/design/CEDAR_HITL_GATES.md §15.6,
# decision #23): both engines are pinned EXACTLY (no ^/~) and must move
# together. Golden-file parity fixtures under contracts/cedar-parity/ fail
# CI if the engines diverge on any (policy, input) pair.
# - agent: cedarpy==4.8.4 (agent/pyproject.toml)
# - cdk: @cedar-policy/cedar-wasm@4.8.2 (cdk/package.json)
min_version = "2026.2.6"
experimental_monorepo_root = true
[settings]
experimental = true
[tools]
node = "22"
prek = "latest"
gitleaks = "latest"
# uv must be declared so it is on PATH before semgrep installs: mise's
# `pipx.uvx` default routes pipx tools through `uv tool install` when uv is
# present, avoiding the classic-pipx "Failed to upgrade shared libraries" path
# that breaks under the mise 2026.6.x default `minimum_release_age`
# (jdx/mise#10279; see #320).
uv = "latest"
semgrep = "latest"
osv-scanner = "latest"
"grype" = "latest"
"aqua:zizmorcore/zizmor" = "latest"
[monorepo]
config_roots = ["cdk", "agent", "cli", "docs"]
##################
###### CORE ######
##################
# One `yarn install` at the repo root installs every Yarn workspace (`cdk`, `cli`, `docs`).
# `//cdk:install`, `//cli:install`, and `//docs:install` are thin wrappers around the same command.
[tasks.install]
description = "Yarn workspaces (cdk, cli, docs) + agent Python (uv) + prek git hooks when inside a Git repo"
run = [
"yarn install --check-files",
"cd agent && mise run install",
# Install prek shims only in a real checkout (skip tarballs / no-.git environments).
"bash -c 'git rev-parse --git-dir >/dev/null 2>&1 || exit 0; prek install --prepare-hooks'",
]
# Dependency upgrades for the scheduled upgrade-main workflow (and local use).
# Upgrades stay WITHIN the ranges/pins declared in each manifest — no
# range-widening flags (e.g. `yarn upgrade --latest`) — so exact pins are never
# rewritten. This is what keeps the Cedar engine parity contract intact:
# cedarpy (agent/pyproject.toml) and @cedar-policy/cedar-wasm (cdk/package.json)
# are exact pins that must only ever move together, by hand, with refreshed
# contracts/cedar-parity/ fixtures (CEDAR_HITL_GATES.md §15.6, decision #23).
[tasks.upgrade]
description = "Upgrade dependencies within declared ranges: yarn workspaces (cdk, cli, docs) + agent uv lockfile. Exact pins (incl. Cedar parity) are not rewritten."
run = [
# Regenerate the lockfile rather than `yarn upgrade`: Yarn 1 has a known bug
# where `yarn upgrade` copies `resolutions` entries into `dependencies` in
# package.json. A fresh resolve upgrades within declared ranges (and honors
# resolutions) without mutating any manifest.
"rm -f yarn.lock && yarn install",
"cd agent && mise run upgrade",
]
##################
###### QUALITY ###
##################
[tasks.quality]
description = "Monorepo quality checks (agent quality, then cdk, cli, docs)"
depends = ["//agent:quality"]
run = [
"MISE_EXPERIMENTAL=1 mise //cdk:eslint",
"MISE_EXPERIMENTAL=1 mise //cli:eslint",
"MISE_EXPERIMENTAL=1 mise //docs:check",
]
[tasks."check:types-sync"]
description = "Drift check: CDK shared/types.ts ↔ cli/src/types.ts (S8). Fails if a public type exists in both with different shapes, or if CLI exports a name CDK doesn't."
run = "node --experimental-strip-types scripts/check-types-sync.ts"
[tasks."check:constants-sync"]
description = "Drift check: cross-language constants in contracts/constants.json (S9). Fails if agent/src/policy.py declares a literal for a name owned by the JSON contract."
run = "node --experimental-strip-types scripts/check-constants-sync.ts"
[tasks."check:coverage-thresholds-sync"]
description = "Drift check: contracts/coverage-thresholds.json ↔ cdk/cli jest coverageThreshold and agent pytest fail_under"
run = "node --experimental-strip-types scripts/check-coverage-thresholds-sync.ts"
[tasks."sync:abca-commands"]
description = "Generate commands stubs from .abca/commands for multiple AI assistants"
run = "node scripts/sync-abca-commands.mjs"
[tasks."drift-prevention"]
description = "Run checks to prevent drift in contracts between packages"
run = [
{ task = "sync:abca-commands" },
{ task = "check:constants-sync" },
{ task = "check:types-sync" },
{ task = "check:coverage-thresholds-sync" },
]
##################
#### SECURITY ####
##################
[tasks."security:secrets"]
description = "Scan all git history for secrets with gitleaks (full-history sweep)"
# `gitleaks git` (history-aware) replaces the deprecated `gitleaks detect`
# (removed from --help in v8.19.0). With no --log-opts this scans the full
# history reachable from the checkout, matching the previous behaviour.
run = "gitleaks git . --no-banner --redact"
[tasks."security:secrets:range"]
description = "gitleaks over a commit range only (per-PR gate). Set GITLEAKS_RANGE, e.g. origin/main..HEAD"
# Range-scoped scan: only the commits a branch/PR introduces, not full history.
# Defaults to the full history when GITLEAKS_RANGE is unset so the task is safe
# to run anywhere. The per-PR CI job sets GITLEAKS_RANGE=origin/$BASE..HEAD.
run = 'gitleaks git . --no-banner --redact --log-opts="${GITLEAKS_RANGE:-}"'
[tasks."security:secrets:staged"]
description = "gitleaks on staged changes (pre-commit hook)"
# `gitleaks git --staged` replaces the deprecated `gitleaks protect --staged`.
run = "gitleaks git . --staged --no-banner --redact"
[tasks."security:sast"]
description = "SAST scan with semgrep (auto + OWASP top 10)"
run = "semgrep scan --config auto --config p/python --config p/typescript --config p/owasp-top-ten --config p/security-audit --error --quiet ."
[tasks."security:sast:masking"]
description = "Custom semgrep rules: silent-success masking (AI004, #257). Blocking — intentional degraded-mode fallbacks use inline justified nosemgrep on the return line."
# `semgrep test` validates the rules against their .semgrep/ fixtures first.
# The scan excludes those fixtures (they trigger by design) and writes SARIF
# to test-reports/ (gitignored) so findings stay agent-routable (CA-06).
run = [
"semgrep test .semgrep/",
"mkdir -p test-reports",
"semgrep scan --config .semgrep/silent-success-masking.yaml --exclude '.semgrep/*' --sarif-output=test-reports/semgrep-silent-success-masking.sarif --error --quiet .",
]
[tasks."security:deps"]
description = "Audit dependencies for known vulnerabilities (osv-scanner)"
# Yarn workspaces use the repo-root lockfile only; do not scan stale cli/docs yarn.lock copies.
run = "osv-scanner scan --lockfile agent/uv.lock --lockfile yarn.lock"
[tasks."security:grype"]
description = "Run Grype on source files; generated/vendor dirs are excluded because lockfile, Retire, and image scans cover dependencies and runtime artifacts"
run = [
# Dependency locks, node packages, and the built image have dedicated scans.
# Keep this filesystem scan focused on source files, not generated/vendor output.
"grype . --fail-on high --exclude './cdk/cdk.out/**' --exclude './node_modules/**' --exclude './**/node_modules/**' --exclude './**/.venv/**' --exclude './docs/dist/**'"
]
[tasks."security:retire"]
description = "Retire.js (CDK, CLI, docs)"
run = "npx retire --path cdk --severity high --ignore \"node_modules/**,cdk.out/**,cdk/cdk.out/**\" && cd cli && npm run security:retire && cd ../docs && npm run security:retire"
[tasks."security:gh-actions"]
description = "Static analysis of GitHub Actions workflows (zizmor)"
# Offline: no GitHub API for online-only rules; config in .github/zizmor.yml
run = "zizmor --offline .github"
[tasks.security]
description = "Run security scans"
run = [
{ task = "security:secrets" },
{ task = "security:deps" },
{ task = "security:sast" },
{ task = "security:sast:masking" },
{ task = "security:grype" },
{ task = "security:retire" },
{ task = "security:gh-actions" },
"MISE_EXPERIMENTAL=1 mise //agent:security",
"echo All good!"
]
##################
##### HOOKS ######
##################
[tasks."hooks:install"]
description = "Install or refresh prek git hooks (also runs at end of `mise run install` in a Git repo)"
run = "prek install --prepare-hooks"
[tasks."hooks:run"]
description = "Run prek on all files (pre-commit then pre-push stages)"
run = [
"prek run --all-files --stage pre-commit",
"prek run --all-files --stage pre-push",
]
[tasks."hooks:pre-push:security"]
description = "Pre-push security scans"
run = "mise run security"
[tasks."hooks:pre-push:tests"]
description = "Pre-push tests in cdk/cli/agent"
run = [
"MISE_EXPERIMENTAL=1 mise //cdk:test",
"MISE_EXPERIMENTAL=1 mise //cli:test",
"cd agent && mise run test",
]
[tasks."hooks:pre-push"]
description = "Pre-push gate: security scans then tests in cdk/cli/agent"
run = [
"mise run hooks:pre-push:security",
"mise run hooks:pre-push:tests",
]
##################
##### BUILD #####
##################
# All packages run in parallel via DAG. Each resolves its own internal dependencies.
# Agent quality runs alongside CDK/CLI/docs — no sequential bottleneck.
[tasks.build]
description = "Monorepo build (agent, cdk, cli, docs in parallel)"
depends = [
"//agent:quality",
"//cdk:build",
"//cli:build",
"//docs:build",
":drift-prevention"
]
[tasks.default]
description = "Install + build"
depends = [":install", ":build"]