diff --git a/.github/workflows/pr-impact.yml b/.github/workflows/pr-impact.yml new file mode 100644 index 00000000..82e737a2 --- /dev/null +++ b/.github/workflows/pr-impact.yml @@ -0,0 +1,133 @@ +name: PR Review Signals +run-name: 'PR impact map #${{ github.event.pull_request.number }}' + +on: + pull_request_target: + types: [opened, synchronize, reopened, ready_for_review, edited] + +permissions: + contents: read + +concurrency: + group: pr-review-signals-${{ github.event.pull_request.number }} + cancel-in-progress: true + +jobs: + analyze: + runs-on: ubuntu-latest + timeout-minutes: 15 + permissions: + contents: read + pull-requests: read + steps: + # Only the trusted controller is checked out. PR objects are fetched as + # data by collect.mjs; never install dependencies or execute code from them. + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + ref: ${{ github.sha }} + persist-credentials: false + fetch-depth: 0 + - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 + with: + node-version: 24 + - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 + with: + python-version: '3.12' + - name: Install trusted analysis tools + run: | + npm ci --ignore-scripts + npm ci --prefix scripts/pr-impact --ignore-scripts + python -m venv "$RUNNER_TEMP/isobar-venv" + "$RUNNER_TEMP/isobar-venv/bin/pip" install -r scripts/pr-impact/requirements.txt + sudo apt-get update + sudo apt-get install -y fonts-dejavu + - name: Fetch pinned Isobar engine + run: | + git clone --filter=blob:none --no-checkout https://github.com/r3al1tym/isobar.git "$RUNNER_TEMP/isobar-engine" + git -C "$RUNNER_TEMP/isobar-engine" checkout --detach 2ec719904ac7dc30de08e152e4622fe8e02fa57a + - name: Compute static review signals + env: + ISOBAR_UPSTREAM: ${{ runner.temp }}/isobar-engine + ISOBAR_PYTHON: ${{ runner.temp }}/isobar-venv/bin/python + REVIEW_REPORT_DIRECTORY: ${{ runner.temp }}/review-report + run: node --import ./scripts/pr-impact/node_modules/tsx/dist/loader.mjs scripts/pr-impact/collect.mjs + - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 + with: + name: review-signals-${{ github.run_attempt }} + path: ${{ runner.temp }}/review-report/ + if-no-files-found: error + retention-days: 7 + + publish: + needs: analyze + runs-on: ubuntu-latest + timeout-minutes: 5 + permissions: + contents: write + pull-requests: write + actions: read + # Share the lock with both existing quality publishers so enrichment and + # static updates cannot overwrite each other concurrently. + concurrency: + group: pr-quality-comment-${{ github.event.pull_request.head.repo.id }}-${{ github.event.pull_request.head.ref }} + cancel-in-progress: false + queue: max + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + ref: ${{ github.sha }} + persist-credentials: false + sparse-checkout-cone-mode: false + sparse-checkout: | + /scripts/complexity-report.mjs + /scripts/publish-complexity-comment.mjs + /scripts/pr-impact/comment.mjs + /scripts/pr-impact/publish.mjs + - uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 + with: + name: review-signals-${{ github.run_attempt }} + path: review-report + - name: Find latest legacy quality under the publication lock + id: latest + uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7 + with: + script: | + const { legacyQualityArtifact } = await import( + `${process.env.GITHUB_WORKSPACE}/scripts/pr-impact/publish.mjs` + ); + const previous = await legacyQualityArtifact({ github, context }); + if (previous) { + core.setOutput('run', previous.runId); + core.setOutput('artifact', previous.artifactName); + } + - uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 + if: steps.latest.outputs.artifact != '' + continue-on-error: true + with: + name: ${{ steps.latest.outputs.artifact }} + path: previous-quality + run-id: ${{ steps.latest.outputs.run }} + github-token: ${{ github.token }} + - uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7 + env: + LEGACY_RUN_ID: ${{ steps.latest.outputs.run }} + LEGACY_ARTIFACT: ${{ steps.latest.outputs.artifact }} + with: + script: | + const { publishReviewSignals } = await import( + `${process.env.GITHUB_WORKSPACE}/scripts/pr-impact/publish.mjs` + ); + await publishReviewSignals({ + github, context, + reportDirectory: `${process.env.GITHUB_WORKSPACE}/review-report`, + warn: core.warning, + loadLegacyQuality: async (selected) => { + if (selected.runId !== Number(process.env.LEGACY_RUN_ID) || + selected.artifactName !== process.env.LEGACY_ARTIFACT) return null; + const { lstat, readFile } = await import("node:fs/promises"); + const path = `${process.env.GITHUB_WORKSPACE}/previous-quality/comparison.json`; + const stat = await lstat(path); + if (!stat.isFile() || stat.size > 20 * 1024 * 1024) return null; + return JSON.parse(await readFile(path, "utf8")); + }, + }); diff --git a/.github/workflows/pr-quality-comment.yml b/.github/workflows/pr-quality-comment.yml index 0ca3f192..48e38cc4 100644 --- a/.github/workflows/pr-quality-comment.yml +++ b/.github/workflows/pr-quality-comment.yml @@ -6,13 +6,14 @@ on: types: [completed] permissions: - contents: read + contents: write actions: read pull-requests: write concurrency: group: pr-quality-comment-${{ github.event.workflow_run.head_repository.id }}-${{ github.event.workflow_run.head_branch }} cancel-in-progress: false + queue: max jobs: comment: @@ -33,6 +34,8 @@ jobs: sparse-checkout: | /scripts/publish-complexity-comment.mjs /scripts/complexity-report.mjs + /scripts/pr-impact/comment.mjs + /scripts/pr-impact/publish.mjs - uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7 id: artifacts with: @@ -45,7 +48,7 @@ jobs: github, repo: context.repo, runId: run.id, attempt: run.run_attempt, }); core.setOutput('report', names.report); - - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4 + - uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 if: steps.artifacts.outputs.report != '' continue-on-error: true with: diff --git a/.github/workflows/pr-quality.yml b/.github/workflows/pr-quality.yml index 5bbff11f..2d96b7fc 100644 --- a/.github/workflows/pr-quality.yml +++ b/.github/workflows/pr-quality.yml @@ -148,23 +148,26 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 5 permissions: - contents: read + contents: write actions: read pull-requests: write concurrency: group: pr-quality-comment-${{ github.event.pull_request.head.repo.id }}-${{ github.event.pull_request.head.ref }} cancel-in-progress: false + queue: max steps: - # Same-repository authors already control this PR workflow. Forks and - # Dependabot use the default-branch publisher in pr-quality-comment.yml. + # Publish with default-branch code only, including for same-repository PRs. + # Contributor code runs only in the read-token analysis/test jobs. - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: - ref: ${{ github.sha }} + ref: ${{ github.event.repository.default_branch }} persist-credentials: false sparse-checkout-cone-mode: false sparse-checkout: | /scripts/publish-complexity-comment.mjs /scripts/complexity-report.mjs + /scripts/pr-impact/comment.mjs + /scripts/pr-impact/publish.mjs - uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7 id: artifacts with: @@ -177,7 +180,7 @@ jobs: attempt: Number(process.env.GITHUB_RUN_ATTEMPT), }); core.setOutput('report', names.report); - - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4 + - uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 if: steps.artifacts.outputs.report != '' continue-on-error: true with: @@ -224,13 +227,13 @@ jobs: }); core.setOutput('base', names.base); core.setOutput('pr', names.pr); - - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4 + - uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 if: steps.artifacts.outputs.base != '' continue-on-error: true with: name: ${{ steps.artifacts.outputs.base }} path: coverage-input/base - - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4 + - uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 if: steps.artifacts.outputs.pr != '' continue-on-error: true with: diff --git a/.gitignore b/.gitignore index 35c57455..61aa308d 100644 --- a/.gitignore +++ b/.gitignore @@ -78,3 +78,9 @@ reports/dependency/ # Local cognitive-complexity analysis reports/complexity/ + +# Generated Isobar previews and local tooling +.isobar/previews/ +.isobar/upstream/ +scripts/pr-impact/.venv/ +scripts/pr-impact/__pycache__/ diff --git a/.isobar/anchors.json b/.isobar/anchors.json new file mode 100644 index 00000000..83911b97 --- /dev/null +++ b/.isobar/anchors.json @@ -0,0 +1,6573 @@ +{ + "version": 1, + "baselineSha": "e9ec7d6161b09ebc02a1a339cc3e41e44c7da04c", + "mapDigest": "9d0f43dcd572f8848c2892d840a5720780906b51685982421dfdce6c4f5f6219", + "algorithm": "isobar-path-loc-baseline-v1", + "files": { + "frontend/src/pages/AccountSettings.tsx": { + "leafId": "ui-pages", + "x": 0.0766279, + "y": 0.1228474 + }, + "frontend/src/pages/AgentPage.tsx": { + "leafId": "ui-pages", + "x": 0.1466406, + "y": 0.1228474 + }, + "frontend/src/pages/AuthCallback.test.tsx": { + "leafId": "ui-pages", + "x": 0.1304527, + "y": 0.2098956 + }, + "frontend/src/pages/AuthCallback.tsx": { + "leafId": "ui-pages", + "x": 0.1304527, + "y": 0.2706266 + }, + "frontend/src/pages/BlockEditor.tsx": { + "leafId": "ui-pages", + "x": 0.268285, + "y": 0.1328991 + }, + "frontend/src/pages/BlockLibrary.tsx": { + "leafId": "ui-pages", + "x": 0.268285, + "y": 0.2525175 + }, + "frontend/src/pages/ConstructionPage.tsx": { + "leafId": "ui-pages", + "x": 0.4106265, + "y": 0.1301538 + }, + "frontend/src/pages/Dashboard.test.tsx": { + "leafId": "ui-pages", + "x": 0.5063462, + "y": 0.1301538 + }, + "frontend/src/pages/Dashboard.tsx": { + "leafId": "ui-pages", + "x": 0.4318243, + "y": 0.2497722 + }, + "frontend/src/pages/GitOAuthCallback.tsx": { + "leafId": "ui-pages", + "x": 0.0887073, + "y": 0.3715736 + }, + "frontend/src/pages/InceptionPage.tsx": { + "leafId": "ui-pages", + "x": 0.1824477, + "y": 0.3715736 + }, + "frontend/src/pages/IntentAuditPage.tsx": { + "leafId": "ui-pages", + "x": 0.1541804, + "y": 0.4883063 + }, + "frontend/src/pages/IntentComposePage.test.tsx": { + "leafId": "ui-pages", + "x": 0.3218942, + "y": 0.4199294 + }, + "frontend/src/pages/IntentComposePage.tsx": { + "leafId": "ui-pages", + "x": 0.4617058, + "y": 0.4199294 + }, + "frontend/src/pages/IntentGraphPage.test.tsx": { + "leafId": "ui-pages", + "x": 0.1312785, + "y": 0.5744585 + }, + "frontend/src/pages/IntentGraphPage.tsx": { + "leafId": "ui-pages", + "x": 0.1312785, + "y": 0.6455213 + }, + "frontend/src/pages/IntentLoopBack.test.tsx": { + "leafId": "ui-pages", + "x": 0.1312785, + "y": 0.7306155 + }, + "frontend/src/pages/IntentNavigation.test.tsx": { + "leafId": "ui-pages", + "x": 0.2605795, + "y": 0.5900543 + }, + "frontend/src/pages/IntentObservabilityPage.test.tsx": { + "leafId": "ui-pages", + "x": 0.2605795, + "y": 0.712945 + }, + "frontend/src/pages/IntentObservabilityPage.tsx": { + "leafId": "ui-pages", + "x": 0.1311956, + "y": 0.8610017 + }, + "frontend/src/pages/IntentReleaseSemantics.test.tsx": { + "leafId": "ui-pages", + "x": 0.2604966, + "y": 0.8610017 + }, + "frontend/src/pages/IntentView.migration.test.tsx": { + "leafId": "ui-pages", + "x": 0.423293, + "y": 0.5658176 + }, + "frontend/src/pages/IntentView.test.tsx": { + "leafId": "ui-pages", + "x": 0.423293, + "y": 0.7005583 + }, + "frontend/src/pages/IntentView.tsx": { + "leafId": "ui-pages", + "x": 0.423293, + "y": 0.8728517 + }, + "frontend/src/pages/JiraCallback.tsx": { + "leafId": "ui-pages", + "x": 0.5910704, + "y": 0.1062553 + }, + "frontend/src/pages/Login.test.tsx": { + "leafId": "ui-pages", + "x": 0.5910704, + "y": 0.1854769 + }, + "frontend/src/pages/Login.tsx": { + "leafId": "ui-pages", + "x": 0.7047738, + "y": 0.1431817 + }, + "frontend/src/pages/NewIntentPage.releases.test.tsx": { + "leafId": "ui-pages", + "x": 0.6412475, + "y": 0.2667661 + }, + "frontend/src/pages/NewIntentPage.test.tsx": { + "leafId": "ui-pages", + "x": 0.8472555, + "y": 0.0973359 + }, + "frontend/src/pages/NewIntentPage.tsx": { + "leafId": "ui-pages", + "x": 0.8472555, + "y": 0.1899382 + }, + "frontend/src/pages/ObservabilityDashboard.tsx": { + "leafId": "ui-pages", + "x": 0.8472555, + "y": 0.2801468 + }, + "frontend/src/pages/ObservabilityLayout.tsx": { + "leafId": "ui-pages", + "x": 0.5738655, + "y": 0.3772822 + }, + "frontend/src/pages/PlatformAdmin.test.tsx": { + "leafId": "ui-pages", + "x": 0.6583122, + "y": 0.3772822 + }, + "frontend/src/pages/PlatformAdmin.tsx": { + "leafId": "ui-pages", + "x": 0.6119907, + "y": 0.4752528 + }, + "frontend/src/pages/Project.test.tsx": { + "leafId": "ui-pages", + "x": 0.7291938, + "y": 0.4090995 + }, + "frontend/src/pages/Project.tsx": { + "leafId": "ui-pages", + "x": 0.8507551, + "y": 0.3809253 + }, + "frontend/src/pages/ProjectSettings.test.tsx": { + "leafId": "ui-pages", + "x": 0.8507551, + "y": 0.4788959 + }, + "frontend/src/pages/ProjectSettings.tsx": { + "leafId": "ui-pages", + "x": 0.6178604, + "y": 0.5451257 + }, + "frontend/src/pages/ReviewPage.tsx": { + "leafId": "ui-pages", + "x": 0.6178604, + "y": 0.6429397 + }, + "frontend/src/pages/SprintGraph.tsx": { + "leafId": "ui-pages", + "x": 0.6178604, + "y": 0.72481 + }, + "frontend/src/pages/WorkflowComposer.tsx": { + "leafId": "ui-pages", + "x": 0.7669178, + "y": 0.6269959 + }, + "frontend/src/pages/WorkflowList.tsx": { + "leafId": "ui-pages", + "x": 0.8826094, + "y": 0.5754046 + }, + "frontend/src/pages/composer/BlockPalette.tsx": { + "leafId": "ui-pages", + "x": 0.8826094, + "y": 0.6953304 + }, + "frontend/src/pages/composer/PhaseLanes.test.tsx": { + "leafId": "ui-pages", + "x": 0.6118276, + "y": 0.7803247 + }, + "frontend/src/pages/composer/PhaseLanes.tsx": { + "leafId": "ui-pages", + "x": 0.6118276, + "y": 0.8766438 + }, + "frontend/src/pages/composer/ScopeBuilder.test.tsx": { + "leafId": "ui-pages", + "x": 0.718364, + "y": 0.8432409 + }, + "frontend/src/pages/composer/ScopeBuilder.tsx": { + "leafId": "ui-pages", + "x": 0.8183317, + "y": 0.8042369 + }, + "frontend/src/pages/composer/StageEditModal.tsx": { + "leafId": "ui-pages", + "x": 0.8183317, + "y": 0.900556 + }, + "frontend/src/pages/composer/defaultPhases.ts": { + "leafId": "ui-pages", + "x": 0.9178033, + "y": 0.7795794 + }, + "frontend/src/pages/composer/phaseDisplay.ts": { + "leafId": "ui-pages", + "x": 0.9178033, + "y": 0.8758985 + }, + "frontend/src/components/agent-output/AgentOutputTranscript.test.tsx": { + "leafId": "ui-intent", + "x": 0.1183267, + "y": 0.0894407 + }, + "frontend/src/components/agent-output/AgentOutputTranscript.tsx": { + "leafId": "ui-intent", + "x": 0.1183267, + "y": 0.1650301 + }, + "frontend/src/components/discussion/DiscussButton.tsx": { + "leafId": "ui-intent", + "x": 0.2077461, + "y": 0.1005123 + }, + "frontend/src/components/discussion/DiscussionInput.test.tsx": { + "leafId": "ui-intent", + "x": 0.2641714, + "y": 0.1005123 + }, + "frontend/src/components/discussion/DiscussionInput.tsx": { + "leafId": "ui-intent", + "x": 0.2326387, + "y": 0.1761017 + }, + "frontend/src/components/discussion/DiscussionPanel.test.tsx": { + "leafId": "ui-intent", + "x": 0.0848748, + "y": 0.2591251 + }, + "frontend/src/components/discussion/DiscussionPanel.tsx": { + "leafId": "ui-intent", + "x": 0.1716864, + "y": 0.2591251 + }, + "frontend/src/components/discussion/DiscussionProvider.test.tsx": { + "leafId": "ui-intent", + "x": 0.2615635, + "y": 0.2591251 + }, + "frontend/src/components/discussion/DiscussionProvider.tsx": { + "leafId": "ui-intent", + "x": 0.3538827, + "y": 0.1048576 + }, + "frontend/src/components/discussion/DiscussionThread.tsx": { + "leafId": "ui-intent", + "x": 0.3538827, + "y": 0.174555 + }, + "frontend/src/components/discussion/DiscussionsTab.tsx": { + "leafId": "ui-intent", + "x": 0.4633951, + "y": 0.1086274 + }, + "frontend/src/components/discussion/MentionToasts.tsx": { + "leafId": "ui-intent", + "x": 0.4633951, + "y": 0.1783248 + }, + "frontend/src/components/discussion/MessageBubble.tsx": { + "leafId": "ui-intent", + "x": 0.3220972, + "y": 0.2532331 + }, + "frontend/src/components/discussion/ResolveDialog.tsx": { + "leafId": "ui-intent", + "x": 0.3854771, + "y": 0.2532331 + }, + "frontend/src/components/discussion/index.ts": { + "leafId": "ui-intent", + "x": 0.4619563, + "y": 0.2133305 + }, + "frontend/src/components/graph/GraphCanvas.test.tsx": { + "leafId": "ui-intent", + "x": 0.4619563, + "y": 0.2632087 + }, + "frontend/src/components/graph/GraphCanvas.tsx": { + "leafId": "ui-intent", + "x": 0.1273088, + "y": 0.3774373 + }, + "frontend/src/components/graph/GraphFilterBar.tsx": { + "leafId": "ui-intent", + "x": 0.095455, + "y": 0.4819427 + }, + "frontend/src/components/graph/GraphKeyboardHelp.tsx": { + "leafId": "ui-intent", + "x": 0.1623239, + "y": 0.4819427 + }, + "frontend/src/components/graph/GraphLegend.tsx": { + "leafId": "ui-intent", + "x": 0.2195027, + "y": 0.3455515 + }, + "frontend/src/components/graph/GraphMinimap.tsx": { + "leafId": "ui-intent", + "x": 0.2760163, + "y": 0.3455515 + }, + "frontend/src/components/graph/GraphNodePanel.tsx": { + "leafId": "ui-intent", + "x": 0.2506912, + "y": 0.4500569 + }, + "frontend/src/components/graph/GraphStatsPanel.tsx": { + "leafId": "ui-intent", + "x": 0.3317834, + "y": 0.3606834 + }, + "frontend/src/components/graph/GraphToolbar.tsx": { + "leafId": "ui-intent", + "x": 0.3910375, + "y": 0.3606834 + }, + "frontend/src/components/graph/GraphZoomControls.tsx": { + "leafId": "ui-intent", + "x": 0.366459, + "y": 0.4371349 + }, + "frontend/src/components/graph/graphTypes.ts": { + "leafId": "ui-intent", + "x": 0.4669009, + "y": 0.3795629 + }, + "frontend/src/components/graph/nodeStyles.ts": { + "leafId": "ui-intent", + "x": 0.3506062, + "y": 0.4840683 + }, + "frontend/src/components/intent/AgentProgressCard.tsx": { + "leafId": "ui-intent", + "x": 0.4510482, + "y": 0.4840683 + }, + "frontend/src/components/intent/ArtifactContentEditor.tsx": { + "leafId": "ui-intent", + "x": 0.0853299, + "y": 0.5724226 + }, + "frontend/src/components/intent/ArtifactEditControls.tsx": { + "leafId": "ui-intent", + "x": 0.1552527, + "y": 0.5724226 + }, + "frontend/src/components/intent/ArtifactHistoryDrawer.test.tsx": { + "leafId": "ui-intent", + "x": 0.0909217, + "y": 0.6850228 + }, + "frontend/src/components/intent/ArtifactHistoryDrawer.tsx": { + "leafId": "ui-intent", + "x": 0.1608445, + "y": 0.6850228 + }, + "frontend/src/components/intent/ArtifactMarkdown.test.tsx": { + "leafId": "ui-intent", + "x": 0.2482301, + "y": 0.5401814 + }, + "frontend/src/components/intent/ArtifactMarkdown.tsx": { + "leafId": "ui-intent", + "x": 0.2482301, + "y": 0.6187837 + }, + "frontend/src/components/intent/ArtifactViewer.tsx": { + "leafId": "ui-intent", + "x": 0.2482301, + "y": 0.7033246 + }, + "frontend/src/components/intent/CodeSection.test.tsx": { + "leafId": "ui-intent", + "x": 0.1109645, + "y": 0.7787907 + }, + "frontend/src/components/intent/CodeSection.tsx": { + "leafId": "ui-intent", + "x": 0.1109645, + "y": 0.847307 + }, + "frontend/src/components/intent/ComposePanel.test.tsx": { + "leafId": "ui-intent", + "x": 0.1866206, + "y": 0.8058387 + }, + "frontend/src/components/intent/ComposePanel.tsx": { + "leafId": "ui-intent", + "x": 0.136096, + "y": 0.9069575 + }, + "frontend/src/components/intent/DerivedItemCountChip.tsx": { + "leafId": "ui-intent", + "x": 0.2539633, + "y": 0.7573175 + }, + "frontend/src/components/intent/DerivedItemRow.tsx": { + "leafId": "ui-intent", + "x": 0.2539633, + "y": 0.8016909 + }, + "frontend/src/components/intent/GateCard.tsx": { + "leafId": "ui-intent", + "x": 0.2539633, + "y": 0.8828146 + }, + "frontend/src/components/intent/HistorySection.tsx": { + "leafId": "ui-intent", + "x": 0.362496, + "y": 0.5574794 + }, + "frontend/src/components/intent/IntentConfigurationDialog.tsx": { + "leafId": "ui-intent", + "x": 0.362496, + "y": 0.6374682 + }, + "frontend/src/components/intent/IntentGraphPopover.test.tsx": { + "leafId": "ui-intent", + "x": 0.4684531, + "y": 0.5466008 + }, + "frontend/src/components/intent/IntentGraphPopover.tsx": { + "leafId": "ui-intent", + "x": 0.4684531, + "y": 0.6265897 + }, + "frontend/src/components/intent/IntentPhaseDiagram.tsx": { + "leafId": "ui-intent", + "x": 0.350238, + "y": 0.7205252 + }, + "frontend/src/components/intent/IntentStageList.tsx": { + "leafId": "ui-intent", + "x": 0.456195, + "y": 0.7205252 + }, + "frontend/src/components/intent/MethodologyReleaseBadge.test.tsx": { + "leafId": "ui-intent", + "x": 0.3293326, + "y": 0.791094 + }, + "frontend/src/components/intent/MethodologyReleaseBadge.tsx": { + "leafId": "ui-intent", + "x": 0.3293326, + "y": 0.8379942 + }, + "frontend/src/components/intent/NativeExportSetupDialog.test.tsx": { + "leafId": "ui-intent", + "x": 0.3936606, + "y": 0.8158509 + }, + "frontend/src/components/intent/NativeExportSetupDialog.tsx": { + "leafId": "ui-intent", + "x": 0.3605026, + "y": 0.9011556 + }, + "frontend/src/components/intent/PendingQuestionsTabs.test.tsx": { + "leafId": "ui-intent", + "x": 0.4664597, + "y": 0.8029422 + }, + "frontend/src/components/intent/PendingQuestionsTabs.tsx": { + "leafId": "ui-intent", + "x": 0.4664597, + "y": 0.8882469 + }, + "frontend/src/components/intent/ProvenanceTree.test.tsx": { + "leafId": "ui-intent", + "x": 0.5680494, + "y": 0.1218591 + }, + "frontend/src/components/intent/ProvenanceTree.tsx": { + "leafId": "ui-intent", + "x": 0.5680494, + "y": 0.2386205 + }, + "frontend/src/components/intent/QuorumEditPanel.test.tsx": { + "leafId": "ui-intent", + "x": 0.6875525, + "y": 0.0937121 + }, + "frontend/src/components/intent/QuorumEditPanel.tsx": { + "leafId": "ui-intent", + "x": 0.6875525, + "y": 0.1685917 + }, + "frontend/src/components/intent/RecomposePanel.test.tsx": { + "leafId": "ui-intent", + "x": 0.6875525, + "y": 0.2556009 + }, + "frontend/src/components/intent/RecomposePanel.tsx": { + "leafId": "ui-intent", + "x": 0.79312, + "y": 0.1234209 + }, + "frontend/src/components/intent/ScopeBadge.tsx": { + "leafId": "ui-intent", + "x": 0.852752, + "y": 0.1234209 + }, + "frontend/src/components/intent/SensorChips.test.tsx": { + "leafId": "ui-intent", + "x": 0.9029595, + "y": 0.1234209 + }, + "frontend/src/components/intent/SensorChips.tsx": { + "leafId": "ui-intent", + "x": 0.7760524, + "y": 0.2401822 + }, + "frontend/src/components/intent/SensorDiagnostics.test.tsx": { + "leafId": "ui-intent", + "x": 0.8356403, + "y": 0.2401822 + }, + "frontend/src/components/intent/SensorDiagnostics.tsx": { + "leafId": "ui-intent", + "x": 0.9029154, + "y": 0.2401822 + }, + "frontend/src/components/intent/StageDetail.test.tsx": { + "leafId": "ui-intent", + "x": 0.5329594, + "y": 0.352713 + }, + "frontend/src/components/intent/StageDetail.tsx": { + "leafId": "ui-intent", + "x": 0.6147328, + "y": 0.352713 + }, + "frontend/src/components/intent/StageGridEditor.tsx": { + "leafId": "ui-intent", + "x": 0.5363066, + "y": 0.4553641 + }, + "frontend/src/components/intent/StageReviewPanel.test.tsx": { + "leafId": "ui-intent", + "x": 0.6180799, + "y": 0.4553641 + }, + "frontend/src/components/intent/StageReviewPanel.tsx": { + "leafId": "ui-intent", + "x": 0.7119386, + "y": 0.4001338 + }, + "frontend/src/components/intent/UnitBranchEntry.tsx": { + "leafId": "ui-intent", + "x": 0.8003448, + "y": 0.3251503 + }, + "frontend/src/components/intent/UnitLaneBoard.test.tsx": { + "leafId": "ui-intent", + "x": 0.8003448, + "y": 0.414886 + }, + "frontend/src/components/intent/UnitLaneBoard.tsx": { + "leafId": "ui-intent", + "x": 0.894004, + "y": 0.3872184 + }, + "frontend/src/components/intent/UsageMetrics.test.tsx": { + "leafId": "ui-intent", + "x": 0.8459008, + "y": 0.4898695 + }, + "frontend/src/components/intent/UsageMetrics.tsx": { + "leafId": "ui-intent", + "x": 0.5399624, + "y": 0.5571576 + }, + "frontend/src/components/intent/WaitingCard.tsx": { + "leafId": "ui-intent", + "x": 0.6115349, + "y": 0.5571576 + }, + "frontend/src/components/intent/WorkProductsSection.tsx": { + "leafId": "ui-intent", + "x": 0.5796612, + "y": 0.6353532 + }, + "frontend/src/components/intent/artifactAccent.ts": { + "leafId": "ui-intent", + "x": 0.5321094, + "y": 0.6943133 + }, + "frontend/src/components/intent/documentHelpers.test.ts": { + "leafId": "ui-intent", + "x": 0.6036819, + "y": 0.6943133 + }, + "frontend/src/components/intent/documentHelpers.ts": { + "leafId": "ui-intent", + "x": 0.6977362, + "y": 0.5318678 + }, + "frontend/src/components/intent/stageStyle.tsx": { + "leafId": "ui-intent", + "x": 0.6977362, + "y": 0.5926693 + }, + "frontend/src/components/intent/workProductsFocus.ts": { + "leafId": "ui-intent", + "x": 0.6977362, + "y": 0.6450605 + }, + "frontend/src/components/observability/ActivityFeed.tsx": { + "leafId": "ui-intent", + "x": 0.6977362, + "y": 0.6975919 + }, + "frontend/src/components/observability/AgentFocusCard.tsx": { + "leafId": "ui-intent", + "x": 0.7749538, + "y": 0.5611637 + }, + "frontend/src/components/observability/AgentStatusCards.tsx": { + "leafId": "ui-intent", + "x": 0.8457239, + "y": 0.5611637 + }, + "frontend/src/components/observability/BusinessView.tsx": { + "leafId": "ui-intent", + "x": 0.9126694, + "y": 0.5611637 + }, + "frontend/src/components/observability/IntentStatusCards.tsx": { + "leafId": "ui-intent", + "x": 0.7779256, + "y": 0.6744965 + }, + "frontend/src/components/observability/IterationDetailView.tsx": { + "leafId": "ui-intent", + "x": 0.8410582, + "y": 0.6744965 + }, + "frontend/src/components/observability/PhaseBlock.tsx": { + "leafId": "ui-intent", + "x": 0.9050319, + "y": 0.6744965 + }, + "frontend/src/components/observability/ProjectDiagram.tsx": { + "leafId": "ui-intent", + "x": 0.556922, + "y": 0.7686169 + }, + "frontend/src/components/observability/StepNode.tsx": { + "leafId": "ui-intent", + "x": 0.556922, + "y": 0.8335134 + }, + "frontend/src/components/observability/StuckAlert.tsx": { + "leafId": "ui-intent", + "x": 0.6243948, + "y": 0.794347 + }, + "frontend/src/components/observability/TaskStatusRow.tsx": { + "leafId": "ui-intent", + "x": 0.5288201, + "y": 0.8994018 + }, + "frontend/src/components/observability/buildInsights.ts": { + "leafId": "ui-intent", + "x": 0.5962929, + "y": 0.8994018 + }, + "frontend/src/components/observability/index.ts": { + "leafId": "ui-intent", + "x": 0.6567692, + "y": 0.7644464 + }, + "frontend/src/components/observability/phaseConfig.ts": { + "leafId": "ui-intent", + "x": 0.7151865, + "y": 0.7644464 + }, + "frontend/src/components/v2/UnitLaneGraph.tsx": { + "leafId": "ui-intent", + "x": 0.7014516, + "y": 0.8361629 + }, + "frontend/src/components/v2/WorkflowScopeGraph.test.tsx": { + "leafId": "ui-intent", + "x": 0.7014516, + "y": 0.9062217 + }, + "frontend/src/components/v2/WorkflowScopeGraph.tsx": { + "leafId": "ui-intent", + "x": 0.813139, + "y": 0.7850119 + }, + "frontend/src/components/v2/index.ts": { + "leafId": "ui-intent", + "x": 0.9029846, + "y": 0.7379335 + }, + "frontend/src/components/v2/scope-graph-utils.ts": { + "leafId": "ui-intent", + "x": 0.9029846, + "y": 0.7934949 + }, + "frontend/src/components/v2/unit-lane-graph.ts": { + "leafId": "ui-intent", + "x": 0.8105653, + "y": 0.8900666 + }, + "frontend/src/components/v2/unit-lane-layout.test.ts": { + "leafId": "ui-intent", + "x": 0.9004109, + "y": 0.8900666 + }, + "frontend/src/components/admin/AgentCredentialsCard.tsx": { + "leafId": "ui-admin", + "x": 0.0689865, + "y": 0.1164761 + }, + "frontend/src/components/admin/AidlcReleasesTab.test.tsx": { + "leafId": "ui-admin", + "x": 0.1591358, + "y": 0.1164761 + }, + "frontend/src/components/admin/AidlcReleasesTab.tsx": { + "leafId": "ui-admin", + "x": 0.1505893, + "y": 0.2301717 + }, + "frontend/src/components/admin/AidlcReleasesTab.upgrade.test.tsx": { + "leafId": "ui-admin", + "x": 0.2741902, + "y": 0.1321554 + }, + "frontend/src/components/admin/CodeCommitSourceControlCard.tsx": { + "leafId": "ui-admin", + "x": 0.2741902, + "y": 0.2458509 + }, + "frontend/src/components/admin/ComposerCard.tsx": { + "leafId": "ui-admin", + "x": 0.0860527, + "y": 0.35997 + }, + "frontend/src/components/admin/DefaultModelsCard.test.tsx": { + "leafId": "ui-admin", + "x": 0.1556241, + "y": 0.35997 + }, + "frontend/src/components/admin/DefaultModelsCard.tsx": { + "leafId": "ui-admin", + "x": 0.1300114, + "y": 0.4706463 + }, + "frontend/src/components/admin/DeploymentInfoCard.tsx": { + "leafId": "ui-admin", + "x": 0.2536123, + "y": 0.322618 + }, + "frontend/src/components/admin/GitHubSourceControlCard.test.tsx": { + "leafId": "ui-admin", + "x": 0.2536123, + "y": 0.3860581 + }, + "frontend/src/components/admin/GitHubSourceControlCard.tsx": { + "leafId": "ui-admin", + "x": 0.2536123, + "y": 0.4654676 + }, + "frontend/src/components/admin/GlobalMcpServersCard.tsx": { + "leafId": "ui-admin", + "x": 0.3351656, + "y": 0.1110337 + }, + "frontend/src/components/admin/GraphEnrichmentCard.tsx": { + "leafId": "ui-admin", + "x": 0.4006286, + "y": 0.1110337 + }, + "frontend/src/components/admin/OAuthAppConfigForm.test.tsx": { + "leafId": "ui-admin", + "x": 0.3731047, + "y": 0.1792397 + }, + "frontend/src/components/admin/OAuthAppConfigForm.tsx": { + "leafId": "ui-admin", + "x": 0.478233, + "y": 0.132166 + }, + "frontend/src/components/admin/PrStrategyCard.test.tsx": { + "leafId": "ui-admin", + "x": 0.3356353, + "y": 0.2466558 + }, + "frontend/src/components/admin/PrStrategyCard.tsx": { + "leafId": "ui-admin", + "x": 0.4009771, + "y": 0.2466558 + }, + "frontend/src/components/admin/StageSkippingCard.tsx": { + "leafId": "ui-admin", + "x": 0.4781118, + "y": 0.2466558 + }, + "frontend/src/components/admin/TrackerMigrationCard.tsx": { + "leafId": "ui-admin", + "x": 0.3430101, + "y": 0.3540192 + }, + "frontend/src/components/admin/UserManagementCard.test.tsx": { + "leafId": "ui-admin", + "x": 0.404873, + "y": 0.3540192 + }, + "frontend/src/components/admin/UserManagementCard.tsx": { + "leafId": "ui-admin", + "x": 0.4746329, + "y": 0.3540192 + }, + "frontend/src/components/admin/tabs/EnvironmentRegistry.tsx": { + "leafId": "ui-admin", + "x": 0.4127699, + "y": 0.4639013 + }, + "frontend/src/components/admin/tabs/EnvironmentsTab.test.tsx": { + "leafId": "ui-admin", + "x": 0.1197184, + "y": 0.605126 + }, + "frontend/src/components/admin/tabs/EnvironmentsTab.tsx": { + "leafId": "ui-admin", + "x": 0.1197184, + "y": 0.7139046 + }, + "frontend/src/components/admin/tabs/SourceControlTab.tsx": { + "leafId": "ui-admin", + "x": 0.2371482, + "y": 0.5405324 + }, + "frontend/src/components/admin/tabs/ToolsRegistry.test.tsx": { + "leafId": "ui-admin", + "x": 0.2371482, + "y": 0.649311 + }, + "frontend/src/components/admin/tabs/ToolsRegistry.tsx": { + "leafId": "ui-admin", + "x": 0.1409824, + "y": 0.8349105 + }, + "frontend/src/components/admin/tabs/TrackersTab.tsx": { + "leafId": "ui-admin", + "x": 0.2584122, + "y": 0.778931 + }, + "frontend/src/components/admin/tabs/environment-builder/ComputeSelector.test.tsx": { + "leafId": "ui-admin", + "x": 0.2584122, + "y": 0.8835806 + }, + "frontend/src/components/admin/tabs/environment-builder/ComputeSelector.tsx": { + "leafId": "ui-admin", + "x": 0.3276691, + "y": 0.5856364 + }, + "frontend/src/components/admin/tabs/environment-builder/EnvironmentBuilder.tsx": { + "leafId": "ui-admin", + "x": 0.4389685, + "y": 0.5856364 + }, + "frontend/src/components/admin/tabs/environment-builder/EnvironmentRevisionWorkspace.tsx": { + "leafId": "ui-admin", + "x": 0.4065989, + "y": 0.6973535 + }, + "frontend/src/components/admin/tabs/environment-builder/model.ts": { + "leafId": "ui-admin", + "x": 0.3638534, + "y": 0.7802196 + }, + "frontend/src/components/admin/tabs/environment-builder/ui.tsx": { + "leafId": "ui-admin", + "x": 0.3638534, + "y": 0.8622893 + }, + "frontend/src/components/blocks/StageEditor.test.tsx": { + "leafId": "ui-admin", + "x": 0.3638534, + "y": 0.9199187 + }, + "frontend/src/components/blocks/StageEditor.tsx": { + "leafId": "ui-admin", + "x": 0.4751527, + "y": 0.837849 + }, + "frontend/src/components/blocks/WorkflowInsights.tsx": { + "leafId": "ui-admin", + "x": 0.5811222, + "y": 0.1000418 + }, + "frontend/src/components/blocks/blockFields.ts": { + "leafId": "ui-admin", + "x": 0.5811222, + "y": 0.1780219 + }, + "frontend/src/components/project-settings/AgentTab.tsx": { + "leafId": "ui-admin", + "x": 0.7002976, + "y": 0.1419401 + }, + "frontend/src/components/project-settings/EnvironmentTab.test.tsx": { + "leafId": "ui-admin", + "x": 0.5752005, + "y": 0.2670247 + }, + "frontend/src/components/project-settings/EnvironmentTab.tsx": { + "leafId": "ui-admin", + "x": 0.694376, + "y": 0.2670247 + }, + "frontend/src/components/project-settings/GeneralTab.tsx": { + "leafId": "ui-admin", + "x": 0.814143, + "y": 0.1137017 + }, + "frontend/src/components/project-settings/MembersTab.test.tsx": { + "leafId": "ui-admin", + "x": 0.9057984, + "y": 0.1137017 + }, + "frontend/src/components/project-settings/MembersTab.tsx": { + "leafId": "ui-admin", + "x": 0.8479046, + "y": 0.2093369 + }, + "frontend/src/components/project-settings/RepositoriesTab.test.tsx": { + "leafId": "ui-admin", + "x": 0.8479046, + "y": 0.2846798 + }, + "frontend/src/components/project-settings/RepositoriesTab.tsx": { + "leafId": "ui-admin", + "x": 0.5750675, + "y": 0.3759469 + }, + "frontend/src/components/project-settings/SourceControlBindingSection.test.tsx": { + "leafId": "ui-admin", + "x": 0.6691393, + "y": 0.3759469 + }, + "frontend/src/components/project-settings/SourceControlBindingSection.tsx": { + "leafId": "ui-admin", + "x": 0.6119701, + "y": 0.4801714 + }, + "frontend/src/components/project-settings/TrackersTab.test.tsx": { + "leafId": "ui-admin", + "x": 0.7321774, + "y": 0.4183536 + }, + "frontend/src/components/project-settings/TrackersTab.tsx": { + "leafId": "ui-admin", + "x": 0.8037591, + "y": 0.3883637 + }, + "frontend/src/components/settings/AgentAuthenticationModeSettings.test.tsx": { + "leafId": "ui-admin", + "x": 0.8943827, + "y": 0.3883637 + }, + "frontend/src/components/settings/AgentAuthenticationModeSettings.tsx": { + "leafId": "ui-admin", + "x": 0.8489364, + "y": 0.4925881 + }, + "frontend/src/components/settings/AgentCredentialScopeCard.test.tsx": { + "leafId": "ui-admin", + "x": 0.5710312, + "y": 0.5885532 + }, + "frontend/src/components/settings/AgentCredentialScopeCard.tsx": { + "leafId": "ui-admin", + "x": 0.6783751, + "y": 0.5885532 + }, + "frontend/src/components/settings/AuthenticationImpactReview.test.tsx": { + "leafId": "ui-admin", + "x": 0.5826172, + "y": 0.7037296 + }, + "frontend/src/components/settings/AuthenticationImpactReview.tsx": { + "leafId": "ui-admin", + "x": 0.689961, + "y": 0.7037296 + }, + "frontend/src/components/settings/ConfigStatusBadge.tsx": { + "leafId": "ui-admin", + "x": 0.5726787, + "y": 0.775369 + }, + "frontend/src/components/settings/CustomMcpServersSection.tsx": { + "leafId": "ui-admin", + "x": 0.5726787, + "y": 0.8686835 + }, + "frontend/src/components/settings/CustomRulesSection.tsx": { + "leafId": "ui-admin", + "x": 0.6800225, + "y": 0.8215961 + }, + "frontend/src/components/settings/SaveStatusButton.tsx": { + "leafId": "ui-admin", + "x": 0.6800225, + "y": 0.9149106 + }, + "frontend/src/components/settings/SecretField.tsx": { + "leafId": "ui-admin", + "x": 0.7718439, + "y": 0.5678303 + }, + "frontend/src/components/settings/SettingsCard.tsx": { + "leafId": "ui-admin", + "x": 0.8403007, + "y": 0.5678303 + }, + "frontend/src/components/settings/TierModelsSection.tsx": { + "leafId": "ui-admin", + "x": 0.8010427, + "y": 0.6481861 + }, + "frontend/src/components/settings/agent-auth/bedrock-iam/BedrockIamWizard.test.tsx": { + "leafId": "ui-admin", + "x": 0.9045298, + "y": 0.6029338 + }, + "frontend/src/components/settings/agent-auth/bedrock-iam/BedrockIamWizard.tsx": { + "leafId": "ui-admin", + "x": 0.836073, + "y": 0.7220005 + }, + "frontend/src/components/settings/agent-auth/bedrock-iam/api.ts": { + "leafId": "ui-admin", + "x": 0.7852293, + "y": 0.7865245 + }, + "frontend/src/components/settings/agent-auth/bedrock-iam/index.test.tsx": { + "leafId": "ui-admin", + "x": 0.7852293, + "y": 0.8759488 + }, + "frontend/src/components/settings/agent-auth/bedrock-iam/index.ts": { + "leafId": "ui-admin", + "x": 0.8572205, + "y": 0.8030647 + }, + "frontend/src/components/settings/agent-auth/boundary.test.ts": { + "leafId": "ui-admin", + "x": 0.9080641, + "y": 0.8030647 + }, + "frontend/src/components/settings/agent-auth/contract.ts": { + "leafId": "ui-admin", + "x": 0.8887164, + "y": 0.8630734 + }, + "frontend/src/components/settings/agent-auth/registry.ts": { + "leafId": "ui-admin", + "x": 0.8575709, + "y": 0.9101443 + }, + "frontend/src/components/settings/agent-auth/summary.ts": { + "leafId": "ui-admin", + "x": 0.9084145, + "y": 0.9101443 + }, + "frontend/src/App.tsx": { + "leafId": "ui-shared", + "x": 0.1034886, + "y": 0.1282452 + }, + "frontend/src/auth/README.md": { + "leafId": "ui-shared", + "x": 0.1757029, + "y": 0.1282452 + }, + "frontend/src/components/AgentStreamPanel.tsx": { + "leafId": "ui-shared", + "x": 0.2508738, + "y": 0.1282452 + }, + "frontend/src/components/AidlcSettingsPanel.test.tsx": { + "leafId": "ui-shared", + "x": 0.1065934, + "y": 0.2489459 + }, + "frontend/src/components/AidlcSettingsPanel.tsx": { + "leafId": "ui-shared", + "x": 0.1962605, + "y": 0.2489459 + }, + "frontend/src/components/CodeCommitConnectForm.test.tsx": { + "leafId": "ui-shared", + "x": 0.2683267, + "y": 0.2489459 + }, + "frontend/src/components/CodeCommitConnectForm.tsx": { + "leafId": "ui-shared", + "x": 0.1204186, + "y": 0.362434 + }, + "frontend/src/components/CodeFileViewer.tsx": { + "leafId": "ui-shared", + "x": 0.1979571, + "y": 0.362434 + }, + "frontend/src/components/CollaborativeTextarea.test.tsx": { + "leafId": "ui-shared", + "x": 0.1379785, + "y": 0.4607184 + }, + "frontend/src/components/CollaborativeTextarea.tsx": { + "leafId": "ui-shared", + "x": 0.256198, + "y": 0.4036459 + }, + "frontend/src/components/ConnectionStatus.tsx": { + "leafId": "ui-shared", + "x": 0.3447437, + "y": 0.0840066 + }, + "frontend/src/components/CreateProjectModal.test.tsx": { + "leafId": "ui-shared", + "x": 0.3447437, + "y": 0.1808655 + }, + "frontend/src/components/CreateProjectModal.tsx": { + "leafId": "ui-shared", + "x": 0.4472775, + "y": 0.1608189 + }, + "frontend/src/components/ErrorBoundary.tsx": { + "leafId": "ui-shared", + "x": 0.3994128, + "y": 0.2716439 + }, + "frontend/src/components/GitConnectButton.test.tsx": { + "leafId": "ui-shared", + "x": 0.3547904, + "y": 0.3093067 + }, + "frontend/src/components/GitConnectButton.tsx": { + "leafId": "ui-shared", + "x": 0.3547904, + "y": 0.378379 + }, + "frontend/src/components/GitFileBrowser.tsx": { + "leafId": "ui-shared", + "x": 0.4573242, + "y": 0.3546824 + }, + "frontend/src/components/GitRepoLink.tsx": { + "leafId": "ui-shared", + "x": 0.3342546, + "y": 0.4628425 + }, + "frontend/src/components/GitRepoSelect.tsx": { + "leafId": "ui-shared", + "x": 0.4367884, + "y": 0.4628425 + }, + "frontend/src/components/IntentSourcePicker.tsx": { + "leafId": "ui-shared", + "x": 0.1211752, + "y": 0.5578878 + }, + "frontend/src/components/JiraConnectButton.tsx": { + "leafId": "ui-shared", + "x": 0.1211752, + "y": 0.6407913 + }, + "frontend/src/components/JiraProjectPickerDialog.test.tsx": { + "leafId": "ui-shared", + "x": 0.1211752, + "y": 0.6980514 + }, + "frontend/src/components/JiraProjectPickerDialog.tsx": { + "leafId": "ui-shared", + "x": 0.2361861, + "y": 0.5527784 + }, + "frontend/src/components/MigrateTrackerCard.tsx": { + "leafId": "ui-shared", + "x": 0.2361861, + "y": 0.6356085 + }, + "frontend/src/components/OAuthCallbackShell.tsx": { + "leafId": "ui-shared", + "x": 0.2361861, + "y": 0.6979781 + }, + "frontend/src/components/PrCheckoutCommand.tsx": { + "leafId": "ui-shared", + "x": 0.1000726, + "y": 0.7715514 + }, + "frontend/src/components/ProtectedRoute.tsx": { + "leafId": "ui-shared", + "x": 0.1689061, + "y": 0.7715514 + }, + "frontend/src/components/QuestionEditor.tsx": { + "leafId": "ui-shared", + "x": 0.1292735, + "y": 0.8771486 + }, + "frontend/src/components/ReviewEditor.tsx": { + "leafId": "ui-shared", + "x": 0.2442844, + "y": 0.7887844 + }, + "frontend/src/components/TimelinePanel.tsx": { + "leafId": "ui-shared", + "x": 0.2442844, + "y": 0.8943815 + }, + "frontend/src/components/TrackerIssueListPanel.tsx": { + "leafId": "ui-shared", + "x": 0.3595809, + "y": 0.559168 + }, + "frontend/src/components/domain/AgentStatusBadge.tsx": { + "leafId": "ui-shared", + "x": 0.4653233, + "y": 0.559168 + }, + "frontend/src/components/domain/ArtifactCard.tsx": { + "leafId": "ui-shared", + "x": 0.3551327, + "y": 0.671195 + }, + "frontend/src/components/domain/ArtifactGraphPopover.tsx": { + "leafId": "ui-shared", + "x": 0.4608751, + "y": 0.671195 + }, + "frontend/src/components/domain/PhaseProgressRing.tsx": { + "leafId": "ui-shared", + "x": 0.33088, + "y": 0.7852262 + }, + "frontend/src/components/domain/PresenceAvatars.tsx": { + "leafId": "ui-shared", + "x": 0.4045991, + "y": 0.7852262 + }, + "frontend/src/components/icons/git-providers.tsx": { + "leafId": "ui-shared", + "x": 0.4699234, + "y": 0.7852262 + }, + "frontend/src/components/layout/ActivityPanel.tsx": { + "leafId": "ui-shared", + "x": 0.3962042, + "y": 0.892014 + }, + "frontend/src/components/layout/AppHeader.tsx": { + "leafId": "ui-shared", + "x": 0.5509348, + "y": 0.1386612 + }, + "frontend/src/components/layout/AppShell.test.tsx": { + "leafId": "ui-shared", + "x": 0.6424364, + "y": 0.1386612 + }, + "frontend/src/components/layout/AppShell.tsx": { + "leafId": "ui-shared", + "x": 0.5934482, + "y": 0.2527897 + }, + "frontend/src/components/layout/AppSidebar.test.tsx": { + "leafId": "ui-shared", + "x": 0.7218153, + "y": 0.1780885 + }, + "frontend/src/components/layout/AppSidebar.tsx": { + "leafId": "ui-shared", + "x": 0.8193557, + "y": 0.1475729 + }, + "frontend/src/components/layout/CommandPalette.tsx": { + "leafId": "ui-shared", + "x": 0.9097953, + "y": 0.1475729 + }, + "frontend/src/components/layout/IntentActivityPanel.personaEvents.test.tsx": { + "leafId": "ui-shared", + "x": 0.8491204, + "y": 0.2617014 + }, + "frontend/src/components/layout/IntentActivityPanel.releaseEvents.test.tsx": { + "leafId": "ui-shared", + "x": 0.5546519, + "y": 0.3405402 + }, + "frontend/src/components/layout/IntentActivityPanel.test.tsx": { + "leafId": "ui-shared", + "x": 0.5546519, + "y": 0.4502339 + }, + "frontend/src/components/layout/IntentActivityPanel.tsx": { + "leafId": "ui-shared", + "x": 0.6653803, + "y": 0.4019107 + }, + "frontend/src/components/layout/IntentPipelineBar.test.tsx": { + "leafId": "ui-shared", + "x": 0.7616394, + "y": 0.3510692 + }, + "frontend/src/components/layout/IntentPipelineBar.tsx": { + "leafId": "ui-shared", + "x": 0.8541726, + "y": 0.3510692 + }, + "frontend/src/components/layout/SprintLayout.tsx": { + "leafId": "ui-shared", + "x": 0.9240148, + "y": 0.3510692 + }, + "frontend/src/components/layout/SprintPipelineBar.tsx": { + "leafId": "ui-shared", + "x": 0.7908529, + "y": 0.460763 + }, + "frontend/src/components/layout/StatusBar.test.tsx": { + "leafId": "ui-shared", + "x": 0.8989312, + "y": 0.4273637 + }, + "frontend/src/components/layout/StatusBar.tsx": { + "leafId": "ui-shared", + "x": 0.8989312, + "y": 0.4782052 + }, + "frontend/src/components/theme/ThemeProvider.tsx": { + "leafId": "ui-shared", + "x": 0.5355754, + "y": 0.561768 + }, + "frontend/src/components/theme/ThemeToggle.tsx": { + "leafId": "ui-shared", + "x": 0.5977507, + "y": 0.561768 + }, + "frontend/src/components/ui/accordion.tsx": { + "leafId": "ui-shared", + "x": 0.564122, + "y": 0.6354285 + }, + "frontend/src/components/ui/alert-dialog.tsx": { + "leafId": "ui-shared", + "x": 0.564122, + "y": 0.6939011 + }, + "frontend/src/components/ui/avatar.tsx": { + "leafId": "ui-shared", + "x": 0.6529025, + "y": 0.5631849 + }, + "frontend/src/components/ui/badge.tsx": { + "leafId": "ui-shared", + "x": 0.7045913, + "y": 0.5631849 + }, + "frontend/src/components/ui/button.tsx": { + "leafId": "ui-shared", + "x": 0.6779861, + "y": 0.6424695 + }, + "frontend/src/components/ui/card.tsx": { + "leafId": "ui-shared", + "x": 0.6779861, + "y": 0.6995252 + }, + "frontend/src/components/ui/collapsible.tsx": { + "leafId": "ui-shared", + "x": 0.5494196, + "y": 0.7481481 + }, + "frontend/src/components/ui/command.tsx": { + "leafId": "ui-shared", + "x": 0.5494196, + "y": 0.8182244 + }, + "frontend/src/components/ui/dialog.tsx": { + "leafId": "ui-shared", + "x": 0.6259388, + "y": 0.798953 + }, + "frontend/src/components/ui/dropdown-menu.tsx": { + "leafId": "ui-shared", + "x": 0.5784659, + "y": 0.9042946 + }, + "frontend/src/components/ui/input.tsx": { + "leafId": "ui-shared", + "x": 0.69233, + "y": 0.7545703 + }, + "frontend/src/components/ui/label.tsx": { + "leafId": "ui-shared", + "x": 0.69233, + "y": 0.8041415 + }, + "frontend/src/components/ui/popover.tsx": { + "leafId": "ui-shared", + "x": 0.69233, + "y": 0.8575185 + }, + "frontend/src/components/ui/progress.tsx": { + "leafId": "ui-shared", + "x": 0.69233, + "y": 0.9132889 + }, + "frontend/src/components/ui/resizable.tsx": { + "leafId": "ui-shared", + "x": 0.7749098, + "y": 0.538739 + }, + "frontend/src/components/ui/scroll-area.tsx": { + "leafId": "ui-shared", + "x": 0.7749098, + "y": 0.5972057 + }, + "frontend/src/components/ui/select.tsx": { + "leafId": "ui-shared", + "x": 0.8627112, + "y": 0.5700712 + }, + "frontend/src/components/ui/separator.tsx": { + "leafId": "ui-shared", + "x": 0.9224188, + "y": 0.5700712 + }, + "frontend/src/components/ui/sheet.tsx": { + "leafId": "ui-shared", + "x": 0.7731308, + "y": 0.6794578 + }, + "frontend/src/components/ui/skeleton.tsx": { + "leafId": "ui-shared", + "x": 0.8279499, + "y": 0.6794578 + }, + "frontend/src/components/ui/switch.tsx": { + "leafId": "ui-shared", + "x": 0.8894366, + "y": 0.6497452 + }, + "frontend/src/components/ui/tabs.tsx": { + "leafId": "ui-shared", + "x": 0.8894366, + "y": 0.7006652 + }, + "frontend/src/components/ui/textarea.tsx": { + "leafId": "ui-shared", + "x": 0.7524348, + "y": 0.7715669 + }, + "frontend/src/components/ui/toggle-group.tsx": { + "leafId": "ui-shared", + "x": 0.803726, + "y": 0.7715669 + }, + "frontend/src/components/ui/tooltip.tsx": { + "leafId": "ui-shared", + "x": 0.8585381, + "y": 0.7715669 + }, + "frontend/src/components/ui/tree-view.tsx": { + "leafId": "ui-shared", + "x": 0.8072469, + "y": 0.876158 + }, + "frontend/src/dev/agent-output-preview.tsx": { + "leafId": "ui-shared", + "x": 0.9121895, + "y": 0.8101799 + }, + "frontend/src/main.tsx": { + "leafId": "ui-shared", + "x": 0.9121895, + "y": 0.914771 + }, + "frontend/src/services/adminUsers.ts": { + "leafId": "client-state-api", + "x": 0.1082206, + "y": 0.1100233 + }, + "frontend/src/services/agents.test.ts": { + "leafId": "client-state-api", + "x": 0.2210224, + "y": 0.1100233 + }, + "frontend/src/services/agents.ts": { + "leafId": "client-state-api", + "x": 0.1732418, + "y": 0.2340424 + }, + "frontend/src/services/aidlcReleases.test.ts": { + "leafId": "client-state-api", + "x": 0.3936554, + "y": 0.1237834 + }, + "frontend/src/services/aidlcReleases.ts": { + "leafId": "client-state-api", + "x": 0.3936554, + "y": 0.2478024 + }, + "frontend/src/services/api.test.ts": { + "leafId": "client-state-api", + "x": 0.1381326, + "y": 0.3625567 + }, + "frontend/src/services/api.ts": { + "leafId": "client-state-api", + "x": 0.1381326, + "y": 0.4728375 + }, + "frontend/src/services/auth.test.ts": { + "leafId": "client-state-api", + "x": 0.2850668, + "y": 0.4222789 + }, + "frontend/src/services/auth.ts": { + "leafId": "client-state-api", + "x": 0.4277879, + "y": 0.4222789 + }, + "frontend/src/services/authErrors.ts": { + "leafId": "client-state-api", + "x": 0.1285845, + "y": 0.5830568 + }, + "frontend/src/services/blocks.ts": { + "leafId": "client-state-api", + "x": 0.1285845, + "y": 0.6915307 + }, + "frontend/src/services/codeFiles.ts": { + "leafId": "client-state-api", + "x": 0.2417878, + "y": 0.5713185 + }, + "frontend/src/services/codecommit.ts": { + "leafId": "client-state-api", + "x": 0.2417878, + "y": 0.6797923 + }, + "frontend/src/services/discussions.test.ts": { + "leafId": "client-state-api", + "x": 0.1058967, + "y": 0.8445337 + }, + "frontend/src/services/discussions.ts": { + "leafId": "client-state-api", + "x": 0.2191, + "y": 0.8445337 + }, + "frontend/src/services/environments.ts": { + "leafId": "client-state-api", + "x": 0.394057, + "y": 0.613624 + }, + "frontend/src/services/generalInfo.ts": { + "leafId": "client-state-api", + "x": 0.3239204, + "y": 0.744489 + }, + "frontend/src/services/gitProvider.test.ts": { + "leafId": "client-state-api", + "x": 0.4311307, + "y": 0.744489 + }, + "frontend/src/services/gitProvider.ts": { + "leafId": "client-state-api", + "x": 0.394057, + "y": 0.8669248 + }, + "frontend/src/services/intents.test.ts": { + "leafId": "client-state-api", + "x": 0.5311027, + "y": 0.197893 + }, + "frontend/src/services/intents.ts": { + "leafId": "client-state-api", + "x": 0.6780807, + "y": 0.197893 + }, + "frontend/src/services/projects.test.ts": { + "leafId": "client-state-api", + "x": 0.8673916, + "y": 0.1028918 + }, + "frontend/src/services/projects.ts": { + "leafId": "client-state-api", + "x": 0.8673916, + "y": 0.2368248 + }, + "frontend/src/services/questions.ts": { + "leafId": "client-state-api", + "x": 0.5324381, + "y": 0.4239889 + }, + "frontend/src/services/realtime.test.ts": { + "leafId": "client-state-api", + "x": 0.6261197, + "y": 0.4239889 + }, + "frontend/src/services/realtime.ts": { + "leafId": "client-state-api", + "x": 0.7707156, + "y": 0.4239889 + }, + "frontend/src/services/requirements.ts": { + "leafId": "client-state-api", + "x": 0.8961804, + "y": 0.3732523 + }, + "frontend/src/services/reviews.ts": { + "leafId": "client-state-api", + "x": 0.8961804, + "y": 0.4654152 + }, + "frontend/src/services/sessionExpiry.test.ts": { + "leafId": "client-state-api", + "x": 0.5618471, + "y": 0.5746505 + }, + "frontend/src/services/sessionExpiry.ts": { + "leafId": "client-state-api", + "x": 0.5618471, + "y": 0.6784622 + }, + "frontend/src/services/sourceControl.ts": { + "leafId": "client-state-api", + "x": 0.6779232, + "y": 0.6199635 + }, + "frontend/src/services/sprintGraph.test.ts": { + "leafId": "client-state-api", + "x": 0.6173435, + "y": 0.761167 + }, + "frontend/src/services/sprintGraph.ts": { + "leafId": "client-state-api", + "x": 0.5474159, + "y": 0.8690594 + }, + "frontend/src/services/sprints.ts": { + "leafId": "client-state-api", + "x": 0.6373036, + "y": 0.8690594 + }, + "frontend/src/services/tasks.ts": { + "leafId": "client-state-api", + "x": 0.7072312, + "y": 0.8690594 + }, + "frontend/src/services/timelineEvents.ts": { + "leafId": "client-state-api", + "x": 0.7619893, + "y": 0.6038628 + }, + "frontend/src/services/trackers.ts": { + "leafId": "client-state-api", + "x": 0.8650595, + "y": 0.6038628 + }, + "frontend/src/services/userStories.ts": { + "leafId": "client-state-api", + "x": 0.7700934, + "y": 0.7405751 + }, + "frontend/src/services/workflows.test.ts": { + "leafId": "client-state-api", + "x": 0.8731636, + "y": 0.7405751 + }, + "frontend/src/services/workflows.ts": { + "leafId": "client-state-api", + "x": 0.8364898, + "y": 0.8645681 + }, + "frontend/src/contexts/AuthContext.test.tsx": { + "leafId": "client-state-state", + "x": 0.1314585, + "y": 0.1229593 + }, + "frontend/src/contexts/AuthContext.tsx": { + "leafId": "client-state-state", + "x": 0.1314585, + "y": 0.2561685 + }, + "frontend/src/contexts/IntentContext.test.tsx": { + "leafId": "client-state-state", + "x": 0.2714333, + "y": 0.1971692 + }, + "frontend/src/contexts/IntentContext.tsx": { + "leafId": "client-state-state", + "x": 0.4287738, + "y": 0.1971692 + }, + "frontend/src/contexts/SprintContext.tsx": { + "leafId": "client-state-state", + "x": 0.117837, + "y": 0.4314765 + }, + "frontend/src/hooks/useAgentStatus.ts": { + "leafId": "client-state-state", + "x": 0.2401753, + "y": 0.4314765 + }, + "frontend/src/hooks/useAuthSession.ts": { + "leafId": "client-state-state", + "x": 0.3655671, + "y": 0.3543295 + }, + "frontend/src/hooks/useAutoSave.test.tsx": { + "leafId": "client-state-state", + "x": 0.3655671, + "y": 0.4554276 + }, + "frontend/src/hooks/useAutoSave.ts": { + "leafId": "client-state-state", + "x": 0.4715878, + "y": 0.4314765 + }, + "frontend/src/hooks/useCollaborativeArtifact.ts": { + "leafId": "client-state-state", + "x": 0.1465149, + "y": 0.5837334 + }, + "frontend/src/hooks/useCollaborativeArtifactContent.ts": { + "leafId": "client-state-state", + "x": 0.1465149, + "y": 0.6872467 + }, + "frontend/src/hooks/useCollaborativeInception.test.tsx": { + "leafId": "client-state-state", + "x": 0.1465149, + "y": 0.7719022 + }, + "frontend/src/hooks/useCollaborativeInception.ts": { + "leafId": "client-state-state", + "x": 0.2824501, + "y": 0.6683889 + }, + "frontend/src/hooks/useCollaborativeIntentDraft.test.tsx": { + "leafId": "client-state-state", + "x": 0.1963751, + "y": 0.8718816 + }, + "frontend/src/hooks/useCollaborativeIntentDraft.ts": { + "leafId": "client-state-state", + "x": 0.4247341, + "y": 0.6160214 + }, + "frontend/src/hooks/useCollaborativeLifecycle.test.tsx": { + "leafId": "client-state-state", + "x": 0.4247341, + "y": 0.7582135 + }, + "frontend/src/hooks/useCollaborativeStructuredAnswer.ts": { + "leafId": "client-state-state", + "x": 0.4247341, + "y": 0.8782594 + }, + "frontend/src/hooks/useConstructionStatus.ts": { + "leafId": "client-state-state", + "x": 0.58555, + "y": 0.1484742 + }, + "frontend/src/hooks/useDebounce.ts": { + "leafId": "client-state-state", + "x": 0.58555, + "y": 0.2642992 + }, + "frontend/src/hooks/useDiscussion.ts": { + "leafId": "client-state-state", + "x": 0.7117353, + "y": 0.179785 + }, + "frontend/src/hooks/useGitProviderStatus.ts": { + "leafId": "client-state-state", + "x": 0.8092824, + "y": 0.1308687 + }, + "frontend/src/hooks/useIntentEvents.test.ts": { + "leafId": "client-state-state", + "x": 0.8942982, + "y": 0.1308687 + }, + "frontend/src/hooks/useIntentEvents.ts": { + "leafId": "client-state-state", + "x": 0.8545443, + "y": 0.2466937 + }, + "frontend/src/hooks/useIntentGraph.test.tsx": { + "leafId": "client-state-state", + "x": 0.60692, + "y": 0.3489547 + }, + "frontend/src/hooks/useIntentGraph.ts": { + "leafId": "client-state-state", + "x": 0.60692, + "y": 0.4593274 + }, + "frontend/src/hooks/useMediaQuery.ts": { + "leafId": "client-state-state", + "x": 0.7584358, + "y": 0.3224703 + }, + "frontend/src/hooks/useObservability.ts": { + "leafId": "client-state-state", + "x": 0.7584358, + "y": 0.432843 + }, + "frontend/src/hooks/usePresence.ts": { + "leafId": "client-state-state", + "x": 0.8798748, + "y": 0.3534621 + }, + "frontend/src/hooks/useProjectSort.ts": { + "leafId": "client-state-state", + "x": 0.8798748, + "y": 0.4638348 + }, + "frontend/src/hooks/useProjectsCache.test.ts": { + "leafId": "client-state-state", + "x": 0.5695921, + "y": 0.6232993 + }, + "frontend/src/hooks/useProjectsCache.ts": { + "leafId": "client-state-state", + "x": 0.6971007, + "y": 0.6232993 + }, + "frontend/src/hooks/useQuestionAnchor.ts": { + "leafId": "client-state-state", + "x": 0.8084476, + "y": 0.5903616 + }, + "frontend/src/hooks/useResizablePanel.ts": { + "leafId": "client-state-state", + "x": 0.8921401, + "y": 0.5903616 + }, + "frontend/src/hooks/useSprintEvents.ts": { + "leafId": "client-state-state", + "x": 0.8558675, + "y": 0.6973057 + }, + "frontend/src/hooks/useSprintGraph.ts": { + "leafId": "client-state-state", + "x": 0.5800557, + "y": 0.7903252 + }, + "frontend/src/hooks/useTrackerProviders.ts": { + "leafId": "client-state-state", + "x": 0.5800557, + "y": 0.8949835 + }, + "frontend/src/hooks/useYjsDocument.test.tsx": { + "leafId": "client-state-state", + "x": 0.7077491, + "y": 0.8349017 + }, + "frontend/src/hooks/useYjsDocument.ts": { + "leafId": "client-state-state", + "x": 0.8560524, + "y": 0.8349017 + }, + "frontend/src/lib/agentCli.ts": { + "leafId": "client-state-helpers", + "x": 0.1536002, + "y": 0.1181944 + }, + "frontend/src/lib/agentCredentialFormat.test.ts": { + "leafId": "client-state-helpers", + "x": 0.1536002, + "y": 0.2115183 + }, + "frontend/src/lib/agentCredentialFormat.ts": { + "leafId": "client-state-helpers", + "x": 0.1536002, + "y": 0.2861125 + }, + "frontend/src/lib/aidlcSettings.ts": { + "leafId": "client-state-helpers", + "x": 0.3091719, + "y": 0.1927887 + }, + "frontend/src/lib/appOrigin.test.ts": { + "leafId": "client-state-helpers", + "x": 0.4422719, + "y": 0.1148279 + }, + "frontend/src/lib/appOrigin.ts": { + "leafId": "client-state-helpers", + "x": 0.4422719, + "y": 0.2021231 + }, + "frontend/src/lib/autonomy.ts": { + "leafId": "client-state-helpers", + "x": 0.4422719, + "y": 0.2800838 + }, + "frontend/src/lib/buildSprintDescription.ts": { + "leafId": "client-state-helpers", + "x": 0.0932873, + "y": 0.3959871 + }, + "frontend/src/lib/collaborativeSave.test.ts": { + "leafId": "client-state-helpers", + "x": 0.1814249, + "y": 0.3959871 + }, + "frontend/src/lib/collaborativeSave.ts": { + "leafId": "client-state-helpers", + "x": 0.1485776, + "y": 0.5067299 + }, + "frontend/src/lib/discussion.test.ts": { + "leafId": "client-state-helpers", + "x": 0.3096908, + "y": 0.4323601 + }, + "frontend/src/lib/discussion.ts": { + "leafId": "client-state-helpers", + "x": 0.4478134, + "y": 0.4323601 + }, + "frontend/src/lib/intentPhases.ts": { + "leafId": "client-state-helpers", + "x": 0.1430194, + "y": 0.5860843 + }, + "frontend/src/lib/intentRecovery.test.ts": { + "leafId": "client-state-helpers", + "x": 0.1430194, + "y": 0.6830744 + }, + "frontend/src/lib/intentRecovery.ts": { + "leafId": "client-state-helpers", + "x": 0.2780288, + "y": 0.640093 + }, + "frontend/src/lib/intentSectionPreference.test.ts": { + "leafId": "client-state-helpers", + "x": 0.1954494, + "y": 0.7788692 + }, + "frontend/src/lib/intentSectionPreference.ts": { + "leafId": "client-state-helpers", + "x": 0.1216921, + "y": 0.8801076 + }, + "frontend/src/lib/intentStageSelection.test.ts": { + "leafId": "client-state-helpers", + "x": 0.2567015, + "y": 0.8801076 + }, + "frontend/src/lib/intentStageSelection.ts": { + "leafId": "client-state-helpers", + "x": 0.4217096, + "y": 0.5770829 + }, + "frontend/src/lib/metricAggregation.test.ts": { + "leafId": "client-state-helpers", + "x": 0.4217096, + "y": 0.6911266 + }, + "frontend/src/lib/metricAggregation.ts": { + "leafId": "client-state-helpers", + "x": 0.4217096, + "y": 0.8553752 + }, + "frontend/src/lib/observability/buildFocusSentence.ts": { + "leafId": "client-state-helpers", + "x": 0.5994123, + "y": 0.1119872 + }, + "frontend/src/lib/observability/fetchProjectInfos.ts": { + "leafId": "client-state-helpers", + "x": 0.5994123, + "y": 0.2326683 + }, + "frontend/src/lib/observability/l2Intelligence.ts": { + "leafId": "client-state-helpers", + "x": 0.7370288, + "y": 0.1846411 + }, + "frontend/src/lib/observability/toolLabels.ts": { + "leafId": "client-state-helpers", + "x": 0.8638767, + "y": 0.1019991 + }, + "frontend/src/lib/observability/useObservabilityEvents.ts": { + "leafId": "client-state-helpers", + "x": 0.8638767, + "y": 0.2226802 + }, + "frontend/src/lib/persistentCache.ts": { + "leafId": "client-state-helpers", + "x": 0.5865306, + "y": 0.3674418 + }, + "frontend/src/lib/questionAnchor.ts": { + "leafId": "client-state-helpers", + "x": 0.5865306, + "y": 0.469468 + }, + "frontend/src/lib/realtimeToken.test.ts": { + "leafId": "client-state-helpers", + "x": 0.7092997, + "y": 0.4073484 + }, + "frontend/src/lib/realtimeToken.ts": { + "leafId": "client-state-helpers", + "x": 0.8490293, + "y": 0.381908 + }, + "frontend/src/lib/scope-utils.ts": { + "leafId": "client-state-helpers", + "x": 0.8490293, + "y": 0.4839342 + }, + "frontend/src/lib/seqDeduplicator.ts": { + "leafId": "client-state-helpers", + "x": 0.5604295, + "y": 0.5831565 + }, + "frontend/src/lib/sprintStatus.ts": { + "leafId": "client-state-helpers", + "x": 0.6625258, + "y": 0.5831565 + }, + "frontend/src/lib/timeAgo.test.ts": { + "leafId": "client-state-helpers", + "x": 0.6150567, + "y": 0.7024065 + }, + "frontend/src/lib/timeAgo.ts": { + "leafId": "client-state-helpers", + "x": 0.7431546, + "y": 0.6286246 + }, + "frontend/src/lib/trackerProviders.tsx": { + "leafId": "client-state-helpers", + "x": 0.8543581, + "y": 0.5935096 + }, + "frontend/src/lib/trackerSourceLabel.test.ts": { + "leafId": "client-state-helpers", + "x": 0.8543581, + "y": 0.7127596 + }, + "frontend/src/lib/trackerSourceLabel.ts": { + "leafId": "client-state-helpers", + "x": 0.5627869, + "y": 0.7995537 + }, + "frontend/src/lib/utils.ts": { + "leafId": "client-state-helpers", + "x": 0.6420911, + "y": 0.7995537 + }, + "frontend/src/lib/workProductsPreference.test.ts": { + "leafId": "client-state-helpers", + "x": 0.5922646, + "y": 0.8953964 + }, + "frontend/src/lib/workProductsPreference.ts": { + "leafId": "client-state-helpers", + "x": 0.7382856, + "y": 0.7864704 + }, + "frontend/src/lib/yjsSeed.test.ts": { + "leafId": "client-state-helpers", + "x": 0.7382856, + "y": 0.8823131 + }, + "frontend/src/lib/yjsSeed.ts": { + "leafId": "client-state-helpers", + "x": 0.8722811, + "y": 0.8026737 + }, + "frontend/src/utils/colors.ts": { + "leafId": "client-state-helpers", + "x": 0.8722811, + "y": 0.8985164 + }, + "frontend/public/logo.svg": { + "leafId": "frontend-platform-assets", + "x": 0.2367329, + "y": 0.4472776 + }, + "frontend/src/assets/react.svg": { + "leafId": "frontend-platform-assets", + "x": 0.2367329, + "y": 0.8850776 + }, + "frontend/src/index.css": { + "leafId": "frontend-platform-assets", + "x": 0.6762929, + "y": 0.50176 + }, + "frontend/.env.example": { + "leafId": "frontend-platform-build", + "x": 0.1133655, + "y": 0.1678674 + }, + "frontend/.gitignore": { + "leafId": "frontend-platform-build", + "x": 0.2214698, + "y": 0.1678674 + }, + "frontend/README.md": { + "leafId": "frontend-platform-build", + "x": 0.3514965, + "y": 0.1678674 + }, + "frontend/agent-output-preview.html": { + "leafId": "frontend-platform-build", + "x": 0.5178966, + "y": 0.1091197 + }, + "frontend/components.json": { + "leafId": "frontend-platform-build", + "x": 0.5178966, + "y": 0.2130272 + }, + "frontend/index.html": { + "leafId": "frontend-platform-build", + "x": 0.6562694, + "y": 0.1678674 + }, + "frontend/package-lock.json": { + "leafId": "frontend-platform-build", + "x": 0.3817651, + "y": 0.6056674 + }, + "frontend/package.json": { + "leafId": "frontend-platform-build", + "x": 0.7956528, + "y": 0.182137 + }, + "frontend/postcss.config.js": { + "leafId": "frontend-platform-build", + "x": 0.9138877, + "y": 0.182137 + }, + "frontend/src/test/setup.ts": { + "leafId": "frontend-platform-build", + "x": 0.7626239, + "y": 0.3580977 + }, + "frontend/tailwind.config.js": { + "leafId": "frontend-platform-build", + "x": 0.7626239, + "y": 0.4736651 + }, + "frontend/tsconfig.app.json": { + "leafId": "frontend-platform-build", + "x": 0.8808589, + "y": 0.4158814 + }, + "frontend/tsconfig.json": { + "leafId": "frontend-platform-build", + "x": 0.7884075, + "y": 0.5717699 + }, + "frontend/tsconfig.node.json": { + "leafId": "frontend-platform-build", + "x": 0.7884075, + "y": 0.681929 + }, + "frontend/tsconfig.test.json": { + "leafId": "frontend-platform-build", + "x": 0.9066424, + "y": 0.641608 + }, + "frontend/vite.config.ts": { + "leafId": "frontend-platform-build", + "x": 0.7590541, + "y": 0.8456636 + }, + "frontend/vitest.config.ts": { + "leafId": "frontend-platform-build", + "x": 0.877289, + "y": 0.8456636 + }, + "lambda/intent-pin-lookup/index.js": { + "leafId": "intent-api-lifecycle", + "x": 0.1306698, + "y": 0.1326773 + }, + "lambda/intent-pin-lookup/package.json": { + "leafId": "intent-api-lifecycle", + "x": 0.1306698, + "y": 0.2328165 + }, + "lambda/intent-pin-lookup/test/index.test.js": { + "leafId": "intent-api-lifecycle", + "x": 0.2688996, + "y": 0.1640992 + }, + "lambda/intents/attachments.js": { + "leafId": "intent-api-lifecycle", + "x": 0.1986698, + "y": 0.3055479 + }, + "lambda/intents/audit.js": { + "leafId": "intent-api-lifecycle", + "x": 0.4275389, + "y": 0.1440677 + }, + "lambda/intents/impact.js": { + "leafId": "intent-api-lifecycle", + "x": 0.4275389, + "y": 0.2855164 + }, + "lambda/intents/index.js": { + "leafId": "intent-api-lifecycle", + "x": 0.2893091, + "y": 0.5147792 + }, + "lambda/intents/knowledge-graph.js": { + "leafId": "intent-api-lifecycle", + "x": 0.1315572, + "y": 0.8111305 + }, + "lambda/intents/native-export.js": { + "leafId": "intent-api-lifecycle", + "x": 0.3009249, + "y": 0.8111305 + }, + "lambda/intents/package.json": { + "leafId": "intent-api-lifecycle", + "x": 0.4586768, + "y": 0.7271255 + }, + "lambda/intents/test/attachments.test.js": { + "leafId": "intent-api-lifecycle", + "x": 0.4586768, + "y": 0.8555549 + }, + "lambda/intents/test/audit.test.js": { + "leafId": "intent-api-lifecycle", + "x": 0.5901989, + "y": 0.1576412 + }, + "lambda/intents/test/gate-answer-race.test.js": { + "leafId": "intent-api-lifecycle", + "x": 0.7438202, + "y": 0.1576412 + }, + "lambda/intents/test/impact.test.js": { + "leafId": "intent-api-lifecycle", + "x": 0.8824903, + "y": 0.1576412 + }, + "lambda/intents/test/intents.test.js": { + "leafId": "intent-api-lifecycle", + "x": 0.7288691, + "y": 0.4818831 + }, + "lambda/intents/test/knowledge-graph.test.js": { + "leafId": "intent-api-lifecycle", + "x": 0.6247705, + "y": 0.8260019 + }, + "lambda/intents/test/native-export.test.js": { + "leafId": "intent-api-lifecycle", + "x": 0.8354614, + "y": 0.8260019 + }, + "lambda/building-blocks/index.js": { + "leafId": "intent-api-authoring", + "x": 0.20852, + "y": 0.1705949 + }, + "lambda/building-blocks/package.json": { + "leafId": "intent-api-authoring", + "x": 0.3884946, + "y": 0.1705949 + }, + "lambda/building-blocks/test/building-blocks.test.js": { + "leafId": "intent-api-authoring", + "x": 0.2404146, + "y": 0.3946549 + }, + "lambda/seed-blocks/index.js": { + "leafId": "intent-api-authoring", + "x": 0.5045244, + "y": 0.28802 + }, + "lambda/seed-blocks/package.json": { + "leafId": "intent-api-authoring", + "x": 0.1716491, + "y": 0.5443169 + }, + "lambda/seed-blocks/test/seed-blocks.test.js": { + "leafId": "intent-api-authoring", + "x": 0.1716491, + "y": 0.758057 + }, + "lambda/workflows/index.js": { + "leafId": "intent-api-authoring", + "x": 0.435759, + "y": 0.72582 + }, + "lambda/workflows/package.json": { + "leafId": "intent-api-authoring", + "x": 0.6225088, + "y": 0.1698725 + }, + "lambda/workflows/test/aidlc-release-upgrade.test.js": { + "leafId": "intent-api-authoring", + "x": 0.797959, + "y": 0.1698725 + }, + "lambda/workflows/test/aidlc-releases.test.js": { + "leafId": "intent-api-authoring", + "x": 0.7641098, + "y": 0.4553784 + }, + "lambda/workflows/test/workflows.test.js": { + "leafId": "intent-api-authoring", + "x": 0.7641098, + "y": 0.7872659 + }, + "lambda/v2-orchestrator/index.js": { + "leafId": "orchestrator-flow", + "x": 0.2353667, + "y": 0.211815 + }, + "lambda/v2-orchestrator/package.json": { + "leafId": "orchestrator-flow", + "x": 0.0841337, + "y": 0.4615599 + }, + "lambda/v2-orchestrator/test/construction-autonomy-gates.test.js": { + "leafId": "orchestrator-flow", + "x": 0.2590603, + "y": 0.4615599 + }, + "lambda/v2-orchestrator/test/construction-autonomy-grant-store.integration.test.js": { + "leafId": "orchestrator-flow", + "x": 0.5059055, + "y": 0.1589329 + }, + "lambda/v2-orchestrator/test/fixtures/engine-gate-before-recovery.js": { + "leafId": "orchestrator-flow", + "x": 0.5059055, + "y": 0.3077974 + }, + "lambda/v2-orchestrator/test/intent-settings-reach.test.js": { + "leafId": "orchestrator-flow", + "x": 0.5059055, + "y": 0.4625694 + }, + "lambda/v2-orchestrator/test/learnings-ritual.test.js": { + "leafId": "orchestrator-flow", + "x": 0.1855929, + "y": 0.6271021 + }, + "lambda/v2-orchestrator/test/orchestrator-replay.test.js": { + "leafId": "orchestrator-flow", + "x": 0.1855929, + "y": 0.8151572 + }, + "lambda/v2-orchestrator/test/orchestrator.test.js": { + "leafId": "orchestrator-flow", + "x": 0.4561317, + "y": 0.7515049 + }, + "lambda/v2-orchestrator/test/poc/poc-a-wavefront.test.js": { + "leafId": "orchestrator-flow", + "x": 0.7018267, + "y": 0.1554289 + }, + "lambda/v2-orchestrator/test/poc/poc-b-multi-callback.test.js": { + "leafId": "orchestrator-flow", + "x": 0.8708479, + "y": 0.1554289 + }, + "lambda/v2-orchestrator/test/poc/poc-c-interrupted-step.test.js": { + "leafId": "orchestrator-flow", + "x": 0.6758404, + "y": 0.3264618 + }, + "lambda/v2-orchestrator/test/poc/poc-d-async-stage.test.js": { + "leafId": "orchestrator-flow", + "x": 0.8448616, + "y": 0.3264618 + }, + "lambda/v2-orchestrator/test/release-coexistence-simulation.test.js": { + "leafId": "orchestrator-flow", + "x": 0.7705388, + "y": 0.4881219 + }, + "lambda/v2-orchestrator/test/skeleton-switch.test.js": { + "leafId": "orchestrator-flow", + "x": 0.6606957, + "y": 0.6980218 + }, + "lambda/v2-orchestrator/test/stage-loopback.test.js": { + "leafId": "orchestrator-flow", + "x": 0.8297169, + "y": 0.6980218 + }, + "lambda/v2-orchestrator/test/stage-skip.test.js": { + "leafId": "orchestrator-flow", + "x": 0.7705388, + "y": 0.8826928 + }, + "lambda/v2-orchestrator/gate-callback.js": { + "leafId": "orchestrator-gates", + "x": 0.1389978, + "y": 0.1657481 + }, + "lambda/v2-orchestrator/pr-attribution.js": { + "leafId": "orchestrator-gates", + "x": 0.241882, + "y": 0.1657481 + }, + "lambda/v2-orchestrator/quorum-edit.js": { + "leafId": "orchestrator-gates", + "x": 0.1633242, + "y": 0.4384448 + }, + "lambda/v2-orchestrator/section.js": { + "leafId": "orchestrator-gates", + "x": 0.4398207, + "y": 0.3366567 + }, + "lambda/v2-orchestrator/test/gate-callback.test.js": { + "leafId": "orchestrator-gates", + "x": 0.1400014, + "y": 0.7744567 + }, + "lambda/v2-orchestrator/test/gate-findings.test.js": { + "leafId": "orchestrator-gates", + "x": 0.4164979, + "y": 0.7744567 + }, + "lambda/v2-orchestrator/test/lane-gate-resume.test.js": { + "leafId": "orchestrator-gates", + "x": 0.7764965, + "y": 0.1788919 + }, + "lambda/v2-orchestrator/test/quorum-edit.test.js": { + "leafId": "orchestrator-gates", + "x": 0.7764965, + "y": 0.3900341 + }, + "lambda/v2-orchestrator/test/section-integration.test.js": { + "leafId": "orchestrator-gates", + "x": 0.7764965, + "y": 0.62973 + }, + "lambda/v2-orchestrator/test/section.test.js": { + "leafId": "orchestrator-gates", + "x": 0.7764965, + "y": 0.8563878 + }, + "lambda/agentcore/command-registry.js": { + "leafId": "agentcore-commands", + "x": 0.0775205, + "y": 0.1060673 + }, + "lambda/agentcore/commands/capabilities.js": { + "leafId": "agentcore-commands", + "x": 0.2110745, + "y": 0.1060673 + }, + "lambda/agentcore/commands/compose-plan-start.js": { + "leafId": "agentcore-commands", + "x": 0.193994, + "y": 0.2462237 + }, + "lambda/agentcore/commands/create-workflow-checkpoint.js": { + "leafId": "agentcore-commands", + "x": 0.4178435, + "y": 0.1093682 + }, + "lambda/agentcore/commands/derive-artifacts.js": { + "leafId": "agentcore-commands", + "x": 0.4178435, + "y": 0.2495245 + }, + "lambda/agentcore/commands/discussion-assist-start.js": { + "leafId": "agentcore-commands", + "x": 0.1870846, + "y": 0.4369813 + }, + "lambda/agentcore/commands/init-ws.js": { + "leafId": "agentcore-commands", + "x": 0.4109341, + "y": 0.4369813 + }, + "lambda/agentcore/commands/inspect.js": { + "leafId": "agentcore-commands", + "x": 0.1094251, + "y": 0.6622378 + }, + "lambda/agentcore/commands/lane.js": { + "leafId": "agentcore-commands", + "x": 0.2438601, + "y": 0.6622378 + }, + "lambda/agentcore/commands/managed-runtime-check.js": { + "leafId": "agentcore-commands", + "x": 0.1014058, + "y": 0.8671729 + }, + "lambda/agentcore/commands/promote-units.js": { + "leafId": "agentcore-commands", + "x": 0.2358408, + "y": 0.8671729 + }, + "lambda/agentcore/commands/quorum-edit-apply-start.js": { + "leafId": "agentcore-commands", + "x": 0.4187245, + "y": 0.6481796 + }, + "lambda/agentcore/commands/quorum-edit-plan-start.js": { + "leafId": "agentcore-commands", + "x": 0.4187245, + "y": 0.8531147 + }, + "lambda/agentcore/commands/quorum-edit-shared.js": { + "leafId": "agentcore-commands", + "x": 0.6110703, + "y": 0.1343552 + }, + "lambda/agentcore/commands/record-learning.js": { + "leafId": "agentcore-commands", + "x": 0.6110703, + "y": 0.2638336 + }, + "lambda/agentcore/commands/record-pr.js": { + "leafId": "agentcore-commands", + "x": 0.7451775, + "y": 0.1934384 + }, + "lambda/agentcore/commands/record-unit-pr.js": { + "leafId": "agentcore-commands", + "x": 0.5535933, + "y": 0.4028177 + }, + "lambda/agentcore/commands/repair-structure.js": { + "leafId": "agentcore-commands", + "x": 0.6877005, + "y": 0.4028177 + }, + "lambda/agentcore/commands/resolve-conflict.js": { + "leafId": "agentcore-commands", + "x": 0.8579566, + "y": 0.1836749 + }, + "lambda/agentcore/commands/run-stage-start.js": { + "leafId": "agentcore-commands", + "x": 0.8579566, + "y": 0.3930543 + }, + "lambda/agentcore/commands/run-stage.js": { + "leafId": "agentcore-commands", + "x": 0.7238495, + "y": 0.6542095 + }, + "lambda/agentcore/commands/verify-connection.js": { + "leafId": "agentcore-commands", + "x": 0.5693813, + "y": 0.8826302 + }, + "lambda/agentcore/commands/verify-mcp.js": { + "leafId": "agentcore-commands", + "x": 0.7850919, + "y": 0.8826302 + }, + "lambda/agentcore/cli/backend-adapters.js": { + "leafId": "agentcore-cli", + "x": 0.1289633, + "y": 0.1986179 + }, + "lambda/agentcore/cli/codex-parser.js": { + "leafId": "agentcore-cli", + "x": 0.3272222, + "y": 0.1986179 + }, + "lambda/agentcore/cli/codex-store.js": { + "leafId": "agentcore-cli", + "x": 0.2586989, + "y": 0.4373451 + }, + "lambda/agentcore/cli/credential-errors.js": { + "leafId": "agentcore-cli", + "x": 0.5157687, + "y": 0.201567 + }, + "lambda/agentcore/cli/discover.js": { + "leafId": "agentcore-cli", + "x": 0.5157687, + "y": 0.4402942 + }, + "lambda/agentcore/cli/drivers.js": { + "leafId": "agentcore-cli", + "x": 0.2271553, + "y": 0.6814326 + }, + "lambda/agentcore/cli/environment.js": { + "leafId": "agentcore-cli", + "x": 0.2271553, + "y": 0.8805054 + }, + "lambda/agentcore/cli/kiro-parser.js": { + "leafId": "agentcore-cli", + "x": 0.4842251, + "y": 0.7404872 + }, + "lambda/agentcore/cli/kiro-store.js": { + "leafId": "agentcore-cli", + "x": 0.6448841, + "y": 0.2331374 + }, + "lambda/agentcore/cli/one-shot.js": { + "leafId": "agentcore-cli", + "x": 0.8273743, + "y": 0.2331374 + }, + "lambda/agentcore/cli/opencode-parser.js": { + "leafId": "agentcore-cli", + "x": 0.7570698, + "y": 0.4880767 + }, + "lambda/agentcore/cli/opencode-store.js": { + "leafId": "agentcore-cli", + "x": 0.7570698, + "y": 0.636554 + }, + "lambda/agentcore/cli/spawn.js": { + "leafId": "agentcore-cli", + "x": 0.7570698, + "y": 0.8194147 + }, + "lambda/agentcore/mcp/graph-manager.js": { + "leafId": "agentcore-mcp", + "x": 0.1096551, + "y": 0.3119333 + }, + "lambda/agentcore/mcp/graph-writer.js": { + "leafId": "agentcore-mcp", + "x": 0.3944641, + "y": 0.3119333 + }, + "lambda/agentcore/mcp/index.js": { + "leafId": "agentcore-mcp", + "x": 0.1262613, + "y": 0.7497333 + }, + "lambda/agentcore/mcp/process-bridge.js": { + "leafId": "agentcore-mcp", + "x": 0.4110703, + "y": 0.7497333 + }, + "lambda/agentcore/mcp/runtime-bridge.js": { + "leafId": "agentcore-mcp", + "x": 0.7848091, + "y": 0.1423458 + }, + "lambda/agentcore/mcp/server.js": { + "leafId": "agentcore-mcp", + "x": 0.7848091, + "y": 0.4275784 + }, + "lambda/agentcore/mcp/startup-context.js": { + "leafId": "agentcore-mcp", + "x": 0.745543, + "y": 0.7869926 + }, + "lambda/agentcore/mcp/stdio-relay.js": { + "leafId": "agentcore-mcp", + "x": 0.900294, + "y": 0.7869926 + }, + "lambda/agentcore/code-traceability.js": { + "leafId": "agentcore-git", + "x": 0.2460409, + "y": 0.2392313 + }, + "lambda/agentcore/git-auth.js": { + "leafId": "agentcore-git", + "x": 0.5244423, + "y": 0.2392313 + }, + "lambda/agentcore/git-engine.js": { + "leafId": "agentcore-git", + "x": 0.3388414, + "y": 0.6770313 + }, + "lambda/agentcore/git-runner.js": { + "leafId": "agentcore-git", + "x": 0.7784014, + "y": 0.171578 + }, + "lambda/agentcore/repo-paths.js": { + "leafId": "agentcore-git", + "x": 0.7784014, + "y": 0.3557505 + }, + "lambda/agentcore/workspace.js": { + "leafId": "agentcore-git", + "x": 0.7784014, + "y": 0.6859325 + }, + "lambda/agentcore/attachments.js": { + "leafId": "agentcore-context", + "x": 0.1200224, + "y": 0.2205626 + }, + "lambda/agentcore/block-loader.js": { + "leafId": "agentcore-context", + "x": 0.2951022, + "y": 0.2205626 + }, + "lambda/agentcore/context-compiler.js": { + "leafId": "agentcore-context", + "x": 0.4850324, + "y": 0.2205626 + }, + "lambda/agentcore/custom-rules.js": { + "leafId": "agentcore-context", + "x": 0.1074581, + "y": 0.5247448 + }, + "lambda/agentcore/ensemble-runner.js": { + "leafId": "agentcore-context", + "x": 0.3569708, + "y": 0.5247448 + }, + "lambda/agentcore/output-normalizer.js": { + "leafId": "agentcore-context", + "x": 0.2036298, + "y": 0.8059422 + }, + "lambda/agentcore/persona-dispatch.js": { + "leafId": "agentcore-context", + "x": 0.4531425, + "y": 0.8059422 + }, + "lambda/agentcore/prompts/invoke-dialect-annex.md": { + "leafId": "agentcore-context", + "x": 0.6765231, + "y": 0.1181469 + }, + "lambda/agentcore/prompts/mcp-execution-annex.md": { + "leafId": "agentcore-context", + "x": 0.6765231, + "y": 0.2606393 + }, + "lambda/agentcore/release-script-closure.js": { + "leafId": "agentcore-context", + "x": 0.8665705, + "y": 0.2064523 + }, + "lambda/agentcore/sensor-runner.js": { + "leafId": "agentcore-context", + "x": 0.7495126, + "y": 0.4949907 + }, + "lambda/agentcore/stage-materializer.js": { + "leafId": "agentcore-context", + "x": 0.7495126, + "y": 0.7902984 + }, + "lambda/agentcore/Dockerfile": { + "leafId": "agentcore-host", + "x": 0.1633914, + "y": 0.1903704 + }, + "lambda/agentcore/auth-resolver.js": { + "leafId": "agentcore-host", + "x": 0.3836735, + "y": 0.1903704 + }, + "lambda/agentcore/authentication-command-registry.js": { + "leafId": "agentcore-host", + "x": 0.1131535, + "y": 0.3916459 + }, + "lambda/agentcore/bedrock-iam-material.js": { + "leafId": "agentcore-host", + "x": 0.2317588, + "y": 0.3916459 + }, + "lambda/agentcore/bedrock-iam-runtime-provider.js": { + "leafId": "agentcore-host", + "x": 0.1790453, + "y": 0.5177885 + }, + "lambda/agentcore/bedrock-iam.js": { + "leafId": "agentcore-host", + "x": 0.3993274, + "y": 0.4429235 + }, + "lambda/agentcore/clients.js": { + "leafId": "agentcore-host", + "x": 0.2110775, + "y": 0.6730361 + }, + "lambda/agentcore/credential-lease-adapters.js": { + "leafId": "agentcore-host", + "x": 0.2110775, + "y": 0.858283 + }, + "lambda/agentcore/credential-material-registry.js": { + "leafId": "agentcore-host", + "x": 0.4313596, + "y": 0.7543131 + }, + "lambda/agentcore/credential-session.js": { + "leafId": "agentcore-host", + "x": 0.5869482, + "y": 0.227921 + }, + "lambda/agentcore/http-server.js": { + "leafId": "agentcore-host", + "x": 0.806226, + "y": 0.227921 + }, + "lambda/agentcore/invocation-accounting.js": { + "leafId": "agentcore-host", + "x": 0.7202821, + "y": 0.4501996 + }, + "lambda/agentcore/keys-runtime-provider.js": { + "leafId": "agentcore-host", + "x": 0.5534337, + "y": 0.5926723 + }, + "lambda/agentcore/mcp-secret-paths.js": { + "leafId": "agentcore-host", + "x": 0.6721818, + "y": 0.5926723 + }, + "lambda/agentcore/mcp-secret-resolver.js": { + "leafId": "agentcore-host", + "x": 0.6197523, + "y": 0.8081937 + }, + "lambda/agentcore/model-resolver.js": { + "leafId": "agentcore-host", + "x": 0.8390302, + "y": 0.633429 + }, + "lambda/agentcore/package.json": { + "leafId": "agentcore-host", + "x": 0.8029173, + "y": 0.8489503 + }, + "lambda/agentcore/runtime-auth-providers.js": { + "leafId": "agentcore-host", + "x": 0.9034471, + "y": 0.8489503 + }, + "lambda/agentcore/test/a7-answer.mjs": { + "leafId": "agentcore-tests", + "x": 0.0862951, + "y": 0.0915131 + }, + "lambda/agentcore/test/a7-answer2.mjs": { + "leafId": "agentcore-tests", + "x": 0.1405266, + "y": 0.0915131 + }, + "lambda/agentcore/test/a7-harness.mjs": { + "leafId": "agentcore-tests", + "x": 0.1146715, + "y": 0.1470024 + }, + "lambda/agentcore/test/a7-run.sh": { + "leafId": "agentcore-tests", + "x": 0.1868211, + "y": 0.0900861 + }, + "lambda/agentcore/test/agentcore-iam-policy.test.js": { + "leafId": "agentcore-tests", + "x": 0.1868211, + "y": 0.1455753 + }, + "lambda/agentcore/test/aidlc-release-adapters.test.js": { + "leafId": "agentcore-tests", + "x": 0.1325896, + "y": 0.2189696 + }, + "lambda/agentcore/test/attachments.test.js": { + "leafId": "agentcore-tests", + "x": 0.1325896, + "y": 0.2820051 + }, + "lambda/agentcore/test/auth-resolver.test.js": { + "leafId": "agentcore-tests", + "x": 0.2577051, + "y": 0.1116423 + }, + "lambda/agentcore/test/bedrock-iam-verification.test.js": { + "leafId": "agentcore-tests", + "x": 0.2577051, + "y": 0.1880717 + }, + "lambda/agentcore/test/bedrock-iam.test.js": { + "leafId": "agentcore-tests", + "x": 0.2577051, + "y": 0.258914 + }, + "lambda/agentcore/test/block-loader-release.test.js": { + "leafId": "agentcore-tests", + "x": 0.0979307, + "y": 0.3631788 + }, + "lambda/agentcore/test/block-loader.test.js": { + "leafId": "agentcore-tests", + "x": 0.1649911, + "y": 0.3631788 + }, + "lambda/agentcore/test/capabilities.test.js": { + "leafId": "agentcore-tests", + "x": 0.2193549, + "y": 0.3631788 + }, + "lambda/agentcore/test/change-control.test.js": { + "leafId": "agentcore-tests", + "x": 0.1522944, + "y": 0.4648251 + }, + "lambda/agentcore/test/checkpoint-confirmation.test.js": { + "leafId": "agentcore-tests", + "x": 0.2774099, + "y": 0.4026557 + }, + "lambda/agentcore/test/checkpoint-ladder.test.js": { + "leafId": "agentcore-tests", + "x": 0.3474071, + "y": 0.1343053 + }, + "lambda/agentcore/test/code-traceability.test.js": { + "leafId": "agentcore-tests", + "x": 0.4195879, + "y": 0.1343053 + }, + "lambda/agentcore/test/codex-parser.test.js": { + "leafId": "agentcore-tests", + "x": 0.4817389, + "y": 0.1343053 + }, + "lambda/agentcore/test/codex-store.test.js": { + "leafId": "agentcore-tests", + "x": 0.3454376, + "y": 0.2553152 + }, + "lambda/agentcore/test/compose-plan-start.test.js": { + "leafId": "agentcore-tests", + "x": 0.4443248, + "y": 0.2553152 + }, + "lambda/agentcore/test/compose-prompt-budget.test.js": { + "leafId": "agentcore-tests", + "x": 0.3592576, + "y": 0.3313754 + }, + "lambda/agentcore/test/container-deps.test.js": { + "leafId": "agentcore-tests", + "x": 0.3592576, + "y": 0.3851644 + }, + "lambda/agentcore/test/context-compiler.test.js": { + "leafId": "agentcore-tests", + "x": 0.4385819, + "y": 0.3597687 + }, + "lambda/agentcore/test/create-workflow-checkpoint.test.js": { + "leafId": "agentcore-tests", + "x": 0.4888825, + "y": 0.3597687 + }, + "lambda/agentcore/test/credential-errors.test.js": { + "leafId": "agentcore-tests", + "x": 0.3265493, + "y": 0.4589298 + }, + "lambda/agentcore/test/credential-lease.test.js": { + "leafId": "agentcore-tests", + "x": 0.3791737, + "y": 0.4589298 + }, + "lambda/agentcore/test/credential-session.test.js": { + "leafId": "agentcore-tests", + "x": 0.4621825, + "y": 0.4589298 + }, + "lambda/agentcore/test/custom-rules.test.js": { + "leafId": "agentcore-tests", + "x": 0.0821637, + "y": 0.5552011 + }, + "lambda/agentcore/test/derive-artifacts.test.js": { + "leafId": "agentcore-tests", + "x": 0.1401891, + "y": 0.5552011 + }, + "lambda/agentcore/test/discover.test.js": { + "leafId": "agentcore-tests", + "x": 0.0806521, + "y": 0.6310226 + }, + "lambda/agentcore/test/discussion-assist-start.test.js": { + "leafId": "agentcore-tests", + "x": 0.1386774, + "y": 0.6310226 + }, + "lambda/agentcore/test/dockerfile.test.js": { + "leafId": "agentcore-tests", + "x": 0.2158227, + "y": 0.5176788 + }, + "lambda/agentcore/test/drivers.test.js": { + "leafId": "agentcore-tests", + "x": 0.2158227, + "y": 0.5935003 + }, + "lambda/agentcore/test/ensemble-runner.test.js": { + "leafId": "agentcore-tests", + "x": 0.1577973, + "y": 0.6994169 + }, + "lambda/agentcore/test/fixtures/agent-output/claude.jsonl": { + "leafId": "agentcore-tests", + "x": 0.2754597, + "y": 0.5201695 + }, + "lambda/agentcore/test/fixtures/agent-output/codex.jsonl": { + "leafId": "agentcore-tests", + "x": 0.2754597, + "y": 0.553579 + }, + "lambda/agentcore/test/fixtures/agent-output/kiro.jsonl": { + "leafId": "agentcore-tests", + "x": 0.3104958, + "y": 0.5377116 + }, + "lambda/agentcore/test/fixtures/agent-output/opencode.jsonl": { + "leafId": "agentcore-tests", + "x": 0.2671235, + "y": 0.5948613 + }, + "lambda/agentcore/test/fixtures/aidlc-sensor-linter-runtime-budget.ts": { + "leafId": "agentcore-tests", + "x": 0.3021596, + "y": 0.5948613 + }, + "lambda/agentcore/test/fixtures/aidlc-sensor-linter.ts": { + "leafId": "agentcore-tests", + "x": 0.2901906, + "y": 0.6807451 + }, + "lambda/agentcore/test/fixtures/aidlc-sensor-type-check.ts": { + "leafId": "agentcore-tests", + "x": 0.0981328, + "y": 0.7944123 + }, + "lambda/agentcore/test/fixtures/iam-sdk-child.js": { + "leafId": "agentcore-tests", + "x": 0.1682053, + "y": 0.7627895 + }, + "lambda/agentcore/test/fixtures/mcp-stdio-entry.js": { + "leafId": "agentcore-tests", + "x": 0.1682053, + "y": 0.8002411 + }, + "lambda/agentcore/test/fixtures/process-tree-cli.mjs": { + "leafId": "agentcore-tests", + "x": 0.1682053, + "y": 0.8318638 + }, + "lambda/agentcore/test/fixtures/process-tree-late-writer.mjs": { + "leafId": "agentcore-tests", + "x": 0.07294, + "y": 0.8686674 + }, + "lambda/agentcore/test/fixtures/provider-quota-messages.json": { + "leafId": "agentcore-tests", + "x": 0.1125804, + "y": 0.8686674 + }, + "lambda/agentcore/test/fixtures/requirements-analysis.md": { + "leafId": "agentcore-tests", + "x": 0.1000805, + "y": 0.9154795 + }, + "lambda/agentcore/test/fixtures/spawn-shutdown-orphan.mjs": { + "leafId": "agentcore-tests", + "x": 0.1551544, + "y": 0.8754591 + }, + "lambda/agentcore/test/fixtures/spawn-shutdown-plain-child.mjs": { + "leafId": "agentcore-tests", + "x": 0.1855864, + "y": 0.8754591 + }, + "lambda/agentcore/test/fixtures/spawn-shutdown-runner.mjs": { + "leafId": "agentcore-tests", + "x": 0.1701529, + "y": 0.9222712 + }, + "lambda/agentcore/test/git-auth.test.js": { + "leafId": "agentcore-tests", + "x": 0.2629058, + "y": 0.7612075 + }, + "lambda/agentcore/test/git-engine.test.js": { + "leafId": "agentcore-tests", + "x": 0.2629058, + "y": 0.8595431 + }, + "lambda/agentcore/test/git-runner.test.js": { + "leafId": "agentcore-tests", + "x": 0.357355, + "y": 0.553657 + }, + "lambda/agentcore/test/graph-manager.test.js": { + "leafId": "agentcore-tests", + "x": 0.4117808, + "y": 0.553657 + }, + "lambda/agentcore/test/graph-pipeline.integration.test.js": { + "leafId": "agentcore-tests", + "x": 0.4712618, + "y": 0.553657 + }, + "lambda/agentcore/test/graph-writer.test.js": { + "leafId": "agentcore-tests", + "x": 0.416836, + "y": 0.6626397 + }, + "lambda/agentcore/test/helpers/fake-runtime-provider.js": { + "leafId": "agentcore-tests", + "x": 0.3713701, + "y": 0.7429544 + }, + "lambda/agentcore/test/helpers/release-fixture.js": { + "leafId": "agentcore-tests", + "x": 0.3713701, + "y": 0.7905835 + }, + "lambda/agentcore/test/helpers/stock-grounding.js": { + "leafId": "agentcore-tests", + "x": 0.3713701, + "y": 0.837949 + }, + "lambda/agentcore/test/helpers/v2-table.js": { + "leafId": "agentcore-tests", + "x": 0.4629794, + "y": 0.7427242 + }, + "lambda/agentcore/test/http-server.test.js": { + "leafId": "agentcore-tests", + "x": 0.4629794, + "y": 0.8107766 + }, + "lambda/agentcore/test/init-ws.test.js": { + "leafId": "agentcore-tests", + "x": 0.416836, + "y": 0.8989661 + }, + "lambda/agentcore/test/inspect.test.js": { + "leafId": "agentcore-tests", + "x": 0.5644919, + "y": 0.0927031 + }, + "lambda/agentcore/test/integration.test.js": { + "leafId": "agentcore-tests", + "x": 0.5644919, + "y": 0.1521652 + }, + "lambda/agentcore/test/invocation-accounting.test.js": { + "leafId": "agentcore-tests", + "x": 0.6428059, + "y": 0.1234222 + }, + "lambda/agentcore/test/kiro-parser.test.js": { + "leafId": "agentcore-tests", + "x": 0.6992471, + "y": 0.1234222 + }, + "lambda/agentcore/test/kiro-store.test.js": { + "leafId": "agentcore-tests", + "x": 0.529741, + "y": 0.2385874 + }, + "lambda/agentcore/test/lane.test.js": { + "leafId": "agentcore-tests", + "x": 0.5864829, + "y": 0.2385874 + }, + "lambda/agentcore/test/local-e2e-config.js": { + "leafId": "agentcore-tests", + "x": 0.6321312, + "y": 0.2385874 + }, + "lambda/agentcore/test/local-e2e-harness.mjs": { + "leafId": "agentcore-tests", + "x": 0.6878771, + "y": 0.2385874 + }, + "lambda/agentcore/test/local-e2e.test.js": { + "leafId": "agentcore-tests", + "x": 0.7635411, + "y": 0.104614 + }, + "lambda/agentcore/test/loopback-recommendation.test.js": { + "leafId": "agentcore-tests", + "x": 0.8333752, + "y": 0.104614 + }, + "lambda/agentcore/test/managed-runtime-check.test.js": { + "leafId": "agentcore-tests", + "x": 0.7560933, + "y": 0.179426 + }, + "lambda/agentcore/test/mcp-secret-resolver.test.js": { + "leafId": "agentcore-tests", + "x": 0.8259274, + "y": 0.179426 + }, + "lambda/agentcore/test/mcp-server.test.js": { + "leafId": "agentcore-tests", + "x": 0.9063245, + "y": 0.138772 + }, + "lambda/agentcore/test/mcp-stdio.test.js": { + "leafId": "agentcore-tests", + "x": 0.7909344, + "y": 0.2539372 + }, + "lambda/agentcore/test/model-resolver.test.js": { + "leafId": "agentcore-tests", + "x": 0.894004, + "y": 0.2539372 + }, + "lambda/agentcore/test/one-shot-smoke.mjs": { + "leafId": "agentcore-tests", + "x": 0.5651851, + "y": 0.3108997 + }, + "lambda/agentcore/test/one-shot.test.js": { + "leafId": "agentcore-tests", + "x": 0.5651851, + "y": 0.3716154 + }, + "lambda/agentcore/test/opencode-parser.test.js": { + "leafId": "agentcore-tests", + "x": 0.6437327, + "y": 0.3550062 + }, + "lambda/agentcore/test/opencode-store.test.js": { + "leafId": "agentcore-tests", + "x": 0.5326617, + "y": 0.4641007 + }, + "lambda/agentcore/test/persona-dispatch.test.js": { + "leafId": "agentcore-tests", + "x": 0.6112093, + "y": 0.4641007 + }, + "lambda/agentcore/test/persona-session-scope.test.js": { + "leafId": "agentcore-tests", + "x": 0.704231, + "y": 0.3566067 + }, + "lambda/agentcore/test/pr-363-v2-reproduction.test.js": { + "leafId": "agentcore-tests", + "x": 0.704231, + "y": 0.4657012 + }, + "lambda/agentcore/test/process-bridge.test.js": { + "leafId": "agentcore-tests", + "x": 0.8007141, + "y": 0.3341469 + }, + "lambda/agentcore/test/promote-units.test.js": { + "leafId": "agentcore-tests", + "x": 0.8007141, + "y": 0.4027921 + }, + "lambda/agentcore/test/quorum-edit-start.test.js": { + "leafId": "agentcore-tests", + "x": 0.8990333, + "y": 0.3629357 + }, + "lambda/agentcore/test/record-learning.test.js": { + "leafId": "agentcore-tests", + "x": 0.7698679, + "y": 0.4720302 + }, + "lambda/agentcore/test/record-pr.test.js": { + "leafId": "agentcore-tests", + "x": 0.8180549, + "y": 0.4720302 + }, + "lambda/agentcore/test/record-unit-pr.test.js": { + "leafId": "agentcore-tests", + "x": 0.8598619, + "y": 0.4720302 + }, + "lambda/agentcore/test/release-integrity-gate.test.js": { + "leafId": "agentcore-tests", + "x": 0.9099941, + "y": 0.4720302 + }, + "lambda/agentcore/test/release-script-closure-resolver.test.js": { + "leafId": "agentcore-tests", + "x": 0.565171, + "y": 0.5519212 + }, + "lambda/agentcore/test/release-script-closure.test.js": { + "leafId": "agentcore-tests", + "x": 0.565171, + "y": 0.6232126 + }, + "lambda/agentcore/test/resolve-conflict.test.js": { + "leafId": "agentcore-tests", + "x": 0.565171, + "y": 0.6895072 + }, + "lambda/agentcore/test/run-stage-ensemble.test.js": { + "leafId": "agentcore-tests", + "x": 0.6750512, + "y": 0.5824702 + }, + "lambda/agentcore/test/run-stage-start.test.js": { + "leafId": "agentcore-tests", + "x": 0.6750512, + "y": 0.6882066 + }, + "lambda/agentcore/test/run-stage.test.js": { + "leafId": "agentcore-tests", + "x": 0.6183256, + "y": 0.811324 + }, + "lambda/agentcore/test/runtime-auth-providers.test.js": { + "leafId": "agentcore-tests", + "x": 0.6183256, + "y": 0.919128 + }, + "lambda/agentcore/test/sensor-planes.test.js": { + "leafId": "agentcore-tests", + "x": 0.776016, + "y": 0.5594912 + }, + "lambda/agentcore/test/sensor-runner-script.test.js": { + "leafId": "agentcore-tests", + "x": 0.776016, + "y": 0.6392097 + }, + "lambda/agentcore/test/sensor-runner.test.js": { + "leafId": "agentcore-tests", + "x": 0.8816932, + "y": 0.592198 + }, + "lambda/agentcore/test/spawn-shutdown.test.js": { + "leafId": "agentcore-tests", + "x": 0.7832554, + "y": 0.7004557 + }, + "lambda/agentcore/test/spawn.test.js": { + "leafId": "agentcore-tests", + "x": 0.8889325, + "y": 0.7004557 + }, + "lambda/agentcore/test/stage-attempt-commits.test.js": { + "leafId": "agentcore-tests", + "x": 0.7974003, + "y": 0.7597641 + }, + "lambda/agentcore/test/stage-materializer.test.js": { + "leafId": "agentcore-tests", + "x": 0.7974003, + "y": 0.8391215 + }, + "lambda/agentcore/test/verify-connection.test.js": { + "leafId": "agentcore-tests", + "x": 0.7974003, + "y": 0.9136349 + }, + "lambda/agentcore/test/verify-mcp.test.js": { + "leafId": "agentcore-tests", + "x": 0.9030775, + "y": 0.7791258 + }, + "lambda/agentcore/test/workspace.test.js": { + "leafId": "agentcore-tests", + "x": 0.9030775, + "y": 0.8844083 + }, + "lambda/code-files/index.js": { + "leafId": "history-reads", + "x": 0.1530464, + "y": 0.1495109 + }, + "lambda/code-files/package.json": { + "leafId": "history-reads", + "x": 0.2902297, + "y": 0.1495109 + }, + "lambda/general-info/index.js": { + "leafId": "history-reads", + "x": 0.1976234, + "y": 0.2928134 + }, + "lambda/general-info/package.json": { + "leafId": "history-reads", + "x": 0.4282988, + "y": 0.1047506 + }, + "lambda/questions/index.js": { + "leafId": "history-reads", + "x": 0.4282988, + "y": 0.2480531 + }, + "lambda/questions/package.json": { + "leafId": "history-reads", + "x": 0.0962706, + "y": 0.4541605 + }, + "lambda/questions/test/questions.test.js": { + "leafId": "history-reads", + "x": 0.2509379, + "y": 0.4541605 + }, + "lambda/requirements/index.js": { + "leafId": "history-reads", + "x": 0.4457827, + "y": 0.4541605 + }, + "lambda/requirements/package.json": { + "leafId": "history-reads", + "x": 0.1685858, + "y": 0.5930195 + }, + "lambda/reviews/index.js": { + "leafId": "history-reads", + "x": 0.1685858, + "y": 0.7107852 + }, + "lambda/reviews/package.json": { + "leafId": "history-reads", + "x": 0.3091145, + "y": 0.6755217 + }, + "lambda/sprint-graph/index.js": { + "leafId": "history-reads", + "x": 0.2009687, + "y": 0.8664237 + }, + "lambda/sprint-graph/package.json": { + "leafId": "history-reads", + "x": 0.4316442, + "y": 0.598932 + }, + "lambda/sprint-graph/test/sprint-graph.test.js": { + "leafId": "history-reads", + "x": 0.4316442, + "y": 0.789834 + }, + "lambda/sprints/index.js": { + "leafId": "history-reads", + "x": 0.6259203, + "y": 0.1685647 + }, + "lambda/sprints/package.json": { + "leafId": "history-reads", + "x": 0.6259203, + "y": 0.3088163 + }, + "lambda/sprints/test/sprints.test.js": { + "leafId": "history-reads", + "x": 0.8348048, + "y": 0.2042116 + }, + "lambda/tasks/index.js": { + "leafId": "history-reads", + "x": 0.6234689, + "y": 0.4292088 + }, + "lambda/tasks/package.json": { + "leafId": "history-reads", + "x": 0.6234689, + "y": 0.5524355 + }, + "lambda/tasks/test/tasks.test.js": { + "leafId": "history-reads", + "x": 0.8323535, + "y": 0.4676898 + }, + "lambda/timeline-events/index.js": { + "leafId": "history-reads", + "x": 0.6189282, + "y": 0.6739555 + }, + "lambda/timeline-events/package.json": { + "leafId": "history-reads", + "x": 0.760766, + "y": 0.6739555 + }, + "lambda/timeline-events/test/timeline-events.test.js": { + "leafId": "history-reads", + "x": 0.6636287, + "y": 0.8482773 + }, + "lambda/user-stories/index.js": { + "leafId": "history-reads", + "x": 0.8725133, + "y": 0.7083585 + }, + "lambda/user-stories/package.json": { + "leafId": "history-reads", + "x": 0.8725133, + "y": 0.8826802 + }, + "lambda/shared/agent-command-registry.js": { + "leafId": "shared-execution", + "x": 0.116219, + "y": 0.1282533 + }, + "lambda/shared/changed-file-provenance.js": { + "leafId": "shared-execution", + "x": 0.2336639, + "y": 0.1282533 + }, + "lambda/shared/construction-autonomy.js": { + "leafId": "shared-execution", + "x": 0.177885, + "y": 0.2473592 + }, + "lambda/shared/environment-snapshot.js": { + "leafId": "shared-execution", + "x": 0.3484381, + "y": 0.1830658 + }, + "lambda/shared/gate-answer.js": { + "leafId": "shared-execution", + "x": 0.0968837, + "y": 0.403803 + }, + "lambda/shared/gate-preconditions.js": { + "leafId": "shared-execution", + "x": 0.2674369, + "y": 0.403803 + }, + "lambda/shared/pr-strategy.js": { + "leafId": "shared-execution", + "x": 0.4639687, + "y": 0.1386214 + }, + "lambda/shared/runtime-compatibility.js": { + "leafId": "shared-execution", + "x": 0.5522082, + "y": 0.1386214 + }, + "lambda/shared/runtime-session-ids.js": { + "leafId": "shared-execution", + "x": 0.4897857, + "y": 0.2496339 + }, + "lambda/shared/runtime-session.js": { + "leafId": "shared-execution", + "x": 0.4897857, + "y": 0.3957097 + }, + "lambda/shared/runtime-target.js": { + "leafId": "shared-execution", + "x": 0.1396795, + "y": 0.5464727 + }, + "lambda/shared/sensor-verdict.js": { + "leafId": "shared-execution", + "x": 0.1396795, + "y": 0.6601747 + }, + "lambda/shared/session-cleanup-store.js": { + "leafId": "shared-execution", + "x": 0.2872747, + "y": 0.5859552 + }, + "lambda/shared/stage-attempt.js": { + "leafId": "shared-execution", + "x": 0.2872747, + "y": 0.6996572 + }, + "lambda/shared/stage-loopback.js": { + "leafId": "shared-execution", + "x": 0.1404001, + "y": 0.8361992 + }, + "lambda/shared/stage-skip.js": { + "leafId": "shared-execution", + "x": 0.2879953, + "y": 0.8361992 + }, + "lambda/shared/unit-kind-pruning.js": { + "leafId": "shared-execution", + "x": 0.4668278, + "y": 0.5426745 + }, + "lambda/shared/v2-execution-plan.js": { + "leafId": "shared-execution", + "x": 0.4668278, + "y": 0.7597373 + }, + "lambda/shared/v2-process-keys.js": { + "leafId": "shared-execution", + "x": 0.7587926, + "y": 0.1792986 + }, + "lambda/shared/v2-process-store.js": { + "leafId": "shared-execution", + "x": 0.7587926, + "y": 0.4669802 + }, + "lambda/shared/v2-sensor-contract.js": { + "leafId": "shared-execution", + "x": 0.6790026, + "y": 0.7894417 + }, + "lambda/shared/v2-workflow-plan.js": { + "leafId": "shared-execution", + "x": 0.85977, + "y": 0.7894417 + }, + "lambda/shared/agent-auth-actions.js": { + "leafId": "shared-authentication", + "x": 0.1342711, + "y": 0.1972232 + }, + "lambda/shared/agent-auth-bedrock-iam-schema.js": { + "leafId": "shared-authentication", + "x": 0.2773547, + "y": 0.1260533 + }, + "lambda/shared/agent-auth-builtin-modes.js": { + "leafId": "shared-authentication", + "x": 0.2773547, + "y": 0.2593165 + }, + "lambda/shared/agent-auth-catalog.js": { + "leafId": "shared-authentication", + "x": 0.4317892, + "y": 0.0780976 + }, + "lambda/shared/agent-auth-changes.js": { + "leafId": "shared-authentication", + "x": 0.4317892, + "y": 0.2113608 + }, + "lambda/shared/agent-auth-contracts.js": { + "leafId": "shared-authentication", + "x": 0.1419935, + "y": 0.4273178 + }, + "lambda/shared/agent-auth-inventory-repository.js": { + "leafId": "shared-authentication", + "x": 0.3053372, + "y": 0.4273178 + }, + "lambda/shared/agent-auth-inventory.js": { + "leafId": "shared-authentication", + "x": 0.4520494, + "y": 0.4273178 + }, + "lambda/shared/agent-auth-key-changes.js": { + "leafId": "shared-authentication", + "x": 0.0991829, + "y": 0.604907 + }, + "lambda/shared/agent-auth-mode-registry.js": { + "leafId": "shared-authentication", + "x": 0.2219513, + "y": 0.604907 + }, + "lambda/shared/agent-auth-modes.js": { + "leafId": "shared-authentication", + "x": 0.0932053, + "y": 0.7466151 + }, + "lambda/shared/agent-auth-protocol.js": { + "leafId": "shared-authentication", + "x": 0.2159738, + "y": 0.7466151 + }, + "lambda/shared/agent-auth-providers.js": { + "leafId": "shared-authentication", + "x": 0.1041954, + "y": 0.8735627 + }, + "lambda/shared/agent-auth-redemption.js": { + "leafId": "shared-authentication", + "x": 0.2269639, + "y": 0.8735627 + }, + "lambda/shared/agent-auth-review-repository.js": { + "leafId": "shared-authentication", + "x": 0.3631522, + "y": 0.620671 + }, + "lambda/shared/agent-auth-runtime-capabilities.js": { + "leafId": "shared-authentication", + "x": 0.4686494, + "y": 0.620671 + }, + "lambda/shared/agent-auth-selection-strategies.js": { + "leafId": "shared-authentication", + "x": 0.4114741, + "y": 0.7773261 + }, + "lambda/shared/agent-binding-selection.js": { + "leafId": "shared-authentication", + "x": 0.4114741, + "y": 0.8885097 + }, + "lambda/shared/agent-connection-repository.js": { + "leafId": "shared-authentication", + "x": 0.6009098, + "y": 0.1802951 + }, + "lambda/shared/agent-credential-grants.js": { + "leafId": "shared-authentication", + "x": 0.7752411, + "y": 0.1802951 + }, + "lambda/shared/agent-credential-lease.js": { + "leafId": "shared-authentication", + "x": 0.9025969, + "y": 0.1802951 + }, + "lambda/shared/agent-credential-metadata.js": { + "leafId": "shared-authentication", + "x": 0.6273159, + "y": 0.3498172 + }, + "lambda/shared/agent-credential-service.js": { + "leafId": "shared-authentication", + "x": 0.6273159, + "y": 0.4617763 + }, + "lambda/shared/agent-credentials.js": { + "leafId": "shared-authentication", + "x": 0.8386103, + "y": 0.3124114 + }, + "lambda/shared/agent-key-repository.js": { + "leafId": "shared-authentication", + "x": 0.8386103, + "y": 0.4243705 + }, + "lambda/shared/agent-oauth-contract.js": { + "leafId": "shared-authentication", + "x": 0.5908162, + "y": 0.6265514 + }, + "lambda/shared/agent-oauth-state-repository.js": { + "leafId": "shared-authentication", + "x": 0.7271451, + "y": 0.6265514 + }, + "lambda/shared/authz.js": { + "leafId": "shared-authentication", + "x": 0.5718542, + "y": 0.8360571 + }, + "lambda/shared/bedrock-iam.js": { + "leafId": "shared-authentication", + "x": 0.7081831, + "y": 0.8360571 + }, + "lambda/shared/legacy-authz.js": { + "leafId": "shared-authentication", + "x": 0.8645946, + "y": 0.596324 + }, + "lambda/shared/sso-roles.js": { + "leafId": "shared-authentication", + "x": 0.8645946, + "y": 0.7633274 + }, + "lambda/shared/tenant.js": { + "leafId": "shared-authentication", + "x": 0.8645946, + "y": 0.8970577 + }, + "lambda/shared/aidlc-capabilities.js": { + "leafId": "shared-methodology", + "x": 0.1524676, + "y": 0.1853328 + }, + "lambda/shared/aidlc-compatibility-profiles.js": { + "leafId": "shared-methodology", + "x": 0.2847592, + "y": 0.1853328 + }, + "lambda/shared/aidlc-compatibility.js": { + "leafId": "shared-methodology", + "x": 0.1927317, + "y": 0.4057422 + }, + "lambda/shared/aidlc-custom-source.js": { + "leafId": "shared-methodology", + "x": 0.3884614, + "y": 0.1206564 + }, + "lambda/shared/aidlc-ref.js": { + "leafId": "shared-methodology", + "x": 0.4870885, + "y": 0.1206564 + }, + "lambda/shared/aidlc-release-importer.js": { + "leafId": "shared-methodology", + "x": 0.4236505, + "y": 0.2358938 + }, + "lambda/shared/aidlc-release.js": { + "leafId": "shared-methodology", + "x": 0.4236505, + "y": 0.3996068 + }, + "lambda/shared/annex-reach.js": { + "leafId": "shared-methodology", + "x": 0.1290974, + "y": 0.5411022 + }, + "lambda/shared/artifact-edit.js": { + "leafId": "shared-methodology", + "x": 0.1290974, + "y": 0.6646017 + }, + "lambda/shared/artifact-extractors.js": { + "leafId": "shared-methodology", + "x": 0.2593363, + "y": 0.6282783 + }, + "lambda/shared/artifact-structure-contract.js": { + "leafId": "shared-methodology", + "x": 0.1003704, + "y": 0.8456689 + }, + "lambda/shared/artifact-versioning.js": { + "leafId": "shared-methodology", + "x": 0.2306093, + "y": 0.8456689 + }, + "lambda/shared/block-mappers.js": { + "leafId": "shared-methodology", + "x": 0.4215977, + "y": 0.585425 + }, + "lambda/shared/blocks.js": { + "leafId": "shared-methodology", + "x": 0.4215977, + "y": 0.7380329 + }, + "lambda/shared/compile.js": { + "leafId": "shared-methodology", + "x": 0.4215977, + "y": 0.8747773 + }, + "lambda/shared/compose-match.js": { + "leafId": "shared-methodology", + "x": 0.602588, + "y": 0.1509081 + }, + "lambda/shared/composed-grid.js": { + "leafId": "shared-methodology", + "x": 0.602588, + "y": 0.274335 + }, + "lambda/shared/custom-rule-versions.js": { + "leafId": "shared-methodology", + "x": 0.7297182, + "y": 0.1045256 + }, + "lambda/shared/distribution-archive.js": { + "leafId": "shared-methodology", + "x": 0.7297182, + "y": 0.2279526 + }, + "lambda/shared/ensemble-contribution.js": { + "leafId": "shared-methodology", + "x": 0.7898493, + "y": 0.1169508 + }, + "lambda/shared/frontmatter.js": { + "leafId": "shared-methodology", + "x": 0.8713602, + "y": 0.1169508 + }, + "lambda/shared/intent-aidlc-settings.js": { + "leafId": "shared-methodology", + "x": 0.858049, + "y": 0.2403778 + }, + "lambda/shared/intent-methodology.js": { + "leafId": "shared-methodology", + "x": 0.5609563, + "y": 0.3948812 + }, + "lambda/shared/methodology-catalog.js": { + "leafId": "shared-methodology", + "x": 0.6689525, + "y": 0.3948812 + }, + "lambda/shared/native-repositories.js": { + "leafId": "shared-methodology", + "x": 0.6302738, + "y": 0.5128869 + }, + "lambda/shared/native-workspace-projector.js": { + "leafId": "shared-methodology", + "x": 0.838915, + "y": 0.4288197 + }, + "lambda/shared/release-registry.js": { + "leafId": "shared-methodology", + "x": 0.6405156, + "y": 0.669703 + }, + "lambda/shared/release-resolver.js": { + "leafId": "shared-methodology", + "x": 0.6405156, + "y": 0.8660703 + }, + "lambda/shared/script-closure.js": { + "leafId": "shared-methodology", + "x": 0.8491568, + "y": 0.5830042 + }, + "lambda/shared/upstream-artifact-ids.json": { + "leafId": "shared-methodology", + "x": 0.8491568, + "y": 0.683878 + }, + "lambda/shared/workflow-checkpoint.js": { + "leafId": "shared-methodology", + "x": 0.8491568, + "y": 0.8056436 + }, + "lambda/shared/workflows.js": { + "leafId": "shared-methodology", + "x": 0.8491568, + "y": 0.9011371 + }, + "lambda/shared/agent-model-discovery.js": { + "leafId": "shared-helpers", + "x": 0.0749432, + "y": 0.0902548 + }, + "lambda/shared/bedrock-models.js": { + "leafId": "shared-helpers", + "x": 0.1189662, + "y": 0.0902548 + }, + "lambda/shared/cli-models.js": { + "leafId": "shared-helpers", + "x": 0.104463, + "y": 0.1375147 + }, + "lambda/shared/codecommit-connection.js": { + "leafId": "shared-helpers", + "x": 0.1669543, + "y": 0.1112199 + }, + "lambda/shared/codecommit-role.js": { + "leafId": "shared-helpers", + "x": 0.1229313, + "y": 0.1802805 + }, + "lambda/shared/concurrency.js": { + "leafId": "shared-helpers", + "x": 0.2124652, + "y": 0.0773738 + }, + "lambda/shared/git-connection-store.js": { + "leafId": "shared-helpers", + "x": 0.2124652, + "y": 0.1291001 + }, + "lambda/shared/git-handler.js": { + "leafId": "shared-helpers", + "x": 0.2708699, + "y": 0.1156863 + }, + "lambda/shared/git-oauth.js": { + "leafId": "shared-helpers", + "x": 0.2438273, + "y": 0.1847469 + }, + "lambda/shared/git-token.js": { + "leafId": "shared-helpers", + "x": 0.0988107, + "y": 0.2586787 + }, + "lambda/shared/github-admin.js": { + "leafId": "shared-helpers", + "x": 0.1688831, + "y": 0.2347632 + }, + "lambda/shared/github-app-discovery.js": { + "leafId": "shared-helpers", + "x": 0.1688831, + "y": 0.2913607 + }, + "lambda/shared/github-auth-config.js": { + "leafId": "shared-helpers", + "x": 0.2260966, + "y": 0.2281771 + }, + "lambda/shared/graph-rows.js": { + "leafId": "shared-helpers", + "x": 0.2769202, + "y": 0.2281771 + }, + "lambda/shared/intent-deletion.js": { + "leafId": "shared-helpers", + "x": 0.2514083, + "y": 0.2847746 + }, + "lambda/shared/intent-url.js": { + "leafId": "shared-helpers", + "x": 0.0794681, + "y": 0.3268474 + }, + "lambda/shared/lambda-payload.js": { + "leafId": "shared-helpers", + "x": 0.0794681, + "y": 0.3522488 + }, + "lambda/shared/mcp-secrets-store.js": { + "leafId": "shared-helpers", + "x": 0.1319067, + "y": 0.3406776 + }, + "lambda/shared/mcp-validator.js": { + "leafId": "shared-helpers", + "x": 0.1128786, + "y": 0.3997439 + }, + "lambda/shared/metric-classification.js": { + "leafId": "shared-helpers", + "x": 0.177105, + "y": 0.3743426 + }, + "lambda/shared/model-pricing.js": { + "leafId": "shared-helpers", + "x": 0.0937951, + "y": 0.4745567 + }, + "lambda/shared/realtime-token.js": { + "leafId": "shared-helpers", + "x": 0.1580215, + "y": 0.4745567 + }, + "lambda/shared/repo-fetch.js": { + "leafId": "shared-helpers", + "x": 0.2185428, + "y": 0.3569067 + }, + "lambda/shared/repo-provider.js": { + "leafId": "shared-helpers", + "x": 0.2185428, + "y": 0.4090389 + }, + "lambda/shared/repo-validation.js": { + "leafId": "shared-helpers", + "x": 0.2752123, + "y": 0.3499856 + }, + "lambda/shared/response.js": { + "leafId": "shared-helpers", + "x": 0.2752123, + "y": 0.4021178 + }, + "lambda/shared/safe-event-logger.js": { + "leafId": "shared-helpers", + "x": 0.2092985, + "y": 0.4676226 + }, + "lambda/shared/source-control-bindings.js": { + "leafId": "shared-helpers", + "x": 0.265968, + "y": 0.4676226 + }, + "lambda/shared/source-control-credentials.js": { + "leafId": "shared-helpers", + "x": 0.3567724, + "y": 0.0963276 + }, + "lambda/shared/test/agent-auth-binding-identity.test.js": { + "leafId": "shared-helpers", + "x": 0.3307032, + "y": 0.1577779 + }, + "lambda/shared/test/agent-auth-boundary.test.js": { + "leafId": "shared-helpers", + "x": 0.3852436, + "y": 0.1577779 + }, + "lambda/shared/test/agent-auth-changes.test.js": { + "leafId": "shared-helpers", + "x": 0.463554, + "y": 0.0990418 + }, + "lambda/shared/test/agent-auth-default-selection.test.js": { + "leafId": "shared-helpers", + "x": 0.463554, + "y": 0.1604921 + }, + "lambda/shared/test/agent-auth-foundation.test.js": { + "leafId": "shared-helpers", + "x": 0.343543, + "y": 0.2190918 + }, + "lambda/shared/test/agent-auth-mode-injection.test.js": { + "leafId": "shared-helpers", + "x": 0.343543, + "y": 0.2710606 + }, + "lambda/shared/test/agent-auth-mode-registry.test.js": { + "leafId": "shared-helpers", + "x": 0.4136335, + "y": 0.2388294 + }, + "lambda/shared/test/agent-auth-review-regressions.test.js": { + "leafId": "shared-helpers", + "x": 0.4791041, + "y": 0.2388294 + }, + "lambda/shared/test/agent-auth-runtime-capabilities.test.js": { + "leafId": "shared-helpers", + "x": 0.3305781, + "y": 0.3234899 + }, + "lambda/shared/test/agent-credential-grants.test.js": { + "leafId": "shared-helpers", + "x": 0.3898925, + "y": 0.3234899 + }, + "lambda/shared/test/agent-credentials.test.js": { + "leafId": "shared-helpers", + "x": 0.3435906, + "y": 0.38399 + }, + "lambda/shared/test/agent-model-discovery.test.js": { + "leafId": "shared-helpers", + "x": 0.402905, + "y": 0.38399 + }, + "lambda/shared/test/aidlc-capabilities-ensemble.test.js": { + "leafId": "shared-helpers", + "x": 0.4683279, + "y": 0.3086772 + }, + "lambda/shared/test/aidlc-capabilities.test.js": { + "leafId": "shared-helpers", + "x": 0.4683279, + "y": 0.3691773 + }, + "lambda/shared/test/aidlc-compatibility.test.js": { + "leafId": "shared-helpers", + "x": 0.3522485, + "y": 0.4637513 + }, + "lambda/shared/test/aidlc-custom-source.test.js": { + "leafId": "shared-helpers", + "x": 0.4199577, + "y": 0.4637513 + }, + "lambda/shared/test/aidlc-intent-settings.test.js": { + "leafId": "shared-helpers", + "x": 0.4767228, + "y": 0.4637513 + }, + "lambda/shared/test/aidlc-ref.test.js": { + "leafId": "shared-helpers", + "x": 0.0750937, + "y": 0.5457552 + }, + "lambda/shared/test/aidlc-release-adapters.test.js": { + "leafId": "shared-helpers", + "x": 0.123664, + "y": 0.5457552 + }, + "lambda/shared/test/aidlc-release-collaborators.test.js": { + "leafId": "shared-helpers", + "x": 0.1090103, + "y": 0.6069781 + }, + "lambda/shared/test/aidlc-release-importer.test.js": { + "leafId": "shared-helpers", + "x": 0.1779245, + "y": 0.5769273 + }, + "lambda/shared/test/aidlc-release-policy.test.js": { + "leafId": "shared-helpers", + "x": 0.1018104, + "y": 0.6898674 + }, + "lambda/shared/test/aidlc-release-scope-policy.test.js": { + "leafId": "shared-helpers", + "x": 0.1707246, + "y": 0.6898674 + }, + "lambda/shared/test/aidlc-release-scope-settings.test.js": { + "leafId": "shared-helpers", + "x": 0.2465094, + "y": 0.5397938 + }, + "lambda/shared/test/aidlc-release.test.js": { + "leafId": "shared-helpers", + "x": 0.2465094, + "y": 0.6149406 + }, + "lambda/shared/test/artifact-checkpoint.test.js": { + "leafId": "shared-helpers", + "x": 0.2246001, + "y": 0.7037913 + }, + "lambda/shared/test/artifact-edit.test.js": { + "leafId": "shared-helpers", + "x": 0.272841, + "y": 0.7037913 + }, + "lambda/shared/test/artifact-extractors.test.js": { + "leafId": "shared-helpers", + "x": 0.0927605, + "y": 0.7717219 + }, + "lambda/shared/test/artifact-structure-contract.test.js": { + "leafId": "shared-helpers", + "x": 0.0927605, + "y": 0.8301822 + }, + "lambda/shared/test/authz.test.js": { + "leafId": "shared-helpers", + "x": 0.1517885, + "y": 0.7708146 + }, + "lambda/shared/test/bedrock-iam-activation.test.js": { + "leafId": "shared-helpers", + "x": 0.1517885, + "y": 0.829275 + }, + "lambda/shared/test/bedrock-iam-schema.test.js": { + "leafId": "shared-helpers", + "x": 0.0834894, + "y": 0.8990326 + }, + "lambda/shared/test/bedrock-iam-shell.test.js": { + "leafId": "shared-helpers", + "x": 0.1425174, + "y": 0.8990326 + }, + "lambda/shared/test/bedrock-iam.test.js": { + "leafId": "shared-helpers", + "x": 0.2095487, + "y": 0.7671494 + }, + "lambda/shared/test/bedrock-models.test.js": { + "leafId": "shared-helpers", + "x": 0.2095487, + "y": 0.8205649 + }, + "lambda/shared/test/block-mappers.test.js": { + "leafId": "shared-helpers", + "x": 0.2676759, + "y": 0.795 + }, + "lambda/shared/test/bundle-smoke.test.js": { + "leafId": "shared-helpers", + "x": 0.2145583, + "y": 0.8635478 + }, + "lambda/shared/test/checkpoint-release-gating.test.js": { + "leafId": "shared-helpers", + "x": 0.2145583, + "y": 0.90912 + }, + "lambda/shared/test/cli-models.test.js": { + "leafId": "shared-helpers", + "x": 0.2726855, + "y": 0.8939878 + }, + "lambda/shared/test/codecommit-connection.test.js": { + "leafId": "shared-helpers", + "x": 0.3261507, + "y": 0.5615316 + }, + "lambda/shared/test/codecommit-credential.test.js": { + "leafId": "shared-helpers", + "x": 0.3852107, + "y": 0.5615316 + }, + "lambda/shared/test/codecommit-role.test.js": { + "leafId": "shared-helpers", + "x": 0.3538102, + "y": 0.6289594 + }, + "lambda/shared/test/codecommit.test.js": { + "leafId": "shared-helpers", + "x": 0.3538102, + "y": 0.6920735 + }, + "lambda/shared/test/compile.test.js": { + "leafId": "shared-helpers", + "x": 0.4643327, + "y": 0.5456968 + }, + "lambda/shared/test/compose-match.test.js": { + "leafId": "shared-helpers", + "x": 0.4643327, + "y": 0.6049312 + }, + "lambda/shared/test/composed-grid.test.js": { + "leafId": "shared-helpers", + "x": 0.439164, + "y": 0.6638632 + }, + "lambda/shared/test/concurrency.test.js": { + "leafId": "shared-helpers", + "x": 0.439164, + "y": 0.7135702 + }, + "lambda/shared/test/construction-autonomy.test.js": { + "leafId": "shared-helpers", + "x": 0.4906266, + "y": 0.6838801 + }, + "lambda/shared/test/custom-rule-versions.test.js": { + "leafId": "shared-helpers", + "x": 0.3143094, + "y": 0.7618101 + }, + "lambda/shared/test/distribution-archive.test.js": { + "leafId": "shared-helpers", + "x": 0.3483138, + "y": 0.7618101 + }, + "lambda/shared/test/environment-snapshot.test.js": { + "leafId": "shared-helpers", + "x": 0.3287547, + "y": 0.819705 + }, + "lambda/shared/test/fixtures/agent-auth-binding-identity.json": { + "leafId": "shared-helpers", + "x": 0.3893416, + "y": 0.7914821 + }, + "lambda/shared/test/fixtures/aidlc-211-scopes.json": { + "leafId": "shared-helpers", + "x": 0.4262895, + "y": 0.7914821 + }, + "lambda/shared/test/fixtures/aidlc-compatibility/current-stable.json": { + "leafId": "shared-helpers", + "x": 0.3657026, + "y": 0.8944685 + }, + "lambda/shared/test/fixtures/aidlc-compatibility/v2.11.0.json": { + "leafId": "shared-helpers", + "x": 0.476225, + "y": 0.8365736 + }, + "lambda/shared/test/fixtures/aidlc-compatibility/v2.6.18.json": { + "leafId": "shared-helpers", + "x": 0.5635234, + "y": 0.1375848 + }, + "lambda/shared/test/fixtures/aidlc-compatibility/v2.7.0.json": { + "leafId": "shared-helpers", + "x": 0.660715, + "y": 0.1375848 + }, + "lambda/shared/test/fixtures/aidlc-compatibility/v2.8.2.json": { + "leafId": "shared-helpers", + "x": 0.6129868, + "y": 0.2508564 + }, + "lambda/shared/test/fixtures/aidlc-compatibility/v2.9.0.json": { + "leafId": "shared-helpers", + "x": 0.7443867, + "y": 0.1772316 + }, + "lambda/shared/test/fixtures/aidlc-release-invoke-lines.json": { + "leafId": "shared-helpers", + "x": 0.8237491, + "y": 0.1163481 + }, + "lambda/shared/test/fixtures/legacy-release.js": { + "leafId": "shared-helpers", + "x": 0.8237491, + "y": 0.183595 + }, + "lambda/shared/test/fixtures/release-store-fakes.js": { + "leafId": "shared-helpers", + "x": 0.9042316, + "y": 0.0910236 + }, + "lambda/shared/test/fixtures/repo-files.js": { + "leafId": "shared-helpers", + "x": 0.9042316, + "y": 0.1582705 + }, + "lambda/shared/test/frontmatter.test.js": { + "leafId": "shared-helpers", + "x": 0.7963112, + "y": 0.2444785 + }, + "lambda/shared/test/gate-preconditions.test.js": { + "leafId": "shared-helpers", + "x": 0.8767937, + "y": 0.2444785 + }, + "lambda/shared/test/gate-question-channel-outputs.test.js": { + "leafId": "shared-helpers", + "x": 0.5410754, + "y": 0.3287512 + }, + "lambda/shared/test/git-connection-store.test.js": { + "leafId": "shared-helpers", + "x": 0.5992091, + "y": 0.3287512 + }, + "lambda/shared/test/git-oauth.test.js": { + "leafId": "shared-helpers", + "x": 0.5441789, + "y": 0.3917042 + }, + "lambda/shared/test/git-provider-issue-close.test.js": { + "leafId": "shared-helpers", + "x": 0.6023126, + "y": 0.3917042 + }, + "lambda/shared/test/git-providers.test.js": { + "leafId": "shared-helpers", + "x": 0.683448, + "y": 0.3534561 + }, + "lambda/shared/test/git-token.test.js": { + "leafId": "shared-helpers", + "x": 0.5561345, + "y": 0.4640368 + }, + "lambda/shared/test/github-auth-config.test.js": { + "leafId": "shared-helpers", + "x": 0.6173619, + "y": 0.4437222 + }, + "lambda/shared/test/helpers/auth-modes.js": { + "leafId": "shared-helpers", + "x": 0.6173619, + "y": 0.4913499 + }, + "lambda/shared/test/helpers/auth-table.js": { + "leafId": "shared-helpers", + "x": 0.6506054, + "y": 0.4640368 + }, + "lambda/shared/test/intent-deletion-sessions.test.js": { + "leafId": "shared-helpers", + "x": 0.6988969, + "y": 0.4640368 + }, + "lambda/shared/test/intent-methodology.test.js": { + "leafId": "shared-helpers", + "x": 0.7609115, + "y": 0.3339072 + }, + "lambda/shared/test/intent-url.test.js": { + "leafId": "shared-helpers", + "x": 0.7609115, + "y": 0.3896706 + }, + "lambda/shared/test/mcp-validator.test.js": { + "leafId": "shared-helpers", + "x": 0.8168371, + "y": 0.3462665 + }, + "lambda/shared/test/methodology-catalog.test.js": { + "leafId": "shared-helpers", + "x": 0.8718756, + "y": 0.3230387 + }, + "lambda/shared/test/metric-classification.test.js": { + "leafId": "shared-helpers", + "x": 0.9183134, + "y": 0.3230387 + }, + "lambda/shared/test/model-pricing.test.js": { + "leafId": "shared-helpers", + "x": 0.8931222, + "y": 0.3788021 + }, + "lambda/shared/test/native-repositories.test.js": { + "leafId": "shared-helpers", + "x": 0.7500902, + "y": 0.4568471 + }, + "lambda/shared/test/native-workspace-projector.test.js": { + "leafId": "shared-helpers", + "x": 0.8093987, + "y": 0.4568471 + }, + "lambda/shared/test/pr-strategy.test.js": { + "leafId": "shared-helpers", + "x": 0.8965051, + "y": 0.413627 + }, + "lambda/shared/test/release-closure-upgrade.test.js": { + "leafId": "shared-helpers", + "x": 0.8965051, + "y": 0.4684443 + }, + "lambda/shared/test/release-matrix.test.js": { + "leafId": "shared-helpers", + "x": 0.5812912, + "y": 0.5456634 + }, + "lambda/shared/test/release-registry.test.js": { + "leafId": "shared-helpers", + "x": 0.5812912, + "y": 0.6545954 + }, + "lambda/shared/test/release-resolver.test.js": { + "leafId": "shared-helpers", + "x": 0.6911437, + "y": 0.5769802 + }, + "lambda/shared/test/repo-fetch.test.js": { + "leafId": "shared-helpers", + "x": 0.6739718, + "y": 0.6859122 + }, + "lambda/shared/test/repo-validation.test.js": { + "leafId": "shared-helpers", + "x": 0.7183283, + "y": 0.6859122 + }, + "lambda/shared/test/runtime-handler-ownership.test.js": { + "leafId": "shared-helpers", + "x": 0.7806283, + "y": 0.524704 + }, + "lambda/shared/test/runtime-session.test.js": { + "leafId": "shared-helpers", + "x": 0.7806283, + "y": 0.5732626 + }, + "lambda/shared/test/runtime-target.test.js": { + "leafId": "shared-helpers", + "x": 0.7806283, + "y": 0.6245375 + }, + "lambda/shared/test/safe-event-logger.test.js": { + "leafId": "shared-helpers", + "x": 0.8498947, + "y": 0.5759788 + }, + "lambda/shared/test/script-closure.test.js": { + "leafId": "shared-helpers", + "x": 0.9067965, + "y": 0.5349439 + }, + "lambda/shared/test/sensor-verdict.test.js": { + "leafId": "shared-helpers", + "x": 0.9067965, + "y": 0.5992583 + }, + "lambda/shared/test/session-cleanup-store.test.js": { + "leafId": "shared-helpers", + "x": 0.7524926, + "y": 0.6849108 + }, + "lambda/shared/test/source-control-bindings.test.js": { + "leafId": "shared-helpers", + "x": 0.7996177, + "y": 0.6849108 + }, + "lambda/shared/test/source-control-credentials.test.js": { + "leafId": "shared-helpers", + "x": 0.8606242, + "y": 0.6849108 + }, + "lambda/shared/test/stage-loopback.test.js": { + "leafId": "shared-helpers", + "x": 0.9155291, + "y": 0.6849108 + }, + "lambda/shared/test/stage-skip.test.js": { + "leafId": "shared-helpers", + "x": 0.5414607, + "y": 0.7730306 + }, + "lambda/shared/test/tier-models.test.js": { + "leafId": "shared-helpers", + "x": 0.5872808, + "y": 0.7730306 + }, + "lambda/shared/test/unit-kind-pruning.test.js": { + "leafId": "shared-helpers", + "x": 0.5616153, + "y": 0.8325731 + }, + "lambda/shared/test/v2-execution-plan.test.js": { + "leafId": "shared-helpers", + "x": 0.6594684, + "y": 0.789071 + }, + "lambda/shared/test/v2-process.test.js": { + "leafId": "shared-helpers", + "x": 0.6136483, + "y": 0.8940867 + }, + "lambda/shared/test/v2-receipts.test.js": { + "leafId": "shared-helpers", + "x": 0.7251581, + "y": 0.8345443 + }, + "lambda/shared/test/v2-sensor-contract.test.js": { + "leafId": "shared-helpers", + "x": 0.7772581, + "y": 0.7851836 + }, + "lambda/shared/test/v2-workflow-plan.test.js": { + "leafId": "shared-helpers", + "x": 0.8456066, + "y": 0.7851836 + }, + "lambda/shared/test/workflow-checkpoint.test.js": { + "leafId": "shared-helpers", + "x": 0.907536, + "y": 0.75499 + }, + "lambda/shared/test/yjs-revocation.test.js": { + "leafId": "shared-helpers", + "x": 0.907536, + "y": 0.810645 + }, + "lambda/shared/tier-models.js": { + "leafId": "shared-helpers", + "x": 0.7800787, + "y": 0.8645302 + }, + "lambda/shared/tracker-migration.js": { + "leafId": "shared-helpers", + "x": 0.7800787, + "y": 0.9138909 + }, + "lambda/shared/trackers.js": { + "leafId": "shared-helpers", + "x": 0.838286, + "y": 0.8901993 + }, + "lambda/shared/ws-fanout.js": { + "leafId": "shared-helpers", + "x": 0.8973948, + "y": 0.8572329 + }, + "lambda/shared/yjs-revocation.js": { + "leafId": "shared-helpers", + "x": 0.8973948, + "y": 0.9065936 + }, + "config/platform-roles.json": { + "leafId": "identity-projects-users", + "x": 0.164559, + "y": 0.0763951 + }, + "lambda/cognito-users/index.js": { + "leafId": "identity-projects-users", + "x": 0.164559, + "y": 0.2264615 + }, + "lambda/cognito-users/package-lock.json": { + "leafId": "identity-projects-users", + "x": 0.3877593, + "y": 0.2140264 + }, + "lambda/cognito-users/package.json": { + "leafId": "identity-projects-users", + "x": 0.0992458, + "y": 0.4669287 + }, + "lambda/cognito-users/test/cognito-users.test.js": { + "leafId": "identity-projects-users", + "x": 0.322446, + "y": 0.4669287 + }, + "lambda/projects/index.js": { + "leafId": "identity-projects-users", + "x": 0.2836403, + "y": 0.7546623 + }, + "lambda/projects/package.json": { + "leafId": "identity-projects-users", + "x": 0.7232003, + "y": 0.0871365 + }, + "lambda/projects/test/projects.test.js": { + "leafId": "identity-projects-users", + "x": 0.7232003, + "y": 0.3351374 + }, + "lambda/sso-token/index.js": { + "leafId": "identity-projects-users", + "x": 0.5665479, + "y": 0.6453342 + }, + "lambda/sso-token/package.json": { + "leafId": "identity-projects-users", + "x": 0.6717523, + "y": 0.6453342 + }, + "lambda/sso-token/test/sso-token.test.js": { + "leafId": "identity-projects-users", + "x": 0.612045, + "y": 0.8351333 + }, + "lambda/users/index.js": { + "leafId": "identity-projects-users", + "x": 0.8052716, + "y": 0.7497609 + }, + "lambda/users/package.json": { + "leafId": "identity-projects-users", + "x": 0.9164269, + "y": 0.7497609 + }, + "lambda/agents/authentication-connection-verification.js": { + "leafId": "identity-agent-settings", + "x": 0.1378727, + "y": 0.130212 + }, + "lambda/agents/authentication-iam-settings.js": { + "leafId": "identity-agent-settings", + "x": 0.11293, + "y": 0.2472075 + }, + "lambda/agents/authentication-settings-providers.js": { + "leafId": "identity-agent-settings", + "x": 0.1903627, + "y": 0.2472075 + }, + "lambda/agents/authentication-settings-service.js": { + "leafId": "identity-agent-settings", + "x": 0.2949078, + "y": 0.1809554 + }, + "lambda/agents/index.js": { + "leafId": "identity-agent-settings", + "x": 0.2174751, + "y": 0.4122596 + }, + "lambda/agents/package.json": { + "leafId": "identity-agent-settings", + "x": 0.4492109, + "y": 0.0978467 + }, + "lambda/agents/test/authentication-connection-verification.test.js": { + "leafId": "identity-agent-settings", + "x": 0.4492109, + "y": 0.2422831 + }, + "lambda/agents/test/authentication-iam-settings.test.js": { + "leafId": "identity-agent-settings", + "x": 0.4492109, + "y": 0.4397007 + }, + "lambda/agents/test/authentication-settings-providers.test.js": { + "leafId": "identity-agent-settings", + "x": 0.17893, + "y": 0.606707 + }, + "lambda/agents/test/authentication-settings.test.js": { + "leafId": "identity-agent-settings", + "x": 0.17893, + "y": 0.7439418 + }, + "lambda/agents/test/event-logging.test.js": { + "leafId": "identity-agent-settings", + "x": 0.1263282, + "y": 0.8702991 + }, + "lambda/agents/test/helpers/fake-settings-providers.js": { + "leafId": "identity-agent-settings", + "x": 0.2448182, + "y": 0.8702991 + }, + "lambda/agents/test/helpers/settings-harness.js": { + "leafId": "identity-agent-settings", + "x": 0.4106659, + "y": 0.5830854 + }, + "lambda/agents/test/history-auth.test.js": { + "leafId": "identity-agent-settings", + "x": 0.4106659, + "y": 0.7171499 + }, + "lambda/agents/test/runtime-routing.test.js": { + "leafId": "identity-agent-settings", + "x": 0.4106659, + "y": 0.8671287 + }, + "lambda/agents/test/settings.test.js": { + "leafId": "identity-agent-settings", + "x": 0.5976497, + "y": 0.1404476 + }, + "lambda/credential-broker/agent-authentication-entry.js": { + "leafId": "identity-agent-settings", + "x": 0.5976497, + "y": 0.2328264 + }, + "lambda/credential-broker/agent-authentication.js": { + "leafId": "identity-agent-settings", + "x": 0.7241981, + "y": 0.1563389 + }, + "lambda/credential-broker/agent-broker-providers.js": { + "leafId": "identity-agent-settings", + "x": 0.5582692, + "y": 0.2927482 + }, + "lambda/credential-broker/agent-credential-renewal.js": { + "leafId": "identity-agent-settings", + "x": 0.6848176, + "y": 0.2927482 + }, + "lambda/credential-broker/agent-provider-registry.js": { + "leafId": "identity-agent-settings", + "x": 0.8582842, + "y": 0.1650539 + }, + "lambda/credential-broker/bedrock-iam-provider.js": { + "leafId": "identity-agent-settings", + "x": 0.8582842, + "y": 0.3014632 + }, + "lambda/credential-broker/bedrock-iam-wire.js": { + "leafId": "identity-agent-settings", + "x": 0.5709061, + "y": 0.3978561 + }, + "lambda/credential-broker/bedrock-iam.js": { + "leafId": "identity-agent-settings", + "x": 0.6770336, + "y": 0.3978561 + }, + "lambda/credential-broker/index.js": { + "leafId": "identity-agent-settings", + "x": 0.6300393, + "y": 0.518393 + }, + "lambda/credential-broker/key-broker-provider.js": { + "leafId": "identity-agent-settings", + "x": 0.773894, + "y": 0.3726433 + }, + "lambda/credential-broker/package.json": { + "leafId": "identity-agent-settings", + "x": 0.8755906, + "y": 0.3726433 + }, + "lambda/credential-broker/test/bedrock-iam.test.js": { + "leafId": "identity-agent-settings", + "x": 0.8378635, + "y": 0.4931802 + }, + "lambda/credential-broker/test/broker-providers.test.js": { + "leafId": "identity-agent-settings", + "x": 0.6483482, + "y": 0.6782492 + }, + "lambda/credential-broker/test/credential-broker.test.js": { + "leafId": "identity-agent-settings", + "x": 0.6483482, + "y": 0.8591029 + }, + "lambda/credential-broker/test/helpers/fixture-broker-provider.js": { + "leafId": "identity-agent-settings", + "x": 0.8561724, + "y": 0.6230245 + }, + "lambda/credential-metadata/index.js": { + "leafId": "identity-agent-settings", + "x": 0.8561724, + "y": 0.7244059 + }, + "lambda/credential-metadata/package.json": { + "leafId": "identity-agent-settings", + "x": 0.7997047, + "y": 0.8600876 + }, + "lambda/credential-metadata/test/credential-metadata.test.js": { + "leafId": "identity-agent-settings", + "x": 0.8830923, + "y": 0.8600876 + }, + "lambda/environments/build-guardrails.js": { + "leafId": "identity-environments", + "x": 0.1221826, + "y": 0.1197824 + }, + "lambda/environments/build-lifecycle.js": { + "leafId": "identity-environments", + "x": 0.2332048, + "y": 0.1197824 + }, + "lambda/environments/catalog-recipe.js": { + "leafId": "identity-environments", + "x": 0.1714622, + "y": 0.2357666 + }, + "lambda/environments/compute-model.js": { + "leafId": "identity-environments", + "x": 0.3922109, + "y": 0.109759 + }, + "lambda/environments/fixed-tool-recipe.js": { + "leafId": "identity-environments", + "x": 0.3922109, + "y": 0.2257432 + }, + "lambda/environments/index.js": { + "leafId": "identity-environments", + "x": 0.1386117, + "y": 0.4041272 + }, + "lambda/environments/package.json": { + "leafId": "identity-environments", + "x": 0.2621083, + "y": 0.328652 + }, + "lambda/environments/registry.js": { + "leafId": "identity-environments", + "x": 0.2621083, + "y": 0.393438 + }, + "lambda/environments/request.js": { + "leafId": "identity-environments", + "x": 0.2621083, + "y": 0.4689132 + }, + "lambda/environments/runtime-backends/capacity-provider.js": { + "leafId": "identity-environments", + "x": 0.3684499, + "y": 0.3498459 + }, + "lambda/environments/runtime-backends/index.js": { + "leafId": "identity-environments", + "x": 0.3684499, + "y": 0.4325249 + }, + "lambda/environments/runtime-backends/instances.js": { + "leafId": "identity-environments", + "x": 0.465702, + "y": 0.3786074 + }, + "lambda/environments/runtime-backends/microvms.js": { + "leafId": "identity-environments", + "x": 0.4046852, + "y": 0.4868061 + }, + "lambda/environments/status.js": { + "leafId": "identity-environments", + "x": 0.1714389, + "y": 0.5985923 + }, + "lambda/environments/store.js": { + "leafId": "identity-environments", + "x": 0.1714389, + "y": 0.7648536 + }, + "lambda/environments/test/build-admission.test.js": { + "leafId": "identity-environments", + "x": 0.1714389, + "y": 0.8922042 + }, + "lambda/environments/test/build-guardrails.test.js": { + "leafId": "identity-environments", + "x": 0.3292631, + "y": 0.576619 + }, + "lambda/environments/test/capacity-provider.test.js": { + "leafId": "identity-environments", + "x": 0.4390129, + "y": 0.576619 + }, + "lambda/environments/test/catalog-recipe.test.js": { + "leafId": "identity-environments", + "x": 0.3921875, + "y": 0.6895634 + }, + "lambda/environments/test/compute-model.test.js": { + "leafId": "identity-environments", + "x": 0.3348998, + "y": 0.8388874 + }, + "lambda/environments/test/fixed-tool-recipe.test.js": { + "leafId": "identity-environments", + "x": 0.4446496, + "y": 0.8388874 + }, + "lambda/environments/test/helpers/verification-lease.js": { + "leafId": "identity-environments", + "x": 0.5990447, + "y": 0.0779586 + }, + "lambda/environments/test/index.test.js": { + "leafId": "identity-environments", + "x": 0.5990447, + "y": 0.1803336 + }, + "lambda/environments/test/runtime-backends.test.js": { + "leafId": "identity-environments", + "x": 0.5990447, + "y": 0.3102591 + }, + "lambda/environments/test/status-instances.test.js": { + "leafId": "identity-environments", + "x": 0.7615243, + "y": 0.207884 + }, + "lambda/environments/test/status.test.js": { + "leafId": "identity-environments", + "x": 0.8832282, + "y": 0.207884 + }, + "lambda/environments/test/store.test.js": { + "leafId": "identity-environments", + "x": 0.5770756, + "y": 0.4363888 + }, + "lambda/environments/test/terraform-packaging.test.js": { + "leafId": "identity-environments", + "x": 0.6762577, + "y": 0.4363888 + }, + "lambda/environments/test/tool-catalog.test.js": { + "leafId": "identity-environments", + "x": 0.7645888, + "y": 0.4363888 + }, + "lambda/environments/test/tool-store.test.js": { + "leafId": "identity-environments", + "x": 0.884218, + "y": 0.4363888 + }, + "lambda/environments/test/tools-index.test.js": { + "leafId": "identity-environments", + "x": 0.5833199, + "y": 0.5856615 + }, + "lambda/environments/test/tools-status.test.js": { + "leafId": "identity-environments", + "x": 0.5833199, + "y": 0.709465 + }, + "lambda/environments/test/verification-lease.test.js": { + "leafId": "identity-environments", + "x": 0.7093358, + "y": 0.6447731 + }, + "lambda/environments/tool-catalog.js": { + "leafId": "identity-environments", + "x": 0.6279532, + "y": 0.8540683 + }, + "lambda/environments/tool-store.js": { + "leafId": "identity-environments", + "x": 0.8467645, + "y": 0.5935843 + }, + "lambda/environments/tools-index.js": { + "leafId": "identity-environments", + "x": 0.8467645, + "y": 0.7396532 + }, + "lambda/environments/tools-status.js": { + "leafId": "identity-environments", + "x": 0.8312039, + "y": 0.8763337 + }, + "lambda/environments/vitest.config.js": { + "leafId": "identity-environments", + "x": 0.9239994, + "y": 0.8763337 + }, + "lambda/discussions/clients.js": { + "leafId": "realtime-discussions", + "x": 0.1581543, + "y": 0.1412009 + }, + "lambda/discussions/constants.js": { + "leafId": "realtime-discussions", + "x": 0.1581543, + "y": 0.3063559 + }, + "lambda/discussions/data-access.js": { + "leafId": "realtime-discussions", + "x": 0.3853104, + "y": 0.229115 + }, + "lambda/discussions/handlers.js": { + "leafId": "realtime-discussions", + "x": 0.2875961, + "y": 0.5614548 + }, + "lambda/discussions/index.js": { + "leafId": "realtime-discussions", + "x": 0.1694059, + "y": 0.8340999 + }, + "lambda/discussions/mappers.js": { + "leafId": "realtime-discussions", + "x": 0.3965621, + "y": 0.8340999 + }, + "lambda/discussions/package.json": { + "leafId": "realtime-discussions", + "x": 0.6247041, + "y": 0.1102398 + }, + "lambda/discussions/scope.js": { + "leafId": "realtime-discussions", + "x": 0.6247041, + "y": 0.2563167 + }, + "lambda/discussions/services.js": { + "leafId": "realtime-discussions", + "x": 0.837108, + "y": 0.2100369 + }, + "lambda/discussions/test/discussions.test.js": { + "leafId": "realtime-discussions", + "x": 0.7271561, + "y": 0.5940003 + }, + "lambda/discussions/test/services.test.js": { + "leafId": "realtime-discussions", + "x": 0.7271561, + "y": 0.8857235 + }, + "lambda/ws-authorizer/index.js": { + "leafId": "realtime-transports", + "x": 0.121333, + "y": 0.1261764 + }, + "lambda/ws-authorizer/package.json": { + "leafId": "realtime-transports", + "x": 0.121333, + "y": 0.2275365 + }, + "lambda/ws-authorizer/test/ws-authorizer.test.js": { + "leafId": "realtime-transports", + "x": 0.2567853, + "y": 0.1653201 + }, + "lambda/ws-connection/index.js": { + "leafId": "realtime-transports", + "x": 0.1958923, + "y": 0.3135866 + }, + "lambda/ws-connection/package.json": { + "leafId": "realtime-transports", + "x": 0.4208472, + "y": 0.089881 + }, + "lambda/ws-connection/test/ws-connection.test.js": { + "leafId": "realtime-transports", + "x": 0.4208472, + "y": 0.2381476 + }, + "lambda/ws-message/index.js": { + "leafId": "realtime-transports", + "x": 0.1140588, + "y": 0.4134858 + }, + "lambda/ws-message/package.json": { + "leafId": "realtime-transports", + "x": 0.1140588, + "y": 0.5097469 + }, + "lambda/ws-message/test/ws-message.test.js": { + "leafId": "realtime-transports", + "x": 0.2215694, + "y": 0.4567542 + }, + "lambda/yjs-server/Dockerfile": { + "leafId": "realtime-transports", + "x": 0.2995623, + "y": 0.4567542 + }, + "lambda/yjs-server/aws-store.js": { + "leafId": "realtime-transports", + "x": 0.4170067, + "y": 0.4567542 + }, + "lambda/yjs-server/cluster.js": { + "leafId": "realtime-transports", + "x": 0.1516652, + "y": 0.6624008 + }, + "lambda/yjs-server/config.js": { + "leafId": "realtime-transports", + "x": 0.2911704, + "y": 0.620022 + }, + "lambda/yjs-server/doc-name.js": { + "leafId": "realtime-transports", + "x": 0.2911704, + "y": 0.7294074 + }, + "lambda/yjs-server/load.js": { + "leafId": "realtime-transports", + "x": 0.1999452, + "y": 0.8556731 + }, + "lambda/yjs-server/package-lock.json": { + "leafId": "realtime-transports", + "x": 0.4249002, + "y": 0.7176685 + }, + "lambda/yjs-server/package.json": { + "leafId": "realtime-transports", + "x": 0.4249002, + "y": 0.9109409 + }, + "lambda/yjs-server/protocol.js": { + "leafId": "realtime-transports", + "x": 0.6030818, + "y": 0.1199028 + }, + "lambda/yjs-server/realtime-token.js": { + "leafId": "realtime-transports", + "x": 0.6030818, + "y": 0.2423002 + }, + "lambda/yjs-server/rooms.js": { + "leafId": "realtime-transports", + "x": 0.7795151, + "y": 0.1863574 + }, + "lambda/yjs-server/server.js": { + "leafId": "realtime-transports", + "x": 0.9013883, + "y": 0.1863574 + }, + "lambda/yjs-server/service.js": { + "leafId": "realtime-transports", + "x": 0.6095362, + "y": 0.4098126 + }, + "lambda/yjs-server/test/aws-store.test.js": { + "leafId": "realtime-transports", + "x": 0.7882483, + "y": 0.4098126 + }, + "lambda/yjs-server/test/doc-name.test.js": { + "leafId": "realtime-transports", + "x": 0.9036671, + "y": 0.4098126 + }, + "lambda/yjs-server/test/dynamodb.integration.test.js": { + "leafId": "realtime-transports", + "x": 0.6213093, + "y": 0.5832998 + }, + "lambda/yjs-server/test/helpers.js": { + "leafId": "realtime-transports", + "x": 0.6213093, + "y": 0.7245477 + }, + "lambda/yjs-server/test/realtime-token.test.js": { + "leafId": "realtime-transports", + "x": 0.6213093, + "y": 0.8664631 + }, + "lambda/yjs-server/test/service.test.js": { + "leafId": "realtime-transports", + "x": 0.8359144, + "y": 0.6447591 + }, + "lambda/yjs-server/test/verify-snapshots.test.js": { + "leafId": "realtime-transports", + "x": 0.7618945, + "y": 0.8591039 + }, + "lambda/yjs-server/verify-snapshots.js": { + "leafId": "realtime-transports", + "x": 0.8463164, + "y": 0.8591039 + }, + "lambda/yjs-server/vitest.config.js": { + "leafId": "realtime-transports", + "x": 0.9203363, + "y": 0.8591039 + }, + "lambda/shared/git-providers.js": { + "leafId": "integrations-git", + "x": 0.2580367, + "y": 0.123791 + }, + "lambda/shared/git-providers/bitbucket.js": { + "leafId": "integrations-git", + "x": 0.2580367, + "y": 0.3722268 + }, + "lambda/shared/git-providers/codecommit-credential.js": { + "leafId": "integrations-git", + "x": 0.5193506, + "y": 0.3123958 + }, + "lambda/shared/git-providers/codecommit-repo.js": { + "leafId": "integrations-git", + "x": 0.1096634, + "y": 0.7501958 + }, + "lambda/shared/git-providers/codecommit.js": { + "leafId": "integrations-git", + "x": 0.3709773, + "y": 0.7501958 + }, + "lambda/shared/git-providers/errors.js": { + "leafId": "integrations-git", + "x": 0.7613139, + "y": 0.092114 + }, + "lambda/shared/git-providers/github.js": { + "leafId": "integrations-git", + "x": 0.7613139, + "y": 0.3208341 + }, + "lambda/shared/git-providers/gitlab.js": { + "leafId": "integrations-git", + "x": 0.7613139, + "y": 0.7304801 + }, + "lambda/bitbucket/index.js": { + "leafId": "integrations-oauth", + "x": 0.1393648, + "y": 0.1329689 + }, + "lambda/bitbucket/package.json": { + "leafId": "integrations-oauth", + "x": 0.2765794, + "y": 0.1329689 + }, + "lambda/codecommit/index.js": { + "leafId": "integrations-oauth", + "x": 0.1976546, + "y": 0.2999403 + }, + "lambda/codecommit/package.json": { + "leafId": "integrations-oauth", + "x": 0.4525253, + "y": 0.0999982 + }, + "lambda/codecommit/test/index.test.js": { + "leafId": "integrations-oauth", + "x": 0.4525253, + "y": 0.2669695 + }, + "lambda/github/index.js": { + "leafId": "integrations-oauth", + "x": 0.1300585, + "y": 0.4912682 + }, + "lambda/github/package.json": { + "leafId": "integrations-oauth", + "x": 0.2427605, + "y": 0.4912682 + }, + "lambda/github/test/github-admin.test.js": { + "leafId": "integrations-oauth", + "x": 0.4280127, + "y": 0.4912682 + }, + "lambda/github/test/github-app-discovery.test.js": { + "leafId": "integrations-oauth", + "x": 0.1252157, + "y": 0.7620968 + }, + "lambda/github/test/github.test.js": { + "leafId": "integrations-oauth", + "x": 0.3800864, + "y": 0.7620968 + }, + "lambda/gitlab/index.js": { + "leafId": "integrations-oauth", + "x": 0.6749992, + "y": 0.1143225 + }, + "lambda/gitlab/package.json": { + "leafId": "integrations-oauth", + "x": 0.8596886, + "y": 0.1143225 + }, + "lambda/gitlab/test/gitlab.test.js": { + "leafId": "integrations-oauth", + "x": 0.7548706, + "y": 0.3293599 + }, + "lambda/source-control/index.js": { + "leafId": "integrations-oauth", + "x": 0.7548706, + "y": 0.623295 + }, + "lambda/source-control/package.json": { + "leafId": "integrations-oauth", + "x": 0.6218854, + "y": 0.8460576 + }, + "lambda/source-control/test/source-control.test.js": { + "leafId": "integrations-oauth", + "x": 0.8065748, + "y": 0.8460576 + }, + "lambda/migrate-tracker-fields/index.js": { + "leafId": "integrations-trackers", + "x": 0.153774, + "y": 0.1351363 + }, + "lambda/migrate-tracker-fields/package.json": { + "leafId": "integrations-trackers", + "x": 0.2919441, + "y": 0.1351363 + }, + "lambda/migrate-tracker-fields/test/migrate-tracker-fields.test.js": { + "leafId": "integrations-trackers", + "x": 0.1986101, + "y": 0.2807574 + }, + "lambda/trackers/delivery-sync.js": { + "leafId": "integrations-trackers", + "x": 0.4408601, + "y": 0.2095811 + }, + "lambda/trackers/index.js": { + "leafId": "integrations-trackers", + "x": 0.3026899, + "y": 0.4559599 + }, + "lambda/trackers/package.json": { + "leafId": "integrations-trackers", + "x": 0.1417423, + "y": 0.5970451 + }, + "lambda/trackers/providers/adf-to-markdown.js": { + "leafId": "integrations-trackers", + "x": 0.1417423, + "y": 0.72317 + }, + "lambda/trackers/providers/errors.js": { + "leafId": "integrations-trackers", + "x": 0.2836552, + "y": 0.6014632 + }, + "lambda/trackers/providers/github-issues.js": { + "leafId": "integrations-trackers", + "x": 0.2836552, + "y": 0.7275882 + }, + "lambda/trackers/providers/gitlab-issues.js": { + "leafId": "integrations-trackers", + "x": 0.1342017, + "y": 0.8742637 + }, + "lambda/trackers/providers/index.js": { + "leafId": "integrations-trackers", + "x": 0.2761146, + "y": 0.8742637 + }, + "lambda/trackers/providers/jira-cloud.js": { + "leafId": "integrations-trackers", + "x": 0.4446028, + "y": 0.7481388 + }, + "lambda/trackers/test/adf-to-markdown.test.js": { + "leafId": "integrations-trackers", + "x": 0.6241462, + "y": 0.1972511 + }, + "lambda/trackers/test/delivery-sync.test.js": { + "leafId": "integrations-trackers", + "x": 0.8214562, + "y": 0.1972511 + }, + "lambda/trackers/test/gitlab-issues.test.js": { + "leafId": "integrations-trackers", + "x": 0.5823165, + "y": 0.4609644 + }, + "lambda/trackers/test/jira-cloud.test.js": { + "leafId": "integrations-trackers", + "x": 0.7796266, + "y": 0.4609644 + }, + "lambda/trackers/test/providers.test.js": { + "leafId": "integrations-trackers", + "x": 0.5769836, + "y": 0.7654733 + }, + "lambda/trackers/test/trackers.test.js": { + "leafId": "integrations-trackers", + "x": 0.7742937, + "y": 0.7654733 + }, + "lambda/.dockerignore": { + "leafId": "infrastructure-app", + "x": 0.1532246, + "y": 0.0861846 + }, + "terraform/modules/api/agents.tf": { + "leafId": "infrastructure-app", + "x": 0.1532246, + "y": 0.2107387 + }, + "terraform/modules/api/bedrock-iam.tf": { + "leafId": "infrastructure-app", + "x": 0.0776805, + "y": 0.3618979 + }, + "terraform/modules/api/cors/main.tf": { + "leafId": "infrastructure-app", + "x": 0.1515791, + "y": 0.3618979 + }, + "terraform/modules/api/lambda/bedrock-iam.tf": { + "leafId": "infrastructure-app", + "x": 0.2271231, + "y": 0.3618979 + }, + "terraform/modules/api/lambda/main.tf": { + "leafId": "infrastructure-app", + "x": 0.3746727, + "y": 0.2373438 + }, + "terraform/modules/api/lambda/outputs.tf": { + "leafId": "infrastructure-app", + "x": 0.1661759, + "y": 0.4758003 + }, + "terraform/modules/api/lambda/variables.tf": { + "leafId": "infrastructure-app", + "x": 0.387624, + "y": 0.4758003 + }, + "terraform/modules/api/main.tf": { + "leafId": "infrastructure-app", + "x": 0.2116204, + "y": 0.6050921 + }, + "terraform/modules/api/outputs.tf": { + "leafId": "infrastructure-app", + "x": 0.3974841, + "y": 0.6050921 + }, + "terraform/modules/api/routes.tf": { + "leafId": "infrastructure-app", + "x": 0.2463036, + "y": 0.8044355 + }, + "terraform/modules/api/variables.tf": { + "leafId": "infrastructure-app", + "x": 0.4677517, + "y": 0.7402165 + }, + "terraform/modules/compute/agentcore/main.tf": { + "leafId": "infrastructure-app", + "x": 0.6285438, + "y": 0.1496959 + }, + "terraform/modules/compute/agentcore/outputs.tf": { + "leafId": "infrastructure-app", + "x": 0.5564246, + "y": 0.3098099 + }, + "terraform/modules/compute/agentcore/variables.tf": { + "leafId": "infrastructure-app", + "x": 0.6816322, + "y": 0.3098099 + }, + "terraform/modules/compute/agents/main.tf": { + "leafId": "infrastructure-app", + "x": 0.8466557, + "y": 0.084222 + }, + "terraform/modules/compute/managed-environments/main.tf": { + "leafId": "infrastructure-app", + "x": 0.8466557, + "y": 0.244336 + }, + "terraform/modules/compute/managed-environments/outputs.tf": { + "leafId": "infrastructure-app", + "x": 0.5420162, + "y": 0.4626607 + }, + "terraform/modules/compute/managed-environments/variables.tf": { + "leafId": "infrastructure-app", + "x": 0.6498891, + "y": 0.4626607 + }, + "terraform/modules/frontend/cloudfront-origin-secret.tf": { + "leafId": "infrastructure-app", + "x": 0.7394368, + "y": 0.4626607 + }, + "terraform/modules/frontend/main.tf": { + "leafId": "infrastructure-app", + "x": 0.8496758, + "y": 0.4626607 + }, + "terraform/modules/frontend/outputs.tf": { + "leafId": "infrastructure-app", + "x": 0.5452995, + "y": 0.5985807 + }, + "terraform/modules/frontend/variables.tf": { + "leafId": "infrastructure-app", + "x": 0.6409062, + "y": 0.5985807 + }, + "terraform/modules/realtime/lambda.tf": { + "leafId": "infrastructure-app", + "x": 0.5989429, + "y": 0.7119955 + }, + "terraform/modules/realtime/outputs.tf": { + "leafId": "infrastructure-app", + "x": 0.7141883, + "y": 0.6545482 + }, + "terraform/modules/realtime/secret.tf": { + "leafId": "infrastructure-app", + "x": 0.5675974, + "y": 0.7960602 + }, + "terraform/modules/realtime/variables.tf": { + "leafId": "infrastructure-app", + "x": 0.5675974, + "y": 0.8818587 + }, + "terraform/modules/realtime/websocket.tf": { + "leafId": "infrastructure-app", + "x": 0.6828428, + "y": 0.8537615 + }, + "terraform/modules/realtime/yjs-server/main.tf": { + "leafId": "infrastructure-app", + "x": 0.8366935, + "y": 0.6200559 + }, + "terraform/modules/realtime/yjs-server/outputs.tf": { + "leafId": "infrastructure-app", + "x": 0.8366935, + "y": 0.7284858 + }, + "terraform/modules/realtime/yjs-server/scaling.tf": { + "leafId": "infrastructure-app", + "x": 0.7818328, + "y": 0.8487766 + }, + "terraform/modules/realtime/yjs-server/variables.tf": { + "leafId": "infrastructure-app", + "x": 0.8846994, + "y": 0.8487766 + }, + "lambda/purge-neptune/index.js": { + "leafId": "infrastructure-data", + "x": 0.1334868, + "y": 0.1445844 + }, + "lambda/purge-neptune/package.json": { + "leafId": "infrastructure-data", + "x": 0.2512655, + "y": 0.1445844 + }, + "lambda/purge-neptune/test/purge-neptune.test.js": { + "leafId": "infrastructure-data", + "x": 0.1782187, + "y": 0.296365 + }, + "terraform/modules/auth/main.tf": { + "leafId": "infrastructure-data", + "x": 0.4077841, + "y": 0.2157407 + }, + "terraform/modules/auth/outputs.tf": { + "leafId": "infrastructure-data", + "x": 0.1569607, + "y": 0.4482385 + }, + "terraform/modules/auth/variables.tf": { + "leafId": "infrastructure-data", + "x": 0.3865261, + "y": 0.4482385 + }, + "terraform/modules/data/dynamodb/main.tf": { + "leafId": "infrastructure-data", + "x": 0.2006845, + "y": 0.6688639 + }, + "terraform/modules/data/dynamodb/outputs.tf": { + "leafId": "infrastructure-data", + "x": 0.2006845, + "y": 0.8741661 + }, + "terraform/modules/data/dynamodb/variables.tf": { + "leafId": "infrastructure-data", + "x": 0.4302499, + "y": 0.5841207 + }, + "terraform/modules/data/neptune/main.tf": { + "leafId": "infrastructure-data", + "x": 0.4302499, + "y": 0.7277465 + }, + "terraform/modules/data/neptune/outputs.tf": { + "leafId": "infrastructure-data", + "x": 0.4302499, + "y": 0.8778837 + }, + "terraform/modules/data/neptune/variables.tf": { + "leafId": "infrastructure-data", + "x": 0.5738851, + "y": 0.1911067 + }, + "terraform/modules/data/s3/main.tf": { + "leafId": "infrastructure-data", + "x": 0.7437659, + "y": 0.1911067 + }, + "terraform/modules/data/s3/outputs.tf": { + "leafId": "infrastructure-data", + "x": 0.8994463, + "y": 0.1911067 + }, + "terraform/modules/data/s3/variables.tf": { + "leafId": "infrastructure-data", + "x": 0.549523, + "y": 0.4426099 + }, + "terraform/modules/git/main.tf": { + "leafId": "infrastructure-data", + "x": 0.6925424, + "y": 0.4426099 + }, + "terraform/modules/git/outputs.tf": { + "leafId": "infrastructure-data", + "x": 0.8725848, + "y": 0.4426099 + }, + "terraform/modules/git/variables.tf": { + "leafId": "infrastructure-data", + "x": 0.5692178, + "y": 0.6607473 + }, + "terraform/modules/security/dynamodb-kms-runtime-access/main.tf": { + "leafId": "infrastructure-data", + "x": 0.684729, + "y": 0.6607473 + }, + "terraform/modules/security/dynamodb-kms-runtime-access/variables.tf": { + "leafId": "infrastructure-data", + "x": 0.7890496, + "y": 0.6607473 + }, + "terraform/modules/security/waf/main.tf": { + "leafId": "infrastructure-data", + "x": 0.6735384, + "y": 0.8470441 + }, + "terraform/modules/security/waf/outputs.tf": { + "leafId": "infrastructure-data", + "x": 0.883533, + "y": 0.6195246 + }, + "terraform/modules/security/waf/variables.tf": { + "leafId": "infrastructure-data", + "x": 0.883533, + "y": 0.7482468 + }, + "terraform/modules/security/waf/versions.tf": { + "leafId": "infrastructure-data", + "x": 0.883533, + "y": 0.8819854 + }, + "terraform/.terraform.lock.hcl": { + "leafId": "infrastructure-stack", + "x": 0.1708109, + "y": 0.1618574 + }, + "terraform/.tflint.hcl": { + "leafId": "infrastructure-stack", + "x": 0.1708109, + "y": 0.277433 + }, + "terraform/agent-credential-grant.tf": { + "leafId": "infrastructure-stack", + "x": 0.0966344, + "y": 0.3935327 + }, + "terraform/environments/dev.tfvars.example": { + "leafId": "infrastructure-stack", + "x": 0.2070053, + "y": 0.3935327 + }, + "terraform/main.tf": { + "leafId": "infrastructure-stack", + "x": 0.3924151, + "y": 0.2779571 + }, + "terraform/modules/domain/main.tf": { + "leafId": "infrastructure-stack", + "x": 0.2820441, + "y": 0.530333 + }, + "terraform/modules/domain/outputs.tf": { + "leafId": "infrastructure-stack", + "x": 0.1459167, + "y": 0.6048041 + }, + "terraform/modules/domain/variables.tf": { + "leafId": "infrastructure-stack", + "x": 0.1459167, + "y": 0.7080966 + }, + "terraform/modules/domain/versions.tf": { + "leafId": "infrastructure-stack", + "x": 0.2658811, + "y": 0.6720043 + }, + "terraform/modules/networking/main.tf": { + "leafId": "infrastructure-stack", + "x": 0.1804043, + "y": 0.8574284 + }, + "terraform/modules/networking/outputs.tf": { + "leafId": "infrastructure-stack", + "x": 0.3640414, + "y": 0.6526326 + }, + "terraform/modules/networking/variables.tf": { + "leafId": "infrastructure-stack", + "x": 0.4656812, + "y": 0.6526326 + }, + "terraform/modules/networking/vpc-endpoints/main.tf": { + "leafId": "infrastructure-stack", + "x": 0.4020085, + "y": 0.7733125 + }, + "terraform/modules/networking/vpc-endpoints/outputs.tf": { + "leafId": "infrastructure-stack", + "x": 0.3392746, + "y": 0.8748158 + }, + "terraform/modules/networking/vpc-endpoints/variables.tf": { + "leafId": "infrastructure-stack", + "x": 0.4409144, + "y": 0.8748158 + }, + "terraform/outputs.tf": { + "leafId": "infrastructure-stack", + "x": 0.6137315, + "y": 0.2133083 + }, + "terraform/tests/auth-domain.tftest.hcl": { + "leafId": "infrastructure-stack", + "x": 0.8316874, + "y": 0.1570717 + }, + "terraform/tests/fixtures/lambda-packaging/main.tf": { + "leafId": "infrastructure-stack", + "x": 0.8316874, + "y": 0.30642 + }, + "terraform/tests/fixtures/lambda-packaging/src/lookup/index.js": { + "leafId": "infrastructure-stack", + "x": 0.5509646, + "y": 0.3864646 + }, + "terraform/tests/fixtures/lambda-packaging/src/workflows/index.js": { + "leafId": "infrastructure-stack", + "x": 0.5509646, + "y": 0.4340804 + }, + "terraform/tests/fixtures/lambda-packaging/workspace.py": { + "leafId": "infrastructure-stack", + "x": 0.5509646, + "y": 0.5083924 + }, + "terraform/tests/lambda-packaging.tftest.hcl": { + "leafId": "infrastructure-stack", + "x": 0.6752969, + "y": 0.4607766 + }, + "terraform/tests/managed-environments.tftest.hcl": { + "leafId": "infrastructure-stack", + "x": 0.8459364, + "y": 0.4607766 + }, + "terraform/tests/waf.tftest.hcl": { + "leafId": "infrastructure-stack", + "x": 0.6236783, + "y": 0.6428401 + }, + "terraform/tests/yjs.tftest.hcl": { + "leafId": "infrastructure-stack", + "x": 0.6236783, + "y": 0.8331718 + }, + "terraform/variables.tf": { + "leafId": "infrastructure-stack", + "x": 0.8416341, + "y": 0.7110751 + }, + "terraform/yjs.tf": { + "leafId": "infrastructure-stack", + "x": 0.8416341, + "y": 0.9014068 + }, + ".github/CODEOWNERS": { + "leafId": "release-actions", + "x": 0.0830696, + "y": 0.1703555 + }, + ".github/ISSUE_TEMPLATE/bug_report.yml": { + "leafId": "release-actions", + "x": 0.2154005, + "y": 0.1703555 + }, + ".github/ISSUE_TEMPLATE/config.yml": { + "leafId": "release-actions", + "x": 0.1927709, + "y": 0.3082648 + }, + ".github/ISSUE_TEMPLATE/documentation.yml": { + "leafId": "release-actions", + "x": 0.1927709, + "y": 0.4307509 + }, + ".github/ISSUE_TEMPLATE/feature_request.yml": { + "leafId": "release-actions", + "x": 0.4338186, + "y": 0.1735794 + }, + ".github/ISSUE_TEMPLATE/rfc.yml": { + "leafId": "release-actions", + "x": 0.4338186, + "y": 0.402461 + }, + ".github/dependabot.yml": { + "leafId": "release-actions", + "x": 0.1261401, + "y": 0.7306417 + }, + ".github/workflows/deploy-demo.yml": { + "leafId": "release-actions", + "x": 0.3671878, + "y": 0.7306417 + }, + ".github/workflows/deploy-main.yml": { + "leafId": "release-actions", + "x": 0.6690532, + "y": 0.1312428 + }, + ".github/workflows/docs.yml": { + "leafId": "release-actions", + "x": 0.6690532, + "y": 0.3001203 + }, + ".github/workflows/frontend.yml": { + "leafId": "release-actions", + "x": 0.8675656, + "y": 0.2328376 + }, + ".github/workflows/lint.yml": { + "leafId": "release-actions", + "x": 0.7410477, + "y": 0.4579535 + }, + ".github/workflows/release.yml": { + "leafId": "release-actions", + "x": 0.6392448, + "y": 0.6656291 + }, + ".github/workflows/terraform.yml": { + "leafId": "release-actions", + "x": 0.8377571, + "y": 0.6656291 + }, + ".github/workflows/test.yml": { + "leafId": "release-actions", + "x": 0.7410477, + "y": 0.8783132 + }, + "scripts/agent-e2e-testing.sh": { + "leafId": "release-scripts", + "x": 0.1465478, + "y": 0.1496275 + }, + "scripts/backfill-yjs-deletion-cleanup.mjs": { + "leafId": "release-scripts", + "x": 0.268646, + "y": 0.1496275 + }, + "scripts/bootstrap.sh": { + "leafId": "release-scripts", + "x": 0.1179891, + "y": 0.290687 + }, + "scripts/deploy-frontend.sh": { + "leafId": "release-scripts", + "x": 0.2400874, + "y": 0.290687 + }, + "scripts/deploy-terraform.sh": { + "leafId": "release-scripts", + "x": 0.4099911, + "y": 0.1392612 + }, + "scripts/destroy.sh": { + "leafId": "release-scripts", + "x": 0.3817782, + "y": 0.2803206 + }, + "scripts/docker-proxy-build-args.mjs": { + "leafId": "release-scripts", + "x": 0.4871328, + "y": 0.2803206 + }, + "scripts/generate-agent-output-fixtures.mjs": { + "leafId": "release-scripts", + "x": 0.1152933, + "y": 0.4195141 + }, + "scripts/generate-env.sh": { + "leafId": "release-scripts", + "x": 0.2260972, + "y": 0.4195141 + }, + "scripts/initialize-agent-auth-inventory.mjs": { + "leafId": "release-scripts", + "x": 0.0943316, + "y": 0.5463703 + }, + "scripts/inspect-terraform-plan.mjs": { + "leafId": "release-scripts", + "x": 0.2051355, + "y": 0.5463703 + }, + "scripts/install.sh": { + "leafId": "release-scripts", + "x": 0.3986967, + "y": 0.4729351 + }, + "scripts/phaseb-answer.mjs": { + "leafId": "release-scripts", + "x": 0.1381035, + "y": 0.6449357 + }, + "scripts/phaseb.sh": { + "leafId": "release-scripts", + "x": 0.1381035, + "y": 0.7611734 + }, + "scripts/release.mjs": { + "leafId": "release-scripts", + "x": 0.2581384, + "y": 0.7160291 + }, + "scripts/snapshot-aidlc-compatibility.mjs": { + "leafId": "release-scripts", + "x": 0.1804749, + "y": 0.8859134 + }, + "scripts/snapshot-upstream-artifacts.mjs": { + "leafId": "release-scripts", + "x": 0.3461631, + "y": 0.6936397 + }, + "scripts/sso-config.mjs": { + "leafId": "release-scripts", + "x": 0.4535811, + "y": 0.6936397 + }, + "scripts/sync-aws-sdk.mjs": { + "leafId": "release-scripts", + "x": 0.356858, + "y": 0.863524 + }, + "scripts/test/agent-e2e-proxy.test.mjs": { + "leafId": "release-scripts", + "x": 0.4642759, + "y": 0.863524 + }, + "scripts/test/auth-parent-dns.test.mjs": { + "leafId": "release-scripts", + "x": 0.5590148, + "y": 0.136367 + }, + "scripts/test/bedrock-iam-wiring.test.mjs": { + "leafId": "release-scripts", + "x": 0.6352862, + "y": 0.136367 + }, + "scripts/test/docker-proxy-build-args.test.mjs": { + "leafId": "release-scripts", + "x": 0.7018988, + "y": 0.136367 + }, + "scripts/test/fixtures/inspect-terraform-plan-v2.2.0.mjs": { + "leafId": "release-scripts", + "x": 0.5802287, + "y": 0.2699096 + }, + "scripts/test/helpers/public-ecr.mjs": { + "leafId": "release-scripts", + "x": 0.6905103, + "y": 0.2699096 + }, + "scripts/test/lambda-package-deployment.test.mjs": { + "leafId": "release-scripts", + "x": 0.8377345, + "y": 0.1362948 + }, + "scripts/test/public-ecr-build-auth.test.mjs": { + "leafId": "release-scripts", + "x": 0.8377345, + "y": 0.2698374 + }, + "scripts/test/release-tools.test.mjs": { + "leafId": "release-scripts", + "x": 0.7274529, + "y": 0.4242392 + }, + "scripts/test/sso-config.test.mjs": { + "leafId": "release-scripts", + "x": 0.5655631, + "y": 0.6270862 + }, + "scripts/test/terraform-hardening.test.mjs": { + "leafId": "release-scripts", + "x": 0.6875623, + "y": 0.6270862 + }, + "scripts/test/terraform-sso-privacy.test.mjs": { + "leafId": "release-scripts", + "x": 0.5810286, + "y": 0.7986832 + }, + "scripts/wait-for-auth-parent-dns.mjs": { + "leafId": "release-scripts", + "x": 0.5810286, + "y": 0.9000935 + }, + "scripts/with-public-ecr-auth.mjs": { + "leafId": "release-scripts", + "x": 0.7030279, + "y": 0.8381497 + }, + "test/dynamodb-setup.js": { + "leafId": "release-scripts", + "x": 0.8017123, + "y": 0.5679956 + }, + "test/fixtures/oidc-idp/.gitignore": { + "leafId": "release-scripts", + "x": 0.8652646, + "y": 0.5679956 + }, + "test/fixtures/oidc-idp/index.mjs": { + "leafId": "release-scripts", + "x": 0.9130043, + "y": 0.5679956 + }, + "test/fixtures/oidc-idp/main.tf": { + "leafId": "release-scripts", + "x": 0.8494521, + "y": 0.66798 + }, + "test/fixtures/oidc-idp/outputs.tf": { + "leafId": "release-scripts", + "x": 0.8494521, + "y": 0.7516188 + }, + "test/fixtures/oidc-idp/variables.tf": { + "leafId": "release-scripts", + "x": 0.8093098, + "y": 0.8238397 + }, + "test/fixtures/oidc-idp/versions.tf": { + "leafId": "release-scripts", + "x": 0.8093098, + "y": 0.9007019 + }, + "test/gremlin-setup.js": { + "leafId": "release-scripts", + "x": 0.8994177, + "y": 0.8401465 + }, + "test/setup.js": { + "leafId": "release-scripts", + "x": 0.8994177, + "y": 0.9170087 + }, + "docs/concepts/aidlc-release-compatibility.md": { + "leafId": "docs-architecture", + "x": 0.2274149, + "y": 0.2179868 + }, + "docs/concepts/architecture.md": { + "leafId": "docs-architecture", + "x": 0.2274149, + "y": 0.4501261 + }, + "docs/concepts/data-model.md": { + "leafId": "docs-architecture", + "x": 0.4861062, + "y": 0.2960993 + }, + "docs/concepts/execution.md": { + "leafId": "docs-architecture", + "x": 0.139129, + "y": 0.6674975 + }, + "docs/concepts/index.md": { + "leafId": "docs-architecture", + "x": 0.2934987, + "y": 0.6674975 + }, + "docs/concepts/workflows-and-blocks.md": { + "leafId": "docs-architecture", + "x": 0.2148097, + "y": 0.8731583 + }, + "docs/development/agent-authentication-foundation.md": { + "leafId": "docs-architecture", + "x": 0.473501, + "y": 0.7338993 + }, + "docs/development/bedrock-iam-rebuild.md": { + "leafId": "docs-architecture", + "x": 0.6269769, + "y": 0.2229063 + }, + "docs/development/demo-deployment.md": { + "leafId": "docs-architecture", + "x": 0.8078456, + "y": 0.2229063 + }, + "docs/development/recovery-ownership.md": { + "leafId": "docs-architecture", + "x": 0.7586913, + "y": 0.4141021 + }, + "docs/development/testing.md": { + "leafId": "docs-architecture", + "x": 0.7586913, + "y": 0.5837324 + }, + "docs/development/yjs-operations.md": { + "leafId": "docs-architecture", + "x": 0.7586913, + "y": 0.8303366 + }, + "AGENTS.md": { + "leafId": "docs-guides", + "x": 0.1172531, + "y": 0.1754226 + }, + "CHANGELOG.md": { + "leafId": "docs-guides", + "x": 0.2506224, + "y": 0.1754226 + }, + "CODE_OF_CONDUCT.md": { + "leafId": "docs-guides", + "x": 0.0861706, + "y": 0.3433466 + }, + "CONTRIBUTING.md": { + "leafId": "docs-guides", + "x": 0.21954, + "y": 0.3433466 + }, + "LICENSE": { + "leafId": "docs-guides", + "x": 0.4214551, + "y": 0.0906506 + }, + "README.md": { + "leafId": "docs-guides", + "x": 0.4214551, + "y": 0.2585745 + }, + "RELEASING.md": { + "leafId": "docs-guides", + "x": 0.1320495, + "y": 0.486674 + }, + "SECURITY.md": { + "leafId": "docs-guides", + "x": 0.2229707, + "y": 0.486674 + }, + "docs/getting-started/enterprise-sso.md": { + "leafId": "docs-guides", + "x": 0.379007, + "y": 0.486674 + }, + "docs/getting-started/first-intent.md": { + "leafId": "docs-guides", + "x": 0.1166861, + "y": 0.6666682 + }, + "docs/getting-started/methodology-map.md": { + "leafId": "docs-guides", + "x": 0.2511909, + "y": 0.6666682 + }, + "docs/getting-started/methodology.md": { + "leafId": "docs-guides", + "x": 0.105194, + "y": 0.8496781 + }, + "docs/getting-started/prerequisites.md": { + "leafId": "docs-guides", + "x": 0.2396989, + "y": 0.8496781 + }, + "docs/getting-started/setup.md": { + "leafId": "docs-guides", + "x": 0.4225906, + "y": 0.7565501 + }, + "docs/index.md": { + "leafId": "docs-guides", + "x": 0.6075047, + "y": 0.1140193 + }, + "docs/overview-video.md": { + "leafId": "docs-guides", + "x": 0.6075047, + "y": 0.2211551 + }, + "docs/using-the-platform/bedrock-iam.md": { + "leafId": "docs-guides", + "x": 0.7455947, + "y": 0.1710958 + }, + "docs/using-the-platform/creating-intents.md": { + "leafId": "docs-guides", + "x": 0.6538216, + "y": 0.3209662 + }, + "docs/using-the-platform/discussions.md": { + "leafId": "docs-guides", + "x": 0.8657358, + "y": 0.1388952 + }, + "docs/using-the-platform/exporting-workspaces.md": { + "leafId": "docs-guides", + "x": 0.8657358, + "y": 0.2887657 + }, + "docs/using-the-platform/git-integration.md": { + "leafId": "docs-guides", + "x": 0.6081828, + "y": 0.4440835 + }, + "docs/using-the-platform/intent-observability.md": { + "leafId": "docs-guides", + "x": 0.6081828, + "y": 0.5879738 + }, + "docs/using-the-platform/managed-environments.md": { + "leafId": "docs-guides", + "x": 0.820097, + "y": 0.5075911 + }, + "docs/using-the-platform/platform-settings.md": { + "leafId": "docs-guides", + "x": 0.6230572, + "y": 0.7044862 + }, + "docs/using-the-platform/projects.md": { + "leafId": "docs-guides", + "x": 0.6230572, + "y": 0.8135751 + }, + "docs/using-the-platform/real-time-collaboration.md": { + "leafId": "docs-guides", + "x": 0.6230572, + "y": 0.9046096 + }, + "docs/using-the-platform/recovering-intents.md": { + "leafId": "docs-guides", + "x": 0.7861531, + "y": 0.7447999 + }, + "docs/using-the-platform/workflows.md": { + "leafId": "docs-guides", + "x": 0.8907417, + "y": 0.7447999 + }, + "zensical.toml": { + "leafId": "docs-guides", + "x": 0.8349714, + "y": 0.8888392 + }, + ".dependency-cruiser.cjs": { + "leafId": "repository-setup", + "x": 0.1639225, + "y": 0.213602 + }, + ".gitignore": { + "leafId": "repository-setup", + "x": 0.3271507, + "y": 0.213602 + }, + ".husky/pre-commit": { + "leafId": "repository-setup", + "x": 0.4450899, + "y": 0.213602 + }, + ".oxfmtrc.json": { + "leafId": "repository-setup", + "x": 0.5547153, + "y": 0.1079714 + }, + ".oxlintignore": { + "leafId": "repository-setup", + "x": 0.5547153, + "y": 0.2040576 + }, + ".oxlintrc.json": { + "leafId": "repository-setup", + "x": 0.6813851, + "y": 0.1600463 + }, + ".secretlintrc.json": { + "leafId": "repository-setup", + "x": 0.5567462, + "y": 0.3096883 + }, + "lint-staged.config.mjs": { + "leafId": "repository-setup", + "x": 0.6834159, + "y": 0.3096883 + }, + "package-lock.json": { + "leafId": "repository-setup", + "x": 0.4085314, + "y": 0.651402 + }, + "package.json": { + "leafId": "repository-setup", + "x": 0.8480914, + "y": 0.1836709 + }, + "pyproject.toml": { + "leafId": "repository-setup", + "x": 0.8480914, + "y": 0.3365836 + }, + "uv.lock": { + "leafId": "repository-setup", + "x": 0.8480914, + "y": 0.5263003 + }, + "vitest.aidlc-compatibility.config.js": { + "leafId": "repository-setup", + "x": 0.8480914, + "y": 0.7403225 + }, + "vitest.config.js": { + "leafId": "repository-setup", + "x": 0.8480914, + "y": 0.8686949 + } + } +} diff --git a/.isobar/map.json b/.isobar/map.json new file mode 100644 index 00000000..949ed42d --- /dev/null +++ b/.isobar/map.json @@ -0,0 +1,698 @@ +{ + "version": 1, + "repo": "Collaborative AI-DLC", + "head": "e9ec7d6161b09ebc02a1a339cc3e41e44c7da04c", + "builtAt": "2026-10-26T18:23:30.768Z", + "source": "repo-file", + "layers": [ + { + "id": "experience", + "name": "Experience", + "blurb": "Where people collaborate", + "height": 350 + }, + { + "id": "execution", + "name": "Execution", + "blurb": "Intent lifecycle and coding agents", + "height": 550 + }, + { + "id": "foundations", + "name": "Foundations", + "blurb": "Contracts, integrations and shared state", + "height": 420 + }, + { + "id": "delivery", + "name": "Delivery", + "blurb": "Build, infrastructure and guidance", + "height": 330 + } + ], + "regions": [ + { + "id": "ui", + "name": "Screens & components", + "blurb": "Screens, intent views and reusable controls", + "layer": "experience", + "paths": ["frontend/src/", "frontend/src/App.tsx", "frontend/src/main.tsx"], + "width": 840, + "columns": 2, + "weight": 10, + "children": [ + { + "id": "pages", + "name": "Pages", + "blurb": "Top-level routes and workflow composition", + "paths": ["frontend/src/pages/"] + }, + { + "id": "intent", + "name": "Intent widgets", + "blurb": "Execution, graph and collaboration views", + "paths": [ + "frontend/src/components/intent/", + "frontend/src/components/discussion/", + "frontend/src/components/graph/", + "frontend/src/components/observability/", + "frontend/src/components/agent-output/", + "frontend/src/components/v2/" + ] + }, + { + "id": "admin", + "name": "Admin widgets", + "blurb": "Platform and project configuration screens", + "paths": [ + "frontend/src/components/admin/", + "frontend/src/components/project-settings/", + "frontend/src/components/settings/", + "frontend/src/components/blocks/" + ] + }, + { + "id": "shared", + "name": "Shared components", + "blurb": "App shell and reusable interface controls", + "paths": [], + "fallback": true + } + ] + }, + { + "id": "client-state", + "name": "Client state & APIs", + "blurb": "Browser requests, state and derived views", + "layer": "experience", + "paths": [ + "frontend/src/services/", + "frontend/src/hooks/", + "frontend/src/contexts/", + "frontend/src/lib/", + "frontend/src/utils/", + "frontend/src/types/" + ], + "width": 840, + "columns": 2, + "weight": 7, + "children": [ + { + "id": "api", + "name": "API clients", + "blurb": "Authenticated browser requests and DTOs", + "paths": ["frontend/src/services/"] + }, + { + "id": "state", + "name": "Hooks & state", + "blurb": "Subscriptions, editing and context state", + "paths": ["frontend/src/hooks/", "frontend/src/contexts/"] + }, + { + "id": "helpers", + "name": "Client helpers", + "blurb": "Derived UI data and browser-side utilities", + "paths": [], + "fallback": true + } + ] + }, + { + "id": "frontend-platform", + "name": "Frontend tooling", + "blurb": "Styles, assets and browser build setup", + "layer": "experience", + "paths": [ + "frontend/", + "frontend/src/assets/", + "frontend/src/index.css", + "frontend/src/test/", + "frontend/src/vite-env.d.ts" + ], + "width": 600, + "columns": 1, + "weight": 3, + "children": [ + { + "id": "assets", + "name": "Styles & assets", + "blurb": "Visual styles and bundled public assets", + "paths": ["frontend/public/", "frontend/src/assets/", "frontend/src/index.css"] + }, + { + "id": "build", + "name": "Browser build", + "blurb": "Vite, TypeScript and browser test setup", + "paths": [], + "fallback": true + } + ] + }, + { + "id": "intent-api", + "name": "Intent & workflow APIs", + "blurb": "Intent lifecycle and versioned workflows", + "layer": "execution", + "paths": [ + "lambda/intents/", + "lambda/intent-pin-lookup/", + "lambda/workflows/", + "lambda/building-blocks/", + "lambda/seed-blocks/" + ], + "width": 500, + "columns": 1, + "weight": 6, + "children": [ + { + "id": "lifecycle", + "name": "Intent lifecycle", + "blurb": "Starts, rewinds, artifacts and attachments", + "paths": ["lambda/intents/", "lambda/intent-pin-lookup/"] + }, + { + "id": "authoring", + "name": "Workflow authoring", + "blurb": "Versioned workflows and building blocks", + "paths": [], + "fallback": true + } + ] + }, + { + "id": "orchestrator", + "name": "Durable orchestration", + "blurb": "Scheduling, gates, recovery and delivery", + "layer": "execution", + "paths": ["lambda/v2-orchestrator/"], + "width": 500, + "columns": 1, + "weight": 7, + "children": [ + { + "id": "flow", + "name": "Durable flow", + "blurb": "Replay-safe execution and delivery", + "paths": [], + "fallback": true + }, + { + "id": "gates", + "name": "Gate & lane helpers", + "blurb": "Callbacks, lane control and artifact edits", + "paths": [ + "lambda/v2-orchestrator/gate-callback.js", + "lambda/v2-orchestrator/section.js", + "lambda/v2-orchestrator/pr-attribution.js", + "lambda/v2-orchestrator/quorum-edit.js", + "lambda/v2-orchestrator/test/gate-*", + "lambda/v2-orchestrator/test/section*", + "lambda/v2-orchestrator/test/pr-*", + "lambda/v2-orchestrator/test/quorum-*", + "lambda/v2-orchestrator/test/lane-*" + ] + } + ] + }, + { + "id": "agentcore", + "name": "Agent runtime", + "blurb": "CLI execution, MCP, sensors and workspaces", + "layer": "execution", + "paths": ["lambda/agentcore/", "lambda/mcp-tools/"], + "width": 860, + "columns": 3, + "weight": 10, + "children": [ + { + "id": "commands", + "name": "Commands", + "blurb": "Runtime command handlers and dispatch", + "paths": ["lambda/agentcore/commands/", "lambda/agentcore/command-registry.js"] + }, + { + "id": "cli", + "name": "CLI drivers", + "blurb": "CLI processes, parsers and transcript stores", + "paths": ["lambda/agentcore/cli/"] + }, + { + "id": "mcp", + "name": "MCP tools", + "blurb": "Scoped graph tools and process-state access", + "paths": ["lambda/agentcore/mcp/", "lambda/mcp-tools/"] + }, + { + "id": "git", + "name": "Git & workspace", + "blurb": "Engine-owned repositories and workspace I/O", + "paths": [ + "lambda/agentcore/workspace.js", + "lambda/agentcore/git-engine.js", + "lambda/agentcore/git-runner.js", + "lambda/agentcore/git-auth.js", + "lambda/agentcore/repo-paths.js", + "lambda/agentcore/code-traceability.js" + ] + }, + { + "id": "context", + "name": "Stage context", + "blurb": "Stage prompts and deterministic validation", + "paths": [ + "lambda/agentcore/sensor-runner.js", + "lambda/agentcore/context-compiler.js", + "lambda/agentcore/stage-materializer.js", + "lambda/agentcore/block-loader.js", + "lambda/agentcore/custom-rules.js", + "lambda/agentcore/release-script-closure.js", + "lambda/agentcore/ensemble-runner.js", + "lambda/agentcore/persona-dispatch.js", + "lambda/agentcore/output-normalizer.js", + "lambda/agentcore/attachments.js", + "lambda/agentcore/prompts/" + ] + }, + { + "id": "host", + "name": "Runtime host", + "blurb": "Runtime entry point and invocation identity", + "paths": [], + "fallback": true + }, + { + "id": "tests", + "name": "Runtime tests", + "blurb": "Agent execution regressions and fixtures", + "paths": ["lambda/agentcore/test/", "lambda/mcp-tools/test/"] + } + ] + }, + { + "id": "history", + "name": "Archived sprint data", + "blurb": "Read-only v1 artifacts and execution history", + "layer": "execution", + "paths": [ + "lambda/code-files/", + "lambda/requirements/", + "lambda/user-stories/", + "lambda/tasks/", + "lambda/timeline-events/", + "lambda/sprint-graph/", + "lambda/sprints/", + "lambda/questions/", + "lambda/reviews/", + "lambda/general-info/" + ], + "width": 400, + "columns": 1, + "weight": 4, + "children": [ + { + "id": "reads", + "name": "Archived reads", + "blurb": "Retired sprint records, reviews and questions", + "paths": [], + "fallback": true + } + ] + }, + { + "id": "shared", + "name": "Shared contracts", + "blurb": "Execution, access and methodology contracts", + "layer": "foundations", + "paths": ["lambda/shared/", "lambda/engine-data/"], + "width": 600, + "columns": 2, + "weight": 10, + "children": [ + { + "id": "execution", + "name": "State & data", + "blurb": "Process state, data access and runtime ownership", + "paths": [ + "lambda/shared/v2-*", + "lambda/shared/stage-*", + "lambda/shared/gate-*", + "lambda/shared/runtime-*", + "lambda/shared/environment-snapshot.js", + "lambda/shared/session-cleanup-store.js", + "lambda/shared/construction-autonomy.js", + "lambda/shared/pr-strategy.js", + "lambda/shared/sensor-verdict.js", + "lambda/shared/changed-file-provenance.js", + "lambda/shared/agent-command-registry.js", + "lambda/shared/unit-kind-pruning.js", + "lambda/engine-data/" + ] + }, + { + "id": "authentication", + "name": "Agent auth", + "blurb": "Credential bindings and access contracts", + "paths": [ + "lambda/shared/agent-auth-*", + "lambda/shared/agent-credential*", + "lambda/shared/agent-oauth-*", + "lambda/shared/agent-binding-selection.js", + "lambda/shared/agent-connection-repository.js", + "lambda/shared/agent-key-repository.js", + "lambda/shared/authz.js", + "lambda/shared/legacy-authz.js", + "lambda/shared/sso-roles.js", + "lambda/shared/tenant.js", + "lambda/shared/bedrock-iam.js" + ] + }, + { + "id": "methodology", + "name": "Methodology", + "blurb": "Release catalogs and canonical artifact rules", + "paths": [ + "lambda/shared/aidlc-*", + "lambda/shared/artifact-*", + "lambda/shared/annex-reach.js", + "lambda/shared/block-mappers.js", + "lambda/shared/blocks.js", + "lambda/shared/compile.js", + "lambda/shared/compose-match.js", + "lambda/shared/composed-grid.js", + "lambda/shared/custom-rule-versions.js", + "lambda/shared/distribution-archive.js", + "lambda/shared/ensemble-contribution.js", + "lambda/shared/frontmatter.js", + "lambda/shared/intent-aidlc-settings.js", + "lambda/shared/intent-methodology.js", + "lambda/shared/methodology-catalog.js", + "lambda/shared/native-repositories.js", + "lambda/shared/native-workspace-projector.js", + "lambda/shared/release-registry.js", + "lambda/shared/release-resolver.js", + "lambda/shared/script-closure.js", + "lambda/shared/workflow-checkpoint.js", + "lambda/shared/workflows.js", + "lambda/shared/upstream-artifact-ids.json" + ] + }, + { + "id": "helpers", + "name": "Helpers & tests", + "blurb": "Shared support code and regression fixtures", + "paths": ["lambda/engine-data/test/"], + "fallback": true + } + ] + }, + { + "id": "identity", + "name": "Projects & admin", + "blurb": "Access, credentials and managed environments", + "layer": "foundations", + "paths": [ + "lambda/projects/", + "lambda/users/", + "lambda/cognito-users/", + "lambda/sso-token/", + "lambda/agents/", + "lambda/credential-broker/", + "lambda/credential-metadata/", + "lambda/environments/", + "config/platform-roles.json" + ], + "width": 540, + "columns": 2, + "weight": 5, + "children": [ + { + "id": "projects-users", + "name": "Projects & users", + "blurb": "Project membership and platform identity", + "paths": [ + "lambda/projects/", + "lambda/users/", + "lambda/cognito-users/", + "lambda/sso-token/", + "config/platform-roles.json" + ] + }, + { + "id": "agent-settings", + "name": "Agent settings", + "blurb": "Credential services, models and legacy reads", + "paths": ["lambda/agents/", "lambda/credential-broker/", "lambda/credential-metadata/"] + }, + { + "id": "environments", + "name": "Environments", + "blurb": "Tool images, builds and runtime backends", + "paths": [], + "fallback": true + } + ] + }, + { + "id": "realtime", + "name": "Collaboration & sync", + "blurb": "Discussions, Yjs and WebSocket updates", + "layer": "foundations", + "paths": [ + "lambda/discussions/", + "lambda/yjs-server/", + "lambda/ws-authorizer/", + "lambda/ws-connection/", + "lambda/ws-message/" + ], + "width": 600, + "columns": 1, + "weight": 4, + "children": [ + { + "id": "discussions", + "name": "Discussions", + "blurb": "Durable conversations and scope tokens", + "paths": ["lambda/discussions/"] + }, + { + "id": "transports", + "name": "Live transports", + "blurb": "Yjs sync and application WebSockets", + "paths": [], + "fallback": true + } + ] + }, + { + "id": "integrations", + "name": "Git & tracker adapters", + "blurb": "Repository access and issue synchronization", + "layer": "foundations", + "paths": [ + "lambda/source-control/", + "lambda/github/", + "lambda/gitlab/", + "lambda/bitbucket/", + "lambda/codecommit/", + "lambda/trackers/", + "lambda/migrate-tracker-fields/", + "lambda/shared/git-providers/", + "lambda/shared/git-providers.js" + ], + "width": 520, + "columns": 2, + "weight": 5, + "children": [ + { + "id": "git", + "name": "Git providers", + "blurb": "Repository-provider operation adapters", + "paths": ["lambda/shared/git-providers/", "lambda/shared/git-providers.js"] + }, + { + "id": "oauth", + "name": "Connections", + "blurb": "Repository connections and OAuth endpoints", + "paths": [ + "lambda/source-control/", + "lambda/github/", + "lambda/gitlab/", + "lambda/bitbucket/", + "lambda/codecommit/" + ] + }, + { + "id": "trackers", + "name": "Issue trackers", + "blurb": "Issue imports and delivery synchronization", + "paths": [], + "fallback": true + } + ] + }, + { + "id": "infrastructure", + "name": "Infrastructure", + "blurb": "AWS resources and operational maintenance", + "layer": "delivery", + "paths": ["terraform/", "lambda/purge-neptune/", "lambda/.dockerignore"], + "width": 720, + "columns": 2, + "weight": 6, + "children": [ + { + "id": "app", + "name": "App resources", + "blurb": "API, agents, frontend and realtime services", + "paths": [ + "terraform/modules/api/", + "terraform/modules/compute/", + "terraform/modules/frontend/", + "terraform/modules/realtime/", + "lambda/.dockerignore" + ] + }, + { + "id": "data", + "name": "Data & access", + "blurb": "Storage, identities and operational cleanup", + "paths": [ + "terraform/modules/data/", + "terraform/modules/auth/", + "terraform/modules/security/", + "terraform/modules/git/", + "lambda/purge-neptune/" + ] + }, + { + "id": "stack", + "name": "Network & stack", + "blurb": "VPC, domains and root stack configuration", + "paths": [], + "fallback": true + } + ] + }, + { + "id": "release", + "name": "CI, release & checks", + "blurb": "Builds, installs and regression harnesses", + "layer": "delivery", + "paths": ["scripts/", ".github/", ".isobar/", "test/"], + "width": 560, + "columns": 1, + "weight": 4, + "children": [ + { + "id": "actions", + "name": "Actions & map", + "blurb": "GitHub automation and the fixed impact map", + "paths": [".github/", ".isobar/"] + }, + { + "id": "scripts", + "name": "Scripts & harnesses", + "blurb": "Installers, release tools and test services", + "paths": [], + "fallback": true + } + ] + }, + { + "id": "docs", + "name": "Documentation", + "blurb": "Architecture, setup and contributor guidance", + "layer": "delivery", + "paths": [ + "docs/", + "README.md", + "CONTRIBUTING.md", + "AGENTS.md", + "SECURITY.md", + "CODE_OF_CONDUCT.md", + "LICENSE", + "NOTICE", + "zensical.toml", + "CHANGELOG.md", + "RELEASING.md" + ], + "width": 580, + "columns": 1, + "weight": 4, + "children": [ + { + "id": "architecture", + "name": "Architecture & ops", + "blurb": "System contracts and developer runbooks", + "paths": ["docs/concepts/", "docs/development/"] + }, + { + "id": "guides", + "name": "Guides & policy", + "blurb": "Setup, user guides and contribution policy", + "paths": [], + "fallback": true + } + ] + }, + { + "id": "repository", + "name": "Repository setup", + "blurb": "Dependencies and development configuration", + "layer": "delivery", + "paths": [ + "package.json", + "package-lock.json", + "pyproject.toml", + "uv.lock", + ".dependency-cruiser.cjs", + ".gitignore", + ".oxfmtrc.json", + ".oxlintrc.json", + ".oxlintignore", + ".secretlintrc.json", + ".husky/", + ".vscode/", + "vitest.config.js", + "vitest.aidlc-compatibility.config.js", + "lint-staged.config.mjs" + ], + "width": 400, + "columns": 1, + "weight": 3, + "children": [ + { + "id": "setup", + "name": "Development setup", + "blurb": "Dependency, lint and test configuration", + "paths": [ + "package.json", + "package-lock.json", + "pyproject.toml", + "uv.lock", + ".dependency-cruiser.cjs", + ".gitignore", + ".oxfmtrc.json", + ".oxlintrc.json", + ".oxlintignore", + ".secretlintrc.json", + ".husky/", + ".vscode/", + "vitest.config.js", + "vitest.aidlc-compatibility.config.js", + "lint-staged.config.mjs" + ] + }, + { + "id": "other", + "name": "Other files", + "blurb": "Files outside the authored code areas", + "paths": [], + "fallback": true + } + ] + } + ], + "fallbackSection": "repository" +} diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 36b6b564..4c22135b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -66,6 +66,8 @@ The [internal testing guide](docs/development/testing.md) documents the determin ## Contributing via Pull Requests +See [PR review signals](docs/development/pr-quality.md) for the automated quality metrics, repository map and fork workflow behavior. + Contributions via pull requests are much appreciated. Before sending us a pull request, please ensure that: 1. You are working against the latest source on the _main_ branch. diff --git a/docs/development/pr-quality.md b/docs/development/pr-quality.md index 95391667..7fe96157 100644 --- a/docs/development/pr-quality.md +++ b/docs/development/pr-quality.md @@ -1,11 +1,13 @@ -# PR quality reports +# PR review signals -CI updates one PR comment with cognitive-complexity, dependency counts, and branch-coverage changes -for source files changed between the merge base and PR commit. Findings are advisory: functions above 15 appear +One automatically computed, deterministic PR comment combines quality metrics and an +[Isobar](https://github.com/r3al1tym/isobar) repository map. Both sections open by default and can be collapsed independently. +Quality metrics cover source files changed between the merge base and PR commit. Findings are advisory: functions above 15 appear when complexity or coverage worsens, or when the function is new/unmatched. Unchanged debt is omitted; improvements appear in the same table. When no source files are analyzed, or no findings, improvements, or analysis warnings remain, -CI posts no comment and removes its previous report if present. +the quality section is omitted. Without a map, CI removes its previous quality-only comment. +The map can remain visible for infrastructure, CI or documentation changes. ## Reading the table @@ -34,6 +36,14 @@ Rows are sorted ๐ŸŸฃ โ†’ ๐Ÿ”ด โ†’ ๐ŸŸ  โ†’ ๐ŸŸข. The first 10 are visible, or al the remaining rows appear under โ€œShow moreโ€. GitHub comment size limits still apply; artifacts contain all results. Coverage diagnostics stay in the artifacts; the comment shows one notice if measurements are unavailable or incomplete. +## Reading the map + +The atlas stays fixed across PRs. Red marks changed files; green marks static name matches or import links. +These links show possible reach, not proven runtime impact or a risk grade. +A/B identify changed files described in Signals; they need not match the first functions in the quality table. +The Legend explains marker shapes, test/documentation colors and solid/dotted links. +Terraform/IAM, CI and documentation changes can have a map even when production JS/TS metrics do not apply. + ## CI Backend and frontend suites run independently at both revisions when their source, tests, or configuration change. @@ -43,11 +53,23 @@ Each `coverage-base-*` / `coverage-pr-*` artifact contains the requested suites' Dependency analysis failures leave only those counts unknown. Partial reruns reuse artifacts only when their producers were not rerun; missing or stale results are reported explicitly. -Same-repository PRs can comment immediately. Forks and Dependabot need the comment -workflow on the default branch; it validates report data without executing PR code. +`PR Review Signals` uses `pull_request_target` and the trusted default-branch controller. +It reads contributor Git objects as data without checking out or executing contributor code. +For supported fork events, the static report can run before contributor-code approval, subject to +[GitHub's event policies](https://docs.github.com/en/actions/reference/security/securely-using-pull_request_target). +The existing `PR Quality` workflow uses `pull_request`; its tests retain the fork-approval policy. +Approved coverage runs enrich the same comment through a trusted publisher; later static updates preserve valid measurements. +The target workflow activates once it exists on the default branch; existing PRs update on their next supported event. + Artifacts are retained for seven days: `complexity-*` lists every function in changed files with base/PR scores and coverage; `dependencies-*` lists their direct production importers. Both include Markdown and JSON. `pr-quality-*` holds the data used to publish the comment. +`review-signals-*` contains the map PNG, static evidence and quality JSON. + +The fixed atlas and file positions live in `.isobar/map.json` and `.isobar/anchors.json`. +The `pr-impact-assets` branch stores images and validated snapshots; comments link to an immutable asset commit. +Updates replace the same bot comment with one image. Full results remain in the linked artifacts when the display is shortened. +Run `npm run test:release` when changing the atlas or reporting tools. ## Local use diff --git a/scripts/complexity-report.mjs b/scripts/complexity-report.mjs index 36c6cbde..5e927e01 100644 --- a/scripts/complexity-report.mjs +++ b/scripts/complexity-report.mjs @@ -55,7 +55,42 @@ export function changeIcon(row) { return icon; } -function renderTable(rows) { +function functionLocation(row, headSha) { + const text = `${row.path}:${row.line} โ€” ${row.function}`.slice(0, 500); + const plain = cell(text); + const location = `${row.path}:${row.line}`; + if ( + !/^[a-f0-9]{40}$/.test(headSha ?? '') || + !Number.isSafeInteger(row.line) || + row.line < 1 || + location.length >= 500 || + row.path.includes('\\') || + Array.from(row.path).some((character) => { + const code = character.charCodeAt(0); + return code < 32 || code === 127; + }) || + /^[a-z]:/i.test(row.path) || + row.path.split('/').some((segment) => !segment || segment === '.' || segment === '..') + ) + return plain; + let path; + try { + path = row.path + .split('/') + .map((segment) => + encodeURIComponent(segment).replace( + /[!'()*]/g, + (character) => `%${character.charCodeAt(0).toString(16).toUpperCase()}`, + ), + ) + .join('/'); + } catch { + return plain; + } + return `[${cell(location)}](https://github.com/aws-samples/sample-collaborative-ai-dlc/blob/${headSha}/${path}#L${row.line})${cell(text.slice(location.length))}`; +} + +function renderTable(rows, headSha) { return [ '| | File / function | Complexity | ฮ” | Branch coverage | ฮ” | Uncovered branches | Depending files |', '| --- | --- | ---: | ---: | --- | ---: | ---: | ---: |', @@ -75,20 +110,28 @@ function renderTable(rows) { const dependents = row.path.startsWith('frontend/') ? 'n/a' : (row.dependentFiles ?? 'unknown'); - return `| ${changeIcon(row)} | ${cell(`${row.path}:${row.line} โ€” ${row.function}`)} | ${row.before ?? 'โ€”'} โ†’ ${row.after} | ${row.delta === null ? 'โ€”' : signed(row.delta)} | ${coverage} | ${delta == null ? 'โ€”' : signed(Number(delta.toFixed(1)))} | ${branches} | ${dependents} |`; + return `| ${changeIcon(row)} | ${functionLocation(row, headSha)} | ${row.before ?? 'โ€”'} โ†’ ${row.after} | ${row.delta === null ? 'โ€”' : signed(row.delta)} | ${coverage} | ${delta == null ? 'โ€”' : signed(Number(delta.toFixed(1)))} | ${branches} | ${dependents} |`; }), ].join('\n'); } -function renderRows(rows) { +function renderRows(rows, headSha, maxRows) { const ordered = rows.toSorted( (a, b) => iconOrder.indexOf(changeIcon(a)) - iconOrder.indexOf(changeIcon(b)), ); const visibleCount = Math.max(10, ordered.filter((row) => changeIcon(row) === '๐ŸŸฃ').length); - const visible = renderTable(ordered.slice(0, visibleCount)); - const remaining = ordered.slice(visibleCount); - if (!remaining.length) return visible; - return `${visible}\n\n
\nShow ${remaining.length} more functions\n\n${renderTable(remaining)}\n\n
`; + const displayed = ordered.slice(0, maxRows); + const remaining = displayed.slice(visibleCount); + const lines = displayed.length ? [renderTable(displayed.slice(0, visibleCount), headSha)] : []; + if (remaining.length) + lines.push( + `
\nShow ${remaining.length} more functions\n\n${renderTable(remaining, headSha)}\n\n
`, + ); + if (displayed.length < ordered.length) + lines.push( + `Display truncated: showing ${displayed.length} of ${ordered.length} functions. See the full report artifacts.`, + ); + return lines.join('\n\n'); } export function hasIncompleteCoverage(report) { @@ -121,35 +164,41 @@ export function hasIncompleteCoverage(report) { ); } -export function renderComparison(report) { +export function comparisonRows(report) { const findings = new Set(report.findings.map(rowKey)); // A complexity improvement can also be a coverage regression; show it once. - const rows = [ - ...report.findings, - ...report.improvements.filter((row) => !findings.has(rowKey(row))), - ]; - const lines = [ - '# Complexity and test coverage', - '', - 'Automated quality report using code complexity and test coverage to highlight potential hot spots in this PR.', - 'Review ๐ŸŸฃ and ๐Ÿ”ด items first: consider simplifying the code, improving test coverage, or both. This report is advisory.', - ]; + return [...report.findings, ...report.improvements.filter((row) => !findings.has(rowKey(row)))]; +} + +export function renderComparison(report, { embedded = false, headSha, maxRows = Infinity } = {}) { + if (maxRows !== Infinity && (!Number.isSafeInteger(maxRows) || maxRows < 0)) + throw new Error('Invalid comparison row limit'); + const rows = comparisonRows(report); + const lines = embedded + ? [] + : [ + '# Complexity and test coverage', + '', + 'Automated quality report using code complexity and test coverage to highlight potential hot spots in this PR.', + 'Review ๐ŸŸฃ and ๐Ÿ”ด items first: consider simplifying the code, improving test coverage, or both. This report is advisory.', + ]; const incompleteCoverage = hasIncompleteCoverage(report); - if (incompleteCoverage) { + if (incompleteCoverage && !embedded) { lines.push( '', 'Some coverage data is unavailable or incomplete; see the report artifacts for details.', ); } if (report.dependencyNote) lines.push('', cell(report.dependencyNote)); - if (rows.length) lines.push('', renderRows(rows)); - lines.push( - '', - '๐ŸŸข Improving ยท ๐ŸŸ  Needs attention ยท ๐Ÿ”ด High risk ยท ๐ŸŸฃ Highest risk', - '', - 'โ€” = unavailable ยท n/a = not applicable ยท \\* = incomplete tests', - '', - ); + if (rows.length) lines.push('', renderRows(rows, embedded ? headSha : undefined, maxRows)); + if (rows.length || !embedded) + lines.push( + '', + '๐ŸŸข Improving ยท ๐ŸŸ  Needs attention ยท ๐Ÿ”ด High risk ยท ๐ŸŸฃ Highest risk', + '', + 'โ€” = unavailable ยท n/a = not applicable ยท \\* = incomplete tests', + '', + ); return lines.join('\n'); } diff --git a/scripts/pr-impact/anchors.mjs b/scripts/pr-impact/anchors.mjs new file mode 100644 index 00000000..57241322 --- /dev/null +++ b/scripts/pr-impact/anchors.mjs @@ -0,0 +1,49 @@ +import { createHash } from 'node:crypto'; + +export const ANCHOR_VERSION = 1; +export const digestOf = (bytes) => createHash('sha256').update(bytes).digest('hex'); + +// Existing files use coordinates frozen from the authored baseline. New paths +// receive reproducible positions independent of file counts, LOC, or neighbours. +export function loadAnchors(source, frame) { + if (source?.version !== ANCHOR_VERSION || !/^[a-f0-9]{40}$/.test(source.baselineSha)) { + throw new Error('Invalid fixed file-anchor baseline'); + } + if (!source.files || typeof source.files !== 'object' || Array.isArray(source.files)) { + throw new Error('Invalid fixed file anchors'); + } + for (const [path, point] of Object.entries(source.files)) { + if ( + !point || + point.leafId !== frame.assign(path).leaf.id || + !Number.isFinite(point.x) || + !Number.isFinite(point.y) || + point.x < 0 || + point.x > 1 || + point.y < 0 || + point.y > 1 + ) { + throw new Error(`Invalid fixed file anchor: ${path}`); + } + } + const get = (path) => { + const prior = source.files[path]; + if (prior) return { ...prior, basis: 'baseline', version: ANCHOR_VERSION }; + const leafId = frame.assign(path).leaf.id; + const hash = createHash('sha256').update(`isobar-anchor-v1:${leafId}:${path}`).digest(); + return { + leafId, + x: 0.07 + 0.86 * (hash.readUInt32BE(0) / 0xffffffff), + y: 0.07 + 0.86 * (hash.readUInt32BE(4) / 0xffffffff), + basis: 'new-path', + version: ANCHOR_VERSION, + }; + }; + return { get, baselineSha: source.baselineSha, version: ANCHOR_VERSION }; +} + +// Place a point within its own geographic rectangle. No state/weights derived +// from the PR participate; the same file appears in the same place each time. +export function pixelAnchor(point, rect) { + return { x: rect.x + point.x * rect.w, y: rect.y + point.y * rect.h }; +} diff --git a/scripts/pr-impact/collect.mjs b/scripts/pr-impact/collect.mjs new file mode 100644 index 00000000..ab36ad1d --- /dev/null +++ b/scripts/pr-impact/collect.mjs @@ -0,0 +1,146 @@ +import { execFile } from 'node:child_process'; +import { mkdir, readFile, writeFile } from 'node:fs/promises'; +import { resolve } from 'node:path'; +import { fileURLToPath } from 'node:url'; +import { promisify } from 'node:util'; +import { compareRevisions } from '../compare-complexity.mjs'; +import { render } from './render.mjs'; + +const execute = promisify(execFile); +const sha = (value) => typeof value === 'string' && /^[a-f0-9]{40}$/.test(value); +const positive = (value) => Number.isSafeInteger(value) && value > 0; +const gitEnvironment = { + ...process.env, + GIT_CONFIG_NOSYSTEM: '1', + GIT_CONFIG_GLOBAL: '/dev/null', + GIT_TERMINAL_PROMPT: '0', +}; + +function requireMetadata(metadata) { + if ( + metadata?.schemaVersion !== 1 || + !/^[\w.-]+\/[\w.-]+$/.test(metadata.repository ?? '') || + ![metadata.headSha, metadata.baseSha, metadata.controllerSha].every(sha) || + ![metadata.prNumber, metadata.runId, metadata.runAttempt, metadata.headRepositoryId].every( + positive, + ) || + typeof metadata.baseRef !== 'string' || + !metadata.baseRef || + metadata.baseRef.length > 255 || + Array.from(metadata.baseRef).some( + (character) => character.charCodeAt(0) < 32 || character.charCodeAt(0) === 127, + ) + ) { + throw new Error('Invalid trusted PR event context'); + } +} + +export function captureContext(event, environment) { + const pr = event.pull_request; + const metadata = { + schemaVersion: 1, + repository: environment.GITHUB_REPOSITORY, + prNumber: event.number, + headSha: pr?.head?.sha, + baseSha: pr?.base?.sha, + baseRef: pr?.base?.ref, + controllerSha: environment.GITHUB_SHA, + runId: Number(environment.GITHUB_RUN_ID), + runAttempt: Number(environment.GITHUB_RUN_ATTEMPT), + headRepositoryId: pr?.head?.repo?.id, + }; + if ( + environment.GITHUB_EVENT_NAME !== 'pull_request_target' || + event.repository?.full_name !== metadata.repository || + pr?.base?.repo?.full_name !== metadata.repository + ) { + throw new Error('Invalid trusted PR event context'); + } + requireMetadata(metadata); + return metadata; +} + +// Install and execute only the controller's tooling. The contributor revision +// is fetched into its object database and read as immutable blobs, never checked out. +export async function collectReviewSignals({ + cwd, + metadata, + upstream, + python, + output, + git = async (args) => + ( + await execute( + 'git', + ['-c', 'core.hooksPath=/dev/null', '-c', 'core.fsmonitor=false', ...args], + { + cwd, + env: gitEnvironment, + encoding: 'utf8', + maxBuffer: 32 * 1024 * 1024, + timeout: 180_000, + }, + ) + ).stdout, + compare = compareRevisions, + renderImpact = render, +}) { + requireMetadata(metadata); + const controller = (await git(['rev-parse', 'HEAD'])).trim(); + if (controller !== metadata.controllerSha) throw new Error('Controller checkout changed'); + await git([ + 'fetch', + '--no-tags', + '--no-recurse-submodules', + `https://github.com/${metadata.repository}.git`, + metadata.baseSha, + `+refs/pull/${metadata.prNumber}/head:refs/pr-review/head`, + ]); + const capturedHead = (await git(['rev-parse', 'refs/pr-review/head'])).trim(); + if (capturedHead !== metadata.headSha) throw new Error('PR advanced during static collection'); + if ((await git(['rev-parse', 'HEAD'])).trim() !== controller) + throw new Error('Contributor source replaced the controller checkout'); + const mergeBaseSha = (await git(['merge-base', metadata.baseSha, metadata.headSha])).trim(); + if (!sha(mergeBaseSha)) throw new Error('No valid PR merge base'); + const quality = await compare({ + cwd, + base: metadata.baseSha, + pr: metadata.headSha, + baseRef: metadata.baseRef, + }); + if (quality.pr !== metadata.headSha || quality.mergeBase !== mergeBaseSha) + throw new Error('Quality revision mismatch'); + await mkdir(resolve(output, 'quality'), { recursive: true }); + await writeFile( + resolve(output, 'quality/comparison.json'), + `${JSON.stringify(quality, null, 2)}\n`, + ); + const impact = await renderImpact({ + repo: cwd, + upstream, + mapPath: resolve(cwd, '.isobar/map.json'), + baseSha: metadata.baseSha, + headSha: metadata.headSha, + prNumber: metadata.prNumber, + repository: metadata.repository, + out: resolve(output, 'impact'), + python, + }); + if (impact.headSha !== metadata.headSha || impact.mergeBaseSha !== mergeBaseSha) + throw new Error('Map revision mismatch'); + const context = { ...metadata, mergeBaseSha }; + await writeFile(resolve(output, 'context.json'), `${JSON.stringify(context, null, 2)}\n`); + return { context, quality, impact }; +} + +if (process.argv[1] && resolve(process.argv[1]) === fileURLToPath(import.meta.url)) { + const event = JSON.parse(await readFile(process.env.GITHUB_EVENT_PATH, 'utf8')); + const metadata = captureContext(event, process.env); + await collectReviewSignals({ + cwd: process.cwd(), + metadata, + upstream: resolve(process.env.ISOBAR_UPSTREAM), + python: resolve(process.env.ISOBAR_PYTHON), + output: resolve(process.env.REVIEW_REPORT_DIRECTORY), + }); +} diff --git a/scripts/pr-impact/comment.mjs b/scripts/pr-impact/comment.mjs new file mode 100644 index 00000000..a9c77a9d --- /dev/null +++ b/scripts/pr-impact/comment.mjs @@ -0,0 +1,224 @@ +// Dependency-free: imported by the trusted publisher after report validation. +import { comparisonRows, hasIncompleteCoverage, renderComparison } from '../complexity-report.mjs'; + +const repository = 'aws-samples/sample-collaborative-ai-dlc'; +const sha = (value) => typeof value === 'string' && /^[a-f0-9]{40}$/.test(value); +const escape = (value) => + String(value) + .slice(0, 500) + .replace(/[&<>|`\r\n@[\]\\!*_~]/g, (character) => `&#${character.charCodeAt(0)};`); +const plural = (count, noun) => `${count} ${noun}${count === 1 ? '' : 's'}`; +const count = (value) => { + if (!Number.isSafeInteger(value) || value < 0) throw new Error('Invalid impact count'); + return value; +}; + +function validateUrls(imageUrl, artifactUrl) { + const rawPrefix = `https://raw.githubusercontent.com/${repository}/`; + const artifactPrefix = `https://github.com/${repository}/actions/runs/`; + if ( + imageUrl != null && + (typeof imageUrl !== 'string' || + !imageUrl.startsWith(rawPrefix) || + !/^[a-f0-9]{40}\/pr-[1-9]\d*\/map\.png$/.test(imageUrl.slice(rawPrefix.length))) + ) + throw new Error('Invalid impact image URL'); + if ( + artifactUrl != null && + (typeof artifactUrl !== 'string' || + !artifactUrl.startsWith(artifactPrefix) || + !/^[1-9]\d*(?:#artifacts)?$/.test(artifactUrl.slice(artifactPrefix.length))) + ) + throw new Error('Invalid report artifact URL'); +} + +function coverageSummary(report, rows) { + const measurements = (revision) => { + const values = report.files.flatMap((file) => + Array.isArray(file[revision]) ? file[revision].map((fn) => fn?.coverage) : [], + ); + return values.length + ? values + : rows.filter((row) => row[revision] !== null).map((row) => row.coverage?.[revision]); + }; + const before = measurements('before'); + const after = measurements('after'); + const measuredBefore = before.some((value) => value?.status === 'measured'); + const measuredAfter = after.some((value) => value?.status === 'measured'); + const partial = [...before, ...after].some((value) => value?.partial); + if (!measuredBefore && !measuredAfter) + return 'Coverage unavailable; test protection cannot be compared.'; + if (!measuredBefore) + return `Coverage: ${partial ? 'partial PR measurements' : 'PR measurements only'}; no comparable baseline, so no before/after comparison.`; + if (!measuredAfter) + return `Coverage: ${partial ? 'partial baseline measurements' : 'baseline measurements only'}; PR coverage unavailable, so no before/after comparison.`; + const unavailable = + [...before, ...after].some((value) => value?.status !== 'measured') || + report.coverageNotes?.some( + (note) => + /unknown/.test(note) && + report.files.some((file) => + file.path.startsWith(note.startsWith('Frontend ') ? 'frontend/' : 'lambda/'), + ), + ); + if (partial) + return `Coverage: partial measurements${unavailable ? '; some data unavailable' : ''}. Available deltas may reflect incomplete tests.`; + if (unavailable) return 'Coverage: before/after measurements available; some data unavailable.'; + return 'Coverage: before/after measurements available for the analyzed functions.'; +} + +function qualitySection(report, headSha, maxRows = Infinity) { + const rows = comparisonRows(report); + const improvements = rows.length - report.findings.length; + return [ + '
', + 'Complexity and test coverage', + '', + `${plural(report.files.length, 'changed JS/TS file')} analyzed ยท ${plural(report.findings.length, 'flagged function')}${improvements ? ` ยท ${plural(improvements, 'improvement')}` : ''}.`, + coverageSummary(report, rows), + '', + renderComparison(report, { embedded: true, headSha, maxRows }).trim(), + '', + '
', + ].join('\n'); +} + +function emptyQualityScope(impactReport) { + const paths = (impactReport?.files ?? impactReport?.evidence?.changes ?? []).map( + (file) => file.path, + ); + const notes = ['No production JS/TS in scope.']; + if (paths.some((path) => /^(?:\.github|scripts)\//.test(path))) + notes.push('CI and tooling changes are outside these production JS/TS metrics.'); + if (paths.some((path) => path.startsWith('terraform/') || /\.tf(?:\.json)?$/.test(path))) + notes.push('The quality analyzer does not assess Terraform or IAM changes.'); + return notes.join(' '); +} + +function mapSection(report, imageUrl, revision) { + const { annotations, summary } = report.evidence; + if (!Array.isArray(annotations) || annotations.length > 2) + throw new Error('Invalid impact annotations'); + const signals = annotations.map( + (annotation) => + `- ${escape(annotation.key)}: ${escape(annotation.path)} โ€” ${escape(annotation.detail)}.`, + ); + signals.push( + `- Total static reach: ${count(summary.productionReachFiles)} unchanged production files; ${count(summary.testReachFiles)} unchanged test files.`, + ); + if (count(summary.unavailableReachFiles)) + signals.push( + `- Static reach unavailable for ${plural(summary.unavailableReachFiles, 'changed file')}.`, + ); + signals.push(`- ${revision}`); + return [ + '
', + 'Isobar repository map', + '', + `![PR impact map](${imageUrl})`, + '', + 'This fixed repository map locates changed files and their possible reach through static links.', + 'Red marks changed files; green marks static links, not proven runtime impact or a risk grade.', + '', + '[Isobar](https://github.com/r3al1tym/isobar) by [r3al1tym](https://github.com/r3al1tym).', + '', + '
', + 'Signals', + '', + ...signals, + '', + '
', + '', + '
', + 'Legend', + '', + '- โ—‹ modified ยท โ—‡ added ยท ร— deleted. Blue markers: tests; gray markers: documentation.', + '- Solid green: import-linked name matches. Dotted green: broader file-level import fallback.', + '', + '
', + '', + '
', + ].join('\n'); +} + +/** + * Compose validated quality/map data. The publisher owns artifact validation, + * PR identity, asset publication and comment updates; this function has no I/O. + */ +export function renderReviewComment({ + qualityReport, + impactReport, + imageUrl, + headSha, + updatedAt, + artifactUrl, + maxLength = 50000, +}) { + if (!Number.isSafeInteger(maxLength) || maxLength < 1 || maxLength > 60000) + throw new Error('Invalid review comment size budget'); + if (!sha(headSha)) throw new Error('Invalid review head SHA'); + if (qualityReport && qualityReport.pr !== headSha) + throw new Error('Quality report belongs to a different revision'); + if (impactReport && impactReport.headSha !== headSha) + throw new Error('Impact report belongs to a different revision'); + validateUrls(imageUrl, artifactUrl); + if (imageUrl && !impactReport) throw new Error('Impact image requires an impact report'); + if (imageUrl && !imageUrl.endsWith(`/pr-${impactReport.prNumber}/map.png`)) + throw new Error('Impact image belongs to a different PR'); + const date = new Date(updatedAt); + if (!Number.isFinite(date.getTime())) throw new Error('Invalid review update time'); + const revision = `Revision: \`${headSha.slice(0, 7)}\`; updated ${date.toISOString().slice(0, 16).replace('T', ' ')} UTC.`; + const hasQualityScope = qualityReport?.files.length > 0; + const hasQuality = + hasQualityScope && + (comparisonRows(qualityReport).length > 0 || + hasIncompleteCoverage(qualityReport) || + Boolean(qualityReport.dependencyNote)); + const hasMap = Boolean(impactReport && imageUrl); + if (qualityReport && !hasQuality && !hasMap) return ''; + const lines = ['**Automatically computed PR review signals (deterministic)**', '']; + let qualityIndex; + if (hasQuality) { + lines.push( + 'Complexity and branch coverage help focus review on functions and their tests; these signals are advisory.', + '', + qualitySection(qualityReport, headSha), + ); + qualityIndex = lines.length - 1; + } else { + lines.push( + qualityReport + ? hasQualityScope + ? `${plural(qualityReport.files.length, 'changed JS/TS file')} analyzed; no flagged functions, improvements or analysis warnings.` + : emptyQualityScope(impactReport) + : 'Quality report unavailable; this is not a clean result. See the report artifacts.', + ); + } + if (hasMap) lines.push('', '---', '', mapSection(impactReport, imageUrl, revision)); + else { + if (impactReport) lines.push('', 'Isobar map unavailable; see the report artifacts.'); + lines.push('', revision); + } + if (artifactUrl) lines.push('', `[Full report artifacts](${artifactUrl})`); + const render = () => `${lines.join('\n')}\n`; + const complete = render(); + if (complete.length <= maxLength) return complete; + if (hasQuality) { + // Re-render only complete rows. The fixed map, footer and disclosures are + // reserved in every candidate instead of cutting arbitrary Markdown. + let low = 0; + let high = comparisonRows(qualityReport).length; + let bounded; + while (low <= high) { + const maxRows = Math.floor((low + high) / 2); + lines[qualityIndex] = qualitySection(qualityReport, headSha, maxRows); + const candidate = render(); + if (candidate.length <= maxLength) { + bounded = candidate; + low = maxRows + 1; + } else high = maxRows - 1; + } + if (bounded) return bounded; + } + throw new Error('Review comment size budget cannot fit the map and metadata'); +} diff --git a/scripts/pr-impact/evidence.mjs b/scripts/pr-impact/evidence.mjs new file mode 100644 index 00000000..fa0aa234 --- /dev/null +++ b/scripts/pr-impact/evidence.mjs @@ -0,0 +1,211 @@ +// Static orientation evidence from Git data. No project code is executed. +const SOURCE = + /\.(py|[cm]?[jt]sx?|vue|svelte|go|rs|java|kt|kts|swift|rb|php|cs|fs|c|cc|cpp|cxx|h|hh|hpp|m|mm|scala|ex|exs|erl|clj|dart|lua|zig)$/; +const readable = (path) => + path.endsWith('.py') || (/\.[cm]?[jt]sx?$/.test(path) && !/\.d\.[cm]?ts$/.test(path)); +const production = (role) => ['source', 'runtime-input', 'infrastructure'].includes(role); + +function roleOf(path, isTest) { + if (isTest(path)) return 'test'; + if (path.startsWith('lambda/agentcore/prompts/')) return 'runtime-input'; + if (/^(docs|aidlc-docs)\//.test(path) || /\.(md|mdx|rst|adoc)$/i.test(path)) + return 'documentation'; + if ( + /^(terraform|scripts|\.github)\//.test(path) || + /(^|\/)(Dockerfile[^/]*|docker-compose[^/]*|compose[^/]*)$|\.(tf|tfvars|sh|ya?ml)$/.test(path) + ) + return 'infrastructure'; + if (SOURCE.test(path)) return 'source'; + if (/\.(json|toml|ini|conf|cfg|env|lock)$|(^|\/)(requirements[^/]*\.txt|Makefile)$/.test(path)) + return 'runtime-input'; + return 'unknown'; +} + +function annotationOf(change, rows) { + const matched = rows.filter( + (row) => row.of === change.path && row.evidence === 'name-match' && !row.isChanged, + ).length; + const imports = rows.filter( + (row) => row.of === change.path && row.evidence === 'import-fallback' && !row.isChanged, + ).length; + const reach = matched + ? `${matched} static name-match target${matched === 1 ? '' : 's'}` + : imports + ? `${imports} file-level import-link target${imports === 1 ? '' : 's'}` + : change.reachStatus === 'unavailable' + ? 'static reach unavailable' + : 'no static reach detected'; + return { + path: change.path, + leafId: change.leafId, + title: change.path.split('/').at(-1), + detail: `${change.status} file ยท ${reach}`, + kind: change.kind, + role: change.role, + }; +} + +export function evidenceOf({ + frame, + facts, + changes, + read, + graph, + baseGraph, + reachOf, + isTest, + anchors, + revision, + mapDigest, +}) { + const changed = new Set(changes.map(({ path }) => path)); + const eligible = changes.filter( + (c) => !c.isNew && !c.isDeleted && readable(c.path) && (facts.lines.get(c.path) ?? 0) <= 20_000, + ); + const selected = new Set(eligible.slice(0, 40).map(({ path }) => path)); + const reachByCause = []; + const result = changes.map((change) => { + const { path } = change; + const shape = read?.shapes?.get(path); + const kind = shape?.kind ?? 'file'; + const role = roleOf(path, isTest); + const semantic = kind !== 'comments' && kind !== 'imports'; + const status = change.isDeleted ? 'deleted' : change.isNew ? 'added' : 'modified'; + let fallbackReason = null; + if (production(role) && kind === 'file') { + fallbackReason = + read?.fallbacks?.get(path) ?? + (change.isDeleted + ? baseGraph + ? 'deleted-file-base-import-fallback' + : 'deleted-head-graph-unavailable' + : change.isNew + ? 'new-file' + : !readable(path) + ? 'unsupported-language' + : (facts.lines.get(path) ?? 0) > 20_000 + ? 'head-line-limit' + : !selected.has(path) + ? 'declaration-file-limit' + : read?.added?.has(path) + ? 'module-level-or-unparsed' + : 'declaration-read-unavailable'); + } + const sourceGraph = change.isDeleted ? baseGraph : graph; + const rows = + !production(role) || !semantic + ? [] + : kind === 'file' + ? sourceGraph + ? reachOf(sourceGraph, [path], 3).map((row) => ({ ...row, of: path, uses: null })) + : [] + : (read?.users ?? []).filter(({ of }) => of === path); + const ownRows = rows.map((row) => ({ + of: path, + path: row.path, + via: row.via, + hop: row.hop, + uses: row.uses ?? null, + evidence: + row.uses == null ? 'import-fallback' : row.uses > 0 ? 'name-match' : 'transit-import', + isChanged: changed.has(row.path), + targetRole: roleOf(row.path, isTest), + })); + reachByCause.push(...ownRows); + const uncertain = + production(role) && + semantic && + (fallbackReason === 'deleted-head-graph-unavailable' || + (kind === 'file' && rows.length === 0 && (role !== 'source' || !readable(path)))); + const { section, leaf } = frame.assign(path); + return { + id: path, + path, + role, + kind, + status, + added: change.added, + deleted: change.deleted, + sectionId: section.id, + leafId: leaf.id, + anchor: anchors?.get(path) ?? null, + touches: (shape?.touches ?? []).map(({ name, owner, kind: touchKind }) => ({ + name, + ...(owner === undefined ? {} : { owner }), + kind: touchKind, + })), + analysisMode: !production(role) + ? 'not-applicable' + : kind === 'file' + ? 'file-wide' + : 'declaration', + fallbackReason, + reachStatus: uncertain ? 'unavailable' : rows.length ? 'observed' : 'not-detected', + }; + }); + reachByCause.sort( + (a, b) => a.of.localeCompare(b.of) || a.hop - b.hop || a.path.localeCompare(b.path), + ); + const ranked = result.toSorted((a, b) => { + const named = (change) => + reachByCause.some( + (row) => row.of === change.path && row.evidence === 'name-match' && !row.isChanged, + ); + return ( + Number(production(b.role) && named(b)) - Number(production(a.role) && named(a)) || + Number(production(b.role)) - Number(production(a.role)) || + b.added + b.deleted - a.added - a.deleted || + a.path.localeCompare(b.path) + ); + }); + const chosen = ranked.slice(0, 1); + if (ranked.length > 1) + chosen.push(ranked.slice(1).find((c) => c.leafId !== chosen[0].leafId) ?? ranked[1]); + const reached = (predicate) => + new Set( + reachByCause + .filter((r) => !r.isChanged && r.evidence !== 'transit-import' && predicate(r.targetRole)) + .map((r) => r.path), + ).size; + return { + version: 1, + analysis: { + toolRevision: revision, + mapDigest, + comparison: 'merge-base-to-head', + declarationLimits: { files: 40, headLines: 20_000, words: 60 }, + declarationSelection: { + eligibleFiles: eligible.length, + selectedFiles: selected.size, + omittedFiles: Math.max(0, eligible.length - selected.size), + }, + reachLimits: { fileFallbackHops: 3, symbolHops: 64 }, + limitations: [ + 'Static import-linked name matches do not prove execution or API visibility.', + 'Import fallback is file-wide, not declaration-level impact.', + 'Infrastructure and runtime inputs can affect consumers absent from static imports.', + 'File-wide shapes cannot distinguish all module-level edits from failed source reads.', + 'Known lexical ambiguity falls back to file-wide imports, without named declaration claims.', + "Paths outside the fixed map use Other files; paths without a child match use their section's fallback; new paths use deterministic fallback positions.", + ], + }, + changes: result, + reachByCause, + summary: { + productionChanges: result.filter(({ role }) => production(role)).length, + testChanges: result.filter(({ role }) => role === 'test').length, + documentationChanges: result.filter(({ role }) => role === 'documentation').length, + nameMatchTargets: reachByCause.filter(({ evidence }) => evidence === 'name-match').length, + importFallbackTargets: reachByCause.filter(({ evidence }) => evidence === 'import-fallback') + .length, + transitTargets: reachByCause.filter(({ evidence }) => evidence === 'transit-import').length, + productionReachFiles: reached(production), + testReachFiles: reached((role) => role === 'test'), + unavailableReachFiles: result.filter((c) => c.reachStatus === 'unavailable').length, + }, + annotations: chosen.map((change, index) => ({ + key: index === 0 ? 'A' : 'B', + ...annotationOf(change, reachByCause), + })), + }; +} diff --git a/scripts/pr-impact/frame.mjs b/scripts/pr-impact/frame.mjs new file mode 100644 index 00000000..07a5791d --- /dev/null +++ b/scripts/pr-impact/frame.mjs @@ -0,0 +1,282 @@ +import { pixelAnchor } from './anchors.mjs'; + +const ID = /^[a-z][a-z0-9-]{0,63}$/; +const text = (value, max) => + typeof value === 'string' && value.length > 0 && value.length <= max && !/[\p{C}]/u.test(value); + +function check(condition, message) { + if (!condition) throw new Error(`Invalid fixed map: ${message}`); +} + +function rules(paths) { + check(Array.isArray(paths), 'path rules must be an array'); + for (const path of paths) { + check(text(path, 300) && !path.startsWith('/') && !path.includes('..'), 'relative path rule'); + check(!path.slice(0, -1).includes('*'), 'only a trailing prefix wildcard is supported'); + } + return paths; +} + +function match(path, rule) { + if (rule.endsWith('*')) return path.startsWith(rule.slice(0, -1)); + return path === rule || (rule.endsWith('/') && path.startsWith(rule)); +} + +function bestMatch(path, entries) { + return entries + .flatMap((entry) => entry.paths.map((rule) => ({ entry, rule }))) + .filter(({ rule }) => match(path, rule)) + .toSorted((a, b) => b.rule.replace(/\*$/, '').length - a.rule.replace(/\*$/, '').length)[0] + ?.entry; +} + +// This authored hierarchy owns classification. Imports never retarget a file's +// box, and Isobar's 21-region sanitation limit never truncates the finer frame. +export function loadFrame(source) { + check(source?.version === 1, 'version'); + check( + Array.isArray(source.layers) && source.layers.length > 0 && source.layers.length <= 6, + 'bands', + ); + check( + Array.isArray(source.regions) && source.regions.length > 0 && source.regions.length <= 20, + 'sections', + ); + const used = new Set(); + const layers = source.layers.map((layer) => { + check(ID.test(layer.id) && !used.has(layer.id), 'unique band ID'); + used.add(layer.id); + check(text(layer.name, 48), 'band name'); + check(text(layer.blurb, 80), 'band description'); + check( + Number.isInteger(layer.height) && layer.height >= 240 && layer.height <= 800, + 'band height', + ); + return { ...layer }; + }); + const layerIds = new Set(layers.map(({ id }) => id)); + const sections = source.regions.map((section) => { + check(ID.test(section.id) && !used.has(section.id), 'unique section ID'); + used.add(section.id); + check(text(section.name, 24) && text(section.blurb, 48), 'section name and description'); + check(layerIds.has(section.layer), 'section band'); + check( + Number.isInteger(section.width) && section.width >= 350 && section.width <= 1200, + 'section width', + ); + check( + Number.isInteger(section.columns) && section.columns >= 1 && section.columns <= 3, + 'child columns', + ); + check( + Array.isArray(section.children) && + section.children.length >= 1 && + section.children.length <= 8, + 'children', + ); + const children = section.children.map((child) => { + check(ID.test(child.id), 'child ID'); + const id = `${section.id}-${child.id}`; + check(!used.has(id), 'unique child ID'); + used.add(id); + check(text(child.name, 24) && text(child.blurb, 48), 'child name and description'); + check(child.fallback === undefined || typeof child.fallback === 'boolean', 'fallback marker'); + return { + ...child, + id, + sectionId: section.id, + layer: section.layer, + paths: rules(child.paths), + }; + }); + check( + children.filter(({ fallback }) => fallback === true).length === 1, + 'one fallback child per section', + ); + return { ...section, paths: rules(section.paths), children }; + }); + check( + sections.every((section) => layers.some(({ id }) => id === section.layer)), + 'section membership', + ); + check( + layers.every((layer) => sections.some(({ layer: id }) => id === layer.id)), + 'nonempty bands', + ); + const leaves = sections.flatMap(({ children }) => children); + check(leaves.length <= 80, 'at most 80 children'); + const fallbackSection = sections.find(({ id }) => id === source.fallbackSection); + check(fallbackSection, 'fallback section'); + const assign = (path) => { + const section = bestMatch(path, sections) ?? fallbackSection; + const leaf = + bestMatch(path, section.children) ?? section.children.find(({ fallback }) => fallback); + return { section, leaf }; + }; + return { layers, sections, leaves, assign }; +} + +// A continuous atlas: every leaf tiles its parent, and every parent tiles its +// band. Titles overlay the geography; no header rows, padding or card gutters. +export function frameLayout(frame) { + const width = 2400; + const margin = 12; + const panels = []; + let y = 52; + for (const layer of frame.layers) { + const sections = frame.sections.filter((section) => section.layer === layer.id); + const available = width - 2 * margin; + const total = sections.reduce((sum, section) => sum + section.width, 0); + let x = margin; + for (const [index, section] of sections.entries()) { + const w = + index === sections.length - 1 + ? width - margin - x + : Math.round((section.width / total) * available); + const rect = { x, y, w, h: layer.height }; + const inside = { ...rect }; + const rows = Math.ceil(section.children.length / section.columns); + const rowHeight = Math.floor(inside.h / rows); + const children = []; + for (let row = 0; row < rows; row++) { + const items = section.children.slice(row * section.columns, (row + 1) * section.columns); + const cellWidth = Math.floor(inside.w / items.length); + for (const [column, leaf] of items.entries()) { + const cx = inside.x + column * cellWidth; + children.push({ + ...leaf, + rect: { + x: cx, + y: inside.y + row * rowHeight, + w: column === items.length - 1 ? inside.x + inside.w - cx : cellWidth, + h: row === rows - 1 ? inside.y + inside.h - (inside.y + row * rowHeight) : rowHeight, + }, + }); + } + } + panels.push({ ...section, rect, children }); + x += w; + } + y += layer.height; + } + return { + width, + height: y + 52, + panels, + mapRect: { x: margin, y: 52, w: width - 2 * margin, h: y - 52 }, + }; +} + +export async function nestedPicture({ frame, weather, fieldOf, inks, anchors, evidence }) { + const layout = frameLayout(frame); + // Blob radius and final pixel grain are independent: larger visible hotspots, + // still sampled to fine 4 px cells by the PNG renderer. + const sample = 7; + for (const panel of layout.panels) { + for (const leaf of panel.children) { + const cells = weather.cells.filter(({ region: owner }) => owner === leaf.id); + const reach = evidence.reachByCause.filter( + (r) => + frame.assign(r.path).leaf.id === leaf.id && + !r.isChanged && + r.evidence !== 'transit-import', + ); + // The ownership rectangle is all field. Thin boundaries and glyph halos + // are drawn afterward; they never become padded miniature pictures. + leaf.body = { ...leaf.rect }; + check(leaf.body.h >= 24, `label space for ${leaf.name}`); + if (!cells.length && !reach.length) continue; + const cols = Math.floor(leaf.body.w / sample); + const rows = Math.max(2, Math.floor(leaf.body.h / (2 * sample))); + const local = { + cols, + rows, + cells: [], + points: new Map( + cells.map(({ path }) => { + const p = anchors.get(path); + return [path, { x: p.x * cols, y: p.y * rows * 2 }]; + }), + ), + }; + const w = local.cols, + h = local.rows * 2; + const level = new Uint8Array(w * h), + wet = new Uint8Array(w * h); + for (const cell of cells) { + const change = evidence.changes.find(({ path }) => path === cell.path); + const production = ['source', 'runtime-input', 'infrastructure'].includes(change.role); + const shape = fieldOf( + local, + { + ...weather, + // The upstream drawing primitive uses a field named "risk". + // A constant makes this solely a change-location marker. + cells: [{ ...cell, risk: production ? 0.5 : 0.15, isLatest: true }], + reach: [], + arms: [], + offshoots: [], + expected: [], + }, + { code: false, impact: false, risk: true, history: false }, + `Collaborative AI-DLC:${cell.path}`, + ); + const shapePeak = Math.max(1, ...shape.level); + // Deemphasize test/docs markers without assigning a risk grade. + const peak = production ? 11 : 4; + for (let i = 0; i < level.length; i++) { + level[i] = Math.max(level[i], Math.round((shape.level[i] / shapePeak) * peak)); + } + } + // Render fallback as dotted rain; never turn unknown uses into a match. + // Deduplicate only for painting. All causes stay intact in the report. + const painted = new Map(); + for (const row of reach) { + const prior = painted.get(row.path); + if (!prior || row.evidence === 'name-match') painted.set(row.path, row); + } + for (const row of painted.values()) { + const p = anchors.get(row.path); + const cx = p.x * w, + cy = p.y * h; + const radius = row.evidence === 'name-match' ? 4 : 3; + for ( + let y = Math.max(0, Math.floor(cy - radius * 3)); + y < Math.min(h, cy + radius * 3); + y++ + ) { + for ( + let x = Math.max(0, Math.floor(cx - radius * 3)); + x < Math.min(w, cx + radius * 3); + x++ + ) { + if (row.evidence === 'import-fallback' && (x + y) % 3 !== 0) continue; + const v = Math.round( + (row.targetRole === 'test' ? 3 : 8) * + Math.exp(-((x - cx) ** 2 + (y - cy) ** 2) / (2 * radius ** 2)), + ); + const i = y * w + x; + if (v > level[i] && (level[i] === 0 || wet[i])) { + level[i] = v; + wet[i] = 1; + } + } + } + } + leaf.heat = { w, h, level: [...level], wet: [...wet] }; + leaf.markers = evidence.changes + .filter((c) => c.leafId === leaf.id) + .map((c) => ({ + path: c.path, + ...pixelAnchor(c.anchor, leaf.body), + status: c.status, + role: c.role, + key: evidence.annotations.find((a) => a.path === c.path)?.key, + })); + } + } + return { + ...layout, + palette: { paper: inks.paper, radar: inks.radar, rain: inks.rain }, + }; +} diff --git a/scripts/pr-impact/package-lock.json b/scripts/pr-impact/package-lock.json new file mode 100644 index 00000000..737173c4 --- /dev/null +++ b/scripts/pr-impact/package-lock.json @@ -0,0 +1,502 @@ +{ + "name": "collaborative-ai-dlc-pr-impact", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "collaborative-ai-dlc-pr-impact", + "dependencies": { + "tsx": "4.23.15" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.2.tgz", + "integrity": "sha512-XExcO+dvLKvVtNTibSTBej1NCAbaGhWn9Ww1ZPx80qsahhPFe/8jgWP0IchNe0F3HwkU7n8ejhH8bjonqht8mQ==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.2.tgz", + "integrity": "sha512-kXXoiPVVGQcnIYGOeaovwOURpniDBpSq4A03qkQ+BMQqtGG6HYap3xne9C1O1yo4TR3qxlCX5IqqmX6fFo2Lqg==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.2.tgz", + "integrity": "sha512-5YfKeeI8qWfBZIX+u2xZC3Zlb3Os/gLS2sbEKM+I4ZOcsWmHS2WLysCcQZDAFRslDUU5Oiq44gf6PYN1vGwG5A==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.2.tgz", + "integrity": "sha512-O387ite7SzUyCcy3JQX4P4bLtEA7bLLkx+esve5JHnyYfNTxcVpXZo9jhdB0lTKN44gztELTdU7nS8Nr16Fs1Q==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.2.tgz", + "integrity": "sha512-n4KqkOQrraxHJcgjM1RvwbigfQKIKJVpM7xp+KsxiyUSrRdIXnt73VhrPAx0fV44hgfmIVKjxMN9J1t5jySVkw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.2.tgz", + "integrity": "sha512-uq6suIWYP37qzGddBKPw5QEQPi6HiLGsO7UmkpfyaYNQ3D+rN6w6WfwH+nuqcGXWvawGwxOEroO4YGnFh95azw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.2.tgz", + "integrity": "sha512-n+I0BTSRIoy+d6RPKnEVwql5UwBJolytvY4mAOIEJorKlqgPII8ix6slVVrfZ5Tnj7glIZvloylbB/EJPMWEXw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.2.tgz", + "integrity": "sha512-78XJTJkvPs0kz2w61301PJjXl4g7q3JqiYMZ/M/yVI73EHBrCRTgkhu9oqG7vPqq+a/yadEW8aD+agKlk5xrmg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.2.tgz", + "integrity": "sha512-XlDnu2q5yoqems+xay6wSAcg9DDD7K9RLKZEBOMZm3ckNpJBvOX20tSfby8KfrrhINDyv9V2YVZKY/SpoGJI8w==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.2.tgz", + "integrity": "sha512-pW4AC0P3it8c7do9MVM4p51FzHzdM/TZrerurgRcHJ2WTa1VQ1CIq18xncfpBJw4ojkiZZrKW2yIBWBP92j6Ug==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.2.tgz", + "integrity": "sha512-CYbnj78HsIeA+DhgUKgFCfvNsTHFhMMrinUrMZpDXJXKN8T3XViTZ/+wtHeVxEWY8ewSzTFN+nRmSwO2tZaLUQ==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.2.tgz", + "integrity": "sha512-buwkd8nsph4R+ajRvw0qM5Hja/TXQow3ptzWO2EbG/cqcIkHloRrdlBtQlshyYGTNFvfkfJ5tpPLVkY4DtsPfQ==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.2.tgz", + "integrity": "sha512-ZVykbDyk7519VwiNb9Lcj9m8XM6v5V9uKPvrEMkkEedVewf+0itkhahp4HDpgERXhwLRpWFypsGbG/J8s0QjJA==", + "cpu": [ + "mips64el" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.2.tgz", + "integrity": "sha512-CAXl+Dtd9UUuJd8pKKdwh6MLm3MUMiqMPmhZ3tTSXPqfyQ3vDl6R5hZdZ/kYojK4ofXtdfSv1tFq8XzWx3heNQ==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.2.tgz", + "integrity": "sha512-GeXCej4IQtU1B+QlDV8W/RRvbzI3O/Stss+/bCXv4lZls5WGRtu2a+3JkA3i4qIUlMXpcHebWpF8AkJhATowuA==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.2.tgz", + "integrity": "sha512-3H1weTYZPxt/WOhByszQZybS9w5lKzUn1FDMsgEChbHWQwHYQQRfBxgCcZvPhjHfKyJjIievvMmEUawJrdY9Dg==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.2.tgz", + "integrity": "sha512-4xTZr1FUmSoQW4XIWmit3tzQrUTZM+N3P0XV8xROKYF50XfI7xeO90+1bZvNwxIufQ9hDQVRJH5YhgPVF8A/HQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.2.tgz", + "integrity": "sha512-sSATRjPeDBg3pdgHoQfoYBob11Kk1FGa9lui5RIHZCoCkJa9QKlvl3/vKz2usCmYYjs7ymJR/2Nnsqe+Hjt5nw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.2.tgz", + "integrity": "sha512-lqnzCV+mM0gIADaKihiCg6ifgfU2L3h5E33rNQBN1Y4MaVGnzryzmvvf7UHxprpQdE8hpqLolJ9Rl+SkIRDpyw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.2.tgz", + "integrity": "sha512-AL2qJILH7lNjrDmCQDvdxMfAUIv8KMNZOvrwAQ8i8//ntL9FflhOyMJ8OZSMBb8/AWXe3/5v5S20y3zCoZWKoQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.2.tgz", + "integrity": "sha512-QtiuPytchRyC4rwUKhexJdQKvDuZ6hWloi3igqPQNUJCS1/v9EiO3UTOXR6A3FoMo4fnAKbWJdqaIwhOzh8qEw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.2.tgz", + "integrity": "sha512-WkhYDmpTjLvGlScA1rwjRUmhl4k8oXR3cIbtqWmELgU/dFeHHlEllxDvdWcNJV9rbzCexB5vz8gtNewWLgCT7Q==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.2.tgz", + "integrity": "sha512-GPMSkTOtMnv2U2F8gxe4Io6qmVs+YKyp832Etqqxr0hFngmXQ3rzwytelm3GIn7T4VviRUlf3sOgBOiTdvaf7g==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.2.tgz", + "integrity": "sha512-PIhhEkE9uPBleRBrQEJpUn7MBnibZzbGzYWPmY3x+YoVg/95zbjB4CxPPOQ8l5tYYM4mMaCthF8/1DIfBQQyWQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.2.tgz", + "integrity": "sha512-YmJbfTlvU7Sdn9BB+4PRES4oB6pxgS37MAONj+hBr/cpXS1aBPKXxNnDbu+QCWPj0o9dgyxeq79g6c5P8KeuYA==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.2.tgz", + "integrity": "sha512-5ebpxr3nWMzrL/rnUI755Jkuee0bHL/Gq0WTF9lvcpv73wAp5eu8MfBUgWK9bhWvZjj7yX8etf/8tI8Ney695g==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/esbuild": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.2.tgz", + "integrity": "sha512-HKVLS8dvII+xoKW9kmqxbRKrnWEXfJJr/FZhhJmiqIB0e053QNYFqOBouTMO/k5sID4MvCiUCvv8b9M4h32wIA==", + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.28.2", + "@esbuild/android-arm": "0.28.2", + "@esbuild/android-arm64": "0.28.2", + "@esbuild/android-x64": "0.28.2", + "@esbuild/darwin-arm64": "0.28.2", + "@esbuild/darwin-x64": "0.28.2", + "@esbuild/freebsd-arm64": "0.28.2", + "@esbuild/freebsd-x64": "0.28.2", + "@esbuild/linux-arm": "0.28.2", + "@esbuild/linux-arm64": "0.28.2", + "@esbuild/linux-ia32": "0.28.2", + "@esbuild/linux-loong64": "0.28.2", + "@esbuild/linux-mips64el": "0.28.2", + "@esbuild/linux-ppc64": "0.28.2", + "@esbuild/linux-riscv64": "0.28.2", + "@esbuild/linux-s390x": "0.28.2", + "@esbuild/linux-x64": "0.28.2", + "@esbuild/netbsd-arm64": "0.28.2", + "@esbuild/netbsd-x64": "0.28.2", + "@esbuild/openbsd-arm64": "0.28.2", + "@esbuild/openbsd-x64": "0.28.2", + "@esbuild/openharmony-arm64": "0.28.2", + "@esbuild/sunos-x64": "0.28.2", + "@esbuild/win32-arm64": "0.28.2", + "@esbuild/win32-ia32": "0.28.2", + "@esbuild/win32-x64": "0.28.2" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/tsx": { + "version": "4.23.15", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.23.15.tgz", + "integrity": "sha512-Yiex1Ovn8z2xPpOWckIiysV1SSyRMY9BkLF++q0yKiDxCqRhosKfMg3janKkiLBwZ5c/YryloKwGZcrEmtwxKw==", + "license": "MIT", + "dependencies": { + "esbuild": "~0.28.0" + }, + "bin": { + "tsx": "dist/cli.mjs" + }, + "engines": { + "node": ">=18.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + } + } + } +} diff --git a/scripts/pr-impact/package.json b/scripts/pr-impact/package.json new file mode 100644 index 00000000..1d7494b5 --- /dev/null +++ b/scripts/pr-impact/package.json @@ -0,0 +1,9 @@ +{ + "name": "collaborative-ai-dlc-pr-impact", + "private": true, + "description": "Isolated tooling for deterministic PR impact images", + "type": "module", + "dependencies": { + "tsx": "4.23.15" + } +} diff --git a/scripts/pr-impact/publish.mjs b/scripts/pr-impact/publish.mjs new file mode 100644 index 00000000..79b42146 --- /dev/null +++ b/scripts/pr-impact/publish.mjs @@ -0,0 +1,834 @@ +import { lstat, readFile } from 'node:fs/promises'; +import { join } from 'node:path'; + +import { + commentMarker, + qualityArtifactNames, + validCoverage, + validateReport, +} from '../publish-complexity-comment.mjs'; +import { renderReviewComment } from './comment.mjs'; + +export const COMMENT_MARKER = commentMarker; +const ASSET_BRANCH = 'pr-impact-assets'; +const TOOL_REVISION = '2ec719904ac7dc30de08e152e4622fe8e02fa57a'; +const SHA = /^[0-9a-f]{40}$/i; +const PNG_SIGNATURE = Buffer.from([137, 80, 78, 71, 13, 10, 26, 10]); +const BOT_LOGIN = 'github-actions[bot]'; + +function requireValue(condition, message) { + if (!condition) throw new Error(`Invalid PR impact artifact: ${message}`); +} + +function isSha(value) { + return typeof value === 'string' && SHA.test(value); +} + +function isCount(value) { + return Number.isSafeInteger(value) && value >= 0 && value <= 10_000_000; +} + +function isText(value, length) { + return ( + typeof value === 'string' && + value.length > 0 && + value.length <= length && + !Array.from(value).some((character) => { + const code = character.charCodeAt(0); + return code < 32 || code === 127; + }) + ); +} + +export function validateReportArtifacts(reportBytes, pngBytes) { + requireValue(Buffer.isBuffer(reportBytes) && reportBytes.length <= 1_000_000, 'report size'); + requireValue(Buffer.isBuffer(pngBytes) && pngBytes.length <= 5_000_000, 'PNG size'); + requireValue( + pngBytes.length >= 24 && pngBytes.subarray(0, 8).equals(PNG_SIGNATURE), + 'PNG signature', + ); + requireValue( + pngBytes.readUInt32BE(8) === 13 && pngBytes.toString('ascii', 12, 16) === 'IHDR', + 'PNG header', + ); + const width = pngBytes.readUInt32BE(16); + const height = pngBytes.readUInt32BE(20); + requireValue(width > 0 && width <= 8192 && height > 0 && height <= 8192, 'PNG dimensions'); + return validateImpactReport(reportBytes); +} + +export function validateImpactReport(reportBytes) { + requireValue(Buffer.isBuffer(reportBytes) && reportBytes.length <= 1_000_000, 'report size'); + let report; + try { + report = JSON.parse(reportBytes.toString('utf8')); + } catch { + throw new Error('Invalid PR impact artifact: report JSON'); + } + requireValue(report && typeof report === 'object' && !Array.isArray(report), 'report shape'); + requireValue(report.schemaVersion === 1, 'schema version'); + requireValue( + typeof report.repository === 'string' && + /^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/.test(report.repository), + 'repository', + ); + requireValue(Number.isSafeInteger(report.prNumber) && report.prNumber > 0, 'PR number'); + for (const key of ['headSha', 'baseSha', 'mergeBaseSha']) { + requireValue(isSha(report[key]), key); + } + requireValue( + typeof report.generatedAt === 'string' && + /^\d{4}-\d\d-\d\dT\d\d:\d\d:\d\d(?:\.\d{1,3})?Z$/.test(report.generatedAt) && + !Number.isNaN(Date.parse(report.generatedAt)), + 'timestamp', + ); + const summary = report.summary; + requireValue(summary && typeof summary === 'object' && !Array.isArray(summary), 'summary'); + for (const key of ['files', 'added', 'deleted', 'testFiles']) { + requireValue(isCount(summary[key]), `summary ${key}`); + } + requireValue(summary.testFiles <= summary.files, 'test file count'); + requireValue( + report.tool?.name === 'isobar' && report.tool.revision === TOOL_REVISION, + 'tool revision', + ); + { + const e = report.evidence; + requireValue( + e?.version === 1 && e.analysis?.toolRevision === TOOL_REVISION, + 'evidence version', + ); + requireValue(/^[a-f0-9]{64}$/.test(e.analysis.mapDigest), 'map digest'); + requireValue( + Array.isArray(e.changes) && e.changes.length === summary.files, + 'evidence changes', + ); + const selection = e.analysis.declarationSelection; + requireValue(selection && typeof selection === 'object', 'declaration selection'); + for (const key of ['eligibleFiles', 'selectedFiles', 'omittedFiles']) { + requireValue( + isCount(selection[key]) && selection[key] <= summary.files, + `declaration selection ${key}`, + ); + } + requireValue( + selection.selectedFiles <= 40 && + selection.omittedFiles === selection.eligibleFiles - selection.selectedFiles, + 'declaration selection counts', + ); + requireValue(Array.isArray(e.annotations) && e.annotations.length <= 2, 'annotations'); + const paths = new Set(e.changes.map((c) => c.path)); + requireValue(paths.size === e.changes.length, 'unique changed paths'); + const keys = new Set(); + const annotationPaths = new Set(); + for (const a of e.annotations) { + requireValue( + ['A', 'B'].includes(a.key) && + !keys.has(a.key) && + !annotationPaths.has(a.path) && + paths.has(a.path) && + e.changes.find((c) => c.path === a.path).leafId === a.leafId && + isText(a.path, 500) && + isText(a.detail, 700), + 'annotation', + ); + keys.add(a.key); + annotationPaths.add(a.path); + } + requireValue(e.summary && typeof e.summary === 'object', 'evidence summary'); + for (const key of [ + 'productionChanges', + 'testChanges', + 'documentationChanges', + 'nameMatchTargets', + 'importFallbackTargets', + 'transitTargets', + 'productionReachFiles', + 'testReachFiles', + 'unavailableReachFiles', + ]) { + requireValue(isCount(e.summary[key]), `evidence ${key}`); + } + for (const c of e.changes) { + requireValue(isText(c.path, 500) && isText(c.leafId, 80), 'changed file ownership'); + requireValue( + ['source', 'runtime-input', 'infrastructure', 'test', 'documentation', 'unknown'].includes( + c.role, + ), + 'changed file role', + ); + } + } + return report; +} + +const QUALITY_LIMIT = 20 * 1024 * 1024; +const metadataPattern = //; +const botOwned = (comment) => + comment?.user?.login === BOT_LOGIN && + comment.user.type === 'Bot' && + comment.body?.startsWith(COMMENT_MARKER); +const validSourceRun = (run) => + run && + Number.isSafeInteger(run.id) && + run.id > 0 && + Number.isSafeInteger(run.attempt) && + run.attempt > 0; +const newerSourceRun = (previous, next) => + previous && + (!next || previous.id > next.id || (previous.id === next.id && previous.attempt > next.attempt)); + +export function validateQualitySnapshot(report) { + validateReport(report); + for (const file of report.files) { + requireValue( + file && typeof file.path === 'string' && file.path.length <= 10000, + 'quality file', + ); + for (const functions of [file.before, file.after]) { + if (functions === undefined) continue; + requireValue(Array.isArray(functions) && functions.length <= 100000, 'quality functions'); + for (const fn of functions) { + requireValue(fn && typeof fn === 'object', 'quality function'); + if (fn.coverage !== undefined) requireValue(validCoverage(fn.coverage), 'file coverage'); + } + } + } + return report; +} + +export function reviewMetadata(comment) { + if (!botOwned(comment)) return null; + const encoded = comment.body.match(metadataPattern)?.[1]; + if (!encoded) return null; + try { + const metadata = JSON.parse(Buffer.from(encoded, 'base64url').toString('utf8')); + if ( + metadata.schemaVersion !== 1 || + ![metadata.assetSha, metadata.headSha, metadata.mergeBaseSha].every(isSha) || + !Number.isSafeInteger(metadata.prNumber) || + metadata.prNumber < 1 || + !isText(metadata.baseRef, 255) || + [metadata.qualityRun, metadata.staticRun].some( + (run) => run !== undefined && !validSourceRun(run), + ) + ) + return null; + return metadata; + } catch { + return null; + } +} + +async function readJsonFile(directory, filename, limit) { + if (filename.includes('/')) { + const parent = await lstat(join(directory, filename.slice(0, filename.lastIndexOf('/')))); + requireValue(parent.isDirectory(), `${filename} directory`); + } + const path = join(directory, filename); + const info = await lstat(path); + requireValue(info.isFile() && info.size <= limit, `${filename} file`); + const bytes = await readFile(path); + requireValue(bytes.length <= limit, `${filename} size`); + return JSON.parse(bytes.toString('utf8')); +} + +async function readPng(directory) { + const parent = await lstat(join(directory, 'impact')); + requireValue(parent.isDirectory(), 'impact directory'); + const path = join(directory, 'impact/map.png'); + const info = await lstat(path); + requireValue(info.isFile() && info.size <= 5_000_000, 'map.png file'); + const bytes = await readFile(path); + requireValue(bytes.length <= 5_000_000, 'map.png size'); + return bytes; +} + +function identity(context) { + const { owner, repo } = context.repo; + const repository = `${owner}/${repo}`; + requireValue( + /^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/.test(repository) && + context.payload.repository?.full_name === repository, + 'event repository', + ); + return { owner, repo, repository }; +} + +// The publisher recovers JSON from a legacy bot report under the shared lock. +// Comment Markdown never supplies measurements or a publication destination. +export async function legacyQualityArtifact({ github, context }) { + if (context.eventName !== 'pull_request_target') return null; + try { + const repo = identity(context); + const pr = context.payload.pull_request; + if (!Number.isSafeInteger(pr?.number) || pr.number < 1 || !isSha(pr.head?.sha)) return null; + const comments = await github.paginate(github.rest.issues.listComments, { + owner: repo.owner, + repo: repo.repo, + issue_number: pr.number, + per_page: 100, + }); + const existing = comments.find( + (comment) => botOwned(comment) && !comment.body.includes('/); + if (!stamp) return null; + const runId = Number(stamp[1]); + const commentAttempt = Number(stamp[2]); + if (![runId, commentAttempt].every((value) => Number.isSafeInteger(value) && value > 0)) + return null; + const { data: run } = await github.rest.actions.getWorkflowRun({ + owner: repo.owner, + repo: repo.repo, + run_id: runId, + }); + if ( + run.id !== runId || + run.event !== 'pull_request' || + run.name !== 'PR Quality' || + !/^\.github\/workflows\/pr-quality\.yml(?:@.+)?$/.test(run.path) || + run.repository?.id !== context.payload.repository.id || + run.head_sha !== pr.head.sha || + run.head_repository?.id !== pr.head.repo?.id || + run.status !== 'completed' || + !Number.isSafeInteger(run.run_attempt) || + run.run_attempt < commentAttempt + ) + return null; + const names = await qualityArtifactNames({ + github, + repo: { owner: repo.owner, repo: repo.repo }, + runId, + attempt: run.run_attempt, + }); + const selectedAttempt = Number(/^pr-quality-(\d+)$/.exec(names.report)?.[1]); + if (!Number.isSafeInteger(selectedAttempt) || selectedAttempt < 1) return null; + const jobs = await github.paginate(github.rest.actions.listJobsForWorkflowRun, { + owner: repo.owner, + repo: repo.repo, + run_id: runId, + filter: 'all', + per_page: 100, + }); + const producer = jobs.find( + (job) => job.name === 'report' && job.run_attempt === selectedAttempt, + ); + if (producer?.conclusion !== 'success') return null; + const artifacts = await github.paginate(github.rest.actions.listWorkflowRunArtifacts, { + owner: repo.owner, + repo: repo.repo, + run_id: runId, + per_page: 100, + }); + if (!artifacts.some((artifact) => artifact.name === names.report && artifact.expired === false)) + return null; + return { + runId, + artifactName: names.report, + qualityRun: { id: runId, attempt: selectedAttempt }, + }; + } catch { + return null; + } +} + +function validateProducer({ context, metadata, attempt, repo }) { + requireValue(context.eventName === 'pull_request_target', 'publisher event'); + requireValue( + metadata.schemaVersion === 1 && + metadata.repository === repo.repository && + Number.isSafeInteger(metadata.prNumber) && + metadata.prNumber > 0 && + [metadata.headSha, metadata.baseSha, metadata.mergeBaseSha, metadata.controllerSha].every( + isSha, + ) && + isText(metadata.baseRef, 255) && + Number.isSafeInteger(metadata.runId) && + metadata.runId > 0 && + Number.isSafeInteger(metadata.runAttempt) && + metadata.runAttempt > 0 && + Number.isSafeInteger(metadata.headRepositoryId) && + metadata.headRepositoryId > 0, + 'producer context', + ); + const pr = context.payload.pull_request; + requireValue( + pr?.number === metadata.prNumber && + pr.head.sha === metadata.headSha && + pr.head.repo?.id === metadata.headRepositoryId && + pr.base.sha === metadata.baseSha && + pr.base.ref === metadata.baseRef && + context.sha === metadata.controllerSha && + context.runId === metadata.runId && + attempt === metadata.runAttempt, + 'trusted PR event binding', + ); +} + +async function currentPr(github, repo, expected) { + const { data: pr } = await github.rest.pulls.get({ + owner: repo.owner, + repo: repo.repo, + pull_number: expected.prNumber, + }); + if ( + pr.state !== 'open' || + pr.head.sha !== expected.headSha || + (expected.headRepositoryId !== undefined && pr.head.repo?.id !== expected.headRepositoryId) || + pr.base.ref !== expected.baseRef || + pr.base.repo?.full_name !== repo.repository + ) + return null; + const { data: comparison } = await github.rest.repos.compareCommitsWithBasehead({ + owner: repo.owner, + repo: repo.repo, + basehead: `${pr.base.ref}...${pr.head.sha}`, + per_page: 1, + }); + return comparison.merge_base_commit?.sha === expected.mergeBaseSha ? pr : null; +} + +async function savedJson(github, repo, metadata, filename, limit) { + const { data } = await github.rest.repos.getContent({ + owner: repo.owner, + repo: repo.repo, + path: `pr-${metadata.prNumber}/${filename}`, + ref: metadata.assetSha, + }); + requireValue( + data?.type === 'file' && Number.isSafeInteger(data.size) && data.size <= limit, + 'saved file', + ); + let content = data; + if (data.encoding !== 'base64') { + requireValue(isSha(data.sha), 'saved blob'); + ({ data: content } = await github.rest.git.getBlob({ + owner: repo.owner, + repo: repo.repo, + file_sha: data.sha, + })); + } + requireValue( + content.encoding === 'base64' && + typeof content.content === 'string' && + content.content.length <= Math.ceil(limit / 3) * 4 + Math.ceil(limit / 50), + 'saved content', + ); + const bytes = Buffer.from(content.content, 'base64'); + requireValue(bytes.length <= limit, 'saved content size'); + return JSON.parse(bytes.toString('utf8')); +} + +export async function loadReviewSnapshot({ + github, + context, + existing, + expected, + warn = console.warn, +}) { + const metadata = reviewMetadata(existing); + if ( + !metadata || + metadata.prNumber !== expected.prNumber || + metadata.headSha !== expected.headSha || + metadata.baseRef !== expected.baseRef || + metadata.mergeBaseSha !== expected.mergeBaseSha + ) + return null; + try { + const repo = identity(context); + const impact = validateImpactReport( + Buffer.from( + JSON.stringify(await savedJson(github, repo, metadata, 'impact.json', 1_000_000)), + ), + ); + requireValue( + impact.repository === repo.repository && + impact.prNumber === expected.prNumber && + impact.headSha === expected.headSha && + impact.mergeBaseSha === expected.mergeBaseSha, + 'saved impact revision', + ); + const quality = await savedJson(github, repo, metadata, 'quality.json', QUALITY_LIMIT); + const { data: map } = await github.rest.repos.getContent({ + owner: repo.owner, + repo: repo.repo, + path: `pr-${metadata.prNumber}/map.png`, + ref: metadata.assetSha, + }); + requireValue( + map?.type === 'file' && + isSha(map.sha) && + Number.isSafeInteger(map.size) && + map.size <= 5_000_000, + 'saved map', + ); + if (quality !== null) { + validateQualitySnapshot(quality); + requireValue( + quality.pr === expected.headSha && + quality.mergeBase === expected.mergeBaseSha && + quality.baseRef === expected.baseRef, + 'saved quality revision', + ); + } + return { metadata, impact, quality, mapSha: map.sha }; + } catch (error) { + warn(`Saved review data unavailable: ${error.message}`); + return null; + } +} + +export function coverageMeasurements(report) { + if (!report) return 0; + const functions = report.files.flatMap((file) => [...(file.before ?? []), ...(file.after ?? [])]); + const values = functions.length + ? functions.map((fn) => fn.coverage) + : [...report.findings, ...report.improvements].flatMap((row) => [ + row.coverage.before, + row.coverage.after, + ]); + return values.reduce( + (total, value) => total + (value?.status === 'measured' ? (value.partial ? 1 : 2) : 0), + 0, + ); +} + +async function storeAssets({ github, repo, prNumber, impact, quality, png, mapSha }) { + const payloads = [ + ['impact.json', Buffer.from(JSON.stringify(impact))], + ['quality.json', Buffer.from(JSON.stringify(quality))], + ]; + if (png) payloads.push(['map.png', png]); + const treeEntries = []; + if (!png) { + requireValue(isSha(mapSha), 'saved map blob'); + treeEntries.push({ path: `pr-${prNumber}/map.png`, mode: '100644', type: 'blob', sha: mapSha }); + } + for (const [filename, bytes] of payloads) { + requireValue( + bytes.length <= (filename === 'impact.json' ? 1_000_000 : QUALITY_LIMIT), + 'asset size', + ); + const { data: blob } = await github.rest.git.createBlob({ + owner: repo.owner, + repo: repo.repo, + encoding: 'base64', + content: bytes.toString('base64'), + }); + treeEntries.push({ + path: `pr-${prNumber}/${filename}`, + mode: '100644', + type: 'blob', + sha: blob.sha, + }); + } + for (let attempt = 0; attempt < 3; attempt++) { + let ref; + try { + ({ data: ref } = await github.rest.git.getRef({ + owner: repo.owner, + repo: repo.repo, + ref: `heads/${ASSET_BRANCH}`, + })); + } catch (error) { + if (error.status !== 404) throw error; + } + const parentSha = ref?.object?.sha; + const baseTree = parentSha + ? ( + await github.rest.git.getCommit({ + owner: repo.owner, + repo: repo.repo, + commit_sha: parentSha, + }) + ).data.tree.sha + : undefined; + const { data: tree } = await github.rest.git.createTree({ + owner: repo.owner, + repo: repo.repo, + ...(baseTree ? { base_tree: baseTree } : {}), + tree: treeEntries, + }); + const { data: commit } = await github.rest.git.createCommit({ + owner: repo.owner, + repo: repo.repo, + message: `chore(ci): update PR #${prNumber} review signals`, + tree: tree.sha, + parents: parentSha ? [parentSha] : [], + }); + try { + if (parentSha) { + await github.rest.git.updateRef({ + owner: repo.owner, + repo: repo.repo, + ref: `heads/${ASSET_BRANCH}`, + sha: commit.sha, + force: false, + }); + } else { + await github.rest.git.createRef({ + owner: repo.owner, + repo: repo.repo, + ref: `refs/heads/${ASSET_BRANCH}`, + sha: commit.sha, + }); + } + return commit.sha; + } catch (error) { + if (![409, 422].includes(error.status) || attempt === 2) throw error; + } + } + throw new Error('Unable to publish review assets'); +} + +function commentBody({ + context, + expected, + assetSha, + quality, + impact, + run, + qualityRun, + staticRun, + updatedAt, +}) { + const repo = identity(context); + const metadata = { + schemaVersion: 1, + assetSha, + headSha: expected.headSha, + mergeBaseSha: expected.mergeBaseSha, + baseRef: expected.baseRef, + prNumber: expected.prNumber, + ...(qualityRun ? { qualityRun } : {}), + ...(staticRun ? { staticRun } : {}), + }; + const content = renderReviewComment({ + qualityReport: quality, + impactReport: impact, + imageUrl: `https://raw.githubusercontent.com/${repo.repository}/${assetSha}/pr-${expected.prNumber}/map.png`, + headSha: expected.headSha, + updatedAt, + artifactUrl: `https://github.com/${repo.repository}/actions/runs/${run.id}`, + maxLength: 50000, + }); + requireValue(content.length <= 50000, 'comment size'); + return `${COMMENT_MARKER}\n\n\n${content}`; +} + +async function writeComment(github, repo, expected, existing, body) { + if (existing) { + await github.rest.issues.updateComment({ + owner: repo.owner, + repo: repo.repo, + comment_id: existing.id, + body, + }); + } else { + await github.rest.issues.createComment({ + owner: repo.owner, + repo: repo.repo, + issue_number: expected.prNumber, + body, + }); + } +} + +async function publishSnapshot({ + github, + context, + repo, + expected, + existing, + quality, + impact, + png, + mapSha, + run, + qualityRun, + staticRun, + now, +}) { + const updatedAt = now(); + const content = { context, expected, quality, impact, run, qualityRun, staticRun, updatedAt }; + commentBody({ ...content, assetSha: '0'.repeat(40) }); + if (!(await currentPr(github, repo, expected))) return { published: false, reason: 'stale PR' }; + const assetSha = await storeAssets({ + github, + repo, + prNumber: expected.prNumber, + impact, + quality, + png, + mapSha, + }); + if (!(await currentPr(github, repo, expected))) + return { published: false, reason: 'stale PR before comment write' }; + await writeComment(github, repo, expected, existing, commentBody({ ...content, assetSha })); + return { published: true, prNumber: expected.prNumber, assetSha }; +} + +export async function publishReviewSignals({ + github, + context, + reportDirectory, + attempt = Number(process.env.GITHUB_RUN_ATTEMPT), + warn = console.warn, + now = () => new Date().toISOString(), + loadLegacyQuality, +}) { + const repo = identity(context); + const expected = await readJsonFile(reportDirectory, 'context.json', 10000); + validateProducer({ context, metadata: expected, attempt, repo }); + let impact; + let quality; + let png; + try { + impact = await readJsonFile(reportDirectory, 'impact/report.json', 1_000_000); + png = await readPng(reportDirectory); + validateReportArtifacts(Buffer.from(JSON.stringify(impact)), png); + requireValue( + impact.evidence && + impact.repository === repo.repository && + impact.prNumber === expected.prNumber && + impact.headSha === expected.headSha && + impact.mergeBaseSha === expected.mergeBaseSha && + impact.baseSha === expected.baseSha, + 'impact context', + ); + quality = validateQualitySnapshot( + await readJsonFile(reportDirectory, 'quality/comparison.json', QUALITY_LIMIT), + ); + requireValue( + quality.pr === expected.headSha && + quality.mergeBase === expected.mergeBaseSha && + quality.baseRef === expected.baseRef, + 'quality context', + ); + } catch (error) { + warn(`Review report unavailable: ${error.message}`); + return { published: false, reason: 'report unavailable' }; + } + if (!(await currentPr(github, repo, expected))) return { published: false, reason: 'stale PR' }; + const comments = await github.paginate(github.rest.issues.listComments, { + owner: repo.owner, + repo: repo.repo, + issue_number: expected.prNumber, + per_page: 100, + }); + const existing = comments.find(botOwned); + const run = { id: expected.runId, run_attempt: expected.runAttempt }; + const staticRun = { id: run.id, attempt: run.run_attempt }; + const previousMetadata = reviewMetadata(existing); + if ( + previousMetadata?.headSha === expected.headSha && + previousMetadata.mergeBaseSha === expected.mergeBaseSha && + previousMetadata.baseRef === expected.baseRef && + newerSourceRun(previousMetadata.staticRun, staticRun) + ) + return { published: false, reason: 'older run' }; + const saved = await loadReviewSnapshot({ github, context, existing, expected, warn }); + let qualityRun = saved?.metadata.qualityRun; + if ( + saved && + (qualityRun || coverageMeasurements(saved.quality) > coverageMeasurements(quality)) + ) { + if (saved.quality || coverageMeasurements(quality) > 0) quality = saved.quality; + } + if (existing && !previousMetadata) { + const stamp = existing.body.match(//); + const legacyRun = stamp && { id: Number(stamp[1]), attempt: Number(stamp[2]) }; + if (validSourceRun(legacyRun)) { + const selected = await legacyQualityArtifact({ github, context }); + if (!selected || !loadLegacyQuality) + return { published: false, reason: 'newer legacy quality requires recovery' }; + try { + const recovered = validateQualitySnapshot(await loadLegacyQuality(selected)); + requireValue( + recovered.pr === expected.headSha && + recovered.mergeBase === expected.mergeBaseSha && + recovered.baseRef === expected.baseRef, + 'latest legacy quality context', + ); + quality = recovered; + qualityRun = selected.qualityRun; + } catch (error) { + warn(`Latest legacy quality unavailable: ${error.message}`); + return { published: false, reason: 'newer legacy quality requires recovery' }; + } + } + } + return publishSnapshot({ + github, + context, + repo, + expected, + existing, + quality, + impact, + png, + run, + qualityRun, + staticRun, + now, + }); +} + +export async function enrichReviewSignals({ + github, + context, + pr, + run, + report, + existing, + warn = console.warn, + now = () => new Date().toISOString(), +}) { + const metadata = reviewMetadata(existing); + if (!metadata) return false; + const repo = identity(context); + const expected = { + prNumber: pr.number, + headSha: pr.head.sha, + headRepositoryId: pr.head.repo.id, + baseRef: pr.base.ref, + mergeBaseSha: metadata.mergeBaseSha, + }; + if (!(await currentPr(github, repo, expected))) return false; + const saved = await loadReviewSnapshot({ github, context, existing, expected, warn }); + if (!saved) return false; + if (report) { + validateQualitySnapshot(report); + if ( + report.pr !== expected.headSha || + report.baseRef !== expected.baseRef || + report.mergeBase !== expected.mergeBaseSha + ) + return false; + } + const previousQualityRun = saved.metadata.qualityRun; + if ( + previousQualityRun && + (previousQualityRun.id > run.id || + (previousQualityRun.id === run.id && previousQualityRun.attempt > run.run_attempt)) + ) + return true; + const qualityRun = { id: run.id, attempt: run.run_attempt }; + await publishSnapshot({ + github, + context, + repo, + expected, + existing, + quality: report ?? null, + impact: saved.impact, + mapSha: saved.mapSha, + run, + qualityRun, + staticRun: saved.metadata.staticRun, + now, + }); + return true; +} diff --git a/scripts/pr-impact/reader-guard.mjs b/scripts/pr-impact/reader-guard.mjs new file mode 100644 index 00000000..88aef95c --- /dev/null +++ b/scripts/pr-impact/reader-guard.mjs @@ -0,0 +1,39 @@ +// Conservative adapter around known limitations in the pinned lexical reader. +// No contributor code is evaluated. Ambiguity loses precision, never review cues. +export function lexicalAmbiguity(lines = []) { + for (const line of lines) { + const comment = line.indexOf('//'); + if (comment >= 0 && line.slice(comment + 2).includes('/*')) return 'line-comment-block-token'; + for (const match of line.matchAll(/(["'])(?:\\.|(?!\1)[^\\])*?\1/g)) { + if (/(? !/^\s*(?:$|\/\/|\/\*|\*)/.test(line)) + ) { + reason = 'quiet-code-contradiction'; + } + if (!reason) continue; + fallbacks.set(path, `lexical-ambiguity:${reason}`); + read.shapes.set(path, { ...shape, kind: 'file', touches: [], words: [], members: [] }); + } + read.users = read.users.filter((row) => !fallbacks.has(row.of)); + read.fallbacks = fallbacks; + return read; +} diff --git a/scripts/pr-impact/render-frame.py b/scripts/pr-impact/render-frame.py new file mode 100644 index 00000000..a79dd4d6 --- /dev/null +++ b/scripts/pr-impact/render-frame.py @@ -0,0 +1,203 @@ +"""Draw one continuous Isobar atlas with a quiet hierarchical boundary mesh.""" + +import json +import math +import os +import sys +from PIL import Image, ImageDraw, ImageFont + + +def font(size): + path = os.environ.get( + "ISOBAR_FONT", "/usr/share/fonts/truetype/dejavu/DejaVuSansCondensed.ttf" + ) + try: + return ImageFont.truetype(path, size) + except OSError as error: + raise RuntimeError(f"Required Isobar condensed font is unavailable: {path}") from error + + +def rgb(value): + return tuple((value >> shift) & 255 for shift in (16, 8, 0)) + + +def render(source, destination): + data = json.load(open(source, encoding="utf-8")) + width, height = data["width"], data["height"] + paper = rgb(data["palette"]["paper"]) + canvas = Image.new("RGB", (width, height), paper) + draw = ImageDraw.Draw(canvas) + # The obstruction mask measures the actual union of opaque glyphs/halos + # and boundary strokes, rather than reporting reserved rectangle area. + blocked = Image.new("L", (width, height), 0) + mask = ImageDraw.Draw(blocked) + map_rect = data["mapRect"] + frame_box = ( + map_rect["x"], map_rect["y"], + map_rect["x"] + map_rect["w"], map_rect["y"] + map_rect["h"], + ) + for panel in data["panels"]: + for leaf in panel["children"]: + body = leaf["body"] + if "heat" not in leaf: + continue + heat = leaf["heat"] + image = Image.new("RGB", (heat["w"], heat["h"])) + image.putdata([ + rgb(data["palette"]["rain" if wet else "radar"][level]) + for level, wet in zip(heat["level"], heat["wet"]) + ]) + image = image.resize( + (math.ceil(body["w"] / 4), math.ceil(body["h"] / 4)), + Image.Resampling.NEAREST, + ) + canvas.paste( + image.resize((body["w"], body["h"]), Image.Resampling.NEAREST), + (body["x"], body["y"]), + ) + + def line(box, color, thickness): + draw.rectangle(box, outline=color, width=thickness) + mask.rectangle(box, outline=255, width=thickness) + + # One mesh, not nested cards: no fills, no insets, no reserved title strips. + for panel in data["panels"]: + for leaf in panel["children"]: + r = leaf["rect"] + line((r["x"], r["y"], r["x"] + r["w"], r["y"] + r["h"]), (223, 201, 178), 1) + for panel in data["panels"]: + r = panel["rect"] + line((r["x"], r["y"], r["x"] + r["w"], r["y"] + r["h"]), (185, 157, 129), 2) + line(frame_box, (163, 135, 107), 2) + + labels = [] + parent_face, leaf_face = font(35), font(31) + ink = (64, 43, 25) + + def text(value, x, y, face, box, kind): + if face.getlength(value) > box[2] - box[0] - 16: + raise ValueError(f"Architectural label is wider than its ownership box: {value}") + bbox = draw.textbbox((x, y), value, font=face, stroke_width=2) + if bbox[0] < box[0] or bbox[2] > box[2] or bbox[3] > box[3]: + raise ValueError(f"Architectural label crosses its ownership box: {value}") + draw.text((x, y), value, font=face, fill=ink, stroke_width=2, stroke_fill=paper) + mask.text((x, y), value, font=face, fill=255, stroke_width=2, stroke_fill=255) + labels.append({"text": value, "kind": kind, "bbox": list(bbox), "position": [x, y]}) + + for panel in data["panels"]: + p = panel["rect"] + box = (p["x"], p["y"], p["x"] + p["w"], p["y"] + p["h"]) + text(panel["name"], p["x"] + 8, p["y"] + 3, parent_face, box, "parent") + for leaf in panel["children"]: + r = leaf["rect"] + bounds = (r["x"], r["y"], r["x"] + r["w"], r["y"] + r["h"]) + # Only the label moves below its parent's title, never its heat. + ty = r["y"] + (43 if r["y"] == p["y"] else 5) + text(leaf["name"], r["x"] + 8, ty, leaf_face, bounds, "leaf") + + # Every changed path has a stable eye. The letters resolve to evidence in + # the same comment; shapes communicate status, colors communicate role. + for panel in data["panels"]: + for leaf in panel["children"]: + for mark in leaf.get("markers", []): + x, y = round(mark["x"]), round(mark["y"]) + color = (55, 91, 125) if mark["role"] == "test" else ( + (99, 99, 99) if mark["role"] == "documentation" else (83, 34, 29)) + radius = 8 + box = (x-radius, y-radius, x+radius, y+radius) + if mark["status"] == "added": + points = [(x,y-radius),(x+radius,y),(x,y+radius),(x-radius,y)] + draw.polygon(points, fill=paper, outline=color, width=3) + mask.polygon(points, fill=255) + elif mark["status"] == "deleted": + draw.line((x-radius,y-radius,x+radius,y+radius), fill=color, width=4) + draw.line((x-radius,y+radius,x+radius,y-radius), fill=color, width=4) + mask.rectangle(box, fill=255) + else: + draw.ellipse(box, fill=paper, outline=color, width=3) + mask.ellipse(box, fill=255) + occupied_badges = [] + for panel in data["panels"]: + for leaf in panel["children"]: + r = leaf["rect"] + for mark in leaf.get("markers", []): + if not mark.get("key"): + continue + x, y = round(mark["x"]), round(mark["y"]) + radius = 14 + candidates = [(x, y)] + for distance in (28, 42, 56, 70, 84): + candidates.extend((x+dx*distance, y+dy*distance) for dx,dy in + ((0,1),(1,0),(-1,0),(0,-1),(1,1),(-1,1),(1,-1),(-1,-1))) + def fits(point): + cx,cy = point + b = (cx-radius,cy-radius,cx+radius,cy+radius) + if b[0] < r["x"] or b[1] < r["y"] or b[2] > r["x"]+r["w"] or b[3] > r["y"]+r["h"]: + return False + return not any(min(b[2],q[2])+2 > max(b[0],q[0]) and + min(b[3],q[3])+2 > max(b[1],q[1]) + for q in [l["bbox"] for l in labels]+occupied_badges) + placed = next((point for point in candidates if fits(point)), None) + if placed is None: + raise ValueError(f"No legible annotation placement: {mark['path']}") + cx,cy = placed + color = (55,91,125) if mark["role"] == "test" else ( + (99,99,99) if mark["role"] == "documentation" else (83,34,29)) + if placed != (x,y): + draw.line((x,y,cx,cy), fill=color, width=2) + mask.line((x,y,cx,cy), fill=255, width=2) + box = (cx-radius,cy-radius,cx+radius,cy+radius) + occupied_badges.append(box) + mark["badge"] = {"x": cx, "y": cy, "bbox": list(box)} + draw.ellipse(box, fill=color) + mask.ellipse(box, fill=255) + draw.text((cx,cy), mark["key"], font=font(22), fill=paper, anchor="mm") + # Architecture remains readable even where a true file eye/leader crosses + # a glyph. Badges themselves are placed only on open ground. + for label in labels: + draw.text(tuple(label["position"]), label["text"], + font=parent_face if label["kind"] == "parent" else leaf_face, + fill=ink, stroke_width=2, stroke_fill=paper) + + draw.text((12, 9), "ISOBAR ยท COLLABORATIVE AI-DLC", font=font(29), fill=(101, 77, 55)) + caption = data["caption"] + caption_face = font(25) + draw.text((width - caption_face.getlength(caption) - 12, 12), caption, font=caption_face, fill=(112, 88, 67)) + footer = height - 47 + draw.rectangle((12, footer + 5, 31, footer + 24), fill=rgb(data["palette"]["radar"][11])) + draw.text((42, footer), "changed files ยท not a risk grade", font=font(26), fill=ink) + draw.rectangle((475, footer + 5, 494, footer + 24), fill=rgb(data["palette"]["rain"][8])) + draw.text((505, footer), "static reach: solid matched / dotted fallback", font=font(26), fill=ink) + draw.text((1190, footer), "โ—‹ modified โ—‡ new ร— deleted ยท blue test / gray docs ยท A/B: comment", font=font(25), fill=(112, 88, 67)) + + cropped = blocked.crop(frame_box) + blocked_pixels = sum(cropped.histogram()[1:]) + map_area = map_rect["w"] * map_rect["h"] + data["density"] = { + "mapArea": map_area, + "leafFieldArea": sum(l["body"]["w"] * l["body"]["h"] for p in data["panels"] for l in p["children"]), + "opaqueObstructionUnionArea": blocked_pixels, + "visibleHeatRatio": (map_area - blocked_pixels) / (width * height), + "visibleHeatWithinFrame": (map_area - blocked_pixels) / map_area, + "labelCount": len(labels), + "opaquePlateArea": 0, + } + if data["density"]["leafFieldArea"] != map_area: + raise ValueError("Leaf fields must cover the full atlas frame") + if data["density"]["visibleHeatRatio"] < 0.85 or data["density"]["visibleHeatWithinFrame"] < 0.90: + raise ValueError("Text or scaffolding obstructs too much of the atlas") + data["labels"] = labels + for index, a in enumerate(labels): + for b in labels[index + 1:]: + ax1, ay1, ax2, ay2 = a["bbox"] + bx1, by1, bx2, by2 = b["bbox"] + if min(ax2, bx2) > max(ax1, bx1) and min(ay2, by2) > max(ay1, by1): + raise ValueError(f"Architectural labels overlap: {a['text']} / {b['text']}") + with open(source, "w", encoding="utf-8") as output: + json.dump(data, output) + canvas.save(destination) + print(f"{destination} ({width} ร— {height}), visible map {(map_area-blocked_pixels)/map_area:.1%}") + + +if __name__ == "__main__": + render(sys.argv[1], sys.argv[2]) diff --git a/scripts/pr-impact/render.mjs b/scripts/pr-impact/render.mjs new file mode 100644 index 00000000..9eb9a5c0 --- /dev/null +++ b/scripts/pr-impact/render.mjs @@ -0,0 +1,323 @@ +import { execFile } from 'node:child_process'; +import { promisify } from 'node:util'; +import { parseArgs } from 'node:util'; +import { mkdir, readFile, writeFile } from 'node:fs/promises'; +import { dirname, resolve } from 'node:path'; +import { fileURLToPath, pathToFileURL } from 'node:url'; +import { loadFrame, nestedPicture } from './frame.mjs'; +import { digestOf, loadAnchors } from './anchors.mjs'; +import { evidenceOf } from './evidence.mjs'; +import { guardRead } from './reader-guard.mjs'; + +const exec = promisify(execFile); +export const ISOBAR_REVISION = '2ec719904ac7dc30de08e152e4622fe8e02fa57a'; +const SHA = /^[a-f0-9]{40}$/; +const ROOT = resolve(dirname(fileURLToPath(import.meta.url)), '../..'); +const TEST = + /(^|\/)(test|tests|__tests__|spec|specs)\/|\.(test|spec)\.[cm]?[jt]sx?$|(^|\/)test_[^/]+\.py$|_test\.py$/; + +// Repository content is data: these commands do not run builds, hooks, or PR scripts. +export async function runGit(argv) { + if (argv[0] !== 'git') throw new Error('The Isobar adapter only permits Git reads'); + try { + const { stdout } = await exec('git', argv.slice(1), { + shell: false, + maxBuffer: 64 * 1024 * 1024, + timeout: 120_000, + env: { + ...process.env, + GIT_CONFIG_NOSYSTEM: '1', + GIT_CONFIG_GLOBAL: '/dev/null', + GIT_OPTIONAL_LOCKS: '0', + GIT_TERMINAL_PROMPT: '0', + }, + }); + return { exitCode: 0, stdout }; + } catch (error) { + return { exitCode: error.code ?? 1, stdout: error.stdout ?? '' }; + } +} + +export async function gitText(repo, ...args) { + const result = await runGit(['git', '-C', repo, '-c', 'diff.autoRefreshIndex=false', ...args]); + if (result.exitCode !== 0) throw new Error(`Git ${args[0]} failed (${result.exitCode})`); + return result.stdout; +} + +// Read immutable blobs instead of the working tree. This also supports a bare +// object store in CI, where no contributor files are ever checked out. +export function treeRun(headSha, invoke = runGit) { + return async (argv) => { + let command = 3; + while (argv[command] === '-c') command += 2; + if (argv[command] === 'rev-parse' && argv[command + 1] === 'HEAD') { + return invoke([...argv.slice(0, command + 1), headSha]); + } + if (argv[command] === 'log') { + return invoke([...argv, headSha, '--']); + } + if (argv[command] !== 'grep' && argv[command] !== 'ls-files') return invoke(argv); + if (argv[command] === 'ls-files') { + const result = await invoke([...argv.slice(0, command), 'ls-tree', '-r', '-z', headSha]); + return { + ...result, + stdout: result.stdout + .split('\0') + .map((row) => row.replace(/^([0-7]+) blob ([a-f0-9]+)\t/, '$1 $2 0\t')) + .join('\0'), + }; + } + const args = argv.slice(command + 1); + const separator = args.indexOf('--'); + const end = separator < 0 ? args.length : separator; + let hasRevision = false; + for (let i = 0; i < end; i++) { + if (args[i] === '-e' || args[i] === '-f') { + i++; + continue; + } + if (SHA.test(args[i]) || args[i] === 'HEAD') hasRevision = true; + } + if (hasRevision) return invoke(argv); + args.splice(end, 0, headSha); + const result = await invoke([...argv.slice(0, command + 1), ...args]); + const prefix = `${headSha}:`; + return { + ...result, + stdout: result.stdout + .split('\n') + .map((line) => (line.startsWith(prefix) ? line.slice(prefix.length) : line)) + .join('\n'), + }; + }; +} + +export function changeFlags(status) { + const parts = status.split('\0'); + const flags = new Map(); + for (let i = 0; i + 1 < parts.length; i += 2) { + flags.set(parts[i + 1], { isNew: parts[i] === 'A', isDeleted: parts[i] === 'D' }); + } + return flags; +} + +export function summaryOf(changes) { + return { + files: changes.length, + added: changes.reduce((sum, change) => sum + change.added, 0), + deleted: changes.reduce((sum, change) => sum + change.deleted, 0), + testFiles: changes.filter(({ path }) => TEST.test(path)).length, + }; +} + +export async function render({ + repo, + upstream, + mapPath, + baseSha, + headSha, + prNumber, + repository, + out, + python = 'python3', +}) { + if (!SHA.test(baseSha) || !SHA.test(headSha)) + throw new Error('Expected full base and head commit SHAs'); + if (!Number.isSafeInteger(prNumber) || prNumber < 1) throw new Error('Invalid PR number'); + if (!/^[\w.-]+\/[\w.-]+$/.test(repository)) throw new Error('Invalid repository'); + await gitText(repo, 'cat-file', '-e', `${headSha}^{commit}`); + await gitText(repo, 'cat-file', '-e', `${baseSha}^{commit}`); + if ((await gitText(upstream, 'rev-parse', 'HEAD')).trim() !== ISOBAR_REVISION) { + throw new Error('Isobar checkout does not match the pinned tool revision'); + } + const mergeBaseSha = (await gitText(repo, 'merge-base', baseSha, headSha)).trim(); + if (!SHA.test(mergeBaseSha)) throw new Error('No merge base found'); + const load = (path) => import(pathToFileURL(resolve(upstream, path)).href); + const [ + { gatherFacts, parseNumstat }, + { graphOf, reachOf, isTest }, + { readChange, textsOf }, + { fieldOf }, + { inksOf }, + ] = await Promise.all([ + load('hooks/engine/git.ts'), + load('hooks/engine/graph.ts'), + load('hooks/engine/symbols.ts'), + load('hooks/render/field.ts'), + load('hooks/render/palette.ts'), + ]); + // Never call Isobar's preview CLI: its missing-map fallback invokes a model. + const mapBytes = await readFile(mapPath); + const mapDigest = digestOf(mapBytes); + const frame = loadFrame(JSON.parse(mapBytes)); + const anchorSource = JSON.parse( + await readFile(resolve(dirname(mapPath), 'anchors.json'), 'utf8'), + ); + if (anchorSource.mapDigest !== mapDigest) throw new Error('Fixed anchors do not match the map'); + const anchors = loadAnchors(anchorSource, frame); + const [facts, numstat, status] = await Promise.all([ + // History is not part of the orientation map. + gatherFacts(treeRun(headSha), repo, 0), + gitText( + repo, + 'diff', + '--numstat', + '-z', + '--no-renames', + '--no-ext-diff', + mergeBaseSha, + headSha, + '--', + ), + gitText( + repo, + 'diff', + '--name-status', + '-z', + '--no-renames', + '--no-ext-diff', + mergeBaseSha, + headSha, + '--', + ), + ]); + if (facts.head !== headSha || facts.lines.size === 0) + throw new Error('Isobar could not read the PR tree'); + const flags = changeFlags(status); + const changes = parseNumstat(numstat).map((change) => ({ ...change, ...flags.get(change.path) })); + const graph = graphOf(facts.edges); + const read = await readChange( + runGit, + repo, + facts, + changes, + { from: mergeBaseSha, to: headSha }, + graph, + ); + const guardedPaths = [...read.shapes].filter(([, s]) => s.kind !== 'file').map(([p]) => p); + if (guardedPaths.length) { + const [before, after] = await Promise.all( + [mergeBaseSha, headSha].map(async (sha) => { + const result = await runGit([ + 'git', + '-C', + repo, + 'grep', + '-z', + '-n', + '-I', + '-e', + '', + sha, + '--', + ...guardedPaths, + ]); + if (result.exitCode !== 0 && result.exitCode !== 1) + throw new Error('Source evidence grep failed'); + return result.stdout; + }), + ); + guardRead(read, textsOf(before, mergeBaseSha), textsOf(after, headSha)); + } + const baseGraph = changes.some(({ isDeleted }) => isDeleted) + ? graphOf((await gatherFacts(treeRun(mergeBaseSha), repo, 0)).edges) + : undefined; + const evidence = evidenceOf({ + frame, + facts, + changes, + read, + graph, + baseGraph, + reachOf, + isTest, + anchors, + revision: ISOBAR_REVISION, + mapDigest, + }); + // Upstream's visual field uses weather-shaped inputs. Supply a constant + // marker for every change; no score or history influences the image. + const weather = { + cells: evidence.changes.map(({ path, leafId }) => ({ + path, + region: leafId, + risk: 0.5, + isLatest: true, + })), + reach: [], + arms: [], + offshoots: [], + expected: [], + }; + const picture = await nestedPicture({ + frame, + weather, + fieldOf, + inks: inksOf('paper', 'truecolor'), + anchors, + evidence, + }); + const summary = summaryOf(changes); + picture.caption = `PR #${prNumber} ยท ${headSha.slice(0, 7)} ยท ${summary.files} files ยท +${summary.added} / โˆ’${summary.deleted} ยท full PR diff`; + const report = { + schemaVersion: 1, + repository, + prNumber, + headSha, + baseSha, + mergeBaseSha, + generatedAt: new Date().toISOString(), + tool: { name: 'isobar', revision: ISOBAR_REVISION }, + summary, + files: changes, + evidence, + provenance: { + mapDigest, + anchorVersion: anchors.version, + anchorBaselineSha: anchors.baselineSha, + }, + }; + await mkdir(out, { recursive: true }); + const gridPath = resolve(out, 'grid.json'); + await writeFile(gridPath, JSON.stringify(picture)); + await exec( + python, + [resolve(ROOT, 'scripts/pr-impact/render-frame.py'), gridPath, resolve(out, 'map.png')], + { timeout: 120_000 }, + ); + await writeFile(resolve(out, 'report.json'), `${JSON.stringify(report, null, 2)}\n`); + console.log( + `PR #${prNumber}: ${report.summary.files} files ยท +${report.summary.added} โˆ’${report.summary.deleted} ยท ${evidence.reachByCause.length} static reach links`, + ); + return report; +} + +if (process.argv[1] && resolve(process.argv[1]) === fileURLToPath(import.meta.url)) { + const { values } = parseArgs({ + options: { + repo: { type: 'string' }, + upstream: { type: 'string' }, + map: { type: 'string', default: resolve(ROOT, '.isobar/map.json') }, + base: { type: 'string' }, + head: { type: 'string' }, + number: { type: 'string' }, + repository: { type: 'string', default: 'aws-samples/sample-collaborative-ai-dlc' }, + out: { type: 'string' }, + python: { type: 'string', default: 'python3' }, + }, + }); + for (const key of ['repo', 'upstream', 'base', 'head', 'number', 'out']) { + if (!values[key]) throw new Error(`Missing --${key}`); + } + await render({ + repo: resolve(values.repo), + upstream: resolve(values.upstream), + mapPath: resolve(values.map), + baseSha: values.base, + headSha: values.head, + prNumber: Number(values.number), + repository: values.repository, + out: resolve(values.out), + python: values.python, + }); +} diff --git a/scripts/pr-impact/requirements.txt b/scripts/pr-impact/requirements.txt new file mode 100644 index 00000000..7126a796 --- /dev/null +++ b/scripts/pr-impact/requirements.txt @@ -0,0 +1 @@ +Pillow==12.0.0 diff --git a/scripts/publish-complexity-comment.mjs b/scripts/publish-complexity-comment.mjs index 50cefb54..afbde675 100644 --- a/scripts/publish-complexity-comment.mjs +++ b/scripts/publish-complexity-comment.mjs @@ -6,7 +6,7 @@ const sha = (value) => typeof value === 'string' && /^[a-f0-9]{40}$/.test(value) const integer = (value) => Number.isSafeInteger(value) && value >= 0; const text = (value) => typeof value === 'string' && value.length <= 10000; -function validCoverage(value) { +export function validCoverage(value) { if (value === null) return true; if (!value || !['unknown', 'measured'].includes(value.status)) return false; if (value.status === 'unknown') return true; @@ -175,12 +175,17 @@ export async function publishComplexityComment({ comment.body?.startsWith(commentMarker), ); const previous = existing?.body.match(//); - if ( + const olderRun = previous && (Number(previous[1]) > run.id || - (Number(previous[1]) === run.id && Number(previous[2]) > run.run_attempt)) - ) - continue; + (Number(previous[1]) === run.id && Number(previous[2]) > run.run_attempt)); + const combinedReport = existing?.body.includes('\nExisting quality table`, + }); + const run = { + id: runId, + run_attempt: 2, + event: 'pull_request', + name: 'PR Quality', + path: '.github/workflows/pr-quality.yml', + status: 'completed', + repository: { id: 1 }, + head_repository: { id: 2 }, + head_sha: headSha, + }; + const jobs = [ + { name: 'report', run_attempt: 1, conclusion: 'success' }, + { name: 'report', run_attempt: 2, conclusion: 'success' }, + ]; + const artifacts = [ + { name: 'pr-quality-1', expired: false }, + { name: 'pr-quality-2', expired: false }, + ]; + const listJobs = () => {}; + const listArtifacts = () => {}; + f.github.rest.actions = { + getWorkflowRun: async ({ run_id }) => { + assert.equal(run_id, runId); + return { data: run }; + }, + listJobsForWorkflowRun: listJobs, + listWorkflowRunArtifacts: listArtifacts, + }; + const paginate = f.github.paginate; + f.github.paginate = async (method, input) => + method === listJobs ? jobs : method === listArtifacts ? artifacts : paginate(method, input); + return { run, jobs, artifacts }; +} + +test('legacy recovery selects the latest successful artifact and keeps approved coverage in the first map', async (t) => { + const f = await fixture(t); + legacyRun(f); + const selected = await legacyQualityArtifact(f); + assert.deepEqual(selected, { + runId: 120, + artifactName: 'pr-quality-2', + qualityRun: { id: 120, attempt: 2 }, + }); + assert.deepEqual(f.writes, []); + f.loadLegacyQuality = async (artifact) => { + assert.deepEqual(artifact, selected); + return quality(true); + }; + await publishReviewSignals(f); + assert.equal(f.comments.length, 1); + assert.match(f.comments[0].body, /100.0% โ†’ 50.0%/); + assert.match(f.comments[0].body, /!\[PR impact map\]/); + assert.deepEqual(reviewMetadata(f.comments[0]).qualityRun, { id: 120, attempt: 2 }); +}); + +test('recovered quality retains its older base tip when the head, target and merge base match', async (t) => { + const f = await fixture(t); + const recovered = { ...quality(true), base: 'e'.repeat(40) }; + legacyRun(f); + f.loadLegacyQuality = async () => recovered; + assert.equal((await publishReviewSignals(f)).published, true); + assert.match(f.comments[0].body, /100.0% โ†’ 50.0%/); + const pinned = reviewMetadata(f.comments[0]); + const { data } = await f.github.rest.repos.getContent({ + path: 'pr-42/quality.json', + ref: pinned.assetSha, + }); + assert.equal( + JSON.parse(Buffer.from(data.content, 'base64').toString('utf8')).base, + recovered.base, + ); +}); + +test('earlier static run attaches its map after a later coverage run publishes the same head', async (t) => { + const f = await fixture(t); + await f.enrich(quality(true), 124); + assert.match(f.comments[0].body, /100.0% โ†’ 50.0%/); + assert.doesNotMatch(f.comments[0].body, /PR impact map/); + const state = legacyRun(f, 124); + state.run.run_attempt = 1; + state.jobs.pop(); + state.artifacts.pop(); + f.loadLegacyQuality = async () => quality(true); + assert.equal((await publishReviewSignals(f)).published, true); + assert.equal(f.comments.length, 1); + assert.match(f.comments[0].body, /100.0% โ†’ 50.0%/); + assert.match(f.comments[0].body, /!\[PR impact map\]/); + assert.deepEqual(reviewMetadata(f.comments[0]).staticRun, { id: 123, attempt: 1 }); + assert.deepEqual(reviewMetadata(f.comments[0]).qualityRun, { id: 124, attempt: 1 }); +}); + +test('first map recovers coverage that arrived after static collection', async (t) => { + const f = await fixture(t); + await f.enrich(quality(true), 124); + legacyRun(f, 124); + await f.writeQuality(quality()); + let selected; + f.loadLegacyQuality = async (artifact) => { + selected = artifact; + return { ...quality(true), base: 'e'.repeat(40) }; + }; + assert.equal((await publishReviewSignals(f)).published, true); + assert.equal(selected.runId, 124); + assert.equal(f.comments.length, 1); + assert.match(f.comments[0].body, /100.0% โ†’ 50.0%/); + assert.match(f.comments[0].body, /!\[PR impact map\]/); +}); + +test('a later comment-only attempt recovers the latest successful coverage producer', async (t) => { + const f = await fixture(t); + const state = legacyRun(f, 124); + state.run.run_attempt = 3; + f.comments[0].body = `${COMMENT_MARKER}\n\nExisting quality table`; + f.loadLegacyQuality = async (selected) => { + assert.equal(selected.artifactName, 'pr-quality-2'); + return quality(true); + }; + assert.equal((await publishReviewSignals(f)).published, true); + assert.match(f.comments[0].body, /100.0% โ†’ 50.0%/); + assert.deepEqual(reviewMetadata(f.comments[0]).qualityRun, { id: 124, attempt: 2 }); +}); + +test('first map does not erase newer legacy coverage when bounded recovery is unavailable', async (t) => { + for (const recovered of [undefined, { ...quality(true), pr: 'f'.repeat(40) }]) { + const f = await fixture(t); + await f.enrich(quality(true), 124); + legacyRun(f, 124); + const original = f.comments[0].body; + await f.writeQuality(quality()); + if (recovered) f.loadLegacyQuality = async () => recovered; + f.writes.length = 0; + const result = await publishReviewSignals(f); + assert.equal(result.reason, 'newer legacy quality requires recovery'); + assert.deepEqual(f.writes, []); + assert.equal(f.comments[0].body, original); + } +}); + +test('latest validated unknown coverage allows the first map and blocks older known measurements', async (t) => { + const f = await fixture(t); + await f.enrich(quality(true), 124); + await f.enrich(quality(), 125); + legacyRun(f, 125); + f.loadLegacyQuality = async () => quality(); + assert.equal((await publishReviewSignals(f)).published, true); + assert.equal(f.comments.length, 1); + assert.match(f.comments[0].body, /!\[PR impact map\]/); + assert.match(f.comments[0].body, /Coverage unavailable/); + assert.doesNotMatch(f.comments[0].body, /100.0% โ†’ 50.0%/); + assert.deepEqual(reviewMetadata(f.comments[0]).qualityRun, { id: 125, attempt: 2 }); + f.writes.length = 0; + await f.enrich(quality(true), 124); + assert.deepEqual(f.writes, []); + assert.doesNotMatch(f.comments[0].body, /100.0% โ†’ 50.0%/); +}); + +test('legacy recovery rejects mismatched, failed, expired, foreign and non-target state without writes', async (t) => { + for (const change of [ + (_f, state) => { + state.run.head_sha = 'f'.repeat(40); + }, + (_f, state) => { + state.run.head_repository.id = 999; + }, + (_f, state) => { + state.run.repository.id = 999; + }, + (_f, state) => { + state.run.event = 'pull_request_target'; + }, + (_f, state) => { + state.run.path = '.github/workflows/attacker.yml'; + }, + (_f, state) => { + state.run.status = 'in_progress'; + }, + (_f, state) => { + state.jobs[1].conclusion = 'failure'; + }, + (_f, state) => { + state.artifacts[1].expired = true; + }, + (f) => { + f.comments[0].user.type = 'User'; + }, + (f) => { + f.comments[0].body += '\n'; + }, + (f) => { + f.context.eventName = 'workflow_run'; + }, + ]) { + const f = await fixture(t); + const state = legacyRun(f); + change(f, state); + assert.equal(await legacyQualityArtifact(f), null); + assert.deepEqual(f.writes, []); + } +}); diff --git a/scripts/test/pr-impact-reader-guard.test.mjs b/scripts/test/pr-impact-reader-guard.test.mjs new file mode 100644 index 00000000..5c513221 --- /dev/null +++ b/scripts/test/pr-impact-reader-guard.test.mjs @@ -0,0 +1,62 @@ +import assert from 'node:assert/strict'; +import test from 'node:test'; +import { guardRead, lexicalAmbiguity } from '../pr-impact/reader-guard.mjs'; + +test('pinned reader hazards in real pricing/pagination changes require file-wide evidence', () => { + assert.equal( + lexicalAmbiguity(['// esbuild WITHOUT `--external:@aws-sdk/*`']), + 'line-comment-block-token', + ); + assert.equal( + lexicalAmbiguity(['const tokenPattern = /(```|`[^`]+`)/g;']), + 'regex-backtick-token', + ); + assert.equal(lexicalAmbiguity(['const message = "Use `code`";']), 'quoted-backtick-token'); + assert.equal(lexicalAmbiguity(['const message = `Hello ${name}`;']), null); +}); + +test('escaped regex bodies are scanned without ambiguous backtracking', () => { + const repeated = '\\.'.repeat(20_000); + assert.equal(lexicalAmbiguity([`const pattern = /${repeated}`]), null); + assert.equal(lexicalAmbiguity([`const pattern = /${repeated}\`/g;`]), 'regex-backtick-token'); + assert.equal(lexicalAmbiguity([`const text = "${'\\\\'.repeat(20_000)}";`]), null); +}); + +test('ambiguous declarations lose named attribution and retain an explicit fallback', () => { + const read = { + shapes: new Map([['pricing.js', { kind: 'comments', touches: [{ name: 'wrong' }] }]]), + users: [{ of: 'pricing.js', path: 'user.js', uses: 1 }], + added: new Map([['pricing.js', ['const price = 11;']]]), + }; + guardRead(read, new Map(), new Map()); + assert.equal(read.shapes.get('pricing.js').kind, 'file'); + assert.deepEqual(read.shapes.get('pricing.js').touches, []); + assert.deepEqual(read.users, []); + assert.equal(read.fallbacks.get('pricing.js'), 'lexical-ambiguity:quiet-code-contradiction'); +}); + +test('actual quiet comment changes retain their precise classification', () => { + const read = { + shapes: new Map([['source.js', { kind: 'comments' }]]), + users: [], + added: new Map([['source.js', ['// Explain the return value.', '']]]), + }; + guardRead(read, new Map(), new Map()); + assert.equal(read.shapes.get('source.js').kind, 'comments'); + assert.equal(read.fallbacks.size, 0); +}); + +test('pure removal of behavior after a quoted block token cannot remain comments-only', () => { + const read = { + shapes: new Map([['source.js', { kind: 'comments', touches: [] }]]), + users: [], + added: new Map([['source.js', []]]), + }; + guardRead( + read, + new Map([['source.js', ['const delimiter = "/*";', 'export const send = () => 1;']]]), + new Map([['source.js', ['const delimiter = "/*";']]]), + ); + assert.equal(read.shapes.get('source.js').kind, 'file'); + assert.equal(read.fallbacks.get('source.js'), 'lexical-ambiguity:quoted-block-comment-token'); +}); diff --git a/scripts/test/pr-impact-render.test.mjs b/scripts/test/pr-impact-render.test.mjs new file mode 100644 index 00000000..59a30c4a --- /dev/null +++ b/scripts/test/pr-impact-render.test.mjs @@ -0,0 +1,85 @@ +import assert from 'node:assert/strict'; +import test from 'node:test'; +import { + changeFlags, + ISOBAR_REVISION, + render, + runGit, + summaryOf, + treeRun, +} from '../pr-impact/render.mjs'; + +const change = (path, added = 1, deleted = 0) => ({ path, added, deleted }); + +test('summary counts changed files and lines without judging coverage', () => { + const summary = summaryOf([ + change('lambda/shared/authz.js', 8, 2), + change('lambda/intents/index.js', 4, 3), + change('frontend/src/services/intents.test.ts', 11), + change('terraform/main.tf', 2, 1), + change('package-lock.json', 100, 50), + ]); + assert.equal(summary.files, 5); + assert.equal(summary.added, 125); + assert.equal(summary.deleted, 56); + assert.equal(summary.testFiles, 1); + assert.equal('reviewCues' in summary, false); +}); + +test('test-only and documentation-only changes stay factual', () => { + const tests = summaryOf([change('lambda/agentcore/test/fixtures/child.mjs')]); + assert.equal(tests.testFiles, 1); + const docs = summaryOf([change('docs/development/testing.md')]); + assert.equal(docs.testFiles, 0); +}); + +test('name-status preserves additions, deletions, spaces, and newline-bearing paths', () => { + const flags = changeFlags('A\0new file.js\0D\0old\nfile.js\0M\0existing.js\0'); + assert.deepEqual(flags.get('new file.js'), { isNew: true, isDeleted: false }); + assert.deepEqual(flags.get('old\nfile.js'), { isNew: false, isDeleted: true }); + assert.deepEqual(flags.get('existing.js'), { isNew: false, isDeleted: false }); +}); + +test('renderer rejects revision injection before touching a repository or loading tooling', async () => { + await assert.rejects( + render({ baseSha: '--output=/tmp/x', headSha: 'a'.repeat(40) }), + /full base and head/, + ); + await assert.rejects(runGit(['bash', '-c', 'exit 0']), /only permits Git reads/); + assert.match(ISOBAR_REVISION, /^[a-f0-9]{40}$/); +}); + +test('immutable tree adapter inserts and removes grep revision prefixes for facts only', async () => { + const sha = 'a'.repeat(40); + const commands = []; + const run = treeRun(sha, async (argv) => { + commands.push(argv); + return { exitCode: 0, stdout: `${sha}:file.js\u00003\n` }; + }); + assert.deepEqual(await run(['git', '-C', '/repo', 'grep', '-z', '-c', '-e', '', '--', '*.js']), { + exitCode: 0, + stdout: 'file.js\u00003\n', + }); + assert.deepEqual(commands[0].slice(3), ['grep', '-z', '-c', '-e', '', sha, '--', '*.js']); + await run(['git', '-C', '/repo', 'grep', '-e', sha, '--', '*.js']); + assert.deepEqual(commands[1].slice(3), ['grep', '-e', sha, sha, '--', '*.js']); + await run(['git', '-C', '/repo', 'grep', '-e', '', sha, '--', '*.js']); + assert.deepEqual(commands[2].slice(3), ['grep', '-e', '', sha, '--', '*.js']); +}); + +test('bare tree adapter retains empty tracked files without relying on an index', async () => { + const sha = 'a'.repeat(40); + const blob = 'e69de29bb2d1d6434b8b29ae775ad8c2e48c5391'; + const run = treeRun(sha, async (argv) => { + assert.deepEqual(argv, ['git', '-C', '/repo', 'ls-tree', '-r', '-z', sha]); + return { + exitCode: 0, + stdout: [`100644 blob ${blob}\tempty.js`, `100644 blob ${blob}\tother.js`, ''].join('\0'), + }; + }); + const result = await run(['git', '-C', '/repo', 'ls-files', '-z', '-s']); + assert.equal( + result.stdout, + [`100644 ${blob} 0\tempty.js`, `100644 ${blob} 0\tother.js`, ''].join('\0'), + ); +}); diff --git a/scripts/test/pr-impact-workflow.test.mjs b/scripts/test/pr-impact-workflow.test.mjs new file mode 100644 index 00000000..22c9862f --- /dev/null +++ b/scripts/test/pr-impact-workflow.test.mjs @@ -0,0 +1,70 @@ +import assert from 'node:assert/strict'; +import { readFileSync } from 'node:fs'; +import { test } from 'node:test'; +import yaml from 'js-yaml'; + +const load = (name) => + yaml.load(readFileSync(new URL(`../../.github/workflows/${name}`, import.meta.url), 'utf8')); + +test('static reporting accepts normal PR events with no maintainer or publication-variable gate', () => { + const workflow = load('pr-impact.yml'); + assert.deepEqual(workflow.on.pull_request_target.types, [ + 'opened', + 'synchronize', + 'reopened', + 'ready_for_review', + 'edited', + ]); + assert.equal(workflow.jobs.analyze.if, undefined); + assert.equal(workflow.jobs.publish.if, undefined); + assert.match(workflow['run-name'], /PR impact map #/); + assert.doesNotMatch(JSON.stringify(workflow), /author_association|PR_IMPACT_PUBLISH|secrets\./); +}); + +test('contributor source never becomes the controller checkout or an executable installation', () => { + const workflow = load('pr-impact.yml'); + assert.deepEqual(workflow.jobs.analyze.permissions, { + contents: 'read', + 'pull-requests': 'read', + }); + for (const step of workflow.jobs.analyze.steps.filter((s) => + s.uses?.startsWith('actions/checkout@'), + )) { + assert.equal(step.with.ref, '${{ github.sha }}'); + assert.equal(step.with['persist-credentials'], false); + } + const code = workflow.jobs.analyze.steps.map((s) => s.run ?? '').join('\n'); + assert.match(code, /npm ci --ignore-scripts/); + assert.doesNotMatch( + code, + /npm test|npm run build|pull_request\.head|head\.repo\.clone_url|git checkout.*head/, + ); +}); + +test('write tokens are limited to dependency-free trusted publishers with a shared lock', () => { + const initial = load('pr-impact.yml').jobs.publish; + const same = load('pr-quality.yml').jobs.comment; + const fork = load('pr-quality-comment.yml'); + assert.equal(initial.permissions.contents, 'write'); + assert.equal(same.permissions.contents, 'write'); + assert.equal(fork.permissions.contents, 'write'); + assert.equal(initial.concurrency.group, same.concurrency.group); + for (const job of [initial, same, fork.jobs.comment]) { + const checkout = job.steps.find((s) => s.uses?.startsWith('actions/checkout@')); + assert.equal(checkout.with['persist-credentials'], false); + assert.match(checkout.with['sparse-checkout'], /pr-impact\/publish\.mjs/); + assert.doesNotMatch(job.steps.map((s) => s.run ?? '').join('\n'), /npm|pip|git checkout/); + } + assert.equal( + same.steps.find((s) => s.uses?.startsWith('actions/checkout@')).with.ref, + '${{ github.event.repository.default_branch }}', + ); +}); + +test('fork tests retain their pull_request trigger and read-token execution boundary', () => { + const workflow = load('pr-quality.yml'); + assert.ok(Object.hasOwn(workflow.on, 'pull_request')); + assert.equal(workflow.on.pull_request_target, undefined); + assert.equal(workflow.permissions.contents, 'read'); + assert.match(workflow.jobs.coverage.steps.map((s) => s.run ?? '').join('\n'), /npm test/); +}); diff --git a/scripts/test/publish-complexity-comment.test.mjs b/scripts/test/publish-complexity-comment.test.mjs index 73c8d54b..143c0d19 100644 --- a/scripts/test/publish-complexity-comment.test.mjs +++ b/scripts/test/publish-complexity-comment.test.mjs @@ -510,7 +510,8 @@ test('both workflow paths download selected producer artifacts and call the shar assert.equal(checkout.with['persist-credentials'], false); if (file === 'pr-quality-comment.yml') assert.equal(checkout.with.ref, undefined); else { - assert.equal(checkout.with.ref, '${{ github.sha }}'); + assert.equal(checkout.with.ref, '${{ github.event.repository.default_branch }}'); + assert.equal(workflow.jobs.comment.permissions.contents, 'write'); const uploads = workflow.jobs.report.steps .filter((step) => step.uses?.startsWith('actions/upload-artifact@')) .map((step) => [step.with.name, step.with.path]); @@ -572,7 +573,11 @@ test('workflow tools support PR heads that predate them without measuring the me const checkout = workflow.jobs[jobName].steps.find((step) => step.uses?.startsWith('actions/checkout@'), ); - assert.equal(checkout.with.ref, '${{ github.sha }}', jobName); + assert.equal( + checkout.with.ref, + jobName === 'comment' ? '${{ github.event.repository.default_branch }}' : '${{ github.sha }}', + jobName, + ); } const sourceCheckout = workflow.jobs.coverage.steps.find((step) => step.with?.path === 'source'); assert.equal( diff --git a/zensical.toml b/zensical.toml index f8021fbc..ec1b399a 100644 --- a/zensical.toml +++ b/zensical.toml @@ -37,6 +37,7 @@ nav = [ { "Development" = [ "development/demo-deployment.md", "development/testing.md", + "development/pr-quality.md", ] }, { "Roadmap" = "roadmap/index.md" }, ]