Skip to content

refactor(deploy_keys): validate the key's base64 blob with z.base64(), the published pattern held in lockstep - #565

Merged
Vivswan merged 1 commit into
mainfrom
refactor/deploy-keys-zod-base64
Oct 27, 2026
Merged

Vivswan merged 1 commit into
mainfrom
refactor/deploy-keys-zod-base64

Conversation

@Vivswan

@Vivswan Vivswan commented Oct 26, 2026

Copy link
Copy Markdown
Owner

What this changes

parse time   materialPattern() regex over the whole key line
               ->  one structured walk: fields, form checks, the side's algorithm rule, z.base64() on the blob
published    PUBLIC_KEY_PATTERN keeps a hand-spelled base64 grammar (zod's own pattern opens with ^$| and cannot be embedded)
lockstep     test/sections/deploy_keys/published-pattern.test.ts compiles the built schema's pattern with ajv
             and holds it to parsePublicKey's verdict: the e2e generators' keys, a 5,000-key sweep, 14 invalid rows

differential, old against new on verdict, message text, and material:
  20,050 key lines (45 hand-made, 5 generator, 20,000 seeded random)   0 mismatches   952 accepted, 19,098 refused
  published pattern (ajv) against the new parse                        0 mismatches

How

  • Two spellings of one rule, by design: zod validates at parse time, the schema needs a pattern string; the lockstep test fails CI when a zod bump moves base64 semantics or one spelling is edited alone.
  • Removed: materialPattern, STORED_KEY_PATTERN, the regex-driven parseMaterial, declaredRejection, storedRejection; parseMaterial now yields the material or the reason.
  • The one blob where zod and the grammar differ is the empty string, unreachable behind the two-field check on both sides.
  • Library: zod's z.base64(), the schema library already in use; ajv in the test, already a devDependency.

Proof

  • Tests: deploy_keys, refusal-messages, published-schema, schema-corpus, slice-exports, layout: 183 pass; e2e 373/373; every refusal message byte-identical.
  • Gates: typecheck, knip, build:check 14 files unchanged, fleet biome 0, member-shape 0, line cap.
Technical details
  • Published pattern text: its two capture groups became non-capturing, the only textual change; the accepted language is unchanged.
  • Renamed: BASE64_BLOB is BASE64_PATTERN (the refusal-messages constant table follows).
  • Files: src/sections/deploy_keys/schema.ts, test/sections/deploy_keys/published-pattern.test.ts (new), test/sections/refusal-messages.test.ts.

…z.base64() at parse time

The deploy key line was accepted by one hand-written regex built from a hand-written base64 grammar, with a second instance for material GitHub returned, and the rejection helpers ran only after the regex failed, to name a reason. The parse is now one structured walk: the fields, the form checks, the side's algorithm rule, then the blob under zod's z.base64(), which covers the alphabet, the padding, and the multiple-of-four length. materialPattern(), STORED_KEY_PATTERN, declaredRejection(), and storedRejection() are gone; the hand-spelled grammar remains only inside PUBLIC_KEY_PATTERN, the published JSON Schema pattern for the key field, whose capture groups are now non-capturing since nothing reads them.

zod's check takes the empty string too; the two-field check ahead of it makes an empty blob a missing field on both sides. zod's own published base64 pattern opens with ^$| and cannot sit inside a larger pattern, so the published grammar stays hand-spelled, and test/sections/deploy_keys/published-pattern.test.ts holds the published pattern and parsePublicKey to one verdict over the generators' keys, a seeded sweep over every axis of the line, and the hand-made invalid set (bad padding, a non-base64 character, an empty blob, a wrong length class).

Differential check, the origin/main module against this one: 20,050 distinct key lines (45 hand-made, 5 from the e2e generators, 20,000 seeded random), parsePublicKey and parseStoredKey compared on verdict, message, and material: 0 mismatches. The published pattern against the new parsePublicKey: 0 mismatches. Blob-level control: zod's check and the hand grammar diverge on exactly one blob, the empty string. Every refusal message is unchanged.
Copilot AI balanced review requested due to automatic review settings October 26, 2026 20:30
@github-actions

Copy link
Copy Markdown
Contributor

File size check

0 over a hard cap (fails), 6 warning(s).

File Size Tier Cap
src/engine/diff.ts:56 11 comment lines warn 10
src/github/api-error.ts:9 11 comment lines warn 10
src/problem.ts:73 18 comment lines warn 10
src/sections/contract/errors.ts:13 11 comment lines warn 10
src/sections/contract/module.ts:55 12 comment lines warn 10
src/sections/shared/list/decl.ts:265 14 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.

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

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 focused parser refactor and schema-agreement tests have no identified blocking defects.

No open issues 🎉

What changed in this PR

Refactors deploy-key parsing to validate the base64 field with z.base64(), while retaining a separate pattern for the published JSON Schema.

Changes:

  • Replaces regex-driven parsing with structured field, form, algorithm, and base64 checks.
  • Adds tests comparing the published schema pattern with parser verdicts across generated, randomized, and invalid keys.
  • Updates the refusal-message test's constant list for the renamed base64 pattern.
File Description
test/​sections/​refusal-messages.test.ts Updates the base64 constant name in the test allowlist.
test/​sections/​deploy_keys/​published-pattern.test.ts Adds schema-pattern and parser agreement tests.
src/​sections/​deploy_keys/​schema.ts Introduces structured parsing with Zod base64 validation.

Review effort: Balanced

@Vivswan
Vivswan marked this pull request as ready for review October 26, 2026 20:36
@Vivswan
Vivswan merged commit b2ed711 into main Oct 27, 2026
31 checks passed
@Vivswan
Vivswan deleted the refactor/deploy-keys-zod-base64 branch October 27, 2026 07:19
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