Repository navigation
[PROJ-1431] Ship isolated shadow-governance reviewer demo backend - #330
Conversation
|
Bugbot is not enabled for your account, so this pull request was not reviewed. Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs. |
Summary by CodeRabbit
WalkthroughThis pull request adds an isolated ChangesShadow governance demo
Birders feed readiness
Estimated code review effort: 5 (Critical) | ~120 minutes Possibly related issues
Suggested labels: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
✨ Simplify code
Warning Review ran into problems🔥 ProblemsThese MCP integrations need to be re-authenticated in the Integrations settings: Notion Comment |
There was a problem hiding this comment.
Actionable comments posted: 17
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/feed/routes/feed-skeleton.ts (1)
269-301: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick winEnforce
community.publicin the serving path.
publicFeedUris()only hides private feeds from discovery. This handler still serves anyenabledcommunity wheneverFEED_PRIVATE_MODEis off, sopublic: falsehas no request-time effect. A futureenabled + public:falsecommunity would be publicly fetchable unless this gate also checks!community.public.🔒 Proposed fix
- if (config.FEED_PRIVATE_MODE) { + if (config.FEED_PRIVATE_MODE || !community.public) { const viewerDid = await verifyFeedRequesterDid(authHeader); if (!viewerDid) return reply.send({ feed: [] }); const approved = await isParticipantApproved(viewerDid); if (!approved) return reply.send({ feed: [] }); precomputedViewerDid = viewerDid; }Add coverage for:
enabled/public:falsewithFEED_PRIVATE_MODE=false→ empty feed for unauthenticated/unapproved callersenabled/public:truewithFEED_PRIVATE_MODE=false→ normal feed response🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/feed/routes/feed-skeleton.ts` around lines 269 - 301, Enforce the community’s public visibility in the serving path: update the gate after isFeedCommunityServable in the feed handler to treat enabled communities with public === false as inaccessible when FEED_PRIVATE_MODE is disabled, returning an empty feed for unauthenticated or unapproved callers. Preserve normal responses for enabled, public communities, and add coverage for both scenarios.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@scripts/birders-feed-scout.ts`:
- Around line 47-50: Update the finally cleanup in the script’s main execution
flow so failures from redis.disconnect() or db.end() cannot replace the original
try-block error; perform cleanup defensively by catching and logging cleanup
errors while preserving the initial failure, and ensure both cleanup operations
are still attempted.
In `@src/demo/corpus.ts`:
- Around line 232-264: Sequential score reads in buildScoredCorpusItems increase
demo latency; parallelize them while respecting backend capacity. Refactor the
loop to issue readScore calls concurrently, preferably with Promise.all over
bounded chunks of roughly 10–20 rows if the Redis/DB pool cannot safely handle
all candidates at once, then preserve the existing filtering and item
construction behavior for missing or non-finite scores.
In `@src/demo/service.ts`:
- Around line 143-158: Session creation currently persists the full corpus
inside ShadowDemoSessionState, causing each anonymous session write to duplicate
substantial Redis data. In the session state construction and store.writeSession
flow, replace the embedded corpus with a reference to a shared corpus key or
otherwise minimize the persisted record, and ensure reads/mutations resolve that
reference; also add monitoring for demo:* key count/memory and enforce a per-IP
concurrent-session limit.
In `@src/demo/store.ts`:
- Around line 198-213: Remove the corpusKey setex operation from writeSession,
leaving only the sessionKey persistence in the Redis transaction. Update or add
tests for writeSession to verify only the session blob is written and no
demo:corpus entry is created.
In `@src/demo/weights.ts`:
- Around line 34-58: Replace the manual checks in validateShadowWeights with a
Zod schema for the five SHADOW_DEMO_SIGNAL_KEYS, requiring finite non-negative
numbers and a sum within SUM_TOLERANCE of 1. Use safeParse or parse at the
external-input boundary in routes.ts, map validation failures to the existing
error behavior, and have validateShadowWeights return the parsed typed result so
the schema is the single source of truth.
In `@src/feed/community-materializer.ts`:
- Around line 119-137: Handle partial MULTI/EXEC failures explicitly in the
materialization transaction around the ranked-candidate writes and snapshot
metadata updates. When results contain a failed command, identify the affected
command and perform best-effort cleanup or reconciliation of the Birders keys
before throwing; alternatively, include which writes may have committed in the
error. Preserve the existing queue-abort handling and use the transaction
construction/materialization symbols to keep the mitigation scoped to this
namespace.
- Around line 491-505: Prevent nullableFiniteInteger() from converting null into
0: explicitly return null for null input before calling finiteNumber(), while
preserving validation for strings and numbers. Add a regression test covering
readCommunitySnapshot() with active_epoch_id: null, asserting reportStatus()
returns unavailable and reportWarnings() includes the missing active production
epoch warning.
In `@tests/birders-feed-materializer.test.ts`:
- Around line 161-204: Add a separate test for a genuinely missing active epoch,
distinct from the existing zero-candidate case: configure the mocked database
row with active_epoch_id: null, invoke scoutCommunityFeed, and assert the report
status is 'unavailable' and warnings include 'No active production epoch was
available for Birders materialization.'. Ensure the nullable epoch coercion used
by scoutCommunityFeed/materialization preserves null rather than converting it
to 0.
In `@tests/birders-scout-command.test.ts`:
- Around line 29-35: Add coverage in the existing invalid-options test for the
missing-value branches of parseBirdersScoutArgs by asserting --limit and
--window-hours throw their respective “requires a value” messages, and verify
the -h alias throws BirdersScoutHelpRequested.
- Around line 1-9: Add direct test coverage for the exported
renderBirdersMaterializeResult function in the birders scout command tests,
using a representative MaterializedCommunityFeedResult and asserting the
rendered output contains “Materialized ranked posts:” and “Redis keys written:”.
In `@tests/demo-shadow-isolation.test.ts`:
- Around line 23-42: Pair the static checks in the tests covering
demoSourceText() with a behavioral isolation test, such as in the demo
shadow-store tests, that exercises the demo store using a mocked or spied
production database client and asserts no writes occur to governance, feed,
audit, or export tables. Keep these regex assertions as a cheap first-line
guard, but ensure the behavioral test detects indirect calls through renamed,
wrapped, or re-exported helpers.
In `@tests/demo-shadow-public-view.test.ts`:
- Around line 31-220: Extend the existing shadow public-view Vitest suite with
focused cases for empty and exactly 25 URI inputs to the batching/URL helper,
null and undefined inputs to publicPostFromAppView, malformed JSON from the
AppView fetch response, and abort/timeout behavior that verifies the fetch mock
receives an AbortSignal. Use the existing hydration and URL-builder symbols,
avoid duplicating the malformed-post and HTTP-503 coverage, and assert the
expected fail-closed or transport-error results.
In `@tests/demo-shadow-routes.test.ts`:
- Around line 568-604: Add edge-case tests in the existing shadow route suite:
exercise two overlapping vote requests for one session and assert one returns
409 with “session is busy”; submit all-zero weights and assert the documented
validation error status; and use a store whose readSession returns malformed
JSON, asserting a 500 response with the generic demo error body. Reuse the
existing app setup and route symbols, and ensure concurrency is genuinely
overlapping rather than sequential.
In `@tests/demo-shadow-store.test.ts`:
- Around line 40-52: Update RedisDemoStore.writeSession to handle partial
MULTI/EXEC failures: when the corpus SETEX result fails after the session SETEX
succeeds, delete or invalidate the demo:session:* key before rethrowing the
transaction error. Ensure the existing “Redis transaction failed” error still
includes the underlying failure, and keep the partial-failure test asserting the
cleanup behavior.
In `@tests/demo-shadow-weights.test.ts`:
- Around line 44-232: Add tests in the existing “shadow demo weight math” suite
for both uncovered edge paths: assert aggregateShadowVotes([]) throws an error
matching “zero shadow demo votes”, and call scoreFromRawWeights with an empty
topicWeights object, asserting effectiveRawScores.relevance remains equal to
rawScores.relevance.
In `@tests/feed-community-registry.test.ts`:
- Around line 14-51: Expand the “feed community registry” tests beyond happy
paths: add assertions that resolveFeedCommunityByRkey and
resolveFeedCommunityByUri return null for unknown values, and that
publicFeedUris and the resolver handle an empty communities array. Add coverage
for feedUriForRkey and directly verify isFeedCommunityServable returns true for
enabled and false for disabled communities, using the existing registry fixtures
and publisher DID.
In `@tests/feed-skeleton-validation.test.ts`:
- Around line 258-323: Extend tests in the existing feed skeleton suite to cover
cursor-based pagination for a non-community-gov community, verifying the
subsequent page uses getCommunityFeedSnapshotById and the namespaced
snapshot-by-id Redis key. Add a test for an enabled but non-public Birders
configuration using feedUriForCommunity, asserting the unauthenticated request
returns the expected empty feed or auth challenge after public access is
enforced; include empty or boundary pagination behavior where appropriate.
---
Outside diff comments:
In `@src/feed/routes/feed-skeleton.ts`:
- Around line 269-301: Enforce the community’s public visibility in the serving
path: update the gate after isFeedCommunityServable in the feed handler to treat
enabled communities with public === false as inaccessible when FEED_PRIVATE_MODE
is disabled, returning an empty feed for unauthenticated or unapproved callers.
Preserve normal responses for enabled, public communities, and add coverage for
both scenarios.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository YAML (base), Organization UI (inherited)
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 840777fc-1f1a-465d-8a42-19d7826a37ef
📒 Files selected for processing (43)
CHANGELOG.mdREADME.mddocs/RECSYS_VALIDATION_EVIDENCE.mddocs/dev-journal.mddocs/lab/birders-feed-readiness.mddocs/lab/demo-shadow-governance-contract.mddocs/lab/open-science-demo-readiness.mdpackage.jsonscripts/birders-feed-scout.tssrc/demo/appview.tssrc/demo/corpus.tssrc/demo/public-view.tssrc/demo/routes.tssrc/demo/service.tssrc/demo/store.tssrc/demo/synthetic-voters.tssrc/demo/topic-intent.tssrc/demo/types.tssrc/demo/weights.tssrc/feed/birders-scout-command.tssrc/feed/community-materializer.tssrc/feed/community-registry.tssrc/feed/rate-limit-config.tssrc/feed/routes/describe-generator.tssrc/feed/routes/feed-skeleton.tssrc/feed/server.tssrc/feed/snapshot-cache.tssrc/governance/aggregation-math.tssrc/governance/aggregation.tssrc/scoring/components/relevance.tstests/birders-feed-materializer.test.tstests/birders-scout-command.test.tstests/demo-shadow-isolation.test.tstests/demo-shadow-public-view.test.tstests/demo-shadow-routes.test.tstests/demo-shadow-store.test.tstests/demo-shadow-weights.test.tstests/feed-community-registry.test.tstests/feed-skeleton-validation.test.tstests/rate-limit-config.test.tstests/web-next-shadow-demo-contract.test.tsweb-next/app/demo/shadow-demo-contract.tsweb-next/app/demo/shadow-demo-contract.type-test.ts
|
Bugbot is not enabled for your account, so this pull request was not reviewed. Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs. |
There was a problem hiding this comment.
Actionable comments posted: 2
♻️ Duplicate comments (1)
tests/demo-shadow-weights.test.ts (1)
216-242: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winStill missing:
scoreFromRawWeightsempty-topicWeightsfallback test.The past review flagged two untested branches — zero votes (now fixed at lines 74-76) and
scoreFromRawWeightsfalling back to unchangedrawScores.relevancewhentopicIntent.topicWeightsis empty. Only the first was added; this fallback branch is still only exercised via the non-emptyTOPIC_INTENTfixture.🧪 Suggested addition
it('falls back to raw relevance when topic intent has no weights', () => { const scored = scoreFromRawWeights( { recency: 0.5, engagement: 0.8, bridging: 0.25, source_diversity: 1, relevance: 0.4 }, { recency: 0.2, engagement: 0.3, bridging: 0.1, source_diversity: 0.1, relevance: 0.3 }, { 'science-research': 0.8 }, { topicWeights: {} } ); expect(scored.effectiveRawScores.relevance).toBe(0.4); });As per path instructions, "Check for tests that only cover the happy path. Suggest edge cases: empty inputs, boundary values, null/undefined... and error conditions."
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tests/demo-shadow-weights.test.ts` around lines 216 - 242, Add a test covering the empty-topicWeights fallback in scoreFromRawWeights, passing a topic intent with topicWeights: {} and asserting effectiveRawScores.relevance remains equal to the raw relevance value; keep the existing non-empty topic intent contribution test unchanged.Source: Path instructions
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/demo/store.ts`:
- Around line 198-199: Refactor ShadowDemoSessionState and the persistence flow
in writeSession and its corresponding read method so Redis sessions store only a
corpusId or content-hash/version reference, while the frozen ShadowDemoCorpus is
written once to a shared record and hydrated on reads to preserve the existing
returned payload shape. Update session creation and vote/epoch update paths to
reuse the shared corpus record, and add tests verifying multiple sessions share
one corpus blob and updates do not rewrite corpus bytes.
In `@tests/feed-skeleton-auth.test.ts`:
- Around line 158-181: Add private-community authorization tests alongside the
existing anonymous case: configure a valid requester DID with
isParticipantApprovedMock returning false, then assert a 200 empty feed, no
redisMock.zrevrange call, and approval verification is invoked; add a
DID-verification-null case asserting an empty feed, no Redis access, and
isParticipantApprovedMock is not called. Ensure verifyFeedRequesterDidMock and
related mocks reflect the behavior implemented in jwt-verifier.ts.
---
Duplicate comments:
In `@tests/demo-shadow-weights.test.ts`:
- Around line 216-242: Add a test covering the empty-topicWeights fallback in
scoreFromRawWeights, passing a topic intent with topicWeights: {} and asserting
effectiveRawScores.relevance remains equal to the raw relevance value; keep the
existing non-empty topic intent contribution test unchanged.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository YAML (base), Organization UI (inherited)
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 5c3715ba-4976-4bf1-98e0-01ca07d6fecb
📒 Files selected for processing (10)
scripts/birders-feed-scout.tssrc/demo/corpus.tssrc/demo/store.tssrc/feed/community-materializer.tssrc/feed/routes/feed-skeleton.tstests/birders-feed-materializer.test.tstests/demo-shadow-store.test.tstests/demo-shadow-weights.test.tstests/feed-community-registry.test.tstests/feed-skeleton-auth.test.ts
|
Bugbot is not enabled for your account, so this pull request was not reviewed. Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs. |
|
Bugbot is not enabled for your account, so this pull request was not reviewed. Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs. |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/feed/snapshot-cache.ts`:
- Around line 240-259: Protect the fallback zrevrange in createCurrentSnapshot
with error handling equivalent to the metric write: catch Redis read failures,
log the degraded fallback outcome, and return null instead of allowing the
exception to escape. First verify the caller’s handling, but ensure this
function itself safely handles failures while reading spec.fallbackSortedSetKey.
- Around line 8-9: The fallback Redis keys are hard-coded global values instead
of being scoped per community. Remove FEED_LAST_KNOWN_GOOD_KEY and
FEED_LAST_KNOWN_GOOD_FALLBACK_TOTAL_KEY, add corresponding last-known-good key
fields to each community’s redis configuration (such as lastKnownGood and
lastKnownGoodFallbackTotal), and update FeedSnapshotSpec and all references
around the fallback logic to read those configured values.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository YAML (base), Organization UI (inherited)
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 3d97ee4f-ab07-4fa4-b6d3-45f04d9d9212
📒 Files selected for processing (2)
docs/dev-journal.mdsrc/feed/snapshot-cache.ts
|
Bugbot is not enabled for your account, so this pull request was not reviewed. Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs. |
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
tests/demo-shadow-weights.test.ts (2)
45-72: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick winAdd a negative-weight boundary case.
The suite validates sum≠1, NaN, and all-zero, but not a negative component that still sums to 1.0 (e.g.
recency: -0.5, engagement: 1.5). The test name implies "non-negative" is an enforced property, but no test provesvalidateShadowWeightsrejects it.it('rejects negative weights even when they sum to one', () => { expect(() => validateShadowWeights({ recency: -0.5, engagement: 1.5, bridging: 0, source_diversity: 0, relevance: 0, }) ).toThrow(/non-negative|negative/); });As per path instructions,
**/*.test.tsfiles should cover boundary values and error conditions.🤖 Prompt for AI Agents
In `tests/demo-shadow-weights.test.ts`, inside the `'validates finite non-negative weights that sum to one'` test (around lines 45-72), add a case asserting validateShadowWeights throws for a weights object containing a negative component whose total still sums to 1.0. Confirm the thrown message pattern against the actual guard in src/demo/weights.ts.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tests/demo-shadow-weights.test.ts` around lines 45 - 72, Add a boundary assertion in the “validates finite non-negative weights that sum to one” test for validateShadowWeights, using a weights object with recency -0.5 and engagement 1.5 while the total remains 1.0. Assert that it throws using the actual negative/non-negative error message pattern from validateShadowWeights.Source: Path instructions
89-124: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick winCover the exact trimming boundary (9 vs. 10 votes).
Small-electorate coverage uses 2 votes, and trimming coverage jumps straight to 10. The off-by-one boundary at 9 votes (should still be
trimmed_mean_no_trim_under_10withtrimCount: 0) is untested, leaving the< 10threshold unverified for the value closest to the switch.it('does not trim exactly nine votes', () => { const summary = aggregateShadowVotes(Array(9).fill(RECENCY_ONLY)); expect(summary.aggregateMethod).toBe('trimmed_mean_no_trim_under_10'); expect(summary.trimCount).toBe(0); });As per path instructions, suggest boundary-value edge cases for
**/*.test.tsfiles.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tests/demo-shadow-weights.test.ts` around lines 89 - 124, Add a boundary-value test in the aggregateShadowVotes test suite for exactly nine votes, using Array(9).fill(RECENCY_ONLY); assert aggregateMethod is trimmed_mean_no_trim_under_10 and trimCount is 0 to verify the threshold remains exclusive below ten votes.Source: Path instructions
♻️ Duplicate comments (1)
tests/feed-skeleton-auth.test.ts (1)
158-182: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick winMissing assertion that approval check is short-circuited for anonymous callers.
The prior review specifically requested asserting
isParticipantApprovedMockis not called when DID verification returnsnull. That assertion is still absent here — onlyzrevrangeandverifyFeedRequesterDidMockare checked. Without it, a regression that callsisParticipantApproved(null)(or skips the null check entirely) would pass this test silently.🤖 Prompt for AI Agents
In `tests/feed-skeleton-auth.test.ts` in the test `'does not serve an enabled private community to an anonymous caller'` (around lines 158-182), add: expect(isParticipantApprovedMock).not.toHaveBeenCalled(); right after the existing `redisMock.zrevrange` assertion, to confirm the fail-closed path never reaches participant approval when DID is null.Also worth confirming: this test doesn't override
config.FEED_PRIVATE_MODE, so it runs with whateveroriginalPrivateModedefaults to. If the private-community gate infeed-skeleton.tsis conditioned on the globalFEED_PRIVATE_MODEflag rather than purely oncommunity.public, this test (and the unapproved-caller test below) may not actually exercise the fail-closed path when the flag is off in the default environment — which is precisely the gap flagged in the linked security review offeed-skeleton.ts.#!/bin/bash set -euo pipefail fd config.ts src --exec cat -n {} \; | rg -n "FEED_PRIVATE_MODE" -A3 -B3 fd feed-skeleton.ts src --exec cat -n {} \;🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tests/feed-skeleton-auth.test.ts` around lines 158 - 182, In the test “does not serve an enabled private community to an anonymous caller,” add an expectation immediately after the existing redisMock.zrevrange assertion that isParticipantApprovedMock was not called. Also ensure the test explicitly enables the relevant FEED_PRIVATE_MODE configuration when required so the private-community authorization path is exercised reliably.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@tests/demo-shadow-weights.test.ts`:
- Around line 45-72: Add a boundary assertion in the “validates finite
non-negative weights that sum to one” test for validateShadowWeights, using a
weights object with recency -0.5 and engagement 1.5 while the total remains 1.0.
Assert that it throws using the actual negative/non-negative error message
pattern from validateShadowWeights.
- Around line 89-124: Add a boundary-value test in the aggregateShadowVotes test
suite for exactly nine votes, using Array(9).fill(RECENCY_ONLY); assert
aggregateMethod is trimmed_mean_no_trim_under_10 and trimCount is 0 to verify
the threshold remains exclusive below ten votes.
---
Duplicate comments:
In `@tests/feed-skeleton-auth.test.ts`:
- Around line 158-182: In the test “does not serve an enabled private community
to an anonymous caller,” add an expectation immediately after the existing
redisMock.zrevrange assertion that isParticipantApprovedMock was not called.
Also ensure the test explicitly enables the relevant FEED_PRIVATE_MODE
configuration when required so the private-community authorization path is
exercised reliably.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository YAML (base), Organization UI (inherited)
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 1a0a6b9d-529c-4921-a08b-6585a426c807
📒 Files selected for processing (6)
src/demo/store.tssrc/feed/community-registry.tssrc/feed/snapshot-cache.tstests/demo-shadow-store.test.tstests/demo-shadow-weights.test.tstests/feed-skeleton-auth.test.ts
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
tests/demo-shadow-weights.test.ts (2)
158-196: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick winVerify seed and epoch sensitivity, not only repeatability.
The test proves identical inputs produce identical votes, but an implementation that ignores
seedandepochIdwould still pass. Generate votes with a different seed and epoch, then assert the generated vote payloads differ to protect session and epoch isolation.AI agent prompt
Keep the existing identical-input repeatability assertion. Add one generated vote set with a different seed and another with a different epochId, then assert each differs from the baseline payload.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tests/demo-shadow-weights.test.ts` around lines 158 - 196, Extend the test for createSyntheticVoterVotes by generating one additional vote set with a different seed and another with a different epochId, while keeping the existing repeated-input equality assertion. Assert that each altered-input result differs from syntheticVotes, comparing the generated vote payloads directly.Source: Path instructions
45-81: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick winAdd malformed runtime-value cases to the validator suite.
The test covers
NaN, negative values, and invalid sums, but notInfinity,-Infinity, or missing/null components. These can appear after deserialization despite the TypeScript type; add explicit runtime-invalid cases and assert the intended validation errors.AI agent prompt
Extend validateShadowWeights tests with Infinity, -Infinity, undefined, and null component values. Cast malformed objects only at the test boundary and assert the validator rejects them with the appropriate finite/type error.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tests/demo-shadow-weights.test.ts` around lines 45 - 81, Add runtime-invalid cases to the validateShadowWeights test in the “validates finite non-negative weights that sum to one” block for Infinity, -Infinity, undefined, and null component values. Cast malformed objects only at the test boundary, and assert Infinity values fail with the finite error while undefined/null values fail with the intended type or validation error.Source: Path instructions
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@tests/demo-shadow-weights.test.ts`:
- Around line 158-196: Extend the test for createSyntheticVoterVotes by
generating one additional vote set with a different seed and another with a
different epochId, while keeping the existing repeated-input equality assertion.
Assert that each altered-input result differs from syntheticVotes, comparing the
generated vote payloads directly.
- Around line 45-81: Add runtime-invalid cases to the validateShadowWeights test
in the “validates finite non-negative weights that sum to one” block for
Infinity, -Infinity, undefined, and null component values. Cast malformed
objects only at the test boundary, and assert Infinity values fail with the
finite error while undefined/null values fail with the intended type or
validation error.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository YAML (base), Organization UI (inherited)
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: c9b3239d-88b6-47b9-8370-fb97e358dd78
📒 Files selected for processing (2)
tests/demo-shadow-weights.test.tstests/feed-skeleton-auth.test.ts
|
Applying the audited |
Summary
Builds the isolated backend contract for Corgi's no-login reviewer demo. A visitor can create a shadow session from a production-scored snapshot, cast a demo-only vote, run 24 deterministic synthetic community voters, advance up to ten shadow epochs, inspect the reordered feed, and read post-level receipt math without mutating production governance or the live feed.
Linear: PROJ-1431
Changes
/api/demo/*Fastify route family with Redis-only sessions, corpora, locks, and idempotency records.community-govfeed or publishing a new feed rkey./docsto/api/docsso the static public product documentation can own/docs/.Safety Boundaries
demo:*Redis keys.governance_votes,governance_epochs,governance_audit_log, research exports,feed:current, or production snapshot keys.birders-who-coderemains disabled and is not advertised bydescribeFeedGenerator.Verification
npm run verifypassed on currentorigin/main: 118 Vitest files / 1,065 tests, TypeScript, CLI, SDK, fixture, legacy web lint/build, and Next static build.npm run docs:verifypassed: 14 tracked docs / 35 Markdown files.git diff --checkpassed.Checklist
npm run verifypasses locallyCHANGELOG.mdupdated under## [Unreleased]npm run docs:verifypasses