Content Audit Tool: Closing the Loop Between Content Design and Source Code

My Role

Product Design Intern

Team

Design Foundations

Timeline

9 Weeks

Tools

Figma, Claude Code, Miro, Github

Platform

Internal Tools

Section 01: The Brief & The Discovery

The Brief

Operating within the Design Foundations team, my mandate was to identify a systemic problem and ship a plug-in to solve it proving the value of "agentic design" by using AI to build real software.

The Discovery

I expected to hear complaints about layer naming or detached components. To validate the actual friction points, I engaged the broader design org:

  • 40-Designer Survey: A wide-net assessment focused on daily Figma workflows, repetitive manual tasks, and tool friction.
  • 8 Internal Interviews: Deep-dive conversations with product designers to uncover their most expensive bottlenecks.

The Insight: The Copy Blind Spot

Instead of component issues, the research revealed a massive organizational gap regarding product copy:

  • Designers ≠ Writers: Designers were writing the UI text that ultimately shipped to production, despite not being content experts.
  • Zero Quality Gates: With limited UX-writer capacity and no centralised glossary, brand consistency was checked manually, if at all.
  • The Codebase Disconnect: The person qualified to judge the copy did not have the codebase open. Fixing a single string meant filing a Jira ticket and waiting weeks for an engineer to implement it.

Section 02: Architecture & Key Decisions

The Core Thesis

The foundational rule of this tool is that the person qualified to judge the copy must be able to fix it without leaving their canvas. It reads the UI copy directly from the codebase, judges it against the brand guidelines, and writes approved fixes straight back into the source files they came from.

Architectural Decisions

page.tsx:112

Add lecture

Add a lecture

cta.no-leading-article

Tone Check

Approve

Reject

Skip

Decision 01: Hybrid Evaluation (Code + LLM): The Scan engine utilises a two-pass hybrid approach. Deterministic rules (character limits, accessibility) are checked instantly, while the LLM handles holistic judgment (tone, redundancy). Both are fed by a centralised Rule registry.

filePath

/course-hero.tsx

stableId: component

+ ATS anchor

status: approved-local

