Source-derived document; review findings and open questions with the application owner.
Evidence Gaps
In this document
Evidence Gaps
The supplied material provides a partial source-level view of the system rather than a complete, independently verified current-system specification. It includes source excerpts, view and resource files, request contracts, handlers, mappings, migrations, fixtures, tests, configuration, and secondary analyses. These artifacts establish that particular constructs or intended behaviours are represented, but they do not consistently establish that the corresponding paths are deployed, reachable, registered, persisted, authorized, or used in production.
Coverage and provenance
- Source ranges, hashes, file inventories, and reported coverage boundaries differ between analyses. Some files described as omitted from fleet or contract summaries are present in other supplied ranges, while other files and implementations are genuinely unavailable or only described indirectly.
- Per-file byte offsets and line numbers are generally unavailable. Conclusions are therefore attributable to the named artifacts or symbols, not to precise source locations.
- Several analyses concern potentially different applications, projects, releases, or runtime boundaries. The relationship between the MVC application, Web API service, core libraries, request assemblies, document-generation components, scanning libraries, email components, and database utilities is not fully established.
- Some migrations and source files could not be analysed as text because of NUL bytes, unsupported encoding, or unavailable content. Their names and surrounding migration order do not establish their implementation or execution.
- Secondary fleet documents and summaries contain omissions, misattributions, and stronger “confirmed” language than the underlying evidence supports. They should not be treated as authoritative inventories.
Runtime and deployment gaps
The deployed topology, hosting model, application boundaries, runtime target, and active configuration are unresolved. Evidence refers to .NET Framework 4.8, .NET Framework 4.5.2 or 4.0-era metadata, MVC 5.2.3 and 5.2.9, and generated runtime metadata such as 4.0.30319.42000. These may describe different projects, package or assembly versions, build tooling, or deployment contexts; they do not establish one application-wide runtime target.
The evidence does not establish:
- which routes, areas, controllers, Web API endpoints, filters, middleware, and dependency registrations are active;
- whether release configuration transforms are applied;
- which authentication authority, token scopes, certificates, secrets, database connections, SMTP settings, scanner endpoints, or external URLs are active;
- whether development-oriented configuration remains in use;
- the hosting, IIS, application-pool, proxy, TLS, filesystem, and network configuration;
- build, package-restoration, deployment, startup, migration, or smoke-test success;
- background processing, scheduled jobs, queues, brokers, or external service boundaries;
- monitoring, alerting, health checks, operational ownership, runbooks, backup, retention, restoration, or incident recovery.
Workflow and business-rule gaps
Status names, request contracts, view branches, domain methods, and test assertions expose many possible states and operations, but do not establish a complete lifecycle. Assessment and movement statuses have multiple partially overlapping vocabularies and, in some cases, hierarchical states. For example, one state description shows NotificationReceived transitioning to concrete state AwaitingPayment, while other summaries describe this as a transition to Submitted. The relationship between parent and concrete states is unresolved.
The complete rules for the following remain unknown or only partly evidenced:
- valid notification, assessment, consent, financial-guarantee, movement, receipt, rejection, cancellation, archive, deletion, and resubmission transitions;
- the actors permitted to initiate each operation;
- whether transitions are idempotent, reversible, terminal, or mutually exclusive;
- the authoritative meaning of Boolean,
Guid,Unit, status, and decision results; - the relationship between notification, assessment, movement, receipt, rejection, partial-rejection, guarantee, payment, audit, and document changes;
- whether UI state, handler rules, domain rules, database constraints, and stored procedures enforce the same invariants;
- the complete consent, working-day, quantity, shipment-count, active-load, pricing, payment, refund, and financial-guarantee calculations.
A material contradiction remains unresolved between a 30-day and a 60-day prenotification-to-shipment rule. Executable-code descriptions commonly indicate 60 days, while messages, resource names, or other summaries refer to 30 days. Similar uncertainty exists around date-boundary inclusivity, working-day calculations, consent expiry, completion ordering, quantity tolerances, and whether exact 12- or 36-month shipment-period boundaries are valid.
Validation and model-integrity gaps
Validation is distributed across view models, DataAnnotations, IValidatableObject, FluentValidation, custom attributes, domain guards, handlers, repositories, stored procedures, browser attributes, and JavaScript. The order and interaction of these layers are not established.
Unresolved validation areas include:
- malformed, partial, missing, future, timezone-sensitive, or culture-specific dates;
- null and default enum values;
- decimal parsing, precision, rounding, overflow, negative and zero amounts;
- requiredness and conditional requiredness;
- collection initialization, null collections, duplicate entries, and cardinality;
- shipment, movement, notification, user, facility, carrier, and waste-code identifier ownership;
- mutually exclusive flags and conflicting representations;
- uploaded-file content, size, extension, MIME, malware, and duplicate handling;
- report filters, pagination, date boundaries, and selected columns;
- hidden fields, posted statuses, notification numbers, charges, and other client-supplied values.
Several source-level inconsistencies are recorded, including different field names for equivalent concepts, misspelled request and property names, conflicting resource messages, inconsistent return identifiers, different null-handling conventions, and different validation behaviour for related operations. Their reachability and business impact are unknown.
Authorization and identity gaps
Authorization metadata, controller attributes, ownership filters, competent-authority checks, shared-user checks, user-context logic, and authorization services are present in selected paths. They do not establish a complete access-control model or universal enforcement.
The evidence does not establish:
- the complete role, claim, activity, permission, and organisation matrix;
- how internal, external, administrator, read-only, owner, shared, and competent-authority users are distinguished;
- whether every controller, API action, mediator request, handler, repository, download, deletion, upload, AJAX endpoint, and stored procedure is protected;
- whether resource-level ownership, notification membership, movement membership, tenant isolation, or authority scope is independently checked;
- how missing, malformed, stale, or conflicting identity claims are handled;
- whether unknown activities or missing authorization metadata fail closed in every path;
- how authorization failures are logged, returned, or separated from not-found and other errors.
Some potentially sensitive paths have only partial visible protection, including anonymous or smoke-test actions, a GET action that changes state, user administration, posted applicant identifiers, notification deletion, owner transfer, sharing, transaction deletion, file access, and dynamically dispatched mediator requests. These are verification points, not confirmed exploitable vulnerabilities.
Persistence and transaction gaps
The evidence shows Entity Framework-style contexts, repositories, raw SQL, stored procedures, asynchronous saves, explicit transactions in selected paths, and post-save event dispatch. It does not establish uniform unit-of-work or transaction semantics.
Unknowns include:
- which operations save immediately and which defer persistence;
- whether multiple saves share an ambient or explicit transaction;
- whether file storage, database changes, audit writes, event dispatch, email, and external calls are atomic;
- rollback and compensation behaviour;
- concurrency and row-version handling;
- duplicate prevention and uniqueness enforcement;
- behaviour after partial failure, timeout, cancellation, or retry;
- whether database and ORM constraints match domain and view-model assumptions.
Potential orphan-file and partial-update paths are visible in some document, upload, movement, annex, and notification operations, but the existence of cleanup, transaction sharing, or compensating processing is not shown. A stored procedure or repository returning false may be treated as success by a caller in some paths; the broader result contract is unresolved.
Database and migration gaps
Migrations show substantial schema changes, backfills, lookup replacement, relationship changes, destructive cleanup, column removal, status remapping, and constraint tightening. They do not establish the final deployed schema or successful execution.
The evidence does not establish:
- migration order and runner semantics;
- whether scripts are idempotent or safe to rerun;
- preconditions, backups, transaction scope, rollback, and recovery;
- post-migration validation, reconciliation, and affected-row checks;
- deployed foreign keys, unique constraints, indexes, cascade rules, collations, and permissions;
- treatment of unmatched, duplicate, null, malformed, or legacy data;
- compatibility between historical migrations and current application mappings;
- whether reported SQL syntax, scalar-query,
NOT IN, truncation, conversion, or join risks were encountered in execution.
Examples of unresolved migration concerns include possible loss of shipment fields, non-null columns added before complete backfill, unordered TOP 1 selection, duplicate cleanup with uncertain retention, nullable NOT IN predicates, missing ELSE branches, lossy date and unit conversion, cross-schema references, possible over-broad deletion, and lookup inserts without visible existence checks. These remain conditional risks rather than confirmed data loss or migration failure.
External integrations, files, email, and documents
The system references Companies House, OAuth and user-information services, email infrastructure, virus scanners, document and PDF generators, SQL Server reporting objects, and API clients. Their contracts and operational behaviour are incomplete.
Unresolved areas include:
- authentication, scopes, certificates, URLs, secrets, and token refresh;
- request and response formats, serialization compatibility, and type-name dispatch;
- timeouts, retries, cancellation, rate limits, circuit breaking, and response disposal;
- scanner semantics, quarantine, temporary-file cleanup, file permissions, and failure classification;
- document templates, merge-field rules, annex thresholds, rendering, output validation, storage, naming, collisions, and repeated generation;
- email template selection, recipient filtering, SMTP or pickup delivery, retry, durable delivery, and false-result handling;
- download authorization, file retention, access control, and protection of sensitive documents.
A scanner health-style action is described as anonymous in one implementation, while other material presents it as a characterization scenario. The effective deployed exposure is unresolved.
Client-side, presentation, accessibility, and localization gaps
The evidence contains Razor views, JavaScript, GOV.UK-oriented helpers, SCSS, generated resources, raw HTML, AJAX interactions, and dynamic form controls. Generated or rendered output is generally unavailable.
It is not established:
- which scripts and styles are bundled and loaded;
- the final rendered HTML and browser DOM;
- model-binding results for duplicate names, hidden values, disabled controls, duplicate IDs, and ambient route values;
- network failure handling for AJAX;
- keyboard, focus, label, ARIA, screen-reader, and no-JavaScript behaviour;
- effective CSS compilation, cascade, browser compatibility, and layout;
- localization culture selection, fallback, satellite resources, or translated content completeness;
- whether values passed to
Html.Raw,.html(),InnerHtml, JavaScript strings, or spreadsheet cells are trusted or sanitized.
Raw-output and client-side insertion patterns are potential injection or markup-integrity boundaries. Their exploitability depends on input provenance, encoding, sanitization, and deployed policies not supplied.
Testing and assurance gaps
The supplied tests describe selected expectations for controllers, handlers, validators, mappings, database access, document generation, authorization, and fixtures. No test execution results were supplied. The evidence does not establish that tests compile, pass, run against representative data, or cover the deployed system.
Test limitations include:
- mocked mediator, repository, context, user, and scanner behaviour;
- assertions that verify calls or non-null values without verifying arguments, mappings, persistence, or output;
- in-memory or custom EF helpers that may not reproduce SQL Server, EF tracking, constraints, transactions, or query translation;
- skipped, empty, timing-sensitive,
async void, weakly asserted, misnamed, or miswired tests; - test fixtures with inconsistent identifiers, authorities, units, statuses, and related records;
- commented-out tests for important calculations;
- tests that set properties directly, bypass constructors, or use reflection to bypass normal invariants;
- missing coverage for concurrency, retries, deployment, external services, document transmission, file security, and operational recovery.
Test names, fixtures, resource messages, and comments are evidence of expectations or test data, not independent confirmation of production rules.
Failure and recovery gaps
Failure paths are heterogeneous. Possible outcomes include null or empty results, false, default objects, validation errors, SecurityException, InvalidOperationException, ArgumentException, parsing exceptions, null dereferences, HTTP error responses, redirects, not-found results, generic error pages, suppressed exceptions, and broad catches that return null or continue processing.
The evidence does not establish consistent handling for:
- missing or duplicate records;
- malformed identifiers, dates, JSON, files, and enum values;
- authorization failures;
- database, event, email, scanner, document, and external-service failures;
- partial writes and post-commit event failures;
- retries, duplicate submissions, stale pages, multiple tabs, and replay;
- logging, alerting, user notification, support tracing, rollback, and recovery.
Some handlers suppress broad exceptions or return success without visibly inspecting downstream results. These are source-level observations; the actual operational and user-visible consequences remain unknown.
Overall, the supplied evidence supports a bounded description of a substantial notification and movement-management application family, but it does not establish a complete current-system contract. The unresolved areas above should remain explicitly qualified rather than being converted into assumptions of absence, correctness, security, approval, successful execution, or production impact.
Content quality review
Advisory; not approval. Review status: advisory.
Advisory review
The draft is highly relevant to gaps.md and is broadly consistent with the supplied evidence. It correctly treats the material as a partial, source-level review rather than a verified production specification. It also generally preserves uncertainty, avoids claiming that unobserved controls are absent, and distinguishes conditional security or data-integrity risks from confirmed runtime vulnerabilities. The coverage of runtime/deployment, workflows, validation, authorization, persistence, migrations, integrations, presentation, testing, and recovery is materially supported by the supplied notes.
However, the draft is substantially longer than necessary for an evidence-gaps document and sometimes mixes four different things without enough separation: evidence that is absent, source-level defects or inconsistencies, unresolved contradictions, and general verification recommendations. This makes the document difficult to use as a gap register and can obscure which statements are directly supported by an artifact and which are merely reported by a secondary analysis.
Relevance and purpose
The opening qualification is appropriate and should be retained. The draft is especially strong where it states that source constructs do not establish deployment, reachability, registration, persistence, authorization, or production use. That distinction is repeated consistently throughout the document.
The main relevance problem is scope. Sections such as “External integrations, files, email, and documents,” “Client-side, presentation, accessibility, and localization gaps,” and “Testing and assurance gaps” contain useful material, but the document also reproduces a broad system description and many detailed implementation observations. Some of those observations belong in a risk register, defect log, or subsystem review rather than in a concise evidence-gap document. For example, the discussion of annex numbering, document-block ordering, report page size, and specific failure types is relevant only when it explains a missing piece of evidence or an unresolved contradiction.
A more focused structure would distinguish:
- Evidence coverage and provenance gaps — what artifacts, versions, callers, or execution records are missing.
- Unresolved contradictions — where supplied evidence gives incompatible answers.
- Source-level observations requiring verification — possible defects or security boundaries.
- Evidence needed to resolve each gap — specific artefacts, tests, or runtime checks.
Unsupported or over-strong wording
Most wording is appropriately qualified, but a few phrases should be tightened.
The statement that “other files and implementations are genuinely unavailable” is stronger than the evidence supports. The evidence establishes that they are unavailable in the supplied material, not that they do not exist in the repository or current system. Replace it with wording such as:
> Other files and implementations are not present in the reviewed corpus or are described only indirectly; their existence outside that corpus is unresolved.
Similarly, references to files being “genuinely unavailable” should generally be changed to “not supplied,” “not recoverable as text in the supplied material,” or “not available for this review.” This is particularly important for binary or NUL-containing migrations.
The draft says that “some files described as omitted from fleet or contract summaries are present in other supplied ranges, while other files and implementations are genuinely unavailable or only described indirectly.” The first half is supported; the second should be limited to the evidence boundary. A summary omission does not establish repository absence.
The phrase “the system references Companies House, OAuth and user-information services…” is supported at source or configuration level, but should remain explicitly qualified as a reference in the supplied source, not evidence of an active integration. The later text usually does this correctly, but the opening sentence could be read more strongly than intended.
The conclusion that the evidence supports a “substantial notification and movement-management application family” is reasonable, but “application family” should remain qualified because several notes expressly warn that the MVC application, Web API service, core libraries, document generation components, and database utilities may not share one deployed boundary.
Evidence versus defect
The draft is careful in many places, for example:
> These are verification points, not confirmed exploitable vulnerabilities.
and:
> These remain conditional risks rather than confirmed data loss or migration failure.
Those formulations are good. They should be applied more systematically.
Some paragraphs currently combine an observed source fact with a possible consequence in a way that could be read as a confirmed defect. For example:
> Potential orphan-file and partial-update paths are visible in some document, upload, movement, annex, and notification operations…
This is acceptable, but should identify the condition more precisely: a file is stored before a later database save, the transaction boundary is not shown, and cleanup is not evidenced. That is stronger and clearer than grouping many operations together.
Likewise, the statement:
> A stored procedure or repository returning false may be treated as success by a caller in some paths
should identify the observed pattern and avoid implying that the same result contract applies across all repositories. A better formulation would be:
> In selected paths, a caller returns success without visibly inspecting a downstream Boolean or service result. Whether the ignored result can indicate failure, and whether this path is reachable, is unresolved.
The statement that “some handlers suppress broad exceptions or return success without visibly inspecting downstream results” is supported by the notes, but it should distinguish broad exception suppression from ignored Boolean results. They have different evidence and different possible consequences.
Contradictions and evidence gaps
The draft records several important contradictions, including:
- the 30-day versus 60-day prenotification rule;
NotificationReceivedtransitioning to concreteAwaitingPaymentversus summaries describing a transition toSubmitted;- inconsistent receipt clearing during rejection or partial rejection;
- differing external and internal receipt/completion rules;
- inconsistent authorization visibility;
- conflicting migration descriptions and final-schema assumptions;
- differing scanner-health exposure descriptions;
- inconsistent test strength and fixture quality.
These are valuable inclusions. The weakness is that the draft does not consistently identify the two sides of each contradiction or state what evidence would resolve it. For example, the 30/60-day issue should explicitly say that executable validation is reported to allow 60 days while resource text or summaries state 30 days, and that the resolution requires the authoritative current validator, resource, release version, and boundary tests. The receipt-clearing contradiction should identify the relevant receive, reject, partial-reject, and database-procedure paths separately rather than describing the conflict generally.
The draft should also avoid treating repetition across secondary analyses as corroboration. Multiple notes repeating the same claim do not make it independently verified. Where a statement comes only from a secondary analysis, it should say so.
Missing behaviours that should be made more explicit
The draft lists many missing behaviours, but several important gaps would benefit from clearer treatment:
- Version identity and artifact correspondence: which source ranges, projects, binaries, migrations, tests, and configurations belong to the same release or deployment.
- Composition root and registration: actual Autofac registrations, mediator decorators, route registration, filter registration, mapper scanning, and active implementation selection.
- Authoritative state ownership: whether UI models, handlers, domain objects, stored procedures, or database constraints are authoritative for status, quantities, dates, and permissions.
- Cross-entity integrity: whether posted notification, movement, shipment, user, facility, carrier, waste-code, and file identifiers are checked for membership and ownership.
- Result semantics: the meaning of
bool,Guid, nullable results,Unit, empty objects, andnullacross request and repository contracts. - Replay and concurrency: stale pages, multiple tabs, duplicate submissions, concurrent movement-number allocation, duplicate completion, repeated uploads, and repeated document generation.
- Operational evidence: actual logs, health checks, alerts, migration receipts, deployment records, backup tests, restoration tests, and runbooks.
- Data protection and privacy: treatment of personal data, banking details, uploaded documents, logs, temporary state, and diagnostic output.
These topics are partly present, but they are distributed across the draft rather than presented as explicit gaps with requested evidence.
Specific corrections and improvements
The draft should be shortened and made more operational. For each major gap, add a short prose correction in the following form:
> The supplied source shows X, but does not establish Y. This is an evidence gap, not evidence that Y is absent. Resolve it by obtaining or examining Z.
Examples:
> Request authorization attributes are present on selected contracts, but the supplied material does not establish that every request reaches the authorization decorator or that repository and download paths enforce resource ownership. Obtain the composition-root registrations, mediator pipeline, route inventory, and authorization tests for owner, shared-user, internal, administrator, and cross-authority cases.
> Several migrations alter or delete data, but the supplied material does not establish execution order, deployed schema state, transaction scope, or successful backfill. Obtain the migration-runner output, target database schema, affected-row reports, backup and rollback records, and post-migration reconciliation results.
> Source paths store files before later database or audit operations, but the supplied material does not establish whether file storage participates in a transaction or whether cleanup compensates for database failure. Trace the file-store implementation, transaction connection, failure handlers, cleanup jobs, and retry behaviour.
This would satisfy the requested purpose better than simply adding further lists of unknowns.
Traceability and provenance
The draft’s largest assurance weakness is lack of claim-level traceability. It names symbols and artifact types, but it does not identify which supplied note or source observation supports each material claim. Because the evidence contains conflicting analyses, different source ranges, and secondary summaries, readers need to know whether a claim is:
- directly visible in supplied source;
- asserted by a test;
- inferred from a mapping or resource;
- reported by a secondary analysis;
- contradicted by another supplied account; or
- not evidenced at all.
A compact provenance label or parenthetical reference for material claims would substantially improve the draft. This is particularly necessary for the 30/60-day rule, anonymous endpoints, plaintext secrets, migration syntax, receipt-clearing behaviour, status transitions, SQL interpolation, and test execution limitations.
Redundancy and internal presentation
The document repeats the same qualification in almost every section: source-level observations do not prove production reachability, authorization, persistence, or impact. That qualification is correct, but it can be stated once at the beginning and then applied locally only where a paragraph might otherwise be misread.
The “Overall” paragraph is also largely a repetition of the opening. It would be more useful if it summarized the highest-value unresolved questions and the evidence needed to resolve them, without implying completion or approval.
The headings are generally clear, but “Evidence Gaps” contains “Known risks,” which blurs purpose. Consider moving conditional risks to a separate subsection such as Source observations requiring verification. This would make it clear that a gap is not itself a defect.
Unresolved questions requiring prioritisation
The draft would benefit from prioritising unresolved questions rather than presenting them as an undifferentiated catalogue. The most consequential questions appear to be:
- Which application, release, and deployment boundary do the supplied artifacts describe?
- What is the authoritative notification and movement lifecycle, including the 30/60-day rule and hierarchical assessment statuses?
- Are identifiers, ownership, competent-authority scope, and notification membership revalidated on every mutation, deletion, download, upload, and report path?
- Are database changes, file operations, audits, events, and emails atomic or compensating?
- What schema and migration sequence are actually deployed, and did destructive or non-null migrations complete successfully?
- Which authentication, authorization, anonymous, scanner-health, diagnostic, and maintenance endpoints are reachable in the deployed environment?
- Are the reported raw-output, SQL-construction, temporary-data, and client-controlled-field boundaries reachable with untrusted data?
- What tests actually compile and pass against representative SQL Server, file, document, scanner, and authorization configurations?
These questions should be connected to specific missing evidence and not presented as assumptions about defects.
Overall assessment
The draft is substantively cautious and captures most of the major evidence limitations in the supplied material. Its principal weaknesses are excessive breadth, insufficient claim-level provenance, occasional wording that implies repository absence rather than absence from the reviewed corpus, and insufficient separation between missing evidence, contradictions, and possible defects. It should not be treated as a verified completeness statement. The most useful revision would preserve the qualifications while reducing repetition, adding explicit evidence-status labels, and pairing each material gap with a concrete unresolved question and the artifact or test needed to resolve it.
Contains public sector information licensed under the Open Government Licence v3.0. Original public repository. This independent Harten analysis was not commissioned, approved or endorsed by DEFRA or the Environment Agency.
Analysed source-archive hash is recorded; its exact upstream Git commit has not been established. The generated material does not establish complete requirements, operational security or functional equivalence.