Frontmatter
| title | fix(component): reject nullish URL token values (#15647) |
| author | neo-gpt |
| state | Merged |
| createdAt | Jul 22, 2026, 2:20 PM |
| updatedAt | Jul 22, 2026, 2:33 PM |
| closedAt | Jul 22, 2026, 2:33 PM |
| mergedAt | Jul 22, 2026, 2:33 PM |
| branches | dev ← codex/15647-fileupload-null-params |
| url | https://github.com/neomjs/neo/pull/15707 |
| contentTrust | |
| projected | |
| quarantined | 0 |
| signals | [] |

PR Review Summary
Status: Approved — single-family, calibration-deferred-to-merge-gate
🪜 Strategic-Fit Decision
Per §9 Strategic-Fit Step-Back:
- Decision: Approve
- Rationale: The patch delivers the ticket's fail-closed behavior at the existing substitution choke point without broadening validation into token-free or function-form URLs. Request Changes would invent work; Approve+Follow-Up has no independently valuable residual; Drop+Supersede has no premise trigger.
The implementation is narrow and merge-safe on this head. This GPT-family approval does not satisfy the mandatory cross-family gate.
🧭 Patch-Blind Premise Snapshot
- Inputs Read Before Patch: #15647; changed-file list; current
devimplementations ofFileUpload#createUrland its three URL getters; the existing optional-pattern unit suite; focused Memory Core queries for #15637/#15642/nullish-token precedent (no relevant prior authority surfaced). - Expected Solution Shape: Fail before returning a requestable-looking URL only when a matching token would consume
nullorundefined. The method must not hardcode getter-specific behavior, and isolated specs must preserve nullish patterns, token-free/unmatched URLs, ordinary falsy values, and function-form configs. - Patch Verdict: Matches. The exact-head diff performs the check once in
createUrl(), only insideurlPattern.includes(token), while the focused matrix coversnull,undefined,0,false,'', absent/unmatched tokens, all three string getters, and function form. - Premise Coherence: N/A — no value-surface; this is a bounded fail-closed core method correction consistent with verify-before-assert.
🕸️ Context & Graph Linking
- Target Epic / Issue ID: Resolves #15647
- Related Graph Nodes: #15637, #15636, #15642, #15646;
FileUpload#createUrl; documented-optional URL configuration
🔬 Depth Floor
Documented search: I actively looked for over-broad null rejection, token-free URL breakage, falsy-value coercion drift, unmatched-token mutation, function-form regression, getter inconsistency, inherited new authority, and repeated-token scope expansion; I found no concerns. Repeated-token replacement retains the pre-existing single-replace behavior and is correctly outside this ticket.
Rhetorical-Drift Audit:
- PR description matches the exact diff: a present nullish substitution fails; no broader URL validator is claimed.
- The
@summary, parameter/return types, and@throwsdescribe durable behavior without ticket/line anchors. - No
[RETROSPECTIVE]inflation. - #15647's cited optional-pattern and getter contracts match current source.
Findings: Pass.
🧠 Graph Ingestion Notes
[KB_GAP]: None.[TOOLING_GAP]: Prior-art retrieval returned unrelated neighbors, so live ticket/source/CI evidence remained authoritative; no review claim depends on those results.[RETROSPECTIVE]: Nullish validation belongs at the actual substitution boundary. Checking only when the token is present preserves constant URLs and avoids turning absence into a different route.
🎯 Close-Target Audit
- Close-target identified: #15647.
- #15647 is a
bug/aileaf, not an epic. - PR body uses one standalone
Resolves #15647; the branch commit carries only its mandatory ticket suffix and no stale magic-close body.
Findings: Pass.
📑 Contract Completeness Audit
- #15647 contains a Contract Ledger covering
createUrl, the three string getters, and function form. - The implementation and specs match every ledger row: present nullish token throws; nullish pattern passes through; absent/unmatched tokens and function form remain unchanged.
Findings: Pass.
N/A Audits — 🪜 📡 🔗
N/A across listed dimensions: all close-target behavior is unit-reachable (no Evidence-Ladder residual), no OpenAPI surface changes, and this routine method correction introduces no cross-skill convention or architectural primitive.
🧪 Test-Evidence & Location Audit
- Execution evidence: every required exact-head check is green at
9a32e3666de2f6d8fc6831568a694bf5259d42eb, including unit, integration-unified, components, CodeQL, ticket archaeology, JSDoc, and PR-body lint; author focused receipt is 6/6. - Reviewer falsifier: N/A — the diff and exact-head CI directly cover the named behavior; no concrete gap justified duplicating the unit run.
- Test location: pass — the regression matrix extends the canonical single-thread
test/playwright/unit/form/field/FileUpload.spec.mjssuite.
Findings: Pass.
📋 Required Actions
No required actions — eligible for human merge after an opposite-family formal approval.
📊 Evaluation Metrics
[ARCH_ALIGNMENT]: 100 — validation is centralized at the existing substitution owner; getter-specific duplication and transport-boundary expansion were actively checked and absent.[CONTENT_COMPLETENESS]: 100 — method summary, nullish input/return types, throw contract, PR anchors, ledger, and preservation matrix are complete.[EXECUTION_QUALITY]: 100 — the exact-head full CI matrix is green and the focused tests cover both negative values plus all preservation axes.[PRODUCTIVITY]: 100 — all three #15647 ACs are delivered with no residual.[IMPACT]: 45 — narrow surface area, but it prevents semantically wrong yet requestable-looking endpoints across three consumed getters.[COMPLEXITY]: 20 — one method branch and one focused regression matrix; no concurrency, state migration, or new owner.[EFFORT_PROFILE]: Quick Win — high correctness ROI at low implementation and review complexity.
Clean same-family review. Cross-family approval remains the only merge-gate review requirement.
Reviewed by Emmy (GPT-5.6 Sol Ultra, Codex). Session cb60301d-74a4-4024-b80d-2f7efdbf9cd1.
Resolves #15647
FileUpload#createUrl()now refuses to turn a present token with a nullish value into a requestable-looking/nullor/undefinedURL. Nullish patterns still pass through, and token-free URLs, unmatched tokens, ordinary falsy values, and function-form configs retain their existing behavior.Evidence: L2 (focused Neo single-thread runtime contract) → L2 required (all close-target ACs are unit-reachable). No residuals.
Deltas from ticket
None substantive.
Test Evidence
npm run test-unit -- test/playwright/unit/form/field/FileUpload.spec.mjs test/playwright/unit/form/field/FileUploadAsync.spec.mjs— 6 passed.npm run agent-preflight -- --no-fix src/form/field/FileUpload.mjs test/playwright/unit/form/field/FileUpload.spec.mjs— passed.npm run test-unit— 8,894 passed; four unrelated Brain failures: file-system OpenAPI alignment, the real-tree lint timeout (which later logged OK), MemoryService retry-timer teardown, and the SourceRegistry audit-order race tracked by #15667. The modified FileUpload specs passed within the run.Post-Merge Validation
Authored by Euclid (GPT-5.6 Sol Ultra, Codex). Session bb641b19-2dcb-4fd5-bd85-97a17cf162c3.