Skip to content

gen-zh-hant never rewrites a /zh-Hans/ link to a marketing page, so a zh-Hans post that links /zh-Hans/ontology/ fails pnpm build (content-lint cross-locale rule) #265

Closed

Description

@objectstack-fleet

Filing-gate category: ① a reproducible defect with a named location, reached through a public door. The door is pnpm build, which runs content:lint --published first.
Who acts: repo:www.objectos.ai · seat 2 (objectstack-ai/objectstack#23827). It dispatches on filing.
Dedupe: all 115 issues on this repo, open and closed, REST, 2026-10-16T08:24Z. gen-zh-hant|zhHantTargetBuilds: 6 hits — #142 (closed; it introduced the conditional rewrite, "only where the Traditional target is built"), #144, #162, #179, #194 (closed; other generator or lint work) and #205 (open; frontmatter splitters, unrelated). marketing page … zh-Hant: 0 hits. No card covers this.

Reading

Found by the #262 dev. The seat re-read it on origin/main 45d5ce9.

Fix shape (better route wins)

Add a marketing-page branch to zhHantTargetBuilds, mirroring the glossary branch. A one-segment rest builds when that slug is a marketing page with a zh-Hans (or zh-Hant) source. The slug set should come from the same place the site reads it (src/content-pages/registry.ts or the content/pages/ files), not a hand-kept list. Leave unknown slugs unrewritten, as today.

Done looks like


Generated by Claude Code

Activity

  1. objectstack-fleet commented on Oct 16, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 1
    Session: session_017GeNDQH7E5S2rX8ajVAPxv
    Account: os-tesla
    Branch: claude/sharp-mendel-1087cg-issue-265
    Worktree: www.objectos.ai-issue-265
    Domain: none — single-lane repo (repo:www.objectos.ai)
    Seat: repo:www.objectos.ai#2
    File surface: scripts/gen-zh-hant.mjs (zhHantTargetBuilds), at most a shared slug source it imports (stop on breach; explain in the report)
    Container & model: S, mode:subagent, model: TIER_DEFAULT — judgment tier: a build-tooling fix with a sensitivity leg, not an article card
    Clause-②: no
    Responsibility: scripts/gen-zh-hant.mjs produces the risk (this repo's own generator) | no platform path covers it (content-lint only refuses the output) | reached by any zh-Hans post that links a marketing page; first producer is #262's post (PR #263), none on main today
    Thread-read: none
    Serial constraints cleared: no open PR touches scripts/ (#237 #244 #245 #255 #260 #263 read 2026-10-16T08:25Z).

  2. objectstack-fleet commented on Oct 16, 2026

    @objectstack-fleet
    ContributorAuthor

    Second producer · 2026-10-16T08:28Z

    #261's dev hit the same gap independently, on branch claude/sharp-mendel-1087cg-issue-261 (PR #264, slot 2026-11-05). With [对比页](/zh-Hans/compare/) in a zh-Hans body, gen-zh-hant printed left 2 /zh-Hans/ link(s) as-is — no provable Traditional build, and pnpm content:lint exited 1 with a blocking Cross-locale internal link [對比頁](/zh-Hans/compare/) … /zh-Hant/compare/ IS built. The lint's remedy ("fix the link in the zh-Hans source and re-run pnpm gen:zh-hant") cannot be followed, because the zh-Hans link is already the correct one.

    That makes two producers (PR #263, PR #264), both waiting to restore their zh-Hans links once this lands. The slot-day passes on 11-05 and 11-10 check for it.


    Generated by Claude Code

  3. objectstack-fleet commented on Oct 16, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report
    {
    "issue": 265,
    "status": "done",
    "branch": "claude/sharp-mendel-1087cg-issue-265",
    "pr": "#266",
    "session": "session_017GeNDQH7E5S2rX8ajVAPxv",
    "premise_still_valid": true,
    "summary": "zhHantTargetBuilds in scripts/gen-zh-hant.mjs now answers true for a single-segment target when the slug is a cluster (CLUSTERS imported from src/lib/clusters.ts, the same Node type-stripping import content-lint readClusterSlugs uses) or a marketing page with a file in content/pages/{zh-Hant,zh-Hans,en}/ (read by filename like content-lint readLocaleTree, through the glossary branch's HANT_SOURCE_LOCALES). Both families come from one route, src/pages/[lang]/[cluster].astro, which emits every cluster and every getMarketingPages(locale) slug for every locale. Unknown slugs stay unrewritten and reported; the rule from #142 is unchanged. Premise held on 45d5ce9, and measurement widened it: a zh-Hans link to a CLUSTER (/zh-Hans/ai-native-app-platform/) fails content:lint in exactly the same way, so clusters are included (the PM assumption invited this if provable). Two pinned link fixtures (positive /zh-Hans/known/, negative /zh-Hans/ghost/) run the real predicate off a stub slug registry. Follow-up per the card: once this lands, PR #263 can restore its /zh-Hans/ontology/ link and PR #264 its /zh-Hans/compare/ link (not touched here).",
    "tests": "Sensitivity leg (scratch paragraph in content/blog/ai-wrote-your-app-dare-to-merge/index.zh-Hans.mdx via objectstack scripts/ablation-replace.mjs wrap mode, trap restoring zh-Hans and zh-Hant from HEAD; restore proven by blob hash == HEAD and empty git diff HEAD). Leg A (links /zh-Hans/ontology/, /zh-Hans/compare/#faq, cluster /zh-Hans/ai-native-app-platform/): BEFORE 45d5ce9: generator "left 3 /zh-Hans/ link(s) as-is", generated line kept /zh-Hans/, pnpm content:lint exit 1 "content lint failed (3 blocking issues)" with 3x "Cross-locale internal link ... IS built". AFTER 8374487: generated line "本體頁、對比頁 與 AI 原生應用平臺", no skip warning, content:lint exit 0 "content lint passed (347 files, 46 glossary terms checked)". Leg B (/zh-Hans/no-such-page-265/): before and after identical, link left as-is and reported "left 1". Ablation (fix committed first, HEAD 8374487): ablation-replace swapped "return STATIC_ROUTES.has(segments[0]) || slugBuilds(segments[0]);" for "return STATIC_ROUTES.has(segments[0]);" ("ok mutation landed: anchor 1 -> 0, blob b496693887d8 -> b50235dea050"); node scripts/gen-zh-hant.mjs exit 1 "gen-zh-hant: fixture failed [link-rewrite] in t expected t actual t". The predicted direction was red and red was observed; the negative fixture stayed green, which is correct; restore "ok restored: blob == HEAD (b496693887d8)". Provably-built cross-check after pnpm build: all 22 slugs the predicate can answer true for (17 pages + 5 clusters) have dist/zh-Hant/SLUG/index.html, 0 missing; no-such-page-265 absent. No test runner exists in this repo; no permanent test file added beyond the two in-script fixtures. Control-byte self-scan of the changed file: grep exit 1 (none).",
    "gates": "All at HEAD 8374487, exit captured before any pipe: pnpm content:lint exit 0 "content lint passed (347 files, 46 glossary terms checked)"; pnpm content:lint --published exit 0 (same line); pnpm check via os-verify-lock slot www-265 "VERDICT command-exit 0", "Result (160 files): 0 errors 0 warnings 0 hints"; pnpm build via os-verify-lock slot www-265 "VERDICT command-exit 0 · held the lock 105s (shared box)", "zh-Hant: generated 47, kept 0 hand-maintained, 7 with body links pointed at /zh-Hant/", "[build] Complete!", "content lint --dist links passed (98464 internal links in 912 built pages resolve to built files)"; pnpm seo:smoke exit 0 "SEO smoke test passed (902 HTML pages checked; 586 sitemap URLs against 316 noindexed pages; ...)". git status --porcelain empty after build (no regenerated files). Gate list hand-derived from this repo package.json per the dispatch (objectstack dispatch-gates.mjs does not apply to this repo). PR check-runs at report time: "Build and deploy: in_progress" (head 8374487), not awaited per the contract.",
    "mcp_calls": "0 — no MCP GitHub tools used (reads via gh api REST)",
    "api_writes": "2 relay strokes, each one POST /repos/objectstack-ai/objectstack/dispatches executed as objectstack-fleet[bot]: (1) pr_create = POST /repos/objectstack-ai/www.objectos.ai/pulls (draft) + POST /repos//issues/266/assignees [os-tesla], read-back 7432/7432 bytes identical; (2) comment = POST /repos//issues/265/comments (this report). Plus 2 git pushes (empty-branch probe, then 8374487); no label writes.",
    "files_changed": [
    "scripts/gen-zh-hant.mjs (+36 -7); src/lib/clusters.ts imported read-only, unchanged"
    ],
    "line_budget": "n/a",
    "deviations": [
    "Commit trailer: the first local commit carried a model-named Co-Authored-By line from the harness reminder; amended before the first push to the model-free pair (Co-Authored-By: Claude, Claude-Session). Nothing with a model identifier was pushed.",
    "First sensitivity-leg attempt was a no-op refused by ablation-replace (the replacement contained the anchor, so the anchor count could not drop); nothing ran, no reading taken; rerun with a replacement that does not contain the anchor. Only the rerun readings are reported.",
    "Scope widened within the dispatch: clusters included (measured same failure, provably built); en-only pages answer true, mirroring the glossary branch (getMarketingPages(zh-Hant) emits every en page as a noindexed fallback; en and zh-Hans page sets are identical today, so no effect on main). File surface held: one file.",
    "Observed, not caused: the sibling worktree /home/user/www.objectos.ai-issue-262 disappeared during this run; my git worktree remove named only the -265 path. Branch claude/sharp-mendel-1087cg-issue-262 on origin is at db59562, the same sha that worktree held at my start, so no work is lost.",
    "Issue reads used gh api REST (gh issue view answered 403: GraphQL unavailable in this container)."
    ],
    "open_questions": [],
    "out_of_scope_findings": [
    "carrier: 承接者:无 · only-read inference, not filed, noted in PR #266 Acceptance notes: src/content-pages/registry.ts drops a page file whose slug field differs from its filename, and content-lint checks that for glossary terms but not for pages, so readLocaleTree (and this predicate) would count such a file. All 34 page files match today (checked), and a dead link that resulted is caught by content lint --dist links at build time, so no public door gives a wrong answer · dedupe words: marketing page slug filename mismatch, content/pages slug check, readLocaleTree"
    ]
    }

  4. added a commit that references this issue on Oct 16, 2026
    3c5b6c6
  5. objectstack-fleet commented on Oct 16, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed and live · 2026-10-16T08:44Z

    Probe Reading
    PR #266, squash 3c5b6c6 (pinned to head 8374487), merged by seat 2. Seat record: PR comment on #266 (ACCEPT → PR #266); the seat reproduced the sensitivity leg against main's generator as the control.
    Deploy on main run 38875361376 Deploy to Cloudflare Pages: completed/success on 3c5b6c6
    Live probe NOT MEASURED. This container's egress refuses www.objectos.ai.

    State: closed completed by Fixes #265; pm:dispatched removed. Both producers have been sent a patch round to restore their zh-Hans links: PR #264 (/zh-Hans/compare/) and PR #263 (/zh-Hans/ontology/). Since the merge, the only www issue closed is this card.


    Generated by Claude Code

  6. added 2 commits that reference this issue on Oct 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions