README claim locks: lock the new narrative against drift#208
Merged
Conversation
PR 2 of the README narrative refresh round. PR 1 (#207) rewrote the public copy; this PR adds the lint job that prevents the new claims from drifting back to the older wording or accepting the disallowed phrases the spec called out. Spec readme-product-narrative-refresh-2026-04-26 lists the required and forbidden surfaces. The existing readme-public-copy job already tracks an earlier round's claim set; this new readme-narrative-locks job is additive. Five new check groups: 1. Required English tokens. Five-adapter set + opt-in E2E framing must appear by name so the public claim cannot quietly degrade to "and more" or imply always-on coverage: - opt-in E2E workflow - Verified adapters - OpenAI Codex - OpenCode - Gemini CLI 2. Required Spanish form. Either "E2E opt-in" or "workflow E2E opt-in" must appear in README.es.md so the Spanish surface is honest about the runtime harness being workflow_dispatch. 3. Forbidden literal phrases (across both READMEs). Tightens the stale-strings list with phrases that have appeared in drafts: - npx create-nanostack install (specific bad install command) - on every workflow run / every workflow run - 4 commands / Cuatro comandos - zero dependencies / Zero dependencies / cero dependencias / Cero dependencias - marketplace / plugin ecosystem - GDPR ready / SOC2 ready / compliance certified - works in every agent identically - full engineering team 4. Forbidden agent names with bare-word boundary. Spec rejects bare references to Amp, Cline, and Antigravity because Nanostack does not have verified adapters for them today. Word-boundary regex (\bAmp\b, \bCline\b, \bAntigravity\b) so legitimate uses like "amplifier" or "decline" do not trip the lock. 5. Sprint-order arrow check. Any arrow form that places /qa before /security (-> or unicode →) is a regression on the "do not show /qa before /security" rule. Each rule was sabotage-tested locally: drop a required token, inject a forbidden phrase, plant a bare agent name, plant a mis-ordered arrow, drop the Spanish E2E form -- every sabotage fired the corresponding lock, the happy path passes clean. YAML parses. All 10 suites green: 83 unit, 100 user-flows, 30 framework e2e, 51 stack examples e2e, 49 stack contract, 32 examples contract, 25 think archetypes, 32 think, 34 onboarding, 17 delivery matrix.
Codex's PR 2 review caught two real gaps in the lock surface.
P2.1 The required-tokens loop only locked OpenAI Codex, OpenCode,
and Gemini CLI by name — Claude Code and Cursor lived under the
generic "Verified adapters" header. A future edit could drop them
from the public claim and the lint would still pass. Added Claude
Code and Cursor as required tokens so the five-adapter set is
locked element-wise, not just by header.
P2.2 The forbidden-phrase sweep used grep -nF / grep -nE without
-i, so trivial case variants like Marketplace, GDPR Ready, Every
workflow run, Full engineering team, AMP, Cline, ANTIGRAVITY all
slipped through. For a public-narrative lock the casing should
not matter; switched both the literal sweep (now grep -niF) and
the bare-word agent-name sweep (now grep -niE "\b...\b") to
case-insensitive. Spanish forms collapse with -i (cero/Cero,
cuatro/Cuatro), so the previous "two entries per Spanish form"
duplication is gone.
Word-boundary semantics still hold under -i: \bamp\b (case-i)
matches "Amp" / "AMP" / "amp" but not "amplifier" / "ramp",
because the boundary is at start of "amplifier" / end of "ramp".
Sabotage replay (case-flipped):
- Marketplace, Plugin Ecosystem, Every workflow run, GDPR Ready,
Full engineering team, Zero Dependencies, Cuatro Comandos
- bare AMP, CLINE, antigravity
- dropping Claude Code or Cursor from the required set
All caught. Happy path stays clean on current README.md +
README.es.md.
10 suites green; lint.yml parses.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
PR 2 of the README narrative refresh round. PR 1 #207 rewrote the public copy; this PR adds the lint job (
readme-narrative-locks) that prevents the new claims from drifting back to older wording or accepting the disallowed phrases Codex's spec called out. The existingreadme-public-copyjob is preserved untouched; this is additive.Five new check groups
1. Required English tokens
Five-adapter set + opt-in E2E framing must appear by name so the public claim cannot quietly degrade to "and more" or imply always-on coverage. Each adapter is required element-wise so dropping any one of them fires the lint.
opt-in E2E workflowVerified adaptersClaude CodeCursorOpenAI CodexOpenCodeGemini CLI2. Required Spanish form
Either
E2E opt-inorworkflow E2E opt-inmust appear inREADME.es.md. The Spanish surface stays honest about the runtime harness beingworkflow_dispatch.3. Forbidden literal phrases (case-insensitive, both READMEs)
grep -niFsweep so trivial casing variants (Marketplace,GDPR Ready,Every workflow run,Full engineering team, etc.) are caught the same way as the canonical lowercase form. Spanish/English forms collapse under-i(cero/Cero,cuatro/Cuatro).npx create-nanostack install(specific bad install command)on every workflow run/every workflow run4 commands/cuatro comandoszero dependencies/cero dependenciasmarketplace/plugin ecosystemGDPR ready/SOC2 ready/compliance certifiedworks in every agent identicallyfull engineering team4. Forbidden agent names (bare-word boundary, case-insensitive)
grep -niE "\b<name>\b". Spec rejects bare references to Amp, Cline, and Antigravity because Nanostack does not ship verified adapters for them today. Word boundaries hold under-iso legitimate words likeamplifier,ramp,decline,inclinedo not trip the lock; only standaloneAmp/AMP/amp,Cline/CLINE,Antigravity/ANTIGRAVITYfire.5. Sprint-order arrow check
Any arrow form (
->or unicode→) placing/qaimmediately before/securityis a regression on the "do not show /qa before /security" rule.Sabotage-tested
Each rule fired correctly when the PR head was deliberately broken. Replay summary:
Claude Codefrom READMECursorfrom READMEOpenAI Codexfrom READMEMarketplace(case-flipped)GDPR Ready(case-flipped)Full engineering team(case-flipped)Zero Dependencies/Cuatro Comandos(case-flipped)AMP/CLINE/antigravity(case-flipped)Sprint: /qa -> /security -> /shipE2E opt-infromREADME.es.mdHappy path passes clean on current
maincontent.Test plan
README.md+README.es.mdRound closure
After this lands, the README narrative refresh round is complete:
compliance-release, Spanish parity restored, existing required-strings lock updated to match the new pillarsreadme-narrative-locksjob protects the new claim surface from drift, including the full five-adapter set element-wise and case-insensitive forbidden-phrase + bare-agent-name sweepsThe README is now the canonical product page: clear for first-time users, precise for technical users, honest about enforcement, current with framework + workflow stack support, and protected from known stale claims.