feat: add preferences.anonymous for blind-review mode#68
Conversation
a0f9abf to
6be4fee
Compare
📝 WalkthroughWalkthroughAdds ChangesAnonymous / blind-review mode
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
lib.typ (1)
1264-1267:⚠️ Potential issue | 🟠 Major | ⚡ Quick winAnonymous mode still leaks identity when
pageFooteris"auto".Line 1266 always passes
cv.basics.nameinto_auto_page_footer(...), so multi-page output can expose the real name even withpreferences.anonymous: true.Proposed fix
- let resolved-footer = if page-footer != none { + let footer-name = if preferences.anonymous { "Candidate" } else { cv.basics.name } + let resolved-footer = if page-footer != none { if page-footer == "auto" { - _auto_page_footer(cv.basics.name) + _auto_page_footer(footer-name) } else { page-footer }🤖 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 `@lib.typ` around lines 1264 - 1267, The _auto_page_footer() function on line 1266 always receives the actual name from cv.basics.name, which exposes the user's identity even when anonymous mode is enabled via preferences.anonymous. Check if anonymous mode is active before calling _auto_page_footer(), and if it is, pass an empty string or placeholder value instead of cv.basics.name to prevent identity leakage in the footer.
🤖 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 `@lib.typ`:
- Around line 1245-1246: The anonymous mode document title on line 1245 is
inconsistent with the documented placeholder value. The doc-author is correctly
set to "Candidate" as documented, but doc-title uses "Candidate --- CV" instead
of just "Candidate". Update the doc-title assignment to use "Candidate" as the
anonymous title value (without the " --- CV" suffix) to align with the
documented placeholder and maintain consistency with the doc-author value on
line 1246.
In `@tests/anonymous.typ`:
- Around line 18-39: The test fixture in tests/anonymous.typ is incomplete at
two locations and does not validate all advertised anonymous-mode behaviors. At
the first location (lines 18-39) with the cv object containing basics and work,
add a basics.image field to properly exercise portrait suppression during
testing. At the second location (lines 45-52), add both a summary field to the
basics section and include a sections array with data so the fixture can
properly validate that summary and sections content still render correctly in
anonymous mode, matching what the test comments assert.
---
Outside diff comments:
In `@lib.typ`:
- Around line 1264-1267: The _auto_page_footer() function on line 1266 always
receives the actual name from cv.basics.name, which exposes the user's identity
even when anonymous mode is enabled via preferences.anonymous. Check if
anonymous mode is active before calling _auto_page_footer(), and if it is, pass
an empty string or placeholder value instead of cv.basics.name to prevent
identity leakage in the footer.
🪄 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: ASSERTIVE
Plan: Pro Plus
Run ID: 2301e5af-ac9f-4e20-b9ee-1ce410ff71c0
⛔ Files ignored due to path filters (1)
examples/tests/anonymous.pdfis excluded by!**/*.pdf
📒 Files selected for processing (3)
README.mdlib.typtests/anonymous.typ
| let doc-title = if preferences.anonymous { "Candidate --- CV" } else { cv.basics.name + " --- CV" } | ||
| let doc-author = if preferences.anonymous { "Candidate" } else { cv.basics.name } |
There was a problem hiding this comment.
Anonymous metadata title value is inconsistent with the stated "Candidate" placeholder.
Line 1245 sets title to "Candidate --- CV" while the feature docs describe "Candidate" as the placeholder. Please align implementation and documentation to one contract.
🤖 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 `@lib.typ` around lines 1245 - 1246, The anonymous mode document title on line
1245 is inconsistent with the documented placeholder value. The doc-author is
correctly set to "Candidate" as documented, but doc-title uses "Candidate ---
CV" instead of just "Candidate". Update the doc-title assignment to use
"Candidate" as the anonymous title value (without the " --- CV" suffix) to align
with the documented placeholder and maintain consistency with the doc-author
value on line 1246.
| #let cv = ( | ||
| basics: ( | ||
| name: "Jane Doe", | ||
| label: "Senior Software Engineer", | ||
| summary: [Backend engineer with eight years' experience.], | ||
| email: "jane@example.com", | ||
| phone: "+353 1 555 0100", | ||
| location: "Dublin, Ireland", | ||
| url: "https://janedoe.dev", | ||
| profiles: ( | ||
| (network: "GitHub", username: "janedoe", url: "https://github.com/janedoe"), | ||
| ), | ||
| ), | ||
| work: ( | ||
| ( | ||
| name: "Acme Corp", | ||
| position: "Senior Software Engineer", | ||
| startDate: "Jan 2022", | ||
| highlights: ([Led the platform migration.],), | ||
| ), | ||
| ), | ||
| ) |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial | ⚡ Quick win
This fixture misses two advertised anonymous-mode behaviors.
Case 1 doesn’t provide basics.image, so portrait suppression isn’t exercised. Case 2 claims summary/sections still render, but includes neither. Please add those inputs so the fixture validates what its comments assert.
Suggested fixture adjustments
`#let` cv = (
basics: (
name: "Jane Doe",
label: "Senior Software Engineer",
+ image: read("../examples/avatar-placeholder.svg", encoding: none),
summary: [Backend engineer with eight years' experience.],
@@
`#alta`(
(basics: (
name: "Jane Doe",
+ summary: [Anonymous summary should still render.],
email: "jane@example.com",
phone: "+353 1 555 0100",
- )),
+ ),
+ work: (
+ (
+ name: "Acme Corp",
+ position: "Engineer",
+ startDate: "2024",
+ highlights: ([Section rendering still works.],),
+ ),
+ )),
preferences: (anonymous: true),
)Also applies to: 45-52
🤖 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/anonymous.typ` around lines 18 - 39, The test fixture in
tests/anonymous.typ is incomplete at two locations and does not validate all
advertised anonymous-mode behaviors. At the first location (lines 18-39) with
the cv object containing basics and work, add a basics.image field to properly
exercise portrait suppression during testing. At the second location (lines
45-52), add both a summary field to the basics section and include a sections
array with data so the fixture can properly validate that summary and sections
content still render correctly in anonymous mode, matching what the test
comments assert.
6be4fee to
1d1459e
Compare
Enables a single-toggle blind-review render: the header drops basics.name, basics.image, and the contact bar; basics.label (when present) becomes the sole header line. PDF metadata title and author are swapped for the placeholder "Candidate" so the file itself cannot unmask the candidate via its document properties. All other sections render normally — same data dict, same compile command, single toggle. Closes #55
2c10506 to
adcc661
Compare
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
lib.typ (1)
1523-1526:⚠️ Potential issue | 🟠 Major | ⚡ Quick winAnonymous mode still leaks identity when
pageFooteris"auto".Line 1525 always passes
cv.basics.nameinto_auto_page_footer(...). Withpreferences.anonymous: true, that reintroduces identifying data in rendered output.🔧 Suggested fix
let resolved-footer = if page-footer != none { if page-footer == "auto" { - _auto_page_footer(cv.basics.name) + _auto_page_footer(if preferences.anonymous { "Candidate" } else { cv.basics.name }) } else { page-footer }🤖 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 `@lib.typ` around lines 1523 - 1526, The _auto_page_footer function is being called with cv.basics.name unconditionally when page-footer equals "auto", which leaks the user's identity even when anonymous mode is enabled through preferences.anonymous. Modify the condition where _auto_page_footer is called to check the anonymous preference setting, and pass either cv.basics.name or none (or an appropriate anonymous placeholder) based on whether preferences.anonymous is true or false.
♻️ Duplicate comments (2)
lib.typ (1)
1504-1510:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winAlign anonymous
titlemetadata with the documented"Candidate"placeholder.Line 1504 sets
"Candidate --- CV"while the documented contract says anonymoustitle/authoruse"Candidate".🔧 Suggested fix
- let doc-title = if preferences.anonymous { "Candidate --- CV" } else { cv.basics.name + " --- CV" } + let doc-title = if preferences.anonymous { "Candidate" } else { cv.basics.name + " --- CV" }🤖 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 `@lib.typ` around lines 1504 - 1510, The doc-title variable in the anonymous preference block is set to "Candidate --- CV" but the documented contract specifies that the anonymous title should be just "Candidate" to match the author metadata. Update the doc-title assignment in the conditional expression (where preferences.anonymous is true) to use "Candidate" instead of "Candidate --- CV" to align with the documented behavior and maintain consistency with the anonymous author value.tests/anonymous.typ (1)
9-14:⚠️ Potential issue | 🟠 Major | ⚡ Quick winFixture comments overstate coverage for anonymous mode.
The current data does not exercise two behaviors it claims:
- Case 1 (Lines 9-10/18-39) never sets
basics.image, so portrait suppression isn’t tested.- Case 2 (Lines 11-12/45-52) includes neither
basics.summarynor any section data, so “summary + sections still render” is unverified.🔧 Suggested fixture update
`#let` cv = ( basics: ( name: "Jane Doe", label: "Senior Software Engineer", + image: read("../examples/avatar-placeholder.svg", encoding: none), summary: [Backend engineer with eight years' experience.], @@ `#alta`( (basics: ( name: "Jane Doe", + summary: [Anonymous summary should still render.], email: "jane@example.com", phone: "+353 1 555 0100", - )), + ), + work: ( + ( + name: "Acme Corp", + position: "Engineer", + startDate: "2024", + highlights: ([Section rendering still works.],), + ), + )), preferences: (anonymous: true), )Also applies to: 18-39, 45-52
🤖 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/anonymous.typ` around lines 9 - 14, The test fixture comments in the anonymous mode test cases describe behaviors that aren't actually exercised by the fixture data. Update Case 1 (the first anonymous-on test with fully-populated basics around lines 18-39) to include a basics.image field so that portrait suppression is properly tested as claimed in the comment. Update Case 2 (the anonymous-on test with no label around lines 45-52) to include both basics.summary content and at least one section with data so that the comment's claim about "summary + sections still render" is actually verified by the fixture rather than just asserted without evidence.
🤖 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.
Outside diff comments:
In `@lib.typ`:
- Around line 1523-1526: The _auto_page_footer function is being called with
cv.basics.name unconditionally when page-footer equals "auto", which leaks the
user's identity even when anonymous mode is enabled through
preferences.anonymous. Modify the condition where _auto_page_footer is called to
check the anonymous preference setting, and pass either cv.basics.name or none
(or an appropriate anonymous placeholder) based on whether preferences.anonymous
is true or false.
---
Duplicate comments:
In `@lib.typ`:
- Around line 1504-1510: The doc-title variable in the anonymous preference
block is set to "Candidate --- CV" but the documented contract specifies that
the anonymous title should be just "Candidate" to match the author metadata.
Update the doc-title assignment in the conditional expression (where
preferences.anonymous is true) to use "Candidate" instead of "Candidate --- CV"
to align with the documented behavior and maintain consistency with the
anonymous author value.
In `@tests/anonymous.typ`:
- Around line 9-14: The test fixture comments in the anonymous mode test cases
describe behaviors that aren't actually exercised by the fixture data. Update
Case 1 (the first anonymous-on test with fully-populated basics around lines
18-39) to include a basics.image field so that portrait suppression is properly
tested as claimed in the comment. Update Case 2 (the anonymous-on test with no
label around lines 45-52) to include both basics.summary content and at least
one section with data so that the comment's claim about "summary + sections
still render" is actually verified by the fixture rather than just asserted
without evidence.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: aa358486-f646-4558-a310-beb393250e5b
⛔ Files ignored due to path filters (1)
examples/tests/anonymous.pdfis excluded by!**/*.pdf
📒 Files selected for processing (3)
README.mdlib.typtests/anonymous.typ
|
Superseded by #122 — rewritten from scratch on top of the post-#68 refactorings ( |
Summary
Adds
preferences.anonymous: bool(defaultfalse). Whentrue, the rendered header dropsbasics.name,basics.image, and the contact bar entirely;basics.labelbecomes the sole header line. PDF metadatatitleandauthorare swapped for the generic placeholder"Candidate"so the file itself cannot leak identity via document properties.Closes #55
Rendered output
CI uploads the
example-pdfartifact. A newtests/anonymous.typfixture renders three pages exercising the toggle:basics— name / photo / contact bar dropped, label remains.label— header collapses cleanly (summary + sections still render).Test plan
typst compile --root . examples/example.typ examples/example.pdfsucceedstests/*.typfixture compilestests/(newtests/anonymous.typ)anonymouskeyNotes for the reviewer
linkContactInfofor non-blind cases.basics.imagevalidation still runs whenanonymous: trueso a malformed value cannot slip through unnoticed via the flag.set document(title:, author:)placeholder is"Candidate"— keeps a friendly value over an empty string (which some PDF readers render as"Untitled").JSON Resume alignment
NOT IN SPEC —
preferences.anonymousis a rendering/template preference for blind-review use, not part of the JSON Resume data schema (https://jsonresume.org/schema/). The schema fields it suppresses (basics.name, contact info, photo) remain spec-compliant in the data; only the rendered output is redacted.Summary by CodeRabbit
New Features
preferences.anonymous(default off). When enabled, the resume header suppresses identifying details (name/photo and the contact bar, while still showing any label). PDF document metadata is also redacted by using generic placeholders and removing identity-revealing fields.Documentation
preferences.anonymousoption and its effects on header rendering and PDF metadata.Tests