Files
zeekay a5b4a4835c site: say only what is kept: /referral on the real score, a copy gate, plain wording
/referral promised $25/$100/$500 credits, a 10% token kickback, a free week per
paid upgrade and a free Enterprise year; nothing in the cloud pays any of it
(the score is +1 signup, +20 referral that pays, +1 per 100K tokens, +10 star,
+1 follow). The page is the real rules and the same share card as the beta.
scripts/audit-copy.ts fails words that sell and marks of work not done; the
customer, proof, history and careers files, which move to the CMS, are listed
there until they do.

Claude-Session: https://claude.ai/code/session_017vrVus6PPBgP5YRzKV1iqW
2026-10-26 09:57:01 -07:00

72 lines
2.9 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* THE SITE SAYS WHAT IT KNOWS, PLAINLY.
*
* Fails on words that sell instead of say, and on markers of work not done, in the
* lines a reader sees (comments are the engineers' own and are skipped). A phrase
* a page needs for a true reason is allowed by file and word below, with the reason.
*
* node scripts/audit-copy.ts report and fail
*/
import { readFileSync, readdirSync, statSync } from 'node:fs'
import { join, relative } from 'node:path'
const BANNED = [
'seamless(?:ly)?', 'revolutionary', 'revolutionize', 'cutting-edge', 'state-of-the-art', 'best-in-class', 'world-class',
'game-chang(?:er|ing)', 'next-gen(?:eration)?', 'supercharge', 'turbocharge', 'blazing(?:-| )fast', 'lightning(?:-| )fast',
'effortless(?:ly)?', 'empower(?:s|ing)?', 'leverag(?:e|es|ing)', 'unlock(?:s|ing)?', 'robust', 'holistic', 'synergy', 'delve', 'elevate', 'streamline',
'coming soon', 'lorem ipsum', 'placeholder text', 'TBD',
]
const RE = new RegExp(`\\b(${BANNED.join('|')})\\b`, 'i')
/** file → the words it may carry, and why. */
const ALLOW: Record<string, { words: string[]; why: string }> = {
'components/zen/hexagrams.ts': { words: ['leverage'], why: 'the name of hexagram 42’s principle' },
'app/(marketing)/zen/models/view.tsx': { words: ['tbd'], why: 'a model whose parameter count is not published is not drawn' },
}
/**
* Files whose words are CONTENT, not code: customer stories, proof points, the
* company's history and the jobs. They move to the CMS (cms.hanzo.ai), where an
* editor reviews, rewrites and publishes them; each entry leaves this list when
* its file does. Nothing new is added here.
*/
const IN_THE_CMS_NEXT = new Set([
'app/(marketing)/customers/page.tsx',
'components/about/HistoryTimeline.tsx',
'components/home/Proof.tsx',
'lib/careers.ts',
])
const ROOTS = ['app', 'components', 'lib']
const SKIP = /(^|\/)(node_modules|data|content)(\/|$)|\.(test|spec)\.|\.json$/
function* walk(dir: string): Generator<string> {
for (const name of readdirSync(dir)) {
const path = join(dir, name)
if (SKIP.test(path)) continue
if (statSync(path).isDirectory()) yield* walk(path)
else if (/\.(tsx?|css)$/.test(name)) yield path
}
}
const found: string[] = []
for (const root of ROOTS) {
for (const path of walk(root)) {
const file = relative('.', path)
if (IN_THE_CMS_NEXT.has(file)) continue
const allowed = ALLOW[file]?.words ?? []
readFileSync(path, 'utf8').split('\n').forEach((line, i) => {
const text = line.trim()
if (text.startsWith('//') || text.startsWith('*') || text.startsWith('/*') || text.startsWith('{/*')) return
const hit = RE.exec(text)?.[1]
if (hit && !allowed.includes(hit.toLowerCase())) found.push(`${file}:${i + 1} ${hit}`)
})
}
}
if (found.length) {
console.error(`${found.length} line(s) say it in a way that sells, or point at work not done:\n${found.join('\n')}`)
process.exit(1)
}
console.log('copy: clean')