{"review_threads":[{"is_resolved":true,"is_outdated":false,"is_collapsed":true,"comments":[{"body":"The PR description/issue indicates this workflow should use `semgrep/semgrep-action@v1`, but the implementation runs the job in a `semgrep/semgrep` container instead. If you keep the container approach, ensure the image includes the runtime/tools required by JS actions like `actions/checkout` and `actions/upload-artifact` (or switch to `semgrep/semgrep-action@v1` running on the hosted runner to avoid container requirements).","path":".github/workflows/semgrep.yml","line":23,"author":"copilot-pull-request-reviewer","created_at":"2026-04-27T06:46:57Z","updated_at":"2026-04-27T06:46:59Z","html_url":"https://github.com/Mesya82/Service-Book/pull/23#discussion_r3145347319"}],"total_count":1},{"is_resolved":true,"is_outdated":false,"is_collapsed":true,"comments":[{"body":"Workflow-level `pull-requests: write` grants write access even on `push` runs where it isn’t needed. Consider reducing default permissions to read-only and setting `pull-requests: write` only on the `stale-baseline-check` job to follow least-privilege.","path":".github/workflows/smoke.yml","line":18,"author":"copilot-pull-request-reviewer","created_at":"2026-04-27T06:46:58Z","updated_at":"2026-04-27T06:46:59Z","html_url":"https://github.com/Mesya82/Service-Book/pull/23#discussion_r3145347362"}],"total_count":1},{"is_resolved":true,"is_outdated":false,"is_collapsed":true,"comments":[{"body":"The PR description mentions smoke tests should cover changes to \"storage logic\" / ViewModels under `app/src/main`, but the PR path filter only triggers on `app/src/main/**/ui/**`. If smoke coverage is intended for broader `app/src/main` changes, expand the `paths:` filter (or adjust the description/runbook so contributors don’t assume smoke/stale-baseline checks will run for non-UI `app/src/main` changes).","path":".github/workflows/smoke.yml","line":29,"author":"copilot-pull-request-reviewer","created_at":"2026-04-27T06:46:58Z","updated_at":"2026-04-27T06:46:59Z","html_url":"https://github.com/Mesya82/Service-Book/pull/23#discussion_r3145347382"}],"total_count":1},{"is_resolved":true,"is_outdated":true,"is_collapsed":true,"comments":[{"body":"`CHANGED` is built with `sort -u | head -5`, which returns the first 5 filenames in lexicographic order, not the most recently changed files. This makes the later label \"Recently changed\" misleading; consider preserving commit order (e.g., de-dup while keeping first-seen order) or explicitly naming it as an alphabetical sample.\n```suggestion\n # Top 5 source files newer than the baseline, preserving git log order.\n CHANGED=$(git log --name-only --pretty=format: --since=\"@$BASELINE_TS\" -- app/src/main \\\n | grep -v '^$' | awk '!seen[$0]++' | head -5 | sed 's/^/- /')\n```","path":".github/workflows/smoke.yml","author":"copilot-pull-request-reviewer","created_at":"2026-04-27T06:46:58Z","updated_at":"2026-04-27T06:46:59Z","html_url":"https://github.com/Mesya82/Service-Book/pull/23#discussion_r3145347398"}],"total_count":1},{"is_resolved":true,"is_outdated":true,"is_collapsed":true,"comments":[{"body":"This implies the sticky PR comment will prompt baseline refreshes whenever `app/src/main` is newer than the baseline, but the Smoke workflow is path-filtered on PRs and won’t run (and therefore won’t comment) for many `app/src/main` changes outside the filter. Suggest clarifying that the comment appears only when the Smoke workflow runs for the PR (or broadening the workflow’s `paths:` filter if that’s not intended).\n```suggestion\nCI can surface a sticky PR comment from the `Smoke / Stale Baseline Check` job when `app/src/main` has commits newer than the baseline, but that comment only appears for PRs where the Smoke workflow runs. Use the comment as a prompt when it is present, and otherwise refresh the baseline manually whenever relevant `app/src/main` changes would affect smoke-test coverage.\n```","path":"TESTING_SETUP.md","author":"copilot-pull-request-reviewer","created_at":"2026-04-27T06:46:58Z","updated_at":"2026-04-27T06:46:59Z","html_url":"https://github.com/Mesya82/Service-Book/pull/23#discussion_r3145347421"}],"total_count":1},{"is_resolved":true,"is_outdated":true,"is_collapsed":true,"comments":[{"body":"`pull-requests: write` is granted at the workflow level, but only the `stale-baseline-check` job needs it to post a sticky comment. For least privilege, consider moving `pull-requests: write` to that job (or even just the final step) and keeping the main smoke test job read-only.","path":".github/workflows/smoke.yml","author":"copilot-pull-request-reviewer","created_at":"2026-04-27T07:01:52Z","updated_at":"2026-04-27T07:01:53Z","html_url":"https://github.com/Mesya82/Service-Book/pull/23#discussion_r3145417717"}],"total_count":1},{"is_resolved":true,"is_outdated":true,"is_collapsed":true,"comments":[{"body":"The udev rule sets `/dev/kvm` to mode `0666` (world-writable). Even on ephemeral runners this is broader access than necessary; prefer `0660` with group `kvm` and ensure the runner user is in that group (or otherwise grant access without making the device world-writable).\n```suggestion\n echo 'KERNEL==\"kvm\", GROUP=\"kvm\", MODE=\"0660\", OPTIONS+=\"static_node=kvm\"' \\\n | sudo tee /etc/udev/rules.d/99-kvm4all.rules\n sudo usermod -a -G kvm \"$USER\"\n```","path":".github/workflows/smoke.yml","line":59,"author":"copilot-pull-request-reviewer","created_at":"2026-04-27T07:01:52Z","updated_at":"2026-04-27T07:01:53Z","html_url":"https://github.com/Mesya82/Service-Book/pull/23#discussion_r3145417751"}],"total_count":1},{"is_resolved":true,"is_outdated":true,"is_collapsed":true,"comments":[{"body":"The \"Recently changed\" list is produced by `sort -u`, which makes the output alphabetical rather than recent/chronological. Either adjust the wording (e.g., \"Changed (top 5)\"), or preserve recency while de-duping (e.g., keep first-seen order and then `head -5`).\n```suggestion\n | grep -v '^$' | awk '!seen[$0]++' | head -5 | sed 's/^/- /')\n```","path":".github/workflows/smoke.yml","author":"copilot-pull-request-reviewer","created_at":"2026-04-27T07:01:52Z","updated_at":"2026-04-27T07:01:53Z","html_url":"https://github.com/Mesya82/Service-Book/pull/23#discussion_r3145417785"}],"total_count":1},{"is_resolved":true,"is_outdated":true,"is_collapsed":true,"comments":[{"body":"The Semgrep container image is unpinned (`semgrep/semgrep`), which can change unexpectedly and break scans. Pin to a specific tag/digest (and periodically bump it intentionally) to make CI reproducible.\n```suggestion\n image: semgrep/semgrep:1.76.0\n```","path":".github/workflows/semgrep.yml","author":"copilot-pull-request-reviewer","created_at":"2026-04-27T07:01:53Z","updated_at":"2026-04-27T07:01:53Z","html_url":"https://github.com/Mesya82/Service-Book/pull/23#discussion_r3145417804"}],"total_count":1},{"is_resolved":true,"is_outdated":false,"is_collapsed":true,"comments":[{"body":"`stale-baseline-check` posts a PR comment from a workflow triggered by `pull_request`. For PRs opened from forks, the `GITHUB_TOKEN` typically won't have permission to write PR comments, so this step may fail/no-op. If you need this to work for fork PRs, consider moving just the commenting portion to a `pull_request_target` workflow/job (with careful handling to avoid checking out/running untrusted fork code).","path":".github/workflows/smoke.yml","line":24,"author":"copilot-pull-request-reviewer","created_at":"2026-04-27T07:01:53Z","updated_at":"2026-04-27T07:01:53Z","html_url":"https://github.com/Mesya82/Service-Book/pull/23#discussion_r3145417821"}],"total_count":1},{"is_resolved":true,"is_outdated":false,"is_collapsed":true,"comments":[{"body":"This workflow is documented as “never fails the PR”, but on PRs from forks the `pull_request` event runs with a read-only `GITHUB_TOKEN`, so `pull-requests: write` won’t actually be granted and the sticky-comment step is likely to fail with a 403. To keep it informational, consider switching to `pull_request_target` (safe here since you don’t checkout or execute PR code) or conditionally skipping / `continue-on-error` for the comment upsert when the token can’t write.","path":".github/workflows/baseline-reminder.yml","line":15,"author":"copilot-pull-request-reviewer","created_at":"2026-04-27T07:35:34Z","updated_at":"2026-04-27T07:35:35Z","html_url":"https://github.com/Mesya82/Service-Book/pull/23#discussion_r3145581623"},{"body":"Forks are unlikely since the repo will be privte","path":".github/workflows/baseline-reminder.yml","line":15,"author":"Mesya82","created_at":"2026-04-27T07:37:37Z","updated_at":"2026-04-27T07:37:37Z","html_url":"https://github.com/Mesya82/Service-Book/pull/23#discussion_r3145592705"}],"total_count":2},{"is_resolved":true,"is_outdated":false,"is_collapsed":true,"comments":[{"body":"PR description mentions a “stale-baseline check” that flips ⚠️ stale ⇄ ✅ current based on git timestamps and uses header `stale-baseline-bot`, but this workflow only posts a generic reminder and uses header `baseline-reminder-bot`. Either adjust the implementation to match the described behavior (staleness detection + status flip + top changed files), or update the PR description to reflect what’s actually being shipped.","path":".github/workflows/baseline-reminder.yml","line":5,"author":"copilot-pull-request-reviewer","created_at":"2026-04-27T07:35:34Z","updated_at":"2026-04-27T07:35:35Z","html_url":"https://github.com/Mesya82/Service-Book/pull/23#discussion_r3145581643"}],"total_count":1},{"is_resolved":true,"is_outdated":true,"is_collapsed":true,"comments":[{"body":"`continue-on-error: true` means the workflow will succeed even if Semgrep fails to run (e.g., config/network/runtime errors), which can silently drop scanning. If the intent is “don’t fail on findings”, consider keeping the job failing on execution errors while tolerating findings (e.g., by making Semgrep exit 0 on findings or by post-processing the exit code) so a broken scanner still shows up as a failed check.\n```suggestion\n shell: bash\n run: |\n semgrep ci --sarif --output=semgrep.sarif --config=p/default --config=p/kotlin --config=p/owasp-top-ten\n status=$?\n if [ \"$status\" -ne 0 ] \u0026\u0026 [ \"$status\" -ne 1 ]; then\n exit \"$status\"\n fi\n exit 0\n```","path":".github/workflows/semgrep.yml","author":"copilot-pull-request-reviewer","created_at":"2026-04-27T07:35:34Z","updated_at":"2026-04-27T07:35:35Z","html_url":"https://github.com/Mesya82/Service-Book/pull/23#discussion_r3145581664"}],"total_count":1},{"is_resolved":true,"is_outdated":false,"is_collapsed":true,"comments":[{"body":"The PR description says free `ubuntu-latest` runners have **no nested KVM**, but this workflow comment states they expose `/dev/kvm` for CPU acceleration and includes an “Enable KVM” step. Please reconcile these (either update the comment/PR description, or adjust the workflow) so the rationale and expected runner capabilities are consistent.","path":".github/workflows/smoke.yml","line":8,"author":"copilot-pull-request-reviewer","created_at":"2026-04-27T08:06:23Z","updated_at":"2026-04-27T08:06:23Z","html_url":"https://github.com/Mesya82/Service-Book/pull/23#discussion_r3145750652"}],"total_count":1},{"is_resolved":true,"is_outdated":true,"is_collapsed":true,"comments":[{"body":"The PR description says the Semgrep workflow uses `semgrep/semgrep-action@v1`, but the implementation runs Semgrep in a job-level Docker container (`semgrep/semgrep:...`) and then runs `actions/checkout` inside that container. Either update the PR description or switch the workflow to the action as described (which also avoids potential issues if the container image lacks tooling required by `actions/checkout`).","path":".github/workflows/semgrep.yml","author":"copilot-pull-request-reviewer","created_at":"2026-04-27T08:06:23Z","updated_at":"2026-04-27T08:06:23Z","html_url":"https://github.com/Mesya82/Service-Book/pull/23#discussion_r3145750701"}],"total_count":1},{"is_resolved":true,"is_outdated":true,"is_collapsed":true,"comments":[{"body":"The udev rule makes `/dev/kvm` world-writable (`MODE=\"0666\"`). Even on ephemeral CI runners, it’s better to grant the minimum required permissions (for example, restrict to the `kvm` group and ensure only the runner user has access) rather than opening it to all users.\n```suggestion\n echo 'KERNEL==\"kvm\", GROUP=\"kvm\", MODE=\"0660\", OPTIONS+=\"static_node=kvm\"' \\\n | sudo tee /etc/udev/rules.d/99-kvm4all.rules\n sudo udevadm control --reload-rules\n sudo udevadm trigger --name-match=kvm\n sudo setfacl -m \"u:${USER}:rw\" /dev/kvm\n```","path":".github/workflows/smoke.yml","line":61,"author":"copilot-pull-request-reviewer","created_at":"2026-04-27T08:06:23Z","updated_at":"2026-04-27T08:06:24Z","html_url":"https://github.com/Mesya82/Service-Book/pull/23#discussion_r3145750730"}],"total_count":1},{"is_resolved":true,"is_outdated":false,"is_collapsed":true,"comments":[{"body":"The header comment says this workflow is “Purely informational — never fails the PR”, but the sticky-comment step will currently fail the job (and therefore the PR check) if the GitHub API call errors (permissions, rate limits, transient outage, etc.). To match the intent, make the upsert step non-blocking (e.g., `continue-on-error: true` on that step or equivalent error-tolerant handling).","path":".github/workflows/baseline-reminder.yml","line":51,"author":"copilot-pull-request-reviewer","created_at":"2026-04-27T08:18:22Z","updated_at":"2026-04-27T08:18:22Z","html_url":"https://github.com/Mesya82/Service-Book/pull/23#discussion_r3145814861"}],"total_count":1},{"is_resolved":true,"is_outdated":false,"is_collapsed":true,"comments":[{"body":"PR description says this workflow uses `semgrep/semgrep-action@v1`, but the implementation runs Semgrep via `docker run ... semgrep/semgrep:...`. Either update the workflow to use the action as described (simpler + less custom shell logic), or update the PR description so it accurately reflects what’s being merged.","path":".github/workflows/semgrep.yml","line":34,"author":"copilot-pull-request-reviewer","created_at":"2026-04-27T08:18:22Z","updated_at":"2026-04-27T08:18:22Z","html_url":"https://github.com/Mesya82/Service-Book/pull/23#discussion_r3145814897"}],"total_count":1},{"is_resolved":true,"is_outdated":false,"is_collapsed":true,"comments":[{"body":"The reviewdog steps run on all workflow triggers (push/schedule/workflow_dispatch) due to `if: always()`. `-reporter=github-pr-review` is PR-specific, so these steps should be gated to `github.event_name == 'pull_request'` (or use a non-PR reporter on non-PR events) to avoid failing the job on pushes/scheduled runs.","path":".github/workflows/semgrep.yml","line":64,"author":"copilot-pull-request-reviewer","created_at":"2026-04-27T08:30:02Z","updated_at":"2026-04-27T08:30:03Z","html_url":"https://github.com/Mesya82/Service-Book/pull/23#discussion_r3145886966"}],"total_count":1},{"is_resolved":true,"is_outdated":false,"is_collapsed":true,"comments":[{"body":"The udev rule sets `/dev/kvm` to MODE `0666` (world-writable). The PR description says permissions were tightened to `0660`, so either update the rule to `0660` (and ensure the runner user is in the `kvm` group) or adjust the description/comment to match the actual permissions being applied.","path":".github/workflows/smoke.yml","line":59,"author":"copilot-pull-request-reviewer","created_at":"2026-04-27T08:30:03Z","updated_at":"2026-04-27T08:30:03Z","html_url":"https://github.com/Mesya82/Service-Book/pull/23#discussion_r3145887026"}],"total_count":1},{"is_resolved":false,"is_outdated":false,"is_collapsed":false,"comments":[{"body":"`reviewdog_version: latest` makes the workflow non-deterministic and can break CI unexpectedly when reviewdog releases a new major/minor with behavior changes. Pin this to a specific version (and update intentionally) to keep Semgrep reporting stable.\n```suggestion\n reviewdog_version: v0.20.3\n```","path":".github/workflows/semgrep.yml","line":55,"author":"copilot-pull-request-reviewer","created_at":"2026-04-27T08:50:05Z","updated_at":"2026-04-27T08:50:05Z","html_url":"https://github.com/Mesya82/Service-Book/pull/23#discussion_r3146003301"}],"total_count":1}],"totalCount":21,"pageInfo":{"hasNextPage":false,"hasPreviousPage":false,"startCursor":"Y3Vyc29yOnYyOpK0MjAyNi0wNC0yN1QwNjo0Njo1N1rOfb3dug==","endCursor":"Y3Vyc29yOnYyOpK0MjAyNi0wNC0yN1QwODo1MDowNVrOfcVegg=="}}