Summary
pkcprotocol/pkc-js#73 lets a community operator choose which page sorts (feeds) their community generates, configure options on each, and install third-party sort packages. seedit needs a UI for that, in the community settings area alongside the existing challenge configuration.
Tracking issue. Blocked on pkc-js#73 landing and on the first sort package shipping.
What operators will be configuring
settings: {
pages: {
posts: [
{ name: "hot" },
{ name: "top", options: { maxAge: "2w" } },
{ name: "@pkcprotocol/active-no-bump-keyword-page-sort", options: { noBumpKeywords: ["sage"] } }
],
replies: [{ name: "old" }],
preloadedPostSorts: ["hot"],
preloadedReplySorts: ["old"]
}
}
Entry shape mirrors settings.challenges exactly: { name | path, options }, resolved against a registry of built-ins plus installed packages. There is no name field for the wire key, because the sort file supplies its own sortName.
UI requirements
1. Sort pickers for posts and replies. Two ordered lists, drawn from built-ins plus installed packages. Ordering matters, see the preloaded section below.
2. Scope filtering. Each sort declares scope: "posts" | "replies" | "both". The picker must only offer valid sorts per slot, because some combinations are genuinely broken rather than merely odd: the active score is rooted at depth 0 and has no reply meaning, and flat sorts have no post equivalent. Putting a reply-scoped sort under posts is a config validation error.
3. Preloaded sorts are arrays. preloadedPostSorts / preloadedReplySorts select which sorts get their first page embedded in the record. Two things to convey:
- The size budget is shared. Preloading four sorts gives each a quarter of the room. This is a real cost decision, not a free win, and the UI should say so rather than presenting checkboxes with no consequence.
- The first entry is the default clients open, so the array is ordered and the operator controls that order. Needs to be reorderable, not just a multi-select.
4. Typed option values, which differ from challenges. This is the main reason the existing challenge option renderer cannot be reused as-is. settings.challenges[].options is z.record(z.string(), z.string()), every value a string. Page sort options allow string | string[] | boolean | number, because a keyword list is genuinely a list and pinnedFirst: "false" was always a trap. So:
optionInputs carries a value type per input; the renderer needs a tag-list control for arrays and a real checkbox for booleans, not just text fields.
ChallengeOptionInputSchema currently assumes text, so the shared schema may need widening or a page-sort-specific variant.
5. Moderation exclusion options, with a warning. Every sort exposes excludeRemovedComments, excludeDeletedComments, excludeCommentPendingApproval, excludeCommentWithApprovedFalse, defaulting to today's values. Turning excludeRemovedComments off publishes removed posts into the community's feed. That is intentional and has legitimate uses (archive feeds, mod-review sorts), but it is not something to flip past in a config form without the operator understanding it.
6. Cost feedback. The motivation for the whole feature is that generating fourteen sorts is wasteful. A board generating one post sort and one reply sort instead of fourteen is the target. Showing roughly what a configuration costs, even qualitatively, is what makes the feature usable. Also worth surfacing: a windowed sort (maxAge) is a sliding window whose page CIDs rotate every cycle, so adding many windowed sorts works against the same goal.
7. Validation surfaced inline. Two entries resolving to the same sortName is an error, as is a preloadedPostSorts entry not present in the posts list. Both are catchable before community.edit().
8. Package installation is out of scope here. Installing sort packages is a CLI concern, tracked in bitsocialnet/bitsocial-cli#138. The web UI configures what is already installed and should degrade gracefully when a configured package is missing.
Sequencing
Blocked on pkc-js#73 merging and on @pkcprotocol/active-no-bump-keyword-page-sort existing, since that package is the first real consumer of the typed-options and package-picker paths.
Summary
pkcprotocol/pkc-js#73 lets a community operator choose which page sorts (feeds) their community generates, configure options on each, and install third-party sort packages. seedit needs a UI for that, in the community settings area alongside the existing challenge configuration.
Tracking issue. Blocked on pkc-js#73 landing and on the first sort package shipping.
What operators will be configuring
Entry shape mirrors
settings.challengesexactly:{ name | path, options }, resolved against a registry of built-ins plus installed packages. There is no name field for the wire key, because the sort file supplies its ownsortName.UI requirements
1. Sort pickers for posts and replies. Two ordered lists, drawn from built-ins plus installed packages. Ordering matters, see the preloaded section below.
2. Scope filtering. Each sort declares
scope: "posts" | "replies" | "both". The picker must only offer valid sorts per slot, because some combinations are genuinely broken rather than merely odd: theactivescore is rooted at depth 0 and has no reply meaning, andflatsorts have no post equivalent. Putting a reply-scoped sort underpostsis a config validation error.3. Preloaded sorts are arrays.
preloadedPostSorts/preloadedReplySortsselect which sorts get their first page embedded in the record. Two things to convey:4. Typed option values, which differ from challenges. This is the main reason the existing challenge option renderer cannot be reused as-is.
settings.challenges[].optionsisz.record(z.string(), z.string()), every value a string. Page sort options allowstring | string[] | boolean | number, because a keyword list is genuinely a list andpinnedFirst: "false"was always a trap. So:optionInputscarries a value type per input; the renderer needs a tag-list control for arrays and a real checkbox for booleans, not just text fields.ChallengeOptionInputSchemacurrently assumes text, so the shared schema may need widening or a page-sort-specific variant.5. Moderation exclusion options, with a warning. Every sort exposes
excludeRemovedComments,excludeDeletedComments,excludeCommentPendingApproval,excludeCommentWithApprovedFalse, defaulting to today's values. TurningexcludeRemovedCommentsoff publishes removed posts into the community's feed. That is intentional and has legitimate uses (archive feeds, mod-review sorts), but it is not something to flip past in a config form without the operator understanding it.6. Cost feedback. The motivation for the whole feature is that generating fourteen sorts is wasteful. A board generating one post sort and one reply sort instead of fourteen is the target. Showing roughly what a configuration costs, even qualitatively, is what makes the feature usable. Also worth surfacing: a windowed sort (
maxAge) is a sliding window whose page CIDs rotate every cycle, so adding many windowed sorts works against the same goal.7. Validation surfaced inline. Two entries resolving to the same
sortNameis an error, as is apreloadedPostSortsentry not present in thepostslist. Both are catchable beforecommunity.edit().8. Package installation is out of scope here. Installing sort packages is a CLI concern, tracked in bitsocialnet/bitsocial-cli#138. The web UI configures what is already installed and should degrade gracefully when a configured package is missing.
Sequencing
Blocked on pkc-js#73 merging and on
@pkcprotocol/active-no-bump-keyword-page-sortexisting, since that package is the first real consumer of the typed-options and package-picker paths.