@zigrivers/scaffold 3.32.0 → 3.33.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (128) hide show
  1. package/README.md +42 -19
  2. package/content/guides/knowledge-freshness/.diagrams/diagram-0.svg +1 -1
  3. package/content/guides/knowledge-freshness/.diagrams/manifest.json +1 -1
  4. package/content/guides/knowledge-freshness/index.html +9 -5
  5. package/content/guides/knowledge-freshness/index.md +5 -4
  6. package/content/guides/multi-agent/index.html +16 -15
  7. package/content/guides/multi-agent/index.md +16 -15
  8. package/content/guides/pipeline/index.html +2 -2
  9. package/content/guides/pipeline/index.md +2 -2
  10. package/content/knowledge/execution/worktree-management.md +4 -4
  11. package/content/knowledge/mcp-server/mcp-authentication.md +100 -0
  12. package/content/knowledge/mcp-server/mcp-deployment-patterns.md +119 -0
  13. package/content/knowledge/mcp-server/mcp-error-handling.md +131 -0
  14. package/content/knowledge/mcp-server/mcp-observability.md +125 -0
  15. package/content/knowledge/mcp-server/mcp-prompt-primitives.md +119 -0
  16. package/content/knowledge/mcp-server/mcp-protocol-fundamentals.md +130 -0
  17. package/content/knowledge/mcp-server/mcp-resource-design.md +111 -0
  18. package/content/knowledge/mcp-server/mcp-sdk-selection.md +136 -0
  19. package/content/knowledge/mcp-server/mcp-testing-strategies.md +127 -0
  20. package/content/knowledge/mcp-server/mcp-tool-design.md +125 -0
  21. package/content/knowledge/mcp-server/mcp-transport-patterns.md +122 -0
  22. package/content/knowledge/mcp-server/mcp-versioning.md +115 -0
  23. package/content/methodology/custom-defaults.yml +2 -0
  24. package/content/methodology/deep.yml +2 -0
  25. package/content/methodology/mcp-server-overlay.yml +88 -0
  26. package/content/methodology/mvp.yml +2 -0
  27. package/content/pipeline/build/multi-agent-resume.md +107 -11
  28. package/content/pipeline/build/multi-agent-start.md +104 -11
  29. package/content/pipeline/build/single-agent-resume.md +74 -8
  30. package/content/pipeline/build/single-agent-start.md +69 -12
  31. package/content/pipeline/environment/git-workflow.md +8 -2
  32. package/content/pipeline/finalization/materialize-plan-to-beads.md +473 -0
  33. package/content/pipeline/foundation/beads.md +6 -0
  34. package/content/pipeline/planning/implementation-plan-review.md +25 -0
  35. package/content/pipeline/planning/implementation-plan.md +75 -1
  36. package/content/pipeline/specification/mcp-tool-resource-contract.md +77 -0
  37. package/dist/cli/commands/adopt.d.ts.map +1 -1
  38. package/dist/cli/commands/adopt.js +33 -1
  39. package/dist/cli/commands/adopt.js.map +1 -1
  40. package/dist/cli/commands/init.d.ts +6 -0
  41. package/dist/cli/commands/init.d.ts.map +1 -1
  42. package/dist/cli/commands/init.js +46 -3
  43. package/dist/cli/commands/init.js.map +1 -1
  44. package/dist/cli/init-flag-families.d.ts +6 -1
  45. package/dist/cli/init-flag-families.d.ts.map +1 -1
  46. package/dist/cli/init-flag-families.js +59 -2
  47. package/dist/cli/init-flag-families.js.map +1 -1
  48. package/dist/cli/init-flag-families.test.js +86 -1
  49. package/dist/cli/init-flag-families.test.js.map +1 -1
  50. package/dist/config/schema.d.ts +2310 -126
  51. package/dist/config/schema.d.ts.map +1 -1
  52. package/dist/config/schema.js +26 -1
  53. package/dist/config/schema.js.map +1 -1
  54. package/dist/config/schema.test.js +75 -2
  55. package/dist/config/schema.test.js.map +1 -1
  56. package/dist/config/validators/index.d.ts.map +1 -1
  57. package/dist/config/validators/index.js +2 -0
  58. package/dist/config/validators/index.js.map +1 -1
  59. package/dist/config/validators/mcp-server.d.ts +4 -0
  60. package/dist/config/validators/mcp-server.d.ts.map +1 -0
  61. package/dist/config/validators/mcp-server.js +37 -0
  62. package/dist/config/validators/mcp-server.js.map +1 -0
  63. package/dist/config/validators/mcp-server.test.d.ts +2 -0
  64. package/dist/config/validators/mcp-server.test.d.ts.map +1 -0
  65. package/dist/config/validators/mcp-server.test.js +47 -0
  66. package/dist/config/validators/mcp-server.test.js.map +1 -0
  67. package/dist/core/assembly/materialize-plan-to-beads-assembly.test.d.ts +2 -0
  68. package/dist/core/assembly/materialize-plan-to-beads-assembly.test.d.ts.map +1 -0
  69. package/dist/core/assembly/materialize-plan-to-beads-assembly.test.js +75 -0
  70. package/dist/core/assembly/materialize-plan-to-beads-assembly.test.js.map +1 -0
  71. package/dist/e2e/project-type-overlays.test.js +83 -0
  72. package/dist/e2e/project-type-overlays.test.js.map +1 -1
  73. package/dist/project/adopt.d.ts.map +1 -1
  74. package/dist/project/adopt.js +3 -1
  75. package/dist/project/adopt.js.map +1 -1
  76. package/dist/project/detectors/coverage.test.js +1 -0
  77. package/dist/project/detectors/coverage.test.js.map +1 -1
  78. package/dist/project/detectors/disambiguate.d.ts.map +1 -1
  79. package/dist/project/detectors/disambiguate.js +6 -1
  80. package/dist/project/detectors/disambiguate.js.map +1 -1
  81. package/dist/project/detectors/disambiguate.test.js +18 -0
  82. package/dist/project/detectors/disambiguate.test.js.map +1 -1
  83. package/dist/project/detectors/index.d.ts.map +1 -1
  84. package/dist/project/detectors/index.js +2 -1
  85. package/dist/project/detectors/index.js.map +1 -1
  86. package/dist/project/detectors/mcp-server.d.ts +4 -0
  87. package/dist/project/detectors/mcp-server.d.ts.map +1 -0
  88. package/dist/project/detectors/mcp-server.js +91 -0
  89. package/dist/project/detectors/mcp-server.js.map +1 -0
  90. package/dist/project/detectors/mcp-server.test.d.ts +2 -0
  91. package/dist/project/detectors/mcp-server.test.d.ts.map +1 -0
  92. package/dist/project/detectors/mcp-server.test.js +115 -0
  93. package/dist/project/detectors/mcp-server.test.js.map +1 -0
  94. package/dist/project/detectors/types.d.ts +6 -2
  95. package/dist/project/detectors/types.d.ts.map +1 -1
  96. package/dist/project/detectors/types.js.map +1 -1
  97. package/dist/project/gitignore.d.ts.map +1 -1
  98. package/dist/project/gitignore.js +4 -0
  99. package/dist/project/gitignore.js.map +1 -1
  100. package/dist/project/gitignore.test.js +1 -0
  101. package/dist/project/gitignore.test.js.map +1 -1
  102. package/dist/types/config.d.ts +8 -1
  103. package/dist/types/config.d.ts.map +1 -1
  104. package/dist/wizard/copy/core.d.ts.map +1 -1
  105. package/dist/wizard/copy/core.js +4 -0
  106. package/dist/wizard/copy/core.js.map +1 -1
  107. package/dist/wizard/copy/index.d.ts.map +1 -1
  108. package/dist/wizard/copy/index.js +2 -0
  109. package/dist/wizard/copy/index.js.map +1 -1
  110. package/dist/wizard/copy/mcp-server.d.ts +3 -0
  111. package/dist/wizard/copy/mcp-server.d.ts.map +1 -0
  112. package/dist/wizard/copy/mcp-server.js +40 -0
  113. package/dist/wizard/copy/mcp-server.js.map +1 -0
  114. package/dist/wizard/copy/types.d.ts +5 -1
  115. package/dist/wizard/copy/types.d.ts.map +1 -1
  116. package/dist/wizard/flags.d.ts +9 -1
  117. package/dist/wizard/flags.d.ts.map +1 -1
  118. package/dist/wizard/questions.d.ts +4 -2
  119. package/dist/wizard/questions.d.ts.map +1 -1
  120. package/dist/wizard/questions.js +37 -0
  121. package/dist/wizard/questions.js.map +1 -1
  122. package/dist/wizard/questions.test.js +107 -0
  123. package/dist/wizard/questions.test.js.map +1 -1
  124. package/dist/wizard/wizard.d.ts +3 -2
  125. package/dist/wizard/wizard.d.ts.map +1 -1
  126. package/dist/wizard/wizard.js +3 -1
  127. package/dist/wizard/wizard.js.map +1 -1
  128. package/package.json +1 -1
@@ -1442,7 +1442,7 @@ yesterday's signals still aggregate tomorrow; suppression filters the <em>emit</
1442
1442
  step, not the aggregation step (<span class="fp" data-path="src/observability/checks/lens-i-knowledge-gaps.ts:155">src/observability/checks/lens-i-knowledge-gaps.ts:155</span>).
1443
1443
  Signals only fade as they age out of the 90-day window naturally.</p>
1444
1444
  <h2 id="system-map">System map</h2>
