Skip to content

ci(ci): apply scripts/deno.json permission grants in the repo scripts tests - #338

Merged
ryanleecode merged 1 commit into
mainfrom
ci/scripts-tests-permissions
Oct 13, 2026
Merged

ryanleecode merged 1 commit into
mainfrom
ci/scripts-tests-permissions

Conversation

@systemfsoftware-maker

@systemfsoftware-maker systemfsoftware-maker commented Oct 13, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Root owns this change. The check job's verdict steps in .github/workflows/ci.yml are a judgment surface, and its owner is root.

CONST-E7: the gate owner (root) differs from the graded pin owners G and K. Root ordered and owns the gate change; nobody's graded work is shaped to pass by changing it.

The change is one line, at .github/workflows/ci.yml:137, in the existing Repo scripts tests step:

-        run: ./bin/deno test --config=scripts/deno.json scripts/
+        run: ./bin/deno test -P --config=scripts/deno.json scripts/

Nothing else in ci.yml changes, and no other file changes. Without -P, Deno ignores any permissions set in scripts/deno.json, so a script test that needs a granted permission would fail with NotCapable in CI even though the config allows it. With -P, the step loads the config's default permission set.

This PR is separate from #332 and does not touch release.jsonc, turbo.json, dependency files, or other CI. The owed docs/solutions entry (the release intent gate keys on typecheck, not build, because build inputs omit shipped contract/ and lib/ files) is a different concern from this flag, so it stays separate rather than folded in here.

Does scripts/deno.json grant anything on main?

No. It grants no permissions today: git show origin/main:scripts/deno.json | jq -c '{permissions, test}' returns {"permissions":null,"test":null}. The file holds only compilerOptions, minimumDependencyAge and imports. The step therefore has no grants to apply yet. Root ruled that this PR enables the grant path, so grants added later take effect, and adds no grant.

Scripts-step evidence (deno 2.9.7, head d2bc3e0198f266c61da51cf01c3e370a3babe627)

Run Result
./bin/deno test -P --config=scripts/deno.json scripts/ ok | 10 passed | 0 failed, exit 0: scripts/change-lane.test.ts (6) and scripts/turbo-summary.test.ts (4); prints Warning Permissions in the config file is an experimental feature and may change in the future.
Same without -P (main's command) ok | 10 passed | 0 failed, exit 0
Scratch config {"permissions":{"default":{"env":["PROBE_VAR"]}}} plus a test that reads PROBE_VAR, no -P NotCapable: Requires env access to "PROBE_VAR", FAILED
Same scratch config, with -P ok | 1 passed

The last two rows prove that -P applies grants from the config.

The step's log in CI on this head (CI run 38383735483, job check 115250611957, step Repo scripts tests):

##[group]Run ./bin/deno test -P --config=scripts/deno.json scripts/
Warning Permissions in the config file is an experimental feature and may change in the future.
running 6 tests from ./scripts/change-lane.test.ts
running 4 tests from ./scripts/turbo-summary.test.ts
ok | 10 passed | 0 failed (117ms)

CI on d2bc3e01: all 5 workflow runs passed

Verification

Check Result
Diff git diff --stat origin/main...HEAD: .github/workflows/ci.yml, 1 insertion and 1 deletion
pnpm format:check exit 0
pnpm check:ci on d2bc3e01 exit 0, turbo 120/120 and 18/18
CE pack resolver on head exit 0; 7 packs loaded, 0 skipped (no warnings, no errors), all at a578c704a48db36b697d21359c7c09b73eee0ece
Stack gh stack view: trunk main lists ci/scripts-tests-permissions
Overlap file-level match only, with #288 (stryker/mutant-drop-audit-ci, ci.yml hunk at line 699) and #286 (stryker/tsgo-checker-shortcut, hunk at line 688). Neither touches line 137. git merge-tree with #288 is clean; #286's only conflict is in its own CheckerRuntime.service.ts. The branch is based on current main as root ordered.

No mutation testing was run locally.

Review (ce-code-review, full path, report-only, head d2bc3e0198f266c61da51cf01c3e370a3babe627, base 3797debd60e55f45498dcc08403774457c06c25e = origin/main)

Served models, read from each reviewer's transcript (none on Grok):

  • Correctness, project-standards, adversarial and learnings personas, and both validators: openrouter/deepseek/deepseek-v4.1-flash.
  • Cross-model adversarial peer (omp -p --model minimax-code/MiniMax-M3.1-Flash-Preview --thinking high --no-tools): served by minimax-code/MiniMax-M3.1-Flash-Preview with no fallback, session 01a134a6-9d52-76a8-9f40-95ab128269d5.

Pack rules (project-standards lens): all 57 rule files of the 7 enrolled packs

7 comply, 1 violate (pre-existing; see finding 1), 49 not-applicable.

Rule Verdict Reviewed at
cell-architecture/callable-vs-resource-syntax.md not-applicable .github/workflows/ci.yml:None
cell-architecture/decode-never-cast.md not-applicable .github/workflows/ci.yml:None
cell-architecture/four-channel-contracts.md not-applicable .github/workflows/ci.yml:None
cell-architecture/handle-state-privacy.md not-applicable .github/workflows/ci.yml:None
cell-architecture/pipeable-dual-parity.md not-applicable .github/workflows/ci.yml:None
cell-architecture/pipeline-composition.md not-applicable .github/workflows/ci.yml:None
cell-architecture/pure-decision-workflows.md not-applicable .github/workflows/ci.yml:None
cell-architecture/resource-vs-handle-duality.md not-applicable .github/workflows/ci.yml:None
cell-architecture/sandwich-phase-order.md not-applicable .github/workflows/ci.yml:None
cell-architecture/scoped-lifecycle-boundaries.md not-applicable .github/workflows/ci.yml:None
cell-architecture/service-and-layer-boundaries.md not-applicable .github/workflows/ci.yml:None
cell-architecture/single-namespace-barrel.md not-applicable .github/workflows/ci.yml:None
cell-architecture/staged-lawful-builders.md not-applicable .github/workflows/ci.yml:None
cell-architecture/store-serializable-unit-of-work.md not-applicable .github/workflows/ci.yml:None
cell-architecture/store-unit-of-work-handle.md not-applicable .github/workflows/ci.yml:None
boundary-testing/expected-values-never-come-from-the-subjects-output.md not-applicable .github/workflows/ci.yml:None
boundary-testing/fake-and-real-store-laws.md not-applicable .github/workflows/ci.yml:None
boundary-testing/no-mocks-on-internal-glue.md not-applicable .github/workflows/ci.yml:None
boundary-testing/pin-dependency-semantics.md not-applicable .github/workflows/ci.yml:None
boundary-testing/port-fakes-pass-the-port-contract.md not-applicable .github/workflows/ci.yml:None
boundary-testing/real-system-oracles.md not-applicable .github/workflows/ci.yml:None
boundary-testing/staged-protocol-evidence.md not-applicable .github/workflows/ci.yml:None
schema-laws/arbitrary-filter-floors.md not-applicable .github/workflows/ci.yml:None
schema-laws/cross-field-invariants-as-struct-checks.md not-applicable .github/workflows/ci.yml:None
schema-laws/data-only-schema-classes.md not-applicable .github/workflows/ci.yml:None
schema-laws/invariants-as-refinements.md not-applicable .github/workflows/ci.yml:None
schema-laws/law-failure-is-a-codec-defect.md not-applicable .github/workflows/ci.yml:None
schema-laws/recursive-schema-suspend.md not-applicable .github/workflows/ci.yml:None
schema-laws/refusals-beside-generated-laws.md not-applicable .github/workflows/ci.yml:None
schema-laws/rich-type-over-foreign-encoded.md not-applicable .github/workflows/ci.yml:None
schema-laws/tagged-unions-over-state-by-presence.md not-applicable .github/workflows/ci.yml:None
schema-laws/tests-own-no-schemas.md not-applicable .github/workflows/ci.yml:None
package-topology/condition-branch-agreement.md not-applicable .github/workflows/ci.yml:None
package-topology/declared-entry-points.md not-applicable .github/workflows/ci.yml:None
package-topology/enumerated-entry-modules.md not-applicable .github/workflows/ci.yml:None
package-topology/import-time-inertness.md not-applicable .github/workflows/ci.yml:None
package-topology/one-access-path.md not-applicable .github/workflows/ci.yml:None
package-topology/public-signature-types.md not-applicable .github/workflows/ci.yml:None
package-topology/surface-changes-are-versioned.md not-applicable .github/workflows/ci.yml:None
mutation-discipline/kill-survivors-with-contract-properties.md not-applicable .github/workflows/ci.yml:None
mutation-discipline/suppress-by-shape-in-an-ignorer.md not-applicable .github/workflows/ci.yml:None
mutation-discipline/unkillable-survivors-are-dead-code.md not-applicable .github/workflows/ci.yml:None
ci-wall-clock/failures-name-the-gate-and-location.md violate .github/workflows/ci.yml:137
ci-wall-clock/flake-outputs-build-once-on-main.md not-applicable .github/workflows/ci.yml:None
ci-wall-clock/gates-share-one-job.md comply .github/workflows/ci.yml:137
ci-wall-clock/heavy-lanes-state-their-daily-minutes.md not-applicable .github/workflows/ci.yml:None
ci-wall-clock/heavy-suites-judge-every-main-commit.md not-applicable .github/workflows/ci.yml:None
ci-wall-clock/light-checks-run-the-pinned-tool.md not-applicable .github/workflows/ci.yml:None
ci-wall-clock/local-gate-equals-pr-gate.md comply .github/workflows/ci.yml:137
ci-wall-clock/no-dev-shell-on-verdict-lanes.md comply .github/workflows/ci.yml:137
ci-wall-clock/no-lane-grades-the-repos-own-docs.md comply .github/workflows/ci.yml:137
ci-wall-clock/one-stuck-job-backstop.md comply .github/workflows/ci.yml:137
ci-wall-clock/pr-gate-runs-only-what-the-diff-affects.md comply .github/workflows/ci.yml:137
ci-wall-clock/red-main-reverts-its-culprit-same-day.md not-applicable .github/workflows/ci.yml:None
ci-wall-clock/release-promotes-the-staging-proven-build.md not-applicable .github/workflows/ci.yml:None
ci-wall-clock/setup-under-a-minute.md comply .github/workflows/ci.yml:137
turbo-task-graph/selection-and-caching-go-through-turbo.md not-applicable .github/workflows/ci.yml:None

Repo rules: CONST-E7 and CONST-E9 (root owns the gate), CONST-W1 (one line, as ordered), AGENTS.md:7 (.github/workflows/ is read-only for agents; this edit is root-ordered), GATE1 (no new gate; an existing step gains a flag), and OP13b (stacked on main) all comply.

Findings: every one is closed

# Sev Reviewer Finding Disposition
1 P2 project-standards (deepseek-v4.1-flash) Changed verdict step has no id and no reason code rejected by validator: Inspection confirms the fact (ci.yml:136 - name: Repo scripts tests carries no id:, and the verdict env at ci.yml:196-215 has no SCRIPTS entry, so its failure falls through to the final else giving reason=CHECK_SETUP_FAILED with a log pointer), but the diff changes only the run: text at ci.yml:137 and the missing id / absent table row predate and are unaffected by that one-line change, so the pre-existing ground for rejection applies. (pack rule ci-wall-clock/failures-name-the-gate-and-location.md, pre-existing since ee2c4cf)
2 P3 learnings (deepseek-v4.1-flash) Flag is inert: scripts/deno.json defines no permission set closed by root ruling (2026-10-13): the validator confirmed it twice (second pass with the full order: On reviewed head d2bc3e0 (deno 2.9.7) scripts/deno.json's only top-level keys are compilerOptions, minimumDependencyAge and imports, so ./bin/deno test -P --config=scripts/deno.json scripts/ emitted only Warning Permissions in the config file is an experimental feature and may change in the future. before ok / 10 passed / 0 failed (exit 0), i.e. -P at ci.yml:137 loads no permission set and the step's sole new effect is that warning; the commit subject ci(ci): apply scripts/deno.json permission grants in the repo scripts tests therefore names an effect the tree cannot produce (its own ). Root ruled it out of scope: this PR enables the grant path so that future grants in scripts/deno.json apply, and adds no grant. No commit.
3 P2 cross-model peer (MiniMax M3.1) Test step becomes more privileged than the gate it validates rejected by validator: The premise is false: package.json check:ci runs format:check, lint:conventions, gate:tasks and gate:dist, and gate:tasks runs gate:repo plus turbo lint lint:tsgo typecheck test — none invokes a deno test of scripts/ — while grep shows the repo's only deno test ... scripts/ invocation is ci.yml:137, so no test-versus-gate permission divergence exists to introduce.
4 P2 cross-model peer (MiniMax M3.1) scripts/deno.json becomes an unreviewed privilege-grant channel rejected by validator: The diff adds no grant — scripts/deno.json:1-15 contains no permissions key (grep for permissions under scripts/ returns nothing) — so it introduces no privilege-boundary change and cannot widen what the step may do; the alleged unreviewed-grant harm requires a future commit and describes no defect in the reviewed diff.
5 P3 cross-model peer (MiniMax M3.1) Local and CI run the scripts tests with different permissions rejected by validator: check:ci does not run the scripts tests (package.json check:ci/gate:tasks contain no deno test; the only deno test ... scripts/ occurrence in the repo is ci.yml:137), and the hand-written invocation at ci.yml:136-137 predates this diff (only the run: text changed), so no local/CI permission divergence is created by this change.

Correctness and adversarial raised no findings.

… tests

The Repo scripts tests step ran deno test with --config=scripts/deno.json
but without -P, so a permissions block in that config would never reach
the tests: a script test needing a grant would fail with NotCapable in CI
while the config said it was allowed. With -P the step applies the
config's default permission set. scripts/deno.json grants nothing today,
so the ten existing tests run the same either way.
@systemfsoftware-maker systemfsoftware-maker changed the title ci/scripts tests permissions ci(ci): apply scripts/deno.json permission grants in the repo scripts tests Oct 13, 2026

@ryanleecode ryanleecode left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Root verdict: one-line -P at ci.yml:137, CI green on d2bc3e0 incl. the Repo scripts tests log, full-path receipt (DeepSeek v4.1 flash + MiniMax M3.1 peer), 0 threads. Pre-existing finding 1 (scripts step has no id/reason code) is routed as a follow-up.

@ryanleecode
ryanleecode merged commit cec409b into main Oct 13, 2026
22 checks passed
@ryanleecode
ryanleecode deleted the ci/scripts-tests-permissions branch October 13, 2026 14:33
systemfsoftware-maker added a commit that referenced this pull request Oct 13, 2026
The root ruled that the pin moves into the Turbo graph. turbo.json gains //#test:scripts, whose inputs are what the suite reads and runs (scripts/**, the lockfile and pnpm-workspace.yaml for the turbo it drives, bin/deno and the flake for the deno that runs it), and gate:tasks runs test:scripts beside lint, typecheck and test. The plan records that main's #338 already added -P to Repo scripts tests, repoints the reader table at the fixture tsconfig include that replaced the deleted fixture-project.js, and the changeset separates the cached and the never-cached package.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants