Skip to content

fix(accessibility): make asynchronous viewer actions nested-safe - #264

Merged
seonghobae merged 6 commits into
mainfrom
fix/accessible-async-viewer-controls
Aug 12, 2026
Merged

fix(accessibility): make asynchronous viewer actions nested-safe#264
seonghobae merged 6 commits into
mainfrom
fix/accessible-async-viewer-controls

Conversation

@seonghobae

@seonghobae seonghobae commented Aug 5, 2026

Copy link
Copy Markdown
Collaborator

Accessibility objective

Make repeated viewer actions understandable to assistive technology and safe under overlapping asynchronous work without parsing HTML or losing original DOM, disabled, or ARIA state.

Fresh exact state — 2026-08-11

  • exact source head: 56286060a01c739861e95ddfb76f0c3e307bad69;
  • exact protected main: 55d7ae8647208e301f282350f076eeddaba61d11 after protected merge of fix(security): harden audit pseudonymization and refresh Netty evidence #270;
  • direct compare to protected main: six commits ahead, zero behind, merge base exactly protected main;
  • six changed files and no inherited pom.xml, workflow, or cross-cutting documentation replacement;
  • open, Ready and mergeable;
  • exact-head CI 31396835418: success;
  • exact-head Security Scan 31396834442: success;
  • exact-head SAST Semgrep 31396835210: success;
  • exact-head fuzz 31396834437: success;
  • all current inline review threads are resolved; the three current CodeRabbit findings were addressed and are resolved;
  • formal reviews contain COMMENTED/advisory evidence only, with no qualifying independent write-authorized APPROVED review.

The former divergent stack, predecessor heads and earlier run identifiers are historical. This exact branch is already reconciled directly onto the post-#270 protected baseline; no further source rewrite is justified unless the source head or protected base moves.

Test-first current-base evidence

RED

Test-only head 525696a908786554393577b7603b62f66e7e7eb5 added the historical DOM/integration regressions plus a repository-native Python wrapper while production dom-utils.js was still absent and demo.js lacked the accessible nested-safe behavior. CI 31391875837 failed the buyer-readiness accessibility script with the expected missing-module and document-specific accessible-name regressions while Maven compatibility remained green.

GREEN

Current head provides the reusable nested-safe busy-state primitive and buyer-demo integration:

  • dom-utils.js snapshots original child nodes, disabled state, aria-busy, and aria-label with nested depth counting and idempotent restoration;
  • demo.js uses DOM/text APIs, adds document-specific accessible names, keeps markup-like filenames inert, and blocks repeated activation while work is pending;
  • the Node integration suite now shares one mock DOM contract and explicitly verifies repeated activation does not issue a second request;
  • the Python wrapper is discoverable by repository-standard unittest and requires the Node 22 coverage capabilities actually used by the suite.

Exact-head CI, Security Scan, SAST and fuzz are GREEN on the unchanged source identity.

Clean changed paths

  1. scripts/test_accessible_async_viewer_controls.py
  2. src/main/resources/static/assets/viewer/demo.js
  3. src/main/resources/static/assets/viewer/dom-utils.js
  4. src/test/js/demo-integration.test.mjs
  5. src/test/js/dom-utils.test.mjs
  6. src/test/js/mock-dom.mjs

Scope / non-completion boundary

This is a reusable accessibility primitive and its current buyer-demo integration. It does not implement issue #317's production workspace/session authority, issue #263's complete deletion UX, issue #322's PDF.js generation ownership, or issue #324's focus appearance. Production demo-authority removal and lifecycle integration remain separate work.

Merge gate

Keep this exact head unchanged. Merge or auto-merge may complete only after live protection still sees every applicable required check passing, zero valid unresolved findings, and a counted approving review from a qualifying independent reviewer with write access. Automated comments, checks, statuses and model output are evidence, not approval.

@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

공통 DOM 유틸리티에 비동기 busy 상태와 접근성 처리를 추가했다. demo.js는 이를 사용해 버튼 상태를 관리한다. DOM 유틸리티와 viewer 통합 동작을 Node.js 테스트와 전체 커버리지 검사로 검증한다.

Changes

접근성 viewer 컨트롤

Layer / File(s) Summary
DOM 유틸리티와 단위 검증
src/main/resources/static/assets/viewer/dom-utils.js, src/test/js/dom-utils.test.mjs
setBusyState, createLink, createActionButton을 추가했다. 중첩 호출, 상태 복원, 접근성 라벨, 링크 보안 속성과 텍스트 처리를 검증한다.
Viewer 비동기 컨트롤 통합
src/main/resources/static/assets/viewer/demo.js, src/test/js/demo-integration.test.mjs
viewer 버튼이 공통 busy 상태와 접근성 라벨을 사용한다. 작업 상태, 재시도, KPI, 데모 데이터, 문서 제출 흐름의 상태 복원을 통합 테스트로 검증한다.
Node.js 접근성 회귀 실행
scripts/test_accessible_async_viewer_controls.py
Node.js 설치와 버전 20 이상을 확인한다. 두 JavaScript 테스트를 라인·분기·함수 커버리지 100% 조건으로 실행하고 실패 출력을 보고한다.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant demo_js
  participant dom_utils_js
  participant BrowserDOM
  demo_js->>dom_utils_js: setBusyState 호출
  dom_utils_js->>BrowserDOM: 버튼 비활성화와 aria-busy 설정
  demo_js->>BrowserDOM: 비동기 결과와 팝업 내용 갱신
  dom_utils_js->>BrowserDOM: restore 호출 후 원래 상태 복원
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 제목은 비동기 뷰어 작업의 중첩 안전성 개선이라는 변경 사항의 핵심을 정확하고 간결하게 설명합니다.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/accessible-async-viewer-controls

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@opencode-agent @cwl-noema-review Please independently review exact current head 81c2c7f0cc8326e049429ef99ef64a9fa40f77b4. This one-commit branch supersedes the mutable Jules branch #162. Verify the nested-safe WeakMap busy-state contract, exact DOM/ARIA restoration, contextual accessible names, inert markup-like labels, executable Node tests, 100% line/branch/function coverage for the production helper, Java test/Javadoc gates, and all repository protections. Submit APPROVE only after exact-head CI, Security Scan, SAST, and fuzzing are complete and clean.

@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown

@seonghobae I will review pull request #264 at the specified commit.

I will check the busy-state contract, DOM and ARIA restoration, accessible names, test coverage, and required repository checks. I will not approve the pull request until the exact-head checks and required protections are complete and clean.

⚠️ Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@seonghobae
seonghobae enabled auto-merge (squash) August 5, 2026 02:27

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

Copy link
Copy Markdown
Collaborator Author

@opencode-agent Please independently review exact current head 81c2c7f0cc8326e049429ef99ef64a9fa40f77b4. This clean PR supersedes #162 and is one commit on the protected main baseline. Exact-head CI, Security Scan, SAST Semgrep, and fuzzing are successful. Verify the shared WeakMap busy-state contract, consumer import, contextual accessible names, inert text handling, Node 100% line/branch/function gate, changelog consolidation, and repository protection evidence before approval.

@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown
⚠️ Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown
Collaborator Author