1445
- <figure class="mermaid"><svg id="my-svg" width="100%" xmlns="http://www.w3.org/2000/svg" class="flowchart" style="max-width: 951.219px; background-color: transparent;" viewBox="0 0 951.21875 940.3999633789062" role="graphics-document document">#my-svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#000000;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#my-svg .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#my-svg .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#my-svg .error-icon{fill:#552222;}#my-svg .error-text{fill:#552222;stroke:#552222;}#my-svg .edge-thickness-normal{stroke-width:1px;}#my-svg .edge-thickness-thick{stroke-width:3.5px;}#my-svg .edge-pattern-solid{stroke-dasharray:0;}#my-svg .edge-thickness-invisible{stroke-width:0;fill:none;}#my-svg .edge-pattern-dashed{stroke-dasharray:3;}#my-svg .edge-pattern-dotted{stroke-dasharray:2;}#my-svg .marker{fill:#666;stroke:#666;}#my-svg .marker.cross{stroke:#666;}#my-svg svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#my-svg p{margin:0;}#my-svg .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#000000;}#my-svg .cluster-label text{fill:#333;}#my-svg .cluster-label span{color:#333;}#my-svg .cluster-label span p{background-color:transparent;}#my-svg .label text,#my-svg span{fill:#000000;color:#000000;}#my-svg .node rect,#my-svg .node circle,#my-svg .node ellipse,#my-svg .node polygon,#my-svg .node path{fill:#eee;stroke:#999;stroke-width:1px;}#my-svg .rough-node .label text,#my-svg .node .label text,#my-svg .image-shape .label,#my-svg .icon-shape .label{text-anchor:middle;}#my-svg .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#my-svg .rough-node .label,#my-svg .node .label,#my-svg .image-shape .label,#my-svg .icon-shape .label{text-align:center;}#my-svg .node.clickable{cursor:pointer;}#my-svg .root .anchor path{fill:#666!important;stroke-width:0;stroke:#666;}#my-svg .arrowheadPath{fill:#333333;}#my-svg .edgePath .path{stroke:#666;stroke-width:1px;}#my-svg .flowchart-link{stroke:#666;fill:none;}#my-svg .edgeLabel{background-color:white;text-align:center;}#my-svg .edgeLabel p{background-color:white;}#my-svg .edgeLabel rect{opacity:0.5;background-color:white;fill:white;}#my-svg .labelBkg{background-color:rgba(255, 255, 255, 0.5);}#my-svg .cluster rect{fill:hsl(0, 0%, 98.9215686275%);stroke:#707070;stroke-width:1px;}#my-svg .cluster text{fill:#333;}#my-svg .cluster span{color:#333;}#my-svg div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(-160, 0%, 93.3333333333%);border:1px solid #707070;border-radius:2px;pointer-events:none;z-index:100;}#my-svg .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#000000;}#my-svg rect.text{fill:none;stroke-width:0;}#my-svg .icon-shape,#my-svg .image-shape{background-color:white;text-align:center;}#my-svg .icon-shape p,#my-svg .image-shape p{background-color:white;padding:2px;}#my-svg .icon-shape .label rect,#my-svg .image-shape .label rect{opacity:0.5;background-color:white;fill:white;}#my-svg .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#my-svg .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#my-svg .node .neo-node{stroke:#999;}#my-svg [data-look="neo"].node rect,#my-svg [data-look="neo"].cluster rect,#my-svg [data-look="neo"].node polygon{stroke:url(#my-svg-gradient);filter:drop-shadow( 1px 2px 2px rgba(185,185,185,1));}#my-svg [data-look="neo"].node path{stroke:url(#my-svg-gradient);stroke-width:1px;}#my-svg [data-look="neo"].node .outer-path{filter:drop-shadow( 1px 2px 2px rgba(185,185,185,1));}#my-svg [data-look="neo"].node .neo-line path{stroke:#999;filter:none;}#my-svg [data-look="neo"].node circle{stroke:url(#my-svg-gradient);filter:drop-shadow( 1px 2px 2px rgba(185,185,185,1));}#my-svg [data-look="neo"].node circle .state-start{fill:#000000;}#my-svg [data-look="neo"].icon-shape .icon{fill:url(#my-svg-gradient);filter:drop-shadow( 1px 2px 2px rgba(185,185,185,1));}#my-svg [data-look="neo"].icon-shape .icon-neo path{stroke:url(#my-svg-gradient);filter:drop-shadow( 1px 2px 2px rgba(185,185,185,1));}#my-svg :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}<g><marker id="my-svg_flowchart-v2-pointEnd" class="marker flowchart-v2" viewBox="0 0 10 10" refX="5" refY="5" markerUnits="userSpaceOnUse" markerWidth="8" markerHeight="8" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowMarkerPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker><marker id="my-svg_flowchart-v2-pointStart" class="marker flowchart-v2" viewBox="0 0 10 10" refX="4.5" refY="5" markerUnits="userSpaceOnUse" markerWidth="8" markerHeight="8" orient="auto"><path d="M 0 5 L 10 10 L 10 0 z" class="arrowMarkerPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker><marker id="my-svg_flowchart-v2-pointEnd-margin" class="marker flowchart-v2" viewBox="0 0 11.5 14" refX="11.5" refY="7" markerUnits="userSpaceOnUse" markerWidth="10.5" markerHeight="14" orient="auto"><path d="M 0 0 L 11.5 7 L 0 14 z" class="arrowMarkerPath" style="stroke-width: 0; stroke-dasharray: 1, 0;"></path></marker><marker id="my-svg_flowchart-v2-pointStart-margin" class="marker flowchart-v2" viewBox="0 0 11.5 14" refX="1" refY="7" markerUnits="userSpaceOnUse" markerWidth="11.5" markerHeight="14" orient="auto"><polygon points="0,7 11.5,14 11.5,0" class="arrowMarkerPath" style="stroke-width: 0; stroke-dasharray: 1, 0;"></polygon></marker><marker id="my-svg_flowchart-v2-circleEnd" class="marker flowchart-v2" viewBox="0 0 10 10" refX="11" refY="5" markerUnits="userSpaceOnUse" markerWidth="11" markerHeight="11" orient="auto"><circle cx="5" cy="5" r="5" class="arrowMarkerPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></circle></marker><marker id="my-svg_flowchart-v2-circleStart" class="marker flowchart-v2" viewBox="0 0 10 10" refX="-1" refY="5" markerUnits="userSpaceOnUse" markerWidth="11" markerHeight="11" orient="auto"><circle cx="5" cy="5" r="5" class="arrowMarkerPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></circle></marker><marker id="my-svg_flowchart-v2-circleEnd-margin" class="marker flowchart-v2" viewBox="0 0 10 10" refY="5" refX="12.25" markerUnits="userSpaceOnUse" markerWidth="14" markerHeight="14" orient="auto"><circle cx="5" cy="5" r="5" class="arrowMarkerPath" style="stroke-width: 0; stroke-dasharray: 1, 0;"></circle></marker><marker id="my-svg_flowchart-v2-circleStart-margin" class="marker flowchart-v2" viewBox="0 0 10 10" refX="-2" refY="5" markerUnits="userSpaceOnUse" markerWidth="14" markerHeight="14" orient="auto"><circle cx="5" cy="5" r="5" class="arrowMarkerPath" style="stroke-width: 0; stroke-dasharray: 1, 0;"></circle></marker><marker id="my-svg_flowchart-v2-crossEnd" class="marker cross flowchart-v2" viewBox="0 0 11 11" refX="12" refY="5.2" markerUnits="userSpaceOnUse" markerWidth="11" markerHeight="11" orient="auto"><path d="M 1,1 l 9,9 M 10,1 l -9,9" class="arrowMarkerPath" style="stroke-width: 2; stroke-dasharray: 1, 0;"></path></marker><marker id="my-svg_flowchart-v2-crossStart" class="marker cross flowchart-v2" viewBox="0 0 11 11" refX="-1" refY="5.2" markerUnits="userSpaceOnUse" markerWidth="11" markerHeight="11" orient="auto"><path d="M 1,1 l 9,9 M 10,1 l -9,9" class="arrowMarkerPath" style="stroke-width: 2; stroke-dasharray: 1, 0;"></path></marker><marker id="my-svg_flowchart-v2-crossEnd-margin" class="marker cross flowchart-v2" viewBox="0 0 15 15" refX="17.7" refY="7.5" markerUnits="userSpaceOnUse" markerWidth="12" markerHeight="12" orient="auto"><path d="M 1,1 L 14,14 M 1,14 L 14,1" class="arrowMarkerPath" style="stroke-width: 2.5;"></path></marker><marker id="my-svg_flowchart-v2-crossStart-margin" class="marker cross flowchart-v2" viewBox="0 0 15 15" refX="-3.5" refY="7.5" markerUnits="userSpaceOnUse" markerWidth="12" markerHeight="12" orient="auto"><path d="M 1,1 L 14,14 M 1,14 L 14,1" class="arrowMarkerPath" style="stroke-width: 2.5; stroke-dasharray: 1, 0;"></path></marker><g class="root"><g class="clusters"><g class="cluster" id="my-svg-gap"><rect style="" x="390.40625" y="8" width="552.8125" height="625.5999908447266"></rect><g class="cluster-label" transform="translate(636.375, 8)"><g><rect class="background" style="stroke: none"></rect><text y="-10.1" style=""><tspan class="text-outer-tspan row" x="0" y="-0.1em"><tspan class="text-inner-tspan">Gap</tspan><tspan class="text-inner-tspan"> arm</tspan></tspan></text></g></g></g><g class="cluster" id="my-svg-refresh"><rect style="" x="8" y="149.5999984741211" width="362.40625" height="782.7999877929688"></rect><g class="cluster-label" transform="translate(146.1015625, 149.5999984741211)"><g><rect class="background" style="stroke: none"></rect><text y="-10.1" style=""><tspan class="text-outer-tspan row" x="0" y="-0.1em"><tspan class="text-inner-tspan">Refresh</tspan><tspan class="text-inner-tspan"> arm</tspan></tspan></text></g></g></g></g><g class="edgePaths"><path d="M132.684,241.2L132.684,245.367C132.684,249.533,132.684,257.867,132.684,267C132.684,276.133,132.684,286.067,132.684,291.033L132.684,296" id="my-svg-L_CRON_PF_0" class="edge-thickness-normal edge-pattern-solid edge-thickness-normal edge-pattern-solid flowchart-link" style=";" marker-end="url(#my-svg_flowchart-v2-pointEnd)"></path><path d="M132.684,366.6L132.684,372.233C132.684,377.867,132.684,389.133,132.684,398.267C132.684,407.4,132.684,414.4,132.684,417.9L132.684,421.4" id="my-svg-L_PF_RUN_0" class="edge-thickness-normal edge-pattern-solid edge-thickness-normal edge-pattern-solid flowchart-link" style=";" marker-end="url(#my-svg_flowchart-v2-pointEnd)"></path><path d="M132.684,492L132.684,496.167C132.684,500.333,132.684,508.667,132.684,516.333C132.684,524,132.684,531,132.684,534.5L132.684,538" id="my-svg-L_RUN_APPLY_0" class="edge-thickness-normal edge-pattern-solid edge-thickness-normal edge-pattern-solid flowchart-link" style=";" marker-end="url(#my-svg_flowchart-v2-pointEnd)"></path><path d="M132.684,608.6L132.684,612.767C132.684,616.933,132.684,625.267,132.684,638.45C132.684,651.633,132.684,669.667,138.932,687.163C145.18,704.66,157.676,721.62,163.925,730.1L170.173,738.58" id="my-svg-L_APPLY_GATES_0" class="edge-thickness-normal edge-pattern-solid edge-thickness-normal edge-pattern-solid flowchart-link" style=";" marker-end="url(#my-svg_flowchart-v2-pointEnd)"></path><path d="M190.598,790.8L190.598,794.967C190.598,799.133,190.598,807.467,190.598,815.133C190.598,822.8,190.598,829.8,190.598,833.3L190.598,836.8" id="my-svg-L_GATES_MERGE_0" class="edge-thickness-normal edge-pattern-solid edge-thickness-normal edge-pattern-solid flowchart-link" style=";" marker-end="url(#my-svg_flowchart-v2-pointEnd)"></path><path d="M536.594,99.6L536.594,103.767C536.594,107.933,536.594,116.267,536.594,124.6C536.594,132.933,536.594,141.267,536.594,148.933C536.594,156.6,536.594,163.6,536.594,167.1L536.594,170.6" id="my-svg-L_TAIL_EVENT_0" class="edge-thickness-normal edge-pattern-solid edge-thickness-normal edge-pattern-solid flowchart-link" style=";" marker-end="url(#my-svg_flowchart-v2-pointEnd)"></path><path d="M536.594,241.2L536.594,245.367C536.594,249.533,536.594,257.867,536.594,267C536.594,276.133,536.594,286.067,536.594,291.033L536.594,296" id="my-svg-L_EVENT_LEDGER_0" class="edge-thickness-normal edge-pattern-solid edge-thickness-normal edge-pattern-solid flowchart-link" style=";" marker-end="url(#my-svg_flowchart-v2-pointEnd)"></path><path d="M536.594,366.6L536.594,372.233C536.594,377.867,536.594,389.133,544.883,398.65C553.172,408.168,569.751,415.935,578.04,419.819L586.329,423.703" id="my-svg-L_LEDGER_LENSI_0" class="edge-thickness-normal edge-pattern-solid edge-thickness-normal edge-pattern-solid flowchart-link" style=";" marker-end="url(#my-svg_flowchart-v2-pointEnd)"></path><path d="M661.023,492L661.023,496.167C661.023,500.333,661.023,508.667,661.023,516.333C661.023,524,661.023,531,661.023,534.5L661.023,538" id="my-svg-L_LENSI_FINDING_0" class="edge-thickness-normal edge-pattern-solid edge-thickness-normal edge-pattern-solid flowchart-link" style=";" marker-end="url(#my-svg_flowchart-v2-pointEnd)"></path><path d="M785.453,375.4L785.453,379.567C785.453,383.733,785.453,392.067,777.164,400.117C768.875,408.168,752.296,415.935,744.007,419.819L735.718,423.703" id="my-svg-L_RESOLVER_LENSI_0" class="edge-thickness-normal edge-pattern-solid edge-thickness-normal edge-pattern-solid flowchart-link" style=";" marker-end="url(#my-svg_flowchart-v2-pointEnd)"></path><path d="M661.023,608.6L661.023,612.767C661.023,616.933,661.023,625.267,592.271,638.45C523.52,651.633,386.016,669.667,311.015,687.163C236.015,704.66,223.519,721.62,217.271,730.1L211.023,738.58" id="my-svg-L_FINDING_GATES_0" class="edge-thickness-normal edge-pattern-dotted edge-thickness-normal edge-pattern-solid flowchart-link" style=";" marker-end="url(#my-svg_flowchart-v2-pointEnd)"></path></g><g class="edgeLabels"><g class="edgeLabel"><g class="label" transform="translate(0, 0)"><text y="-10.1" text-anchor="middle"><tspan class="text-outer-tspan row" x="0" y="-0.1em" text-anchor="middle"></tspan></text></g></g><g><rect class="background" style="stroke: none"></rect></g><g class="edgeLabel"><g class="label" transform="translate(0, 0)"><text y="-10.1" text-anchor="middle"><tspan class="text-outer-tspan row" x="0" y="-0.1em" text-anchor="middle"></tspan></text></g></g><g><rect class="background" style="stroke: none"></rect></g><g class="edgeLabel"><g class="label" transform="translate(0, 0)"><text y="-10.1" text-anchor="middle"><tspan class="text-outer-tspan row" x="0" y="-0.1em" text-anchor="middle"></tspan></text></g></g><g><rect class="background" style="stroke: none"></rect></g><g class="edgeLabel"><g class="label" transform="translate(0, 0)"><text y="-10.1" text-anchor="middle"><tspan class="text-outer-tspan row" x="0" y="-0.1em" text-anchor="middle"></tspan></text></g></g><g><rect class="background" style="stroke: none"></rect></g><g class="edgeLabel"><g class="label" transform="translate(0, 0)"><text y="-10.1" text-anchor="middle"><tspan class="text-outer-tspan row" x="0" y="-0.1em" text-anchor="middle"></tspan></text></g></g><g><rect class="background" style="stroke: none"></rect></g><g class="edgeLabel"><g class="label" transform="translate(0, 0)"><text y="-10.1" text-anchor="middle"><tspan class="text-outer-tspan row" x="0" y="-0.1em" text-anchor="middle"></tspan></text></g></g><g><rect class="background" style="stroke: none"></rect></g><g class="edgeLabel"><g class="label" transform="translate(0, 0)"><text y="-10.1" text-anchor="middle"><tspan class="text-outer-tspan row" x="0" y="-0.1em" text-anchor="middle"></tspan></text></g></g><g><rect class="background" style="stroke: none"></rect></g><g class="edgeLabel"><g class="label" transform="translate(0, 0)"><text y="-10.1" text-anchor="middle"><tspan class="text-outer-tspan row" x="0" y="-0.1em" text-anchor="middle"></tspan></text></g></g><g><rect class="background" style="stroke: none"></rect></g><g class="edgeLabel"><g class="label" transform="translate(0, 0)"><text y="-10.1" text-anchor="middle"><tspan class="text-outer-tspan row" x="0" y="-0.1em" text-anchor="middle"></tspan></text></g></g><g><rect class="background" style="stroke: none"></rect></g><g class="edgeLabel"><g class="label" transform="translate(0, 0)"><text y="-10.1" text-anchor="middle"><tspan class="text-outer-tspan row" x="0" y="-0.1em" text-anchor="middle"></tspan></text></g></g><g><rect class="background" style="stroke: none"></rect></g><g class="edgeLabel" transform="translate(433.84693, 663.39369)"><g class="label" transform="translate(0, -28.099998474121094)"><g><rect class="background" style="" x="-95.828125" y="-1" width="191.65625" height="58.19999694824219"></rect><text y="-10.1" text-anchor="middle" style=""><tspan class="text-outer-tspan row" x="0" y="-0.1em" text-anchor="middle"><tspan class="text-inner-tspan">operator</tspan><tspan class="text-inner-tspan"> adds</tspan><tspan class="text-inner-tspan"> an</tspan><tspan class="text-inner-tspan"> entry</tspan></tspan><tspan class="text-outer-tspan row" x="0" y="1em" text-anchor="middle"><tspan class="text-inner-tspan">whose</tspan><tspan class="text-inner-tspan"> name:</tspan><tspan class="text-inner-tspan"> matches</tspan><tspan class="text-inner-tspan"> the</tspan></tspan><tspan class="text-outer-tspan row" x="0" y="2.1em" text-anchor="middle"><tspan class="text-inner-tspan">bucket</tspan><tspan class="text-inner-tspan"> →</tspan><tspan class="text-inner-tspan"> PR</tspan></tspan></text></g></g></g></g><g class="nodes"><g class="node default" id="my-svg-flowchart-CRON-0" transform="translate(132.68359375, 207.89999771118164)"><rect class="basic label-container" style="" x="-86.40625" y="-33.29999923706055" width="172.8125" height="66.5999984741211"></rect><g class="label" style="" transform="translate(0, -18.299999237060547)"><rect></rect><g><rect class="background" style="stroke: none"></rect><text y="-10.1" style=""><tspan class="text-outer-tspan row" x="0" y="-0.1em"><tspan class="text-inner-tspan">cron</tspan></tspan><tspan class="text-outer-tspan row" x="0" y="1em"><tspan class="text-inner-tspan">09:00</tspan><tspan class="text-inner-tspan"> UTC</tspan><tspan class="text-inner-tspan"> daily</tspan></tspan></text></g></g></g><g class="node default" id="my-svg-flowchart-PF-1" transform="translate(132.68359375, 333.2999954223633)"><rect class="basic label-container" style="" x="-81.59375" y="-33.29999923706055" width="163.1875" height="66.5999984741211"></rect><g class="label" style="" transform="translate(0, -18.299999237060547)"><rect></rect><g><rect class="background" style="stroke: none"></rect><text y="-10.1" style=""><tspan class="text-outer-tspan row" x="0" y="-0.1em"><tspan class="text-inner-tspan">audit-prefilter</tspan></tspan><tspan class="text-outer-tspan row" x="0" y="1em"><tspan class="text-inner-tspan">--max=10</tspan></tspan></text></g></g></g><g class="node default" id="my-svg-flowchart-RUN-3" transform="translate(132.68359375, 458.6999931335449)"><rect class="basic label-container" style="" x="-85.171875" y="-33.29999923706055" width="170.34375" height="66.5999984741211"></rect><g class="label" style="" transform="translate(0, -18.299999237060547)"><rect></rect><g><rect class="background" style="stroke: none"></rect><text y="-10.1" style=""><tspan class="text-outer-tspan row" x="0" y="-0.1em"><tspan class="text-inner-tspan">audit-run-entry</tspan></tspan><tspan class="text-outer-tspan row" x="0" y="1em"><tspan class="text-inner-tspan">grounded</tspan><tspan class="text-inner-tspan"> LLM</tspan></tspan></text></g></g></g><g class="node default" id="my-svg-flowchart-APPLY-5" transform="translate(132.68359375, 575.299991607666)"><rect class="basic label-container" style="" x="-70.84375" y="-33.29999923706055" width="141.6875" height="66.5999984741211"></rect><g class="label" style="" transform="translate(0, -18.299999237060547)"><rect></rect><g><rect class="background" style="stroke: none"></rect><text y="-10.1" style=""><tspan class="text-outer-tspan row" x="0" y="-0.1em"><tspan class="text-inner-tspan">audit-apply</tspan></tspan><tspan class="text-outer-tspan row" x="0" y="1em"><tspan class="text-inner-tspan">--open-pr</tspan></tspan></text></g></g></g><g class="node default" id="my-svg-flowchart-GATES-7" transform="translate(190.59765625, 766.2999877929688)"><rect class="basic label-container" style="" x="-67.1328125" y="-24.5" width="134.265625" height="49"></rect><g class="label" style="" transform="translate(0, -9.5)"><rect></rect><g><rect class="background" style="stroke: none"></rect><text y="-10.1" style=""><tspan class="text-outer-tspan row" x="0" y="-0.1em"><tspan class="text-inner-tspan">5</tspan><tspan class="text-inner-tspan"> PR</tspan><tspan class="text-inner-tspan"> gates</tspan></tspan></text></g></g></g><g class="node default" id="my-svg-flowchart-MERGE-9" transform="translate(190.59765625, 874.0999870300293)"><rect class="basic label-container" style="" x="-92.9609375" y="-33.29999923706055" width="185.921875" height="66.5999984741211"></rect><g class="label" style="" transform="translate(0, -18.299999237060547)"><rect></rect><g><rect class="background" style="stroke: none"></rect><text y="-10.1" style=""><tspan class="text-outer-tspan row" x="0" y="-0.1em"><tspan class="text-inner-tspan">human</tspan><tspan class="text-inner-tspan"> merge</tspan></tspan><tspan class="text-outer-tspan row" x="0" y="1em"><tspan class="text-inner-tspan">→</tspan><tspan class="text-inner-tspan"> VERSION</tspan><tspan class="text-inner-tspan"> bump</tspan></tspan></text></g></g></g><g class="node default" id="my-svg-flowchart-TAIL-10" transform="translate(536.59375, 66.29999923706055)"><rect class="basic label-container" style="" x="-90.6171875" y="-33.29999923706055" width="181.234375" height="66.5999984741211"></rect><g class="label" style="" transform="translate(0, -18.299999237060547)"><rect></rect><g><rect class="background" style="stroke: none"></rect><text y="-10.1" style=""><tspan class="text-outer-tspan row" x="0" y="-0.1em"><tspan class="text-inner-tspan">gap-signal-tail</tspan></tspan><tspan class="text-outer-tspan row" x="0" y="1em"><tspan class="text-inner-tspan">89</tspan><tspan class="text-inner-tspan"> pipeline</tspan><tspan class="text-inner-tspan"> steps</tspan></tspan></text></g></g></g><g class="node default" id="my-svg-flowchart-EVENT-11" transform="translate(536.59375, 207.89999771118164)"><rect class="basic label-container" style="" x="-111.1875" y="-33.29999923706055" width="222.375" height="66.5999984741211"></rect><g class="label" style="" transform="translate(0, -18.299999237060547)"><rect></rect><g><rect class="background" style="stroke: none"></rect><text y="-10.1" style=""><tspan class="text-outer-tspan row" x="0" y="-0.1em"><tspan class="text-inner-tspan">scaffold</tspan><tspan class="text-inner-tspan"> observe</tspan><tspan class="text-inner-tspan"> event</tspan></tspan><tspan class="text-outer-tspan row" x="0" y="1em"><tspan class="text-inner-tspan">knowledge_gap_signal</tspan></tspan></text></g></g></g><g class="node default" id="my-svg-flowchart-LEDGER-13" transform="translate(536.59375, 333.2999954223633)"><rect class="basic label-container" style="" x="-76.09375" y="-33.29999923706055" width="152.1875" height="66.5999984741211"></rect><g class="label" style="" transform="translate(0, -18.299999237060547)"><rect></rect><g><rect class="background" style="stroke: none"></rect><text y="-10.1" style=""><tspan class="text-outer-tspan row" x="0" y="-0.1em"><tspan class="text-inner-tspan">ledger</tspan></tspan><tspan class="text-outer-tspan row" x="0" y="1em"><tspan class="text-inner-tspan">activity.jsonl</tspan></tspan></text></g></g></g><g class="node default" id="my-svg-flowchart-LENSI-15" transform="translate(661.0234375, 458.6999931335449)"><rect class="basic label-container" style="" x="-83.65625" y="-33.29999923706055" width="167.3125" height="66.5999984741211"></rect><g class="label" style="" transform="translate(0, -18.299999237060547)"><rect></rect><g><rect class="background" style="stroke: none"></rect><text y="-10.1" style=""><tspan class="text-outer-tspan row" x="0" y="-0.1em"><tspan class="text-inner-tspan">Lens</tspan><tspan class="text-inner-tspan"> I</tspan></tspan><tspan class="text-outer-tspan row" x="0" y="1em"><tspan class="text-inner-tspan">90-day</tspan><tspan class="text-inner-tspan"> window</tspan></tspan></text></g></g></g><g class="node default" id="my-svg-flowchart-FINDING-17" transform="translate(661.0234375, 575.299991607666)"><rect class="basic label-container" style="" x="-56.3359375" y="-33.29999923706055" width="112.671875" height="66.5999984741211"></rect><g class="label" style="" transform="translate(0, -18.299999237060547)"><rect></rect><g><rect class="background" style="stroke: none"></rect><text y="-10.1" style=""><tspan class="text-outer-tspan row" x="0" y="-0.1em"><tspan class="text-inner-tspan">finding</tspan></tspan><tspan class="text-outer-tspan row" x="0" y="1em"><tspan class="text-inner-tspan">P1</tspan><tspan class="text-inner-tspan"> /</tspan><tspan class="text-inner-tspan"> P2</tspan></tspan></text></g></g></g><g class="node default" id="my-svg-flowchart-RESOLVER-18" transform="translate(785.453125, 333.2999954223633)"><rect class="basic label-container" style="" x="-122.765625" y="-42.099998474121094" width="245.53125" height="84.19999694824219"></rect><g class="label" style="" transform="translate(0, -27.099998474121094)"><rect></rect><g><rect class="background" style="stroke: none"></rect><text y="-10.1" style=""><tspan class="text-outer-tspan row" x="0" y="-0.1em"><tspan class="text-inner-tspan">3-tier</tspan><tspan class="text-inner-tspan"> --knowledge-root</tspan></tspan><tspan class="text-outer-tspan row" x="0" y="1em"><tspan class="text-inner-tspan">resolver</tspan></tspan><tspan class="text-outer-tspan row" x="0" y="2.1em"><tspan class="text-inner-tspan">suppresses</tspan><tspan class="text-inner-tspan"> covered</tspan><tspan class="text-inner-tspan"> topics</tspan></tspan></text></g></g></g></g></g></g><defs></defs><defs></defs></svg></figure>
1445
+ <figure class="mermaid"><svg id="my-svg" width="100%" xmlns="http://www.w3.org/2000/svg" class="flowchart" style="max-width: 951.219px; background-color: transparent;" viewBox="0 0 951.21875 940.3999633789062" role="graphics-document document">#my-svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#000000;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#my-svg .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#my-svg .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#my-svg .error-icon{fill:#552222;}#my-svg .error-text{fill:#552222;stroke:#552222;}#my-svg .edge-thickness-normal{stroke-width:1px;}#my-svg .edge-thickness-thick{stroke-width:3.5px;}#my-svg .edge-pattern-solid{stroke-dasharray:0;}#my-svg .edge-thickness-invisible{stroke-width:0;fill:none;}#my-svg .edge-pattern-dashed{stroke-dasharray:3;}#my-svg .edge-pattern-dotted{stroke-dasharray:2;}#my-svg .marker{fill:#666;stroke:#666;}#my-svg .marker.cross{stroke:#666;}#my-svg svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#my-svg p{margin:0;}#my-svg .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#000000;}#my-svg .cluster-label text{fill:#333;}#my-svg .cluster-label span{color:#333;}#my-svg .cluster-label span p{background-color:transparent;}#my-svg .label text,#my-svg span{fill:#000000;color:#000000;}#my-svg .node rect,#my-svg .node circle,#my-svg .node ellipse,#my-svg .node polygon,#my-svg .node path{fill:#eee;stroke:#999;stroke-width:1px;}#my-svg .rough-node .label text,#my-svg .node .label text,#my-svg .image-shape .label,#my-svg .icon-shape .label{text-anchor:middle;}#my-svg .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#my-svg .rough-node .label,#my-svg .node .label,#my-svg .image-shape .label,#my-svg .icon-shape .label{text-align:center;}#my-svg .node.clickable{cursor:pointer;}#my-svg .root .anchor path{fill:#666!important;stroke-width:0;stroke:#666;}#my-svg .arrowheadPath{fill:#333333;}#my-svg .edgePath .path{stroke:#666;stroke-width:1px;}#my-svg .flowchart-link{stroke:#666;fill:none;}#my-svg .edgeLabel{background-color:white;text-align:center;}#my-svg .edgeLabel p{background-color:white;}#my-svg .edgeLabel rect{opacity:0.5;background-color:white;fill:white;}#my-svg .labelBkg{background-color:rgba(255, 255, 255, 0.5);}#my-svg .cluster rect{fill:hsl(0, 0%, 98.9215686275%);stroke:#707070;stroke-width:1px;}#my-svg .cluster text{fill:#333;}#my-svg .cluster span{color:#333;}#my-svg div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(-160, 0%, 93.3333333333%);border:1px solid #707070;border-radius:2px;pointer-events:none;z-index:100;}#my-svg .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#000000;}#my-svg rect.text{fill:none;stroke-width:0;}#my-svg .icon-shape,#my-svg .image-shape{background-color:white;text-align:center;}#my-svg .icon-shape p,#my-svg .image-shape p{background-color:white;padding:2px;}#my-svg .icon-shape .label rect,#my-svg .image-shape .label rect{opacity:0.5;background-color:white;fill:white;}#my-svg .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#my-svg .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#my-svg .node .neo-node{stroke:#999;}#my-svg [data-look="neo"].node rect,#my-svg [data-look="neo"].cluster rect,#my-svg [data-look="neo"].node polygon{stroke:url(#my-svg-gradient);filter:drop-shadow( 1px 2px 2px rgba(185,185,185,1));}#my-svg [data-look="neo"].node path{stroke:url(#my-svg-gradient);stroke-width:1px;}#my-svg [data-look="neo"].node .outer-path{filter:drop-shadow( 1px 2px 2px rgba(185,185,185,1));}#my-svg [data-look="neo"].node .neo-line path{stroke:#999;filter:none;}#my-svg [data-look="neo"].node circle{stroke:url(#my-svg-gradient);filter:drop-shadow( 1px 2px 2px rgba(185,185,185,1));}#my-svg [data-look="neo"].node circle .state-start{fill:#000000;}#my-svg [data-look="neo"].icon-shape .icon{fill:url(#my-svg-gradient);filter:drop-shadow( 1px 2px 2px rgba(185,185,185,1));}#my-svg [data-look="neo"].icon-shape .icon-neo path{stroke:url(#my-svg-gradient);filter:drop-shadow( 1px 2px 2px rgba(185,185,185,1));}#my-svg :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}<g><marker id="my-svg_flowchart-v2-pointEnd" class="marker flowchart-v2" viewBox="0 0 10 10" refX="5" refY="5" markerUnits="userSpaceOnUse" markerWidth="8" markerHeight="8" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowMarkerPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker><marker id="my-svg_flowchart-v2-pointStart" class="marker flowchart-v2" viewBox="0 0 10 10" refX="4.5" refY="5" markerUnits="userSpaceOnUse" markerWidth="8" markerHeight="8" orient="auto"><path d="M 0 5 L 10 10 L 10 0 z" class="arrowMarkerPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker><marker id="my-svg_flowchart-v2-pointEnd-margin" class="marker flowchart-v2" viewBox="0 0 11.5 14" refX="11.5" refY="7" markerUnits="userSpaceOnUse" markerWidth="10.5" markerHeight="14" orient="auto"><path d="M 0 0 L 11.5 7 L 0 14 z" class="arrowMarkerPath" style="stroke-width: 0; stroke-dasharray: 1, 0;"></path></marker><marker id="my-svg_flowchart-v2-pointStart-margin" class="marker flowchart-v2" viewBox="0 0 11.5 14" refX="1" refY="7" markerUnits="userSpaceOnUse" markerWidth="11.5" markerHeight="14" orient="auto"><polygon points="0,7 11.5,14 11.5,0" class="arrowMarkerPath" style="stroke-width: 0; stroke-dasharray: 1, 0;"></polygon></marker><marker id="my-svg_flowchart-v2-circleEnd" class="marker flowchart-v2" viewBox="0 0 10 10" refX="11" refY="5" markerUnits="userSpaceOnUse" markerWidth="11" markerHeight="11" orient="auto"><circle cx="5" cy="5" r="5" class="arrowMarkerPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></circle></marker><marker id="my-svg_flowchart-v2-circleStart" class="marker flowchart-v2" viewBox="0 0 10 10" refX="-1" refY="5" markerUnits="userSpaceOnUse" markerWidth="11" markerHeight="11" orient="auto"><circle cx="5" cy="5" r="5" class="arrowMarkerPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></circle></marker><marker id="my-svg_flowchart-v2-circleEnd-margin" class="marker flowchart-v2" viewBox="0 0 10 10" refY="5" refX="12.25" markerUnits="userSpaceOnUse" markerWidth="14" markerHeight="14" orient="auto"><circle cx="5" cy="5" r="5" class="arrowMarkerPath" style="stroke-width: 0; stroke-dasharray: 1, 0;"></circle></marker><marker id="my-svg_flowchart-v2-circleStart-margin" class="marker flowchart-v2" viewBox="0 0 10 10" refX="-2" refY="5" markerUnits="userSpaceOnUse" markerWidth="14" markerHeight="14" orient="auto"><circle cx="5" cy="5" r="5" class="arrowMarkerPath" style="stroke-width: 0; stroke-dasharray: 1, 0;"></circle></marker><marker id="my-svg_flowchart-v2-crossEnd" class="marker cross flowchart-v2" viewBox="0 0 11 11" refX="12" refY="5.2" markerUnits="userSpaceOnUse" markerWidth="11" markerHeight="11" orient="auto"><path d="M 1,1 l 9,9 M 10,1 l -9,9" class="arrowMarkerPath" style="stroke-width: 2; stroke-dasharray: 1, 0;"></path></marker><marker id="my-svg_flowchart-v2-crossStart" class="marker cross flowchart-v2" viewBox="0 0 11 11" refX="-1" refY="5.2" markerUnits="userSpaceOnUse" markerWidth="11" markerHeight="11" orient="auto"><path d="M 1,1 l 9,9 M 10,1 l -9,9" class="arrowMarkerPath" style="stroke-width: 2; stroke-dasharray: 1, 0;"></path></marker><marker id="my-svg_flowchart-v2-crossEnd-margin" class="marker cross flowchart-v2" viewBox="0 0 15 15" refX="17.7" refY="7.5" markerUnits="userSpaceOnUse" markerWidth="12" markerHeight="12" orient="auto"><path d="M 1,1 L 14,14 M 1,14 L 14,1" class="arrowMarkerPath" style="stroke-width: 2.5;"></path></marker><marker id="my-svg_flowchart-v2-crossStart-margin" class="marker cross flowchart-v2" viewBox="0 0 15 15" refX="-3.5" refY="7.5" markerUnits="userSpaceOnUse" markerWidth="12" markerHeight="12" orient="auto"><path d="M 1,1 L 14,14 M 1,14 L 14,1" class="arrowMarkerPath" style="stroke-width: 2.5; stroke-dasharray: 1, 0;"></path></marker><g class="root"><g class="clusters"><g class="cluster" id="my-svg-gap"><rect style="" x="390.40625" y="8" width="552.8125" height="625.5999908447266"></rect><g class="cluster-label" transform="translate(636.375, 8)"><g><rect class="background" style="stroke: none"></rect><text y="-10.1" style=""><tspan class="text-outer-tspan row" x="0" y="-0.1em"><tspan class="text-inner-tspan">Gap</tspan><tspan class="text-inner-tspan"> arm</tspan></tspan></text></g></g></g><g class="cluster" id="my-svg-refresh"><rect style="" x="8" y="149.5999984741211" width="362.40625" height="782.7999877929688"></rect><g class="cluster-label" transform="translate(146.1015625, 149.5999984741211)"><g><rect class="background" style="stroke: none"></rect><text y="-10.1" style=""><tspan class="text-outer-tspan row" x="0" y="-0.1em"><tspan class="text-inner-tspan">Refresh</tspan><tspan class="text-inner-tspan"> arm</tspan></tspan></text></g></g></g></g><g class="edgePaths"><path d="M132.684,241.2L132.684,245.367C132.684,249.533,132.684,257.867,132.684,267C132.684,276.133,132.684,286.067,132.684,291.033L132.684,296" id="my-svg-L_CRON_PF_0" class="edge-thickness-normal edge-pattern-solid edge-thickness-normal edge-pattern-solid flowchart-link" style=";" marker-end="url(#my-svg_flowchart-v2-pointEnd)"></path><path d="M132.684,366.6L132.684,372.233C132.684,377.867,132.684,389.133,132.684,398.267C132.684,407.4,132.684,414.4,132.684,417.9L132.684,421.4" id="my-svg-L_PF_RUN_0" class="edge-thickness-normal edge-pattern-solid edge-thickness-normal edge-pattern-solid flowchart-link" style=";" marker-end="url(#my-svg_flowchart-v2-pointEnd)"></path><path d="M132.684,492L132.684,496.167C132.684,500.333,132.684,508.667,132.684,516.333C132.684,524,132.684,531,132.684,534.5L132.684,538" id="my-svg-L_RUN_APPLY_0" class="edge-thickness-normal edge-pattern-solid edge-thickness-normal edge-pattern-solid flowchart-link" style=";" marker-end="url(#my-svg_flowchart-v2-pointEnd)"></path><path d="M132.684,608.6L132.684,612.767C132.684,616.933,132.684,625.267,132.684,638.45C132.684,651.633,132.684,669.667,138.932,687.163C145.18,704.66,157.676,721.62,163.925,730.1L170.173,738.58" id="my-svg-L_APPLY_GATES_0" class="edge-thickness-normal edge-pattern-solid edge-thickness-normal edge-pattern-solid flowchart-link" style=";" marker-end="url(#my-svg_flowchart-v2-pointEnd)"></path><path d="M190.598,790.8L190.598,794.967C190.598,799.133,190.598,807.467,190.598,815.133C190.598,822.8,190.598,829.8,190.598,833.3L190.598,836.8" id="my-svg-L_GATES_MERGE_0" class="edge-thickness-normal edge-pattern-solid edge-thickness-normal edge-pattern-solid flowchart-link" style=";" marker-end="url(#my-svg_flowchart-v2-pointEnd)"></path><path d="M536.594,99.6L536.594,103.767C536.594,107.933,536.594,116.267,536.594,124.6C536.594,132.933,536.594,141.267,536.594,148.933C536.594,156.6,536.594,163.6,536.594,167.1L536.594,170.6" id="my-svg-L_TAIL_EVENT_0" class="edge-thickness-normal edge-pattern-solid edge-thickness-normal edge-pattern-solid flowchart-link" style=";" marker-end="url(#my-svg_flowchart-v2-pointEnd)"></path><path d="M536.594,241.2L536.594,245.367C536.594,249.533,536.594,257.867,536.594,267C536.594,276.133,536.594,286.067,536.594,291.033L536.594,296" id="my-svg-L_EVENT_LEDGER_0" class="edge-thickness-normal edge-pattern-solid edge-thickness-normal edge-pattern-solid flowchart-link" style=";" marker-end="url(#my-svg_flowchart-v2-pointEnd)"></path><path d="M536.594,366.6L536.594,372.233C536.594,377.867,536.594,389.133,544.883,398.65C553.172,408.168,569.751,415.935,578.04,419.819L586.329,423.703" id="my-svg-L_LEDGER_LENSI_0" class="edge-thickness-normal edge-pattern-solid edge-thickness-normal edge-pattern-solid flowchart-link" style=";" marker-end="url(#my-svg_flowchart-v2-pointEnd)"></path><path d="M661.023,492L661.023,496.167C661.023,500.333,661.023,508.667,661.023,516.333C661.023,524,661.023,531,661.023,534.5L661.023,538" id="my-svg-L_LENSI_FINDING_0" class="edge-thickness-normal edge-pattern-solid edge-thickness-normal edge-pattern-solid flowchart-link" style=";" marker-end="url(#my-svg_flowchart-v2-pointEnd)"></path><path d="M785.453,375.4L785.453,379.567C785.453,383.733,785.453,392.067,777.164,400.117C768.875,408.168,752.296,415.935,744.007,419.819L735.718,423.703" id="my-svg-L_RESOLVER_LENSI_0" class="edge-thickness-normal edge-pattern-solid edge-thickness-normal edge-pattern-solid flowchart-link" style=";" marker-end="url(#my-svg_flowchart-v2-pointEnd)"></path><path d="M661.023,608.6L661.023,612.767C661.023,616.933,661.023,625.267,592.271,638.45C523.52,651.633,386.016,669.667,311.015,687.163C236.015,704.66,223.519,721.62,217.271,730.1L211.023,738.58" id="my-svg-L_FINDING_GATES_0" class="edge-thickness-normal edge-pattern-dotted edge-thickness-normal edge-pattern-solid flowchart-link" style=";" marker-end="url(#my-svg_flowchart-v2-pointEnd)"></path></g><g class="edgeLabels"><g class="edgeLabel"><g class="label" transform="translate(0, 0)"><text y="-10.1" text-anchor="middle"><tspan class="text-outer-tspan row" x="0" y="-0.1em" text-anchor="middle"></tspan></text></g></g><g><rect class="background" style="stroke: none"></rect></g><g class="edgeLabel"><g class="label" transform="translate(0, 0)"><text y="-10.1" text-anchor="middle"><tspan class="text-outer-tspan row" x="0" y="-0.1em" text-anchor="middle"></tspan></text></g></g><g><rect class="background" style="stroke: none"></rect></g><g class="edgeLabel"><g class="label" transform="translate(0, 0)"><text y="-10.1" text-anchor="middle"><tspan class="text-outer-tspan row" x="0" y="-0.1em" text-anchor="middle"></tspan></text></g></g><g><rect class="background" style="stroke: none"></rect></g><g class="edgeLabel"><g class="label" transform="translate(0, 0)"><text y="-10.1" text-anchor="middle"><tspan class="text-outer-tspan row" x="0" y="-0.1em" text-anchor="middle"></tspan></text></g></g><g><rect class="background" style="stroke: none"></rect></g><g class="edgeLabel"><g class="label" transform="translate(0, 0)"><text y="-10.1" text-anchor="middle"><tspan class="text-outer-tspan row" x="0" y="-0.1em" text-anchor="middle"></tspan></text></g></g><g><rect class="background" style="stroke: none"></rect></g><g class="edgeLabel"><g class="label" transform="translate(0, 0)"><text y="-10.1" text-anchor="middle"><tspan class="text-outer-tspan row" x="0" y="-0.1em" text-anchor="middle"></tspan></text></g></g><g><rect class="background" style="stroke: none"></rect></g><g class="edgeLabel"><g class="label" transform="translate(0, 0)"><text y="-10.1" text-anchor="middle"><tspan class="text-outer-tspan row" x="0" y="-0.1em" text-anchor="middle"></tspan></text></g></g><g><rect class="background" style="stroke: none"></rect></g><g class="edgeLabel"><g class="label" transform="translate(0, 0)"><text y="-10.1" text-anchor="middle"><tspan class="text-outer-tspan row" x="0" y="-0.1em" text-anchor="middle"></tspan></text></g></g><g><rect class="background" style="stroke: none"></rect></g><g class="edgeLabel"><g class="label" transform="translate(0, 0)"><text y="-10.1" text-anchor="middle"><tspan class="text-outer-tspan row" x="0" y="-0.1em" text-anchor="middle"></tspan></text></g></g><g><rect class="background" style="stroke: none"></rect></g><g class="edgeLabel"><g class="label" transform="translate(0, 0)"><text y="-10.1" text-anchor="middle"><tspan class="text-outer-tspan row" x="0" y="-0.1em" text-anchor="middle"></tspan></text></g></g><g><rect class="background" style="stroke: none"></rect></g><g class="edgeLabel" transform="translate(433.84693, 663.39369)"><g class="label" transform="translate(0, -28.099998474121094)"><g><rect class="background" style="" x="-95.828125" y="-1" width="191.65625" height="58.19999694824219"></rect><text y="-10.1" text-anchor="middle" style=""><tspan class="text-outer-tspan row" x="0" y="-0.1em" text-anchor="middle"><tspan class="text-inner-tspan">operator</tspan><tspan class="text-inner-tspan"> adds</tspan><tspan class="text-inner-tspan"> an</tspan><tspan class="text-inner-tspan"> entry</tspan></tspan><tspan class="text-outer-tspan row" x="0" y="1em" text-anchor="middle"><tspan class="text-inner-tspan">whose</tspan><tspan class="text-inner-tspan"> name:</tspan><tspan class="text-inner-tspan"> matches</tspan><tspan class="text-inner-tspan"> the</tspan></tspan><tspan class="text-outer-tspan row" x="0" y="2.1em" text-anchor="middle"><tspan class="text-inner-tspan">bucket</tspan><tspan class="text-inner-tspan"> →</tspan><tspan class="text-inner-tspan"> PR</tspan></tspan></text></g></g></g></g><g class="nodes"><g class="node default" id="my-svg-flowchart-CRON-0" transform="translate(132.68359375, 207.89999771118164)"><rect class="basic label-container" style="" x="-86.40625" y="-33.29999923706055" width="172.8125" height="66.5999984741211"></rect><g class="label" style="" transform="translate(0, -18.299999237060547)"><rect></rect><g><rect class="background" style="stroke: none"></rect><text y="-10.1" style=""><tspan class="text-outer-tspan row" x="0" y="-0.1em"><tspan class="text-inner-tspan">cron</tspan></tspan><tspan class="text-outer-tspan row" x="0" y="1em"><tspan class="text-inner-tspan">09:00</tspan><tspan class="text-inner-tspan"> UTC</tspan><tspan class="text-inner-tspan"> daily</tspan></tspan></text></g></g></g><g class="node default" id="my-svg-flowchart-PF-1" transform="translate(132.68359375, 333.2999954223633)"><rect class="basic label-container" style="" x="-81.59375" y="-33.29999923706055" width="163.1875" height="66.5999984741211"></rect><g class="label" style="" transform="translate(0, -18.299999237060547)"><rect></rect><g><rect class="background" style="stroke: none"></rect><text y="-10.1" style=""><tspan class="text-outer-tspan row" x="0" y="-0.1em"><tspan class="text-inner-tspan">audit-prefilter</tspan></tspan><tspan class="text-outer-tspan row" x="0" y="1em"><tspan class="text-inner-tspan">--max=10</tspan></tspan></text></g></g></g><g class="node default" id="my-svg-flowchart-RUN-3" transform="translate(132.68359375, 458.6999931335449)"><rect class="basic label-container" style="" x="-85.171875" y="-33.29999923706055" width="170.34375" height="66.5999984741211"></rect><g class="label" style="" transform="translate(0, -18.299999237060547)"><rect></rect><g><rect class="background" style="stroke: none"></rect><text y="-10.1" style=""><tspan class="text-outer-tspan row" x="0" y="-0.1em"><tspan class="text-inner-tspan">audit-run-entry</tspan></tspan><tspan class="text-outer-tspan row" x="0" y="1em"><tspan class="text-inner-tspan">grounded</tspan><tspan class="text-inner-tspan"> LLM</tspan></tspan></text></g></g></g><g class="node default" id="my-svg-flowchart-APPLY-5" transform="translate(132.68359375, 575.299991607666)"><rect class="basic label-container" style="" x="-70.84375" y="-33.29999923706055" width="141.6875" height="66.5999984741211"></rect><g class="label" style="" transform="translate(0, -18.299999237060547)"><rect></rect><g><rect class="background" style="stroke: none"></rect><text y="-10.1" style=""><tspan class="text-outer-tspan row" x="0" y="-0.1em"><tspan class="text-inner-tspan">audit-apply</tspan></tspan><tspan class="text-outer-tspan row" x="0" y="1em"><tspan class="text-inner-tspan">--open-pr</tspan></tspan></text></g></g></g><g class="node default" id="my-svg-flowchart-GATES-7" transform="translate(190.59765625, 766.2999877929688)"><rect class="basic label-container" style="" x="-67.1328125" y="-24.5" width="134.265625" height="49"></rect><g class="label" style="" transform="translate(0, -9.5)"><rect></rect><g><rect class="background" style="stroke: none"></rect><text y="-10.1" style=""><tspan class="text-outer-tspan row" x="0" y="-0.1em"><tspan class="text-inner-tspan">5</tspan><tspan class="text-inner-tspan"> PR</tspan><tspan class="text-inner-tspan"> gates</tspan></tspan></text></g></g></g><g class="node default" id="my-svg-flowchart-MERGE-9" transform="translate(190.59765625, 874.0999870300293)"><rect class="basic label-container" style="" x="-92.9609375" y="-33.29999923706055" width="185.921875" height="66.5999984741211"></rect><g class="label" style="" transform="translate(0, -18.299999237060547)"><rect></rect><g><rect class="background" style="stroke: none"></rect><text y="-10.1" style=""><tspan class="text-outer-tspan row" x="0" y="-0.1em"><tspan class="text-inner-tspan">human</tspan><tspan class="text-inner-tspan"> merge</tspan></tspan><tspan class="text-outer-tspan row" x="0" y="1em"><tspan class="text-inner-tspan">→</tspan><tspan class="text-inner-tspan"> VERSION</tspan><tspan class="text-inner-tspan"> bump</tspan></tspan></text></g></g></g><g class="node default" id="my-svg-flowchart-TAIL-10" transform="translate(536.59375, 66.29999923706055)"><rect class="basic label-container" style="" x="-90.6171875" y="-33.29999923706055" width="181.234375" height="66.5999984741211"></rect><g class="label" style="" transform="translate(0, -18.299999237060547)"><rect></rect><g><rect class="background" style="stroke: none"></rect><text y="-10.1" style=""><tspan class="text-outer-tspan row" x="0" y="-0.1em"><tspan class="text-inner-tspan">gap-signal-tail</tspan></tspan><tspan class="text-outer-tspan row" x="0" y="1em"><tspan class="text-inner-tspan">90</tspan><tspan class="text-inner-tspan"> pipeline</tspan><tspan class="text-inner-tspan"> steps</tspan></tspan></text></g></g></g><g class="node default" id="my-svg-flowchart-EVENT-11" transform="translate(536.59375, 207.89999771118164)"><rect class="basic label-container" style="" x="-111.1875" y="-33.29999923706055" width="222.375" height="66.5999984741211"></rect><g class="label" style="" transform="translate(0, -18.299999237060547)"><rect></rect><g><rect class="background" style="stroke: none"></rect><text y="-10.1" style=""><tspan class="text-outer-tspan row" x="0" y="-0.1em"><tspan class="text-inner-tspan">scaffold</tspan><tspan class="text-inner-tspan"> observe</tspan><tspan class="text-inner-tspan"> event</tspan></tspan><tspan class="text-outer-tspan row" x="0" y="1em"><tspan class="text-inner-tspan">knowledge_gap_signal</tspan></tspan></text></g></g></g><g class="node default" id="my-svg-flowchart-LEDGER-13" transform="translate(536.59375, 333.2999954223633)"><rect class="basic label-container" style="" x="-76.09375" y="-33.29999923706055" width="152.1875" height="66.5999984741211"></rect><g class="label" style="" transform="translate(0, -18.299999237060547)"><rect></rect><g><rect class="background" style="stroke: none"></rect><text y="-10.1" style=""><tspan class="text-outer-tspan row" x="0" y="-0.1em"><tspan class="text-inner-tspan">ledger</tspan></tspan><tspan class="text-outer-tspan row" x="0" y="1em"><tspan class="text-inner-tspan">activity.jsonl</tspan></tspan></text></g></g></g><g class="node default" id="my-svg-flowchart-LENSI-15" transform="translate(661.0234375, 458.6999931335449)"><rect class="basic label-container" style="" x="-83.65625" y="-33.29999923706055" width="167.3125" height="66.5999984741211"></rect><g class="label" style="" transform="translate(0, -18.299999237060547)"><rect></rect><g><rect class="background" style="stroke: none"></rect><text y="-10.1" style=""><tspan class="text-outer-tspan row" x="0" y="-0.1em"><tspan class="text-inner-tspan">Lens</tspan><tspan class="text-inner-tspan"> I</tspan></tspan><tspan class="text-outer-tspan row" x="0" y="1em"><tspan class="text-inner-tspan">90-day</tspan><tspan class="text-inner-tspan"> window</tspan></tspan></text></g></g></g><g class="node default" id="my-svg-flowchart-FINDING-17" transform="translate(661.0234375, 575.299991607666)"><rect class="basic label-container" style="" x="-56.3359375" y="-33.29999923706055" width="112.671875" height="66.5999984741211"></rect><g class="label" style="" transform="translate(0, -18.299999237060547)"><rect></rect><g><rect class="background" style="stroke: none"></rect><text y="-10.1" style=""><tspan class="text-outer-tspan row" x="0" y="-0.1em"><tspan class="text-inner-tspan">finding</tspan></tspan><tspan class="text-outer-tspan row" x="0" y="1em"><tspan class="text-inner-tspan">P1</tspan><tspan class="text-inner-tspan"> /</tspan><tspan class="text-inner-tspan"> P2</tspan></tspan></text></g></g></g><g class="node default" id="my-svg-flowchart-RESOLVER-18" transform="translate(785.453125, 333.2999954223633)"><rect class="basic label-container" style="" x="-122.765625" y="-42.099998474121094" width="245.53125" height="84.19999694824219"></rect><g class="label" style="" transform="translate(0, -27.099998474121094)"><rect></rect><g><rect class="background" style="stroke: none"></rect><text y="-10.1" style=""><tspan class="text-outer-tspan row" x="0" y="-0.1em"><tspan class="text-inner-tspan">3-tier</tspan><tspan class="text-inner-tspan"> --knowledge-root</tspan></tspan><tspan class="text-outer-tspan row" x="0" y="1em"><tspan class="text-inner-tspan">resolver</tspan></tspan><tspan class="text-outer-tspan row" x="0" y="2.1em"><tspan class="text-inner-tspan">suppresses</tspan><tspan class="text-inner-tspan"> covered</tspan><tspan class="text-inner-tspan"> topics</tspan></tspan></text></g></g></g></g></g></g><defs></defs><defs></defs></svg></figure>
1446
1446
  <p>Three real hooks sit beside the two arms: the <strong>phase-audit hook</strong> (runs Lens H
1447
1447
  only, never Lens I), the <strong>doc-conformance MMR channel</strong> (routes Lens I findings
1448
1448
  into MMR), and the <strong><code>--fix</code> flow</strong> (initial + verifier + postfix audit). They
