Skip to content

feat(challenges): {success, error, reason, comment?, commentUpdate?} result shape (#88)#99

Merged
Rinse12 merged 10 commits into
masterfrom
feat/issue-88-challenge-result-extras
May 23, 2026
Merged

feat(challenges): {success, error, reason, comment?, commentUpdate?} result shape (#88)#99
Rinse12 merged 10 commits into
masterfrom
feat/issue-88-challenge-result-extras

Conversation

@Rinse12
Copy link
Copy Markdown
Collaborator

@Rinse12 Rinse12 commented May 22, 2026

Summary

Closes #88. Replaces the originally proposed `extraProps` bag with a typed shape on the challenge result:

```ts
ChallengeResultSchema = z
.object({
success: z.literal(true),
reason: z.string().optional(),
comment: z.looseObject({}).optional(), // partial CommentIpfs
commentUpdate: z.looseObject({}).optional() // partial CommentUpdate
})
.or(z.object({
success: z.literal(false),
error: z.string(),
reason: z.string().optional()
}));
```

Aggregated across successful challenges (last-wins per key):

  • `comment` is spread last into the IPFS-bound `CommentIpfs` literal, so challenge keys become part of the CID. Cannot override anything in `CommentSignedPropertyNames` (the author signed those).
  • `commentUpdate` is persisted on a new `challengeCommentUpdate` JSON column on the comments table and seeded into `queryCalculatedCommentUpdate` with lowest priority, per-field. Each challenge-supplied field stays until a mod publishes a `commentModeration` setting that same field name; other challenge-set fields keep persisting.
  • `reason` propagates to the published `ChallengeVerificationMessage.reason` (both success and failure paths).

Override-guard

A new helper `validateChallengeResultExtras` throws a `PKCError` if a challenge sets:

  • any `comment.` in `CommentSignedPropertyNames` (would invalidate the author's signature)
  • any `commentUpdate.` in the new `CommentUpdateChallengeReservedFieldNames` (community-computed fields: counts, cid, signature, updatedAt, etc.)

The list is co-located with `CommentUpdateSchema` and uses `as const satisfies readonly (keyof z.infer)[]` so renaming a CommentUpdate field surfaces a stale entry at compile time.

`getChallengeVerification` already wraps the classification loops in try/catch and turns thrown PKCErrors into `{ challengeSuccess: false, reason: "One of the community challenges is misconfigured: …" }`, so misconfigured challenges fail loudly without crashing the community.

First commentUpdate signing

The `CommentUpdateForChallengeVerificationSchema` stays `.strict()` to keep types clean across the existing union; `signCommentUpdateForChallengeVerification` instead computes `signedPropertyNames` dynamically as `[...base, ...extraKeysOnUpdate]` so challenge keys actually land in the signature.

DB migration

`DB_VERSION` bumped 39 → 40 (additive column, NULL for legacy rows). `_copyTable` handles the migration automatically.

Test plan

  • `test/challenges/result-extras.test.ts` (7 tests): aggregation across challenges + guard
  • `test/node/community/v39-to-v40.migration.db.community.test.ts` (4 tests): migration + column read/write
  • `test/node/community/challengeCommentUpdate.db.community.test.ts` (5 tests): per-field override semantics with real `queryCalculatedCommentUpdate`
  • `npm run build` clean
  • `npx tsc --project test/tsconfig.json --noEmit` clean
  • Existing `test/challenges/challenges.test.ts` (46 tests) still pass
  • Existing `test/node/community/v38-to-v39.migration.db.community.test.ts` still passes
  • Full e2e (publish a comment through a custom challenge in a running test community, assert IPFS bytes + commentUpdate regeneration over IPNS) — left for follow-up since it needs more infra setup; the integration test on the DB seeding path covers the same per-field override semantics.

Out of scope (per plan)

  • Updating `@bitsocial/mintpass-challenge` to use the new shape — separate package, follow-up PR there.
  • Vote / commentEdit / commentModeration / communityEdit challenge-result extras — comment only.
  • Promoting `countryCode` (or similar) to a first-class typed `CommentIpfs` field.

Summary by CodeRabbit

  • New Features

    • Challenges can attach extra metadata (comment, partial comment updates, reason) that are validated, aggregated, signed, and persisted; aggregated extras surface in verification and pending-approval payloads.
  • Bug Fixes

    • Validation blocks challenges from overriding protected comment signed fields or reserved comment-update/community-author fields.
  • Tests

    • New unit and integration tests cover aggregation, override-guards, signing, DB persistence/migration; DB version bumped to 40.

Review Change Stack

…result shape (#88)

Replaces the previously proposed `extraProps` bag with a typed shape on the
challenge result. Aggregated across successful challenges (last-wins per key):
- `comment` spread last into the IPFS-bound CommentIpfs (becomes part of the CID)
- `commentUpdate` persisted on a new `challengeCommentUpdate` JSON column on the
  comments table; seeded into queryCalculatedCommentUpdate with lowest priority
  so any mod-published commentModeration overrides matching fields per-field

Adds an override guard: throws PKCError if a challenge tries to override a key
in CommentSignedPropertyNames (would invalidate the author's signature) or a
key in the new CommentUpdateChallengeReservedFieldNames list (community-computed
fields like counts, cid, updatedAt). Misconfigured challenges fail loudly via
the existing try/catch in getChallengeVerification.

The first commentUpdate (encrypted with the verification message) carries the
challenge-supplied keys by computing signedPropertyNames at sign time from the
actual object keys.

DB_VERSION bumped 39 → 40 (additive column, NULL for legacy rows).
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 22, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds optional comment/commentUpdate/reason to ChallengeResult; enforces override guards; aggregates extras across challenges; threads aggregates through signing, publishing, and storage; persists challengeCommentUpdate in DB with a v39→v40 migration; and adds tests covering aggregation, overrides, and migration.

Changes

Challenge Extras Implementation

Layer / File(s) Summary
Challenge Result Schema and Validation Contracts
src/community/schema.ts, src/errors.ts, src/publications/comment/schema.ts, src/runtime/node/community/challenges/validate-challenge-result.ts
ChallengeResultSchema expanded to allow comment and commentUpdate on success and optional reason on failure; new error codes added; CommentUpdateChallengeReservedFieldNames and CommunityAuthorChallengeReservedFieldNames added; validateChallengeResultExtras enforces no overrides of author-signed comment fields or reserved commentUpdate/community-author fields.
Challenge Verification Aggregation and Orchestration
src/runtime/node/community/challenges/index.ts
Introduces ChallengeResultAggregate and accumulateChallengeResultExtras; validates and accumulates aggregatedComment, aggregatedCommentUpdate, and aggregatedReason during both request-time and verify-time classification; widens verification return types and propagates aggregated fields into getChallengeVerification.
Challenge Publishing and Aggregate Threading
src/runtime/node/community/local-community/challenges.ts, src/signer/signatures.ts
publishChallengeVerification and storePublicationAndEncryptForChallengeVerification accept and forward challengeAggregate; unsigned commentUpdate used for signing spreads aggregatedCommentUpdate so signature covers extra keys; signing computes signedPropertyNames as base fields plus any extra keys present.
Publication Storage and Challenge Data Persistence
src/runtime/node/community/local-community/publication-store.ts, src/runtime/node/community/db-handler.ts, src/version.ts
storeComment/storePublication accept challengeAggregate; aggregatedComment is merged into IPFS-bound commentIpfs (last), non-empty aggregatedCommentUpdate is persisted into commentRow.challengeCommentUpdate; DB schema adds nullable challengeCommentUpdate JSON column; insertComments binds the new column; queryCalculatedCommentUpdate seeds calculated update from challengeCommentUpdate with adjusted per-field precedence; DB_VERSION bumped 39→40.
Tests and Migration
test/challenges/result-extras.test.ts, test/node/community/challengeCommentUpdate.db.community.test.ts, test/node/community/modqueue/pendingapproval.modqueue.community.test.ts, test/node/community/v39-to-v40.migration.db.community.test.ts, updated migration expectations in other migration tests
Adds unit and integration tests covering aggregation semantics (last-wins), failure propagation, pending-approval reason handling and signing, override-guard throws, persistence and per-field moderation override semantics, and v39→v40 DB migration behavior; updates existing migration assertions to expect DB_VERSION 40.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • pkcprotocol/pkc-js#97: Overlaps on threading/publishing of ChallengeResultAggregate and related changes in local-community/challenges.ts.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 14.29% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: introducing a richer ChallengeResultSchema with typed fields (success, error, reason, comment, commentUpdate).
Linked Issues check ✅ Passed The PR implements all primary coding objectives from #88: typed ChallengeResultSchema with comment/commentUpdate/reason fields, aggregation logic, override guards, DB migration (v39→v40), and comprehensive test coverage.
Out of Scope Changes check ✅ Passed All changes align with #88 scope: schema updates, validation, aggregation, plumbing through challenge flow, DB migration, and tests. No out-of-scope modifications detected.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/issue-88-challenge-result-extras

Comment @coderabbitai help to get the list of available commands and usage tips.

Rinse12 added 4 commits May 22, 2026 14:27
…tests

DB_VERSION was bumped 39 → 40 in this branch; two pre-existing migration tests
assert that the migrated DB lands at the latest version with a hardcoded literal.
Adds coverage for the driving use case where a challenge with pendingApproval: true
succeeds and attaches a rationale on commentUpdate.reason, so the mod reviewing
the pending queue can see why the challenge sent the comment there.
…author

Pins the author-side end of the new commentUpdate-extras flow:
- signCommentUpdateForChallengeVerification puts challenge-supplied keys (reason,
  countryCode, etc.) into signature.signedPropertyNames so the community's signature
  actually covers them
- JSON roundtrip (matches what the encrypt/decrypt boundary does) preserves the
  reason field
…ason

Replaces the lighter sign+JSON-roundtrip test with a real end-to-end test in the
existing pending-approval modqueue suite: registers a custom challenge on
pkc.settings.challenges that returns {success: true, commentUpdate: {reason}},
publishes through the real challenge pipeline, and asserts on the author-side
challengeverification event that:
  - challengeVerification.commentUpdate.reason carries the rationale
  - signature.signedPropertyNames includes "reason" (community really signed it)
  - the Comment instance exposes `comment.reason` via the unknown-props hoist
@Rinse12 Rinse12 marked this pull request as ready for review May 23, 2026 01:44
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 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/runtime/node/community/challenges/index.ts`:
- Around line 62-66: The code currently uses truthy checks like `if
(challengeResult.reason)` before assigning to `agg.aggregatedReason`, which
drops valid empty-string reasons; change these checks to explicit undefined
comparisons (`if (challengeResult.reason !== undefined)`) wherever
`challengeResult.reason` is inspected (including the occurrences around the
early return and the later assignment and the similar block at lines ~807-810)
so empty-string values are preserved and still propagated to
`agg.aggregatedReason`.

In `@test/challenges/result-extras.test.ts`:
- Around line 153-180: The test currently expects getChallengeVerification to
throw when a challenge overrides a comment-signed field; update it to reflect
the new contract where override violations are returned as a failed verification
instead of thrown. Specifically, call getChallengeVerification as before but do
not wrap it in try/catch expecting an exception; instead assert the returned
value has challengeSuccess === false and that the returned reason/code or
failure metadata indicates ERR_CHALLENGE_RESULT_OVERRIDES_COMMENT_SIGNED_FIELD
(reference getChallengeVerification and the error identifier
ERR_CHALLENGE_RESULT_OVERRIDES_COMMENT_SIGNED_FIELD); apply the same change
pattern to the similar assertions around lines 182-203.

In `@test/node/community/challengeCommentUpdate.db.community.test.ts`:
- Line 22: Add a one-line comment immediately above the
describeSkipIfRpc("queryCalculatedCommentUpdate seeded with
challengeCommentUpdate", ...) that explicitly states why this test cannot run
under RPC (e.g., relies on in-process DB seeding/state, uses local-only helpers,
or depends on synchronous access to in-memory fixtures). Reference the test name
"queryCalculatedCommentUpdate seeded with challengeCommentUpdate" and the helper
describeSkipIfRpc so reviewers can see the RPC incompatibility reason at a
glance; keep the comment short and specific to the RPC limitation.

In `@test/node/community/modqueue/pendingapproval.modqueue.community.test.ts`:
- Around line 349-361: Add a clear RPC-skip rationale comment immediately above
the describeSkipIfRpc(...) suite explaining why the test cannot run under RPC
(e.g., it depends on in-process challenge execution, local commentUpdate-extras
flow, or direct access to in-memory modqueue/encryption hooks that RPC does not
provide). Reference the suite name describeSkipIfRpc and the custom challenge
function pendingWithReasonChallenge so readers understand this test exercises
the local getChallenge → commentUpdate roundtrip and therefore must be skipped
for RPC runs.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 69b6b610-229c-416c-95b5-2d1e8bbd392e

📥 Commits

Reviewing files that changed from the base of the PR and between 540f275 and 523540c.

📒 Files selected for processing (16)
  • src/community/schema.ts
  • src/errors.ts
  • src/publications/comment/schema.ts
  • src/runtime/node/community/challenges/index.ts
  • src/runtime/node/community/challenges/validate-challenge-result.ts
  • src/runtime/node/community/db-handler.ts
  • src/runtime/node/community/local-community/challenges.ts
  • src/runtime/node/community/local-community/publication-store.ts
  • src/signer/signatures.ts
  • src/version.ts
  • test/challenges/result-extras.test.ts
  • test/node/community/challengeCommentUpdate.db.community.test.ts
  • test/node/community/modqueue/pendingapproval.modqueue.community.test.ts
  • test/node/community/v29-production.migration.db.community.test.ts
  • test/node/community/v36-to-v37.migration.db.community.test.ts
  • test/node/community/v39-to-v40.migration.db.community.test.ts

Comment on lines +62 to +66
if (challengeResult.reason) agg.aggregatedReason = challengeResult.reason;
return;
}
if (challengeResult.reason) agg.aggregatedReason = challengeResult.reason;
if (challengeResult.comment) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Preserve empty-string reason values during aggregation.

Using truthy checks drops valid reason: "" values. Use explicit !== undefined checks so all schema-valid reasons propagate consistently.

Suggested fix
-    if (!("success" in challengeResult) || challengeResult.success !== true) {
-        if (challengeResult.reason) agg.aggregatedReason = challengeResult.reason;
+    if (!("success" in challengeResult) || challengeResult.success !== true) {
+        if (challengeResult.reason !== undefined) agg.aggregatedReason = challengeResult.reason;
         return;
     }
-    if (challengeResult.reason) agg.aggregatedReason = challengeResult.reason;
+    if (challengeResult.reason !== undefined) agg.aggregatedReason = challengeResult.reason;
-        if (res.aggregatedReason) challengeVerification.aggregatedReason = res.aggregatedReason;
+        if (res.aggregatedReason !== undefined) challengeVerification.aggregatedReason = res.aggregatedReason;

Also applies to: 807-810

🤖 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/runtime/node/community/challenges/index.ts` around lines 62 - 66, The
code currently uses truthy checks like `if (challengeResult.reason)` before
assigning to `agg.aggregatedReason`, which drops valid empty-string reasons;
change these checks to explicit undefined comparisons (`if
(challengeResult.reason !== undefined)`) wherever `challengeResult.reason` is
inspected (including the occurrences around the early return and the later
assignment and the similar block at lines ~807-810) so empty-string values are
preserved and still propagated to `agg.aggregatedReason`.

Comment on lines +153 to +180
it("surfaces failure when a challenge tries to override a comment-signed field", async () => {
// `content` is part of CommentSignedPropertyNames. getChallengeVerification wraps its inner
// loops in try/catch and turns a thrown PKCError into `{ challengeSuccess: false, reason }`
// so misconfigured challenges fail loudly with a descriptive message.
(mockPkc.settings ??= {}).challenges = {
"bad-comment": makeExtrasChallenge({ success: true, comment: { content: "spoofed by challenge" } })
};
const community = {
settings: { challenges: [{ name: "bad-comment" }] },
_pkc: mockPkc
} as unknown as LocalCommunity;

let caught: Error | undefined;
try {
await getChallengeVerification({
challengeRequestMessage,
community,
getChallengeAnswers: (async () => []) as GetChallengeAnswers
});
} catch (e) {
caught = e as Error;
}
// The thrown PKCError bubbles out of the inner classification loop. local-community/challenges.ts
// catches it at the outer caller (`runChallengeExchangeIfNeeded`); here we exercise the inner
// function directly, so we see the throw.
expect(caught).to.not.equal(undefined);
expect((caught as { code?: string })?.code).to.equal("ERR_CHALLENGE_RESULT_OVERRIDES_COMMENT_SIGNED_FIELD");
});
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Override-guard tests currently enforce a throw path that conflicts with the target contract.

These assertions expect getChallengeVerification to throw, but this PR’s intended behavior is to convert override violations into a failed verification result (non-throwing). Keeping these as throw assertions will lock in the wrong API behavior.

Suggested test-shape adjustment
- let caught: Error | undefined;
- try {
-   await getChallengeVerification(...);
- } catch (e) {
-   caught = e as Error;
- }
- expect(caught).to.not.equal(undefined);
- expect((caught as { code?: string })?.code).to.equal("ERR_...");

+ const verification = await getChallengeVerification(...);
+ expect(verification.challengeSuccess).to.equal(false);
+ expect(verification.challengeErrors).to.exist;
+ expect(verification.aggregatedReason).to.be.a("string");

Also applies to: 182-203

🤖 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 `@test/challenges/result-extras.test.ts` around lines 153 - 180, The test
currently expects getChallengeVerification to throw when a challenge overrides a
comment-signed field; update it to reflect the new contract where override
violations are returned as a failed verification instead of thrown.
Specifically, call getChallengeVerification as before but do not wrap it in
try/catch expecting an exception; instead assert the returned value has
challengeSuccess === false and that the returned reason/code or failure metadata
indicates ERR_CHALLENGE_RESULT_OVERRIDES_COMMENT_SIGNED_FIELD (reference
getChallengeVerification and the error identifier
ERR_CHALLENGE_RESULT_OVERRIDES_COMMENT_SIGNED_FIELD); apply the same change
pattern to the similar assertions around lines 182-203.

Comment thread test/node/community/challengeCommentUpdate.db.community.test.ts
Rinse12 added 4 commits May 23, 2026 03:44
…Schema

`reason` only makes sense on the failure path — a successful challenge has
nothing to explain. Remove it from the success branch of ChallengeResultSchema,
stop propagating it through accumulateChallengeResultExtras on success, and
revert publishChallengeVerification's success path to `reason: undefined`.

Failure-side aggregatedReason (challenge-supplied rationale for rejection)
stays as-is.
The previous refactor included `aggregatedComment` and `aggregatedCommentUpdate`
as explicit `undefined` keys on the success return, which broke a deep-equal
assertion that expected those keys to be absent when no challenge populated
them. Destructure `aggregatedReason` away from the success branch and spread
the rest so undefined fields stay absent.
AGENTS.md requires an explicit reason above describeSkipIfRpc. Added one-line
rationales on the two new suites added in this PR (challengeCommentUpdate DB
seeding test and the pending-approval commentUpdate.reason roundtrip test).
Lets a challenge attach `commentUpdate.author.community.<key>` (e.g. a
country-code badge from an IP geolocation check) without the previous
wholesale `author` ban. The guard is now path-aware:

- `commentUpdate.author.<key>`: only `community` is permitted; any other
  key throws ERR_CHALLENGE_RESULT_OVERRIDES_NON_COMMUNITY_AUTHOR_KEY
- `commentUpdate.author.community.<key>`: forbidden if `<key>` is in
  CommunityAuthorChallengeReservedFieldNames (postScore, replyScore,
  firstCommentTimestamp, lastCommentCid — community-computed;
  banExpiresAt — mod-settable via commentModeration.author.banExpiresAt),
  else allowed as lowest-priority extra

`flairs` is intentionally not reserved: a challenge may seed
`author.community.flairs` with lowest priority, and a mod publishing
`commentModeration.author.flairs` overrides it via the existing
queryAuthorModEdits path. queryCalculatedCommentUpdate merges
`challengeCommentUpdate.author.community.*` underneath the computed
authorCommunity, so any mod-set field wins automatically.

`CommunityAuthorChallengeReservedFieldNames` is co-located with
`CommunityAuthorSchema` and uses `as const satisfies readonly (keyof ...)[]`
so renaming a CommunityAuthor field surfaces a stale entry at compile
time, matching CommentUpdateChallengeReservedFieldNames.
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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/publications/comment/schema.ts`:
- Around line 161-162: The comment above the schema about allowed
author.community keys is contradictory: it says "no schema-defined keys under
community" but the reserved-field contract permits at least certain keys (e.g.,
flairs). Update the comment near the schema and the note referencing
validateChallengeResultExtras to explicitly state that top-level author keys
remain disallowed but reserved author.community keys (such as "flairs") are
allowed per the reserved-field contract; mention validateChallengeResultExtras
and the reserved-field contract by name so future maintainers know validation is
enforced separately and which community keys are permitted.

In `@test/node/community/challengeCommentUpdate.db.community.test.ts`:
- Around line 183-197: The test claims "Same author" but currently `insertPost`
generates a unique `authorSignerAddress` per CID, so make both posts share the
same author to actually validate per-comment isolation: update the test to
create a single author object (or a fixed `authorSignerAddress`) and pass that
same author into both `insertPost(...)` calls for `commentA` and `commentB`,
then run `calculate(...)` as before (symbols: insertPost, calculate,
authorSignerAddress) so the two comments truly originate from the same author
while still having different `author.community.countryCode` 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 317f6c9e-df8e-45bb-82b9-9ce5ee6d0c11

📥 Commits

Reviewing files that changed from the base of the PR and between 20df244 and df823f9.

📒 Files selected for processing (7)
  • src/errors.ts
  • src/publications/comment/schema.ts
  • src/runtime/node/community/challenges/validate-challenge-result.ts
  • src/runtime/node/community/db-handler.ts
  • src/schema/schema.ts
  • test/challenges/result-extras.test.ts
  • test/node/community/challengeCommentUpdate.db.community.test.ts

Comment thread src/publications/comment/schema.ts Outdated
Comment thread test/node/community/challengeCommentUpdate.db.community.test.ts
…are author across per-comment isolation test

- schema.ts: fix contradictory comment that claimed no schema-defined `author.community`
  keys are allowed. `flairs` is intentionally permitted (lowest-priority seed; mod
  override via commentModeration.author.flairs).
- challengeCommentUpdate.db.community.test.ts: the "Same author, two posts" case
  was generating a distinct authorSignerAddress per CID, so it could pass even if
  per-comment isolation broke. Add an override param and pass a shared address.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Allow challenges to attach extraProps to CommentIpfs via the challenge result

1 participant