@cwl-noema-review Please independently review exact current head 81c2c7f0cc8326e049429ef99ef64a9fa40f77b4. This clean one-commit PR supersedes #162 and exact-head CI, Security Scan, SAST Semgrep, and fuzzing are successful. Verify the production consumer import, WeakMap depth/idempotence contract, exact restoration of DOM/disabled/ARIA state, contextual inert labels, Node 100% line/branch/function gate, documentation, and repository protections. Submit APPROVE only for this exact head if no blocker remains.

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@opencode-agent @cwl-noema-review Please independently review exact current head 734a72686f5671f757cd9f2a6e1fec0ecc93d1fe. CI, Security Scan, SAST Semgrep, and fuzzing are successful on this head. Verify the shared WeakMap state contract, production consumer import, contextual and inert labels, exact DOM/disabled/ARIA restoration, full-SHA Node.js 24 pin, Node 100% line/branch/function gate, documentation, and repository protections. Submit APPROVE only for this exact head if no blocker remains.

@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown

@seonghobae I will review pull request #264 at exact head 734a72686f5671f757cd9f2a6e1fec0ecc93d1fe. I will verify the requested implementation and check requirements before I approve it.

⚠️ Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown
Collaborator Author

@opencode-agent @cwl-noema-review Please independently review exact current head 734a72686f5671f757cd9f2a6e1fec0ecc93d1fe. Exact-head CI, Node 24 executable DOM tests with 100% dom-utils.js line/branch/function coverage, Security Scan, SAST Semgrep, fuzzing, and CodeRabbit all succeed. Verify document-specific action names, original child-node identity preservation, exact disabled/ARIA restoration, nested/idempotent WeakMap busy state, markup-like filename inertness, duplicate-activation prevention, Java/JaCoCo preservation, pinned Actions, consolidated CHANGELOG, and accessibility doctoring. Submit APPROVE only if no blocker remains.

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@opencode-agent @cwl-noema-review Please independently review exact current head 734a72686f5671f757cd9f2a6e1fec0ecc93d1fe. Current-head CI, Security Scan, SAST Semgrep, and fuzz are successful. Verify the WeakMap depth-counted busy-state contract, idempotent and exact DOM/disabled/ARIA restoration, inert treatment of markup-like document names, operation-specific accessible names, duplicate-activation prevention, Node 24 full-SHA workflow pin, and exact 100% line/branch/function coverage for dom-utils.js. Submit APPROVE only for this exact head after all repository protections pass.

@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

expected='734a72686f5671f757cd9f2a6e1fec0ecc93d1fe'

printf '%s\n' '== Local commit and changed files =='
git rev-parse HEAD
git diff --name-status "${expected}^" "${expected}"
git diff --stat "${expected}^" "${expected}"

printf '%s\n' '== JavaScript and build/workflow candidates =='
fd -t f . | rg '(^|/)(dom-utils\.js|.*dom.*test.*\.(js|mjs|cjs)|pom\.xml|CHANGELOG.*|.*journal.*|.*accessib.*|.*\.ya?ml)$' || true

printf '%s\n' '== Source outlines =='
while IFS= read -r f; do
  case "$f" in
    *.js|*.mjs|*.cjs)
      echo "--- $f"
      ast-grep outline "$f" --items all || true
      ;;
  esac
done < <(git diff --name-only "${expected}^" "${expected}" | rg '\.(js|mjs|cjs)$' || true)

printf '%s\n' '== Changed diff =='
git diff --find-renames --find-copies "${expected}^" "${expected}"

printf '%s\n' '== GitHub PR, checks, and protection metadata =='
gh pr view 264 --repo ContextualWisdomLab/clearfolio --json number,headRefOid,baseRefName,state,isDraft,mergeStateStatus,reviewDecision,statusCheckRollup,url
gh api 'repos/ContextualWisdomLab/clearfolio/commits/734a72686f5671f757cd9f2a6e1fec0ecc93d1fe/check-runs?per_page=100' \
  --jq '.check_runs[] | [.name,.status,.conclusion,.details_url] | `@tsv`' || true
gh api 'repos/ContextualWisdomLab/clearfolio/branches/main/protection' || true

Length of output: 2177


🏁 Script executed:

#!/bin/bash
set -u

repo='ContextualWisdomLab/clearfolio'
sha='734a72686f5671f757cd9f2a6e1fec0ecc93d1fe'

echo '== Pull request metadata =='
gh pr view 264 --repo "$repo" --json number,headRefOid,baseRefName,baseRefOid,state,isDraft,mergeStateStatus,reviewDecision,statusCheckRollup,url || true

echo '== Pull request file list =='
gh pr diff 264 --repo "$repo" --name-only || true

echo '== Merge base and full pull request changed files =='
base="$(git merge-base HEAD origin/main 2>/dev/null || true)"
printf 'merge-base=%s\n' "$base"
if [ -n "$base" ]; then
  git diff --name-status "$base" HEAD
fi

echo '== dom-utils.js outline and content =='
ast-grep outline src/main/resources/static/assets/viewer/dom-utils.js --items all || true
nl -ba src/main/resources/static/assets/viewer/dom-utils.js | sed -n '1,320p' || true

echo '== Node DOM test content =='
nl -ba src/test/js/dom-utils.test.mjs | sed -n '1,420p' || true

echo '== Maven Node test and coverage configuration =='
rg -n -C 12 'dom-utils|node|coverage|nyc|c8|exec-maven|frontend' pom.xml || true

echo '== CI Node setup configuration =='
nl -ba .github/workflows/ci.yml | sed -n '1,260p' || true

echo '== Production consumers and accessible action labels =='
rg -n -C 8 'setBusy|busy|Details|Status JSON|Open viewer|aria-label|disabled' src/main/resources/static || true

echo '== Changelog and accessibility documentation changes from merge base =='
if [ -n "$base" ]; then
  git diff --unified=40 "$base" HEAD -- CHANGELOG.md docs || true
fi

Length of output: 45940


🏁 Script executed:

#!/bin/bash
set -u

repo='ContextualWisdomLab/clearfolio'
base='8e2d36f260395dbd0304abc503d8bd15ffcf8dab'
head='734a72686f5671f757cd9f2a6e1fec0ecc93d1fe'

echo '== Complete helper implementation =='
sed -n '1,180p' src/main/resources/static/assets/viewer/dom-utils.js || true

echo '== Complete executable Node DOM test =='
sed -n '1,460p' src/test/js/dom-utils.test.mjs || true

echo '== Relevant production consumer implementation =='
sed -n '100,155p' src/main/resources/static/assets/viewer/demo.js || true
sed -n '250,520p' src/main/resources/static/assets/viewer/demo.js || true

echo '== Complete CI workflow =='
sed -n '1,300p' .github/workflows/ci.yml || true

echo '== Focused base-to-head diffs =='
git diff --check "$base" "$head" || true
git diff --unified=20 "$base" "$head" -- \
  .github/workflows/ci.yml pom.xml \
  src/main/resources/static/assets/viewer/demo.js \
  src/main/resources/static/assets/viewer/dom-utils.js \
  src/test/js/dom-utils.test.mjs || true