@@ -1993,7 +1993,7 @@ maintainers want this URL to be the verbatim grounding for a P0/P1 finding?"</p>
1993
1993
  <h3 id="most-cited-hosts">Most-cited hosts</h3>
1994
1994
  <p>Counted live from every entry's <code>sources[*].url</code> at build time.</p>
1995
1995
 
1996
- <div class="chart-block"><div class="chart chart-bar"><div class="chart-row" aria-label="martinfowler.com: 37"><span class="chart-label">martinfowler.com</span><div class="chart-bar" style="width:100%"></div></div><div class="chart-row" aria-label="developer.mozilla.org: 24"><span class="chart-label">developer.mozilla.org</span><div class="chart-bar" style="width:65%"></div></div><div class="chart-row" aria-label="owasp.org: 17"><span class="chart-label">owasp.org</span><div class="chart-bar" style="width:46%"></div></div><div class="chart-row" aria-label="developer.android.com: 15"><span class="chart-label">developer.android.com</span><div class="chart-bar" style="width:41%"></div></div><div class="chart-row" aria-label="the-turing-way.netlify.app: 15"><span class="chart-label">the-turing-way.netlify.app</span><div class="chart-bar" style="width:41%"></div></div><div class="chart-row" aria-label="developer.apple.com: 14"><span class="chart-label">developer.apple.com</span><div class="chart-bar" style="width:38%"></div></div><div class="chart-row" aria-label="developer.chrome.com: 14"><span class="chart-label">developer.chrome.com</span><div class="chart-bar" style="width:38%"></div></div><div class="chart-row" aria-label="sre.google: 12"><span class="chart-label">sre.google</span><div class="chart-bar" style="width:32%"></div></div><div class="chart-row" aria-label="w3.org: 12"><span class="chart-label">w3.org</span><div class="chart-bar" style="width:32%"></div></div><div class="chart-row" aria-label="microservices.io: 11"><span class="chart-label">microservices.io</span><div class="chart-bar" style="width:30%"></div></div><div class="chart-row" aria-label="ethereum.org: 10"><span class="chart-label">ethereum.org</span><div class="chart-bar" style="width:27%"></div></div><div class="chart-row" aria-label="rfc-editor.org: 10"><span class="chart-label">rfc-editor.org</span><div class="chart-bar" style="width:27%"></div></div><div class="chart-row" aria-label="consensys.github.io: 9"><span class="chart-label">consensys.github.io</span><div class="chart-bar" style="width:24%"></div></div><div class="chart-row" aria-label="docs.openzeppelin.com: 9"><span class="chart-label">docs.openzeppelin.com</span><div class="chart-bar" style="width:24%"></div></div><div class="chart-row" aria-label="opentelemetry.io: 9"><span class="chart-label">opentelemetry.io</span><div class="chart-bar" style="width:24%"></div></div></div>
1996
+ <div class="chart-block"><div class="chart chart-bar"><div class="chart-row" aria-label="martinfowler.com: 37"><span class="chart-label">martinfowler.com</span><div class="chart-bar" style="width:100%"></div></div><div class="chart-row" aria-label="developer.mozilla.org: 24"><span class="chart-label">developer.mozilla.org</span><div class="chart-bar" style="width:65%"></div></div><div class="chart-row" aria-label="modelcontextprotocol.io: 19"><span class="chart-label">modelcontextprotocol.io</span><div class="chart-bar" style="width:51%"></div></div><div class="chart-row" aria-label="owasp.org: 17"><span class="chart-label">owasp.org</span><div class="chart-bar" style="width:46%"></div></div><div class="chart-row" aria-label="developer.android.com: 15"><span class="chart-label">developer.android.com</span><div class="chart-bar" style="width:41%"></div></div><div class="chart-row" aria-label="the-turing-way.netlify.app: 15"><span class="chart-label">the-turing-way.netlify.app</span><div class="chart-bar" style="width:41%"></div></div><div class="chart-row" aria-label="developer.apple.com: 14"><span class="chart-label">developer.apple.com</span><div class="chart-bar" style="width:38%"></div></div><div class="chart-row" aria-label="developer.chrome.com: 14"><span class="chart-label">developer.chrome.com</span><div class="chart-bar" style="width:38%"></div></div><div class="chart-row" aria-label="sre.google: 12"><span class="chart-label">sre.google</span><div class="chart-bar" style="width:32%"></div></div><div class="chart-row" aria-label="w3.org: 12"><span class="chart-label">w3.org</span><div class="chart-bar" style="width:32%"></div></div><div class="chart-row" aria-label="microservices.io: 11"><span class="chart-label">microservices.io</span><div class="chart-bar" style="width:30%"></div></div><div class="chart-row" aria-label="rfc-editor.org: 11"><span class="chart-label">rfc-editor.org</span><div class="chart-bar" style="width:30%"></div></div><div class="chart-row" aria-label="ethereum.org: 10"><span class="chart-label">ethereum.org</span><div class="chart-bar" style="width:27%"></div></div><div class="chart-row" aria-label="consensys.github.io: 9"><span class="chart-label">consensys.github.io</span><div class="chart-bar" style="width:24%"></div></div><div class="chart-row" aria-label="docs.openzeppelin.com: 9"><span class="chart-label">docs.openzeppelin.com</span><div class="chart-bar" style="width:24%"></div></div></div>
1997
1997
 
