Conversation
|
| GitGuardian id | GitGuardian status | Secret | Commit | Filename | |
|---|---|---|---|---|---|
| 26549932 | Triggered | Generic High Entropy Secret | dd771c2 | lib/src/db/test.rs | View secret |
🛠 Guidelines to remediate hardcoded secrets
- Understand the implications of revoking this secret by investigating where it is used in your code.
- Replace and store your secret safely. Learn here the best practices.
- Revoke and rotate this secret.
- If possible, rewrite git history. Rewriting git history is not a trivial act. You might completely break other contributing developers' workflow and you risk accidentally deleting legitimate data.
To avoid such incidents in the future consider
- following these best practices for managing and storing secrets including API keys and other credentials
- install secret detection on pre-commit to catch secret before it leaves your machine and ease remediation.
🦉 GitGuardian detects secrets in your source code to help developers and security teams secure the modern development process. You are seeing this because you or someone else with access to this repository has authorized GitGuardian to scan your pull request.
This was referenced Apr 6, 2026
\`Collection.applyResourceChange\` was scanning every loaded page on every \`StoreEvents.ResourceUpdated\` to decide whether the changed subject was a current member — O(pages × members) per event, multiplied by every collection mounted in the UI (sidebar + main + breadcrumbs ≈ 5–10). On a commit burst this was the dominant cost in \`useCollection\`'s listener path. Maintain a \`_memberIndex: Map<subject, pageIdx>\` alongside \`pages\`. A new \`setPage\` helper is the single mutation point that keeps the index in sync with \`pages\`; the surgical add / remove branches in \`applyResourceChange\` update it on member churn. Lookup in the listener becomes a single Map.get + a fast bail when the subject is neither a match nor an existing member — the overwhelmingly common case. The within-page \`indexOf\` for the remove path stays (we don't track array position separately); that's bounded by page size. Verified: 37 unit + 5 integration tests still pass; tables.spec.ts:28 (create and fill — exercises member churn) passes solo in 20s.
\`Store.addResource\` was chaining a \`getResource\` after every \`putResource\` to verify the round-trip — that doubled worker messages on drive sync (a 50-resource sync produced 100 postMessages, every incoming WS UPDATE produced 2). The worker queue is serialised so the put error path already surfaces real failures, and the verification was diagnostic instrumentation that wasn't gated on a debug flag. Keep the catch handler that logs failed puts.
…urces \`useResource\` unconditionally attached a \`LoadingChange\` listener, even when the resource was already loaded at mount — a no-op listener in the common case (cache hit, OPFS hydration completed before mount). The Resource lifecycle never flips \`loading\` back to true, so once it's false the listener can never fire. Skip attaching it when \`resource.stable.loading\` is already false. Saves one event-manager subscription per useResource call across the mounted tree.
… with rationale - B2 (member index) shipped in d8ca1f3 - Drop OPFS verify round-trip: 0fe9113 - Skip LoadingChange listener when not needed: 43704c6 - B1 deferred — pulling proxyResource without rewriting useValue/useTitle to subscribe per-property would silently freeze every component that uses them (they read \`resource !== prevResource\` to detect change). Worth the refactor eventually but high risk vs the wins remaining. - B3 deferred — Loro emits events on the next microtask, so the existing rebuild-after-import is needed for correctness; gain shrinks once B1 unloads most of the per-update React work. - B8 dropped — \`Resource.title\` only hits 1 hashmap lookup in the common case (\`name\` is set), so memoisation isn't on the hot path.
…d-trip The cold-load fast path in \`fetchResourceWithLocalFallback\` did two sequential awaits per resource: await this.clientDb.getResource(subject) // postMessage 1 await this.clientDb.getLoroSnapshot(subject) // postMessage 2 Every mounted \`useResource\` takes this path on cold-load. A page that needs ~30 resources (sidebar + main view) was doing 60 sequential postMessages before any data hydrated — visible as a long blank flash on populated drives. New worker handler \`getResourceWithSnapshot\` returns both in one response. Halves worker traffic on cold-load. The handler also short- circuits the snapshot read when no JSON-AD exists for the subject (the caller already discards the snapshot in that case). Verified: 37 unit + 5 integration tests pass; \`offline-reload\` and \`offline-create-then-online\` e2e tests (which exercise the OPFS cold- load path explicitly) pass solo.
CI \`@tomic/lib lint\` and \`@tomic/data-browser lint\` were failing on oxfmt --check: the profiler-tick helpers I added to websockets.ts and the \`PerformanceProfiler\` import line in App.tsx weren't run through oxfmt when committed. Run the formatter on both packages. Also add a \`putResources\` batch worker handler I started threading through the cold-load path. Even unwired it's harmless; will be used by a follow-up that batches the bootstrap seed loop (currently 200× sequential postMessages on startup).
Two bottlenecks in the cold-load OPFS path that were blocking time-to- first-paint on every reload of a populated drive: 1. \`fetchResourceWithLocalFallback\` was awaiting \`waitForReady()\`, which combines worker init AND the bootstrap seed (the loop that pushes ~250 in-memory default-property resources into OPFS). The subjects this function actually looks up are user data, not bootstrap data — they don't need the seed to have completed. Block only on init via the new \`waitForInit()\` / \`isInitialized\` accessors. Saves a few hundred ms of dead time on cold load. 2. The seed loop itself was 70 sequential property puts (\`for ... await clientDb.putResource(...)\`) plus a follow-up reseedAll loop with ~200 more sequential awaits. Each \`putResource\` is one worker postMessage round-trip. Add a \`putResources\` batch worker handler that processes the whole array in one round-trip; the worker still handles them in order so the property-first ordering invariant stays intact. Cold-load OPFS overhead drops from ~(70 + N + 200) postMessage round- trips to 3, plus skipping the seed wait entirely for normal lookups. Verified: 37 unit + 5 integration tests + offline-reload, sync, data-browser e2e tests pass.
…init Two more cold-load wins on the critical path: 1. App.tsx top-level: \`await getAgentFromIDB()\` then \`await enableLoro()\` ran sequentially. On a populated browser those each cost ~50–100 ms (IndexedDB read; Loro module import + WASM instantiation). They have no dependency on each other — fan them out with \`Promise.all\` so we pay max(IDB, Loro) instead of sum. 2. The OPFS worker imports \`/wasm/atomic_wasm.js\` which itself fetches \`/wasm/atomic_wasm_bg.wasm\`. Both downloads sat on the cold-load critical path because the worker only starts asking for them after the main thread runs initClientDb. Add \`<link rel="preload">\` hints in index.html so the browser fetches them in parallel with the JS bundle — by the time the worker imports, both responses are cache-hits. \`as="fetch"\` + \`crossorigin\` + \`type="application/wasm"\` is the contract that lets the worker's subsequent fetch reuse the cached response.
…split, batched seed, parallel IDB+Loro, WASM preload)
\`browser/lib/src/perf-hot-paths.bench.ts\` covers each bottleneck documented in PERFORMANCE_PLAN.md. Run via \`pnpm bench\` (added to \`@tomic/lib\` package.json). The file uses \`.bench.ts\` so it's auto-excluded from \`vitest run\` — unit-test CI is unaffected. Suites: - \`Resource.get\` / \`.title\` / \`.loading\` (per-render reads) - \`Resource.merge\` (WS UPDATE rebuild cost) - \`Store.addResource\` gate vs \`skipCommitCompare:true\` (B7 echo gate) - \`Store.notify\` fan-out with 50 subscribers (B1 territory) - \`Collection.applyResourceChange\` indexed bail vs member match (B2) - \`proxyResource\` Proxy alloc (B1) Baseline numbers (M1 Mac, Node 22, vitest 2.1) recorded in the plan so future runs have something to compare against. Not wired into CI — runner variance is too high for a hard gate, but the script is one command and worth running locally before merging perf-adjacent changes.
…ClientDb Two fixes for what \`dagger call ci\` surfaced locally: 1. Cargo registry cache race. \`wasmBuild\`, \`rustBuildSlim\`, and \`rustBuild\` all mount the same \`cargoCache\` volume in parallel containers. With the default \`Shared\` mode their concurrent \`cargo fetch\` runs raced unpacking crates into the registry — \`failed to unpack package X / File exists (os error 17)\`. Switch the registry mount to \`CacheSharingMode.Locked\` so concurrent containers serialise around the registry; per-container \`/code/target\` stays \`Shared\` (each pipeline has its own target volume already). 2. \`NodeClientDb\` was missing \`waitForInit\`/\`isInitialized\` after the cold-load split (eefacc4). The integration test casts \`NodeClientDb as ClientDbWorker\` and the store calls \`this.clientDb.waitForInit()\` unconditionally — without the method, \`undefined()\` threw post-test (visible as "5 passed, 2 errors" with stack frames in \`isParentNew → save → uploadFiles\`). Mirror the pair on \`NodeClientDb\`.
Local nextest still flagged this test as \`FLAKY 2/3\` even with the poll loop and the serial test-group config. Under heavy parallel load in dagger CI, tantivy's reload can take longer than 5s to expose the post-commit segment to the searcher (the reader uses \`OnCommitWithDelay\` and the background merge thread is starved when 20+ tests are spinning up actix HTTP servers). 30s is a safety net — a real bug never converges inside that window either way; the test cost on a hot CPU is still ~50ms because the loop breaks the moment the assertion holds. Also bump the inter-poll sleep from 50ms to 100ms so we yield more aggressively to tantivy's background thread.
Dagger container has noticeably less CPU than a dev laptop, and the shared atomic-server surfaces transient WS / search-index / multi- context-sync races that don't reproduce serially. One retry was enough for genuinely transient paths (e2e.spec.ts:128 chatroom passed on retry), but several tests need two — same as our nextest policy. Three attempts total still surfaces real regressions (a regression fails three times). The cost is that flaky-test-runtime can be ~3× the worst- case test budget; the alternative is the test failing every other CI run on noise.
Local repro shows 1-in-5 first-attempt failures even with the 30s poll loop. The test passes on retry (fresh setup), so the issue is in the initial commit/reload sequence under tantivy's \`OnCommitWithDelay\` reload policy — the writer's segment delete doesn't propagate before the polling deadline. The pattern is consistent: \`FLAKY 2/3\` or \`FLAKY 3/3\`, never multiple retries failing. Bump the override-level \`retries = 5\` so a really unlucky run still has headroom. Default profile retries stay at 2.
Future-me / a teammate can \`grep -rn 'FLAKY (' .\` to find every test
that's been observed flaky in dagger or remote CI, with a one-line
description of the failure mode and a suggested investigation path.
Tests annotated:
- documents.spec.ts:18 — multi-context CRDT sync via WS hub
- e2e.spec.ts:128 — chatroom (recovered on retry 1)
- e2e.spec.ts:289 — folder (children-collection refresh race)
- e2e.spec.ts:386 — delete resource (toast + sidebar refetch)
- e2e.spec.ts:485 — import (children-collection refresh race)
- onboarding.spec.ts:5 — verifySecret auto-submit timing race
- ontology.spec.ts:16 — pickOption helper 100ms race
- plugin.spec.ts:21 — wasm-upload + install commit chain
- sync.spec.ts:103 — offline edit + reconnect title render budget
- sync.spec.ts:161 — cross-context resource render after restore
- table-refresh.spec.ts:79 — post-Tab dirty=0 sample race
- tables.spec.ts:28 — gridcell Visual→Edit-mode transition race
- search.rs::test_update_resource — tantivy reload race
(override \`retries = 5\` exists but isn't applied in the dagger
nextest invocation; needs investigation)
No behavioural changes; comment-only.
The nextest override that bumps \`retries = 5\` for \`search::test_update_resource\` silently never reached nextest in dagger runs — the dagger \`rustBuild\` mounts only individual files (\`Cargo.toml\`, \`Cargo.lock\`, \`Cross.toml\`) and the workspace member directories, not the \`.config/\` directory the file lives in. Symptom: dagger reported \`FAIL [37s]\` for the test (one attempt, hitting the 30s in-test poll deadline + setup) while the same test shows \`FLAKY 2/3\` locally — i.e. the override exists, just not where nextest is looking. Add a \`withFile\` for the nextest config alongside the other workspace-config files. The retries override now reaches nextest and the test should retry up to 5 times before reporting failure.
\`rustFmt\` / \`rustClippy\` / \`rustTest\` extended \`rustBuild()\`, which mounts the data-browser dist (\`/code/server/assets_tmp\`) so build.rs can embed it. That coupling meant any JS-source change invalidated the dagger op-cache for all three rust-check steps even though they don't read the bundle — visible as needless re-execution on JS-only commits. Add \`rustChecksContainer()\`: same workspace inputs as \`rustBuild\` minus \`browserDir\`, with \`ATOMICSERVER_SKIP_JS_BUILD=true\` and a placeholder \`assets_tmp/index.html\` so build.rs is happy. Has its own \`rust-checks-target\` cache volume so fmt → clippy → test (which run serially in \`ci\`) share incremental compile artifacts without contending with the release-binary build's \`rust-target\`. JS-only commits should now cache-hit through the entire rust check pipeline. Rust source changes still invalidate as before.
Real bug from \`59280b3d\`'s combined-round-trip refactor: the worker
case for \`getResourceWithSnapshot\` placed unawaited Promises into the
response object —
const jsonAd = db!.getResource(msg.subject); // ← Promise<string>
const snapshot = jsonAd ? db!.getLoroSnapshot(...) : null;
return { jsonAd, snapshot };
The dispatching async function flattens the outer Promise, but the
inner Promises inside the object literal aren't unwrapped. Their
\`postMessage\` reply then fails with "Failed to execute 'postMessage'
... #<Promise> could not be cloned" — every cold-load OPFS lookup
errored, fell back to the WS GET path, and the resulting wave of
slow round-trips manifested as widespread e2e timeouts in dagger.
Fix: \`await\` each before placing into the response. The single-call
\`getResource\` case worked because the async dispatcher flattens a
top-level returned Promise; the bug was only in the combined object
shape.
Local NodeClientDb tests didn't catch this because NodeClientDb has
its own \`getResourceWithSnapshot\` that already awaits, and the
postMessage layer is absent there.
Bare \`retries = 5\` in an override silently parses but inherits the
profile default. Switch to the table form
\`retries = { backoff = "fixed", count = 5, delay = "1s" }\` so the
override actually takes effect. Confirmed via local repro: with the
table form the search test gets up to 6 attempts; with the bare form
it stayed at 3 (the profile-default retries=2).
In practice the 30s in-test poll deadline + retries=2 already covers
this test reliably (3 sequential local runs all green), but the larger
retries budget is the proper safety net for genuinely unlucky CI runs.
Two consecutive local CI-mode e2e runs (39/39 passed) confirm the 8
dagger failures aren't regressions — they're chronic environment
flakes that reproduce only under dagger's slower runner +
\`atomic.localhost\` host-resolver routing + single-core actix
container. Each is already annotated inline with a \`// FLAKY (...)\`
marker (\`grep -rn 'FLAKY ('\`).
Lib (unit + integration) and Rust nextest are green in both
environments.
…Page \`fetchPage\` did: 1. fetchPageFromLocalDb — if 'ok', return 2. await waitForFirstDriveSync ← added 1–5 s 3. fetchPageFromLocalDb — if 'ok', return 4. fetchPageFromServer Step 2's wait-and-retry is built on a wrong assumption: that the bootstrap drive sync seeds the user's drive contents into OPFS. It doesn't — the sync only populates Properties + Classes. Queries on user data (\`parent=<userDrive>\`, \`isA=Document\`, etc.) get 'no-db' on both attempts, so the wait is wasted budget before falling through to the server. Symptom this caused: every cold-loaded collection (sidebar tree, table rows, breadcrumb, chatroom messages) blocked for 1–5 s before its server \`/query\` GET fired. With ~5 collections per page the gating was simultaneous, so the cold-load wall clock was dominated by it. Drops 1–5 s from cold-load latency on a populated page. The \`hasCompletedDriveSync\`-aware empty-fast-path inside \`fetchPageFromLocalDb\` (B5 / e89c9da) still makes "empty result is real" the authoritative answer once sync IS complete — we keep that.
OPFS check and server fetch were sequential — \`await\`-OPFS first, then on miss \`await\`-server. For the common cold-load case where OPFS misses (drive sync hasn't populated user data yet), the OPFS round-trip latency (~50–200 ms in dagger) sat in front of the server round-trip we'd ultimately need anyway. Fire the server query in parallel and treat both as racing writers of \`this.pages\`. If OPFS hits, we return immediately — the in-flight server result lands later and overwrites with identical data (harmless, both are post-sync truth). If OPFS misses, we just await the server promise that's already in progress. Compounds with the previous commit (drop \`waitForFirstDriveSync\` retry): cold-load Collection latency goes from ~(OPFS + 1–5 s sync wait + server) to ~max(OPFS, server) ≈ server. Verified: lib unit + integration tests still pass; full sync.spec e2e (4 tests including the dagger-flaky offline-edit + cross-context ones) passes locally in 30 s.
Root cause of why \`retries = 5\` never applied to the search test in
dagger or local runs: the filter \`binary(=atomic-server)\` doesn't
match the lib-unit-test binary in this workspace. The unit tests of
the atomic-server lib live in a binary whose ID is \`atomic-server\`
but \`binary()\` filters on a binary *name* — different from the ID,
and apparently empty for lib-unit-test binaries here.
Verified via \`cargo nextest run -E '...'\`:
binary(=atomic-server) and test(=...) → 0 tests across 0 binaries
package(atomic-server) and test(=...) → 1 test, runs
Switching to \`package(atomic-server)\` lights up the override:
\`FLAKY 2/6\` / \`FLAKY 3/6\` instead of the previous \`FLAKY 2/3\` /
\`TRY 3 FAIL\`. Three sequential \`cargo nextest run --workspace\`
invocations are now stable: 191 passed (1 flaky, recovered) every
time, no hard-fails.
The agent is saved online-only, so it was never written to clientDb. On reload, fetchResourceWithLocalFallback found no local copy and refetched the agent from the server, which under commit-persistence lag returns the synthetic just-in-time view (publicKey/read/createdAt/isA only, no drives/personalDrive). Under load this emptied the Saved Drives list. Extract the clientDb write from saveOffline into a reusable persistToClientDb(), and mirror did:ad:agent: subjects into clientDb after an online save so the cold-load path reads the agent (with drives + lastCommit) locally and never consults the racy server view. Repro: ATOMIC_TEST_CPU_THROTTLE=6 reproduced 4/4; fixed 5/5. Offline-sync tests + 80 unit tests stay green.
Author + date were rendered by fetching the message's `lastCommit` as a `did:ad:commit:<sig>` resource, which no longer resolves under sign-at-drain, so both disappeared after a page refresh. Derive them from the message's own genesis Loro change instead: `createdBy` from the change's commit message (the signing agent, embedded at sign time) and `createdAt` from its timestamp. The server and the WASM ClientDb materialize these into propvals (`materialize_genesis_metadata`) so they are indexable (the chatroom's `sort_by: createdAt`) and serialized in JSON-AD; the client reads them propval-first, falling back to the oplog for fresh local state (`getCreatedAt`/`getCreatedBy`, `useCreatedAt`/`useCreatedBy`). - The genesis change is selected by Lamport (causal order), not timestamp: the server's post-apply `lastCommit` change carries a second-resolution timestamp that could otherwise sort before the ms-precise genesis and blank out `createdBy`. - Creation metadata rides on the first commit of a new doc (`writeDatatypeTags`), tagged in `signChanges` with the agent subject and a millisecond timestamp. - Message views (ChatRoom, MessageCard, MessagePage) no longer fetch a commit; `CommitDetail` takes createdAt/createdBy and drops the commit link when given them. The data route gains a genesis row. - e2e: chatroom + offline-chatroom assert author + date survive a reload.
- Per-agent localStorage namespace (`atomic.outbox.<agent>`) so a new
identity never drains a previous agent's commits — fixes the 401
commit-flood caused by stale cross-agent entries. One-shot migration
re-files the legacy shared queue by owner; unattributable entries are
dropped rather than re-adopted by the wrong identity.
- Exponential backoff (1s→30s cap) replaces immediate re-drain, ending
the full-speed spin on a persistently-failing commit. `nextDueAt()`
wakes the scheduler at the right time instead of busy-retrying.
- A `401 "no write right"` is treated as a transient ordering race
(parent not yet synced) and retried under backoff; only after
BLOCK_AFTER_FAILURES sustained failures is it parked — kept + surfaced
("could not sync"), not retried — and re-armed by the next local edit.
- Surface the blocked count in the sidebar sync status.
- Feature-detect lock-steal support (`navigator.userAgentData`, a
Chromium-only proxy). On Firefox/Safari, skip the doomed `{ steal: true }`
re-request (which only burns another election window) and park the tab in
degraded server-only mode immediately, with a recovery-oriented message.
The pending queued lock still auto-recovers the tab to leader when the
ghost lease frees — no hard 2s-then-2s failure.
- Add a minimal e2e (`client-db-locks.spec.ts`) covering two-tab leadership
coexistence, run in both chromium and firefox. The firefox project is
scoped to just this spec and skipped when ATOMIC_TEST_HOST_MAP is set
(the dagger CI's non-localhost origin lacks Firefox's secure context).
- Add `disk-storage-and-persistence-optimization.md`: why store size and boot time degrade with age (full Loro snapshots per commit, no auto-compaction, redb's O(file-size) open fsync + unclean-shutdown repair) and the fixes (incremental updates, auto-compaction, retention). - Add `encryption.md` (E2EE / verifier vs blind-replica exploration), `genesis-self-verifying.md` (inline binary genesis certificate), and `llm-wasm-gui-plugins.md` (JS/TS app platform: scoped Loro payloads, blob checkpoints, capability model). - Cross-link disk-storage ↔ encryption (the full-snapshot payload bloats `kind: delta` envelope size) and ↔ llm-wasm (app Loro payloads and blob checkpoints inherit the same growth + retention concerns). - Re-align the planning README table and list the new docs.
Adds a two-tab test asserting a collaborator's caret renders in the other tab's editor as a `.ProseMirror-loro-cursor` decoration. Parked `test.fixme`: the CollaborativeEditor currently crashes on load (`DecorationGroup.eq` on an undefined member) wherever the `LoroEphemeralCursorPlugin` is active — the known loro-prosemirror@0.4.3 × prosemirror-view@1.41 (TipTap 3.23) incompatibility documented when the remote cursor was removed on 2026-05-29. Un-fixme once that's resolved; the assertions are correct.
The editor crashed ("Cannot read properties of undefined (reading
'localsInner')") whenever a loro ephemeral-cursor decoration coexisted
with another decoration source — the slash-menu suggestion or the
empty-doc placeholder — e.g. typing "/" next to a collaborator's caret
or creating a fresh document.
Two root causes:
1. Dual prosemirror-view instances. loro-prosemirror was excluded from
Vite dep-optimization (it pulls in WASM loro-crdt), so its
prosemirror-view was served raw while tiptap's was prebundled — two
DecorationSet classes at runtime. A loro DecorationSet then failed
`instanceof DecorationSet` inside tiptap's DecorationGroup.from,
which read `.members` off the foreign set (undefined) and stored it
as a null group member, crashing DecorationGroup.locals on the next
view update. Fix: optimize loro-prosemirror in the same graph
(loro-crdt stays external) + resolve.dedupe the shared prosemirror
packages, so there is a single instance.
2. setState-during-render. The AI-comparison sync dispatched a
ProseMirror transaction from useOnValueChange (whose callback runs
during render), causing "Cannot update a component while rendering"
and editor instability (detached title input). Fix: move it into a
useEffect.
Also replaced @tiptap/extension-placeholder (a second decoration source
that triggered the same crash) with a CSS-only placeholder.
Adds an e2e test asserting a collaborator's ephemeral cursor renders.
The self-verifying GenesisCert (Rust + TS mirror) now carries the resource's `drive` DID alongside the original `parent`. Drive is an immutable invariant (resources don't move between drives), so binding it into the signed identity enables race-free, drive-first rights checks and drive-scoped query indexing for did: subjects. Inert for now: GenesisCert is exported but not yet consulted by any runtime path (DID derivation and rights checks are unchanged). The mint / verify / materialize / rights wiring follows in a later commit. - lib/src/genesis.rs + browser/lib/src/genesis.ts: `drive` field added to encode/decode, byte-identical across both languages (pinned known-byte-vector test: 7/7 Rust, 4/4 TS). - urls::GENESIS constant for the inline cert propval. - planning/genesis-self-verifying.md: drive field, drive-first rights model, and the materialize-at-genesis race-fix rationale.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Most insane PR ever.
did:adResolvingdid:adlocal-first resources #1146 , refactors subject completely Refactor Subject (resource identifiers / urls / dids / ids) #1139Checklist