@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.
- package/README.md +42 -19
- package/content/guides/knowledge-freshness/.diagrams/diagram-0.svg +1 -1
- package/content/guides/knowledge-freshness/.diagrams/manifest.json +1 -1
- package/content/guides/knowledge-freshness/index.html +9 -5
- package/content/guides/knowledge-freshness/index.md +5 -4
- package/content/guides/multi-agent/index.html +16 -15
- package/content/guides/multi-agent/index.md +16 -15
- package/content/guides/pipeline/index.html +2 -2
- package/content/guides/pipeline/index.md +2 -2
- package/content/knowledge/execution/worktree-management.md +4 -4
- package/content/knowledge/mcp-server/mcp-authentication.md +100 -0
- package/content/knowledge/mcp-server/mcp-deployment-patterns.md +119 -0
- package/content/knowledge/mcp-server/mcp-error-handling.md +131 -0
- package/content/knowledge/mcp-server/mcp-observability.md +125 -0
- package/content/knowledge/mcp-server/mcp-prompt-primitives.md +119 -0
- package/content/knowledge/mcp-server/mcp-protocol-fundamentals.md +130 -0
- package/content/knowledge/mcp-server/mcp-resource-design.md +111 -0
- package/content/knowledge/mcp-server/mcp-sdk-selection.md +136 -0
- package/content/knowledge/mcp-server/mcp-testing-strategies.md +127 -0
- package/content/knowledge/mcp-server/mcp-tool-design.md +125 -0
- package/content/knowledge/mcp-server/mcp-transport-patterns.md +122 -0
- package/content/knowledge/mcp-server/mcp-versioning.md +115 -0
- package/content/methodology/custom-defaults.yml +2 -0
- package/content/methodology/deep.yml +2 -0
- package/content/methodology/mcp-server-overlay.yml +88 -0
- package/content/methodology/mvp.yml +2 -0
- package/content/pipeline/build/multi-agent-resume.md +107 -11
- package/content/pipeline/build/multi-agent-start.md +104 -11
- package/content/pipeline/build/single-agent-resume.md +74 -8
- package/content/pipeline/build/single-agent-start.md +69 -12
- package/content/pipeline/environment/git-workflow.md +8 -2
- package/content/pipeline/finalization/materialize-plan-to-beads.md +473 -0
- package/content/pipeline/foundation/beads.md +6 -0
- package/content/pipeline/planning/implementation-plan-review.md +25 -0
- package/content/pipeline/planning/implementation-plan.md +75 -1
- package/content/pipeline/specification/mcp-tool-resource-contract.md +77 -0
- package/dist/cli/commands/adopt.d.ts.map +1 -1
- package/dist/cli/commands/adopt.js +33 -1
- package/dist/cli/commands/adopt.js.map +1 -1
- package/dist/cli/commands/init.d.ts +6 -0
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +46 -3
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/init-flag-families.d.ts +6 -1
- package/dist/cli/init-flag-families.d.ts.map +1 -1
- package/dist/cli/init-flag-families.js +59 -2
- package/dist/cli/init-flag-families.js.map +1 -1
- package/dist/cli/init-flag-families.test.js +86 -1
- package/dist/cli/init-flag-families.test.js.map +1 -1
- package/dist/config/schema.d.ts +2310 -126
- package/dist/config/schema.d.ts.map +1 -1
- package/dist/config/schema.js +26 -1
- package/dist/config/schema.js.map +1 -1
- package/dist/config/schema.test.js +75 -2
- package/dist/config/schema.test.js.map +1 -1
- package/dist/config/validators/index.d.ts.map +1 -1
- package/dist/config/validators/index.js +2 -0
- package/dist/config/validators/index.js.map +1 -1
- package/dist/config/validators/mcp-server.d.ts +4 -0
- package/dist/config/validators/mcp-server.d.ts.map +1 -0
- package/dist/config/validators/mcp-server.js +37 -0
- package/dist/config/validators/mcp-server.js.map +1 -0
- package/dist/config/validators/mcp-server.test.d.ts +2 -0
- package/dist/config/validators/mcp-server.test.d.ts.map +1 -0
- package/dist/config/validators/mcp-server.test.js +47 -0
- package/dist/config/validators/mcp-server.test.js.map +1 -0
- package/dist/core/assembly/materialize-plan-to-beads-assembly.test.d.ts +2 -0
- package/dist/core/assembly/materialize-plan-to-beads-assembly.test.d.ts.map +1 -0
- package/dist/core/assembly/materialize-plan-to-beads-assembly.test.js +75 -0
- package/dist/core/assembly/materialize-plan-to-beads-assembly.test.js.map +1 -0
- package/dist/e2e/project-type-overlays.test.js +83 -0
- package/dist/e2e/project-type-overlays.test.js.map +1 -1
- package/dist/project/adopt.d.ts.map +1 -1
- package/dist/project/adopt.js +3 -1
- package/dist/project/adopt.js.map +1 -1
- package/dist/project/detectors/coverage.test.js +1 -0
- package/dist/project/detectors/coverage.test.js.map +1 -1
- package/dist/project/detectors/disambiguate.d.ts.map +1 -1
- package/dist/project/detectors/disambiguate.js +6 -1
- package/dist/project/detectors/disambiguate.js.map +1 -1
- package/dist/project/detectors/disambiguate.test.js +18 -0
- package/dist/project/detectors/disambiguate.test.js.map +1 -1
- package/dist/project/detectors/index.d.ts.map +1 -1
- package/dist/project/detectors/index.js +2 -1
- package/dist/project/detectors/index.js.map +1 -1
- package/dist/project/detectors/mcp-server.d.ts +4 -0
- package/dist/project/detectors/mcp-server.d.ts.map +1 -0
- package/dist/project/detectors/mcp-server.js +91 -0
- package/dist/project/detectors/mcp-server.js.map +1 -0
- package/dist/project/detectors/mcp-server.test.d.ts +2 -0
- package/dist/project/detectors/mcp-server.test.d.ts.map +1 -0
- package/dist/project/detectors/mcp-server.test.js +115 -0
- package/dist/project/detectors/mcp-server.test.js.map +1 -0
- package/dist/project/detectors/types.d.ts +6 -2
- package/dist/project/detectors/types.d.ts.map +1 -1
- package/dist/project/detectors/types.js.map +1 -1
- package/dist/project/gitignore.d.ts.map +1 -1
- package/dist/project/gitignore.js +4 -0
- package/dist/project/gitignore.js.map +1 -1
- package/dist/project/gitignore.test.js +1 -0
- package/dist/project/gitignore.test.js.map +1 -1
- package/dist/types/config.d.ts +8 -1
- package/dist/types/config.d.ts.map +1 -1
- package/dist/wizard/copy/core.d.ts.map +1 -1
- package/dist/wizard/copy/core.js +4 -0
- package/dist/wizard/copy/core.js.map +1 -1
- package/dist/wizard/copy/index.d.ts.map +1 -1
- package/dist/wizard/copy/index.js +2 -0
- package/dist/wizard/copy/index.js.map +1 -1
- package/dist/wizard/copy/mcp-server.d.ts +3 -0
- package/dist/wizard/copy/mcp-server.d.ts.map +1 -0
- package/dist/wizard/copy/mcp-server.js +40 -0
- package/dist/wizard/copy/mcp-server.js.map +1 -0
- package/dist/wizard/copy/types.d.ts +5 -1
- package/dist/wizard/copy/types.d.ts.map +1 -1
- package/dist/wizard/flags.d.ts +9 -1
- package/dist/wizard/flags.d.ts.map +1 -1
- package/dist/wizard/questions.d.ts +4 -2
- package/dist/wizard/questions.d.ts.map +1 -1
- package/dist/wizard/questions.js +37 -0
- package/dist/wizard/questions.js.map +1 -1
- package/dist/wizard/questions.test.js +107 -0
- package/dist/wizard/questions.test.js.map +1 -1
- package/dist/wizard/wizard.d.ts +3 -2
- package/dist/wizard/wizard.d.ts.map +1 -1
- package/dist/wizard/wizard.js +3 -1
- package/dist/wizard/wizard.js.map +1 -1
- 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="
|
|
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>
|
|
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>
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
**
|
|
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
|
|
1384
|
-
<pre><code class="language-text"
|
|
1385
|
-
|
|
1386
|
-
├──
|
|
1387
|
-
└──
|
|
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
|
|
1402
|
-
|
|
1401
|
+
<code>Agent_1</code> becomes <code>agent-1</code>), then derives the worktree directory project-local
|
|
1402
|
+
under the primary repo: <code>.worktrees/<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><slug>-workspace</code> if it does not already
|
|
1404
|
-
exist <span class="fp" data-path="scripts/setup-agent-worktree.sh:
|
|
1405
|
-
that branch <span class="fp" data-path="scripts/setup-agent-worktree.sh:
|
|
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:
|
|
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:
|
|
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:
|
|
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>
|
|
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 & 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 <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
|
|
1533
|
+
<li>Return to the agent's worktree directory (<code>.worktrees/<agent></code>).</li>
|
|
1533
1534
|
<li>Run <strong><code>multi-agent-resume <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
|
|
21
|
+
checkout with all agent worktrees project-local under `.worktrees/`:
|
|
22
22
|
|
|
23
23
|
```text
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
├──
|
|
27
|
-
└──
|
|
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
|
|
48
|
-
|
|
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:
|
|
51
|
-
that branch :cite[scripts/setup-agent-worktree.sh:
|
|
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:
|
|
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:
|
|
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:
|
|
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 `
|
|
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 (
|
|
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>
|
|
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 & 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/<phase>/*.md</code></td><td>The
|
|
1802
|
+
<table><thead><tr><th>path</th><th>what it holds</th></tr></thead><tbody><tr><td><code>content/pipeline/<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
|
-
**
|
|
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
|
|
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
|
|
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
|
-
#
|
|
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
|
|
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
|
|
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).
|