diff --git a/CHANGELOG.md b/CHANGELOG.md
index 79e1618..47abefa 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,9 +1,11 @@
# Changelog
-Delivered changes are recorded here. Version tags use `v` followed by a semantic version. Foundation releases describe repository infrastructure; the first runnable preview is planned as `v0.1.0-alpha.1`.
+Delivered changes are recorded here. Version tags use `v` followed by a semantic version. Foundation releases describe repository infrastructure; `v0.1.0-alpha.1` is the first research source-preview version.
## [Unreleased]
+## [0.1.0-alpha.1] - 2026-10-25
+
### Added
- Static capability plugins for Markdown/LaTeX editing, recoverable drafts, immutable human revisions, comparison, BusyTeX compilation, PDF.js preview and portable v2 archives with v1 import compatibility.
@@ -29,9 +31,20 @@ Delivered changes are recorded here. Version tags use `v` followed by a semantic
### Fixed
- Keep comparison revision reads within the selected document; prepare pinned TeX components before browser CI and retain failed compiler diagnostics, screenshots and traces.
-- Align development and acceptance documentation with implemented plugin capabilities, request limits and independent archive/database versions; separate historical local verification from the unresolved PR #11 XeLaTeX CI timeout.
+- Download the unchanged, hash-pinned Fandol font from a fixed CTAN mirror after candidate CI exposed a certificate failure through the rotating mirror endpoint; retain TLS verification.
+- Merge concurrently completed material uploads into the latest conversation selection, preserving every selected file through refresh and run creation.
+- Align development and acceptance documentation with implemented plugin capabilities, request limits and independent archive/database versions; retain the initial XeLaTeX CI failure separately from the subsequent passing checks.
- Preserve the selected report revision when navigating to its producing step, bind creation keys to limits/retry ancestry, reject invalid replay cursor indices, close interrupted AG-UI projections and retain TLS verification during isolated Windows Git installation.
+### Preview boundary
+
+- Source preview for Node.js 24 and a locally launched browser workspace; no installer, hosted deployment or npm package is provided.
+- Windows user-scoped credential protection; Crossref metadata research; dated DeepSeek non-thinking compatibility. Metadata and model interpretation do not establish full-text access or scientific claim support.
+- Static trusted plugins and supervised workers are not an untrusted-code sandbox. No arbitrary execution, multiple agents, team hosting or automatic process-loss recovery.
+- TeX/font resources are downloaded separately (202,592,248 bytes), with checksums and resumable ranges; first preparation needs network access and curl. Cached offline compilation is tested. Missing packages fail while retaining the prior PDF; the Worker deadline is 120 seconds.
+- Supervisor-Skills, local research data, credentials, installed local Skills/hooks, generated bundles and compiler/font binaries are excluded from source archives. Third-party licenses remain independent; see THIRD_PARTY_NOTICES.md.
+- Validation includes 57 Node tests and 13 browser scenarios on the candidate, plus required Windows/Linux/browser CI. Historical live model/retrieval evidence remains dated; no new paid provider calls were made for this release preparation.
+
## [0.0.1] - 2026-10-24
### Added
@@ -47,5 +60,6 @@ Delivered changes are recorded here. Version tags use `v` followed by a semantic
This foundation release contains specifications and repository tooling. It does not contain a runnable research application, an installer, a verified Supervisor-Skills integration, or runtime security guarantees.
-[Unreleased]: https://github.com/IsaacHuo/OpenLab/compare/v0.0.1...HEAD
+[Unreleased]: https://github.com/IsaacHuo/OpenLab/compare/v0.1.0-alpha.1...HEAD
+[0.1.0-alpha.1]: https://github.com/IsaacHuo/OpenLab/releases/tag/v0.1.0-alpha.1
[0.0.1]: https://github.com/IsaacHuo/OpenLab/releases/tag/v0.0.1
diff --git a/PLAN.md b/PLAN.md
index 44fd756..6b39ad9 100644
--- a/PLAN.md
+++ b/PLAN.md
@@ -2,13 +2,13 @@
更新时间:2026-10-25(Asia/Shanghai)。本文件是用户指定的计划入口,文件名固定为大写 `PLAN.md`。本次按 [ROADMAP](docs/ROADMAP.md) 的 ENG-00 至 ENG-06 顺序执行;当前事实和实际检查结果见 [STATUS](docs/STATUS.md),详细证据见 [verification](docs/verification.md)。下方保留前两轮历史台账,不把历史限制误当成本轮授权。
-## 当前阶段:ENG-04 数据与权限验收
+## 当前阶段:ENG-05 alpha 源码候选
-- 前置:ENG-03 已通过本地构建、57 项 Node 测试和 13 项浏览器;[PR #11](https://github.com/IsaacHuo/OpenLab/pull/11) 的 Windows/Linux/browser、actionlint、Gitleaks、required-checks 全通过,已合并至 main `c9a96f3`。
-- 范围:将 alpha 数据和权限门槛逐项映射到现有实现及测试,不改变已确认的架构。
-- 完成条件:新轮确认、权限拒绝、只读重放、取消/重启、凭据隔离、人工修订、档案 v1/v2 和跨项目引用各有通过证据;预览限制明确记录。
-- 精确验证:`node --test app/tests/platform.test.ts app/tests/runtime.test.ts app/tests/service.test.ts app/tests/store.test.ts app/tests/documents.test.ts app/tests/context.test.ts app/tests/workflow.test.ts`;本轮已运行 30 项,全部通过。
-- 交付:更新验收表、STATUS 和本文件,通过本地文档检查及精确 PR CI 后合并。
+- 前置:[PR #11](https://github.com/IsaacHuo/OpenLab/pull/11) 修复和 [PR #12](https://github.com/IsaacHuo/OpenLab/pull/12) 数据/权限验收均在精确 PR CI 全通过、无待解决讨论后合并。ENG-04 的 30 项边界测试通过;新基线为 main `14b8a65`。
+- 范围:统一 `VERSION`、npm 根版本、OpenAPI 版本元数据为 `0.1.0-alpha.1`,整理双语启动说明、第三方清单、预览限制和带日期的 changelog;不改变 API 形状或数据库/档案版本。
+- 完成条件:候选只含明确纳入的源码,第三方声明和使用边界完整;本地全检查及精确候选 PR CI 通过后合并。
+- 精确验证:`npm run check`、`npm run build`、`npm run test:browser`、`npm run check:actions`、`npm run check:secrets`、`git diff --check`;核对源代码档案与版本一致性。
+- 交付:候选 PR;随后 ENG-06 等精确 main 的 push CI 通过,再 `npm run release:check -- 0.1.0-alpha.1` 并按既有工作流源码预发布,核对 tag、提交和 prerelease 标志。
## 阶段清单
@@ -18,8 +18,8 @@
| ENG-01 收敛既有实现 | 已完成 | 项目源码、设计与许可纳入 PR #11,本地工具和研究数据排除 |
| ENG-02 文档口径 | 已完成 | 能力、限制、版本及历史证据对齐,文档检查通过 |
| ENG-03 构建与浏览器 | 已完成 | CI 独立准备 TeX;跨文档对比回归先失败后通过;本地 13 项和远程门槛通过,PR #11 已合并 |
-| ENG-04 数据与权限 | 进行中 | 30 项边界测试通过,验收表与预览限制需提交并通过 PR 门槛 |
-| ENG-05 alpha 候选 | 待 ENG-04 | 统一版本 `0.1.0-alpha.1`、启动说明、许可和发布说明;完整检查、构建、浏览器、actionlint、Gitleaks 及精确候选 CI |
+| ENG-04 数据与权限 | 已完成 | 30 项边界测试通过,验收表/预览限制和大写 PLAN 入口在 PR #12 通过全部 CI 后合并 |
+| ENG-05 alpha 候选 | 进行中 | 统一版本 `0.1.0-alpha.1`、启动说明、许可和发布说明;完整检查、构建、浏览器、actionlint、Gitleaks 及精确候选 CI |
| ENG-06 源码预发布 | 待 ENG-05 | 精确 main 的 push CI、release dry-run 通过后,按既有工作流创建不可变 tag 和 GitHub prerelease,核对版本/提交/说明一致 |
## 执行约束和完成边界
diff --git a/README.md b/README.md
index bf6befd..a7c141a 100644
--- a/README.md
+++ b/README.md
@@ -21,7 +21,7 @@ OpenLab is a local-first research workspace being designed to connect open resea
## Current status
-**The published v0.0.1 release is foundation-only.** Current development source includes a runnable local research preview; no installer is provided.
+**This source is the v0.1.0-alpha.1 research preview.** It runs locally with Node.js 24 and a browser; no installer is provided. The historical v0.0.1 release remains foundation-only. See the [changelog](CHANGELOG.md) for the preview boundary and [PLAN](PLAN.md) for delivery progress.
The preview combines projects, a supervised Harness, DeepSeek-tested model configuration, Crossref metadata retrieval, plan confirmation, source-linked Markdown reports and portable research archives. See [development](docs/development.md) and the [implementation plan](docs/implementation-plan.md) for tested scope and remaining gates.
@@ -35,6 +35,7 @@ The preview combines projects, a supervised Harness, DeepSeek-tested model confi
| Supervisor-Skills execution through the platform runtime adapter | Planned; not an endorsed or verified integration yet |
| Conversation, execution state, and live artifacts workspace | React/assistant-ui with AG-UI; plan, input, denial and replay checked |
| Source tracking, execution history, and artifact export | Immutable revisions, material copies and verified archive round trips |
+| Markdown/LaTeX document plugins | Recoverable drafts, immutable manual revisions, comparison, BusyTeX and PDF.js; portable v2 archives with v1 imports |
## Run the development preview
@@ -48,6 +49,8 @@ npm start
Open the launch link printed in the terminal. Add and test your model provider in settings, create a project, and submit a question. Review the plan before research starts. Model planning and execution use your provider account. Windows protects credentials under the current user; saved projects remain readable without provider access. Crossref retrieval needs a network connection. Public-page reading asks for scoped access and can be unavailable; metadata alone does not verify a paper's conclusions. DeepSeek currently uses non-thinking mode.
+For direct metadata search, select the metadata tool without a model credential. Document editing and TeX compilation also require no model. Before first TeX use, optionally run `npm run plugins:prepare`: it downloads about 203 MB of pinned components using curl, separately from the source archive. The workspace can prepare them on demand; failed downloads retain ranges for an explicit retry. See [compiler setup and limits](docs/plugins.md#tex-compiler-and-pdf-preview). On PowerShell, use `npm.cmd` if execution policy blocks `npm.ps1`.
+

This screenshot shows a real metadata-only task, not a full-text or scientific claim-verification result. [Verification details](docs/verification.md) distinguish live probes from synthetic browser fixtures.
diff --git a/README.zh-CN.md b/README.zh-CN.md
index 3914cdc..fd2a2c2 100644
--- a/README.zh-CN.md
+++ b/README.zh-CN.md
@@ -1,6 +1,6 @@
# OpenLab
-当前开发源码已提供可运行的本地科研预览,包括平台档案、通用 Harness、受监督的 worker 和浏览器工作区。已实现范围、验证结果与剩余验收项见[开发说明](docs/development.md)和[实施计划](docs/implementation-plan.md)。已发布的 v0.0.1 仍为仓库基础设施。
+当前源码为 v0.1.0-alpha.1 科研预览,包括平台档案、通用 Harness、受监督的 worker 和浏览器工作区。已实现范围、验证结果与后续任务见[开发说明](docs/development.md)和[执行计划](PLAN.md)。历史 v0.0.1 仍为仓库基础设施版。
@@ -23,7 +23,7 @@ OpenLab 致力于建立本地优先的科研工作空间,将已有的开源科
## 当前状态
-**已发布的 v0.0.1 仅交付仓库规范、协作流程和设计文档。** 当前开发源码已提供本地科研应用预览,尚不提供安装包。
+**当前源码为 v0.1.0-alpha.1 科研预览。** 使用 Node.js 24 和浏览器在本地运行,尚不提供安装包。历史 v0.0.1 仅交付仓库基础设施;预览边界见[变更日志](CHANGELOG.md),交付进度见[PLAN](PLAN.md)。
| 能力 | 状态 |
| --- | --- |
@@ -35,6 +35,7 @@ OpenLab 致力于建立本地优先的科研工作空间,将已有的开源科
| 通过平台运行时适配器执行 Supervisor-Skills | 计划集成,尚未通过执行验证 |
| 对话、执行状态与实时研究产物工作台 | React/assistant-ui 与 AG-UI,已验证确认、回答、拒绝与重放 |
| 来源追踪、运行历史与成果导出 | 不可变修订、附件副本与校验后的档案导入导出 |
+| Markdown/LaTeX 文档插件 | 可恢复草稿、不可变人工修订、对比、BusyTeX 与 PDF.js;v2 档案及 v1 导入兼容 |
## 运行开发预览
@@ -48,6 +49,8 @@ npm start
打开终端输出的启动链接,在设置中添加并测试模型服务,新建项目后提交研究问题。研究工具会等待你确认计划;生成计划和执行研究会使用你的模型账户。Windows 使用当前用户保护凭据,已保存项目不依赖模型服务即可查看。Crossref 检索需要网络。公开页面读取会请求具体授权,也可能不可用;仅有元数据不能证明论文支持某个结论。当前 DeepSeek 使用非思考模式。
+直接元数据检索可选择工具模式,无需模型凭据。文档编辑和 TeX 编译也不调用模型。首次使用 TeX 前可先运行 `npm run plugins:prepare`,通过 curl 下载约 203 MB 固定组件;这些组件独立于源码档案。工作区也可按需准备,下载失败会保留分片供显式重试。[编译准备与限制](docs/plugins.md#tex-compiler-and-pdf-preview)有详细说明。PowerShell 若阻止 `npm.ps1`,请使用 `npm.cmd`。
+

截图展示真实的元数据研究任务,不代表全文或科学论点已经核实。[验证记录](docs/verification.md)分别说明真实测试与合成浏览器夹具。
diff --git a/SECURITY.md b/SECURITY.md
index 9d46533..36c40a7 100644
--- a/SECURITY.md
+++ b/SECURITY.md
@@ -2,7 +2,12 @@
## Supported versions
-During the foundation stage, maintainers address security problems in the current `main` branch and latest published foundation release. No application runtime has shipped in v0.0.1. A version support matrix will be added before the first application release.
+Maintainers address security problems in the current `main` branch and latest published research prerelease. The v0.1.0-alpha.1 source preview targets a local Windows-first service; it is not a hosted or multi-user service. No application runtime shipped in v0.0.1.
+
+| Version line | Security scope |
+| --- | --- |
+| Current main / latest v0.1.0 alpha | Current source-preview fixes, with limitations below |
+| v0.0.1 foundation | Historical repository tooling and documentation; no application runtime |
## Report privately
diff --git a/THIRD_PARTY_NOTICES.md b/THIRD_PARTY_NOTICES.md
index 5a80fbb..1a3c5b5 100644
--- a/THIRD_PARTY_NOTICES.md
+++ b/THIRD_PARTY_NOTICES.md
@@ -38,10 +38,31 @@ These application components are not installed or bundled in the historical v0.0
## Document plugins and editor dependencies
+### Source-preview inventory, 2026-10-25
+
+The v0.1.0-alpha.1 candidate reuses the existing lockfile dependency graph; only the root application version changes. Direct package metadata in the installed lockfile-matched packages was checked as follows, in addition to the React/assistant-ui/AG-UI/Radix/Lucide inventory above:
+
+| Package | Installed version | Declared license |
+| --- | --- | --- |
+| `@codemirror/commands` | 6.11.1 | MIT |
+| `@codemirror/lang-markdown` | 6.5.2 | MIT |
+| `@codemirror/language` | 6.13.1 | MIT |
+| `@codemirror/legacy-modes` | 6.5.5 | MIT |
+| `@codemirror/search` | 6.7.2 | MIT |
+| `@codemirror/state` | 6.7.6 | MIT |
+| `@codemirror/view` | 6.43.15 | MIT |
+| `@lezer/highlight` | 1.2.5 | MIT |
+| `diff` | 9.0.0 | BSD-3-Clause |
+| `pdfjs-dist` | 6.4.299 | Apache-2.0 |
+
+GitHub source archives contain tracked OpenLab code and retained design/license notices. They exclude `node_modules`, `dist`, prepared BusyTeX/font components, research data, protected credentials, local `.agents`/`.codex` installations and unselected mockups. `npm ci` installs dependencies with their own license files. Preparing compiler resources downloads third-party components separately; their terms and sources below still apply. No Supervisor-Skills contents or compiler/font binaries are redistributed by this source release.
+
+### Editor and compiler provenance
+
The default editors use CodeMirror 6 (`@codemirror/state`, `view`, `commands`, `search`, `language`, `lang-markdown`, `legacy-modes` and `@lezer/highlight`), under MIT licenses. Current upstream sources and licenses are linked from [CodeMirror](https://codemirror.net/); its repositories have moved to the maintainer's forge. OpenLab supplies a React host and a neutral theme, not a fork of the editor.
Version comparison uses [jsdiff](https://github.com/kpdecker/jsdiff), BSD-3-Clause, in a bounded Worker. PDF previews use [PDF.js](https://github.com/mozilla/pdf.js), Apache-2.0; the dependency and worker are loaded only for PDF viewing. Installed versions are pinned in the npm lockfile.
The default TeX adapter uses [BusyTeX](https://github.com/busytex/busytex) release `build_wasm_4499aa69fd3cf77ad86a47287d9a5193cf5ad993_7936974349_1`, source commit `4499aa69fd3cf77ad86a47287d9a5193cf5ad993`. BusyTeX's repository glue is MIT; its compiled binaries include TeX Live and other components under their respective licenses. Those binaries are downloaded into a separate runtime cache, with release/source references and checksums. They are not relicensed as OpenLab code. The pinned pipeline invokes TeX with shell escape disabled.
-The compiler additionally supplies [Fandol Song](https://ctan.org/tex-archive/fonts/fandol) 0.3 by the Fandol team, GPL with the font exception described in its COPYING file. Its SHA-256 is `a3820003227d4abe31fe28b493200d94a849ccfd078b50a019264f70353020b0`. Retain the upstream license/source materials when redistributing prepared compiler/font components. The plugin SDK, resource layout and scope are documented in [plugins](docs/plugins.md).
+The compiler additionally supplies [Fandol Song](https://ctan.org/tex-archive/fonts/fandol) 0.3 by the Fandol team, GPL with the font exception described in its COPYING file. Its SHA-256 is `a3820003227d4abe31fe28b493200d94a849ccfd078b50a019264f70353020b0`. Downloads use the [MIT CTAN mirror](https://ctan.csail.mit.edu/fonts/fandol/), with the same bytes and hash; TLS verification is retained. Retain the upstream license/source materials when redistributing prepared compiler/font components. The plugin SDK, resource layout and scope are documented in [plugins](docs/plugins.md).
diff --git a/VERSION b/VERSION
index 8acdd82..d6711f8 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-0.0.1
+0.1.0-alpha.1
diff --git a/app/openapi.ts b/app/openapi.ts
index fa46f3d..d2127b8 100644
--- a/app/openapi.ts
+++ b/app/openapi.ts
@@ -47,7 +47,7 @@ for (const [path, item] of Object.entries(paths)) {
if (parameters.length) item.parameters = parameters;
}
export const openapi = {
- openapi: '3.1.0', info: { title: 'OpenLab local research API', version: '0.1.0-dev', description: 'Loopback only. Use the per-launch link to establish a local session. Mutations require Origin and x-openlab-csrf. Research records are authoritative; SSE attachment never starts work.' },
+ openapi: '3.1.0', info: { title: 'OpenLab local research API', version: '0.1.0-alpha.1', description: 'Loopback only. Use the per-launch link to establish a local session. Mutations require Origin and x-openlab-csrf. Research records are authoritative; SSE attachment never starts work.' },
servers: [{ url: '/api/v1' }], paths,
components: {
securitySchemes: { LocalSession: { type: 'apiKey', in: 'cookie', name: 'openlab_session' } },
diff --git a/app/tex-resources.ts b/app/tex-resources.ts
index 9ed4a18..c857a72 100644
--- a/app/tex-resources.ts
+++ b/app/tex-resources.ts
@@ -29,7 +29,7 @@ export class TexResources {
if (this.stopped) throw new Error('Compiler preparation cancelled');
const path = join(texRoot, name);
if (!existsSync(path) || statSync(path).size !== size) {
- const url = name === 'FandolSong-Regular.otf' ? 'https://mirrors.ctan.org/fonts/fandol/FandolSong-Regular.otf' : `https://github.com/busytex/busytex/releases/download/${texRelease}/${name}`;
+ const url = name === 'FandolSong-Regular.otf' ? 'https://ctan.csail.mit.edu/fonts/fandol/FandolSong-Regular.otf' : `https://github.com/busytex/busytex/releases/download/${texRelease}/${name}`;
let downloadUrl = url; try { const head = await fetch(assetIds[name] ? `https://api.github.com/repos/busytex/busytex/releases/assets/${assetIds[name]}` : url, { headers: { Accept: 'application/octet-stream' }, method: 'HEAD', signal: AbortSignal.timeout(20_000) }); if (head.ok) downloadUrl = head.url; } catch { /* curl can still use the original pinned URL. */ }
const chunkSize = 512 * 1024; const chunks: Buffer[] = new Array(Math.ceil(size / chunkSize)); let next = 0;
const downloaded = await Promise.allSettled(Array.from({ length: Math.min(16, chunks.length) }, async () => {
diff --git a/browser-tests/workspace.spec.ts b/browser-tests/workspace.spec.ts
index cb132ca..cc28377 100644
--- a/browser-tests/workspace.spec.ts
+++ b/browser-tests/workspace.spec.ts
@@ -240,13 +240,27 @@ test('project search, conversation rename, continuous history and refresh persis
test('material selections stay frozen and provider editing shows local failures', async ({ page }) => {
await launch(page); await project(page, '材料与设置');
+ let uploaded = 0;
+ let releaseUploads!: () => void;
+ const uploadsComplete = new Promise(resolve => { releaseUploads = resolve; });
+ await page.route('**/projects/*/materials', async route => {
+ if (route.request().method() !== 'POST') { await route.continue(); return; }
+ const response = await route.fetch();
+ if (++uploaded === 2) releaseUploads();
+ await uploadsComplete;
+ await route.fulfill({ response });
+ });
for (const name of ['selected.txt', 'excluded.txt']) await page.locator('input[type=file]').first().setInputFiles({ name, mimeType: 'text/plain', buffer: Buffer.from(name + ' evidence') });
await page.getByRole('button', { name: '研究成果', exact: true }).click();
await page.getByRole('tab', { name: '附件', exact: false }).click();
+ await expect(page.getByRole('checkbox', { name: '用于本次研究 selected.txt' })).toBeChecked();
+ await expect(page.getByRole('checkbox', { name: '用于本次研究 excluded.txt' })).toBeChecked();
+ await page.unroute('**/projects/*/materials');
await page.getByRole('checkbox', { name: '用于本次研究 excluded.txt' }).uncheck();
await page.reload();
await page.getByRole('tab', { name: '附件', exact: false }).click();
await expect(page.getByRole('checkbox', { name: '用于本次研究 excluded.txt' })).not.toBeChecked();
+ await expect(page.getByRole('checkbox', { name: '用于本次研究 selected.txt' })).toBeChecked();
const request = page.waitForRequest(request => request.url().endsWith('/runs') && request.method() === 'POST');
await page.getByLabel('研究问题', { exact: true }).fill('Materials review');
await page.getByRole('button', { name: '生成计划', exact: true }).click();
diff --git a/docs/STATUS.md b/docs/STATUS.md
index f6fdce3..e71b3c0 100644
--- a/docs/STATUS.md
+++ b/docs/STATUS.md
@@ -1,10 +1,10 @@
# OpenLab 当前状态与交接
-更新时间:2026-10-25(Asia/Shanghai)。当前任务 **ENG-04:alpha 数据与权限验收**。ENG-03 已通过精确 PR CI 并合并;本轮 30 项边界测试通过,验收映射已写入既有记录,正在准备文档 PR。用户指定的计划入口为根 [PLAN.md](../PLAN.md),详细任务合同见 [ROADMAP](ROADMAP.md),约束见 [DECISIONS](DECISIONS.md)。
+更新时间:2026-10-25(Asia/Shanghai)。当前任务 **ENG-05:alpha 源码候选准备**。ENG-04 的 [PR #12](https://github.com/IsaacHuo/OpenLab/pull/12) 已通过全部必需检查并合并,当前准备 `0.1.0-alpha.1` 版本身份、启动说明、许可和发布材料。计划入口为根 [PLAN.md](../PLAN.md),详细任务合同见 [ROADMAP](ROADMAP.md),约束见 [DECISIONS](DECISIONS.md)。
## Git、授权与交付边界
-- 当前分支:`codex/alpha-data-gates`,起点为 main `c9a96f3ca22fd85276ca9fb09defa1a541bd08c1`([PR #11](https://github.com/IsaacHuo/OpenLab/pull/11) squash 合并)。ENG-02 文档和 ENG-03 修复已随该 PR 交付。
+- 当前分支:`codex/alpha-source-candidate`,起点为 main `14b8a652f63c196b1746878f376bab259a141192`([PR #12](https://github.com/IsaacHuo/OpenLab/pull/12) squash 合并)。此前 PR #11 交付实现、ENG-02 文档和 ENG-03 修复。
- 用户已授权按 ENG-00 至 ENG-06 顺序提交、PR、必需检查通过后合并,满足候选和精确 main CI 门槛后源码预发布;不绕过规则,不调用付费模型,不把远期候选当成已批准功能。
- Windows x64、Node.js `24.19.0`、npm `11.17.0`;沿用锁文件和已有依赖,未升级依赖。
- 原小写根计划已按用户要求更名为大写 `PLAN.md`,顶部补当前阶段和验收出口,保留两轮历史台账并同步链接。README 中英文导航已同步。
@@ -18,8 +18,8 @@
| ENG-01 | 已完成 | 既有实现盘点、提交、推送,PR #11 已合并 |
| ENG-02 | 已完成 | 文档能力、限制、版本和历史证据对齐;三项文档检查通过 |
| ENG-03 | 已完成 | 本地 57 项 Node、13 项浏览器、构建和检查通过;精确 PR CI 全通过后合并 |
-| ENG-04 | 进行中 | 30 项数据/权限/兼容边界测试通过,验收表已更新,待文档 PR CI 和合并 |
-| ENG-05 | 待开始 | 依赖 ENG-04;候选版本、许可、启动与发布说明及精确候选 CI |
+| ENG-04 | 已完成 | 30 项边界测试通过,验收映射和大写 PLAN 入口在 PR #12 通过 CI 后合并 |
+| ENG-05 | 进行中 | 固定字体镜像已通过远程准备和真实编译;随后 CI 暴露并发材料选择覆盖,确定性回归先失败后通过,正在复验候选 |
| ENG-06 | 待开始 | 已授权按门槛发布;依赖 ENG-05、release dry-run 与精确 main push CI |
## 本轮实际验证
@@ -27,14 +27,18 @@
- ENG-03:`npm run check`(57 项 Node,0 失败/跳过)、`npm run build`、`npm run test:browser`(13 项)、`npm run check:actions`、`npm run check:secrets`、`git diff --check` 通过。桌面/平板/手机文档截图已检查。
- [CI 40170016084](https://github.com/IsaacHuo/OpenLab/actions/runs/40170016084):head `73ad1658c7f9f3d4d283d5221af4922668661a99` 的 Windows/Linux、独立 TeX 准备、13 项浏览器、actionlint、Gitleaks、required-checks 全通过。该结果不替代后续文档和版本候选的 CI。
- ENG-04:`node --test app/tests/platform.test.ts app/tests/runtime.test.ts app/tests/service.test.ts app/tests/store.test.ts app/tests/documents.test.ts app/tests/context.test.ts app/tests/workflow.test.ts`:30 项通过,0 失败/跳过。均使用隔离受控夹具,未调用真实模型。
+- [CI 40170593908](https://github.com/IsaacHuo/OpenLab/actions/runs/40170593908):PR #12 head `b1373907f448642991c55840d2c9893c7af1d4b0` 的全部必需检查通过,已合并为 main `14b8a65`。
- 本阶段 `npm.cmd run lint:markdown`(36 份)、`npm.cmd run check:repository`(159 个文件)及 `git diff --check` 通过,大写路径和链接已核对;详细阶段证据见 [verification](verification.md),alpha 门槛映射见 [acceptance](acceptance.md#alpha-data-and-permission-gates-eng-04-2026-10-25)。
+- ENG-05 候选:`npm run check`(57 项)、build、browser(13 项)、actionlint、Gitleaks、npm audit(零漏洞)和空白检查通过;版本/OpenAPI 一致、依赖图未变及 154 个源码路径的排除检查通过。尚未发布;精确候选和 main CI 不用历史结果替代。
+- PR #13 首次 CI `40171037488`:仓库、actionlint、Gitleaks 通过;准备字体的一个分片 curl 60,浏览器未启动。改用固定 MIT CTAN 镜像,Node HTTPS 实取的 4,947,904 字节与既有 SHA-256 完全一致;TLS 验证保持开启。修复后 check(57 项)、actionlint、空白检查再次通过,等待新远程验证。
+- 后续 CI `40171390131`:固定字体准备和真实 TeX 通过,材料选择场景失败,整体 12/13。受控并发上传回归复现旧状态覆盖;修复为基于最新选择合并,针对场景、类型检查、构建及完整 13 项浏览器再次通过;等待新 head CI。
## 限制与下一动作
- 早期 XeLaTeX CI 超时的精确原因没有被日志证明;分离准备后的新 CI 已通过。隔离本地冷下载仍观察到 curl 35 TLS 错误,缓存分片保留,明确重试可续传;不把本地 TLS 故障等同于旧 CI 根因。
- 预览范围保持 Windows 凭据保护、单 Crossref 元数据提供商、具日期的 DeepSeek 非思考模式兼容;没有通用全文/科学论点核实、任意代码、动态插件隔离、多 Agent、安装包或团队部署。Supervisor-Skills 不随源码分发。
- 现有超过 500 kB 的分块提示保留;尚无用户性能测量,不为发布引入无目标重构。
-- 下一动作:完成 ENG-04 文档检查与精确 PR CI,按规则合并,再推进 ENG-05 候选准备。
+- 下一动作:执行 ENG-05 的完整候选检查,建立候选 PR,通过后合并;ENG-06 继续等待精确 main push CI 和 release dry-run。
## 保留的本地预览记录
diff --git a/docs/maintaining.md b/docs/maintaining.md
index 3baf638..ea0df87 100644
--- a/docs/maintaining.md
+++ b/docs/maintaining.md
@@ -35,16 +35,16 @@ The Gitleaks check scans Git history and the current working tree. This is compl
1. Use a PR to update VERSION, package.json and package-lock.json to the same version. Move actual delivered changes from `Unreleased` into a dated CHANGELOG section. Keep an empty `Unreleased` section for subsequent work.
2. Check local validation and the PR's CI. Squash merge after all required checks pass and discussions are resolved.
3. Wait for the `Repository checks` push workflow on the exact new `main` commit to succeed. PR checks alone do not authorize a release.
-4. Optionally run `npm run release:check -- 0.0.1` from a clean checkout at current main. It performs all identity, changelog, CI, main-target and remote-tag checks without creating a tag or release.
+4. Run `npm run release:check -- 0.1.0-alpha.1` from a clean checkout at current main for this preview. It performs all identity, changelog, CI, main-target and remote-tag checks without creating a tag or release.
5. Dispatch the [Release workflow](https://github.com/IsaacHuo/OpenLab/actions/workflows/release.yml) on `main`, entering the version without `v`. Example:
```sh
- gh workflow run release.yml --repo IsaacHuo/OpenLab --ref main -f version=0.0.1
+ gh workflow run release.yml --repo IsaacHuo/OpenLab --ref main -f version=0.1.0-alpha.1
```
The workflow runs with default read permission and job-scoped content write permission. It revalidates identity and the exact main commit, creates an annotated tag, pushes it, then publishes a GitHub Release with reviewed CHANGELOG content plus categorized merged-PR notes and contributor credits. Stable semantic versions become the latest release; versions containing a prerelease suffix are marked prerelease. A repository-wide release concurrency group serializes publication.
-The first release is `v0.0.1`: repository governance, specifications and tooling. GitHub provides source archives; no application installer is attached. The first runnable preview is planned as `v0.1.0-alpha.1`, only after the product acceptance gates pass.
+The historical first release is `v0.0.1`: repository governance, specifications and tooling. The first research source preview is `v0.1.0-alpha.1`, gated by the [alpha acceptance](acceptance.md#alpha-data-and-permission-gates-eng-04-2026-10-25) and [execution plan](../PLAN.md). GitHub provides source archives; no application installer, npm publication or prepared TeX/font binary bundle is attached. Publishing still requires the exact main push workflow to pass and explicit release authorization; candidate version files alone do not prove publication.
## Failure and recovery
diff --git a/docs/openapi.json b/docs/openapi.json
index 8cdef62..09068c8 100644
--- a/docs/openapi.json
+++ b/docs/openapi.json
@@ -2,7 +2,7 @@
"openapi": "3.1.0",
"info": {
"title": "OpenLab local research API",
- "version": "0.1.0-dev",
+ "version": "0.1.0-alpha.1",
"description": "Loopback only. Use the per-launch link to establish a local session. Mutations require Origin and x-openlab-csrf. Research records are authoritative; SSE attachment never starts work."
},
"servers": [
diff --git a/docs/plugins.md b/docs/plugins.md
index 323f5e4..5ebe33e 100644
--- a/docs/plugins.md
+++ b/docs/plugins.md
@@ -32,6 +32,8 @@ Browser CI runs that preparation as a separate bounded step before Playwright. T
The Fandol Song 0.3 font is supplied as `fonts/FandolSong-Regular.otf` in the compiler's virtual project. For Chinese text, use fontspec and select this font by that relative path. It retains its GPL font-exception licensing. Package and font availability is explicit: cached inputs compile offline, while unavailable dependencies fail visibly.
+The font download uses the fixed MIT CTAN mirror at `https://ctan.csail.mit.edu/fonts/fandol/FandolSong-Regular.otf`, retaining the existing 4,947,904-byte size and SHA-256 pin. This avoids selecting a different redirecting CTAN mirror during preparation; certificate verification remains enabled. Candidate CI exposed a certificate failure on one font range when using the rotating mirror endpoint. The replacement file was independently fetched and matched the existing hash before changing the source URL.
+
Compilation freezes an already saved revision and its resource hashes. Unsaved changes use save-and-compile. Only one compiler invocation runs per browser module at a time; cancellation and the 120-second deadline terminate its Worker. Logs and failed/cancelled status remain inspectable. A failed build does not discard the previous successful PDF; the preview identifies its source revision.
PDF.js CMaps, standard fonts and decoder resources are copied to separate on-demand static assets during the build. PDF.js is a separate lazy preview provider, with pages, zoom, text selection and download. Build records contain input revision/hash, resource hashes, compiler/plugin versions, status, log and output hash. These are client-submitted compiler receipts, not server attestation or scientific-claim verification.
diff --git a/docs/verification.md b/docs/verification.md
index 72f741d..130fa05 100644
--- a/docs/verification.md
+++ b/docs/verification.md
@@ -40,6 +40,20 @@ The planning research inspected these popular projects on 2026-10-25. Star count
## Local delivery preflight, 2026-10-25
+### ENG-05 source candidate
+
+The first candidate [CI 40171037488](https://github.com/IsaacHuo/OpenLab/actions/runs/40171037488) on `6e8660f8c65cdebac5a5746a0398922afced7e75` passed both repository jobs, actionlint and Gitleaks but failed compiler preparation before Playwright: one Fandol font range returned curl exit 60 (certificate validation failed), after 202,067,960 of 202,592,248 bytes. The candidate was not merged or published. The rotating CTAN font URL was replaced with the fixed MIT CTAN mirror. A real Node.js HTTPS fetch with normal certificate verification returned exactly 4,947,904 bytes and the existing SHA-256 `a3820003227d4abe31fe28b493200d94a849ccfd078b50a019264f70353020b0`. No font version, digest, license, compiler version or TLS policy changed. Native curl additionally encountered the already documented offline revocation environment; this is separate from the CI certificate failure. New exact-head CI is required to validate preparation with the replacement URL.
+
+The next [CI 40171390131](https://github.com/IsaacHuo/OpenLab/actions/runs/40171390131) on `524e9f894e3857d13e9784d0c420d4facf4da511` prepared the fixed font and passed real compilation, but browser acceptance was 12/13: the material-selection request unexpectedly contained zero IDs. Retained failure artifacts were uploaded. Inspection found the upload completion handler appended to a selection captured before the asynchronous upload. The existing browser scenario was strengthened to hold both upload responses until both files were stored; it then failed locally because `selected.txt` was unchecked. The handler now appends to the latest conversation selection inside the functional state update. The strengthened scenario passed after the fix, including persistence on reload and exactly one selected material in the run request. Type checking, build, Markdown/repository checks, whitespace checks and the full local 13-scenario browser suite passed again after this repair. Exact-head remote acceptance remains required before merge.
+
+ENG-04's [PR #12](https://github.com/IsaacHuo/OpenLab/pull/12) passed [workflow 40170593908](https://github.com/IsaacHuo/OpenLab/actions/runs/40170593908) on head `b1373907f448642991c55840d2c9893c7af1d4b0`, with all required jobs successful and no unresolved review threads, then merged as `14b8a652f63c196b1746878f376bab259a141192`. The source candidate starts from that commit.
+
+The candidate sets VERSION, package.json, both root package-lock version fields and OpenAPI info metadata to `0.1.0-alpha.1`; the generated OpenAPI JSON matches the source exactly. An explicit comparison against the parent lockfile confirmed that the dependency graph is unchanged. API paths/types, database version 1 and archive v1/v2 compatibility are unchanged. The dated changelog includes startup, evidence and preview limits. English/Chinese README instructions, security scope and third-party notices were updated together where applicable.
+
+On native Windows x64, Node.js 24.19.0 / npm 11.17.0, this candidate passed `npm run check` (57 tests, no failures/skips), `npm run build`, all 13 `npm run test:browser` scenarios, `npm run check:actions` (actionlint 1.7.12), `npm run check:secrets` (Gitleaks 8.30.1), `npm audit --audit-level=high` (zero vulnerabilities) and `git diff --check`. The compiler test used the existing pinned cache. The existing large-chunk advisory remains. No live model/retrieval calls were made; the earlier dated live records were reused without broadening their compatibility claims.
+
+Inspection of all 154 tracked paths found uppercase PLAN.md and no tracked research/configuration/cache/dependency/build/test-output directories. Direct dependency version/license metadata was checked against installed lockfile-matched packages; retained component notices remain present. GitHub source archives exclude Supervisor-Skills, local Skills/hooks and prepared TeX/font binaries. Remote candidate CI and exact main push CI remain separate gates; these local results alone do not establish publication.
+
### ENG-03 remote completion and ENG-04 gate audit
[Workflow 40170016084](https://github.com/IsaacHuo/OpenLab/actions/runs/40170016084) passed on PR #11 head `73ad1658c7f9f3d4d283d5221af4922668661a99`, using temporary merge checkout `c99db1b22a68a6296889d687cbe51f8400f05ba7`. Both repository jobs, actionlint, Gitleaks, independent compiler preparation, all 13 browser scenarios and required-checks succeeded. Compiler preparation took 12 seconds on that runner. Review threads were empty, and PR #11 was squash merged to main `c9a96f3ca22fd85276ca9fb09defa1a541bd08c1`. This resolves the merge blocker; the old timeout's exact cause remains unproven.
diff --git a/package-lock.json b/package-lock.json
index b398d97..3ff6753 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "openlab-repository",
- "version": "0.0.1",
+ "version": "0.1.0-alpha.1",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "openlab-repository",
- "version": "0.0.1",
+ "version": "0.1.0-alpha.1",
"license": "Apache-2.0",
"dependencies": {
"@ag-ui/client": "1.0.3",
diff --git a/package.json b/package.json
index 3e4a09e..b2d7250 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "openlab-repository",
- "version": "0.0.1",
+ "version": "0.1.0-alpha.1",
"private": true,
"type": "module",
"description": "Repository governance and documentation tooling for OpenLab",
diff --git a/web/workspace.tsx b/web/workspace.tsx
index 24f474b..5515aa9 100644
--- a/web/workspace.tsx
+++ b/web/workspace.tsx
@@ -356,7 +356,7 @@ export function App() {
{paneOpen && viewportWidth >= 1024 && <>