Skip to content

docs(zh-Hant): name this app's own sidebar in English, and empty the CRM quarantine ledger - #1546

Merged
os-sales merged 1 commit into
mainfrom
claude/issue-1544-crm-nav-quarantine-worklist
Sep 3, 2026
Merged

docs(zh-Hant): name this app's own sidebar in English, and empty the CRM quarantine ledger#1546
os-sales merged 1 commit into
mainfrom
claude/issue-1544-crm-nav-quarantine-worklist

Conversation

@os-sales

@os-sales os-sales commented Sep 3, 2026

Copy link
Copy Markdown
Collaborator

Fixes #1544

KNOWN_UNRESOLVED_CRM in test/docs-setup-navigation-names.test.ts quarantined five zh-Hant group → child sidebar pairs on purpose, and wrote its own unblock condition into a comment because it could not write one into code: "when #1368 is decided, these five lines are the worklist". #1368 was decided on 2026-08-31. This is that worklist executed — in one commit, because the two halves fail in opposite directions.

#1368 itself stays open — this PR acts only on the worklist that ruling unblocked, and nothing here is a verdict on the rest of that card.

The convention, on its measured reason

This app ships en / zh-CN / ja-JP / es-ES and no Traditional-Chinese bundle, so a zh-Hant reader's console falls back to Simplified, and a Traditional page names navigation in English rather than mix Simplified glyphs into Traditional prose. It is not that the reader sees an English console — that reason was measured false and is retired.

The six citation sites

Every replacement was resolved live against src/apps/crm.app.ts + src/translations/* and cross-checked against the page's English twin, never translated by eye.

site was now resolves to
guides/email-and-calendar.zh-Hant.mdx:82 我的工作 → 我的行事曆 My Work → My Calendar group_worknav_my_calendar
sales/activities.zh-Hant.mdx:94 我的工作 › 我的任務 My Work › My Tasks group_worknav_my_tasks
sales/activities.zh-Hant.mdx:109 我的工作 › 我的任務 My Work › My Tasks group_worknav_my_tasks
sales/leads.zh-Hant.mdx:144 我的工作 › 我的線索 My Work › My Leads group_worknav_my_leads
sales/meetings-and-calls.zh-Hant.mdx:134 活動 › 活動 Activity › Events group_activitynav_event
sales/meetings-and-calls.zh-Hant.mdx:145 我的工作 › 我的日曆 My Work › My Calendar group_worknav_my_calendar

The Activity pair is the one to read twice

The card's own worked example proposed Activity → Activities. That pair is in no locale of this app's navigation — checked against the live CRM_PAIRS set, which holds 104 pairs across the four bundles. The Activity group ships exactly two children: Events (nav_event) and Sales Activity (nav_activity_dashboard). The citation resolves to Activity › Events, and the surrounding sentence — "the sidebar has only this one entry, and every way of reading those rows is a tab across the top of the page it opens" — is about the Events list, which confirms it. It looked self-referential only because zh-CN labels both the group and the Events entry 活动; the group half resolved at all only because 活動 collides with ja-JP's spelling of the group.

Why one commit — proven, not asserted

Three-legged ablation on origin/main at 05f867e1, guard file only. Each leg mutated, proved the mutation on disk by blob hash plus anchored counts on the removed and injected text, ran the guard, then restored via git checkout HEAD -- ABSOLUTE_PATH under a trap and verified the restore by state (git diff HEAD empty, blobs back to their HEAD values).

Leg (a) — prose only: 1 failed | 17 passed

FAIL … > holds no quarantined pair the docs no longer cite
AssertionError: KNOWN_UNRESOLVED_CRM entries no longer cited by any page:
我的工作 → 我的行事曆, 我的工作 → 我的任務, 我的工作 → 我的線索, 我的工作 → 我的日曆, 活動 → 活動.
Someone fixed the prose — delete these lines so the ledger keeps measuring the real remainder.

Leg (b) — ledger only: 1 failed | 17 passed

FAIL … > name a group and a child this app really ships, in one locale
AssertionError: docs cite sidebar paths this app does not ship:
  content/docs/guides/email-and-calendar.zh-Hant.mdx: '我的工作 → 我的行事曆'
  content/docs/sales/activities.zh-Hant.mdx: '我的工作 → 我的任務'
  content/docs/sales/leads.zh-Hant.mdx: '我的工作 → 我的線索'
  content/docs/sales/meetings-and-calls.zh-Hant.mdx: '活動 → 活動'
  content/docs/sales/meetings-and-calls.zh-Hant.mdx: '我的工作 → 我的日曆'

Leg (c) — both: 18 passed. The guard was already green on main before any of this (18 passed), so neither red is pre-existing.

The stale clause, corrected

The block's comment claimed #1368 "carries needs-user-decision". It does not any more, and a quarantine note that misstates its own unblock condition is how the next reader concludes the block is still live. The comment now records the decision, its date, the measured reason, and the opposite-direction failure pair. The set itself stays — empty and still checked in both directions, exactly as KNOWN_UNRESOLVED does: an asserted zero, not an absent one.

Scope held

No rule change. CITATION, CRM_CITATION, APP_WORDS, RETIRED_UI_NAMES and the platform ledger KNOWN_UNRESOLVED are untouched. Deleting a satisfied quarantine entry is the ledger doing its job; widening a rule to get green would not be.

Saved view names on these pages (全部任務, 我的待辦任務, 我的日曆, 我的線索) are deliberately left alone — that spelling question is the open decision card #1329, not this one, and #1329 stays undecided. This change touches navigation citations only.

content/docs/releases/ untouched.

Verification

pnpm verifyvalidate && typecheck && lint && lint:i18n-gate && hygiene && hygiene:tokens && build && test — green end to end, and the ratchet family plus the guard re-run after the final commit at d979ece7:

✓ i18n lint gate: 0 `i18n/missing-*` issues
✓ source hygiene clean
✓ business semantics ~83,423 tokens (ceiling ~85,000; headroom ~1,577).
✓ interaction layer ~37,426 tokens (ceiling ~40,000; headroom ~2,574).
✓ authored total ~135,190 tokens (ceiling ~140,000; headroom ~4,810).
✓ source token ratchet clean
 Test Files  159 passed (159)
      Tests  3344 passed | 1 skipped (3345)

A changeset is included.

🤖 Generated with Claude Code

https://claude.ai/code/session_019hUuCQStzXGMFSX4dzww5t


Generated by Claude Code

…CRM quarantine ledger (#1544)

`KNOWN_UNRESOLVED_CRM` in `test/docs-setup-navigation-names.test.ts` held five
zh-Hant `group -> child` pairs on purpose, pending #1368, and wrote its own
unblock condition into a comment because it could not write one into code:
"when #1368 is decided, these five lines are the worklist". #1368 was decided
on 2026-08-31. This is that worklist executed.

The convention holds on its measured reason: this app ships en / zh-CN / ja-JP
/ es-ES and no Traditional-Chinese bundle, so a zh-Hant reader's console falls
back to Simplified, and a Traditional page names navigation in English rather
than mix Simplified glyphs into Traditional prose. Not because the reader sees
an English console - that reason was measured false and is retired.

Six citation sites, four pages, each replacement taken from the page's English
twin rather than translated back:

  guides/email-and-calendar.zh-Hant.mdx:82    My Work -> My Calendar
  sales/activities.zh-Hant.mdx:94, :109       My Work -> My Tasks
  sales/leads.zh-Hant.mdx:144                 My Work -> My Leads
  sales/meetings-and-calls.zh-Hant.mdx:134    Activity -> Events
  sales/meetings-and-calls.zh-Hant.mdx:145    My Work -> My Calendar

The Activity pair is the one to read twice. Its Traditional citation spelled
group and child with the same word, and it does NOT mean Activity -> Activities,
which this app ships nowhere. It resolves against src/apps/crm.app.ts to
group_activity -> nav_event: Activity -> Events. It looked self-referential
only because zh-CN labels the group and the Events entry with one same string.

Prose and ledger land together because the two staleness checks fail in
opposite directions and each catches exactly half a change. Measured by
ablation before the fix, guard file only:

  prose only    1 failed | 17 passed - "holds no quarantined pair the docs no
                longer cite", naming all five entries
  ledger only   1 failed | 17 passed - "name a group and a child this app
                really ships, in one locale", naming all six sites
  both          18 passed

The block's comment is corrected in the same change: it said #1368 "carries
needs-user-decision", which stopped being true when the card was decided. A
quarantine note that misstates its own unblock condition is how the next reader
concludes the block is still live. The set itself stays, empty and still
checked in both directions, exactly as KNOWN_UNRESOLVED does.

No rule change. CITATION, CRM_CITATION, APP_WORDS, RETIRED_UI_NAMES and the
platform ledger KNOWN_UNRESOLVED are untouched.

pnpm verify green end to end: 159 test files, 3344 passed | 1 skipped.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019hUuCQStzXGMFSX4dzww5t
@vercel

vercel Bot commented Sep 3, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated
hotcrm Ignored Ignored Sep 3, 2026 11:01am UTC

Request Review

@github-actions github-actions Bot added the ci/cd CI plumbing and the verification pipeline label Sep 3, 2026
@os-sales
os-sales marked this pull request as ready for review September 3, 2026 11:04
@os-sales
os-sales added this pull request to the merge queue Sep 3, 2026
Merged via the queue into main with commit 30f2500 Sep 3, 2026
11 checks passed
os-sales added a commit that referenced this pull request Sep 3, 2026
…nctions (#1553)

#1368 corrected the REASON zh-Hant pages name platform navigation in English —
the console falls back to Simplified, so a Traditional page labels navigation in
English rather than ship mixed Simplified/Traditional script — and wrote it into
AGENTS.md:343-345. Reaching the reader took four PRs across two rounds (#1537,
#1546, #1549, #1554) and the sentence ended up corrected in nine places. Nothing
went red at any point, because nothing in CI reads prose.

The new guard pins the CLAIM, not the punctuation: a passage naming the
convention must state the sanctioned reason in the same passage, matched
wrap-insensitively over de-commented, emphasis-stripped text. The three measured
register variants — full stop inside the parens, outside it, and the short
glossary form that drops the trailing clause — all pass unchanged.

Replayed over the drift's real history it is red for the whole window and green
only from #1554: 7 red of 7 convention passages at 05f867e^, 7 of 8 at 30f2500,
1 of 9 at 18f523f^, 0 of 9 at 18f523f and today. The last red is the
navigation guard's own file header, the site that survived three days because
that file exempts itself from its own scan.

This file takes no exemption. It matches the assertion rather than the
vocabulary, so the deliberate negation #1546 wrote is read and passed on its
merits rather than skipped; and its retired-reason ledger is escaped the way
docs-object-term-consistency.test.ts escapes retired spellings, so the file
never literally spells the sentence it bans. The rule caught two violations in
this file itself on its first run, and both were rewritten rather than exempted.

The English markers are derived — the first test parses the AGENTS.md bullet and
asserts they are substrings of it, so the next correction to the rulebook goes
red here. The Chinese markers cannot be derived (AGENTS.md carries no
Traditional rendering) and are pinned constants citing it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019hUuCQStzXGMFSX4dzww5t
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci/cd CI plumbing and the verification pipeline

Projects

None yet

2 participants