feat(web): reader customization of wiki pages (human prior injection) - #447
Draft
YashJayswal24 wants to merge 2 commits into
Draft
feat(web): reader customization of wiki pages (human prior injection)#447YashJayswal24 wants to merge 2 commits into
YashJayswal24 wants to merge 2 commits into
Conversation
added 2 commits
August 6, 2026 06:30
Turns the inert "Refresh this wiki" button into a Customize control: a reader
states how they want a page written — a free-text instruction and/or a section
structure — and the page is regenerated to match. This is the "human prior
injection" space discussed for the demo.
It is a presentation layer, not a change to the grounded generation pipeline.
The page already exposes rendered markdown; Customizer rewrites that markdown in
one LLM pass, instructed to preserve every citation marker and add no facts. It
never touches the plan/quality-guarded generator, and is fail-soft: any error
returns the default markdown unchanged. A customized page is labeled a reader
lens, never presented as re-grounded.
Priors are ephemeral and global, held in RAM (CustomizationStore), never
persisted: the durable wiki stays authoritative and customizations vanish on
restart. Two scopes cascade most-specific-wins — a whole-wiki house style plus
per-page overrides. Cleanup is lazy on access (idle TTL + LRU cap), so the
single-process demo needs no scheduler. The store sits behind a narrow
interface so a shared backend (only needed for multi-worker serving) is a
one-file swap.
API: POST /api/repos/{id}/customize sets a prior and, for page scope, returns
the transformed markdown; DELETE clears it; GET wiki/{page_id} applies any
active prior and flags `customized`. Whole-wiki priors apply lazily on view.
Frontend: a Customize panel (scope, instruction, optional structure, Apply,
Reset), gated off in the static export where there is no backend.
Tests: store cascade/override/memoize/TTL/LRU/drop; customizer transform,
no-op, fail-soft, fence-strip, citation-preserving prompt; endpoint round-trip,
reset, clear, lazy whole-wiki. 186 web tests pass; tsc clean; pre-commit clean.
fishmingyu
marked this pull request as draft
August 7, 2026 19:47
Member
|
Returning this feature to Draft pending an explicit isolation/security decision. The current POST/DELETE customization API is unauthenticated and writes a process-global store, so any reader can change or clear the lens seen by every other reader. The transformed page also is not re-run through grounding guards. Require at least per-session/visitor isolation or administrator authorization, cross-user/concurrency regressions, and a deliberate grounding policy before this can re-enter the merge queue. |
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.
Summary
Turns the inert "Refresh this wiki" button into a Customize control: a reader
states how they want a page written — a free-text instruction and/or a section
structure — and the page is regenerated to match. This is the "human prior
injection" space discussed for the demo (Zhongming: "leave space for human prior
injection"): the grounded wiki stays authoritative, and the reader gets to layer
their own intuition on top.
Key design choice: this is a presentation layer, not a change to the grounded
generation pipeline (
AgentWiki,_PAGE_PROMPT_VERSION = "102", plan → page →repair → quality guards). The page already exposes rendered markdown; the
Customizerrewrites that markdown in one LLM pass, instructed to preserveevery citation marker and add no facts. It never touches the plan/quality-guarded
generator, so it can't destabilize grounding — and it's fail-soft: any error
returns the default markdown unchanged.
Changes
codenib/wiki/customizer.py(new) —Customizer.apply(markdown, instruction, structure) -> markdown. One LLM pass reusing the wiki model/creds; preservescitations, strips a stray
```markdownfence, returns the inputunchanged on empty prior or any error.
codenib/web/customization_store.py(new) — global, in-RAM prior store.Two scopes (
wiki,page) cascade most-specific-wins;resolve(page_id)merges them. Memoizes transformed markdown per
(source, prior). Lazy cleanupon access: idle-TTL (30 min) + LRU cap (64) — no background thread, so the
single-process deploy needs no scheduler. Narrow interface so a shared backend
(only needed for multi-worker serving) is a one-file swap.
codenib/web/app.py—POST /api/repos/{id}/customize(set/return),DELETE …/customize(clear), andGET …/wiki/{page_id}applies any activeprior and sets a
customizedflag. Whole-wiki priors apply lazily on view.A single
Customizer+CustomizationStoreare created inlifespan.codenib/web/schemas.py—CustomizeRequest/CustomizeResponse.CustomizePanel.tsx(scope selector, instruction textarea,optional structure field, Apply, Reset), replacing the refresh button; gated
off in the static export (
customizationAvailable()), which has no backend.WikiPage.customized+customizeWiki/resetCustomizationinlib/api.ts.Design doc:
.claude/design/wiki-customization-design.md.Behavior
wiki is authoritative; customizations vanish on restart (and after idle-TTL).
instruction appends after the wiki one, a page structure replaces the wiki one.
told to preserve citations and add no facts, but it is not re-run through
the grounding guards, so it is never presented as re-grounded.
Type of Change
Testing
pytest test/web/— 186 passed. Newtest/web/test_customization.pycoversthe store (cascade / override / memoize / TTL / LRU / drop / unknown-scope), the
customizer (transform / no-op-without-LLM-call / fail-soft / fence-strip /
citation-preserving prompt / bounds), and the endpoints (page round-trip, reset
restores default, empty clears, whole-wiki applies lazily on view).
test/web/test_app_runtime.pyupdated for the newcustomizedflag.tsc --noEmitclean; black, isort, flake8, and the CodeNib namespace check pass.Out of scope (follow-ups): section-level scope + selection UI; per-visitor
isolation (session token — the store key already has room); a shared/Redis store
for multi-worker serving.
Checklist