Skip to content

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

Draft
seonghobae wants to merge 1 commit into
fix/pii-logging-16240128950440010639from
fix/accessible-async-viewer-controls
Draft

fix(accessibility): make asynchronous viewer actions nested-safe#264
seonghobae wants to merge 1 commit into
fix/pii-logging-16240128950440010639from
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.

This clean draft supersedes #162, whose managed branch repeatedly reintroduced stale workflow pins, duplicate changelog sections, and an unsafe innerHTML restoration recommendation.

Current clean reconstruction

Exact current head is f328ec5d1c3dec48c9a47181f194cb547c30a8b0.

It is one clean commit on authoritative parent #270 exact head 2ff43fc1b280f6de2ca903695e5cbeef5c0b3c17, zero commits behind, mergeable, and changes exactly seven bounded files:

  • .github/workflows/ci.yml;
  • CHANGELOG.md;
  • pom.xml;
  • 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.

The reconstruction preserves the parent’s dedicated artifact:read direct-download boundary and its current changelog evidence. Jules metadata and temporary write-scoped workflows are absent. All predecessor heads and predecessor check results are stale.

Product and accessibility contract

  • Document-specific accessible names for Details, Status JSON, and Open viewer actions.
  • A documented WeakMap-backed busy-state helper snapshots original child-node identities, disabled state, aria-busy, and aria-label exactly once.
  • Nested/repeated busy calls use depth counting and idempotent restore callbacks; only the final release restores original state.
  • External labels use textContent, Array.from(childNodes), and replaceChildren(...); no innerHTML backup or restoration.
  • Absence, empty values, and non-empty values of ARIA attributes are restored exactly.
  • Duplicate Details and Status JSON activation is blocked while work is pending.
  • Pending accessible names are operation-specific, including Loading status JSON....
  • Markup-like document names remain inert and original child-node identity survives restoration.

Executable contract

Node.js 24 tests cover exact DOM-node identity, initially disabled controls, all ARIA-value states, nested calls, duplicate restore callbacks, contextual names, safe new-tab attributes, inert markup-like labels, non-empty history rows, operation-specific pending state, and duplicate-activation blocking.

Maven verify runs the Node tests and requires 100% line, branch, and function coverage for production dom-utils.js; the exact-head and synthetic-merge CI paths both include Node.js 24 through the immutable action SHA 820762786026740c76f36085b0efc47a31fe5020.

Current acceptance state

For exact current head f328ec5d1c3dec48c9a47181f194cb547c30a8b0:

  • fuzz run 31086215835 completed successfully across all required targets;
  • CodeRabbit commit status is successful;
  • CodeRabbit independently inspected the exact seven-file parent-relative slice and found no source-level blocker, including the WeakMap depth/idempotence contract, exact DOM/ARIA restoration, operation-specific pending labels, inert text handling, immutable Node setup action pin, and Maven coverage integration;
  • this advisory comment and commit status are not a formal PR-level review or counted approval;
  • all inline review threads are resolved or outdated; zero actionable unresolved thread remains;
  • CI, Security Scan, SAST, Strix, formal CodeRabbit/OpenCode/Noema review submissions, and counted independent write-authorized approval are absent for this stacked head and therefore not passing.

Old evidence for ad29eab0b2ea925933adcd8c407affd027fa8ec2 and every other predecessor head is not reused. Queued, pending, cancelled, skipped-required, absent-required, stale-head, advisory-only, or status-only evidence is not passing.

Stack and merge gate

Keep this PR draft while parent #270 remains open. After #270 integrates, retarget this unchanged seven-file slice to protected main, confirm the same effective diff, and rerun every exact-head and base-sensitive gate.

Before merge, require formal exact-current-head CodeRabbit and OpenCode/Noema/Strix evidence, zero unresolved actionable threads, a counted approval from an independent reviewer with repository write permission, expected-head-safe satisfaction of every branch-protection rule, successful CI/security/accessibility/coverage/documentation/merge-compatibility/fuzz evidence, and preservation of the parent security contract. Do not bypass protections or infer approval from advisory status.

@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@seonghobae, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 12 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 448a810f-a1c8-4185-acd9-0d89cd0caf60

📥 Commits

Reviewing files that changed from the base of the PR and between 2ff43fc and f328ec5.

📒 Files selected for processing (7)
  • .github/workflows/ci.yml
  • CHANGELOG.md
  • pom.xml
  • 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

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

Copy link
Copy Markdown
Collaborator Author

@opencode-agent @cwl-noema-review @coderabbitai review

Independently review exact current head 718107a7a6eaca15a1f3e33ea7ceebefaf23d85a. Verify nested/repeated busy-state depth semantics, original DOM-node identity and ARIA/disabled-state restoration, duplicate-activation prevention, inert filename handling, operation-specific accessible names, exact 100% JavaScript helper coverage, immutable workflow action pins, removal of privileged one-shot workflows, and same-head CI/Security/SAST/fuzz evidence. Submit APPROVE only for this exact head if every required gate is satisfied; advisory bot output is not a substitute for the protected branch's counted independent approval.

@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'
head='718107a7a6eaca15a1f3e33ea7ceebefaf23d85a'
prior='b3453021182e99337e67d8b57a237f7196bd4e53'

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

echo '== Exact-head focused diff =='
git diff --check "$prior" "$head"
git diff --name-status "$prior" "$head"
git diff --unified=40 "$prior" "$head" -- \
  src/main/resources/static/assets/viewer/demo.js \
  src/test/js/demo-integration.test.mjs

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-state helper =='
nl -ba src/main/resources/static/assets/viewer/dom-utils.js | sed -n '1,240p'

echo '== Action consumers and accessible names =='
nl -ba src/main/resources/static/assets/viewer/demo.js | sed -n '70,165p'
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,590p'

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

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

echo '== Workflow pins and privileged workflow inventory =='
rg -n -C 5 -P 'uses:\s*[^[:space:]@]+@[0-9a-f]{40}|actions/setup-node@|node-version:' .github/workflows
fd -t f . .github/workflows | sort
rg -n -i -C 4 -P '(contents:\s*write|pull-requests:\s*write|persist-credentials:\s*true|reconcile)' .github/workflows || true

echo '== PDF.js version contract =='
rg -n -C 3 -P '(pdfjs|pdf\.js|PDF\.js|6\.1\.200)' pom.xml src/main README.md || true

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

echo '== Unresolved review threads =='
gh api graphql \
  -F owner='ContextualWisdomLab' -F name='clearfolio' -F number=264 \
  -f query='
query($owner: String!, $name: String!, $number: Int!) {
  repository(owner: $owner, name: $name) {
    pullRequest(number: $number) {
      reviewThreads(first: 100) {
        nodes {
          isResolved
          comments(first: 1) { nodes { author { login } path line body } }
        }
      }
    }
  }
}' \
  --jq '.data.repository.pullRequest.reviewThreads.nodes[]
    | select(.isResolved == false)
    | [.comments.nodes[0].author.login,.comments.nodes[0].path,(.comments.nodes[0].line | tostring),.comments.nodes[0].body]
    | `@tsv`' || true

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

Length of output: 24510


🏁 Script executed:

#!/bin/bash
set -euo pipefail

repo='ContextualWisdomLab/clearfolio'
head='718107a7a6eaca15a1f3e33ea7ceebefaf23d85a'

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 action consumers =='
numbered src/main/resources/static/assets/viewer/demo.js | sed -n '70,165p'
numbered src/main/resources/static/assets/viewer/demo.js | sed -n '215,330p'
numbered src/main/resources/static/assets/viewer/demo.js | sed -n '420,590p'

echo '== Busy-state unit tests =='
numbered src/test/js/dom-utils.test.mjs | sed -n '1,520p'

echo '== Production integration test =='
numbered src/test/js/demo-integration.test.mjs | sed -n '110,300p'

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

echo '== Workflow inventory and action references =='
fd -t f . .github/workflows | sort
rg -n -C 5 -P '^\s*uses:|actions/setup-node@|node-version:|contents:\s*write|pull-requests:\s*write|persist-credentials:\s*true|reconcile' .github/workflows || true

echo '== PDF.js version references =='
rg -n -C 3 -P '(pdfjs|pdf\.js|PDF\.js|6\.1\.200)' pom.xml src/main README.md || true

echo '== Unresolved review threads =='
gh api graphql \
  -F owner='ContextualWisdomLab' -F name='clearfolio' -F number=264 \
  -f query='
query($owner: String!, $name: String!, $number: Int!) {
  repository(owner: $owner, name: $name) {
    pullRequest(number: $number) {
      reviewThreads(first: 100) {
        nodes {
          isResolved
          comments(first: 1) { nodes { author { login } path line body } }
        }
      }
    }
  }
}' \
  --jq '.data.repository.pullRequest.reviewThreads.nodes[]
    | select(.isResolved == false)
    | [.comments.nodes[0].author.login,.comments.nodes[0].path,(.comments.nodes[0].line | tostring),.comments.nodes[0].body]
    | `@tsv`' || true

echo '== Rules and protection data =='
gh api "repos/$repo/branches/main/protection" || true
gh api "repos/$repo/rules/branches/main" || true
gh api "repos/$repo/rulesets?includes_parents=true" || true

echo '== Current PR merge requirements =='
gh pr view 264 --repo "$repo" \
  --json headRefOid,mergeStateStatus,reviewDecision,statusCheckRollup,latestReviews

Length of output: 62600


@seonghobae Review complete for exact head 718107a7a6eaca15a1f3e33ea7ceebefaf23d85a.

I found no source-level blocker.

  • setBusyState uses WeakMap state and depth counting.
  • Each restore callback is idempotent.
  • The helper restores only after the final restore call.
  • The helper preserves original child-node identities with Array.from(button.childNodes) and replaceChildren(...).
  • The helper restores the original disabled, aria-busy, and aria-label states. It distinguishes absent and empty ARIA values.
  • Details and Status JSON apply the helper before asynchronous work.
  • Status JSON uses Loading status JSON... and restores state through .finally(restore).
  • Native disabled-button behavior prevents repeated user activation while the request is pending.
  • Details, Status JSON, and Open viewer have document-specific accessible names.
  • Filenames use textContent. Markup-like filenames remain inert text.
  • The helper tests cover nesting, duplicate restores, original node identity, disabled controls, and ARIA restoration.
  • The production integration test verifies the pending Status JSON label, disabled state, aria-busy, exact restoration, popup opener isolation, and JSON rendering.
  • Maven runs the Node tests during test and requires 100% line, branch, and function coverage for dom-utils.js.
  • Node.js 24 and actions/setup-node use the configured full-SHA workflow pin.
  • The workflow inventory contains no privileged reconciliation workflow.
  • The PDF.js paths remain at version 6.1.200.
  • Exact-head Maven, Security Scan, Semgrep, fuzz, CodeQL, and strix checks are successful.
  • The review-thread query found no unresolved threads.

I cannot submit approval. GitHub still reports BLOCKED and REVIEW_REQUIRED. The available repository ruleset requires one approving repository review, and that approval is not present. The branch-protection API returned HTTP 403, so I could not inspect its complete configuration.

You are interacting with an AI system.

Copy link
Copy Markdown
Collaborator Author

@opencode-agent @cwl-noema-review Independently review exact current head 718107a7a6eaca15a1f3e33ea7ceebefaf23d85a. Exact-head CI 30977565425, Security Scan 30977565430, SAST Semgrep 30977565499, fuzz 30977565442, and CodeRabbit status are successful. The two prior GitHub Advanced Security token-permission findings are resolved and outdated after the temporary write-scoped workflows were removed; there are zero unresolved threads. Verify keyboard and assistive-technology behavior, accessible loading and focus semantics, deterministic tests, least-privilege workflow state, coverage/Javadocs, and repository policy. Approve or recommend merge only for this exact head and only if independent-review policy is satisfied.

Copy link
Copy Markdown
Collaborator Author

@opencode-agent @cwl-noema-review Please independently review exact current head 718107a7a6eaca15a1f3e33ea7ceebefaf23d85a. Verify nested and repeated busy-state restoration, preservation of original DOM node identities and pre-existing disabled/ARIA state, inert handling of markup-like labels, contextual accessible names, Status JSON pending semantics, exact 100% production JavaScript coverage, immutable workflow-source pins, and all exact-head CI, security, fuzz, and repository protections. Submit APPROVE only for this exact head.

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@opencode-agent @cwl-noema-review Please independently review exact current head 718107a7a6eaca15a1f3e33ea7ceebefaf23d85a only. Verify the accessible asynchronous viewer contract: document-specific accessible names, operation-specific pending names, nested/repeated busy depth, idempotent restoration, exact preservation of child-node identity and prior disabled/ARIA state, inert treatment of markup-like filenames, duplicate-activation prevention, and executable Node DOM tests with 100% production line, branch, and function coverage. Confirm the previously flagged write-scoped reconciliation workflow is absent and no stale workflow finding remains.

Exact-head Actions are successful: CI 30977565425, Security Scan 30977565430, SAST Semgrep 30977565499, and fuzz 30977565442. Existing GitHub Advanced Security threads are resolved and outdated. Submit a formal exact-head review and APPROVE only if no blocker remains; do not treat a commit status, stale comment, or owner review as independent approval.

@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'
head='718107a7a6eaca15a1f3e33ea7ceebefaf23d85a'
prior='b3453021182e99337e67d8b57a237f7196bd4e53'

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

echo '== Exact-head delta =='
git diff --check "$prior" "$head"
git diff --name-status "$prior" "$head"
git diff --unified=35 "$prior" "$head" -- \
  src/main/resources/static/assets/viewer/demo.js \
  src/test/js/demo-integration.test.mjs

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-state helper =='
nl -ba src/main/resources/static/assets/viewer/dom-utils.js | sed -n '1,240p'

echo '== Viewer actions and accessible labels =='
nl -ba src/main/resources/static/assets/viewer/demo.js | sed -n '70,170p'
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,590p'

echo '== Busy-state unit tests and viewer integration test =='
nl -ba src/test/js/dom-utils.test.mjs | sed -n '1,520p'
nl -ba src/test/js/demo-integration.test.mjs | sed -n '100,330p'

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

echo '== Workflow inventory, pins, and privileged-workflow indicators =='
fd -t f . .github/workflows | sort
rg -n -C 5 -P '^\s*uses:|actions/setup-node@|node-version:|contents:\s*write|pull-requests:\s*write|persist-credentials:\s*true|reconcile' .github/workflows || true

echo '== PDF.js version contract =='
rg -n -C 3 -P '(pdfjs|pdf\.js|PDF\.js|6\.1\.200)' pom.xml src/main README.md || true

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

echo '== Unresolved review threads =='
gh api graphql \
  -F owner='ContextualWisdomLab' -F name='clearfolio' -F number=264 \
  -f query='
query($owner: String!, $name: String!, $number: Int!) {
  repository(owner: $owner, name: $name) {
    pullRequest(number: $number) {
      reviewThreads(first: 100) {
        nodes {
          isResolved
          comments(first: 1) { nodes { author { login } path line body } }
        }
      }
    }
  }
}' \
  --jq '.data.repository.pullRequest.reviewThreads.nodes[]
    | select(.isResolved == false)
    | [.comments.nodes[0].author.login,.comments.nodes[0].path,(.comments.nodes[0].line | tostring),.comments.nodes[0].body]
    | `@tsv`' || true

echo '== Protection and ruleset data =='
gh api "repos/$repo/branches/main/protection" || true
gh api "repos/$repo/rules/branches/main" || true
gh api "repos/$repo/rulesets?includes_parents=true" || true

Length of output: 23725


🏁 Script executed:

#!/bin/bash
set -euo pipefail

repo='ContextualWisdomLab/clearfolio'
head='718107a7a6eaca15a1f3e33ea7ceebefaf23d85a'

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 '== Viewer action consumers =='
numbered src/main/resources/static/assets/viewer/demo.js | sed -n '70,170p'
numbered src/main/resources/static/assets/viewer/demo.js | sed -n '215,330p'
numbered src/main/resources/static/assets/viewer/demo.js | sed -n '420,590p'

echo '== Busy-state unit tests =='
numbered src/test/js/dom-utils.test.mjs | sed -n '1,520p'

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

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

echo '== Workflow inventory and relevant references =='
fd -t f . .github/workflows | sort
rg -n -C 5 -P '^\s*uses:|actions/setup-node@|node-version:|contents:\s*write|pull-requests:\s*write|persist-credentials:\s*true|reconcile' .github/workflows || true

echo '== PDF.js version contract =='
rg -n -C 3 -P '(pdfjs|pdf\.js|PDF\.js|6\.1\.200)' pom.xml src/main README.md || true

echo '== Unresolved review threads =='
gh api graphql \
  -F owner='ContextualWisdomLab' -F name='clearfolio' -F number=264 \
  -f query='
query($owner: String!, $name: String!, $number: Int!) {
  repository(owner: $owner, name: $name) {
    pullRequest(number: $number) {
      reviewThreads(first: 100) {
        nodes {
          isResolved
          comments(first: 1) { nodes { author { login } path line body } }
        }
      }
    }
  }
}' \
  --jq '.data.repository.pullRequest.reviewThreads.nodes[]
    | select(.isResolved == false)
    | [.comments.nodes[0].author.login,.comments.nodes[0].path,(.comments.nodes[0].line | tostring),.comments.nodes[0].body]
    | `@tsv`' || true

echo '== Current PR state and available protection data =='
gh pr view 264 --repo "$repo" \
  --json headRefOid,mergeStateStatus,reviewDecision,latestReviews,statusCheckRollup
gh api "repos/$repo/branches/main/protection" || true
gh api "repos/$repo/rules/branches/main" || true
gh api "repos/$repo/rulesets?includes_parents=true" || true

Length of output: 63105


@seonghobae Review complete for exact head 718107a7a6eaca15a1f3e33ea7ceebefaf23d85a.

I found no source-level blocker.

  • setBusyState uses WeakMap state and depth counting.
  • Restore callbacks are idempotent.
  • The helper restores state only after the final restore call.
  • The helper preserves original child-node identities with Array.from(button.childNodes) and replaceChildren(...).
  • The helper restores the original disabled, aria-busy, and aria-label values. It distinguishes absent and empty ARIA values.
  • Details, Status JSON, and Open viewer have document-specific accessible names.
  • Status JSON applies setBusyState before the asynchronous request. It uses Loading status JSON... and restores state in .finally(restore).
  • A disabled native button prevents repeated user activation during the pending request.
  • Filenames use textContent. The tests verify that markup-like filenames remain inert text.
  • The integration test verifies the pending Status JSON label, disabled state, aria-busy, restored state, popup opener isolation, and rendered JSON.
  • Maven runs the Node tests during test. It requires 100% line, branch, and function coverage for src/main/resources/static/assets/viewer/dom-utils.js.
  • CI uses Node.js 24 and a full-SHA actions/setup-node pin.
  • The checked workflow inventory contains no reconciliation workflow or write-scoped workflow indicator.
  • The PDF.js module and worker paths remain at version 6.1.200.
  • Maven, Security Scan, Semgrep, Strix, CodeQL, and fuzz checks succeeded for this exact head.
  • The review-thread query returned no unresolved threads.

I cannot approve this pull request. GitHub still reports BLOCKED and REVIEW_REQUIRED. The repository ruleset requires one approving repository review, and the current review list does not contain that approval. The branch-protection endpoint returned HTTP 403, so I could not inspect its complete 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 718107a7a6eaca15a1f3e33ea7ceebefaf23d85a. Verify the WeakMap depth-counted busy-state contract, exact child-node identity and disabled/ARIA restoration, inert handling of markup-like document names, operation-specific accessible names, duplicate-activation prevention, executable Node 24 DOM tests with 100% line/branch/function coverage for the production helper, immutable action pins, and absence of the superseded write-scoped reconciliation workflows. Exact-head CI, Security Scan, SAST, and fuzz are successful; submit formal review evidence only for this head.

@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown
🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

repo='ContextualWisdomLab/clearfolio'
head='718107a7a6eaca15a1f3e33ea7ceebefaf23d85a'
prior='b3453021182e99337e67d8b57a237f7196bd4e53'

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

echo '== Exact-head delta and whitespace =='
git diff --check "$prior" "$head"
git diff --name-status "$prior" "$head"
git diff --unified=35 "$prior" "$head" -- \
  src/main/resources/static/assets/viewer/demo.js \
  src/test/js/demo-integration.test.mjs

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-state helper =='
nl -ba src/main/resources/static/assets/viewer/dom-utils.js | sed -n '1,250p'

echo '== Viewer action consumers =='
nl -ba src/main/resources/static/assets/viewer/demo.js | sed -n '65,180p'
nl -ba src/main/resources/static/assets/viewer/demo.js | sed -n '210,340p'
nl -ba src/main/resources/static/assets/viewer/demo.js | sed -n '415,600p'

echo '== Unit and integration test assertions =='
nl -ba src/test/js/dom-utils.test.mjs | sed -n '1,540p'
nl -ba src/test/js/demo-integration.test.mjs | sed -n '90,350p'

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

echo '== Workflow inventory, immutable pins, and privileged indicators =='
fd -t f . .github/workflows | sort
rg -n -C 5 -P '^\s*uses:|actions/setup-node@|node-version:|contents:\s*write|pull-requests:\s*write|persist-credentials:\s*true|reconcile' .github/workflows || true

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

echo '== Unresolved review threads =='
gh api graphql \
  -F owner='ContextualWisdomLab' -F name='clearfolio' -F number=264 \
  -f query='
query($owner: String!, $name: String!, $number: Int!) {
  repository(owner: $owner, name: $name) {
    pullRequest(number: $number) {
      reviewThreads(first: 100) {
        nodes {
          isResolved
          comments(first: 1) { nodes { author { login } path line body } }
        }
      }
    }
  }
}' \
  --jq '.data.repository.pullRequest.reviewThreads.nodes[]
    | select(.isResolved == false)
    | [.comments.nodes[0].author.login, .comments.nodes[0].path, (.comments.nodes[0].line | tostring), .comments.nodes[0].body]
    | `@tsv`' || true

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

Length of output: 23619


🏁 Script executed:

#!/bin/bash
set -euo pipefail

repo='ContextualWisdomLab/clearfolio'
head='718107a7a6eaca15a1f3e33ea7ceebefaf23d85a'

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,250p'

echo '== Viewer action consumers =='
numbered src/main/resources/static/assets/viewer/demo.js | sed -n '65,180p'
numbered src/main/resources/static/assets/viewer/demo.js | sed -n '210,340p'
numbered src/main/resources/static/assets/viewer/demo.js | sed -n '415,600p'

echo '== Busy-state unit tests =='
numbered src/test/js/dom-utils.test.mjs | sed -n '1,540p'

echo '== Production integration test =='
numbered src/test/js/demo-integration.test.mjs | sed -n '90,350p'

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

echo '== Workflow inventory and relevant references =='
fd -t f . .github/workflows | sort
rg -n -C 5 -P '^\s*uses:|actions/setup-node@|node-version:|contents:\s*write|pull-requests:\s*write|persist-credentials:\s*true|reconcile' .github/workflows || true

echo '== Unresolved review threads =='
gh api graphql \
  -F owner='ContextualWisdomLab' -F name='clearfolio' -F number=264 \
  -f query='
query($owner: String!, $name: String!, $number: Int!) {
  repository(owner: $owner, name: $name) {
    pullRequest(number: $number) {
      reviewThreads(first: 100) {
        nodes {
          isResolved
          comments(first: 1) { nodes { author { login } path line body } }
        }
      }
    }
  }
}' \
  --jq '.data.repository.pullRequest.reviewThreads.nodes[]
    | select(.isResolved == false)
    | [.comments.nodes[0].author.login, .comments.nodes[0].path, (.comments.nodes[0].line | tostring), .comments.nodes[0].body]
    | `@tsv`' || true

echo '== Current PR review and merge state =='
gh pr view 264 --repo "$repo" \
  --json headRefOid,mergeStateStatus,reviewDecision,latestReviews,statusCheckRollup

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

echo '== Exact-head check state summary =='
gh api "repos/$repo/commits/$head/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")) or (.name | startswith("Analyze")))
    | [.name,.status,.conclusion]
    | `@tsv`'

Length of output: 56758


@seonghobae Review complete for exact head 718107a7a6eaca15a1f3e33ea7ceebefaf23d85a.

I found no source-level blocker.

  • setBusyState uses WeakMap state and depth counting.
  • Each restore callback is idempotent.
  • The helper restores state only after the final restore call.
  • The helper preserves child-node identity with Array.from(button.childNodes) and replaceChildren(...).
  • The helper restores the original disabled, aria-busy, and aria-label values. It distinguishes absent and empty ARIA values.
  • Details, Status JSON, and Open viewer have document-specific accessible names.
  • Status JSON applies setBusyState(btn, "Loading status JSON...") before asynchronous work. Its .finally(restore) call restores the original state.
  • A disabled native button prevents repeated user activation while the JSON request is pending.
  • The integration test verifies the operation-specific pending name, disabled state, aria-busy, restored state, inert markup-like filename text, popup opener isolation, and JSON rendering.
  • Maven runs the Node DOM tests during test.
  • Maven requires 100% line, branch, and function coverage for src/main/resources/static/assets/viewer/dom-utils.js.
  • CI uses Node.js 24 and a full-SHA actions/setup-node pin.
  • The checked workflow inventory contains no reconciliation workflow or write-scoped workflow indicator.
  • Exact-head Maven, Semgrep, OSV scan, Strix, CodeQL, and all fuzz checks succeeded.
  • The review-thread query found no unresolved threads.

I cannot approve this pull request yet. GitHub reports BLOCKED and REVIEW_REQUIRED. The repository ruleset requires one approving repository review, and latestReviews contains no approval. The branch-protection REST endpoint returned HTTP 403, so I could not inspect its complete configuration.

⚠️ 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 marked this pull request as draft August 6, 2026 02:58
auto-merge was automatically disabled August 6, 2026 02:58

Pull request was converted to draft

Copy link
Copy Markdown
Collaborator Author

Dependency-order correction: this PR is now Draft so it cannot auto-merge ahead of authoritative security parent #270. Both slices modify shared pom.xml, CI, and CHANGELOG.md; allowing #264 to merge first would invalidate #270's current synthetic-merge and generated-evidence assumptions and force avoidable reconciliation.

After #270 integrates, rebuild or reconcile this same bounded accessibility implementation onto the resulting protected main, preserve the WeakMap nested/idempotent busy-state and exact DOM/ARIA restoration contract, and rerun exact-head CI, Security Scan, SAST, fuzz, CodeRabbit/OpenCode/Noema/Strix, zero unresolved threads, and counted independent approval. Previous head 718107a7a6eaca15a1f3e33ea7ceebefaf23d85a remains provenance, not post-parent merge evidence. Do not re-enable auto-merge before that reconciliation.

@seonghobae
seonghobae force-pushed the fix/accessible-async-viewer-controls branch from 718107a to 0326f8f Compare August 6, 2026 03:14
Comment thread .github/workflows/ci.yml Fixed
@seonghobae seonghobae changed the title fix: make asynchronous viewer actions accessible and nested-safe fix(accessibility): make asynchronous viewer actions nested-safe Aug 6, 2026

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@opencode-agent @cwl-noema-review Please independently review exact current head ad29eab0b2ea925933adcd8c407affd027fa8ec2 only, treating the divergent predecessor head and all predecessor results as stale.

This draft is a clean descendant of parent #270 exact 26563218ae42eaa876c784fcf56b27f8cb810080, 5 commits ahead and 0 behind. The effective parent-relative diff is exactly seven files. Verify the WeakMap depth and idempotent restore contract; exact original child-node, disabled, aria-busy, and aria-label restoration; contextual accessible names; operation-specific Status JSON pending state; duplicate-activation blocking; inert markup-like labels; safe new-tab defaults; Node.js 24 immutable action pin; 100% line/branch/function coverage for dom-utils.js; and preservation of every #270 privacy, Netty, SBOM/attribution, Maven-report, zero-missed production coverage, and public-Javadoc contract.

Exact-head evidence is CI 31068159869 (Maven 92510259829: 472 Java tests plus 8 Node tests, zero failures/errors/skips, Node coverage 100% line/branch/function, 59 production classes, zero missed Java lines/branches, warning-free public Javadocs, Surefire tests=472 skipped=0; merge compatibility 92510259774; buyer scripts 92510259790), Security Scan 31068159898, SAST Semgrep 31068159918, and fuzz 31068159875, all successful. Current inline review threads are zero unresolved; historical GHAS workflow findings are resolved and outdated.

Submit actionable current-head findings or a formal review only after your own inspection. Parent #270 integration and a counted independent write-authorized approval remain separate mandatory gates.

@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown
🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

repo='ContextualWisdomLab/clearfolio'
head='ad29eab0b2ea925933adcd8c407affd027fa8ec2'
parent='26563218ae42eaa876c784fcf56b27f8cb810080'

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

echo '== Parent ancestry and bounded parent-relative diff =='
git merge-base --is-ancestor "$parent" "$head" && echo 'parent_is_ancestor=true'
printf 'commits_ahead_of_parent='
git rev-list --count "${parent}..${head}"
printf 'commits_parent_ahead_of_head='
git rev-list --count "${head}..${parent}"
git diff --check "$parent" "$head"
git diff --name-status "$parent" "$head"
git diff --stat "$parent" "$head"

echo '== Changed-file outlines =='
while IFS= read -r file; do
  case "$file" in
    *.js|*.mjs|*.cjs)
      echo "--- $file"
      ast-grep outline "$file" --items all || true
      ;;
  esac
done < <(git diff --name-only "$parent" "$head")

echo '== Busy-state helper and viewer consumers =='
nl -ba src/main/resources/static/assets/viewer/dom-utils.js | sed -n '1,260p'
nl -ba src/main/resources/static/assets/viewer/demo.js | sed -n '60,180p'
nl -ba src/main/resources/static/assets/viewer/demo.js | sed -n '210,350p'
nl -ba src/main/resources/static/assets/viewer/demo.js | sed -n '410,620p'

echo '== Executable Node test modules (read only) =='
nl -ba src/test/js/dom-utils.test.mjs | sed -n '1,560p'
nl -ba src/test/js/demo-integration.test.mjs | sed -n '1,620p'

echo '== Maven coverage, Java quality gates, and Node test integration =='
rg -n -C 20 -P '(dom-utils|node|c8|coverage|line|branch|function|exec-maven|jacoco|javadoc|surefire)' pom.xml

echo '== CI Node pin and workflow inventory =='
rg -n -C 8 -P '(actions/setup-node@|node-version:|permissions:|contents:\s*write|pull-requests:\s*write|persist-credentials:\s*true)' .github/workflows || true
fd -t f . .github/workflows | sort

echo '== Complete parent-relative diff =='
git diff --unified=35 "$parent" "$head" -- \
  .github/workflows pom.xml CHANGELOG.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 '== Parent-contract reference scan =='
rg -n -C 3 -P '(privacy|Netty|netty|SBOM|attribution|jacoco|javadoc|maven-report|zero missed|pdfjs|6\.1\.200)' \
  pom.xml CHANGELOG.md src/main .github/workflows || true

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

echo '== Unresolved pull request threads =='
gh api graphql \
  -F owner='ContextualWisdomLab' -F name='clearfolio' -F number=264 \
  -f query='
query($owner: String!, $name: String!, $number: Int!) {
  repository(owner: $owner, name: $name) {
    pullRequest(number: $number) {
      reviewThreads(first: 100) {
        nodes {
          isResolved
          comments(first: 1) { nodes { author { login } path line body } }
        }
      }
    }
  }
}' \
  --jq '.data.repository.pullRequest.reviewThreads.nodes[]
    | select(.isResolved == false)
    | [.comments.nodes[0].author.login,.comments.nodes[0].path,(.comments.nodes[0].line|tostring),.comments.nodes[0].body] | `@tsv`' || true

echo '== Available repository protection and rulesets =='
gh api "repos/$repo/branches/main/protection" || true
gh api "repos/$repo/rules/branches/main" || true
gh api "repos/$repo/rulesets?includes_parents=true" || true

Length of output: 15868


🏁 Script executed:

#!/bin/bash
set -euo pipefail

repo='ContextualWisdomLab/clearfolio'
head='ad29eab0b2ea925933adcd8c407affd027fa8ec2'
parent='26563218ae42eaa876c784fcf56b27f8cb810080'

echo '== Relevant source and test outlines =='
for file in \
  src/main/resources/static/assets/viewer/dom-utils.js \
  src/main/resources/static/assets/viewer/demo.js \
  src/test/js/dom-utils.test.mjs \
  src/test/js/demo-integration.test.mjs
do
  echo "--- $file"
  ast-grep outline "$file" --items all || true
done

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

echo '== Viewer actions and accessible labels =='
nl -ba src/main/resources/static/assets/viewer/demo.js | sed -n '60,190p'
nl -ba src/main/resources/static/assets/viewer/demo.js | sed -n '210,360p'
nl -ba src/main/resources/static/assets/viewer/demo.js | sed -n '410,640p'

echo '== Node DOM unit tests =='
nl -ba src/test/js/dom-utils.test.mjs | sed -n '1,600p'

echo '== Demo-module integration tests =='
nl -ba src/test/js/demo-integration.test.mjs | sed -n '1,680p'

echo '== Maven integration, coverage, and Java quality gates =='
rg -n -C 24 -P '(dom-utils|node|c8|coverage|line|branch|function|exec-maven|jacoco|javadoc|surefire|maven-report)' pom.xml

echo '== Workflow pinning and permission indicators =='
fd -t f . .github/workflows | sort
rg -n -C 8 -P '(actions/setup-node@|node-version:|permissions:|contents:\s*write|pull-requests:\s*write|persist-credentials:\s*true)' .github/workflows || true

echo '== Full parent-relative diff =='
git diff --unified=45 "$parent" "$head" -- \
  .github/workflows/ci.yml CHANGELOG.md 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 '== Parent-contract references in the effective tree =='
rg -n -C 4 -i -P '(privacy|netty|sbom|attribution|jacoco|javadoc|maven-report|pdfjs|6\.1\.200)' \
  pom.xml CHANGELOG.md src/main .github/workflows || true

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

echo '== Unresolved review threads =='
gh api graphql \
  -F owner='ContextualWisdomLab' -F name='clearfolio' -F number=264 \
  -f query='
query($owner: String!, $name: String!, $number: Int!) {
  repository(owner: $owner, name: $name) {
    pullRequest(number: $number) {
      reviewThreads(first:100) {
        nodes {
          isResolved
          comments(first:1) { nodes { author { login } path line body } }
        }
      }
    }
  }
}' \
  --jq '.data.repository.pullRequest.reviewThreads.nodes[]
    | select(.isResolved == false)
    | [.comments.nodes[0].author.login,.comments.nodes[0].path,(.comments.nodes[0].line|tostring),.comments.nodes[0].body] | `@tsv`' || true

echo '== Current review and repository policy data =='
gh pr view 264 --repo "$repo" \
  --json headRefOid,mergeStateStatus,reviewDecision,latestReviews,statusCheckRollup
gh api "repos/$repo/branches/main/protection" || true
gh api "repos/$repo/rules/branches/main" || true
gh api "repos/$repo/rulesets?includes_parents=true" || true

Length of output: 7159


🏁 Script executed:

#!/bin/bash
set -euo pipefail

repo='ContextualWisdomLab/clearfolio'
head='ad29eab0b2ea925933adcd8c407affd027fa8ec2'
parent='26563218ae42eaa876c784fcf56b27f8cb810080'

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,260p'

echo '== Viewer action consumers =='
numbered src/main/resources/static/assets/viewer/demo.js | sed -n '70,165p'
numbered src/main/resources/static/assets/viewer/demo.js | sed -n '220,325p'
numbered src/main/resources/static/assets/viewer/demo.js | sed -n '420,610p'

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

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

echo '== Maven test integration and quality thresholds =='
rg -n -C 20 -P '(dom-utils|node|c8|coverage|line|branch|function|exec-maven|jacoco|javadoc|surefire|maven-report)' pom.xml

echo '== Workflow references and permission indicators =='
find .github/workflows -type f -print | sort
rg -n -C 8 -P '(actions/setup-node@|node-version:|permissions:|contents:\s*write|pull-requests:\s*write|persist-credentials:\s*true)' .github/workflows || true

echo '== Full parent-relative diff =='
git diff --unified=35 "$parent" "$head" -- \
  .github/workflows/ci.yml CHANGELOG.md 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 '== Parent-contract reference scan =='
rg -n -C 4 -i -P '(privacy|netty|sbom|attribution|jacoco|javadoc|maven-report|pdfjs|6\.1\.200)' \
  pom.xml CHANGELOG.md src/main .github/workflows || true

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

echo '== Unresolved review threads =='
gh api graphql \
  -F owner='ContextualWisdomLab' -F name='clearfolio' -F number=264 \
  -f query='
query($owner: String!, $name: String!, $number: Int!) {
  repository(owner: $owner, name: $name) {
    pullRequest(number: $number) {
      reviewThreads(first:100) {
        nodes {
          isResolved
          comments(first:1) { nodes { author { login } path line body } }
        }
      }
    }
  }
}' \
  --jq '.data.repository.pullRequest.reviewThreads.nodes[]
    | select(.isResolved == false)
    | [.comments.nodes[0].author.login,.comments.nodes[0].path,(.comments.nodes[0].line|tostring),.comments.nodes[0].body] | `@tsv`' || true

echo '== Current pull request state and available policy 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
gh api "repos/$repo/rulesets?includes_parents=true" || true

Length of output: 126239


@seonghobae Review complete for exact head ad29eab0b2ea925933adcd8c407affd027fa8ec2.

I found no current source-level blocker.

The inspected head is a descendant of parent head 26563218ae42eaa876c784fcf56b27f8cb810080. It is five commits ahead and zero commits behind. The effective diff changes seven files. git diff --check reported no whitespace errors.

I verified the following items:

  • setBusyState uses WeakMap state and depth counting.
  • Each restore callback is idempotent.
  • The final restore restores the original child-node identities with replaceChildren(...).
  • The helper restores the original disabled, aria-busy, and aria-label values. It distinguishes absent and empty ARIA values.
  • Details and Status JSON set busy state before asynchronous work. Both restore state through .finally(restore).
  • Status JSON uses the operation-specific pending name Loading status JSON....
  • A disabled native button prevents repeated user activation during the pending request.
  • Details, Status JSON, and Open viewer have document-specific accessible names.
  • File names use textContent. The integration test verifies that markup-like file names remain inert.
  • New-tab links use target="_blank" with rel="noopener noreferrer".
  • The integration test verifies pending state, restored state, popup opener isolation, JSON rendering, and a non-empty history row.
  • Maven runs both Node DOM test modules during test.
  • Maven requires 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 full SHA 820762786026740c76f36085b0efc47a31fe5020.
  • The effective tree retains the inspected PDF.js 6.1.200, Netty, JaCoCo zero-missed-line/branch, public-Javadoc, privacy, and attribution-related configuration.
  • The exact-head Maven, merge-compatibility, buyer-readiness, Semgrep, OSV, fuzz, and CodeQL checks were successful.
  • The review-thread query returned no unresolved threads.

I cannot approve this draft.

The current exact-head query reports strix as in_progress. GitHub reports BLOCKED and REVIEW_REQUIRED. The repository rules require one approving review, and the current review list has no approval. The branch-protection API returned HTTP 403, so complete branch-protection verification is unavailable.

After #270 merges, this head must be reconciled with protected main. The current check results must then be replaced with new exact-head and merge-revision evidence.

⚠️ 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 changed the base branch from main to fix/pii-logging-16240128950440010639 August 6, 2026 03:32

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@opencode-agent @cwl-noema-review Independently review exact current head ad29eab0b2ea925933adcd8c407affd027fa8ec2 relative to parent #270 exact 26563218ae42eaa876c784fcf56b27f8cb810080. The clean stack is 5 commits ahead, 0 behind, mergeable, and contains exactly seven bounded accessibility/build files.

Verify WeakMap-backed nested and idempotent busy-state depth; exact child-node identity, disabled-state, aria-busy, and aria-label restoration; absent/empty/non-empty ARIA preservation; inert markup-like filenames; contextual accessible names; duplicate Details and Status JSON activation prevention; final-release-only restoration; safe popup/link attributes; immutable Node setup pin; Maven exact-head and synthetic-merge Node integration; and 100% line/branch/function coverage for production dom-utils.js without innerHTML backup/restore.

Exact-head CI 31068159869, Security Scan 31068159898, SAST Semgrep 31068159918, and fuzz 31068159875 all succeeded; unresolved inline threads are zero. Keep Draft behind #270, report exact-head findings or advisory review evidence, and do not infer the missing counted independent human approval.

@coderabbitai

coderabbitai Bot commented Aug 6, 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'
head='ad29eab0b2ea925933adcd8c407affd027fa8ec2'
parent='26563218ae42eaa876c784fcf56b27f8cb810080'

echo '== Exact identity, ancestry, and PR state =='
printf 'checkout='; git rev-parse HEAD
git show -s --format='commit=%H%nparents=%P%nsubject=%s' "$head"
git merge-base --is-ancestor "$parent" "$head" && echo 'parent_is_ancestor=true'
printf 'ahead='; git rev-list --count "${parent}..${head}"
printf 'behind='; git rev-list --count "${head}..${parent}"
gh pr view 264 --repo "$repo" \
  --json number,state,isDraft,headRefOid,baseRefOid,mergeStateStatus,reviewDecision,latestReviews,statusCheckRollup

echo '== Parent-relative scope =='
git diff --check "$parent" "$head"
git diff --name-status "$parent" "$head"
git diff --stat "$parent" "$head"

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 viewer consumers =='
nl -ba src/main/resources/static/assets/viewer/dom-utils.js | sed -n '1,260p'
nl -ba src/main/resources/static/assets/viewer/demo.js | sed -n '60,180p'
nl -ba src/main/resources/static/assets/viewer/demo.js | sed -n '210,350p'
nl -ba src/main/resources/static/assets/viewer/demo.js | sed -n '410,620p'

echo '== Tests and Maven integration =='
nl -ba src/test/js/dom-utils.test.mjs | sed -n '1,560p'
nl -ba src/test/js/demo-integration.test.mjs | sed -n '1,650p'
rg -n -C 18 -P '(dom-utils|node|c8|coverage|line|branch|function|exec-maven|jacoco|javadoc|surefire)' pom.xml

echo '== Workflow pins and permission indicators =='
fd -t f . .github/workflows | sort
rg -n -C 6 -P '(actions/setup-node@|node-version:|permissions:|contents:\s*write|pull-requests:\s*write|persist-credentials:\s*true|reconcile)' .github/workflows || true

echo '== Effective diff =='
git diff --unified=35 "$parent" "$head" -- \
  .github/workflows/ci.yml pom.xml CHANGELOG.md \
  src/main/resources/static/assets/viewer/dom-utils.js \
  src/main/resources/static/assets/viewer/demo.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/$head/check-runs?per_page=100" --paginate \
  --jq '.check_runs[] | [.name,.status,.conclusion,.details_url] | `@tsv`'

echo '== Unresolved review threads =='
gh api graphql \
  -F owner='ContextualWisdomLab' -F name='clearfolio' -F number=264 \
  -f query='
query($owner: String!, $name: String!, $number: Int!) {
  repository(owner: $owner, name: $name) {
    pullRequest(number: $number) {
      reviewThreads(first: 100) {
        nodes {
          isResolved
          comments(first: 1) { nodes { author { login } path line body } }
        }
      }
    }
  }
}' \
  --jq '.data.repository.pullRequest.reviewThreads.nodes[]
    | select(.isResolved == false)
    | [.comments.nodes[0].author.login, .comments.nodes[0].path, (.comments.nodes[0].line | tostring), .comments.nodes[0].body]
    | `@tsv`' || true

echo '== Available repository policy data =='
gh api "repos/$repo/rules/branches/main" || true
gh api "repos/$repo/rulesets?includes_parents=true" || true
gh api "repos/$repo/branches/main/protection" || true

Length of output: 18344


🏁 Script executed:

#!/bin/bash
set -euo pipefail

repo='ContextualWisdomLab/clearfolio'
head='ad29eab0b2ea925933adcd8c407affd027fa8ec2'
parent='26563218ae42eaa876c784fcf56b27f8cb810080'

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,180p'

echo '== Viewer action consumers =='
numbered src/main/resources/static/assets/viewer/demo.js | sed -n '75,155p'
numbered src/main/resources/static/assets/viewer/demo.js | sed -n '225,320p'
numbered src/main/resources/static/assets/viewer/demo.js | sed -n '425,610p'

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

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

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

echo '== CI Node setup and workflow privilege indicators =='
rg -n -C 8 -P '(actions/setup-node@|node-version:|permissions:|contents:\s*write|pull-requests:\s*write|persist-credentials:\s*true|reconcile)' .github/workflows || true

echo '== Complete relevant parent-relative diff =='
git diff --unified=35 "$parent" "$head" -- \
  .github/workflows/ci.yml pom.xml CHANGELOG.md \
  src/main/resources/static/assets/viewer/dom-utils.js \
  src/main/resources/static/assets/viewer/demo.js \
  src/test/js/dom-utils.test.mjs \
  src/test/js/demo-integration.test.mjs

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

echo '== Unresolved review threads =='
gh api graphql \
  -F owner='ContextualWisdomLab' -F name='clearfolio' -F number=264 \
  -f query='
query($owner: String!, $name: String!, $number: Int!) {
  repository(owner: $owner, name: $name) {
    pullRequest(number: $number) {
      reviewThreads(first: 100) {
        nodes {
          isResolved
          comments(first: 1) { nodes { author { login } path line body } }
        }
      }
    }
  }
}' \
  --jq '.data.repository.pullRequest.reviewThreads.nodes[]
    | select(.isResolved == false)
    | [.comments.nodes[0].author.login, .comments.nodes[0].path, (.comments.nodes[0].line | tostring), .comments.nodes[0].body]
    | `@tsv`' || true

echo '== Current review and policy state =='
gh pr view 264 --repo "$repo" \
  --json headRefOid,isDraft,mergeStateStatus,reviewDecision,latestReviews
gh api "repos/$repo/rules/branches/main" || true
gh api "repos/$repo/rulesets?includes_parents=true" || true
gh api "repos/$repo/branches/main/protection" || true

Length of output: 102689


@seonghobae Review complete for exact head ad29eab0b2ea925933adcd8c407affd027fa8ec2.

I found no current source-level blocker.

The requested parent is an ancestor of this head. The head is five commits ahead and zero commits behind. The parent-relative diff changes the reported seven files. git diff --check reported no whitespace errors.

I verified these items:

  • setBusyState stores per-button state in a WeakMap.
  • The helper increments depth for nested calls.
  • Each restore callback is idempotent.
  • Only the final restore restores state.
  • The helper snapshots original child-node references with Array.from(button.childNodes).
  • The helper restores the same node objects with replaceChildren(...).
  • The helper restores the original disabled, aria-busy, and aria-label values.
  • The helper distinguishes absent attributes from empty and non-empty attribute values.
  • The helper does not use innerHTML.
  • Details and Status JSON set busy state before asynchronous work and restore state with .finally(restore).
  • Status JSON uses Loading status JSON... and is disabled while its request is pending.
  • Details, Status JSON, and Open viewer use document-specific accessible names.
  • File names use textContent. The integration test verifies that markup-like file names remain inert text.
  • New-tab links use target="_blank" and rel="noopener noreferrer".
  • The integration test verifies the Status JSON pending state, popup opener isolation, final restoration, JSON rendering, and a non-empty history row.
  • Maven runs both Node test modules during test.
  • Maven requires 100% line, branch, and function coverage for src/main/resources/static/assets/viewer/dom-utils.js.
  • Both exact-head and synthetic-merge CI jobs configure Node.js 24 with the immutable actions/setup-node SHA 820762786026740c76f36085b0efc47a31fe5020.
  • The current exact-head Maven, merge-compatibility, buyer-readiness, Semgrep, OSV, fuzz, and CodeQL checks are successful.
  • The review-thread query returned no unresolved threads.

I cannot approve this draft.

The live exact-head query still reports strix as in_progress. The PR has no counted approval. The repository ruleset requires one approving repository review and resolved review threads. The branch-protection REST endpoint returned HTTP 403, so I could not inspect its complete configuration.

Keep this PR behind #270. After #270 merges, reconcile this bounded diff with protected main and replace the current evidence with checks for the new exact head and synthetic merge revision.

You are interacting with an AI system.

Copy link
Copy Markdown
Collaborator Author

Exact stack refresh: authoritative parent #270 is now 2ff43fc1b280f6de2ca903695e5cbeef5c0b3c17. This PR remains at ad29eab0b2ea925933adcd8c407affd027fa8ec2 and is currently diverged: 5 slice commits ahead and 11 parent commits behind, with merge base 26563218ae42eaa876c784fcf56b27f8cb810080. Historical checks remain evidence for this child head only; every parent-sensitive merge-compatibility or review conclusion is stale. Keep draft, do not merge, and reconcile only after #270 integrates or its exact head is deliberately imported and all resulting exact-head gates are rerun.

@seonghobae
seonghobae force-pushed the fix/accessible-async-viewer-controls branch from ad29eab to f328ec5 Compare August 6, 2026 08:45

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@opencode-agent @cwl-noema-review Independently review exact current head f328ec5d1c3dec48c9a47181f194cb547c30a8b0 relative to parent #270 exact head 2ff43fc1b280f6de2ca903695e5cbeef5c0b3c17. Treat every predecessor-head result as stale.

Verify the seven-file accessibility slice only: WeakMap depth and idempotent restore; exact original child-node, disabled, aria-busy, and aria-label restoration; contextual accessible names; operation-specific Status JSON pending state; duplicate-activation blocking; inert markup-like labels; safe new-tab defaults; Node.js 24 immutable action pin; Maven integration and 100% line/branch/function coverage for dom-utils.js; preservation of the parent artifact:read, tenant-concealment, privacy, Netty, SBOM, complete Maven-report, zero-missed production coverage, and warning-free-Javadoc contracts; and absence of temporary/write-scoped workflows.

Submit actionable exact-head findings or a no-blocker advisory conclusion after independent inspection. Keep Draft and do not infer counted independent approval.

@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown
🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

repo='ContextualWisdomLab/clearfolio'
head='f328ec5d1c3dec48c9a47181f194cb547c30a8b0'
parent='2ff43fc1b280f6de2ca903695e5cbeef5c0b3c17'

echo '== Exact identity, ancestry, and PR state =='
printf 'checkout='; git rev-parse HEAD
git show -s --format='commit=%H%nparents=%P%nsubject=%s' "$head"
git merge-base --is-ancestor "$parent" "$head" && echo 'parent_is_ancestor=true'
printf 'ahead='; git rev-list --count "${parent}..${head}"
printf 'behind='; git rev-list --count "${head}..${parent}"
gh pr view 264 --repo "$repo" \
  --json number,state,isDraft,headRefOid,baseRefName,baseRefOid,mergeStateStatus,reviewDecision,latestReviews,statusCheckRollup

echo '== Parent-relative scope =='
git diff --check "$parent" "$head"
git diff --name-status "$parent" "$head"
git diff --stat "$parent" "$head"

echo '== JavaScript 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 viewer consumers =='
nl -ba src/main/resources/static/assets/viewer/dom-utils.js | sed -n '1,270p'
nl -ba src/main/resources/static/assets/viewer/demo.js | sed -n '60,190p'
nl -ba src/main/resources/static/assets/viewer/demo.js | sed -n '210,360p'
nl -ba src/main/resources/static/assets/viewer/demo.js | sed -n '410,640p'

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

echo '== Maven Node and Java quality gates =='
rg -n -C 22 -P '(dom-utils|node|c8|coverage|line|branch|function|exec-maven|jacoco|javadoc|surefire|maven-report)' pom.xml

echo '== Workflow pins, permissions, and inventory =='
fd -t f . .github/workflows | sort
rg -n -C 8 -P '(actions/setup-node@|node-version:|permissions:|artifact:read|contents:\s*write|pull-requests:\s*write|persist-credentials:\s*true|reconcile)' .github/workflows || true

echo '== Parent-contract references in effective tree =='
rg -n -C 4 -i -P '(tenant|conceal|privacy|netty|sbom|attribution|jacoco|javadoc|maven-report|zero missed|pdfjs|6\.1\.200)' \
  pom.xml CHANGELOG.md src/main .github/workflows || true

echo '== Complete bounded diff =='
git diff --unified=35 "$parent" "$head" -- \
  .github/workflows/ci.yml CHANGELOG.md 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 '== Exact-head check runs =='
gh api "repos/$repo/commits/$head/check-runs?per_page=100" --paginate \
  --jq '.check_runs[] | [.name,.status,.conclusion,.details_url] | `@tsv`'

echo '== Unresolved pull request threads =='
gh api graphql \
  -F owner='ContextualWisdomLab' -F name='clearfolio' -F number=264 \
  -f query='
query($owner: String!, $name: String!, $number: Int!) {
  repository(owner: $owner, name: $name) {
    pullRequest(number: $number) {
      reviewThreads(first: 100) {
        nodes {
          isResolved
          comments(first: 1) { nodes { author { login } path line body } }
        }
      }
    }
  }
}' \
  --jq '.data.repository.pullRequest.reviewThreads.nodes[]
    | select(.isResolved == false)
    | [.comments.nodes[0].author.login,.comments.nodes[0].path,(.comments.nodes[0].line|tostring),.comments.nodes[0].body] | `@tsv`' || true

echo '== Available repository policy data =='
gh api "repos/$repo/rules/branches/main" || true
gh api "repos/$repo/rulesets?includes_parents=true" || true
gh api "repos/$repo/branches/main/protection" || true

Length of output: 9792


🏁 Script executed:

#!/bin/bash
set -euo pipefail

repo='ContextualWisdomLab/clearfolio'
head='f328ec5d1c3dec48c9a47181f194cb547c30a8b0'
parent='2ff43fc1b280f6de2ca903695e5cbeef5c0b3c17'

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,280p'

echo '== Viewer action consumers =='
numbered src/main/resources/static/assets/viewer/demo.js | sed -n '65,180p'
numbered src/main/resources/static/assets/viewer/demo.js | sed -n '220,360p'
numbered src/main/resources/static/assets/viewer/demo.js | sed -n '410,640p'

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

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

echo '== Maven Node and Java quality gates =='
rg -n -C 22 -P '(dom-utils|node|c8|coverage|line|branch|function|exec-maven|jacoco|javadoc|surefire|maven-report)' pom.xml

echo '== Workflow inventory, immutable pins, and privilege indicators =='
find .github/workflows -type f -print | sort
rg -n -C 8 -P '(actions/setup-node@|node-version:|permissions:|artifact:read|contents:\s*write|pull-requests:\s*write|persist-credentials:\s*true|reconcile)' .github/workflows || true

echo '== Parent-contract references in the effective tree =='
rg -n -C 4 -i -P '(tenant|conceal|privacy|netty|sbom|attribution|jacoco|javadoc|maven-report|zero missed|pdfjs|6\.1\.200)' \
  pom.xml CHANGELOG.md src/main .github/workflows || true

echo '== Complete seven-file diff =='
git diff --unified=35 "$parent" "$head" -- \
  .github/workflows/ci.yml CHANGELOG.md pom.xml \
  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

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

echo '== Unresolved pull request threads =='
gh api graphql \
  -F owner='ContextualWisdomLab' -F name='clearfolio' -F number=264 \
  -f query='
query($owner: String!, $name: String!, $number: Int!) {
  repository(owner: $owner, name: $name) {
    pullRequest(number: $number) {
      reviewThreads(first: 100) {
        nodes {
          isResolved
          comments(first: 1) { nodes { author { login } path line body } }
        }
      }
    }
  }
}' \
  --jq '.data.repository.pullRequest.reviewThreads.nodes[]
    | select(.isResolved == false)
    | [.comments.nodes[0].author.login,.comments.nodes[0].path,(.comments.nodes[0].line|tostring),.comments.nodes[0].body] | `@tsv`' || true

echo '== Current review state and available policy data =='
gh pr view 264 --repo "$repo" \
  --json headRefOid,isDraft,mergeStateStatus,reviewDecision,latestReviews,statusCheckRollup
gh api "repos/$repo/rules/branches/main" || true
gh api "repos/$repo/rulesets?includes_parents=true" || true
gh api "repos/$repo/branches/main/protection" || true

Length of output: 164507


@seonghobae Advisory review complete for exact head f328ec5d1c3dec48c9a47181f194cb547c30a8b0.

I found no source-level blocker in the seven-file parent-relative diff.

The requested parent 2ff43fc1b280f6de2ca903695e5cbeef5c0b3c17 is the direct parent of this head. The diff changes exactly the reported seven files. git diff --check reported no whitespace errors.

I verified these implementation conditions:

  • setBusyState stores state in a WeakMap.
  • Nested calls increment a depth counter.
  • Each restore callback is idempotent.
  • Only the final restore restores the original state.
  • The helper snapshots original child-node references with Array.from(button.childNodes).
  • The helper restores the same node objects with replaceChildren(...).
  • The helper restores disabled, aria-busy, and aria-label exactly.
  • The helper distinguishes absent, empty, and non-empty ARIA values.
  • The helper does not use innerHTML.
  • Details and Status JSON set busy state before asynchronous work.
  • Status JSON uses Loading status JSON... and restores state through .finally(restore).
  • Native disabled-button behavior blocks repeated user activation while the request is pending.
  • Details, Status JSON, and Open viewer use document-specific accessible names.
  • External document names use textContent. The integration test verifies that markup-like names remain inert.
  • New-tab links use target="_blank" and rel="noopener noreferrer".
  • The integration test verifies pending state, restoration, popup opener isolation, and JSON rendering.
  • Maven runs both Node test modules during test.
  • Maven requires 100% line, branch, and function coverage for src/main/resources/static/assets/viewer/dom-utils.js.
  • Both CI jobs configure Node.js 24 with the immutable actions/setup-node SHA 820762786026740c76f36085b0efc47a31fe5020.
  • The diff adds the accessibility test integration without removing the parent JaCoCo, Javadoc, Maven-report, Netty, SBOM, privacy, tenant-concealment, or artifact:read configuration.
  • The changed workflow file has read-only top-level permissions. The inspected seven-file diff contains no temporary or write-scoped workflow.

I cannot confirm all required gates for this exact head. The exact-head check-run query returned only the three successful fuzz jobs. It did not return exact-head CI, Security Scan, SAST, merge-compatibility, or the required organization workflow results. The review-thread query returned no unresolved threads.

The PR remains a draft. It has no approving review. The repository rules include one required approving review. The branch-protection API returned HTTP 403, so complete branch-protection verification is unavailable. I do not infer approval from the CodeRabbit status or from predecessor-head evidence.

⚠️ 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.

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