diff --git a/.github/ISSUE_TEMPLATE/reader-field-note.yml b/.github/ISSUE_TEMPLATE/reader-field-note.yml index 703fa55b..10121c47 100644 --- a/.github/ISSUE_TEMPLATE/reader-field-note.yml +++ b/.github/ISSUE_TEMPLATE/reader-field-note.yml @@ -24,18 +24,46 @@ body: description: What did you actually do or make after reading? A small or unsuccessful attempt is useful evidence. validations: required: true + - type: input + id: time_to_first_action + attributes: + label: Time to first action / 到第一次行动的时间 + description: Approximate minutes from opening the page to a first saved output; write "not recorded" if unknown. + validations: + required: true + - type: textarea + id: conditions + attributes: + label: Non-sensitive conditions / 非敏感条件 + description: Record only useful context such as device type, available time, prior familiarity, or whether help was used. Do not include identity, location, employer, health, or private project details. + validations: + required: true + - type: textarea + id: immediate_result + attributes: + label: Immediate result / 即时结果 + description: Record what you completed, what remained incomplete, direct feedback, the largest error or resistance, the conclusion you might exaggerate, and the next retest date. Include approximate minutes to the first saved output; write "not recorded" if unknown. + validations: + required: true + - type: textarea + id: retest + attributes: + label: Retest after 3–7 days / 三到七天后复测 + description: Record the retest interval, prompts removed, related task, independent result, prompts still needed, what remained, and a private evidence location. Write "not retested yet" when applicable; do not include private paths or identifying details. + validations: + required: true - type: textarea - id: delayed_result + id: transfer attributes: - label: Delayed result / 延迟结果 - description: What remained after several days, what transferred to a new situation, and what disappeared? Write "not retested yet" when applicable. + label: Changed condition and transfer / 改变条件与迁移 + description: Change one condition (topic, audience, time, material, tool permission, or purpose), then record the new task, independent result, where it failed, and the next step. Write "not attempted" when applicable. validations: required: true - type: textarea - id: revision + id: editorial_feedback attributes: - label: What should change / 哪些内容需要改变 - description: Name one unclear passage, missing boundary, weak example, unusable tool, or unnecessary section. + label: Editorial feedback / 对书稿的反馈 + description: Address six items when possible: what most supported action; what remained abstract or unusable; a missing boundary, example, or prerequisite; what could be removed or shortened; what failed when tried; and what question the next edition should answer. validations: required: true - type: checkboxes @@ -43,7 +71,15 @@ body: attributes: label: Privacy and claims / 隐私与事实 options: - - label: This note contains no private customer data, credentials, medical records, or unnecessary third-party identity details. + - label: Passwords, keys, identity documents, exact addresses, and private contact details have been removed. + required: true + - label: Customer data, company secrets, medical records, and non-public financial information have been removed. + required: true + - label: Unnecessary third-party names, photos, relationships, and identifying details have been removed. + required: true + - label: Material involving other people is authorised or reduced to non-identifying minimum facts. required: true - label: I have separated what I observed from what I infer or hope. required: true + - label: I accept that this record may remain public and searchable for a long time. + required: true diff --git a/.github/ISSUE_TEMPLATE/site.yml b/.github/ISSUE_TEMPLATE/site.yml index ea5090c0..004ea7bc 100644 --- a/.github/ISSUE_TEMPLATE/site.yml +++ b/.github/ISSUE_TEMPLATE/site.yml @@ -6,25 +6,49 @@ body: - type: input id: url attributes: - label: URL + label: URL / 页面地址 validations: required: true - type: dropdown id: type attributes: - label: Problem type + label: Problem type / 问题类型 options: - - Route or redirect - - Search - - Mobile layout - - Keyboard or screen reader - - Image or media - - Build or other + - Route or redirect / 路由或跳转 + - Search / 搜索 + - Mobile layout / 移动端布局 + - Keyboard or screen reader / 键盘或读屏 + - Image or media / 图片或媒体 + - Build or other / 构建或其他 + validations: + required: true + - type: textarea + id: environment + attributes: + label: Environment / 环境 + description: Browser and version, assistive technology, viewport or zoom, language edition, and device class. Do not include identity or private project details. / 请填写浏览器及版本、辅助技术、视口或缩放、语言版本和设备类别;不要填写身份或私人项目细节。 validations: required: true - type: textarea id: reproduce attributes: - label: Reproduction and expected result + label: Reproduction steps / 复现步骤 + description: List the smallest steps that trigger the problem. / 列出能够触发问题的最小步骤。 + validations: + required: true + - type: textarea + id: observed + attributes: + label: Observed and expected behavior / 实际与预期行为 + description: State what happened and what you expected separately. Include a short error message if useful; do not attach recordings or private data without permission. / 分开说明实际发生和预期发生的情况;必要时附简短错误信息,不要在未经授权时附录音或私人资料。 + validations: + required: true + - type: checkboxes + id: privacy + attributes: + label: Privacy check / 隐私确认 + options: + - label: I removed names, recordings, customer data, health information, credentials, and other private material from this public report. / 我已从公开报告中删除姓名、录音、客户资料、健康信息、凭据及其他私人内容。 + required: true validations: required: true diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000..eee4be65 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,46 @@ +version: 2 +updates: + - package-ecosystem: npm + directory: / + schedule: + interval: weekly + day: monday + time: "09:00" + timezone: Asia/Shanghai + open-pull-requests-limit: 3 + groups: + npm-compatible: + patterns: ["*"] + update-types: [minor, patch] + commit-message: + prefix: "chore(deps)" + + - package-ecosystem: github-actions + directory: / + schedule: + interval: weekly + day: monday + time: "09:00" + timezone: Asia/Shanghai + open-pull-requests-limit: 3 + groups: + actions-compatible: + patterns: ["*"] + update-types: [minor, patch] + commit-message: + prefix: "chore(ci)" + + - package-ecosystem: pip + directory: / + schedule: + interval: weekly + day: monday + time: "09:00" + timezone: Asia/Shanghai + open-pull-requests-limit: 3 + groups: + publication-compatible: + patterns: ["*"] + update-types: [minor, patch] + commit-message: + prefix: "chore(pdf)" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2fecc0ab..e4bdb290 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,9 +8,14 @@ on: permissions: contents: read +concurrency: + group: ci-${{ github.ref }} + cancel-in-progress: true + jobs: validate: runs-on: ubuntu-latest + timeout-minutes: 20 steps: - uses: actions/checkout@v7 - uses: actions/setup-node@v7 @@ -20,23 +25,49 @@ jobs: - uses: actions/setup-python@v6 with: python-version: "3.12" + cache: pip + cache-dependency-path: | + requirements-pdf.txt + requirements-audit.txt + - uses: actions/setup-java@v5 + with: + distribution: temurin + java-version: "21" - run: npm ci - run: python -m pip install -r requirements-pdf.txt + - run: python -m pip install -r requirements-audit.txt - run: npm audit --audit-level=high + - run: python -m pip_audit -r requirements-pdf.txt - run: npm run check - - run: npm run docs:build + - run: npm run book:validate -- --reports-dir outputs/epubcheck - uses: actions/upload-artifact@v7 + if: always() with: - name: site-preview - path: docs/.vitepress/dist/ + name: epubcheck-report + path: outputs/epubcheck/ + if-no-files-found: ignore retention-days: 14 - name: Generated files are committed run: | npm run sync:content git diff --exit-code + if [[ -n "$(git ls-files --others --exclude-standard)" ]]; then + git status --short + echo 'Generated files must be committed.' >&2 + exit 1 + fi + - run: npm run docs:build + - uses: actions/upload-artifact@v7 + with: + name: site-preview + path: docs/.vitepress/dist/ + if-no-files-found: error + retention-days: 14 smoke: runs-on: ubuntu-latest + needs: validate + timeout-minutes: 20 steps: - uses: actions/checkout@v7 - uses: actions/setup-node@v7 @@ -44,8 +75,19 @@ jobs: node-version: 24 cache: npm - run: npm ci + - uses: actions/download-artifact@v8 + with: + name: site-preview + path: docs/.vitepress/dist/ + - name: Remove stale runner Chrome apt source + run: | + while IFS= read -r source; do + sudo rm -f "$source" + done < <(sudo grep -ril 'dl\.google\.com/linux/chrome' /etc/apt/sources.list.d || true) - run: npx playwright install --with-deps chromium - run: npm run test:smoke + env: + PLAYWRIGHT_SKIP_BUILD: "1" - uses: actions/upload-artifact@v7 if: failure() with: diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index ad2ab444..a3621778 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -7,8 +7,6 @@ on: permissions: contents: read - pages: write - id-token: write concurrency: group: pages @@ -16,7 +14,11 @@ concurrency: jobs: build: + permissions: + contents: read + pages: read runs-on: ubuntu-latest + timeout-minutes: 30 steps: - uses: actions/checkout@v7 - uses: actions/setup-node@v7 @@ -26,20 +28,57 @@ jobs: - uses: actions/setup-python@v6 with: python-version: "3.12" + cache: pip + cache-dependency-path: | + requirements-pdf.txt + requirements-audit.txt + - uses: actions/setup-java@v5 + with: + distribution: temurin + java-version: "21" - uses: actions/configure-pages@v6 - run: npm ci - run: python -m pip install -r requirements-pdf.txt + - run: python -m pip install -r requirements-audit.txt - run: npm run check + - run: python -m pip_audit -r requirements-pdf.txt + - run: npm run book:validate -- --reports-dir outputs/epubcheck + - uses: actions/upload-artifact@v7 + if: always() + with: + name: deployment-epubcheck-report + path: outputs/epubcheck/ + if-no-files-found: ignore + retention-days: 14 - run: npm run docs:build + - name: Remove stale runner Chrome apt source + run: | + while IFS= read -r source; do + sudo rm -f "$source" + done < <(sudo grep -ril 'dl\.google\.com/linux/chrome' /etc/apt/sources.list.d || true) + - run: npx playwright install --with-deps chromium + - run: npm run test:smoke + env: + PLAYWRIGHT_SKIP_BUILD: "1" + - uses: actions/upload-artifact@v7 + if: failure() + with: + name: deployment-playwright-report + path: playwright-report/ + retention-days: 7 - uses: actions/upload-pages-artifact@v5 with: path: docs/.vitepress/dist deploy: + permissions: + pages: write + id-token: write environment: name: github-pages url: ${{ steps.deployment.outputs.page_url }} runs-on: ubuntu-latest + timeout-minutes: 15 needs: build steps: - name: Deploy to GitHub Pages diff --git a/.github/workflows/links.yml b/.github/workflows/links.yml index adda3fca..a9f1c503 100644 --- a/.github/workflows/links.yml +++ b/.github/workflows/links.yml @@ -12,30 +12,41 @@ permissions: jobs: links: runs-on: ubuntu-latest + timeout-minutes: 30 steps: - uses: actions/checkout@v7 - name: Verify catalog and project entry points + id: catalog run: | set -euo pipefail - { - grep -rhoE 'https://(book|movie)\.douban\.com/[^) >]+' docs/threads || true - printf '%s\n' https://token.love/ https://ku0.com/ - } | while IFS= read -r url; do - [ -z "$url" ] && continue - curl --fail --location --http1.1 --compressed \ + failed=0 + mkdir -p lychee + while IFS= read -r url; do + [ -z "$url" ] && continue + if ! curl --fail --location --http1.1 --compressed \ --retry 3 --retry-delay 5 --connect-timeout 15 --max-time 45 \ -A 'Mozilla/5.0 (compatible; Life-Level-Guide-Link-Check/1.0)' \ - -o /dev/null "$url" - done + -o /dev/null "$url"; then + printf -- '- Failed catalog or project URL: %s\n' "$url" >> lychee/catalog.md + failed=1 + fi + done < <({ + grep -rhoE --include='*.md' 'https://(book|movie)\.douban\.com/[^) >]+' docs/threads docs/en/threads || true + printf '%s\n' https://token.love/ https://ku0.com/ + } | sort -u) + exit "$failed" - name: Guard retired failure URLs + id: retired + if: ${{ !cancelled() }} run: | set -euo pipefail - if grep -REni 'scholarspace\.manoa\.hawaii\.edu|doi\.org/10\.64152/10125/66973|10\.1076/edre\.7\.1\.403\.3989|web\.archive\.org/web/20160424221725' \ + if grep -REni --include='*.md' 'scholarspace\.manoa\.hawaii\.edu|doi\.org/10\.64152/10125/66973|10\.1076/edre\.7\.1\.403\.3989|web\.archive\.org/web/20160424221725' \ ATTRIBUTIONS.md docs README.md; then echo 'A retired URL from the 193-197 failure series has returned.' >&2 exit 1 fi - uses: lycheeverse/lychee-action@v2.9.0 + if: ${{ !cancelled() }} with: args: >- --no-progress @@ -76,6 +87,22 @@ jobs: gh issue close "$issue" --repo "${{ github.repository }}" \ --comment "The latest scheduled link check passed, so this stale automation issue is now closed." done + - name: Prepare a report for every failure path + if: failure() + env: + RETIRED_RESULT: ${{ steps.retired.outcome }} + RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} + run: | + mkdir -p lychee + touch lychee/out.md + if [[ -f lychee/catalog.md ]]; then + printf '\n## Catalog and project failures\n\n' >> lychee/out.md + cat lychee/catalog.md >> lychee/out.md + fi + if [[ "$RETIRED_RESULT" == failure ]]; then + printf '\nA retired URL has returned. See the workflow log for its location.\n' >> lychee/out.md + fi + printf '\n[Inspect the failed workflow run](%s).\n' "$RUN_URL" >> lychee/out.md - uses: peter-evans/create-issue-from-file@v6 if: failure() with: diff --git a/.gitignore b/.gitignore index 1d567e1f..1654cb98 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,7 @@ .DS_Store node_modules +__pycache__/ +*.py[cod] /dist docs/.vitepress/cache/ docs/.vitepress/dist/ diff --git a/CHANGELOG.md b/CHANGELOG.md index 8e5a4a47..2f57bc30 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,56 @@ All notable project-level changes are documented here. Content pages retain thei ## Unreleased +### 2026-09-10 reader entry refinement + +#### Changed + +- Put a bilingual four-line first action at the top of the Toolkit Overview, linking directly to the complete cross-session walkthrough so readers who do not know which worksheet to use can begin without scanning the full routing table. +- Added a visible bilingual homepage speaking-plan entry, routing readers asking for oral-English practice to an unscripted baseline, listener feedback, interaction repair, and fourteen-day transfer experiment. +- Clarified the bilingual homepage project boundary: this repository publishes an open manuscript and static reading/EPUB/PDF editions; its source code supports corrections, content checks, and builds rather than requiring software installation. +- Added time-to-first-action and non-sensitive conditions to the reader field-note form and bilingual template, making future reader evidence more comparable without collecting identity or private project data. +- Regenerated both EPUB and PDF editions after the toolkit entry change and added bilingual browser assertions for the new first-use path. +- Added an npm override for `smol-toml@1.8.0`, resolving the high-severity DoS advisory reached through `markdownlint-cli2` while retaining the current Markdown lint tool. +- Added pinned `pip-audit==2.10.1` checks for the complete Python PDF dependency tree in CI and Pages builds; the current audit reports no known vulnerabilities. +- Added `READER_RESEARCH.md`, a privacy-first protocol for repeatable first-use, saved-output, return-visit, and accessibility observations; it keeps future reader evidence separate from synthetic examples and automated regression claims. +- Added a plain-language consent opening, sensitive-material stop rule, and neutral closing script to `READER_RESEARCH.md`, so maintainers can run comparable observations without teaching the route or treating silence as consent. +- Made the public reader-field-note issue form preserve immediate results, delayed retests, changed-condition transfer, and six privacy checks from the downloadable worksheet; added a contract test so the public route cannot silently drop those fields. +- Split the public site/accessibility issue form into environment, reproduction, observed-versus-expected behavior, and a required privacy check, so assistive-technology reports can be reproduced without inviting private material. +- Localized the site/accessibility issue form's labels, options, descriptions, and privacy confirmation in Chinese and English so the public feedback path matches both editions. +- Reverified the npm release channels for VitePress, Playwright, and sharp on 2026-09-10; no dependency migration is justified before the documented stable-channel or Node LTS gates. +- Added a bilingual-homepage contract test that keeps the public WCAG boundary and safe accessibility feedback route visible after future content edits. +- Added a localized, accessible recovery message and reload action when the VitePress local search index fails to load, with desktop and mobile regression coverage for both languages. +- Disabled VitePress's automatic offscreen route prefetching after a fresh-page A/B (same Chrome harness, `networkidle` plus 500 ms) showed 20 prefetch links and 31 initial requests with it enabled versus 0 prefetch links and 11 requests when disabled; navigation remains on-demand. +- Made EPUB XHTML and stylesheet direction-aware for future RTL editions, using logical blockquote properties and preserving LTR code blocks; added a generator regression without changing the current Chinese and English direction output. + +### 2026-09-09 learning tools and accessible publication + +#### Changed + +- Added 42 complete editable Markdown worksheets with bilingual download/copy controls, portable source links, and generated-file validation. Download copies are excluded from page compilation and search indexing. +- Corrected the bilingual cross-session walkthrough so its current snapshot preserves the goal, initial baseline, capacity, boundaries, and next task; made evidence access, manual saving, and the three functional acceptance conditions explicit. +- Repaired mobile focus isolation, closed-sidebar tab stops, named search dialogs and options, result announcements, and focus restoration; added axe and keyboard regressions across languages, themes, and narrow viewports. +- Removed website-only controls and invalid Vue attributes from EPUB code, preserved literal worksheet content, improved narrow-table reading, and added EPUBCheck 5.3.0 plus complete offline XHTML checks. +- Fixed PDF preformatted text clipping by wrapping at measured font widths while preserving content, whitespace, and font size; added synthetic and full-publication layout regression checks and rebuilt both publication formats. +- Recorded remaining evidence needs in `QUALITY_ROADMAP.md`, including real reader outcomes, assistive technology, device performance, and common EPUB readers. +- Added an SSR HTML page-size budget of 150,000 bytes (about 146.5 KiB) to catch route-level payload growth before it reaches the compressed Pages response; the current largest page remains below the limit. +- Updated the pinned Playwright test runtime to 1.63.0 with its Chromium 153 release and refreshed the verified test counts and maintenance evidence. +- Hardened Linux browser setup by removing any runner apt source whose contents target the unrelated Google Chrome repository before Playwright installs Chromium; a real CI failure showed the runner used a `.sources` entry rather than the initial `.list` filename assumption. + +### 2026-09-09 site and maintenance audit + +#### Changed + +- Updated pinned `sharp` to 0.35.4 to resolve its high-severity libheif advisory. +- Aligned canonical URLs and language alternates with the sitemap; repaired legacy README/Markdown routes, query and section preservation, and same-page hash changes; excluded missing pages from indexing metadata. +- Improved dark-theme link contrast, sidebar keyboard and screen-reader controls, tablet navigation, wide-table containment, and printing from dark mode. +- Replaced regular-expression-only link checks with VitePress parsing for reference links, HTML images, and real heading anchors; added calendar-date and bilingual navigation integrity checks. +- Blocked private session assets from development requests and conventional JSON, raw, URL, CSS, HTML, and `new URL()` build references, with synthetic real-build regression fixtures. +- Made missing generated mirrors recoverable without mutating check-only runs, preserved word-list editorial dates, and reported invalid explicit PDF interpreters without a silent fallback. +- Added fast Node regression tests to the standard check; made CI smoke tests reuse the validated artifact, required browser tests before Pages upload, and completed external-link failure reporting. +- Documented environment setup, explicit browser and preview selection, and the full audit in `PROJECT_REVIEW.md`. +- Added weekly grouped Dependabot updates for npm, Actions, and Python, plus source-checked migration criteria for the next Node LTS, stable VitePress 2, and accessibility standards; dependency changes remain subject to review and publication checks. + ### 2026-09-07 link-audit hardening #### Changed diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 2981e1b0..79559955 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -6,12 +6,18 @@ Thank you for improving this open-content project. Contributions should make a c 1. Use Node 24: `nvm use` or your preferred version manager. 2. Install exactly from the lock file: `npm ci`. -3. Create a focused branch and avoid unrelated formatting or media changes. -4. Run `npm run sync` after changing navigation, the Chinese homepage, or a Chinese word list. -5. Run `npm run check`, `npm run docs:build`, and `npm run test:smoke`. +3. Install the browser used by smoke tests: `npx playwright install chromium` (Linux CI uses `--with-deps`). +4. Use Python 3.12 with `python3 -m pip install -r requirements-pdf.txt` for PDF validation. A virtual environment is recommended; set `PDF_PYTHON=/absolute/path/to/venv/bin/python` to select it explicitly. Install `requirements-audit.txt` and run `python -m pip_audit -r requirements-pdf.txt` when checking the complete publication dependency tree. Keep `pip-audit==2.10.1` pinned; if your package index cannot resolve it, use an approved index that can or rely on the CI result rather than silently downgrading the audit tool. +5. Create a focused branch and avoid unrelated formatting or media changes. +6. Run `npm run sync` after changing navigation, the Chinese homepage, or a Chinese word list. +7. Run `npm run check`, `npm run docs:build`, and `npm run test:smoke`. + +`npm run test:unit` runs fast content, routing, and build-tool regressions without a browser and is included in `npm run check`. Smoke tests build a fresh site and start their own preview by default. After a successful build, use `PLAYWRIGHT_SKIP_BUILD=1 npm run test:smoke` to test that artifact. To reuse a preview you have explicitly refreshed, also set `PLAYWRIGHT_REUSE_SERVER=1`. An installed Google Chrome can be selected with `PLAYWRIGHT_CHANNEL=chrome`; CI uses the Playwright-managed Chromium version. ## Content Standard +EPUB changes also require `npm run book:validate`, using Java 21 (or `EPUBCHECK_JAVA` to select a runtime). CI enforces the pinned EPUBCheck version with zero errors and warnings. Use `-- --reports-dir outputs/epubcheck` to preserve its JSON reports locally. Editable worksheet downloads are generated by `npm run sync:worksheets` from the template source; do not edit files under `docs/public/downloads/worksheets/` directly. + - Separate research findings, personal experience, and hypotheses. - For factual or product claims, prefer primary sources and include an access/update date. - State population, conditions, outcome, and uncertainty when summarising research. diff --git a/MAINTENANCE.md b/MAINTENANCE.md index b10e9ec6..9845ef3d 100644 --- a/MAINTENANCE.md +++ b/MAINTENANCE.md @@ -20,12 +20,20 @@ - 使用 Node.js 24,版本约束见 `.nvmrc`、`.node-version` 和 `package.json`。 - GitHub Actions 使用 Node.js 24 兼容的官方 major 版本;升级 action 前先查对应仓库的 release,升级后运行 CI、Pages 部署和外链检查。 - 首次安装运行 `npm ci`。 +- 浏览器测试首次运行前执行 `npx playwright install chromium`;Linux CI 使用 `npx playwright install --with-deps chromium`。 +- PDF 校验使用 Python 3.12,建议在虚拟环境中安装 `requirements-pdf.txt`。可以设置 `PDF_PYTHON` 指定解释器;显式指定的解释器不可用时会直接报错,避免静默切换环境。 +- 依赖审计工具由 `requirements-audit.txt` 锁定为 `pip-audit==2.10.1`。如果本机包索引无法解析该版本,不要静默降级到旧版本;改用组织批准且能解析锁定版本的索引,或以 GitHub Actions 的 Python 3.12 门禁为权威结果,并记录环境差异。 - 本地开发运行 `npm run docs:dev`。 +- 快速脚本回归运行 `npm run test:unit`,已包含在完整校验中。 +- 模板下载运行 `npm run sync:worksheets` 生成,`npm run check:worksheets` 检查同步;两者已分别纳入 `sync:content` 和 `check`。 +- EPUB 独立标准检查运行 `npm run book:validate`,需要 Java 21 或兼容运行时;可用 `EPUBCHECK_JAVA` 指定 Java。命令固定 EPUBCheck 5.3.0 并验证下载 ZIP 的 SHA256,可用 `--reports-dir outputs/epubcheck` 保留 JSON 报告。CI 与 Pages 发布都要求零错误、零警告。 - 完整校验运行 `npm run check`。 - 生产构建运行 `npm run docs:build`;构建完成后会自动检查搜索索引、框架和主题脚本的原始与 gzip 体积预算。 - 本地预览生产产物运行 `npm run docs:preview`。 - 端到端测试运行 `npm run test:smoke`。 +烟测默认使用 Playwright 管理的 Chromium,并重新构建、启动独立预览,避免误测旧服务器。刚完成生产构建后可设置 `PLAYWRIGHT_SKIP_BUILD=1` 复用磁盘产物;明确要连接已更新的本地预览时再设置 `PLAYWRIGHT_REUSE_SERVER=1`。本机也可通过 `PLAYWRIGHT_CHANNEL=chrome` 显式使用 Google Chrome。 + ## 导航与生成文件 `docs/.vitepress/navigation.mjs` 是中英文导航的唯一来源。修改导航后运行: @@ -41,14 +49,17 @@ npm run sync - `docs/en/SUMMARY.md`; - 根目录 `README.md`; - 英文词表镜像; -- VitePress `public` 分享图。 +- VitePress `public` 分享图; +- 中英文完整工作表 Markdown 下载。 CI 会再次生成这些文件,并阻止未提交的差异进入主分支。 + +`docs/public/downloads/worksheets/` 是生成的下载目录,由中英文模板导航和源文决定。不要直接编辑下载文件;生成器保留说明、GFM 表格、复选框和提示词,将填写用 Markdown 代码块展开并保留逐行字段,站内链接转换为可从本地文件使用的在线地址。`toolkit` 和 `toolkit-walkthrough` 是使用说明,不作为空白工作表提供下载。`public/**` 明确排除在网页编译和搜索之外,避免下载副本被重复索引;独立同步检查保证它们未漂移。 同步脚本还会检查每个导航条目的字段、重复链接和 `source` 文件是否存在;路径写错时会在 `npm run check:navigation` 阶段失败。 它还会反向检查 `docs/` 下的所有公开 Markdown 是否都被中英文导航收录,避免新页面成为孤岛。 Playwright 的 `test-results/` 和 `playwright-report/` 只保存失败诊断与 HTML 报告,属于生成文件,不是书稿内容;它们已被 Git 和 Markdown lint 忽略。测试失败后可以安全清理,再重新运行 `npm run check`。 -本地会话凭据文件 `docs/assets/session.json` 被精确加入 `.gitignore`,并由 VitePress 开发服务器、构建钩子和浏览器烟测共同拦截;任何本地会话文件都不得进入仓库或站点产物。 +本地会话凭据文件 `docs/assets/session.json` 被精确加入 `.gitignore`,并由 VitePress 开发服务器、文件访问规则、构建导入拦截和浏览器烟测共同保护。`raw`、`url` 等导入方式也会被拒绝,避免凭据以带哈希的文件名进入产物;畸形 URL 返回请求错误。任何本地会话文件都不得进入仓库或站点产物。 本地搜索按读者任务控制索引粒度:第二至第五部保留 H2 级入口;第一部已经按技能拆成独立页面,工具模板、术语、归档和词表使用页面级入口。H3 正文仍会并入所属页面或 H2,因此关键词不会消失。代码块不进入倒排索引,避免复制用工作表和重复示例放大下载体积。调整规则后必须运行 `npm run docs:build`,并确认 `check:bundle` 通过。 @@ -63,6 +74,8 @@ Playwright 的 `test-results/` 和 `playwright-report/` 只保存失败诊断与 - 图片必须有描述场景或用途的替代文本;`image`、`photo`、`hotel` 等占位词会被内容校验拒绝,英文页面的 alt 也不得混入中文字符。图片不得包含 GPS、EXIF、IPTC 或 XMP 元数据。构建会为本地位图自动注入真实宽高以预留版面,外链图片和 SVG 不推测尺寸。 - 英文正文应优先使用英文表达;语言切换标签、书名/产品的官方原名和无法可靠翻译的专名可以保留原文,并在需要时提供英文解释。 - 站内链接使用 VitePress 干净路径,不新增 `#/` 路由;旧 hash 链接仅由兼容脚本处理。 +- 规范网址、语言替代网址和站点地图使用同一组公开路由规则:文章无尾斜杠,首页和归档目录保留尾斜杠。历史 `README`、`.md`、查询参数与章节锚点由兼容跳转保留。 +- 站内目标通过 Markdown 解析器检查,覆盖引用式链接、HTML 图片、下载文件和页面锚点;代码示例中的伪链接不会被当成正文链接。日期必须是真实日历日期,`updated` 和 `sources_checked` 均不得晚于项目时区当天。 - 外部素材必须登记在 `ATTRIBUTIONS.md`,无法确认再分发权限时不进入仓库。 - `check-content.mjs` 会验证归属表中明确写出的本地路径;删除或移动素材时必须同步更新登记,合法 glob 路径除外。 - `check-content.mjs` 还会检查 `docs/assets/` 中的图片和 SVG 是否被正文、配置或构建脚本引用;归属表和变更记录不会把文件伪装成正在使用的资产。 @@ -95,6 +108,8 @@ Playwright 的 `test-results/` 和 `playwright-report/` 只保存失败诊断与 3. 合并到 `master` 后,由 GitHub Pages Actions 工作流部署。 4. 部署后检查中文首页、英文首页、代表性章节、搜索、语言切换和旧 hash 跳转。 +CI 的浏览器测试下载并验证内容校验任务生成的同一份站点产物,避免重复构建造成差异。Pages 工作流也会在上传待发布产物前完成浏览器测试;脚本回归或浏览器测试失败时不会进入发布。生成文件检查同时检查已跟踪差异与未跟踪文件,避免遗漏新生成的输出。 + 仓库的 Pages 发布源必须保持为 **GitHub Actions**,不要切回 `master:/docs` 的 Legacy 模式;`deploy.yml` 会在发布后请求中文首页、英文首页和代表性章节,并校验每个入口的期望标题与当前提交的 `build-revision`。正文使用 VitePress clean URLs,文章入口按无尾斜杠路径检查;任何公开入口返回非成功状态、错误页面或旧构建标识都会使部署失败。 Pages 发布组启用 `cancel-in-progress`:快速连续提交时,旧的构建或部署会被取消,只允许最新提交继续发布。需要回看旧版本时,应从 Git 历史或 CI 构建产物查看,不要依赖线上页面暂时保留旧内容。 @@ -103,11 +118,24 @@ GitHub Actions 不包含分析脚本、广告或用户追踪器。 ## 定期维护 +真实读者观察按 [READER_RESEARCH.md](READER_RESEARCH.md) 执行:先取得自愿同意,记录首次行动和延迟回访,最少收集非敏感条件,按期删除原始材料,并把每项产品改变连接到回归检查。不要把公开 issue、个人故事或一次顺利体验当成独立效果研究。 + - 每周定时任务检查外链;Douban、`token.love` 和 `ku0.com` 由浏览器 User-Agent 的独立 `curl` 探针检查,Lychee 负责其余外链。第三方站点短暂失败不会阻塞普通提交,但会留下可追踪的自动 issue。 - 每月至少检查一次 AI 章节;超过 120 天未更新会被内容校验阻止。 - 每季度检查依赖、安全公告、素材授权和无障碍回归。 - 合并图片前先运行 `npm run assets:sanitize`,再执行完整校验。 +`.github/dependabot.yml` 在进入默认分支后每周检查 npm、GitHub Actions 和 Python 出版依赖,兼容的 minor/patch 更新按生态合并为 PR,每个生态最多保留 3 个版本更新 PR;主版本更新单独评估。它不自动合并或部署。PDF/字体依赖更新仍须通过出版物语义、文件清单与必要的排版复核,不能只看包版本是否最新。 + +运行 `npm run book:validate -- --reports-dir outputs/epubcheck` 可以保存 EPUBCheck JSON 报告。该命令固定并校验官方 EPUBCheck 5.3.0 发布档案;需要 Java 21。CI 和 Pages 发布在上传产物前执行同一门禁。 + +### 技术演进条件(2026-09-10 核验) + +- 2026-09-10 通过 [npm dist-tags](https://registry.npmjs.org/-/package/vitepress/dist-tags) 核验:VitePress `latest` 仍为 1.6.4,`next` 为 2.0.0-alpha.20;当前锁定的 Playwright 1.63.0 与 sharp 0.35.4 也分别匹配 npm 当前版本。待 VitePress 2.x 进入稳定通道后,再单独检查 Vite 配置、主题选择器、原生导航语义、搜索索引、Markdown 锚点和干净路径,满足现有门禁后迁移。判断稳定性同时检查版本号及官方 dist-tags,不只依赖 GitHub release 的标志位。 +- [Node.js 官方支持计划](https://github.com/nodejs/Release/blob/main/schedule.json)列出 Node 24 于 2026-10-20 进入维护期、2028-04-30 结束支持;Node 26 计划在 2026-10-28 进入 LTS。维护期继续接收安全维护;新 LTS 可用且依赖兼容后,再同步评估本地版本约束和 CI 环境。 +- 无障碍检查以 [WCAG 2.2](https://www.w3.org/TR/WCAG22/) AA 为目标,结合自动检查与键盘、读屏、缩放和重排复核。当前通过的回归不等于完整 WCAG 合规认证。[WCAG 3](https://www.w3.org/TR/wcag-3.0/)仍为 Working Draft,跟踪进展,不作为正式合规声明。 +- 保持预渲染 HTML、本地搜索、稳定双语 URL 和离线出版的路线。引入远程搜索、统计或 AI 功能前,应确认读者任务、资源成本和数据需求,遵循 [W3C 数据最小化原则](https://www.w3.org/TR/privacy-principles/#data-minimization)。 + ## 回滚 迁移前的 Docsify 版本保留在 Git 历史提交 `42e6faa` 中,包括原 `docs/index.html`。若新站点发布后出现路径或索引故障,优先在 GitHub Pages 中重新运行上一次成功部署;需要恢复旧站时,从该提交创建临时回滚分支并部署其 `docs/` 目录,不覆盖当前内容分支。 diff --git a/PROJECT_REVIEW.md b/PROJECT_REVIEW.md new file mode 100644 index 00000000..c682a677 --- /dev/null +++ b/PROJECT_REVIEW.md @@ -0,0 +1,84 @@ +# 项目全面审查与优化记录 + +审查日期:2026-09-10(Asia/Shanghai)。对象:当前本地工作区,优化位于 `codex/project-audit-20260909` 分支,结果不代表已部署到线上。 + +提交前独立复核未发现必须修复的发布阻塞;当前提交已通过 58 项 Node 测试、6 项 PDF 布局测试、177 个 Markdown 检查和工作流门禁。正式托管平台验证以对应提交的 GitHub Actions 结果为准。 + +## 项目定位与架构 + +本项目已从英语学习资料演进为《人生进阶指南》开放书稿。当前架构适合以阅读、检索、练习模板和离线下载为主的产品: + +- 内容层:78 对中英文公开页面,按 10 个导航分组组织;每个语言版本的出版物包含 62 个章节或附录条目。 +- 网站层:VitePress 1.6.4、Vue 主题扩展、本地双语搜索、阅读进度、打印样式、语言切换和历史地址兼容。 +- 出版层:共享导航生成目录、README 镜像和 EPUB;Python 工具生成并核验 PDF,清单约束发布文件的哈希与语义。 +- 工程层:Node 24、锁定依赖、内容规则、资源预算、桌面/移动浏览器测试,以及 CI、Pages 和定期外链检查。 + +现有优势是内容结构统一、双语覆盖完整、离线出版有确定性校验、搜索资源已有体积预算。优化应优先填补验证盲区、修复可复现的体验问题,并减少本地与 CI 的环境差异。 + +## 已发现问题与实施结果 + +| 领域 | 原问题与证据 | 本次修复 | +| --- | --- | --- | +| 依赖安全 | `npm audit` 报告直接依赖 `sharp@0.35.3` 存在 1 个高危告警 | 升级到锁定的 `0.35.4`;复查告警为 0 | +| 旧地址兼容 | 浏览器实测 `#/README`、`#/…/1-understanding.md` 进入 404;`?id=` 锚点被丢弃 | 统一处理 README/index、扩展名、英文旧章节、查询参数与锚点;兼容当前页面内的 hash 变化 | +| 搜索引擎元数据 | 文章 canonical/hreflang 带尾斜杠,站点地图使用无尾斜杠地址 | 文章、首页和归档采用一致路由规则;增加全部双语页面的元数据与 sitemap 对照检查;404 不再输出书稿结构化数据并标记 noindex | +| 暗色阅读 | 正文链接对比度约 2.83:1,悬停约 2.17:1 | 设置暗色品牌与提示颜色,正文链接对比度提高到约 9.68:1,悬停约 11.91:1 | +| 键盘与读屏 | 侧栏分组缺少展开状态、空格键无效、同一分组出现重复焦点 | 补充 `aria-expanded`/`aria-controls`,支持 Space/Enter,保留鼠标操作,移除重复 Tab 停靠点 | +| 响应式表格 | 7 列英文模板在 641px 视口将页面撑到约 986px,部分桌面宽度侵入目录区域 | 所有屏幕尺寸均让宽表格在内部滚动,保持页面宽度;增加中间断点回归 | +| 打印 | 暗色模式打印会保留深色表格底色;移动端表格与代码样式不适合纸面 | 独立设置浅色打印变量、表格布局与换行规则,确保正文、表格、引用和代码可读 | +| 内容完整性 | 正则检查遗漏引用式链接、HTML 图片源和章节锚点;部分合法目录/下载路径无法正确解析 | 使用 VitePress Markdown 解析器,校验真实链接目标与标题 ID,跳过代码示例,覆盖双语首页、归档与下载 | +| 日期与导航 | 格式校验会接受不存在的日期和未来核验日期,缺少导航来源/顺序的完整对照 | 校验真实日历、项目时区、120 天边界和双语导航顺序、重复来源及实际目标 | +| 私有资产 | 原先按固定输出名称删除会话文件,无法阻止 raw/url、CSS、HTML、`new URL()` 引用产生内联或带哈希的资源 | 在常规资产转换前拦截引用,结合导入/产物检查、开发文件访问规则和畸形请求处理;回归使用路径及合成数据,不读取实际凭据 | +| 生成工具 | 缺失镜像无法由同步命令恢复;只检查模式会创建目录;词表同步可能覆盖编辑日期 | 同步命令可重建缺失输出,只检查模式保持只读,保留中英文一致的稿件日期 | +| 环境可重复性 | 本地默认依赖系统 Chrome;错误 `PDF_PYTHON` 被静默忽略;已有预览可能是旧版本 | 默认使用 Playwright 管理的 Chromium;浏览器/预览复用需显式选择;显式 Python 配置失败直接报错 | +| CI 与发布 | CI 重复构建,Pages 上传前没有浏览器测试,生成文件检查遗漏未跟踪输出 | CI 测试同一构建产物;部署前完成 smoke;增加运行超时和未跟踪文件检查 | +| 定期外链检查 | 前置 curl 失败后其余检查跳过,失败报告文件可能不存在 | 汇总前置失败,继续执行独立检查,为各类失败生成可追踪报告 | + +依赖修复依据:[GitHub 官方安全公告 GHSA-rgj7-g3m4-5g8c](https://github.com/advisories/GHSA-rgj7-g3m4-5g8c)以及 `smol-toml` 的高危 DoS 公告。`sharp` 升级到 0.35.4,并通过 npm override 锁定 `smol-toml` 1.8.0;本次未扩大到无关依赖的大版本迁移。 + +## 验证方法 + +基线阶段,原有 174 个 Markdown 文件、导航、README、EPUB、PDF 语义及发布哈希检查通过,原生产构建和资源预算通过。新问题通过额外审查和具体复现发现,说明原检查通过并不足以覆盖上述行为。 + +本次新增三类脚本回归:内容解析与日期、构建同步与 Python 环境、路由与私有资源拦截。浏览器回归新增全站元数据一致性、历史链接、404、浅深色对比度、侧栏键盘操作、打印与表格断点。原有全站页面、检索、导航和出版物下载测试继续保留。 + +已完成的验证结果: + +- Node 脚本回归:58/58 通过,其中 13 项使用真实 Vite 构建检查私有资产的内联与文件输出路径;另有 6 项 PDF 布局回归通过。 +- 桌面与移动端浏览器回归:554/554 通过,完整运行耗时约 7.5 分钟;本机验收使用 Chrome,自动重新构建并启动独立生产预览,Linux CI 使用 Playwright 管理的 Chromium。 +- 内容与格式:177 个 Markdown 文件通过;导航、README、词表和品牌资源保持同步。 +- 离线出版:EPUB 同步检查、PDF 语义检查和已发布文件哈希检查通过。 +- 生产构建与体积预算:通过。中文搜索约 565.5 KiB 原始 / 166.6 KiB gzip,英文约 454.7 KiB / 97.8 KiB;主题脚本约 56.5 KiB / 16.7 KiB,均在现有预算内。 +- 依赖审计:0 个已知漏洞;Git 差异空白检查通过。 +- 人工图像复核:暗色正文与平板表格可读;768px 页面宽度实测仍为 768px,检查页面未出现客户端运行错误。 + +首次整测确认旧预览进程会缓存之前的资源清单;重建磁盘产物后仅复用该进程可能导致脚本和样式加载失败。最终浏览器验收采用重新构建并重新启动的独立预览,因此维护文档要求显式复用服务时同时确保进程对应当前产物。 + +完整复验命令: + +```bash +npm run check +npm run docs:build +npm run test:smoke +npm audit --audit-level=high +git diff --check +``` + +本机可用 `PLAYWRIGHT_CHANNEL=chrome` 选择已安装的 Chrome;显式复用刚完成构建的预览时同时设置 `PLAYWRIGHT_REUSE_SERVER=1`。CI 使用锁定 Playwright 对应的 Chromium。具体环境准备见 [CONTRIBUTING.md](CONTRIBUTING.md) 与 [MAINTENANCE.md](MAINTENANCE.md)。 + +## 维护建议与审查边界 + +1. 把脚本与浏览器回归作为持续维护的一部分。新增路径、模板、图像或日期规则时,优先补行为用例,避免只断言源码中是否存在一句话。 +2. 保持搜索索引按语言延迟加载和现有预算。当前中文搜索仍是最大的单个可选下载;扩充书稿时继续观察原始与 gzip 体积,不通过放大预算掩盖增长。 +3. 保持导航为唯一来源。此次没有为追求改动数量而重写已通过审查的双语书稿,也没有更改 PDF/EPUB 正文或出版布局。 +4. 定期检查外部来源。此轮验证了站内链接与来源日期规则,没有逐条重新核实所有外部研究、产品说明和推荐链接,因此没有批量刷新 `sources_checked`。 +5. 本地验证不能替代托管平台实跑。优化分支通过 PR 执行远端 CI;合并到默认分支后才触发 Pages 发布,部署仍须通过浏览器和线上入口验证。 +6. 私有文件保护用于防止本项目会话文件通过开发访问和常规构建引用意外公开。它不替代通用凭据扫描,也不把不可信的构建插件变成安全沙箱。 + +## 最新资料与后续演进 + +2026-09-10 直接核验官方文档及 npm API:VitePress 稳定通道仍为 1.6.4,2.0.0-alpha.20 属于下一代预览;Node 24 仍在支持期,Node 26 计划于 2026-10-28 进入 LTS;WCAG 2.2 是正式推荐标准,WCAG 3 仍为草案。对应来源和升级门槛已写入 [技术演进条件](MAINTENANCE.md#技术演进条件-2026-09-10-核验)。 + +已升级到 [Playwright 1.63.0](https://github.com/microsoft/playwright/releases/tag/v1.63.0) 稳定版本,并在本地脚本、生产构建和完整浏览器回归中验证;它带来 Chromium 153 配套版本。升级后的 Linux CI 会再次验证托管 Chromium,避免测试运行时与浏览器版本漂移。 + +新增 `.github/dependabot.yml`,按 [GitHub 官方配置规则](https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file) 每周检查 npm、Actions、pip,合并兼容更新、限制积压并保留人工审核。该配置进入默认分支后生效;不自动合并、不自动绕过出版和发布门禁。 diff --git a/QUALITY_ROADMAP.md b/QUALITY_ROADMAP.md new file mode 100644 index 00000000..cba917b1 --- /dev/null +++ b/QUALITY_ROADMAP.md @@ -0,0 +1,53 @@ +# 持续质量目标与证据 + +目标:把《人生进阶指南》持续提升为值得信赖、容易使用、能够帮助读者形成实际学习证据的开放双语作品。达到世界一流水准需要内容、真实使用结果、可访问性、性能和出版可靠性共同成立,单次构建或自动测试通过不能完成这一判断。 + +## 当前已建立的证据 + +- 58 项 Node 脚本回归和 6 项 PDF 布局回归覆盖内容解析、生成同步、私有资源、路由、EPUB(含未来 RTL 方向契约)、PDF、公开读者回执、无障碍反馈和双语首页边界契约;内容检查覆盖 177 个 Markdown,格式检查同时覆盖 42 份生成的工作表。 +- 代表性桌面和移动页面、双语搜索、模板下载/复制、双主题、键盘操作、离屏预取门禁和 320px 重排都有浏览器回归;上一轮完整站点回归为 554/554,使用 Playwright 1.63.0 与 Chromium 153。 +- 两种 EPUB 通过固定版本 EPUBCheck 5.3.0 的零错误、零警告检查,130 个 XHTML 通过断网小屏阅读检查;PDF 代码边界与受影响页面有实际渲染复核。 +- CI 使用同一构建产物完成 Linux 浏览器测试;依赖、外链、生成文件和发布入口均有自动门禁。 +- Linux CI browser setup removes an unrelated stale runner Google Chrome apt source before installing the pinned Playwright Chromium dependency; this was added after a real runner hash-mismatch failure, not as a speculative workaround. +- 生产构建现在还限制每个 SSR HTML 页面为 150,000 bytes 原始大小(约 146.5 KiB),防止预渲染页面无意中膨胀;本次最大页面约 114 KiB,低于门禁。 +- npm audit 当前为 0 vulnerabilities;`markdownlint-cli2` 通过 `smol-toml@1.8.0` override 避免了传递依赖的高危 DoS 版本,且 58 项脚本测试与格式检查仍通过。 +- Python 3.12 的 `pip-audit==2.10.1` 已对完整 `requirements-pdf.txt` 依赖树检查通过(No known vulnerabilities found),并已加入 CI/Pages 门禁。 + +## 真实反馈到产品决策 + +- [Issue 190](https://github.com/byoungd/up/issues/190) 描述长期学习跨会话状态丢失。已转成完整学习状态模板、跨会话 Python 实战、可编辑下载和“路径不等于 AI 已读证据”的边界说明;仍需要真实读者复测保存和恢复流程。 +- [Issue 172](https://github.com/byoungd/up/issues/172) 说工具不知道怎样使用。已在工具箱首屏提供四行最小动作、完整 walkthrough 和 42 份可编辑工作表;仍需要观察第一次使用者能否在一次访问内完成最小输出。 +- [Issue 173](https://github.com/byoungd/up/issues/173) 询问初中阶段学习方法。家庭学习篇、共同协议和首页入口已覆盖学习者主体性、家长边界、学校现实、数据隐私和十四天复查;不能把成人案例直接当成儿童效果证据。 +- [Issue 151](https://github.com/byoungd/up/issues/151) 请求口语方案。首页现在直接进入无稿基线、陌生追问、听众复述、互动修复和十四天迁移;仍需要真实听众反馈,而不是把录音或语音识别分数当成能力证明。 +- [Issue 178](https://github.com/byoungd/up/issues/178) 提议外部医疗英语工具。当前没有把第三方考试或医疗资源直接加入主线,因为供应方、认证、隐私、医学边界和长期可用性尚未完成独立核验;若纳入,必须保留第三方标识、官方来源、核验日期和不构成专业/考试保证的边界。 + +具体的招募、任务脚本、数据最小化、停止条件和分析记录见 [READER_RESEARCH.md](READER_RESEARCH.md)。它为后续真实读者观察提供可重复起点,不把当前自动化测试或合成案例包装成效果研究。 + +## 尚需继续取得的证据 + +| 维度 | 下一项有价值的验证 | +| --- | --- | +| 实际学习使用 | 对新读者观察从首次进入到完成首版、保存证据和一周回访的流程;保留失败和中断,不用合成案例代替效果证据 | +| 内容与双语质量 | 逐章检查论证、重复、认知负担与翻译自然度;外部研究和产品资料按实际核验日期更新 | +| 可访问性 | 以 WCAG 2.2 AA 为目标继续做读屏、缩放、重排和辅助技术人工检查;axe 零违规不等于完整合规认证 | +| 性能 | 在低速网络和中端设备测量首次阅读、翻页与搜索,再按读者任务优化资源;包体预算不能代替真实性能指标 | +| 出版与离线使用 | 在常用阅读器中复查字号、链接、表格、代码、图片、字体回退和辅助阅读功能;当前 EPUB 只覆盖中英文,RTL `dir`、嵌入字体缺失时的字形与混排仍未验证;保持 EPUBCheck、离线 XHTML 和 PDF 检查 | +| 可信维护 | 继续跟踪 Node 支持期、稳定 VitePress、浏览器和 Python 出版依赖;每次更新都经过独立 PR 与完整门禁 | + +### 本地网络基线(2026-09-10) + +在新 Chromium context 中以 Chrome DevTools 网络模拟器测量刚完成的生产构建预览;每个路由独立冷启动,未把本地服务器的未压缩字节误报为线上 CDN 结果。关闭离屏路由预取后,Chrome 152、Service Worker 禁用的冷启动中文首页约 17 个请求、约 162 KiB CDP 编码传输(资源 timing 约 144 KiB),英文长章约 19 个请求、约 312 KiB;此前开启预取时的 46/48 个请求和 451/607 KiB 记录已废弃。Fast 3G(200 kB/s、150 ms)下,中文首页与英文长章的 FCP/LCP 约 0.96/0.96 s 与 0.93/0.93 s;Slow 3G(62.5 kB/s、400 ms)下约 2.19/2.19 s 与 2.20/2.20 s。首次打开搜索还会按需增加约 148 KiB 索引传输,必须与首屏阅读分开评估。项目已关闭离屏路由自动预取,后续导航仍按点击按需加载;这些是本地预览基线,不代表已部署到 GitHub Pages。 + +这些数值说明首屏 HTML 仍是主要传输项,搜索索引已经明确延迟到用户打开搜索时载入。下一步应在真实 Pages/CDN 响应和中端设备上复测,并记录 gzip、LCP、缓存命中和搜索打开延迟;当前证据不足以支持重写渲染或引入新的性能架构。 + +### 当前 GitHub Pages 生产基线(2026-09-10) + +从 `https://byoungd.github.io/up/` 实测的是默认分支当时已发布的 `7478ac2`,不是本审查分支。2026-09-10 重测中文首页、英文首页、代表性章节和学习状态模板,四个入口仍返回 `build-revision=7478ac2b740cba5d423ebf61143f14442b278725`,`last-modified: Mon, 07 Sep 2026 13:43:11 GMT`;因此本 PR 的工作表、无障碍反馈、预取和出版物改动尚未部署。Pages/varnish 对四个代表性 HTML 入口返回 gzip、`cache-control: max-age=600`、`vary: Accept-Encoding`;压缩传输大小分别约为中文首页 22.1 KiB、英文首页 21.8 KiB、阅读篇 22.5 KiB、学习状态模板 15.2 KiB。静态 CSS 约 20.4 KiB gzip,框架脚本约 43.8 KiB gzip。页面和静态资源均返回成功状态,响应含 `etag` 与 `last-modified`。 + +该生产观测证明 Pages 的压缩和缓存链路正在工作,但由于线上仍是默认分支,不能用它证明本分支的新工作表、无障碍或出版物已部署。合并后应重新核对 `build-revision`、同一路由的 gzip 大小和缓存头,并将真实设备 LCP 与本地基线分开记录。 + +## 演进边界 + +当前路线保持预渲染 HTML、本地搜索、稳定双语 URL、私有优先记录和 EPUB/PDF 离线出版。只有当真实读者任务证明必要时,才引入远程搜索、统计、账户或 AI 服务,并先评估数据最小化、成本、失败回滚和维护负担。 + +本文件记录质量证据和未决工作,避免把一次绿色构建误称为“世界顶级已完成”。 diff --git a/READER_RESEARCH.md b/READER_RESEARCH.md new file mode 100644 index 00000000..f1c706a5 --- /dev/null +++ b/READER_RESEARCH.md @@ -0,0 +1,69 @@ +# Reader research protocol + +This protocol turns the remaining quality question into a small, privacy-preserving observation: can a new reader find the right entry, complete a first useful action, preserve evidence, and return to the task later? It is a research aid for maintainers, not a claim that the book works for everyone. + +## Before inviting anyone + +- Ask for voluntary participation and explain the purpose, duration, recording choice, retention period, and deletion contact in plain language. +- Do not require an account, public post, screen recording, voice recording, location, employer, school, health, relationship, financial, customer, or private project information. +- Use a synthetic task or the participant's own non-sensitive task. Let the participant skip a question or stop without explaining why. +- Collect only a random session code, language edition, device class, viewport/zoom condition, starting question, and the minimum outcome needed to improve the path. +- Store notes privately with access limited to the maintainers who need them. Delete raw recordings and identifying notes after the stated retention period; retain only de-identified findings and the decision they changed. + +## Plain-language opening script + +Read this before the first task and invite questions: + +> This is a voluntary 25–35 minute usability observation of the reading path. I am testing the pages and instructions, not your intelligence, English level, work, or learning outcome. You may skip any question, stop at any time, or ask me to delete your notes under the retention plan we just discussed. Please use a non-sensitive task and do not show passwords, customer information, health details, private messages, or anything you are not authorised to share. I will record only a random session code and the minimum non-sensitive conditions needed to improve the path. May we begin? + +Do not treat silence as consent. Record the participant's yes, no, or decision to stop before continuing. If the participant reveals sensitive material, pause the task, ask them to close or redact it, and do not copy it into the observation record. + +## One 25–35 minute session + +1. **Entry:** Give the reader only a realistic question, such as “I want a first speaking practice task” or “I need to carry a Python learning state into a new AI conversation.” Do not explain the correct route. +2. **Find:** Record the first page they choose, the time to first meaningful action, and every place they hesitate or backtrack. Do not correct them during this phase. +3. **Act:** Ask them to complete one small output: fill the four-line start, save a baseline, or download/copy one worksheet. Record whether they know what completion means without maintainer help. +4. **Return:** Ask them to close the page and describe what they would bring to a new session or a seven-day retest. Check whether they can locate the saved worksheet and its next review point. +5. **Debrief:** Ask which wording, field, route, or boundary was unclear; distinguish observed behavior from the participant's interpretation and preference. + +Use a task script with the same wording for comparable sessions. A maintainer may clarify safety or privacy, but should not silently teach the intended route during the first attempt. + +## Neutral closing script + +End with the same questions each time: + +> The observation is complete. Before I explain anything, what would you carry into a new session or a seven-day retest? Which wording, route, field, or boundary was unclear? Is there anything in my notes you want removed? I will separate what I observed from what you think it means, and I will not publish a quote, image, recording, or identifying detail without separate permission. + +Only after the participant answers may the maintainer explain the intended route or show an alternative. Record that explanation as post-task assistance; do not rewrite the first-attempt result. + +## Minimum observation record + +```markdown +Session code: +Date and language edition: +Device class / viewport / zoom: +Starting question: +First route and time to first meaningful action: +First saved output and time: +Where the reader hesitated or backtracked: +What the reader thought the completion standard was: +What they would carry into a new session: +Seven-day retest status: not yet / attempted / completed / stopped +Observed facts: +Participant interpretation or preference: +Privacy-safe product change considered: +Decision: keep / revise / remove / gather more evidence +Evidence retained after deletion: +``` + +Do not convert one person's preference into a universal rule. Look for repeated task failures across at least three readers or two independent sessions before changing shared navigation, wording, or safeguards. A single severe privacy, safety, or accessibility failure is an immediate stop condition even without repetition. + +## Analysis and release gate + +Group findings by task and language, then compare first route, time to first action, completion, abandonment, and delayed return. Preserve counterexamples and failed attempts. For every proposed change, write the observed trigger, the smallest change, the risk introduced, and the regression test or manual check that will catch it. + +After a change, repeat the same task script with a fresh reader or a deliberately different condition. Do not publish participant quotes, screenshots, recordings, or outcome claims without explicit permission and a separate privacy review. Do not describe this protocol as a clinical, educational, hiring, or efficacy study. + +## English summary + +Run a voluntary, private 25–35 minute observation. Give a realistic question without teaching the route. Measure first route, time to first useful action, saved output, hesitation, completion understanding, and whether the reader can return with a state file or worksheet after the page is closed. Collect only a random code and non-sensitive context. Delete raw material on schedule, keep de-identified decisions, repeat the task after changes, and never present a small usability sample as proof of learning effectiveness. diff --git a/README.md b/README.md index 5e5f3c6f..11131855 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ --- title: 人生进阶指南|AI 时代终身学习 description: 《人生进阶指南》帮助普通人在 AI 时代持续学习、完成真实项目、穿越人生低谷并留下成长证据。 -updated: 2026-09-02 +updated: 2026-09-10 --- # 人生进阶指南 @@ -12,6 +12,8 @@ updated: 2026-09-02 副标题:**AI 时代终身学习指南**。这是一份持续更新的书稿,从英语这扇具体的门出发,写到 AI 学习、真实项目、创业失败、身体恢复,以及一个普通人怎样把生活一点点交还给自己。 +这是一个开放的双语书稿与静态阅读/出版项目,不是需要安装的软件包:网页、EPUB 和 PDF 负责阅读,仓库源码负责勘误、内容校验与构建。 +
持续更新书稿 下载中文 EPUB @@ -49,6 +51,7 @@ AI 正在让答案变得前所未有地廉价。几秒钟里,我们可以得 基础能力:英语用英语连接全球知识、技术文档与国际 AI 工具,以可理解度而不是口音相似度进入跨文化协作。 语法基础与真实表达不从背完整规则开始,而从时间、责任、条件与确定性是否被听清开始,用一项高影响结构完成十四天复测。 写作与异步交付保留无辅助初稿、事实来源和修改理由,让邮件、报告、决定与交接在作者离线后仍然可用。 + 口语方案:先让意思到达用无稿独白、陌生追问、听众复述、互动修复和十四天迁移,把“想练口语”变成一项可以开始的真实任务。
@@ -173,6 +176,12 @@ AI 可以降低探索、学习和创造的门槛,却不能替你建立信誉 韩先凯参与的产品、公司参访与现实项目统一放在 [作者项目与现实实践](docs/projects.md)。页面明确作者关联、用途、更新时间和非赞助关系。正文不因商业关系改变推荐标准,站点默认不接入广告、分析脚本或追踪器。 +## 无障碍与反馈 + +网站以 WCAG 2.2 AA 为目标,已对键盘操作、焦点恢复、双主题、窄屏重排、表格滚动、搜索对话框和代表性页面做自动与浏览器回归。它不等于完整的 WCAG 合规认证;读屏软件、放大/重排组合、低速设备和第三方 EPUB 阅读器仍需要人工复核。 + +如果你遇到无法阅读、操作或下载的地方,可以提交[无障碍反馈 issue](https://github.com/byoungd/up/issues/new?template=site.yml),请只写页面路径、浏览器或辅助技术、预期行为和实际行为,不要粘贴姓名、录音、客户资料、健康信息或其他私人内容。涉及安全或隐私的内容请使用 [SECURITY.md](https://github.com/byoungd/up/blob/master/SECURITY.md) 的私下流程。 + ## 项目边界 - 本项目是开放内容项目,不是 OSI 意义上的开源软件:正文与作者内容采用 **CC BY-NC 4.0**,站点配置、检查脚本和构建代码采用 **MIT**。详见 [许可证说明](https://github.com/byoungd/up/blob/master/LICENSE.md)。 diff --git a/docs/.vitepress/config.mts b/docs/.vitepress/config.mts index 102d5770..d3bee4f1 100644 --- a/docs/.vitepress/config.mts +++ b/docs/.vitepress/config.mts @@ -1,9 +1,12 @@ -import { existsSync, readdirSync, rmSync } from "node:fs"; +import { readdirSync } from "node:fs"; import { dirname, join, resolve } from "node:path"; import { fileURLToPath } from "node:url"; import sharp from "sharp"; import { defineConfig } from "vitepress"; import { bilingualRoutePairs, enNavigation, toSidebar, zhNavigation } from "./navigation.mjs"; +import { legacyRedirectScript, publicRoutePath } from "./routing.mjs"; +import { privateAssetGuard } from "./private-assets.mjs"; +import { worksheetBySource } from "./worksheets.mjs"; const origin = "https://byoungd.github.io"; const base = "/up/"; @@ -50,8 +53,49 @@ function localImagePath(source: string, pagePath?: string) { return resolve(dirname(pagePath), clean); } +function localSearchFailurePlugin() { + return { + name: "reader-local-search-failure", + enforce: "pre" as const, + transform(source: string, id: string) { + const normalizedId = id.split("?", 1)[0].replaceAll("\\", "/"); + if (!normalizedId.endsWith("/vitepress/dist/client/theme-default/components/VPLocalSearchBox.vue")) { + return undefined; + } + + const searchStart = "const searchIndex = computedAsync(async () =>"; + const searchEnd = "\n)\n\nconst disableQueryPersistence"; + if (!source.includes(searchStart) || !source.includes(searchEnd)) return undefined; + + return source + .replace( + searchStart, + "const searchIndexError = ref(false);\nconst searchIndex = computedAsync(async () =>", + ) + .replace( + searchEnd, + "\n, undefined, { onError: () => { searchIndexError.value = true } })\n\nconst disableQueryPersistence", + ) + .replace( + "const translate = createSearchTranslate(defaultTranslations)", + "function searchFailureMessage() { return document.documentElement.lang.startsWith('en') ? 'Search is temporarily unavailable. Reload to try again.' : '搜索索引暂时无法加载,请刷新后重试。' }\nfunction searchFailureRetryLabel() { return document.documentElement.lang.startsWith('en') ? 'Reload search' : '刷新搜索' }\nfunction reloadSearch() { window.location.reload() }\n\nconst translate = createSearchTranslate(defaultTranslations)", + ) + .replace( + ' + {{ searchFailureMessage() }} + +

+ +
@@ -173,6 +176,12 @@ AI 可以降低探索、学习和创造的门槛,却不能替你建立信誉 韩先凯参与的产品、公司参访与现实项目统一放在 [作者项目与现实实践](projects.md)。页面明确作者关联、用途、更新时间和非赞助关系。正文不因商业关系改变推荐标准,站点默认不接入广告、分析脚本或追踪器。 +## 无障碍与反馈 + +网站以 WCAG 2.2 AA 为目标,已对键盘操作、焦点恢复、双主题、窄屏重排、表格滚动、搜索对话框和代表性页面做自动与浏览器回归。它不等于完整的 WCAG 合规认证;读屏软件、放大/重排组合、低速设备和第三方 EPUB 阅读器仍需要人工复核。 + +如果你遇到无法阅读、操作或下载的地方,可以提交[无障碍反馈 issue](https://github.com/byoungd/up/issues/new?template=site.yml),请只写页面路径、浏览器或辅助技术、预期行为和实际行为,不要粘贴姓名、录音、客户资料、健康信息或其他私人内容。涉及安全或隐私的内容请使用 [SECURITY.md](https://github.com/byoungd/up/blob/master/SECURITY.md) 的私下流程。 + ## 项目边界 - 本项目是开放内容项目,不是 OSI 意义上的开源软件:正文与作者内容采用 **CC BY-NC 4.0**,站点配置、检查脚本和构建代码采用 **MIT**。详见 [许可证说明](https://github.com/byoungd/up/blob/master/LICENSE.md)。 diff --git a/docs/en/README.md b/docs/en/README.md index e8c2eab3..83e4d5bb 100644 --- a/docs/en/README.md +++ b/docs/en/README.md @@ -1,7 +1,7 @@ --- title: "Life Level-up Guide | Lifelong Learning in the AI Era" description: Learning continuously in the AI era, Life Level-up Guide helps ordinary people complete real projects, move through difficult seasons, and preserve evidence of growth. -updated: 2026-09-02 +updated: 2026-09-10 --- # Life Level-up Guide @@ -12,6 +12,8 @@ updated: 2026-09-02 Subtitle: **Lifelong Learning Guide for the AI Era**. This living manuscript begins with English and continues into AI learning, real projects, entrepreneurship, recovery, and the work of returning your life to yourself one small act at a time. +This is an open bilingual manuscript and static reading/publication project, not software you need to install: the website, EPUB, and PDF are for reading, while the repository source holds corrections, content checks, and builds. +
Living manuscript Download English EPUB @@ -47,6 +49,7 @@ It also keeps three kinds of claim separate: Foundation: EnglishUse English to reach global knowledge, technical documentation, and international AI tools, entering cross-cultural work through intelligibility rather than accent similarity. Grammar for Real ExpressionBegin with whether time, responsibility, condition, and certainty are understood, then retest one high-impact structure for fourteen days instead of memorising every rule first. Writing and Asynchronous DeliveryPreserve an unaided draft, fact sources, and revision reasons so email, reports, decisions, and handovers remain usable when the author is offline. + Speaking Plan: Make Meaning ArriveTurn “I want to improve speaking” into a real task with an unscripted baseline, unfamiliar follow-ups, listener retelling, interaction repair, and a fourteen-day transfer check.
02

Amplify Ability with Tools

Let AI accelerate questions and verification while people keep judgment, testing, and responsibility.

Learn Anything with AIUse AI for questions, research, and feedback while keeping fact-checking and final judgment in human hands. @@ -161,6 +164,12 @@ A method reveals its strength only after it enters a life. Relationships end and Products, company visits, and real-world projects involving Han Xiankai live on [Author Projects and Practice](projects.md). That page states the relationship, purpose, update date, and non-sponsorship status. Commercial relationships do not change the guide's recommendation standard; by default, the site uses no ads, analytics, or trackers. +## Accessibility and Feedback + +The site targets WCAG 2.2 AA. Keyboard operation, focus restoration, themes, narrow reflow, table scrolling, the search dialog, and representative pages have automated and browser regression coverage. This is not a full WCAG conformance certification; screen readers, zoom/reflow combinations, low-powered devices, and third-party EPUB readers still need manual review. + +If you cannot read, operate, or download something, use the [accessibility feedback issue](https://github.com/byoungd/up/issues/new?template=site.yml). Include only the page path, browser or assistive technology, expected behavior, and observed behavior. Do not paste names, recordings, customer data, health information, or other private material. Use the private process in [SECURITY.md](https://github.com/byoungd/up/blob/master/SECURITY.md) for security or privacy concerns. + ## Project Boundaries - This is an open-content project, not open-source software in the OSI sense. Text and author-created content use **CC BY-NC 4.0**; site configuration, checks, and build code use **MIT**. See [Licensing](https://github.com/byoungd/up/blob/master/LICENSE.md). diff --git a/docs/en/templates/learning-state.md b/docs/en/templates/learning-state.md index da9d246d..efdcba05 100644 --- a/docs/en/templates/learning-state.md +++ b/docs/en/templates/learning-state.md @@ -1,13 +1,17 @@ --- title: Learning State Template description: Keep goals, baselines, completed work, error evidence, and the next action in one file so a person or AI can resume responsibly. -updated: 2026-09-01 +updated: 2026-09-09 --- # Learning State Template Copy this into a private note. It is a cross-session source of truth, not a performance diary. Do not include passwords, government IDs, exact addresses, sensitive health data, or third-party information without permission. +On first use, save a file named `learning-state.md`, or create a private note with that name in your usual notes tool, and record where the evidence folder lives. After each session, check the updates proposed by AI, then manually write them back into this main file and update its version and date. Retain the goal, initial baseline, capacity, and boundaries that still apply so the latest version is a complete snapshot. Older versions can be archived; a list of changes alone cannot ask the next conversation to reconstruct the past. + +A file path helps you locate evidence; it does not mean AI has read the file. In an ordinary chat, paste the state and separately attach the files or necessary excerpts to be checked this time. With a tool that can read files, confirm which materials it actually read. When only a path is supplied and the content is unavailable, mark that evidence as “not yet verified”. + ```markdown # Learning State @@ -15,6 +19,7 @@ State version: v1 Updated: YYYY-MM-DD Owner: Primary file location: +Evidence folder location (relative paths below start here): ## Goal - Real context: @@ -32,7 +37,8 @@ Primary file location: - A person must confirm: ## Current Level and Baseline -- I can currently: +- Initial baseline date and conditions: +- I can currently (separate from the initial baseline): - Baseline sample: - Latest score/feedback: @@ -72,7 +78,7 @@ Primary file location: ## Cross-session Recovery Prompt ```text -Below is my learning-state file. In no more than six bullets, restate the state version, goal, current evidence, main errors, boundaries, and next action. Flag conflicts or missing information; do not pretend to remember another chat or invent facts absent from the file. Design one exercise only for the “smallest next task”: let me answer first, then give feedback against the acceptance criteria. Do not provide a complete answer unless I ask. Finish with five paste-ready updates: completed, evidence, errors/risks, handover, next action. +Below is my learning-state file. In no more than six bullets, restate the state version, goal, current evidence, main errors, boundaries, and next action. Flag conflicts or missing information; do not pretend to remember another chat or invent facts absent from the file. Distinguish results I report from evidence you actually read this time; mark files supplied only as paths without content as not yet verified. Design one exercise only for the “smallest next task”: let me answer first, then give feedback against the acceptance criteria. Do not provide a complete answer unless I ask. Finish with five paste-ready updates: completed, evidence, errors/risks, handover, next action. Remind me to check them before writing them back to the main file; do not claim to have saved them for me. [paste Learning State] ``` diff --git a/docs/en/templates/reader-field-note.md b/docs/en/templates/reader-field-note.md index 9d256c82..616a67d3 100644 --- a/docs/en/templates/reader-field-note.md +++ b/docs/en/templates/reader-field-note.md @@ -1,7 +1,7 @@ --- title: "Reader Field Note: What Remains Seven Days Later" description: Use a private-first two-pass record to connect reading entry, real action, immediate result, delayed retention, failed transfer, and editorial feedback before deciding whether to share publicly. -updated: 2026-09-02 +updated: 2026-09-10 --- # Reader Field Note: What Remains Seven Days Later @@ -77,6 +77,8 @@ The conclusion I am most tempted to exaggerate: Next retest date: ``` +Record the approximate minutes from opening the page to the first saved output, plus non-sensitive conditions such as device, available time, prior familiarity, or whether help was used. Write “not recorded” when unknown; do not submit location, employer, health, or private project details for comparability. + An immediate success shows only what happened under the present conditions. If AI was used, keep the assisted version separate from the independent version completed after closing it. ## Second Pass: Three to Seven Days Later diff --git a/docs/en/templates/toolkit-walkthrough.md b/docs/en/templates/toolkit-walkthrough.md index fcd44faf..454a34f4 100644 --- a/docs/en/templates/toolkit-walkthrough.md +++ b/docs/en/templates/toolkit-walkthrough.md @@ -1,7 +1,7 @@ --- title: "Toolkit Walkthrough: Let AI Continue a 90-Day Learning Project across Sessions" description: Use an explicitly synthetic Python-learning case to show how Learning State, an AI Task Brief, an unaided baseline, an artifact, an Evidence Chain, Weekly Review, and a Reader Field Note hand work over. -updated: 2026-09-02 +updated: 2026-09-09 --- # Toolkit Walkthrough: Let AI Continue a 90-Day Learning Project across Sessions @@ -52,33 +52,42 @@ If this is your first use of the toolkit, follow this page for one week. Do not The learner creates `python-learning-state.md` instead of using an AI thread as memory: +Save this main file in a private notes tool or local folder, with practice materials in `evidence/week-01/` alongside it. All paths below are relative to the main file's folder. They are naming examples within the synthetic demonstration, not code downloads supplied with the book. Paths help the learner find files; file contents provide evidence that can be checked. + ```markdown # Learning State — python-90d-v1 Updated: 2026-09-02 +Main file: python-learning-state.md +Evidence location: evidence/week-01/ (relative to the main file's folder) Ninety-day situation: independently deliver a CSV-summary command-line tool and explain input validation, error handling, and tests. -Current baseline: can write variables, if, and for; cannot independently read CSV, separate functions, or write tests. +Initial baseline: day one, no AI, 25 minutes; can write variables, if, and for, and has handled only normal CSV rows; cannot independently complete input validation, separate functions, or write tests. Reliable capacity: Monday, Wednesday, Friday, and Sunday, 45 minutes each. -Existing evidence: baseline/day-01.py; crashes on a row with an empty value. +Existing evidence: evidence/week-01/baseline.py; crashes on completely empty rows or empty amount fields. Repeated errors: looking at answers first; treating running code as explained code; changing several variables and losing the cause. -Boundaries: synthetic data only; submit my version first; no make-up study after 23:00. +Boundaries: synthetic data only; submit my version first, no AI-written final artifact; no make-up study after 23:00. Current phase: days 1–14, calibrate. -Smallest next task: read a 12-row synthetic CSV, skip empty rows, and print valid-row count plus total amount. -Acceptance: the unaided version runs; I can explain each function; at least one failing test is preserved. +Phase gate: if core code still cannot be explained independently on day fourteen, add no framework or new course. +Smallest next task: revise reading of a 12-row synthetic CSV so normal-row summaries and completely empty rows pass first. +Fixed functional acceptance: (1) correct valid-row count and total for normal rows; (2) skip completely empty rows; (3) report row numbers for invalid amounts and skip those rows without crashing. +Invalid amounts: an empty amount field, letters, or a negative number; these are input rules chosen for this demonstration only. +Learning evidence kept separately: functions I can explain; passing and failing tests saved; neither counts toward the three functional conditions. Stop condition: save state when 45 minutes ends; do not stay up to finish. ``` -The state file keeps only what can change the next action. Course notes, full chat logs, and every attempt belong in the evidence folder rather than on the state page. +The state file keeps only what can change the next action. Course notes, full chat logs, and every attempt belong in the evidence folder rather than on the state page. Future updates retain the goal, initial baseline, capacity, and boundaries that still apply. The latest version should be a complete snapshot that stands alone, not just a list of changes. ## Step Two: Give AI One Task at a Time A new conversation does not ask AI to “remember me”. It receives the latest state and one task brief: +An ordinary chat does not gain file access by seeing a local path. The learner pastes the state and attaches `evidence/week-01/baseline.py` plus the necessary synthetic input for this task, or provides only the relevant excerpts. Even when a tool can read files, confirm which materials it actually read. A file whose contents were not supplied remains an index entry awaiting verification; it is not evidence already checked in this session. + ```markdown -Below is my Learning State file. First restate the version, goal, current evidence, main errors, boundaries, and next task in no more than six bullets. Point out conflicts or gaps. Do not add facts that are absent. +Below is my Learning State file. First restate the version, goal, current evidence, main errors, boundaries, and next task in no more than six bullets. Point out conflicts or gaps. Do not add facts that are absent; distinguish results I report from evidence you actually read this time. -This session has one task: read a synthetic CSV, skip empty rows, and print valid-row count plus total amount. -Process: let me submit an unaided version first; identify at most three problems that affect the result without giving full code; after I revise it, test with two cases. At 45 minutes, return five updates: completed, evidence, error/risk, handover, and next step. +This session has one task: revise reading of the synthetic CSV so normal-row summaries and completely empty rows pass first. +Process: let me submit an unaided version first; identify at most three problems that affect the result without giving full code; after I revise it, test normal and completely empty rows first and record the invalid-amount condition that has not passed. At 45 minutes, return five updates: completed, evidence, error/risk, handover, and next step. I will check them before writing them back to the main file. ``` AI's first job is to restate the state, not begin a lecture. When the restatement is wrong, repair the state or prompt before generating another plan on a false premise. @@ -89,11 +98,11 @@ The synthetic unaided attempt produces: | Condition | Result | Evidence | | --- | --- | --- | -| 25 minutes, no answer | Reads valid rows; empty amount raises an exception; all logic in one function | `evidence/week-01/baseline.py` | -| AI identifies only three issues | Empty-value validation, function ownership, and missing tests become visible | `evidence/week-01/feedback.md` | -| After revision | Normal-row and empty-row tests pass; invalid amount format remains unsupported | `evidence/week-01/revision.py` | +| 25 minutes, no answer | Correct summaries for normal rows; completely empty rows and empty amounts raise exceptions; all logic in one function | `evidence/week-01/baseline.py` | +| AI identifies only three issues | Empty-row and amount validation, function ownership, and missing tests become visible | `evidence/week-01/feedback.md` | +| After revision | Normal and completely empty rows pass; invalid amounts still violate the specification; two functions can be explained and failing tests are saved | `evidence/week-01/revision.py` · `evidence/week-01/tests.md` | -The record is not “AI wrote the program”. It says the unaided version exposed three issues, AI helped classify them, the learner repaired two, and the third became the next task. +The record is not “AI wrote the program”. It says the unaided version exposed issues, AI helped classify them, and the learner completed empty-row handling, function separation, and test records. The unmet invalid-amount condition became the next task. The three feedback categories and the three functional conditions are different counts. Asking for complete code first may produce a better-looking file while erasing the baseline and any way to tell which ability belongs to the learner. @@ -101,34 +110,49 @@ Asking for complete code first may produce a better-looking file while erasing t Week one does not preserve the statement “learned CSV”. It records four time points: +The denominator below always refers to the same three functional conditions in the state file: normal-row summaries, completely empty rows, and invalid amounts. The third condition passes only when empty, alphabetic, and negative amounts are all handled as specified. Changing the denominator cannot improve the result. Save function explanations and failing-test locations separately; they cannot replace a failed function. + | Time point | Condition | Synthetic result | What it still cannot show | | --- | --- | --- | --- | -| Baseline | No AI, 25 minutes | 1/3 acceptance conditions pass | Understanding of error handling | -| Immediate after assistance | Three feedback points seen | 2/3 pass; two functions can be explained | Retention after several days | -| Day-seven delayed retest | Old code closed; parallel CSV | 2/3 pass; invalid amount is missed again | Adaptation to a new field | -| Transfer | Add a `currency` field | Finds where change belongs; currency validation incomplete | Structure begins to transfer, prerequisites remain missing | +| Baseline | No AI, 25 minutes | 1/3: only normal-row summaries pass; empty rows and invalid amounts fail | Understanding of error handling | +| Immediate after assistance | Three feedback points seen | 2/3: normal and completely empty rows pass; invalid amounts fail | Retention after several days | +| Day-seven delayed retest | Old code closed; parallel CSV | 2/3: the same two conditions pass; invalid amounts fail again | Adaptation to a new field | +| Transfer | Add a `currency` field and record the new requirement separately | Finds where change belongs; currency validation incomplete; excluded from the original three-condition score | Structure begins to transfer, prerequisites remain missing | + +Function explanations and passing/failing cases are saved in `evidence/week-01/tests.md`; the independent day-seven version is saved in `evidence/week-01/day-07-retest.py`. Explaining two functions after immediate revision is a separate learning observation and does not change the functional count. The result is not perfect and is more informative than “maintained a seven-day streak”. The next variable is not pandas, a web framework, and a database. It is input validation and failing tests. ## Step Five: Continue in a New Conversation -The weekly review writes only decision-changing information back into state: +After the weekly review, the learner checks the artifacts and tests, writes changes back into the same main file, and updates the version and date. Here is the complete `v2` snapshot, retaining the goal and boundaries: ```markdown # Learning State — python-90d-v2 Updated: 2026-09-08 +Main file: python-learning-state.md +Evidence location: evidence/week-01/ (relative to the main file's folder) +Ninety-day situation: independently deliver a CSV-summary command-line tool and explain input validation, error handling, and tests. +Initial baseline: day one, no AI, 25 minutes; can write variables, if, and for, and has handled only normal CSV rows; cannot independently complete input validation, separate functions, or write tests; only normal-row summaries passed the three functional conditions. +Reliable capacity: Monday, Wednesday, Friday, and Sunday, 45 minutes each. +Current phase: days 1–14, calibrate; the day-seven retest is complete. Completed: normal and empty CSV rows; logic separated into read_rows and summarize. -Evidence: week-01/baseline.py; revision.py; day-07-retest.py; tests.md. -Delayed result: 2/3 conditions remain on day seven; invalid amount fails again. -Main error: failure paths lack tests; normal output causes testing to stop too early. -Boundaries retained: synthetic data; unaided answer first; stop at 45 minutes; no repayment of missed time. +Evidence: evidence/week-01/baseline.py; evidence/week-01/feedback.md; evidence/week-01/revision.py; evidence/week-01/day-07-retest.py; evidence/week-01/tests.md. +Fixed functional acceptance: (1) correct valid-row count and total for normal rows; (2) skip completely empty rows; (3) report row numbers for invalid amounts and skip those rows without crashing. +Invalid amounts: an empty amount field, letters, or a negative number; these are input rules chosen for this demonstration only. +Delayed result: still 2/3 on day seven; (1) and (2) pass, (3) fails; this does not establish mastery of input validation. +Learning evidence kept separately: two functions could be explained after immediate revision; passing/failing tests and explanations are in evidence/week-01/tests.md. +Main error: test coverage of failure paths is incomplete; normal output causes testing to stop too early. +Boundaries retained: synthetic data, no company data; unaided answer first, no AI-written final artifact; no make-up study after 23:00; no repayment of missed time. +Phase gate: if core code still cannot be explained independently on day fourteen, add no framework or new course. Smallest next task: write three failing tests before implementing parse_amount. -Acceptance: empty, alphabetic, and negative inputs have explicit outcomes; design choice can be explained aloud. +Acceptance for this task: empty, alphabetic, and negative amounts are reported with row numbers and skipped; existing normal-row and completely empty-row tests still pass; record independent explanation of the design separately. +Stop condition: save the current result and remaining errors when 45 minutes ends. Next review: 2026-09-15. ``` -The old conversation can close. The new one needs only `v2` and the relevant evidence locations, not tens of thousands of words from the chat. **AI did not track learning across sessions. The state file tracked it, and AI read and served that state.** +After saving, the learner reopens the main file and confirms that it shows `v2`, the next task, and the review date before closing the old conversation. The new conversation uses the complete `v2`; when artifacts need checking, their relevant contents are supplied separately, without assuming a path means AI has read them. There is no need to paste tens of thousands of chat words or ask AI to infer deleted goals. **The state file preserved continuity across sessions; AI continues only from the material actually supplied this time.** ## Step Six: Complete a Reader Field Note after Seven Days @@ -168,8 +192,8 @@ When health, safety, work responsibility, or relationships need priority, recove 3. Handle one minimum task only and let me submit the unaided version first. 4. Give at most three high-impact feedback points, separating observation, interpretation, and suggestion. 5. Do not provide a complete answer unless I explicitly request it. -6. End with: completed, evidence, error/risk, handover, and next step. -7. Treat the file as the source of truth and do not claim memory of other conversations. +6. End with: completed, evidence, error/risk, handover, and next step. I will check and write these back into the complete state; do not claim to have saved them for me. +7. Treat the file as the source of truth and do not claim memory of other conversations. Mark evidence supplied only as a path, without contents you have read, as not yet verified. ``` This protocol cannot guarantee that AI never errs. It makes errors easier to detect and preserves the learner's ownership of the problem, state, and final judgment. diff --git a/docs/en/templates/toolkit.md b/docs/en/templates/toolkit.md index 73bca4cf..950322a6 100644 --- a/docs/en/templates/toolkit.md +++ b/docs/en/templates/toolkit.md @@ -1,7 +1,7 @@ --- title: "Toolkit Overview: Choose the Problem Before the Tool" description: "Route every template by starting point, skill practice, AI collaboration, artifact delivery, review, and recovery so a reader can build one complete action loop with minimal record-keeping." -updated: 2026-09-02 +updated: 2026-09-10 --- # Toolkit Overview: Choose the Problem Before the Tool @@ -10,6 +10,8 @@ Templates are not another course to collect. They are work sheets you can reuse: If you do not know where to begin, choose one sheet. An incomplete sheet used on a real problem is more valuable than ten blank templates. +> **First time here? Start with four lines.** Write the real problem, the baseline you already have, the smallest output you can finish in 25–45 minutes, and where you will save the evidence. Then open the [Toolkit Walkthrough](toolkit-walkthrough.md) once to see a complete handover. Do not fill the whole routing table or open every template first; return here after one small action and choose the next sheet. + ## First Ask: Where Am I Stuck? | Current block | First tool | Open next | What this tool cannot prove for you | diff --git a/docs/public/downloads/epub-manifest.json b/docs/public/downloads/epub-manifest.json index 4ad3bdb9..61f24dfa 100644 --- a/docs/public/downloads/epub-manifest.json +++ b/docs/public/downloads/epub-manifest.json @@ -8,18 +8,18 @@ "language": "zh-CN", "chapters": 62, "images": 20, - "bytes": 2683678, - "sha256": "0be770bfe1dbdb1635b6d23d32c958e0931a2047aed9b9856767f741318341cb", - "sourceSha256": "1eaee7e82cde562a1ccef8a1d2417fb13ff00ce11d68daad49bf2a7026111d66" + "bytes": 2672850, + "sha256": "756847f347134fa8a34ed7f0e16b18a691d57842dd43f9946937f1204ef47954", + "sourceSha256": "a734d96474165da7cf3e59ef3c42527a6abe1c9fa782208ce81f4818d7deb3fb" }, "en-US": { "file": "life-level-up-guide-en.epub", "language": "en-US", "chapters": 62, "images": 20, - "bytes": 2653100, - "sha256": "db2dd190d6de53442ed8c1aca8c9c37ea3b593a6433d3b7b6cfd2bb152b5aa23", - "sourceSha256": "e4fa606c079c508cf4b45dae611c492e19ac147d745e8360fae7351bf43a7ff3" + "bytes": 2643701, + "sha256": "3c58d21577a467e82ad55fb6ea497d0fd26b59c0099d67bb8ab7f6f79bb87b22", + "sourceSha256": "b8629006220466d8675126990a3d54a009091583d54a55b74ce0c162fe666c76" } } } diff --git a/docs/public/downloads/life-level-up-guide-en.epub b/docs/public/downloads/life-level-up-guide-en.epub index 13cc112d..b73d70eb 100644 Binary files a/docs/public/downloads/life-level-up-guide-en.epub and b/docs/public/downloads/life-level-up-guide-en.epub differ diff --git a/docs/public/downloads/life-level-up-guide-en.pdf b/docs/public/downloads/life-level-up-guide-en.pdf index 558e9f51..0108d644 100644 Binary files a/docs/public/downloads/life-level-up-guide-en.pdf and b/docs/public/downloads/life-level-up-guide-en.pdf differ diff --git a/docs/public/downloads/life-level-up-guide-zh.epub b/docs/public/downloads/life-level-up-guide-zh.epub index cc2b8c6a..ef9f1ef5 100644 Binary files a/docs/public/downloads/life-level-up-guide-zh.epub and b/docs/public/downloads/life-level-up-guide-zh.epub differ diff --git a/docs/public/downloads/life-level-up-guide-zh.pdf b/docs/public/downloads/life-level-up-guide-zh.pdf index 91cd6dec..12b0fd4d 100644 Binary files a/docs/public/downloads/life-level-up-guide-zh.pdf and b/docs/public/downloads/life-level-up-guide-zh.pdf differ diff --git a/docs/public/downloads/pdf-manifest.json b/docs/public/downloads/pdf-manifest.json index b3e17cd6..01d7353a 100644 --- a/docs/public/downloads/pdf-manifest.json +++ b/docs/public/downloads/pdf-manifest.json @@ -11,14 +11,14 @@ "zh-CN": { "file": "life-level-up-guide-zh.pdf", "language": "zh-CN", - "pages": 339, + "pages": 345, "chapters": 62, - "bytes": 4701109, - "sha256": "238235821e2e29fe79f78204661a25a26272d2a4cf63ece04cc50af396b4e8d1", - "sourceEpubSha256": "0be770bfe1dbdb1635b6d23d32c958e0931a2047aed9b9856767f741318341cb", - "semanticSha256": "71161ff6e2f5b2eac0fa587ebb3b8d944a4ccc090ac0fe7565c747061f0d0323", + "bytes": 4714077, + "sha256": "dfc85da19e7d7f1e4fadc2e778846310a5d63b3bce015637ae58b8b990ee215d", + "sourceEpubSha256": "756847f347134fa8a34ed7f0e16b18a691d57842dd43f9946937f1204ef47954", + "semanticSha256": "c3a5dc056c444012789908e18f8fb0bf13422bb35cb1c35e1b8f4e824911be3a", "outlineEntries": 779, - "linkAnnotations": 792, + "linkAnnotations": 793, "images": 21, "fonts": [ { @@ -46,14 +46,14 @@ "en-US": { "file": "life-level-up-guide-en.pdf", "language": "en-US", - "pages": 381, + "pages": 389, "chapters": 62, - "bytes": 3895358, - "sha256": "212e89dd801b340387cfb0084b739a8bf67d27d87b2c2e3711dcb3cf92dda822", - "sourceEpubSha256": "db2dd190d6de53442ed8c1aca8c9c37ea3b593a6433d3b7b6cfd2bb152b5aa23", - "semanticSha256": "f814de3aaedb337b90bef6baa8947da8eeeb12c321e48755c3047481768f09a1", + "bytes": 3907262, + "sha256": "df2ceab92ab2b6b72472d293a762686bca461c3ed4ef883328b73515f5a4ad39", + "sourceEpubSha256": "3c58d21577a467e82ad55fb6ea497d0fd26b59c0099d67bb8ab7f6f79bb87b22", + "semanticSha256": "0007963e35307155130fcb88ac535ef6f1c931d16c905dd2d5824846208ef01f", "outlineEntries": 779, - "linkAnnotations": 810, + "linkAnnotations": 811, "images": 21, "fonts": [ { diff --git a/docs/public/downloads/worksheets/90-day-cycle.en.md b/docs/public/downloads/worksheets/90-day-cycle.en.md new file mode 100644 index 00000000..557afac5 --- /dev/null +++ b/docs/public/downloads/worksheets/90-day-cycle.en.md @@ -0,0 +1,91 @@ +# 90-Day Cycle Map + +This sheet manages one cycle; it is not a test of daily discipline. Keep one main question each week, one input, one output, and one transfer test. When health, work, or relationships change, adjust the plan's weight first. Do not include passwords, IDs, client data, sensitive health information, or unauthorised third-party details. + +This sheet owns cycle direction and phase gates, not every detail: the [Evidence Chain Template](https://byoungd.github.io/up/en/templates/evidence-chain) explains results, the [Rhythm Ledger](https://byoungd.github.io/up/en/templates/rhythm-ledger) maintains weekly rhythm, and [Learning State](https://byoungd.github.io/up/en/templates/learning-state) carries cross-session handover. + +## 1. Cycle commitment + +### 90-Day Cycle — YYYY-MM-DD to YYYY-MM-DD + +Real context:\ +Deliverable by day 90:\ +Completion standard:\ +Three core pieces of evidence:\ +Weekly time and boundaries:\ +What must be reduced or paused: + +## 2. Day-one baseline + +| Item | Current evidence | Largest barrier | Planned treatment | +| -------------------------------------------- | ---------------- | --------------- | ----------------- | +| What I can do independently | | | | +| Situation where I will use it | | | | +| Materials, tools, and people available | | | | +| Sleep, energy, and responsibility boundaries | | | | + +Keep one sample made without AI doing the task: a recording, short text, reading reconstruction, code, presentation, or real conversation note. + +## 3. Gates for three phases + +| Phase | Dates | Question to answer | Evidence to enter the next phase | +| --------- | ---------- | -------------------------------------------------------- | ---------------------------------------------------------- | +| Calibrate | Days 1–14 | What exactly am I training, and what is the bottleneck? | Baseline, three error categories, one stable time slot | +| Stack | Days 15–56 | Which action is becoming stable under which conditions? | At least four comparable outputs and one external feedback | +| Ship | Days 57–90 | Can a new listener, topic, or user still use the result? | Independent, revised, and real-delivery versions | + +Without evidence for a gate, do not raise difficulty automatically. Shrink the task or repair prerequisites first. + +## 4. Twelve weekly questions + +| Week | One question only | Input evidence | Output evidence | Feedback/transfer | +| ---- | ----------------- | -------------- | --------------- | ----------------- | +| 1 | | | | | +| 2 | | | | | +| 3 | | | | | +| 4 | | | | | +| 5 | | | | | +| 6 | | | | | +| 7 | | | | | +| 8 | | | | | +| 9 | | | | | +| 10 | | | | | +| 11 | | | | | +| 12 | | | | | + +Write an observable question such as “Can I explain project risk in English without a script and handle one follow-up?” Do not write “be better this week”. + +## 5. Evidence chain + +| Date | Evidence card/tool | Location kept | Result or error | Next variable | +| ---- | -------------------------------------------------------- | ------------- | --------------- | ------------- | +| | Listening / Reading / Speaking / Writing / Life Practice | | | | + +Chat logs, playback time, and check-in screenshots are process traces. Key judgments should return to artifacts, recordings, reader/user feedback, and performance under a new condition; use the [Evidence Chain Template](https://byoungd.github.io/up/en/templates/evidence-chain) when comparing all four time points. + +## 6. Interruption and recovery + +Interruption fact (no character judgment):\ +Main resistance: time / difficulty / energy / environment / responsibility\ +Task reduced to:\ +Smallest output possible within 24 hours:\ +Work I will not repay:\ +Review date: + +Do not stay up late to repay missed work or rewrite the 90 days after one failure. When the same barrier appears three times, record capacity and resistance in the [Rhythm Ledger](https://byoungd.github.io/up/en/templates/rhythm-ledger), then change the system condition instead of demanding more force. + +## 7. Day-ninety review + +Final delivery:\ +What genuinely changed from the baseline:\ +Errors that still recur:\ +What a real reader/user said:\ +Cost that proved unsustainable:\ +One habit to keep next cycle:\ +One entry point to stop next cycle: + +Related chapters: [90-Day Action Plan: Return Your Life to Yourself](https://byoungd.github.io/up/threads/part-5/90-day-plan) | [Evidence Chain Template](https://byoungd.github.io/up/en/templates/evidence-chain) | [Rhythm Ledger](https://byoungd.github.io/up/en/templates/rhythm-ledger) + +--- + +Source: [Life Level-up Guide](https://byoungd.github.io/up/en/templates/90-day-cycle) · Manuscript updated: 2026-09-01. Content: [CC BY-NC 4.0](https://creativecommons.org/licenses/by-nc/4.0/). diff --git a/docs/public/downloads/worksheets/90-day-cycle.zh.md b/docs/public/downloads/worksheets/90-day-cycle.zh.md new file mode 100644 index 00000000..f2969c92 --- /dev/null +++ b/docs/public/downloads/worksheets/90-day-cycle.zh.md @@ -0,0 +1,91 @@ +# 九十日行动总表 + +这张表用来管理一个周期,不用来证明你每天都很自律。每周只保留一个主问题,保存一项输入、一项输出和一次迁移;如果身体、工作或关系出现变化,先调整计划的重量。不要写入密码、证件、客户资料、医疗隐私或未获授权的第三方信息。 + +这张表负责周期方向和阶段门槛,不负责承载所有细节:[证据链模板](https://byoungd.github.io/up/templates/evidence-chain)解释结果,[节律账本](https://byoungd.github.io/up/templates/rhythm-ledger)维护每周节奏,[学习状态](https://byoungd.github.io/up/templates/learning-state)负责跨会话交接。 + +## 1. 周期承诺 + +### 90-Day Cycle — YYYY-MM-DD to YYYY-MM-DD + +真实场景:\ +九十天后要完成的交付:\ +完成标准:\ +三项核心证据:\ +每周可用时间与边界:\ +必须减少或暂停的事情: + +## 2. 第一天基线 + +| 项目 | 当前证据 | 最大阻碍 | 计划处理 | +| ---------- | ---- | ---- | ---- | +| 能独立完成什么 | | | | +| 在什么场景会使用 | | | | +| 可用材料、工具和同伴 | | | | +| 睡眠、精力和责任边界 | | | | + +基线应留下一个未经 AI 代做的样本:录音、短文、阅读重构、代码、演示或真实沟通记录。 + +## 3. 三个阶段的门槛 + +| 阶段 | 日期 | 必须回答的问题 | 进入下一阶段的证据 | +| -- | --------- | ------------------ | ------------------ | +| 校准 | 第 1–14 天 | 我究竟在练什么,最大瓶颈是什么? | 一份基线、三个错误类别、一个稳定时段 | +| 堆叠 | 第 15–56 天 | 哪个动作在什么条件下开始稳定? | 至少四次可比较输出和一次外部反馈 | +| 交付 | 第 57–90 天 | 新听众、主题或真实用户是否仍然能用? | 独立版、修订版和真实交付版 | + +如果门槛没有证据,不要自动升级难度;先缩小任务或修复前置知识。 + +## 4. 十二周主问题 + +| 周次 | 本周只回答一个问题 | 输入证据 | 输出证据 | 反馈/迁移 | +| -- | --------- | ---- | ---- | ----- | +| 1 | | | | | +| 2 | | | | | +| 3 | | | | | +| 4 | | | | | +| 5 | | | | | +| 6 | | | | | +| 7 | | | | | +| 8 | | | | | +| 9 | | | | | +| 10 | | | | | +| 11 | | | | | +| 12 | | | | | + +主问题要写成可观察的句子,例如“我能否在没有稿件的情况下,用英语说明项目风险并处理一个追问?”不要写“本周变得更好”。 + +## 5. 证据链 + +| 日期 | 使用的证据卡/工具 | 保留的位置 | 结果或错误 | 下一变量 | +| -- | ------------------------ | ----- | ----- | ---- | +| | 听力 / 阅读 / 口语 / 写作 / 生活进阶 | | | | + +聊天记录、播放时长和打卡截图只能作为过程痕迹。关键判断应回到作品、录音、读者/用户反馈和新条件下的表现;需要完整比较四个时间点时,使用[证据链模板](https://byoungd.github.io/up/templates/evidence-chain)。 + +## 6. 中断与恢复协议 + +中断事实(不做人格判断):\ +主要阻力:时间 / 难度 / 精力 / 环境 / 责任\ +任务缩小到原来的:\ +24 小时内能完成的最小输出:\ +不需要补做的内容:\ +重新检查日期: + +不熬夜偿还缺席,不用一次失败重写九十天。连续三次出现同一阻力时,先在[节律账本](https://byoungd.github.io/up/templates/rhythm-ledger)记录容量和阻力,再改变系统条件,而不是只要求自己更用力。 + +## 7. 第九十天复盘 + +最终交付:\ +相对基线真正改变的地方:\ +仍然反复出现的错误:\ +真实读者/用户如何评价:\ +哪项代价不可持续:\ +下一周期保留的一个习惯:\ +下一周期停止的一个入口: + +相关章节:[行动篇:九十天,把生活交还给自己](https://byoungd.github.io/up/threads/part-5/90-day-plan) | [证据链模板](https://byoungd.github.io/up/templates/evidence-chain) | [节律账本](https://byoungd.github.io/up/templates/rhythm-ledger) + +--- + +来源:[人生进阶指南](https://byoungd.github.io/up/templates/90-day-cycle) · 稿件更新:2026-09-01。内容许可:[CC BY-NC 4.0](https://creativecommons.org/licenses/by-nc/4.0/)。 diff --git a/docs/public/downloads/worksheets/ai-case-review.en.md b/docs/public/downloads/worksheets/ai-case-review.en.md new file mode 100644 index 00000000..e4c3c90c --- /dev/null +++ b/docs/public/downloads/worksheets/ai-case-review.en.md @@ -0,0 +1,38 @@ +# AI Case Review Template + +Use the author's public writing, official pages, or clearly authorised material only. A third-party narrative cannot independently prove capability, revenue, or project impact. + +## AI Case Review — YYYY-MM-DD + +### Source and facts + +- Experience/project: +- Primary source and publication date: +- Access/check date: +- What may be public: +- What must be removed or redacted: + +### Judgment + +- Problem at the time: +- Facts known then: +- Assumptions: +- Choice made: + +### Outcome + +- What happened: +- Evidence location: +- What remains unknown: +- Failure or cost: + +### Transferable principle + +- Principle that still holds: +- Part that depended on the old conditions: +- Small exercise for a reader: +- How to test it next: + +--- + +Source: [Life Level-up Guide](https://byoungd.github.io/up/en/templates/ai-case-review) · Manuscript updated: 2026-08-24. Content: [CC BY-NC 4.0](https://creativecommons.org/licenses/by-nc/4.0/). diff --git a/docs/public/downloads/worksheets/ai-case-review.zh.md b/docs/public/downloads/worksheets/ai-case-review.zh.md new file mode 100644 index 00000000..95a5d546 --- /dev/null +++ b/docs/public/downloads/worksheets/ai-case-review.zh.md @@ -0,0 +1,38 @@ +# AI 经历案例复盘模板 + +只使用本人公开文章、官方页面或明确授权材料。第三方叙事不能单独证明能力、收入或项目效果。 + +## AI Case Review — YYYY-MM-DD + +### 来源与事实 + +- 经历/项目: +- 原始来源与发布日期: +- 访问/核验日期: +- 哪些内容可以公开: +- 哪些内容必须删除或脱敏: + +### 判断 + +- 当时面对的问题: +- 当时知道的事实: +- 当时的假设: +- 做出的选择: + +### 结果 + +- 发生了什么: +- 证据在哪里: +- 哪些结果仍未知: +- 失败或代价: + +### 可迁移原则 + +- 今天仍成立的原则: +- 只适用于当时条件的部分: +- 读者可以完成的最小练习: +- 下一次如何检验: + +--- + +来源:[人生进阶指南](https://byoungd.github.io/up/templates/ai-case-review) · 稿件更新:2026-08-24。内容许可:[CC BY-NC 4.0](https://creativecommons.org/licenses/by-nc/4.0/)。 diff --git a/docs/public/downloads/worksheets/ai-learning-log.en.md b/docs/public/downloads/worksheets/ai-learning-log.en.md new file mode 100644 index 00000000..7ac1285f --- /dev/null +++ b/docs/public/downloads/worksheets/ai-learning-log.en.md @@ -0,0 +1,113 @@ +# AI Learning Log: From Tool Collaboration to Independent Ability + +Record one inspectable learning slice at a time. An AI-generated summary, score, or explanation is not a source of truth; original material, your first version, actual work, and real feedback are evidence. Do not write “what I discussed with the model”. Write “what I can still complete independently after the tool leaves”. + +## 1. Task and Starting Point + +### AI Learning Log - YYYY-MM-DD + +Real situation and audience:\ +Main question:\ +Action and acceptance standard:\ +Material, version, and source:\ +Time, device, and environment limits:\ +Permitted dictionary / translation / search / AI / human help:\ +Privacy, copyright, exam, and ownership boundary: + +## 2. Unaided Baseline + +Start/end time of independent attempt:\ +Unaided sample location:\ +What I could explain or complete:\ +Errors, unknowns, and judgment blind spots exposed:\ +Confidence (0-2): + +Do not ask AI to write an answer first and call that the starting point. If the task permits a dictionary or documentation, record the permitted support; the baseline states what you can do independently under those conditions. + +## 3. Agree What AI Does + +Model / version / date:\ +Mode: diagnosis / follow-up / explanation / counterexample / transcript / candidate / other\ +AI may:\ +AI may not:\ +Minimum material sent:\ +Fields or files withheld: + +Move one slice per round. Ask the model to identify gaps, assumptions, sources, and uncertainty before requesting any rewrite or candidate. + +## 4. Interaction and Source Verification + +| Turn | My question/action | Model suggestion | Type | Source/uncertainty | My decision | +| ---- | ------------------ | ---------------- | ------------------------------------------------------------ | ------------------ | --------------------------------- | +| | | | explanation / question / candidate / feedback / code / other | | accept / partly / reject / verify | + +Primary sources I checked:\ +Errors, outdated claims, or invented material I found:\ +Suggestions that changed my understanding and why:\ +Suggestions that changed only surface wording: + +People confirm sources, facts, permissions, privacy, and final judgment. Model confidence does not raise the evidence level. + +## 5. Active Production After Closing AI + +Time AI was closed:\ +Work, explanation, code, or decision completed independently:\ +Independent time:\ +Cues still required:\ +Can I explain every critical step? yes / partly / no\ +Test, reader/user feedback, or run result: + +## 6. Three Comparisons + +| Sample | Conditions | Task/quality | Time | Rework | Confidence | Evidence location | +| --------------------------------- | ---------- | ------------ | ---: | -----: | ---------: | ----------------- | +| Unaided baseline | | | | | | | +| AI-assisted version | | | | | | | +| Delayed independent (3-7 days) | | | | | | | +| Parallel task (changed condition) | | | | | | | + +| Result | Cautious interpretation | +| ----------------------------------------- | ------------------------------------------------------- | +| Assisted and independent versions improve | A removable scaffold may be forming; test more transfer | +| Only assisted version improves | Product improved; critical steps may be outsourced | +| Time falls while rework rises | Speed created speed debt | +| Confidence rises while facts/tests fall | Calibrate judgment before increasing tool access | + +One comparison cannot prove causality, but it records contribution more clearly than “AI was useful”. + +## 7. Errors, Feedback, and Transfer + +| Error/gap | Sample | Type | Change only this next | Parallel-task result | +| --------- | ------ | -------------------------------------------------------------------------------- | --------------------- | -------------------- | +| | | fact / vocabulary / structure / grammar / strategy / attention / tool dependence | | | + +Real reader/user retelling or execution result:\ +Feedback accepted, partly accepted, rejected, or deferred and why:\ +Action that survived a changed topic/audience/mode/time:\ +Action that still succeeds only on the original task: + +## 8. Delayed Retention and Handover + +Day 1: what I removed and completed independently:\ +Days 3-7: what changed and what happened:\ +Day 14: can I explain and use it after closing the old chat:\ +Day 30: did the real task require less guessing or rework:\ +State-file location:\ +Handover owner, date, and access:\ +Stop or rollback condition: + +## 9. Next Cycle Decision + +What the tool genuinely helped:\ +Risk or dependence the tool created:\ +Evidence of ability I now own:\ +Conclusion still unsupported:\ +Continue / downgrade / change variable / pause / seek help:\ +Smallest next task:\ +Next review date: + +Related entry points: [Learning Principles: Turn Effort into Verifiable Learning](https://byoungd.github.io/up/en/threads/part-1/1-understanding) | [Learning Anything with AI](https://byoungd.github.io/up/en/threads/part-3/1-ai-learning) | [AI Task Brief](https://byoungd.github.io/up/en/templates/ai-task-brief) | [Learning State](https://byoungd.github.io/up/en/templates/learning-state) | [Evidence Chain](https://byoungd.github.io/up/en/templates/evidence-chain) + +--- + +Source: [Life Level-up Guide](https://byoungd.github.io/up/en/templates/ai-learning-log) · Manuscript updated: 2026-09-02. Content: [CC BY-NC 4.0](https://creativecommons.org/licenses/by-nc/4.0/). diff --git a/docs/public/downloads/worksheets/ai-learning-log.zh.md b/docs/public/downloads/worksheets/ai-learning-log.zh.md new file mode 100644 index 00000000..fa07390f --- /dev/null +++ b/docs/public/downloads/worksheets/ai-learning-log.zh.md @@ -0,0 +1,113 @@ +# AI 学习记录:从工具协作到独立能力 + +每次只记录一个可检查的学习切片。AI 生成的摘要、评分和解释不是事实来源;原始材料、自己的首版、实际作品和真实反馈才是证据。不要把学习记录写成“我和模型聊了什么”,而要写成“工具退出后,我还能独立完成什么”。 + +## 1. 任务与起点 + +### AI Learning Log - YYYY-MM-DD + +真实场景与受众:\ +本次主问题:\ +要完成的动作与标准:\ +材料、版本与来源:\ +时间、设备和环境限制:\ +允许的词典 / 翻译 / 搜索 / AI / 人工帮助:\ +隐私、版权、考试与责任边界: + +## 2. 无 AI 基线 + +独立尝试的开始/结束时间:\ +无 AI 样本位置:\ +我当时能够解释或完成的内容:\ +暴露的错误、未知和判断盲点:\ +当时的信心(0-2): + +不要先让 AI 写答案再把它叫作起点。若任务本身允许查词或看文档,记录允许的帮助;基线的价值是说明你在这些条件下独立能做什么。 + +## 3. 约定 AI 只做什么 + +模型 / 版本 / 日期:\ +使用模式:诊断 / 追问 / 解释 / 反例 / 转写 / 候选 / 其他\ +AI 可以做:\ +AI 不可以做:\ +传给模型的最小材料:\ +不会传入的字段或文件: + +每轮只推进一个切片。先让模型指出缺口、假设、来源和不确定性,不先请求整段代做。 + +## 4. 交互与来源核验 + +| 回合 | 我的问题/动作 | 模型建议 | 建议类型 | 来源/不确定性 | 我的决定 | +| -- | ------- | ---- | --------------------------- | ------- | ------------------ | +| | | | 解释 / 追问 / 候选 / 反馈 / 代码 / 其他 | | 采纳 / 部分 / 拒绝 / 待核验 | + +我核对过的原始来源:\ +我发现的错误、过时或捏造内容:\ +哪些建议改变了我的理解,为什么:\ +哪些建议只改变了表面表达: + +来源、事实、权限、隐私和最终判断由人确认。模型说得自信不提高证据等级。 + +## 5. 关闭 AI 后主动产出 + +关闭 AI 的时间:\ +独立完成的作品、解释、代码或决定:\ +独立用时:\ +仍然需要的提示:\ +我能否解释每个关键步骤:是 / 部分 / 否\ +测试、读者/用户反馈或运行结果: + +## 6. 三次对照 + +| 样本 | 条件 | 任务/质量 | 用时 | 返工 | 信心 | 证据位置 | +| ------------ | -- | ----- | -: | -: | -: | ---- | +| 无 AI 基线 | | | | | | | +| AI 辅助版 | | | | | | | +| 延迟独立版(3-7 天) | | | | | | | +| 平行任务版(换条件) | | | | | | | + +| 结果 | 更谨慎的解释 | +| ------------ | ------------------ | +| 辅助版和独立版都改善 | 可能形成了可撤掉的支架,仍需更多迁移 | +| 只有辅助版改善 | 成品改善,关键步骤可能被外包 | +| 时间变短但返工增多 | 速度换来了速度债 | +| 信心上升但事实/测试下降 | 先校准判断,再增加工具权限 | + +一次对照不能证明因果,但能比“AI 很有用”更清楚地记录工具贡献。 + +## 7. 错误、反馈与迁移 + +| 错误/缺口 | 样本 | 类型 | 下一次只修什么 | 平行任务结果 | +| ----- | -- | ---------------------------------- | ------- | ------ | +| | | 事实 / 词汇 / 结构 / 语法 / 策略 / 注意 / 工具依赖 | | | + +真实读者/用户复述或执行结果:\ +我采纳、部分采纳、拒绝或延后的反馈及理由:\ +换主题/受众/模态/时间后仍能完成的动作:\ +仍然只在原题成功的动作: + +## 8. 延迟保持与交接 + +第 1 天:撤掉了什么,独立完成什么:\ +第 3-7 天:换了什么条件,结果如何:\ +第 14 天:关闭旧对话后能否解释和使用:\ +第 30 天:真实任务是否减少猜测或返工:\ +状态文件位置:\ +交接给谁、何时、什么权限:\ +停止或回滚条件: + +## 9. 下一周期决定 + +工具真正帮助的部分:\ +工具制造的风险或依赖:\ +我已经拥有的独立能力证据:\ +仍无证据的结论:\ +继续 / 降档 / 改变变量 / 暂停 / 求助:\ +下一项最小任务:\ +下一次复查日期: + +相关入口:[认知篇:把努力变成可验证的学习](https://byoungd.github.io/up/threads/part-1/1-understanding) | [AI 学习、项目开发与资源层创业](https://byoungd.github.io/up/threads/part-3/1-ai-learning) | [AI 任务简报](https://byoungd.github.io/up/templates/ai-task-brief) | [学习状态](https://byoungd.github.io/up/templates/learning-state) | [证据链模板](https://byoungd.github.io/up/templates/evidence-chain) + +--- + +来源:[人生进阶指南](https://byoungd.github.io/up/templates/ai-learning-log) · 稿件更新:2026-09-02。内容许可:[CC BY-NC 4.0](https://creativecommons.org/licenses/by-nc/4.0/)。 diff --git a/docs/public/downloads/worksheets/ai-project-scorecard.en.md b/docs/public/downloads/worksheets/ai-project-scorecard.en.md new file mode 100644 index 00000000..7677dfff --- /dev/null +++ b/docs/public/downloads/worksheets/ai-project-scorecard.en.md @@ -0,0 +1,51 @@ +# AI Project Scorecard Template + +Complete this after each release or pilot. Every number should lead back to a test, ledger, feedback record, or operations log. + +## AI Project Scorecard — YYYY-MM-DD + +Project/version:\ +Owner:\ +User and situation:\ +Test conditions and sample scope:\ +Locations of baseline, assisted, and delayed independent retest: + +| Metric | Result | Evidence location | Change from last time | +| ------------------------------- | ------ | ----------------- | --------------------- | +| Task completion | | | | +| First-pass acceptance | | | | +| Average/high-percentile latency | | | | +| Human time and rework | | | | +| Model/infrastructure cost | | | | +| Delayed independent performance | | | | +| Security/privacy issues | | | | +| User feedback | | | | + +### Gates + +- Facts and sources checked: yes / no +- Tests and edge cases covered: yes / no +- Permissions and data scope confirmed: yes / no +- Pause/degrade/rollback path works: yes / no +- Owner can explain critical decisions without the chat: yes / no + +### Release Gates + +| Gate | Evidence location | Owner | Date | Pass | +| ------------------------------------ | ----------------- | ----- | ---- | -------- | +| Requirements and acceptance criteria | | | | yes / no | +| Real samples and boundary tests | | | | yes / no | +| Permissions, privacy, and retention | | | | yes / no | +| Cost ceiling and monitoring | | | | yes / no | +| Pause, degrade, rollback, and notice | | | | yes / no | + +### Decision + +- Keep: +- Adjust: +- Stop: +- Smallest next experiment: + +--- + +Source: [Life Level-up Guide](https://byoungd.github.io/up/en/templates/ai-project-scorecard) · Manuscript updated: 2026-08-31. Content: [CC BY-NC 4.0](https://creativecommons.org/licenses/by-nc/4.0/). diff --git a/docs/public/downloads/worksheets/ai-project-scorecard.zh.md b/docs/public/downloads/worksheets/ai-project-scorecard.zh.md new file mode 100644 index 00000000..e625258e --- /dev/null +++ b/docs/public/downloads/worksheets/ai-project-scorecard.zh.md @@ -0,0 +1,51 @@ +# AI 项目评分卡模板 + +每次发布或试点后填写一次。数字应能回到测试、账本、反馈或运行记录。 + +## AI Project Scorecard — YYYY-MM-DD + +项目/版本:\ +负责人:\ +用户与场景:\ +测试条件与样本范围:\ +基线、辅助版和延迟独立复测位置: + +| 指标 | 本次结果 | 证据位置 | 与上次相比 | +| --------- | ---- | ---- | ----- | +| 任务完成率 | | | | +| 首次通过率 | | | | +| 平均/高位延迟 | | | | +| 人工时间与返工 | | | | +| 模型/基础设施成本 | | | | +| 延迟独立表现 | | | | +| 安全/隐私问题 | | | | +| 用户反馈 | | | | + +### 门禁 + +- 事实与来源已核验:是 / 否 +- 测试与边界已覆盖:是 / 否 +- 权限与数据范围已确认:是 / 否 +- 失败时可以暂停/降级/回滚:是 / 否 +- 负责人能在没有聊天记录时解释关键决定:是 / 否 + +### 上线门禁 + +| 门禁 | 证据位置 | 负责人 | 日期 | 通过 | +| ----------- | ---- | --- | -- | ----- | +| 需求与验收标准 | | | | 是 / 否 | +| 真实样本与边界测试 | | | | 是 / 否 | +| 权限、隐私与留存 | | | | 是 / 否 | +| 成本上限与监控 | | | | 是 / 否 | +| 暂停、降级、回滚与通知 | | | | 是 / 否 | + +### 决策 + +- 保留: +- 调整: +- 停止: +- 下一项最小实验: + +--- + +来源:[人生进阶指南](https://byoungd.github.io/up/templates/ai-project-scorecard) · 稿件更新:2026-08-31。内容许可:[CC BY-NC 4.0](https://creativecommons.org/licenses/by-nc/4.0/)。 diff --git a/docs/public/downloads/worksheets/ai-task-brief.en.md b/docs/public/downloads/worksheets/ai-task-brief.en.md new file mode 100644 index 00000000..406b5d22 --- /dev/null +++ b/docs/public/downloads/worksheets/ai-task-brief.en.md @@ -0,0 +1,130 @@ +# AI Task Brief: From Problem to Human Acceptance + +Copy this into a private project directory before a model call. It is not a prompt collection. It is permission to start: when task, data, sources, acceptance, or ownership remain unclear, do not ask a model for the final result yet. + +Do not include passwords, identity documents, precise addresses, medical privacy, children's data, customer records, unpublished vulnerabilities, or unauthorised third-party material. Redact sensitive material or use an organisation-approved environment. + +## 1. Task and Ownership + +### AI Task Brief - YYYY-MM-DD + +Real situation:\ +User/audience:\ +Decision or action to complete:\ +Why now:\ +Deadline and non-negotiable checkpoints:\ +Final owner and human reviewer:\ +Who is affected if this is delayed or not done: + +Replace “learn AI” or “build an intelligent assistant” with an observable action, such as “a user can import a file in ten minutes and see an explainable report with sources and errors”. + +## 2. Inputs, Sources, and Data Boundary + +| Input/claim | Type | Source, version, location | May reach model? | Verifier | Expiry condition | +| ----------- | ------------------------------------------------------- | ------------------------- | ----------------------------------------- | -------- | ---------------- | +| | fact / inference / experience / user data / third-party | | public / redacted / approved / prohibited | | | + +Files and fields allowed:\ +Material deliberately withheld:\ +Data sensitivity: public / internal / confidential / restricted\ +Collection, transfer, retention, and deletion dates:\ +Required consent obtained:\ +Copyright, licence, citation, and authorship requirements:\ +Minimum data scope the model can see: + +A source is not automatically true. Each critical claim must return to an original passage, version, data definition, or direct observation. Model links, numbers, and quotations still require human verification. + +## 3. Output and Evaluation Set + +Final deliverable:\ +Format, length, and audience:\ +Observable definition of done:\ +Hard gates that must pass:\ +Acceptable variation:\ +Content that must not appear: + +Build a small, realistic evaluation set instead of only model-friendly examples: + +| Sample | Input condition | Expected result | Unacceptable result | Actual result | Evidence location | +| ------------------------- | --------------- | --------------- | ------------------- | ------------- | ----------------- | +| Normal case | | | | | | +| Boundary case | | | | | | +| Missing/conflicting input | | | | | | +| Redacted historical case | | | | | | + +Acceptance should answer whether facts are traceable, the action is complete, errors are visible, permissions are correct, and failure can stop. Fluent, fast, or human-like is not an acceptance standard. + +## 4. AI's Working Scope + +AI may: ask / classify / propose explanations / give counterexamples / transcribe\ +/ draft / suggest tests\ +AI may not: make final factual decisions / invent sources / approve for the owner\ +/ cross permissions / complete a prohibited exam or application\ +/ publish or execute automatically\ +Mode: diagnosis / assistance / candidate generation / batch processing / other\ +Model, version, region, and call date:\ +Prompt, system instruction, or workflow version location: + +Ask the model to restate goal, input, limits, unknowns, and acceptance before generation. Version prompts, and never treat one chat window as the project's only record. + +## 5. Human Gates + +| Gate | Who confirms | Passing evidence | If it fails | +| ----------------------- | ------------ | ----------------------------------------- | --------------------------------- | +| Source gate | | Original link, version, location | Mark unverified; do not circulate | +| Fact gate | | Sample checks and data definition | Delete or downgrade claim | +| Privacy/permission gate | | Scope, consent, access record | Stop and redact | +| Quality gate | | Evaluation set, edge cases, real feedback | Repair, narrow, or reject | +| Cost gate | | Tokens, time, human rework, budget | Downgrade or stop | +| Ownership gate | | Named approval and disclosure | Do not publish or execute | + +Critical decisions cannot be approved only by the generator, an automated score, or one developer alone. High-risk domains return to current primary sources and qualified professionals. + +## 6. Cost, Retention, and Reversibility + +Call volume, time, and cost ceiling:\ +Human review and rework budget:\ +Does data enter training, logs, or third-party retention:\ +Acceptable latency and downgrade path:\ +Version that can be withdrawn, rerun, or restored:\ +Release scope and pilot audience: + +A cheap call that causes a privacy incident, wrong decision, or major rework is not cheap in reality. Record human time, review, failure, reruns, and communication in addition to model fees. + +## 7. Failure, Pause, and Rollback + +| Trigger | Immediate action | Notify | Recovery/rollback location | +| --------------------------------- | ------------------------------------ | ------ | -------------------------- | +| Source or version cannot be found | Stop circulation; return to original | | | +| Evaluation hard gate fails | Block release or automatic action | | | +| Input crosses permission boundary | Stop upload; revoke access | | | +| Cost/latency exceeds ceiling | Downgrade, throttle, or stop | | | +| Real user reports harm | Remove, preserve evidence, escalate | | | + +Without a named stop owner, notification path, and known-good version, the task is not ready for a real workflow. + +## 8. Handover and Public Disclosure + +Current state: not started / experiment / internal pilot / limited release / delivered / stopped\ +Completed work and evidence locations:\ +Open questions and risks:\ +Smallest next task:\ +Handover owner, date, and access:\ +What readers/users need to know about AI involvement:\ +Source, privacy, copyright, and conflict-of-interest note: + +The next operator should not search chat history to discover what to do. Public work should state which step used a tool, which facts a person confirmed, and which content remains a candidate. + +## 9. Preflight Check + +- [ ] Audience, action, deadline, and owner are explicit. +- [ ] Input fields, sensitivity, consent, copyright, and retention are confirmed. +- [ ] Critical sources, versions, and expiry conditions are traceable. +- [ ] Normal, boundary, conflict, and redacted historical cases are in the evaluation set. +- [ ] AI may/may-not scope is explicit. +- [ ] Human gates, cost ceiling, stop conditions, and rollback location are named. +- [ ] Handover, disclosure, and next review date are set. + +--- + +Source: [Life Level-up Guide](https://byoungd.github.io/up/en/templates/ai-task-brief) · Manuscript updated: 2026-09-02. Content: [CC BY-NC 4.0](https://creativecommons.org/licenses/by-nc/4.0/). diff --git a/docs/public/downloads/worksheets/ai-task-brief.zh.md b/docs/public/downloads/worksheets/ai-task-brief.zh.md new file mode 100644 index 00000000..5525c6d4 --- /dev/null +++ b/docs/public/downloads/worksheets/ai-task-brief.zh.md @@ -0,0 +1,128 @@ +# AI 任务简报:从问题到人工验收 + +复制到私有项目目录,在模型调用前填写。它不是 prompt 收集器,而是一张开始许可:如果任务、数据、来源、验收或责任人仍然不清楚,就先不要让模型生成最终结果。 + +不要写入密码、证件、精确住址、医疗隐私、儿童数据、客户记录、未公开漏洞或无权使用的第三方内容。敏感材料先脱敏,或改用组织批准的环境。 + +## 1. 任务与责任 + +### AI Task Brief - YYYY-MM-DD + +真实场景:\ +使用者/受众:\ +要完成的决策或动作:\ +为什么现在做:\ +截止时间与不可错过的节点:\ +最终负责人与人工审阅者:\ +如果不做或延迟,谁会受影响: + +把“学 AI”“做一个智能助手”改成可观察的动作,例如“用户能在 10 分钟内导入一份文件,并看到一份能解释来源和错误的报告”。 + +## 2. 输入、来源与数据边界 + +| 输入/主张 | 类型 | 来源、版本与位置 | 可否提供给模型 | 核验人 | 失效条件 | +| ----- | ----------------------------- | -------- | ------------------- | --- | ---- | +| | 事实 / 推断 / 个人经验 / 用户数据 / 第三方内容 | | 公开 / 脱敏 / 组织批准 / 禁止 | | | + +允许使用的文件和字段:\ +明确不提供的材料:\ +数据敏感等级:公开 / 内部 / 机密 / 受限\ +收集、传输、留存和删除期限:\ +是否取得必要同意:\ +版权、许可证、引用和署名要求:\ +模型能接触的最小数据范围: + +来源不等于真相。每个关键主张要能回到原文、版本、数据口径或直接观察;模型给出的链接、数字和引语仍需人工核验。 + +## 3. 输出与评估集 + +最终交付物:\ +格式、长度和受众:\ +可观察的完成标准:\ +必须通过的硬门:\ +允许的可接受变体:\ +明确不能出现的内容: + +建立一份小而真实的评估集,不要只用模型最擅长的示例: + +| 样本 | 输入条件 | 预期结果 | 不可接受结果 | 实测结果 | 证据位置 | +| ----------- | ---- | ---- | ------ | ---- | ---- | +| 正常样本 | | | | | | +| 边界样本 | | | | | | +| 缺失/冲突输入 | | | | | | +| 真实历史样本(已脱敏) | | | | | | + +验收至少回答:事实是否可追溯,关键动作是否完成,错误是否可见,权限是否正确,失败是否可停止。流畅、快速或“像人”不是验收标准。 + +## 4. AI 的工作范围 + +AI 可以做:提问 / 分类 / 候选解释 / 反例 / 转写 / 草稿 / 测试建议\ +AI 不可以做:最终事实判断 / 虚构来源 / 代替责任人批准 / 越过权限\ +/ 完成禁止外部帮助的考试或申请 / 自动发布\ +使用模式:诊断 / 辅助 / 生成候选 / 批量处理 / 其他\ +模型、版本、区域和调用日期:\ +提示词、系统指令或工作流版本位置: + +先让模型复述目标、输入、限制、未知项和验收,再开始生成。提示词版本化;不要把一次聊天窗口当作唯一的项目记录。 + +## 5. 人工门 + +| 门 | 必须由谁确认 | 通过证据 | 未通过时 | +| ------ | ------ | ---------------- | ---------- | +| 来源门 | | 原始链接、版本、位置 | 标记未核验,不传播 | +| 事实门 | | 抽样核对、数据口径 | 删除或降级主张 | +| 隐私/权限门 | | 数据范围、同意、访问日志 | 停止处理并脱敏 | +| 质量门 | | 评估集、边界样本、真实反馈 | 修复、缩小或拒绝交付 | +| 成本门 | | token、时间、人工返工与预算 | 降级模型或停止 | +| 责任门 | | 具名批准和披露文字 | 不发布、不自动执行 | + +关键决定不能只由生成模型、自动评分或单个开发者自己批准。高风险领域回到当前一手材料和合格专业人员。 + +## 6. 成本、留存与可逆性 + +预计调用量、时间和费用上限:\ +人工审阅与返工预算:\ +数据是否进入训练、日志或第三方留存:\ +可接受延迟与降级方案:\ +可以撤回、重跑或恢复到哪个版本:\ +发布范围与灰度对象: + +一次便宜的调用如果造成隐私事件、错误决定或大量返工,真实成本并不便宜。记录模型费用之外的人工时间、审阅、失败、重跑和沟通成本。 + +## 7. 失败、暂停与回滚 + +| 触发条件 | 立即动作 | 通知谁 | 恢复/回滚位置 | +| --------- | ------------ | --- | ------- | +| 找不到来源或版本 | 停止传播,回到原始材料 | | | +| 评估集硬门失败 | 禁止发布或自动执行 | | | +| 输入越过权限边界 | 停止上传,撤销访问 | | | +| 成本/延迟超过上限 | 降级、限流或停止 | | | +| 真实用户报告伤害 | 下线、保留证据、升级处理 | | | + +如果没有明确的停止人、通知路径和已知可用版本,就还没有准备好接入真实流程。 + +## 8. 交接与公开说明 + +当前状态:未开始 / 实验 / 内部试用 / 灰度 / 已交付 / 已停止\ +已完成与证据位置:\ +未决问题和风险:\ +下一项最小任务:\ +交接负责人、时间和权限:\ +读者/用户需要知道的 AI 参与范围:\ +来源、隐私、版权和利益关系说明: + +交接者不应需要翻找聊天记录才能知道下一步。公开文本至少说明工具参与了哪一步、哪些事实由人确认、哪些内容仍是候选。 + +## 9. 开始前检查 + +- [ ] 真实受众、动作、截止时间和负责人已写清; +- [ ] 输入字段、敏感等级、同意、版权和留存边界已确认; +- [ ] 关键来源、版本和失效条件可回溯; +- [ ] 正常、边界、冲突和历史脱敏样本已进入评估集; +- [ ] AI 可以做与不可以做的范围已写清; +- [ ] 人工门、费用上限、停止条件和回滚位置已指定; +- [ ] 交接、披露和下一次复查日期已确定。 + +--- + +来源:[人生进阶指南](https://byoungd.github.io/up/templates/ai-task-brief) · 稿件更新:2026-09-02。内容许可:[CC BY-NC 4.0](https://creativecommons.org/licenses/by-nc/4.0/)。 diff --git a/docs/public/downloads/worksheets/artifact-brief.en.md b/docs/public/downloads/worksheets/artifact-brief.en.md new file mode 100644 index 00000000..84f91fb1 --- /dev/null +++ b/docs/public/downloads/worksheets/artifact-brief.en.md @@ -0,0 +1,80 @@ +# Artifact Brief and Delivery Card + +An artifact does not need to be complete on day one, but it needs boundaries on day one. Copy this card into a private project directory and keep the independent, revised, reviewed, and delivered versions. Do not include passwords, client data, unauthorised third-party information, or unnecessary personal details. + +## 1. Artifact boundary + +### Artifact Brief — YYYY-MM-DD + +Artifact name:\ +Real situation:\ +Audience/user:\ +One problem to solve: + +Inputs and sources:\ +My current baseline:\ +Key assumptions: + +Smallest deliverable:\ +Format, time, and other constraints:\ +Acceptance criteria:\ +What this will not include: + +First-version deadline:\ +Who will give feedback:\ +Evidence to preserve:\ +How to shrink, pause, or roll back:\ +Next review date: + +## 2. Four versions + +| Version | Completion condition | What to keep | +| ----------- | -------------------------------------------------------------------- | ------------------------------------------------------- | +| Independent | Complete the smallest action without an answer key or AI writing it | Original file, time, bottlenecks | +| Structure | Audience can find the problem, conclusion, and next step | Structural diff, fact/guess marks | +| Review | A real reader, user, peer, or defined AI reviewer completes a review | Feedback, error categories, accept/reject reasons | +| Delivery | Another person can begin without your oral explanation | Version, limits, sources, known issues, handover record | + +## 3. Quality gates + +| Gate | Check | Evidence location | Owner/date | +| ------------ | -------------------------------------------------------------------- | ----------------- | ---------- | +| Clear | Does the audience know the problem and next action? | | | +| Accurate | Do facts, citations, code, and numbers return to a source or test? | | | +| Usable | Can the main action work under real constraints? | | | +| Maintainable | Are version, dependencies, limits, and owner visible? | | | +| Responsible | Are privacy, copyright, permissions, and error consequences handled? | | | + +Write “unverified” when there is no evidence for a pass. Speed, word count, and feature count are proxy measures, not quality gates. + +## 4. AI and feedback record + +AI/tool and date:\ +Work it was allowed to do:\ +Human judgments I kept:\ +Three highest-impact issues it raised:\ +What I accepted/rejected, and why:\ +Main point restated by a real reader/user:\ +Most important repair: + +Save your version first, then use AI to diagnose, simulate an audience, or generate a parallel task. A person confirms critical facts, permissions, privacy, cost, and final authorship. + +## 5. Delivery and rollback + +Delivery audience and permission scope:\ +Delivery date and version:\ +Instructions:\ +Known limits:\ +Support owner/contact:\ +Cost and retention period:\ +Pause/degrade/rollback trigger:\ +Who must be notified after a problem:\ +Next review date: + +Delivery is not the end. After 3–7 days, run a parallel test and record whether another person can start independently, what still needs explanation, and the one change for the next version. + +Related chapters: [Artifacts: Turn Learning into Something Made](https://byoungd.github.io/up/en/threads/part-3/4-artifacts-and-delivery) | [90-Day Cycle Map](https://byoungd.github.io/up/en/templates/90-day-cycle) + +--- + +Source: [Life Level-up Guide](https://byoungd.github.io/up/en/templates/artifact-brief) · Manuscript updated: 2026-08-31. Content: [CC BY-NC 4.0](https://creativecommons.org/licenses/by-nc/4.0/). diff --git a/docs/public/downloads/worksheets/artifact-brief.zh.md b/docs/public/downloads/worksheets/artifact-brief.zh.md new file mode 100644 index 00000000..4f32f717 --- /dev/null +++ b/docs/public/downloads/worksheets/artifact-brief.zh.md @@ -0,0 +1,80 @@ +# 作品简报与交付卡 + +作品不必从一开始就完整,但必须从一开始就有边界。复制这张卡到私有项目目录,保留独立版、修订版、反馈版和交付版。不要写入密码、客户资料、未获授权的第三方信息或不必要的隐私。 + +## 1. 作品边界 + +### Artifact Brief — YYYY-MM-DD + +作品名称:\ +真实场景:\ +受众/使用者:\ +要解决的一个问题: + +输入材料与来源:\ +我当前的基线:\ +关键假设: + +最小交付物:\ +格式、时间与其他限制:\ +完成标准:\ +明确不做什么: + +第一版截止时间:\ +谁会提供反馈:\ +需要保留的证据:\ +失败时如何缩小、暂停或回滚:\ +下一次复查日期: + +## 2. 四个版本 + +| 版本 | 完成条件 | 保留什么 | +| --- | ------------------------ | ------------------ | +| 独立版 | 不看答案、不让 AI 代写,完成最小动作 | 原始文件、用时、卡点 | +| 结构版 | 受众能找到问题、结论和下一步 | 结构差异、事实与推测标记 | +| 反馈版 | 真实读者、用户、同伴或明确角色的 AI 完成审阅 | 反馈、错误分类、采纳/拒绝理由 | +| 交付版 | 他人不依赖你的口头补充也能开始使用 | 版本、限制、来源、已知问题、交接记录 | + +## 3. 质量门 + +| 门 | 检查问题 | 证据位置 | 负责人/日期 | +| --- | --------------------- | ---- | ------ | +| 清楚 | 受众知道问题和下一步吗? | | | +| 准确 | 事实、引用、代码和数字能回到来源或测试吗? | | | +| 可用 | 主要动作在真实限制下能完成吗? | | | +| 可维护 | 版本、依赖、限制和接手人清楚吗? | | | +| 可负责 | 隐私、版权、权限和错误后果已处理吗? | | | + +没有证据的“通过”先写成“待核验”。速度、字数和功能数量只是代理指标,不能替代质量门。 + +## 4. AI 与反馈记录 + +AI/工具与日期:\ +允许它做的工作:\ +我保留的人类判断:\ +它指出的三个最高影响问题:\ +我采纳/拒绝了什么,为什么:\ +真实读者/用户复述的主旨:\ +最需要修正的一处: + +先保存自己的版本,再让 AI 诊断、模拟受众或生成平行任务。关键事实、权限、隐私、成本和最终署名由人确认。 + +## 5. 交付与回滚 + +交付对象与授权范围:\ +交付日期与版本:\ +使用说明:\ +已知限制:\ +支持与联系人:\ +成本与留存期限:\ +暂停/降级/回滚触发条件:\ +发现问题后的通知对象:\ +下一次复查日期: + +交付不是终点。至少在 3–7 天后用相近条件复测一次,记录别人是否能独立开始、哪里需要解释,以及下一版本只改变什么。 + +相关章节:[作品篇:把学会变成做出](https://byoungd.github.io/up/threads/part-3/4-artifacts-and-delivery) | [九十日行动总表](https://byoungd.github.io/up/templates/90-day-cycle) + +--- + +来源:[人生进阶指南](https://byoungd.github.io/up/templates/artifact-brief) · 稿件更新:2026-08-31。内容许可:[CC BY-NC 4.0](https://creativecommons.org/licenses/by-nc/4.0/)。 diff --git a/docs/public/downloads/worksheets/english-diagnostic.en.md b/docs/public/downloads/worksheets/english-diagnostic.en.md new file mode 100644 index 00000000..788c486b --- /dev/null +++ b/docs/public/downloads/worksheets/english-diagnostic.en.md @@ -0,0 +1,140 @@ +# English Diagnostic: Four-skill Baseline and Transfer Record + +This is not an exam that pins a person to A1-C2. It is an evidence page for choosing the next action. Choose one real topic, complete listening, reading, speaking, and writing first versions under comparable time and explicit limits, then retest a parallel task after seven days and one real delivery after thirty days. + +Copy this card into a private note. Do not include passwords, customer records, identity documents, medical privacy, unauthorised third-party material, or exam content that may not be recorded. + +## 1. Define the Diagnostic Boundary + +### English Diagnostic - YYYY-MM-DD + +Real context: work / study / job search / life / other\ +Real topic:\ +Audience or conversation partner:\ +Smallest shared delivery across four skills:\ +Start/end dates:\ +Material, version, and source:\ +Shared limits (time, device, environment):\ +Permitted dictionary / captions / translation / search / AI / human help:\ +Privacy, copyright, exam, and expert-responsibility boundary:\ +Day-7 parallel-task date:\ +Day-30 retest date:\ +Week-12 real-task date: + +The four tasks need not use identical material. Keep topic, difficulty, time, and acceptance standards comparable enough to interpret. For a real role, do not let one overall level replace the language actions in the job description. + +## 2. Four First-version Tasks + +Complete the first version without looking things up or asking AI to answer or rewrite. Finish first, then mark where support was needed. + +| Skill | Suggested first version | Minimum delivery | +| --------- | ------------------------------------------------------------------- | ------------------------------------------------------------------------------------ | +| Listening | Hear a real 2-4 minute clip once | Main point, three certain details, responsibility/next step, and 60-second retelling | +| Reading | Read a real 600-1000-word text | Five-line main thread, one evidence location, and one challenge or unknown | +| Speaking | Record an unscripted two-minute explanation, experience, or process | Listener can retell purpose, key facts, and next step | +| Writing | Write a 180-250-word email, explanation, or argument in 20 minutes | Reader knows conclusion, support, limits, and action | + +Do not flatten genuine differences to make the four skills look equal. The diagnostic should show where ability works, not manufacture a flattering average. + +## 3. Preserve the First Version and Conditions + +| Skill | First-version location | Start/end | Tools and cues | Completed? | Main uncertainty | +| --------- | ---------------------- | --------- | -------------- | ---------- | ---------------- | +| Listening | | | | | | +| Reading | | | | | | +| Speaking | | | | | | +| Writing | | | | | | + +What I can still explain independently:\ +Condition I would most like to change:\ +Conclusion this first version cannot support: + +## 4. Score Impact, Not Feeling + +Score each `0-2`: `0=no evidence/not completed`, `1=partial, cue-dependent, or unstable`, `2=independent under current conditions`. Give every number an evidence location. + +| Skill | Task completion | Comprehensibility | Accuracy/range | Organisation/fluency | Independence/transfer | Evidence reason | +| --------- | --------------: | ----------------: | -------------: | -------------------: | --------------------: | --------------- | +| Listening | | | | | | | +| Reading | | | | | | | +| Speaking | | | | | | | +| Writing | | | | | | | + +### Scoring Meaning + +- **Task completion**: did information and intention arrive, and can the action continue? +- **Comprehensibility**: could a real reader/listener understand without excessive guessing? +- **Accuracy and range**: did vocabulary, grammar, pronunciation, spelling, and detail support the task? +- **Organisation/fluency**: did structure, order, pauses, or layout obstruct use? +- **Independence/transfer**: can the task return after recent cues are removed and one condition changes? + +Use totals only for your own longitudinal comparison, never as a personality, intelligence, or hiring label. For CEFR direction, combine this with [CEFR Goals and Self-check](https://byoungd.github.io/up/en/threads/part-1/0-cefr) rather than turning one diagnostic into a permanent level. + +## 5. Choose One Primary Barrier per Skill + +| Skill | Primary barrier | Sample/timestamp | Task impact | Smallest next repair | Evidence card | +| --------- | -------------------------------------------------------------------------- | ---------------- | ----------- | -------------------- | ------------------------------------------------------------------------------------- | +| Listening | vocabulary / sound / syntax / background / attention / device | | | | [Listening Evidence Card](https://byoungd.github.io/up/en/templates/listening-audit) | +| Reading | vocabulary / structure / background / evidence / layout / capacity | | | | [Reading Evidence Card](https://byoungd.github.io/up/en/templates/reading-evidence) | +| Speaking | chunks / pronunciation / organisation / interaction / register / follow-up | | | | [Speaking Evidence Card](https://byoungd.github.io/up/en/templates/speaking-evidence) | +| Writing | task / fact / structure / sentence / register / delivery | | | | [Writing Evidence Card](https://byoungd.github.io/up/en/templates/writing-evidence) | + +If a barrier cannot be tied to a sample or timestamp, do not treat it as a conclusion yet. A learner may know many words and still fail to segment speech, or be accurate while unable to organise an asynchronous handover. + +## 6. Design One Targeted Repair + +One barrier I will repair:\ +Repair action (25-45 minutes):\ +Material and source:\ +Minimum scaffold allowed:\ +Acceptance standard:\ +Before/after samples to preserve:\ +Feedback that would change the plan: + +Usually protect meaning and task completion first, then facts and structure, then high-impact vocabulary, grammar, pronunciation, or register. Leave style details that do not change the result until later. + +## 7. Delayed Retest and Transfer + +| Time | Remove | Change | Output | Result/evidence | +| ------- | ------------------------------ | ------------------------------------ | ----------------- | --------------- | +| Day 1 | Answers after first version | Original conditions | Repair version | | +| Day 7 | Recent cues and old sentences | Parallel topic or audience | Same kind of task | | +| Day 30 | Tool conversation and comments | Real source or time pressure | One real delivery | | +| Week 12 | Old task and score | Target role, course, or life context | Complete task | | + +What I can still do independently on day 7:\ +Error that still returns on day 30:\ +Skill that succeeded only on a familiar topic:\ +Where extra time would most affect life:\ +What this retest cannot prove: + +## 8. Record AI, Translation, and Human Feedback + +Tool / model / version and date:\ +Samples that existed before tool use:\ +What it did: diagnosis / questions / counterexample / transcript / feedback / other\ +Scope generated or rewritten:\ +Primary source, dictionary, teacher, peer, or real-audience check:\ +Suggestions accepted, rejected, or deferred and why:\ +Independent sample after closing the tool:\ +Disclosure required by school, client, employer, or exam: + +Model answers, speech-recognition scores, and polished final prose cannot independently prove ability. Important judgments return to original material, actual response, and a named accountable owner. + +## 9. Decide the Next Cycle + +Current component direction (not a permanent level):\ +Strongest real evidence:\ +Weakest evidence with the largest life impact:\ +Continue:\ +Downgrade:\ +Change variable:\ +Pause or seek help:\ +Smallest next task:\ +Next review date: + +Related entry points: [Learning Principles: Turn Effort into Verifiable Learning](https://byoungd.github.io/up/en/threads/part-1/1-understanding) | [Vocabulary Evidence Card](https://byoungd.github.io/up/en/templates/vocabulary-audit) | [Grammar Evidence Card](https://byoungd.github.io/up/en/templates/grammar-evidence) | [Listening Evidence Card](https://byoungd.github.io/up/en/templates/listening-audit) | [Reading Evidence Card](https://byoungd.github.io/up/en/templates/reading-evidence) | [Speaking Evidence Card](https://byoungd.github.io/up/en/templates/speaking-evidence) | [Writing Evidence Card](https://byoungd.github.io/up/en/templates/writing-evidence) | [Evidence Chain](https://byoungd.github.io/up/en/templates/evidence-chain) + +--- + +Source: [Life Level-up Guide](https://byoungd.github.io/up/en/templates/english-diagnostic) · Manuscript updated: 2026-09-02. Content: [CC BY-NC 4.0](https://creativecommons.org/licenses/by-nc/4.0/). diff --git a/docs/public/downloads/worksheets/english-diagnostic.zh.md b/docs/public/downloads/worksheets/english-diagnostic.zh.md new file mode 100644 index 00000000..120e6bc7 --- /dev/null +++ b/docs/public/downloads/worksheets/english-diagnostic.zh.md @@ -0,0 +1,140 @@ +# 英语能力诊断:四项基线与迁移记录 + +这不是一次把人钉在 A1-C2 上的考试,而是一张决定下一步的证据页。选一个真实主题,在相近时间和明确限制下完成听、读、说、写的首版;保存原始样本,分别记录障碍,七天后撤掉最近提示做平行任务,三十天后重复一项真实交付。 + +把这张卡复制到私有笔记中。不要写入密码、客户资料、证件、医疗隐私、未授权的第三方内容或禁止记录的考试材料。 + +## 1. 先定义诊断边界 + +### English Diagnostic - YYYY-MM-DD + +真实场景:工作 / 学习 / 求职 / 生活 / 其他\ +真实主题:\ +目标受众或对话对象:\ +四项共同的最小交付:\ +诊断开始/结束日期:\ +材料、版本与来源:\ +共同限制(时间、设备、环境):\ +允许的词典 / 字幕 / 翻译 / 搜索 / AI / 人工帮助:\ +隐私、版权、考试、专业责任边界:\ +第 7 天平行任务日期:\ +第 30 天复测日期:\ +第 12 周真实任务日期: + +四项不必使用完全同一种材料,但要让主题、难度、时间和完成标准可比较。若真实目标是岗位,不要让一个综合等级替代岗位描述中的具体语言动作。 + +## 2. 四项首版任务 + +第一版尽量不查词、不让 AI 代写或代答。先完成,再标出哪里需要帮助。 + +| 能力 | 建议首版 | 最低交付 | +| -- | ------------------------- | -------------------------- | +| 听力 | 听 2-4 分钟真实音频一次 | 写主旨、3 个确定细节、责任/下一步并复述 60 秒 | +| 阅读 | 读 600-1000 词真实文本 | 写五句主线、一个证据位置、一个质疑或未知 | +| 口语 | 不看稿录 2 分钟解释、经历或流程 | 听众能复述目的、关键事实和下一步 | +| 写作 | 20 分钟完成 180-250 词邮件、说明或短文 | 受众知道结论、依据、限制和行动 | + +不要为了让四项“公平”而削掉真实任务的差异。诊断要显示能力在哪些条件下工作,而不是制造一张漂亮的平均表。 + +## 3. 保存首版与条件 + +| 能力 | 首版位置 | 开始/结束 | 工具与提示 | 完成/未完成 | 我最不确定什么 | +| -- | ---- | ----- | ----- | ------ | ------- | +| 听力 | | | | | | +| 阅读 | | | | | | +| 口语 | | | | | | +| 写作 | | | | | | + +首版之后我仍能独立说明的内容:\ +如果重做,我最想改变的条件:\ +不能从首版推出的结论: + +## 4. 按影响评分,不按感觉评分 + +每项 `0-2` 分:`0=没有证据或未完成`,`1=部分完成、依赖提示或不稳定`,`2=在当前条件下独立完成`。每个分数都写证据位置。 + +| 能力 | 任务完成 | 可理解度 | 准确与范围 | 组织/流畅 | 独立与迁移 | 证据理由 | +| -- | ---: | ---: | ----: | ----: | ----: | ---- | +| 听力 | | | | | | | +| 阅读 | | | | | | | +| 口语 | | | | | | | +| 写作 | | | | | | | + +### 分数解释 + +- **任务完成**:信息和意图是否到达,动作是否能继续; +- **可理解度**:真实读者/听众是否无需过度猜测; +- **准确与范围**:词汇、语法、发音、拼写和细节是否支持任务; +- **组织/流畅**:结构、顺序、停顿或版面是否妨碍使用; +- **独立与迁移**:撤掉最近提示、改变一个条件后能否再次完成。 + +总分只用于同一个人的纵向比较,不是人格、智力或录用资格。CEFR 方向请结合[CEFR 目标与英语能力自测](https://byoungd.github.io/up/threads/part-1/0-cefr),不要把一次诊断写成永久等级。 + +## 5. 为每项只选一个首要障碍 + +| 能力 | 首要障碍 | 样本/时间段 | 任务影响 | 下一项最小修复 | 对应证据卡 | +| -- | --------------------------- | ------ | ---- | ------- | ----------------------------------------------------------------- | +| 听力 | 词汇 / 声音 / 句法 / 背景 / 注意 / 设备 | | | | [听力证据卡](https://byoungd.github.io/up/templates/listening-audit) | +| 阅读 | 词汇 / 结构 / 背景 / 证据 / 版面 / 容量 | | | | [阅读证据卡](https://byoungd.github.io/up/templates/reading-evidence) | +| 口语 | 词块 / 发音 / 组织 / 互动 / 语域 / 追问 | | | | [口语证据卡](https://byoungd.github.io/up/templates/speaking-evidence) | +| 写作 | 任务 / 事实 / 结构 / 句子 / 语域 / 交付 | | | | [写作证据卡](https://byoungd.github.io/up/templates/writing-evidence) | + +若一个障碍无法指出样本或时间段,先不要把它当作结论。一个人可以“知道很多词”却在听力切分上失败,也可以语法准确却无法组织异步交接。 + +## 6. 设计一次定向修复 + +我只要修复的一个障碍:\ +修复动作(25-45 分钟):\ +材料与来源:\ +允许的最小支架:\ +完成标准:\ +我要保存的前后样本:\ +哪条反馈会让我改变方案: + +顺序通常是:先保证意思和任务完成,再修事实与结构,之后处理高影响词汇、语法、发音或写作语域,最后才做不改变结果的风格细节。 + +## 7. 延迟复测与迁移 + +| 时间 | 撤掉什么 | 改变什么 | 输出 | 结果/证据 | +| ------ | ------- | ------------ | ------ | ----- | +| 第 1 天 | 首版之后的答案 | 原条件 | 修复版 | | +| 第 7 天 | 最近提示和旧句 | 平行主题或受众 | 同类任务 | | +| 第 30 天 | 工具对话和批注 | 真实材料或时间压力 | 一项真实交付 | | +| 第 12 周 | 旧任务与旧评分 | 目标岗位/课程/生活场景 | 完整任务 | | + +第 7 天仍然能独立完成:\ +第 30 天仍然反复的错误:\ +哪一项只在熟悉主题成功:\ +四项能力中最值得增加时间的地方:\ +我不能从这次复测推出什么: + +## 8. 记录 AI、翻译和人工反馈 + +工具 / 模型 / 版本与日期:\ +工具介入前的样本位置:\ +它只做了什么:诊断 / 追问 / 反例 / 转写 / 反馈 / 其他\ +它生成或改写的范围:\ +我用什么一手来源、词典、教师、同伴或真实受众核验:\ +我采纳、拒绝或延后的建议及理由:\ +关闭工具后的独立样本:\ +按学校、客户、雇主或考试规则需要怎样披露: + +模型答案、语音识别分数和润色终稿都不能单独证明能力。重要判断必须回到原始材料、实际回应和具名责任人。 + +## 9. 形成下一周期决定 + +当前分项方向(不是永久等级):\ +最强的真实证据:\ +最弱且最影响生活的证据:\ +继续:\ +降档:\ +换变量:\ +暂停或求助:\ +下一项最小任务:\ +下一次复查日期: + +相关入口:[认知篇:把努力变成可验证的学习](https://byoungd.github.io/up/threads/part-1/1-understanding) | [词汇证据卡](https://byoungd.github.io/up/templates/vocabulary-audit) | [语法证据卡](https://byoungd.github.io/up/templates/grammar-evidence) | [听力证据卡](https://byoungd.github.io/up/templates/listening-audit) | [阅读证据卡](https://byoungd.github.io/up/templates/reading-evidence) | [口语证据卡](https://byoungd.github.io/up/templates/speaking-evidence) | [写作证据卡](https://byoungd.github.io/up/templates/writing-evidence) | [证据链模板](https://byoungd.github.io/up/templates/evidence-chain) + +--- + +来源:[人生进阶指南](https://byoungd.github.io/up/templates/english-diagnostic) · 稿件更新:2026-09-02。内容许可:[CC BY-NC 4.0](https://creativecommons.org/licenses/by-nc/4.0/)。 diff --git a/docs/public/downloads/worksheets/evidence-chain.en.md b/docs/public/downloads/worksheets/evidence-chain.en.md new file mode 100644 index 00000000..64d6a6d1 --- /dev/null +++ b/docs/public/downloads/worksheets/evidence-chain.en.md @@ -0,0 +1,99 @@ +# Evidence Chain Template + +This worksheet answers one concrete question: **What exactly do I know has changed?** + +It does not require every result to improve or turn life into a score. It places samples from the same task under different conditions side by side, so you can distinguish “I can do it now”, “I still can after a few days”, and “I can use it somewhere new”. + +Copy it into a private note and use one copy for each main question. Do not record passwords, identity documents, customer data, medical privacy, or unauthorised third-party information. For health, safety, legal, financial, or persistent loss-of-control concerns, contact a trusted person and a qualified professional first. + +## 1. Define the Question + +Record start date:\ +Real situation and audience/user:\ +The one question this record answers:\ +Acceptance standard:\ +Possible risks and stop conditions: + +The question should be observable, such as “Can I explain a project risk in English without a script and answer one follow-up?” Do not write “Am I better now?” + +## 2. Save an Unaided Baseline + +The baseline should happen before AI, peer feedback, or concentrated training whenever possible. Record the conditions so tools, extra time, and familiar material do not disappear from the comparison. + +| Date | Task and constraints | Tool used? | Result/errors | Raw evidence location | +| ---- | -------------------- | ---------- | ------------- | --------------------- | +| | | No | | | + +What I could complete independently at baseline:\ +Where I stopped or needed a prompt:\ +What the baseline cannot prove: + +## 3. Record Immediate Performance + +Immediate performance says what happened under the current conditions. It does not automatically say that ability is stable. + +| Date | Conditions and prompts | What I completed | Quality/time/rework | Evidence location | +| ---- | ---------------------- | ---------------- | ------------------- | ----------------- | +| | | | | | +| | | | | | + +If AI was used, state what it did and what you completed independently after closing it. A chat log is a process trace, not proof of ability by itself. + +## 4. Test Delayed Retention + +Wait for a period, remove recent prompts and the original answer, and complete a related task. Choose the interval according to the task and your capacity, but write it down. + +Retest date:\ +Time since the last practice:\ +Prompts removed:\ +Related task:\ +Independent result:\ +Errors that remained:\ +Evidence location: + +## 5. Test Transfer + +Keep the core action and change at least one condition: topic, listener, time limit, material, tool permission, or purpose. + +| Changed condition | New task | Independent result | How did the other person/user understand it? | Evidence location | +| ----------------- | -------- | ------------------ | -------------------------------------------- | ----------------- | +| | | | | | + +A failed transfer does not make earlier practice worthless. It shows that the change may be too large, prerequisite knowledge is missing, or the acceptance standard needs revision. + +## 6. Separate Fact, Interpretation, and Hypothesis + +Fact: I can point to a date, condition, sample, source, or direct observation.\ +Interpretation: How I understand those facts; it may need revision.\ +Hypothesis: The judgment I will test in the next action.\ +Conclusion I cannot draw yet: + +For example, “the unaided version finished in 90 seconds” is a record. “It was clearer because my sleep improved” is an interpretation. “It may work if I can repeat it with an unfamiliar listener next week” is a hypothesis. + +## 7. Let Evidence Choose the Next Step + +This evidence most supports: continue / downgrade / change one variable / pause or stop\ +The one condition I will change:\ +Smallest next task:\ +Acceptance standard for the next task:\ +Support, permission, or professional judgment needed:\ +Next review date: + +When evidence conflicts, do not hide the conflict in an average. Write the different conditions first, then decide whether another sample is worth collecting. When evidence is thin, shrinking the question is usually more honest than manufacturing a precise score. + +## 8. Handover Summary + +Main question and acceptance standard:\ +Most reliable evidence:\ +Least reliable or still missing evidence:\ +Repeated errors/risks:\ +Smallest next task and stop condition:\ +Evidence folder or link: + +When handing this summary to your future self, a peer, or AI, ask them to work only from this record. They should not pretend to remember another session or fill in facts that are not present. + +Related chapters: [Evidence: How Change Becomes Visible](https://byoungd.github.io/up/en/threads/part-3/5-evidence-and-transfer) | [Toolkit Overview](https://byoungd.github.io/up/en/templates/toolkit) | [Rhythm Ledger](https://byoungd.github.io/up/en/templates/rhythm-ledger) | [Glossary of Terms and Methods](https://byoungd.github.io/up/en/reference/glossary) + +--- + +Source: [Life Level-up Guide](https://byoungd.github.io/up/en/templates/evidence-chain) · Manuscript updated: 2026-09-01. Content: [CC BY-NC 4.0](https://creativecommons.org/licenses/by-nc/4.0/). diff --git a/docs/public/downloads/worksheets/evidence-chain.zh.md b/docs/public/downloads/worksheets/evidence-chain.zh.md new file mode 100644 index 00000000..a45ae414 --- /dev/null +++ b/docs/public/downloads/worksheets/evidence-chain.zh.md @@ -0,0 +1,99 @@ +# 证据链模板 + +这张表用来回答一个具体问题:**我究竟知道自己改变了什么?** + +它不要求所有结果都变好,也不把生活压缩成分数。它只把同一任务在不同条件下的样本放在一起,让你分清“当下做得到”“过几天还记得”“换个地方仍能使用”分别有什么证据。 + +复制到自己的私有笔记,每个主问题使用一份。不要写入密码、证件、客户资料、医疗隐私或未获授权的第三方信息。涉及健康、安全、法律、财务或持续失控时,先联系可信任的人和合格的专业人士。 + +## 1. 先定义要回答的问题 + +记录开始日期:\ +真实场景与受众/用户:\ +本次只回答的问题:\ +完成标准:\ +可能的风险与停止条件: + +问题要能被观察,例如“我能否在没有稿件的情况下,用英语说明项目风险并回答一个追问?”不要写“我是否变得更好”。 + +## 2. 保存未经修饰的基线 + +基线应尽量发生在 AI、同伴反馈或集中训练之前。记录条件,避免把工具、额外时间和熟悉材料藏进比较里。 + +| 日期 | 任务与限制 | 是否使用工具 | 结果/错误 | 原始证据位置 | +| -- | ----- | ------ | ----- | ------ | +| | | 否 | | | + +我在基线时能够独立完成什么:\ +我在哪里停住或需要提示:\ +基线不能说明什么: + +## 3. 记录即时表现 + +即时表现说明这一次在当前条件下发生了什么,不自动说明能力已经稳定。 + +| 日期 | 条件与提示 | 完成了什么 | 质量/用时/返工 | 证据位置 | +| -- | ----- | ----- | -------- | ---- | +| | | | | | +| | | | | | + +如果使用 AI,请写清它做了什么,以及关闭 AI 后你独立完成了什么。聊天记录可以作为过程痕迹,不能单独作为能力证明。 + +## 4. 做一次延迟保持 + +等待一段时间,撤掉最近的提示和原答案,再完成相近任务。时间间隔按任务和个人容量决定,但必须写清楚。 + +复测日期:\ +距离上次练习:\ +撤掉了哪些提示:\ +相近任务:\ +独立结果:\ +仍然出现的错误:\ +证据位置: + +## 5. 做一次迁移 + +保留核心动作,改变至少一个条件:主题、听众、时间限制、材料、工具权限或任务目的。 + +| 改变的条件 | 新任务 | 独立结果 | 对方/用户如何理解 | 证据位置 | +| ----- | --- | ---- | --------- | ---- | +| | | | | | + +迁移失败不等于前面的练习没有价值。它说明你需要降低变化幅度、补充前置知识,或重新定义完成标准。 + +## 6. 把事实、解释和假设分开 + +事实:我能指出日期、条件、样本、来源或直接观察。\ +解释:我如何理解这些事实;它可能需要修正。\ +假设:我准备在下一项行动中检验的判断。\ +不能推出的结论: + +例如,“独立版在 90 秒内完成”是记录;“因为睡眠变好所以表达更清楚”是解释;“下周换一个陌生听众仍能完成,才说明改动可能有效”是待验证假设。 + +## 7. 让证据决定下一步 + +这条证据最支持:继续 / 降档 / 改变变量 / 暂停或停止\ +我只改变的一个条件:\ +下一项最小任务:\ +下一项任务的完成标准:\ +需要的支持、授权或专业判断:\ +下一次复查日期: + +如果证据互相冲突,不要用平均数掩盖冲突。先写出不同条件,再决定要不要补一次样本。证据不足时,缩小问题通常比制造一个精确分数更诚实。 + +## 8. 交接摘要 + +主问题与完成标准:\ +最可靠的证据:\ +最不可靠或仍缺少的证据:\ +重复出现的错误/风险:\ +下一项最小任务与停止条件:\ +证据文件夹或链接: + +把这段摘要交给未来的自己、同伴或 AI 时,要求对方只根据这份记录工作,不要假装记得其他会话,也不要补写不存在的事实。 + +相关章节:[证据篇:变化要如何被看见](https://byoungd.github.io/up/threads/part-3/5-evidence-and-transfer) | [工具箱总览](https://byoungd.github.io/up/templates/toolkit) | [节律账本](https://byoungd.github.io/up/templates/rhythm-ledger) | [术语与方法索引](https://byoungd.github.io/up/reference/glossary) + +--- + +来源:[人生进阶指南](https://byoungd.github.io/up/templates/evidence-chain) · 稿件更新:2026-09-01。内容许可:[CC BY-NC 4.0](https://creativecommons.org/licenses/by-nc/4.0/)。 diff --git a/docs/public/downloads/worksheets/family-learning-agreement.en.md b/docs/public/downloads/worksheets/family-learning-agreement.en.md new file mode 100644 index 00000000..02e55015 --- /dev/null +++ b/docs/public/downloads/worksheets/family-learning-agreement.en.md @@ -0,0 +1,180 @@ +# Family Learning Agreement: Fourteen Days of Negotiable Support + +This is not a parent-issued contract or a promise a child must sign in obedience. It is a private worksheet that lets a learner and parent or guardian write separately, read each other accurately, and use fourteen days of evidence to choose the next step. + +Keep it in a private family location. Do not include passwords, identity numbers, precise addresses, internal school accounts, medical records, or private information about teachers and classmates. Do not publish the agreement, baseline, or failed samples unless the learner understands the scope, relevant people have authorised the use, and the content has been minimised. + +## 1. Write Separately, Then Read Together + +### Learner First + +One real thing I want to become easier after two weeks:\ +What I can already complete:\ +Where I most often stop:\ +Help that works for me:\ +Help that makes starting harder or makes honesty less safe:\ +Time and capacity I can carry today: + +### Parent or Guardian Next + +Specific facts I have observed:\ +What I am most concerned about:\ +Concerns supported by evidence:\ +Parts that remain my interpretation:\ +Time, space, device, or communication support I can provide:\ +Monitoring, substituted work, or public sharing I will not do: + +When reading together, do not rebut immediately. Restate the other person's meaning until they consider it substantially accurate. + +## 2. Write One Shared Question + +The one question these fourteen days answer:\ +School or life situation where it occurs:\ +Explicit school requirement:\ +Learner's own acceptance standard:\ +Safety and responsibility boundary the adult must protect:\ +Result that supports continuation:\ +Result that supports reduction, pause, or closure: + +The question must permit an unsuccessful result. “Can I retell the main idea of a parallel text after two weeks?” preserves reality more easily than “increase vocabulary by 500 words”. + +## 3. Preserve the Baseline + +| Date | Task and constraints | Learner's independent result | Where prompts entered | Raw evidence location | +| ---- | -------------------- | ---------------------------- | --------------------- | --------------------- | +| | | | | | + +What the baseline can show:\ +What it still cannot show:\ +The one condition this experiment changes: + +An adult may help preserve the file but does not give the complete answer before the baseline is finished. + +## 4. Three Capacity Modes + +| Mode | When it applies | Learner action to preserve | Adult support to preserve | +| ---------- | --------------- | -------------------------- | ------------------------- | +| Full | | | | +| Compressed | | | | +| Recovery | | | | + +Latest ending time:\ +Work explicitly not repaid:\ +Minimum return action within 24 hours after interruption: + +A recovery day may contain no learning artifact. Safety, basic care, communication, and preparing the next entry can be the whole result. + +## 5. Adult Support List + +Choose only two or three for these two weeks: + +- [ ] Protect one time box from casual interruption. +- [ ] Prepare school-designated material or necessary equipment. +- [ ] Help contact a teacher or confirm an assignment requirement. +- [ ] Give no more than three concrete feedback points after the learner's first version. +- [ ] Give one reminder at the agreed time without repeated questioning. +- [ ] Help save versions and the next entry point. +- [ ] Agree to downgrade or pause when capacity falls. + +The adult explicitly will not: + +- [ ] Write or answer in the learner's place, or ask AI to produce work the learner submits under their name. +- [ ] Inspect the screen, chat history, or minute-by-minute status all day. +- [ ] Send artifacts, grades, or failures to unrelated relatives or public platforms. +- [ ] Shame through comparison with classmates, siblings, or past high points. +- [ ] Repay the plan through lost sleep, removed basic rest, or continuing conflict. + +## 6. AI and Data Agreement + +Permitted platform and account:\ +Current platform age/guardian rules checked: yes / no / not applicable\ +Does the school permit AI for this task?\ +AI may: ask / explain / give feedback / create parallel practice / other\ +AI may not:\ +Independent version the learner submits first:\ +Evidence saved after each use:\ +Retelling or independent action after the session closes: + +Never upload: + +- [ ] Name, school, class, identity document, precise address, or private contact details. +- [ ] Face, voiceprint, health, family relationships, or non-minimised grade records. +- [ ] Private information or unauthorised work from teachers, classmates, or other third parties. +- [ ] Internal school accounts, test answers, restricted material, or sensitive family information. + +When the platform, school, or family cannot confirm the boundary, use paper, offline material, synthetic data, or a teacher-approved alternative first. + +## 7. Feedback Rules + +One main question kept in each review:\ +Maximum number of adult feedback points:\ +How the learner may reject or question feedback:\ +Fact to establish first during disagreement:\ +When a teacher should participate: + +Feedback form: + +I observed:\ +Effect on the task:\ +What I remain uncertain about:\ +One thing I suggest testing next: + +Avoid “you are just…”, “you never…”, and “everyone else can…”. + +## 8. Fourteen-Day Evidence + +| Time point | Condition | Independent result | Feedback received | Still unknown | +| -------------------------------- | --------- | ------------------ | ----------------- | ------------- | +| Day-one baseline | | | | | +| Immediate revision | | | | | +| Delayed retest | | | | | +| Transfer under one new condition | | | | | + +Chat duration, streaks, and reminder counts are process traces. Key judgment returns to artifacts, problems, recordings, classroom use, and performance after prompts are removed. + +## 9. Pause and Support Gate + +Safety, physical, sleep, emotional, school, or family conditions that pause the experiment immediately:\ +Trusted adult the learner can contact first:\ +School contact route:\ +Qualified local or emergency support route:\ +Work that does not need repayment after a pause: + +For persistent functional difficulty, thoughts of harm, violence, bullying, threats, or unsafe communication, protect safety and seek appropriate support rather than diagnosing or handling the situation through this worksheet. + +## 10. Two-Week Review: Learner Speaks First + +### Learner + +One thing that genuinely became easier:\ +One thing still impossible or prompt-dependent:\ +Most useful support:\ +Monitoring that added no value or made me uncomfortable:\ +Action I am willing to continue: + +### Parent or Guardian + +Artifacts and facts I observed:\ +Control or failed demand I reduced:\ +Concern that remains unsupported by enough evidence:\ +Support I will keep in the next cycle: + +### Shared Decision + +Continue / reduce / change one condition / pause or stop:\ +Evidence:\ +Smallest next task:\ +Next review date:\ +Teacher or professional involvement needed: + +## Closing: Support Must Face Review Too + +Families often review whether the learner completed the task and rarely review whether adult support worked. This agreement asks both sides for evidence: did the task become clearer, did support reduce friction, and can the relationship still tell the truth? + +When help becomes only surveillance, substituted work, and transferred anxiety, it too must shrink or stop. Useful support may not make a learner do more immediately. It helps them see the problem, state a need, own a version, and know whom to contact when difficulty grows. + +Related chapter: [Family Learning: Return Ownership of Growth to the Learner](https://byoungd.github.io/up/en/threads/part-4/family-learning) | [First Week Practice](https://byoungd.github.io/up/en/threads/part-4/week-1) | [Evidence Chain Template](https://byoungd.github.io/up/en/templates/evidence-chain) + +--- + +Source: [Life Level-up Guide](https://byoungd.github.io/up/en/templates/family-learning-agreement) · Manuscript updated: 2026-09-02. Content: [CC BY-NC 4.0](https://creativecommons.org/licenses/by-nc/4.0/). diff --git a/docs/public/downloads/worksheets/family-learning-agreement.zh.md b/docs/public/downloads/worksheets/family-learning-agreement.zh.md new file mode 100644 index 00000000..dff74dd4 --- /dev/null +++ b/docs/public/downloads/worksheets/family-learning-agreement.zh.md @@ -0,0 +1,180 @@ +# 家庭学习共同协议:十四天,把帮助变得可商量 + +这不是家长给孩子下达的合同,也不是要求孩子签字服从的承诺。它是一张私密工作纸,让学习者、家长或监护人把同一件事各自写清楚,再用十四天事实决定下一步。 + +请保存在家庭私有位置。不要写入密码、证件号码、精确地址、学校内部账号、医疗记录、同学或教师的私人信息。不要把协议、基线或失败样本公开展示,除非学习者理解公开范围、相关人员已经授权,并且内容已经最小化处理。 + +## 1. 分别写,再一起读 + +### 学习者先写 + +我希望两周后哪件真实事情变容易一点:\ +我现在已经能够完成什么:\ +我最常停住的地方:\ +哪一种帮助对我有用:\ +哪一种帮助让我更难开始或不愿说实话:\ +今天我能承担的时间与容量: + +### 家长/监护人再写 + +我观察到的具体事实:\ +我最担心的事情:\ +哪些担心有证据:\ +哪些部分仍然只是我的推测:\ +我能提供的时间、空间、设备或沟通支持:\ +我承诺不做的监督、代做或公开行为: + +一起阅读时,不立即反驳。先用一句话复述对方的意思,直到对方认为基本准确。 + +## 2. 写成一个共同问题 + +十四天只回答的问题:\ +它发生在哪个学校或生活场景:\ +学校明确要求:\ +孩子自己的完成标准:\ +成人必须保护的安全与责任边界:\ +什么结果会让我们继续:\ +什么结果会让我们缩小、暂停或停止: + +共同问题应允许不成功。例如:“能否在两周后独立复述相近文章的主旨”比“词汇量必须增加 500”更容易保留真实结果。 + +## 3. 保存起点 + +| 日期 | 任务与限制 | 学习者独立结果 | 提示出现在哪里 | 原始证据位置 | +| -- | ----- | ------- | ------- | ------ | +| | | | | | + +起点能够说明:\ +起点仍然不能说明:\ +这次只改变的一个条件: + +成人可以帮助保存文件,不在基线完成前给出完整答案。 + +## 4. 三个容量档位 + +| 档位 | 适用情况 | 学习者保留的动作 | 成人保留的支持 | +| --- | ---- | -------- | ------- | +| 完整日 | | | | +| 压缩日 | | | | +| 恢复日 | | | | + +最晚结束时间:\ +明确不补做的内容:\ +中断后 24 小时内的最小回归动作: + +恢复日可以没有学习作品。安全、基本照料、沟通和准备下次入口可以是当天全部结果。 + +## 5. 成人支持清单 + +这两周,成人只选择两到三项: + +- [ ] 提供一个不被随意打断的时间盒; +- [ ] 准备学校指定材料或必要设备; +- [ ] 帮助联系教师或确认作业要求; +- [ ] 在孩子提交首版后,提供最多三条具体反馈; +- [ ] 在约定时间提醒一次,不重复追问; +- [ ] 帮助保存版本和下一步入口; +- [ ] 当容量下降时主动同意降档或暂停。 + +成人明确不做: + +- [ ] 不代写、代答或让 AI 代做后要求孩子署名; +- [ ] 不全天查看屏幕、聊天记录或每分钟状态; +- [ ] 不把作品、成绩或失败发给无关亲友或公开平台; +- [ ] 不用同学、兄弟姐妹或过去的高光时刻羞辱比较; +- [ ] 不用熬夜、取消基本休息或持续冲突偿还计划。 + +## 6. AI 与数据约定 + +允许使用的平台与账户:\ +平台当前年龄/监护规则已核对:是 / 否 / 不适用\ +学校是否允许本任务使用 AI:\ +AI 可以做:提问 / 解释 / 反馈 / 平行练习 / 其他\ +AI 不可以做:\ +孩子必须先提交的独立版本:\ +每次使用后要保存的证据:\ +会话结束后的复述或独立动作: + +绝不上传: + +- [ ] 姓名、学校、班级、证件、精确地址和私人联系方式; +- [ ] 面部、声纹、健康、家庭关系和未经最小化的成绩记录; +- [ ] 教师、同学和其他第三方的私人信息或未授权作品; +- [ ] 学校内部账号、试卷答案、受限制材料或家庭敏感信息。 + +若平台、学校或家庭无法确认边界,就先使用纸笔、离线材料、合成数据或教师批准的替代方式。 + +## 7. 反馈规则 + +每次只保留的一个主问题:\ +成人最多提供几条反馈:\ +学习者可以如何拒绝或追问反馈:\ +发生分歧时先确认哪项事实:\ +何时需要请教师参与: + +反馈句式: + +我观察到:\ +它对任务的影响:\ +我不确定的是:\ +我建议下一次只测试: + +避免“你就是……”“你从来不……”和“别人都能……”。 + +## 8. 十四天证据 + +| 时间点 | 条件 | 独立结果 | 得到的反馈 | 仍然未知 | +| ------- | -- | ---- | ----- | ---- | +| 第 1 天基线 | | | | | +| 即时修订 | | | | | +| 延迟复测 | | | | | +| 新条件迁移 | | | | | + +聊天时长、打卡天数和家长提醒次数只是过程痕迹。关键判断应回到作品、题目、录音、课堂使用和撤掉提示后的表现。 + +## 9. 暂停与求助门 + +出现哪些安全、身体、睡眠、情绪、校园或家庭情况时立即暂停:\ +孩子可以先联系的可信成人:\ +学校联系入口:\ +当地专业或紧急支持入口:\ +暂停后不需要补做的内容: + +出现持续功能受损、伤害念头、暴力、欺凌、威胁或无法安全沟通时,先保护安全并寻求合适支持,不用这张表自行诊断或处理。 + +## 10. 两周复盘:学习者先说 + +### 学习者 + +真正变容易的一件事:\ +仍然不会或需要提示的一件事:\ +最有用的支持:\ +最没有价值或让我不舒服的监督:\ +下一步我愿意继续的动作: + +### 家长/监护人 + +我观察到的作品与事实:\ +我减少了什么控制或无效要求:\ +我仍然担心但尚无足够证据的部分:\ +下一轮我只保留的支持: + +### 共同决定 + +继续 / 缩小 / 改变一个条件 / 暂停或停止:\ +依据:\ +下一项最小任务:\ +下一次复查日期:\ +需要教师或专业人员参与的事项: + +## 结尾:帮助也要接受复盘 + +家庭通常会复盘孩子是否完成,很少复盘成人的帮助是否有效。这张协议要求双方都留下证据:孩子的任务是否更清楚,成人的支持是否降低了摩擦,关系是否仍然能够说真话。 + +当帮助只剩监控、代做和焦虑传递时,它也需要被缩小或停止。好的支持不一定让孩子立刻做得更多,却会让他逐渐更能看见问题、提出需要、承担自己的版本,并知道困难出现时可以向谁求助。 + +相关章节:[家庭学习篇:把成长还给孩子](https://byoungd.github.io/up/threads/part-4/family-learning) | [实践篇](https://byoungd.github.io/up/threads/part-4/week-1) | [证据链模板](https://byoungd.github.io/up/templates/evidence-chain) + +--- + +来源:[人生进阶指南](https://byoungd.github.io/up/templates/family-learning-agreement) · 稿件更新:2026-09-02。内容许可:[CC BY-NC 4.0](https://creativecommons.org/licenses/by-nc/4.0/)。 diff --git a/docs/public/downloads/worksheets/grammar-evidence.en.md b/docs/public/downloads/worksheets/grammar-evidence.en.md new file mode 100644 index 00000000..41617992 --- /dev/null +++ b/docs/public/downloads/worksheets/grammar-evidence.en.md @@ -0,0 +1,104 @@ +# Grammar Evidence Card: From Rule Recognition to Real Expression + +Track one high-impact structure per card. Copy it into a private note and keep the original sentence plus revision reason. Do not record sensitive customer, company, school, medical, or third-party material; use synthetic facts or a minimised excerpt. + +## 1. Define the Real Task + +Date:\ +Situation: email / explanation / dialogue / retelling / interview / other\ +Audience:\ +What the task must let the other person understand or do:\ +Time, tool, and length restrictions:\ +Raw sample location: + +## 2. Locate One Structural Problem + +My original sentence/segment:\ +Most likely interpretation:\ +Meaning I intended:\ +Impact: meaning-changing / task-blocking / recurring / register mismatch / low-impact\ +One structure tracked in this cycle: + +| Sample | Structural choice | Real relationship expressed | Fits the task? | +| ---------- | ----------------- | --------------------------- | -------------- | +| Original | | | | +| Contrast A | | | | +| Contrast B | | | | + +## 3. Write a Meaning Contrast Card + +Meaning I need to express:\ +Forms I confuse:\ +Example and source from reliable material:\ +One-sentence explanation in my words:\ +Counterexample or boundary: + +The explanation should answer why the form matches the fact rather than copy only a terminology definition. + +## 4. Preserve Revision and Reason + +| Version | Condition | Sentence/output location | What changed | Why | +| ------------------ | ------------------------- | ------------------------ | ------------ | --- | +| First | No prompt | | | | +| Revised | Explanation/feedback seen | | | | +| Independent repeat | Material closed | | | | + +How the other person understood the revision:\ +Problem still affecting the task:\ +Suggested style change I rejected: + +## 5. Retrieve across Four Skills + +| Skill | Small task | Result | Evidence | +| --------- | ---------------------------------------------------- | ------ | -------- | +| Listening | Hear the relationship carried by the structure | | | +| Reading | Mark scope, reference, or logical connection | | | +| Speaking | Use under time pressure and repair after error | | | +| Writing | Compare how two versions change reader understanding | | | + +You do not need all four every cycle. Keep at least one input observation and one active output. + +## 6. AI and Feedback Record + +Tool/reviewer and date:\ +Problem observed:\ +Explanation given:\ +Did it separate error, ambiguity, register, and style?\ +Dictionary, corpus, teacher, or reader check:\ +What I accepted/rejected, and why: + +## 7. Delayed Retest + +| Time point | Prompt condition | New task | Independent choice | Result | +| ---------- | ----------------------------- | -------------- | ------------------ | ------ | +| Day 1 | Original task, no prompt | | | | +| Days 3–7 | Rule and old answer removed | Parallel topic | | | +| Day 14 | New audience or time pressure | Transfer task | | | + +Judgment retained on day seven:\ +Error that returned:\ +Where transfer failed: + +## 8. Score and Decide + +Score 0–2: `0=not completed`, `1=prompt-dependent or unstable`, `2=completed under the current condition`. + +| Item | Day 1 | Day 7 | Day 14 | Evidence reason | +| ------------------------------------ | ----: | ----: | -----: | --------------- | +| Explain form–meaning difference | | | | | +| Recognise it in a new sentence | | | | | +| Retrieve it in output | | | | | +| Self-repair after error | | | | | +| Stop repeatedly changing key meaning | | | | | + +Current evidence supports: continue same structure / add variation / move to another problem / pause\ +Evidence:\ +Conclusion I still cannot draw:\ +Smallest next task:\ +Next review date: + +Related chapters: [Grammar: Let Structure Serve Meaning](https://byoungd.github.io/up/en/threads/part-1/grammar) | [Learning Principles](https://byoungd.github.io/up/en/threads/part-1/1-understanding) | [Evidence Chain Template](https://byoungd.github.io/up/en/templates/evidence-chain) + +--- + +Source: [Life Level-up Guide](https://byoungd.github.io/up/en/templates/grammar-evidence) · Manuscript updated: 2026-09-02. Content: [CC BY-NC 4.0](https://creativecommons.org/licenses/by-nc/4.0/). diff --git a/docs/public/downloads/worksheets/grammar-evidence.zh.md b/docs/public/downloads/worksheets/grammar-evidence.zh.md new file mode 100644 index 00000000..b6397b92 --- /dev/null +++ b/docs/public/downloads/worksheets/grammar-evidence.zh.md @@ -0,0 +1,104 @@ +# 语法证据卡:从规则识别到真实表达 + +这张卡每次只追踪一个高影响结构。复制到私有笔记,保留原始句子与修改理由。不要记录客户、公司、学校、医疗或第三方的敏感内容;使用合成事实或最小化片段练习。 + +## 1. 定义真实任务 + +日期:\ +场景:邮件 / 说明 / 对话 / 复述 / 面试 / 其他\ +受众:\ +任务必须让对方理解或完成什么:\ +时间、工具和长度限制:\ +原始样本位置: + +## 2. 找到一个结构问题 + +我的原句/片段:\ +对方最可能理解成:\ +我真正想表达:\ +影响类型:意思改变 / 任务阻断 / 高频重复 / 语域不合 / 低影响\ +本轮只追踪的结构: + +| 样本 | 结构选择 | 表达的现实关系 | 是否符合任务 | +| ---- | ---- | ------- | ------ | +| 原句 | | | | +| 对比 A | | | | +| 对比 B | | | | + +## 3. 写一张意义对比卡 + +我要表达的意义:\ +容易混淆的形式:\ +来自可靠材料的例句与来源:\ +一句自己的解释:\ +反例或适用边界: + +解释应回答“为什么这个形式适合这个事实”,而不是只复制术语定义。 + +## 4. 保存修改与理由 + +| 版本 | 条件 | 句子/输出位置 | 修改了什么 | 为什么 | +| ---- | ------- | ------- | ----- | --- | +| 首版 | 无提示 | | | | +| 修改版 | 看过讲解/反馈 | | | | +| 独立重做 | 合上材料 | | | | + +修改后对方如何理解:\ +仍然影响任务的问题:\ +被建议但我没有采纳的风格修改: + +## 5. 在四项能力中调用 + +| 能力 | 小任务 | 结果 | 证据 | +| -- | -------------- | -- | -- | +| 听力 | 听出同一结构承担的关系 | | | +| 阅读 | 标出范围、指向或逻辑连接 | | | +| 口语 | 限时使用并在出错后修复 | | | +| 写作 | 比较两个版本对读者理解的影响 | | | + +不必每轮都完成四项。至少保留一项输入观察和一项主动输出。 + +## 6. AI 与反馈记录 + +工具/反馈者与日期:\ +它观察到的问题:\ +它给出的解释:\ +它是否区分错误、歧义、语域和风格:\ +我如何用词典、语料、教师或读者复核:\ +我采纳/拒绝什么,为什么: + +## 7. 延迟复测 + +| 时间点 | 提示条件 | 新任务 | 独立选择 | 结果 | +| ------- | -------- | ---- | ---- | -- | +| 第 1 天 | 原任务、无提示 | | | | +| 第 3–7 天 | 撤掉规则与原答案 | 平行主题 | | | +| 第 14 天 | 新受众或时间压力 | 迁移任务 | | | + +第 7 天仍然保留的判断:\ +再次出现的错误:\ +换条件后失败在哪里: + +## 8. 评分与去留 + +每项 0–2:`0=未完成`,`1=依赖提示或不稳定`,`2=当前条件下完成`。 + +| 项目 | 第 1 天 | 第 7 天 | 第 14 天 | 证据理由 | +| ---------- | ----: | ----: | -----: | ---- | +| 能说明形式与意义差异 | | | | | +| 能在新句子中识别 | | | | | +| 能在输出中调用 | | | | | +| 出错后能自我修复 | | | | | +| 不再持续改变关键意思 | | | | | + +当前最支持:继续同一结构 / 增加变式 / 转向另一问题 / 暂停\ +依据:\ +仍不能推出的结论:\ +下一项最小任务:\ +下一次复查日期: + +相关章节:[语法篇:让结构服务于意思](https://byoungd.github.io/up/threads/part-1/grammar) | [认知与训练原则](https://byoungd.github.io/up/threads/part-1/1-understanding) | [证据链模板](https://byoungd.github.io/up/templates/evidence-chain) + +--- + +来源:[人生进阶指南](https://byoungd.github.io/up/templates/grammar-evidence) · 稿件更新:2026-09-02。内容许可:[CC BY-NC 4.0](https://creativecommons.org/licenses/by-nc/4.0/)。 diff --git a/docs/public/downloads/worksheets/interview-evidence.en.md b/docs/public/downloads/worksheets/interview-evidence.en.md new file mode 100644 index 00000000..af31fa56 --- /dev/null +++ b/docs/public/downloads/worksheets/interview-evidence.en.md @@ -0,0 +1,160 @@ +# Job-search English Evidence Card: From Job Description to Unfamiliar Follow-up + +This card does not decide whether you are suited to overseas work or promise an interview result. It answers a narrower question: **under this role and process, can I deliver my real ability in English?** + +Copy it into a private note. Job descriptions, recruiting email, take-home tasks, company code, customer information, and interview recordings may contain confidential or personal information. Preserve only the minimum material you have a right to use, and obtain necessary consent before recording. + +## 1. Role and Process + +Role title and public link:\ +Application deadline or interview date:\ +Work mode: remote / hybrid / on-site\ +Primary time zones and collaboration mode:\ +Known interview stages:\ +Explicit language requirement:\ +Recruiting rules still unknown: + +## 2. Role Language Map + +| Role fact | Language task | Current evidence | Risk | Build evidence in two weeks? | +| --------- | ----------------------------------------------------------------------------------------------------------------------------------- | ---------------- | ------------------- | ---------------------------- | +| | recruiter communication / project explanation / technical follow-up / behavioural question / async writing / customer communication | | high / medium / low | | + +Can complete independently:\ +Can complete with preparation:\ +Depends on prompts or translation:\ +Has no sample:\ +One highest-risk gap to repair: + +## 3. Complete Baseline + +Date:\ +Preparation time:\ +Visible support: none / outline / full script\ +Tools: none / dictionary / captions / AI / other\ +Recording and text location: + +| Stage | Time | Acceptance | Independent result | Main error | +| -------------------------- | ----------: | --------------------------------------------------- | ------------------ | ---------- | +| Role-relevant introduction | 2 min | Present work, evidence, direction | | | +| Project explanation | 5 min | Context, responsibility, trade-off, result, unknown | | | +| Unfamiliar follow-up | 3 questions | Understand, answer, or clarify | | | +| Asynchronous update | 20 min | Progress, evidence, risk, next step, owner | | | +| Interaction repair | 1 case | Repeat/confirm/thinking time/unknown boundary | | | + +## 4. Error Map + +| Segment/question | Type | Effect on the task | What to test next | +| ---------------- | ----------------------------------------------------------------------- | ------------------ | ----------------- | +| | content / retrieval / listening / organisation / interaction / accuracy | | | + +Largest problem that is not primarily English:\ +Language error that repeatedly changes key meaning:\ +Repair action worth preserving: + +## 5. Real Story Bank + +Keep six lines rather than a full script: + +Story name:\ +Situation and required task:\ +My specific responsibility:\ +Key action and trade-off:\ +Result, cost, and unknown:\ +What I would change now:\ +Evidence location: + +| Story | Questions it can answer | Available after unfamiliar follow-up? | Fact/privacy check | +| ----- | ------------------------------------------------------------- | ------------------------------------- | ------------------ | +| | problem / failure / conflict / decision / feedback / stopping | yes / no | | + +## 6. Listening and Repair + +Original question I did not understand:\ +Sentence used to request repetition or confirmation:\ +Meaning after restatement:\ +My answer:\ +How shared understanding was confirmed: + +| Repair ability | Baseline 0–2 | Day seven 0–2 | Evidence | +| --------------------------------------------- | -----------: | ------------: | -------- | +| Request a specific repetition | | | | +| Confirm scope | | | | +| Ask for thinking time | | | | +| Admit an unknown and give a verification step | | | | +| Summarise agreement and next action | | | | + +## 7. Asynchronous Writing Sample + +Context:\ +Completed:\ +Evidence:\ +Blocked / risk:\ +Decision needed:\ +Owner and next update: + +Ask one reader: + +What happened:\ +What needs a decision:\ +Who continues and when:\ +Sentence that required guessing: + +## 8. AI and Integrity Record + +Tool and date:\ +Role it simulated:\ +Independent version submitted first:\ +Three problems it raised:\ +Feedback accepted/rejected and why:\ +Parallel result after closing the tool:\ +Stage where AI must be disclosed or is prohibited:\ +Confidential/personal information kept out: + +Do not invent experience, numbers, or ownership. Do not use covert real-time prompting in a live interview without explicit permission. + +## 9. Fourteen-Day Comparison + +| Time point | Condition | Task completion | Understanding/repair | Organisation/retrieval | Async writing | Evidence | +| --------------------- | ------------------------------------------- | --------------: | -------------------: | ---------------------: | ------------: | -------- | +| Day-one baseline | Unscripted, no AI | | | | | | +| Immediate revision | Feedback seen | | | | | | +| Day-seven retest | Parallel questions, original answer removed | | | | | | +| Day-fourteen transfer | New interviewer/order/role question | | | | | | + +Score each 0–2: `0=not completed`, `1=partial or prompt-dependent`, `2=completed under the current condition`. Use only for one person's comparable tasks. + +## 10. Current Role Gates + +- [ ] At least three real stories remain available under changed wording. +- [ ] Recruiter screen, project explanation, and unfamiliar follow-up can be completed. +- [ ] Unclear questions produce clarification rather than guessing. +- [ ] Repeated language errors do not change key meaning. +- [ ] One usable asynchronous update can be written. +- [ ] Confidentiality, recording, and AI boundaries are known. +- [ ] Unknowns can be admitted with a verification method. +- [ ] Equipment, time zone, and interview environment are checked. + +Current evidence most supports: apply and continue practising / repair one high-risk gap / defer this role\ +Evidence:\ +Conclusion I still cannot draw:\ +Smallest next task:\ +Next review date: + +## 11. Post-interview Close + +Actual questions:\ +Evidence of correct understanding:\ +Clarification that worked:\ +Story that failed to answer the question:\ +Structure that transferred:\ +Difficulty not caused primarily by English:\ +Recruiter feedback in original wording:\ +One variable to change:\ +Preparation to stop: + +Related chapters: [Job-search English: Bring Ability into Interviews and Remote Work](https://byoungd.github.io/up/en/threads/part-1/8-job-search-english) | [Speaking Evidence Card](https://byoungd.github.io/up/en/templates/speaking-evidence) | [Writing Evidence Card](https://byoungd.github.io/up/en/templates/writing-evidence) + +--- + +Source: [Life Level-up Guide](https://byoungd.github.io/up/en/templates/interview-evidence) · Manuscript updated: 2026-09-02. Content: [CC BY-NC 4.0](https://creativecommons.org/licenses/by-nc/4.0/). diff --git a/docs/public/downloads/worksheets/interview-evidence.zh.md b/docs/public/downloads/worksheets/interview-evidence.zh.md new file mode 100644 index 00000000..5bb545ab --- /dev/null +++ b/docs/public/downloads/worksheets/interview-evidence.zh.md @@ -0,0 +1,160 @@ +# 求职英语证据卡:从岗位描述到陌生追问 + +这张卡不判断你“适不适合海外工作”,也不承诺通过面试。它回答一个更具体的问题:**在当前岗位和流程下,我能否把真实能力用英语完成交付?** + +复制到私有笔记。岗位描述、招聘邮件、take-home task、公司代码、客户信息和面试录音可能含有保密或个人信息;只保存你有权使用的最少内容,录音前取得必要同意。 + +## 1. 岗位与流程 + +岗位名称与公开链接:\ +申请截止或面试日期:\ +工作方式:远程 / 混合 / 现场\ +主要时区与协作方式:\ +已知面试阶段:\ +岗位明确语言要求:\ +当前仍未知的招聘规则: + +## 2. 岗位语言地图 + +| 岗位事实 | 语言任务 | 当前证据 | 风险等级 | 两周内是否补证据 | +| ---- | --------------------------------------- | ---- | --------- | -------- | +| | 招聘沟通 / 项目说明 / 技术追问 / 行为问题 / 异步写作 / 客户沟通 | | 高 / 中 / 低 | | + +已经能独立完成:\ +需要准备才能完成:\ +依赖提示或翻译:\ +没有样本:\ +只补的一个最高风险缺口: + +## 3. 完整基线 + +日期:\ +准备时间:\ +可见稿件:无 / 提纲 / 逐字稿\ +工具:无 / 词典 / 字幕 / AI / 其他\ +录音与文本位置: + +| 阶段 | 时间 | 完成标准 | 独立结果 | 主要错误 | +| -------- | ----: | ---------------- | ---- | ---- | +| 岗位相关自我介绍 | 2 分钟 | 现在、证据、方向清楚 | | | +| 项目说明 | 5 分钟 | 背景、责任、取舍、结果、未知 | | | +| 陌生追问 | 3 题 | 理解、回答或主动澄清 | | | +| 异步更新 | 20 分钟 | 进展、证据、风险、下一步、负责人 | | | +| 互动修复 | 1 次 | 重复/确认/思考时间/未知边界 | | | + +## 4. 错误地图 + +| 片段/问题 | 类型 | 它如何影响任务 | 下一次只测试什么 | +| ----- | --------------------------- | ------- | -------- | +| | 内容 / 检索 / 听力 / 组织 / 互动 / 准确 | | | + +最大问题其实不是英语的部分:\ +持续改变关键意思的语言错误:\ +最值得保留的修复动作: + +## 5. 真实故事库 + +每个故事只保存六行,不写逐字稿: + +故事名称:\ +场景与必须完成的任务:\ +我的具体责任:\ +关键动作与取舍:\ +结果、代价和未知:\ +如果重来会改变什么:\ +证据位置: + +| 故事 | 可回答的问题 | 陌生追问后是否仍可调用 | 事实/隐私检查 | +| -- | ----------------------------- | ----------- | ------- | +| | 解决问题 / 失败 / 冲突 / 决策 / 反馈 / 停止 | 是 / 否 | | + +## 6. 听力与修复 + +没有听清的原问题:\ +我请求重复或确认的句子:\ +对方重述后我理解的意思:\ +我的回答:\ +最后如何确认双方理解: + +| 修复能力 | 首版 0–2 | 第 7 天 0–2 | 证据 | +| ---------- | -----: | --------: | -- | +| 请求重复具体部分 | | | | +| 确认问题范围 | | | | +| 争取思考时间 | | | | +| 承认未知并给验证步骤 | | | | +| 总结共识与下一步 | | | | + +## 7. 异步写作样本 + +Context:\ +Completed:\ +Evidence:\ +Blocked / risk:\ +Decision needed:\ +Owner and next update: + +请一位读者回答: + +发生了什么:\ +什么需要决定:\ +谁在什么时候继续:\ +哪一句需要猜测: + +## 8. AI 与诚信记录 + +工具与日期:\ +它模拟的角色:\ +我先提交的独立版本:\ +它提出的三个问题:\ +我采纳/拒绝的反馈与理由:\ +关闭工具后的平行问题结果:\ +必须披露或禁止 AI 的阶段:\ +没有上传的保密/个人信息: + +不要虚构经历、数字和职责。未经明确允许,不在真实面试中使用隐蔽实时提示。 + +## 9. 十四天比较 + +| 时间点 | 条件 | 任务完成 | 理解/修复 | 组织/检索 | 异步写作 | 证据 | +| -------- | ------------ | ---: | ----: | ----: | ---: | -- | +| 第 1 天基线 | 无稿、无 AI | | | | | | +| 即时修订 | 看过反馈 | | | | | | +| 第 7 天复测 | 平行问题、撤掉原答案 | | | | | | +| 第 14 天迁移 | 新面试者/顺序/岗位问题 | | | | | | + +每项 0–2:`0=未完成`,`1=部分完成或依赖提示`,`2=在当前条件下完成`。只用于同一人的同类任务比较。 + +## 10. 当前岗位门槛 + +- [ ] 至少三个真实故事可以在不同问法下调用; +- [ ] 能完成招聘筛选、项目说明和陌生追问; +- [ ] 没听清时会确认,不用猜测维持流畅; +- [ ] 关键语言错误不持续改变意思; +- [ ] 能写一份可继续工作的异步更新; +- [ ] 知道保密、录音和 AI 使用边界; +- [ ] 能承认未知,并说明验证方法; +- [ ] 面试设备、时区和环境已检查。 + +当前最支持:立即投递并继续练习 / 先补一个高风险缺口 / 暂缓该岗位\ +依据:\ +仍不能推出的结论:\ +下一项最小任务:\ +下次复查日期: + +## 11. 面试后关账 + +实际问题:\ +理解正确的证据:\ +有效的澄清:\ +没有回答问题的故事:\ +成功迁移的结构:\ +并非英语造成的困难:\ +招聘方原话反馈:\ +下一次只改变的变量:\ +停止准备的内容: + +相关章节:[求职英语篇:把能力带进面试与远程协作](https://byoungd.github.io/up/threads/part-1/8-job-search-english) | [口语证据卡](https://byoungd.github.io/up/templates/speaking-evidence) | [写作证据卡](https://byoungd.github.io/up/templates/writing-evidence) + +--- + +来源:[人生进阶指南](https://byoungd.github.io/up/templates/interview-evidence) · 稿件更新:2026-09-02。内容许可:[CC BY-NC 4.0](https://creativecommons.org/licenses/by-nc/4.0/)。 diff --git a/docs/public/downloads/worksheets/learning-state.en.md b/docs/public/downloads/worksheets/learning-state.en.md new file mode 100644 index 00000000..f5736656 --- /dev/null +++ b/docs/public/downloads/worksheets/learning-state.en.md @@ -0,0 +1,91 @@ +# Learning State Template + +Copy this into a private note. It is a cross-session source of truth, not a performance diary. Do not include passwords, government IDs, exact addresses, sensitive health data, or third-party information without permission. + +On first use, save a file named `learning-state.md`, or create a private note with that name in your usual notes tool, and record where the evidence folder lives. After each session, check the updates proposed by AI, then manually write them back into this main file and update its version and date. Retain the goal, initial baseline, capacity, and boundaries that still apply so the latest version is a complete snapshot. Older versions can be archived; a list of changes alone cannot ask the next conversation to reconstruct the past. + +A file path helps you locate evidence; it does not mean AI has read the file. In an ordinary chat, paste the state and separately attach the files or necessary excerpts to be checked this time. With a tool that can read files, confirm which materials it actually read. When only a path is supplied and the content is unavailable, mark that evidence as “not yet verified”. + +## Learning State + +State version: v1\ +Updated: YYYY-MM-DD\ +Owner:\ +Primary file location:\ +Evidence folder location (relative paths below start here): + +### Goal + +- Real context: +- Current main task: +- 12-week outcome: +- This week's focus: +- Acceptance criteria: +- Deadline: + +### Constraints and Boundaries + +- Weekly time/energy available: +- Materials and tools allowed: +- Content that must not be uploaded or published: +- AI may assist with: +- A person must confirm: + +### Current Level and Baseline + +- Initial baseline date and conditions: +- I can currently (separate from the initial baseline): +- Baseline sample: +- Latest score/feedback: + +| Sample | Conditions | Location | Date | What it does not show yet | +| ------ | ---------- | -------- | ---- | ------------------------- | +| | | | | | + +### Completed + +- \[date] task — output/evidence location — result/next step + +### Errors, Risks, and Knowledge Gaps + +| Error/risk | Evidence | Likely cause/confidence | Next treatment and stop condition | +| ---------- | -------- | ----------------------- | --------------------------------- | + +### Methods That Worked + +- Method — conditions — evidence + +### Hypotheses to Test + +- Hypothesis — counterexample — next test — deadline + +### Latest Handover + +- Completed and evidence: +- Facts still unconfirmed: +- Open decisions: +- Cost/rework so far: +- First action when reopening: +- People to notify or consult: + +### Next Action + +1. Smallest next task: +2. Expected time: +3. Material needed: +4. Evidence to save: +5. Next review date: + +## Cross-session Recovery Prompt + +```text +Below is my learning-state file. In no more than six bullets, restate the state version, goal, current evidence, main errors, boundaries, and next action. Flag conflicts or missing information; do not pretend to remember another chat or invent facts absent from the file. Distinguish results I report from evidence you actually read this time; mark files supplied only as paths without content as not yet verified. Design one exercise only for the “smallest next task”: let me answer first, then give feedback against the acceptance criteria. Do not provide a complete answer unless I ask. Finish with five paste-ready updates: completed, evidence, errors/risks, handover, next action. Remind me to check them before writing them back to the main file; do not claim to have saved them for me. + +[paste Learning State] +``` + +An AI summary is not the source of truth. Resume from the file, saved work, sources, and version number; after a weekly review, update the [Weekly Review](https://byoungd.github.io/up/en/templates/weekly-review), [Evidence Chain](https://byoungd.github.io/up/en/templates/evidence-chain), and [90-Day Cycle Map](https://byoungd.github.io/up/en/templates/90-day-cycle) by their separate jobs instead of copying the same record. + +--- + +Source: [Life Level-up Guide](https://byoungd.github.io/up/en/templates/learning-state) · Manuscript updated: 2026-09-09. Content: [CC BY-NC 4.0](https://creativecommons.org/licenses/by-nc/4.0/). diff --git a/docs/public/downloads/worksheets/learning-state.zh.md b/docs/public/downloads/worksheets/learning-state.zh.md new file mode 100644 index 00000000..2b24dcde --- /dev/null +++ b/docs/public/downloads/worksheets/learning-state.zh.md @@ -0,0 +1,91 @@ +# 学习状态模板 + +复制下列模板到自己的私有笔记。它是跨会话的事实源,不是展示自律的日记。不要写入密码、证件、精确住址、医疗隐私或未获授权的第三方信息。 + +第一次使用时,把文件保存为 `learning-state.md`,或在常用笔记工具中建立同名私有笔记,并写明证据文件夹的位置。每次结束后,先核对 AI 建议的更新,再手动写回这份主文件,更新版本和日期;保留仍有效的目标、初始基线、容量与边界,让最新版本身就是完整快照。旧版本可以归档,不能只留下本次变化而要求下次会话猜出过去。 + +文件路径是给你定位证据的索引,不代表 AI 已经读过该文件。普通聊天需要你粘贴状态,并另外附上本次需要核验的文件或必要片段;使用能够读取文件的工具时,也要确认它实际读取了哪些材料。只提供路径、没有提供内容时,相关证据应标为“尚未核验”。 + +## Learning State + +状态版本:v1\ +更新时间:YYYY-MM-DD\ +维护人:\ +主文件位置:\ +证据文件夹位置(下列相对路径从这里开始): + +### 目标 + +- 真实场景: +- 当前主任务: +- 12 周结果: +- 本周重点: +- 完成标准: +- 截止日期: + +### 约束与边界 + +- 每周可用时间/精力: +- 可以使用的材料与工具: +- 不应上传或公开的内容: +- AI 可以协助: +- 必须由人确认: + +### 当前水平与基线 + +- 初始基线日期与条件: +- 我现在能完成(与初始基线分开): +- 基线样本位置: +- 最近一次评分/反馈: + +| 样本 | 条件 | 位置 | 日期 | 仍然不能说明什么 | +| -- | -- | -- | -- | -------- | +| | | | | | + +### 已完成 + +- \[日期] 任务 — 输出/证据位置 — 结果/下一步 + +### 错误、风险与待补知识 + +| 错误/风险 | 证据 | 可能原因/置信度 | 下一次处理与停止条件 | +| ----- | -- | -------- | ---------- | + +### 已验证有效的方法 + +- 方法 — 在什么条件下有效 — 证据 + +### 待验证假设 + +- 假设 — 反例 — 下一次怎么检验 — 截止日期 + +### 最近一次交接 + +- 已完成与证据: +- 仍未确认的事实: +- 未决选择: +- 已发生的成本/返工: +- 下一次打开文件先做什么: +- 需要通知或征求意见的人: + +### 下一步 + +1. 下一项最小任务: +2. 预计时长: +3. 需要材料: +4. 完成后保存什么证据: +5. 下次复查日期: + +## AI 跨会话恢复提示词 + +```text +下面是我的学习状态文件。先用不超过 6 条要点复述状态版本、目标、当前证据、主要错误、边界和下一步,指出信息冲突或缺口,不要假装记得其他会话,也不要补写文件里没有的事实。区分我报告的结果与本次实际读到的证据;只有路径而没有内容的文件,标为尚未核验。然后只为“下一项最小任务”设计一次练习:先让我作答,再按完成标准反馈;除非我请求,不要直接给完整答案。结束时输出可粘贴回状态文件的“本次完成、证据、错误/风险、交接、下一步”五项更新,提醒我核对后写回主文件,不要声称已经替我保存。 + +[粘贴 Learning State] +``` + +AI 生成的状态摘要不是事实来源。每次恢复时都以你保存的文件、作品、来源和版本号为准;完成一次周复盘后,按文件职责更新[每周复盘](https://byoungd.github.io/up/templates/weekly-review)、[证据链](https://byoungd.github.io/up/templates/evidence-chain)和[九十日行动总表](https://byoungd.github.io/up/templates/90-day-cycle),不要复制同一段记录。 + +--- + +来源:[人生进阶指南](https://byoungd.github.io/up/templates/learning-state) · 稿件更新:2026-09-09。内容许可:[CC BY-NC 4.0](https://creativecommons.org/licenses/by-nc/4.0/)。 diff --git a/docs/public/downloads/worksheets/life-practice-toolkit.en.md b/docs/public/downloads/worksheets/life-practice-toolkit.en.md new file mode 100644 index 00000000..afda0975 --- /dev/null +++ b/docs/public/downloads/worksheets/life-practice-toolkit.en.md @@ -0,0 +1,169 @@ +# Life Practice Toolkit + +This is not a perfect daily streak. It is a private record for seeing reality again. When you face an important choice, scattered attention, relationship conflict, or prolonged exhaustion, copy the relevant section and write facts and a next step. + +Keep the file in a private notes or project directory. Do not include passwords, identity numbers, precise addresses, medical privacy, customer records, or unauthorised third-party information. When there is immediate danger, persistent insomnia, severe low mood, violence, debt, or legal responsibility, contact qualified professional support first. + +## How to Use It + +1. Write the date and current problem before interpreting yourself; +2. complete only the worksheet relevant to the current problem; +3. leave one executable action and one evidence location; +4. return on the agreed review date; do not turn the result into a personality verdict; +5. remove records that no longer help and keep facts that improve the next decision. + +## 1. Decision Brief + +### Decision Brief — YYYY-MM-DD + +Problem to solve:\ +Decision deadline: + +Known facts and sources:\ +My interpretation:\ +Still unknown:\ +Problem type: missing information / outcome uncertainty / value conflict / identity defence\ +Non-negotiable values and boundaries: + +Option A:\ +Option B:\ +Do nothing for now: + +Benefits of each option:\ +Money cost of each option:\ +Health cost of each option:\ +Impact on relationships and responsibility:\ +What is reversible: + +Smallest experiment:\ +Evidence gate and review date:\ +Cost gate:\ +Safety gate:\ +Responsibility gate:\ +Action when triggered: pause / stop / roll back / escalate for help\ +What evidence would overturn this choice: + +Proposer:\ +Final decision owner and basis of authority:\ +Affected people and what they will actually carry:\ +Matters requiring explicit consent:\ +Implementer and required resources:\ +Reviewer and authority to pause:\ +Whose advice is relevant:\ +Current decision:\ +Review date:\ +Evidence to preserve: + +Related chapter: [Decision-Making: Choosing Under Uncertainty](https://byoungd.github.io/up/en/threads/part-2/decision). When a decision affects shared life, privacy, or unequal power, also use [Relationships](https://byoungd.github.io/up/en/threads/part-2/relationships) to check consent and exit routes. + +## 2. Attention Audit + +### Attention Audit — YYYY-MM-DD to YYYY-MM-DD + +Most important question this week: + +| Area | Facts this week | Result | Adjustment next week | +| ------------------------------------------------- | --------------- | ------ | -------------------- | +| Input: reading, video, meetings, chat | | | | +| Switching: notifications, interruptions, browsing | | | | +| Output: work, decisions, retelling, delivery | | | | +| Relationships: conversations where I was present | | | | +| Body: sleep, movement, energy | | | | + +One entrance to close:\ +One 25–45 minute time box to protect:\ +What I know before using AI:\ +What I can still do after closing AI:\ +One experiment for next week: + +Related chapter: [Attention: Return Your Attention to Yourself](https://byoungd.github.io/up/en/threads/part-3/3-attention-and-judgment) + +## 3. Relationship Conversation Card + +### Relationship Conversation Card — YYYY-MM-DD + +Relationship and situation:\ +Who holds more resources, evaluation power, account access, information, or exit cost:\ +What I want this conversation to accomplish:\ +Can the other person safely refuse, pause, or leave this conversation?\ +Do I have explicit consent to record, upload, forward, or publish any material? + +Specific facts I observed:\ +Impact and feelings:\ +What I actually need:\ +One concrete request:\ +Boundary I can enforce:\ +Which responsibilities are mine, and which are not?\ +If the conversation becomes unsafe, I will contact: + +After the conversation: + +- What did the other person actually say? +- Did I really listen? +- What did we explicitly agree to, and what did we not agree to? +- Who owns each action, and when is it due? +- What repair can be observed without requiring forgiveness or reconciliation? +- What remains unresolved? +- When will we review it? + +Related chapter: [Relationships: Becoming an Adult in Connection](https://byoungd.github.io/up/en/threads/part-2/relationships) + +## 4. Recovery Reset + +### Recovery Reset — YYYY-MM-DD + +Safety issue to protect today:\ +People I can contact:\ +High-risk decision to pause:\ +Today's mode: safety / reduced load / rebuilding\ +If safety worsens, what will I stop, whom will I contact, and where will I go? + +Body: + +- Sleep: +- Food: +- Light activity I can tolerate: +- Professional support to consult: + +Basic-life floor: food / sleep preparation / necessary care / critical bills and communication\ +One smallest task today:\ +Evidence of completion:\ +Task limit and end time:\ +Next-day cost to check:\ +What I am allowed not to do today:\ +First action after opening the file tomorrow: + +Support agreement: + +- What a supporter may do: +- What a supporter must not do in my place: +- Signals that require escalation: +- How accounts, documents, and decisions return as risk falls: +- Minimum information needed for the safety task: + +Return-to-work gates: + +- Safety gate: +- Basic-life gate: +- Time-boxed task gate: +- Boundary communication gate: +- Review date and person authorised to pause:\ + One variable to increase next: + +Related chapter: [Recovery: Catch Yourself Before You Push Forward](https://byoungd.github.io/up/en/threads/part-2/recovery) + +## 5. Weekly Review + +Answer five questions each week: + +1. Which fact changed my judgment? +2. Which action left an inspectable result? +3. Which error repeated, and what might cause it? +4. Which boundary needs clearer language or firmer follow-through? +5. Which single smallest experiment will I keep next week? + +Keep this toolkit beside the [Weekly Review template](https://byoungd.github.io/up/en/templates/weekly-review) in the same private directory. The purpose is not to turn life into a spreadsheet. It is to leave one small piece of fact standing when emotion becomes loud. + +--- + +Source: [Life Level-up Guide](https://byoungd.github.io/up/en/templates/life-practice-toolkit) · Manuscript updated: 2026-09-07. Content: [CC BY-NC 4.0](https://creativecommons.org/licenses/by-nc/4.0/). diff --git a/docs/public/downloads/worksheets/life-practice-toolkit.zh.md b/docs/public/downloads/worksheets/life-practice-toolkit.zh.md new file mode 100644 index 00000000..922eb423 --- /dev/null +++ b/docs/public/downloads/worksheets/life-practice-toolkit.zh.md @@ -0,0 +1,169 @@ +# 生活进阶工作表 + +这不是一张要求你每天满分的打卡表,而是一份帮助你重新看见现实的私有记录。遇到重要选择、注意力失控、关系冲突或长期疲惫时,复制对应部分,写下事实和下一步。 + +请把文件放在自己的私有笔记或项目目录里。不要写入密码、证件号码、精确住址、医疗隐私、客户资料或未获授权的第三方信息。涉及紧迫危险、持续失眠、严重低落、暴力、债务或法律责任时,优先联系合格的专业支持。 + +## 使用方式 + +1. 先写日期和当前问题,不急着解释自己; +2. 只填写与当前问题相关的一张表; +3. 每次留下一个可执行动作和一个证据位置; +4. 在约定日期回来复查,不用结果倒推当时的人格; +5. 每周删除已经无用的记录,保留能帮助下一次判断的事实。 + +## 一、选择简报 + +### 选择简报 — YYYY-MM-DD + +要解决的问题:\ +必须在什么时候决定: + +已知事实与来源:\ +我的解释:\ +仍然未知:\ +问题类型:信息不足 / 结果不确定 / 价值冲突 / 身份防卫\ +不可谈判的价值与底线: + +选项 A:\ +选项 B:\ +暂不行动: + +每个选项的收益:\ +每个选项的金钱成本:\ +每个选项的健康成本:\ +每个选项对关系和责任的影响:\ +哪些部分可逆: + +最小实验:\ +证据门槛及复查日期:\ +成本门槛:\ +安全门槛:\ +责任门槛:\ +触发后采取:暂停 / 停止 / 回滚 / 升级求助\ +什么证据会推翻当前选择: + +提议者:\ +最终决定者及其权限依据:\ +受影响的人及其实际承担:\ +需要明确同意的事项:\ +执行者及所需资源:\ +复查者及暂停权限:\ +需要征求谁的意见:\ +当前决定:\ +复查日期:\ +决定之后留下的证据: + +相关章节:[选择篇:在不确定中做决定](https://byoungd.github.io/up/threads/part-2/decision);决定涉及共同生活、隐私或不对等权力时,同时使用[关系篇](https://byoungd.github.io/up/threads/part-2/relationships)检查同意与退出通道。 + +## 二、注意力审计 + +### 注意力审计 — YYYY-MM-DD 至 YYYY-MM-DD + +本周最重要的问题: + +| 区域 | 本周事实 | 带来的结果 | 下周调整 | +| ---------------- | ---- | ----- | ---- | +| 输入:阅读、视频、会议、聊天 | | | | +| 切换:通知、临时任务、无意识浏览 | | | | +| 输出:作品、决定、复述、交付 | | | | +| 关系:真正投入在场的谈话 | | | | +| 身体:睡眠、活动、精力 | | | | + +本周要关闭的一个入口:\ +本周要保护的一个 25–45 分钟时间盒:\ +使用 AI 前我已经知道:\ +关闭 AI 后我还能独立完成:\ +下一周只做的一个实验: + +相关章节:[注意力篇:把注意力还给自己](https://byoungd.github.io/up/threads/part-3/3-attention-and-judgment) + +## 三、关系沟通卡 + +### 关系沟通卡 — YYYY-MM-DD + +关系与场景:\ +谁掌握更多资源、评价权、账号、信息或退出成本:\ +我希望这次谈话完成什么:\ +对方是否可以安全地拒绝、暂停或退出这次谈话:\ +是否获得记录、上传、转发或公开材料的明确同意: + +我观察到的具体事实:\ +我受到的影响和感受:\ +我真正需要的是什么:\ +我希望对方考虑的一个具体请求:\ +我能执行的边界:\ +哪些责任属于我,哪些不属于我:\ +如果谈话变得不安全,我会联系: + +谈话后记录: + +- 对方实际说了什么: +- 我是否真正听完: +- 我们明确同意了什么,没有同意什么: +- 谁负责哪个动作,何时完成: +- 哪个修复可以被观察,而不以原谅或和好为条件: +- 哪个问题仍未解决: +- 下一次何时复查: + +相关章节:[关系篇:在关系中成为成年人](https://byoungd.github.io/up/threads/part-2/relationships) + +## 四、恢复重置表 + +### 恢复重置 — YYYY-MM-DD + +今天最需要保护的安全事项:\ +可以联系的人:\ +需要暂停的高风险决定:\ +今天的模式:安全 / 降档 / 重建\ +如果安全恶化,我会停止什么、联系谁、去哪里: + +身体: + +- 睡眠情况: +- 吃过什么: +- 可以完成的轻量活动: +- 需要咨询的专业支持: + +基本生活底线:饮食 / 睡眠准备 / 必要照护 / 关键账单与沟通\ +今天的一个最小任务:\ +任务完成证据:\ +任务上限和结束时间:\ +第二天需要检查的代价:\ +今天允许自己不做的事:\ +明天打开文件后要做的第一步: + +支持协议: + +- 支持者可以做: +- 支持者不能替我做: +- 需要升级求助的信号: +- 风险降低后如何归还账号、文件和决定权: +- 只分享完成安全任务所需的最少信息: + +复工门槛: + +- 安全门槛: +- 基本生活门槛: +- 限时任务门槛: +- 边界沟通门槛: +- 复查日期与有权暂停的人:\ + 下一次只增加的一个变量: + +相关章节:[恢复篇:先把自己接住](https://byoungd.github.io/up/threads/part-2/recovery) + +## 五、每周复盘 + +每周只回答五个问题: + +1. 哪个事实改变了我的判断? +2. 哪个动作留下了可以检查的结果? +3. 哪个错误在重复,它的可能原因是什么? +4. 哪个边界需要说得更清楚或执行得更坚定? +5. 下周只保留哪一个最小实验? + +把这份工作表和[每周复盘模板](https://byoungd.github.io/up/templates/weekly-review)放在同一个私有目录里。记录不是为了把生活变成表格,而是为了在情绪最响亮的时候,仍然有一小块事实可以站立。 + +--- + +来源:[人生进阶指南](https://byoungd.github.io/up/templates/life-practice-toolkit) · 稿件更新:2026-09-07。内容许可:[CC BY-NC 4.0](https://creativecommons.org/licenses/by-nc/4.0/)。 diff --git a/docs/public/downloads/worksheets/listening-audit.en.md b/docs/public/downloads/worksheets/listening-audit.en.md new file mode 100644 index 00000000..92e1c941 --- /dev/null +++ b/docs/public/downloads/worksheets/listening-audit.en.md @@ -0,0 +1,154 @@ +# Listening Evidence Card: From Playback Time to Meaning Reconstruction + +Copy this card into a private note for one main source and one parallel source at a time. Do not record passwords, client data, or unapproved meeting, student, or family audio. Preserve copyrighted clips, transcripts, and notes only within permitted personal-learning use. + +## 1. Define the Task and Real-World Boundary + +### Listening Evidence - YYYY-MM-DD + +Real situation:\ +Task: gist / detail / relationship / action / interaction / transfer\ +What must I answer, decide, or do afterwards?\ +Completion standard:\ +Confirmation, captions, and written support allowed in reality:\ +Recording, upload, transcript, and sharing permission: + +Training may remove scaffolds. Real work must not abandon necessary safety confirmation to prove ability. + +## 2. Audit Material and Conditions + +Main-source title, origin, and access date:\ +Parallel-source title, origin, and access date:\ +Segment length:\ +Reliable English transcript: human / automatic-needs-checking / none\ +Topic, speaker, and accent familiarity:\ +Device / network / room noise:\ +Copyright and retention boundary:\ +Why I will return during the next seven days: + +| Condition | Main source | Parallel source | Comparable? | +| ------------------------------ | ----------- | --------------- | ----------- | +| Task and difficulty | | | | +| Length and information density | | | | +| Transcript quality | | | | +| Speaker/accent familiarity | | | | +| Device and environment | | | | + +Different material is not automatically a comparable transfer condition. Keep the task and approximate difficulty similar. + +## 3. Preserve a No-Caption First Pass + +First-pass permission: pause / speed / captions / notes / replay\ +One-sentence gist:\ +Three certain details:\ +Speaker stance or purpose:\ +Critical number / time / person / condition:\ +Uncertain timestamps:\ +Action I would take from what I heard:\ +First-pass answer location: + +Do not overwrite the first pass after a replay or caption check. It is the comparison baseline. + +## 4. Build the Six-Layer Error Map + +| Timestamp | I thought I heard | Reliable content | Barrier layer | Task impact | This cycle's action | +| --------- | ----------------- | ---------------- | ---------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------- | ------------------- | +| | | | technical / unknown language / known-not-heard / structure-reference / background-inference / attention-capacity | meaning-changing / task-blocking / recurring / effortful / low-impact | | + +One to three problems that most affect the task:\ +Low-impact missing words I will not repair yet:\ +Device or fatigue effects that cannot be assigned directly to ability: + +## 5. Use the Scaffold Ladder + +| Stage | Action | What became visible? | What remains unproven? | +| ----- | ----------------------------------------------------------------- | -------------------- | ---------------------- | +| 1 | First pass without captions | | | +| 2 | Replay only the 5-20 second problem segment | | | +| 3 | Open the English transcript for boundaries and structure | | | +| 4 | Check minimum definition, background, or translation | | | +| 5 | Close the text and listen at normal speed | | | +| 6 | Remove old support and retest on parallel material after 3-7 days | | | + +Automatic-caption errors:\ +What translation helped:\ +Meaning still triggered after the text closed:\ +Segment understood only while captions remained visible: + +## 6. Make Each Pass Produce Different Evidence + +| Pass | Question | Output | Result | +| ---- | ------------------------------------------------ | ----------------------------------------- | ------ | +| 1 | What did I predict and recover? | Raw gist and details | | +| 2 | Where did the difference occur? | Timestamp and barrier layer | | +| 3 | What did minimum support explain? | Mishearing, transcript, and cause | | +| 4 | Does sound trigger meaning after support closes? | No-text replay | | +| 5 | How can I reconstruct and act? | Retelling / process / decision / handover | | + +Play count is not a result. Each pass should create a new judgment or show that repetition should stop. + +## 7. Move from Dictation and Shadowing into Generation + +High-impact 5-20 second segment:\ +My dictation:\ +Reliable transcript:\ +Boundary / ending / reduction / stress difference:\ +Delayed-shadow recording:\ +Three keywords:\ +Retelling after closing the text:\ +Explanation after changing one fact or position:\ +Unfamiliar follow-up and answer: + +When shadowing is smooth and retelling is empty, shorten imitation and increase keyword reconstruction. When every word is written correctly but the gist is missing, return to structure and relationship. + +## 8. Record AI, Teacher, and Real-Task Feedback + +Tool / reviewer / model version and date:\ +Did it use raw audio, automatic transcript, or my candidate transcript?\ +Error category it proposed:\ +Did it invent wording, background, or speaker intention?\ +Teacher/peer check:\ +Response, action, or repair result in the real task:\ +What I accepted / rejected, and why: + +AI and automatic transcripts provide candidates, not final judgment about the original sound. + +## 9. Test Delayed Retention and Transfer + +| Time | What is removed | Changed condition | Output | Result | +| -------- | -------------------------------- | ------------------------------------- | ------------------------------------- | ------ | +| Day 1 | No full captions | Main source | First pass and meaning reconstruction | | +| Days 3-7 | Old notes and transcript removed | Parallel source | Gist, detail, and action | | +| Day 14 | Recent feedback removed | New speaker, accent, or device | Retelling plus unfamiliar follow-up | | +| Day 30 | All practice prompts closed | Real meeting, course, or conversation | Complete task | | + +Method still available after seven days:\ +Barrier that returned after material changed:\ +Did full-caption or translation dependence decrease?\ +Can I request repetition, confirm, and preserve agreement more reliably?\ +One variable for the next cycle: + +## 10. Score and Decide + +Score 0-2: `0=not completed`, `1=prompt-dependent or unstable`, `2=completed under the current condition`. + +| Item | Day 1 | Day 7 | Day 14 | Evidence reason | +| --------------------------------------------------- | ----: | ----: | -----: | --------------- | +| Preserve the first-pass main line | | | | | +| Recover critical details and relationships | | | | | +| Locate the barrier layer | | | | | +| Understand after captions close | | | | | +| Reconstruct, respond, or act | | | | | +| Complete after material, speaker, or device changes | | | | | + +Current evidence supports: continue main source / downgrade to extensive listening / replace source / move to another problem\ +Most important evidence:\ +Conclusion I still cannot draw:\ +Smallest next task:\ +Next review date: + +Related chapters: [Listening: From Sound Recognition to Real Understanding](https://byoungd.github.io/up/en/threads/part-1/3-listening) | [Speaking](https://byoungd.github.io/up/en/threads/part-1/5-speaking) | [Learning English with AI](https://byoungd.github.io/up/en/threads/part-1/7-ai) | [Evidence Chain Template](https://byoungd.github.io/up/en/templates/evidence-chain) + +--- + +Source: [Life Level-up Guide](https://byoungd.github.io/up/en/templates/listening-audit) · Manuscript updated: 2026-09-02. Content: [CC BY-NC 4.0](https://creativecommons.org/licenses/by-nc/4.0/). diff --git a/docs/public/downloads/worksheets/listening-audit.zh.md b/docs/public/downloads/worksheets/listening-audit.zh.md new file mode 100644 index 00000000..e72916db --- /dev/null +++ b/docs/public/downloads/worksheets/listening-audit.zh.md @@ -0,0 +1,154 @@ +# 听力证据卡:从播放时长到意义重构 + +把这张卡复制到私有笔记中,一次只处理一份主材料与一份平行材料。不要记录密码、客户资料、未经许可的会议、学生或家庭录音;版权材料只在允许的个人学习范围内保存片段、转写和笔记。 + +## 1. 定义任务与现实边界 + +### Listening Evidence — YYYY-MM-DD + +真实场景:\ +任务:抓主旨 / 找细节 / 追踪关系 / 执行动作 / 进入互动 / 迁移\ +听完以后需要回答、决定或做什么:\ +完成标准:\ +现实中允许的确认、字幕与书面辅助:\ +录音、上传、转写和分享许可: + +训练可以撤掉支架,真实工作不能为了证明能力而放弃必要的安全确认。 + +## 2. 审计材料与条件 + +主材料标题、来源与访问日期:\ +平行材料标题、来源与访问日期:\ +片段时长:\ +可靠英文转写:人工 / 自动待核 / 无\ +主题、说话者与口音熟悉度:\ +设备 / 网络 / 房间噪声:\ +版权与保存边界:\ +我为什么愿意在七天内回来: + +| 条件 | 主材料 | 平行材料 | 是否可比较 | +| --------- | --- | ---- | ----- | +| 任务与难度 | | | | +| 时长与信息密度 | | | | +| 转写质量 | | | | +| 说话者/口音熟悉度 | | | | +| 设备与环境 | | | | + +材料不同不等于迁移条件可比。至少保持任务和大致难度相近。 + +## 3. 保存无字幕首听 + +首听允许:暂停 / 倍速 / 字幕 / 笔记 / 重播\ +一句话主旨:\ +三个确定细节:\ +说话者态度或目的:\ +关键数字 / 时间 / 人物 / 条件:\ +不确定时间段:\ +我根据所听会采取的行动:\ +首听答案位置: + +不要用第二遍或字幕后的答案覆盖首听。它是以后比较的基线。 + +## 4. 建立六层错误地图 + +| 时间段 | 我以为听到 | 可靠内容 | 障碍层 | 任务影响 | 本轮动作 | +| --- | ----- | ---- | ----------------------------------------- | ------------------------------- | ---- | +| | | | 技术环境 / 语言未知 / 已知未听出 / 结构指向 / 背景推断 / 注意力容量 | 意思改变 / 任务阻断 / 高频重复 / 理解费力 / 低影响 | | + +最影响任务的一到三个问题:\ +先不处理的低影响漏词:\ +可能来自设备或疲劳、不能直接归因于能力的部分: + +## 5. 使用支架阶梯 + +| 阶段 | 动作 | 我新看见了什么 | 仍然不能证明什么 | +| -- | -------------- | ------- | -------- | +| 1 | 无字幕首听 | | | +| 2 | 只重听 5-20 秒问题片段 | | | +| 3 | 打开英文转写核对词界与结构 | | | +| 4 | 只查最小定义、背景或翻译 | | | +| 5 | 关闭文字按正常速度再听 | | | +| 6 | 三到七天后用平行材料撤架复测 | | | + +自动字幕错误:\ +中文翻译帮助了什么:\ +关闭文字后仍然触发的意思:\ +只在字幕可见时才理解的片段: + +## 6. 让每一遍产生不同证据 + +| 遍次 | 问题 | 输出 | 结果 | +| -- | ---------------- | ----------------- | -- | +| 1 | 我预测什么,首听恢复什么? | 原始主旨与细节 | | +| 2 | 差异出现在哪个时间段? | 时间戳与障碍层 | | +| 3 | 最小支架解释了什么? | 听错、原文与原因 | | +| 4 | 关闭支架后声音是否独立触发意思? | 无文字复听 | | +| 5 | 我能怎样重构并行动? | 复述 / 流程 / 决定 / 交接 | | + +播放次数不是结果。每一遍都应留下新的判断,或证明不必继续重复。 + +## 7. 从听写与跟读进入生成 + +高影响 5-20 秒片段:\ +我的听写:\ +可靠转写:\ +词界 / 词尾 / 弱读 / 重音差异:\ +延迟跟读录音:\ +三个关键词:\ +合上文本后的复述:\ +改变一个事实或立场后的说明:\ +陌生追问与回答: + +跟读顺畅而复述空白时,减少模仿长度,增加关键词重构;每个词都写对却说不出主旨时,回到结构和关系。 + +## 8. 记录 AI、教师与真实任务反馈 + +工具 / 反馈者 / 模型版本与日期:\ +它使用原始音频、自动转写还是我的候选转写:\ +它提出的错误分类:\ +它是否编造词语、背景或说话者意图:\ +教师/同伴核验:\ +真实任务中的回应、执行或修复结果:\ +我采纳 / 拒绝什么,为什么: + +AI 与自动转写可以提供候选,不是原音的最终裁判。 + +## 9. 做延迟保持与迁移 + +| 时间 | 撤掉什么 | 改变的条件 | 输出 | 结果 | +| ------- | -------- | ---------- | --------- | -- | +| 第 1 天 | 不使用完整字幕 | 主材料 | 首听与意义重构 | | +| 第 3-7 天 | 撤掉旧笔记与转写 | 平行材料 | 主旨、细节、行动 | | +| 第 14 天 | 撤掉最近反馈 | 新说话者、口音或设备 | 复述 + 陌生追问 | | +| 第 30 天 | 关闭全部练习提示 | 真实会议、课程或对话 | 完整任务 | | + +七天后仍能使用的方法:\ +换材料后再次出现的障碍:\ +是否更少依赖全文字幕或翻译:\ +是否更能请求重复、确认并留下共识:\ +下一轮只改变的变量: + +## 10. 评分与去留 + +每项 0-2:`0=未完成`,`1=依赖提示或不稳定`,`2=当前条件下完成`。 + +| 项目 | 第 1 天 | 第 7 天 | 第 14 天 | 证据理由 | +| --------------- | ----: | ----: | -----: | ---- | +| 首听保留主线 | | | | | +| 恢复关键细节与关系 | | | | | +| 能定位障碍层 | | | | | +| 关闭字幕后仍能理解 | | | | | +| 能重构、回应或执行 | | | | | +| 换材料、说话者或设备后仍能完成 | | | | | + +当前证据支持:继续主材料 / 降级为泛听 / 更换材料 / 转向另一问题\ +最重要的依据:\ +仍不能推出的结论:\ +下一项最小任务:\ +下一次复查日期: + +相关章节:[听力篇:从声音辨认到真实理解](https://byoungd.github.io/up/threads/part-1/3-listening) | [口语篇](https://byoungd.github.io/up/threads/part-1/5-speaking) | [用 AI 学英语](https://byoungd.github.io/up/threads/part-1/7-ai) | [证据链模板](https://byoungd.github.io/up/templates/evidence-chain) + +--- + +来源:[人生进阶指南](https://byoungd.github.io/up/templates/listening-audit) · 稿件更新:2026-09-02。内容许可:[CC BY-NC 4.0](https://creativecommons.org/licenses/by-nc/4.0/)。 diff --git a/docs/public/downloads/worksheets/reader-field-note.en.md b/docs/public/downloads/worksheets/reader-field-note.en.md new file mode 100644 index 00000000..09dcfe18 --- /dev/null +++ b/docs/public/downloads/worksheets/reader-field-note.en.md @@ -0,0 +1,146 @@ +# Reader Field Note: What Remains Seven Days Later + +This field note is not a book review and does not ask you to prove that a book works. It follows a plainer path: **what brought you in, what you did after reading, and what remained several days later.** + +Copy it into a private note first. Complete the first pass within ten minutes of reading and the second pass three to seven days later. Do not repeatedly reread the chapter just to complete the form. The second record matters because fewer prompts remain. + +Public sharing is always optional. Names, employers, customers, relationships, health, finances, and conversation content that lack permission should not enter a public note merely to make it look “real”. + +## Complete It Privately First + +A useful field note answers only four things: + +1. What real problem did I bring to the page? +2. What did I actually make or do rather than merely agree with? +3. Three to seven days later, could I act again with fewer prompts or under a changed condition? +4. Which passage supported action, and which remained abstract, unsafe, or unusable? + +It is valid to record no action or no retest. “This produced agreement but no action yet” is evidence. You do not need to invent a success story to complete the sheet. + +## First Pass: Ten Minutes after Reading + +### 1. Entry Problem + +Date:\ +Chapter or page:\ +Why I opened it:\ +Real situation at the time:\ +What I could already do before reading:\ +Where I was stuck before reading:\ +Time and capacity available today: + +Do not write “I want to improve myself”. Name a situation that can occur, such as: “I need to hand project risks to a colleague, but the current record contains only chat messages and scattered screenshots.” + +### 2. Retell It in Your Own Words + +Close the page and use no more than three sentences: + +Core judgment as I understand it:\ +Fact, example, or source supporting it:\ +What it still cannot prove for me: + +If you can only copy the original wording, do not rush to rate the chapter. Write “I cannot explain this in my own words yet”. That is more accurate than a polished quotation. + +### 3. Take One Minimum Action + +Choose an action that can end within 10–45 minutes and leaves something visible. + +Minimum action I will complete:\ +Acceptance standard:\ +AI or human assistance used:\ +What I must decide myself:\ +Location of the artifact, recording, code, or note:\ +Stop condition: + +Possible actions include rewriting an email, recording an explanation, repairing one test, creating a learning-state page, removing an invalid requirement, or confirming a boundary with someone affected. Saving more material is not an action. + +### 4. Preserve the Immediate Result + +What I actually completed:\ +What remained incomplete:\ +Direct feedback or outcome:\ +Largest error or resistance:\ +The conclusion I am most tempted to exaggerate:\ +Next retest date: + +Record the approximate minutes from opening the page to the first saved output, plus non-sensitive conditions such as device, available time, prior familiarity, or whether help was used. Write “not recorded” when unknown; do not submit location, employer, health, or private project details for comparability. + +An immediate success shows only what happened under the present conditions. If AI was used, keep the assisted version separate from the independent version completed after closing it. + +## Second Pass: Three to Seven Days Later + +### 5. Retest before Rereading + +Do not open the original chapter, chat, or answer first. Complete a related task and then record: + +Retest date and interval:\ +Prompts removed:\ +Related task:\ +What I completed independently:\ +Prompts still needed:\ +What genuinely remained from the first attempt:\ +Evidence location: + +If nothing returns, do not convert the result into “I was busy”. Record the fact first. Then decide whether the task was too large, the entry unclear, or the chapter produced only short-term agreement. + +### 6. Change One Condition + +For transfer, change only one condition: topic, audience, time limit, material, tool permission, or purpose. + +| Changed condition | New task | Independent result | Where it failed | Next step | +| ----------------- | -------- | ------------------ | --------------- | --------- | +| | | | | | + +A failed transfer is not a bad review. It exposes the boundary of a method and helps an author distinguish a sentence that sounds right from something a reader can actually use. + +### 7. Give Editorial Feedback + +Point to a specific paragraph, heading, example, or tool whenever possible: + +Passage that most supported action:\ +Passage that remained abstract or unusable:\ +Missing boundary, example, or prerequisite:\ +Passage that could be removed or shortened:\ +Part that did not work when I tried it:\ +Question I hope the next edition answers: + +“This is excellent” may encourage the author but rarely changes the next edition. “I followed step three but could not define the acceptance standard” carries more editorial value. + +## Separate Fact, Interpretation, and Wish + +Before sharing, check whether three layers have been mixed: + +| Layer | Example | +| -------------- | -------------------------------------------------------------------------------------------------- | +| Fact | Seven days later, without the page, I completed two requirements and needed a prompt for the third | +| Interpretation | The example may have helped me retain the structure, while the boundary remained abstract | +| Wish | I hope the next edition includes one fully completed example | + +Do not turn one personal result into “this works for everyone”, or one failure into “the method is useless”. Keep the task, conditions, and sample so the conclusion retains boundaries. + +## Privacy Gate before Sharing + +Consider public sharing only when every item passes: + +- [ ] Passwords, keys, identity documents, exact addresses, and private contact details are removed; +- [ ] Customer data, company secrets, medical records, and non-public financial information are removed; +- [ ] Unnecessary third-party names, photos, relationships, and identifying details are removed; +- [ ] Material involving others is authorised or reduced to non-identifying minimum facts; +- [ ] Direct observation, personal interpretation, and next hypothesis are separated; +- [ ] I accept that this record may remain public and searchable for a long time. + +If any item is uncertain, keep the note private. An author does not need your privacy in order to improve a book. + +## When to Move into an Evidence Chain + +A Reader Field Note answers whether one reading entered action. When one ability needs several comparable samples, scoring conditions, delayed retention, and transfer across contexts, move the record into the [Evidence Chain Template](https://byoungd.github.io/up/en/templates/evidence-chain). + +For a completed walkthrough, read [Toolkit Walkthrough: Let AI Continue a 90-Day Learning Project across Sessions](https://byoungd.github.io/up/en/templates/toolkit-walkthrough). It uses synthetic data to show how Learning State, an AI task, an artifact, a retest, and this field note connect. + +After the privacy gate, you may optionally submit a [public Reader Field Note](https://github.com/byoungd/up/issues/new?template=reader-field-note.yml). Public sharing does not determine the value of the practice. + +Related entry points: [Case Study: Let the Book Prove Its Method](https://byoungd.github.io/up/en/threads/part-5/book-as-proof) | [Toolkit Overview](https://byoungd.github.io/up/en/templates/toolkit) | [Weekly Review](https://byoungd.github.io/up/en/templates/weekly-review) + +--- + +Source: [Life Level-up Guide](https://byoungd.github.io/up/en/templates/reader-field-note) · Manuscript updated: 2026-09-10. Content: [CC BY-NC 4.0](https://creativecommons.org/licenses/by-nc/4.0/). diff --git a/docs/public/downloads/worksheets/reader-field-note.zh.md b/docs/public/downloads/worksheets/reader-field-note.zh.md new file mode 100644 index 00000000..bbdd12f8 --- /dev/null +++ b/docs/public/downloads/worksheets/reader-field-note.zh.md @@ -0,0 +1,146 @@ +# 读者实践回执:七天后,还留下了什么 + +这张回执不是书评,也不是要求你证明一本书有效。它只追踪一条更朴素的路径:**你因为什么问题进入,读完后做了什么,几天以后还留下什么。** + +请先复制到自己的私有笔记。第一次在阅读后十分钟填写,第二次在三到七天后填写。不要为了完成表格反复重读原文;第二次记录的价值,正来自提示已经变少。 + +公开分享始终是可选项。没有得到授权的姓名、公司、客户、关系、健康、财务和会话内容,不应为了“证明真实”进入公开回执。 + +## 先在私下完成 + +一份有用的回执只需要回答四件事: + +1. 我原来面对的真实问题是什么? +2. 我实际做出了什么,而不是只同意了什么? +3. 三到七天后,我能否在提示减少或条件变化时再做一次? +4. 哪一段帮助了行动,哪一段仍然抽象、越界或无法使用? + +没有行动、没有复测,也可以如实填写。“暂时只产生认同感”本身就是证据,不需要补写一个成功故事。 + +## 第一次填写:阅读后十分钟 + +### 1. 进入问题 + +日期:\ +章节或页面:\ +我为什么打开它:\ +当时的真实场景:\ +阅读前已经会什么:\ +阅读前卡在哪里:\ +今天可用的时间与容量: + +不要写“我想变优秀”。写一个能够发生的场景,例如:“我需要把项目风险交接给同事,但现有记录只有聊天和零散截图。” + +### 2. 用自己的话复述 + +合上页面,用不超过三句话写: + +我理解的核心判断:\ +它依据的事实、例子或来源:\ +它仍然不能替我证明什么: + +如果只能复制原句,先不要急着评价好坏。写下“我还不能用自己的话说明”,这会比一段漂亮摘抄更准确。 + +### 3. 做一个最小行动 + +选择一个 10–45 分钟可以结束的动作。动作必须留下可查看的痕迹。 + +我要完成的最小动作:\ +完成标准:\ +是否使用 AI / 他人帮助:\ +我必须自己决定的部分:\ +作品、录音、代码或记录位置:\ +停止条件: + +可用动作包括:重写一封邮件、录一段说明、修复一个测试、建立一页学习状态、删除一项无效要求,或向一个受影响的人确认边界。继续收藏资料不算行动。 + +### 4. 保存即时结果 + +实际完成了什么:\ +没有完成什么:\ +收到的直接反馈或结果:\ +最大错误 / 阻力:\ +现在最容易夸大的结论:\ +下一次复测日期: + +记录从打开页面到第一次保存输出的大致时间,以及不涉及身份的条件(设备、可用时间、已有熟悉度、是否得到帮助)。不知道时写“未记录”;不要为了获得可比数字提交位置、雇主、健康或私人项目细节。 + +即时顺利只能说明这一次在当前条件下发生了什么。若使用 AI,请把辅助版和关闭 AI 后的独立版分开保存。 + +## 第二次填写:三到七天后 + +### 5. 不重读,先复测 + +先不要打开原章节、聊天记录或答案。完成一个相近任务,再填写: + +复测日期与间隔:\ +撤掉了哪些提示:\ +相近任务:\ +我独立完成了什么:\ +我仍然需要什么提示:\ +与第一次相比,真正留下了什么:\ +证据位置: + +如果完全记不起来,也不要把失败改成“最近太忙”。先记录事实,再决定任务是否过大、入口是否不清,或内容只制造了短期认同。 + +### 6. 换一个条件 + +迁移只改变一个条件即可:主题、受众、时间限制、材料、工具权限或任务目的。 + +| 改变的条件 | 新任务 | 独立结果 | 失败在哪里 | 下一步 | +| ----- | --- | ---- | ----- | --- | +| | | | | | + +迁移失败不是差评。它能指出一个方法的适用边界,也能帮助作者区分“句子听起来正确”和“读者真的能够使用”。 + +### 7. 写出对书稿的反馈 + +请尽量指向具体段落、标题、例子或工具: + +最帮助我行动的一处:\ +仍然抽象或不知道怎样使用的一处:\ +缺少的边界、例子或前置条件:\ +可以删除或缩短的一处:\ +我尝试后没有奏效的部分:\ +我希望下一版回答的问题: + +“写得很好”让作者开心,却很难改变下一版。“我按第三步做了,但不知道完成标准怎么写”更有编辑价值。 + +## 把事实、解释和愿望分开 + +分享前,检查三层是否混在一起: + +| 层 | 示例 | +| -- | -------------------------- | +| 事实 | 我在七天后没有看原文,完成了两项要求,第三项需要提示 | +| 解释 | 可能因为示例让我记住了结构,但边界部分仍然抽象 | +| 愿望 | 我希望下一版增加一个完整填写样例 | + +不要把一次个人结果写成“所有人都会有效”,也不要把一次失败写成“这个方法完全无用”。保留任务、条件和样本,结论才有边界。 + +## 分享前的隐私门 + +只有全部通过,才考虑公开: + +- [ ] 已删除密码、密钥、证件、精确地址和私人联系方式; +- [ ] 已删除客户数据、公司机密、医疗记录和未公开财务信息; +- [ ] 已删除不必要的第三方姓名、照片、关系与可识别细节; +- [ ] 涉及他人的内容已经获得授权,或改写为不可识别的最少事实; +- [ ] 已区分直接观察、个人解释与下一步假设; +- [ ] 我接受这份记录可能长期公开并被搜索。 + +若任何一项不能确认,就保留在私有笔记。作者不需要通过获得你的隐私来改进一本书。 + +## 什么时候转入证据链 + +读者回执适合回答“这一次阅读有没有进入行动”。当同一能力需要比较多个样本、评分条件、延迟保持和跨场景迁移时,把记录转入[证据链模板](https://byoungd.github.io/up/templates/evidence-chain)。 + +如果你需要看一份完整填写过程,先读[工具箱实战:让 AI 跨会话继续一项 90 天学习](https://byoungd.github.io/up/templates/toolkit-walkthrough)。它使用合成数据演示如何把学习状态、AI 任务、作品、复测和这张回执串起来。 + +完成隐私检查后,可以选择提交[公开读者回执](https://github.com/byoungd/up/issues/new?template=reader-field-note.yml)。公开与否不会改变这次实践的价值。 + +相关入口:[案例篇:让这本书证明它的方法](https://byoungd.github.io/up/threads/part-5/book-as-proof) | [工具箱总览](https://byoungd.github.io/up/templates/toolkit) | [每周复盘](https://byoungd.github.io/up/templates/weekly-review) + +--- + +来源:[人生进阶指南](https://byoungd.github.io/up/templates/reader-field-note) · 稿件更新:2026-09-10。内容许可:[CC BY-NC 4.0](https://creativecommons.org/licenses/by-nc/4.0/)。 diff --git a/docs/public/downloads/worksheets/reading-evidence.en.md b/docs/public/downloads/worksheets/reading-evidence.en.md new file mode 100644 index 00000000..be6b1c8e --- /dev/null +++ b/docs/public/downloads/worksheets/reading-evidence.en.md @@ -0,0 +1,164 @@ +# Reading Evidence Card: From Finished Summary to Real Delivery + +Finishing a text is an action, not proof of comprehension. Copy this card into a private note for one article, chapter, documentation section, or source set at a time. Do not record passwords, client data, unauthorised third-party information, or unnecessary personal details. + +## 1. Define the Task, Reader, and Boundary + +### Reading Evidence - YYYY-MM-DD + +Real situation:\ +Task: locate information / follow an argument / read documentation / build stamina / synthesise sources / support a decision\ +Who must know, decide, execute, or continue something after the reading?\ +Completion standard:\ +Time limit:\ +Dictionary / translation / search / notes / AI allowed:\ +Copyright, privacy, and retention boundary: + +Write completion as a result, such as "can run the minimum example under the current version", not only "finished". + +## 2. Record Source and Version + +| Item | Main source | Parallel source | Comparable? | +| ---------------------------------------------- | ----------- | --------------- | ----------- | +| Author/maintainer, title, link | | | | +| Edition, publication date, or version | | | | +| Access date and length | | | | +| Author/institution position or interest | | | | +| Quotation, image, code, and copyright boundary | | | | +| Topic, genre, and difficulty | | | | + +Web pages change, become paid, or disappear. Keep necessary citation details; do not copy an entire article without permission. + +## 3. Preserve an Unpolished First Pass + +First-pass conditions:\ +First-pass time:\ +Did I look up every word?\ +One-sentence gist:\ +How the text moves:\ +Three certain details:\ +What the author/maintainer wants me to believe or do:\ +One unresolved point:\ +Action I would take from this understanding: + +Finish the first pass before checking words or explanations. Do not replace it with a polished translation. + +## 4. Build a Six-Layer Barrier Map + +| Paragraph/page | Where I got stuck | Barrier layer | Task impact | This cycle's action | +| -------------- | ----------------- | ------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------- | ------------------- | +| | | vocabulary/grammar / structure/reference / background/schema / argument/evidence / layout/technical / attention/capacity | meaning-changing / task-blocking / recurring / effortful / low-impact | | + +One to three barriers that most affect the task:\ +Low-impact words or sentences I will skip for now:\ +Possible device, version, fatigue, or environment effects: + +If almost every sentence blocks the gist, choose easier parallel material or learn domain chunks first. Lowering the entry point does not lower the destination. + +## 5. Map Claims, Evidence, and Limits + +| Paragraph/page | Function | Author claim | Source evidence/example | Limit, counterexample, or unknown | +| -------------- | -------- | ------------ | ----------------------- | --------------------------------- | +| | | | | | + +Facts stated directly:\ +Inference supported by the source:\ +My own judgment or association:\ +Evidence still missing:\ +What new evidence would change my judgment: + +Separate what the author says from whether you agree. For technical, health, legal, or financial claims, return to reliable primary sources or qualified professional advice. + +## 6. Technical Documentation Fact Card + +For an API, SDK, migration guide, command-line help, error reference, or README, add: + +Goal and applicable version:\ +Prerequisites, permissions, and environment:\ +Minimum input:\ +Expected output:\ +Actual output:\ +Defaults, ranges, order, or side effects:\ +Failure condition/error:\ +Limit explicitly stated in the source:\ +Part I am still inferring:\ +Smallest next test: + +Reading documentation without running, reasoning through, reproducing, or confirming one minimum fact shows that you saw the page. It does not show mastery. + +## 7. Record Unknown Words, Word Families, and Translation + +| Word/expression | Role in the task | Definition/family/collocation checked | Source location | Explainable after tools close? | +| --------------- | ----------------------------------------- | ------------------------------------- | --------------- | ------------------------------ | +| | core / recurring / technical / low-impact | | | | + +Background the translation helped me supply:\ +English structure, stance, or qualifier the translation may hide:\ +Word I decided not to check yet: + +Unknown-word count diagnoses source fit; it does not directly set a level. Word families help guessing and coverage, but a derived form is not automatically usable. + +## 8. Compare Sources and Deliver an Output + +Shared question:\ +Definition, date, and evidence in source A:\ +Definition, date, and evidence in source B:\ +Omitted evidence or institutional interest:\ +Which differences are factual, and which are values? + +| Output | Audience | What I delivered | Audience response | Traceable basis? | +| -------------------------------------------------------------------- | -------- | ---------------- | ----------------- | ---------------- | +| Confirmation / minimum test / explanation / decision memo / handover | | | | | + +After reading, let a reader, code, decision, or next task test the understanding. + +## 9. Record Tools and Feedback + +Tool / reviewer / version and date:\ +Did it see the source, my first pass, or my summary?\ +Source locations it says I missed:\ +Did it confuse fact, inference, and style?\ +Teacher/peer/primary-source check:\ +What I accepted/rejected, and why: + +AI may extract candidate terms, ask structural questions, and create parallel tasks, but it may invent summaries, citations, background, and author intention. Preserve the first pass before asking it to locate evidence. + +## 10. Test Delayed Retention and Transfer + +| Date | What is removed | Changed condition | Output | Result | +| -------- | --------------------------------- | ---------------------------------- | ------------------------------------------- | ------ | +| Day 1 | No full translation or AI summary | Main source | First pass and five-sentence reconstruction | | +| Days 3-7 | Old notes and dictionary removed | Parallel source | Gist, evidence, and inference | | +| Day 14 | Recent feedback removed | New topic or genre | Explanation, test, or decision memo | | +| Day 30 | All prompts closed | Real document, report, or handover | Complete delivery | | + +Method still available after seven days:\ +Barrier that returned after the source changed:\ +Did word-by-word translation or summary dependence decrease?\ +Which post-reading action remains unstable?\ +One variable for the next cycle: + +## 11. Score and Decide + +Score 0-2: `0=not completed`, `1=prompt-dependent or unstable`, `2=completed under the current condition`. + +| Item | Day 1 | Day 7 | Day 14 | Evidence reason | +| --------------------------------------------- | ----: | ----: | -----: | --------------- | +| Preserve the first-pass main line | | | | | +| Separate claim, evidence, and inference | | | | | +| Locate the barrier layer and choose an action | | | | | +| Verify a technical fact or source location | | | | | +| Reconstruct after tools close | | | | | +| Deliver after source, topic, or genre changes | | | | | + +Current evidence supports: continue main source / downgrade to extensive reading / replace source / move to another problem\ +Most important evidence:\ +Conclusion I still cannot draw:\ +Smallest next task:\ +Next review date: + +Related chapters: [Reading: From Word-by-word Translation to Claims and Evidence](https://byoungd.github.io/up/en/threads/part-1/4-reading) | [Vocabulary](https://byoungd.github.io/up/en/threads/part-1/2-vocabulary) | [Grammar](https://byoungd.github.io/up/en/threads/part-1/grammar) | [Listening](https://byoungd.github.io/up/en/threads/part-1/3-listening) | [Learning English with AI](https://byoungd.github.io/up/en/threads/part-1/7-ai) | [Evidence Chain Template](https://byoungd.github.io/up/en/templates/evidence-chain) + +--- + +Source: [Life Level-up Guide](https://byoungd.github.io/up/en/templates/reading-evidence) · Manuscript updated: 2026-09-02. Content: [CC BY-NC 4.0](https://creativecommons.org/licenses/by-nc/4.0/). diff --git a/docs/public/downloads/worksheets/reading-evidence.zh.md b/docs/public/downloads/worksheets/reading-evidence.zh.md new file mode 100644 index 00000000..a30a106d --- /dev/null +++ b/docs/public/downloads/worksheets/reading-evidence.zh.md @@ -0,0 +1,164 @@ +# 阅读证据卡:从读完摘要到真实交付 + +“读完”只是一个动作,不是理解的证明。把这张卡复制到私有笔记中,每次记录一篇短文、一个章节、一个技术文档小节或一组来源。不要写入密码、客户资料、未获授权的第三方信息或不必要的隐私。 + +## 1. 定义任务、读者与边界 + +### Reading Evidence - YYYY-MM-DD + +真实场景:\ +任务:定位信息 / 理解论证 / 读懂技术文档 / 建立耐力 / 综合来源 / 支持决定\ +读完以后谁要知道、决定、执行或交接什么:\ +完成标准:\ +限时:\ +允许的词典 / 翻译 / 搜索 / 笔记 / AI:\ +版权、隐私与保存边界: + +把完成标准写成结果,例如“能在当前版本运行最小示例”,不要只写“看完”。 + +## 2. 记录来源与版本 + +| 项目 | 主材料 | 平行材料 | 是否可比较 | +| ------------- | --- | ---- | ----- | +| 作者/维护者、标题、链接 | | | | +| 版本、发布日期或章节 | | | | +| 访问日期与文本长度 | | | | +| 作者/机构立场或利益关系 | | | | +| 引用、图片、代码与版权边界 | | | | +| 主题、体裁与难度 | | | | + +网页会改版、付费或下架。保存必要的引用信息,不要未经许可复制整篇文章。 + +## 3. 保存未经修饰的首读 + +首读条件:\ +首读用时:\ +是否逐词查词:\ +一句话主旨:\ +文章/文档怎样推进:\ +三个确定细节:\ +作者/维护者要我相信或完成什么:\ +一个仍然不确定的地方:\ +根据当前理解我会采取什么行动: + +先完成首读,再查词或看解释。不要用翻译后更漂亮的摘要覆盖它。 + +## 4. 建立六层障碍地图 + +| 段落/页码 | 我卡在哪里 | 障碍层 | 任务影响 | 本轮动作 | +| ----- | ----- | ---------------------------------------------- | ------------------------------- | ---- | +| | | 词汇与语法 / 结构与指向 / 背景与图式 / 论证与证据 / 版面与技术 / 注意力与容量 | 意思改变 / 任务阻断 / 高频重复 / 理解费力 / 低影响 | | + +最影响任务的一到三个障碍:\ +可以先略过的低影响词句:\ +可能来自设备、版本、疲劳或环境的部分: + +若几乎每句都阻断主旨,先换更容易的平行材料或补领域词块。降低入口不等于降低目标。 + +## 5. 画主张、证据与限制 + +| 段落/页码 | 段落功能 | 作者主张 | 原文证据/例子 | 限制、反例或未知 | +| ----- | ---- | ---- | ------- | -------- | +| | | | | | + +原文直接说出的事实:\ +有原文支持的推断:\ +我自己的判断或联想:\ +仍缺少的证据:\ +什么新证据会改变我的判断: + +把“作者说了什么”和“我是否同意”分开。技术、健康、法律或财务内容,回到可靠的一手来源或合格专业意见。 + +## 6. 技术文档事实卡 + +如果材料是 API、SDK、迁移指南、命令行帮助、错误文档或 README,再补这一页: + +目标与适用版本:\ +前置条件、权限与环境:\ +最小输入:\ +预期输出:\ +实际输出:\ +默认值、范围、顺序或副作用:\ +失败条件与错误信息:\ +文档明确写出的限制:\ +我仍然推测的部分:\ +下一项最小测试: + +读完技术文档却没有运行、手算、复现或确认一个最小事实,只能说明你看过页面,不能说明已经掌握。 + +## 7. 生词、词族与翻译记录 + +| 词/表达 | 在本任务中的作用 | 查到的定义/词族/搭配 | 原文位置 | 关闭工具后能否解释 | +| ---- | ------------------ | ----------- | ---- | --------- | +| | 核心 / 反复 / 技术 / 低影响 | | | | + +翻译帮助我补充的背景:\ +翻译可能遮住的英文结构、语气或限定:\ +我决定暂时不查的词: + +未知词数量用于诊断材料难度,不直接决定水平。词族帮助猜测和覆盖率,但派生词不自动等于可用词。 + +## 8. 多来源比较与真实输出 + +共同问题:\ +来源 A 的定义、时间与证据:\ +来源 B 的定义、时间与证据:\ +各自省略或利益关系:\ +哪些差异是事实,哪些是价值判断: + +| 输出 | 受众 | 我交付了什么 | 对方如何回应 | 依据是否可追溯 | +| ------------------------------ | -- | ------ | ------ | ------- | +| 确认邮件 / 最小测试 / 口头解释 / 决策备忘 / 交接 | | | | | + +完成阅读之后,优先让读者、代码、决定或下一项任务检验你的理解。 + +## 9. 记录工具与反馈 + +工具 / 反馈者 / 版本与日期:\ +它看到了原文、我的首读还是我的摘要:\ +它指出的遗漏位置:\ +它是否混淆事实、推断和风格:\ +教师/同伴/一手来源核验:\ +我采纳 / 拒绝什么,为什么: + +AI 可以提取候选术语、提问结构和生成平行任务,但可能编造摘要、引用、背景与作者意图。先保留自己的首读,再请求定位原文。 + +## 10. 做延迟保持与迁移 + +| 日期 | 撤掉什么 | 改变的条件 | 输出 | 结果 | +| ------- | ------------- | ---------- | ---------- | -- | +| 第 1 天 | 不用完整翻译或 AI 摘要 | 主材料 | 首读与五句重构 | | +| 第 3-7 天 | 撤掉旧笔记与词典 | 平行材料 | 主旨、证据、推断 | | +| 第 14 天 | 撤掉最近反馈 | 新主题或新体裁 | 解释、测试或决策备忘 | | +| 第 30 天 | 关闭全部提示 | 真实文档、报告或交接 | 完整交付 | | + +七天后仍能保留的方法:\ +换材料后再次出现的障碍:\ +是否更少逐词翻译或依赖摘要:\ +哪一个读后动作仍然不稳定:\ +下一轮只改变的变量: + +## 11. 评分与去留 + +每项 0-2:`0=未完成`,`1=依赖提示或不稳定`,`2=当前条件下完成`。 + +| 项目 | 第 1 天 | 第 7 天 | 第 14 天 | 证据理由 | +| -------------- | ----: | ----: | -----: | ---- | +| 首读保留主线 | | | | | +| 能区分主张、证据与推断 | | | | | +| 能定位障碍层并选择动作 | | | | | +| 能核验技术事实或来源位置 | | | | | +| 合上工具后能重构 | | | | | +| 换材料、主题或体裁后仍能交付 | | | | | + +当前证据支持:继续主材料 / 降级为泛读 / 更换材料 / 转向另一问题\ +最重要的依据:\ +仍不能推出的结论:\ +下一项最小任务:\ +下一次复查日期: + +相关章节:[阅读篇:从逐词翻译到观点与证据](https://byoungd.github.io/up/threads/part-1/4-reading) | [词汇篇](https://byoungd.github.io/up/threads/part-1/2-vocabulary) | [语法篇](https://byoungd.github.io/up/threads/part-1/grammar) | [听力篇](https://byoungd.github.io/up/threads/part-1/3-listening) | [用 AI 学英语](https://byoungd.github.io/up/threads/part-1/7-ai) | [证据链模板](https://byoungd.github.io/up/templates/evidence-chain) + +--- + +来源:[人生进阶指南](https://byoungd.github.io/up/templates/reading-evidence) · 稿件更新:2026-09-02。内容许可:[CC BY-NC 4.0](https://creativecommons.org/licenses/by-nc/4.0/)。 diff --git a/docs/public/downloads/worksheets/rhythm-ledger.en.md b/docs/public/downloads/worksheets/rhythm-ledger.en.md new file mode 100644 index 00000000..7db79e3c --- /dev/null +++ b/docs/public/downloads/worksheets/rhythm-ledger.en.md @@ -0,0 +1,78 @@ +# Rhythm Ledger Template + +Copy this ledger into a private note and use one page each week. It is not a streak table or a dashboard for scoring your character. It helps you see what deserves to stay, which condition needs to change, and how to return after an interruption. + +Do not write passwords, identity documents, customer data, medical privacy, or unauthorised third-party information. When safety, health, money, or relationship risks are involved, contact a qualified professional or a trusted support person first. + +## 1. One Main Question + +Date range:\ +The one question this week:\ +Real situation and audience:\ +Acceptance standard:\ +Baseline evidence at the start of the week: + +The question should be observable, such as “Can I explain a project risk in English without a script and answer a follow-up?” Do not write “be better this week”. + +## 2. Three Capacity Versions + +| Capacity | When to use it | Minimum action | Evidence that must remain | Stop or downgrade condition | +| -------------- | -------------------------------------------------------------- | -------------- | ------------------------- | --------------------------- | +| Full day | Time and capacity are relatively stable | | | | +| Compressed day | Time is short or attention is fragmented | | | | +| Recovery day | Illness, sleeplessness, grief, or responsibility rises sharply | | | | + +The three versions serve one direction. A recovery day is not a failure. When safety, sleep, the body, or relationships are clearly affected, protect those limits before completing the plan. + +## 3. Give Repetition an Echo + +| Date | Action | Recall / variation / output / feedback | What new information appeared? | Which variable changes next time? | +| ---- | ------ | -------------------------------------- | ------------------------------ | --------------------------------- | +| | | | | | +| | | | | | +| | | | | | +| | | | | | + +If four repetitions produce no new information, change the topic, listener, time limit, number of prompts, or tool permission before simply adding more repetitions. + +## 4. Record One Useful Piece of Feedback + +Who or what provided the feedback:\ +Observation: What did the person actually see, hear, or measure?\ +Impact: How did it affect understanding, use, or the result?\ +Next adjustment: Which one important variable will I change?\ +Evidence location: + +When asking AI for feedback, submit your own version first. Ask for no more than three issues that affect the result, and require a distinction between observation, inference, and suggestion. A person decides what to accept. + +## 5. Interruption and Return + +What happened, as facts (no character judgment):\ +Which condition changed: time / capacity / difficulty / environment / responsibility\ +The smallest return action within 24 hours:\ +What I will explicitly not make up:\ +Who I need to contact or which risk needs escalation: + +If the same resistance appears three times, change the time box, task size, environment, boundary, or support network. Do not repay an interruption with sleep deprivation or shame. + +## 6. This Week's Decision + +One design I will keep:\ +One demand or entry point I will remove:\ +One condition I will change next week:\ +One number I will stop tracking:\ +Next review date:\ +First action when I open the file next time: + +## 7. Handover and Evidence Locations + +First version:\ +Revised version:\ +Feedback or retest:\ +Next task: owner / date: + +Related chapters: [Rhythm: Let Small Things Travel Through Time](https://byoungd.github.io/up/en/threads/part-4/rhythm-and-compounding) | [Daily System: Put Change into the Day](https://byoungd.github.io/up/en/threads/part-4/daily-system) | [Weekly Review Template](https://byoungd.github.io/up/en/templates/weekly-review) + +--- + +Source: [Life Level-up Guide](https://byoungd.github.io/up/en/templates/rhythm-ledger) · Manuscript updated: 2026-09-01. Content: [CC BY-NC 4.0](https://creativecommons.org/licenses/by-nc/4.0/). diff --git a/docs/public/downloads/worksheets/rhythm-ledger.zh.md b/docs/public/downloads/worksheets/rhythm-ledger.zh.md new file mode 100644 index 00000000..17d70fb8 --- /dev/null +++ b/docs/public/downloads/worksheets/rhythm-ledger.zh.md @@ -0,0 +1,78 @@ +# 节律账本模板 + +把这张账本复制到自己的私有笔记,每周使用一页。它不是连续打卡表,也不是给自己评分的仪表盘;它只帮助你看见:什么动作值得保留,什么阻力需要改变条件,以及中断后怎样回来。 + +不要写入密码、证件、客户资料、医疗隐私或未获授权的第三方信息。涉及安全、健康、财务或关系风险时,先求助合格的专业人士或可信的支持者。 + +## 1. 本周主问题 + +日期范围:\ +本周只回答一个问题:\ +真实场景与受众:\ +完成标准:\ +本周开始时的基线证据: + +主问题要能被观察,例如“我能否在没有稿件的情况下,用英语解释一个项目风险并回答追问?”不要写“本周变得更好”。 + +## 2. 三种容量版本 + +| 容量 | 何时使用 | 最小动作 | 必须留下的证据 | 停止或降档条件 | +| --- | --------------- | ---- | ------- | ------- | +| 完整日 | 时间与精力相对稳定 | | | | +| 压缩日 | 时间变少或注意力被切碎 | | | | +| 恢复日 | 生病、失眠、悲伤或责任突然增加 | | | | + +三个版本服务同一个方向。恢复日不是失败;当安全、睡眠、身体或关系受到明显影响时,保护这些底线优先于完成计划。 + +## 3. 重复要带着回声 + +| 日期 | 做了什么动作 | 回忆 / 变式 / 输出 / 反馈 | 新信息是什么 | 下一次改变哪个变量 | +| -- | ------ | ----------------- | ------ | --------- | +| | | | | | +| | | | | | +| | | | | | +| | | | | | + +如果连续四次重复都没有产生新信息,先改变主题、听众、时间限制、提示数量或工具权限,不要只增加次数。 + +## 4. 记录一次有效反馈 + +反馈来自谁或什么结果:\ +观察:对方实际看见、听见或测到了什么?\ +影响:它怎样影响理解、使用或结果?\ +下一次调整:我只改变哪一个重要变量?\ +证据位置: + +向 AI 请求反馈时,先提交自己的版本,要求它最多指出三个影响结果的问题,并区分观察、推断和建议。最终是否采纳,由人决定。 + +## 5. 中断与回归 + +发生了什么事实(不做人格判断):\ +哪个条件改变了:时间 / 精力 / 难度 / 环境 / 责任\ +24 小时内能完成的最小回归动作:\ +这次明确不补做什么:\ +需要联系谁或升级什么风险: + +如果同一阻力连续出现三次,改变时间盒、任务大小、环境、边界或支持网络。不要用熬夜和羞耻偿还缺席。 + +## 6. 本周决定 + +本周保留的一个设计:\ +本周删除的一个要求或入口:\ +下周要改变的一个条件:\ +我停止追踪的一个数字:\ +下次复查日期:\ +下次打开文件后的第一步: + +## 7. 交接与证据位置 + +首版位置:\ +修订版位置:\ +反馈或复测位置:\ +下一项任务交给谁/何时: + +相关章节:[节律篇:让小事穿过时间](https://byoungd.github.io/up/threads/part-4/rhythm-and-compounding) | [生活系统篇:把改变安放在日子里](https://byoungd.github.io/up/threads/part-4/daily-system) | [每周复盘模板](https://byoungd.github.io/up/templates/weekly-review) + +--- + +来源:[人生进阶指南](https://byoungd.github.io/up/templates/rhythm-ledger) · 稿件更新:2026-09-01。内容许可:[CC BY-NC 4.0](https://creativecommons.org/licenses/by-nc/4.0/)。 diff --git a/docs/public/downloads/worksheets/speaking-evidence.en.md b/docs/public/downloads/worksheets/speaking-evidence.en.md new file mode 100644 index 00000000..5e04e1fe --- /dev/null +++ b/docs/public/downloads/worksheets/speaking-evidence.en.md @@ -0,0 +1,152 @@ +# Speaking Evidence Card: From Accent Anxiety to Verifiable Interaction + +Copy this card into a private note for one real situation at a time. Keep raw recordings private by default. Before recording another person or using customer, family, medical, or unreleased project information, obtain necessary permission or practise with fictional details. + +## 1. Define the Task, Listener, and Boundary + +### Speaking Evidence - YYYY-MM-DD + +Real situation:\ +Task: explain / answer / repair / collaborate / transfer\ +Listener and relationship:\ +What the listener must know or do afterwards:\ +Time limit:\ +Allowed notes / retakes / captions / dictionary / AI:\ +Recording and upload permission:\ +Content that must remain private: + +Write completion as a listener result, such as "can retell the risk and next step", not only "sounds fluent". + +## 2. Record Reference Variety and Technical Conditions + +Current reference variety or audio source:\ +Why it fits:\ +Differences I only need to recognise, not force myself to imitate:\ +Other English varieties added this cycle: + +Device / microphone:\ +Network / room noise:\ +Recording or call platform:\ +Listener familiarity with the topic and my accent: + +When device, network, or listener familiarity changes, do not assign the entire score difference to ability. + +## 3. Preserve Three Unscripted Baselines + +| Sample | Condition | Recording | First break | Task completed? | +| ----------------------- | ------------------------------------------------------ | --------- | ----------- | --------------- | +| 90-120 second monologue | Explain a real experience/problem without a script | | | | +| Five-turn exchange | Include at least one unfamiliar follow-up | | | | +| One interaction repair | Repetition, scope confirmation, rephrasing, or summary | | | | + +One-sentence main point:\ +Two details the listener must hear:\ +Critical number / time / responsibility / condition:\ +What I most expect to be misunderstood: + +Do not remove pauses, clean noise, or ask AI for a script first. The baseline shows what remains when scaffolding leaves. + +## 4. Preserve What the Listener Actually Heard + +Ask the listener to hear the recording before seeing a transcript: + +| Listener/condition | Retold gist | Retold details | Guess/replay point | Next response | +| ------------------------ | ----------- | -------------- | ------------------ | ------------- | +| Listener A | | | | | +| Listener B or new device | | | | | + +Noticeable accent that remained intelligible:\ +Place where meaning was actually lost:\ +Place that required effort without misunderstanding:\ +Familiarity or bias that may shape the feedback: + +One subjective impression is not a conclusion. Preserve what the person heard and could do, not only whether you resembled a prestige accent. + +## 5. Build a High-Impact Problem Map + +| Segment/time | Listener may hear | Intended meaning | Type | Task impact | This cycle's action | +| ------------ | ----------------- | ---------------- | ---------------------------------------------------------------- | -------------------------------------------------------------------------------- | ------------------- | +| | | | sound / ending / stress / pause / chunk / grammar / organisation | meaning-changing / task-blocking / recurring / effortful / low-impact difference | | + +Choose only one to three problems. When a difference marks reference variety, region, or personal voice and does not raise comprehension cost, record it without forcing it away. + +## 6. Move from Chunks into Unfamiliar Follow-ups + +Five replaceable chunks:\ +1.\ +2.\ +3.\ +4.\ +5\. + +Topic variation:\ +Position variation:\ +Listener variation:\ +Unfamiliar follow-up:\ +Unscripted answer: + +When fluency exists only inside a memorised script, reduce complete-sentence memorisation and increase keyword reconstruction plus follow-ups. + +## 7. Record Interaction Repair + +| Break | How I noticed | Repair action | Listener response | How shared understanding was confirmed | +| ------------------------------------------------------------------------------------ | ------------- | ------------- | ----------------- | -------------------------------------- | +| Not heard / scope unclear / thinking needed / expression failed / agreement unstable | | | | | + +My repetition or confirmation request:\ +My rephrasing:\ +My final summary of agreement:\ +If repair failed, the one change for next time: + +Repair is not a penalty. Failing to notice a misunderstanding, or failing to restore the task after noticing it, is the training signal. + +## 8. Record Teacher, Listener, and AI Feedback + +Reviewer / tool / model version and date:\ +Did it use raw audio or a transcript?\ +Speech-recognition transcript errors:\ +Problems it marked as high impact:\ +Did it separate accent difference, misunderstanding, effort, grammar, register, and style?\ +Dictionary audio, teacher, or real-listener check:\ +What I accepted / rejected, and why: + +Recognition scores change with microphone, noise, network, model, and accent. Treat them as clues only. + +## 9. Test Delayed Retention and Transfer + +| Time | What is removed | Changed condition | Output | Listener result | +| -------- | ---------------------------------- | ---------------------------------------- | ---------------------------------- | --------------- | +| Day 1 | No AI-written script | Original situation | First take and retake | | +| Days 3-7 | Old script and model audio removed | New topic or listener | 90-120 seconds plus follow-up | | +| Day 14 | Recent feedback removed | New device, accent, or time pressure | Collaboration/decision explanation | | +| Day 30 | All practice prompts closed | Real meeting, interview, or conversation | Complete task | | + +What remained retrievable after seven days:\ +What failed again after conditions changed:\ +Did the listener guess or replay less often?\ +Next variable: + +## 10. Score and Decide + +Score 0-2: `0=not completed`, `1=prompt-dependent or unstable`, `2=completed under the current condition`. + +| Item | Day 1 | Day 7 | Day 14 | Evidence reason | +| ------------------------------------------------------- | ----: | ----: | -----: | --------------- | +| Complete task and main line | | | | | +| Listener recovers critical information | | | | | +| Understanding does not require repeated guessing/replay | | | | | +| Handle an unfamiliar follow-up | | | | | +| Notice and repair an interaction break | | | | | +| Complete after listener, device, or topic changes | | | | | + +Current evidence supports: continue same problem / add variation / move to another problem / pause\ +Most important evidence:\ +Conclusion I still cannot draw:\ +Smallest next task:\ +Next review date: + +Related chapters: [Speaking: Make Meaning Arrive](https://byoungd.github.io/up/en/threads/part-1/5-speaking) | [Listening](https://byoungd.github.io/up/en/threads/part-1/3-listening) | [Job-search English](https://byoungd.github.io/up/en/threads/part-1/8-job-search-english) | [Evidence Chain Template](https://byoungd.github.io/up/en/templates/evidence-chain) + +--- + +Source: [Life Level-up Guide](https://byoungd.github.io/up/en/templates/speaking-evidence) · Manuscript updated: 2026-09-02. Content: [CC BY-NC 4.0](https://creativecommons.org/licenses/by-nc/4.0/). diff --git a/docs/public/downloads/worksheets/speaking-evidence.zh.md b/docs/public/downloads/worksheets/speaking-evidence.zh.md new file mode 100644 index 00000000..9e503c43 --- /dev/null +++ b/docs/public/downloads/worksheets/speaking-evidence.zh.md @@ -0,0 +1,152 @@ +# 口语证据卡:从口音焦虑到可验证互动 + +把这张卡复制到私有笔记中,一次只记录一个真实场景。原始录音优先保持私密;录到他人声音、客户信息、家庭内容、医疗信息或未公开项目时,先取得必要同意,或改用虚构信息练习。 + +## 1. 定义任务、听众与边界 + +### Speaking Evidence — YYYY-MM-DD + +真实场景:\ +任务:说明 / 问答 / 修复 / 协作 / 迁移\ +听众与关系:\ +结束后对方需要知道或做什么:\ +时间限制:\ +允许提纲 / 重录 / 字幕 / 词典 / AI:\ +录音与上传许可:\ +必须保持私密的内容: + +完成标准要写成听众结果,例如“能复述风险和下一步”,不要只写“说得流利”。 + +## 2. 记录参考变体与技术条件 + +当前参考变体或音频来源:\ +选择理由:\ +只需识别、不必强迫模仿的差异:\ +本轮新增的其他英语变体: + +设备 / 麦克风:\ +网络 / 房间噪声:\ +录音或通话平台:\ +听众是否熟悉主题与我的口音: + +设备、网络、听众熟悉度改变时,不要把分数差异全部解释成能力变化。 + +## 3. 保存三种无稿基线 + +| 样本 | 条件 | 录音位置 | 首次断点 | 是否完成任务 | +| ---------- | --------------- | ---- | ---- | ------ | +| 90-120 秒独白 | 无稿说明真实经历/问题 | | | | +| 五轮问答 | 至少一个陌生追问 | | | | +| 一次互动修复 | 请求重复、确认范围、重述或总结 | | | | + +我想传达的一句话主旨:\ +听众必须听见的两个细节:\ +关键数字 / 时间 / 责任 / 条件:\ +我最担心被误解的地方: + +不要先剪掉停顿、降噪或让 AI 生成稿件。首版要显示支架撤掉后能完成什么。 + +## 4. 保存听众实际听见的内容 + +请听众先听录音,不看转写: + +| 听众/条件 | 复述的主旨 | 复述的细节 | 猜测/重听位置 | 下一步反应 | +| --------- | ----- | ----- | ------- | ----- | +| 听众 A | | | | | +| 听众 B 或新设备 | | | | | + +口音显著但仍然理解的地方:\ +真正造成意思丢失的地方:\ +理解需要额外努力但未误解的地方:\ +听众反馈中可能存在的熟悉度或偏见: + +一次主观评价不是结论。优先保存对方听见了什么、需要做什么,而不是“像不像某种标准口音”。 + +## 5. 建立高影响问题地图 + +| 片段/时间 | 听众可能听成 | 我的原意 | 类型 | 任务影响 | 本轮动作 | +| ----- | ------ | ---- | ------------------------------- | --------------------------------- | ---- | +| | | | 音 / 词尾 / 重音 / 停顿 / 词块 / 语法 / 组织 | 意思改变 / 任务阻断 / 高频重复 / 理解费力 / 低影响差异 | | + +每轮只选一到三个问题。若差异只表明参考变体、地区或个人声音不同,且没有提高理解成本,就记录而不必强行修掉。 + +## 6. 从词块进入陌生追问 + +本轮五个可替换词块:\ +1.\ +2.\ +3.\ +4.\ +5\. + +主题变式:\ +立场变式:\ +听众变式:\ +陌生追问:\ +无稿回答位置: + +若只在背熟稿件里流畅,换条件后无法继续,就减少完整句背诵,增加关键词重构与追问。 + +## 7. 记录互动修复 + +| 断点 | 我怎样发现 | 修复动作 | 对方回应 | 如何确认恢复共同理解 | +| ------------------------------- | ----- | ---- | ---- | ---------- | +| 没听清 / 范围不明 / 需要思考 / 表达失败 / 共识不稳 | | | | | + +我主动请求重复或确认的句子:\ +我换用的说法:\ +我最后总结的共识:\ +若修复失败,下一次只改什么: + +修复不是扣分项。没有发现误解、或发现后无法恢复任务,才是需要训练的地方。 + +## 8. 教师、听众与 AI 反馈记录 + +反馈者 / 工具 / 模型版本与日期:\ +它使用的是原始音频还是转写:\ +语音识别转写错误:\ +它判断为高影响的问题:\ +它是否区分口音差异、理解错误、理解费力、语法、语域与风格:\ +我怎样用词典音频、教师或真实听众复核:\ +我采纳 / 拒绝什么,为什么: + +语音识别分数会受麦克风、噪声、网络、模型和口音影响,只能作为线索。 + +## 9. 做延迟保持与迁移 + +| 时间 | 撤掉什么 | 改变的条件 | 输出 | 听众结果 | +| ------- | --------- | ----------- | ------------- | ---- | +| 第 1 天 | 不使用 AI 稿件 | 原场景 | 首版与重录 | | +| 第 3-7 天 | 撤掉原稿与示范音频 | 新主题或新听众 | 90-120 秒 + 追问 | | +| 第 14 天 | 撤掉最近反馈 | 新设备、口音或时间压力 | 协作/决策说明 | | +| 第 30 天 | 关闭全部练习提示 | 真实会议、面试或对话 | 完整任务 | | + +七天后仍然能调用的部分:\ +换条件后再次失败的部分:\ +听众是否更少猜测或重听:\ +下一轮变量: + +## 10. 评分与去留 + +每项 0-2:`0=未完成`,`1=依赖提示或不稳定`,`2=当前条件下完成`。 + +| 项目 | 第 1 天 | 第 7 天 | 第 14 天 | 证据理由 | +| -------------- | ----: | ----: | -----: | ---- | +| 任务与主线完成 | | | | | +| 听众实际恢复关键信息 | | | | | +| 理解不需要持续猜测或重听 | | | | | +| 能处理陌生追问 | | | | | +| 能发现并修复互动断点 | | | | | +| 换听众、设备或主题后仍能完成 | | | | | + +当前证据支持:继续同一问题 / 增加变式 / 转向另一问题 / 暂停\ +最重要的依据:\ +仍不能推出的结论:\ +下一项最小任务:\ +下一次复查日期: + +相关章节:[口语篇:让意思清楚到达](https://byoungd.github.io/up/threads/part-1/5-speaking) | [听力篇](https://byoungd.github.io/up/threads/part-1/3-listening) | [求职英语篇](https://byoungd.github.io/up/threads/part-1/8-job-search-english) | [证据链模板](https://byoungd.github.io/up/templates/evidence-chain) + +--- + +来源:[人生进阶指南](https://byoungd.github.io/up/templates/speaking-evidence) · 稿件更新:2026-09-02。内容许可:[CC BY-NC 4.0](https://creativecommons.org/licenses/by-nc/4.0/)。 diff --git a/docs/public/downloads/worksheets/vocabulary-audit.en.md b/docs/public/downloads/worksheets/vocabulary-audit.en.md new file mode 100644 index 00000000..ec605ea9 --- /dev/null +++ b/docs/public/downloads/worksheets/vocabulary-audit.en.md @@ -0,0 +1,176 @@ +# Vocabulary Evidence Card: From Card Familiarity to Contextual Retrieval + +Copy this card into a private note for one real topic or task. Do not include passwords, customer records, unpublished documents, exam answers, medical privacy, or unauthorised third-party material. A final word list may be public without making source material, recordings, and feedback public. + +## 1. Define the Task and Evidence Conditions + +### Vocabulary Evidence - YYYY-MM-DD + +Real situation and audience:\ +Task: listen / read / speak / write / exam / hand over\ +Material, version, and source:\ +What should another person understand, decide, or complete?\ +Time and length limit:\ +Permitted captions / dictionary / translation / search / AI / people:\ +Privacy, copyright, confidentiality, exam, and expert boundary:\ +First-encounter date:\ +Parallel-task date: + +The target is not "items added." It is understanding, choosing, and retrieving under these conditions. + +## 2. Preserve a No-Lookup First Encounter + +First-encounter start/end time:\ +Gist, relationships, and next step before lookup:\ +Details understood with confidence:\ +Places that required guessing:\ +Sentence or timestamp where meaning stopped:\ +Sense/expression I tried then:\ +Raw retelling, recording, cloze, or draft location:\ +Did it complete the real task? yes / partly / no + +First check whether the barrier is lexical. Sound segmentation, syntax, background, layout, and attention can also break a sentence. + +## 3. Build an Unknown-Item Decision Queue + +| Word/chunk | Task impact | Decision | Basis then | Next check | +| ---------- | ----------------------------------- | -------------------------------------------------- | ---------- | ---------- | +| | blocking / important / minor / none | skip / infer / quick lookup / learn / expert check | | | + +Five to eight chunks entering deliberate learning:\ +Items to skip and why:\ +Items requiring a primary source or expert:\ +Items deferred because of capacity: + +## 4. Record Eight Dimensions for Each Valuable Chunk + +Copy once per chunk: + +Word/chunk:\ +Task function:\ +Form, inflection, and derivation:\ +Sound, stress, and connected speech:\ +Current sense in my own words:\ +Common collocation or sentence slot:\ +Grammatical behaviour:\ +Register, politeness, stance, and identity:\ +Concept, referent, version, or domain boundary:\ +Current retrieval time and required cue:\ +One near-synonym/counterexample and difference: + +Do not copy an entire dictionary page to fill the fields. Keep only what can change understanding or use in this task. + +## 5. Verify Sense, Collocation, and Source + +| Item to check | My candidate | Source, version, location | Result | Unknown | +| ------------------------------- | ------------ | ------------------------- | ------ | ------- | +| Sense | | | | | +| Pronunciation | | | | | +| Collocation | | | | | +| Register | | | | | +| Technical/institutional concept | | | | | + +Why this dictionary/corpus fits this task:\ +Primary document / standard / code location:\ +Check date:\ +Who decides the high-risk term:\ +What evidence would change the decision: + +AI examples and explanations are candidates, not sources. Frequency or confident model tone cannot decide high-risk terminology. + +## 6. Design Unaided Retrieval + +Real intention or situational cue:\ +Prompt allowed on first attempt:\ +Prompt removed next time:\ +Target retrieval time:\ +Speaking task:\ +Writing task:\ +Person / time / topic / tone / mode to change: + +| Attempt | Condition | Actual expression | Retrieval time | Result | +| ---------------- | ------------------------ | ----------------- | -------------: | ------ | +| Original context | Answer hidden | | | | +| Changed context | Source sentence removed | | | | +| Real task | Audience and consequence | | | | + +Reproducing only the complete source sentence is not transfer. + +## 7. Ask a Real Reader or Listener to Check It + +Meaning retold by the reader/listener:\ +Relationship, certainty, and next step they heard:\ +Place that required guessing or confirmation:\ +Did the lexical choice change fact or responsibility?\ +Task completed? yes / partly / no\ +Real response or execution result: + +| Feedback | Type | Decision | Reason | Used in parallel task? | +| -------- | -------------------------------------------------------- | -------------------------------- | ------ | ---------------------- | +| | necessary repair / acceptable variant / register / style | accept / partly / reject / defer | | | + +## 8. Record the Error and Minimum Repair + +| Error sample | Type | Likely gap | Change only this | Retest condition | +| ------------ | ----------------------------------------------------------------------------------- | ---------- | ---------------- | ---------------- | +| | form / sound / sense / collocation / grammar / register / slow retrieval / transfer | | | | + +Chunks correct on cards but failed in the task:\ +Chunks heard but not written:\ +Chunks read but not heard:\ +Acceptable variation mislabelled as error:\ +Items needing a split card, lower volume, or more background: + +## 9. Record AI and Tool Use + +Tool / model / version and date:\ +First encounter and candidate that existed before use:\ +Request: sense contrast / collocation candidate / cloze / counterexample\ +/ audience simulation / error classification / parallel task\ +/ other\ +Scope generated or rewritten by the model:\ +Content that may be invented or outdated:\ +Dictionary / corpus / primary source / human verification:\ +What I accepted, rejected, or deferred, and why:\ +Retrieval task after closing the tool: + +## 10. Test Delayed Retention and Transfer + +| Time | Remove | Change | Output | Result | +| -------- | ---------------------- | ------------------------- | ------------------------ | ------ | +| Same day | Answer and gloss | Original topic | Contextual recall | | +| Day 1 | Source sentence | Sentence and people | Spoken/written retrieval | | +| Days 3-7 | Recent cue | Mode or audience | Parallel input/output | | +| Day 14 | Old cards and feedback | New topic, same task | Timed real output | | +| Day 30 | All practice prompts | Real material/consequence | Full delivery | | + +Chunks still retrieved in time:\ +Chunks successful only in the original item:\ +Most frequent returning error:\ +Did the real task require less guessing or rework? + +## 11. Score and Decide What to Keep + +Score each item `0-2`: `0=no evidence/not completed`, `1=cue-dependent or unstable`, `2=independent under the current condition`. + +| Item | Same day | Day 7 | Day 14 | Evidence reason | +| ----------------------------------------------- | -------: | ----: | -----: | --------------- | +| Recognise it in sound and text | | | | | +| Judge current sense and task impact | | | | | +| Use fitting collocation, form, and register | | | | | +| Retrieve without prompts under time | | | | | +| Deliver intended meaning to reader/listener | | | | | +| Transfer after topic, audience, or mode changes | | | | | + +Chunks to keep learning and why:\ +Chunks needing a split or new cue:\ +Chunks to archive:\ +Chunks requiring expert verification:\ +One condition to change next cycle:\ +Next review date: + +Related chapters: [Vocabulary: From Familiarity to Retrieval in Real Tasks](https://byoungd.github.io/up/en/threads/part-1/2-vocabulary) | [Listening](https://byoungd.github.io/up/en/threads/part-1/3-listening) | [Reading](https://byoungd.github.io/up/en/threads/part-1/4-reading) | [Speaking](https://byoungd.github.io/up/en/threads/part-1/5-speaking) | [Writing](https://byoungd.github.io/up/en/threads/part-1/6-writing) | [Learning English with AI](https://byoungd.github.io/up/en/threads/part-1/7-ai) + +--- + +Source: [Life Level-up Guide](https://byoungd.github.io/up/en/templates/vocabulary-audit) · Manuscript updated: 2026-09-02. Content: [CC BY-NC 4.0](https://creativecommons.org/licenses/by-nc/4.0/). diff --git a/docs/public/downloads/worksheets/vocabulary-audit.zh.md b/docs/public/downloads/worksheets/vocabulary-audit.zh.md new file mode 100644 index 00000000..afe98b15 --- /dev/null +++ b/docs/public/downloads/worksheets/vocabulary-audit.zh.md @@ -0,0 +1,175 @@ +# 词汇证据卡:从卡片眼熟到情境调用 + +把这张卡复制到私有笔记中,一次只记录一个真实主题或任务。不要写入密码、客户资料、未公开文档、考试答案、医疗隐私或未获许可的第三方内容。最终词表可以公开,不代表原始材料、录音和反馈也可以公开。 + +## 1. 定义任务与证据条件 + +### Vocabulary Evidence - YYYY-MM-DD + +真实场景与受众:\ +任务:听 / 读 / 说 / 写 / 考试 / 交接\ +材料、版本与来源:\ +完成后对方应理解、决定或完成什么:\ +时间与长度限制:\ +允许的字幕 / 词典 / 翻译 / 搜索 / AI / 人工帮助:\ +隐私、版权、保密、考试与专业责任边界:\ +首遇日期:\ +平行任务日期: + +词汇目标不是“新增多少”,而是在这些条件下理解、选对并及时调用。 + +## 2. 保存未经查词的首遇 + +首遇开始/结束时间:\ +不查词时理解的主旨、关系与下一步:\ +确定理解的细节:\ +需要猜测的位置:\ +让我停住的原句或时间段:\ +当时尝试的义项/表达:\ +原始复述、录音、填空或写作位置:\ +首遇是否完成真实任务:是 / 部分 / 否 + +先判断障碍是否真是词汇:声音切分、句法、背景、版面和注意力也可能让一句话失败。 + +## 3. 建立未知项决策队列 + +| 词/词块 | 任务影响 | 决定 | 当时依据 | 下一检查点 | +| ---- | ------------------ | ------------------------ | ---- | ----- | +| | 阻断 / 重要 / 次要 / 无影响 | 放过 / 推断 / 速查 / 学习 / 专业核验 | | | + +本轮进入主动学习的 5-8 个词块:\ +可以放过的词及理由:\ +必须由一手来源或专业人员核验的词:\ +因容量不足暂缓的词: + +## 4. 为每个高价值词块记录八个维度 + +每个词块复制一次: + +词/词块:\ +任务功能:\ +词形、屈折与派生:\ +声音、重音与自然语流:\ +当前义项(自己的话):\ +常见搭配或句型槽位:\ +语法行为:\ +语域、礼貌、立场与身份:\ +概念、现实指代、版本或领域边界:\ +当前调用时间与所需提示:\ +一个近义项/反例及差异: + +不要为了填满栏目抄整页词典。只保留会改变当前理解或使用的内容。 + +## 5. 核验义项、搭配与来源 + +| 待核对内容 | 我的候选 | 来源、版本与位置 | 核验结果 | 仍未知 | +| ------- | ---- | -------- | ---- | --- | +| 义项 | | | | | +| 发音 | | | | | +| 搭配 | | | | | +| 语域 | | | | | +| 技术/制度概念 | | | | | + +词典或语料为什么适合这个任务:\ +一手文档/标准/代码位置:\ +查证日期:\ +谁对高风险术语作最终判断:\ +什么新证据会改变当前决定: + +AI 生成的例句和解释是候选,不是来源。高风险术语不能只靠使用频率或模型语气裁决。 + +## 6. 设计无提示调用 + +真实意图或情境线索:\ +第一轮允许的提示:\ +下一轮将撤掉的提示:\ +目标调用时间:\ +口头任务:\ +书面任务:\ +改变的人物 / 时间 / 主题 / 语气 / 模态: + +| 尝试 | 条件 | 我的实际表达 | 调用时间 | 结果 | +| ---- | ------ | ------ | ---: | -- | +| 原情境 | 无答案展示 | | | | +| 改变情境 | 撤掉原句 | | | | +| 真实任务 | 有受众与后果 | | | | + +若只能完整背出原句,先不要记作迁移成功。 + +## 7. 让真实读者或听众验收 + +读者/听众复述的意思:\ +他理解的关系、确定性和下一步:\ +需要猜测或确认的位置:\ +词汇是否改变事实或责任:\ +是否完成任务:是 / 部分 / 否\ +真实回应或执行结果: + +| 反馈 | 类型 | 决定 | 理由 | 是否进入平行任务 | +| -- | ---------------------- | ----------------- | -- | -------- | +| | 必要修复 / 可接受变体 / 语域 / 风格 | 采纳 / 部分 / 拒绝 / 延后 | | | + +## 8. 记录错误与最小修复 + +| 错误样本 | 类型 | 可能缺口 | 下一次只改什么 | 复测条件 | +| ---- | ---------------------------------------- | ---- | ------- | ---- | +| | 词形 / 声音 / 义项 / 搭配 / 语法 / 语域 / 调用慢 / 迁移失败 | | | | + +卡片答对但任务失败的词块:\ +听得懂却写不出的词块:\ +看得懂却听不出的词块:\ +可以接受但被误判成错误的变体:\ +需要拆卡、降量或补背景的项目: + +## 9. 记录 AI 与工具使用 + +工具 / 模型 / 版本与日期:\ +使用前已经存在的首遇和候选:\ +请求:义项比较 / 搭配候选 / 填空 / 反例 / 受众模拟\ +/ 错误分类 / 平行任务 / 其他\ +模型生成或改写的范围:\ +可能捏造或过时的内容:\ +词典 / 语料 / 一手文档 / 人工核验:\ +我采纳、拒绝与延后的项目及理由:\ +关闭工具后的调用任务: + +## 10. 做延迟保持与迁移 + +| 时间 | 撤掉什么 | 改变什么 | 输出 | 结果 | +| ------- | ------- | ------- | ------- | -- | +| 当天 | 答案与释义 | 原主题 | 情境回忆 | | +| 第 1 天 | 原句 | 句子与人物 | 口头/书面调用 | | +| 第 3-7 天 | 最近提示 | 模态或受众 | 平行输入/输出 | | +| 第 14 天 | 旧卡与即时反馈 | 新主题、同任务 | 限时真实输出 | | +| 第 30 天 | 全部练习提示 | 真实材料与后果 | 完整交付 | | + +仍能及时调用的词块:\ +只在原题中成功的词块:\ +最常复发的错误:\ +真实任务是否减少猜测或返工: + +## 11. 评分并决定保留什么 + +每项 `0-2` 分:`0=无证据或未完成`,`1=依赖提示或不稳定`,`2=当前条件下独立完成`。 + +| 项目 | 当天 | 第 7 天 | 第 14 天 | 证据理由 | +| ------------ | -: | ----: | -----: | ---- | +| 在声音和文字中识别 | | | | | +| 判断当前义项与任务影响 | | | | | +| 使用合适搭配、词形与语域 | | | | | +| 在时限内无提示调用 | | | | | +| 让读者/听众收到预期意思 | | | | | +| 换主题、受众或模态后迁移 | | | | | + +继续学习的词块及理由:\ +需要拆分或更换线索的词块:\ +可以归档的词块:\ +必须专业核验的词块:\ +下一轮只改变的一个条件:\ +下次复查日期: + +相关章节:[词汇篇:从眼熟到在真实任务中调用](https://byoungd.github.io/up/threads/part-1/2-vocabulary) | [听力篇](https://byoungd.github.io/up/threads/part-1/3-listening) | [阅读篇](https://byoungd.github.io/up/threads/part-1/4-reading) | [口语篇](https://byoungd.github.io/up/threads/part-1/5-speaking) | [写作篇](https://byoungd.github.io/up/threads/part-1/6-writing) | [用 AI 学英语](https://byoungd.github.io/up/threads/part-1/7-ai) + +--- + +来源:[人生进阶指南](https://byoungd.github.io/up/templates/vocabulary-audit) · 稿件更新:2026-09-02。内容许可:[CC BY-NC 4.0](https://creativecommons.org/licenses/by-nc/4.0/)。 diff --git a/docs/public/downloads/worksheets/weekly-review.en.md b/docs/public/downloads/worksheets/weekly-review.en.md new file mode 100644 index 00000000..0ee6540f --- /dev/null +++ b/docs/public/downloads/worksheets/weekly-review.en.md @@ -0,0 +1,77 @@ +# Weekly Review Template + +A review is not a verdict. It gives next week a more accurate starting point. Reserve 20 minutes, inspect evidence before explaining causes, and change one variable only. Do not include passwords, client data, sensitive health information, or unauthorised third-party details. + +## Weekly Review — YYYY-Www + +### Main Question + +- Goal: +- One question this week: +- Acceptance criteria: +- Constraints (time, energy, responsibility): + +### Evidence Inventory + +- Completed: +- Work/recording/test location: +- First, assisted, and delayed-retest locations: +- External reader/user feedback: + +| Evidence | What it shows | What it does not show yet | +| -------- | ------------- | ------------------------- | +| | | | + +### Four Checks (0–2) + +| Item | Score | Reason and evidence | +| ------------------------------------------------ | ----: | ------------------- | +| Completion: was the task done? | | | +| Quality: did it meet the standard? | | | +| Retention: can it be reproduced days later? | | | +| Transfer: does it work under changed conditions? | | | + +### Errors and Causes + +| Error/barrier | Evidence | Likely cause | Next test | +| ------------- | -------- | ------------ | --------- | +| | | | | + +### Energy and Recovery + +- Effect of sleep/stress on performance: +- Unsustainable arrangement: +- What needs pausing or support: + +### Change One Variable + +- Keep: +- Stop: +- Adjust: +- Most important task and acceptance criteria: +- Next review date: + +### Write Back Without Duplicating Records + +Write back only what can change a decision. Do not copy the same paragraph into four files. Choose the file by its job: + +- [Evidence Chain Template](https://byoungd.github.io/up/en/templates/evidence-chain): compare baseline, immediate performance, delayed retention, and transfer; +- [Rhythm Ledger](https://byoungd.github.io/up/en/templates/rhythm-ledger): keep this week's rhythm, capacity versions, repeated resistance, and next condition to change; +- [Learning State](https://byoungd.github.io/up/en/templates/learning-state): keep cross-session handover, unconfirmed facts, boundaries, and the smallest next task; +- [90-Day Cycle Map](https://byoungd.github.io/up/en/templates/90-day-cycle): keep phase gates, twelve weekly questions, and the direction of the cycle. + +Evidence Chain updated: yes / no / not applicable\ +Rhythm Ledger updated: yes / no / not applicable\ +Learning State updated: yes / no\ +90-Day Cycle Map updated: yes / no / not applicable\ +Evidence location for the smallest next task: + +## Handover Links + +After the review, open only the files whose jobs apply: the [Evidence Chain Template](https://byoungd.github.io/up/en/templates/evidence-chain) compares four time points; the [Rhythm Ledger](https://byoungd.github.io/up/en/templates/rhythm-ledger) records this week's rhythm; [Learning State](https://byoungd.github.io/up/en/templates/learning-state) carries cross-session handover; the [90-Day Cycle Map](https://byoungd.github.io/up/en/templates/90-day-cycle) carries cycle gates. + +Do not redesign the whole system after one poor week. Separate random variation from a pattern repeated at least three times; when a pattern persists, change the environment, task size, or support network first. + +--- + +Source: [Life Level-up Guide](https://byoungd.github.io/up/en/templates/weekly-review) · Manuscript updated: 2026-09-01. Content: [CC BY-NC 4.0](https://creativecommons.org/licenses/by-nc/4.0/). diff --git a/docs/public/downloads/worksheets/weekly-review.zh.md b/docs/public/downloads/worksheets/weekly-review.zh.md new file mode 100644 index 00000000..9b245ceb --- /dev/null +++ b/docs/public/downloads/worksheets/weekly-review.zh.md @@ -0,0 +1,77 @@ +# 每周复盘模板 + +复盘不是给自己判分,而是为下一周留下一个更准确的起点。每周预留 20 分钟,先看证据,再解释原因,最后只改变一个变量。不要写入密码、客户资料、医疗隐私或未获授权的第三方信息。 + +## Weekly Review — YYYY-Www + +### 本周主问题 + +- 目标: +- 本周只回答一个问题: +- 完成标准: +- 约束(时间、精力、责任): + +### 证据清单 + +- 完成了什么: +- 作品/录音/测试位置: +- 首版、辅助版、延迟复测位置: +- 外部读者/用户反馈: + +| 证据 | 它说明了什么 | 仍然不能说明什么 | +| -- | ------ | -------- | +| | | | + +### 四项检查(0–2) + +| 项目 | 分数 | 评分理由与证据 | +| ---------- | -: | ------- | +| 完成:任务是否完成 | | | +| 质量:是否达到标准 | | | +| 保持:几天后还能复现 | | | +| 迁移:换条件还能使用 | | | + +### 错误与原因 + +| 错误/阻碍 | 证据 | 可能原因 | 下一次测试 | +| ----- | -- | ---- | ----- | +| | | | | + +### 精力与恢复 + +- 睡眠/压力对表现的影响: +- 哪个安排不可持续: +- 本周需要暂停或求助的事项: + +### 下周只改一个变量 + +- 保留: +- 停止: +- 调整: +- 最重要任务及完成标准: +- 下次复查日期: + +### 写回状态 + +复盘只写回真正改变决定的内容,不要把同一段话复制到四个文件。按任务选择职责: + +- [证据链模板](https://byoungd.github.io/up/templates/evidence-chain):保存基线、即时表现、延迟保持和迁移的比较; +- [节律账本](https://byoungd.github.io/up/templates/rhythm-ledger):保存本周节奏、容量版本、反复阻力和下周要改变的条件; +- [学习状态](https://byoungd.github.io/up/templates/learning-state):保存跨会话交接、未确认事实、边界和下一项最小任务; +- [九十日行动总表](https://byoungd.github.io/up/templates/90-day-cycle):保存阶段门槛、十二周主问题和周期方向。 + +证据链已更新:是 / 否 / 不适用\ +节律账本已更新:是 / 否 / 不适用\ +学习状态文件已更新:是 / 否\ +九十日行动总表已更新:是 / 否 / 不适用\ +下一项最小任务的证据位置: + +## 写回后的交接入口 + +完成复盘后,按职责打开需要更新的文件: [证据链模板](https://byoungd.github.io/up/templates/evidence-chain) 负责比较四个时间点;[节律账本](https://byoungd.github.io/up/templates/rhythm-ledger) 负责记录本周节奏;[学习状态](https://byoungd.github.io/up/templates/learning-state) 负责跨会话交接;[九十日行动总表](https://byoungd.github.io/up/templates/90-day-cycle) 负责周期门槛。 + +不要因为一周状态差就重写整套计划。先区分偶发波动与连续三次出现的模式;连续出现时,优先改变环境、任务大小或支持网络。 + +--- + +来源:[人生进阶指南](https://byoungd.github.io/up/templates/weekly-review) · 稿件更新:2026-09-01。内容许可:[CC BY-NC 4.0](https://creativecommons.org/licenses/by-nc/4.0/)。 diff --git a/docs/public/downloads/worksheets/writing-evidence.en.md b/docs/public/downloads/worksheets/writing-evidence.en.md new file mode 100644 index 00000000..c6353a21 --- /dev/null +++ b/docs/public/downloads/worksheets/writing-evidence.en.md @@ -0,0 +1,175 @@ +# Writing Evidence Card: From Tool Polish to Accountable Delivery + +Copy this card into a private note for one real writing task at a time. Do not include passwords, client data, unauthorised third-party information, exam answers, or unnecessary personal details. A final version may be public without making the raw draft, feedback, and tool record public. + +## 1. Define the Task, Reader, and Responsibility + +### Writing Evidence - YYYY-MM-DD + +Real situation:\ +Task: explain / request / status / decide / narrate / reflect / hand over\ +Audience and relationship:\ +What should they understand, decide, or do afterwards?\ +Genre, length, and deadline:\ +Completion standard:\ +Dictionary / translation / search / AI / human help allowed:\ +Confidentiality, copyright, privacy, and authorship boundary:\ +Final accountable owner: + +When an institution, school, client, or hiring process prohibits assistance, follow the current rule. + +## 2. Preserve an Unaided Draft + +Raw draft location:\ +First-version time and length:\ +Outline or sources allowed:\ +One sentence the reader should remember:\ +Fact I trust least:\ +Gap most likely hidden by attractive prose:\ +Action I expect from the first version: + +Do not check whole-sentence translations or ask AI for prose first. Keep pauses, repetition, and failed paragraphs as the baseline. + +## 3. Build a Fact and Responsibility Ledger + +| Claim/content | Type | Source, version, and location | Check date | Confidence | Publishable? | What changes it? | +| ------------- | ------------------------------------------------------------------------------- | ----------------------------- | ---------- | ---------- | ------------ | ---------------- | +| | fact / number / quotation / experience / inference / advice / other-person data | | | | | | + +What I knew then and learned later:\ +Third-party content requiring permission:\ +Part still unverifiable:\ +Content to remove or anonymise before delivery: + +## 4. Preserve the Document Skeleton + +Problem facing the reader:\ +Direct answer:\ +Support 1:\ +Support 2:\ +Concrete example/minimum fact:\ +Limit, counterexample, or unknown:\ +Reader's next step: + +| Paragraph | Function | Must keep | Delete/move | Reason | +| --------- | ------------------------------------------------------------------------------------------------------ | --------- | ----------- | ------ | +| | context / problem / claim / reason / evidence / example / turn / limit / request / decision / handover | | | | + +## 5. Record Translation Meaning Changes + +| What I mean | English first draft | Translation/tool candidate | Final decision | Reason | +| ----------- | ------------------- | -------------------------- | -------------- | ------ | +| | | | | | + +Did agent or responsibility change?\ +Was certainty strengthened or weakened?\ +Did negation or condition scope change?\ +Does tone fit the relationship?\ +Non-equivalent institutional/cultural term:\ +Glossary and reviewer: + +Natural, fluent, and faithful are different judgments. The final author explains the trade-off. + +## 6. Complete Five Revision Passes + +| Pass | Main problem | Before | After | Why it changes the task result | +| ---------------------- | ------------ | ------ | ----- | ------------------------------ | +| Task and fact | | | | | +| Structure and evidence | | | | | +| Sentence and meaning | | | | | +| Register and voice | | | | | +| Delivery and boundary | | | | | + +Necessary correction:\ +Ambiguity repair:\ +Register choice:\ +Personal voice retained:\ +Change I rejected because I could not explain it: + +## 7. Record Feedback Uptake + +Ask for a retelling before comments: + +Reader's retold point:\ +Evidence and limits the reader heard:\ +Next step the reader understood:\ +Place requiring guessing: + +| Feedback | Source/relationship | Category | Decision | Reason | Used in parallel text? | +| -------- | ------------------------------------------ | ---------------------------------------------------------------- | -------------------------------- | ------ | ---------------------- | +| | real reader / peer / teacher / editor / AI | correction / ambiguity / structure / evidence / register / style | accept / partly / reject / defer | | | + +An improved old draft does not prove new-task use. Feedback begins to show transfer when it enters a parallel text. + +## 8. Record AI and Automated Tool Use + +Tool / model / version and date:\ +Draft and sources that existed before use:\ +Request: diagnosis / reader simulation / fact candidate / correction\ +/ version comparison / counterexample / other\ +Scope generated or rewritten by the model:\ +Facts, quotations, or sources it may have invented:\ +My item-by-item verification:\ +What I accepted/rejected, and why:\ +Disclosure required for school, client, employer, or reader:\ +Parallel task after closing the tool: + +Model output is a candidate. It does not own authorship or carry final accountability. + +## 9. Check Asynchronous Delivery + +| Check | Content | Accepted? | +| ------------------------------------ | ------- | --------- | +| One-sentence conclusion/subject | | | +| Completed work and evidence location | | | +| Risk, block, and unknown | | | +| Who decides what by when | | | +| Next step, owner, and checkpoint | | | +| What happens without a response | | | +| Failure, stop, and rollback | | | +| Links, attachments, and permissions | | | + +Can the reader continue without another meeting?\ +Real response or execution result:\ +Gap that still required oral explanation: + +## 10. Test Delayed Retention and Transfer + +| Time | What is removed | Changed condition | Output | Result | +| -------- | --------------------------------------- | -------------------------------------------- | -------------------------- | ------ | +| Day 1 | No AI-written prose | Original task | Draft and delivery version | | +| Days 3-7 | Old sentences and comments removed | New topic, same genre | Parallel text | | +| Day 14 | Recent feedback and translation removed | New audience, same information | Register-transfer text | | +| Day 30 | All practice prompts closed | Real email, report, application, or handover | Complete delivery | | + +Structure and judgment available after seven days:\ +Problem that returned with a new topic:\ +Did whole-sentence translation/full rewrite dependence decrease?\ +Did the reader guess less?\ +One variable for the next cycle: + +## 11. Score and Decide Whether to Sign + +Score 0-2: `0=not completed`, `1=prompt-dependent or unstable`, `2=completed under the current condition`. + +| Item | Day 1 | Day 7 | Day 14 | Evidence reason | +| ----------------------------------------------- | ----: | ----: | -----: | --------------- | +| Leave an independent draft | | | | | +| Make task, reader, and next step clear | | | | | +| Separate fact, source, and inference | | | | | +| Support conclusion with structure and evidence | | | | | +| Explain translation/AI/feedback changes | | | | | +| Let async reader continue or roll back | | | | | +| Deliver after topic, audience, or genre changes | | | | | + +Current version: willing to sign / needs verification / narrow scope / do not deliver\ +Most important evidence:\ +Conclusion I still cannot draw:\ +Smallest next task:\ +Next review date: + +Related chapters: [Writing: From Draft to Verifiable Revision](https://byoungd.github.io/up/en/threads/part-1/6-writing) | [Grammar](https://byoungd.github.io/up/en/threads/part-1/grammar) | [Reading](https://byoungd.github.io/up/en/threads/part-1/4-reading) | [Learning English with AI](https://byoungd.github.io/up/en/threads/part-1/7-ai) | [Job-search English](https://byoungd.github.io/up/en/threads/part-1/8-job-search-english) | [Artifacts](https://byoungd.github.io/up/en/threads/part-3/4-artifacts-and-delivery) + +--- + +Source: [Life Level-up Guide](https://byoungd.github.io/up/en/templates/writing-evidence) · Manuscript updated: 2026-09-02. Content: [CC BY-NC 4.0](https://creativecommons.org/licenses/by-nc/4.0/). diff --git a/docs/public/downloads/worksheets/writing-evidence.zh.md b/docs/public/downloads/worksheets/writing-evidence.zh.md new file mode 100644 index 00000000..7482503d --- /dev/null +++ b/docs/public/downloads/worksheets/writing-evidence.zh.md @@ -0,0 +1,174 @@ +# 写作证据卡:从工具润色到署名交付 + +把这张卡复制到私有笔记中,一次只记录一个真实写作任务。不要写入密码、客户资料、未获许可的第三方信息、考试答案或不必要的隐私。最终版本可以公开,不代表原始初稿、反馈和工具记录必须公开。 + +## 1. 定义任务、读者与责任 + +### Writing Evidence - YYYY-MM-DD + +真实场景:\ +任务:说明 / 请求 / 状态更新 / 决策 / 叙事 / 反思 / 交接\ +受众与关系:\ +读完后对方需要理解、决定或做什么:\ +体裁、字数与截止时间:\ +完成标准:\ +允许的词典 / 翻译 / 搜索 / AI / 人工帮助:\ +保密、版权、隐私与署名边界:\ +最终责任人: + +若机构、学校、客户或招聘流程禁止某类帮助,以当前规则为准。 + +## 2. 保存无辅助初稿 + +原始初稿位置:\ +首版用时与字数:\ +首版允许的提纲或资料:\ +我想让读者记住的一句话:\ +我最没有把握的事实:\ +最可能被漂亮话掩盖的空缺:\ +我根据首版期待读者采取的行动: + +不先查整句译文、不让 AI 生成正文。保留停顿、重复和失败段落;它们是以后比较的基线。 + +## 3. 建立事实与责任账本 + +| 主张/内容 | 类型 | 来源、版本与位置 | 核验日期 | 置信度 | 可否公开 | 什么会改变它 | +| ----- | ---------------------------------- | -------- | ---- | --- | ---- | ------ | +| | 事实 / 数字 / 引语 / 经历 / 推断 / 建议 / 他人信息 | | | | | | + +当时知道什么、后来才知道什么:\ +需要许可的第三方内容:\ +仍然无法核验的部分:\ +必须在交付前删除或匿名化的内容: + +## 4. 保存文档骨架 + +读者面对的问题:\ +直接回答:\ +依据 1:\ +依据 2:\ +具体例子/最小事实:\ +限制、反例或未知:\ +读者下一步: + +| 段落 | 功能 | 必须保留 | 可以删除/移动 | 理由 | +| -- | ---------------------------------------------------- | ---- | ------- | -- | +| | 背景 / 问题 / 主张 / 理由 / 证据 / 例子 / 转折 / 限制 / 请求 / 决定 / 交接 | | | | + +## 5. 记录翻译的意义变化 + +| 我真正想表达 | 英文首版 | 翻译/工具候选 | 最终决定 | 理由 | +| ------ | ---- | ------- | ---- | -- | +| | | | | | + +主体或责任是否改变:\ +确定性是否被放大/减弱:\ +否定或条件范围是否变化:\ +语气是否适合关系:\ +不可直译的术语/制度/文化概念:\ +术语表与审校者: + +自然、流畅和忠实是不同判断。最终作者需要解释取舍。 + +## 6. 完成五次修订 + +| 遍次 | 主要问题 | 修改前 | 修改后 | 为什么改变任务结果 | +| ----- | ---- | --- | --- | --------- | +| 任务与事实 | | | | | +| 结构与证据 | | | | | +| 句子与意义 | | | | | +| 语域与声音 | | | | | +| 交付与边界 | | | | | + +本轮必要纠错:\ +歧义修复:\ +语域选择:\ +保留的个人风格:\ +无法解释、因此没有接受的修改: + +## 7. 记录反馈吸收 + +先请读者复述,再看批注: + +读者复述的主旨:\ +读者认为的依据与限制:\ +读者理解的下一步:\ +需要猜测的位置: + +| 反馈 | 来源/关系 | 分类 | 决定 | 理由 | 是否进入平行文本 | +| -- | ------------------------ | --------------------------- | ----------------- | -- | -------- | +| | 真实读者 / 同伴 / 教师 / 编辑 / AI | 纠错 / 歧义 / 结构 / 证据 / 语域 / 风格 | 采纳 / 部分 / 拒绝 / 延后 | | | + +旧稿改好不等于新任务会用。反馈必须进入一份平行文本才开始证明迁移。 + +## 8. 记录 AI 与自动工具使用 + +工具 / 模型 / 版本与日期:\ +使用前已有的初稿与来源:\ +请求:诊断 / 模拟读者 / 事实候选 / 语言纠错 / 版本比较 / 反例 / 其他\ +模型生成或重写的范围:\ +模型可能编造的事实、引语或来源:\ +我逐项核验的方式:\ +我采纳 / 拒绝什么,为什么:\ +需要向学校、客户、雇主或读者披露什么:\ +关闭工具后的平行任务: + +模型输出可以成为候选,不拥有署名,也不能替最终作者承担责任。 + +## 9. 检查异步交付 + +| 检查项 | 内容 | 验收 | +| ----------- | -- | -- | +| 一句结论/主题行 | | | +| 已完成与证据位置 | | | +| 风险、阻塞与未知 | | | +| 需要谁何时决定什么 | | | +| 下一步、负责人和检查点 | | | +| 无回应时的处理 | | | +| 失败、停止与回滚 | | | +| 链接、附件与权限 | | | + +读者能否不参加额外会议就继续:\ +真实回应或执行结果:\ +交接后仍需作者口头补充的缺口: + +## 10. 做延迟保持与迁移 + +| 时间 | 撤掉什么 | 改变的条件 | 输出 | 结果 | +| ------- | --------- | ------------- | ------ | -- | +| 第 1 天 | 不使用 AI 正文 | 原任务 | 初稿与交付版 | | +| 第 3-7 天 | 撤掉旧句子和批注 | 新主题、同体裁 | 平行文本 | | +| 第 14 天 | 撤掉最近反馈与翻译 | 新受众、同信息 | 语域迁移文本 | | +| 第 30 天 | 关闭全部练习提示 | 真实邮件、报告、申请或交接 | 完整交付 | | + +七天后仍能调用的结构与判断:\ +换主题后再次出现的问题:\ +是否减少整句翻译或全文重写依赖:\ +读者是否更少猜测:\ +下一轮只改变的变量: + +## 11. 评分与署名决定 + +每项 0-2:`0=未完成`,`1=依赖提示或不稳定`,`2=当前条件下完成`。 + +| 项目 | 第 1 天 | 第 7 天 | 第 14 天 | 证据理由 | +| -------------- | ----: | ----: | -----: | ---- | +| 独立留下初稿 | | | | | +| 任务、读者和下一步清楚 | | | | | +| 事实、来源与推断可区分 | | | | | +| 结构和证据支持结论 | | | | | +| 能解释翻译/AI/反馈修改 | | | | | +| 异步读者能继续或回滚 | | | | | +| 换主题、受众或体裁后仍能交付 | | | | | + +当前版本:愿意署名 / 需再核验 / 需缩小范围 / 不应交付\ +最重要的依据:\ +仍不能推出的结论:\ +下一项最小任务:\ +下一次复查日期: + +相关章节:[写作篇:从初稿到可验证修订](https://byoungd.github.io/up/threads/part-1/6-writing) | [语法篇](https://byoungd.github.io/up/threads/part-1/grammar) | [阅读篇](https://byoungd.github.io/up/threads/part-1/4-reading) | [用 AI 学英语](https://byoungd.github.io/up/threads/part-1/7-ai) | [求职英语篇](https://byoungd.github.io/up/threads/part-1/8-job-search-english) | [作品篇](https://byoungd.github.io/up/threads/part-3/4-artifacts-and-delivery) + +--- + +来源:[人生进阶指南](https://byoungd.github.io/up/templates/writing-evidence) · 稿件更新:2026-09-02。内容许可:[CC BY-NC 4.0](https://creativecommons.org/licenses/by-nc/4.0/)。 diff --git a/docs/public/en/threads/part-4/my-story/index.html b/docs/public/en/threads/part-4/my-story/index.html index ce93773a..3d34f6ef 100644 --- a/docs/public/en/threads/part-4/my-story/index.html +++ b/docs/public/en/threads/part-4/my-story/index.html @@ -4,7 +4,7 @@ - + ', + '', + 'Target', + 'Existing photo', + '
', + ].join("\n"); + const content = inspect(source, page); + assert.deepEqual(content.links, [{ target: "target.md", line: 8 }, { target: "assets/photo.webp", line: 9 }]); + assert.deepEqual(content.images, [{ alt: "Existing photo", line: 9 }]); + assert.deepEqual([...content.anchors], ["script-block", "style-block", "real-link"]); + assert.deepEqual(contentLinkErrors(content, page, docsRoot, inspectFile), []); +}); + +test("multiline HTML images validate src and preserve alt and source line", () => { + const source = "Text\n\n\nExisting photo\n"; + const content = inspect(source, page); + assert.deepEqual(content.images, [{ alt: "A > B diagram", line: 3 }, { alt: "Existing photo", line: 7 }]); + assert.deepEqual(contentLinkErrors(content, page, docsRoot, inspectFile), [ + { line: 3, message: "链接目标不存在: missing.webp" }, + ]); +}); + +test("site root routes, README rewrites and public downloads resolve to files", () => { + for (const [route, source] of [ + ["/", "README.md"], + ["/index", "README.md"], + ["/index.html", "README.md"], + ["/en/", "en/README.md"], + ["/en/index.html", "en/README.md"], + ["/threads/archive/", "threads/archive/README.md"], + ["/chapter", "chapter.md"], + ["/chapter.md", "chapter.md"], + ["/chapter.html?mode=read", "chapter.md"], + ["/downloads/book.pdf", "public/downloads/book.pdf"], + ["/assets/photo.webp", "assets/photo.webp"], + ["a%20(draft).md", "a (draft).md"], + ]) { + assert.equal(resolveContentTarget(page, route, docsRoot).file, join(docsRoot, source), route); + } + assert.match(resolveContentTarget(page, "empty/", docsRoot).error, /目标不存在/); +}); + +test("anchors include Chinese headings, duplicate slugs and explicit HTML IDs", () => { + const content = inspectFile(join(docsRoot, "target.md")); + for (const id of ["target", "工具与交付", "repeat", "repeat-1", "stable-id", "inline-id", "legacy"]) { + assert.ok(content.anchors.has(id), id); + } + const links = inspect([ + "[zh](target.md#%E5%B7%A5%E5%85%B7%E4%B8%8E%E4%BA%A4%E4%BB%98)", + "[duplicate](target.md#repeat-1)", + "[explicit](target.md#stable-id)", + "[html](target.md#inline-id)", + "[legacy](target.md#legacy)", + "[text fragment](target.md#repeat:~:text=Repeat)", + "[top](#top)", + ].join("\n"), page); + assert.deepEqual(contentLinkErrors(links, page, docsRoot, inspectFile), []); +}); + +test("missing cross-page and same-page anchors are errors", () => { + const content = inspect("[missing](target.md#removed)\n[self](#absent)\n", page); + assert.deepEqual(contentLinkErrors(content, page, docsRoot, inspectFile), [ + { line: 1, message: "链接锚点不存在: target.md#removed" }, + { line: 2, message: "链接锚点不存在: #absent" }, + ]); +}); + +test("frontmatter does not generate headings and CRLF keeps line positions", () => { + const content = inspect("---\r\ntitle: Title\r\nupdated: 2026-09-09\r\n---\r\n# Actual\r\n[missing](lost.md)\r\n", page); + assert.deepEqual(content.headingShape, [1]); + assert.deepEqual([...content.anchors], ["actual"]); + assert.deepEqual(content.links, [{ target: "lost.md", line: 6 }]); +}); + +test("external schemes and malformed encoded URLs are handled explicitly", () => { + for (const link of ["https://example.com/a", "mailto:reader@example.com", "tel:+1234", "ftp://example.com/a", "//example.com/a", "data:image/png;base64,AA=="]) { + assert.equal(resolveContentTarget(page, link, docsRoot), null); + } + assert.match(resolveContentTarget(page, "target.md#%zz", docsRoot).error, /无效的 URL 编码/); +}); + +test("raw HTML cannot introduce executable or machine-local links", () => { + const content = inspect("Unsafe\nLocal\n", page); + const errors = contentLinkErrors(content, page, docsRoot, inspectFile); + assert.equal(errors.length, 2); + assert.ok(errors.every(({ message }) => message.includes("可执行或本地文件协议"))); + assert.match(resolveContentTarget(page, "java\nscript:alert(1)", docsRoot).error, /可执行或本地文件协议/); +}); + +test("dates must exist in the calendar, including leap-day rules", () => { + for (const date of ["2024-02-29", "2000-02-29", "2026-09-09"]) assert.ok(validCalendarDate(date), date); + for (const date of ["2026-02-29", "2026-02-30", "1900-02-29", "2026-13-01", "2026-00-10", "2026-9-9", "invalid"]) { + assert.equal(validCalendarDate(date), false, date); + } +}); + +test("future dates are rejected for both updated and sources_checked", () => { + const errors = dateErrors({ updated: "2026-09-10", sources_checked: "2026-09-10" }, { today: "2026-09-09" }); + assert.equal(errors.length, 2); + assert.match(errors[0], /updated.*不能晚于/); + assert.match(errors[1], /sources_checked.*不能晚于/); +}); + +test("source freshness uses complete publication dates at the 120-day boundary", () => { + const options = { today: "2026-09-09", requireSourcesChecked: true }; + assert.deepEqual(dateErrors({ sources_checked: "2026-05-12" }, options), []); + assert.deepEqual(dateErrors({ sources_checked: "2026-05-11" }, options), ["AI 产品资料超过 120 天未核验"]); + assert.deepEqual(dateErrors({}, options), ["AI 页面缺少 sources_checked"]); + assert.match(dateErrors({ sources_checked: "2026-02-30" }, options)[0], /有效的 YYYY-MM-DD/); +}); + +const zhNavigation = [{ items: [{ link: "/", source: "README.md" }, { link: "/chapter", source: "chapter.md" }] }]; +const enNavigation = [{ items: [{ link: "/en/", source: "en/README.md" }, { link: "/en/chapter", source: "en/chapter.md" }] }]; + +test("bilingual navigation accepts matching source files and order", () => { + assert.deepEqual(navigationErrors(zhNavigation, enNavigation, docsRoot), []); +}); + +test("navigation detects wrong destinations, duplicate routes and translation order", () => { + const reversed = [{ items: [...enNavigation[0].items].reverse() }]; + assert.ok(navigationErrors(zhNavigation, reversed, docsRoot).some((error) => error.includes("顺序或来源不一致"))); + const mismatched = [{ items: [{ link: "/chapter", source: "README.md" }] }]; + assert.ok(navigationErrors(mismatched, enNavigation, docsRoot).some((error) => error.includes("链接与来源不一致"))); + const duplicate = [{ items: [zhNavigation[0].items[0], { link: "/", source: "README.md" }] }]; + assert.ok(navigationErrors(duplicate, enNavigation, docsRoot).some((error) => error.includes("重复路由"))); +}); diff --git a/tests/epub-reading.spec.mjs b/tests/epub-reading.spec.mjs new file mode 100644 index 00000000..6f0cbcfb --- /dev/null +++ b/tests/epub-reading.spec.mjs @@ -0,0 +1,52 @@ +import { execFileSync } from "node:child_process"; +import { mkdtempSync, readdirSync, rmSync } from "node:fs"; +import { tmpdir } from "node:os"; +import { join, resolve } from "node:path"; +import { pathToFileURL } from "node:url"; +import { expect, test } from "@playwright/test"; +import { enNavigation, publicationChapterCount, zhNavigation } from "../docs/.vitepress/navigation.mjs"; + +// EPUB readers lay reflowable XHTML into their own viewport; mobile browser +// emulation would otherwise impose a 980px page viewport on standalone files. +test.use({ isMobile: false }); + +for (const [language, label] of [["zh", "Chinese"], ["en", "English"]]) { + test(`${label} EPUB content reads offline at 320 CSS pixels`, async ({ page, context }, testInfo) => { + test.setTimeout(120_000); + const staging = mkdtempSync(join(tmpdir(), `life-guide-epub-reading-${language}-`)); + try { + execFileSync("unzip", ["-q", resolve(`docs/public/downloads/life-level-up-guide-${language}.epub`), "-d", staging]); + const root = join(staging, "OEBPS"); + const textDir = join(root, "text"); + const files = [join(root, "nav.xhtml"), ...readdirSync(textDir).filter((file) => file.endsWith(".xhtml")).map((file) => join(textDir, file))]; + expect(files).toHaveLength(publicationChapterCount(language === "zh" ? zhNavigation : enNavigation) + 3); + await page.setViewportSize({ width: 320, height: 760 }); + await context.setOffline(true); + for (const file of files) { + await test.step(file.slice(root.length + 1), async () => { + await page.goto(pathToFileURL(file).href); + await expect(page.locator("parsererror, button, [v-pre]")).toHaveCount(0); + const state = await page.evaluate(async () => { + await Promise.all([...document.images].map((image) => image.decode().catch(() => {}))); + return { + viewport: window.innerWidth, + width: Math.max(document.documentElement.scrollWidth, document.body.scrollWidth), + missingImages: [...document.images].filter((image) => !image.complete || !image.naturalWidth).map((image) => image.getAttribute("src")), + }; + }); + try { + expect(state.viewport).toBe(320); + expect(state.missingImages).toEqual([]); + expect(state.width).toBeLessThanOrEqual(state.viewport + 2); + } catch (error) { + await testInfo.attach("epub-reading-failure", { body: await page.screenshot(), contentType: "image/png" }); + throw error; + } + }); + } + } finally { + await context.setOffline(false); + rmSync(staging, { recursive: true, force: true }); + } + }); +} diff --git a/tests/epub-rendering.test.mjs b/tests/epub-rendering.test.mjs new file mode 100644 index 00000000..b5827858 --- /dev/null +++ b/tests/epub-rendering.test.mjs @@ -0,0 +1,46 @@ +import assert from "node:assert/strict"; +import { resolve } from "node:path"; +import test from "node:test"; +import { createMarkdownRenderer } from "vitepress"; +import { configureEpubMarkdown, directionAttribute, makeXhtml } from "../scripts/epub-rendering.mjs"; + +const markdown = await createMarkdownRenderer(resolve("docs"), { config: configureEpubMarkdown }); + +test("EPUB worksheets preserve literal code and whitespace without website controls", () => { + const template = 'Task: & "result"\n Evidence: {{ draft }}\n\nDone: [ ]\n'; + const body = markdown.render(`\`\`\`markdown\n${template}\`\`\`\n`); + assert.equal(body, `
${markdown.utils.escapeHtml(template)}
\n`); + assert.doesNotMatch(body, /Worksheet & evidence<\/title>/); + assert.match(xhtml, /lang="en-US" xml:lang="en-US"/); + assert.match(xhtml, /Task: <audience> & "result"/); + assert.match(xhtml, /\n Evidence: \{\{ draft \}\}\n\nDone: \[ \]\n/); +}); + +test("EPUB indented code also preserves text without executable markup", () => { + const body = markdown.render(" \n a && b\n"); + assert.equal(body, "
<script>alert('x')</script>\na && b\n
\n"); +}); + +test("EPUB table headers identify their columns for assistive reading", () => { + const body = markdown.render("| Task | Evidence |\n| --- | --- |\n| First attempt | Saved draft |\n"); + assert.equal((body.match(//g) || []).length, 2); + assert.match(body, /Saved draft<\/td>/); +}); + +test("EPUB preserves chapter link targets while removing heading permalink controls", () => { + const body = markdown.render("# Reading guide\n\n[Next chapter](chapter-002.xhtml#practice)\n\n---\n"); + const xhtml = makeXhtml({ lang: "en-US", title: "Guide", body }); + assert.match(xhtml, /id="reading-guide"/); + assert.match(xhtml, /href="chapter-002.xhtml#practice"/); + assert.doesNotMatch(xhtml, /header-anchor|tabindex/); + assert.match(xhtml, //); +}); + +test("EPUB marks RTL languages and leaves existing LTR editions unchanged", () => { + assert.equal(directionAttribute("en-US"), ""); + assert.equal(directionAttribute("ar"), ' dir="rtl"'); + const xhtml = makeXhtml({ lang: "ar", title: "دليل", body: "

نص

" }); + assert.match(xhtml, /lang="ar" xml:lang="ar" dir="rtl"/); +}); diff --git a/tests/epub-standard.test.mjs b/tests/epub-standard.test.mjs new file mode 100644 index 00000000..29f35916 --- /dev/null +++ b/tests/epub-standard.test.mjs @@ -0,0 +1,30 @@ +import assert from "node:assert/strict"; +import { spawnSync } from "node:child_process"; +import { chmodSync, existsSync, mkdirSync, mkdtempSync, readdirSync, rmSync, writeFileSync } from "node:fs"; +import { tmpdir } from "node:os"; +import { join, resolve } from "node:path"; +import test from "node:test"; + +test("EPUB standard validation rejects a substituted archive before executing its contents", (t) => { + const root = mkdtempSync(join(tmpdir(), "life-guide-epub-standard-test-")); + t.after(() => rmSync(root, { recursive: true, force: true })); + const scratch = join(root, "tmp"); + mkdirSync(scratch); + for (const language of ["zh", "en"]) writeFileSync(join(root, `life-level-up-guide-${language}.epub`), "fixture"); + const archive = join(root, "substituted.zip"); + writeFileSync(archive, "untrusted replacement archive"); + const sentinel = join(root, "jar-executed"); + const java = join(root, "java-fixture"); + writeFileSync(java, `#!/usr/bin/env node\nif (process.argv.includes('-jar')) { require('node:fs').writeFileSync(${JSON.stringify(sentinel)}, 'executed'); }\n`); + chmodSync(java, 0o755); + + const result = spawnSync(process.execPath, [resolve("scripts/check-epub-standard.mjs"), "--input-dir", root, "--archive", archive], { + encoding: "utf8", + env: { ...process.env, EPUBCHECK_JAVA: java, TMPDIR: scratch }, + timeout: 15_000, + }); + assert.equal(result.status, 1, result.stdout); + assert.match(result.stderr, /archive checksum mismatch/); + assert.equal(existsSync(sentinel), false, "unverified JAR must never run"); + assert.deepEqual(readdirSync(scratch), [], "temporary tooling must be removed after failure"); +}); diff --git a/tests/pdf_layout_test.py b/tests/pdf_layout_test.py new file mode 100644 index 00000000..f7648eb3 --- /dev/null +++ b/tests/pdf_layout_test.py @@ -0,0 +1,132 @@ +import importlib.util +from io import BytesIO +from pathlib import Path +import sys +import tempfile +import unittest +from xml.etree import ElementTree as ET + +from pypdf import PdfReader +from reportlab.lib.styles import ParagraphStyle +from reportlab.pdfbase import pdfmetrics +from reportlab.pdfbase.ttfonts import TTFont +from reportlab.platypus import BaseDocTemplate, Frame, PageTemplate + + +ROOT = Path(__file__).resolve().parents[1] +SPEC = importlib.util.spec_from_file_location("life_guide_pdf", ROOT / "scripts/build-pdf.py") +PDF = importlib.util.module_from_spec(SPEC) +sys.modules[SPEC.name] = PDF +SPEC.loader.exec_module(PDF) + + +class PreformattedLayoutTests(unittest.TestCase): + @classmethod + def setUpClass(cls): + pdfmetrics.registerFont(TTFont("NotoSerifSC-LifeLevelUp", str(PDF.ZH_REGULAR_FONT))) + + def render_code(self, source, edition): + styles = PDF.style_sheet(edition) + parent = ET.Element("main") + ET.SubElement(parent, "pre").text = source + story = PDF.convert_children(parent, Path(tempfile.gettempdir()), "fixture.xhtml", styles, edition, {}, {"headings": 0}) + output = BytesIO() + doc = BaseDocTemplate(output, pagesize=PDF.PAGE_SIZE) + frame = Frame(PDF.LEFT_MARGIN, PDF.BOTTOM_MARGIN, PDF.CONTENT_WIDTH, PDF.CONTENT_HEIGHT, + leftPadding=0, rightPadding=0, topPadding=0, bottomPadding=0) + doc.addPageTemplates(PageTemplate(id="code", frames=[frame])) + doc.build(story) + return PdfReader(BytesIO(output.getvalue())), styles["code"] + + def assert_pdf_text_intact_and_inside_frame(self, reader, source, edition, code_style): + extracted = [] + segments = [] + for page in reader.pages: + def visit(text, cm, tm, font, font_size): + if not text: + return + extracted.append(text) + x = tm[4] * cm[0] + tm[5] * cm[2] + cm[4] + for line in text.split("\n"): + if line: + width = pdfmetrics.stringWidth(line, edition.mono_font, font_size) + segments.append((line, x, x + width, font_size)) + page.extract_text(visitor_text=visit) + self.assertEqual("".join(extracted).replace("\n", ""), source.replace("\t", " ").replace("\n", "")) + self.assertTrue(segments) + for line, left, right, font_size in segments: + self.assertGreaterEqual(left, PDF.LEFT_MARGIN - 0.001, repr(line)) + self.assertLessEqual(right, PDF.PAGE_WIDTH - PDF.RIGHT_MARGIN + 0.001, repr(line)) + self.assertAlmostEqual(font_size, code_style.fontSize, msg="Wrapping must not shrink the font") + + def test_long_chinese_and_english_lines_are_inside_the_actual_pdf_frame(self): + fixtures = { + "zh": "学习任务:写下已知条件,再给出证据,并说明下一步。" * 15 + "\n\n 保存证据: (任务) & 结果 \n", + "en": "EvidenceWithoutAnyWordBoundary" * 35 + "\n\n Keep these words and spaces: & result \n\tIndented line\n", + } + for edition in PDF.EDITIONS: + with self.subTest(language=edition.key): + source = fixtures[edition.key] + reader, style = self.render_code(source, edition) + self.assert_pdf_text_intact_and_inside_frame(reader, source, edition, style) + + def test_spaces_and_blank_lines_survive_layout_without_trimming(self): + style = PDF.style_sheet(PDF.EDITIONS[1])["code"] + source = "\n\n first & \n\n second \n\n" + flowable = PDF.code_flowable(source, style) + self.assertEqual(flowable.getPlainText(), source) + _, height = flowable.wrap(PDF.CONTENT_WIDTH, PDF.CONTENT_HEIGHT) + self.assertAlmostEqual(height, len(source.split("\n")) * style.leading) + + def test_asymmetric_padding_and_indents_reduce_the_available_text_width(self): + style = ParagraphStyle("NarrowCode", parent=PDF.style_sheet(PDF.EDITIONS[1])["code"], + leftIndent=11, rightIndent=17, firstLineIndent=3, + borderPadding=(2, 19, 2, 7)) + source = " preserve every space " * 12 + flowable = PDF.code_flowable(source, style, available_width=150) + self.assertEqual(flowable.getPlainText().replace("\n", ""), source) + for line in flowable.getPlainText().split("\n"): + self.assertLessEqual(pdfmetrics.stringWidth(line, style.fontName, style.fontSize), 150 - 11 - 17 - 3 - 19 - 7) + + def test_wrapped_preformatted_text_can_split_across_pdf_pages_without_text_loss(self): + edition = PDF.EDITIONS[1] + source = "\n".join(f" Record {index}: " + "a long evidence line with original spaces " * 4 for index in range(80)) + "\n\n" + reader, style = self.render_code(source, edition) + self.assertGreater(len(reader.pages), 1) + self.assert_pdf_text_intact_and_inside_frame(reader, source, edition, style) + + def test_a_character_that_cannot_fit_is_rejected_instead_of_clipped(self): + with self.assertRaisesRegex(ValueError, "cannot fit"): + PDF.wrap_preformatted_text("W", "Courier", 7.3, 0.1) + + def test_published_bilingual_pdfs_keep_every_code_line_inside_the_frame(self): + """Scan every generated page's 7.3pt code text after a full build. + + Code is the only full-book content emitted at this size. This catches a + regression in the real artifacts that a synthetic fixture could miss. + """ + for edition in PDF.EDITIONS: + target = PDF.DOWNLOADS / edition.pdf_file + with self.subTest(language=edition.key, file=target): + self.assertTrue(target.exists(), f"run the PDF build first: {target}") + reader = PdfReader(str(target)) + segments = [] + for page_number, page in enumerate(reader.pages, start=1): + def visit(text, cm, tm, _font, font_size): + if abs(float(font_size) - 7.3) > 0.02: + return + x = tm[4] * cm[0] + tm[5] * cm[2] + cm[4] + for line in text.split("\n"): + if line: + right = x + pdfmetrics.stringWidth(line, edition.mono_font, 7.3) + segments.append((page_number, line, x, right)) + + page.extract_text(visitor_text=visit) + self.assertTrue(segments, f"no 7.3pt code text found in {target}") + for page_number, line, left, right in segments: + self.assertGreaterEqual(left, PDF.LEFT_MARGIN - 0.5, (page_number, line, left)) + self.assertLessEqual(right, PDF.PAGE_WIDTH - PDF.RIGHT_MARGIN + 0.5, (page_number, line, right)) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/private-assets.test.mjs b/tests/private-assets.test.mjs new file mode 100644 index 00000000..19a06d70 --- /dev/null +++ b/tests/private-assets.test.mjs @@ -0,0 +1,106 @@ +import assert from "node:assert/strict"; +import { mkdirSync, mkdtempSync, realpathSync, rmSync, writeFileSync } from "node:fs"; +import { tmpdir } from "node:os"; +import { join } from "node:path"; +import { test } from "node:test"; +import { build } from "vite"; +import { privateAssetGuard } from "../docs/.vitepress/private-assets.mjs"; + +async function buildFixture({ script = "console.log('fixture');", css, html = "", assetsInlineLimit, entryDirectory = "" } = {}) { + // Resolve macOS /var symlinks so Rollup's entry path stays inside the root. + const root = realpathSync(mkdtempSync(join(tmpdir(), "private-assets-test-"))); + try { + mkdirSync(join(root, "assets")); + mkdirSync(join(root, "public")); + writeFileSync(join(root, "assets/session.json"), '{"fixture":"PRIVATE_ASSET_TEST_SENTINEL"}'); + writeFileSync(join(root, "assets/session-notes.json"), '{"title":"Public session notes"}'); + const svg = ''; + writeFileSync(join(root, "assets/photo.svg"), svg); + writeFileSync(join(root, "public/logo.svg"), svg); + writeFileSync(join(root, "index.html"), `${html}`); + writeFileSync(join(root, entryDirectory, "main.js"), `${css === undefined ? "" : 'import "./style.css";\n'}${script}`); + if (css !== undefined) writeFileSync(join(root, entryDirectory, "style.css"), css); + return await build({ + configFile: false, + root, + logLevel: "silent", + plugins: [privateAssetGuard()], + build: { + outDir: join(root, "dist"), + write: false, + ...(assetsInlineLimit === undefined ? {} : { assetsInlineLimit }), + }, + }); + } finally { + rmSync(root, { recursive: true, force: true }); + } +} + +for (const { name, suffix, assetsInlineLimit } of [ + { name: "default inlining", suffix: "" }, + { name: "explicit inline query", suffix: "?inline" }, + { name: "explicit no-inline query", suffix: "?no-inline" }, + { name: "hashed asset output", suffix: "", assetsInlineLimit: 0 }, +]) { + test(`private new URL assets fail real builds with ${name}`, async () => { + await assert.rejects( + buildFixture({ + script: `console.log(new URL("./assets/session.json${suffix}", import.meta.url).href);`, + assetsInlineLimit, + }), + /Private session assets/, + ); + }); + + test(`private CSS assets fail real builds with ${name}`, async () => { + await assert.rejects( + buildFixture({ css: `body { background-image: url("./assets/session.json${suffix}") }`, assetsInlineLimit }), + /Private session assets/, + ); + }); +} + +test("private HTML asset references fail before inline or hashed publication", async () => { + await assert.rejects(buildFixture({ html: '' }), /Private session assets/); +}); + +test("relative new URL references from inside assets cannot inline private files", async () => { + await assert.rejects( + buildFixture({ script: 'console.log(new URL("./session.json", import.meta.url).href);', entryDirectory: "assets" }), + /Private session assets/, + ); +}); + +test("relative CSS references from inside assets cannot inline private files", async () => { + await assert.rejects( + buildFixture({ css: 'body { background-image: url("./session.json") }', entryDirectory: "assets" }), + /Private session assets/, + ); +}); + +test("escaped JavaScript and CSS paths cannot hide private asset references", async () => { + await assert.rejects( + buildFixture({ script: 'console.log(new URL("./assets/sess\\x69on.json", import.meta.url).href);' }), + /Private session assets/, + ); + await assert.rejects( + buildFixture({ css: 'body { background-image: url("./assets/sess\\69 on.json") }' }), + /Private session assets/, + ); +}); + +test("ordinary source and public assets still compile, including similarly named files", async () => { + const result = await buildFixture({ + script: [ + 'console.log(new URL("./assets/photo.svg", import.meta.url).href);', + 'console.log(new URL("./assets/session-notes.json", import.meta.url).href);', + 'console.log(new URL("/logo.svg", import.meta.url).href);', + ].join("\n"), + css: 'body { background-image: url("./assets/photo.svg") }', + html: '', + assetsInlineLimit: 0, + }); + assert.ok(result.output.some(({ fileName }) => /^assets\/photo-.+\.svg$/.test(fileName))); + assert.ok(result.output.some(({ fileName }) => /^assets\/session-notes-.+\.json$/.test(fileName))); + assert.ok(result.output.some(({ fileName }) => fileName === "index.html")); +}); diff --git a/tests/reader-experience.spec.mjs b/tests/reader-experience.spec.mjs new file mode 100644 index 00000000..279a7c66 --- /dev/null +++ b/tests/reader-experience.spec.mjs @@ -0,0 +1,113 @@ +import { expect, test } from "@playwright/test"; + +async function contrastRatio(locator) { + return locator.evaluate((element) => { + const channels = (color) => color.match(/[\d.]+/g).map(Number); + const luminance = (rgb) => rgb.slice(0, 3).reduce((sum, value, index) => { + const channel = value / 255; + return sum + (channel <= 0.04045 ? channel / 12.92 : ((channel + 0.055) / 1.055) ** 2.4) * [0.2126, 0.7152, 0.0722][index]; + }, 0); + const foreground = channels(getComputedStyle(element).color); + let background = [255, 255, 255]; + for (let ancestor = element; ancestor; ancestor = ancestor.parentElement) { + const candidate = channels(getComputedStyle(ancestor).backgroundColor); + if (candidate.length === 3 || candidate[3] === 1) { + background = candidate; + break; + } + } + const values = [luminance(foreground), luminance(background)].sort((a, b) => b - a); + return (values[0] + 0.05) / (values[1] + 0.05); + }); +} + +for (const colorScheme of ["light", "dark"]) { + test(`reading links remain legible in the ${colorScheme} theme`, async ({ page }) => { + await page.emulateMedia({ colorScheme, reducedMotion: "reduce" }); + await page.goto("./threads/part-1/0-cefr"); + await expect(page.locator("html")).toHaveClass(colorScheme === "dark" ? /\bdark\b/ : /^(?!.*\bdark\b)/); + const link = page.locator(".vp-doc p a").first(); + await expect.poll(() => contrastRatio(link)).toBeGreaterThanOrEqual(4.5); + await link.hover(); + await expect.poll(() => contrastRatio(link)).toBeGreaterThanOrEqual(4.5); + }); +} + +for (const locale of ["zh", "en"]) { + test(`${locale} sidebar groups expose their state and work with Space and Enter`, async ({ page }, testInfo) => { + await page.goto(locale === "en" ? "./en/threads/part-1/0-cefr" : "./threads/part-1/0-cefr"); + if (testInfo.project.name === "mobile-chromium") await page.locator(".VPLocalNav .menu").click(); + + const section = page.locator(".VPSidebarItem.collapsible").first(); + const control = section.locator(":scope > .item"); + const children = section.locator(":scope > .items"); + await expect(control).toHaveAttribute("aria-expanded", "true"); + await expect(section.getByRole("button")).toHaveCount(1); + await expect(control).toHaveAccessibleName(locale === "en" ? "Start Here" : "开始"); + expect(await control.getAttribute("aria-controls")).toBe(await children.getAttribute("id")); + + await control.press("Space"); + await expect(control).toHaveAttribute("aria-expanded", "false"); + await expect(children).toBeHidden(); + await control.press("Enter"); + await expect(control).toHaveAttribute("aria-expanded", "true"); + await expect(children).toBeVisible(); + await section.locator(":scope > .item > .caret").click(); + await expect(control).toHaveAttribute("aria-expanded", "false"); + await expect(children).toBeHidden(); + }); +} + +test("printing a dark page preserves readable tables, quotations, and code", async ({ page }) => { + await page.emulateMedia({ colorScheme: "dark" }); + await page.goto("./threads/part-1/0-cefr"); + await expect(page.locator("html")).toHaveClass(/\bdark\b/); + await page.emulateMedia({ media: "print" }); + await expect(page.locator("body")).toHaveCSS("background-color", "rgb(255, 255, 255)"); + await expect(page.locator("html")).toHaveCSS("color-scheme", "light"); + await expect(page.locator(".vp-doc table").first()).toHaveCSS("display", "table"); + for (const selector of [".vp-doc td", ".vp-doc th", ".vp-doc blockquote"]) { + await expect.poll(() => contrastRatio(page.locator(selector).first()), selector).toBeGreaterThanOrEqual(4.5); + } + + await page.goto("./en/templates/english-diagnostic"); + await expect(page.locator(".vp-doc table").first()).toBeVisible(); + const clippedCells = await page.locator(".vp-doc th, .vp-doc td").evaluateAll((cells) => + cells.filter((cell) => cell.scrollWidth > cell.clientWidth + 1).length, + ); + expect(clippedCells).toBe(0); + + await page.goto("./templates/family-learning-agreement"); + const code = page.locator('.vp-doc [class*="language-"] code span[style]').first(); + await expect(code).toBeAttached(); + await expect.poll(() => contrastRatio(code)).toBeGreaterThanOrEqual(4.5); +}); + +test("wide reference tables scroll within the article across screen sizes", async ({ page }, testInfo) => { + const widths = testInfo.project.name === "mobile-chromium" ? [375] : [641, 768, 960, 1024, 1280]; + for (const width of widths) { + await page.setViewportSize({ width, height: 812 }); + await page.goto("./en/templates/english-diagnostic"); + await expect(page.locator(".vp-doc table").first()).toBeVisible(); + const dimensions = await page.evaluate(() => { + const content = document.querySelector(".vp-doc").getBoundingClientRect(); + return { + overflow: document.documentElement.scrollWidth - document.documentElement.clientWidth, + tables: [...document.querySelectorAll(".vp-doc table")].map((table) => ({ + left: table.getBoundingClientRect().left - content.left, + right: table.getBoundingClientRect().right - content.right, + })), + }; + }); + expect(dimensions.overflow, `${width}px document overflow`).toBeLessThanOrEqual(1); + for (const table of dimensions.tables) { + expect(table.left).toBeGreaterThanOrEqual(-1); + expect(table.right).toBeLessThanOrEqual(1); + } + const search = page.getByRole("button", { name: "Search", exact: true }); + await expect(search).toBeInViewport(); + const wideTable = page.locator(".vp-doc table").filter({ has: page.locator("tr > th:nth-child(7)") }).first(); + await wideTable.evaluate((table) => { table.scrollLeft = table.scrollWidth; }); + await expect.poll(() => wideTable.evaluate((table) => table.scrollLeft)).toBeGreaterThan(0); + } +}); diff --git a/tests/routing.spec.mjs b/tests/routing.spec.mjs new file mode 100644 index 00000000..248cb002 --- /dev/null +++ b/tests/routing.spec.mjs @@ -0,0 +1,48 @@ +import { expect, test } from "@playwright/test"; +import { bilingualRoutePairs } from "../docs/.vitepress/navigation.mjs"; +import { publicRoutePath } from "../docs/.vitepress/routing.mjs"; + +test("canonical URLs and language alternates agree with the sitemap for every page", async ({ request }) => { + test.setTimeout(60_000); + const sitemap = await (await request.get("sitemap.xml")).text(); + const routes = bilingualRoutePairs.flatMap(({ zh, en }) => [zh, en].map((route) => ({ route, zh, en }))); + for (let index = 0; index < routes.length; index += 4) { + await Promise.all(routes.slice(index, index + 4).map(async ({ route, zh, en }) => { + const path = publicRoutePath(route); + const response = await request.get(path); + expect(response.status(), path).toBe(200); + const html = await response.text(); + const canonical = `https://byoungd.github.io${path}`; + expect(html, path).toContain(`rel="canonical" href="${canonical}"`); + expect(sitemap, path).toContain(`${canonical}`); + for (const [language, target] of [["zh-CN", zh], ["en-US", en], ["x-default", zh]]) { + const alternate = `hreflang="${language}" href="https://byoungd.github.io${publicRoutePath(target)}"`; + expect(html, path).toContain(alternate); + expect(sitemap, path).toContain(alternate); + } + })); + } +}); + +test("legacy Markdown links reach their page and preserve a real section anchor", async ({ page }) => { + for (const [path, heading] of [ + ["./#/README.md", /人生进阶指南/], + ["./#/en/README", /Life Level-up Guide/], + ["./#/threads/part-1/1-understanding.md", /认知篇/], + ]) { + await page.goto(path); + await expect(page.locator("main h1")).toHaveText(heading); + await expect(page).not.toHaveURL(/#\/|\.md\/?$/); + } + const anchor = await page.locator("main h2[id]").first().getAttribute("id"); + await page.goto(`./#/threads/part-1/1-understanding.md?from=legacy&id=${encodeURIComponent(anchor)}`); + await expect(page).toHaveURL(new RegExp(`\\?from=legacy#${encodeURIComponent(anchor)}$`)); + await expect(page.locator(`[id="${anchor}"]`)).toBeInViewport(); +}); + +test("missing pages are not advertised as indexable book content", async ({ request }) => { + const html = await (await request.get("404.html")).text(); + expect(html).toContain('name="robots" content="noindex"'); + expect(html).not.toContain('rel="canonical"'); + expect(html).not.toContain('type="application/ld+json"'); +}); diff --git a/tests/routing.test.mjs b/tests/routing.test.mjs new file mode 100644 index 00000000..08cb0d0e --- /dev/null +++ b/tests/routing.test.mjs @@ -0,0 +1,82 @@ +import assert from "node:assert/strict"; +import { test } from "node:test"; +import vm from "node:vm"; +import { legacyRedirectScript, legacyRouteTarget, publicRoutePath } from "../docs/.vitepress/routing.mjs"; +import { privateAssetGuard } from "../docs/.vitepress/private-assets.mjs"; + +test("canonical paths preserve directories and use clean document URLs", () => { + for (const [route, expected] of [ + ["", "/up/"], ["en", "/up/en/"], + ["threads/archive", "/up/threads/archive/"], + ["en/threads/archive", "/up/en/threads/archive/"], + ["threads/part-1/2-vocabulary", "/up/threads/part-1/2-vocabulary"], + ["/en/projects/", "/up/en/projects"], + ]) assert.equal(publicRoutePath(route), expected); +}); + +test("legacy links recover README, Markdown pages, locale, search and anchors", () => { + for (const [hash, expected] of [ + ["#/README", "/up/"], ["#/README.md", "/up/"], + ["#/en/README.md", "/up/en/"], + ["#/threads/archive/README", "/up/threads/archive/"], + ["#/threads/part-1/1-understanding.md", "/up/threads/part-1/1-understanding"], + ["#/en/threads/part-4/my-story.md?from=old&id=narrative-boundary", "/up/en/threads/part-2/my-story?from=old#narrative-boundary"], + ["#/en/projects#disclosure", "/up/en/projects#disclosure"], + ["#/projects?id=%E9%A1%B9%E7%9B%AE", "/up/projects#%E9%A1%B9%E7%9B%AE"], + ]) assert.equal(legacyRouteTarget(hash), expected); + for (const hash of ["#section", "#/../../outside", "#/%2e%2e/outside", "#/https://example.com", "#/%ZZ", "#/a%5Cb"]) { + assert.equal(legacyRouteTarget(hash), null); + } +}); + +test("the actual embedded redirect script works without module scope", () => { + const targets = []; + let onHashChange; + const location = { hash: "#/README.md", pathname: "/up/", search: "", replace: (target) => targets.push(target) }; + vm.runInNewContext(legacyRedirectScript("/up/"), { + URLSearchParams, + window: { location, addEventListener: (event, handler) => { assert.equal(event, "hashchange"); onHashChange = handler; } }, + }); + assert.deepEqual(targets, ["/up/"]); + location.hash = "#/en/README.md"; + onHashChange(); + assert.deepEqual(targets, ["/up/", "/up/en/"]); +}); + +test("private asset middleware rejects encoded requests without reading their contents", () => { + for (const hook of ["configureServer", "configurePreviewServer"]) { + let handler; + privateAssetGuard()[hook]({ middlewares: { use: (value) => { handler = value; } } }); + for (const [url, status] of [ + ["/up/assets/session.json", 404], ["/up/assets/%73ession.json?raw", 404], + ["/@fs/project/docs/assets/session.json?import", 404], + ["/up/assets/session.json/", 404], ["/up/%broken", 400], + ["/up/assets/logo.svg", 200], + ]) { + const response = { statusCode: 200, end() {} }; + let passed = false; + handler({ url }, response, () => { passed = true; }); + assert.equal(response.statusCode, status, url); + assert.equal(passed, status === 200, url); + } + } +}); + +test("private assets cannot enter hashed bundles through raw or URL imports", () => { + const guard = privateAssetGuard(); + for (const suffix of ["", "?raw", "?url", "?commonjs-proxy"]) { + assert.throws(() => guard.load(`/project/docs/assets/session.json${suffix}`), /cannot be imported/); + } + assert.equal(guard.load("/project/docs/assets/logo.svg"), undefined); + const config = { server: { fs: { deny: [".env", "*.pem"] } } }; + assert.deepEqual(guard.config(config).server.fs.deny, [".env", "*.pem", "**/assets/session.json"]); +}); + +test("Vite's resolved filesystem guard retains defaults and blocks session files", async () => { + const { resolveConfig } = await import("vite"); + const config = await resolveConfig({ configFile: false, plugins: [privateAssetGuard()] }, "serve"); + for (const path of ["/project/.env", "/project/.env.local", "/project/key.pem", "/project/.git/config", "/project/docs/assets/session.json"]) { + assert.equal(config.fsDenyGlob(path), true, path); + } + assert.equal(config.fsDenyGlob("/project/docs/assets/logo.svg"), false); +}); diff --git a/tests/site.spec.mjs b/tests/site.spec.mjs index d44bbd4a..e89cf9ff 100644 --- a/tests/site.spec.mjs +++ b/tests/site.spec.mjs @@ -183,19 +183,24 @@ test("long-term action moves from a 90-day cycle through a real case into handov ]); }); -test("reader field notes ask for action, delayed evidence, revision, and privacy", () => { +test("reader field notes preserve immediate, delayed, transfer, editorial, and privacy evidence", () => { const template = readFileSync( resolve(process.cwd(), ".github/ISSUE_TEMPLATE/reader-field-note.yml"), "utf8", ); - for (const field of ["problem", "action", "delayed_result", "revision", "privacy"]) { + for (const field of ["problem", "action", "immediate_result", "retest", "transfer", "editorial_feedback", "privacy"]) { expect(template).toContain(`id: ${field}`); } expect(template).toContain("A small or unsuccessful attempt is useful evidence."); - expect(template).toContain("no private customer data"); + expect(template).toContain("Customer data, company secrets"); expect(template).toContain("separated what I observed from what I infer or hope"); }); +test("fresh pages do not prefetch offscreen route chunks before a reader chooses a link", async ({ page }) => { + await page.goto("./"); + await expect(page.locator('link[rel="prefetch"]')).toHaveCount(0); +}); + test("main book chapters leave continuous reading to the authoritative pager", () => { const manualPager = /^(?:(?:上一篇|下一篇|下一部|返回首页)[::]|(?:Prev|Previous|Next|Next Part|Back to the home page):)/m; const sources = [...zhNavigation.slice(1, 7), ...enNavigation.slice(1, 7)] @@ -669,25 +674,25 @@ test("page metadata follows the route", async ({ page }) => { await expect(page.locator('meta[name="description"]')).toHaveAttribute("content", /词汇/); await expect(page.locator('link[rel="canonical"]')).toHaveAttribute( "href", - "https://byoungd.github.io/up/threads/part-1/2-vocabulary/", + "https://byoungd.github.io/up/threads/part-1/2-vocabulary", ); await expect(page.locator('meta[property="og:url"]')).toHaveAttribute( "content", - "https://byoungd.github.io/up/threads/part-1/2-vocabulary/", + "https://byoungd.github.io/up/threads/part-1/2-vocabulary", ); await expect(page.locator('meta[property="og:image"]')).toHaveAttribute("content", /\/assets\/feature\.png$/); await expect(page.locator('meta[property="og:image:type"]')).toHaveAttribute("content", "image/png"); await expect(page.locator('link[rel="alternate"][hreflang="zh-CN"]')).toHaveAttribute( "href", - "https://byoungd.github.io/up/threads/part-1/2-vocabulary/", + "https://byoungd.github.io/up/threads/part-1/2-vocabulary", ); await expect(page.locator('link[rel="alternate"][hreflang="en-US"]')).toHaveAttribute( "href", - "https://byoungd.github.io/up/en/threads/part-1/2-vocabulary/", + "https://byoungd.github.io/up/en/threads/part-1/2-vocabulary", ); await expect(page.locator('link[rel="alternate"][hreflang="x-default"]')).toHaveAttribute( "href", - "https://byoungd.github.io/up/threads/part-1/2-vocabulary/", + "https://byoungd.github.io/up/threads/part-1/2-vocabulary", ); const chapterData = await structuredDataFromPage(page); expect(chapterData).toMatchObject({ @@ -703,6 +708,7 @@ test("page metadata follows the route", async ({ page }) => { test("home metadata follows the lifelong-learning positioning", async ({ page }) => { await page.goto("./"); await expect(page).toHaveTitle(/人生进阶指南/); + await expect(page.locator("main")).toContainText("开放的双语书稿与静态阅读/出版项目"); await expect(page.locator('meta[name="description"]')).toHaveAttribute( "content", /AI 时代.*真实项目.*低谷/, @@ -741,6 +747,7 @@ test("home metadata follows the lifelong-learning positioning", async ({ page }) await page.goto("./en/"); await expect(page).toHaveTitle(/Life Level-up Guide/); + await expect(page.locator("main")).toContainText("open bilingual manuscript and static reading/publication project"); await expect(page.locator('link[rel="canonical"]')).toHaveAttribute( "href", "https://byoungd.github.io/up/en/", @@ -928,7 +935,7 @@ test("brand and social assets load at their declared dimensions", async ({ page, expect(sitemap).toContain('hreflang="x-default" href="https://byoungd.github.io/up/threads/part-1/2-vocabulary"'); }); -test("AI resource-layer chapter has metadata and navigation", async ({ page }) => { +test("AI resource-layer chapter has metadata and navigation", async ({ page }, testInfo) => { await page.goto("./threads/part-3/2-ai-development-and-resource-layer"); await expect(page).toHaveTitle(/AI 学习、项目开发与资源层创业/); await expect(page.locator('meta[name="description"]')).toHaveAttribute( @@ -937,14 +944,16 @@ test("AI resource-layer chapter has metadata and navigation", async ({ page }) = ); await expect(page.locator('link[rel="canonical"]')).toHaveAttribute( "href", - "https://byoungd.github.io/up/threads/part-3/2-ai-development-and-resource-layer/", + "https://byoungd.github.io/up/threads/part-3/2-ai-development-and-resource-layer", ); + if (testInfo.project.name === "mobile-chromium") await page.locator(".VPLocalNav .menu").click(); await expect( page.getByRole("link", { name: "AI 开发与资源层创业", exact: true }).first(), ).toBeVisible(); await page.goto("./en/threads/part-3/2-ai-development-and-resource-layer"); await expect(page).toHaveTitle(/AI Learning, Project Development/); + if (testInfo.project.name === "mobile-chromium") await page.locator(".VPLocalNav .menu").click(); await expect( page.getByRole("link", { name: "AI Development and Resource-layer Business", @@ -983,7 +992,7 @@ test("legacy English story route redirects to the aligned Part II path", async ( ).toBeVisible(); await expect(page.locator('link[rel="canonical"]')).toHaveAttribute( "href", - "https://byoungd.github.io/up/en/threads/part-2/my-story/", + "https://byoungd.github.io/up/en/threads/part-2/my-story", ); }); @@ -997,7 +1006,7 @@ test("local search uses the current language and returns a result", async ({ pag await expect(zhSearchBox.locator('button[title="显示详细结果"]')).toHaveCount(1); await expect(zhSearchBox.locator('button[title="清除搜索"]')).toHaveCount(1); await zhInput.fill("学习状态"); - await expect(zhSearchBox.getByRole("link", { name: /学习状态/ }).first()).toBeVisible(); + await expect(zhSearchBox.getByRole("option", { name: /学习状态/ }).first()).toBeVisible(); await expect(zhSearchBox).toContainText("选择"); await expect(zhSearchBox).toContainText("切换"); await expect(zhSearchBox).toContainText("关闭"); @@ -1017,7 +1026,7 @@ test("local search uses the current language and returns a result", async ({ pag await expect(enInput).toBeVisible(); await expect(enSearchBox.locator('button[title="Close search"]')).toHaveCount(1); await enInput.fill("Learning State"); - await expect(enSearchBox.getByRole("link", { name: /Learning State/ }).first()).toBeVisible(); + await expect(enSearchBox.getByRole("option", { name: /Learning State/ }).first()).toBeVisible(); }); test("page-level search keeps nested chapter text discoverable", async ({ page }) => { @@ -1025,14 +1034,14 @@ test("page-level search keeps nested chapter text discoverable", async ({ page } await page.getByRole("button", { name: "搜索", exact: true }).click(); const zhSearchBox = page.locator(".VPLocalSearchBox"); await zhSearchBox.locator("input").fill("十四天不是写作速成期限"); - await expect(zhSearchBox.getByRole("link", { name: /写作篇/ }).first()).toBeVisible(); + await expect(zhSearchBox.getByRole("option", { name: /写作篇/ }).first()).toBeVisible(); await page.keyboard.press("Escape"); await page.goto("./en/"); await page.getByRole("button", { name: "Search", exact: true }).click(); const enSearchBox = page.locator(".VPLocalSearchBox"); await enSearchBox.locator("input").fill("Fourteen days is not a writing-fluency deadline"); - await expect(enSearchBox.getByRole("link", { name: /Writing/ }).first()).toBeVisible(); + await expect(enSearchBox.getByRole("option", { name: /Writing/ }).first()).toBeVisible(); }); test("heading-only search keeps long-form chapters and tools discoverable without indexing their full prose", async ({ page }) => { @@ -1040,94 +1049,94 @@ test("heading-only search keeps long-form chapters and tools discoverable withou await page.getByRole("button", { name: "搜索", exact: true }).click(); const zhSearchBox = page.locator(".VPLocalSearchBox"); await zhSearchBox.locator("input").fill("目标必须有到期日与退出门"); - await expect(zhSearchBox.getByRole("link", { name: /目标必须有到期日与退出门/ }).first()).toBeVisible(); + await expect(zhSearchBox.getByRole("option", { name: /目标必须有到期日与退出门/ }).first()).toBeVisible(); await zhSearchBox.locator("input").fill("作品也要接受自己的审判"); - await expect(zhSearchBox.getByRole("link", { name: /作品也要接受自己的审判/ }).first()).toBeVisible(); + await expect(zhSearchBox.getByRole("option", { name: /作品也要接受自己的审判/ }).first()).toBeVisible(); await zhSearchBox.locator("input").fill("把记忆交给文件,把判断留给自己"); - await expect(zhSearchBox.getByRole("link", { name: /把记忆交给文件,把判断留给自己/ }).first()).toBeVisible(); + await expect(zhSearchBox.getByRole("option", { name: /把记忆交给文件,把判断留给自己/ }).first()).toBeVisible(); await zhSearchBox.locator("input").fill("家庭学习篇:把成长还给孩子"); - await expect(zhSearchBox.getByRole("link", { name: /家庭学习篇:把成长还给孩子/ }).first()).toBeVisible(); + await expect(zhSearchBox.getByRole("option", { name: /家庭学习篇:把成长还给孩子/ }).first()).toBeVisible(); await zhSearchBox.locator("input").fill("求职英语篇:把能力带进面试与远程协作"); - await expect(zhSearchBox.getByRole("link", { name: /求职英语篇:把能力带进面试与远程协作/ }).first()).toBeVisible(); + await expect(zhSearchBox.getByRole("option", { name: /求职英语篇:把能力带进面试与远程协作/ }).first()).toBeVisible(); await zhSearchBox.locator("input").fill("语法篇:让结构服务于意思"); - await expect(zhSearchBox.getByRole("link", { name: /语法篇:让结构服务于意思/ }).first()).toBeVisible(); + await expect(zhSearchBox.getByRole("option", { name: /语法篇:让结构服务于意思/ }).first()).toBeVisible(); await zhSearchBox.locator("input").fill("语法证据卡:从规则识别到真实表达"); - await expect(zhSearchBox.getByRole("link", { name: /语法证据卡:从规则识别到真实表达/ }).first()).toBeVisible(); + await expect(zhSearchBox.getByRole("option", { name: /语法证据卡:从规则识别到真实表达/ }).first()).toBeVisible(); await zhSearchBox.locator("input").fill("口语篇:让意思清楚到达"); - await expect(zhSearchBox.getByRole("link", { name: /口语篇:让意思清楚到达/ }).first()).toBeVisible(); + await expect(zhSearchBox.getByRole("option", { name: /口语篇:让意思清楚到达/ }).first()).toBeVisible(); await zhSearchBox.locator("input").fill("口语证据卡:从口音焦虑到可验证互动"); - await expect(zhSearchBox.getByRole("link", { name: /口语证据卡:从口音焦虑到可验证互动/ }).first()).toBeVisible(); + await expect(zhSearchBox.getByRole("option", { name: /口语证据卡:从口音焦虑到可验证互动/ }).first()).toBeVisible(); await zhSearchBox.locator("input").fill("听力篇:从声音辨认到真实理解"); - await expect(zhSearchBox.getByRole("link", { name: /听力篇:从声音辨认到真实理解/ }).first()).toBeVisible(); + await expect(zhSearchBox.getByRole("option", { name: /听力篇:从声音辨认到真实理解/ }).first()).toBeVisible(); await zhSearchBox.locator("input").fill("听力证据卡:从播放时长到意义重构"); - await expect(zhSearchBox.getByRole("link", { name: /听力证据卡:从播放时长到意义重构/ }).first()).toBeVisible(); + await expect(zhSearchBox.getByRole("option", { name: /听力证据卡:从播放时长到意义重构/ }).first()).toBeVisible(); await zhSearchBox.locator("input").fill("阅读篇:从逐词翻译到观点与证据"); - await expect(zhSearchBox.getByRole("link", { name: /阅读篇:从逐词翻译到观点与证据/ }).first()).toBeVisible(); + await expect(zhSearchBox.getByRole("option", { name: /阅读篇:从逐词翻译到观点与证据/ }).first()).toBeVisible(); await zhSearchBox.locator("input").fill("阅读证据卡:从读完摘要到真实交付"); - await expect(zhSearchBox.getByRole("link", { name: /阅读证据卡:从读完摘要到真实交付/ }).first()).toBeVisible(); + await expect(zhSearchBox.getByRole("option", { name: /阅读证据卡:从读完摘要到真实交付/ }).first()).toBeVisible(); await zhSearchBox.locator("input").fill("词汇篇:从眼熟到在真实任务中调用"); - await expect(zhSearchBox.getByRole("link", { name: /词汇篇:从眼熟到在真实任务中调用/ }).first()).toBeVisible(); + await expect(zhSearchBox.getByRole("option", { name: /词汇篇:从眼熟到在真实任务中调用/ }).first()).toBeVisible(); await zhSearchBox.locator("input").fill("词汇证据卡:从卡片眼熟到情境调用"); - await expect(zhSearchBox.getByRole("link", { name: /词汇证据卡:从卡片眼熟到情境调用/ }).first()).toBeVisible(); + await expect(zhSearchBox.getByRole("option", { name: /词汇证据卡:从卡片眼熟到情境调用/ }).first()).toBeVisible(); await zhSearchBox.locator("input").fill("认知篇:把努力变成可验证的学习"); - await expect(zhSearchBox.getByRole("link", { name: /认知篇:把努力变成可验证的学习/ }).first()).toBeVisible(); + await expect(zhSearchBox.getByRole("option", { name: /认知篇:把努力变成可验证的学习/ }).first()).toBeVisible(); await zhSearchBox.locator("input").fill("英语能力诊断:四项基线与迁移记录"); - await expect(zhSearchBox.getByRole("link", { name: /英语能力诊断:四项基线与迁移记录/ }).first()).toBeVisible(); + await expect(zhSearchBox.getByRole("option", { name: /英语能力诊断:四项基线与迁移记录/ }).first()).toBeVisible(); await zhSearchBox.locator("input").fill("AI 任务简报:从问题到人工验收"); - await expect(zhSearchBox.getByRole("link", { name: /AI 任务简报:从问题到人工验收/ }).first()).toBeVisible(); + await expect(zhSearchBox.getByRole("option", { name: /AI 任务简报:从问题到人工验收/ }).first()).toBeVisible(); await zhSearchBox.locator("input").fill("AI 学习记录:从工具协作到独立能力"); - await expect(zhSearchBox.getByRole("link", { name: /AI 学习记录:从工具协作到独立能力/ }).first()).toBeVisible(); + await expect(zhSearchBox.getByRole("option", { name: /AI 学习记录:从工具协作到独立能力/ }).first()).toBeVisible(); await zhSearchBox.locator("input").fill("写作篇:从初稿到可验证修订"); - await expect(zhSearchBox.getByRole("link", { name: /写作篇:从初稿到可验证修订/ }).first()).toBeVisible(); + await expect(zhSearchBox.getByRole("option", { name: /写作篇:从初稿到可验证修订/ }).first()).toBeVisible(); await zhSearchBox.locator("input").fill("写作证据卡:从工具润色到署名交付"); - await expect(zhSearchBox.getByRole("link", { name: /写作证据卡:从工具润色到署名交付/ }).first()).toBeVisible(); + await expect(zhSearchBox.getByRole("option", { name: /写作证据卡:从工具润色到署名交付/ }).first()).toBeVisible(); await page.keyboard.press("Escape"); await page.goto("./en/"); await page.getByRole("button", { name: "Search", exact: true }).click(); const enSearchBox = page.locator(".VPLocalSearchBox"); await enSearchBox.locator("input").fill("Every Goal Needs an Expiry Date"); - await expect(enSearchBox.getByRole("link", { name: /Every Goal Needs an Expiry Date/ }).first()).toBeVisible(); + await expect(enSearchBox.getByRole("option", { name: /Every Goal Needs an Expiry Date/ }).first()).toBeVisible(); await enSearchBox.locator("input").fill("Let the Work Face Its Own Judgment"); - await expect(enSearchBox.getByRole("link", { name: /Let the Work Face Its Own Judgment/ }).first()).toBeVisible(); + await expect(enSearchBox.getByRole("option", { name: /Let the Work Face Its Own Judgment/ }).first()).toBeVisible(); await enSearchBox.locator("input").fill("Give Memory to the File and Keep Judgment with Yourself"); - await expect(enSearchBox.getByRole("link", { name: /Give Memory to the File and Keep Judgment with Yourself/ }).first()).toBeVisible(); + await expect(enSearchBox.getByRole("option", { name: /Give Memory to the File and Keep Judgment with Yourself/ }).first()).toBeVisible(); await enSearchBox.locator("input").fill("Family Learning: Return Ownership of Growth to the Learner"); - await expect(enSearchBox.getByRole("link", { name: /Family Learning: Return Ownership of Growth to the Learner/ }).first()).toBeVisible(); + await expect(enSearchBox.getByRole("option", { name: /Family Learning: Return Ownership of Growth to the Learner/ }).first()).toBeVisible(); await enSearchBox.locator("input").fill("Job-search English: Bring Ability into Interviews and Remote Work"); - await expect(enSearchBox.getByRole("link", { name: /Job-search English: Bring Ability into Interviews and Remote Work/ }).first()).toBeVisible(); + await expect(enSearchBox.getByRole("option", { name: /Job-search English: Bring Ability into Interviews and Remote Work/ }).first()).toBeVisible(); await enSearchBox.locator("input").fill("Grammar: Let Structure Serve Meaning"); - await expect(enSearchBox.getByRole("link", { name: /Grammar: Let Structure Serve Meaning/ }).first()).toBeVisible(); + await expect(enSearchBox.getByRole("option", { name: /Grammar: Let Structure Serve Meaning/ }).first()).toBeVisible(); await enSearchBox.locator("input").fill("Grammar Evidence Card: From Rule Recognition to Real Expression"); - await expect(enSearchBox.getByRole("link", { name: /Grammar Evidence Card: From Rule Recognition to Real Expression/ }).first()).toBeVisible(); + await expect(enSearchBox.getByRole("option", { name: /Grammar Evidence Card: From Rule Recognition to Real Expression/ }).first()).toBeVisible(); await enSearchBox.locator("input").fill("Speaking: Make Meaning Arrive"); - await expect(enSearchBox.getByRole("link", { name: /Speaking: Make Meaning Arrive/ }).first()).toBeVisible(); + await expect(enSearchBox.getByRole("option", { name: /Speaking: Make Meaning Arrive/ }).first()).toBeVisible(); await enSearchBox.locator("input").fill("Speaking Evidence Card: From Accent Anxiety to Verifiable Interaction"); - await expect(enSearchBox.getByRole("link", { name: /Speaking Evidence Card: From Accent Anxiety to Verifiable Interaction/ }).first()).toBeVisible(); + await expect(enSearchBox.getByRole("option", { name: /Speaking Evidence Card: From Accent Anxiety to Verifiable Interaction/ }).first()).toBeVisible(); await enSearchBox.locator("input").fill("Listening: From Sound Recognition to Real Understanding"); - await expect(enSearchBox.getByRole("link", { name: /Listening: From Sound Recognition to Real Understanding/ }).first()).toBeVisible(); + await expect(enSearchBox.getByRole("option", { name: /Listening: From Sound Recognition to Real Understanding/ }).first()).toBeVisible(); await enSearchBox.locator("input").fill("Listening Evidence Card: From Playback Time to Meaning Reconstruction"); - await expect(enSearchBox.getByRole("link", { name: /Listening Evidence Card: From Playback Time to Meaning Reconstruction/ }).first()).toBeVisible(); + await expect(enSearchBox.getByRole("option", { name: /Listening Evidence Card: From Playback Time to Meaning Reconstruction/ }).first()).toBeVisible(); await enSearchBox.locator("input").fill("Reading: From Word-by-word Translation to Claims and Evidence"); - await expect(enSearchBox.getByRole("link", { name: /Reading: From Word-by-word Translation to Claims and Evidence/ }).first()).toBeVisible(); + await expect(enSearchBox.getByRole("option", { name: /Reading: From Word-by-word Translation to Claims and Evidence/ }).first()).toBeVisible(); await enSearchBox.locator("input").fill("Reading Evidence Card: From Finished Summary to Real Delivery"); - await expect(enSearchBox.getByRole("link", { name: /Reading Evidence Card: From Finished Summary to Real Delivery/ }).first()).toBeVisible(); + await expect(enSearchBox.getByRole("option", { name: /Reading Evidence Card: From Finished Summary to Real Delivery/ }).first()).toBeVisible(); await enSearchBox.locator("input").fill("Vocabulary: From Familiarity to Retrieval in Real Tasks"); - await expect(enSearchBox.getByRole("link", { name: /Vocabulary: From Familiarity to Retrieval in Real Tasks/ }).first()).toBeVisible(); + await expect(enSearchBox.getByRole("option", { name: /Vocabulary: From Familiarity to Retrieval in Real Tasks/ }).first()).toBeVisible(); await enSearchBox.locator("input").fill("Vocabulary Evidence Card: From Card Familiarity to Contextual Retrieval"); - await expect(enSearchBox.getByRole("link", { name: /Vocabulary Evidence Card: From Card Familiarity to Contextual Retrieval/ }).first()).toBeVisible(); + await expect(enSearchBox.getByRole("option", { name: /Vocabulary Evidence Card: From Card Familiarity to Contextual Retrieval/ }).first()).toBeVisible(); await enSearchBox.locator("input").fill("Learning Principles: Turn Effort into Verifiable Learning"); - await expect(enSearchBox.getByRole("link", { name: /Learning Principles: Turn Effort into Verifiable Learning/ }).first()).toBeVisible(); + await expect(enSearchBox.getByRole("option", { name: /Learning Principles: Turn Effort into Verifiable Learning/ }).first()).toBeVisible(); await enSearchBox.locator("input").fill("English Diagnostic: Four-skill Baseline and Transfer Record"); - await expect(enSearchBox.getByRole("link", { name: /English Diagnostic: Four-skill Baseline and Transfer Record/ }).first()).toBeVisible(); + await expect(enSearchBox.getByRole("option", { name: /English Diagnostic: Four-skill Baseline and Transfer Record/ }).first()).toBeVisible(); await enSearchBox.locator("input").fill("AI Task Brief: From Problem to Human Acceptance"); - await expect(enSearchBox.getByRole("link", { name: /AI Task Brief: From Problem to Human Acceptance/ }).first()).toBeVisible(); + await expect(enSearchBox.getByRole("option", { name: /AI Task Brief: From Problem to Human Acceptance/ }).first()).toBeVisible(); await enSearchBox.locator("input").fill("AI Learning Log: From Tool Collaboration to Independent Ability"); - await expect(enSearchBox.getByRole("link", { name: /AI Learning Log: From Tool Collaboration to Independent Ability/ }).first()).toBeVisible(); + await expect(enSearchBox.getByRole("option", { name: /AI Learning Log: From Tool Collaboration to Independent Ability/ }).first()).toBeVisible(); await enSearchBox.locator("input").fill("Writing: From Draft to Verifiable Revision"); - await expect(enSearchBox.getByRole("link", { name: /Writing: From Draft to Verifiable Revision/ }).first()).toBeVisible(); + await expect(enSearchBox.getByRole("option", { name: /Writing: From Draft to Verifiable Revision/ }).first()).toBeVisible(); await enSearchBox.locator("input").fill("Writing Evidence Card: From Tool Polish to Accountable Delivery"); - await expect(enSearchBox.getByRole("link", { name: /Writing Evidence Card: From Tool Polish to Accountable Delivery/ }).first()).toBeVisible(); + await expect(enSearchBox.getByRole("option", { name: /Writing Evidence Card: From Tool Polish to Accountable Delivery/ }).first()).toBeVisible(); }); test("Part I literary closings remain discoverable after bibliography pruning", async ({ page }) => { @@ -1135,14 +1144,14 @@ test("Part I literary closings remain discoverable after bibliography pruning", await page.getByRole("button", { name: "搜索", exact: true }).click(); const zhSearchBox = page.locator(".VPLocalSearchBox"); await zhSearchBox.locator("input").fill("听见声音背后的人"); - await expect(zhSearchBox.getByRole("link", { name: /听力篇/ }).first()).toBeVisible(); + await expect(zhSearchBox.getByRole("option", { name: /听力篇/ }).first()).toBeVisible(); await page.keyboard.press("Escape"); await page.goto("./en/"); await page.getByRole("button", { name: "Search", exact: true }).click(); const enSearchBox = page.locator(".VPLocalSearchBox"); await enSearchBox.locator("input").fill("Hear the Person Behind the Sound"); - await expect(enSearchBox.getByRole("link", { name: /Listening/ }).first()).toBeVisible(); + await expect(enSearchBox.getByRole("option", { name: /Listening/ }).first()).toBeVisible(); }); test("story and AI literary closings remain discoverable", async ({ page }) => { @@ -1150,14 +1159,14 @@ test("story and AI literary closings remain discoverable", async ({ page }) => { await page.getByRole("button", { name: "搜索", exact: true }).click(); const zhSearchBox = page.locator(".VPLocalSearchBox"); await zhSearchBox.locator("input").fill("重来不是凯旋"); - await expect(zhSearchBox.getByRole("link", { name: /我的故事/ }).first()).toBeVisible(); + await expect(zhSearchBox.getByRole("option", { name: /我的故事/ }).first()).toBeVisible(); await page.keyboard.press("Escape"); await page.goto("./en/"); await page.getByRole("button", { name: "Search", exact: true }).click(); const enSearchBox = page.locator(".VPLocalSearchBox"); await enSearchBox.locator("input").fill("Keep the Ability with the Person"); - await expect(enSearchBox.getByRole("link", { name: /Learning Anything with AI/ }).first()).toBeVisible(); + await expect(enSearchBox.getByRole("option", { name: /Learning Anything with AI/ }).first()).toBeVisible(); }); test("language navigation and representative image work", async ({ page }) => { @@ -1345,11 +1354,12 @@ test("home guide paths are grouped by purpose and keep third-party resources dis await expect(zhGroups.nth(1).getByRole("heading", { level: 2, name: "借工具放大能力" })).toBeVisible(); await expect(zhGroups.nth(2).getByRole("heading", { level: 2, name: "进入真实生活" })).toBeVisible(); await expect(zhGroups.nth(3).getByRole("heading", { level: 2, name: "第三方资源" })).toBeVisible(); - await expect(zhGroups.nth(0).locator(".guide-path")).toHaveCount(4); + await expect(zhGroups.nth(0).locator(".guide-path")).toHaveCount(5); await expect(zhGroups.nth(1).locator(".guide-path")).toHaveCount(2); await expect(zhGroups.nth(2).locator(".guide-path")).toHaveCount(4); await expect(zhGroups.nth(3).locator(".guide-path")).toHaveCount(2); await expect(zhGroups.nth(3)).toHaveClass(/guide-path-group-external/); + await expect(zhGroups.nth(0).getByRole("link", { name: /^口语方案:先让意思到达/ })).toHaveAttribute("href", "./threads/part-1/5-speaking"); await page.goto("./en/"); const enGroups = page.locator("main .guide-path-group"); @@ -1359,6 +1369,7 @@ test("home guide paths are grouped by purpose and keep third-party resources dis await expect(enGroups.nth(2).getByRole("heading", { level: 2, name: "Enter Real Life" })).toBeVisible(); await expect(enGroups.nth(3).getByRole("heading", { level: 2, name: "Third-party Resources" })).toBeVisible(); await expect(enGroups.nth(3)).toHaveClass(/guide-path-group-external/); + await expect(enGroups.nth(0).getByRole("link", { name: /^Speaking Plan: Make Meaning Arrive/ })).toHaveAttribute("href", "./threads/part-1/5-speaking"); }); test("home pages expose biezou as a bounded external AI reference", async ({ page }) => { @@ -1443,6 +1454,8 @@ test("rhythm chapter bridges the daily system and 90-day plan", async ({ page }) test("toolkit overview routes readers by problem", async ({ page }) => { await page.goto("./templates/toolkit"); + await expect(page.locator("main")).toContainText("第一次使用?先做四行"); + await expect(page.getByRole("link", { name: "工具箱实战", exact: true }).first()).toBeVisible(); const zhMain = page.locator("main"); await expect(zhMain.getByRole("heading", { level: 2, name: "先回答:我现在卡在哪里?" })).toBeVisible(); await expect(zhMain.getByRole("link", { name: "学习状态", exact: true }).first()).toBeVisible(); @@ -1458,6 +1471,8 @@ test("toolkit overview routes readers by problem", async ({ page }) => { await expect(zhMain.getByRole("link", { name: "写作证据卡", exact: true }).first()).toBeVisible(); await page.goto("./en/templates/toolkit"); + await expect(page.locator("main")).toContainText("First time here? Start with four lines."); + await expect(page.getByRole("link", { name: "Toolkit Walkthrough", exact: true }).first()).toBeVisible(); const enMain = page.locator("main"); await expect(enMain.getByRole("heading", { level: 2, name: "First Ask: Where Am I Stuck?" })).toBeVisible(); await expect(enMain.getByRole("link", { name: "Learning State", exact: true }).first()).toBeVisible(); @@ -1673,14 +1688,14 @@ test("toolkit walkthrough keeps learning state outside the AI conversation", asy await page.goto("./templates/toolkit-walkthrough"); const zhMain = page.locator("main"); await expect(zhMain.getByRole("heading", { level: 2, name: "第一步:把状态放到会话外" })).toBeVisible(); - await expect(zhMain).toContainText("AI 没有跨会话跟踪学习;状态文件完成了跟踪"); + await expect(zhMain).toContainText("状态文件保存了跨会话的连续性;AI 只根据本次实际提供的材料继续"); await expect(zhMain.getByRole("link", { name: "学习状态", exact: true }).first()).toBeVisible(); await expect(zhMain.getByRole("link", { name: "读者实践回执", exact: true }).first()).toBeVisible(); await page.goto("./en/templates/toolkit-walkthrough"); const enMain = page.locator("main"); await expect(enMain.getByRole("heading", { level: 2, name: "Step One: Put State outside the Conversation" })).toBeVisible(); - await expect(enMain).toContainText("AI did not track learning across sessions. The state file tracked it"); + await expect(enMain).toContainText("The state file preserved continuity across sessions; AI continues only from the material actually supplied this time"); await expect(enMain.getByRole("link", { name: "Learning State", exact: true }).first()).toBeVisible(); await expect(enMain.getByRole("link", { name: "Reader Field Note", exact: true }).first()).toBeVisible(); }); diff --git a/tests/worksheets.spec.mjs b/tests/worksheets.spec.mjs new file mode 100644 index 00000000..e05e485d --- /dev/null +++ b/tests/worksheets.spec.mjs @@ -0,0 +1,61 @@ +import { readFileSync } from "node:fs"; +import { expect, test } from "@playwright/test"; +import { worksheetEntries } from "../docs/.vitepress/worksheets.mjs"; + +for (const locale of ["zh", "en"]) { + test(`${locale} worksheets download and copy the complete editable document`, async ({ page }) => { + const entry = worksheetEntries.find((value) => value.locale === locale && value.source.endsWith("/speaking-evidence.md")); + const expected = readFileSync(`docs/public${entry.download}`, "utf8"); + await page.goto(`${locale === "en" ? "./en" : "."}/templates/speaking-evidence`); + const tools = page.getByRole("region", { name: locale === "en" ? "Use this worksheet" : "使用这张工作表" }); + await expect(tools).toBeVisible(); + const downloadPromise = page.waitForEvent("download"); + await tools.getByRole("link", { name: locale === "en" ? "Download Markdown" : "下载 Markdown" }).click(); + const download = await downloadPromise; + expect(download.suggestedFilename()).toBe(entry.name); + expect(readFileSync(await download.path(), "utf8")).toBe(expected); + + await page.evaluate(() => { + Object.defineProperty(navigator, "clipboard", { configurable: true, value: { + write: async (items) => { window.__worksheetCopy = await (await items[0].getType("text/plain")).text(); }, + } }); + }); + await tools.getByRole("button", { name: locale === "en" ? "Copy worksheet" : "复制整张工作表" }).click(); + await expect(tools.getByRole("status")).toContainText(locale === "en" ? "Copied" : "已复制"); + expect(await page.evaluate(() => window.__worksheetCopy)).toBe(expected); + await page.emulateMedia({ media: "print" }); + await expect(tools).toBeHidden(); + }); +} + +test("clipboard refusal leaves a working download and is announced", async ({ page }) => { + await page.goto("./en/templates/learning-state"); + await page.evaluate(() => { + Object.defineProperty(navigator, "clipboard", { configurable: true, value: { + write: async () => { throw new Error("Permission refused"); }, + } }); + }); + const tools = page.getByRole("region", { name: "Use this worksheet" }); + await tools.getByRole("button", { name: "Copy worksheet" }).click(); + await expect(tools.getByRole("status")).toContainText("Use the Markdown download"); + await expect(tools.getByRole("link", { name: "Download Markdown" })).toBeVisible(); + await expect(tools.getByRole("button", { name: "Copy worksheet" })).toBeEnabled(); +}); + +test("every public worksheet is present and guidance pages do not pretend to be blank forms", async ({ request, page }) => { + const sitemap = await (await request.get("sitemap.xml")).text(); + expect(sitemap).not.toContain("public/downloads/worksheets"); + for (let index = 0; index < worksheetEntries.length; index += 4) { + await Promise.all(worksheetEntries.slice(index, index + 4).map(async ({ download, name }) => { + const response = await request.get(`/up${download}`); + expect(response.status(), name).toBe(200); + const text = await response.text(); + expect(text, name).toBe(readFileSync(`docs/public${download}`, "utf8")); + expect(text, name).not.toMatch(/^---\n/); + })); + } + for (const route of ["./templates/toolkit", "./en/templates/toolkit-walkthrough", "./threads/part-1/0-cefr"]) { + await page.goto(route); + await expect(page.locator(".worksheet-actions")).toHaveCount(0); + } +}); diff --git a/tests/worksheets.test.mjs b/tests/worksheets.test.mjs new file mode 100644 index 00000000..21aac474 --- /dev/null +++ b/tests/worksheets.test.mjs @@ -0,0 +1,65 @@ +import assert from "node:assert/strict"; +import { test } from "node:test"; +import { worksheetEntries } from "../docs/.vitepress/worksheets.mjs"; +import { worksheetMarkdown } from "../scripts/worksheet-markdown.mjs"; +import { fromMarkdown } from "mdast-util-from-markdown"; +import { gfm } from "micromark-extension-gfm"; +import { gfmFromMarkdown } from "mdast-util-gfm"; + +const entry = { source: "templates/learning-state.md", locale: "zh" }; +const parse = (source) => fromMarkdown(source, { extensions: [gfm()], mdastExtensions: [gfmFromMarkdown()] }); +function nodesOf(tree, type) { + return [...(tree.type === type ? [tree] : []), ...(tree.children || []).flatMap((child) => nodesOf(child, type))]; +} + +test("every worksheet has an English counterpart and guidance pages remain guidance", () => { + const zh = worksheetEntries.filter(({ locale }) => locale === "zh"); + const en = worksheetEntries.filter(({ locale }) => locale === "en"); + assert.ok(zh.length >= 20); + assert.deepEqual(en.map(({ source }) => source), zh.map(({ source }) => `en/${source}`)); + assert.equal(new Set(worksheetEntries.map(({ name }) => name)).size, worksheetEntries.length); + assert.ok(worksheetEntries.every(({ source }) => !/\/toolkit(?:-walkthrough)?\.md$/.test(source))); +}); + +test("downloads retain instructions and GFM tables while opening Markdown forms for editing", () => { + const source = '---\ntitle: Card\nupdated: 2026-09-09\n---\n\n# Evidence\n\nKeep the original sample private.\n\n## Baseline\n\n```markdown\n# My evidence\n\n- [ ] Save first attempt\n\n| Trial | Evidence |\n| --- | --- |\n| Day 7 | |\n```\n\n```python\nprint("[example](weekly-review.md)")\n```\n'; + const result = worksheetMarkdown(source, entry); + const tree = parse(result); + assert.equal(result.startsWith("---"), false); + assert.match(result, /Keep the original sample private/); + assert.equal(nodesOf(tree, "table").length, 1); + assert.equal(nodesOf(tree, "listItem")[0].checked, false); + assert.equal(nodesOf(tree, "code").length, 1); + assert.equal(nodesOf(tree, "code")[0].value, 'print("[example](weekly-review.md)")'); + assert.deepEqual(nodesOf(tree, "heading").map(({ depth }) => depth), [1, 2, 3]); + assert.match(result, /稿件更新:2026-09-09/); + assert.match(result, /creativecommons.org\/licenses\/by-nc\/4.0/); +}); + +test("portable links preserve query strings, anchors, references, and inline code", () => { + const source = '# Card\n\n[Review](weekly-review.md?from=worksheet#next)\n\n[Guide](/en/templates/toolkit?from=copy#start)\n\n[Reference][ref]\n\n[Local](#card) and `[example](weekly-review.md)`.\n\n[ref]: ../threads/part-1/0-cefr.md "CEFR"\n'; + const result = worksheetMarkdown(source, entry); + const tree = parse(result); + const urls = [...nodesOf(tree, "link"), ...nodesOf(tree, "definition")].map(({ url }) => url); + assert.ok(urls.includes("https://byoungd.github.io/up/templates/weekly-review?from=worksheet#next")); + assert.ok(urls.includes("https://byoungd.github.io/up/en/templates/toolkit?from=copy#start")); + assert.ok(urls.includes("https://byoungd.github.io/up/threads/part-1/0-cefr")); + assert.ok(urls.includes("#card")); + assert.equal(nodesOf(tree, "inlineCode")[0].value, "[example](weekly-review.md)"); +}); + +test("English downloads have localized provenance and stable repeated output", () => { + const source = '# State\n\n[Review](weekly-review.md)\n'; + const en = { source: "en/templates/learning-state.md", locale: "en" }; + const result = worksheetMarkdown(source, en); + assert.match(result, /Source: \[Life Level-up Guide\]/); + assert.match(result, /https:\/\/byoungd.github.io\/up\/en\/templates\/weekly-review/); + assert.equal(worksheetMarkdown(source, en), result); +}); + +test("separate fill-in fields do not collapse into a single rendered paragraph", () => { + const result = worksheetMarkdown('# Card\n\n```markdown\nCurrent evidence:\nNext task:\nReview date:\n```\n', entry); + assert.equal(nodesOf(parse(result), "break").length, 2); + assert.match(result, /Current evidence:/); + assert.match(result, /Review date:/); +});