Hash Key = sha256(filePath + stableStringID + normalised text

Decision 02: The Git-Tracked Cache: To prevent reviewers from answering the same question twice, the tool merges data from the source and a durable scan-log.json. This acts as a decision cache, ensuring the codebase remains the strict single source of truth without duplicating the actual string text.

STEP 01

Action: Approve

Write file locally. Status flipped to approved-local.

No Git operation triggered.

STEP 02

Action: Batch PR

Resolves session branch. One commit per approved string. PR opened via GitHub identity.

Decision 03: Decoupling Writes from Commits: The initial design committed a file change every time a reviewer clicked "Approve," which silently modified the working tree mid-session. The architecture was restructured so that approvals only trigger a local Write-back operation. Git operations are deferred entirely to a session batch, which opens a Pull Request directly via GitHub (GitHub -> PR opened).

Section 03: The Interface

The Audit Scope

The UI docks as a genuine flex sibling, offering three levels of precision: scanning the current route, auditing the full application, or using a live text picker to check a single string.

S

Good evening, Sam

Need help? Tell me a little about yourself so I can make the best recommendations.

Set your goal

In Progress

Completed

Skills

Certificates

Google

Build Wireframes and Low-Fidelity Prototypes

Course

·

16% complete

·

Estimated completion: Oct 20, 2025

Learn more about creating storyboards

Reading (8 minutes)

Resume

September 2026

Mo

Tu

We

Th

Fr

Sa

Su

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

1+ daily goals completed

All daily goals completed

Last 4 weeks

0

Daily goals completed

0

Items completed

0

Minutes learned

Explore

My Learning

Degrees

What do you want to learn?

S

Audit page content

Scan page

Scan app

227 strings scanned · 40 rule violations · 30 style suggestions

Rule violations (40)

Approve all rule violations

Rule violation

page.tsx:112

"Reading (8 minutes)" Uses full spelled-out duration strings in parentheses, violating the microcopy standard for content cards.

Reading (8 minutes)

8 min read

Approve

Reject

Skip

Rule violation

debug-journey-picker.tsx:186

"Good evening, Sam" Uses time-of-day contextual greetings, which violate global product copy standards due to timezone sync discrepancies.

Good evening, Sam

Welcome back, Sam

Approve

Reject

Skip

Rule violation

debug-journey-picker.tsx:186

Two CTAs in the same component convey the same underlying action: 'Starting…' and 'Start journey' both initiate a journey. One should be removed or consolidated.

Start journey

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

error.tsx:18

"Something went wrong." doesn't need its trailing period — single-sentence tooltips and error messages stay unpunctuated.

Something went wrong.

Something went wrong.

Approve

Reject

Skip

Rule violation

plan.tsx:134

The string 'Toggle plan' does not clearly indicate what 'plan' is or what toggling it does. The referent is unclear from the label alone.

Toggle plan

Show plan

Approve

Reject

Skip

Rule violation

reasoning.tsx:156

The strings 'Thought for' and 'seconds' are fragments designed to be concatenated around a number (e.g., 'Thought for 5 seconds'). This concatenation pattern creates localization and accessibility failures because word order differs across languages. Use a complete sentence instead.

Thought for

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

reasoning.tsx:156

The strings 'Thought for' and 'seconds' are fragments designed to be concatenated around a number (e.g., 'Thought for 5 seconds'). This concatenation pattern creates localization and accessibility failures because word order differs across languages. Use a complete sentence instead.

seconds

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

speech-input.tsx:300

The string 'Processing voice input' appears as a label/status message in a component and should not end with a period per Helix guidelines for UI microcopy.

Processing voice input

Processing voice input

Approve

Reject

Skip

Rule violation

web-preview.tsx:152

Accessibility failure: this input has no discrete label — placeholder "Enter URL..." is serving as the label, and it disappears once the user starts typing.

Enter URL...

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

helix-shell.tsx:262

The HelixShell component uses both 'Open wallet' and 'Wallet' to describe the same action. One should be removed or consolidated.

Open wallet

Open wallet

Approve

Reject

Skip

Rule violation

helix-shell.tsx:268

The HelixShell component uses both 'Open wallet' and 'Wallet' to describe the same action. One should be removed or consolidated.

Wallet

Open wallet

Approve

Reject

Skip

Rule violation

conversation-thread-view.tsx:984

Both ConversationThreadView and MicrolessonView use 'Helix is thinking…' identically. This suggests a shared constant that should be defined once.

Helix is thinking…

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

conversation-thread-view.tsx:1068

Accessibility failure: this input has no discrete label — placeholder "Ask Helix…" is serving as the label, and it disappears once the user starts typing.

Ask Helix…

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

feedback-nudge.tsx:35

The DismissButton component uses both 'Dismiss feedback nudge' and 'Dismiss' to describe the same action. One should be removed or consolidated.

Dismiss feedback nudge

Dismiss

Approve

Reject

Skip

Rule violation

feedback-nudge.tsx:40

The DismissButton component uses both 'Dismiss feedback nudge' and 'Dismiss' to describe the same action. One should be removed or consolidated.

Dismiss

Dismiss

Approve

Reject

Skip

Rule violation

microlesson-view.tsx:111

Both ConversationThreadView and MicrolessonView use 'Helix is thinking…' identically. This suggests a shared constant that should be defined once.

Helix is thinking…

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

microlesson-view.tsx:115

The error message 'This lesson hit a snag' uses an exclamation mark, which can read as flippant in a failure state. Per guidelines, errors should avoid exclamation marks.

This lesson hit a snag

This lesson hit a snag.

Approve

Reject

Skip

Rule violation

pathway-handoff-transition.tsx:41

Accessibility failure: this input has no discrete label — placeholder "Message Helix…" is serving as the label, and it disappears once the user starts typing.

Message Helix…

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

spine-referral-card.tsx:62

The ReferralLoadingCard component uses both 'Preparing your activity' and 'Preparing your activity…' to describe the same state. One should be removed or consolidated.

Preparing your activity

Preparing your activity…

Approve

Reject

Skip

Rule violation

spine-referral-card.tsx:63

The ReferralLoadingCard component uses both 'Preparing your activity' and 'Preparing your activity…' to describe the same state. One should be removed or consolidated.

Preparing your activity…

Preparing your activity…

Approve

Reject

Skip

Rule violation

wallet-dashboard.tsx:93

The label 'Total skills' appears in both WalletDashboard (id 2161926a0510) and WalletSurface (id 9b87b4fe967e). These likely refer to the same metric and should be consolidated to a single source string.

Total skills

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

wallet-dashboard.tsx:99

The label 'Average confidence' appears in both WalletDashboard (id 54d7ef7d5061) and WalletSurface (id bfc0d90b0965). These likely refer to the same metric and should be consolidated to a single source string.

Average confidence

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

wallet-surface.tsx:35

The label 'Total skills' appears in both WalletDashboard (id 2161926a0510) and WalletSurface (id 9b87b4fe967e). These likely refer to the same metric and should be consolidated to a single source string.

Total skills

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

wallet-surface.tsx:41

The label 'Average confidence' appears in both WalletDashboard (id 54d7ef7d5061) and WalletSurface (id bfc0d90b0965). These likely refer to the same metric and should be consolidated to a single source string.

Average confidence

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

content-registry.tsx:289

The string 'This is an interactive activity — it launches from its activity card in the conversation, not here.' uses pronouns 'it' and 'its' whose referent is unclear without seeing the UI context. What activity does 'it' refer to, and where specifically is 'the conversation'?

This is an interactive activity — it launches from its activity card in the conversation, not here.

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

concluded-interaction-review.tsx:43

Error copy should avoid exclamation marks. The phrase 'This activity didn't load' appears across multiple error states and should maintain consistent, neutral punctuation. While the current strings lack exclamation marks, ensure they remain absent if these error messages are presented as alerts or toasts.

This activity didn’t load

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

interactions-launch-surface.tsx:67

Error copy should avoid exclamation marks. The phrase 'This activity didn't load' appears across multiple error states and should maintain consistent, neutral punctuation. While the current strings lack exclamation marks, ensure they remain absent if these error messages are presented as alerts or toasts.

This activity didn’t load

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

surface.tsx:327

Error copy should avoid exclamation marks. The phrase 'This activity didn't load' appears across multiple error states and should maintain consistent, neutral punctuation. While the current strings lack exclamation marks, ensure they remain absent if these error messages are presented as alerts or toasts.

This activity didn’t load

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

attachment-tray.tsx:86

Buttons read as a more direct command without an article; "Add an image" uses one, the same shape the guideline's own example drops ("Add lecture", not "Add a lecture").

Add an image

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

comment-popover.tsx:425

Accessibility failure: this input has no discrete label — placeholder "Reply…" is serving as the label, and it disappears once the user starts typing.

Reply…

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

content-audit-finding-row.tsx:160

The strings 'Approved and applied.' and 'Dismissed.' end with periods, but these are short status messages in a component where periods are unnecessary clutter.

Approved and applied.

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

content-audit-finding-row.tsx:161

The strings 'Approved and applied.' and 'Dismissed.' end with periods, but these are short status messages in a component where periods are unnecessary clutter.

Dismissed.

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

feedback-composer.tsx:280

Accessibility failure: this input has no discrete label — placeholder "Share what's on your mind… (or drop an image)" is serving as the label, and it disappears once the user starts typing.

Share what's on your mind… (or drop an image)

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

feedback-composer.tsx:328

"Pin it to the app" uses "it" with nothing nearby naming what it refers to — a reader can't tell what's being acted on.

Pin it to the app

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

feedback-dock.tsx:114

The strings 'Your feedback' appears twice in this batch with the same id concept but used as a CTA in two different components. Review whether both instances are necessary or if one should be removed.

Your feedback

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

feedback-drawer.tsx:344

The strings 'reply' and 'replies' use lowercase, inconsistent with other CTA buttons in the interface that use sentence case. CTAs should use sentence case: 'Reply' and 'Replies'.

reply

Reply

Approve

Reject

Skip

Rule violation

feedback-drawer.tsx:344

The string 'replies' uses lowercase, inconsistent with other CTA buttons in the interface that use sentence case. CTAs should use sentence case: 'Replies'.

replies

Replies

Approve

Reject

Skip

Rule violation

feedback-thread-view.tsx:49

The strings 'Your feedback' appears twice in this batch with the same id concept but used as a CTA in two different components. Review whether both instances are necessary or if one should be removed.

Your feedback

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

feedback-thread-view.tsx:81

Accessibility failure: this input has no discrete label — placeholder "Reply…" is serving as the label, and it disappears once the user starts typing.

Reply…

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

general-composer.tsx:156

Accessibility failure: this input has no discrete label — placeholder "What did you want to flag? (paste or drop an image)" is serving as the label, and it disappears once the user starts typing.

What did you want to flag? (paste or drop an image)

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestions (30)

Dismiss all style suggestions

Style suggestion

onboarding-overlay.tsx:161

The OnboardingOverlay component mixes conversational second-person questions ('What do you want to learn today?' 'What do you want to get better at?') with clinical label-style copy ('Your name', 'A skill or goal'). Consider warming the placeholder text to match the conversational tone of the questions.

Welcome to Helix — what should we call you?

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

onboarding-overlay.tsx:167

The OnboardingOverlay component mixes conversational second-person questions ('What do you want to learn today?' 'What do you want to get better at?') with clinical label-style copy ('Your name', 'A skill or goal'). Consider warming the placeholder text to match the conversational tone of the questions.

Your name

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

onboarding-overlay.tsx:174

The OnboardingOverlay component mixes conversational second-person questions ('What do you want to learn today?' 'What do you want to get better at?') with clinical label-style copy ('Your name', 'A skill or goal'). Consider warming the placeholder text to match the conversational tone of the questions.

What do you want to get better at?

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

onboarding-overlay.tsx:180

The OnboardingOverlay component mixes conversational second-person questions ('What do you want to learn today?' 'What do you want to get better at?') with clinical label-style copy ('Your name', 'A skill or goal'). Consider warming the placeholder text to match the conversational tone of the questions.

A skill or goal

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

not-found.tsx:28

Consider a fresher take on 'Helix routed you off the path.' This phrasing feels somewhat clichéd; a more direct, less metaphorical explanation may feel clearer.

Helix routed you off the path. Head back to where the flow lives.

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

chat-prompt-bar.tsx:183

The strings 'Add attachment' and 'Upload files' both appear to reference the same underlying capability of attaching content to a message. Consider clarifying whether these are distinct actions (e.g., one for existing files, one for capturing new ones) or consolidating them.

Add attachment

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

prompt-input.tsx:842

The strings 'Add attachment' and 'Upload files' both appear to reference the same underlying capability of attaching content to a message. Consider clarifying whether these are distinct actions (e.g., one for existing files, one for capturing new ones) or consolidating them.

Upload files

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

helix-shell.tsx:969

Consider whether 'Helix is thinking…' and 'Loading saved pathways' represent the same state. 'Helix is thinking…' is conversational and personified, while 'Loading saved pathways' is more neutral. If both describe a loading state, align their tone.

Loading saved pathways

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

microlesson-view.tsx:117

The error heading 'This lesson hit a snag' (b584f4539a7b) and body 'The lesson stream failed.' use different punctuation treatment. Consider whether both should end with periods or neither.

The lesson stream failed.

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

wallet-empty-state.tsx:10

Consider whether 'trust-tiered' in the empty-state description is clear to all users. This technical term may not translate well or be immediately understood by learners unfamiliar with credential terminology.

Self-claim a skill or complete a learning path and it shows up here, evidenced and trust-tiered.

Self-claim a skill or complete a learning path and it shows up here, verified and ranked by trustworthiness.

Approve

Reject

Skip

Style suggestion

wallet-view.tsx:40

The ellipsis in 'Loading your wallet…' is acceptable but consider whether a spinner or animated treatment would communicate the loading state more clearly, per guidelines preferring graphical treatments over ellipses.

Loading your wallet…

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

launch-panels.tsx:207

The component labels mix specific and generic terms: 'Practice activity' (id 2fa182404a61), 'Activity launch' (id a8b53b0c4d37), and 'Activity' (id 40e32c8969ac) may refer to overlapping concepts. Consider whether these should use consistent phrasing or are intentionally distinct based on context.

Activity launch

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

practice-launch.tsx:61

Two strings convey that practice isn't available: 'This practice activity didn't load' (id ba3f8a33602b) and 'Practice isn't available here' (id 07cd12dde13a). These may represent different failure modes (load error vs. missing setup), but the distinction isn't clear from the wording alone. Clarify the difference or consolidate.

This practice activity didn’t load

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

practice-launch.tsx:112

The component labels mix specific and generic terms: 'Practice activity' (id 2fa182404a61), 'Activity launch' (id a8b53b0c4d37), and 'Activity' (id 40e32c8969ac) may refer to overlapping concepts. Consider whether these should use consistent phrasing or are intentionally distinct based on context.

Practice activity

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

surface.tsx:234

The component labels mix specific and generic terms: 'Practice activity' (id 2fa182404a61), 'Activity launch' (id a8b53b0c4d37), and 'Activity' (id 40e32c8969ac) may refer to overlapping concepts. Consider whether these should use consistent phrasing or are intentionally distinct based on context.

Activity

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

surface.tsx:321

"Loading this activity" uses "this" with nothing nearby naming what it refers to — a reader can't tell what's being acted on.

Loading this activity

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

surface.tsx:489

The footer component mixes conversational instruction ('Finish the practice above, then submit your answers') with clinical state descriptions ('Your answers didn't go through'). Consider warming 'Your answers didn't go through' to match the supportive tone, perhaps 'Your answers didn't submit—check your connection and try again.'

Your answers didn’t go through

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

surface.tsx:490

The footer component mixes conversational instruction ('Finish the practice above, then submit your answers') with clinical state descriptions ('Your answers didn't go through'). Consider warming 'Your answers didn't go through' to match the supportive tone, perhaps 'Your answers didn't submit—check your connection and try again.'

Check your connection and submit again.

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

surface.tsx:497

The footer component mixes conversational instruction ('Finish the practice above, then submit your answers') with clinical state descriptions ('Your answers didn't go through'). Consider warming 'Your answers didn't go through' to match the supportive tone, perhaps 'Your answers didn't submit—check your connection and try again.'

Finish the practice above, then submit your answers.

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

surface.tsx:601

Two strings convey that practice isn't available: 'This practice activity didn't load' (id ba3f8a33602b) and 'Practice isn't available here' (id 07cd12dde13a). These may represent different failure modes (load error vs. missing setup), but the distinction isn't clear from the wording alone. Clarify the difference or consolidate.

Practice isn’t available here

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

surface.tsx:603

The heading 'This check needs practice that isn't set up in this environment' (id ef6c5c30e6bd) is 61 characters and may exceed optimal brevity for modal-like components. Consider tightening to 'Practice isn't available here' or similar for better scannability.

This check needs practice that isn’t set up in this environment.

Practice isn't available here

Approve

Reject

Skip

Style suggestion

surface.tsx:724

Most error messages use contractions ('didn't', 'isn't'), which is good for approachability. However, 'No result was recorded for it' (id a31159b6e9e3) avoids contraction and feels slightly formal. Consider 'No result was recorded' for consistency.

No result was recorded for it.

No result was recorded

Approve

Reject

Skip

Style suggestion

attachment-tray.tsx:86

Buttons should stay within about 20 characters; "Attachment limit reached" is 24.

Attachment limit reached

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

feedback-composer.tsx:287

In CardBody, 'Add detail (optional)' uses clinical form language, which contrasts with the more conversational tone of nearby copy like 'Pin it to the app' and 'Audit page content'. Consider warming this label to match the component's overall voice.

Add detail (optional)

Add more details (optional)

Approve

Reject

Skip

Style suggestion

feedback-composer.tsx:338

The strings 'Add an image' and 'Add a screenshot' both appear to be attachment actions in the same component. Consider whether these are truly distinct capabilities or should use more specific, less ambiguous wording to clarify the difference.

Add a screenshot

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

general-composer.tsx:131

The GeneralComposerDialog mixes conversational copy with clinical form labels. 'File general feedback' is descriptive and user-friendly, but 'Classification' reads as clinical. Consider warming it to 'Feedback type' or 'Category' for consistency.

File general feedback

Feedback type

Approve

Reject

Skip

Style suggestion

general-composer.tsx:172

The GeneralComposerDialog mixes conversational copy with clinical form labels. 'File general feedback' is descriptive and user-friendly, but 'Classification' reads as clinical. Consider warming it to 'Feedback type' or 'Category' for consistency.

Classification

Feedback type

Approve

Reject

Skip

Style suggestion

thread-card.tsx:144

The ThreadCard component uses 'image' and 'images' as content labels but also includes 'View screenshot' as a separate action, making it unclear whether these are three distinct concepts or varying phrasings of the same capability.

image

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

thread-card.tsx:144

The ThreadCard component uses 'image' and 'images' as content labels but also includes 'View screenshot' as a separate action, making it unclear whether these are three distinct concepts or varying phrasings of the same capability.

images

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

thread-card.tsx:157

The ThreadCard component uses 'image' and 'images' as content labels but also includes 'View screenshot' as a separate action, making it unclear whether these are three distinct concepts or varying phrasings of the same capability.

View screenshot

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Two-Tier Findings

To avoid false precision, findings are strictly tiered rather than scored.

  • Rule Violations: High-confidence deterministic checks flagging mechanical errors like punctuation, character limits, and banned terms.
  • Style Suggestions: Low-confidence LLM judgment calls on tone, voice, and redundancy where human nuance is needed.

200 strings scanned · 9 rule violations · 4 style suggestions

Style suggestions (4)

Dismiss all style suggestions

Style suggestion

error.tsx:18

"Something went wrong." doesn't need its trailing period — single-sentence tooltips and error messages stay unpunctuated.

Something went wrong.

Something went wrong

Approve

Reject

Skip

Style suggestion

checkpoint-host.tsx:223

"Something went wrong fetching this checkpoint." doesn't need its trailing period — single-sentence tooltips and error messages stay unpunctuated.

Something went wrong fetching this checkpoint.

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

attachment-tray.tsx:86

Buttons should stay within about 20 characters; "Attachment limit reached" is 24.

Attachment limit reached

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

feedback-composer.tsx:328

"Pin it to the app" uses "it" with nothing nearby naming what it refers to — a reader can't tell what's being acted on.

Pin it to the app

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Optimistic UI & Outcomes

The interface is built with optimistic UI buttons disable instantly on click to prevent double-submits, and re-enable if a failure occurs. The final action row dictates the string's lifecycle:

  • Approve: Writes the file locally and moves the fix to the pending PR batch.
  • Reject: Records a dismissal; the string will not surface again in subsequent scans.
  • Skip: Defers the decision to a later session.

S

Welcome back, Sam

Need help? Tell me a little about yourself so I can make the best recommendations.

Set your goal

In Progress

Completed

Skills

Certificates

Google

Build Wireframes and Low-Fidelity Prototypes

Course

·

16% complete

·

Estimated completion: Oct 20, 2025

Learn more about creating storyboards

Reading (8 minutes)

Resume

September 2026

Mo

Tu

We

Th

Fr

Sa

Su

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

1+ daily goals completed

All daily goals completed

Last 4 weeks

0

Daily goals completed

0

Items completed

0

Minutes learned

Explore

My Learning

Degrees

What do you want to learn?

S

Manual Edit

To keep reviewers in context, the UI relies on a fluid inline transition. Crucially, the model's rewrite is only a starting point manual editing is an open affordance available at any time:

  • 01 Flagged: The original text receives a muted strikethrough. If no automated rewrite is available, the "Approve" button remains visible but disabled until a fix is provided.
  • 02 Editing: Clicking the pencil icon at any point opens an active textarea, allowing the reviewer to modify the LLM's suggestion or draft their own from scratch. The primary blue "Save" button takes visual focus.
  • 03 Resolved: The finalised rewrite sits below the original. The "Approve" button takes the primary blue accent, signalling it is ready for the batch.

Audit page content

Scan page

Scan app

227 strings scanned · 40 rule violations · 30 style suggestions

Rule violations (40)

Approve all rule violations

Rule violation

page.tsx:112

"Reading (8 minutes)" Uses full spelled-out duration strings in parentheses, violating the microcopy standard for content cards.

Reading (8 minutes)

8 min read

Approve

Reject

Skip

Rule violation

debug-journey-picker.tsx:186

"Good evening, Sam" Uses time-of-day contextual greetings, which violate global product copy standards due to timezone sync discrepancies.

Welcome back! Sam|

Cancel

Save

Approve

Reject

Skip

Rule violation

debug-journey-picker.tsx:186

Two CTAs in the same component convey the same underlying action: 'Starting…' and 'Start journey' both initiate a journey. One should be removed or consolidated.

Start journey

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

error.tsx:18

"Something went wrong." doesn't need its trailing period — single-sentence tooltips and error messages stay unpunctuated.

Something went wrong.

Something went wrong.

Approve

Reject

Skip

Rule violation

plan.tsx:134

The string 'Toggle plan' does not clearly indicate what 'plan' is or what toggling it does. The referent is unclear from the label alone.

Toggle plan

Show plan

Approve

Reject

Skip

Rule violation

reasoning.tsx:156

The strings 'Thought for' and 'seconds' are fragments designed to be concatenated around a number (e.g., 'Thought for 5 seconds'). This concatenation pattern creates localization and accessibility failures because word order differs across languages. Use a complete sentence instead.

Thought for

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

reasoning.tsx:156

The strings 'Thought for' and 'seconds' are fragments designed to be concatenated around a number (e.g., 'Thought for 5 seconds'). This concatenation pattern creates localization and accessibility failures because word order differs across languages. Use a complete sentence instead.

seconds

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

speech-input.tsx:300

The string 'Processing voice input' appears as a label/status message in a component and should not end with a period per Helix guidelines for UI microcopy.

Processing voice input

Processing voice input

Approve

Reject

Skip

Rule violation

web-preview.tsx:152

Accessibility failure: this input has no discrete label — placeholder "Enter URL..." is serving as the label, and it disappears once the user starts typing.

Enter URL...

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

helix-shell.tsx:262

The HelixShell component uses both 'Open wallet' and 'Wallet' to describe the same action. One should be removed or consolidated.

Open wallet

Open wallet

Approve

Reject

Skip

Rule violation

helix-shell.tsx:268

The HelixShell component uses both 'Open wallet' and 'Wallet' to describe the same action. One should be removed or consolidated.

Wallet

Open wallet

Approve

Reject

Skip

Rule violation

conversation-thread-view.tsx:984

Both ConversationThreadView and MicrolessonView use 'Helix is thinking…' identically. This suggests a shared constant that should be defined once.

Helix is thinking…

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

conversation-thread-view.tsx:1068

Accessibility failure: this input has no discrete label — placeholder "Ask Helix…" is serving as the label, and it disappears once the user starts typing.

Ask Helix…

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

feedback-nudge.tsx:35

The DismissButton component uses both 'Dismiss feedback nudge' and 'Dismiss' to describe the same action. One should be removed or consolidated.

Dismiss feedback nudge

Dismiss

Approve

Reject

Skip

Rule violation

feedback-nudge.tsx:40

The DismissButton component uses both 'Dismiss feedback nudge' and 'Dismiss' to describe the same action. One should be removed or consolidated.

Dismiss

Dismiss

Approve

Reject

Skip

Rule violation

microlesson-view.tsx:111

Both ConversationThreadView and MicrolessonView use 'Helix is thinking…' identically. This suggests a shared constant that should be defined once.

Helix is thinking…

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

microlesson-view.tsx:115

The error message 'This lesson hit a snag' uses an exclamation mark, which can read as flippant in a failure state. Per guidelines, errors should avoid exclamation marks.

This lesson hit a snag

This lesson hit a snag.

Approve

Reject

Skip

Rule violation

pathway-handoff-transition.tsx:41

Accessibility failure: this input has no discrete label — placeholder "Message Helix…" is serving as the label, and it disappears once the user starts typing.

Message Helix…

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

spine-referral-card.tsx:62

The ReferralLoadingCard component uses both 'Preparing your activity' and 'Preparing your activity…' to describe the same state. One should be removed or consolidated.

Preparing your activity

Preparing your activity…

Approve

Reject

Skip

Rule violation

spine-referral-card.tsx:63

The ReferralLoadingCard component uses both 'Preparing your activity' and 'Preparing your activity…' to describe the same state. One should be removed or consolidated.

Preparing your activity…

Preparing your activity…

Approve

Reject

Skip

Rule violation

wallet-dashboard.tsx:93

The label 'Total skills' appears in both WalletDashboard (id 2161926a0510) and WalletSurface (id 9b87b4fe967e). These likely refer to the same metric and should be consolidated to a single source string.

Total skills

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

wallet-dashboard.tsx:99

The label 'Average confidence' appears in both WalletDashboard (id 54d7ef7d5061) and WalletSurface (id bfc0d90b0965). These likely refer to the same metric and should be consolidated to a single source string.

Average confidence

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

wallet-surface.tsx:35

The label 'Total skills' appears in both WalletDashboard (id 2161926a0510) and WalletSurface (id 9b87b4fe967e). These likely refer to the same metric and should be consolidated to a single source string.

Total skills

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

wallet-surface.tsx:41

The label 'Average confidence' appears in both WalletDashboard (id 54d7ef7d5061) and WalletSurface (id bfc0d90b0965). These likely refer to the same metric and should be consolidated to a single source string.

Average confidence

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

content-registry.tsx:289

The string 'This is an interactive activity — it launches from its activity card in the conversation, not here.' uses pronouns 'it' and 'its' whose referent is unclear without seeing the UI context. What activity does 'it' refer to, and where specifically is 'the conversation'?

This is an interactive activity — it launches from its activity card in the conversation, not here.

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

concluded-interaction-review.tsx:43

Error copy should avoid exclamation marks. The phrase 'This activity didn't load' appears across multiple error states and should maintain consistent, neutral punctuation. While the current strings lack exclamation marks, ensure they remain absent if these error messages are presented as alerts or toasts.

This activity didn’t load

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

interactions-launch-surface.tsx:67

Error copy should avoid exclamation marks. The phrase 'This activity didn't load' appears across multiple error states and should maintain consistent, neutral punctuation. While the current strings lack exclamation marks, ensure they remain absent if these error messages are presented as alerts or toasts.

This activity didn’t load

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

surface.tsx:327

Error copy should avoid exclamation marks. The phrase 'This activity didn't load' appears across multiple error states and should maintain consistent, neutral punctuation. While the current strings lack exclamation marks, ensure they remain absent if these error messages are presented as alerts or toasts.

This activity didn’t load

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

attachment-tray.tsx:86

Buttons read as a more direct command without an article; "Add an image" uses one, the same shape the guideline's own example drops ("Add lecture", not "Add a lecture").

Add an image

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

comment-popover.tsx:425

Accessibility failure: this input has no discrete label — placeholder "Reply…" is serving as the label, and it disappears once the user starts typing.

Reply…

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

content-audit-finding-row.tsx:160

The strings 'Approved and applied.' and 'Dismissed.' end with periods, but these are short status messages in a component where periods are unnecessary clutter.

Approved and applied.

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

content-audit-finding-row.tsx:161

The strings 'Approved and applied.' and 'Dismissed.' end with periods, but these are short status messages in a component where periods are unnecessary clutter.

Dismissed.

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

feedback-composer.tsx:280

Accessibility failure: this input has no discrete label — placeholder "Share what's on your mind… (or drop an image)" is serving as the label, and it disappears once the user starts typing.

Share what's on your mind… (or drop an image)

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

feedback-composer.tsx:328

"Pin it to the app" uses "it" with nothing nearby naming what it refers to — a reader can't tell what's being acted on.

Pin it to the app

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

feedback-dock.tsx:114

The strings 'Your feedback' appears twice in this batch with the same id concept but used as a CTA in two different components. Review whether both instances are necessary or if one should be removed.

Your feedback

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

feedback-drawer.tsx:344

The strings 'reply' and 'replies' use lowercase, inconsistent with other CTA buttons in the interface that use sentence case. CTAs should use sentence case: 'Reply' and 'Replies'.

reply

Reply

Approve

Reject

Skip

Rule violation

feedback-drawer.tsx:344

The string 'replies' uses lowercase, inconsistent with other CTA buttons in the interface that use sentence case. CTAs should use sentence case: 'Replies'.

replies

Replies

Approve

Reject

Skip

Rule violation

feedback-thread-view.tsx:49

The strings 'Your feedback' appears twice in this batch with the same id concept but used as a CTA in two different components. Review whether both instances are necessary or if one should be removed.

Your feedback

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

feedback-thread-view.tsx:81

Accessibility failure: this input has no discrete label — placeholder "Reply…" is serving as the label, and it disappears once the user starts typing.

Reply…

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

general-composer.tsx:156

Accessibility failure: this input has no discrete label — placeholder "What did you want to flag? (paste or drop an image)" is serving as the label, and it disappears once the user starts typing.

What did you want to flag? (paste or drop an image)

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestions (30)

Dismiss all style suggestions

Style suggestion

onboarding-overlay.tsx:161

The OnboardingOverlay component mixes conversational second-person questions ('What do you want to learn today?' 'What do you want to get better at?') with clinical label-style copy ('Your name', 'A skill or goal'). Consider warming the placeholder text to match the conversational tone of the questions.

Welcome to Helix — what should we call you?

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

onboarding-overlay.tsx:167

The OnboardingOverlay component mixes conversational second-person questions ('What do you want to learn today?' 'What do you want to get better at?') with clinical label-style copy ('Your name', 'A skill or goal'). Consider warming the placeholder text to match the conversational tone of the questions.

Your name

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

onboarding-overlay.tsx:174

The OnboardingOverlay component mixes conversational second-person questions ('What do you want to learn today?' 'What do you want to get better at?') with clinical label-style copy ('Your name', 'A skill or goal'). Consider warming the placeholder text to match the conversational tone of the questions.

What do you want to get better at?

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

onboarding-overlay.tsx:180

The OnboardingOverlay component mixes conversational second-person questions ('What do you want to learn today?' 'What do you want to get better at?') with clinical label-style copy ('Your name', 'A skill or goal'). Consider warming the placeholder text to match the conversational tone of the questions.

A skill or goal

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

not-found.tsx:28

Consider a fresher take on 'Helix routed you off the path.' This phrasing feels somewhat clichéd; a more direct, less metaphorical explanation may feel clearer.

Helix routed you off the path. Head back to where the flow lives.

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

chat-prompt-bar.tsx:183

The strings 'Add attachment' and 'Upload files' both appear to reference the same underlying capability of attaching content to a message. Consider clarifying whether these are distinct actions (e.g., one for existing files, one for capturing new ones) or consolidating them.

Add attachment

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

prompt-input.tsx:842

The strings 'Add attachment' and 'Upload files' both appear to reference the same underlying capability of attaching content to a message. Consider clarifying whether these are distinct actions (e.g., one for existing files, one for capturing new ones) or consolidating them.

Upload files

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

helix-shell.tsx:969

Consider whether 'Helix is thinking…' and 'Loading saved pathways' represent the same state. 'Helix is thinking…' is conversational and personified, while 'Loading saved pathways' is more neutral. If both describe a loading state, align their tone.

Loading saved pathways

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

microlesson-view.tsx:117

The error heading 'This lesson hit a snag' (b584f4539a7b) and body 'The lesson stream failed.' use different punctuation treatment. Consider whether both should end with periods or neither.

The lesson stream failed.

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

wallet-empty-state.tsx:10

Consider whether 'trust-tiered' in the empty-state description is clear to all users. This technical term may not translate well or be immediately understood by learners unfamiliar with credential terminology.

Self-claim a skill or complete a learning path and it shows up here, evidenced and trust-tiered.

Self-claim a skill or complete a learning path and it shows up here, verified and ranked by trustworthiness.

Approve

Reject

Skip

Style suggestion

wallet-view.tsx:40

The ellipsis in 'Loading your wallet…' is acceptable but consider whether a spinner or animated treatment would communicate the loading state more clearly, per guidelines preferring graphical treatments over ellipses.

Loading your wallet…

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

launch-panels.tsx:207

The component labels mix specific and generic terms: 'Practice activity' (id 2fa182404a61), 'Activity launch' (id a8b53b0c4d37), and 'Activity' (id 40e32c8969ac) may refer to overlapping concepts. Consider whether these should use consistent phrasing or are intentionally distinct based on context.

Activity launch

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

practice-launch.tsx:61

Two strings convey that practice isn't available: 'This practice activity didn't load' (id ba3f8a33602b) and 'Practice isn't available here' (id 07cd12dde13a). These may represent different failure modes (load error vs. missing setup), but the distinction isn't clear from the wording alone. Clarify the difference or consolidate.

This practice activity didn’t load

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

practice-launch.tsx:112

The component labels mix specific and generic terms: 'Practice activity' (id 2fa182404a61), 'Activity launch' (id a8b53b0c4d37), and 'Activity' (id 40e32c8969ac) may refer to overlapping concepts. Consider whether these should use consistent phrasing or are intentionally distinct based on context.

Practice activity

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

surface.tsx:234

The component labels mix specific and generic terms: 'Practice activity' (id 2fa182404a61), 'Activity launch' (id a8b53b0c4d37), and 'Activity' (id 40e32c8969ac) may refer to overlapping concepts. Consider whether these should use consistent phrasing or are intentionally distinct based on context.

Activity

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

surface.tsx:321

"Loading this activity" uses "this" with nothing nearby naming what it refers to — a reader can't tell what's being acted on.

Loading this activity

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

surface.tsx:489

The footer component mixes conversational instruction ('Finish the practice above, then submit your answers') with clinical state descriptions ('Your answers didn't go through'). Consider warming 'Your answers didn't go through' to match the supportive tone, perhaps 'Your answers didn't submit—check your connection and try again.'

Your answers didn’t go through

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

surface.tsx:490

The footer component mixes conversational instruction ('Finish the practice above, then submit your answers') with clinical state descriptions ('Your answers didn't go through'). Consider warming 'Your answers didn't go through' to match the supportive tone, perhaps 'Your answers didn't submit—check your connection and try again.'

Check your connection and submit again.

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

surface.tsx:497

The footer component mixes conversational instruction ('Finish the practice above, then submit your answers') with clinical state descriptions ('Your answers didn't go through'). Consider warming 'Your answers didn't go through' to match the supportive tone, perhaps 'Your answers didn't submit—check your connection and try again.'

Finish the practice above, then submit your answers.

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

surface.tsx:601

Two strings convey that practice isn't available: 'This practice activity didn't load' (id ba3f8a33602b) and 'Practice isn't available here' (id 07cd12dde13a). These may represent different failure modes (load error vs. missing setup), but the distinction isn't clear from the wording alone. Clarify the difference or consolidate.

Practice isn’t available here

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

surface.tsx:603

The heading 'This check needs practice that isn't set up in this environment' (id ef6c5c30e6bd) is 61 characters and may exceed optimal brevity for modal-like components. Consider tightening to 'Practice isn't available here' or similar for better scannability.

This check needs practice that isn’t set up in this environment.

Practice isn't available here

Approve

Reject

Skip

Style suggestion

surface.tsx:724

Most error messages use contractions ('didn't', 'isn't'), which is good for approachability. However, 'No result was recorded for it' (id a31159b6e9e3) avoids contraction and feels slightly formal. Consider 'No result was recorded' for consistency.

No result was recorded for it.

No result was recorded

Approve

Reject

Skip

Style suggestion

attachment-tray.tsx:86

Buttons should stay within about 20 characters; "Attachment limit reached" is 24.

Attachment limit reached

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

feedback-composer.tsx:287

In CardBody, 'Add detail (optional)' uses clinical form language, which contrasts with the more conversational tone of nearby copy like 'Pin it to the app' and 'Audit page content'. Consider warming this label to match the component's overall voice.

Add detail (optional)

Add more details (optional)

Approve

Reject

Skip

Style suggestion

feedback-composer.tsx:338

The strings 'Add an image' and 'Add a screenshot' both appear to be attachment actions in the same component. Consider whether these are truly distinct capabilities or should use more specific, less ambiguous wording to clarify the difference.

Add a screenshot

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

general-composer.tsx:131

The GeneralComposerDialog mixes conversational copy with clinical form labels. 'File general feedback' is descriptive and user-friendly, but 'Classification' reads as clinical. Consider warming it to 'Feedback type' or 'Category' for consistency.

File general feedback

Feedback type

Approve

Reject

Skip

Style suggestion

general-composer.tsx:172

The GeneralComposerDialog mixes conversational copy with clinical form labels. 'File general feedback' is descriptive and user-friendly, but 'Classification' reads as clinical. Consider warming it to 'Feedback type' or 'Category' for consistency.

Classification

Feedback type

Approve

Reject

Skip

Style suggestion

thread-card.tsx:144

The ThreadCard component uses 'image' and 'images' as content labels but also includes 'View screenshot' as a separate action, making it unclear whether these are three distinct concepts or varying phrasings of the same capability.

image

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

thread-card.tsx:144

The ThreadCard component uses 'image' and 'images' as content labels but also includes 'View screenshot' as a separate action, making it unclear whether these are three distinct concepts or varying phrasings of the same capability.

images

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

thread-card.tsx:157

The ThreadCard component uses 'image' and 'images' as content labels but also includes 'View screenshot' as a separate action, making it unclear whether these are three distinct concepts or varying phrasings of the same capability.

View screenshot

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Section 04: Outcomes & Lessons

The Impact

By treating UI copy as a governed, versioned instance of a content system, the tool collapses the traditional multi-week Jira ticket loop into a single, on-canvas action. Reviewers edit copy in context, click approve, and the fix lands directly in a source file on a branch, entirely bypassing the need for a developer to open an editor.

The First Live Audit & Partnering with AI

Building this engine directly via Claude Code completely shifted my perspective on what I could ship as a product designer. During the first official end-to-end live run, the tool processed 225 strings, successfully flagging 44 rule violations and 27 style suggestions in roughly 24 seconds—proving my hybrid LLM pass was genuinely functioning.

Getting to that outcome taught me that agentic design is a true partnership, one that still relies heavily on my own architectural judgment. While my mocked tests passed perfectly, running real-repository integration tests surfaced 17 critical Git-layer bugs. Diagnosing those failures is what drove my most important architectural pivot: abandoning the initial "commit-on-approve" design (which corrupted the working tree) in favor of the deferred "Batch PR" model.

Strict Safety Gates

Because I was building a plugin that writes directly to a developer's local source files, ensuring it could not corrupt a production environment fell entirely on my shoulders. I engineered a strict three-gate safety model:

  • Scan Gate: Read-only scanning is enabled on PR preview environments so reviewers can audit real findings.
  • Write Gate: Write-backs and Git operations are hard-locked to local development only, where the developer has full control to undo changes.
  • LLM Gate: An independent kill switch for the model pass, ensuring deterministic rules continue to run even if the AI endpoint fails.

S

Good evening, Sam

Need help? Tell me a little about yourself so I can make the best recommendations.

Set your goal

In Progress

Completed

Skills

Certificates

Google

Build Wireframes and Low-Fidelity Prototypes

Course

·

16% complete

·

Estimated completion: Oct 20, 2025

Learn more about creating storyboards

Reading (8 minutes)

Resume

September 2026

Mo

Tu

We

Th

Fr

Sa

Su

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

1+ daily goals completed

All daily goals completed

Last 4 weeks

0

Daily goals completed

0

Items completed

0

Minutes learned

Explore

My Learning

Degrees

What do you want to learn?

S

Audit page content

Scan page

Scan app

227 strings scanned · 40 rule violations · 30 style suggestions

Rule violations (40)

Approve all rule violations

Rule violation

page.tsx:112

"Reading (8 minutes)" Uses full spelled-out duration strings in parentheses, violating the microcopy standard for content cards.

Reading (8 minutes)

8 min read

Approve

Reject

Skip

Rule violation

debug-journey-picker.tsx:186

"Good evening, Sam" Uses time-of-day contextual greetings, which violate global product copy standards due to timezone sync discrepancies.

Good evening, Sam

Welcome back, Sam

Approve

Reject

Skip

Rule violation

debug-journey-picker.tsx:186

Two CTAs in the same component convey the same underlying action: 'Starting…' and 'Start journey' both initiate a journey. One should be removed or consolidated.

Start journey

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

error.tsx:18

"Something went wrong." doesn't need its trailing period — single-sentence tooltips and error messages stay unpunctuated.

Something went wrong.

Something went wrong.

Approve

Reject

Skip

Rule violation

plan.tsx:134

The string 'Toggle plan' does not clearly indicate what 'plan' is or what toggling it does. The referent is unclear from the label alone.

Toggle plan

Show plan

Approve

Reject

Skip

Rule violation

reasoning.tsx:156

The strings 'Thought for' and 'seconds' are fragments designed to be concatenated around a number (e.g., 'Thought for 5 seconds'). This concatenation pattern creates localization and accessibility failures because word order differs across languages. Use a complete sentence instead.

Thought for

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

reasoning.tsx:156

The strings 'Thought for' and 'seconds' are fragments designed to be concatenated around a number (e.g., 'Thought for 5 seconds'). This concatenation pattern creates localization and accessibility failures because word order differs across languages. Use a complete sentence instead.

seconds

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

speech-input.tsx:300

The string 'Processing voice input' appears as a label/status message in a component and should not end with a period per Helix guidelines for UI microcopy.

Processing voice input

Processing voice input

Approve

Reject

Skip

Rule violation

web-preview.tsx:152

Accessibility failure: this input has no discrete label — placeholder "Enter URL..." is serving as the label, and it disappears once the user starts typing.

Enter URL...

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

helix-shell.tsx:262

The HelixShell component uses both 'Open wallet' and 'Wallet' to describe the same action. One should be removed or consolidated.

Open wallet

Open wallet

Approve

Reject

Skip

Rule violation

helix-shell.tsx:268

The HelixShell component uses both 'Open wallet' and 'Wallet' to describe the same action. One should be removed or consolidated.

Wallet

Open wallet

Approve

Reject

Skip

Rule violation

conversation-thread-view.tsx:984

Both ConversationThreadView and MicrolessonView use 'Helix is thinking…' identically. This suggests a shared constant that should be defined once.

Helix is thinking…

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

conversation-thread-view.tsx:1068

Accessibility failure: this input has no discrete label — placeholder "Ask Helix…" is serving as the label, and it disappears once the user starts typing.

Ask Helix…

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

feedback-nudge.tsx:35

The DismissButton component uses both 'Dismiss feedback nudge' and 'Dismiss' to describe the same action. One should be removed or consolidated.

Dismiss feedback nudge

Dismiss

Approve

Reject

Skip

Rule violation

feedback-nudge.tsx:40

The DismissButton component uses both 'Dismiss feedback nudge' and 'Dismiss' to describe the same action. One should be removed or consolidated.

Dismiss

Dismiss

Approve

Reject

Skip

Rule violation

microlesson-view.tsx:111

Both ConversationThreadView and MicrolessonView use 'Helix is thinking…' identically. This suggests a shared constant that should be defined once.

Helix is thinking…

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

microlesson-view.tsx:115

The error message 'This lesson hit a snag' uses an exclamation mark, which can read as flippant in a failure state. Per guidelines, errors should avoid exclamation marks.

This lesson hit a snag

This lesson hit a snag.

Approve

Reject

Skip

Rule violation

pathway-handoff-transition.tsx:41

Accessibility failure: this input has no discrete label — placeholder "Message Helix…" is serving as the label, and it disappears once the user starts typing.

Message Helix…

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

spine-referral-card.tsx:62

The ReferralLoadingCard component uses both 'Preparing your activity' and 'Preparing your activity…' to describe the same state. One should be removed or consolidated.

Preparing your activity

Preparing your activity…

Approve

Reject

Skip

Rule violation

spine-referral-card.tsx:63

The ReferralLoadingCard component uses both 'Preparing your activity' and 'Preparing your activity…' to describe the same state. One should be removed or consolidated.

Preparing your activity…

Preparing your activity…

Approve

Reject

Skip

Rule violation

wallet-dashboard.tsx:93

The label 'Total skills' appears in both WalletDashboard (id 2161926a0510) and WalletSurface (id 9b87b4fe967e). These likely refer to the same metric and should be consolidated to a single source string.

Total skills

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

wallet-dashboard.tsx:99

The label 'Average confidence' appears in both WalletDashboard (id 54d7ef7d5061) and WalletSurface (id bfc0d90b0965). These likely refer to the same metric and should be consolidated to a single source string.

Average confidence

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

wallet-surface.tsx:35

The label 'Total skills' appears in both WalletDashboard (id 2161926a0510) and WalletSurface (id 9b87b4fe967e). These likely refer to the same metric and should be consolidated to a single source string.

Total skills

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

wallet-surface.tsx:41

The label 'Average confidence' appears in both WalletDashboard (id 54d7ef7d5061) and WalletSurface (id bfc0d90b0965). These likely refer to the same metric and should be consolidated to a single source string.

Average confidence

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

content-registry.tsx:289

The string 'This is an interactive activity — it launches from its activity card in the conversation, not here.' uses pronouns 'it' and 'its' whose referent is unclear without seeing the UI context. What activity does 'it' refer to, and where specifically is 'the conversation'?

This is an interactive activity — it launches from its activity card in the conversation, not here.

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

concluded-interaction-review.tsx:43

Error copy should avoid exclamation marks. The phrase 'This activity didn't load' appears across multiple error states and should maintain consistent, neutral punctuation. While the current strings lack exclamation marks, ensure they remain absent if these error messages are presented as alerts or toasts.

This activity didn’t load

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

interactions-launch-surface.tsx:67

Error copy should avoid exclamation marks. The phrase 'This activity didn't load' appears across multiple error states and should maintain consistent, neutral punctuation. While the current strings lack exclamation marks, ensure they remain absent if these error messages are presented as alerts or toasts.

This activity didn’t load

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

surface.tsx:327

Error copy should avoid exclamation marks. The phrase 'This activity didn't load' appears across multiple error states and should maintain consistent, neutral punctuation. While the current strings lack exclamation marks, ensure they remain absent if these error messages are presented as alerts or toasts.

This activity didn’t load

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

attachment-tray.tsx:86

Buttons read as a more direct command without an article; "Add an image" uses one, the same shape the guideline's own example drops ("Add lecture", not "Add a lecture").

Add an image

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

comment-popover.tsx:425

Accessibility failure: this input has no discrete label — placeholder "Reply…" is serving as the label, and it disappears once the user starts typing.

Reply…

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

content-audit-finding-row.tsx:160

The strings 'Approved and applied.' and 'Dismissed.' end with periods, but these are short status messages in a component where periods are unnecessary clutter.

Approved and applied.

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

content-audit-finding-row.tsx:161

The strings 'Approved and applied.' and 'Dismissed.' end with periods, but these are short status messages in a component where periods are unnecessary clutter.

Dismissed.

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

feedback-composer.tsx:280

Accessibility failure: this input has no discrete label — placeholder "Share what's on your mind… (or drop an image)" is serving as the label, and it disappears once the user starts typing.

Share what's on your mind… (or drop an image)

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

feedback-composer.tsx:328

"Pin it to the app" uses "it" with nothing nearby naming what it refers to — a reader can't tell what's being acted on.

Pin it to the app

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

feedback-dock.tsx:114

The strings 'Your feedback' appears twice in this batch with the same id concept but used as a CTA in two different components. Review whether both instances are necessary or if one should be removed.

Your feedback

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

feedback-drawer.tsx:344

The strings 'reply' and 'replies' use lowercase, inconsistent with other CTA buttons in the interface that use sentence case. CTAs should use sentence case: 'Reply' and 'Replies'.

reply

Reply

Approve

Reject

Skip

Rule violation

feedback-drawer.tsx:344

The string 'replies' uses lowercase, inconsistent with other CTA buttons in the interface that use sentence case. CTAs should use sentence case: 'Replies'.

replies

Replies

Approve

Reject

Skip

Rule violation

feedback-thread-view.tsx:49

The strings 'Your feedback' appears twice in this batch with the same id concept but used as a CTA in two different components. Review whether both instances are necessary or if one should be removed.

Your feedback

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

feedback-thread-view.tsx:81

Accessibility failure: this input has no discrete label — placeholder "Reply…" is serving as the label, and it disappears once the user starts typing.

Reply…

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

general-composer.tsx:156

Accessibility failure: this input has no discrete label — placeholder "What did you want to flag? (paste or drop an image)" is serving as the label, and it disappears once the user starts typing.

What did you want to flag? (paste or drop an image)

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestions (30)

Dismiss all style suggestions

Style suggestion

onboarding-overlay.tsx:161

The OnboardingOverlay component mixes conversational second-person questions ('What do you want to learn today?' 'What do you want to get better at?') with clinical label-style copy ('Your name', 'A skill or goal'). Consider warming the placeholder text to match the conversational tone of the questions.

Welcome to Helix — what should we call you?

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

onboarding-overlay.tsx:167

The OnboardingOverlay component mixes conversational second-person questions ('What do you want to learn today?' 'What do you want to get better at?') with clinical label-style copy ('Your name', 'A skill or goal'). Consider warming the placeholder text to match the conversational tone of the questions.

Your name

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

onboarding-overlay.tsx:174

The OnboardingOverlay component mixes conversational second-person questions ('What do you want to learn today?' 'What do you want to get better at?') with clinical label-style copy ('Your name', 'A skill or goal'). Consider warming the placeholder text to match the conversational tone of the questions.

What do you want to get better at?

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

onboarding-overlay.tsx:180

The OnboardingOverlay component mixes conversational second-person questions ('What do you want to learn today?' 'What do you want to get better at?') with clinical label-style copy ('Your name', 'A skill or goal'). Consider warming the placeholder text to match the conversational tone of the questions.

A skill or goal

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

not-found.tsx:28

Consider a fresher take on 'Helix routed you off the path.' This phrasing feels somewhat clichéd; a more direct, less metaphorical explanation may feel clearer.

Helix routed you off the path. Head back to where the flow lives.

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

chat-prompt-bar.tsx:183

The strings 'Add attachment' and 'Upload files' both appear to reference the same underlying capability of attaching content to a message. Consider clarifying whether these are distinct actions (e.g., one for existing files, one for capturing new ones) or consolidating them.

Add attachment

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

prompt-input.tsx:842

The strings 'Add attachment' and 'Upload files' both appear to reference the same underlying capability of attaching content to a message. Consider clarifying whether these are distinct actions (e.g., one for existing files, one for capturing new ones) or consolidating them.

Upload files

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

helix-shell.tsx:969

Consider whether 'Helix is thinking…' and 'Loading saved pathways' represent the same state. 'Helix is thinking…' is conversational and personified, while 'Loading saved pathways' is more neutral. If both describe a loading state, align their tone.

Loading saved pathways

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

microlesson-view.tsx:117

The error heading 'This lesson hit a snag' (b584f4539a7b) and body 'The lesson stream failed.' use different punctuation treatment. Consider whether both should end with periods or neither.

The lesson stream failed.

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

wallet-empty-state.tsx:10

Consider whether 'trust-tiered' in the empty-state description is clear to all users. This technical term may not translate well or be immediately understood by learners unfamiliar with credential terminology.

Self-claim a skill or complete a learning path and it shows up here, evidenced and trust-tiered.

Self-claim a skill or complete a learning path and it shows up here, verified and ranked by trustworthiness.

Approve

Reject

Skip

Style suggestion

wallet-view.tsx:40

The ellipsis in 'Loading your wallet…' is acceptable but consider whether a spinner or animated treatment would communicate the loading state more clearly, per guidelines preferring graphical treatments over ellipses.

Loading your wallet…

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

launch-panels.tsx:207

The component labels mix specific and generic terms: 'Practice activity' (id 2fa182404a61), 'Activity launch' (id a8b53b0c4d37), and 'Activity' (id 40e32c8969ac) may refer to overlapping concepts. Consider whether these should use consistent phrasing or are intentionally distinct based on context.

Activity launch

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

practice-launch.tsx:61

Two strings convey that practice isn't available: 'This practice activity didn't load' (id ba3f8a33602b) and 'Practice isn't available here' (id 07cd12dde13a). These may represent different failure modes (load error vs. missing setup), but the distinction isn't clear from the wording alone. Clarify the difference or consolidate.

This practice activity didn’t load

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

practice-launch.tsx:112

The component labels mix specific and generic terms: 'Practice activity' (id 2fa182404a61), 'Activity launch' (id a8b53b0c4d37), and 'Activity' (id 40e32c8969ac) may refer to overlapping concepts. Consider whether these should use consistent phrasing or are intentionally distinct based on context.

Practice activity

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

surface.tsx:234

The component labels mix specific and generic terms: 'Practice activity' (id 2fa182404a61), 'Activity launch' (id a8b53b0c4d37), and 'Activity' (id 40e32c8969ac) may refer to overlapping concepts. Consider whether these should use consistent phrasing or are intentionally distinct based on context.

Activity

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

surface.tsx:321

"Loading this activity" uses "this" with nothing nearby naming what it refers to — a reader can't tell what's being acted on.

Loading this activity

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

surface.tsx:489

The footer component mixes conversational instruction ('Finish the practice above, then submit your answers') with clinical state descriptions ('Your answers didn't go through'). Consider warming 'Your answers didn't go through' to match the supportive tone, perhaps 'Your answers didn't submit—check your connection and try again.'

Your answers didn’t go through

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

surface.tsx:490

The footer component mixes conversational instruction ('Finish the practice above, then submit your answers') with clinical state descriptions ('Your answers didn't go through'). Consider warming 'Your answers didn't go through' to match the supportive tone, perhaps 'Your answers didn't submit—check your connection and try again.'

Check your connection and submit again.

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

surface.tsx:497

The footer component mixes conversational instruction ('Finish the practice above, then submit your answers') with clinical state descriptions ('Your answers didn't go through'). Consider warming 'Your answers didn't go through' to match the supportive tone, perhaps 'Your answers didn't submit—check your connection and try again.'

Finish the practice above, then submit your answers.

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

surface.tsx:601

Two strings convey that practice isn't available: 'This practice activity didn't load' (id ba3f8a33602b) and 'Practice isn't available here' (id 07cd12dde13a). These may represent different failure modes (load error vs. missing setup), but the distinction isn't clear from the wording alone. Clarify the difference or consolidate.

Practice isn’t available here

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

surface.tsx:603

The heading 'This check needs practice that isn't set up in this environment' (id ef6c5c30e6bd) is 61 characters and may exceed optimal brevity for modal-like components. Consider tightening to 'Practice isn't available here' or similar for better scannability.

This check needs practice that isn’t set up in this environment.

Practice isn't available here

Approve

Reject

Skip

Style suggestion

surface.tsx:724

Most error messages use contractions ('didn't', 'isn't'), which is good for approachability. However, 'No result was recorded for it' (id a31159b6e9e3) avoids contraction and feels slightly formal. Consider 'No result was recorded' for consistency.

No result was recorded for it.

No result was recorded

Approve

Reject

Skip

Style suggestion

attachment-tray.tsx:86

Buttons should stay within about 20 characters; "Attachment limit reached" is 24.

Attachment limit reached

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

feedback-composer.tsx:287

In CardBody, 'Add detail (optional)' uses clinical form language, which contrasts with the more conversational tone of nearby copy like 'Pin it to the app' and 'Audit page content'. Consider warming this label to match the component's overall voice.

Add detail (optional)

Add more details (optional)

Approve

Reject

Skip

Style suggestion

feedback-composer.tsx:338

The strings 'Add an image' and 'Add a screenshot' both appear to be attachment actions in the same component. Consider whether these are truly distinct capabilities or should use more specific, less ambiguous wording to clarify the difference.

Add a screenshot

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

general-composer.tsx:131

The GeneralComposerDialog mixes conversational copy with clinical form labels. 'File general feedback' is descriptive and user-friendly, but 'Classification' reads as clinical. Consider warming it to 'Feedback type' or 'Category' for consistency.

File general feedback

Feedback type

Approve

Reject

Skip

Style suggestion

general-composer.tsx:172

The GeneralComposerDialog mixes conversational copy with clinical form labels. 'File general feedback' is descriptive and user-friendly, but 'Classification' reads as clinical. Consider warming it to 'Feedback type' or 'Category' for consistency.

Classification

Feedback type

Approve

Reject

Skip

Style suggestion

thread-card.tsx:144

The ThreadCard component uses 'image' and 'images' as content labels but also includes 'View screenshot' as a separate action, making it unclear whether these are three distinct concepts or varying phrasings of the same capability.

image

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

thread-card.tsx:144

The ThreadCard component uses 'image' and 'images' as content labels but also includes 'View screenshot' as a separate action, making it unclear whether these are three distinct concepts or varying phrasings of the same capability.

images

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

thread-card.tsx:157

The ThreadCard component uses 'image' and 'images' as content labels but also includes 'View screenshot' as a separate action, making it unclear whether these are three distinct concepts or varying phrasings of the same capability.

View screenshot

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Content Audit Tool: Closing the Loop Between Content Design and Source Code

My Role

Team

Timeline

Tools

Platform

Product Design Intern/Project Lead

Design

Foundations

9 Weeks

Figma,

Claude Code,

Miro,

Git Hub

Internal

Tools

Section 01: The Brief & The Discovery

The Brief

Operating within the Design Foundations team, my mandate was to identify a systemic problem and ship a plug-in to solve it proving the value of "agentic design" by using AI to build real software.

The Discovery

I expected to hear complaints about layer naming or detached components. To validate the actual friction points, I engaged the broader design org:

  • 40-Designer Survey: A wide-net assessment focused on daily Figma workflows, repetitive manual tasks, and tool friction.
  • 8 Internal Interviews: Deep-dive conversations with product designers to uncover their most expensive bottlenecks.

The Insight: The Copy Blind Spot

Instead of component issues, the research revealed a massive organizational gap regarding product copy:

  • Designers ≠ Writers: Designers were writing the UI text that ultimately shipped to production, despite not being content experts.
  • Zero Quality Gates: With limited UX-writer capacity and no centralised glossary, brand consistency was checked manually, if at all.
  • The Codebase Disconnect: The person qualified to judge the copy did not have the codebase open. Fixing a single string meant filing a Jira ticket and waiting weeks for an engineer to implement it.

Section 02: Architecture & Key Decisions

The Core Thesis

The foundational rule of this tool is that the person qualified to judge the copy must be able to fix it without leaving their canvas. It reads the UI copy directly from the codebase, judges it against the brand guidelines, and writes approved fixes straight back into the source files they came from.

Architectural Decisions

01

page.tsx:112

Add lecture

Add a lecture

cta.no-leading-article

Tone Check

Approve

Reject

Skip

Decision 01: Hybrid Evaluation (Code + LLM): The Scan engine utilises a two-pass hybrid approach. Deterministic rules (character limits, accessibility) are checked instantly, while the LLM handles holistic judgment (tone, redundancy). Both are fed by a centralised Rule registry.

02

filePath

/course-hero.tsx

stableId: component

+ ATS anchor

status: approved-local

Hash Key = sha256(filePath + stableStringID + normalised text

Decision 02: The Git-Tracked Cache: To prevent reviewers from answering the same question twice, the tool merges data from the source and a durable scan-log.json. This acts as a decision cache, ensuring the codebase remains the strict single source of truth without duplicating the actual string text.

03

STEP 01

Action: Approve

Write file locally. Status flipped to approved-local.

No Git operation triggered.

STEP 02

Action: Batch PR

Resolves session branch. One commit per approved string. PR opened via GitHub identity.

Decision 03: Decoupling Writes from Commits: The initial design committed a file change every time a reviewer clicked "Approve," which silently modified the working tree mid-session. The architecture was restructured so that approvals only trigger a local Write-back operation. Git operations are deferred entirely to a session batch, which opens a Pull Request directly via GitHub (GitHub -> PR opened).

Section 03: The Interface

The Audit Scope

The UI docks as a genuine flex sibling, offering three levels of precision: scanning the current route, auditing the full application, or using a live text picker to check a single string.

01

S

Good evening, Sam

Need help? Tell me a little about yourself so I can make the best recommendations.

Set your goal

In Progress

Completed

Skills

Certificates

Google

Build Wireframes and Low-Fidelity Prototypes

Course

·

16% complete

·

Estimated completion: Oct 20, 2025

Learn more about creating storyboards

Reading (8 minutes)

Resume

September 2026

Mo

Tu

We

Th

Fr

Sa

Su

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

1+ daily goals completed

All daily goals completed

Last 4 weeks

0

Daily goals completed

0

Items completed

0

Minutes learned

Explore

My Learning

Degrees

What do you want to learn?

S

Audit page content

Scan page

Scan app

227 strings scanned · 40 rule violations · 30 style suggestions

Rule violations (40)

Approve all rule violations

Rule violation

page.tsx:112

"Reading (8 minutes)" Uses full spelled-out duration strings in parentheses, violating the microcopy standard for content cards.

Reading (8 minutes)

8 min read

Approve

Reject

Skip

Rule violation

debug-journey-picker.tsx:186

"Good evening, Sam" Uses time-of-day contextual greetings, which violate global product copy standards due to timezone sync discrepancies.

Good evening, Sam

Welcome back, Sam

Approve

Reject

Skip

Rule violation

debug-journey-picker.tsx:186

Two CTAs in the same component convey the same underlying action: 'Starting…' and 'Start journey' both initiate a journey. One should be removed or consolidated.

Start journey

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

error.tsx:18

"Something went wrong." doesn't need its trailing period — single-sentence tooltips and error messages stay unpunctuated.

Something went wrong.

Something went wrong.

Approve

Reject

Skip

Rule violation

plan.tsx:134

The string 'Toggle plan' does not clearly indicate what 'plan' is or what toggling it does. The referent is unclear from the label alone.

Toggle plan

Show plan

Approve

Reject

Skip

Rule violation

reasoning.tsx:156

The strings 'Thought for' and 'seconds' are fragments designed to be concatenated around a number (e.g., 'Thought for 5 seconds'). This concatenation pattern creates localization and accessibility failures because word order differs across languages. Use a complete sentence instead.

Thought for

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

reasoning.tsx:156

The strings 'Thought for' and 'seconds' are fragments designed to be concatenated around a number (e.g., 'Thought for 5 seconds'). This concatenation pattern creates localization and accessibility failures because word order differs across languages. Use a complete sentence instead.

seconds

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

speech-input.tsx:300

The string 'Processing voice input' appears as a label/status message in a component and should not end with a period per Helix guidelines for UI microcopy.

Processing voice input

Processing voice input

Approve

Reject

Skip

Rule violation

web-preview.tsx:152

Accessibility failure: this input has no discrete label — placeholder "Enter URL..." is serving as the label, and it disappears once the user starts typing.

Enter URL...

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

helix-shell.tsx:262

The HelixShell component uses both 'Open wallet' and 'Wallet' to describe the same action. One should be removed or consolidated.

Open wallet

Open wallet

Approve

Reject

Skip

Rule violation

helix-shell.tsx:268

The HelixShell component uses both 'Open wallet' and 'Wallet' to describe the same action. One should be removed or consolidated.

Wallet

Open wallet

Approve

Reject

Skip

Rule violation

conversation-thread-view.tsx:984

Both ConversationThreadView and MicrolessonView use 'Helix is thinking…' identically. This suggests a shared constant that should be defined once.

Helix is thinking…

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

conversation-thread-view.tsx:1068

Accessibility failure: this input has no discrete label — placeholder "Ask Helix…" is serving as the label, and it disappears once the user starts typing.

Ask Helix…

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

feedback-nudge.tsx:35

The DismissButton component uses both 'Dismiss feedback nudge' and 'Dismiss' to describe the same action. One should be removed or consolidated.

Dismiss feedback nudge

Dismiss

Approve

Reject

Skip

Rule violation

feedback-nudge.tsx:40

The DismissButton component uses both 'Dismiss feedback nudge' and 'Dismiss' to describe the same action. One should be removed or consolidated.

Dismiss

Dismiss

Approve

Reject

Skip

Rule violation

microlesson-view.tsx:111

Both ConversationThreadView and MicrolessonView use 'Helix is thinking…' identically. This suggests a shared constant that should be defined once.

Helix is thinking…

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

microlesson-view.tsx:115

The error message 'This lesson hit a snag' uses an exclamation mark, which can read as flippant in a failure state. Per guidelines, errors should avoid exclamation marks.

This lesson hit a snag

This lesson hit a snag.

Approve

Reject

Skip

Rule violation

pathway-handoff-transition.tsx:41

Accessibility failure: this input has no discrete label — placeholder "Message Helix…" is serving as the label, and it disappears once the user starts typing.

Message Helix…

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

spine-referral-card.tsx:62

The ReferralLoadingCard component uses both 'Preparing your activity' and 'Preparing your activity…' to describe the same state. One should be removed or consolidated.

Preparing your activity

Preparing your activity…

Approve

Reject

Skip

Rule violation

spine-referral-card.tsx:63

The ReferralLoadingCard component uses both 'Preparing your activity' and 'Preparing your activity…' to describe the same state. One should be removed or consolidated.

Preparing your activity…

Preparing your activity…

Approve

Reject

Skip

Rule violation

wallet-dashboard.tsx:93

The label 'Total skills' appears in both WalletDashboard (id 2161926a0510) and WalletSurface (id 9b87b4fe967e). These likely refer to the same metric and should be consolidated to a single source string.

Total skills

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

wallet-dashboard.tsx:99

The label 'Average confidence' appears in both WalletDashboard (id 54d7ef7d5061) and WalletSurface (id bfc0d90b0965). These likely refer to the same metric and should be consolidated to a single source string.

Average confidence

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

wallet-surface.tsx:35

The label 'Total skills' appears in both WalletDashboard (id 2161926a0510) and WalletSurface (id 9b87b4fe967e). These likely refer to the same metric and should be consolidated to a single source string.

Total skills

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

wallet-surface.tsx:41

The label 'Average confidence' appears in both WalletDashboard (id 54d7ef7d5061) and WalletSurface (id bfc0d90b0965). These likely refer to the same metric and should be consolidated to a single source string.

Average confidence

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

content-registry.tsx:289

The string 'This is an interactive activity — it launches from its activity card in the conversation, not here.' uses pronouns 'it' and 'its' whose referent is unclear without seeing the UI context. What activity does 'it' refer to, and where specifically is 'the conversation'?

This is an interactive activity — it launches from its activity card in the conversation, not here.

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

concluded-interaction-review.tsx:43

Error copy should avoid exclamation marks. The phrase 'This activity didn't load' appears across multiple error states and should maintain consistent, neutral punctuation. While the current strings lack exclamation marks, ensure they remain absent if these error messages are presented as alerts or toasts.

This activity didn’t load

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

interactions-launch-surface.tsx:67

Error copy should avoid exclamation marks. The phrase 'This activity didn't load' appears across multiple error states and should maintain consistent, neutral punctuation. While the current strings lack exclamation marks, ensure they remain absent if these error messages are presented as alerts or toasts.

This activity didn’t load

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

surface.tsx:327

Error copy should avoid exclamation marks. The phrase 'This activity didn't load' appears across multiple error states and should maintain consistent, neutral punctuation. While the current strings lack exclamation marks, ensure they remain absent if these error messages are presented as alerts or toasts.

This activity didn’t load

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

attachment-tray.tsx:86

Buttons read as a more direct command without an article; "Add an image" uses one, the same shape the guideline's own example drops ("Add lecture", not "Add a lecture").

Add an image

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

comment-popover.tsx:425

Accessibility failure: this input has no discrete label — placeholder "Reply…" is serving as the label, and it disappears once the user starts typing.

Reply…

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

content-audit-finding-row.tsx:160

The strings 'Approved and applied.' and 'Dismissed.' end with periods, but these are short status messages in a component where periods are unnecessary clutter.

Approved and applied.

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

content-audit-finding-row.tsx:161

The strings 'Approved and applied.' and 'Dismissed.' end with periods, but these are short status messages in a component where periods are unnecessary clutter.

Dismissed.

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

feedback-composer.tsx:280

Accessibility failure: this input has no discrete label — placeholder "Share what's on your mind… (or drop an image)" is serving as the label, and it disappears once the user starts typing.

Share what's on your mind… (or drop an image)

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

feedback-composer.tsx:328

"Pin it to the app" uses "it" with nothing nearby naming what it refers to — a reader can't tell what's being acted on.

Pin it to the app

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

feedback-dock.tsx:114

The strings 'Your feedback' appears twice in this batch with the same id concept but used as a CTA in two different components. Review whether both instances are necessary or if one should be removed.

Your feedback

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

feedback-drawer.tsx:344

The strings 'reply' and 'replies' use lowercase, inconsistent with other CTA buttons in the interface that use sentence case. CTAs should use sentence case: 'Reply' and 'Replies'.

reply

Reply

Approve

Reject

Skip

Rule violation

feedback-drawer.tsx:344

The string 'replies' uses lowercase, inconsistent with other CTA buttons in the interface that use sentence case. CTAs should use sentence case: 'Replies'.

replies

Replies

Approve

Reject

Skip

Rule violation

feedback-thread-view.tsx:49

The strings 'Your feedback' appears twice in this batch with the same id concept but used as a CTA in two different components. Review whether both instances are necessary or if one should be removed.

Your feedback

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

feedback-thread-view.tsx:81

Accessibility failure: this input has no discrete label — placeholder "Reply…" is serving as the label, and it disappears once the user starts typing.

Reply…

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

general-composer.tsx:156

Accessibility failure: this input has no discrete label — placeholder "What did you want to flag? (paste or drop an image)" is serving as the label, and it disappears once the user starts typing.

What did you want to flag? (paste or drop an image)

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestions (30)

Dismiss all style suggestions

Style suggestion

onboarding-overlay.tsx:161

The OnboardingOverlay component mixes conversational second-person questions ('What do you want to learn today?' 'What do you want to get better at?') with clinical label-style copy ('Your name', 'A skill or goal'). Consider warming the placeholder text to match the conversational tone of the questions.

Welcome to Helix — what should we call you?

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

onboarding-overlay.tsx:167

The OnboardingOverlay component mixes conversational second-person questions ('What do you want to learn today?' 'What do you want to get better at?') with clinical label-style copy ('Your name', 'A skill or goal'). Consider warming the placeholder text to match the conversational tone of the questions.

Your name

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

onboarding-overlay.tsx:174

The OnboardingOverlay component mixes conversational second-person questions ('What do you want to learn today?' 'What do you want to get better at?') with clinical label-style copy ('Your name', 'A skill or goal'). Consider warming the placeholder text to match the conversational tone of the questions.

What do you want to get better at?

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

onboarding-overlay.tsx:180

The OnboardingOverlay component mixes conversational second-person questions ('What do you want to learn today?' 'What do you want to get better at?') with clinical label-style copy ('Your name', 'A skill or goal'). Consider warming the placeholder text to match the conversational tone of the questions.

A skill or goal

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

not-found.tsx:28

Consider a fresher take on 'Helix routed you off the path.' This phrasing feels somewhat clichéd; a more direct, less metaphorical explanation may feel clearer.

Helix routed you off the path. Head back to where the flow lives.

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

chat-prompt-bar.tsx:183

The strings 'Add attachment' and 'Upload files' both appear to reference the same underlying capability of attaching content to a message. Consider clarifying whether these are distinct actions (e.g., one for existing files, one for capturing new ones) or consolidating them.

Add attachment

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

prompt-input.tsx:842

The strings 'Add attachment' and 'Upload files' both appear to reference the same underlying capability of attaching content to a message. Consider clarifying whether these are distinct actions (e.g., one for existing files, one for capturing new ones) or consolidating them.

Upload files

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

helix-shell.tsx:969

Consider whether 'Helix is thinking…' and 'Loading saved pathways' represent the same state. 'Helix is thinking…' is conversational and personified, while 'Loading saved pathways' is more neutral. If both describe a loading state, align their tone.

Loading saved pathways

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

microlesson-view.tsx:117

The error heading 'This lesson hit a snag' (b584f4539a7b) and body 'The lesson stream failed.' use different punctuation treatment. Consider whether both should end with periods or neither.

The lesson stream failed.

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

wallet-empty-state.tsx:10

Consider whether 'trust-tiered' in the empty-state description is clear to all users. This technical term may not translate well or be immediately understood by learners unfamiliar with credential terminology.

Self-claim a skill or complete a learning path and it shows up here, evidenced and trust-tiered.

Self-claim a skill or complete a learning path and it shows up here, verified and ranked by trustworthiness.

Approve

Reject

Skip

Style suggestion

wallet-view.tsx:40

The ellipsis in 'Loading your wallet…' is acceptable but consider whether a spinner or animated treatment would communicate the loading state more clearly, per guidelines preferring graphical treatments over ellipses.

Loading your wallet…

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

launch-panels.tsx:207

The component labels mix specific and generic terms: 'Practice activity' (id 2fa182404a61), 'Activity launch' (id a8b53b0c4d37), and 'Activity' (id 40e32c8969ac) may refer to overlapping concepts. Consider whether these should use consistent phrasing or are intentionally distinct based on context.

Activity launch

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

practice-launch.tsx:61

Two strings convey that practice isn't available: 'This practice activity didn't load' (id ba3f8a33602b) and 'Practice isn't available here' (id 07cd12dde13a). These may represent different failure modes (load error vs. missing setup), but the distinction isn't clear from the wording alone. Clarify the difference or consolidate.

This practice activity didn’t load

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

practice-launch.tsx:112

The component labels mix specific and generic terms: 'Practice activity' (id 2fa182404a61), 'Activity launch' (id a8b53b0c4d37), and 'Activity' (id 40e32c8969ac) may refer to overlapping concepts. Consider whether these should use consistent phrasing or are intentionally distinct based on context.

Practice activity

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

surface.tsx:234

The component labels mix specific and generic terms: 'Practice activity' (id 2fa182404a61), 'Activity launch' (id a8b53b0c4d37), and 'Activity' (id 40e32c8969ac) may refer to overlapping concepts. Consider whether these should use consistent phrasing or are intentionally distinct based on context.

Activity

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

surface.tsx:321

"Loading this activity" uses "this" with nothing nearby naming what it refers to — a reader can't tell what's being acted on.

Loading this activity

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

surface.tsx:489

The footer component mixes conversational instruction ('Finish the practice above, then submit your answers') with clinical state descriptions ('Your answers didn't go through'). Consider warming 'Your answers didn't go through' to match the supportive tone, perhaps 'Your answers didn't submit—check your connection and try again.'

Your answers didn’t go through

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

surface.tsx:490

The footer component mixes conversational instruction ('Finish the practice above, then submit your answers') with clinical state descriptions ('Your answers didn't go through'). Consider warming 'Your answers didn't go through' to match the supportive tone, perhaps 'Your answers didn't submit—check your connection and try again.'

Check your connection and submit again.

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

surface.tsx:497

The footer component mixes conversational instruction ('Finish the practice above, then submit your answers') with clinical state descriptions ('Your answers didn't go through'). Consider warming 'Your answers didn't go through' to match the supportive tone, perhaps 'Your answers didn't submit—check your connection and try again.'

Finish the practice above, then submit your answers.

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

surface.tsx:601

Two strings convey that practice isn't available: 'This practice activity didn't load' (id ba3f8a33602b) and 'Practice isn't available here' (id 07cd12dde13a). These may represent different failure modes (load error vs. missing setup), but the distinction isn't clear from the wording alone. Clarify the difference or consolidate.

Practice isn’t available here

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

surface.tsx:603

The heading 'This check needs practice that isn't set up in this environment' (id ef6c5c30e6bd) is 61 characters and may exceed optimal brevity for modal-like components. Consider tightening to 'Practice isn't available here' or similar for better scannability.

This check needs practice that isn’t set up in this environment.

Practice isn't available here

Approve

Reject

Skip

Style suggestion

surface.tsx:724

Most error messages use contractions ('didn't', 'isn't'), which is good for approachability. However, 'No result was recorded for it' (id a31159b6e9e3) avoids contraction and feels slightly formal. Consider 'No result was recorded' for consistency.

No result was recorded for it.

No result was recorded

Approve

Reject

Skip

Style suggestion

attachment-tray.tsx:86

Buttons should stay within about 20 characters; "Attachment limit reached" is 24.

Attachment limit reached

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

feedback-composer.tsx:287

In CardBody, 'Add detail (optional)' uses clinical form language, which contrasts with the more conversational tone of nearby copy like 'Pin it to the app' and 'Audit page content'. Consider warming this label to match the component's overall voice.

Add detail (optional)

Add more details (optional)

Approve

Reject

Skip

Style suggestion

feedback-composer.tsx:338

The strings 'Add an image' and 'Add a screenshot' both appear to be attachment actions in the same component. Consider whether these are truly distinct capabilities or should use more specific, less ambiguous wording to clarify the difference.

Add a screenshot

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

general-composer.tsx:131

The GeneralComposerDialog mixes conversational copy with clinical form labels. 'File general feedback' is descriptive and user-friendly, but 'Classification' reads as clinical. Consider warming it to 'Feedback type' or 'Category' for consistency.

File general feedback

Feedback type

Approve

Reject

Skip

Style suggestion

general-composer.tsx:172

The GeneralComposerDialog mixes conversational copy with clinical form labels. 'File general feedback' is descriptive and user-friendly, but 'Classification' reads as clinical. Consider warming it to 'Feedback type' or 'Category' for consistency.

Classification

Feedback type

Approve

Reject

Skip

Style suggestion

thread-card.tsx:144

The ThreadCard component uses 'image' and 'images' as content labels but also includes 'View screenshot' as a separate action, making it unclear whether these are three distinct concepts or varying phrasings of the same capability.

image

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

thread-card.tsx:144

The ThreadCard component uses 'image' and 'images' as content labels but also includes 'View screenshot' as a separate action, making it unclear whether these are three distinct concepts or varying phrasings of the same capability.

images

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

thread-card.tsx:157

The ThreadCard component uses 'image' and 'images' as content labels but also includes 'View screenshot' as a separate action, making it unclear whether these are three distinct concepts or varying phrasings of the same capability.

View screenshot

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Two-Tier Findings

To avoid false precision, findings are strictly tiered rather than scored.

  • Rule Violations: High-confidence deterministic checks flagging mechanical errors like punctuation, character limits, and banned terms.
  • Style Suggestions: Low-confidence LLM judgment calls on tone, voice, and redundancy where human nuance is needed.

02

200 strings scanned · 9 rule violations · 4 style suggestions

Style suggestions (4)

Dismiss all style suggestions

Style suggestion

error.tsx:18

"Something went wrong." doesn't need its trailing period — single-sentence tooltips and error messages stay unpunctuated.

Something went wrong.

Something went wrong

Approve

Reject

Skip

Style suggestion

checkpoint-host.tsx:223

"Something went wrong fetching this checkpoint." doesn't need its trailing period — single-sentence tooltips and error messages stay unpunctuated.

Something went wrong fetching this checkpoint.

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

attachment-tray.tsx:86

Buttons should stay within about 20 characters; "Attachment limit reached" is 24.

Attachment limit reached

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

feedback-composer.tsx:328

"Pin it to the app" uses "it" with nothing nearby naming what it refers to — a reader can't tell what's being acted on.

Pin it to the app

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Optimistic UI & Outcomes

The interface is built with optimistic UI—buttons disable instantly on click to prevent double-submits, and re-enable if a failure occurs. The final action row dictates the string's lifecycle:

  • Approve: Writes the file locally and moves the fix to the pending PR batch.
  • Reject: Records a dismissal; the string will not surface again in subsequent scans.
  • Skip: Defers the decision to a later session.

03

S

Welcome back, Sam

Need help? Tell me a little about yourself so I can make the best recommendations.

Set your goal

In Progress

Completed

Skills

Certificates

Google

Build Wireframes and Low-Fidelity Prototypes

Course

·

16% complete

·

Estimated completion: Oct 20, 2025

Learn more about creating storyboards

Reading (8 minutes)

Resume

September 2026

Mo

Tu

We

Th

Fr

Sa

Su

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

1+ daily goals completed

All daily goals completed

Last 4 weeks

0

Daily goals completed

0

Items completed

0

Minutes learned

Explore

My Learning

Degrees

What do you want to learn?

S

Manual Edit

To keep reviewers in context, the UI relies on a fluid inline transition. Crucially, the model's rewrite is only a starting point manual editing is an open affordance available at any time:

  • 01 Flagged: The original text receives a muted strikethrough. If no automated rewrite is available, the "Approve" button remains visible but disabled until a fix is provided.
  • 02 Editing: Clicking the pencil icon at any point opens an active textarea, allowing the reviewer to modify the LLM's suggestion or draft their own from scratch. The primary blue "Save" button takes visual focus.
  • 03 Resolved: The finalised rewrite sits below the original. The "Approve" button takes the primary blue accent, signalling it is ready for the batch.

04

Audit page content

Scan page

Scan app

227 strings scanned · 40 rule violations · 30 style suggestions

Rule violations (40)

Approve all rule violations

Rule violation

page.tsx:112

"Reading (8 minutes)" Uses full spelled-out duration strings in parentheses, violating the microcopy standard for content cards.

Reading (8 minutes)

8 min read

Approve

Reject

Skip

Rule violation

debug-journey-picker.tsx:186

"Good evening, Sam" Uses time-of-day contextual greetings, which violate global product copy standards due to timezone sync discrepancies.

Welcome back! Sam|

Cancel

Save

Approve

Reject

Skip

Rule violation

debug-journey-picker.tsx:186

Two CTAs in the same component convey the same underlying action: 'Starting…' and 'Start journey' both initiate a journey. One should be removed or consolidated.

Start journey

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

error.tsx:18

"Something went wrong." doesn't need its trailing period — single-sentence tooltips and error messages stay unpunctuated.

Something went wrong.

Something went wrong.

Approve

Reject

Skip

Rule violation

plan.tsx:134

The string 'Toggle plan' does not clearly indicate what 'plan' is or what toggling it does. The referent is unclear from the label alone.

Toggle plan

Show plan

Approve

Reject

Skip

Rule violation

reasoning.tsx:156

The strings 'Thought for' and 'seconds' are fragments designed to be concatenated around a number (e.g., 'Thought for 5 seconds'). This concatenation pattern creates localization and accessibility failures because word order differs across languages. Use a complete sentence instead.

Thought for

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

reasoning.tsx:156

The strings 'Thought for' and 'seconds' are fragments designed to be concatenated around a number (e.g., 'Thought for 5 seconds'). This concatenation pattern creates localization and accessibility failures because word order differs across languages. Use a complete sentence instead.

seconds

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

speech-input.tsx:300

The string 'Processing voice input' appears as a label/status message in a component and should not end with a period per Helix guidelines for UI microcopy.

Processing voice input

Processing voice input

Approve

Reject

Skip

Rule violation

web-preview.tsx:152

Accessibility failure: this input has no discrete label — placeholder "Enter URL..." is serving as the label, and it disappears once the user starts typing.

Enter URL...

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

helix-shell.tsx:262

The HelixShell component uses both 'Open wallet' and 'Wallet' to describe the same action. One should be removed or consolidated.

Open wallet

Open wallet

Approve

Reject

Skip

Rule violation

helix-shell.tsx:268

The HelixShell component uses both 'Open wallet' and 'Wallet' to describe the same action. One should be removed or consolidated.

Wallet

Open wallet

Approve

Reject

Skip

Rule violation

conversation-thread-view.tsx:984

Both ConversationThreadView and MicrolessonView use 'Helix is thinking…' identically. This suggests a shared constant that should be defined once.

Helix is thinking…

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

conversation-thread-view.tsx:1068

Accessibility failure: this input has no discrete label — placeholder "Ask Helix…" is serving as the label, and it disappears once the user starts typing.

Ask Helix…

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

feedback-nudge.tsx:35

The DismissButton component uses both 'Dismiss feedback nudge' and 'Dismiss' to describe the same action. One should be removed or consolidated.

Dismiss feedback nudge

Dismiss

Approve

Reject

Skip

Rule violation

feedback-nudge.tsx:40

The DismissButton component uses both 'Dismiss feedback nudge' and 'Dismiss' to describe the same action. One should be removed or consolidated.

Dismiss

Dismiss

Approve

Reject

Skip

Rule violation

microlesson-view.tsx:111

Both ConversationThreadView and MicrolessonView use 'Helix is thinking…' identically. This suggests a shared constant that should be defined once.

Helix is thinking…

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

microlesson-view.tsx:115

The error message 'This lesson hit a snag' uses an exclamation mark, which can read as flippant in a failure state. Per guidelines, errors should avoid exclamation marks.

This lesson hit a snag

This lesson hit a snag.

Approve

Reject

Skip

Rule violation

pathway-handoff-transition.tsx:41

Accessibility failure: this input has no discrete label — placeholder "Message Helix…" is serving as the label, and it disappears once the user starts typing.

Message Helix…

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

spine-referral-card.tsx:62

The ReferralLoadingCard component uses both 'Preparing your activity' and 'Preparing your activity…' to describe the same state. One should be removed or consolidated.

Preparing your activity

Preparing your activity…

Approve

Reject

Skip

Rule violation

spine-referral-card.tsx:63

The ReferralLoadingCard component uses both 'Preparing your activity' and 'Preparing your activity…' to describe the same state. One should be removed or consolidated.

Preparing your activity…

Preparing your activity…

Approve

Reject

Skip

Rule violation

wallet-dashboard.tsx:93

The label 'Total skills' appears in both WalletDashboard (id 2161926a0510) and WalletSurface (id 9b87b4fe967e). These likely refer to the same metric and should be consolidated to a single source string.

Total skills

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

wallet-dashboard.tsx:99

The label 'Average confidence' appears in both WalletDashboard (id 54d7ef7d5061) and WalletSurface (id bfc0d90b0965). These likely refer to the same metric and should be consolidated to a single source string.

Average confidence

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

wallet-surface.tsx:35

The label 'Total skills' appears in both WalletDashboard (id 2161926a0510) and WalletSurface (id 9b87b4fe967e). These likely refer to the same metric and should be consolidated to a single source string.

Total skills

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

wallet-surface.tsx:41

The label 'Average confidence' appears in both WalletDashboard (id 54d7ef7d5061) and WalletSurface (id bfc0d90b0965). These likely refer to the same metric and should be consolidated to a single source string.

Average confidence

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

content-registry.tsx:289

The string 'This is an interactive activity — it launches from its activity card in the conversation, not here.' uses pronouns 'it' and 'its' whose referent is unclear without seeing the UI context. What activity does 'it' refer to, and where specifically is 'the conversation'?

This is an interactive activity — it launches from its activity card in the conversation, not here.

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

concluded-interaction-review.tsx:43

Error copy should avoid exclamation marks. The phrase 'This activity didn't load' appears across multiple error states and should maintain consistent, neutral punctuation. While the current strings lack exclamation marks, ensure they remain absent if these error messages are presented as alerts or toasts.

This activity didn’t load

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

interactions-launch-surface.tsx:67

Error copy should avoid exclamation marks. The phrase 'This activity didn't load' appears across multiple error states and should maintain consistent, neutral punctuation. While the current strings lack exclamation marks, ensure they remain absent if these error messages are presented as alerts or toasts.

This activity didn’t load

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

surface.tsx:327

Error copy should avoid exclamation marks. The phrase 'This activity didn't load' appears across multiple error states and should maintain consistent, neutral punctuation. While the current strings lack exclamation marks, ensure they remain absent if these error messages are presented as alerts or toasts.

This activity didn’t load

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

attachment-tray.tsx:86

Buttons read as a more direct command without an article; "Add an image" uses one, the same shape the guideline's own example drops ("Add lecture", not "Add a lecture").

Add an image

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

comment-popover.tsx:425

Accessibility failure: this input has no discrete label — placeholder "Reply…" is serving as the label, and it disappears once the user starts typing.

Reply…

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

content-audit-finding-row.tsx:160

The strings 'Approved and applied.' and 'Dismissed.' end with periods, but these are short status messages in a component where periods are unnecessary clutter.

Approved and applied.

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

content-audit-finding-row.tsx:161

The strings 'Approved and applied.' and 'Dismissed.' end with periods, but these are short status messages in a component where periods are unnecessary clutter.

Dismissed.

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

feedback-composer.tsx:280

Accessibility failure: this input has no discrete label — placeholder "Share what's on your mind… (or drop an image)" is serving as the label, and it disappears once the user starts typing.

Share what's on your mind… (or drop an image)

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

feedback-composer.tsx:328

"Pin it to the app" uses "it" with nothing nearby naming what it refers to — a reader can't tell what's being acted on.

Pin it to the app

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

feedback-dock.tsx:114

The strings 'Your feedback' appears twice in this batch with the same id concept but used as a CTA in two different components. Review whether both instances are necessary or if one should be removed.

Your feedback

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

feedback-drawer.tsx:344

The strings 'reply' and 'replies' use lowercase, inconsistent with other CTA buttons in the interface that use sentence case. CTAs should use sentence case: 'Reply' and 'Replies'.

reply

Reply

Approve

Reject

Skip

Rule violation

feedback-drawer.tsx:344

The string 'replies' uses lowercase, inconsistent with other CTA buttons in the interface that use sentence case. CTAs should use sentence case: 'Replies'.

replies

Replies

Approve

Reject

Skip

Rule violation

feedback-thread-view.tsx:49

The strings 'Your feedback' appears twice in this batch with the same id concept but used as a CTA in two different components. Review whether both instances are necessary or if one should be removed.

Your feedback

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

feedback-thread-view.tsx:81

Accessibility failure: this input has no discrete label — placeholder "Reply…" is serving as the label, and it disappears once the user starts typing.

Reply…

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

general-composer.tsx:156

Accessibility failure: this input has no discrete label — placeholder "What did you want to flag? (paste or drop an image)" is serving as the label, and it disappears once the user starts typing.

What did you want to flag? (paste or drop an image)

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestions (30)

Dismiss all style suggestions

Style suggestion

onboarding-overlay.tsx:161

The OnboardingOverlay component mixes conversational second-person questions ('What do you want to learn today?' 'What do you want to get better at?') with clinical label-style copy ('Your name', 'A skill or goal'). Consider warming the placeholder text to match the conversational tone of the questions.

Welcome to Helix — what should we call you?

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

onboarding-overlay.tsx:167

The OnboardingOverlay component mixes conversational second-person questions ('What do you want to learn today?' 'What do you want to get better at?') with clinical label-style copy ('Your name', 'A skill or goal'). Consider warming the placeholder text to match the conversational tone of the questions.

Your name

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

onboarding-overlay.tsx:174

The OnboardingOverlay component mixes conversational second-person questions ('What do you want to learn today?' 'What do you want to get better at?') with clinical label-style copy ('Your name', 'A skill or goal'). Consider warming the placeholder text to match the conversational tone of the questions.

What do you want to get better at?

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

onboarding-overlay.tsx:180

The OnboardingOverlay component mixes conversational second-person questions ('What do you want to learn today?' 'What do you want to get better at?') with clinical label-style copy ('Your name', 'A skill or goal'). Consider warming the placeholder text to match the conversational tone of the questions.

A skill or goal

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

not-found.tsx:28

Consider a fresher take on 'Helix routed you off the path.' This phrasing feels somewhat clichéd; a more direct, less metaphorical explanation may feel clearer.

Helix routed you off the path. Head back to where the flow lives.

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

chat-prompt-bar.tsx:183

The strings 'Add attachment' and 'Upload files' both appear to reference the same underlying capability of attaching content to a message. Consider clarifying whether these are distinct actions (e.g., one for existing files, one for capturing new ones) or consolidating them.

Add attachment

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

prompt-input.tsx:842

The strings 'Add attachment' and 'Upload files' both appear to reference the same underlying capability of attaching content to a message. Consider clarifying whether these are distinct actions (e.g., one for existing files, one for capturing new ones) or consolidating them.

Upload files

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

helix-shell.tsx:969

Consider whether 'Helix is thinking…' and 'Loading saved pathways' represent the same state. 'Helix is thinking…' is conversational and personified, while 'Loading saved pathways' is more neutral. If both describe a loading state, align their tone.

Loading saved pathways

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

microlesson-view.tsx:117

The error heading 'This lesson hit a snag' (b584f4539a7b) and body 'The lesson stream failed.' use different punctuation treatment. Consider whether both should end with periods or neither.

The lesson stream failed.

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

wallet-empty-state.tsx:10

Consider whether 'trust-tiered' in the empty-state description is clear to all users. This technical term may not translate well or be immediately understood by learners unfamiliar with credential terminology.

Self-claim a skill or complete a learning path and it shows up here, evidenced and trust-tiered.

Self-claim a skill or complete a learning path and it shows up here, verified and ranked by trustworthiness.

Approve

Reject

Skip

Style suggestion

wallet-view.tsx:40

The ellipsis in 'Loading your wallet…' is acceptable but consider whether a spinner or animated treatment would communicate the loading state more clearly, per guidelines preferring graphical treatments over ellipses.

Loading your wallet…

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

launch-panels.tsx:207

The component labels mix specific and generic terms: 'Practice activity' (id 2fa182404a61), 'Activity launch' (id a8b53b0c4d37), and 'Activity' (id 40e32c8969ac) may refer to overlapping concepts. Consider whether these should use consistent phrasing or are intentionally distinct based on context.

Activity launch

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

practice-launch.tsx:61

Two strings convey that practice isn't available: 'This practice activity didn't load' (id ba3f8a33602b) and 'Practice isn't available here' (id 07cd12dde13a). These may represent different failure modes (load error vs. missing setup), but the distinction isn't clear from the wording alone. Clarify the difference or consolidate.

This practice activity didn’t load

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

practice-launch.tsx:112

The component labels mix specific and generic terms: 'Practice activity' (id 2fa182404a61), 'Activity launch' (id a8b53b0c4d37), and 'Activity' (id 40e32c8969ac) may refer to overlapping concepts. Consider whether these should use consistent phrasing or are intentionally distinct based on context.

Practice activity

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

surface.tsx:234

The component labels mix specific and generic terms: 'Practice activity' (id 2fa182404a61), 'Activity launch' (id a8b53b0c4d37), and 'Activity' (id 40e32c8969ac) may refer to overlapping concepts. Consider whether these should use consistent phrasing or are intentionally distinct based on context.

Activity

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

surface.tsx:321

"Loading this activity" uses "this" with nothing nearby naming what it refers to — a reader can't tell what's being acted on.

Loading this activity

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

surface.tsx:489

The footer component mixes conversational instruction ('Finish the practice above, then submit your answers') with clinical state descriptions ('Your answers didn't go through'). Consider warming 'Your answers didn't go through' to match the supportive tone, perhaps 'Your answers didn't submit—check your connection and try again.'

Your answers didn’t go through

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

surface.tsx:490

The footer component mixes conversational instruction ('Finish the practice above, then submit your answers') with clinical state descriptions ('Your answers didn't go through'). Consider warming 'Your answers didn't go through' to match the supportive tone, perhaps 'Your answers didn't submit—check your connection and try again.'

Check your connection and submit again.

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

surface.tsx:497

The footer component mixes conversational instruction ('Finish the practice above, then submit your answers') with clinical state descriptions ('Your answers didn't go through'). Consider warming 'Your answers didn't go through' to match the supportive tone, perhaps 'Your answers didn't submit—check your connection and try again.'

Finish the practice above, then submit your answers.

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

surface.tsx:601

Two strings convey that practice isn't available: 'This practice activity didn't load' (id ba3f8a33602b) and 'Practice isn't available here' (id 07cd12dde13a). These may represent different failure modes (load error vs. missing setup), but the distinction isn't clear from the wording alone. Clarify the difference or consolidate.

Practice isn’t available here

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

surface.tsx:603

The heading 'This check needs practice that isn't set up in this environment' (id ef6c5c30e6bd) is 61 characters and may exceed optimal brevity for modal-like components. Consider tightening to 'Practice isn't available here' or similar for better scannability.

This check needs practice that isn’t set up in this environment.

Practice isn't available here

Approve

Reject

Skip

Style suggestion

surface.tsx:724

Most error messages use contractions ('didn't', 'isn't'), which is good for approachability. However, 'No result was recorded for it' (id a31159b6e9e3) avoids contraction and feels slightly formal. Consider 'No result was recorded' for consistency.

No result was recorded for it.

No result was recorded

Approve

Reject

Skip

Style suggestion

attachment-tray.tsx:86

Buttons should stay within about 20 characters; "Attachment limit reached" is 24.

Attachment limit reached

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

feedback-composer.tsx:287

In CardBody, 'Add detail (optional)' uses clinical form language, which contrasts with the more conversational tone of nearby copy like 'Pin it to the app' and 'Audit page content'. Consider warming this label to match the component's overall voice.

Add detail (optional)

Add more details (optional)

Approve

Reject

Skip

Style suggestion

feedback-composer.tsx:338

The strings 'Add an image' and 'Add a screenshot' both appear to be attachment actions in the same component. Consider whether these are truly distinct capabilities or should use more specific, less ambiguous wording to clarify the difference.

Add a screenshot

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

general-composer.tsx:131

The GeneralComposerDialog mixes conversational copy with clinical form labels. 'File general feedback' is descriptive and user-friendly, but 'Classification' reads as clinical. Consider warming it to 'Feedback type' or 'Category' for consistency.

File general feedback

Feedback type

Approve

Reject

Skip

Style suggestion

general-composer.tsx:172

The GeneralComposerDialog mixes conversational copy with clinical form labels. 'File general feedback' is descriptive and user-friendly, but 'Classification' reads as clinical. Consider warming it to 'Feedback type' or 'Category' for consistency.

Classification

Feedback type

Approve

Reject

Skip

Style suggestion

thread-card.tsx:144

The ThreadCard component uses 'image' and 'images' as content labels but also includes 'View screenshot' as a separate action, making it unclear whether these are three distinct concepts or varying phrasings of the same capability.

image

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

thread-card.tsx:144

The ThreadCard component uses 'image' and 'images' as content labels but also includes 'View screenshot' as a separate action, making it unclear whether these are three distinct concepts or varying phrasings of the same capability.

images

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

thread-card.tsx:157

The ThreadCard component uses 'image' and 'images' as content labels but also includes 'View screenshot' as a separate action, making it unclear whether these are three distinct concepts or varying phrasings of the same capability.

View screenshot

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Section 04: Outcomes & Lessons

The Impact

By treating UI copy as a governed, versioned instance of a content system, the tool collapses the traditional multi-week Jira ticket loop into a single, on-canvas action. Reviewers edit copy in context, click approve, and the fix lands directly in a source file on a branch, entirely bypassing the need for a developer to open an editor.

The First Live Audit & Partnering with AI

Building this engine directly via Claude Code completely shifted my perspective on what I could ship as a product designer. During the first official end-to-end live run, the tool processed 225 strings, successfully flagging 44 rule violations and 27 style suggestions in roughly 24 seconds—proving my hybrid LLM pass was genuinely functioning.

Getting to that outcome taught me that agentic design is a true partnership, one that still relies heavily on my own architectural judgment. While my mocked tests passed perfectly, running real-repository integration tests surfaced 17 critical Git-layer bugs. Diagnosing those failures is what drove my most important architectural pivot: abandoning the initial "commit-on-approve" design (which corrupted the working tree) in favor of the deferred "Batch PR" model.

Strict Safety Gates

Because I was building a plugin that writes directly to a developer's local source files, ensuring it could not corrupt a production environment fell entirely on my shoulders. I engineered a strict three-gate safety model:

  • Scan Gate: Read-only scanning is enabled on PR preview environments so reviewers can audit real findings.
  • Write Gate: Write-backs and Git operations are hard-locked to local development only, where the developer has full control to undo changes.
  • LLM Gate: An independent kill switch for the model pass, ensuring deterministic rules continue to run even if the AI endpoint fails.

S

Good evening, Sam

Need help? Tell me a little about yourself so I can make the best recommendations.

Set your goal

In Progress

Completed

Skills

Certificates

Google

Build Wireframes and Low-Fidelity Prototypes

Course

·

16% complete

·

Estimated completion: Oct 20, 2025

Learn more about creating storyboards

Reading (8 minutes)

Resume

September 2026

Mo

Tu

We

Th

Fr

Sa

Su

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

1+ daily goals completed

All daily goals completed

Last 4 weeks

0

Daily goals completed

0

Items completed

0

Minutes learned

Explore

My Learning

Degrees

What do you want to learn?

S

Audit page content

Scan page

Scan app

227 strings scanned · 40 rule violations · 30 style suggestions

Rule violations (40)

Approve all rule violations

Rule violation

page.tsx:112

"Reading (8 minutes)" Uses full spelled-out duration strings in parentheses, violating the microcopy standard for content cards.

Reading (8 minutes)

8 min read

Approve

Reject

Skip

Rule violation

debug-journey-picker.tsx:186

"Good evening, Sam" Uses time-of-day contextual greetings, which violate global product copy standards due to timezone sync discrepancies.

Good evening, Sam

Welcome back, Sam

Approve

Reject

Skip

Rule violation

debug-journey-picker.tsx:186

Two CTAs in the same component convey the same underlying action: 'Starting…' and 'Start journey' both initiate a journey. One should be removed or consolidated.

Start journey

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

error.tsx:18

"Something went wrong." doesn't need its trailing period — single-sentence tooltips and error messages stay unpunctuated.

Something went wrong.

Something went wrong.

Approve

Reject

Skip

Rule violation

plan.tsx:134

The string 'Toggle plan' does not clearly indicate what 'plan' is or what toggling it does. The referent is unclear from the label alone.

Toggle plan

Show plan

Approve

Reject

Skip

Rule violation

reasoning.tsx:156

The strings 'Thought for' and 'seconds' are fragments designed to be concatenated around a number (e.g., 'Thought for 5 seconds'). This concatenation pattern creates localization and accessibility failures because word order differs across languages. Use a complete sentence instead.

Thought for

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

reasoning.tsx:156

The strings 'Thought for' and 'seconds' are fragments designed to be concatenated around a number (e.g., 'Thought for 5 seconds'). This concatenation pattern creates localization and accessibility failures because word order differs across languages. Use a complete sentence instead.

seconds

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

speech-input.tsx:300

The string 'Processing voice input' appears as a label/status message in a component and should not end with a period per Helix guidelines for UI microcopy.

Processing voice input

Processing voice input

Approve

Reject

Skip

Rule violation

web-preview.tsx:152

Accessibility failure: this input has no discrete label — placeholder "Enter URL..." is serving as the label, and it disappears once the user starts typing.

Enter URL...

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

helix-shell.tsx:262

The HelixShell component uses both 'Open wallet' and 'Wallet' to describe the same action. One should be removed or consolidated.

Open wallet

Open wallet

Approve

Reject

Skip

Rule violation

helix-shell.tsx:268

The HelixShell component uses both 'Open wallet' and 'Wallet' to describe the same action. One should be removed or consolidated.

Wallet

Open wallet

Approve

Reject

Skip

Rule violation

conversation-thread-view.tsx:984

Both ConversationThreadView and MicrolessonView use 'Helix is thinking…' identically. This suggests a shared constant that should be defined once.

Helix is thinking…

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

conversation-thread-view.tsx:1068

Accessibility failure: this input has no discrete label — placeholder "Ask Helix…" is serving as the label, and it disappears once the user starts typing.

Ask Helix…

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

feedback-nudge.tsx:35

The DismissButton component uses both 'Dismiss feedback nudge' and 'Dismiss' to describe the same action. One should be removed or consolidated.

Dismiss feedback nudge

Dismiss

Approve

Reject

Skip

Rule violation

feedback-nudge.tsx:40

The DismissButton component uses both 'Dismiss feedback nudge' and 'Dismiss' to describe the same action. One should be removed or consolidated.

Dismiss

Dismiss

Approve

Reject

Skip

Rule violation

microlesson-view.tsx:111

Both ConversationThreadView and MicrolessonView use 'Helix is thinking…' identically. This suggests a shared constant that should be defined once.

Helix is thinking…

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

microlesson-view.tsx:115

The error message 'This lesson hit a snag' uses an exclamation mark, which can read as flippant in a failure state. Per guidelines, errors should avoid exclamation marks.

This lesson hit a snag

This lesson hit a snag.

Approve

Reject

Skip

Rule violation

pathway-handoff-transition.tsx:41

Accessibility failure: this input has no discrete label — placeholder "Message Helix…" is serving as the label, and it disappears once the user starts typing.

Message Helix…

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

spine-referral-card.tsx:62

The ReferralLoadingCard component uses both 'Preparing your activity' and 'Preparing your activity…' to describe the same state. One should be removed or consolidated.

Preparing your activity

Preparing your activity…

Approve

Reject

Skip

Rule violation

spine-referral-card.tsx:63

The ReferralLoadingCard component uses both 'Preparing your activity' and 'Preparing your activity…' to describe the same state. One should be removed or consolidated.

Preparing your activity…

Preparing your activity…

Approve

Reject

Skip

Rule violation

wallet-dashboard.tsx:93

The label 'Total skills' appears in both WalletDashboard (id 2161926a0510) and WalletSurface (id 9b87b4fe967e). These likely refer to the same metric and should be consolidated to a single source string.

Total skills

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

wallet-dashboard.tsx:99

The label 'Average confidence' appears in both WalletDashboard (id 54d7ef7d5061) and WalletSurface (id bfc0d90b0965). These likely refer to the same metric and should be consolidated to a single source string.

Average confidence

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

wallet-surface.tsx:35

The label 'Total skills' appears in both WalletDashboard (id 2161926a0510) and WalletSurface (id 9b87b4fe967e). These likely refer to the same metric and should be consolidated to a single source string.

Total skills

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

wallet-surface.tsx:41

The label 'Average confidence' appears in both WalletDashboard (id 54d7ef7d5061) and WalletSurface (id bfc0d90b0965). These likely refer to the same metric and should be consolidated to a single source string.

Average confidence

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

content-registry.tsx:289

The string 'This is an interactive activity — it launches from its activity card in the conversation, not here.' uses pronouns 'it' and 'its' whose referent is unclear without seeing the UI context. What activity does 'it' refer to, and where specifically is 'the conversation'?

This is an interactive activity — it launches from its activity card in the conversation, not here.

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

concluded-interaction-review.tsx:43

Error copy should avoid exclamation marks. The phrase 'This activity didn't load' appears across multiple error states and should maintain consistent, neutral punctuation. While the current strings lack exclamation marks, ensure they remain absent if these error messages are presented as alerts or toasts.

This activity didn’t load

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

interactions-launch-surface.tsx:67

Error copy should avoid exclamation marks. The phrase 'This activity didn't load' appears across multiple error states and should maintain consistent, neutral punctuation. While the current strings lack exclamation marks, ensure they remain absent if these error messages are presented as alerts or toasts.

This activity didn’t load

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

surface.tsx:327

Error copy should avoid exclamation marks. The phrase 'This activity didn't load' appears across multiple error states and should maintain consistent, neutral punctuation. While the current strings lack exclamation marks, ensure they remain absent if these error messages are presented as alerts or toasts.

This activity didn’t load

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

attachment-tray.tsx:86

Buttons read as a more direct command without an article; "Add an image" uses one, the same shape the guideline's own example drops ("Add lecture", not "Add a lecture").

Add an image

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

comment-popover.tsx:425

Accessibility failure: this input has no discrete label — placeholder "Reply…" is serving as the label, and it disappears once the user starts typing.

Reply…

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

content-audit-finding-row.tsx:160

The strings 'Approved and applied.' and 'Dismissed.' end with periods, but these are short status messages in a component where periods are unnecessary clutter.

Approved and applied.

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

content-audit-finding-row.tsx:161

The strings 'Approved and applied.' and 'Dismissed.' end with periods, but these are short status messages in a component where periods are unnecessary clutter.

Dismissed.

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

feedback-composer.tsx:280

Accessibility failure: this input has no discrete label — placeholder "Share what's on your mind… (or drop an image)" is serving as the label, and it disappears once the user starts typing.

Share what's on your mind… (or drop an image)

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

feedback-composer.tsx:328

"Pin it to the app" uses "it" with nothing nearby naming what it refers to — a reader can't tell what's being acted on.

Pin it to the app

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

feedback-dock.tsx:114

The strings 'Your feedback' appears twice in this batch with the same id concept but used as a CTA in two different components. Review whether both instances are necessary or if one should be removed.

Your feedback

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

feedback-drawer.tsx:344

The strings 'reply' and 'replies' use lowercase, inconsistent with other CTA buttons in the interface that use sentence case. CTAs should use sentence case: 'Reply' and 'Replies'.

reply

Reply

Approve

Reject

Skip

Rule violation

feedback-drawer.tsx:344

The string 'replies' uses lowercase, inconsistent with other CTA buttons in the interface that use sentence case. CTAs should use sentence case: 'Replies'.

replies

Replies

Approve

Reject

Skip

Rule violation

feedback-thread-view.tsx:49

The strings 'Your feedback' appears twice in this batch with the same id concept but used as a CTA in two different components. Review whether both instances are necessary or if one should be removed.

Your feedback

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

feedback-thread-view.tsx:81

Accessibility failure: this input has no discrete label — placeholder "Reply…" is serving as the label, and it disappears once the user starts typing.

Reply…

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

general-composer.tsx:156

Accessibility failure: this input has no discrete label — placeholder "What did you want to flag? (paste or drop an image)" is serving as the label, and it disappears once the user starts typing.

What did you want to flag? (paste or drop an image)

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestions (30)

Dismiss all style suggestions

Style suggestion

onboarding-overlay.tsx:161

The OnboardingOverlay component mixes conversational second-person questions ('What do you want to learn today?' 'What do you want to get better at?') with clinical label-style copy ('Your name', 'A skill or goal'). Consider warming the placeholder text to match the conversational tone of the questions.

Welcome to Helix — what should we call you?

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

onboarding-overlay.tsx:167

The OnboardingOverlay component mixes conversational second-person questions ('What do you want to learn today?' 'What do you want to get better at?') with clinical label-style copy ('Your name', 'A skill or goal'). Consider warming the placeholder text to match the conversational tone of the questions.

Your name

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

onboarding-overlay.tsx:174

The OnboardingOverlay component mixes conversational second-person questions ('What do you want to learn today?' 'What do you want to get better at?') with clinical label-style copy ('Your name', 'A skill or goal'). Consider warming the placeholder text to match the conversational tone of the questions.

What do you want to get better at?

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

onboarding-overlay.tsx:180

The OnboardingOverlay component mixes conversational second-person questions ('What do you want to learn today?' 'What do you want to get better at?') with clinical label-style copy ('Your name', 'A skill or goal'). Consider warming the placeholder text to match the conversational tone of the questions.

A skill or goal

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

not-found.tsx:28

Consider a fresher take on 'Helix routed you off the path.' This phrasing feels somewhat clichéd; a more direct, less metaphorical explanation may feel clearer.

Helix routed you off the path. Head back to where the flow lives.

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

chat-prompt-bar.tsx:183

The strings 'Add attachment' and 'Upload files' both appear to reference the same underlying capability of attaching content to a message. Consider clarifying whether these are distinct actions (e.g., one for existing files, one for capturing new ones) or consolidating them.

Add attachment

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

prompt-input.tsx:842

The strings 'Add attachment' and 'Upload files' both appear to reference the same underlying capability of attaching content to a message. Consider clarifying whether these are distinct actions (e.g., one for existing files, one for capturing new ones) or consolidating them.

Upload files

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

helix-shell.tsx:969

Consider whether 'Helix is thinking…' and 'Loading saved pathways' represent the same state. 'Helix is thinking…' is conversational and personified, while 'Loading saved pathways' is more neutral. If both describe a loading state, align their tone.

Loading saved pathways

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

microlesson-view.tsx:117

The error heading 'This lesson hit a snag' (b584f4539a7b) and body 'The lesson stream failed.' use different punctuation treatment. Consider whether both should end with periods or neither.

The lesson stream failed.

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

wallet-empty-state.tsx:10

Consider whether 'trust-tiered' in the empty-state description is clear to all users. This technical term may not translate well or be immediately understood by learners unfamiliar with credential terminology.

Self-claim a skill or complete a learning path and it shows up here, evidenced and trust-tiered.

Self-claim a skill or complete a learning path and it shows up here, verified and ranked by trustworthiness.

Approve

Reject

Skip

Style suggestion

wallet-view.tsx:40

The ellipsis in 'Loading your wallet…' is acceptable but consider whether a spinner or animated treatment would communicate the loading state more clearly, per guidelines preferring graphical treatments over ellipses.

Loading your wallet…

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

launch-panels.tsx:207

The component labels mix specific and generic terms: 'Practice activity' (id 2fa182404a61), 'Activity launch' (id a8b53b0c4d37), and 'Activity' (id 40e32c8969ac) may refer to overlapping concepts. Consider whether these should use consistent phrasing or are intentionally distinct based on context.

Activity launch

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

practice-launch.tsx:61

Two strings convey that practice isn't available: 'This practice activity didn't load' (id ba3f8a33602b) and 'Practice isn't available here' (id 07cd12dde13a). These may represent different failure modes (load error vs. missing setup), but the distinction isn't clear from the wording alone. Clarify the difference or consolidate.

This practice activity didn’t load

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

practice-launch.tsx:112

The component labels mix specific and generic terms: 'Practice activity' (id 2fa182404a61), 'Activity launch' (id a8b53b0c4d37), and 'Activity' (id 40e32c8969ac) may refer to overlapping concepts. Consider whether these should use consistent phrasing or are intentionally distinct based on context.

Practice activity

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

surface.tsx:234

The component labels mix specific and generic terms: 'Practice activity' (id 2fa182404a61), 'Activity launch' (id a8b53b0c4d37), and 'Activity' (id 40e32c8969ac) may refer to overlapping concepts. Consider whether these should use consistent phrasing or are intentionally distinct based on context.

Activity

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

surface.tsx:321

"Loading this activity" uses "this" with nothing nearby naming what it refers to — a reader can't tell what's being acted on.

Loading this activity

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

surface.tsx:489

The footer component mixes conversational instruction ('Finish the practice above, then submit your answers') with clinical state descriptions ('Your answers didn't go through'). Consider warming 'Your answers didn't go through' to match the supportive tone, perhaps 'Your answers didn't submit—check your connection and try again.'

Your answers didn’t go through

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

surface.tsx:490

The footer component mixes conversational instruction ('Finish the practice above, then submit your answers') with clinical state descriptions ('Your answers didn't go through'). Consider warming 'Your answers didn't go through' to match the supportive tone, perhaps 'Your answers didn't submit—check your connection and try again.'

Check your connection and submit again.

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

surface.tsx:497

The footer component mixes conversational instruction ('Finish the practice above, then submit your answers') with clinical state descriptions ('Your answers didn't go through'). Consider warming 'Your answers didn't go through' to match the supportive tone, perhaps 'Your answers didn't submit—check your connection and try again.'

Finish the practice above, then submit your answers.

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

surface.tsx:601

Two strings convey that practice isn't available: 'This practice activity didn't load' (id ba3f8a33602b) and 'Practice isn't available here' (id 07cd12dde13a). These may represent different failure modes (load error vs. missing setup), but the distinction isn't clear from the wording alone. Clarify the difference or consolidate.

Practice isn’t available here

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

surface.tsx:603

The heading 'This check needs practice that isn't set up in this environment' (id ef6c5c30e6bd) is 61 characters and may exceed optimal brevity for modal-like components. Consider tightening to 'Practice isn't available here' or similar for better scannability.

This check needs practice that isn’t set up in this environment.

Practice isn't available here

Approve

Reject

Skip

Style suggestion

surface.tsx:724

Most error messages use contractions ('didn't', 'isn't'), which is good for approachability. However, 'No result was recorded for it' (id a31159b6e9e3) avoids contraction and feels slightly formal. Consider 'No result was recorded' for consistency.

No result was recorded for it.

No result was recorded

Approve

Reject

Skip

Style suggestion

attachment-tray.tsx:86

Buttons should stay within about 20 characters; "Attachment limit reached" is 24.

Attachment limit reached

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

feedback-composer.tsx:287

In CardBody, 'Add detail (optional)' uses clinical form language, which contrasts with the more conversational tone of nearby copy like 'Pin it to the app' and 'Audit page content'. Consider warming this label to match the component's overall voice.

Add detail (optional)

Add more details (optional)

Approve

Reject

Skip

Style suggestion

feedback-composer.tsx:338

The strings 'Add an image' and 'Add a screenshot' both appear to be attachment actions in the same component. Consider whether these are truly distinct capabilities or should use more specific, less ambiguous wording to clarify the difference.

Add a screenshot

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

general-composer.tsx:131

The GeneralComposerDialog mixes conversational copy with clinical form labels. 'File general feedback' is descriptive and user-friendly, but 'Classification' reads as clinical. Consider warming it to 'Feedback type' or 'Category' for consistency.

File general feedback

Feedback type

Approve

Reject

Skip

Style suggestion

general-composer.tsx:172

The GeneralComposerDialog mixes conversational copy with clinical form labels. 'File general feedback' is descriptive and user-friendly, but 'Classification' reads as clinical. Consider warming it to 'Feedback type' or 'Category' for consistency.

Classification

Feedback type

Approve

Reject

Skip

Style suggestion

thread-card.tsx:144

The ThreadCard component uses 'image' and 'images' as content labels but also includes 'View screenshot' as a separate action, making it unclear whether these are three distinct concepts or varying phrasings of the same capability.

image

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

thread-card.tsx:144

The ThreadCard component uses 'image' and 'images' as content labels but also includes 'View screenshot' as a separate action, making it unclear whether these are three distinct concepts or varying phrasings of the same capability.

images

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

thread-card.tsx:157

The ThreadCard component uses 'image' and 'images' as content labels but also includes 'View screenshot' as a separate action, making it unclear whether these are three distinct concepts or varying phrasings of the same capability.

View screenshot

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Content Audit Tool: Closing the Loop Between Content Design and Source Code

My Role

Team

Timeline

Tools

Platform

Product Design Intern/Project Lead

Design

Foundations

9 Weeks

Figma, Claude Code, Miro,

Git Hub

Internal

Tools

Section 01: The Brief & The Discovery

The Brief

Operating within the Design Foundations team, my mandate was to identify a systemic problem and ship a plug-in to solve it proving the value of "agentic design" by using AI to build real software.

The Discovery

I expected to hear complaints about layer naming or detached components. To validate the actual friction points, I engaged the broader design org:

  • 40-Designer Survey: A wide-net assessment focused on daily Figma workflows, repetitive manual tasks, and tool friction.
  • 8 Internal Interviews: Deep-dive conversations with product designers to uncover their most expensive bottlenecks.

The Insight: The Copy Blind Spot

Instead of component issues, the research revealed a massive organizational gap regarding product copy:

  • Designers ≠ Writers: Designers were writing the UI text that ultimately shipped to production, despite not being content experts.
  • Zero Quality Gates: With limited UX-writer capacity and no centralised glossary, brand consistency was checked manually, if at all.
  • The Codebase Disconnect: The person qualified to judge the copy did not have the codebase open. Fixing a single string meant filing a Jira ticket and waiting weeks for an engineer to implement it.

Section 02: Architecture & Key Decisions

The Core Thesis

The foundational rule of this tool is that the person qualified to judge the copy must be able to fix it without leaving their canvas. It reads the UI copy directly from the codebase, judges it against the brand guidelines, and writes approved fixes straight back into the source files they came from.

Architectural Decisions

  • Decision 01: Hybrid Evaluation (Code + LLM): The Scan engine utilises a two-pass hybrid approach. Deterministic rules (character limits, accessibility) are checked instantly, while the LLM handles holistic judgment (tone, redundancy). Both are fed by a centralised Rule registry.
  • Decision 02: The Git-Tracked Cache: To prevent reviewers from answering the same question twice, the tool merges data from the source and a durable scan-log.json. This acts as a decision cache, ensuring the codebase remains the strict single source of truth without duplicating the actual string text.
  • Decision 03: Decoupling Writes from Commits: The initial design committed a file change every time a reviewer clicked "Approve," which silently modified the working tree mid-session. The architecture was restructured so that approvals only trigger a local Write-back operation. Git operations are deferred entirely to a session batch, which opens a Pull Request directly via GitHub (GitHub -> PR opened).

page.tsx:112

Add lecture

Add a lecture

cta.no-leading-article

Tone Check

Approve

Reject

Skip

filePath

/course-hero.tsx

stableId: component

+ ATS anchor

status: approved-local

Hash Key = sha256(filePath + stableStringID + normalised text

STEP 01

Action: Approve

Write file locally. Status flipped to approved-local.

No Git operation triggered.

STEP 02

Action: Batch PR

Resolves session branch. One commit per approved string. PR opened via GitHub identity.

Section 03: The Interface

The Audit Scope

The UI docks as a genuine flex sibling, offering three levels of precision: scanning the current route, auditing the full application, or using a live text picker to check a single string.

Two-Tier Findings

To avoid false precision, findings are strictly tiered rather than scored.

  • Rule Violations: High-confidence deterministic checks flagging mechanical errors like punctuation, character limits, and banned terms.
  • Style Suggestions: Low-confidence LLM judgment calls on tone, voice, and redundancy where human nuance is needed.

Optimistic UI & Outcomes

The interface is built with optimistic UI—buttons disable instantly on click to prevent double-submits, and re-enable if a failure occurs. The final action row dictates the string's lifecycle:

  • Approve: Writes the file locally and moves the fix to the pending PR batch.
  • Reject: Records a dismissal; the string will not surface again in subsequent scans.
  • Skip: Defers the decision to a later session.

Manual Edit

To keep reviewers in context, the UI relies on a fluid inline transition. Crucially, the model's rewrite is only a starting point manual editing is an open affordance available at any time:

  • 01 Flagged: The original text receives a muted strikethrough. If no automated rewrite is available, the "Approve" button remains visible but disabled until a fix is provided.
  • 02 Editing: Clicking the pencil icon at any point opens an active textarea, allowing the reviewer to modify the LLM's suggestion or draft their own from scratch. The primary blue "Save" button takes visual focus.
  • 03 Resolved: The finalised rewrite sits below the original. The "Approve" button takes the primary blue accent, signalling it is ready for the batch.

S

Good evening, Sam

Need help? Tell me a little about yourself so I can make the best recommendations.

Set your goal

In Progress

Completed

Skills

Certificates

Google

Build Wireframes and Low-Fidelity Prototypes

Course

·

16% complete

·

Estimated completion: Oct 20, 2025

Learn more about creating storyboards

Reading (8 minutes)

Resume

September 2026

Mo

Tu

We

Th

Fr

Sa

Su

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

1+ daily goals completed

All daily goals completed

Last 4 weeks

0

Daily goals completed

0

Items completed

0

Minutes learned

Explore

My Learning

Degrees

What do you want to learn?

S

Audit page content

Scan page

Scan app

227 strings scanned · 40 rule violations · 30 style suggestions

Rule violations (40)

Approve all rule violations

Rule violation

page.tsx:112

"Reading (8 minutes)" Uses full spelled-out duration strings in parentheses, violating the microcopy standard for content cards.

Reading (8 minutes)

8 min read

Approve

Reject

Skip

Rule violation

debug-journey-picker.tsx:186

"Good evening, Sam" Uses time-of-day contextual greetings, which violate global product copy standards due to timezone sync discrepancies.

Good evening, Sam

Welcome back, Sam

Approve

Reject

Skip

Rule violation

debug-journey-picker.tsx:186

Two CTAs in the same component convey the same underlying action: 'Starting…' and 'Start journey' both initiate a journey. One should be removed or consolidated.

Start journey

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

error.tsx:18

"Something went wrong." doesn't need its trailing period — single-sentence tooltips and error messages stay unpunctuated.

Something went wrong.

Something went wrong.

Approve

Reject

Skip

Rule violation

plan.tsx:134

The string 'Toggle plan' does not clearly indicate what 'plan' is or what toggling it does. The referent is unclear from the label alone.

Toggle plan

Show plan

Approve

Reject

Skip

Rule violation

reasoning.tsx:156

The strings 'Thought for' and 'seconds' are fragments designed to be concatenated around a number (e.g., 'Thought for 5 seconds'). This concatenation pattern creates localization and accessibility failures because word order differs across languages. Use a complete sentence instead.

Thought for

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

reasoning.tsx:156

The strings 'Thought for' and 'seconds' are fragments designed to be concatenated around a number (e.g., 'Thought for 5 seconds'). This concatenation pattern creates localization and accessibility failures because word order differs across languages. Use a complete sentence instead.

seconds

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

speech-input.tsx:300

The string 'Processing voice input' appears as a label/status message in a component and should not end with a period per Helix guidelines for UI microcopy.

Processing voice input

Processing voice input

Approve

Reject

Skip

Rule violation

web-preview.tsx:152

Accessibility failure: this input has no discrete label — placeholder "Enter URL..." is serving as the label, and it disappears once the user starts typing.

Enter URL...

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

helix-shell.tsx:262

The HelixShell component uses both 'Open wallet' and 'Wallet' to describe the same action. One should be removed or consolidated.

Open wallet

Open wallet

Approve

Reject

Skip

Rule violation

helix-shell.tsx:268

The HelixShell component uses both 'Open wallet' and 'Wallet' to describe the same action. One should be removed or consolidated.

Wallet

Open wallet

Approve

Reject

Skip

Rule violation

conversation-thread-view.tsx:984

Both ConversationThreadView and MicrolessonView use 'Helix is thinking…' identically. This suggests a shared constant that should be defined once.

Helix is thinking…

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

conversation-thread-view.tsx:1068

Accessibility failure: this input has no discrete label — placeholder "Ask Helix…" is serving as the label, and it disappears once the user starts typing.

Ask Helix…

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

feedback-nudge.tsx:35

The DismissButton component uses both 'Dismiss feedback nudge' and 'Dismiss' to describe the same action. One should be removed or consolidated.

Dismiss feedback nudge

Dismiss

Approve

Reject

Skip

Rule violation

feedback-nudge.tsx:40

The DismissButton component uses both 'Dismiss feedback nudge' and 'Dismiss' to describe the same action. One should be removed or consolidated.

Dismiss

Dismiss

Approve

Reject

Skip

Rule violation

microlesson-view.tsx:111

Both ConversationThreadView and MicrolessonView use 'Helix is thinking…' identically. This suggests a shared constant that should be defined once.

Helix is thinking…

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

microlesson-view.tsx:115

The error message 'This lesson hit a snag' uses an exclamation mark, which can read as flippant in a failure state. Per guidelines, errors should avoid exclamation marks.

This lesson hit a snag

This lesson hit a snag.

Approve

Reject

Skip

Rule violation

pathway-handoff-transition.tsx:41

Accessibility failure: this input has no discrete label — placeholder "Message Helix…" is serving as the label, and it disappears once the user starts typing.

Message Helix…

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

spine-referral-card.tsx:62

The ReferralLoadingCard component uses both 'Preparing your activity' and 'Preparing your activity…' to describe the same state. One should be removed or consolidated.

Preparing your activity

Preparing your activity…

Approve

Reject

Skip

Rule violation

spine-referral-card.tsx:63

The ReferralLoadingCard component uses both 'Preparing your activity' and 'Preparing your activity…' to describe the same state. One should be removed or consolidated.

Preparing your activity…

Preparing your activity…

Approve

Reject

Skip

Rule violation

wallet-dashboard.tsx:93

The label 'Total skills' appears in both WalletDashboard (id 2161926a0510) and WalletSurface (id 9b87b4fe967e). These likely refer to the same metric and should be consolidated to a single source string.

Total skills

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

wallet-dashboard.tsx:99

The label 'Average confidence' appears in both WalletDashboard (id 54d7ef7d5061) and WalletSurface (id bfc0d90b0965). These likely refer to the same metric and should be consolidated to a single source string.

Average confidence

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

wallet-surface.tsx:35

The label 'Total skills' appears in both WalletDashboard (id 2161926a0510) and WalletSurface (id 9b87b4fe967e). These likely refer to the same metric and should be consolidated to a single source string.

Total skills

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

wallet-surface.tsx:41

The label 'Average confidence' appears in both WalletDashboard (id 54d7ef7d5061) and WalletSurface (id bfc0d90b0965). These likely refer to the same metric and should be consolidated to a single source string.

Average confidence

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

content-registry.tsx:289

The string 'This is an interactive activity — it launches from its activity card in the conversation, not here.' uses pronouns 'it' and 'its' whose referent is unclear without seeing the UI context. What activity does 'it' refer to, and where specifically is 'the conversation'?

This is an interactive activity — it launches from its activity card in the conversation, not here.

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

concluded-interaction-review.tsx:43

Error copy should avoid exclamation marks. The phrase 'This activity didn't load' appears across multiple error states and should maintain consistent, neutral punctuation. While the current strings lack exclamation marks, ensure they remain absent if these error messages are presented as alerts or toasts.

This activity didn’t load

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

interactions-launch-surface.tsx:67

Error copy should avoid exclamation marks. The phrase 'This activity didn't load' appears across multiple error states and should maintain consistent, neutral punctuation. While the current strings lack exclamation marks, ensure they remain absent if these error messages are presented as alerts or toasts.

This activity didn’t load

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

surface.tsx:327

Error copy should avoid exclamation marks. The phrase 'This activity didn't load' appears across multiple error states and should maintain consistent, neutral punctuation. While the current strings lack exclamation marks, ensure they remain absent if these error messages are presented as alerts or toasts.

This activity didn’t load

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

attachment-tray.tsx:86

Buttons read as a more direct command without an article; "Add an image" uses one, the same shape the guideline's own example drops ("Add lecture", not "Add a lecture").

Add an image

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

comment-popover.tsx:425

Accessibility failure: this input has no discrete label — placeholder "Reply…" is serving as the label, and it disappears once the user starts typing.

Reply…

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

content-audit-finding-row.tsx:160

The strings 'Approved and applied.' and 'Dismissed.' end with periods, but these are short status messages in a component where periods are unnecessary clutter.

Approved and applied.

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

content-audit-finding-row.tsx:161

The strings 'Approved and applied.' and 'Dismissed.' end with periods, but these are short status messages in a component where periods are unnecessary clutter.

Dismissed.

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

feedback-composer.tsx:280

Accessibility failure: this input has no discrete label — placeholder "Share what's on your mind… (or drop an image)" is serving as the label, and it disappears once the user starts typing.

Share what's on your mind… (or drop an image)

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

feedback-composer.tsx:328

"Pin it to the app" uses "it" with nothing nearby naming what it refers to — a reader can't tell what's being acted on.

Pin it to the app

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

feedback-dock.tsx:114

The strings 'Your feedback' appears twice in this batch with the same id concept but used as a CTA in two different components. Review whether both instances are necessary or if one should be removed.

Your feedback

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

feedback-drawer.tsx:344

The strings 'reply' and 'replies' use lowercase, inconsistent with other CTA buttons in the interface that use sentence case. CTAs should use sentence case: 'Reply' and 'Replies'.

reply

Reply

Approve

Reject

Skip

Rule violation

feedback-drawer.tsx:344

The string 'replies' uses lowercase, inconsistent with other CTA buttons in the interface that use sentence case. CTAs should use sentence case: 'Replies'.

replies

Replies

Approve

Reject

Skip

Rule violation

feedback-thread-view.tsx:49

The strings 'Your feedback' appears twice in this batch with the same id concept but used as a CTA in two different components. Review whether both instances are necessary or if one should be removed.

Your feedback

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

feedback-thread-view.tsx:81

Accessibility failure: this input has no discrete label — placeholder "Reply…" is serving as the label, and it disappears once the user starts typing.

Reply…

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

general-composer.tsx:156

Accessibility failure: this input has no discrete label — placeholder "What did you want to flag? (paste or drop an image)" is serving as the label, and it disappears once the user starts typing.

What did you want to flag? (paste or drop an image)

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestions (30)

Dismiss all style suggestions

Style suggestion

onboarding-overlay.tsx:161

The OnboardingOverlay component mixes conversational second-person questions ('What do you want to learn today?' 'What do you want to get better at?') with clinical label-style copy ('Your name', 'A skill or goal'). Consider warming the placeholder text to match the conversational tone of the questions.

Welcome to Helix — what should we call you?

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

onboarding-overlay.tsx:167

The OnboardingOverlay component mixes conversational second-person questions ('What do you want to learn today?' 'What do you want to get better at?') with clinical label-style copy ('Your name', 'A skill or goal'). Consider warming the placeholder text to match the conversational tone of the questions.

Your name

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

onboarding-overlay.tsx:174

The OnboardingOverlay component mixes conversational second-person questions ('What do you want to learn today?' 'What do you want to get better at?') with clinical label-style copy ('Your name', 'A skill or goal'). Consider warming the placeholder text to match the conversational tone of the questions.

What do you want to get better at?

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

onboarding-overlay.tsx:180

The OnboardingOverlay component mixes conversational second-person questions ('What do you want to learn today?' 'What do you want to get better at?') with clinical label-style copy ('Your name', 'A skill or goal'). Consider warming the placeholder text to match the conversational tone of the questions.

A skill or goal

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

not-found.tsx:28

Consider a fresher take on 'Helix routed you off the path.' This phrasing feels somewhat clichéd; a more direct, less metaphorical explanation may feel clearer.

Helix routed you off the path. Head back to where the flow lives.

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

chat-prompt-bar.tsx:183

The strings 'Add attachment' and 'Upload files' both appear to reference the same underlying capability of attaching content to a message. Consider clarifying whether these are distinct actions (e.g., one for existing files, one for capturing new ones) or consolidating them.

Add attachment

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

prompt-input.tsx:842

The strings 'Add attachment' and 'Upload files' both appear to reference the same underlying capability of attaching content to a message. Consider clarifying whether these are distinct actions (e.g., one for existing files, one for capturing new ones) or consolidating them.

Upload files

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

helix-shell.tsx:969

Consider whether 'Helix is thinking…' and 'Loading saved pathways' represent the same state. 'Helix is thinking…' is conversational and personified, while 'Loading saved pathways' is more neutral. If both describe a loading state, align their tone.

Loading saved pathways

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

microlesson-view.tsx:117

The error heading 'This lesson hit a snag' (b584f4539a7b) and body 'The lesson stream failed.' use different punctuation treatment. Consider whether both should end with periods or neither.

The lesson stream failed.

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

wallet-empty-state.tsx:10

Consider whether 'trust-tiered' in the empty-state description is clear to all users. This technical term may not translate well or be immediately understood by learners unfamiliar with credential terminology.

Self-claim a skill or complete a learning path and it shows up here, evidenced and trust-tiered.

Self-claim a skill or complete a learning path and it shows up here, verified and ranked by trustworthiness.

Approve

Reject

Skip

Style suggestion

wallet-view.tsx:40

The ellipsis in 'Loading your wallet…' is acceptable but consider whether a spinner or animated treatment would communicate the loading state more clearly, per guidelines preferring graphical treatments over ellipses.

Loading your wallet…

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

launch-panels.tsx:207

The component labels mix specific and generic terms: 'Practice activity' (id 2fa182404a61), 'Activity launch' (id a8b53b0c4d37), and 'Activity' (id 40e32c8969ac) may refer to overlapping concepts. Consider whether these should use consistent phrasing or are intentionally distinct based on context.

Activity launch

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

practice-launch.tsx:61

Two strings convey that practice isn't available: 'This practice activity didn't load' (id ba3f8a33602b) and 'Practice isn't available here' (id 07cd12dde13a). These may represent different failure modes (load error vs. missing setup), but the distinction isn't clear from the wording alone. Clarify the difference or consolidate.

This practice activity didn’t load

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

practice-launch.tsx:112

The component labels mix specific and generic terms: 'Practice activity' (id 2fa182404a61), 'Activity launch' (id a8b53b0c4d37), and 'Activity' (id 40e32c8969ac) may refer to overlapping concepts. Consider whether these should use consistent phrasing or are intentionally distinct based on context.

Practice activity

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

surface.tsx:234

The component labels mix specific and generic terms: 'Practice activity' (id 2fa182404a61), 'Activity launch' (id a8b53b0c4d37), and 'Activity' (id 40e32c8969ac) may refer to overlapping concepts. Consider whether these should use consistent phrasing or are intentionally distinct based on context.

Activity

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

surface.tsx:321

"Loading this activity" uses "this" with nothing nearby naming what it refers to — a reader can't tell what's being acted on.

Loading this activity

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

surface.tsx:489

The footer component mixes conversational instruction ('Finish the practice above, then submit your answers') with clinical state descriptions ('Your answers didn't go through'). Consider warming 'Your answers didn't go through' to match the supportive tone, perhaps 'Your answers didn't submit—check your connection and try again.'

Your answers didn’t go through

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

surface.tsx:490

The footer component mixes conversational instruction ('Finish the practice above, then submit your answers') with clinical state descriptions ('Your answers didn't go through'). Consider warming 'Your answers didn't go through' to match the supportive tone, perhaps 'Your answers didn't submit—check your connection and try again.'

Check your connection and submit again.

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

surface.tsx:497

The footer component mixes conversational instruction ('Finish the practice above, then submit your answers') with clinical state descriptions ('Your answers didn't go through'). Consider warming 'Your answers didn't go through' to match the supportive tone, perhaps 'Your answers didn't submit—check your connection and try again.'

Finish the practice above, then submit your answers.

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

surface.tsx:601

Two strings convey that practice isn't available: 'This practice activity didn't load' (id ba3f8a33602b) and 'Practice isn't available here' (id 07cd12dde13a). These may represent different failure modes (load error vs. missing setup), but the distinction isn't clear from the wording alone. Clarify the difference or consolidate.

Practice isn’t available here

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

surface.tsx:603

The heading 'This check needs practice that isn't set up in this environment' (id ef6c5c30e6bd) is 61 characters and may exceed optimal brevity for modal-like components. Consider tightening to 'Practice isn't available here' or similar for better scannability.

This check needs practice that isn’t set up in this environment.

Practice isn't available here

Approve

Reject

Skip

Style suggestion

surface.tsx:724

Most error messages use contractions ('didn't', 'isn't'), which is good for approachability. However, 'No result was recorded for it' (id a31159b6e9e3) avoids contraction and feels slightly formal. Consider 'No result was recorded' for consistency.

No result was recorded for it.

No result was recorded

Approve

Reject

Skip

Style suggestion

attachment-tray.tsx:86

Buttons should stay within about 20 characters; "Attachment limit reached" is 24.

Attachment limit reached

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

feedback-composer.tsx:287

In CardBody, 'Add detail (optional)' uses clinical form language, which contrasts with the more conversational tone of nearby copy like 'Pin it to the app' and 'Audit page content'. Consider warming this label to match the component's overall voice.

Add detail (optional)

Add more details (optional)

Approve

Reject

Skip

Style suggestion

feedback-composer.tsx:338

The strings 'Add an image' and 'Add a screenshot' both appear to be attachment actions in the same component. Consider whether these are truly distinct capabilities or should use more specific, less ambiguous wording to clarify the difference.

Add a screenshot

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

general-composer.tsx:131

The GeneralComposerDialog mixes conversational copy with clinical form labels. 'File general feedback' is descriptive and user-friendly, but 'Classification' reads as clinical. Consider warming it to 'Feedback type' or 'Category' for consistency.

File general feedback

Feedback type

Approve

Reject

Skip

Style suggestion

general-composer.tsx:172

The GeneralComposerDialog mixes conversational copy with clinical form labels. 'File general feedback' is descriptive and user-friendly, but 'Classification' reads as clinical. Consider warming it to 'Feedback type' or 'Category' for consistency.

Classification

Feedback type

Approve

Reject

Skip

Style suggestion

thread-card.tsx:144

The ThreadCard component uses 'image' and 'images' as content labels but also includes 'View screenshot' as a separate action, making it unclear whether these are three distinct concepts or varying phrasings of the same capability.

image

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

thread-card.tsx:144

The ThreadCard component uses 'image' and 'images' as content labels but also includes 'View screenshot' as a separate action, making it unclear whether these are three distinct concepts or varying phrasings of the same capability.

images

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

thread-card.tsx:157

The ThreadCard component uses 'image' and 'images' as content labels but also includes 'View screenshot' as a separate action, making it unclear whether these are three distinct concepts or varying phrasings of the same capability.

View screenshot

No automatic rewrite — fix by hand.

Approve

Reject

Skip

200 strings scanned · 9 rule violations · 4 style suggestions

Style suggestions (4)

Dismiss all style suggestions

Style suggestion

error.tsx:18

"Something went wrong." doesn't need its trailing period — single-sentence tooltips and error messages stay unpunctuated.

Something went wrong.

Something went wrong

Approve

Reject

Skip

Style suggestion

checkpoint-host.tsx:223

"Something went wrong fetching this checkpoint." doesn't need its trailing period — single-sentence tooltips and error messages stay unpunctuated.

Something went wrong fetching this checkpoint.

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

attachment-tray.tsx:86

Buttons should stay within about 20 characters; "Attachment limit reached" is 24.

Attachment limit reached

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

feedback-composer.tsx:328

"Pin it to the app" uses "it" with nothing nearby naming what it refers to — a reader can't tell what's being acted on.

Pin it to the app

No automatic rewrite — fix by hand.

Approve

Reject

Skip

S

Welcome back, Sam

Need help? Tell me a little about yourself so I can make the best recommendations.

Set your goal

In Progress

Completed

Skills

Certificates

Google

Build Wireframes and Low-Fidelity Prototypes

Course

·

16% complete

·

Estimated completion: Oct 20, 2025

Learn more about creating storyboards

Reading (8 minutes)

Resume

September 2026

Mo

Tu

We

Th

Fr

Sa

Su

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

1+ daily goals completed

All daily goals completed

Last 4 weeks

0

Daily goals completed

0

Items completed

0

Minutes learned

Explore

My Learning

Degrees

What do you want to learn?

S

Audit page content

Scan page

Scan app

227 strings scanned · 40 rule violations · 30 style suggestions

Rule violations (40)

Approve all rule violations

Rule violation

page.tsx:112

"Reading (8 minutes)" Uses full spelled-out duration strings in parentheses, violating the microcopy standard for content cards.

Reading (8 minutes)

8 min read

Approve

Reject

Skip

Rule violation

debug-journey-picker.tsx:186

"Good evening, Sam" Uses time-of-day contextual greetings, which violate global product copy standards due to timezone sync discrepancies.

Welcome back, Sam|

Cancel

Save

Approve

Reject

Skip

Rule violation

debug-journey-picker.tsx:186

Two CTAs in the same component convey the same underlying action: 'Starting…' and 'Start journey' both initiate a journey. One should be removed or consolidated.

Start journey

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

error.tsx:18

"Something went wrong." doesn't need its trailing period — single-sentence tooltips and error messages stay unpunctuated.

Something went wrong.

Something went wrong.

Approve

Reject

Skip

Rule violation

plan.tsx:134

The string 'Toggle plan' does not clearly indicate what 'plan' is or what toggling it does. The referent is unclear from the label alone.

Toggle plan

Show plan

Approve

Reject

Skip

Rule violation

reasoning.tsx:156

The strings 'Thought for' and 'seconds' are fragments designed to be concatenated around a number (e.g., 'Thought for 5 seconds'). This concatenation pattern creates localization and accessibility failures because word order differs across languages. Use a complete sentence instead.

Thought for

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

reasoning.tsx:156

The strings 'Thought for' and 'seconds' are fragments designed to be concatenated around a number (e.g., 'Thought for 5 seconds'). This concatenation pattern creates localization and accessibility failures because word order differs across languages. Use a complete sentence instead.

seconds

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

speech-input.tsx:300

The string 'Processing voice input' appears as a label/status message in a component and should not end with a period per Helix guidelines for UI microcopy.

Processing voice input

Processing voice input

Approve

Reject

Skip

Rule violation

web-preview.tsx:152

Accessibility failure: this input has no discrete label — placeholder "Enter URL..." is serving as the label, and it disappears once the user starts typing.

Enter URL...

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

helix-shell.tsx:262

The HelixShell component uses both 'Open wallet' and 'Wallet' to describe the same action. One should be removed or consolidated.

Open wallet

Open wallet

Approve

Reject

Skip

Rule violation

helix-shell.tsx:268

The HelixShell component uses both 'Open wallet' and 'Wallet' to describe the same action. One should be removed or consolidated.

Wallet

Open wallet

Approve

Reject

Skip

Rule violation

conversation-thread-view.tsx:984

Both ConversationThreadView and MicrolessonView use 'Helix is thinking…' identically. This suggests a shared constant that should be defined once.

Helix is thinking…

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

conversation-thread-view.tsx:1068

Accessibility failure: this input has no discrete label — placeholder "Ask Helix…" is serving as the label, and it disappears once the user starts typing.

Ask Helix…

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

feedback-nudge.tsx:35

The DismissButton component uses both 'Dismiss feedback nudge' and 'Dismiss' to describe the same action. One should be removed or consolidated.

Dismiss feedback nudge

Dismiss

Approve

Reject

Skip

Rule violation

feedback-nudge.tsx:40

The DismissButton component uses both 'Dismiss feedback nudge' and 'Dismiss' to describe the same action. One should be removed or consolidated.

Dismiss

Dismiss

Approve

Reject

Skip

Rule violation

microlesson-view.tsx:111

Both ConversationThreadView and MicrolessonView use 'Helix is thinking…' identically. This suggests a shared constant that should be defined once.

Helix is thinking…

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

microlesson-view.tsx:115

The error message 'This lesson hit a snag' uses an exclamation mark, which can read as flippant in a failure state. Per guidelines, errors should avoid exclamation marks.

This lesson hit a snag

This lesson hit a snag.

Approve

Reject

Skip

Rule violation

pathway-handoff-transition.tsx:41

Accessibility failure: this input has no discrete label — placeholder "Message Helix…" is serving as the label, and it disappears once the user starts typing.

Message Helix…

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

spine-referral-card.tsx:62

The ReferralLoadingCard component uses both 'Preparing your activity' and 'Preparing your activity…' to describe the same state. One should be removed or consolidated.

Preparing your activity

Preparing your activity…

Approve

Reject

Skip

Rule violation

spine-referral-card.tsx:63

The ReferralLoadingCard component uses both 'Preparing your activity' and 'Preparing your activity…' to describe the same state. One should be removed or consolidated.

Preparing your activity…

Preparing your activity…

Approve

Reject

Skip

Rule violation

wallet-dashboard.tsx:93

The label 'Total skills' appears in both WalletDashboard (id 2161926a0510) and WalletSurface (id 9b87b4fe967e). These likely refer to the same metric and should be consolidated to a single source string.

Total skills

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

wallet-dashboard.tsx:99

The label 'Average confidence' appears in both WalletDashboard (id 54d7ef7d5061) and WalletSurface (id bfc0d90b0965). These likely refer to the same metric and should be consolidated to a single source string.

Average confidence

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

wallet-surface.tsx:35

The label 'Total skills' appears in both WalletDashboard (id 2161926a0510) and WalletSurface (id 9b87b4fe967e). These likely refer to the same metric and should be consolidated to a single source string.

Total skills

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

wallet-surface.tsx:41

The label 'Average confidence' appears in both WalletDashboard (id 54d7ef7d5061) and WalletSurface (id bfc0d90b0965). These likely refer to the same metric and should be consolidated to a single source string.

Average confidence

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

content-registry.tsx:289

The string 'This is an interactive activity — it launches from its activity card in the conversation, not here.' uses pronouns 'it' and 'its' whose referent is unclear without seeing the UI context. What activity does 'it' refer to, and where specifically is 'the conversation'?

This is an interactive activity — it launches from its activity card in the conversation, not here.

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

concluded-interaction-review.tsx:43

Error copy should avoid exclamation marks. The phrase 'This activity didn't load' appears across multiple error states and should maintain consistent, neutral punctuation. While the current strings lack exclamation marks, ensure they remain absent if these error messages are presented as alerts or toasts.

This activity didn’t load

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

interactions-launch-surface.tsx:67

Error copy should avoid exclamation marks. The phrase 'This activity didn't load' appears across multiple error states and should maintain consistent, neutral punctuation. While the current strings lack exclamation marks, ensure they remain absent if these error messages are presented as alerts or toasts.

This activity didn’t load

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

surface.tsx:327

Error copy should avoid exclamation marks. The phrase 'This activity didn't load' appears across multiple error states and should maintain consistent, neutral punctuation. While the current strings lack exclamation marks, ensure they remain absent if these error messages are presented as alerts or toasts.

This activity didn’t load

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

attachment-tray.tsx:86

Buttons read as a more direct command without an article; "Add an image" uses one, the same shape the guideline's own example drops ("Add lecture", not "Add a lecture").

Add an image

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

comment-popover.tsx:425

Accessibility failure: this input has no discrete label — placeholder "Reply…" is serving as the label, and it disappears once the user starts typing.

Reply…

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

content-audit-finding-row.tsx:160

The strings 'Approved and applied.' and 'Dismissed.' end with periods, but these are short status messages in a component where periods are unnecessary clutter.

Approved and applied.

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

content-audit-finding-row.tsx:161

The strings 'Approved and applied.' and 'Dismissed.' end with periods, but these are short status messages in a component where periods are unnecessary clutter.

Dismissed.

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

feedback-composer.tsx:280

Accessibility failure: this input has no discrete label — placeholder "Share what's on your mind… (or drop an image)" is serving as the label, and it disappears once the user starts typing.

Share what's on your mind… (or drop an image)

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

feedback-composer.tsx:328

"Pin it to the app" uses "it" with nothing nearby naming what it refers to — a reader can't tell what's being acted on.

Pin it to the app

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

feedback-dock.tsx:114

The strings 'Your feedback' appears twice in this batch with the same id concept but used as a CTA in two different components. Review whether both instances are necessary or if one should be removed.

Your feedback

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

feedback-drawer.tsx:344

The strings 'reply' and 'replies' use lowercase, inconsistent with other CTA buttons in the interface that use sentence case. CTAs should use sentence case: 'Reply' and 'Replies'.

reply

Reply

Approve

Reject

Skip

Rule violation

feedback-drawer.tsx:344

The string 'replies' uses lowercase, inconsistent with other CTA buttons in the interface that use sentence case. CTAs should use sentence case: 'Replies'.

replies

Replies

Approve

Reject

Skip

Rule violation

feedback-thread-view.tsx:49

The strings 'Your feedback' appears twice in this batch with the same id concept but used as a CTA in two different components. Review whether both instances are necessary or if one should be removed.

Your feedback

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

feedback-thread-view.tsx:81

Accessibility failure: this input has no discrete label — placeholder "Reply…" is serving as the label, and it disappears once the user starts typing.

Reply…

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

general-composer.tsx:156

Accessibility failure: this input has no discrete label — placeholder "What did you want to flag? (paste or drop an image)" is serving as the label, and it disappears once the user starts typing.

What did you want to flag? (paste or drop an image)

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestions (30)

Dismiss all style suggestions

Style suggestion

onboarding-overlay.tsx:161

The OnboardingOverlay component mixes conversational second-person questions ('What do you want to learn today?' 'What do you want to get better at?') with clinical label-style copy ('Your name', 'A skill or goal'). Consider warming the placeholder text to match the conversational tone of the questions.

Welcome to Helix — what should we call you?

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

onboarding-overlay.tsx:167

The OnboardingOverlay component mixes conversational second-person questions ('What do you want to learn today?' 'What do you want to get better at?') with clinical label-style copy ('Your name', 'A skill or goal'). Consider warming the placeholder text to match the conversational tone of the questions.

Your name

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

onboarding-overlay.tsx:174

The OnboardingOverlay component mixes conversational second-person questions ('What do you want to learn today?' 'What do you want to get better at?') with clinical label-style copy ('Your name', 'A skill or goal'). Consider warming the placeholder text to match the conversational tone of the questions.

What do you want to get better at?

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

onboarding-overlay.tsx:180

The OnboardingOverlay component mixes conversational second-person questions ('What do you want to learn today?' 'What do you want to get better at?') with clinical label-style copy ('Your name', 'A skill or goal'). Consider warming the placeholder text to match the conversational tone of the questions.

A skill or goal

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

not-found.tsx:28

Consider a fresher take on 'Helix routed you off the path.' This phrasing feels somewhat clichéd; a more direct, less metaphorical explanation may feel clearer.

Helix routed you off the path. Head back to where the flow lives.

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

chat-prompt-bar.tsx:183

The strings 'Add attachment' and 'Upload files' both appear to reference the same underlying capability of attaching content to a message. Consider clarifying whether these are distinct actions (e.g., one for existing files, one for capturing new ones) or consolidating them.

Add attachment

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

prompt-input.tsx:842

The strings 'Add attachment' and 'Upload files' both appear to reference the same underlying capability of attaching content to a message. Consider clarifying whether these are distinct actions (e.g., one for existing files, one for capturing new ones) or consolidating them.

Upload files

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

helix-shell.tsx:969

Consider whether 'Helix is thinking…' and 'Loading saved pathways' represent the same state. 'Helix is thinking…' is conversational and personified, while 'Loading saved pathways' is more neutral. If both describe a loading state, align their tone.

Loading saved pathways

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

microlesson-view.tsx:117

The error heading 'This lesson hit a snag' (b584f4539a7b) and body 'The lesson stream failed.' use different punctuation treatment. Consider whether both should end with periods or neither.

The lesson stream failed.

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

wallet-empty-state.tsx:10

Consider whether 'trust-tiered' in the empty-state description is clear to all users. This technical term may not translate well or be immediately understood by learners unfamiliar with credential terminology.

Self-claim a skill or complete a learning path and it shows up here, evidenced and trust-tiered.

Self-claim a skill or complete a learning path and it shows up here, verified and ranked by trustworthiness.

Approve

Reject

Skip

Style suggestion

wallet-view.tsx:40

The ellipsis in 'Loading your wallet…' is acceptable but consider whether a spinner or animated treatment would communicate the loading state more clearly, per guidelines preferring graphical treatments over ellipses.

Loading your wallet…

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

launch-panels.tsx:207

The component labels mix specific and generic terms: 'Practice activity' (id 2fa182404a61), 'Activity launch' (id a8b53b0c4d37), and 'Activity' (id 40e32c8969ac) may refer to overlapping concepts. Consider whether these should use consistent phrasing or are intentionally distinct based on context.

Activity launch

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

practice-launch.tsx:61

Two strings convey that practice isn't available: 'This practice activity didn't load' (id ba3f8a33602b) and 'Practice isn't available here' (id 07cd12dde13a). These may represent different failure modes (load error vs. missing setup), but the distinction isn't clear from the wording alone. Clarify the difference or consolidate.

This practice activity didn’t load

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

practice-launch.tsx:112

The component labels mix specific and generic terms: 'Practice activity' (id 2fa182404a61), 'Activity launch' (id a8b53b0c4d37), and 'Activity' (id 40e32c8969ac) may refer to overlapping concepts. Consider whether these should use consistent phrasing or are intentionally distinct based on context.

Practice activity

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

surface.tsx:234

The component labels mix specific and generic terms: 'Practice activity' (id 2fa182404a61), 'Activity launch' (id a8b53b0c4d37), and 'Activity' (id 40e32c8969ac) may refer to overlapping concepts. Consider whether these should use consistent phrasing or are intentionally distinct based on context.

Activity

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

surface.tsx:321

"Loading this activity" uses "this" with nothing nearby naming what it refers to — a reader can't tell what's being acted on.

Loading this activity

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

surface.tsx:489

The footer component mixes conversational instruction ('Finish the practice above, then submit your answers') with clinical state descriptions ('Your answers didn't go through'). Consider warming 'Your answers didn't go through' to match the supportive tone, perhaps 'Your answers didn't submit—check your connection and try again.'

Your answers didn’t go through

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

surface.tsx:490

The footer component mixes conversational instruction ('Finish the practice above, then submit your answers') with clinical state descriptions ('Your answers didn't go through'). Consider warming 'Your answers didn't go through' to match the supportive tone, perhaps 'Your answers didn't submit—check your connection and try again.'

Check your connection and submit again.

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

surface.tsx:497

The footer component mixes conversational instruction ('Finish the practice above, then submit your answers') with clinical state descriptions ('Your answers didn't go through'). Consider warming 'Your answers didn't go through' to match the supportive tone, perhaps 'Your answers didn't submit—check your connection and try again.'

Finish the practice above, then submit your answers.

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

surface.tsx:601

Two strings convey that practice isn't available: 'This practice activity didn't load' (id ba3f8a33602b) and 'Practice isn't available here' (id 07cd12dde13a). These may represent different failure modes (load error vs. missing setup), but the distinction isn't clear from the wording alone. Clarify the difference or consolidate.

Practice isn’t available here

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

surface.tsx:603

The heading 'This check needs practice that isn't set up in this environment' (id ef6c5c30e6bd) is 61 characters and may exceed optimal brevity for modal-like components. Consider tightening to 'Practice isn't available here' or similar for better scannability.

This check needs practice that isn’t set up in this environment.

Practice isn't available here

Approve

Reject

Skip

Style suggestion

surface.tsx:724

Most error messages use contractions ('didn't', 'isn't'), which is good for approachability. However, 'No result was recorded for it' (id a31159b6e9e3) avoids contraction and feels slightly formal. Consider 'No result was recorded' for consistency.

No result was recorded for it.

No result was recorded

Approve

Reject

Skip

Style suggestion

attachment-tray.tsx:86

Buttons should stay within about 20 characters; "Attachment limit reached" is 24.

Attachment limit reached

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

feedback-composer.tsx:287

In CardBody, 'Add detail (optional)' uses clinical form language, which contrasts with the more conversational tone of nearby copy like 'Pin it to the app' and 'Audit page content'. Consider warming this label to match the component's overall voice.

Add detail (optional)

Add more details (optional)

Approve

Reject

Skip

Style suggestion

feedback-composer.tsx:338

The strings 'Add an image' and 'Add a screenshot' both appear to be attachment actions in the same component. Consider whether these are truly distinct capabilities or should use more specific, less ambiguous wording to clarify the difference.

Add a screenshot

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

general-composer.tsx:131

The GeneralComposerDialog mixes conversational copy with clinical form labels. 'File general feedback' is descriptive and user-friendly, but 'Classification' reads as clinical. Consider warming it to 'Feedback type' or 'Category' for consistency.

File general feedback

Feedback type

Approve

Reject

Skip

Style suggestion

general-composer.tsx:172

The GeneralComposerDialog mixes conversational copy with clinical form labels. 'File general feedback' is descriptive and user-friendly, but 'Classification' reads as clinical. Consider warming it to 'Feedback type' or 'Category' for consistency.

Classification

Feedback type

Approve

Reject

Skip

Style suggestion

thread-card.tsx:144

The ThreadCard component uses 'image' and 'images' as content labels but also includes 'View screenshot' as a separate action, making it unclear whether these are three distinct concepts or varying phrasings of the same capability.

image

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

thread-card.tsx:144

The ThreadCard component uses 'image' and 'images' as content labels but also includes 'View screenshot' as a separate action, making it unclear whether these are three distinct concepts or varying phrasings of the same capability.

images

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

thread-card.tsx:157

The ThreadCard component uses 'image' and 'images' as content labels but also includes 'View screenshot' as a separate action, making it unclear whether these are three distinct concepts or varying phrasings of the same capability.

View screenshot

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Section 04: Outcomes & Lessons

The Impact

By treating UI copy as a governed, versioned instance of a content system, the tool collapses the traditional multi-week Jira ticket loop into a single, on-canvas action. Reviewers edit copy in context, click approve, and the fix lands directly in a source file on a branch, entirely bypassing the need for a developer to open an editor.

The First Live Audit & Partnering with AI

Building this engine directly via Claude Code completely shifted my perspective on what I could ship as a product designer. During the first official end-to-end live run, the tool processed 225 strings, successfully flagging 44 rule violations and 27 style suggestions in roughly 24 seconds—proving my hybrid LLM pass was genuinely functioning.

Getting to that outcome taught me that agentic design is a true partnership, one that still relies heavily on my own architectural judgment. While my mocked tests passed perfectly, running real-repository integration tests surfaced 17 critical Git-layer bugs. Diagnosing those failures is what drove my most important architectural pivot: abandoning the initial "commit-on-approve" design (which corrupted the working tree) in favor of the deferred "Batch PR" model.

Strict Safety Gates

Because I was building a plugin that writes directly to a developer's local source files, ensuring it could not corrupt a production environment fell entirely on my shoulders.

I engineered a strict three-gate safety model:

  • Scan Gate: Read-only scanning is enabled on PR preview environments so reviewers can audit real findings.
  • Write Gate: Write-backs and Git operations are hard-locked to local development only, where the developer has full control to undo changes.
  • LLM Gate: An independent kill switch for the model pass, ensuring deterministic rules continue to run even if the AI endpoint fails.

S

Good evening, Sam

Need help? Tell me a little about yourself so I can make the best recommendations.

Set your goal

In Progress

Completed

Skills

Certificates

Google

Build Wireframes and Low-Fidelity Prototypes

Course

·

16% complete

·

Estimated completion: Oct 20, 2025

Learn more about creating storyboards

Reading (8 minutes)

Resume

September 2026

Mo

Tu

We

Th

Fr

Sa

Su

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

1+ daily goals completed

All daily goals completed

Last 4 weeks

0

Daily goals completed

0

Items completed

0

Minutes learned

Explore

My Learning

Degrees

What do you want to learn?

S

Audit page content

Scan page

Scan app

227 strings scanned · 40 rule violations · 30 style suggestions

Rule violations (40)

Approve all rule violations

Rule violation

page.tsx:112

"Reading (8 minutes)" Uses full spelled-out duration strings in parentheses, violating the microcopy standard for content cards.

Reading (8 minutes)

8 min read

Approve

Reject

Skip

Rule violation

debug-journey-picker.tsx:186

"Good evening, Sam" Uses time-of-day contextual greetings, which violate global product copy standards due to timezone sync discrepancies.

Good evening, Sam

Welcome back, Sam

Approve

Reject

Skip

Rule violation

debug-journey-picker.tsx:186

Two CTAs in the same component convey the same underlying action: 'Starting…' and 'Start journey' both initiate a journey. One should be removed or consolidated.

Start journey

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

error.tsx:18

"Something went wrong." doesn't need its trailing period — single-sentence tooltips and error messages stay unpunctuated.

Something went wrong.

Something went wrong.

Approve

Reject

Skip

Rule violation

plan.tsx:134

The string 'Toggle plan' does not clearly indicate what 'plan' is or what toggling it does. The referent is unclear from the label alone.

Toggle plan

Show plan

Approve

Reject

Skip

Rule violation

reasoning.tsx:156

The strings 'Thought for' and 'seconds' are fragments designed to be concatenated around a number (e.g., 'Thought for 5 seconds'). This concatenation pattern creates localization and accessibility failures because word order differs across languages. Use a complete sentence instead.

Thought for

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

reasoning.tsx:156

The strings 'Thought for' and 'seconds' are fragments designed to be concatenated around a number (e.g., 'Thought for 5 seconds'). This concatenation pattern creates localization and accessibility failures because word order differs across languages. Use a complete sentence instead.

seconds

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

speech-input.tsx:300

The string 'Processing voice input' appears as a label/status message in a component and should not end with a period per Helix guidelines for UI microcopy.

Processing voice input

Processing voice input

Approve

Reject

Skip

Rule violation

web-preview.tsx:152

Accessibility failure: this input has no discrete label — placeholder "Enter URL..." is serving as the label, and it disappears once the user starts typing.

Enter URL...

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

helix-shell.tsx:262

The HelixShell component uses both 'Open wallet' and 'Wallet' to describe the same action. One should be removed or consolidated.

Open wallet

Open wallet

Approve

Reject

Skip

Rule violation

helix-shell.tsx:268

The HelixShell component uses both 'Open wallet' and 'Wallet' to describe the same action. One should be removed or consolidated.

Wallet

Open wallet

Approve

Reject

Skip

Rule violation

conversation-thread-view.tsx:984

Both ConversationThreadView and MicrolessonView use 'Helix is thinking…' identically. This suggests a shared constant that should be defined once.

Helix is thinking…

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

conversation-thread-view.tsx:1068

Accessibility failure: this input has no discrete label — placeholder "Ask Helix…" is serving as the label, and it disappears once the user starts typing.

Ask Helix…

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

feedback-nudge.tsx:35

The DismissButton component uses both 'Dismiss feedback nudge' and 'Dismiss' to describe the same action. One should be removed or consolidated.

Dismiss feedback nudge

Dismiss

Approve

Reject

Skip

Rule violation

feedback-nudge.tsx:40

The DismissButton component uses both 'Dismiss feedback nudge' and 'Dismiss' to describe the same action. One should be removed or consolidated.

Dismiss

Dismiss

Approve

Reject

Skip

Rule violation

microlesson-view.tsx:111

Both ConversationThreadView and MicrolessonView use 'Helix is thinking…' identically. This suggests a shared constant that should be defined once.

Helix is thinking…

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

microlesson-view.tsx:115

The error message 'This lesson hit a snag' uses an exclamation mark, which can read as flippant in a failure state. Per guidelines, errors should avoid exclamation marks.

This lesson hit a snag

This lesson hit a snag.

Approve

Reject

Skip

Rule violation

pathway-handoff-transition.tsx:41

Accessibility failure: this input has no discrete label — placeholder "Message Helix…" is serving as the label, and it disappears once the user starts typing.

Message Helix…

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

spine-referral-card.tsx:62

The ReferralLoadingCard component uses both 'Preparing your activity' and 'Preparing your activity…' to describe the same state. One should be removed or consolidated.

Preparing your activity

Preparing your activity…

Approve

Reject

Skip

Rule violation

spine-referral-card.tsx:63

The ReferralLoadingCard component uses both 'Preparing your activity' and 'Preparing your activity…' to describe the same state. One should be removed or consolidated.

Preparing your activity…

Preparing your activity…

Approve

Reject

Skip

Rule violation

wallet-dashboard.tsx:93

The label 'Total skills' appears in both WalletDashboard (id 2161926a0510) and WalletSurface (id 9b87b4fe967e). These likely refer to the same metric and should be consolidated to a single source string.

Total skills

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

wallet-dashboard.tsx:99

The label 'Average confidence' appears in both WalletDashboard (id 54d7ef7d5061) and WalletSurface (id bfc0d90b0965). These likely refer to the same metric and should be consolidated to a single source string.

Average confidence

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

wallet-surface.tsx:35

The label 'Total skills' appears in both WalletDashboard (id 2161926a0510) and WalletSurface (id 9b87b4fe967e). These likely refer to the same metric and should be consolidated to a single source string.

Total skills

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

wallet-surface.tsx:41

The label 'Average confidence' appears in both WalletDashboard (id 54d7ef7d5061) and WalletSurface (id bfc0d90b0965). These likely refer to the same metric and should be consolidated to a single source string.

Average confidence

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

content-registry.tsx:289

The string 'This is an interactive activity — it launches from its activity card in the conversation, not here.' uses pronouns 'it' and 'its' whose referent is unclear without seeing the UI context. What activity does 'it' refer to, and where specifically is 'the conversation'?

This is an interactive activity — it launches from its activity card in the conversation, not here.

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

concluded-interaction-review.tsx:43

Error copy should avoid exclamation marks. The phrase 'This activity didn't load' appears across multiple error states and should maintain consistent, neutral punctuation. While the current strings lack exclamation marks, ensure they remain absent if these error messages are presented as alerts or toasts.

This activity didn’t load

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

interactions-launch-surface.tsx:67

Error copy should avoid exclamation marks. The phrase 'This activity didn't load' appears across multiple error states and should maintain consistent, neutral punctuation. While the current strings lack exclamation marks, ensure they remain absent if these error messages are presented as alerts or toasts.

This activity didn’t load

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

surface.tsx:327

Error copy should avoid exclamation marks. The phrase 'This activity didn't load' appears across multiple error states and should maintain consistent, neutral punctuation. While the current strings lack exclamation marks, ensure they remain absent if these error messages are presented as alerts or toasts.

This activity didn’t load

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

attachment-tray.tsx:86

Buttons read as a more direct command without an article; "Add an image" uses one, the same shape the guideline's own example drops ("Add lecture", not "Add a lecture").

Add an image

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

comment-popover.tsx:425

Accessibility failure: this input has no discrete label — placeholder "Reply…" is serving as the label, and it disappears once the user starts typing.

Reply…

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

content-audit-finding-row.tsx:160

The strings 'Approved and applied.' and 'Dismissed.' end with periods, but these are short status messages in a component where periods are unnecessary clutter.

Approved and applied.

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

content-audit-finding-row.tsx:161

The strings 'Approved and applied.' and 'Dismissed.' end with periods, but these are short status messages in a component where periods are unnecessary clutter.

Dismissed.

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

feedback-composer.tsx:280

Accessibility failure: this input has no discrete label — placeholder "Share what's on your mind… (or drop an image)" is serving as the label, and it disappears once the user starts typing.

Share what's on your mind… (or drop an image)

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

feedback-composer.tsx:328

"Pin it to the app" uses "it" with nothing nearby naming what it refers to — a reader can't tell what's being acted on.

Pin it to the app

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

feedback-dock.tsx:114

The strings 'Your feedback' appears twice in this batch with the same id concept but used as a CTA in two different components. Review whether both instances are necessary or if one should be removed.

Your feedback

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

feedback-drawer.tsx:344

The strings 'reply' and 'replies' use lowercase, inconsistent with other CTA buttons in the interface that use sentence case. CTAs should use sentence case: 'Reply' and 'Replies'.

reply

Reply

Approve

Reject

Skip

Rule violation

feedback-drawer.tsx:344

The string 'replies' uses lowercase, inconsistent with other CTA buttons in the interface that use sentence case. CTAs should use sentence case: 'Replies'.

replies

Replies

Approve

Reject

Skip

Rule violation

feedback-thread-view.tsx:49

The strings 'Your feedback' appears twice in this batch with the same id concept but used as a CTA in two different components. Review whether both instances are necessary or if one should be removed.

Your feedback

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

feedback-thread-view.tsx:81

Accessibility failure: this input has no discrete label — placeholder "Reply…" is serving as the label, and it disappears once the user starts typing.

Reply…

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Rule violation

general-composer.tsx:156

Accessibility failure: this input has no discrete label — placeholder "What did you want to flag? (paste or drop an image)" is serving as the label, and it disappears once the user starts typing.

What did you want to flag? (paste or drop an image)

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestions (30)

Dismiss all style suggestions

Style suggestion

onboarding-overlay.tsx:161

The OnboardingOverlay component mixes conversational second-person questions ('What do you want to learn today?' 'What do you want to get better at?') with clinical label-style copy ('Your name', 'A skill or goal'). Consider warming the placeholder text to match the conversational tone of the questions.

Welcome to Helix — what should we call you?

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

onboarding-overlay.tsx:167

The OnboardingOverlay component mixes conversational second-person questions ('What do you want to learn today?' 'What do you want to get better at?') with clinical label-style copy ('Your name', 'A skill or goal'). Consider warming the placeholder text to match the conversational tone of the questions.

Your name

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

onboarding-overlay.tsx:174

The OnboardingOverlay component mixes conversational second-person questions ('What do you want to learn today?' 'What do you want to get better at?') with clinical label-style copy ('Your name', 'A skill or goal'). Consider warming the placeholder text to match the conversational tone of the questions.

What do you want to get better at?

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

onboarding-overlay.tsx:180

The OnboardingOverlay component mixes conversational second-person questions ('What do you want to learn today?' 'What do you want to get better at?') with clinical label-style copy ('Your name', 'A skill or goal'). Consider warming the placeholder text to match the conversational tone of the questions.

A skill or goal

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

not-found.tsx:28

Consider a fresher take on 'Helix routed you off the path.' This phrasing feels somewhat clichéd; a more direct, less metaphorical explanation may feel clearer.

Helix routed you off the path. Head back to where the flow lives.

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

chat-prompt-bar.tsx:183

The strings 'Add attachment' and 'Upload files' both appear to reference the same underlying capability of attaching content to a message. Consider clarifying whether these are distinct actions (e.g., one for existing files, one for capturing new ones) or consolidating them.

Add attachment

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

prompt-input.tsx:842

The strings 'Add attachment' and 'Upload files' both appear to reference the same underlying capability of attaching content to a message. Consider clarifying whether these are distinct actions (e.g., one for existing files, one for capturing new ones) or consolidating them.

Upload files

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

helix-shell.tsx:969

Consider whether 'Helix is thinking…' and 'Loading saved pathways' represent the same state. 'Helix is thinking…' is conversational and personified, while 'Loading saved pathways' is more neutral. If both describe a loading state, align their tone.

Loading saved pathways

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

microlesson-view.tsx:117

The error heading 'This lesson hit a snag' (b584f4539a7b) and body 'The lesson stream failed.' use different punctuation treatment. Consider whether both should end with periods or neither.

The lesson stream failed.

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

wallet-empty-state.tsx:10

Consider whether 'trust-tiered' in the empty-state description is clear to all users. This technical term may not translate well or be immediately understood by learners unfamiliar with credential terminology.

Self-claim a skill or complete a learning path and it shows up here, evidenced and trust-tiered.

Self-claim a skill or complete a learning path and it shows up here, verified and ranked by trustworthiness.

Approve

Reject

Skip

Style suggestion

wallet-view.tsx:40

The ellipsis in 'Loading your wallet…' is acceptable but consider whether a spinner or animated treatment would communicate the loading state more clearly, per guidelines preferring graphical treatments over ellipses.

Loading your wallet…

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

launch-panels.tsx:207

The component labels mix specific and generic terms: 'Practice activity' (id 2fa182404a61), 'Activity launch' (id a8b53b0c4d37), and 'Activity' (id 40e32c8969ac) may refer to overlapping concepts. Consider whether these should use consistent phrasing or are intentionally distinct based on context.

Activity launch

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

practice-launch.tsx:61

Two strings convey that practice isn't available: 'This practice activity didn't load' (id ba3f8a33602b) and 'Practice isn't available here' (id 07cd12dde13a). These may represent different failure modes (load error vs. missing setup), but the distinction isn't clear from the wording alone. Clarify the difference or consolidate.

This practice activity didn’t load

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

practice-launch.tsx:112

The component labels mix specific and generic terms: 'Practice activity' (id 2fa182404a61), 'Activity launch' (id a8b53b0c4d37), and 'Activity' (id 40e32c8969ac) may refer to overlapping concepts. Consider whether these should use consistent phrasing or are intentionally distinct based on context.

Practice activity

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

surface.tsx:234

The component labels mix specific and generic terms: 'Practice activity' (id 2fa182404a61), 'Activity launch' (id a8b53b0c4d37), and 'Activity' (id 40e32c8969ac) may refer to overlapping concepts. Consider whether these should use consistent phrasing or are intentionally distinct based on context.

Activity

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

surface.tsx:321

"Loading this activity" uses "this" with nothing nearby naming what it refers to — a reader can't tell what's being acted on.

Loading this activity

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

surface.tsx:489

The footer component mixes conversational instruction ('Finish the practice above, then submit your answers') with clinical state descriptions ('Your answers didn't go through'). Consider warming 'Your answers didn't go through' to match the supportive tone, perhaps 'Your answers didn't submit—check your connection and try again.'

Your answers didn’t go through

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

surface.tsx:490

The footer component mixes conversational instruction ('Finish the practice above, then submit your answers') with clinical state descriptions ('Your answers didn't go through'). Consider warming 'Your answers didn't go through' to match the supportive tone, perhaps 'Your answers didn't submit—check your connection and try again.'

Check your connection and submit again.

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

surface.tsx:497

The footer component mixes conversational instruction ('Finish the practice above, then submit your answers') with clinical state descriptions ('Your answers didn't go through'). Consider warming 'Your answers didn't go through' to match the supportive tone, perhaps 'Your answers didn't submit—check your connection and try again.'

Finish the practice above, then submit your answers.

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

surface.tsx:601

Two strings convey that practice isn't available: 'This practice activity didn't load' (id ba3f8a33602b) and 'Practice isn't available here' (id 07cd12dde13a). These may represent different failure modes (load error vs. missing setup), but the distinction isn't clear from the wording alone. Clarify the difference or consolidate.

Practice isn’t available here

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

surface.tsx:603

The heading 'This check needs practice that isn't set up in this environment' (id ef6c5c30e6bd) is 61 characters and may exceed optimal brevity for modal-like components. Consider tightening to 'Practice isn't available here' or similar for better scannability.

This check needs practice that isn’t set up in this environment.

Practice isn't available here

Approve

Reject

Skip

Style suggestion

surface.tsx:724

Most error messages use contractions ('didn't', 'isn't'), which is good for approachability. However, 'No result was recorded for it' (id a31159b6e9e3) avoids contraction and feels slightly formal. Consider 'No result was recorded' for consistency.

No result was recorded for it.

No result was recorded

Approve

Reject

Skip

Style suggestion

attachment-tray.tsx:86

Buttons should stay within about 20 characters; "Attachment limit reached" is 24.

Attachment limit reached

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

feedback-composer.tsx:287

In CardBody, 'Add detail (optional)' uses clinical form language, which contrasts with the more conversational tone of nearby copy like 'Pin it to the app' and 'Audit page content'. Consider warming this label to match the component's overall voice.

Add detail (optional)

Add more details (optional)

Approve

Reject

Skip

Style suggestion

feedback-composer.tsx:338

The strings 'Add an image' and 'Add a screenshot' both appear to be attachment actions in the same component. Consider whether these are truly distinct capabilities or should use more specific, less ambiguous wording to clarify the difference.

Add a screenshot

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

general-composer.tsx:131

The GeneralComposerDialog mixes conversational copy with clinical form labels. 'File general feedback' is descriptive and user-friendly, but 'Classification' reads as clinical. Consider warming it to 'Feedback type' or 'Category' for consistency.

File general feedback

Feedback type

Approve

Reject

Skip

Style suggestion

general-composer.tsx:172

The GeneralComposerDialog mixes conversational copy with clinical form labels. 'File general feedback' is descriptive and user-friendly, but 'Classification' reads as clinical. Consider warming it to 'Feedback type' or 'Category' for consistency.

Classification

Feedback type

Approve

Reject

Skip

Style suggestion

thread-card.tsx:144

The ThreadCard component uses 'image' and 'images' as content labels but also includes 'View screenshot' as a separate action, making it unclear whether these are three distinct concepts or varying phrasings of the same capability.

image

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

thread-card.tsx:144

The ThreadCard component uses 'image' and 'images' as content labels but also includes 'View screenshot' as a separate action, making it unclear whether these are three distinct concepts or varying phrasings of the same capability.

images

No automatic rewrite — fix by hand.

Approve

Reject

Skip

Style suggestion

thread-card.tsx:157

The ThreadCard component uses 'image' and 'images' as content labels but also includes 'View screenshot' as a separate action, making it unclear whether these are three distinct concepts or varying phrasings of the same capability.

View screenshot

No automatic rewrite — fix by hand.

Approve

Reject

Skip