Skip to content

feat: publish custom findings and persist dedupe groups - #667

Merged
kmbroai merged 14 commits into
dev/kyleb/findings-deduplicationfrom
dev/kyleb/findings-writeback
Aug 27, 2026
Merged

feat: publish custom findings and persist dedupe groups#667
kmbroai merged 14 commits into
dev/kyleb/findings-deduplicationfrom
dev/kyleb/findings-writeback

Conversation

@kmbroai

@kmbroai kmbroai commented Aug 27, 2026

Copy link
Copy Markdown
Collaborator

Summary

Stacked on #661. Complete the local scan-to-findings-service flow: publish completed findings from the CLI, review candidates locally, and persist the accepted duplicate relationships in SQLite.

Changes

  • Merge the updated feat(typescript): deduplicate scans through SDK and CLI #661 base, carrying group storage and migration 35 into plugins/codex-security/scripts/ and inheriting the canonical generated-bundle workflow. Preserve the parent's two-stage, transitive deduplication behavior and update the write-back fixture to remove its obsolete whole-group reviewer.
  • Inherit the earlier removal of the unused provisional API. Drop obsolete transition wording and a redundant smoke assertion; production code, unit tests, and the supported local workflow are unchanged.
  • Translate the mounted SQLite smoke fixture directly to TypeScript using Node built-ins, with the existing SQL and assertions retained at this stack layer. Include it explicitly in TypeScript checking; no runtime dependency or public contract changes.
  • Add publish scan --to custom --findings-url http://localhost:3000 and the SDK's publishScanToCustom. The URL is an explicit service base URL with no default; publication posts complete sealed findings and their repository ID to /v1/bulk/findings. Existing scan selection and --dry-run work without changing Linear or Cloud publication.
  • Add an append-only migration for finding_dedupe_groups and finding_dedupe_group_members. Findings can belong to multiple overlapping reviewed groups. Membership identifies a group idempotently; overlapping groups are not automatically united.
  • Add POST /v1/dedupe-groups for atomic group batches and GET /v1/finding/{id}/dedupe-groups for readback. Missing members reject the entire batch.
  • Have dedupe persist accepted groups after all reviews and fail if write-back fails. Preserve its existing result shape, required review fields, original findings, embeddings, and sealed scan artifacts.
  • Document the contracts and extend CLI, SDK, SQLite, installed-package, and Docker coverage. Update the npm runtime-module allowlist; test and Docker fixtures remain excluded.

Testing

Canonical plugin source update (3de1f167)

  • build:plugin and check:plugin-source passed on this branch: 119 generated plugin files, including workbench_findings.py, and no tracked files under sdk/typescript/_bundled_plugin.
  • Focused service, embedding, plugin-build, deduplication, transport, CLI, and custom-publication tests: 48 passed.
  • Both full SDK suites passed: seeds 12345 and 4011281236, each with 1,978 passed, 29 skipped, and zero failures.
  • pnpm run types (including the canonical MCP app), pnpm run format, and git diff --check passed.
  • Compared the relocated findings helper and indexing functions structurally with the previous branch head; their function bodies and migrations 33–35 are unchanged.
  • Updated the existing canonical Python schema expectations for migration 35, embeddings, repository associations, and group tables. All 61 setup/migration tests and both affected scan/coordinator tests passed on this branch.
  • The full canonical Python run reported 1,024 passed, 9 skipped, 103 passing subtests, and eight failures from the old schema snapshots. All eight affected cases pass after the test-only corrections above; the entire Python suite was not rerun after those corrections.
  • The canonical MCP suite (pnpm run test:mcp) passed.
  • Packaged Docker smoke passed using synthetic provider responses: custom publication, scoped candidate retrieval, both review stages, dedupe-group write-back and idempotency, container recreation, SQLite readback, clean shutdown, and test resource cleanup. The 359-entry archive and installed-package checks passed. The production image includes the generated findings helper and excludes smoke fixtures.
  • The host example and manifest now load from canonical source paths, fixing the clean-checkout failure exposed by container CI. The complete Docker smoke passed again with the generated host bundle temporarily absent and restored afterward. Types and formatting passed after that fixture-only correction; production code is unchanged from the full SDK runs above.

