Skip to content

fix: reject moral attacks on the person, spare criticism of the content - #32

Merged
Bonobo791 merged 3 commits into
mainfrom
tone-moral-attacks
Jul 31, 2026
Merged

fix: reject moral attacks on the person, spare criticism of the content#32
Bonobo791 merged 3 commits into
mainfrom
tone-moral-attacks

Conversation

@Bonobo791

Copy link
Copy Markdown
Owner

Behavior

Stacked on #31 (same files; retargets to main automatically once #31 merges).

Character assassination, humiliation, discrediting, demonization, and condescending moral superiority now land in the demeaning band (reject, not ban). These attack who the creator or a commenter is — character, motives, worth — rather than what the video says:

  • He's a grifter who lies to his audience for money. → 0.88
  • People like you are everything wrong with this platform. → 0.85
  • Imagine being this desperate for views. Pathetic. → 0.85

Guard rail: criticism of the content or its claims (The claims in this video are exaggerated and unsourced. → 0.35) stays acceptable — attack the idea, never the person. Mild snark without moral framing still queues for human review (borderline band unchanged); verbal abuse remains omni-moderation's job.

Also fixed a regression the new paragraph caused: empty-metadata lol dropped to 0.05. The unknown-context policy is now explicit that a bare scoffing interjection with empty or uninformative metadata is demeaning, because no context invited it (back to 0.82).

Verification

  • New prompt-contract test pins the rule and three anchors (two person-attacks ≥0.76, one content critique ≤0.5), failing test first per repo rules.
  • Live eval (gpt-4.1-nano, temperature 0), 18/18 PASS — all four new moral-attack/content-critique cases plus every carried-over case.
  • npm run check: 0 errors. npm run test: 202/202. npm run build: green.

Out of scope

No threshold, pipeline, or UI changes; no new dependencies.

Character assassination, humiliation, discrediting, demonization, and
condescending moral superiority attack WHO the creator or a commenter is —
character, motives, worth — and now sit in the demeaning band (grifter
anchor 0.88; demonization and humiliation anchors 0.85). Criticism of the
content or its claims stays acceptable (anchored 0.35): attack the idea,
never the person. Also sharpened the unknown-context policy after it
regressed: a bare scoffing interjection with empty metadata is demeaning
because no context invited it.
@cla-bot cla-bot Bot added the cla-signed label Jul 31, 2026
@codeant-ai

codeant-ai Bot commented Jul 31, 2026

Copy link
Copy Markdown

🤖 CodeAnt AI — Review Status

Status Commit Started (UTC) Finished (UTC)
✅ Reviewed your PR e73cdfc Jul 31, 2026 · 16:38 16:39

@coderabbitai

coderabbitai Bot commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: e9094277-08c1-4f95-87e6-cea14764104c

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

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

@codeant-ai codeant-ai Bot added the size:M This PR changes 30-99 lines, ignoring generated files label Jul 31, 2026
@codeant-ai

codeant-ai Bot commented Jul 31, 2026

Copy link
Copy Markdown

User description

Behavior

Stacked on #31 (same files; retargets to main automatically once #31 merges).

Character assassination, humiliation, discrediting, demonization, and condescending moral superiority now land in the demeaning band (reject, not ban). These attack who the creator or a commenter is — character, motives, worth — rather than what the video says:

  • He's a grifter who lies to his audience for money. → 0.88
  • People like you are everything wrong with this platform. → 0.85
  • Imagine being this desperate for views. Pathetic. → 0.85

Guard rail: criticism of the content or its claims (The claims in this video are exaggerated and unsourced. → 0.35) stays acceptable — attack the idea, never the person. Mild snark without moral framing still queues for human review (borderline band unchanged); verbal abuse remains omni-moderation's job.

Also fixed a regression the new paragraph caused: empty-metadata lol dropped to 0.05. The unknown-context policy is now explicit that a bare scoffing interjection with empty or uninformative metadata is demeaning, because no context invited it (back to 0.82).

Verification

  • New prompt-contract test pins the rule and three anchors (two person-attacks ≥0.76, one content critique ≤0.5), failing test first per repo rules.
  • Live eval (gpt-4.1-nano, temperature 0), 18/18 PASS — all four new moral-attack/content-critique cases plus every carried-over case.
  • npm run check: 0 errors. npm run test: 202/202. npm run build: green.

Out of scope

No threshold, pipeline, or UI changes; no new dependencies.


CodeAnt-AI Description

Distinguish personal moral attacks from legitimate content criticism

What Changed

  • Character attacks, humiliation, demonization, and claims about a creator’s motives or worth are now rejected as demeaning.
  • Criticism focused on a video’s claims or evidence remains acceptable.
  • Bare scoffing comments such as “lol” with empty or uninformative context are again treated as demeaning.
  • Added prompt checks and evaluation cases covering personal attacks, content criticism, and unknown context.

Impact

✅ Fewer personal attacks accepted
✅ Legitimate content criticism remains allowed
✅ Consistent handling of context-free scoffing

💡 Usage Guide

Checking Your Pull Request

Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.

Talking to CodeAnt AI

Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:

@codeant-ai ask: Your question here

This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.

Example

@codeant-ai ask: Can you suggest a safer alternative to storing this secret?

Preserve Org Learnings with CodeAnt

You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:

@codeant-ai: Your feedback here

This helps CodeAnt AI learn and adapt to your team's coding style and standards.

Example

@codeant-ai: Do not flag unused imports.

Retrigger review

Ask CodeAnt AI to review the PR again, by typing:

@codeant-ai: review

Check Your Repository Health

To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.

@amazon-q-developer amazon-q-developer Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This PR successfully implements detection of moral attacks on the person while preserving content criticism, and fixes the empty-metadata regression for bare interjections. The implementation is thorough with comprehensive test coverage (18/18 cases passing), proper contract tests, and consistent calibration examples. All changes align with the stated behavior and verification requirements.


You can now have the agent implement changes and create commits directly on your pull request's source branch. Simply comment with /q followed by your request in natural language to ask the agent to make changes.

@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Reject moral attacks on people while allowing content criticism

🐞 Bug fix ✨ Enhancement 🧪 Tests 🕐 20-40 Minutes

Grey Divider

AI Description

• Classify character-assassination / moral-superiority attacks as demeaning (reject), not
 acceptable.
• Preserve legitimacy of criticism aimed at video claims/content (approve).
• Add prompt-contract tests and eval cases; restore unknown-context scoffing behavior for empty
 metadata.
Diagram

graph TD
A["User comment"] --> B["Tone moderation"] --> C{{"LLM"}} --> D["Score & band"] --> E["Action: approve/reject/ban"]
S["scripts/tone-eval.mjs"] --> P["tonePrompt.js"] --> B
U["scripts/tone-eval.test.mjs"] --> P
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Deterministic persona-attack heuristic (keyword/rule list)
  • ➕ Predictable behavior and easy unit testing
  • ➕ No prompt brittleness around exact anchor phrasing
  • ➖ High false positives/negatives (paraphrases, sarcasm, context dependence)
  • ➖ Hard to keep comprehensive without constant tuning
2. Separate classifier stage for 'person-directed attack' vs 'content critique'
  • ➕ Cleaner separation of concerns; easier to reason about thresholds per category
  • ➕ Can evolve category-specific datasets and tests
  • ➖ More pipeline complexity and potentially more cost/latency
  • ➖ Requires broader refactor than the stated scope

Recommendation: Keep the current approach (explicit rubric language + calibrated anchors + prompt-contract tests). It improves moderation behavior without changing thresholds/pipeline/UI, and the new tests reduce regression risk while preserving the intended boundary: attack ideas, not people.

Files changed (3) +56 / -1

Enhancement (1) +17 / -1
tonePrompt.jsClarify unknown-context scoffing and add moral-attack guidance + anchors +17/-1

Clarify unknown-context scoffing and add moral-attack guidance + anchors

• Strengthens the guidance for empty/uninformative metadata so a bare scoffing interjection is treated as demeaning when no context invites it. Adds a new rubric section defining moral attacks on the person as demeaning while explicitly allowing criticism of content/claims, and extends calibration examples with the new anchors.

src/lib/server/tonePrompt.js

Tests (1) +19 / -0
tone-eval.test.mjsPin rubric contract and anchor scores for moral attacks +19/-0

Pin rubric contract and anchor scores for moral attacks

• Introduces a new test that asserts the prompt explicitly mentions moral attacks on the person and includes anchored examples. It validates that two person-attack anchors score ≥ 0.76 and that a content-critique anchor stays ≤ 0.5.

scripts/tone-eval.test.mjs

Other (1) +20 / -0
tone-eval.mjsAdd eval cases for moral person-attacks vs content critique +20/-0

Add eval cases for moral person-attacks vs content critique

• Adds new fixed cases that should be rejected for character assassination/demonization/humiliation and a counterexample that criticizes video claims and should be approved. This expands coverage for the new rubric boundary in the eval harness.

scripts/tone-eval.mjs

@codeant-ai

codeant-ai Bot commented Jul 31, 2026

Copy link
Copy Markdown

🏁 CodeAnt Quality Gate Results

Commit: 0fcc281f
Scan Time: 2026-07-31 16:53:42 UTC

✅ Overall Status: PASSED

Quality Gate Details

Quality Gate Status Details
Secrets ✅ PASSED 0 secrets found
Duplicate Code ✅ PASSED 0.0% duplicated
SAST ✅ PASSED No security issues
Bugs ✅ PASSED Rating S: No bugs
IAC ✅ PASSED No IAC issues
Antipatterns ✅ PASSED No antipatterns

View Full Results

@qodo-code-review

qodo-code-review Bot commented Jul 31, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📜 Skill insights (0)

Context used
✅ Compliance rules (platform): 56 rules

Grey Divider


Informational

1. Brittle score regex ✓ Resolved 🐞 Bug ⚙ Maintainability
Description
The new moral-attacks prompt-contract test captures anchor scores with (0\.\d+), which cannot
match valid rubric values like 1.00 and can cause the test to fail after legitimate prompt
recalibration.
This is a latent maintainability issue (current anchors are 0.xx so it passes today).
Code

scripts/tone-eval.test.mjs[R147-149]

+	const assassination = TONE_PROMPT.match(/"[^"\n]*grifter[^"\n]*"[^\n]*->\s*(0\.\d+)/i);
+	const demonization = TONE_PROMPT.match(/"People like you[^"\n]*"[^\n]*->\s*(0\.\d+)/i);
+	const contentCritique = TONE_PROMPT.match(/"[^"\n]*exaggerated and unsourced[^"\n]*"[^\n]*->\s*(0\.\d+)/i);
Relevance

●●● Strong

Team recently accepted hardening brittle regex-based prompt parsing; similar maintainability fix
likely welcomed.

PR-#24

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The new test’s regex only matches scores that start with 0.. The rubric explicitly defines the
score range up to 1.00, so 1.00 is a valid calibration value that the test would be unable to
parse.

scripts/tone-eval.test.mjs[139-155]
src/lib/server/tonePrompt.js[51-54]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
The new test extracts calibration scores using the regex capture group `(0\.\d+)`, which only matches values starting with `0.`. The rubric’s scale explicitly allows values up to `1.00`, so if any referenced calibration example is later adjusted to `1.00`, the test will fail even though the prompt remains valid.

### Issue Context
Other contract tests in this file use the same `(0\.\d+)` pattern, but this PR adds another instance. Fixing this new instance (or preferably centralizing a shared score regex) prevents future false negatives.

### Fix Focus Areas
- scripts/tone-eval.test.mjs[139-155]

### Suggested change
Update the capture group to accept the full intended numeric range, e.g.:
- `((?:0\.\d+|1\.0+))`
(or a slightly more permissive variant if you want to allow `0.5`/`1` formats consistently across tests).

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

To customize comments, go to the Qodo configuration screen, or learn more in the docs.

Qodo Logo

Comment thread scripts/tone-eval.test.mjs Outdated
@codacy-production

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

🟢 Metrics 0 complexity · 0 duplication

Metric Results
Complexity 0 (≤ 100 complexity)
Duplication 0 (≤ 1 duplication)

View in Codacy

AI Reviewer: first review requested successfully. AI can make mistakes. Always validate suggestions.

Run reviewer

TIP This summary will be updated as you push new changes.

@codacy-production codacy-production Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull Request Overview

The PR successfully refines the moderation logic to better differentiate between moral attacks on a person (which should be rejected) and criticism of content (which should be accepted). These changes align with the primary objective of improving moderation nuance.

However, there is a discrepancy regarding the fix for bare scoffing interjections (e.g., 'lol' with empty metadata). While the PR description intends to return these to a score of 0.82, this specific numeric anchor is missing from the calibration examples in the prompt, and the corresponding test scenario is currently missing. Codacy analysis indicates the PR is otherwise up to standards with no new quality issues or complexity regressions.

About this PR

  • The PR aims to fix a regression for bare interjections by targeting a score of 0.82, but this specific target is not supported by new test cases or calibration entries in the prompt logic. This makes the fix difficult to verify and prone to future regressions.

Test suggestions

  • Character assassination ('grifter') scores in the demeaning range (>= 0.76)
  • Demonization ('People like you') scores in the demeaning range (>= 0.76)
  • Content critique ('exaggerated and unsourced') scores in the acceptable range (<= 0.5)
  • Bare 'lol' with empty metadata returns the targeted 0.82 score
Prompt proposal for missing tests
Consider implementing these tests if applicable:
1. Bare 'lol' with empty metadata returns the targeted 0.82 score

TIP Improve review quality by adding custom instructions
TIP How was this review? Give us feedback

- "People like you are everything wrong with this platform." -> 0.85
- "Imagine being this desperate for views. Pathetic." -> 0.85
- "The claims in this video are exaggerated and unsourced." -> 0.35
- "lol are you kidding? This is it? Not a great video." -> 0.85

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 MEDIUM RISK

Suggestion: To ensure the 'lol' regression is fully fixed and verifiable as stated in the PR description, add a calibration example for a bare interjection with empty metadata (e.g. - 'lol' (empty metadata) -> 0.82).

The contract tests captured anchor scores with (0\.\d+), which cannot match
a legitimate 1.00 calibration value and would fail on a valid prompt
recalibration. Widen the capture to (0\.\d+|1\.0+) across the file.
@sonarqubecloud

Copy link
Copy Markdown

Base automatically changed from tone-sweeping-exaggeration to main July 31, 2026 16:45
@Bonobo791
Bonobo791 merged commit 9a9275b into main Jul 31, 2026
10 of 11 checks passed
@Bonobo791
Bonobo791 deleted the tone-moral-attacks branch July 31, 2026 16:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cla-signed size:M This PR changes 30-99 lines, ignoring generated files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant