Commit Graph

10 Commits

Author SHA1 Message Date
Clayton Kim 14241ed594 Integrate advisor/010-dx-polish
# Conflicts:
#	.github/workflows/evals.yml
#	scripts/check_suggestions.py
#	scripts/extract_constraints.py
#	scripts/readability_metrics.py
2026-07-07 07:04:32 -07:00
Clayton Kim 71d0014912 Integrate advisor/002-input-robustness 2026-07-07 06:55:28 -07:00
Clayton Kim fcf0fa43b2 Give check_suggestions/readability_metrics/extract_constraints real --help
All three scripts previously treated -h/--help as a filename argument:
check_suggestions.py --help printed "Missing file: --help" and exited 2;
readability_metrics.py and extract_constraints.py emitted a JSON error.
Every sibling script uses argparse and gets proper usage text.

Mirrors structure_scan.py's minimal shape (optional positional path,
stdin fallback). Existing invocations are byte-identical before/after
(verified via before/after snapshots on file-arg, stdin, and
missing-file cases) — only -h/--help behavior changes.
2026-07-07 06:32:35 -07:00
Clayton Kim 1cdfc1c483 Harden stdin and file readers against bad bytes, add ENC- eval rows
Eight scripts (banned_phrase_scan, structure_scan, silhouette_scan,
readability_metrics, extract_constraints, suggest, check_suggestions,
voice_score) raised a raw UnicodeDecodeError traceback on non-UTF-8
stdin or file input. Switch stdin reads to
sys.stdin.buffer.read().decode("utf-8", errors="replace") and CLI
file reads to errors="replace", matching the idiom already used by
voice_profile.py, voice_card.py, and run_mimic_refine.py.

harvest_samples.py aborted an entire batch when one sibling file had
bad encoding or was unreadable: apply errors="replace" at its three
read sites and wrap per-file dispatch in collect_sources with a
try/except (OSError, UnicodeDecodeError) that records a new
"unreadable" drop-stat and warning (reusing the existing
stats/warnings plumbing that already tracks "instruction-injection")
and continues with the rest of the batch.

evals/run_local.py tracebacked when the claude CLI binary was
missing; catch (FileNotFoundError, OSError) alongside the existing
TimeoutExpired handling and degrade that one task instead of crashing
the whole run.

Add six ENC-01..06 eval rows (evals/adversarial-evals.json) covering
each fix, plus a small harvest fixture
(evals/fixtures/harvest/fixture_bad_encoding/good.md) whose marker
sentence must survive a sibling bad-encoding file generated inline by
the eval row (not committed as binary). Confirmed red against
unfixed code via git stash before restoring the fixes.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K6CYksdLbXbTAxcAQjvHz5
2026-07-07 06:20:09 -07:00
Clayton Kim 91a99c4c9d Make the advertised Python 3.8+ floor true, and test it in CI
Insert `from __future__ import annotations` in the 17 files that use
PEP 604/585 annotations in module-level positions evaluated at import
time, so scripts/banned_phrase_scan.py and friends no longer raise
TypeError on Python 3.8/3.9. Add a 3.8 leg to the CI matrix so the
floor claim in README.md is actually gated, and correct the two
imprecise "439 deterministic cases" references to "440 deterministic
script cases (439 pass, 1 documented xfail)".

New scripts must carry the future-import until the floor is raised;
if the maintainer later chooses 3.10+, delete the CI 3.8 leg and
README claim together.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K6CYksdLbXbTAxcAQjvHz5
2026-07-07 06:13:32 -07:00
Clayton Kim 87990359b6 Harden support scripts: unit families, magnitudes, curly quotes, faithful-rewrite fixes
- validate_preservation: unit-swap detection (km/mi, °C/°F, GB/TB, hr) with
  full alias families both directions; spelled magnitude words beyond currency;
  curly-quote tracking; range/quarter/time faithful rewordings pass while true
  swaps fail; --strict promotes semantic warnings (negation/scope/modality) to
  exit 1; modality strengthening (may->will) warned
- extract_constraints: proper-noun spans no longer glue across phrase
  boundaries; and/or no longer extracted as an /or endpoint
- readability_metrics: staccato detection sees em-dash/semicolon-joined
  fragments; sentence splitter handles closing quotes
- diff_check: pure reorder no longer excessive_change; docstring documents the
  exemption
- Rows PRES-10..27, SEM-03..07, ROB-09..11, AS-05 with paired fail guards

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 09:27:58 -07:00
Claude 6bf34a1445 Adversarial writing audit: close the anti-slop register + semantic blind spots
A red-team of the writing the skill PRODUCES (not just detection) confirmed the
core thesis: unslop can swap corporate slop for an equally-detectable "anti-slop"
register, and its validation is blind to the semantic facts most at risk. An
incentivized adversary attacked faithful skill outputs; the top findings were
re-verified by hand before fixing.

Scanner (B1, B7): the gold fragment-contrast form ("Not the technology. The
people.") and staccato triplets scored 0 — the scanner was blind to the skill's
own house style. Added an anti_slop_register category (fragment contrast +
staccato run, soft) and a readability staccato flag with no sentence-count gate.

Validation (B2): extract_constraints now captures cited references (Section 12(b),
Figure 2, Eq. 3) as hard must-preserve; validate_preservation warns when
negations, scope words, or conditionals are dropped ("does not support" ->
"supports"). SKILL.md no longer claims validation covers meaning.

SKILL.md guards (B3/B4/B6/B8): added "Register & genre guards" — don't de-hedge
regulated/technical text, don't invent first-person voice, avoid your own
staccato/fragment tell, keep warm text warm. Em-dash rule rewritten from "default
to zero" (which 2/4 presets violate) to "sparing appositive dash, never a splice".

Evals: +8 deterministic (AS-01/02/03, FP-12, PRES-08/09, SEM-01) and +8 behavioral
(SKILL-FRAGMENT/HEDGE/LEGAL/STACCATO/WARMTH/NOINVENT/OVEREDIT/EMDASH). Full
write-up in evals/ADVERSARIAL-WRITING-ANALYSIS.md.

Suite: 77 cases (51 script: 50 PASS / 1 XFAIL / 0 FAIL, 26 behavioral).
2026-06-14 22:34:30 +00:00
Claude 93c79fd579 Harden scripts/runner, add CI, expand eval coverage to 35 script cases
Robustness:
- every script now exits cleanly (code 2) on a missing/unreadable input file
  instead of raising a traceback (was only fixed for validate_preservation)
- runner adds a per-case timeout and survives a missing command/crash instead
  of aborting the whole run
- gated two more context-sensitive single words behind their jargon
  collocations: "harness" (a horse harness vs "harness the power of") and
  "foster" (a foster family vs "foster a culture of")

CI:
- .github/workflows/evals.yml compiles the scripts and runs the regression
  harness on every push and PR; only an undocumented FAIL breaks the build

New eval cases (script target, all passing):
- FP-07/08 literal harness/foster; FP-09 smart-quote exemption
- REC-01/02/03 recall guards proving the gating still flags real jargon and
  stacked slop (so de-noising can't silently gut detection)
- PRES-05 comma-format equality, PRES-06 $2.4M == $2.4 million, PRES-07 dropped
  quarter is a lost fact
- ROB-04..07 missing-file robustness for each script, ROB-08 empty stdin

Suite: 53 cases (35 script: 34 PASS / 1 XFAIL / 0 FAIL, 18 behavioral skill).
2026-06-14 21:33:42 +00:00
Claude 2fb6375a23 Fix script-level defects exposed by the adversarial suite
Flips 19 of the 20 deterministic xfail cases to PASS (FP-06, literal
"delve into a place", stays xfail as an accepted regex sense-ambiguity limit).
Final: 20 PASS, 1 XFAIL, 0 FAIL.

Fact preservation (validate_preservation.py, extract_constraints.py):
- currency compares absolute magnitude, so $47.3M no longer equals $47.3 billion
- percentages require an exact token match (12% no longer matches 120%)
- dates require the month, not just the year (March 3 2020 != December 2020)
- bare integers and whole phone numbers are now tracked as constraints
- faithful rewordings ($47.3M -> $47.3 million) still pass, no false missing
- missing input files exit cleanly instead of raising a traceback

Scanner (banned_phrase_scan.py):
- removed over-broad entries: "the real" (hit "the real estate"), bare
  "period."/"full stop." (hit any sentence ending in "period")
- gated context-sensitive words (leverage, navigate, tapestry, boasts) behind
  jargon collocations so literal/financial senses aren't flagged
- added missing tells: in conclusion, firstly/secondly, underscore the
  importance, treasure trove, ever-evolving, rich mosaic, plus stop-slop's
  false-agency family (numbers speak for themselves, data tells a story)
- quote masking: dropped the 500-char cap, allowed multi-line quotes, and
  stopped masking single-quoted prose that was hiding real slop

Robustness (readability_metrics.py, diff_check.py):
- numeric-only text counts as words instead of reading as empty
- punctuation-only edits register as change instead of 0%

Kept references/taboo-phrases.md in sync with the new scanner patterns.
2026-06-14 21:25:00 +00:00
Clayton Kim 2ae9d63743 Initial commit: unslop skill for humanizing AI content
Two-pass system (diagnosis → reconstruction) with:
- Comprehensive taboo phrases reference (throat-clearing, jargon, etc.)
- 8-criteria scoring rubric (40 points max)
- 4 voice presets (crisp, warm, expert, story)
- Python validation scripts (constraints, banned phrases, readability)
- Before/after examples for articles, LinkedIn, sales content

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-08 06:38:37 -08:00