A historical rooms record with an empty room name made the backfill call
put('') and abort with "key cannot be an empty String". Skip records with no
room name so the one-time backfill can complete; such rooms have no listing
entry to write.
By specifier.
Capture three time-costing lessons from this session in the architect
process notes so future sessions read them at startup: restore a
manifest stripped by a killed mutate4javascript run with
--update-manifest, gauge gherkin-mutator progress from the mutations
directory, and commit review changes before running verify.sh so the
record's git_sha matches the review commit.
By architect.
Architectural review of the topic recency indexes and pagination:
- Indexer topic index maintenance lives in its own topic-indexing.js,
separate from the action handlers; the backfill library takes injected
LevelDB handles so its logic stays testable.
- DB listTopics reads counts from topicSummaries and paginates the
topicRecency index without iterating the rooms store; the client reuses
PaginatedPage.
- Kill four topic-indexing mutation survivors with focused unit tests
covering the height fallbacks, plus exact-key/isNotFound and max-size
boundary tests.
- One topic-message survivor is an intrinsic equivalent: handlePost reads
the text at push index 1 and ignores push index 0.
Includes tool-written mutate4javascript and acceptance-mutation manifests.
By architect.
The DB soft Gherkin mutation re-ran the whole feature for every mutant;
with a fresh LevelDB world per example, a 48-mutation feature exceeded
900s. The runner-worker now diffs the mutated IR against the base feature
at <work>/base/feature.json (derived from the mutation path, since
job.work_dir may be mutation-specific) and runs only the changed
scenario/example. Safe because each scenario uses an isolated world.
The same feature now completes in ~74s.
By architect.
Run the 15 generated DB acceptance files with bounded concurrency
(default min(4, files), ACCEPTANCE_CONCURRENCY to override) instead of
strictly sequentially. Generation still runs first and sequentially.
Each generated file uses its own tmp/acceptance/level-* world, so the
pool is isolated. Full DB acceptance drops from ~430-790s to ~96s.
Also record the orphaned-mocha mutation-hang finding and remediation in
the architect process notes.
By architect.
- Extract roomFromEntry/applyPost from backfill collectSummaries so its
cyclomatic complexity drops from 7 to 4 (CRAP 7.0 -> 4.0), and extract
the shared roomRange key bounds from getTopicPostTxids/listRoomFollowers.
- Add indexer property tests over arbitrary post/follow/unfollow
interleavings: postCount conservation, newest-height recency shape,
replay idempotence, and inverted-key ordering.
- Add DB property tests for the topic index backfill: conservation,
recency shape, stale-record removal, and inverted-key ordering.
- Cover the topic action error paths (invalid push counts, oversized
topic message), the topic-query room fallbacks, and the client
openTopic/topicFeedPath navigation.
By refactorer.
- Indexer maintains topicSummaries and topicRecency for topic messages and
follows, idempotently, moving each room's recency record to its newest post.
- DB adds the two index stores and serves GET /topics from them with
limit/offset pagination, without iterating the rooms store. Adds
util/room/backfill-topic-indexes.js to build the indexes idempotently.
- Client topics page loads 50 per page with Previous/Next.
By coder.
Add Gherkin for efficient GET /topics ordering by most recent post, the
topicSummaries and topicRecency index stores, an idempotent backfill, and
client topics-page pagination.
By specifier.
Import the browser-safe buffer module in the multi-push adapter so the
CRA production bundle no longer reads the Node global Buffer, add
regression tests for the falsy-wallet and idempotent-attach paths, share
the script-encoding test helper, and de-duplicate the UTF-8 push
acceptance assertions. Refresh the language mutation manifests and the
soft acceptance-mutation manifest.
By architect.
Share a single UTF-8 encoding helper across hex, poll-create, and
topic-post instead of repeating new TextEncoder().encode(), drop the
redundant Uint8Array branch in the push normalizer, rename the
txid-action push builder parameter from buildPayload to buildPushes to
match what it returns, and factor the db repair unit-test setup into a
repairedFixture helper.
Add property tests for the multi-push adapter covering prefix/ordering,
field-byte conservation, buffer round trips, array expansion, single
field delegation, and idempotent attach, plus a unit test for the
unsupported-wallet guard.
By refactorer.
Reply, topic message, add-poll-option, poll-vote, and create-poll now
broadcast each protocol field as its own OP_RETURN script push instead of
combining them into one push. The indexer requires three pushes for reply,
topic message, and poll children, and accepts four for create-poll; the
combined form was rejected or misparsed.
hex.js builds the txid and text as separate pushes, and a new
memo-multipush adapter teaches minimal-slp-wallet's single-push sendOpReturn
to expand an array of fields into separate pushes. Acceptance step handlers
assert the individual pushes, and unit/property tests cover the new shape.
By coder.
Add Gherkin pinning that reply, topic message, add-poll-option, poll
vote, and create-poll broadcast each protocol field as its own OP_RETURN
push, so the indexer and memo.cash can parse them.
By specifier.
Refresh the mutate4javascript and Gherkin acceptance-mutation manifests,
kill the memo-like/memo-reply boundary survivors, and extract the shared
FakeDb/makeLevel double used by the txid repair unit and property tests.
By architect.
Share the txid-and-text payload builder between hex and reply, extract the
repair store loop from repairTxidEncoding to cut CRAP from 13 to 5, correct
the poll-services property test to the little-endian wire order, and add
property tests for wire round trips and repair idempotence/conservation.
By refactorer.
Client likes, replies, poll options, and poll votes now embed the
referenced txid in little-endian wire order, matching the indexer's
byte reversal. Add a psf-memo-db repair library and CLI that rewrites
byte-reversed references in likes, postParents, pollOptions, and
pollVotes and rebuilds the postLikes and postChildren indexes, leaving
correct and unknown references untouched and staying idempotent.
By coder.
Add client Gherkin pinning little-endian wire order for every action that
embeds a parent txid (like, reply, poll option, poll vote), and a
psf-memo-db Gherkin for a utility that repairs existing byte-reversed
references and rebuilds the affected indexes.
By specifier.
Add unit coverage for the LikeTipPage initial state, deps seeding, the
dust-limit boundary, and empty/null tip parsing, and assert exact
validation/broadcast error messages. Add the NewPostPage initial
result-modal state assertion. Refresh the mutate4javascript footer
manifests for the touched services and the soft Gherkin
acceptance-mutation manifest for the like-result feature.
By architect.
Deduplicate the new like-result acceptance steps behind one render helper,
and extract the bch.loping.net transaction link shared by the New Post result
modal, the post options menu, and the like/tip result into a block-explorer
service. Cover the LikeTipPage open/parse/handler failure branches and add
property tests for the explorer URL, the LikeResult markup, and the result
modal state machine.
CRAP is at or below 5 with full coverage on the changed services; every
changed/new plain source file scans at 21 or fewer mutation sites. The
existing mutation manifests are left for the mutation tool to refresh.
By refactorer.
Keep the like/tip modal open after a successful like and show a broadcast
result instead of closing: the success message, the like transaction id, and
a link to that transaction on bch.loping.net that opens in a new tab. The
like count and filled heart update immediately, and dismissing the result
closes the modal. The result state lives on the testable LikeTipPage
controller; a server-renderable LikeResult component backs the modal and the
acceptance adapter, with acceptance step handlers for the new wording.
By coder.
Move the outside-click decision into the pure post-options service so the
effect stays a thin adapter and the previously uncovered `&&` mutation is
unit testable. Add unit tests for the outside-click predicate and for the
default no-focus open menu, killing the two surviving `-1` default-focus
mutations.
Stamp the mutate4javascript manifests for both modules and the soft
acceptance-mutation manifest for post-options-menu.
By architect.
Move the keyboard shortcut mapping into the pure post-options service so the
React component is a thin adapter and the Escape/ArrowDown decisions are unit
and property testable. DRY the duplicated post-options acceptance steps behind
two helpers, and add property tests for the explorer URL, menu-item shape,
state transitions, key command, and rendered markup.
The createElement post-options component and service stay scannable by
mutate4javascript; the JSX call sites (post-feed-item, profile) are unchanged
except for rendering the shared menu.
By refactorer.
Add a shared PostOptionsMenu component, used by the feed/thread post card and
the profile post card, with a pure post-options service for the block explorer
link and the open/close/focus state. Its first item links to the post
transaction on bch.loping.net in a new tab; the menu opens on the button and
closes on the button again, an outside click, or Escape, with ArrowDown moving
focus to the first item.
By coder.
Written review report and machine-readable verification record for the
raised recent-feed total scan cap. Verification passed 4/4 (unit 358,
property 48, acceptance all 12 suites, lint). Mutation killed 37/37 in
post-query.js; CRAP max 6.0; DRY clean for the changed files.
By architect.
Architectural review of the raised recent-feed total scan cap (10 -> 500)
and the refactorer's property tests. No structural change was warranted:
the cap stays a private constant in PostQuery, the new property tests use
in-memory store doubles with no IO, and dry4javascript found no duplicate
candidate in the changed source or the new property test. Mutation killed
all 37 sites in post-query.js.
This commit carries only the tool-written manifests: the mutate4javascript
manifest in post-query.js and the gherkin-mutator acceptance stamps in the
two touched feature files.
By architect.
Cover the total-scan cap and bounded raw scan of
PostQuery.scanRecentPostTxidsAndCount over seeded random corpora: capped
total, newest-first pagination conservation, the raw-scan bound, the 500
default cap, and reply exclusion.
By refactorer.
GET /posts/recent now caps its total scan at 500 eligible top-level posts
instead of 10, so corpora smaller than the cap report an exact total while
larger corpora stay bounded. Added unit coverage for the exact-total-under-cap
and default-cap cases, plus the many-top-level-posts acceptance fixture.
By coder.
Commit the review summary and the client verification record (git_sha
19e57be, the review commit) alongside the review. All five client commands
pass.
By architect.