Provisional endpoint cleanup (a5b2b430)

  • pnpm run types, pnpm run format, and git diff --check: passed.
  • Compared the updated branch with its previous head: production code and unit tests are unchanged. The only file edits here remove obsolete API-transition documentation and a redundant smoke assertion; the existing unit test still verifies that the unsupported route returns HTTP 404.
  • Verified that the parent branch is included and the provisional route/service are absent. No new public CLI syntax, dependency, storage migration, or release gate was added.

TypeScript fixture update (6bf5861f)

  • Local types, formatting, diff checks, and the packaged Docker smoke passed after integrating the updated parent. The translated fixture retains group membership assertions and scan preparation without workflow/checkpoint assertions.
  • Docker packaging validated 354 archive entries and the installed imports, NodeNext types, CLI, bundled plugin/Codex, and nested-worker checks. Smoke fixtures remain excluded.
  • The first local Docker attempt lost its test network during container recreation; an unchanged retry passed, as did the final parent-integrated run.

Earlier verification

  • Focused publication, service, and dedupe tests: 114 passed.
  • Full SDK suites: pnpm run test --seed 12345 and pnpm run test (random seed 2809160346) each passed 1,941 tests, with 28 skipped and no failures.
  • pnpm run types, pnpm run format, and git diff --check: passed.
  • Packed archive and installed consumer check: 354 entries; SDK exports, NodeNext types, CLI, bundled plugin, and bundled Codex checks passed.
  • Docker smoke: host packaged CLI publication, scoped retrieval, native Codex review tool submissions, duplicate write-back, retry idempotency, container replacement, SQLite readback, and clean shutdown passed. Embedding and review providers use synthetic local responses; this does not assess model decision quality.

Risk and rollout

Deploy the updated findings service before using the updated dedupe; older servers do not implement group write-back. The migration adds tables without rewriting findings or scan history. Groups are additive, and retries of the same memberships reuse the existing group. This does not update external issue trackers or replace stored findings with review-generated merged reports.

The preview service's existing network and authentication setup is unchanged: keep it on a trusted local endpoint or behind an authenticated proxy. Custom publication sends findings only to the explicitly selected service and does not forward model credentials. This PR adds no dependencies or package-version changes beyond its updated base.

Public disclosure review

  • No customer, partner, prospect, or user identities, data, or identifying details are included.
  • No credentials, personal data, private source, scan findings, or nonpublic links or tickets are included.
  • I reviewed the branch name, title, description, commits, changes, comments, logs, screenshots, attachments, and links for public disclosure.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Aug 27, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
🔒 Security Review Completed 2026-08-27T02:47:34.726532Z 0a6feab PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@zcrab-oai zcrab-oai left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

One validated P1 persistence issue: successful HTTP status currently masks missing dedupe-group acknowledgments.


async storeDedupeGroups(groups: readonly string[][]): Promise<void> {
if (groups.length === 0) return;
await this.post("v1/dedupe-groups", { groups });

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[P1] Validate duplicate-group write acknowledgments before reporting success

Unlike publish(), this method discards the response body entirely. The added deduplication test explicitly posts a nonempty group, receives Response.json([],{status:201}), and still treats the group as persisted. If the service acknowledges only some groups, later workflow stages mark dedupe completed and retries skip the missing writes permanently. Validate that the receipt contains the expected persisted group memberships and throw on missing or malformed acknowledgments so the write can be retried.

* feat: persist resumable local findings workflows

* fix: store workflow metadata in explicit SQLite columns

* test(plugin): align workflow helper and schema contracts

* feat: checkpoint dedupe reviews and replay group writes (#674)

* feat: checkpoint dedupe reviews and replay group writes

* fix: keep workflow source snapshots within the checkout

* fix: migrate dedupe checkpoint bindings to SQLite columns

* test: retain required canonical ID in translated checkpoint checks

* test: align checkpoint contracts with the updated findings stack

* feat(server): add read-only findings dashboard (#679)

* feat(server): add read-only findings dashboard

* fix(dashboard): show workflows first

* refactor(dashboard): simplify rendering and reuse workflow storage

* fix(dashboard): preserve filters and completed result semantics

* fix(dashboard): retain published repository identities in search

* fix(dashboard): include deep scan activity in freshness

* refactor(dashboard): use native selects and remove dropdown machinery

* refactor(dashboard): show only stored findings and groups

---------

Co-authored-by: kmbroai <272643392+kmbroai@users.noreply.github.com>

---------

Co-authored-by: kmbroai <272643392+kmbroai@users.noreply.github.com>
@kmbroai
kmbroai merged commit 5128225 into dev/kyleb/findings-deduplication Aug 27, 2026
26 of 27 checks passed
@kmbroai
kmbroai deleted the dev/kyleb/findings-writeback branch August 27, 2026 21:42
kmbroai added a commit that referenced this pull request Aug 27, 2026
* feat(typescript): deduplicate stored findings with Codex

* refactor(typescript): group server deduplication modules

* refactor(typescript): run scan deduplication in SDK and CLI

* feat(typescript): scope finding retrieval by repository

* refactor(typescript): trim redundant deduplication code

* fix(typescript): restore complete deduplication reviews

* refactor(typescript): trim deduplication setup and smoke bookkeeping

* perf(typescript): reduce deduplication review work

* test(plugin): include repository associations in schema expectations

* test(plugin): update repository migration snapshots

* test: read scan smoke manifest from canonical plugin source

* feat: publish custom findings and persist dedupe groups (#667)

* feat: publish custom findings and persist dedupe groups

* refactor(test): translate write-back smoke assertions to TypeScript

* test: align findings writeback with pair-only deduplication

* test(plugin): include dedupe groups in schema expectations

* test(plugin): update dedupe group migration snapshots

* feat: persist resumable local findings workflows (#673)

* feat: persist resumable local findings workflows

* fix: store workflow metadata in explicit SQLite columns

* test(plugin): align workflow helper and schema contracts

* feat: checkpoint dedupe reviews and replay group writes (#674)

* feat: checkpoint dedupe reviews and replay group writes

* fix: keep workflow source snapshots within the checkout

* fix: migrate dedupe checkpoint bindings to SQLite columns

* test: retain required canonical ID in translated checkpoint checks

* test: align checkpoint contracts with the updated findings stack

* feat(server): add read-only findings dashboard (#679)

* feat(server): add read-only findings dashboard

* fix(dashboard): show workflows first

* refactor(dashboard): simplify rendering and reuse workflow storage

* fix(dashboard): preserve filters and completed result semantics

* fix(dashboard): retain published repository identities in search

* fix(dashboard): include deep scan activity in freshness

* refactor(dashboard): use native selects and remove dropdown machinery

* refactor(dashboard): show only stored findings and groups

---------

Co-authored-by: kmbroai <272643392+kmbroai@users.noreply.github.com>

---------

Co-authored-by: kmbroai <272643392+kmbroai@users.noreply.github.com>

---------

Co-authored-by: kmbroai <272643392+kmbroai@users.noreply.github.com>

---------

Co-authored-by: Kyle Brown <272643392+kmbroai@users.noreply.github.com>
kmbroai added a commit that referenced this pull request Aug 27, 2026
* feat(typescript): add findings service plumbing

* feat(typescript): persist findings and embeddings through the service API

* test(typescript): extract findings service Docker smoke runner

* refactor(test): translate findings storage fixture to TypeScript

* refactor(server): omit provisional bulk dedupe endpoint

* docs: use canonical plugin source in findings import example

* fix(plugin): support isolated findings helper execution

* test(plugin): include findings storage in schema expectations

* test(plugin): update findings migration snapshots

* test: read findings smoke fixture from canonical plugin source

* feat(typescript): deduplicate scans through SDK and CLI (#661)

* feat(typescript): deduplicate stored findings with Codex

* refactor(typescript): group server deduplication modules

* refactor(typescript): run scan deduplication in SDK and CLI

* feat(typescript): scope finding retrieval by repository

* refactor(typescript): trim redundant deduplication code

* fix(typescript): restore complete deduplication reviews

* refactor(typescript): trim deduplication setup and smoke bookkeeping

* perf(typescript): reduce deduplication review work

* test(plugin): include repository associations in schema expectations

* test(plugin): update repository migration snapshots

* test: read scan smoke manifest from canonical plugin source

* feat: publish custom findings and persist dedupe groups (#667)

* feat: publish custom findings and persist dedupe groups

* refactor(test): translate write-back smoke assertions to TypeScript

* test: align findings writeback with pair-only deduplication

* test(plugin): include dedupe groups in schema expectations

* test(plugin): update dedupe group migration snapshots

* feat: persist resumable local findings workflows (#673)

* feat: persist resumable local findings workflows

* fix: store workflow metadata in explicit SQLite columns

* test(plugin): align workflow helper and schema contracts

* feat: checkpoint dedupe reviews and replay group writes (#674)

* feat: checkpoint dedupe reviews and replay group writes

* fix: keep workflow source snapshots within the checkout

* fix: migrate dedupe checkpoint bindings to SQLite columns

* test: retain required canonical ID in translated checkpoint checks

* test: align checkpoint contracts with the updated findings stack

* feat(server): add read-only findings dashboard (#679)

* feat(server): add read-only findings dashboard

* fix(dashboard): show workflows first

* refactor(dashboard): simplify rendering and reuse workflow storage

* fix(dashboard): preserve filters and completed result semantics

* fix(dashboard): retain published repository identities in search

* fix(dashboard): include deep scan activity in freshness

* refactor(dashboard): use native selects and remove dropdown machinery

* refactor(dashboard): show only stored findings and groups

---------

Co-authored-by: kmbroai <272643392+kmbroai@users.noreply.github.com>

---------

Co-authored-by: kmbroai <272643392+kmbroai@users.noreply.github.com>

---------

Co-authored-by: kmbroai <272643392+kmbroai@users.noreply.github.com>

---------

Co-authored-by: Kyle Brown <272643392+kmbroai@users.noreply.github.com>

* feat(container): publish findings service and distribute workflow runner (#666)

* feat(typescript): deduplicate stored findings with Codex

* refactor(typescript): group server deduplication modules

* refactor(typescript): run scan deduplication in SDK and CLI

* feat(typescript): scope finding retrieval by repository

* refactor(typescript): trim redundant deduplication code

* fix(typescript): restore complete deduplication reviews

* feat(container): publish findings service image to GHCR

* feat: publish custom findings and persist dedupe groups

* refactor(container): trim findings release verification

* refactor(typescript): trim deduplication setup and smoke bookkeeping

* feat(container): add scanner workflow runner Compose

* refactor(test): translate write-back smoke assertions to TypeScript

* refactor(test): translate runner smoke fixtures to TypeScript

* perf(typescript): reduce deduplication review work

* test: align findings writeback with pair-only deduplication

* test(plugin): include repository associations in schema expectations

* test(plugin): include dedupe groups in schema expectations

* test(plugin): update repository migration snapshots

* test(plugin): update dedupe group migration snapshots

* test: read scan smoke manifest from canonical plugin source

---------

Co-authored-by: Kyle Brown <272643392+kmbroai@users.noreply.github.com>

---------

Co-authored-by: kmbroai <272643392+kmbroai@users.noreply.github.com>
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.

3 participants