Skip to content

fix(solid): read a document's agent names once for all its decks - #461

Merged
ixuz merged 1 commit into
mainfrom
fix/deck-agent-names-once
Nov 1, 2026
Merged

ixuz merged 1 commit into
mainfrom
fix/deck-agent-names-once

Conversation

@ixuz

@ixuz ixuz commented Nov 1, 2026

Copy link
Copy Markdown
Member

What and why

Mapping a deck copied the whole map of its document's agent names. The only reason was so that a deck from before format 3 could add the creators it names itself. A catalog or a deck file with many decks and many agents therefore took time that grows with the number of decks times the number of agents. That cost was paid on every deck-list read of the catalog and on each import of the file.

  • No copy per deck. A deck now looks up its creators first in a small map of the names it states itself, and then in the document's map, which it no longer copies (toDeck in deckMapper.ts). A deck's creators read the same as before.
  • A file of several decks is refused first. Reading a deck file now refuses a file with more than one deck before it maps any of them. Before, it refused such a file only after mapping them all (readDeckFile in solidDeckArchive.ts). The error is the same notADeckFile as before.
  • Growth tests. New growth tests time both reads over many decks and agents and require linear time: a catalog's decks (toDecks) and a deck file's refusal (readDeckFile). Another test checks that a file of several decks maps none of them. docs/testing.md lists the new growth tests.

Refs: GHSA-hcrw-cr33-jg78

Checklist

  • One issue. This pull request addresses one issue, linked above. (the advisory referenced 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 was added, and ns/ and decks/ are 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 the generated files are 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; only how decks are read)
  • Policy. Any change to an external rule the code follows (SM-2, the plural rules, a specification) is cited. (n/a: no external rule changed)
  • 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, deck or third-party content 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 enabled auto-merge November 1, 2026 02:53
@ixuz
ixuz added this pull request to the merge queue Nov 1, 2026
@ixuz
ixuz removed this pull request from the merge queue due to a manual request Nov 1, 2026
@ixuz
ixuz added this pull request to the merge queue Nov 1, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to a conflict with the base branch Nov 1, 2026
@ixuz
ixuz enabled auto-merge November 1, 2026 06:04
@ixuz
ixuz force-pushed the fix/deck-agent-names-once branch from af4b324 to d73827e Compare November 1, 2026 06:09
@ixuz
ixuz added this pull request to the merge queue Nov 1, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to a conflict with the base branch Nov 1, 2026
Mapping a deck copied the whole map of the document's agent names, only
so that a deck from before format 3 could add the creators it names
itself. A catalog or a deck file with many decks and many agents then
took time that grows with their product, on every deck-list read of
the catalog and on each import of the file.

A deck now looks its creators up in a small map of its own names first
and in the document's map after, which it no longer copies. Reading a
deck file also refuses a file with more than one deck before it reads
any of them, as it refused such a file only after mapping them all.
Growth tests pin both reads to linear time.

Refs: GHSA-hcrw-cr33-jg78
@ixuz
ixuz force-pushed the fix/deck-agent-names-once branch from d73827e to 4ecfb5f Compare November 1, 2026 06:49
@ixuz
ixuz enabled auto-merge November 1, 2026 06:50
@ixuz
ixuz added this pull request to the merge queue Nov 1, 2026
Merged via the queue into main with commit b49e843 Nov 1, 2026
50 checks passed
@ixuz
ixuz deleted the fix/deck-agent-names-once branch November 1, 2026 07:29
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