Skip to content

feat: harden OINK platform and version delivery - #472

Open
imbajin wants to merge 69 commits into
masterfrom
feat/oink-core-platform
Open

imbajin wants to merge 69 commits into
masterfrom
feat/oink-core-platform

Conversation

@imbajin

@imbajin imbajin commented Sep 4, 2026

Copy link
Copy Markdown
Member

Before → after

Before After
Release entries, version routing, and build behavior were split across configuration and scripts. versions.json drives one immutable latest / 1.7 / 1.5 / 1.3 / 1.0 release contract, including selectors, aliases, SEO, route metadata, and aggregate validation.
Summary search had no durable load-failure recovery path. Native summary search remains primary and exposes distinct empty/error states with a stable keyboard-accessible retry.
No optional AI integration contract existed. Kapa is disabled by default, locale-bound, and loaded only after an explicit click; timeout, late response, and retry remain isolated from native search.
CI mixed build and publication concerns. Fixed event plans build immutable artifacts, revalidate the aggregate, run Chromium gates, and publish only to reviewed ASF targets with minimal permissions.

Main changes

  • Add the shared OINK shell behavior for navigation, version/locale-scoped
    sidebar state, mobile isolation, focus restoration, theme, image zoom,
    Backlinks, and Blog copy-link behavior.
  • Keep local summary search authoritative while adding an optional Search Tail
    • Floating Launcher Kapa adapter with privacy-safe click gating.
  • Generate bilingual latest-only llms-full.txt files without adding them to
    historical releases or making Kapa a build dependency.
  • Build five immutable releases and preserve production historical links from
    latest-only staging. The regenerated route map now covers 213 logical routes,
    keeps users on the equivalent logical page when it exists, and gives a
    locale-correct, one-time-explained Docs-root fallback when it does not.
  • Sync the latest Apache master at 3287b608 and refresh the affected route and
    historical navigation baselines.
  • Replace the previous workflow with fixed production/staging plans,
    short-lived artifacts, aggregate/security validation, Node 24, Playwright,
    Chromium, and fixed ASF publication targets.
  • Apply one fail-closed rendered-request policy to HTML, SVG, CSS, list-valued
    image attributes, runtime URLs, and authored content boundaries. Bootstrap
    control SVGs and shared historical assets remain local and version-complete.
  • Stabilize the versioning e2e selector so documents containing “Releases” are
    not mistaken for the Releases command-palette action.

Ask AI direction

The selected design combines a contextual Search Tail with a restrained
Floating Launcher. It excludes a persistent side panel and the old red/pink
assistant treatment.

Ask AI interaction direction comparison

Full decision record: #467 (comment)

Validation

  • PYTHONDONTWRITEBYTECODE=1 python3 -m unittest discover -s scripts -p 'test_*.py' — 124 passed
  • node --test tests/ui-ai/*.test.cjs tests/e2e/workflow-contract.test.cjs — 24 passed
  • bash dist/validate-links.sh
  • go mod verify with the exact pinned Apache OINK module — passed
  • Five-version production aggregate — 1,108 HTML files and 3,583 published
    files; 213 logical routes regenerated and validated across latest, 1.7, 1.5,
    1.3, and 1.0
  • Local full Chromium suite — 28 passed, 7 conditional skips
  • CI run 35263098357
    — prepare, five version builds, aggregate, e2e, visual, and deploy all
    passed; publish was skipped for the pull-request event
  • Local preview was checked on desktop, Chinese mobile at 390×844, language
    switching, version fallback, HBase search, and dark mode

Delivery boundaries

  • Kapa remains disabled until the reviewed EN/CN source groups, staging corpus,
    CSP hosts, and live privacy/failure smoke checks pass.
  • Community roster and content pilots remain isolated in the separate
    feat/oink-community-content branch.
  • ASF download data remains isolated in the separate feat/oink-download-asf
    branch.
  • Full-content local search remains deferred and is tracked in Track full-content local search with a performance budget #471.

- reject the repository root and its ancestors as outputs
- reject every output path nested inside the active checkout
- cover root, parent, and checkout-child deletion attempts
- add five-group docs navigation and explicit sidebar recovery\n- isolate and persist sidebar state by version and locale\n- add click-gated Kapa adapter with strict privacy defaults\n- enable OINK content helpers and branded social fallback\n- cover UI and AI contracts with dependency-free Node tests
- preserve mobile safe-area positioning\n- defer max and env evaluation to browser CSS\n- keep Hugo Sass compilation compatible
- preserve safe-area browser functions through Sass\n- replace unsupported color syntax with rgba values\n- keep responsive status and menu styles buildable
- compile safe-area and translucent styles with Hugo Sass\n- expose sidebar restore only while the tree is collapsed\n- scope backlinks and image zoom to designed surfaces\n- add enabled and invalid AI build fixtures\n- verify CSP, social image, and feature-scope contracts
- add immutable 1.3 and 1.0 refs to the canonical manifest
- migrate legacy routes into the five-group information architecture
- enforce real hreflang, archive noindex, and sitemap exclusion
- support latest-only aggregates and cross-origin staging menus
- enumerate every registered checkout before deleting outputs
- reject git-marked candidate paths and ancestors
- fail closed when worktree discovery is unavailable
- cover sibling and discovery-failure regressions
- enable LLMSFULL only on the English Docs root\n- enable LLMSFULL only on the Chinese Docs root\n- keep other sections and historical content unchanged
- map PR, master, and trusted dispatch events to fixed targets
- derive direct Hugo version menus from versions.json
- isolate Hugo caches and provision Community render dependencies
- separate read-only deploy gates from write-enabled publishing
- add a locked Node 24 Playwright workspace
- verify five-version archive and alias contracts in Chromium
- assert fixed bilingual Lunr queries rank expected references
- keep visual evidence advisory and outside the deploy gate
- generate locale-aware aliases after historical builds
- mark every archived page noindex,follow
- validate archive robots metadata in artifacts
- upgrade Playwright past the browser-download advisory
- fetch every resolved build SHA inside its isolated job
- build an AI-enabled fixture from the manifest-derived config
- gate shell, AI, Community, ranking, and axe contracts
- keep visual captures advisory with the correct theme key
- remove duplicated static version arrays from Hugo config
- keep localized menu labels in the stable site config
- require generated version config for release entries
- force noindex,follow on regular archive and print pages
- retain noindex,nofollow on generated 404 documents
- cover both prior robots states in the regression fixture
- add noindex metadata when Hugo alias pages omit robots
- preserve dedicated nofollow handling for 404 documents
- fail closed when archive HTML has no head or robots marker
- fetch the generated redirect document without browser navigation
- assert raw refresh and canonical targets
- avoid racing automatic meta refresh in Chromium
- load the metadata query fixture when PR-B is integrated
- keep PR-A fallback cases for standalone validation
- assert expected routes directly within the top three results
- proxy production-origin artifact requests to the local fixture
- stabilize AI tail rendering and shell interaction selectors
- validate ranking routes without assuming option markup
- keep known upstream axe findings as an explicit baseline
- silence fixture server logs without hiding test failures
- persist a non-active top-level sidebar disclosure
- resolve expected search titles from the built index
- click real palette rows while asserting top-three ranking
- persist sidebar state after OINK completes its disclosure update
- wait for asynchronous Lunr results before ranking assertions
- remove animation transients from color-contrast scans
- wait for scoped persistence initialization before disclosure clicks
- exercise the same non-active Develop group in both locales
- scan contrast only after theme and motion styles settle
- select the visible desktop collapse button explicitly
- avoid the hidden restore control that shares the data hook
- retain the collapse, inert, restore, and focus assertions
- install cwebp and dwebp before source validation
- verify both tools are available in the prepare job
- keep the Hugo and WebP setup order under a static contract
- cover navigation, search, sidebar, and Community states
- pair desktop and mobile routes across light and dark themes
- keep all eight screenshots advisory and artifact-backed
- skip Community-only assertions on standalone PR-A artifacts
- retain the blocking 5-3-2 and parity contract after PR-B integration
- keep shared platform coverage active in both release phases
- skip fixed ranking assertions before PR-B metadata is present
- retain native search coverage in standalone PR-A
- run all 24 Top-3 cases automatically after integration
- keep historical selectors on the configured production origin
- scope generated text corpus URLs for staging validation
- reject parent symlinks before resolving removable outputs
- cover selector and sentinel regressions
- keep native search retry DOM stable and keyboard usable
- reset timed-out Kapa scripts and ignore late callbacks
- source Kapa primary colors from the site theme token
- limit backlinks to five before native expansion
- cover pending, failure, and six-link fixtures
- pass the production historical origin through aggregation
- revalidate downloaded artifacts with identical URL scope
- cover the aggregate CLI and workflow contract
- group production runs by the asf-site target
- isolate staging and pull request concurrency
- guard the target-level concurrency contract
- derive the default version from the manifest
- reject configuration and strict-build override forms early
- keep supported base URL and port semantics aligned
- cover negative invocations before either tool can run
- preserve Hugo-authored Palette options during artifact scoping
- compare interactive native links with the route oracle
- cover postprocess ownership and native drift regressions
- exempt print-only outputs without native navigation
- prefer direct targets before consulting equivalence groups
- accept exactly one non-null alternate target
- preserve fallback behavior for absent or ambiguous routes
- cover bilingual latest and historical wrapper output
- derive locale-safe route equivalence groups from reviewed aliases
- fail closed on ambiguous route candidates
- validate localized LLMSFULL and scoped social images
- cover EN/CN selector query and hash preservation
- require aliases to reach a canonical page in the same artifact
- resolve validated alias chains to their terminal logical ID
- reject malformed equivalence types without traceback
- cover missing targets and chained aliases
- inspect every locale-specific Source row
- reject cross-origin and cross-version corpus entries
- detect malformed and duplicate source metadata
- require canonical locale-bound LLMS source rows
- reject ambiguous source URL encodings and delimiters
- validate social metadata as same-artifact image targets
- identify alias pages before social metadata validation
- exempt redirects only when both social tags are absent
- retain strict validation for content and partial metadata
- cover redirect, content, and partial-tag regressions
- derive error-document paths from published version metadata
- validate 1.3 and 1.0 error pages in security-only mode
- fail closed on malformed version metadata
- cover complete five-version paths and malicious SEO tags
- require ordinary aliases to remain on the configured origin
- enforce current-version scope and existing artifact targets
- reuse strict alias checks during route-map generation
- reject external, protocol, encoded, and ambiguous targets
- allow only the two reviewed archived home redirects
- bind English and Chinese homes to exact shared roots
- keep ordinary aliases on strict artifact-local validation
- cover production and staging origins plus hostile targets
- reject HTTP aliases whose parsed authority is empty
- block whitespace and control characters in redirect targets
- cover malformed triple-slash HTTP and HTTPS forms
- retain exact archive-home and artifact-local contracts
- reject HTTP(S) URLs without a parsed authority
- block whitespace, controls, and backslashes before URL resolution
- apply browser-parser shape checks in security-only scans
- cover triple-slash, opaque, and control-character forms
- apply one browser-safe shape policy to HTML and CSS tokens
- cover srcset, object, media, inline CSS, and stylesheets
- run the complete rendered security scan during artifact validation
- reject malformed resource URLs in security-only publication gates
- distinguish contact links from executable resource URLs
- reject non-HTTP schemes across HTML and CSS resources
- preserve explicit mailto and tel anchor behavior
- cover script, iframe, object, media, srcset, and CSS inputs
- classify navigation, active resources, and contact URLs by context
- reject ping and base while validating form and SVG request targets
- cover fetch-capable link relations including prefetch and prerender
- allow only passive base64 raster data images
- mirror active attributes in version scoping and artifact validation
- tokenize CSS requests and reject ambiguous browser URL surfaces
- scope and validate srcset, SVG, and runtime action URLs
- externalize Bootstrap data SVGs into versioned local assets
- copy shared shell images into every historical build
- distinguish media source requests from picture candidates
- mark rendered authored content independently of container nesting
- reject premature boundary exits and spoofed markers
- keep media source classification across mismatched end tags
- mark ordinary and print-rendered authored content boundaries
- cover landing print content without weakening active-markup checks
@imbajin
imbajin marked this pull request as ready for review September 5, 2026 00:55

@bitflicker64 bitflicker64 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Blocking: no. Summary: The biggest simplification is tests/e2e/workflow-contract.test.cjs — 88 lines of regular expressions matched against the literal text of .github/workflows/hugo.yml, of which only the contents: write check encodes a real invariant; the rest fail on reformatting and nothing else. Three smaller ones follow: ~60 lines of scripts/hugo.sh re-parse Hugo's own CLI to forbid flags Hugo's last-wins pflag already lets you override, hooks/body-end.html hardcodes Chinese UI copy two lines after calling T for the English, and version-target.html scans all 195 route entries up to twenty times per page. Evidence: reviewed the full diff at head 25f3e8c (git diff --stat d88167dd797efafea50cec59909d57849703fde5 pr472 — 87 files, +10024/-365) in a worktree at that SHA; parsing data/version_routes.json gives 195 logical entries and 28 path deviations, all from the api-preformance rename; grep -rn version-target layouts/ returns four call sites; grep -c "" i18n/en.yaml i18n/cn.yaml returns 1 and 236; .github/workflows/hugo.yml:353 runs npm run test:ci, which includes the contract test. The route map, the five-version manifest, the CSP/SVG allowlist in dist/validate-site-output.py, the local Bootstrap SVGs and the disabled-by-default Kapa adapter are all justified in the PR description and are not raised.

Comment thread tests/e2e/workflow-contract.test.cjs Outdated
Comment thread scripts/hugo.sh Outdated
Comment thread layouts/_partials/hooks/body-end.html Outdated
Comment thread layouts/_partials/version-target.html
bitflicker64 and others added 8 commits September 18, 2026 02:19
Reduce tests/e2e/workflow-contract.test.cjs to the write-permission
invariant and harden it against write-all and additional write scopes.

Drop the hugo.sh argument reject machinery. Sniff only the documented
baseURL and port spellings, clustered shorthand included, and let
pflag last-wins handle overrides. Replace the three reject tests with
one flag-beats-env origin alignment test.

Route the Ask AI and version-fallback strings through T lookups and
rename i18n/cn.yaml to i18n/zh-CN.yaml: Hugo resolves translations by
locale, so the site catalogue was silently dead behind the hardcoded
Chinese strings.

Cache the version-target route-map lookup per page and stop the scan
at the first match.

(cherry picked from commit 71a6584)
- add current-master backend documentation routes
- include the Vermeer Python client in both locales
- keep archived version targets explicitly null
- align generated data with five-version artifacts
- scope write-permission checks to workflow jobs
- keep publish as the only contents writer
- cover documented baseURL and port spellings
- retain environment-origin precedence coverage
- add SeaTunnel import and export routes
- include the visualization guide in both locales
- keep legacy version targets explicitly null
- align generated data with current master content
- update 1.3 navigation tree digest after master sync
- update 1.0 navigation tree digest after master sync
- keep fixed page and removal counts unchanged
- preserve strict artifact metadata validation
- avoid matching document search results
- keep palette version selection stable
- cover latest master index additions
imbajin added a commit to hugegraph/hugegraph-doc that referenced this pull request Sep 17, 2026
- stage Apache PR apache#472 at 2330fec
- include Apache master at 3287b60
- preserve the org-only release workflow
- provide a temporary parent for phases B and C
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants