Skip to content

fix(domain): list a draft's sources in one pass over its statements - #495

Merged
ixuz merged 1 commit into
mainfrom
fix/draft-listing-index
Nov 2, 2026
Merged

ixuz merged 1 commit into
mainfrom
fix/draft-listing-index

Conversation

@ixuz

@ixuz ixuz commented Nov 1, 2026

Copy link
Copy Markdown
Member

What and why

The Studio's listing of a draft (draftLibraryDeck) found the title, license and creators of each of the draft's sources by going over every statement of the draft, several times per source. That work grew with the square of the number of sources. On a draft drawn from many sources, the release diff and the trial stopped responding each time they were opened, because each makes the listing more than once.

This pull request:

  • Groups by subject in one pass. draftLibraryDeck now gathers the sources' statements by subject in one pass, as sourcesOf already does. A source named twice is listed once.
  • Makes the listing fewer times. The release diff screen (releaseDrafts.ts) makes the listing once and hands it to releaseDiff and simulateLearnerUpgrade, and simulateLearnerUpgrade hands it on to draftLibraryContent. Each takes it as an optional last parameter that defaults to making it, so existing callers don't change. This saves repeated work but doesn't change how the time grows.
  • Adds growth tests. New growth tests check that the listing, the release diff and the learner upgrade take linear time in the number of sources. docs/testing.md lists them in the domain row.

For reviewers: this branch, fix/graph-address-bound and fix/type-index-one-edit each add to the same domain row of the growth tests in docs/testing.md, so they conflict there. Merge them one at a time, and rebase each later branch on main before merging it.

Refs: GHSA-6pp3-vp4m-5m87

Checklist

  • One issue. This pull request addresses one issue, linked above.
  • One step. This pull request does not finish its issue, so it says Refs:, not Closes:. Leave this unchecked otherwise.
  • Done, as AGENTS.md defines it: npm run check passes (lint, Markdown and spelling included), npm run lint:reuse too if a file was added, and npm run crosscheck too if ns/ or decks/ changed. (lint:reuse and crosscheck n/a: no file added, ns/ and decks/ unchanged)
  • Tests. New and changed code has its tests, and every package stays at 100% coverage (docs/testing.md).
  • Docs. The docs say what changed, and a new page in docs/ is listed in docs/docs.ttl.
  • Languages. A new or changed message is in every locale: en, sv, ko, de, es and fr (packages/ui/src/i18n/). (n/a: no message changed)
  • Vocabulary and shapes. Any change to ns/ was agreed in an issue first; no published ns/shapes/*/vN.ttl or decks/*/vN.ttl was edited; generated files were regenerated, not edited. (n/a: ns/, decks/ and generated files unchanged)
  • Breaking? Nothing in the public API breaks, or a commit says so (! and a BREAKING CHANGE: footer). npm run check:breaking sees a line of api/ that goes, but not a feature removed, nor a reader that reads less than before.
  • Pod data. Any change to what the app writes to a pod comes with its migration (docs/migrations.md). (n/a: nothing written to a pod changes)
  • Policy. Any change to an external rule the code follows (SM-2, the plural rules, a specification) is cited. (n/a: no external rule changes)
  • Licenses. New content is MIT, or a deck states its own license; a new file has its SPDX header (npm run lint:reuse), or a new deck its line in REUSE.toml; third-party content is credited. (n/a: no file or deck added)
  • Architecture. Imports follow docs/boundaries.md and the layers of docs/architecture.md.
  • Run. I ran the app (npm run dev) and tried the change, and considered the user journeys.
  • Authorship. I read and understand every line of this pull request, and answer for it, whatever tools helped write it (CONTRIBUTING.md).
  • Commits. Each commit is one logical change, in Conventional Commits form (type(scope): subject, ! and a BREAKING CHANGE: footer if it breaks something), with an imperative subject and a body that explains why (CONTRIBUTING.md).

@ixuz ixuz added the bug Something isn't working label Nov 1, 2026
@ixuz
ixuz force-pushed the fix/draft-listing-index branch from fd52a35 to 0d1872b Compare November 2, 2026 10:24
draftLibraryDeck, which makes the Studio's listing of a draft, read
the title, license and creators of each source the draft is drawn
from by going over every statement of the draft, three times per
source. Each source's own statements are among them, so a draft drawn
from many sources took time that grows with their square, and the
release diff and the trial, which make the listing several times,
stopped responding on such a draft each time they were opened.

The statements of the sources are now gathered by subject in one
pass, as sourcesOf already does, and a source named twice is listed
once. Growth tests hold the listing, the release diff and the learner
upgrade to linear time in the number of sources.

The draft's listing is also made fewer times: the release diff screen
makes it once and hands it to releaseDiff and simulateLearnerUpgrade,
and simulateLearnerUpgrade hands it on to draftLibraryContent. This
saves repeated work rather than changing how the time grows.

Refs: GHSA-6pp3-vp4m-5m87
@ixuz
ixuz force-pushed the fix/draft-listing-index branch from 0d1872b to 592136c Compare November 2, 2026 11:03
@ixuz
ixuz enabled auto-merge November 2, 2026 11:03
@ixuz
ixuz added this pull request to the merge queue Nov 2, 2026
Merged via the queue into main with commit e1011a9 Nov 2, 2026
51 checks passed
@ixuz
ixuz deleted the fix/draft-listing-index branch November 2, 2026 11:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant