Skip to content

๐Ÿ›ก๏ธ Sentinel: [CRITICAL] Fix integer coercion vulnerabilities in interactive prompts - #198

Open
seonghobae wants to merge 2 commits into
masterfrom
sentinel-fix-integer-coercion-675986151613676802
Open

๐Ÿ›ก๏ธ Sentinel: [CRITICAL] Fix integer coercion vulnerabilities in interactive prompts#198
seonghobae wants to merge 2 commits into
masterfrom
sentinel-fix-integer-coercion-675986151613676802

Conversation

@seonghobae

@seonghobae seonghobae commented Aug 1, 2026

Copy link
Copy Markdown
Collaborator

๐Ÿšจ Severity: CRITICAL
๐Ÿ’ก Vulnerability: Weak regex validation (^[0-9]+$) in interactive integer prompts allowed large strings of digits that evaluate to NA when coerced by as.integer(). This can break if conditions and crash the execution pipeline.
๐ŸŽฏ Impact: Unexpected crashes or unhandled exceptions that function as a local Denial of Service (DoS) during model automation.
๐Ÿ”ง Fix: Replaced ^[0-9]+$ with bounded exact-match regex ^[12]$ across all instances in autoFIPC().
โœ… Verification: Ran Rscript -e 'devtools::test()' and explicitly verified interactive fallback logic using mockery inside the regex-security test suite. All tests passed successfully.


PR created automatically by Jules for task 675986151613676802 started by @seonghobae

Summary by CodeRabbit

  • ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ

    • ๋ฌธํ•ญ ๋ชจํ˜• ๊ฒ€์ฆ๊ณผ ์ฒ™๋„ ์—ฐ๊ฒฐ์„ ์ž๋™ํ™”ํ•˜๋Š” autoFIPC๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
    • ์ถ”์ • ์‹คํŒจ ์‹œ ๋ฌธํ•ญ์„ ์ ๊ฒ€ํ•˜๊ณ  ์žฌ์‹œ๋„ํ•˜๋Š” surveyFA ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค.
  • ๋ฒ„๊ทธ ์ˆ˜์ •

    • ๋Œ€ํ™”ํ˜• ์ž…๋ ฅ์—์„œ 1 ๋˜๋Š” 2๋งŒ ํ—ˆ์šฉํ•˜๋„๋ก ๊ฒ€์ฆ์„ ๊ฐ•ํ™”ํ–ˆ์Šต๋‹ˆ๋‹ค.
    • ์ž˜๋ชป๋œ ์ˆซ์ž ์ž…๋ ฅ์œผ๋กœ ์ฒ˜๋ฆฌ๊ฐ€ ์ค‘๋‹จ๋  ์ˆ˜ ์žˆ๋Š” ๋ฌธ์ œ๋ฅผ ๋ฐฉ์ง€ํ–ˆ์Šต๋‹ˆ๋‹ค.
  • ํ…Œ์ŠคํŠธ

    • ์ž…๋ ฅ ๊ฒ€์ฆ, ๋ชจํ˜• ์ถ”์ •, ์˜ค๋ฅ˜ ์ฒ˜๋ฆฌ ๋ฐ ์ฃผ์š” ๊ฒฐ๊ณผ๋ฅผ ํ™•์ธํ•˜๋Š” ํ…Œ์ŠคํŠธ๋ฅผ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค.
  • ๋ฌธ์„œ

    • ์ƒˆ ๊ธฐ๋Šฅ์˜ ์‚ฌ์šฉ๋ฒ•๊ณผ ์ž…๋ ฅ ๊ฒ€์ฆ ๊ธฐ์ค€์„ ๋ฌธ์„œํ™”ํ–ˆ์Šต๋‹ˆ๋‹ค.

@google-labs-jules

Copy link
Copy Markdown

๐Ÿ‘‹ Jules, reporting for duty! I'm here to lend a hand with this pull request.

When you start a review, I'll add a ๐Ÿ‘€ emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down.

I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job!

For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with @jules. You can find this option in the Pull Request section of your global Jules UI settings. You can always switch back!

New to Jules? Learn more at jules.google/docs.


For security, I will only act on instructions from the user who triggered this task.

@coderabbitai

coderabbitai Bot commented Aug 1, 2026

Copy link
Copy Markdown

Review Change Stack

๐Ÿ“ Walkthrough

Walkthrough

autoFIPC()์™€ surveyFA()๋ฅผ ๊ณต๊ฐœ ํŒจํ‚ค์ง€ API๋กœ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋ชจํ˜• ์ถ”์ •, ๋Œ€์ฒด ์ถ”์ •, IPD ๊ฒ€์‚ฌ, ์ฒ™๋„ ์—ฐ๊ฒฐ, ๊ฒฐ๊ณผ ๊ณ„์‚ฐ ๋ฐ ์ž…๋ ฅ ๊ฒ€์ฆ์„ ๊ตฌํ˜„ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋Œ€ํ™”ํ˜• ์ž…๋ ฅ์€ 1 ๋˜๋Š” 2๋กœ ์ œํ•œํ–ˆ์Šต๋‹ˆ๋‹ค. ํŒจํ‚ค์ง€ ๋ฌธ์„œ์™€ ํšŒ๊ท€ ํ…Œ์ŠคํŠธ๋„ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค.

Changes

ํŒจํ‚ค์ง€ API ๋ฐ ์ถ”์ • ํ๋ฆ„

Layer / File(s) Summary
๊ณต๊ฐœ API์™€ ์ž…๋ ฅ ๊ณ„์•ฝ
aFIPC.Rcheck/00_pkg_src/aFIPC/R/*, aFIPC.Rcheck/00_pkg_src/aFIPC/NAMESPACE, aFIPC.Rcheck/00_pkg_src/aFIPC/man/*
autoFIPC()์™€ surveyFA()์˜ ๊ณต๊ฐœ ์ธ์ž, ์ž…๋ ฅ ๊ฒ€์ฆ, ๋ฐ˜ํ™˜๊ฐ’, ๋ฌธ์„œ ๋ฐ export ์„ค์ •์„ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค.
๋ชจํ˜• ์ถ”์ • ๋ฐ ์ฒ™๋„ ์—ฐ๊ฒฐ
aFIPC.Rcheck/00_pkg_src/aFIPC/R/aFIPC.R, aFIPC.Rcheck/00_pkg_src/aFIPC/R/surveyFA.R
old form๊ณผ new form ์ถ”์ •, ์‹คํŒจ ์‹œ ๋Œ€์ฒด ๊ฒฝ๋กœ, IPD ๊ฒ€์‚ฌ, ๊ณตํ†ต ๋ฌธํ•ญ ๋งค๊ฐœ๋ณ€์ˆ˜ ๊ณ ์ •, ์—ฐ๊ฒฐ ๋ชจํ˜• ์ถ”์ • ๋ฐ ์ ์ˆ˜ ๊ณ„์‚ฐ์„ ๊ตฌํ˜„ํ–ˆ์Šต๋‹ˆ๋‹ค.
๋ณด์•ˆ ๋ฐ ๊ธฐ๋Šฅ ํšŒ๊ท€ ๊ฒ€์ฆ
aFIPC.Rcheck/00_pkg_src/aFIPC/tests/testthat/*, tests/testthat/test-regex-security.R
์ž…๋ ฅ ํ˜•์‹, ๋Œ€ํ™”ํ˜• ์ž…๋ ฅ, ๊ณ ์ • ๋งค๊ฐœ๋ณ€์ˆ˜ ์—ฐ๊ฒฐ, ์ตœ์ ํ™” ๋™์น˜์„ฑ, API export์™€ surveyFA() ๋™์ž‘์„ ๊ฒ€์ฆํ•˜๋Š” ํ…Œ์ŠคํŠธ๋ฅผ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค.
ํŒจํ‚ค์ง€ ๋นŒ๋“œ ๋ฐ ๊ฒ€์‚ฌ ์‚ฐ์ถœ๋ฌผ
.Rbuildignore, .jules/sentinel.md, aFIPC.Rcheck/*
๋นŒ๋“œ ์ œ์™ธ ๊ทœ์น™, ์ •์ˆ˜ ์ž…๋ ฅ ๊ฒ€์ฆ ์ง€์นจ, ํŒจํ‚ค์ง€ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ, ๋„์›€๋ง, ๊ฒ€์‚ฌ ์Šคํฌ๋ฆฝํŠธ์™€ ๊ฒ€์‚ฌ ๊ฒฐ๊ณผ๋ฅผ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค.

Estimated code review effort: 4 (Complex) | ~60 minutes

Possibly related PRs

  • ContextualWisdomLab/aFIPC#182: ๋™์ผํ•œ autoFIPC() ์ž…๋ ฅ ๊ฒ€์ฆ ์ •๊ทœ์‹์„ ๋ณ€๊ฒฝํ•ฉ๋‹ˆ๋‹ค.
  • ContextualWisdomLab/aFIPC#195: ๋™์ผํ•œ ์ž…๋ ฅ ๊ฒ€์ฆ ๋ณ€๊ฒฝ๊ณผ ํšŒ๊ท€ ํ…Œ์ŠคํŠธ๋ฅผ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค.
  • ContextualWisdomLab/aFIPC#190: ๋™์ผํ•œ ๋Œ€ํ™”ํ˜• ์ž…๋ ฅ ๊ฒ€์ฆ ๋ณ€๊ฒฝ์„ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค.

Suggested reviewers: copilot

๐Ÿšฅ Pre-merge checks | โœ… 5
โœ… Passed checks (5 passed)
Check name Status Explanation
Description Check โœ… Passed Check skipped - CodeRabbitโ€™s high-level summary is enabled.
Title check โœ… Passed ์ œ๋ชฉ์€ autoFIPC ๋Œ€ํ™”ํ˜• ํ”„๋กฌํ”„ํŠธ์˜ ์ •์ˆ˜ ๋ณ€ํ™˜ ์ทจ์•ฝ์  ์ˆ˜์ •์ด๋ผ๋Š” ์ฃผ์š” ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ์ •ํ™•ํ•˜๊ณ  ๊ตฌ์ฒด์ ์œผ๋กœ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค.
Docstring Coverage โœ… Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check โœ… Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check โœ… Passed Check skipped because no linked issues were found for this pull request.
โœจ Finishing Touches
๐Ÿ“ Generate docstrings
  • Create stacked PR
  • Commit on current branch
๐Ÿงช Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch sentinel-fix-integer-coercion-675986151613676802

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

๐Ÿงน Nitpick comments (1)
tests/testthat/test-regex-security.R (1)

1-16: ๐Ÿ“ Maintainability & Code Quality | ๐Ÿ”ต Trivial | โšก Quick win

์‹ ๊ทœ ์–‘์‹ BILOG-MG ๊ฒฝ๋กœ์˜ ํšŒ๊ท€ ํ…Œ์ŠคํŠธ๋ฅผ ์ถ”๊ฐ€ํ•˜์„ธ์š”.

ํ˜„์žฌ tests/testthat/test-regex-security.R๋Š” R/aFIPC.R Line 144์˜ ๊ณตํ†ต ๋ฌธํ•ญ ๊ฒฝ๋กœ์™€ Line 174์˜ oldform ๊ฒฝ๋กœ๋งŒ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. Line 393์˜ checknewformBILOGprior()๋Š” ์‹คํ–‰๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. newformBILOGprior = NULL์ธ ์‹ ๊ทœ ์–‘์‹ ๊ฒฝ๋กœ์—์„œ "12" ์ž…๋ ฅ์ด ์„ธ ๋ฒˆ ๊ฑฐ๋ถ€๋˜๊ณ  Too many invalid newform BILOG prior attempts๊ฐ€ ๋ฐœ์ƒํ•˜๋Š”์ง€ ํ™•์ธํ•˜์„ธ์š”. oldform ๋‹จ๊ณ„๋Š” fixture ๋˜๋Š” stub์œผ๋กœ ํ†ต๊ณผ์‹œํ‚ค์„ธ์š”.

Also applies to: 18-36

๐Ÿค– Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/testthat/test-regex-security.R` around lines 1 - 16, Add a regression
test alongside the existing regex-security tests that exercises autoFIPC with
newformBILOGprior set to NULL and reaches checknewformBILOGprior. Stub or
fixture the oldform confirmation so it succeeds, provide "12" for the newform
BILOG prior prompt, and assert that three rejected attempts raise "Too many
invalid newform BILOG prior attempts".
๐Ÿค– Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/testthat/test-regex-security.R`:
- Around line 4-5: Declare mockery as a test dependency by adding it to the
Suggests field in DESCRIPTION, so the mockery::stub calls in the regex security
tests are available during CI.

---

Nitpick comments:
In `@tests/testthat/test-regex-security.R`:
- Around line 1-16: Add a regression test alongside the existing regex-security
tests that exercises autoFIPC with newformBILOGprior set to NULL and reaches
checknewformBILOGprior. Stub or fixture the oldform confirmation so it succeeds,
provide "12" for the newform BILOG prior prompt, and assert that three rejected
attempts raise "Too many invalid newform BILOG prior attempts".
๐Ÿช„ Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

โ„น๏ธ Review info
โš™๏ธ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: e6a55407-ed27-405f-a031-3f5a37a54002

๐Ÿ“ฅ Commits

Reviewing files that changed from the base of the PR and between 35e4498 and d05c4a0.

๐Ÿ“’ Files selected for processing (3)
  • .jules/sentinel.md
  • R/aFIPC.R
  • tests/testthat/test-regex-security.R

Comment on lines +4 to +5
mockery::stub(aFIPC::autoFIPC, 'interactive', my_interactive)
mockery::stub(aFIPC::autoFIPC, 'readline', my_readline)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

๐Ÿฉบ Stability & Availability | ๐ŸŸ  Major | โšก Quick win

๐Ÿงฉ Analysis chain

๐Ÿ Script executed:

#!/bin/bash
set -euo pipefail

description_file="$(fd -a '^DESCRIPTION$' . | head -n 1)"
test -n "$description_file"
rg -n -C 2 '^(Suggests|Imports):|mockery' "$description_file"

Repository: ContextualWisdomLab/aFIPC

Length of output: 375


๐Ÿ Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '--- mockery usages and test setup ---'
rg -n -C 3 'mockery|testthat|devtools::test|R CMD check|rcmdcheck|remotes::install' \
  .github tests DESCRIPTION 2>/dev/null || true

printf '%s\n' '--- candidate CI and dependency files ---'
fd -a -t f '(^DESCRIPTION$|^NAMESPACE$|^.*\.(ya?ml|yaml|R|Rmd|md)$)' .github tests . 2>/dev/null \
  | sed -n '1,160p'

Repository: ContextualWisdomLab/aFIPC

Length of output: 16855


mockery๋ฅผ ํ…Œ์ŠคํŠธ ์˜์กด์„ฑ์œผ๋กœ ์„ ์–ธํ•˜์„ธ์š”.

DESCRIPTION์˜ Suggests์— mockery๊ฐ€ ์—†์œผ๋ฏ€๋กœ CI๊ฐ€ mockery::stub๋ฅผ ๋กœ๋“œํ•˜์ง€ ๋ชปํ•˜๊ณ  ํ…Œ์ŠคํŠธ๋ฅผ ์‹คํŒจ์‹œํ‚ต๋‹ˆ๋‹ค. mockery๋ฅผ Suggests์— ์ถ”๊ฐ€ํ•˜์„ธ์š”.

๐Ÿค– Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/testthat/test-regex-security.R` around lines 4 - 5, Declare mockery as
a test dependency by adding it to the Suggests field in DESCRIPTION, so the
mockery::stub calls in the regex security tests are available during CI.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 14

Caution

Some comments are outside the diff and canโ€™t be posted inline due to platform limitations.

โš ๏ธ Outside diff range comments (1)
aFIPC.Rcheck/tests/testthat.Rout (1)

1-288: ๐Ÿ“ Maintainability & Code Quality | ๐ŸŸ  Major | โšก Quick win

R CMD check ์‚ฐ์ถœ๋ฌผ ์ „์ฒด๋ฅผ ๋ฒ„์ „ ๊ด€๋ฆฌ์—์„œ ์ œ๊ฑฐํ•˜์‹ญ์‹œ์˜ค. aFIPC.Rcheck/ ๋””๋ ‰ํ„ฐ๋ฆฌ๋Š” R CMD check ์‹คํ–‰์ด ์ž๋™์œผ๋กœ ์ƒ์„ฑํ•˜๋Š” ์‚ฐ์ถœ๋ฌผ์ž…๋‹ˆ๋‹ค. ์†Œ์Šค ์Šค๋ƒ…์ƒท, ์ปดํŒŒ์ผ๋œ ๋„์›€๋ง ๋ฐ”์ด๋„ˆ๋ฆฌ, ํ…Œ์ŠคํŠธ ๋Ÿฌ๋„ˆ ์‚ฌ๋ณธ, ์‹คํ–‰ ๋กœ๊ทธ๋ฅผ ๋ชจ๋‘ ํฌํ•จํ•˜๋ฉฐ, ์ด ์ „์ฒด๊ฐ€ ์ €์žฅ์†Œ์— ์ปค๋ฐ‹๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๊ทผ๋ณธ ์›์ธ์€ ํ•˜๋‚˜์ž…๋‹ˆ๋‹ค: ์ƒ์„ฑ๋œ ๋นŒ๋“œ/๊ฒ€์‚ฌ ์‚ฐ์ถœ๋ฌผ์ด ์†Œ์Šค ํŠธ๋ฆฌ์™€ ํ•จ๊ป˜ ์ถ”์ ๋˜๊ณ  ์žˆ๋‹ค๋Š” ์ ์ž…๋‹ˆ๋‹ค.

  • aFIPC.Rcheck/tests/testthat.Rout#L1-L288: ํ™˜๊ฒฝ๋ณ„ ์‹คํ–‰ ๋กœ๊ทธ(R ๋ฒ„์ „, ํ”Œ๋žซํผ, ์†Œ์š” ์‹œ๊ฐ„ ํฌํ•จ)๋ฅผ ์ €์žฅ์†Œ์—์„œ ์‚ญ์ œํ•˜์‹ญ์‹œ์˜ค.
  • aFIPC.Rcheck/00_pkg_src/aFIPC/test_dummy.R#L1-L3: R CMD check์ด ์ƒ์„ฑํ•œ ์†Œ์Šค ์Šค๋ƒ…์ƒท ๋‚ด๋ถ€ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ญ์ œํ•˜์‹ญ์‹œ์˜ค.
  • aFIPC.Rcheck/00_pkg_src/aFIPC/test_validation.R#L1-L3: ๊ฐ™์€ ์Šค๋ƒ…์ƒท ๋‚ด๋ถ€์˜ ๊ตฌ๋ฌธ ํ™•์ธ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ญ์ œํ•˜์‹ญ์‹œ์˜ค.
  • aFIPC.Rcheck/00_pkg_src/aFIPC/tests/testthat.R#L1-L4: ์Šค๋ƒ…์ƒท ๋‚ด๋ถ€์˜ testthat ๋Ÿฌ๋„ˆ ์‚ฌ๋ณธ์„ ์‚ญ์ œํ•˜์‹ญ์‹œ์˜ค.
  • aFIPC.Rcheck/aFIPC/help/aFIPC.rdb#L1-L14: ์ปดํŒŒ์ผ๋œ ๋„์›€๋ง ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋ฐ”์ด๋„ˆ๋ฆฌ๋ฅผ ์‚ญ์ œํ•˜์‹ญ์‹œ์˜ค.
  • aFIPC.Rcheck/aFIPC/help/aFIPC.rdx#L1-L1: ์ปดํŒŒ์ผ๋œ ๋„์›€๋ง ์ƒ‰์ธ ๋ฐ”์ด๋„ˆ๋ฆฌ๋ฅผ ์‚ญ์ œํ•˜์‹ญ์‹œ์˜ค.
  • aFIPC.Rcheck/aFIPC/help/aliases.rds#L1-L1: ์ƒ์„ฑ๋œ ๋ณ„์นญ RDS ํŒŒ์ผ์„ ์‚ญ์ œํ•˜์‹ญ์‹œ์˜ค.
  • aFIPC.Rcheck/aFIPC/help/paths.rds#L1-L1: ์ƒ์„ฑ๋œ ๊ฒฝ๋กœ RDS ํŒŒ์ผ์„ ์‚ญ์ œํ•˜์‹ญ์‹œ์˜ค.
  • aFIPC.Rcheck/tests/startup.Rs#L1-L3: ์ƒ์„ฑ๋œ ๊ฒ€์‚ฌ์šฉ startup ํŒŒ์ผ์„ ์‚ญ์ œํ•˜์‹ญ์‹œ์˜ค.
  • aFIPC.Rcheck/tests/testthat.R#L1-L4: ๊ฒ€์‚ฌ ์ถœ๋ ฅ ๋””๋ ‰ํ„ฐ๋ฆฌ ๋‚ด testthat ๋Ÿฌ๋„ˆ ์‚ฌ๋ณธ์„ ์‚ญ์ œํ•˜๊ณ , .gitignore์— *.Rcheck/ ํ•ญ๋ชฉ์„ ์ถ”๊ฐ€ํ•ด ์žฌ๋ฐœ์„ ๋ง‰์œผ์‹ญ์‹œ์˜ค.
๐Ÿค– Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@aFIPC.Rcheck/tests/testthat.Rout` around lines 1 - 288, Remove all generated
R CMD check artifacts from version control: delete the listed files in
aFIPC.Rcheck/tests/testthat.Rout (lines 1-288),
aFIPC.Rcheck/00_pkg_src/aFIPC/test_dummy.R (1-3),
aFIPC.Rcheck/00_pkg_src/aFIPC/test_validation.R (1-3),
aFIPC.Rcheck/00_pkg_src/aFIPC/tests/testthat.R (1-4),
aFIPC.Rcheck/aFIPC/help/aFIPC.rdb (1-14), aFIPC.Rcheck/aFIPC/help/aFIPC.rdx
(1-1), aFIPC.Rcheck/aFIPC/help/aliases.rds (1-1),
aFIPC.Rcheck/aFIPC/help/paths.rds (1-1), aFIPC.Rcheck/tests/startup.Rs (1-3),
and aFIPC.Rcheck/tests/testthat.R (1-4), then add *.Rcheck/ to .gitignore to
prevent these build and check outputs from being tracked again.
๐Ÿงน Nitpick comments (6)
aFIPC.Rcheck/aFIPC-Ex.R (1)

1-44: ๐Ÿ“ Maintainability & Code Quality | ๐Ÿ”ต Trivial | โšก Quick win

aFIPC.Rcheck/ ์ „์ฒด๋ฅผ ์ œ๊ฑฐํ•˜๊ณ  .gitignore์— ์ถ”๊ฐ€ํ•˜์„ธ์š”.

ํ˜„์žฌ aFIPC.Rcheck/ ์•„๋ž˜ 53๊ฐœ ํŒŒ์ผ์ด ์ถ”์ ๋˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๋””๋ ‰ํ„ฐ๋ฆฌ๋Š” R CMD check๊ฐ€ ์ƒ์„ฑํ•œ ์†Œ์Šค ๋ณต์‚ฌ๋ณธ, ์„ค์น˜ ๊ฒฐ๊ณผ, ๋กœ๊ทธ, lazy-load ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋ฐ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋ฅผ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค. CI๋Š” ๊นจ๋—ํ•œ ์ž‘์—… ๋””๋ ‰ํ„ฐ๋ฆฌ์—์„œ ๊ฒ€์‚ฌ๋ฅผ ์‹คํ–‰ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๐Ÿค– Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@aFIPC.Rcheck/aFIPC-Ex.R` around lines 1 - 44, Remove the entire tracked
aFIPC.Rcheck/ directory, including all listed generated files, and add
aFIPC.Rcheck/ to .gitignore so future R CMD check artifacts are not committed.
aFIPC.Rcheck/00_pkg_src/aFIPC/tests/testthat/test-fixed-parameter-calibration.R (1)

1-52: ๐Ÿš€ Performance & Scalability | ๐Ÿ”ต Trivial | โšก Quick win

๊ธด ์‹คํ–‰ ์‹œ๊ฐ„์— ๋Œ€ํ•œ ๋ณดํ˜ธ ์žฅ์น˜๋ฅผ ์ถ”๊ฐ€ํ•˜์‹ญ์‹œ์˜ค.

์ด ํ…Œ์ŠคํŠธ๋Š” N = 1600์œผ๋กœ ๋‘ ๊ฐœ์˜ ๋ชจํ˜•์„ SE = TRUE์™€ ์ตœ๋Œ€ 500 ์‚ฌ์ดํด๋กœ ์ถ”์ •ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ ๋‹ค์Œ autoFIPC()๊ฐ€ ์—ฐ๊ฒฐ ๋ชจํ˜•์„ ์ถ”๊ฐ€๋กœ ์ถ”์ •ํ•ฉ๋‹ˆ๋‹ค. R CMD check ์‹คํ–‰ ์‹œ๊ฐ„์ด CRAN ํ•œ๋„๋ฅผ ์ดˆ๊ณผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. skip_on_cran()์„ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜ ํ‘œ๋ณธ ํฌ๊ธฐ๋ฅผ ์ค„์ด์‹ญ์‹œ์˜ค.

๐Ÿ”ง ์ œ์•ˆ ์ˆ˜์ •
 test_that("autoFIPC fixes common-item parameters on the old-form scale", {
   skip_if_not_installed("mirt")
+  skip_on_cran()
๐Ÿค– Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@aFIPC.Rcheck/00_pkg_src/aFIPC/tests/testthat/test-fixed-parameter-calibration.R`
around lines 1 - 52, Update the test beginning with the autoFIPC calibration
setup to add a CRAN runtime safeguard, preferably by calling skip_on_cran()
before the expensive mirt model fitting; alternatively reduce the simulated
sample size while preserving the testโ€™s calibration coverage.
aFIPC.Rcheck/00_pkg_src/aFIPC/tests/testthat/test-optimization-equivalence.R (1)

37-50: ๐Ÿ“ Maintainability & Code Quality | ๐Ÿ”ต Trivial | ๐Ÿ—๏ธ Heavy lift

์ด ํ…Œ์ŠคํŠธ๋Š” ๊ตฌํ˜„ ์ฝ”๋“œ๋ฅผ ํ˜ธ์ถœํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

Line 37-46๊ณผ Line 64-77์€ ํ‘œํ˜„์‹์„ ํ…Œ์ŠคํŠธ ํŒŒ์ผ ์•ˆ์—์„œ ๋‹ค์‹œ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฏ€๋กœ R/aFIPC.R์˜ ์‹ค์ œ ์ฝ”๋“œ๊ฐ€ ๋ณ€๊ฒฝ๋˜์–ด๋„ ์ด ํ…Œ์ŠคํŠธ๋Š” ์‹คํŒจํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํšŒ๊ท€ ๋ฐฉ์ง€ ํšจ๊ณผ๋ฅผ ์–ป์œผ๋ ค๋ฉด ํ•ด๋‹น ๋กœ์ง์„ ๋‚ด๋ถ€ ํ—ฌํผ ํ•จ์ˆ˜๋กœ ์ถ”์ถœํ•˜๊ณ , ํ…Œ์ŠคํŠธ์—์„œ ๊ทธ ํ—ฌํผ๋ฅผ ํ˜ธ์ถœํ•˜์‹ญ์‹œ์˜ค.

๐Ÿค– Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@aFIPC.Rcheck/00_pkg_src/aFIPC/tests/testthat/test-optimization-equivalence.R`
around lines 37 - 50, Refactor the duplicated optimization logic in R/aFIPC.R
into an internal helper function, then update test-optimization-equivalence.R to
call that helper instead of recreating the expressions locally. Keep the testโ€™s
expected-value and legacy-equivalence assertions, ensuring changes to the
production implementation can cause the test to fail.
aFIPC.Rcheck/00_pkg_src/aFIPC/tests/testthat/test-autoFIPC.R (1)

48-57: ๐Ÿ“ Maintainability & Code Quality | ๐Ÿ”ต Trivial | ๐Ÿ’ค Low value

์ด ํ…Œ์ŠคํŠธ๋Š” ํ˜ผ๋ž€์Šค๋Ÿฌ์šด ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€๋ฅผ ๊ณ ์ •ํ•ฉ๋‹ˆ๋‹ค.

nItems๊ฐ€ 1์ด๋ฏ€๋กœ ๋ฉ”์‹œ์ง€๊ฐ€ "length 1 or length 1"๋กœ ์ถœ๋ ฅ๋ฉ๋‹ˆ๋‹ค. R/aFIPC.R Line 91์˜ itemtype ๊ฒ€์ฆ์„ ์ •๋ฆฌํ•œ ๋’ค ์ด ๊ธฐ๋Œ€๊ฐ’๋„ ํ•จ๊ป˜ ์ˆ˜์ •ํ•˜์‹ญ์‹œ์˜ค.

๐Ÿค– Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@aFIPC.Rcheck/00_pkg_src/aFIPC/tests/testthat/test-autoFIPC.R` around lines 48
- 57, Update the itemtype validation in aFIPC so that its error message is not
redundant when nItems equals 1, then revise the corresponding expect_error
assertion in test-autoFIPC.R to match the corrected message. Preserve the
validation behavior for invalid itemtype lengths and anchor the changes to the
aFIPC function and its itemtype test.
aFIPC.Rcheck/00_pkg_src/aFIPC/NAMESPACE (1)

3-5: ๐Ÿ“ Maintainability & Code Quality | ๐Ÿ”ต Trivial | ๐Ÿ’ค Low value

import(mirt) ์ „์ฒด ์ž„ํฌํŠธ๋ฅผ ์ขํžˆ์‹ญ์‹œ์˜ค.

R/aFIPC.R๊ณผ R/surveyFA.R์€ ๋ชจ๋“  ํ˜ธ์ถœ์— mirt:: ์ ‘๋‘์‚ฌ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฏ€๋กœ ์ „์ฒด ๋„ค์ž„์ŠคํŽ˜์ด์Šค ์ž„ํฌํŠธ๋Š” ํ•„์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. R/aFIPC.R Line 3์˜ @import mirt๋ฅผ ์ œ๊ฑฐํ•˜๊ณ  DESCRIPTION์˜ Imports๋งŒ ์œ ์ง€ํ•˜๋ฉด ์ด๋ฆ„ ์ถฉ๋Œ ์œ„ํ—˜์ด ์ค„์–ด๋“ญ๋‹ˆ๋‹ค.

๐Ÿค– Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@aFIPC.Rcheck/00_pkg_src/aFIPC/NAMESPACE` around lines 3 - 5, Remove the broad
mirt namespace import from the package metadata, specifically the NAMESPACE
import generated from the `@import` mirt directive, while retaining mirt in
DESCRIPTIONโ€™s Imports and preserving the existing explicit mirt:: calls in aFIPC
and surveyFA.
aFIPC.Rcheck/00_pkg_src/aFIPC/R/aFIPC.R (1)

235-291: ๐Ÿ“ Maintainability & Code Quality | ๐Ÿ”ต Trivial | ๐Ÿ’ค Low value

์ค‘๋ณต๋œ !exists() ๊ฒ€์‚ฌ๋ฅผ ์ •๋ฆฌํ•˜์‹ญ์‹œ์˜ค.

Line 235-237์€ oldFormModel์ด ์—†์œผ๋ฉด ์ด๋ฏธ ์ค‘๋‹จํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฏ€๋กœ Line 241๊ณผ Line 265์˜ ์ฒซ ๋ฒˆ์งธ !exists() ์ ˆ์€ ๊ทธ ์‹œ์ ์— ํ•ญ์ƒ FALSE์ž…๋‹ˆ๋‹ค. ๋‹ค๋งŒ Line 248์˜ rm() ์ดํ›„์—๋Š” ์œ ํšจํ•ฉ๋‹ˆ๋‹ค. ์กฐ๊ฑด ์˜๋„๋ฅผ ์ฃผ์„์œผ๋กœ ๋ช…์‹œํ•˜๊ฑฐ๋‚˜, ํ—ฌํผ ํ•จ์ˆ˜ ํ•˜๋‚˜๋กœ "๋ชจํ˜•์ด ์—†๊ฑฐ๋‚˜ 2์ฐจ ์กฐ๊ฑด์„ ํ†ต๊ณผํ•˜์ง€ ๋ชปํ•จ"์„ ํ‘œํ˜„ํ•˜์‹ญ์‹œ์˜ค. ๊ฐ™์€ ํŒจํ„ด์ด ์ƒˆ ํผ ๊ฒฝ๋กœ(Line 453-508)์—๋„ ๋ฐ˜๋ณต๋ฉ๋‹ˆ๋‹ค.

๐Ÿค– Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@aFIPC.Rcheck/00_pkg_src/aFIPC/R/aFIPC.R` around lines 235 - 291, Clarify the
redundant model-validity checks in the oldFormModel estimation flow: after the
initial guard, the first !exists() terms in the QMCEM and MHRM conditions are
always false until rm() runs. Remove those redundant terms or reuse a helper
expressing โ€œmodel missing or second-order test failed,โ€ preserving the post-rm
checks. Apply the same cleanup to the corresponding new-form estimation path
around its model fallback logic.
๐Ÿค– Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@aFIPC.Rcheck/00_pkg_src/aFIPC/DESCRIPTION`:
- Line 13: Add mockery to the DESCRIPTION fileโ€™s Suggests dependency list
alongside testthat, so tests/testthat/test-regex-security.R can use
mockery::stub() when only declared dependencies are installed.

In `@aFIPC.Rcheck/00_pkg_src/aFIPC/R/aFIPC.R`:
- Around line 763-807: The common-item parameter cache uses input strings
instead of the validated model column names, allowing NULL indices and false
successful-link logs. In the loop over oldformCommonItemNames, update the
newScaleParmsItemIdxCache and oldScaleParmsItemIdxCache lookups to use
newFormItemName and oldFormItemName, and warn when either resolved index is
empty before attempting the parameter assignments.
- Around line 639-647: Update the IPDData construction around IPDItemCount to
handle zero matching items safely: check for no matches before creating or
naming the data frame, and use seq_len(IPDItemCount) instead of 1:IPDItemCount
when generating column names. Preserve the existing assignment flow for cases
where common items are found.
- Around line 87-91: Update the itemtype validation near the initial itemtype
checks to reject vectors longer than one, including when nItems remains NA for
mirt inputs, so all later scalar comparisons such as the itemtype checks in the
affected branches remain valid. Preserve the existing character-type validation
and security-error style.
- Around line 293-366: Wrap each fallback surveyFA() invocation in the shown
retry blocks, including the corresponding fallback calls in the new-form path,
so a stop() from one attempt does not abort autoFIPC(). Preserve the existing
exists("oldFormModel", inherits = FALSE) and OptimInfo$secondordertest checks so
execution proceeds to the next fallback whenever the attempt fails.
- Around line 853-879: Update the forceNormalZeroOne branch to target the
single-factor parameter name "MEAN_1" instead of "MEAN_11", setting
NewScaleParms["MEAN_1", ] est to FALSE and value to 0; ensure the corresponding
OldScaleParms mean parameter is also identified consistently, while preserving
the existing COV_11 handling.

In `@aFIPC.Rcheck/00_pkg_src/aFIPC/R/surveyFA.R`:
- Around line 242-251: Update the candidate-selection logic around the
pThreshold filtering and variance fallback so that when a valid p-value column
exists but no item is below pThreshold, it returns NA_character_ immediately
instead of selecting the minimum-variance item. Preserve the variance-based
fallback only for cases where p-values are unavailable or invalid, using the
surrounding surveyFA logic to distinguish those cases.
- Around line 83-92: Update the response_data column subset in surveyFA to use
drop = FALSE, ensuring a single retained column remains a data frame so the
nrow() and ncol() validation works without a length-zero condition.
- Line 86: Add stats to the package DESCRIPTION Imports alongside the existing
mirt and methods declarations, covering the stats::na.omit, stats::var, and
stats::vcov usages in surveyFA.R and aFIPC.R.

In
`@aFIPC.Rcheck/00_pkg_src/aFIPC/tests/testthat/test-fixed-parameter-calibration.R`:
- Around line 63-88: Extend the test around the autoFIPC call and
linked$LinkedModel to assert the latent distribution group parameters produced
with forceNormalZeroOne = TRUE, including the expected fixed mean values. Use
the existing mirt model-value inspection pattern and verify the relevant
group-parameter estimates so a regression in the mean-fixing behavior is
detected, while preserving the current covariance and structural-parameter
checks.

In `@aFIPC.Rcheck/00_pkg_src/aFIPC/tests/testthat/test-surveyFA.R`:
- Around line 61-70: Set a deterministic seed before the rbinom calls in the
surveyFA exhaustion test so the generated response data is reproducible across
runs. Follow the seed-setting convention used by the surrounding tests and leave
the test data generation otherwise unchanged.

In `@aFIPC.Rcheck/aFIPC/html/R.css`:
- Around line 126-129: Update the font-family declaration in span.rlang to quote
the spaced font name Courier New, while preserving the existing fallback Courier
and color styling.

In `@aFIPC.Rcheck/aFIPC/NAMESPACE`:
- Around line 3-5: Remove the generated aFIPC.Rcheck directory contents from
version control, including aFIPC.Rcheck/aFIPC/NAMESPACE and the duplicate
test-fixed-parameter-calibration.R under aFIPC.Rcheck/tests/testthat; retain the
test only in the repositoryโ€™s root tests/testthat directory. Add *.Rcheck/ to
.gitignore so future R CMD check output is ignored.

In `@aFIPC.Rcheck/tests/testthat/test-autoFIPC.R`:
- Around line 1-12: Update the test identified by โ€œautoFIPC raises error in
non-interactive session for inputsโ€ to skip when base R interactive() is TRUE,
before invoking autoFIPC. Keep the existing non-interactive error assertion
unchanged.

---

Outside diff comments:
In `@aFIPC.Rcheck/tests/testthat.Rout`:
- Around line 1-288: Remove all generated R CMD check artifacts from version
control: delete the listed files in aFIPC.Rcheck/tests/testthat.Rout (lines
1-288), aFIPC.Rcheck/00_pkg_src/aFIPC/test_dummy.R (1-3),
aFIPC.Rcheck/00_pkg_src/aFIPC/test_validation.R (1-3),
aFIPC.Rcheck/00_pkg_src/aFIPC/tests/testthat.R (1-4),
aFIPC.Rcheck/aFIPC/help/aFIPC.rdb (1-14), aFIPC.Rcheck/aFIPC/help/aFIPC.rdx
(1-1), aFIPC.Rcheck/aFIPC/help/aliases.rds (1-1),
aFIPC.Rcheck/aFIPC/help/paths.rds (1-1), aFIPC.Rcheck/tests/startup.Rs (1-3),
and aFIPC.Rcheck/tests/testthat.R (1-4), then add *.Rcheck/ to .gitignore to
prevent these build and check outputs from being tracked again.

---

Nitpick comments:
In `@aFIPC.Rcheck/00_pkg_src/aFIPC/NAMESPACE`:
- Around line 3-5: Remove the broad mirt namespace import from the package
metadata, specifically the NAMESPACE import generated from the `@import` mirt
directive, while retaining mirt in DESCRIPTIONโ€™s Imports and preserving the
existing explicit mirt:: calls in aFIPC and surveyFA.

In `@aFIPC.Rcheck/00_pkg_src/aFIPC/R/aFIPC.R`:
- Around line 235-291: Clarify the redundant model-validity checks in the
oldFormModel estimation flow: after the initial guard, the first !exists() terms
in the QMCEM and MHRM conditions are always false until rm() runs. Remove those
redundant terms or reuse a helper expressing โ€œmodel missing or second-order test
failed,โ€ preserving the post-rm checks. Apply the same cleanup to the
corresponding new-form estimation path around its model fallback logic.

In `@aFIPC.Rcheck/00_pkg_src/aFIPC/tests/testthat/test-autoFIPC.R`:
- Around line 48-57: Update the itemtype validation in aFIPC so that its error
message is not redundant when nItems equals 1, then revise the corresponding
expect_error assertion in test-autoFIPC.R to match the corrected message.
Preserve the validation behavior for invalid itemtype lengths and anchor the
changes to the aFIPC function and its itemtype test.

In
`@aFIPC.Rcheck/00_pkg_src/aFIPC/tests/testthat/test-fixed-parameter-calibration.R`:
- Around line 1-52: Update the test beginning with the autoFIPC calibration
setup to add a CRAN runtime safeguard, preferably by calling skip_on_cran()
before the expensive mirt model fitting; alternatively reduce the simulated
sample size while preserving the testโ€™s calibration coverage.

In
`@aFIPC.Rcheck/00_pkg_src/aFIPC/tests/testthat/test-optimization-equivalence.R`:
- Around line 37-50: Refactor the duplicated optimization logic in R/aFIPC.R
into an internal helper function, then update test-optimization-equivalence.R to
call that helper instead of recreating the expressions locally. Keep the testโ€™s
expected-value and legacy-equivalence assertions, ensuring changes to the
production implementation can cause the test to fail.

In `@aFIPC.Rcheck/aFIPC-Ex.R`:
- Around line 1-44: Remove the entire tracked aFIPC.Rcheck/ directory, including
all listed generated files, and add aFIPC.Rcheck/ to .gitignore so future R CMD
check artifacts are not committed.
๐Ÿช„ Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

โ„น๏ธ Review info
โš™๏ธ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 80bc81c6-ede3-4a98-99a7-072099affefd

๐Ÿ“ฅ Commits

Reviewing files that changed from the base of the PR and between d05c4a0 and bed6214.

โ›” Files ignored due to path filters (3)
  • aFIPC.Rcheck/00check.log is excluded by !**/*.log
  • aFIPC.Rcheck/00install.out is excluded by !**/*.out
  • aFIPC.Rcheck/aFIPC-Ex.pdf is excluded by !**/*.pdf
๐Ÿ“’ Files selected for processing (51)
  • .Rbuildignore
  • aFIPC.Rcheck/00_pkg_src/aFIPC/DESCRIPTION
  • aFIPC.Rcheck/00_pkg_src/aFIPC/LICENSE
  • aFIPC.Rcheck/00_pkg_src/aFIPC/NAMESPACE
  • aFIPC.Rcheck/00_pkg_src/aFIPC/R/aFIPC.R
  • aFIPC.Rcheck/00_pkg_src/aFIPC/R/surveyFA.R
  • aFIPC.Rcheck/00_pkg_src/aFIPC/README.md
  • aFIPC.Rcheck/00_pkg_src/aFIPC/man/autoFIPC.Rd
  • aFIPC.Rcheck/00_pkg_src/aFIPC/man/surveyFA.Rd
  • aFIPC.Rcheck/00_pkg_src/aFIPC/test_dummy.R
  • aFIPC.Rcheck/00_pkg_src/aFIPC/test_validation.R
  • aFIPC.Rcheck/00_pkg_src/aFIPC/tests/testthat.R
  • aFIPC.Rcheck/00_pkg_src/aFIPC/tests/testthat/test-autoFIPC.R
  • aFIPC.Rcheck/00_pkg_src/aFIPC/tests/testthat/test-fixed-parameter-calibration.R
  • aFIPC.Rcheck/00_pkg_src/aFIPC/tests/testthat/test-optimization-equivalence.R
  • aFIPC.Rcheck/00_pkg_src/aFIPC/tests/testthat/test-package-api.R
  • aFIPC.Rcheck/00_pkg_src/aFIPC/tests/testthat/test-regex-security.R
  • aFIPC.Rcheck/00_pkg_src/aFIPC/tests/testthat/test-sentinel-validation.R
  • aFIPC.Rcheck/00_pkg_src/aFIPC/tests/testthat/test-surveyFA.R
  • aFIPC.Rcheck/aFIPC-Ex.R
  • aFIPC.Rcheck/aFIPC-Ex.Rout
  • aFIPC.Rcheck/aFIPC/DESCRIPTION
  • aFIPC.Rcheck/aFIPC/INDEX
  • aFIPC.Rcheck/aFIPC/LICENSE
  • aFIPC.Rcheck/aFIPC/Meta/Rd.rds
  • aFIPC.Rcheck/aFIPC/Meta/features.rds
  • aFIPC.Rcheck/aFIPC/Meta/hsearch.rds
  • aFIPC.Rcheck/aFIPC/Meta/links.rds
  • aFIPC.Rcheck/aFIPC/Meta/nsInfo.rds
  • aFIPC.Rcheck/aFIPC/Meta/package.rds
  • aFIPC.Rcheck/aFIPC/NAMESPACE
  • aFIPC.Rcheck/aFIPC/R/aFIPC
  • aFIPC.Rcheck/aFIPC/R/aFIPC.rdb
  • aFIPC.Rcheck/aFIPC/R/aFIPC.rdx
  • aFIPC.Rcheck/aFIPC/help/AnIndex
  • aFIPC.Rcheck/aFIPC/help/aFIPC.rdb
  • aFIPC.Rcheck/aFIPC/help/aFIPC.rdx
  • aFIPC.Rcheck/aFIPC/help/aliases.rds
  • aFIPC.Rcheck/aFIPC/help/paths.rds
  • aFIPC.Rcheck/aFIPC/html/00Index.html
  • aFIPC.Rcheck/aFIPC/html/R.css
  • aFIPC.Rcheck/tests/startup.Rs
  • aFIPC.Rcheck/tests/testthat.R
  • aFIPC.Rcheck/tests/testthat.Rout
  • aFIPC.Rcheck/tests/testthat/test-autoFIPC.R
  • aFIPC.Rcheck/tests/testthat/test-fixed-parameter-calibration.R
  • aFIPC.Rcheck/tests/testthat/test-optimization-equivalence.R
  • aFIPC.Rcheck/tests/testthat/test-package-api.R
  • aFIPC.Rcheck/tests/testthat/test-regex-security.R
  • aFIPC.Rcheck/tests/testthat/test-sentinel-validation.R
  • aFIPC.Rcheck/tests/testthat/test-surveyFA.R

the item response theory paradigm using mirt package estimates.
License: GPL-3 | file LICENSE
Imports: mirt, methods
Suggests: testthat (>= 3.0.0)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

๐Ÿ“ Maintainability & Code Quality | ๐ŸŸ  Major | โšก Quick win

๐Ÿงฉ Analysis chain

๐Ÿ Script executed:

#!/bin/bash
set -eu
printf '%s\n' '--- candidate files ---'
git ls-files | rg '(^|/)(DESCRIPTION|test-regex-security\.R)$' || true
printf '%s\n' '--- DESCRIPTION ---'
desc="$(git ls-files | rg '(^|/)DESCRIPTION$' | head -n 1)"
[ -n "$desc" ] && cat -n "$desc"
printf '%s\n' '--- mockery references ---'
rg -n -C 3 'mockery|stub\s*\(' --glob '*.R' --glob 'DESCRIPTION' . || true

Repository: ContextualWisdomLab/aFIPC

Length of output: 8996


๐Ÿ Script executed:

#!/bin/bash
set -eu
python3 - <<'PY'
from pathlib import Path
import re

description = Path("DESCRIPTION").read_text(encoding="utf-8")
suggests = re.search(r"(?ms)^Suggests:\s*(.*?)(?=^[A-Za-z][A-Za-z0-9.-]*:|\Z)", description)
suggested = set()
if suggests:
    suggested = set(re.findall(r"([A-Za-z][A-Za-z0-9.]*)\s*(?:\([^)]*\))?", suggests.group(1)))

test_files = [Path("tests/testthat/test-regex-security.R")]
refs = set()
for path in test_files:
    text = path.read_text(encoding="utf-8")
    refs.update(re.findall(r"\b([A-Za-z][A-Za-z0-9.]*)::", text))

print("DESCRIPTION:", Path("DESCRIPTION"))
print("Suggests:", sorted(suggested))
print("Test namespace references:", sorted(refs))
print("mockery referenced:", "mockery" in refs)
print("mockery declared in Suggests:", "mockery" in suggested)
print("mockery declared anywhere in DESCRIPTION:", bool(re.search(r"(?im)^\s*mockery\b", description)))
PY
printf '%s\n' '--- tracked mockery/package metadata ---'
git ls-files | rg -i '(^|/)(mockery|DESCRIPTION|packrat/[^/]*(lock|init)|renv\.lock|dependencies)' | head -n 200 || true
printf '%s\n' '--- package test helper files ---'
git ls-files tests | sort

Repository: ContextualWisdomLab/aFIPC

Length of output: 3631


mockery๋ฅผ Suggests์— ์ถ”๊ฐ€ํ•˜์‹ญ์‹œ์˜ค.

tests/testthat/test-regex-security.R๋Š” mockery::stub()๋ฅผ ์‚ฌ์šฉํ•˜์ง€๋งŒ DESCRIPTION์—๋Š” testthat๋งŒ ์„ ์–ธ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ์„ ์–ธ๋œ ์˜์กด์„ฑ๋งŒ ์„ค์น˜ํ•œ ํ™˜๊ฒฝ์—์„œ๋Š” ํ…Œ์ŠคํŠธ๊ฐ€ ์‹คํŒจํ•ฉ๋‹ˆ๋‹ค.

๐Ÿค– Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@aFIPC.Rcheck/00_pkg_src/aFIPC/DESCRIPTION` at line 13, Add mockery to the
DESCRIPTION fileโ€™s Suggests dependency list alongside testthat, so
tests/testthat/test-regex-security.R can use mockery::stub() when only declared
dependencies are installed.

Comment on lines +87 to +91
if (!is.character(itemtype)) stop('Security Error: itemtype must be a character vector')
nItems <- NA_integer_
if (is.data.frame(newformXData) || is.matrix(newformXData)) nItems <- ncol(as.data.frame(newformXData))
else if (is.data.frame(oldformYData) || is.matrix(oldformYData)) nItems <- ncol(as.data.frame(oldformYData))
if (!is.na(nItems) && !(length(itemtype) == 1 || length(itemtype) == nItems)) stop(sprintf('Security Error: itemtype must be length 1 or length %d (number of items).', nItems))

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

๐ŸŽฏ Functional Correctness | ๐ŸŸ  Major | ๐Ÿ—๏ธ Heavy lift

itemtype ๊ธธ์ด ๊ฒ€์ฆ๊ณผ ์ดํ›„ if (itemtype == '3PL') ๋น„๊ต๊ฐ€ ์ถฉ๋Œํ•ฉ๋‹ˆ๋‹ค.

Line 91์€ length(itemtype) == nItems๋ฅผ ํ—ˆ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋‘ ์ž…๋ ฅ์ด ๋ชจ๋‘ mirt ๋ชจํ˜•์ด๋ฉด nItems๊ฐ€ NA๋กœ ๋‚จ์•„ ๊ธธ์ด ๊ฒ€์ฆ ์ž์ฒด๊ฐ€ ์ƒ๋žต๋ฉ๋‹ˆ๋‹ค. ๊ทธ ๋‹ค์Œ Line 166, 189, 385, 408, 607, 657, 891์€ itemtype == '3PL'์„ ์Šค์นผ๋ผ ์กฐ๊ฑด์œผ๋กœ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. itemtype ๊ธธ์ด๊ฐ€ 1๋ณด๋‹ค ํฌ๋ฉด R 4.2 ์ด์ƒ์—์„œ if ์กฐ๊ฑด ๊ธธ์ด ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

๋ฌธํ•ญ๋ณ„ itemtype ๋ฒกํ„ฐ๋ฅผ ์‹ค์ œ๋กœ ์ง€์›ํ•˜๋ ค๋ฉด ๋ชจ๋“  ๋ถ„๊ธฐ ์กฐ๊ฑด์„ identical(itemtype, '3PL') ๋˜๋Š” all(itemtype == '3PL') ํ˜•ํƒœ๋กœ ๋ฐ”๊พธ์‹ญ์‹œ์˜ค. ์ง€์›ํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด ๊ธธ์ด 1๋งŒ ํ—ˆ์šฉํ•˜์‹ญ์‹œ์˜ค.

๐Ÿ”ง ๊ธธ์ด 1๋งŒ ํ—ˆ์šฉํ•˜๋Š” ๋ฐฉ์•ˆ
-    if (!is.na(nItems) && !(length(itemtype) == 1 || length(itemtype) == nItems)) stop(sprintf('Security Error: itemtype must be length 1 or length %d (number of items).', nItems))
+    if (length(itemtype) != 1 || is.na(itemtype)) stop('Security Error: itemtype must be a single non-NA character value.')
๐Ÿ“ Committable suggestion

โ€ผ๏ธ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (!is.character(itemtype)) stop('Security Error: itemtype must be a character vector')
nItems <- NA_integer_
if (is.data.frame(newformXData) || is.matrix(newformXData)) nItems <- ncol(as.data.frame(newformXData))
else if (is.data.frame(oldformYData) || is.matrix(oldformYData)) nItems <- ncol(as.data.frame(oldformYData))
if (!is.na(nItems) && !(length(itemtype) == 1 || length(itemtype) == nItems)) stop(sprintf('Security Error: itemtype must be length 1 or length %d (number of items).', nItems))
if (!is.character(itemtype)) stop('Security Error: itemtype must be a character vector')
nItems <- NA_integer_
if (is.data.frame(newformXData) || is.matrix(newformXData)) nItems <- ncol(as.data.frame(newformXData))
else if (is.data.frame(oldformYData) || is.matrix(oldformYData)) nItems <- ncol(as.data.frame(oldformYData))
if (length(itemtype) != 1 || is.na(itemtype)) stop('Security Error: itemtype must be a single non-NA character value.')
๐Ÿค– Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@aFIPC.Rcheck/00_pkg_src/aFIPC/R/aFIPC.R` around lines 87 - 91, Update the
itemtype validation near the initial itemtype checks to reject vectors longer
than one, including when nItems remains NA for mirt inputs, so all later scalar
comparisons such as the itemtype checks in the affected branches remain valid.
Preserve the existing character-type validation and security-error style.

Comment on lines +293 to +366
if (
(!exists("oldFormModel", inherits = FALSE)) || (!isTRUE(oldFormModel@OptimInfo$secondordertest) &&
itemtype != 'ideal')
) {
message(
'Estimation failed. trying to remove weird items by itemfit statistics'
)
try(rm(oldFormModel))

oldFormModel <-
surveyFA(
oldformYData,
autofix = F,
SE = T,
forceUIRT = T
)
}

if (
(!exists("oldFormModel", inherits = FALSE)) || (!isTRUE(oldFormModel@OptimInfo$secondordertest) &&
itemtype != 'ideal')
) {
message(
'Estimation failed. trying to remove weird items by itemfit statistics by normal MMLE/EM'
)
try(rm(oldFormModel))

oldFormModel <-
surveyFA(
oldformYData,
autofix = F,
SE = T,
forceUIRT = T,
forceNormalEM = T
)
}

if (
(!exists("oldFormModel", inherits = FALSE)) || (!isTRUE(oldFormModel@OptimInfo$secondordertest) &&
itemtype != 'ideal')
) {
message(
'Estimation failed. trying to remove weird items by itemfit statistics by MMLE/QMCEM'
)
try(rm(oldFormModel))

oldFormModel <-
surveyFA(
oldformYData,
autofix = F,
SE = T,
forceUIRT = T,
unstable = T
)
}

if (
(!exists("oldFormModel", inherits = FALSE)) || (!isTRUE(oldFormModel@OptimInfo$secondordertest) &&
itemtype != 'ideal')
) {
message(
'Estimation failed. trying to remove weird items by itemfit statistics by MMLE/MHRM'
)
try(rm(oldFormModel))

oldFormModel <-
surveyFA(
oldformYData,
autofix = F,
SE = T,
forceUIRT = T,
forceMHRM = T
)
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

๐Ÿฉบ Stability & Availability | ๐ŸŸ  Major | โšก Quick win

surveyFA() ๋Œ€์ฒด ๊ฒฝ๋กœ๊ฐ€ ์˜ค๋ฅ˜ ์‹œ ๋‹ค์Œ ๋‹จ๊ณ„๋กœ ์ง„ํ–‰ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

surveyFA()๋Š” ์‹คํŒจํ•  ๋•Œ stop()์„ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค (R/surveyFA.R Line 285-290). Line 302, 320, 339, 358์˜ ํ˜ธ์ถœ์€ try()๋กœ ๊ฐ์‹ธ์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ์ฒซ ๋ฒˆ์งธ surveyFA() ํ˜ธ์ถœ์ด ์‹คํŒจํ•˜๋ฉด autoFIPC()๊ฐ€ ์ฆ‰์‹œ ์ค‘๋‹จ๋ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ Line 311-366์˜ ๋‚˜๋จธ์ง€ ๋„ค ๊ฐœ ๋Œ€์ฒด ๊ฒฝ๋กœ๋Š” ์‹คํ–‰๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ƒˆ ํผ ๊ฒฝ๋กœ(Line 511-584)์—๋„ ๊ฐ™์€ ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ฐ ๋Œ€์ฒด ํ˜ธ์ถœ์„ try()๋กœ ๊ฐ์‹ธ๊ณ  exists() ๊ฒ€์‚ฌ๋กœ ๋‹ค์Œ ๋‹จ๊ณ„๋ฅผ ์ง„ํ–‰ํ•˜์‹ญ์‹œ์˜ค.

๐Ÿ”ง ์ฒซ ๋ฒˆ์งธ ๋Œ€์ฒด ํ˜ธ์ถœ ์˜ˆ์‹œ
-        oldFormModel <-
-          surveyFA(
-            oldformYData,
-            autofix = F,
-            SE = T,
-            forceUIRT = T
-          )
+        try(
+          oldFormModel <-
+            surveyFA(
+              oldformYData,
+              autofix = F,
+              SE = T,
+              forceUIRT = T
+            ),
+          silent = TRUE
+        )
๐Ÿ“ Committable suggestion

โ€ผ๏ธ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (
(!exists("oldFormModel", inherits = FALSE)) || (!isTRUE(oldFormModel@OptimInfo$secondordertest) &&
itemtype != 'ideal')
) {
message(
'Estimation failed. trying to remove weird items by itemfit statistics'
)
try(rm(oldFormModel))
oldFormModel <-
surveyFA(
oldformYData,
autofix = F,
SE = T,
forceUIRT = T
)
}
if (
(!exists("oldFormModel", inherits = FALSE)) || (!isTRUE(oldFormModel@OptimInfo$secondordertest) &&
itemtype != 'ideal')
) {
message(
'Estimation failed. trying to remove weird items by itemfit statistics by normal MMLE/EM'
)
try(rm(oldFormModel))
oldFormModel <-
surveyFA(
oldformYData,
autofix = F,
SE = T,
forceUIRT = T,
forceNormalEM = T
)
}
if (
(!exists("oldFormModel", inherits = FALSE)) || (!isTRUE(oldFormModel@OptimInfo$secondordertest) &&
itemtype != 'ideal')
) {
message(
'Estimation failed. trying to remove weird items by itemfit statistics by MMLE/QMCEM'
)
try(rm(oldFormModel))
oldFormModel <-
surveyFA(
oldformYData,
autofix = F,
SE = T,
forceUIRT = T,
unstable = T
)
}
if (
(!exists("oldFormModel", inherits = FALSE)) || (!isTRUE(oldFormModel@OptimInfo$secondordertest) &&
itemtype != 'ideal')
) {
message(
'Estimation failed. trying to remove weird items by itemfit statistics by MMLE/MHRM'
)
try(rm(oldFormModel))
oldFormModel <-
surveyFA(
oldformYData,
autofix = F,
SE = T,
forceUIRT = T,
forceMHRM = T
)
}
if (
(!exists("oldFormModel", inherits = FALSE)) || (!isTRUE(oldFormModel@OptimInfo$secondordertest) &&
itemtype != 'ideal')
) {
message(
'Estimation failed. trying to remove weird items by itemfit statistics'
)
try(rm(oldFormModel))
try(
oldFormModel <-
surveyFA(
oldformYData,
autofix = F,
SE = T,
forceUIRT = T
),
silent = TRUE
)
}
if (
(!exists("oldFormModel", inherits = FALSE)) || (!isTRUE(oldFormModel@OptimInfo$secondordertest) &&
itemtype != 'ideal')
) {
message(
'Estimation failed. trying to remove weird items by itemfit statistics by normal MMLE/EM'
)
try(rm(oldFormModel))
oldFormModel <-
surveyFA(
oldformYData,
autofix = F,
SE = T,
forceUIRT = T,
forceNormalEM = T
)
}
if (
(!exists("oldFormModel", inherits = FALSE)) || (!isTRUE(oldFormModel@OptimInfo$secondordertest) &&
itemtype != 'ideal')
) {
message(
'Estimation failed. trying to remove weird items by itemfit statistics by MMLE/QMCEM'
)
try(rm(oldFormModel))
oldFormModel <-
surveyFA(
oldformYData,
autofix = F,
SE = T,
forceUIRT = T,
unstable = T
)
}
if (
(!exists("oldFormModel", inherits = FALSE)) || (!isTRUE(oldFormModel@OptimInfo$secondordertest) &&
itemtype != 'ideal')
) {
message(
'Estimation failed. trying to remove weird items by itemfit statistics by MMLE/MHRM'
)
try(rm(oldFormModel))
oldFormModel <-
surveyFA(
oldformYData,
autofix = F,
SE = T,
forceUIRT = T,
forceMHRM = T
)
}
๐Ÿค– Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@aFIPC.Rcheck/00_pkg_src/aFIPC/R/aFIPC.R` around lines 293 - 366, Wrap each
fallback surveyFA() invocation in the shown retry blocks, including the
corresponding fallback calls in the new-form path, so a stop() from one attempt
does not abort autoFIPC(). Preserve the existing exists("oldFormModel", inherits
= FALSE) and OptimInfo$secondordertest checks so execution proceeds to the next
fallback whenever the attempt fails.

Comment on lines +639 to +647
IPDData <-
data.frame(matrix(nrow = length(IPDgroup), ncol = IPDItemCount))
colnames(IPDData) <- paste0('X', 1:IPDItemCount)
print(IPDItemNamesOldForm)
print(IPDItemNamesNewForm)
IPDData[1:nrow(oldformYDataK), ] <-
oldformYDataK[, IPDItemNamesOldForm]
IPDData[nrow(oldformYDataK) + 1:nrow(newformXDataK), ] <-
newformXDataK[, IPDItemNamesNewForm]

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

๐Ÿฉบ Stability & Availability | ๐ŸŸก Minor | โšก Quick win

IPDItemCount๊ฐ€ 0์ด๋ฉด colnames() ํ• ๋‹น์ด ์‹คํŒจํ•ฉ๋‹ˆ๋‹ค.

Line 641์€ 1:IPDItemCount๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๊ณตํ†ต ๋ฌธํ•ญ ์ด๋ฆ„์ด ์–ด๋А ์—ด ์ด๋ฆ„๊ณผ๋„ ์ผ์น˜ํ•˜์ง€ ์•Š์œผ๋ฉด IPDItemCount๋Š” 0์ด ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด 1:0์ด ๊ธธ์ด 2 ๋ฒกํ„ฐ๋ฅผ ๋งŒ๋“ค๊ณ , 0์—ด ๋ฐ์ดํ„ฐ ํ”„๋ ˆ์ž„์— ๋Œ€ํ•œ colnames() ํ• ๋‹น์ด ์˜ค๋ฅ˜๋ฅผ ๋ƒ…๋‹ˆ๋‹ค. seq_len()์„ ์‚ฌ์šฉํ•˜๊ณ  ๋งค์นญ ์‹คํŒจ๋ฅผ ๋จผ์ € ๊ฒ€์‚ฌํ•˜์‹ญ์‹œ์˜ค.

๐Ÿ”ง ์ œ์•ˆ ์ˆ˜์ •
+      if (IPDItemCount == 0) {
+        stop('No common items matched the model column names for IPD analysis.')
+      }
       IPDData <-
         data.frame(matrix(nrow = length(IPDgroup), ncol = IPDItemCount))
-      colnames(IPDData) <- paste0('X', 1:IPDItemCount)
+      colnames(IPDData) <- paste0('X', seq_len(IPDItemCount))
๐Ÿ“ Committable suggestion

โ€ผ๏ธ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
IPDData <-
data.frame(matrix(nrow = length(IPDgroup), ncol = IPDItemCount))
colnames(IPDData) <- paste0('X', 1:IPDItemCount)
print(IPDItemNamesOldForm)
print(IPDItemNamesNewForm)
IPDData[1:nrow(oldformYDataK), ] <-
oldformYDataK[, IPDItemNamesOldForm]
IPDData[nrow(oldformYDataK) + 1:nrow(newformXDataK), ] <-
newformXDataK[, IPDItemNamesNewForm]
if (IPDItemCount == 0) {
stop('No common items matched the model column names for IPD analysis.')
}
IPDData <-
data.frame(matrix(nrow = length(IPDgroup), ncol = IPDItemCount))
colnames(IPDData) <- paste0('X', seq_len(IPDItemCount))
print(IPDItemNamesOldForm)
print(IPDItemNamesNewForm)
IPDData[1:nrow(oldformYDataK), ] <-
oldformYDataK[, IPDItemNamesOldForm]
IPDData[nrow(oldformYDataK) + 1:nrow(newformXDataK), ] <-
newformXDataK[, IPDItemNamesNewForm]
๐Ÿค– Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@aFIPC.Rcheck/00_pkg_src/aFIPC/R/aFIPC.R` around lines 639 - 647, Update the
IPDData construction around IPDItemCount to handle zero matching items safely:
check for no matches before creating or naming the data frame, and use
seq_len(IPDItemCount) instead of 1:IPDItemCount when generating column names.
Preserve the existing assignment flow for cases where common items are found.

Comment on lines +763 to +807
for (i in seq_along(oldformCommonItemNames)) {
newFormItemStr <- newformCommonItemNames[i]
oldFormItemStr <- oldformCommonItemNames[i]

newFormItemName <- newFormColNames[idxNew_all[i]]
oldFormItemName <- oldFormColNames[idxOld_all[i]]

if (
!is.na(newFormItemName) &&
!is.na(oldFormItemName) &&
(length(stats::na.omit(unique(newFormModel@Data$data[, newFormItemName]))) ==
length(stats::na.omit(unique(oldFormModel@Data$data[, oldFormItemName]))))
) {
message(
'applying ',
newFormItemStr,
' <<< ',
oldFormItemStr,
' as common item use'
)

# โšก Bolt: Use cached O(1) dictionary lookups instead of O(N) which() scans
newIdx <- newScaleParmsItemIdxCache[[newFormItemStr]]
oldIdx <- oldScaleParmsItemIdxCache[[oldFormItemStr]]

# โšก Bolt: Remove unnecessary paste0() array string generation overhead
message(' Newform Parms: ', paste(NewScaleParms[newIdx, "value"], collapse = ' '))
message(' Oldform Parms: ', paste(OldScaleParms[oldIdx, "value"], collapse = ' '))

NewScaleParms[newIdx, "value"] <-
OldScaleParms[oldIdx, "value"]
message(' Linkedform Parms: ', paste(NewScaleParms[newIdx, "value"], collapse = ' '), '\n')

NewScaleParms[newIdx, "est"] <-
FALSE
} else {
message(
'skipping ',
newFormItemStr,
' <<< ',
oldFormItemStr,
' as common item use'
)
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

๐ŸŽฏ Functional Correctness | ๐ŸŸก Minor | โšก Quick win

๊ณตํ†ต ๋ฌธํ•ญ ์ธ๋ฑ์Šค ์บ์‹œ ์กฐํšŒ ํ‚ค๊ฐ€ ์—ด ์ด๋ฆ„ ๊ฒ€์ฆ๊ณผ ๋‹ค๋ฆ…๋‹ˆ๋‹ค.

Line 767, 768์€ ๋ชจํ˜• ๋ฐ์ดํ„ฐ์˜ ์—ด ์ด๋ฆ„(newFormColNames)์œผ๋กœ ์กด์žฌ๋ฅผ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. Line 785, 786์€ ์‚ฌ์šฉ์ž ์ž…๋ ฅ ๋ฌธ์ž์—ด(newFormItemStr)๋กœ ์บ์‹œ๋ฅผ ์กฐํšŒํ•ฉ๋‹ˆ๋‹ค. ๋‘ ๊ฐ’์ด ๋‹ค๋ฅด๋ฉด (์˜ˆ: data.frame()์ด make.names()๋กœ ์ด๋ฆ„์„ ๋ณ€๊ฒฝํ•œ ๊ฒฝ์šฐ) ์ธ๋ฑ์Šค๊ฐ€ NULL์ด ๋˜๊ณ , Line 792-797์˜ ํ• ๋‹น์ด ์•„๋ฌด ํ–‰๋„ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ทธ๋ž˜๋„ ๋กœ๊ทธ๋Š” ๋งํ‚น ์„ฑ๊ณต์œผ๋กœ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.

ํ•ด๊ฒฐ๋œ ์ด๋ฆ„(newFormItemName, oldFormItemName)์œผ๋กœ ์บ์‹œ๋ฅผ ์กฐํšŒํ•˜๊ณ , ์ธ๋ฑ์Šค๊ฐ€ ๋น„์–ด ์žˆ์œผ๋ฉด ๊ฒฝ๊ณ ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ค์‹ญ์‹œ์˜ค.

๐Ÿค– Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@aFIPC.Rcheck/00_pkg_src/aFIPC/R/aFIPC.R` around lines 763 - 807, The
common-item parameter cache uses input strings instead of the validated model
column names, allowing NULL indices and false successful-link logs. In the loop
over oldformCommonItemNames, update the newScaleParmsItemIdxCache and
oldScaleParmsItemIdxCache lookups to use newFormItemName and oldFormItemName,
and warn when either resolved index is empty before attempting the parameter
assignments.

Comment on lines +63 to +88
linked <- aFIPC::autoFIPC(
newformXData = new_model,
oldformYData = old_model,
newformCommonItemNames = new_common_items,
oldformCommonItemNames = old_common_items,
itemtype = "2PL",
checkIPD = FALSE,
tryEM = TRUE,
freeMEAN = FALSE,
forceNormalZeroOne = TRUE,
confirmCommonItems = TRUE
)

linked_vcov <- as.matrix(linked$LinkedModel@vcov)
expect_gt(nrow(linked_vcov), 0)
expect_true(all(is.finite(diag(linked_vcov))))
expect_true(isTRUE(linked$LinkedModel@OptimInfo$secondordertest))

old_values <- mirt::mod2values(old_model)
linked_values <- mirt::mod2values(linked$LinkedModel)
linked_structural <- linked_values[
linked_values$item %in% new_item_names[5:6] &
linked_values$name %in% c("g", "u"),
"est"
]
expect_false(any(linked_structural))

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

๐ŸŽฏ Functional Correctness | ๐ŸŸก Minor | โšก Quick win

forceNormalZeroOne = TRUE์˜ ํšจ๊ณผ๋ฅผ ๊ฒ€์ฆํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์ด ํ…Œ์ŠคํŠธ๋Š” forceNormalZeroOne = TRUE๋ฅผ ์ „๋‹ฌํ•˜์ง€๋งŒ, ์ž ์žฌ ๋ถ„ํฌ ๋ชจ์ˆ˜๋ฅผ ํ™•์ธํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. R/aFIPC.R Line 856-868์˜ ํ‰๊ท  ๊ณ ์ • ๊ฒฐํ•จ์ด ์ด ํ…Œ์ŠคํŠธ๋กœ ๊ฒ€์ถœ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์—ฐ๊ฒฐ ๋ชจํ˜•์˜ ๊ทธ๋ฃน ๋ชจ์ˆ˜์— ๋Œ€ํ•œ ๊ธฐ๋Œ€๊ฐ’์„ ์ถ”๊ฐ€ํ•˜์‹ญ์‹œ์˜ค.

๐Ÿ”ง ์ œ์•ˆ ์ถ”๊ฐ€ ๊ฒ€์ฆ
   linked_values <- mirt::mod2values(linked$LinkedModel)
+  group_values <- linked_values[linked_values$item == "GROUP", ]
+  expect_equal(group_values$value[group_values$name == "MEAN_1"], 0)
+  expect_equal(group_values$value[group_values$name == "COV_11"], 1)
+  expect_false(any(group_values$est))
๐Ÿ“ Committable suggestion

โ€ผ๏ธ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
linked <- aFIPC::autoFIPC(
newformXData = new_model,
oldformYData = old_model,
newformCommonItemNames = new_common_items,
oldformCommonItemNames = old_common_items,
itemtype = "2PL",
checkIPD = FALSE,
tryEM = TRUE,
freeMEAN = FALSE,
forceNormalZeroOne = TRUE,
confirmCommonItems = TRUE
)
linked_vcov <- as.matrix(linked$LinkedModel@vcov)
expect_gt(nrow(linked_vcov), 0)
expect_true(all(is.finite(diag(linked_vcov))))
expect_true(isTRUE(linked$LinkedModel@OptimInfo$secondordertest))
old_values <- mirt::mod2values(old_model)
linked_values <- mirt::mod2values(linked$LinkedModel)
linked_structural <- linked_values[
linked_values$item %in% new_item_names[5:6] &
linked_values$name %in% c("g", "u"),
"est"
]
expect_false(any(linked_structural))
linked <- aFIPC::autoFIPC(
newformXData = new_model,
oldformYData = old_model,
newformCommonItemNames = new_common_items,
oldformCommonItemNames = old_common_items,
itemtype = "2PL",
checkIPD = FALSE,
tryEM = TRUE,
freeMEAN = FALSE,
forceNormalZeroOne = TRUE,
confirmCommonItems = TRUE
)
linked_vcov <- as.matrix(linked$LinkedModel@vcov)
expect_gt(nrow(linked_vcov), 0)
expect_true(all(is.finite(diag(linked_vcov))))
expect_true(isTRUE(linked$LinkedModel@OptimInfo$secondordertest))
old_values <- mirt::mod2values(old_model)
linked_values <- mirt::mod2values(linked$LinkedModel)
group_values <- linked_values[linked_values$item == "GROUP", ]
expect_equal(group_values$value[group_values$name == "MEAN_1"], 0)
expect_equal(group_values$value[group_values$name == "COV_11"], 1)
expect_false(any(group_values$est))
linked_structural <- linked_values[
linked_values$item %in% new_item_names[5:6] &
linked_values$name %in% c("g", "u"),
"est"
]
expect_false(any(linked_structural))
๐Ÿค– Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@aFIPC.Rcheck/00_pkg_src/aFIPC/tests/testthat/test-fixed-parameter-calibration.R`
around lines 63 - 88, Extend the test around the autoFIPC call and
linked$LinkedModel to assert the latent distribution group parameters produced
with forceNormalZeroOne = TRUE, including the expected fixed mean values. Use
the existing mirt model-value inspection pattern and verify the relevant
group-parameter estimates so a regression in the mean-fixing behavior is
detected, while preserving the current covariance and structural-parameter
checks.

Comment on lines +61 to +70
test_that("surveyFA reports bounded recovery exhaustion when unrecoverable", {
skip_if_not_installed("mirt")

raw <- as.data.frame(
matrix(
c(rbinom(80, 1, 0.5), rbinom(80, 1, 0.4)),
ncol = 2
)
)
names(raw) <- paste0("item", 1:2)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

๐Ÿ“ Maintainability & Code Quality | ๐ŸŸก Minor | โšก Quick win

set.seed()๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ ์žฌํ˜„์„ฑ์„ ํ™•๋ณดํ•˜์‹ญ์‹œ์˜ค.

Line 66์€ rbinom()์„ ์‹œ๋“œ ์—†์ด ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฏ€๋กœ ๊ฐ ์‹คํ–‰๋งˆ๋‹ค ์‘๋‹ต ๋ฐ์ดํ„ฐ๊ฐ€ ๋‹ฌ๋ผ์ง€๊ณ , ์‹คํŒจ๊ฐ€ ์žฌํ˜„๋˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ํ…Œ์ŠคํŠธ์™€ ๋™์ผํ•˜๊ฒŒ ์‹œ๋“œ๋ฅผ ๊ณ ์ •ํ•˜์‹ญ์‹œ์˜ค.

๐Ÿ”ง ์ œ์•ˆ ์ˆ˜์ •
 test_that("surveyFA reports bounded recovery exhaustion when unrecoverable", {
   skip_if_not_installed("mirt")
+  set.seed(20260703)
๐Ÿ“ Committable suggestion

โ€ผ๏ธ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
test_that("surveyFA reports bounded recovery exhaustion when unrecoverable", {
skip_if_not_installed("mirt")
raw <- as.data.frame(
matrix(
c(rbinom(80, 1, 0.5), rbinom(80, 1, 0.4)),
ncol = 2
)
)
names(raw) <- paste0("item", 1:2)
test_that("surveyFA reports bounded recovery exhaustion when unrecoverable", {
skip_if_not_installed("mirt")
set.seed(20260703)
raw <- as.data.frame(
matrix(
c(rbinom(80, 1, 0.5), rbinom(80, 1, 0.4)),
ncol = 2
)
)
names(raw) <- paste0("item", 1:2)
๐Ÿค– Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@aFIPC.Rcheck/00_pkg_src/aFIPC/tests/testthat/test-surveyFA.R` around lines 61
- 70, Set a deterministic seed before the rbinom calls in the surveyFA
exhaustion test so the generated response data is reproducible across runs.
Follow the seed-setting convention used by the surrounding tests and leave the
test data generation otherwise unchanged.

Comment on lines +126 to +129
span.rlang {
font-family: Courier New, Courier;
color: #666666;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

๐Ÿ“ Maintainability & Code Quality | ๐ŸŸก Minor | โšก Quick win

Stylelint ์˜ค๋ฅ˜๋ฅผ ์ˆ˜์ •ํ•˜์„ธ์š”.

Line 127์˜ Courier New๋Š” ๊ณต๋ฐฑ์ด ์žˆ๋Š” ๊ธ€๊ผด ์ด๋ฆ„์ž…๋‹ˆ๋‹ค. ๋”ฐ์˜ดํ‘œ๋กœ ๊ฐ์‹ธ์„œ font-family-name-quotes ์˜ค๋ฅ˜๋ฅผ ์ œ๊ฑฐํ•˜์„ธ์š”.

์ˆ˜์ • ์˜ˆ์‹œ
 span.rlang {
-    font-family: Courier New, Courier;
+    font-family: "Courier New", Courier;
     color: `#666666`;
 }
๐Ÿ“ Committable suggestion

โ€ผ๏ธ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
span.rlang {
font-family: Courier New, Courier;
color: #666666;
}
span.rlang {
font-family: "Courier New", Courier;
color: `#666666`;
}
๐Ÿงฐ Tools
๐Ÿช› Stylelint (17.14.1)

[error] 127-127: Expected quotes around "Courier New" (font-family-name-quotes)

(font-family-name-quotes)

๐Ÿค– Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@aFIPC.Rcheck/aFIPC/html/R.css` around lines 126 - 129, Update the font-family
declaration in span.rlang to quote the spaced font name Courier New, while
preserving the existing fallback Courier and color styling.

Source: Linters/SAST tools

Comment on lines +3 to +5
export(autoFIPC)
export(surveyFA)
import(mirt)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

๐Ÿ“ Maintainability & Code Quality | ๐ŸŸ  Major | โšก Quick win

R CMD check ์‚ฐ์ถœ๋ฌผ ๋””๋ ‰ํ„ฐ๋ฆฌ๊ฐ€ ์ €์žฅ์†Œ์— ์ปค๋ฐ‹๋˜์—ˆ์Šต๋‹ˆ๋‹ค. aFIPC.Rcheck/๋Š” R CMD check๊ฐ€ ์ƒ์„ฑํ•˜๋Š” ๋””๋ ‰ํ„ฐ๋ฆฌ์ž…๋‹ˆ๋‹ค. ๊ทธ ๊ฒฐ๊ณผ ์†Œ์Šค ํŒŒ์ผ์ด ์—ฌ๋Ÿฌ ์œ„์น˜์— ์ค‘๋ณต๋˜๊ณ , ํŽธ์ง‘ํ•œ ์‚ฌ๋ณธ๊ณผ ์ƒ์„ฑ๋œ ์‚ฌ๋ณธ์ด ์„œ๋กœ ์–ด๊ธ‹๋‚  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • aFIPC.Rcheck/aFIPC/NAMESPACE#L3-L5: ์ด ์ƒ์„ฑ๋œ ์‚ฌ๋ณธ์„ ์ถ”์  ๋Œ€์ƒ์—์„œ ์ œ๊ฑฐํ•˜๊ณ , .gitignore์— *.Rcheck/๋ฅผ ์ถ”๊ฐ€ํ•˜์‹ญ์‹œ์˜ค.
  • aFIPC.Rcheck/tests/testthat/test-fixed-parameter-calibration.R#L1-L123: ์ด ํŒŒ์ผ์€ aFIPC.Rcheck/00_pkg_src/aFIPC/tests/testthat/test-fixed-parameter-calibration.R์™€ ๋™์ผํ•ฉ๋‹ˆ๋‹ค. ํ…Œ์ŠคํŠธ ์›๋ณธ์€ ์ €์žฅ์†Œ ๋ฃจํŠธ์˜ tests/testthat/์—๋งŒ ์œ ์ง€ํ•˜๊ณ  ์ด ์‚ฌ๋ณธ์„ ์ œ๊ฑฐํ•˜์‹ญ์‹œ์˜ค.
๐Ÿ“ Affects 2 files
  • aFIPC.Rcheck/aFIPC/NAMESPACE#L3-L5 (this comment)
  • aFIPC.Rcheck/tests/testthat/test-fixed-parameter-calibration.R#L1-L123
๐Ÿค– Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@aFIPC.Rcheck/aFIPC/NAMESPACE` around lines 3 - 5, Remove the generated
aFIPC.Rcheck directory contents from version control, including
aFIPC.Rcheck/aFIPC/NAMESPACE and the duplicate
test-fixed-parameter-calibration.R under aFIPC.Rcheck/tests/testthat; retain the
test only in the repositoryโ€™s root tests/testthat directory. Add *.Rcheck/ to
.gitignore so future R CMD check output is ignored.

Comment on lines +1 to +12
test_that("autoFIPC raises error in non-interactive session for inputs", {
# interactive() should be FALSE by default in testthat environments
expect_error(
aFIPC::autoFIPC(
newformXData = data.frame(A=1),
oldformYData = data.frame(A=2),
newformCommonItemNames = c('A'),
oldformCommonItemNames = c('A')
),
"Common item confirmation requires an interactive session"
)
})

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

๐Ÿฉบ Stability & Availability | ๐ŸŸ  Major | โšก Quick win

๐Ÿงฉ Analysis chain

๐Ÿ Script executed:

#!/bin/bash
set -euo pipefail

# autoFIPC()์˜ interactive() ๋ถ„๊ธฐ์™€ ํ…Œ์ŠคํŠธ์˜ ๊ธฐ๋Œ€ ์˜ค๋ฅ˜๊ฐ€ ๊ฐ™์€ ๊ฒฝ๋กœ์ธ์ง€ ํ™•์ธํ•œ๋‹ค.
ast-grep outline aFIPC.Rcheck/00_pkg_src/aFIPC/R/aFIPC.R --items all || true
rg -n -C 5 'interactive\(\)|readline|Common item confirmation requires an interactive session' \
  aFIPC.Rcheck/00_pkg_src/aFIPC/R/aFIPC.R \
  aFIPC.Rcheck/tests/testthat/test-autoFIPC.R

Repository: ContextualWisdomLab/aFIPC

Length of output: 5143


๐Ÿ Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '--- package metadata and test configuration ---'
fd -i '^(DESCRIPTION|NAMESPACE|.*test.*|.*config.*)$' . | sed -n '1,120p'
rg -n -C 4 'testthat|devtools::test|autoFIPC|confirmCommonItems' \
  DESCRIPTION NAMESPACE .github tests aFIPC.Rcheck 2>/dev/null | sed -n '1,260p'

printf '%s\n' '--- relevant source and tests ---'
sed -n '110,155p' aFIPC.Rcheck/00_pkg_src/aFIPC/R/aFIPC.R
sed -n '1,80p' aFIPC.Rcheck/tests/testthat/test-autoFIPC.R

printf '%s\n' '--- available R tooling, without loading repository code ---'
command -v Rscript || true
Rscript --version 2>/dev/null || true

Repository: ContextualWisdomLab/aFIPC

Length of output: 28165


๐ŸŒ Web query:

R testthat interactive() devtools::test interactive session behavior

๐Ÿ’ก Result:

When running tests via devtools::test or testthat, the R session is explicitly configured to simulate a non-interactive environment to ensure reproducible results [1][2]. Key behavioral details include: 1. Interaction Suppression: During tests, the testthat package automatically calls local_test_context(), which sets the option rlang_interactive = FALSE [1][2]. This ensures that rlang::is_interactive() returns FALSE, causing your code to behave as if it is not in an interactive session [1][2]. This override is intentionally designed to prevent tests from waiting for user input or behaving differently due to terminal capabilities [1]. 2. Environment Variables: local_test_context() also sets the environment variable TESTTHAT = "true" [1]. Historically, this was the primary mechanism used to signal to code that tests were running; modern R development practice prefers rlang::is_interactive() for this purpose [3][4]. 3. Testing vs. Interactive Development: Because interactive() (from base R) and rlang::is_interactive() will return FALSE during these tests, you cannot directly test code paths that require an interactive terminal by simply calling test() [3][5]. If you need to test code that behaves differently based on interactivity, it is recommended to use rlang::is_interactive() and control its behavior by setting the rlang_interactive option during your test, rather than trying to override the base interactive() function, which is difficult to mock reliably [3][5]. 4. Mocking: While it is possible to mock functions like interactive() by binding them to NULL in your package's namespace and using local_mocked_bindings(), this approach is generally discouraged in favor of the rlang abstraction, which is built to be configurable for testing environments [3][6][5]. In summary, devtools::test enforces a non-interactive state to guarantee consistency [1]. If your code relies on interactivity, you should refactor it to check rlang::is_interactive() and use testthat's built-in tools to manipulate that state within your tests [3][1].

Citations:


๐Ÿ Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '--- bundled testthat/devtools sources ---'
fd -i '^(testthat|devtools)$' packrat/lib 2>/dev/null | sed -n '1,80p'
rg -n -C 5 'local_test_context|rlang_interactive|test_dir|interactive[[:space:]]*=' \
  packrat/lib 2>/dev/null | sed -n '1,260p'

printf '%s\n' '--- project tests that exercise the same branch ---'
sed -n '1,55p' tests/testthat/test-package-api.R 2>/dev/null || true
sed -n '1,35p' tests/testthat/test-autoFIPC.R 2>/dev/null || true

Repository: ContextualWisdomLab/aFIPC

Length of output: 4954


๐ŸŒ Web query:

site:testthat.r-lib.org testthat interactive() base R test_dir devtools::test

๐Ÿ’ก Result:

In the testthat ecosystem, the interaction between test execution and environment settings is managed primarily through automated test contexts. Interactive Execution vs. Testing When running tests, testthat attempts to create a reproducible, non-interactive environment to ensure consistent results regardless of the user's local settings [1]. The function testthat::local_test_context (called automatically by test_that) sets the option rlang_interactive = FALSE, ensuring that rlang::is_interactive returns FALSE [1]. This allows your code to behave as if it were running in a non-interactive, automated environment [1]. Note that base R's interactive function cannot be reliably controlled via test fixtures; it is recommended to use rlang::is_interactive instead [2]. test_dir vs. devtools::test - devtools::test: This is the standard, high-level function for running all tests in an R package [3]. It is designed for developers and is typically triggered by RStudio shortcuts (e.g., Ctrl+Shift+T) [3]. It automatically handles the loading of package code, dependencies, and reporting [3][4]. - test_dir: This is a lower-level function intended for executing test files within a specific directory [5]. It is a "workhorse" function that powers higher-level tools like test_local and test_package [5][6]. Users generally should not call test_dir directly unless building specialized testing infrastructure, as it requires manual configuration of package environments (e.g., how to load the package code) [5]. Key Takeaways - Snapshot Testing: Snapshot tests rely on the context of a full test execution (e.g., via devtools::test or test_dir) to locate snapshot files [7]. They function differently when run interactively at the console compared to when they are part of a full test suite [7]. - Testing Status: You can use testthat::is_testing to check if code is running within a test suite [8]. For package-level checks (like R CMD check), use test_check [6]. - Reproducibility: Always prefer testthat's built-in context management (like local_test_context) over manually altering global options to simulate interactive or non-interactive states [1].

Citations:


๋Œ€ํ™”ํ˜• ์„ธ์…˜์—์„œ๋Š” ์ด ํ…Œ์ŠคํŠธ๋ฅผ ๊ฑด๋„ˆ๋›ฐ์„ธ์š”.

testthat๋Š” rlang::is_interactive()๋งŒ ์ œ์–ดํ•˜๋ฉฐ base R์˜ interactive()๋Š” ๋ณ€๊ฒฝํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋Œ€ํ™”ํ˜• R ์„ธ์…˜์—์„œ devtools::test()๋ฅผ ์‹คํ–‰ํ•˜๋ฉด autoFIPC()๊ฐ€ readline()์„ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. skip_if(interactive())๋ฅผ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜ ๋น„๋Œ€ํ™”ํ˜• ํ•˜์œ„ ํ”„๋กœ์„ธ์Šค์—์„œ assertion์„ ์‹คํ–‰ํ•˜์„ธ์š”.

๐Ÿค– Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@aFIPC.Rcheck/tests/testthat/test-autoFIPC.R` around lines 1 - 12, Update the
test identified by โ€œautoFIPC raises error in non-interactive session for inputsโ€
to skip when base R interactive() is TRUE, before invoking autoFIPC. Keep the
existing non-interactive error assertion unchanged.

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.

1 participant