Skip to content

Generated finding anchors can violate their own schema and break later draft updates #1541

Description

@StErMi

Summary

When a finding omits identity, buildFindings generates identity.anchor from extensions.candidateId (if present) or the finding title. The generator permits a leading underscore, dot or slash, while the identity schema requires a leading lowercase letter or digit.

For example, a valid title of _Unsafe archive_ generates _unsafe-archive_, which fails the schema. A subsequent draft update can fail when the saved canonical findings are read and validated.

Version / source checked

  • npm v0.2.0: 4949af70fcfadff154f6e8fdf100faa5bf2f8169
  • Current main, checked on 2026-10-09: d4a4eaf315371c85088e1c9b0b05e5d206ef518a

The generator/schema mismatch is still present in that main commit.

Reproduction

  1. Save an otherwise-valid fresh Standard scan draft containing one finding with title _Unsafe archive_. Omit its identity and extensions.candidateId.
  2. The generated finding identity has anchor: "_unsafe-archive_".
  3. Submit another draft for the same scan. Reading the saved finding reapplies the identity schema and rejects this generated anchor.

The underlying mismatch can be demonstrated without running a model:

const anchor = "_Unsafe archive_"
  .normalize("NFKD")
  .replace(/[\u0300-\u036f]/gu, "")
  .toLowerCase()
  .replace(/[^a-z0-9._/-]+/gu, "-")
  .replace(/^-+|-+$/gu, "");

console.log(anchor); // "_unsafe-archive_"
console.log(/^[a-z0-9][a-z0-9._/-]*$/u.test(anchor)); // false

Expected behavior

Every host-generated anchor should satisfy the same schema used to validate saved findings, so an accepted draft remains readable during later updates.

Relevant code

Verification scope

The repeated-draft failure was reproduced against the pinned v0.2.0 implementation. On current main, the relevant generation, schema and saved-read paths were inspected, and the normalization/regex mismatch was verified in memory; a full agent scan was not run.

A possible fix is to ensure generated identifiers begin with an allowed character (using a valid fallback when needed), with a regression covering save followed by another draft update. Existing saved findings may require a separate recovery decision.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions