[{"data":1,"prerenderedAt":939},["ShallowReactive",2],{"navigation_docs":3,"-docs-architecture-github-comment-rendering":158,"-docs-architecture-github-comment-rendering-surround":934},[4,15,74,98,113],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":6},"Getting Started",false,"\u002Fdocs\u002Fgetting-started","docs\u002F1.getting-started",[10],{"title":11,"path":12,"stem":13,"icon":14},"Zeeq Introduction","\u002Fdocs\u002Fgetting-started\u002Fintroduction","docs\u002F1.getting-started\u002F1.introduction","i-lucide-house",{"title":16,"path":17,"stem":18,"children":19,"page":6},"Key Features","\u002Fdocs\u002Fkey-features","docs\u002F3.key-features",[20,25,30,35,40,45,50,55,59,64,69],{"title":21,"path":22,"stem":23,"icon":24},"Membership Invitations","\u002Fdocs\u002Fkey-features\u002Fmembership-invitations","docs\u002F3.key-features\u002F1.membership-invitations","i-hugeicons-cube",{"title":26,"path":27,"stem":28,"icon":29},"Command Palette","\u002Fdocs\u002Fkey-features\u002Fcommand-palette","docs\u002F3.key-features\u002F10.command-palette","i-hugeicons-search-01",{"title":31,"path":32,"stem":33,"icon":34},"Library Import and Export","\u002Fdocs\u002Fkey-features\u002Flibrary-import-export","docs\u002F3.key-features\u002F11.library-import-export","i-lucide-package-open",{"title":36,"path":37,"stem":38,"icon":39},"LLM Settings Configuration","\u002Fdocs\u002Fkey-features\u002Fllm-settings-configuration","docs\u002F3.key-features\u002F2.llm-settings-configuration","i-hugeicons-ai-magic",{"title":41,"path":42,"stem":43,"icon":44},"Agent Code Review Findings","\u002Fdocs\u002Fkey-features\u002Fagent-code-review-findings","docs\u002F3.key-features\u002F3.agent-code-review-findings","i-lucide-list-checks",{"title":46,"path":47,"stem":48,"icon":49},"Credentials & API Tokens","\u002Fdocs\u002Fkey-features\u002Fcredentials","docs\u002F3.key-features\u002F4.credentials","i-hugeicons-key-01",{"title":51,"path":52,"stem":53,"icon":54},"Manual Document Libraries","\u002Fdocs\u002Fkey-features\u002Fmanual-document-libraries","docs\u002F3.key-features\u002F5.manual-document-libraries","i-lucide-library-big",{"title":56,"path":57,"stem":58,"icon":29},"Snippet Search","\u002Fdocs\u002Fkey-features\u002Fsnippet-search","docs\u002F3.key-features\u002F6.snippet-search",{"title":60,"path":61,"stem":62,"icon":63},"Shared Prompt Fragment","\u002Fdocs\u002Fkey-features\u002Fshared-prompt-fragment","docs\u002F3.key-features\u002F7.shared-prompt-fragment","i-lucide-notebook-pen",{"title":65,"path":66,"stem":67,"icon":68},"Code Review Sources & Telemetry","\u002Fdocs\u002Fkey-features\u002Fcode-review-sources","docs\u002F3.key-features\u002F8.code-review-sources","i-hugeicons-book-01",{"title":70,"path":71,"stem":72,"icon":73},"Excluding Documents from Code Reviews","\u002Fdocs\u002Fkey-features\u002Fcode-review-document-exclusion","docs\u002F3.key-features\u002F9.code-review-document-exclusion","i-lucide-eye-off",{"title":75,"path":76,"stem":77,"children":78,"page":6},"Runtime Configuration","\u002Fdocs\u002Fconfiguration","docs\u002F5.configuration",[79,84,89,93],{"title":80,"path":81,"stem":82,"icon":83},"Google Cloud Configuration","\u002Fdocs\u002Fconfiguration\u002Fgcp-runtime","docs\u002F5.configuration\u002F1.gcp-runtime","i-hugeicons-google",{"title":85,"path":86,"stem":87,"icon":88},"GitHub Configuration","\u002Fdocs\u002Fconfiguration\u002Fgithub-configuration","docs\u002F5.configuration\u002F2.github-configuration","i-hugeicons-github",{"title":90,"path":91,"stem":92},"Local OpenIddict Certificates","\u002Fdocs\u002Fconfiguration\u002Flocal-openiddict-certificates","docs\u002F5.configuration\u002F3.local-openiddict-certificates",{"title":94,"path":95,"stem":96,"icon":97},"System Admin Access","\u002Fdocs\u002Fconfiguration\u002Fsystem-admin-access","docs\u002F5.configuration\u002F4.system-admin-access","i-hugeicons-shield-01",{"title":99,"path":100,"stem":101,"children":102,"page":6},"Metrics","\u002Fdocs\u002Fmetrics","docs\u002F6.metrics",[103,108],{"title":104,"path":105,"stem":106,"icon":107},"Metrics Dashboard","\u002Fdocs\u002Fmetrics\u002Fmetrics-dashboard","docs\u002F6.metrics\u002F1.metrics-dashboard","i-hugeicons-analytics-01",{"title":109,"path":110,"stem":111,"icon":112},"Metrics Pipeline","\u002Fdocs\u002Fmetrics\u002Fmetrics-pipeline","docs\u002F6.metrics\u002F2.metrics-pipeline","i-hugeicons-database-02",{"title":114,"path":115,"stem":116,"children":117,"page":6},"Design and Architecture","\u002Fdocs\u002Farchitecture","docs\u002F9.architecture",[118,123,128,133,137,141,145,150,154],{"title":119,"path":120,"stem":121,"icon":122},"Caching","\u002Fdocs\u002Farchitecture\u002Fcaching","docs\u002F9.architecture\u002F1.caching","i-lucide-database",{"title":124,"path":125,"stem":126,"icon":127},"Messaging and Queueing","\u002Fdocs\u002Farchitecture\u002Fmessaging-and-queueing","docs\u002F9.architecture\u002F2.messaging-and-queueing","i-lucide-message-square",{"title":129,"path":130,"stem":131,"icon":132},"GitHub Comment Rendering","\u002Fdocs\u002Farchitecture\u002Fgithub-comment-rendering","docs\u002F9.architecture\u002F3.github-comment-rendering","i-lucide-github",{"title":134,"path":135,"stem":136},"GitHub Integration","\u002Fdocs\u002Farchitecture\u002Fgithub-integration","docs\u002F9.architecture\u002F4.github-integration",{"title":138,"path":139,"stem":140},"LLM Settings and Secret Storage","\u002Fdocs\u002Farchitecture\u002Fllm-settings-and-secret-storage","docs\u002F9.architecture\u002F5.llm-settings-and-secret-storage",{"title":142,"path":143,"stem":144},"Organization Activation and Routes","\u002Fdocs\u002Farchitecture\u002Forganization-activation-and-routes","docs\u002F9.architecture\u002F6.organization-activation-and-routes",{"title":146,"path":147,"stem":148,"icon":149},"MCP Uploaded-Diff Code Reviews","\u002Fdocs\u002Farchitecture\u002Fmcp-uploaded-diff-code-reviews","docs\u002F9.architecture\u002F7.mcp-uploaded-diff-code-reviews","i-lucide-file-search",{"title":151,"path":152,"stem":153},"Repository Content Ingest","\u002Fdocs\u002Farchitecture\u002Frepository-content-ingest","docs\u002F9.architecture\u002F8.repository-content-ingest",{"title":155,"path":156,"stem":157},"Telemetry Ingest","\u002Fdocs\u002Farchitecture\u002Ftelemetry-ingest","docs\u002F9.architecture\u002F9.telemetry-ingest",{"id":159,"title":129,"body":160,"description":927,"extension":928,"links":929,"meta":930,"navigation":931,"path":130,"seo":932,"stem":131,"__hash__":933},"docs\u002Fdocs\u002F9.architecture\u002F3.github-comment-rendering.md",{"type":161,"value":162,"toc":911},"minimark",[163,168,177,180,183,193,196,200,203,206,209,215,219,338,342,345,348,406,411,414,418,421,424,451,454,499,502,506,509,512,515,519,522,548,551,554,558,561,567,570,576,585,592,596,599,605,608,614,617,621,624,654,669,672,679,683,686,724,727,731,736,816,822,826,829,848,851,855,858,904,907],[164,165,167],"h2",{"id":166},"summary","Summary",[169,170,171,172,176],"p",{},"Zeeq renders GitHub comments from lightweight queue signals. A producer does not send Markdown and does not store a rendered document in Zeeq. Instead, it publishes a ",[173,174,175],"code",{},"GitHubCommentWriteRequested"," message with a logical target, a render kind, optional sections to clear, and an optional reference to an authoritative code-review record.",[169,178,179],{},"The writer then reads the current GitHub comment body, parses Zeeq markers into a small document object model, applies the requested section updates, and writes the full comment body back to GitHub.",[169,181,182],{},"The important rule is:",[184,185,191],"pre",{"className":186,"code":188,"language":189,"meta":190},[187],"language-text","The live GitHub comment body is the rendered document state.\n","text","",[173,192,188],{"__ignoreMap":190},[169,194,195],{},"Zeeq stores only the durable pointers and coordination rows needed to find and safely update that comment.",[164,197,199],{"id":198},"why-the-comment-body-is-the-document-state","Why the comment body is the document state",[169,201,202],{},"Earlier designs stored a desired-state row in Postgres and used queued messages as wake-up signals for that row. The current design removes that table. This avoids keeping a second rendered-document copy in sync with GitHub and lets the GitHub comment itself remain the source of the published artifact.",[169,204,205],{},"This matters because Zeeq comments are updated over time. A pull request can receive an immediate queued acknowledgement first, then later receive completed review sections, evidence, links, and follow-up actions. Each pass should preserve content it does not own.",[169,207,208],{},"The render loop is therefore:",[184,210,213],{"className":211,"code":212,"language":189,"meta":190},[187],"Queue signal\n  -> acquire target lease\n  -> resolve existing GitHub comment\n  -> parse Zeeq marker DOM from the current body\n  -> clear explicitly named sections\n  -> render sections for the signal kind\n  -> preserve untouched sections\n  -> write the full marked body back to GitHub\n  -> persist or repair the target anchor\n",[173,214,212],{"__ignoreMap":190},[164,216,218],{"id":217},"key-pieces","Key pieces",[220,221,222,235],"table",{},[223,224,225],"thead",{},[226,227,228,232],"tr",{},[229,230,231],"th",{},"Piece",[229,233,234],{},"Purpose",[236,237,238,248,258,268,278,288,298,308,318,328],"tbody",{},[226,239,240,245],{},[241,242,243],"td",{},[173,244,175],{},[241,246,247],{},"Lightweight queue signal for one render\u002Fwrite pass.",[226,249,250,255],{},[241,251,252],{},[173,253,254],{},"GitHubCommentTargetSelector",[241,256,257],{},"Stable logical identity for one owned GitHub comment target.",[226,259,260,265],{},[241,261,262],{},[173,263,264],{},"GitHubCommentAnchor",[241,266,267],{},"Durable pointer from a target selector to a GitHub comment ID.",[226,269,270,275],{},[241,271,272],{},[173,273,274],{},"GitHubCommentLease",[241,276,277],{},"Short-lived write lease for a target.",[226,279,280,285],{},[241,281,282],{},[173,283,284],{},"GitHubCommentDomParser",[241,286,287],{},"Parses the live GitHub comment body into one-level Zeeq sections.",[226,289,290,295],{},[241,291,292],{},[173,293,294],{},"GitHubCommentDomRenderer",[241,296,297],{},"Applies clears and section patches, then renders the full body.",[226,299,300,305],{},[241,301,302],{},[173,303,304],{},"IGitHubCommentSectionRenderer",[241,306,307],{},"Feature-specific section renderer for one or more render kinds.",[226,309,310,315],{},[241,311,312],{},[173,313,314],{},"GitHubCommentResolver",[241,316,317],{},"Finds the existing GitHub comment by anchor or marker scan.",[226,319,320,325],{},[241,321,322],{},[173,323,324],{},"GitHubCommentWriter",[241,326,327],{},"Updates an existing GitHub comment or creates the first one.",[226,329,330,335],{},[241,331,332],{},[173,333,334],{},"CodeReviewRuntimeDigest",[241,336,337],{},"Process-local T-Digest that tracks completed review runtimes for footer percentiles.",[164,339,341],{"id":340},"targets-and-anchors","Targets and anchors",[169,343,344],{},"A target selector names the logical comment Zeeq owns. The selector is also the basis for the lease key and anchor key.",[169,346,347],{},"Examples:",[220,349,350,363],{},[223,351,352],{},[226,353,354,357,360],{},[229,355,356],{},"Target kind",[229,358,359],{},"Scope key",[229,361,362],{},"Meaning",[236,364,365,380,393],{},[226,366,367,372,377],{},[241,368,369],{},[173,370,371],{},"PullRequestSummary",[241,373,374],{},[173,375,376],{},"root",[241,378,379],{},"The main top-level Zeeq PR issue comment.",[226,381,382,387,390],{},[241,383,384],{},[173,385,386],{},"ReviewThread",[241,388,389],{},"Stable review-thread key",[241,391,392],{},"A Zeeq-owned comment in a code-review thread.",[226,394,395,400,403],{},[241,396,397],{},[173,398,399],{},"StandaloneIssueComment",[241,401,402],{},"Message family key",[241,404,405],{},"A separate Zeeq issue comment outside the PR summary.",[169,407,408,410],{},[173,409,264],{}," stores the resolved GitHub comment ID for the target. This keeps the common path cheap: if the anchor is present and valid, Zeeq can fetch or update the known GitHub comment directly.",[169,412,413],{},"The anchor is a repairable lookup cache, not the document state. If the anchor is missing or stale, the resolver scans the pull request comments for the matching Zeeq root marker. When the scan finds the comment, the handler repairs the anchor before continuing.",[164,415,417],{"id":416},"marker-dom","Marker DOM",[169,419,420],{},"Zeeq wraps owned comments in HTML comments. These comments are invisible in GitHub's rendered UI but stable in the Markdown source.",[169,422,423],{},"The root marker identifies the logical target:",[184,425,429],{"className":426,"code":427,"language":428,"meta":190,"style":190},"language-markdown shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u003C!-- (000000):zeeq:pr-comment-root:start -->\n...\n\u003C!-- zeeq:pr-comment-root:end -->\n","markdown",[173,430,431,439,445],{"__ignoreMap":190},[432,433,436],"span",{"class":434,"line":435},"line",1,[432,437,438],{},"\u003C!-- (000000):zeeq:pr-comment-root:start -->\n",[432,440,442],{"class":434,"line":441},2,[432,443,444],{},"...\n",[432,446,448],{"class":434,"line":447},3,[432,449,450],{},"\u003C!-- zeeq:pr-comment-root:end -->\n",[169,452,453],{},"Child sections identify replaceable regions:",[184,455,457],{"className":426,"code":456,"language":428,"meta":190,"style":190},"\u003C!-- (200000):zeeq:pr-comment-header:start -->\nReview queued\n\u003C!-- zeeq:pr-comment-header:end -->\n\n\u003C!-- (500000):zeeq:pr-findings:start -->\nNo findings yet.\n\u003C!-- zeeq:pr-findings:end -->\n",[173,458,459,464,469,474,481,487,493],{"__ignoreMap":190},[432,460,461],{"class":434,"line":435},[432,462,463],{},"\u003C!-- (200000):zeeq:pr-comment-header:start -->\n",[432,465,466],{"class":434,"line":441},[432,467,468],{},"Review queued\n",[432,470,471],{"class":434,"line":447},[432,472,473],{},"\u003C!-- zeeq:pr-comment-header:end -->\n",[432,475,477],{"class":434,"line":476},4,[432,478,480],{"emptyLinePlaceholder":479},true,"\n",[432,482,484],{"class":434,"line":483},5,[432,485,486],{},"\u003C!-- (500000):zeeq:pr-findings:start -->\n",[432,488,490],{"class":434,"line":489},6,[432,491,492],{},"No findings yet.\n",[432,494,496],{"class":434,"line":495},7,[432,497,498],{},"\u003C!-- zeeq:pr-findings:end -->\n",[169,500,501],{},"The value in parentheses is the order key. Sections are rendered in lexical order by that key, not by renderer registration order. Reserved anchors keep the root\u002Fheader near the top and the footer near the bottom, while leaving space to insert new sections later.",[164,503,505],{"id":504},"one-level-rule","One-level rule",[169,507,508],{},"The DOM supports one root and one level of direct child sections.",[169,510,511],{},"This is intentional. GitHub comments are Markdown strings, not a full structured document store. A one-level DOM keeps the parser predictable and keeps ownership simple: a renderer may replace one named section, and every other section remains untouched.",[169,513,514],{},"Different Zeeq-looking marker text inside a section is treated as raw Markdown owned by that section. A nested start marker for the same section is considered malformed and is ignored for that section, because there is no safe way to infer which end marker the writer intended to own.",[164,516,518],{"id":517},"preserving-existing-state","Preserving existing state",[169,520,521],{},"Renderers do not rebuild the whole comment from scratch. The handler parses the live comment body first, then the renderer applies explicit changes:",[523,524,525,533,539,542,545],"ol",{},[526,527,528,529,532],"li",{},"Remove sections named by ",[173,530,531],{},"GitHubCommentWriteRequested.Clear",".",[526,534,535,536,538],{},"Run registered ",[173,537,304],{}," instances for the message kind.",[526,540,541],{},"Apply returned patches.",[526,543,544],{},"Keep all unpatched sections as they appeared in the parsed DOM.",[526,546,547],{},"Sort by order key and write the full body back.",[169,549,550],{},"This is why later events can safely accumulate state. For example, an immediate queued message can write the header, status, and footer. A completed review message can later replace findings and evidence while preserving unrelated sections already present in the comment.",[169,552,553],{},"Closed or merged pull request webhooks do not publish a replacement status comment. They update the durable pull request state and gate new review creation, but leave the last rendered review findings in place.",[164,555,557],{"id":556},"runtime-percentile-footer","Runtime percentile footer",[169,559,560],{},"The pull request footer includes process-local runtime percentiles for completed code-review executions:",[184,562,565],{"className":563,"code":564,"language":189,"meta":190},[187],"50th percentile runtime: 01:23; 95th: 04:56\n",[173,566,564],{"__ignoreMap":190},[169,568,569],{},"If the application process has not recorded any review runtimes yet, the footer renders:",[184,571,574],{"className":572,"code":573,"language":189,"meta":190},[187],"50th percentile runtime: (no data); 95th: (no data)\n",[173,575,573],{"__ignoreMap":190},[169,577,578,580,581,584],{},[173,579,334],{}," is registered as a singleton. ",[173,582,583],{},"CodeReviewRunRequestedHandler"," records one runtime observation after review execution starts and finishes, including failed executions that reach the runner. Capacity deferrals and terminal no-ops are not runtime samples.",[169,586,587,588,591],{},"T-Digest updates take a short write lock because ",[173,589,590],{},"TDigest.Add"," is not thread-safe. Each write publishes an immutable percentile snapshot, and footer rendering reads that snapshot with volatile semantics instead of locking on the digest. This keeps comment rendering cheap and non-blocking at the cost of reading the last published snapshot rather than the mutable digest directly. This data is intentionally not durable: it resets when the web or worker process restarts and should be treated as live operational context, not a billing or audit record.",[164,593,595],{"id":594},"leases","Leases",[169,597,598],{},"GitHub writes for the same target must be serialized. Without serialization, two queue consumers could read the same old comment body, render different changes, and have the later write overwrite the earlier one.",[169,600,601,602,604],{},"Zeeq uses ",[173,603,274],{}," rows to serialize a target. The table is unlogged because lease rows are transient coordination state. Losing all leases after an unclean Postgres shutdown is acceptable: the next worker can reacquire the target and re-read the current GitHub comment body.",[169,606,607],{},"Lease acquire is protected by a transaction-scoped Postgres advisory lock. The advisory lock exists only for the short acquire transaction:",[184,609,612],{"className":610,"code":611,"language":189,"meta":190},[187],"begin transaction\n  -> take transaction advisory lock for target\n  -> check existing lease row\n  -> insert or take over expired lease\ncommit transaction\n",[173,613,611],{"__ignoreMap":190},[169,615,616],{},"The handler does not hold a database transaction, database connection, or advisory lock while calling GitHub. This keeps the design compatible with PgBouncer transaction pooling and avoids tying up database connections during external network calls.",[164,618,620],{"id":619},"renewal-and-cancellation","Renewal and cancellation",[169,622,623],{},"The comment write handler runs two tasks inside the lease window:",[220,625,626,636],{},[223,627,628],{},[226,629,630,633],{},[229,631,632],{},"Task",[229,634,635],{},"Role",[236,637,638,646],{},[226,639,640,643],{},[241,641,642],{},"Work task",[241,644,645],{},"Resolves, parses, renders, writes to GitHub, and updates the anchor.",[226,647,648,651],{},[241,649,650],{},"Renewal task",[241,652,653],{},"Sleeps for half the lease duration, then extends the lease expiry.",[169,655,656,657,660,661,664,665,668],{},"Renewal uses a separate ",[173,658,659],{},"DbContext"," created by ",[173,662,663],{},"IDbContextFactory\u003CPostgresDbContext>",". That is required because the work task uses scoped stores backed by the message scope's ",[173,666,667],{},"PostgresDbContext",", and EF Core contexts are not thread-safe.",[169,670,671],{},"If renewal fails, the renewal task cancels the work token and the handler fails. This prevents a worker from continuing toward a GitHub write after it has lost the target lease. The queue can retry the message later.",[169,673,674,675,678],{},"The lease is released in ",[173,676,677],{},"finally"," with owner checking. Release ignores caller cancellation so cleanup can still run after a timeout or shutdown signal. A stale worker cannot delete a newer worker's lease because release requires the same worker ID that acquired the row.",[164,680,682],{"id":681},"crash-recovery","Crash recovery",[169,684,685],{},"There are three important crash cases:",[220,687,688,698],{},[223,689,690],{},[226,691,692,695],{},[229,693,694],{},"Case",[229,696,697],{},"Recovery behavior",[236,699,700,708,716],{},[226,701,702,705],{},[241,703,704],{},"Worker crashes before writing GitHub",[241,706,707],{},"Lease renewal stops; the lease expires; a retry can acquire and render from the current GitHub body.",[226,709,710,713],{},[241,711,712],{},"Worker writes GitHub but crashes before anchor update",[241,714,715],{},"Later work scans for the target root marker, finds the comment, and repairs the anchor.",[226,717,718,721],{},[241,719,720],{},"Postgres restarts uncleanly",[241,722,723],{},"The unlogged lease table is cleared; the next worker can acquire and re-read GitHub.",[169,725,726],{},"The durable pieces are the GitHub comment body and the anchor row. The lease row is deliberately disposable.",[164,728,730],{"id":729},"message-shape","Message shape",[169,732,733,735],{},[173,734,175],{}," is intentionally small:",[220,737,738,747],{},[223,739,740],{},[226,741,742,745],{},[229,743,744],{},"Field",[229,746,234],{},[236,748,749,763,773,783,793,803],{},[226,750,751,760],{},[241,752,753,756,757],{},[173,754,755],{},"OrganizationId"," and ",[173,758,759],{},"TeamId",[241,761,762],{},"Tenant routing and authorization context.",[226,764,765,770],{},[241,766,767],{},[173,768,769],{},"OwnerQualifiedRepoName",[241,771,772],{},"GitHub repository name used by the resolver and writer.",[226,774,775,780],{},[241,776,777],{},[173,778,779],{},"Target",[241,781,782],{},"Logical comment identity.",[226,784,785,790],{},[241,786,787],{},[173,788,789],{},"Kind",[241,791,792],{},"Tells section renderers which update is being requested.",[226,794,795,800],{},[241,796,797],{},[173,798,799],{},"Clear",[241,801,802],{},"Named sections to remove before rendering new patches.",[226,804,805,813],{},[241,806,807,756,810],{},[173,808,809],{},"CodeReviewRecordId",[173,811,812],{},"CodeReviewCreatedAtUtc",[241,814,815],{},"Optional reference to the authoritative review row.",[169,817,818,819,532],{},"The message does not carry rendered Markdown, JSON payload sections, or desired-state versions. If a renderer needs completed review content, the handler loads the referenced ",[173,820,821],{},"CodeReviewRecord",[164,823,825],{"id":824},"adding-a-new-section","Adding a new section",[169,827,828],{},"To add a new section:",[523,830,831,837,840,845],{},[526,832,833,834,532],{},"Add a stable marker name to ",[173,835,836],{},"GitHubCommentMarkers",[526,838,839],{},"Add a default order key, or ensure the patch provides one.",[526,841,842,843,532],{},"Implement ",[173,844,304],{},[526,846,847],{},"Add tests that prove the new renderer replaces only its own section and preserves unrelated sections.",[169,849,850],{},"Do not renumber existing sections unless there is a clear reason. The order-key space should leave room for new sections between existing anchors.",[164,852,854],{"id":853},"testing-strategy","Testing strategy",[169,856,857],{},"The design is intentionally testable without excessive mocking:",[220,859,860,870],{},[223,861,862],{},[226,863,864,867],{},[229,865,866],{},"Layer",[229,868,869],{},"Test style",[236,871,872,880,888,896],{},[226,873,874,877],{},[241,875,876],{},"Parser and renderer",[241,878,879],{},"Pure unit tests over strings.",[226,881,882,885],{},[241,883,884],{},"Lease and anchor stores",[241,886,887],{},"Postgres integration tests with Testcontainers.",[226,889,890,893],{},[241,891,892],{},"Resolver and writer",[241,894,895],{},"Fake GitHub client tests.",[226,897,898,901],{},[241,899,900],{},"Queue handler",[241,902,903],{},"Focused tests using fake stores, fake writer, and controlled lease timing.",[169,905,906],{},"The core rendering behavior should be proven without GitHub or Postgres. The storage and integration seams then get narrower tests against the real systems they wrap.",[908,909,910],"style",{},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":190,"searchDepth":441,"depth":441,"links":912},[913,914,915,916,917,918,919,920,921,922,923,924,925,926],{"id":166,"depth":441,"text":167},{"id":198,"depth":441,"text":199},{"id":217,"depth":441,"text":218},{"id":340,"depth":441,"text":341},{"id":416,"depth":441,"text":417},{"id":504,"depth":441,"text":505},{"id":517,"depth":441,"text":518},{"id":556,"depth":441,"text":557},{"id":594,"depth":441,"text":595},{"id":619,"depth":441,"text":620},{"id":681,"depth":441,"text":682},{"id":729,"depth":441,"text":730},{"id":824,"depth":441,"text":825},{"id":853,"depth":441,"text":854},"How Zeeq renders and updates owned GitHub comments.","md",null,{},{"icon":132},{"title":129,"description":927},"Hbx2BuEuCOk-llRbsKwUx8lHzOSUsZbeIu7k--51LzY",[935,937],{"title":124,"path":125,"stem":126,"description":936,"icon":127,"children":-1},"Overview of messaging and queueing systems in the architecture.",{"title":134,"path":135,"stem":136,"description":938,"children":-1},"How Zeeq links a GitHub App installation and registers repositories for webhook work.",1784297365800]