1998
1998
 
1999
1999
 
@@ -2062,7 +2062,7 @@ maintainers want this URL to be the verbatim grounding for a P0/P1 finding?"</p>
2062
2062
 
2063
2063
 
2064
2064
 
2065
- <table><thead><tr><th>Host</th><th>Citations</th></tr></thead><tbody><tr><td>martinfowler.com</td><td>37</td></tr><tr><td>developer.mozilla.org</td><td>24</td></tr><tr><td>owasp.org</td><td>17</td></tr><tr><td>developer.android.com</td><td>15</td></tr><tr><td>the-turing-way.netlify.app</td><td>15</td></tr><tr><td>developer.apple.com</td><td>14</td></tr><tr><td>developer.chrome.com</td><td>14</td></tr><tr><td>sre.google</td><td>12</td></tr><tr><td>w3.org</td><td>12</td></tr><tr><td>microservices.io</td><td>11</td></tr><tr><td>ethereum.org</td><td>10</td></tr><tr><td>rfc-editor.org</td><td>10</td></tr><tr><td>consensys.github.io</td><td>9</td></tr><tr><td>docs.openzeppelin.com</td><td>9</td></tr><tr><td>opentelemetry.io</td><td>9</td></tr></tbody></table></div>
2065
+ <table><thead><tr><th>Host</th><th>Citations</th></tr></thead><tbody><tr><td>martinfowler.com</td><td>37</td></tr><tr><td>developer.mozilla.org</td><td>24</td></tr><tr><td>modelcontextprotocol.io</td><td>19</td></tr><tr><td>owasp.org</td><td>17</td></tr><tr><td>developer.android.com</td><td>15</td></tr><tr><td>the-turing-way.netlify.app</td><td>15</td></tr><tr><td>developer.apple.com</td><td>14</td></tr><tr><td>developer.chrome.com</td><td>14</td></tr><tr><td>sre.google</td><td>12</td></tr><tr><td>w3.org</td><td>12</td></tr><tr><td>microservices.io</td><td>11</td></tr><tr><td>rfc-editor.org</td><td>11</td></tr><tr><td>ethereum.org</td><td>10</td></tr><tr><td>consensys.github.io</td><td>9</td></tr><tr><td>docs.openzeppelin.com</td><td>9</td></tr></tbody></table></div>
2066
2066
 