echo '== Pin format checks =='
rg -n -P 'uses:\s*actions/setup-node@|node-version:|node-version-file:' .github/workflows/ci.yml || true

echo '== Required reviews and branch protection =='
gh pr view 264 --repo "$repo" --json latestReviews,reviewRequests,reviewDecision,mergeStateStatus || true
gh api "repos/$repo/branches/main/protection" || true
gh api "repos/$repo/rules/branches/main" || true

Length of output: 57297


@seonghobae Review complete for exact head 734a72686f5671f757cd9f2a6e1fec0ecc93d1fe.

Blocking finding: src/main/resources/static/assets/viewer/demo.js Line 135 creates the Status JSON button without setBusyState. openJsonDocument() is asynchronous. While its fetch is pending, users can activate the button again and open additional popup windows. The action also has no pending accessible name.

Apply setBusyState to this handler and restore it after openJsonDocument() settles. Use an operation-specific pending label, such as Loading status JSON....

I verified the shared WeakMap helper, exact DOM/ARIA restoration, node identity preservation, inert text handling, Node 24 full-SHA pin, Maven coverage thresholds, and successful exact-head checks. I did not approve because this blocker remains. GitHub also reports REVIEW_REQUIRED and BLOCKED; the repository ruleset requires one approving review.

You are interacting with an AI system.

seonghobae added a commit that referenced this pull request Aug 5, 2026
This branch has been superseded by a cleaner replacement PR (#264).
No further work will be performed on this branch.
Comment thread .github/workflows/verify-demo-integration.yml Fixed
@opencode-agent
opencode-agent Bot disabled auto-merge August 5, 2026 03:17

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@opencode-agent @cwl-noema-review Please independently review exact current head 347203d5dc7b6bd4a53877f322bbaba28acb527f. The current-head CI, Security Scan, SAST Semgrep, and fuzz workflows all succeed. The prior CI failure was traced to the executable integration test's DOM double incorrectly manufacturing an empty text node for textContent = ""; the current head now models browser child-removal semantics and preserves exact 100% line, branch, and function coverage for dom-utils.js. Verify the WeakMap depth-counted busy-state contract, idempotent exact DOM/disabled/ARIA restoration, contextual inert document labels, duplicate-activation prevention, full-SHA Node.js 24 pin, test-double fidelity, documentation, and repository protections. Submit APPROVE only for this exact head if no blocker remains.

@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

repo='ContextualWisdomLab/clearfolio'
sha='347203d5dc7b6bd4a53877f322bbaba28acb527f'

echo '== Exact head and PR metadata =='
printf 'local HEAD: '; git rev-parse HEAD
git show -s --format='commit: %H%nparents: %P%nsubject: %s' "$sha"
gh pr view 264 --repo "$repo" \
  --json number,url,state,isDraft,headRefOid,baseRefName,baseRefOid,mergeStateStatus,reviewDecision,statusCheckRollup,latestReviews

echo '== Pull request diff summary =='
base="$(git merge-base "$sha" origin/main)"
printf 'merge-base: %s\n' "$base"
git diff --check "$base" "$sha"
git diff --name-status "$base" "$sha"

echo '== Relevant source outlines =='
ast-grep outline src/main/resources/static/assets/viewer/dom-utils.js --items all
ast-grep outline src/main/resources/static/assets/viewer/demo.js --items all
ast-grep outline src/test/js/dom-utils.test.mjs --items all

echo '== Busy helper =='
nl -ba src/main/resources/static/assets/viewer/dom-utils.js | sed -n '1,260p'

echo '== Viewer consumers and accessible labels =='
rg -n -C 10 -P '\b(setBusyState|openJsonDocument|openViewer|Details|Status JSON|Open viewer|aria-label|aria-busy|disabled)\b' \
  src/main/resources/static/assets/viewer/demo.js

echo '== DOM helper tests and test-double semantics =='
rg -n -C 10 -P '(textContent|childNodes|replaceChildren|setBusyState|nested|restore|aria-busy|aria-label|disabled)' \
  src/test/js/dom-utils.test.mjs

echo '== Maven test and coverage configuration =='
rg -n -C 12 -P '(dom-utils|node|c8|coverage|line|branch|function|exec-maven)' pom.xml

echo '== Node setup pin =='
rg -n -C 4 -P '(actions/setup-node@|node-version:)' .github/workflows/ci.yml

echo '== Documentation changes =='
git diff --unified=20 "$base" "$sha" -- CHANGELOG.md docs

echo '== Exact-commit checks =='
gh api "repos/$repo/commits/$sha/check-runs?per_page=100" --paginate \
  --jq '.check_runs[] | [.name, .status, .conclusion, .details_url] | `@tsv`'

echo '== Branch protection and rules =='
gh api "repos/$repo/branches/main/protection" || true
gh api "repos/$repo/rules/branches/main" || true

Length of output: 15907


🏁 Script executed:

#!/bin/bash
set -euo pipefail

repo='ContextualWisdomLab/clearfolio'
sha='347203d5dc7b6bd4a53877f322bbaba28acb527f'
base='8e2d36f260395dbd0304abc503d8bd15ffcf8dab'

echo '== Helper implementation =='
sed -n '1,180p' src/main/resources/static/assets/viewer/dom-utils.js

echo '== Async viewer actions =='
sed -n '75,150p' src/main/resources/static/assets/viewer/demo.js
sed -n '220,310p' src/main/resources/static/assets/viewer/demo.js

echo '== DOM helper tests =='
sed -n '1,360p' src/test/js/dom-utils.test.mjs

echo '== Integration test and DOM double =='
sed -n '1,420p' src/test/js/demo-integration.test.mjs

echo '== Maven Node test and coverage gate =='
grep -n -E -C 12 'dom-utils|node|c8|coverage|line|branch|function|exec-maven' pom.xml || true

echo '== CI Node setup =='
grep -n -E -C 4 'actions/setup-node@|node-version:' .github/workflows/ci.yml || true

echo '== Exact relevant diff =='
git diff --check "$base" "$sha"
git diff --unified=30 "$base" "$sha" -- \
  .github/workflows/ci.yml pom.xml CHANGELOG.md .jules/palette.md \
  src/main/resources/static/assets/viewer/demo.js \
  src/main/resources/static/assets/viewer/dom-utils.js \
  src/test/js/dom-utils.test.mjs src/test/js/demo-integration.test.mjs

echo '== Current exact-head check states =='
gh api "repos/$repo/commits/$sha/check-runs?per_page=100" --paginate \
  --jq '.check_runs[] | select(.name == "strix" or .name == "Maven test" or .name == "Semgrep (multi-language SAST)" or .name == "osv-scan" or .name == "fuzz (ArtifactTokenParserFuzzTest)") | [.name,.status,.conclusion] | `@tsv`'

echo '== Required branch protection =='
gh api "repos/$repo/branches/main/protection/required_status_checks" || true
gh api "repos/$repo/branches/main/protection/required_pull_request_reviews" || true
gh api "repos/$repo/rules/branches/main" || true

Length of output: 76067


@seonghobae Review complete for exact head 347203d5dc7b6bd4a53877f322bbaba28acb527f.

Blocking finding: The Status JSON action in src/main/resources/static/assets/viewer/demo.js still calls asynchronous openJsonDocument() without setBusyState.

A user can activate this action again before fetchJson() completes. This can open more popup windows. The action also has no pending accessible name.

Apply the shared helper in this handler. Restore the state when openJsonDocument() settles. Use an operation-specific pending label such as Loading status JSON....

I verified the WeakMap depth and idempotence contract, exact DOM and ARIA restoration, original child-node preservation, contextual inert labels, integration test DOM semantics for textContent = "", Node 24 full-SHA setup pin, Maven Node coverage thresholds, changelog consolidation, and journal documentation.

I did not approve this PR. The source blocker remains. The exact-head strix check is also still in progress. GitHub reports the PR as blocked and requires an approval. The branch-protection REST endpoints returned 403, but the available ruleset data shows the required organization workflows and one required approving review.


✏️ Learnings added
Learnt from: seonghobae
URL: https://github.com/ContextualWisdomLab/clearfolio/pull/264

Timestamp: 2026-08-05T03:30:42.098Z
Learning: In `src/test/js/demo-integration.test.mjs`, the `MockElement.textContent` setter must model browser semantics: assigning `textContent = ""` removes all child nodes rather than creating an empty text node. This behavior is necessary for executable viewer integration tests that verify rendered DOM structure.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

You are interacting with an AI system.

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@opencode-agent @cwl-noema-review Please independently review exact current head 347203d5dc7b6bd4a53877f322bbaba28acb527f. CI, Security Scan, SAST Semgrep, and fuzzing all succeeded on this head. Verify the production demo.js consumer import, WeakMap nesting/idempotence contract, exact DOM/disabled/ARIA restoration, inert contextual labels, executable non-empty-history integration test, full-SHA Node.js 24 pin, 100% Node line/branch/function gate, documentation, and repository protections. Submit approval only for this exact head if no blocker remains.

@seonghobae
seonghobae enabled auto-merge (squash) August 5, 2026 03:32

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@opencode-agent @cwl-noema-review Please independently review exact current head 347203d5dc7b6bd4a53877f322bbaba28acb527f. Exact-head CI run 30972309198, Security Scan 30972309188, SAST Semgrep 30972309203, and fuzz 30972309205 are successful. Verify WeakMap depth-counted busy-state behavior, exact and idempotent DOM/disabled/ARIA restoration, inert markup-like filenames, operation-specific accessible names, duplicate-activation prevention, full-SHA Node 24 workflow pinning, demo-module integration, and exact 100% line/branch/function coverage for dom-utils.js. Submit APPROVE only for this exact head and only if all repository protections remain satisfied.

@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

repo='ContextualWisdomLab/clearfolio'
sha='347203d5dc7b6bd4a53877f322bbaba28acb527f'

echo '== Exact commit and pull request =='
printf 'local HEAD: '; git rev-parse HEAD
git show -s --format='commit: %H%nparents: %P%nsubject: %s' "$sha"
gh pr view 264 --repo "$repo" \
  --json number,url,state,isDraft,headRefOid,baseRefName,baseRefOid,mergeStateStatus,reviewDecision,statusCheckRollup,latestReviews

echo '== Merge base and changed files =='
base="$(git merge-base "$sha" origin/main)"
printf 'merge-base: %s\n' "$base"
git diff --check "$base" "$sha"
git diff --name-status "$base" "$sha"

echo '== Relevant source maps =='
ast-grep outline src/main/resources/static/assets/viewer/dom-utils.js --items all
ast-grep outline src/main/resources/static/assets/viewer/demo.js --items all
ast-grep outline src/test/js/dom-utils.test.mjs --items all
ast-grep outline src/test/js/demo-integration.test.mjs --items all

echo '== Busy helper =='
nl -ba src/main/resources/static/assets/viewer/dom-utils.js | sed -n '1,260p'

echo '== Async action consumers and accessible labels =='
rg -n -C 12 -P '\b(setBusyState|openJsonDocument|openViewer|openDocumentDetails|Details|Status JSON|Open viewer|aria-label|aria-busy|disabled)\b' \
  src/main/resources/static/assets/viewer/demo.js

echo '== Unit and integration tests =='
nl -ba src/test/js/dom-utils.test.mjs | sed -n '1,460p'
nl -ba src/test/js/demo-integration.test.mjs | sed -n '1,520p'

echo '== Maven coverage configuration =='
rg -n -C 14 -P '(dom-utils|node|c8|coverage|line|branch|function|exec-maven)' pom.xml

echo '== Node setup action pin =='
rg -n -C 5 -P '(actions/setup-node@|node-version:)' .github/workflows/ci.yml

echo '== Focused diff and documentation =='
git diff --unified=35 "$base" "$sha" -- \
  .github/workflows/ci.yml pom.xml CHANGELOG.md .jules/palette.md \
  src/main/resources/static/assets/viewer/demo.js \
  src/main/resources/static/assets/viewer/dom-utils.js \
  src/test/js/dom-utils.test.mjs src/test/js/demo-integration.test.mjs

echo '== Exact-head check runs =='
gh api "repos/$repo/commits/$sha/check-runs?per_page=100" --paginate \
  --jq '.check_runs[] | [.name,.status,.conclusion,.details_url] | `@tsv`'

echo '== Repository protection and rules =='
gh api "repos/$repo/branches/main/protection" || true
gh api "repos/$repo/rules/branches/main" || true

Length of output: 16589


🏁 Script executed:

#!/bin/bash
set -euo pipefail

repo='ContextualWisdomLab/clearfolio'
sha='347203d5dc7b6bd4a53877f322bbaba28acb527f'
base="$(git merge-base "$sha" origin/main)"

echo '== Busy helper =='
sed -n '1,180p' src/main/resources/static/assets/viewer/dom-utils.js

echo '== Demo imports, JSON action, viewer actions, and history rendering =='
sed -n '1,160p' src/main/resources/static/assets/viewer/demo.js
sed -n '220,310p' src/main/resources/static/assets/viewer/demo.js
sed -n '400,565p' src/main/resources/static/assets/viewer/demo.js

echo '== Busy helper tests =='
sed -n '1,460p' src/test/js/dom-utils.test.mjs

echo '== Demo integration test =='
sed -n '1,540p' src/test/js/demo-integration.test.mjs

echo '== Maven Node execution and coverage gate =='
rg -n -C 16 -P '(dom-utils|node|c8|coverage|line|branch|function|exec-maven)' pom.xml

echo '== CI Node pin =='
sed -n '1,260p' .github/workflows/ci.yml
rg -n -P 'uses:\s*actions/setup-node@[0-9a-f]{40}|node-version:\s*["'\'']?24' .github/workflows/ci.yml

echo '== Changelog and accessibility documentation diff =='
git diff --unified=30 "$base" "$sha" -- CHANGELOG.md .jules/palette.md

echo '== Full relevant source and test diff =='
git diff --check "$base" "$sha"
git diff --unified=35 "$base" "$sha" -- \
  .github/workflows/ci.yml pom.xml \
  src/main/resources/static/assets/viewer/demo.js \
  src/main/resources/static/assets/viewer/dom-utils.js \
  src/test/js/dom-utils.test.mjs src/test/js/demo-integration.test.mjs

echo '== Current exact-head check runs =='
gh api "repos/$repo/commits/$sha/check-runs?per_page=100" --paginate \
  --jq '.check_runs[] | [.name,.status,.conclusion] | `@tsv`'

echo '== Pull-request reviews and merge state =='
gh pr view 264 --repo "$repo" --json headRefOid,mergeStateStatus,reviewDecision,latestReviews

echo '== Branch protection and rulesets =='
gh api "repos/$repo/branches/main/protection" || true
gh api "repos/$repo/rules/branches/main" || true

Length of output: 88657


@seonghobae Review complete for exact head 347203d5dc7b6bd4a53877f322bbaba28acb527f.

Blocking finding: src/main/resources/static/assets/viewer/demo.js creates the Status JSON button without setBusyState.

openJsonDocument() is asynchronous because it awaits fetchJson(). While that request is pending, the button remains enabled. A user can activate it again and open additional popup windows. The action also has no operation-specific pending accessible name.

Apply the shared helper in this handler. Restore the state when openJsonDocument() settles. Use a pending label such as Loading status JSON....

The shared helper otherwise implements the required WeakMap depth counting, idempotent restore callbacks, exact disabled and ARIA restoration, and original child-node preservation. The tests cover the helper contract and the non-empty-history inert-label integration case. Maven enforces 100% line, branch, and function coverage for dom-utils.js. The Node.js 24 setup action uses a full commit SHA. The changelog and engineering journal changes are consistent with the implementation.

I did not approve this PR. The Status JSON source blocker remains. The exact-head strix check is also still in_progress. GitHub reports REVIEW_REQUIRED and BLOCKED. The available repository rules require one approval.

You are interacting with an AI system.

@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

repo='ContextualWisdomLab/clearfolio'
sha='347203d5dc7b6bd4a53877f322bbaba28acb527f'

echo '== Exact head and pull request state =='
printf 'local HEAD: '; git rev-parse HEAD
git show -s --format='commit: %H%nparents: %P%nsubject: %s' "$sha"
gh pr view 264 --repo "$repo" \
  --json number,url,state,isDraft,headRefOid,baseRefName,baseRefOid,mergeStateStatus,reviewDecision,statusCheckRollup,latestReviews

echo '== Merge-base diff and whitespace check =='
base="$(git merge-base "$sha" origin/main)"
printf 'merge-base: %s\n' "$base"
git diff --check "$base" "$sha"
git diff --name-status "$base" "$sha"

echo '== Source outlines =='
ast-grep outline src/main/resources/static/assets/viewer/dom-utils.js --items all
ast-grep outline src/main/resources/static/assets/viewer/demo.js --items all
ast-grep outline src/test/js/dom-utils.test.mjs --items all
ast-grep outline src/test/js/demo-integration.test.mjs --items all

echo '== Busy helper and async action consumers =='
nl -ba src/main/resources/static/assets/viewer/dom-utils.js | sed -n '1,240p'
rg -n -C 12 -P '\b(setBusyState|openJsonDocument|openViewer|fetchJson|Details|Status JSON|Open viewer|aria-label|aria-busy|disabled)\b' \
  src/main/resources/static/assets/viewer/demo.js

echo '== Helper and integration tests =='
rg -n -C 12 -P '(setBusyState|nested|restore|textContent|childNodes|replaceChildren|aria-busy|aria-label|disabled|markup)' \
  src/test/js/dom-utils.test.mjs src/test/js/demo-integration.test.mjs

echo '== Maven test and coverage contract =='
rg -n -C 14 -P '(dom-utils|node|c8|coverage|line|branch|function|exec-maven)' pom.xml

echo '== Node setup pin =='
rg -n -C 5 -P '(actions/setup-node@|node-version:)' .github/workflows/ci.yml

echo '== Documentation diff =='
git diff --unified=20 "$base" "$sha" -- CHANGELOG.md docs .jules/palette.md

echo '== Exact commit check runs =='
gh api "repos/$repo/commits/$sha/check-runs?per_page=100" --paginate \
  --jq '.check_runs[] | [.name,.status,.conclusion,.details_url] | `@tsv`'

echo '== Required review and workflow rules =='
gh api "repos/$repo/branches/main/protection/required_pull_request_reviews" || true
gh api "repos/$repo/branches/main/protection/required_status_checks" || true
gh api "repos/$repo/rules/branches/main" || true

Length of output: 16550


🏁 Script executed:

#!/bin/bash
set -u

repo='ContextualWisdomLab/clearfolio'
sha='347203d5dc7b6bd4a53877f322bbaba28acb527f'
base='8e2d36f260395dbd0304abc503d8bd15ffcf8dab'

numbered() {
  awk '{ printf "%6d\t%s\n", NR, $0 }' "$1"
}

echo '== Busy helper =='
numbered src/main/resources/static/assets/viewer/dom-utils.js | sed -n '1,220p' || true

echo '== Demo imports and async action handlers =='
numbered src/main/resources/static/assets/viewer/demo.js | sed -n '1,155p' || true
numbered src/main/resources/static/assets/viewer/demo.js | sed -n '215,310p' || true
numbered src/main/resources/static/assets/viewer/demo.js | sed -n '425,555p' || true

echo '== All helper calls and async functions in demo =='
rg -n -C 8 -P '\b(setBusyState|openJsonDocument|openJobDetail|retryActiveJob|refreshKpis|refreshKpiEvidence|loadDemoData|submitDocument)\s*\(' \
  src/main/resources/static/assets/viewer/demo.js || true

echo '== DOM helper tests =='
numbered src/test/js/dom-utils.test.mjs | sed -n '1,380p' || true

echo '== Demo module integration test =='
numbered src/test/js/demo-integration.test.mjs | sed -n '1,480p' || true

echo '== Maven Node test and coverage contract =='
rg -n -C 16 -P '(dom-utils|node|c8|coverage|line|branch|function|exec-maven)' pom.xml || true

echo '== Full-SHA Node.js workflow pin =='
rg -n -C 6 -P '(actions/setup-node@|node-version:)' .github/workflows/ci.yml || true

echo '== Focused product diff =='
git diff --unified=30 "$base" "$sha" -- \
  src/main/resources/static/assets/viewer/demo.js \
  src/main/resources/static/assets/viewer/dom-utils.js \
  src/test/js/dom-utils.test.mjs \
  src/test/js/demo-integration.test.mjs \
  pom.xml .github/workflows/ci.yml || true

echo '== Documentation diff =='
git diff --unified=20 "$base" "$sha" -- CHANGELOG.md docs .jules/palette.md || true

echo '== Current exact-head checks =='
gh api "repos/$repo/commits/$sha/check-runs?per_page=100" --paginate \
  --jq '.check_runs[] | select(.name == "Maven test" or .name == "strix" or .name == "Semgrep (multi-language SAST)" or .name == "osv-scan" or (.name | startswith("fuzz"))) | [.name,.status,.conclusion] | `@tsv`' || true

echo '== Pull request reviews and rules =='
gh pr view 264 --repo "$repo" --json headRefOid,mergeStateStatus,reviewDecision,latestReviews,reviewRequests || true
gh api "repos/$repo/branches/main/protection/required_pull_request_reviews" || true
gh api "repos/$repo/branches/main/protection/required_status_checks" || true
gh api "repos/$repo/rules/branches/main" || true

Length of output: 98573


@seonghobae Review complete for exact head 347203d5dc7b6bd4a53877f322bbaba28acb527f.

Blocking finding: src/main/resources/static/assets/viewer/demo.js Line 135 starts asynchronous openJsonDocument() without setBusyState.

A user can activate Status JSON again while fetchJson() is pending. Each activation can open another popup. The control also has no operation-specific pending accessible name.

Apply the shared helper in this handler. Restore the state when openJsonDocument() settles. Use a pending label such as Loading status JSON....

I verified the following items:

  • setBusyState uses a WeakMap and depth counting.
  • Restore callbacks are idempotent.
  • The helper preserves original child-node identity.
  • The helper restores disabled, aria-busy, and aria-label exactly.
  • Repeated actions have contextual accessible names.
  • Markup-like filenames use textContent and remain inert.
  • The production demo.js integration test verifies a non-empty history row.
  • Maven runs the Node tests with exact 100% line, branch, and function thresholds for dom-utils.js.
  • The workflow pins actions/setup-node by full SHA and selects Node.js 24.
  • The changelog has one Unreleased section. The engineering journal documents the shared pattern.

I did not approve this pull request. The Status JSON blocker remains. The exact-head strix check is also still in progress. GitHub reports BLOCKED and REVIEW_REQUIRED. The available ruleset requires one approving review. The branch-protection REST endpoints returned 403, so I could not verify their full configuration.

You are interacting with an AI system.

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@opencode-agent @cwl-noema-review Please independently review exact current head 6d37f2150d527626b9646fccd0d5bf8327ace7cb. The prior Status JSON blocker is addressed: its asynchronous handler now applies setBusyState immediately, disables repeated activation, exposes Loading... View status JSON for <document> while pending, and restores the exact original DOM/disabled/ARIA state in finally. The executable production-module integration test holds the request pending, asserts the busy state and popup safety, resolves JSON, then asserts exact restoration and rendered evidence. Exact-head CI, Security Scan, SAST Semgrep, and fuzzing all succeed. Verify the complete nested-safe contract, operation coverage, inert filename handling, popup behavior, full-SHA Node.js pin, 100% helper coverage, documentation, and repository protections. Submit APPROVE only for this exact head if no blocker remains.

@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

repo='ContextualWisdomLab/clearfolio'
sha='6d37f2150d527626b9646fccd0d5bf8327ace7cb'

echo '== Exact commit and pull request =='
printf 'local HEAD: '; git rev-parse HEAD
git show -s --format='commit: %H%nparents: %P%nsubject: %s' "$sha"
gh pr view 264 --repo "$repo" \
  --json number,url,state,isDraft,headRefOid,baseRefName,baseRefOid,mergeStateStatus,reviewDecision,statusCheckRollup,latestReviews

echo '== Merge-base diff =='
base="$(git merge-base "$sha" origin/main)"
printf 'merge-base: %s\n' "$base"
git diff --check "$base" "$sha"
git diff --name-status "$base" "$sha"

echo '== Relevant source outlines =='
ast-grep outline src/main/resources/static/assets/viewer/dom-utils.js --items all
ast-grep outline src/main/resources/static/assets/viewer/demo.js --items all
ast-grep outline src/test/js/dom-utils.test.mjs --items all
ast-grep outline src/test/js/demo-integration.test.mjs --items all

echo '== Busy helper =='
nl -ba src/main/resources/static/assets/viewer/dom-utils.js | sed -n '1,260p'

echo '== Viewer action consumers =='
nl -ba src/main/resources/static/assets/viewer/demo.js | sed -n '1,180p'
nl -ba src/main/resources/static/assets/viewer/demo.js | sed -n '215,330p'
nl -ba src/main/resources/static/assets/viewer/demo.js | sed -n '420,580p'

echo '== Busy-state and integration tests =='
nl -ba src/test/js/dom-utils.test.mjs | sed -n '1,480p'
nl -ba src/test/js/demo-integration.test.mjs | sed -n '1,560p'

echo '== Maven test and coverage configuration =='
rg -n -C 14 -P '(dom-utils|node|c8|coverage|line|branch|function|exec-maven)' pom.xml

echo '== Node setup configuration =='
rg -n -C 6 -P '(actions/setup-node@|node-version:)' .github/workflows/ci.yml

echo '== Focused product and documentation diff =='
git diff --unified=35 "$base" "$sha" -- \
  .github/workflows/ci.yml pom.xml CHANGELOG.md docs .jules/palette.md \
  src/main/resources/static/assets/viewer/demo.js \
  src/main/resources/static/assets/viewer/dom-utils.js \
  src/test/js/dom-utils.test.mjs \
  src/test/js/demo-integration.test.mjs

echo '== Exact-head check runs =='
gh api "repos/$repo/commits/$sha/check-runs?per_page=100" --paginate \
  --jq '.check_runs[] | [.name,.status,.conclusion,.details_url] | `@tsv`'

echo '== Available protection and ruleset data =='
gh api "repos/$repo/branches/main/protection" || true
gh api "repos/$repo/rules/branches/main" || true

Length of output: 16618


🏁 Script executed:

#!/bin/bash
set -euo pipefail

repo='ContextualWisdomLab/clearfolio'
sha='6d37f2150d527626b9646fccd0d5bf8327ace7cb'
base='8e2d36f260395dbd0304abc503d8bd15ffcf8dab'

numbered() {
  awk '{ printf "%6d\t%s\n", NR, $0 }' "$1"
}

echo '== Busy-state helper =='
numbered src/main/resources/static/assets/viewer/dom-utils.js | sed -n '1,240p'

echo '== Demo imports and Status JSON action =='
numbered src/main/resources/static/assets/viewer/demo.js | sed -n '1,170p'
numbered src/main/resources/static/assets/viewer/demo.js | sed -n '215,320p'
numbered src/main/resources/static/assets/viewer/demo.js | sed -n '420,575p'

echo '== Helper tests =='
numbered src/test/js/dom-utils.test.mjs | sed -n '1,460p'

echo '== Production-module integration test =='
numbered src/test/js/demo-integration.test.mjs | sed -n '1,560p'

echo '== Maven execution and coverage thresholds =='
rg -n -C 16 -P '(dom-utils|node|c8|coverage|line|branch|function|exec-maven)' pom.xml

echo '== Node.js setup pin =='
rg -n -C 6 -P '(actions/setup-node@|node-version:)' .github/workflows/ci.yml

echo '== Focused diff and documentation =='
git diff --check "$base" "$sha"
git diff --unified=35 "$base" "$sha" -- \
  .github/workflows/ci.yml pom.xml CHANGELOG.md .jules/palette.md docs \
  src/main/resources/static/assets/viewer/demo.js \
  src/main/resources/static/assets/viewer/dom-utils.js \
  src/test/js/dom-utils.test.mjs \
  src/test/js/demo-integration.test.mjs

echo '== Current exact-head checks =='
gh api "repos/$repo/commits/$sha/check-runs?per_page=100" --paginate \
  --jq '.check_runs[] | select(.name == "Maven test" or .name == "strix" or .name == "Semgrep (multi-language SAST)" or .name == "osv-scan" or (.name | startswith("fuzz"))) | [.name,.status,.conclusion] | `@tsv`'

echo '== Pull request state and available protection data =='
gh pr view 264 --repo "$repo" --json headRefOid,mergeStateStatus,reviewDecision,latestReviews
gh api "repos/$repo/branches/main/protection" || true
gh api "repos/$repo/rules/branches/main" || true

Length of output: 94832


🏁 Script executed:

#!/bin/bash
set -euo pipefail

repo='ContextualWisdomLab/clearfolio'
sha='6d37f2150d527626b9646fccd0d5bf8327ace7cb'

echo '== Current exact-head required workflow states =='
gh api "repos/$repo/commits/$sha/check-runs?per_page=100" --paginate \
  --jq '.check_runs[]
    | select(
        .name == "Maven test"
        or .name == "strix"
        or .name == "Semgrep (multi-language SAST)"
        or .name == "osv-scan"
        or (.name | startswith("fuzz"))
      )
    | [.name, .status, .conclusion]
    | `@tsv`'

echo '== Pull request head and merge state =='
gh pr view 264 --repo "$repo" \
  --json headRefOid,mergeStateStatus,reviewDecision,statusCheckRollup,latestReviews

echo '== Available main branch protection =='
gh api "repos/$repo/branches/main/protection" || true

echo '== Available main branch rulesets =='
gh api "repos/$repo/rules/branches/main" || true

Length of output: 14024


@seonghobae Review complete for exact head 6d37f2150d527626b9646fccd0d5bf8327ace7cb.

I found no new source-level blocker.

The prior Status JSON finding is fixed. demo.js applies setBusyState before openJsonDocument() starts. It restores state through .finally(restore). The pending accessible name is Loading... View status JSON for <document>. The control is disabled while the request is pending.

I verified these items:

  • setBusyState uses a WeakMap, depth counting, and idempotent restore callbacks.
  • The helper preserves original child-node identities.
  • The helper restores disabled, aria-busy, and aria-label exactly.
  • Details, Status JSON, and Open viewer have document-specific accessible names.
  • textContent keeps markup-like filenames inert.
  • The production-module integration test verifies pending and restored Status JSON state, popup opener isolation, rendered JSON, and browser-like textContent = "" child removal.
  • Maven runs the Node tests during test.
  • Maven enforces 100% line, branch, and function coverage for src/main/resources/static/assets/viewer/dom-utils.js.
  • CI uses Node.js 24 and pins actions/setup-node to a full SHA.
  • The changelog has one Unreleased section. The engineering journal documents the shared contract.

I cannot approve yet. The exact-head strix check is still in_progress. GitHub reports BLOCKED and REVIEW_REQUIRED. The available rulesets also require the organization workflows, resolved review threads, and one repository approval. The branch-protection API returned HTTP 403, so its full configuration could not be verified.

You are interacting with an AI system.

@seonghobae
seonghobae marked this pull request as draft August 5, 2026 03:48
auto-merge was automatically disabled August 5, 2026 03:48

Pull request was converted to draft

@seonghobae
seonghobae marked this pull request as ready for review August 5, 2026 03:48
Comment thread .github/workflows/reconcile-pr-264-on-main.yml Fixed
@opencode-agent

Copy link
Copy Markdown
Contributor

Queued @cwl-noema-review for PR #264 at head 411fd8a9df84a7f3a529d365b4614e7b3f94e148. Central exact-name Actions artifacts are the durable dispatch ledger; existing review workflows remain authoritative for the final verdict and failure evidence.

@opencode-agent
opencode-agent Bot disabled auto-merge August 10, 2026 14:00
@seonghobae
seonghobae enabled auto-merge (squash) August 10, 2026 14:36
@opencode-agent

Copy link
Copy Markdown
Contributor

Queued @cwl-noema-review for PR #264 at head 56286060a01c739861e95ddfb76f0c3e307bad69. Central exact-name Actions artifacts are the durable dispatch ledger; existing review workflows remain authoritative for the final verdict and failure evidence.

@opencode-agent

Copy link
Copy Markdown
Contributor

OpenCode Review Overview

  • Head SHA: 56286060a01c739861e95ddfb76f0c3e307bad69
  • Workflow run: 31559314434
  • Workflow attempt: 1
  • Gate result: APPROVE (exit 0)

Changed-File Evidence Map

flowchart LR
  PR["PR changed files"] --> Evidence["OpenCode bounded evidence"]
  Evidence --> S1["Test: test_accessible_async_viewer_controls.py"]
  S1 --> I1["regression suite"]
  I1 --> R1["Review risk: Test: test_accessible_async_viewer_controls.py"]
  R1 --> V1["targeted test run"]
  Evidence --> S2["Changed file (5 files)"]
  S2 --> I2["repository behavior"]
  I2 --> R2["Review risk: Changed file (5 files)"]
  R2 --> V2["required checks"]
Loading

@opencode-agent opencode-agent Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

OpenCode reviewed the current-head bounded evidence and found no blocking issues.

Findings

No blocking findings.

Summary

Approved. Changed files inspected as changed-file evidence: scripts/test_accessible_async_viewer_controls.py and src/main/resources/static/assets/viewer/demo.js (inlined current-head hunks; PR-head file reads denied by sandbox - source limitation). Approval sufficiency: evidence affirmatively supports the nested-safe async-controls refactor; all five async surfaces (Details, Status JSON, Retry, Refresh evidence, Load demo story) restore via finally. Verification posture: node --test driven by scripts/test_accessible_async_viewer_controls.py with --test-coverage-lines/branches/functions=100 on dom-utils.js. Linter/static: configured lint contracts are mvn verify and hadolint; no JS lint gate exists in the repo. TDD/regression: regression-first tests added with the fix - dom-utils.test.mjs (shared DOM contract) and demo-integration.test.mjs (repeated activation stays blocked). Coverage: Coverage execution evidence reports PASS - supported repository test suites passed; node coverage thresholds 100% on dom-utils.js enforced by the runner. Docstring coverage: configured repository docstring gates passed or advisory per Coverage execution evidence. DAG: base-to-head flowchart demo.js async actions -> setBusyState (dom-utils.js) -> restore callback -> node suite -> CI runner; CodeGraph blast radius shows dom-utils helpers consumed by demo.js. PoC/execution: no OPENCODE_EXECUTION_RECEIPT lines present in bounded evidence; suite outcome attested by trusted Coverage execution evidence PASS. DDD/domain: demo UI slice only; no domain model change. CDD/context: buyer-demo context only; viewer.js untouched. Similar issues: prior async busy-state UX work (#136/#146/#160) consolidated into a shared helper. Claim/concept check: 'nested-safe idempotent restore' claim is test-backed by the shared DOM contract suite. Standards search: WCAG 4.1.2 name/state semantics applied via aria-label and aria-busy; no external standard material required. Compatibility/convention: createActionButton/createLink gained an accessible-name parameter with all demo.js call sites updated; no single-word or reserved identifiers introduced; JS camelCase followed. Breaking-change/backcompat: module-local helpers only; no public contract change. Implementation completeness: all five async surfaces converted with finally restore; no placeholders. Performance: WeakMap-keyed busy state is O(1) per button; no innerHTML. Developer experience: stdlib-only CI-discoverable python runner matches the scripts/test_*.py repository convention. User experience: document-specific accessible names and stable busy states on demo history table actions. Visual/DOM: web UI change but no Playwright/browser execution receipt exists in bounded evidence; source-level DOM/ARIA trace plus the node DOM-mock suite is the available evidence. Accessibility/i18n: per-document aria-label, aria-busy toggling, disabled-state preservation; English-only strings unchanged. Supply-chain/license: no new dependencies (Python stdlib + node built-in test runner). Packaging: node files remain intentionally unpackaged per the repo dependency-free convention; the python script is stdlib-discoverable. Security/privacy: no innerHTML; textContent/replaceChildren only; demo auth headers pre-existing.

Approval sufficiency: bounded evidence supplied affirmative approval evidence for changed files, coverage/docstring posture, risk surfaces, and current-head verification; approval is not based merely on the absence of known blockers.
Verification posture: CodeGraph evidence was initialized and bounded current-head evidence reviewed for changed-file evidence including scripts/test_accessible_async_viewer_controls.py, src/main/resources/static/assets/viewer/demo.js, src/main/resources/static/assets/viewer/dom-utils.js, src/test/js/demo-integration.test.mjs, src/test/js/dom-utils.test.mjs, and 1 more.
Linter/static: workflow/static review evidence is bounded by the current-head GitHub Checks gate and changed-file evidence.
TDD/regression: coverage execution evidence and focused changed hunks were reviewed from bounded-review-evidence.md.
Coverage: coverage execution evidence reports supported repository test suites passed.
Docstring coverage: coverage execution evidence reports configured repository docstring gates passed or docstring coverage was advisory.
DAG: CodeGraph/source-backed behavior map connects scripts/test_accessible_async_viewer_controls.py to the affected review, runtime, or workflow path and required checks.
PoC/execution: coverage-evidence job executed on the current head and reported PASS.
DDD/domain: workflow and repository-governance invariants were reviewed against changed files in bounded evidence.
CDD/context: CodeGraph evidence, changed-file history, and focused hunks were reviewed from bounded-review-evidence.md.
Similar issues: changed-file history evidence was reviewed for comparable local precedents.
Claim/concept check: bounded evidence, repository source, current-head workflow evidence, and, where numeric, scientific, statistical, or literature-backed claims are affected, original-paper/formula evidence and parameter-recovery expectations were used for claims.
Standards search: standards and external-source claims require trusted bounded source evidence prepared outside the isolated model process; no evidence-backed standards blocker is present in bounded evidence.
Compatibility/convention: changed workflow/script conventions, object naming, and reserved-word safety for schema/API/config/code surfaces were checked in bounded evidence.
Breaking-change/backcompat: deployment evidence and changed-file history were checked for backward-compatibility risk.
Performance: changed surfaces were checked for performance risk in bounded evidence.
Developer experience: changed automation, review, test, setup, and maintenance surfaces were checked for helpful or obstructive DX impact in bounded evidence.
User experience: connected user, operator, API, CLI, documentation, review-comment, status-check, rendering, and workflow-reader behavior was checked for contradictions against code, docs, and tests in bounded evidence.
Visual/DOM: deterministic repair does not infer browser runtime execution; source-backed DOM/UI evidence and trusted workflow receipts were reviewed when present, and non-web surfaces used API/CLI/log/docs/workflow evidence instead.
Accessibility/i18n: accessibility, localization, and human-readable text surfaces were checked where UI, CLI, API message, docs, logs, or review text changed.
Supply-chain/license: dependency, package, model, container, and external-tool changes were checked in bounded evidence.
Packaging: package, build, test, lint, and security contracts were checked in bounded evidence.
Security/privacy: workflow-token, review-gate, and repository-automation security/privacy boundaries were checked in bounded evidence.

Adversarial validation

{"status":"passed","probes":[{"path":"src/main/resources/static/assets/viewer/demo.js","line":1,"hypothesis":"A rejected or overlapping async action (network failure, double activation in one tick) permanently disables the action button or restores the wrong child nodes/ARIA state.","attack_or_counterexample":"Trigger Status JSON/Details while the service is unreachable so fetchJson rejects, and activate the same button twice within one tick.","evidence":"Trusted source trace at src/main/resources/static/assets/viewer/demo.js:1 and the changed hunks: restore is registered via openJobDetail(job).finally(restore), openJsonDocument(...).finally(restore) and try/catch/finally in retryActiveJob, refreshKpiEvidence, loadDemoData, so restore runs on both rejection and success; the nested/idempotent restore contract is exercised by src/test/js/dom-utils.test.mjs and src/test/js/demo-integration.test.mjs, which scripts/test_accessible_async_viewer_controls.py:42-67 executes under node --test with 100% line/branch/function coverage on dom-utils.js and asserts returncode 0; Coverage execution evidence reports PASS for supported repository test suites. source-line-sha256=a9528c474f88ec16b2e28ad8eec74c1df01012bc26d7d8eb495996f37e4da375","outcome":"falsified"},{"path":"src/test/js/dom-utils.test.mjs","line":155,"hypothesis":"A crafted fileName containing HTML/quote characters, injected through the new accessible-name parameter, executes markup in the demo history table.","attack_or_counterexample":"fileName = '\" onmouseover=\"...' rendered through the third accessible-name argument of createActionButton and createLink.","evidence":"Trusted source trace at src/test/js/dom-utils.test.mjs:155 plus the demo.js hunks: all changed DOM writes use createElement/textContent/replaceChildren (fileCell.textContent = job.fileName || \"Document\"; rows built with append), the repo removed innerHTML in commit 83e1e349, and the accessible-name strings are plain string arguments to DOM-creation helpers never parsed as HTML; the shared DOM contract suite (dom-utils.test.mjs with mock-dom.mjs) passed per Coverage execution evidence with the runner's 100% branch/function thresholds on dom-utils.js. source-line-sha256=29576b54e255e3c948eea5b5904fa38b81682fdd3cbd9ae841ff0e7bd80d394c","outcome":"falsified"}],"residual_risk":"demo.js now requires ES-module context: the demoShellHtml script-tag type was not visible in bounded evidence (PR-head file reads were denied), so module loading relies on repo convention (viewerShellHtml loads viewer.js with type=\"module\"). dom-utils.js internals beyond the receipt lines were not directly readable; the 100% coverage gate plus PASS evidence mitigates this. No browser-runtime receipts exist, so Visual/DOM confirmation is source-level and node-DOM-mock based."}
  • Result: APPROVE
  • Reason: Nested-safe busy-state refactor is correct, regression-tested, and coverage-gated; both adversarial probes were falsified.
  • Head SHA: 56286060a01c739861e95ddfb76f0c3e307bad69
  • Workflow run: 31559314434
  • Workflow attempt: 1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants