Skip to content

refactor(e2e): an excluded section predicts at no grade - #120

Merged
Vivswan merged 2 commits into
mainfrom
followup/oracle-excluded-grades
Sep 11, 2026
Merged

Vivswan merged 2 commits into
mainfrom
followup/oracle-excluded-grades

Conversation

@Vivswan

@Vivswan Vivswan commented Sep 10, 2026 •

Copy link
Copy Markdown
Owner

Before / After

Before, an excluded section (declared in settings.yml, but outside the sections allowlist) carried mask-derived grades, and three consumers in test/e2e/oracle.ts compensated with an allowed.has("excluded") check:

Consumer Old check
preflightDeniable returned "no" when allowed had "excluded"
fullyGranted (in predictOutcomes) `s.allowed.has("excluded")
writeDeniedSections followed writeGranted over grades the section never ran at

After, one owner. predictSectionAt mints the excluded prediction whole, before the mask is consulted:

{ key, grades: [], allowed: new Set(["excluded"]), mayWrite: false }

How

Proof

  • bun run check green; fuzz 30/30 ok (master seed 2385354755); four whole-object oracle tests added.
Technical details

Mechanism

  • src/engine/orchestrate.ts classifies a section excluded in its disposition filter, which feeds both the preflight list and the section loop. Preflight never probes it and the loop skips it before any read, so no grade can matter.
  • Empty grades make each fold vacuous: preflightDeniable finds no none grade (so "no"), writeGranted is [].every(...) (true), and fullyGranted and writeDeniedSections follow.
  • Grant and grade computation now sit after both early-return folds.
  • test/e2e/fuzz.ts was checked for other readers of grades or allowed on excluded sections: the comparison loop still requires an "excluded" summary row, and only its mismatch diagnostic prints the grade list.

Tests (test/e2e/oracle.test.ts, whole-object)

  • excluded plain section predicts at no grade, beside its unrestricted control (denied 403 read in check mode predicts failed)
  • excluded NO_READ section in check mode is excluded, not the read-free clean
  • excluded org-only section on a personal account: exclusion wins, grades []
  • run level: an excluded denied section beside an active one, whole RunPrediction; negative control with the same meta active predicts preflightAborts: "yes" and exit 1

Gates and review

Gate Result
bun run check green
bun test/e2e/fuzz.ts --iterations 0 green
bun test/e2e/fuzz.ts --iterations 30 30/30 ok, master seed 2385354755
codex rubber-duck round 1 APPROVE (one comment-wording nit, applied); round 2 APPROVE, no findings

@github-actions

github-actions Bot commented Sep 10, 2026 •

Copy link
Copy Markdown
Contributor

Template check

Integrity

Passed - this repository matches the state it was stamped with.

Freshness

This repository is behind the build branch by 17 commit(s). The next sync PR updates the managed files; nothing to do here.

@github-actions

github-actions Bot commented Sep 10, 2026 •

Copy link
Copy Markdown
Contributor

File size check

23 over a hard cap (fails), 108 warning(s).

File Size Tier Cap
src/action/inputs.ts:86 477 chars hard 256
src/action/inputs.ts:93 438 chars hard 256
src/action/inputs.ts:100 583 chars hard 256
src/action/inputs.ts:165 375 chars hard 256
src/action/inputs.ts:544 338 chars hard 256
src/action/inputs.ts:572 324 chars hard 256
src/action/inputs.ts:774 274 chars hard 256
src/github/repo-file.ts:58 277 chars hard 256
test/action/inputs.test.ts:147 260 chars hard 256
test/action/inputs.test.ts:212 278 chars hard 256
test/action/inputs.test.ts:219 282 chars hard 256
test/action/inputs.test.ts:262 319 chars hard 256
test/action/multi.test.ts:282 337 chars hard 256
test/action/run.test.ts:768 326 chars hard 256
test/github/api.test.ts:741 258 chars hard 256
test/github/repo-file.test.ts:62 266 chars hard 256
test/sections/contract.test.ts:319 258 chars hard 256
test/sections/contract.test.ts:380 353 chars hard 256
test/sections/contract.test.ts:556 374 chars hard 256
test/sections/contract.test.ts:607 263 chars hard 256
test/sections/contract.test.ts:1165 263 chars hard 256
test/sections/setup-section.test.ts:59 376 chars hard 256
test/sections/setup-section.test.ts:77 304 chars hard 256
.github/scripts/gen-action-docs.ts:404 204 chars warn 150
.github/scripts/gen-docs.ts:365 190 chars warn 150
.github/scripts/release-pipeline.ts:620 160 chars warn 150
.github/scripts/release-pipeline.ts:750 180 chars warn 150
.github/scripts/release-pipeline.ts:1 40 comment lines (header) warn 25
.github/scripts/release-pipeline.ts:524 22 comment lines warn 10
.github/scripts/release-pipeline.ts:640 11 comment lines warn 10
.github/scripts/release-pipeline.ts:981 17 comment lines warn 10
.github/scripts/release-pipeline.ts:1065 14 comment lines warn 10
.github/workflows/auto-fix.yml:244 185 chars warn 150
.github/workflows/auto-fix.yml:259 155 chars warn 150
.github/workflows/auto-fix.yml:1 36 comment lines (header) warn 25
.github/workflows/post-green.yml:74 205 chars warn 150
.github/workflows/post-green.yml:44 13 comment lines warn 10
.github/workflows/update-release.yml:1 32 comment lines (header) warn 25
src/action/inputs.ts:373 154 chars warn 150
src/action/inputs.ts:374 159 chars warn 150
src/action/inputs.ts:699 217 chars warn 150
src/action/multi.ts:247 194 chars warn 150
src/action/secret-refs.ts:119 11 comment lines warn 10
src/engine/layers.ts:61 11 comment lines warn 10
src/engine/layers.ts:185 11 comment lines warn 10
src/engine/layers.ts:592 13 comment lines warn 10
src/engine/orchestrate.ts:139 249 chars warn 150
src/engine/secrets.ts:51 15 comment lines warn 10
src/engine/validate.ts:11 13 comment lines warn 10
src/report/issue-report.ts:316 13 comment lines warn 10
src/report/issue-report.ts:348 14 comment lines warn 10
src/schema.ts:1 36 comment lines (header) warn 25
src/sections/autolinks/autolinks.test.ts:22 153 chars warn 150
src/sections/collaborators/collaborators.test.ts:110 158 chars warn 150
src/sections/contract/module.ts:68 12 comment lines warn 10
src/sections/contract/module.ts:95 17 comment lines warn 10
src/sections/contract/module.ts:179 11 comment lines warn 10
src/sections/contract/module.ts:325 11 comment lines warn 10
src/sections/contract/module.ts:370 11 comment lines warn 10
src/sections/contract/module.ts:382 18 comment lines warn 10
src/sections/contract/module.ts:421 11 comment lines warn 10
src/sections/contract/module.ts:515 18 comment lines warn 10
src/sections/contract/module.ts:719 12 comment lines warn 10
src/sections/contract/permissions.ts:113 13 comment lines warn 10
src/sections/deploy_keys/deploy_keys.test.ts:315 152 chars warn 150
src/sections/environments/nested.ts:63 12 comment lines warn 10
src/sections/environments/nested.ts:173 12 comment lines warn 10
src/sections/environments/nested.ts:228 14 comment lines warn 10
src/sections/environments/schema.ts:144 11 comment lines warn 10
src/sections/shared/list-section.ts:462 232 chars warn 150
src/sections/shared/repo-secrets.ts:158 13 comment lines warn 10
src/sections/shared/schema-helpers.ts:32 16 comment lines warn 10
test/docs/claims.ts:108 11 comment lines warn 10
test/docs/guides.test.ts:324 13 comment lines warn 10
test/e2e/fuzz.ts:624 18 comment lines warn 10
test/e2e/fuzz.ts:770 14 comment lines warn 10
test/e2e/fuzz.ts:1013 12 comment lines warn 10
test/e2e/fuzz.ts:1450 12 comment lines warn 10
test/e2e/fuzz.ts:1559 12 comment lines warn 10
test/e2e/fuzz.ts:1658 11 comment lines warn 10
test/e2e/fuzz.ts:1685 11 comment lines warn 10
test/e2e/fuzz.ts:1789 11 comment lines warn 10
test/e2e/fuzz.ts:1840 13 comment lines warn 10
test/e2e/gen-support.ts:52 17 comment lines warn 10
test/e2e/gen-support.ts:150 13 comment lines warn 10
test/e2e/generators.ts 2745 lines warn 2560
test/e2e/generators.ts:86 11 comment lines warn 10
test/e2e/generators.ts:225 16 comment lines warn 10
test/e2e/generators.ts:259 19 comment lines warn 10
test/e2e/generators.ts:394 12 comment lines warn 10
test/e2e/generators.ts:809 13 comment lines warn 10
test/e2e/generators.ts:1169 12 comment lines warn 10
test/e2e/generators.ts:1231 11 comment lines warn 10
test/e2e/generators.ts:1252 32 comment lines warn 10
test/e2e/generators.ts:1317 11 comment lines warn 10
test/e2e/generators.ts:1480 13 comment lines warn 10
test/e2e/generators.ts:2295 18 comment lines warn 10
test/e2e/mock/core-paths.ts:75 16 comment lines warn 10
test/e2e/mock/core-paths.ts:173 11 comment lines warn 10
test/e2e/mock/core-paths.ts:242 13 comment lines warn 10
test/e2e/mock/core-paths.ts:373 15 comment lines warn 10
test/e2e/mock/core-paths.ts:418 13 comment lines warn 10
test/e2e/mock/core-paths.ts:588 14 comment lines warn 10
test/e2e/mock/routes.ts:343 212 chars warn 150
test/e2e/mock/routes.ts:174 17 comment lines warn 10
test/e2e/mock/routes.ts:599 11 comment lines warn 10
test/e2e/mock/state.ts:960 15 comment lines warn 10
test/e2e/mock/state.ts:1122 11 comment lines warn 10
test/e2e/openapi/paths.ts:34 16 comment lines warn 10
test/e2e/openapi/validate.ts:85 23 comment lines warn 10
test/e2e/openapi/validate.ts:416 13 comment lines warn 10
test/e2e/openapi/validate.ts:602 12 comment lines warn 10
test/e2e/oracle.ts:77 13 comment lines warn 10
test/e2e/oracle.ts:120 14 comment lines warn 10
test/e2e/oracle.ts:1031 11 comment lines warn 10
test/e2e/oracle.ts:1116 11 comment lines warn 10
test/e2e/runner.ts:59 239 chars warn 150
test/e2e/runner.ts:105 11 comment lines warn 10
test/e2e/runner.ts:480 11 comment lines warn 10
test/e2e/runner.ts:540 11 comment lines warn 10
test/e2e/runner.ts:707 15 comment lines warn 10
test/e2e/schema.ts:172 20 comment lines warn 10
test/e2e/schema.ts:296 11 comment lines warn 10
test/e2e/schema.ts:352 22 comment lines warn 10
test/e2e/schema.ts:561 11 comment lines warn 10
test/e2e/schema.ts:670 18 comment lines warn 10
test/engine/orchestrate.test.ts:144 183 chars warn 150
test/engine/orchestrate.test.ts:170 169 chars warn 150
test/scripts/release-pipeline.test.ts 2602 lines warn 2560
test/sections/registry.test.ts:266 13 comment lines warn 10
test/sections/registry.test.ts:467 11 comment lines warn 10

Split the file, wrap the line, shorten or exempt the comment, or list the path in .file-size-allow.local with a # reason.

8 managed file(s) skipped; repo-platform owns them.

@Vivswan
Vivswan marked this pull request as ready for review September 10, 2026 22:07
An error occurred while trying to automatically change base from docs/layering-guide to feat/underscore-undeclared September 11, 2026 02:24
@Vivswan
Vivswan force-pushed the followup/oracle-excluded-grades branch from 876ad86 to f5ad329 Compare September 11, 2026 02:37
@Vivswan
Vivswan changed the base branch from docs/layering-guide to main September 11, 2026 02:37
…mers stop special-casing it

In test/e2e/oracle.ts an excluded section (declared, but outside the sections allowlist) carried mask-derived grades, and three consumers compensated with allowed.has("excluded") checks: preflightDeniable, the fullyGranted fold in predictOutcomes, and writeDeniedSections through writeGranted.

predictSectionAt, the owner PR #114 chose for the personal-account no-op, now mints the excluded prediction whole: grades [], allowed {excluded}, mayWrite false, before the mask is consulted. The section runs at no grade (orchestrate.ts filters it out of the preflight list and the section loop skips it before any read), so every fold over its grades is vacuous by construction: preflightDeniable finds no none grade, writeGranted is vacuously true, and fullyGranted and writeDeniedSections follow. The three consumer-side checks are deleted.

Tests pin the whole SectionPrediction for an excluded plain section (beside its unrestricted control), an excluded org-only section on a personal account (exclusion wins), and an excluded NO_READ section in check mode, plus the whole RunPrediction for an excluded denied section beside an active one, with the same meta active as the negative control that predicts the preflight abort.

The branch includes a merge of origin/main so it sits on top of PR #114's oracle fix.
The previous commit said "runs at no grade, so every fold is vacuous" in six places in test/e2e/oracle.ts. The one statement now lives on SectionPrediction.grades, with the orchestrate.ts disposition cross-reference and the list of folds it makes vacuous; the predictSectionAt docs point there, and the fullyGranted, writeGranted, and preflightDeniable docs drop their local copies. writeGranted's doc now says "every effective grade is write", which is what the code computes for an empty grade list too.
Copilot AI balanced review requested due to automatic review settings September 11, 2026 02:52
@Vivswan
Vivswan force-pushed the followup/oracle-excluded-grades branch from f5ad329 to fe8b505 Compare September 11, 2026 02:52

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟢 Approval recommended

The implementation matches engine behavior and has focused coverage for affected predictions.

Pull request overview

Refactors the E2E oracle so excluded sections predict no execution grades, simplifying downstream folds.

Changes:

  • Returns empty grades for excluded sections before permission evaluation.
  • Removes redundant exclusion checks from run-level calculations.
  • Adds whole-object regression tests for exclusion behavior.
File summaries
File Description
test/e2e/oracle.ts Centralizes excluded-section prediction and simplifies consumers.
test/e2e/oracle.test.ts Expands regression coverage for excluded sections.
Review details
  • Files reviewed: 2/2 changed files
  • Comments generated: 0
  • Review effort level: Balanced

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@Vivswan
Vivswan merged commit be35b8e into main Sep 11, 2026
30 checks passed
@Vivswan
Vivswan deleted the followup/oracle-excluded-grades branch September 11, 2026 03:14
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