2067
2067
  <h3 id="the-full-allowlist">The full allowlist</h3>
2068
2068
  <p>Every host plus its category, and the pinned GitHub repos.</p>
@@ -2271,7 +2271,7 @@ maintainers want this URL to be the verbatim grounding for a P0/P1 finding?"</p>
2271
2271
  <h3 id="kb-inventory">KB inventory</h3>
2272
2272
  <p>Totals over <code>content/knowledge/</code>, broken down per category.</p>
2273
2273
 
2274
- <p><strong>266 entries</strong> across 19 categories:</p>
2274
+ <p><strong>278 entries</strong> across 20 categories:</p>
2275
2275
 
2276
2276
 
2277
2277
 
@@ -2357,7 +2357,11 @@ maintainers want this URL to be the verbatim grounding for a P0/P1 finding?"</p>
2357
2357
 
2358
2358
 
2359
2359
 
2360
- <table><thead><tr><th>Category</th><th>Entries</th></tr></thead><tbody><tr><td>core</td><td>35</td></tr><tr><td>game</td><td>25</td></tr><tr><td>research</td><td>25</td></tr><tr><td>backend</td><td>22</td></tr><tr><td>review</td><td>20</td></tr><tr><td>web-app</td><td>17</td></tr><tr><td>web3</td><td>14</td></tr><tr><td>data-science</td><td>13</td></tr><tr><td>browser-extension</td><td>12</td></tr><tr><td>data-pipeline</td><td>12</td></tr><tr><td>library</td><td>12</td></tr><tr><td>ml</td><td>12</td></tr><tr><td>mobile-app</td><td>12</td></tr><tr><td>cli</td><td>10</td></tr><tr><td>validation</td><td>7</td></tr><tr><td>product</td><td>6</td></tr><tr><td>execution</td><td>5</td></tr><tr><td>tools</td><td>4</td></tr><tr><td>finalization</td><td>3</td></tr></tbody></table>
2360
+
2361
+
2362
+
2363
+
2364
+ <table><thead><tr><th>Category</th><th>Entries</th></tr></thead><tbody><tr><td>core</td><td>35</td></tr><tr><td>game</td><td>25</td></tr><tr><td>research</td><td>25</td></tr><tr><td>backend</td><td>22</td></tr><tr><td>review</td><td>20</td></tr><tr><td>web-app</td><td>17</td></tr><tr><td>web3</td><td>14</td></tr><tr><td>data-science</td><td>13</td></tr><tr><td>browser-extension</td><td>12</td></tr><tr><td>data-pipeline</td><td>12</td></tr><tr><td>library</td><td>12</td></tr><tr><td>mcp-server</td><td>12</td></tr><tr><td>ml</td><td>12</td></tr><tr><td>mobile-app</td><td>12</td></tr><tr><td>cli</td><td>10</td></tr><tr><td>validation</td><td>7</td></tr><tr><td>product</td><td>6</td></tr><tr><td>execution</td><td>5</td></tr><tr><td>tools</td><td>4</td></tr><tr><td>finalization</td><td>3</td></tr></tbody></table>
2361
2365
 
2362
2366
  <h3 id="how-to-expand-the-allowlist">How to expand the allowlist</h3>
2363
2367
  <p>Adding a host is a one-line PR to
@@ -75,7 +75,7 @@ grounded LLM"]
75
75
  end
76
76
  subgraph gap[Gap arm]
77
77
  TAIL["gap-signal-tail
78
- 89 pipeline steps"] --> EVENT["scaffold observe event
78
+ 90 pipeline steps"] --> EVENT["scaffold observe event
79
79
  knowledge_gap_signal"]
80
80
  EVENT --> LEDGER["ledger
81
81
  activity.jsonl"]
@@ -519,6 +519,7 @@ Counted live from every entry's `sources[*].url` at build time.
519
519
  | --- | --- |
520
520
  | martinfowler.com | 37 |
521
521
  | developer.mozilla.org | 24 |
522
+ | modelcontextprotocol.io | 19 |
522
523
  | owasp.org | 17 |
523
524
  | developer.android.com | 15 |
524
525
  | the-turing-way.netlify.app | 15 |
@@ -527,11 +528,10 @@ Counted live from every entry's `sources[*].url` at build time.
527
528
  | sre.google | 12 |
528
529
  | w3.org | 12 |
529
530
  | microservices.io | 11 |
531
+ | rfc-editor.org | 11 |
530
532
  | ethereum.org | 10 |
531
- | rfc-editor.org | 10 |
532
533
  | consensys.github.io | 9 |
533
534
  | docs.openzeppelin.com | 9 |
534
- | opentelemetry.io | 9 |
535
535
  :::
536
536
  <!-- /gen:host-citations -->
537
537
 
@@ -602,7 +602,7 @@ Every host plus its category, and the pinned GitHub repos.
602
602
  Totals over `content/knowledge/`, broken down per category.
603
603
 
604
604
  <!-- gen:kb-inventory -->
605
- **266 entries** across 19 categories:
605
+ **278 entries** across 20 categories:
606
606
 
607
607
  | Category | Entries |
608
608
  | --- | --- |
@@ -617,6 +617,7 @@ Totals over `content/knowledge/`, broken down per category.
617
617
  | browser-extension | 12 |
618
618
  | data-pipeline | 12 |
619
619
  | library | 12 |
620
+ | mcp-server | 12 |
620
621
  | ml | 12 |
621
622
  | mobile-app | 12 |
622
623
  | cli | 10 |
@@ -1380,11 +1380,11 @@ test run.</p>
1380
1380
  <p>A <strong>git worktree</strong> solves this: it is an independent working directory backed by
1381
1381
  the <em>same</em> <code>.git</code> repository. Each agent gets its own files and its own checked-out
1382
1382
  branch, but commits, refs and history are shared. The layout is one primary
1383
- checkout plus one sibling directory per agent:</p>
1384
- <pre><code class="language-text">~/projects/
1385
- ├── scaffold/ # primary checkout (you work here)
1386
- ├── scaffold-alpha/ # worktree for agent "alpha"
1387
- └── scaffold-beta/ # worktree for agent "beta"
1383
+ checkout with all agent worktrees project-local under <code>.worktrees/</code>:</p>
1384
+ <pre><code class="language-text">scaffold/ # primary checkout (you work here)
1385
+ └── .worktrees/ # agent worktrees (gitignored)
1386
+ ├── alpha/ # worktree for agent "alpha"
1387
+ └── beta/ # worktree for agent "beta"
1388
1388
  </code></pre>
1389
1389
  <p>So worktrees give you <strong>filesystem isolation with a shared object store</strong>:
1390
1390
  agents never overwrite each other's working files, but a PR merged from one
@@ -1398,20 +1398,21 @@ branch.</p></div>
1398
1398
  one parallel agent. Given a name like <code>alpha</code>, it:</p>
1399
1399
  <ol>
1400
1400
  <li><strong>Normalizes the name</strong> to a lowercase, hyphenated, alphanumeric slug (so
1401
- <code>Agent_1</code> becomes <code>agent-1</code>), then derives the worktree directory as a
1402
- <em>sibling</em> of the primary repo: <code>../&#x3C;repo-name>-&#x3C;slug></code>.</li>
1401
+ <code>Agent_1</code> becomes <code>agent-1</code>), then derives the worktree directory project-local
1402
+ under the primary repo: <code>.worktrees/&#x3C;slug></code>. It also ensures <code>.worktrees/</code> is
1403
+ gitignored so the worktree's checkout is never accidentally committed.</li>
1403
1404
  <li><strong>Creates the workspace branch</strong> <code>&#x3C;slug>-workspace</code> if it does not already
1404
- exist <span class="fp" data-path="scripts/setup-agent-worktree.sh:40">scripts/setup-agent-worktree.sh:40</span>, then adds the worktree on
1405
- that branch <span class="fp" data-path="scripts/setup-agent-worktree.sh:44">scripts/setup-agent-worktree.sh:44</span>. Re-running for an
1405
+ exist <span class="fp" data-path="scripts/setup-agent-worktree.sh:62">scripts/setup-agent-worktree.sh:62</span>, then adds the worktree on
1406
+ that branch <span class="fp" data-path="scripts/setup-agent-worktree.sh:65">scripts/setup-agent-worktree.sh:65</span>. Re-running for an
1406
1407
  existing worktree is a safe no-op.</li>
1407
1408
  <li><strong>Writes <code>.scaffold/identity.json</code></strong> — the stable identity that build
1408
1409
  observability stamps onto every event this worktree records. The script
1409
- creates <code>.scaffold/</code> <span class="fp" data-path="scripts/setup-agent-worktree.sh:52">scripts/setup-agent-worktree.sh:52</span> and, only if no
1410
+ creates <code>.scaffold/</code> <span class="fp" data-path="scripts/setup-agent-worktree.sh:73">scripts/setup-agent-worktree.sh:73</span> and, only if no
1410
1411
  identity file exists yet, writes <code>worktree_id</code> (a UUID), <code>worktree_label</code>
1411
1412
  (the agent slug), and <code>created_at</code>
1412
- <span class="fp" data-path="scripts/setup-agent-worktree.sh:71">scripts/setup-agent-worktree.sh:71</span>.</li>
1413
+ <span class="fp" data-path="scripts/setup-agent-worktree.sh:92">scripts/setup-agent-worktree.sh:92</span>.</li>
1413
1414
  <li><strong>Re-syncs Beads</strong> with a fail-soft <code>bd doctor --fix</code> when a <code>.beads/</code>
1414
- directory is present <span class="fp" data-path="scripts/setup-agent-worktree.sh:88">scripts/setup-agent-worktree.sh:88</span>, reconciling the
1415
+ directory is present <span class="fp" data-path="scripts/setup-agent-worktree.sh:109">scripts/setup-agent-worktree.sh:109</span>, reconciling the
1415
1416
  worktree's Beads git hooks and project config against the installed <code>bd</code>
1416
1417
  version. (Beads DB sharing is automatic — worktrees discover the main repo's
1417
1418
  task DB via git's common directory, so there is nothing for <code>bd doctor</code> to
@@ -1467,8 +1468,8 @@ into needless conflicts.</li>
1467
1468
  </ul>
1468
1469
  <p>Each agent otherwise follows the standard PR workflow from its own worktree:
1469
1470
  branch, commit, push, <code>gh pr create</code>, wait for CI, squash-merge. The shared
1470
- object store means a merge from <code>scaffold-alpha</code> is on <code>main</code> for everyone the
1471
- moment it lands.</p>
1471
+ object store means a merge from agent <code>alpha</code>'s worktree is on <code>main</code> for
1472
+ everyone the moment it lands.</p>
1472
1473
  <h2 id="teardown-harvest">Teardown &#x26; harvest</h2>
1473
1474
  <p>When an agent's work is merged, retire its worktree. The single command for this
1474
1475
  is <code>scripts/teardown-agent-worktree.sh &#x3C;worktree-path></code>, and the <strong>order of
@@ -1529,7 +1530,7 @@ worktree — the CLI rejects a worktree primary root
1529
1530
  morning — does <strong>not</strong> mean re-running setup. The worktree and its
1530
1531
  <code>identity.json</code> persist on disk. Instead:</p>
1531
1532
  <ol>
1532
- <li>Return to the agent's worktree directory (<code>../&#x3C;repo>-&#x3C;agent></code>).</li>
1533
+ <li>Return to the agent's worktree directory (<code>.worktrees/&#x3C;agent></code>).</li>
1533
1534
  <li>Run <strong><code>multi-agent-resume &#x3C;agent-name></code></strong> (or <code>single-agent-resume</code> for the
1534
1535
  non-worktree case). It verifies the worktree environment, syncs with <code>main</code>,
1535
1536
  reconciles task status against any PRs merged while you were away, and
@@ -18,13 +18,13 @@ test run.
18
18
  A **git worktree** solves this: it is an independent working directory backed by
19
19
  the *same* `.git` repository. Each agent gets its own files and its own checked-out
20
20
  branch, but commits, refs and history are shared. The layout is one primary
21
- checkout plus one sibling directory per agent:
21
+ checkout with all agent worktrees project-local under `.worktrees/`:
22
22
 
23
23
  ```text
24
- ~/projects/
25
- ├── scaffold/ # primary checkout (you work here)
26
- ├── scaffold-alpha/ # worktree for agent "alpha"
27
- └── scaffold-beta/ # worktree for agent "beta"
24
+ scaffold/ # primary checkout (you work here)
25
+ └── .worktrees/ # agent worktrees (gitignored)
26
+ ├── alpha/ # worktree for agent "alpha"
27
+ └── beta/ # worktree for agent "beta"
28
28
  ```
29
29
 
30
30
  So worktrees give you **filesystem isolation with a shared object store**:
@@ -44,20 +44,21 @@ branch.
44
44
  one parallel agent. Given a name like `alpha`, it:
45
45
 
46
46
  1. **Normalizes the name** to a lowercase, hyphenated, alphanumeric slug (so
47
- `Agent_1` becomes `agent-1`), then derives the worktree directory as a
48
- *sibling* of the primary repo: `../<repo-name>-<slug>`.
47
+ `Agent_1` becomes `agent-1`), then derives the worktree directory project-local
48
+ under the primary repo: `.worktrees/<slug>`. It also ensures `.worktrees/` is
49
+ gitignored so the worktree's checkout is never accidentally committed.
49
50
  2. **Creates the workspace branch** `<slug>-workspace` if it does not already
50
- exist :cite[scripts/setup-agent-worktree.sh:40], then adds the worktree on
51
- that branch :cite[scripts/setup-agent-worktree.sh:44]. Re-running for an
51
+ exist :cite[scripts/setup-agent-worktree.sh:62], then adds the worktree on
52
+ that branch :cite[scripts/setup-agent-worktree.sh:65]. Re-running for an
52
53
  existing worktree is a safe no-op.
53
54
  3. **Writes `.scaffold/identity.json`** — the stable identity that build
54
55
  observability stamps onto every event this worktree records. The script
55
- creates `.scaffold/` :cite[scripts/setup-agent-worktree.sh:52] and, only if no
56
+ creates `.scaffold/` :cite[scripts/setup-agent-worktree.sh:73] and, only if no
56
57
  identity file exists yet, writes `worktree_id` (a UUID), `worktree_label`
57
58
  (the agent slug), and `created_at`
58
- :cite[scripts/setup-agent-worktree.sh:71].
59
+ :cite[scripts/setup-agent-worktree.sh:92].
59
60
  4. **Re-syncs Beads** with a fail-soft `bd doctor --fix` when a `.beads/`
60
- directory is present :cite[scripts/setup-agent-worktree.sh:88], reconciling the
61
+ directory is present :cite[scripts/setup-agent-worktree.sh:109], reconciling the
61
62
  worktree's Beads git hooks and project config against the installed `bd`
62
63
  version. (Beads DB sharing is automatic — worktrees discover the main repo's
63
64
  task DB via git's common directory, so there is nothing for `bd doctor` to
@@ -148,8 +149,8 @@ footprint small and its branches short. The conflict-prevention rules from
148
149
 
149
150
  Each agent otherwise follows the standard PR workflow from its own worktree:
150
151
  branch, commit, push, `gh pr create`, wait for CI, squash-merge. The shared
151
- object store means a merge from `scaffold-alpha` is on `main` for everyone the
152
- moment it lands.
152
+ object store means a merge from agent `alpha`'s worktree is on `main` for
153
+ everyone the moment it lands.
153
154
 
154
155
  ## Teardown & harvest
155
156
 
@@ -225,7 +226,7 @@ Coming back to parallel work — a context reset, a paused session, the next
225
226
  morning — does **not** mean re-running setup. The worktree and its
226
227
  `identity.json` persist on disk. Instead:
227
228
 
228
- 1. Return to the agent's worktree directory (`../<repo>-<agent>`).
229
+ 1. Return to the agent's worktree directory (`.worktrees/<agent>`).
229
230
  2. Run **`multi-agent-resume <agent-name>`** (or `single-agent-resume` for the
230
231
  non-worktree case). It verifies the worktree environment, syncs with `main`,
231
232
  reconciles task status against any PRs merged while you were away, and
@@ -1392,7 +1392,7 @@ run these <em>over and over</em> while actually writing code.</li>
1392
1392
  <p>The 16 phases are the single source of truth in code: the <code>PHASES</code> constant
1393
1393
  (<span class="fp" data-path="src/types/frontmatter.ts:6">src/types/frontmatter.ts:6</span>) defines every slug, number, and display
1394
1394
  name. Everything in this guide is anchored to it.</p>
1395
- <div class="callout callout-note"><p><strong>89 meta-prompts, not 89 steps you run.</strong> The pipeline directory holds 89 files
1395
+ <div class="callout callout-note"><p><strong>90 meta-prompts, not 90 steps you run.</strong> The pipeline directory holds 90 files
1396
1396
  across 16 phase directories, but most projects run only a fraction. Game,
1397
1397
  multi-service, and platform-specific steps are disabled unless an overlay turns
1398
1398
  them on, and many steps are conditional (see <a href="#methodology--depth">Methodology &#x26; depth</a>).</p></div>
@@ -1799,7 +1799,7 @@ how that audit works and what the nine lenses check.</p>
1799
1799
 
1800
1800
 
1801
1801
 
1802
- <table><thead><tr><th>path</th><th>what it holds</th></tr></thead><tbody><tr><td><code>content/pipeline/&#x3C;phase>/*.md</code></td><td>The 89 meta-prompt files, one directory per phase</td></tr><tr><td><code>content/methodology/*.yml</code></td><td>Presets (<code>mvp</code>, <code>custom-defaults</code>, <code>deep</code>) + project-type overlays</td></tr><tr><td><code>content/knowledge/</code></td><td>Domain entries injected into prompts during assembly</td></tr><tr><td><code>src/types/frontmatter.ts</code></td><td>The canonical <code>PHASES</code> constant + frontmatter schema</td></tr><tr><td><code>src/cli/commands/</code></td><td><code>next</code>, <code>run</code>, <code>complete</code>, <code>skip</code>, <code>rework</code>, <code>reset</code>, <code>status</code></td></tr><tr><td><code>.scaffold/state.json</code></td><td>Per-step completion state (planning phases only)</td></tr></tbody></table>
1802
+ <table><thead><tr><th>path</th><th>what it holds</th></tr></thead><tbody><tr><td><code>content/pipeline/&#x3C;phase>/*.md</code></td><td>The 90 meta-prompt files, one directory per phase</td></tr><tr><td><code>content/methodology/*.yml</code></td><td>Presets (<code>mvp</code>, <code>custom-defaults</code>, <code>deep</code>) + project-type overlays</td></tr><tr><td><code>content/knowledge/</code></td><td>Domain entries injected into prompts during assembly</td></tr><tr><td><code>src/types/frontmatter.ts</code></td><td>The canonical <code>PHASES</code> constant + frontmatter schema</td></tr><tr><td><code>src/cli/commands/</code></td><td><code>next</code>, <code>run</code>, <code>complete</code>, <code>skip</code>, <code>rework</code>, <code>reset</code>, <code>status</code></td></tr><tr><td><code>.scaffold/state.json</code></td><td>Per-step completion state (planning phases only)</td></tr></tbody></table>
1803
1803
  <p>The phase list, ordering, and slugs are defined exactly once, in <code>PHASES</code>
1804
1804
  (<span class="fp" data-path="src/types/frontmatter.ts:6">src/types/frontmatter.ts:6</span>); every doc, skill, and command resolves
1805
1805
  against it.</p></main>
@@ -32,7 +32,7 @@ The 16 phases are the single source of truth in code: the `PHASES` constant
32
32
  name. Everything in this guide is anchored to it.
33
33
 
34
34
  :::callout{type=note}
35
- **89 meta-prompts, not 89 steps you run.** The pipeline directory holds 89 files
35
+ **90 meta-prompts, not 90 steps you run.** The pipeline directory holds 90 files
36
36
  across 16 phase directories, but most projects run only a fraction. Game,
37
37
  multi-service, and platform-specific steps are disabled unless an overlay turns
38
38
  them on, and many steps are conditional (see [Methodology & depth](#methodology--depth)).
@@ -375,7 +375,7 @@ how that audit works and what the nine lenses check.
375
375
 
376
376
  | path | what it holds |
377
377
  | --- | --- |
378
- | `content/pipeline/<phase>/*.md` | The 89 meta-prompt files, one directory per phase |
378
+ | `content/pipeline/<phase>/*.md` | The 90 meta-prompt files, one directory per phase |
379
379
  | `content/methodology/*.yml` | Presets (`mvp`, `custom-defaults`, `deep`) + project-type overlays |
380
380
  | `content/knowledge/` | Domain entries injected into prompts during assembly |
381
381
  | `src/types/frontmatter.ts` | The canonical `PHASES` constant + frontmatter schema |
@@ -17,7 +17,7 @@ Expert knowledge for managing git worktrees to enable parallel multi-agent execu
17
17
 
18
18
  ### Setup
19
19
 
20
- Use `scripts/setup-agent-worktree.sh <agent-name>` to create a worktree at `../<project>-<agent-name>/`. Each agent gets its own isolated working directory and workspace branch.
20
+ Use `scripts/setup-agent-worktree.sh <agent-name>` to create a worktree at `.worktrees/<agent-name>/` (project-local). Each agent gets its own isolated working directory and workspace branch.
21
21
 
22
22
  ### Branching Conventions
23
23
 
@@ -40,12 +40,12 @@ After all agents finish, remove worktrees and prune stale references. Delete mer
40
40
  scripts/setup-agent-worktree.sh agent-1
41
41
 
42
42
  # This creates:
43
- # ../<project>-agent-1/ (working directory)
43
+ # .worktrees/agent-1/ (working directory, project-local)
44
44
  # Branch: agent-1-workspace (workspace branch)
45
45
  ```
46
46
 
47
47
  **What the setup script does:**
48
- 1. Creates a new worktree directory adjacent to the main repo
48
+ 1. Creates a new worktree directory project-local under `.worktrees/`
49
49
  2. Creates a workspace branch for the agent
50
50
  3. Sets up the working directory with a clean state
51
51
  4. Installs dependencies if a package manager is detected
@@ -154,7 +154,7 @@ git rebase origin/main
154
154
 
155
155
  ```bash
156
156
  # From the main repository (not from inside the worktree)
157
- git worktree remove ../<project>-agent-1
157
+ git worktree remove .worktrees/agent-1
158
158
  ```
159
159
 
160
160
  **Pruning stale worktree references:**
@@ -0,0 +1,100 @@
1
+ ---
2
+ name: mcp-authentication
3
+ description: MCP authentication patterns — stdio local trust model, OAuth 2.1 for HTTP transports, PKCE, dynamic client registration, API key alternatives, and token validation
4
+ topics: [mcp, authentication, oauth, security, authorization]
5
+ volatility: evolving
6
+ last-reviewed: null
7
+ version-pin: 'MCP spec 2025-11-25; OAuth 2.1 draft-ietf-oauth-v2-1-13'
8
+ sources:
9
+ - url: https://modelcontextprotocol.io/specification/2025-11-25/basic/authorization
10
+ - url: https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-13
11
+ - url: https://datatracker.ietf.org/doc/html/rfc7591
12
+ - url: https://www.rfc-editor.org/rfc/rfc8707.html
13
+ ---
14
+
15
+ Authentication in MCP is transport-dependent. stdio servers rely on OS process isolation (no network auth needed). HTTP servers should use OAuth 2.1 for multi-user or multi-tenant scenarios, or simpler API key patterns for internal/single-tenant deployments.
16
+
17
+ ## Summary
18
+
19
+ **stdio transport**: no network authentication — the server inherits credentials from environment variables and the OS controls process access. **Streamable HTTP transport**: use OAuth 2.1 (per spec) for public or multi-user servers. OAuth flow: client hits protected resource, gets 401 with `WWW-Authenticate`, discovers authorization server via OAuth Protected Resource Metadata, completes OAuth 2.1 with PKCE, presents `Bearer` token on all subsequent requests. For simpler deployments, API keys in headers or environment-injected tokens are practical alternatives. The spec mandates `MCP-Protocol-Version` on HTTP requests and audience validation on tokens.
20
+
21
+ ## Deep Guidance
22
+
23
+ ### stdio: local trust model
24
+
25
+ The stdio transport requires no network authentication. Trust is established by OS-level process ownership: the client spawns the server as a subprocess, which means both run under the same user account. The server process inherits environment variables from the parent, which is the standard mechanism for passing API keys, database credentials, or access tokens to a local MCP server:
26
+
27
+ ```json
28
+ {
29
+ "mcpServers": {
30
+ "my-server": {
31
+ "command": "npx",
32
+ "args": ["my-mcp-server"],
33
+ "env": {
34
+ "DATABASE_URL": "postgresql://localhost/mydb",
35
+ "API_KEY": "sk-..."
36
+ }
37
+ }
38
+ }
39
+ }
40
+ ```
41
+
42
+ The spec is explicit: implementations using stdio SHOULD NOT follow the OAuth specification and SHOULD instead retrieve credentials from the environment. Do not add HTTP authentication middleware to a stdio server.
43
+
44
+ ### OAuth 2.1 for HTTP transports
45
+
46
+ For Streamable HTTP servers accessible over a network, the spec defines an OAuth 2.1 authorization flow. The server acts as an OAuth 2.1 **resource server**; a separate authorization server handles token issuance.
47
+
48
+ **Discovery flow (updated in 2025-11-25 per RFC 9728 and OIDC Discovery 1.0):**
49
+ 1. Client sends an unauthenticated MCP request.
50
+ 2. Server MAY respond `401 Unauthorized` with a `WWW-Authenticate` header pointing to the resource server metadata URL; however, the `WWW-Authenticate` header is now OPTIONAL — clients MUST fall back to fetching `/.well-known/oauth-protected-resource` directly if no header is present.
51
+ 3. Client fetches `/.well-known/oauth-protected-resource` (RFC 9728) to get the authorization server URL.
52
+ 4. Client fetches the authorization server's metadata. Authorization servers that support OpenID Connect SHOULD publish an OIDC Discovery document (`/.well-known/openid-configuration`) in addition to `/.well-known/oauth-authorization-server`.
53
+ 5. Client completes the OAuth 2.1 authorization code flow with PKCE. Clients SHOULD use OAuth Client ID Metadata Documents (a recommended client registration mechanism in 2025-11-25) where supported by the authorization server.
54
+ 6. Client presents `Authorization: Bearer <token>` on all subsequent requests. Servers MAY issue incremental scope consent via the `WWW-Authenticate` header on subsequent `403` responses.
55
+
56
+ **PKCE is mandatory** for public clients (MCP clients cannot keep secrets). The authorization server MUST support PKCE. The client generates a `code_verifier` (random string), hashes it to `code_challenge`, includes the challenge in the authorization request, and presents the verifier in the token request.
57
+
58
+ **Resource parameter** (RFC 8707): clients MUST include a `resource` parameter in both authorization and token requests identifying the MCP server's canonical URI (e.g., `https://mcp.example.com`). This binds tokens to their intended audience and prevents cross-service token reuse.
59
+
60
+ ### Token validation requirements
61
+
62
+ MCP servers MUST validate every incoming access token:
63
+ - Verify the token is valid and not expired.
64
+ - Verify the token's audience claim identifies this server (matches the server's canonical URI).
65
+ - Reject tokens with `401` if invalid or expired; `403` if the token is valid but lacks required scope.
66
+
67
+ NEVER accept tokens issued for a different resource. NEVER forward a received token to an upstream API — issue a separate token for each upstream call. Token passthrough is explicitly forbidden by the spec and creates confused deputy vulnerabilities.
68
+
69
+ ### Dynamic client registration
70
+
71
+ Authorization servers and clients SHOULD support OAuth 2.0 Dynamic Client Registration (RFC 7591). As of 2025-11-25, OAuth Client ID Metadata Documents are the recommended client registration mechanism — they allow clients to declare their identity via a URL rather than requiring a registration round-trip. Without dynamic registration support, MCP clients must be pre-registered with every authorization server, which creates friction for discovering and connecting to new servers. Dynamic registration lets a client auto-register on first connection:
72
+
73
+ ```
74
+ POST /register
75
+ { "client_name": "Claude Desktop", "redirect_uris": ["http://localhost:57842/callback"] }
76
+ → { "client_id": "abc123", ... }
77
+ ```
78
+
79
+ If the authorization server does not support dynamic registration, the client must hardcode a client ID or present a UI for manual credential entry.
80
+
81
+ ### Simpler alternatives for private/internal deployments
82
+
83
+ For servers used only within a controlled environment (team tool, internal service), full OAuth is often unnecessary overhead. Practical alternatives:
84
+
85
+ **API key in header**: The client includes a static API key in a custom header or as a Bearer token. The server validates it against a stored secret. Simple, easy to rotate, no token exchange flow.
86
+
87
+ **Mutual TLS**: Suitable for service-to-service scenarios where both sides have certificates. The TLS handshake authenticates both parties.
88
+
89
+ **Reverse proxy with auth**: Run the MCP server behind nginx/Caddy/Cloudflare with authentication handled at the proxy layer. The server itself trusts all proxied connections.
90
+
91
+ **Network isolation**: For truly internal deployments, rely on network controls (VPN, private subnet, firewall rules) and skip application-layer auth. Acceptable only when the network boundary is the full security boundary.
92
+
93
+ ### Security hardening checklist
94
+
95
+ - Validate the `Origin` header on all Streamable HTTP connections to prevent DNS rebinding attacks.
96
+ - Use HTTPS for all HTTP transport connections (required by OAuth 2.1 for authorization server endpoints and redirect URIs).
97
+ - Bind local HTTP servers to 127.0.0.1, not 0.0.0.0.
98
+ - Rotate API keys and tokens regularly; issue short-lived access tokens.
99
+ - Log all authentication failures with enough context to diagnose attacks.
100
+ - Do not embed credentials in resource URIs (they appear in logs and referrer headers).