Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 95 additions & 3 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ jobs:
runs-on: windows-latest
timeout-minutes: 45
permissions:
actions: read
contents: write
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5
Expand All @@ -28,6 +29,24 @@ jobs:
if ((git rev-parse origin/main).Trim() -ne $env:GITHUB_SHA) {
throw "release tag must point to the current main commit"
}
- name: Require successful exact-SHA CI
env:
GH_TOKEN: ${{ github.token }}
shell: pwsh
run: |
$ciRuns = @(
gh run list --commit $env:GITHUB_SHA --workflow CI --limit 100 `
--json databaseId,headSha,conclusion,status,url,workflowName,createdAt | ConvertFrom-Json
)
$successfulRuns = @($ciRuns | Where-Object {
$_.workflowName -eq "CI" -and
$_.headSha -eq $env:GITHUB_SHA -and
$_.status -eq "completed" -and
$_.conclusion -eq "success"
})
if ($successfulRuns.Count -lt 1) {
throw "exact-SHA CI did not complete successfully"
}
- uses: astral-sh/setup-uv@d0cc045d04ccac9d8b7881df0226f9e82c39688e
with:
enable-cache: true
Expand All @@ -46,7 +65,7 @@ jobs:
--commit $env:GITHUB_SHA `
--tree $tree `
--tag $env:GITHUB_REF_NAME `
--version 0.4.0 `
--version 0.4.1 `
--url "$env:GITHUB_SERVER_URL/$env:GITHUB_REPOSITORY/releases/tag/$env:GITHUB_REF_NAME" `
--ci-url "$env:GITHUB_SERVER_URL/$env:GITHUB_REPOSITORY/actions/runs/$env:GITHUB_RUN_ID" `
--output .hermes/desktop-runtime-v1/runtime/release-identity.json
Expand Down Expand Up @@ -84,7 +103,7 @@ jobs:
if ($manifestNames.Count -ne 3 -or ($manifestNames | Select-Object -Unique).Count -ne 3) {
throw "expected exactly three unique checksum-bound payloads"
}
- name: Publish verified assets
- name: Upload verified assets to draft release
env:
GH_TOKEN: ${{ github.token }}
shell: pwsh
Expand All @@ -97,4 +116,77 @@ jobs:
(Resolve-Path "release-assets/release-identity.json").Path,
(Resolve-Path "release-assets/SHA256SUMS.txt").Path
)
gh release create $env:GITHUB_REF_NAME $releaseAssets --verify-tag --title "ArcheAxis OS $env:GITHUB_REF_NAME" --generate-notes
gh release create $env:GITHUB_REF_NAME $releaseAssets --draft --verify-tag --title "ArcheAxis OS $env:GITHUB_REF_NAME" --generate-notes
- name: Read back and verify draft release assets
env:
GH_TOKEN: ${{ github.token }}
shell: pwsh
run: |
$expectedAssets = @(
"ArcheAxis.OS-Windows-x64-setup.exe",
"cognitive_loop_os-0.4.1-py3-none-any.whl",
"release-identity.json",
"SHA256SUMS.txt"
) | Sort-Object
$release = gh release view $env:GITHUB_REF_NAME --json tagName,targetCommitish,isDraft,assets,url | ConvertFrom-Json
if ($release.tagName -ne $env:GITHUB_REF_NAME) { throw "release tag readback mismatch" }
if ($release.isDraft -ne $true) { throw "release draft state mismatch" }
$acceptedReleaseTargets = @("main", $env:GITHUB_SHA)
if ($release.targetCommitish -notin $acceptedReleaseTargets) {
throw "release target commit is neither main nor exact workflow SHA"
}
if ((git rev-list -n 1 "$($release.tagName)^{}").Trim() -ne $env:GITHUB_SHA) {
throw "release tag target does not equal the exact workflow SHA"
}
$publicAssets = @($release.assets | ForEach-Object name | Sort-Object)
if (Compare-Object $expectedAssets $publicAssets) {
throw "public asset set differs from expected release asset set"
}
$downloadRoot = ".hermes/task-runtime/release-download-readback"
New-Item -ItemType Directory -Force $downloadRoot | Out-Null
gh release download $env:GITHUB_REF_NAME --dir $downloadRoot
foreach ($asset in $release.assets) {
if (-not $asset.digest -or -not $asset.digest.StartsWith("sha256:")) {
throw "provider digest is missing for $($asset.name)"
}
$downloadedDigest = (Get-FileHash "$downloadRoot/$($asset.name)" -Algorithm SHA256).Hash.ToLowerInvariant()
if ($asset.digest.ToLowerInvariant() -ne "sha256:$downloadedDigest") {
throw "provider digest differs from downloaded asset for $($asset.name)"
}
}
$manifest = Get-Content "$downloadRoot/SHA256SUMS.txt" | ForEach-Object {
if ($_ -notmatch '^([0-9a-fA-F]{64}) (.+)$') { throw "invalid downloaded SHA256SUMS line: $_" }
[pscustomobject]@{ digest = $Matches[1].ToLowerInvariant(); name = $Matches[2] }
}
$expectedPayloads = @($expectedAssets | Where-Object { $_ -ne "SHA256SUMS.txt" } | Sort-Object)
$manifestPayloads = @($manifest | ForEach-Object name | Sort-Object)
if (Compare-Object $expectedPayloads $manifestPayloads) {
throw "downloaded checksum payload set differs from expected payload set"
}
foreach ($entry in $manifest) {
$actual = (Get-FileHash "$downloadRoot/$($entry.name)" -Algorithm SHA256).Hash.ToLowerInvariant()
if ($actual -ne $entry.digest) { throw "downloaded SHA-256 mismatch for $($entry.name)" }
$asset = @($release.assets | Where-Object name -eq $entry.name)
if ($asset.Count -ne 1 -or -not $asset[0].digest) { throw "missing provider digest for $($entry.name)" }
if ($asset[0].digest.ToLowerInvariant() -ne "sha256:$actual") { throw "provider digest mismatch for $($entry.name)" }
}
$identity = Get-Content "$downloadRoot/release-identity.json" -Raw | ConvertFrom-Json
$tree = (git rev-parse "$env:GITHUB_SHA^{tree}").Trim()
if ($identity.release.tag -ne $env:GITHUB_REF_NAME -or $identity.source.commit -ne $env:GITHUB_SHA) {
throw "downloaded release identity does not bind tag and exact commit"
}
if ($identity.source.tree -ne $tree) {
throw "downloaded release identity tree mismatch"
}
if ($identity.source.ci_url -ne "$env:GITHUB_SERVER_URL/$env:GITHUB_REPOSITORY/actions/runs/$env:GITHUB_RUN_ID") {
throw "downloaded release identity CI URL mismatch"
}
if ($identity.source.ci_run -ne [int64]$env:GITHUB_RUN_ID -or $identity.release.url -ne $release.url) {
throw "downloaded release identity provenance readback mismatch"
}
- name: Publish verified draft release
env:
GH_TOKEN: ${{ github.token }}
shell: pwsh
run: |
gh release edit $env:GITHUB_REF_NAME --draft=false
20 changes: 20 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Changelog

All notable release changes are recorded here. Dates and publication status
must be read from Git/GitHub; a source entry does not itself prove publication.

## [Unreleased]

- The source Release Manifest remains `unreleased / public=false` until a
release artifact receives an injected and verified public identity.
- Added release-truth, licensing, third-party, and security documentation.
- Added a post-publication gate that reads back the exact public asset set,
provider digests, release identity, and downloaded SHA-256 payloads.

## [0.4.0] - historical release

`v0.4.0` is retained as historical publication evidence. Readback found
incomplete checksum payload coverage: the public installer name did not match
its checksum-manifest name and an extra public payload was absent from the
manifest. The tag, Release, and assets are intentionally preserved; remediation
must use a new version. This entry makes no signature claim.
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2026 DTALEX66

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
10 changes: 9 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ ArcheAxis OS 以受治理的统一知识底座连接个人学习链和 AI 使用
- **个人学习与 AI 使用的双向反馈**:学习笔记、纠错、练习和人工审核不会自动提升为事实;AI 的来源、Claim、解释、任务结果和 Lesson 同样必须先经 Candidate 治理。
- **可治理的本地运行时**:SQLite 持久化、Outbox/Receipt、失败不改状态、重试与回读,以及不暴露内部审计 ID 的公开投影。
- **桌面 Workspace A1**:默认 Apple-light,Violet Core 保留为暗色主题;一级 Rail、动态二级导航、上下文与证据检查器和真实活动坞均已接入。真实 Chromium 验证壳层交互后方可发布;Tauri WebView 点击级证据和公开发布资产仍未闭环,不能用 Chromium 结果替代。
- **当前版本**:`0.4.0`;Release Manifest 仍为 `unreleased / public=false`,公开 Alpha/Beta/Stable 发布尚未宣告。
- **当前版本**:`0.4.1`;Release Manifest 仍为 `unreleased / public=false`,公开 Alpha/Beta/Stable 发布尚未宣告。
- **发布真相**:`v0.4.0` 是保留且不可原地改写的 historical release,但具有 **incomplete checksum payload coverage**;它不证明完整发布完整性。`v0.4.1` 只有在 merge-SHA CI、tag、公开资产集合、下载后 SHA-256、release identity 与 installer lifecycle 全部回读通过后才可宣称发布。

Research candidate 仍必须经过人工审查和来源独立性验证,不能自动当作 verified truth。产品定位见 [`docs/PRODUCT_POSITIONING.md`](docs/PRODUCT_POSITIONING.md);当前事实、限制和验证证据见 [`docs/PROJECT_STATUS.md`](docs/PROJECT_STATUS.md) 与 [`docs/VERIFICATION_POLICY.md`](docs/VERIFICATION_POLICY.md)。

Expand Down Expand Up @@ -190,3 +191,10 @@ pre-commit run --all-files
开发中只运行受影响的定向测试;diff 冻结后运行一次必要完整门禁,推送后以一次 GitHub CI 为准。详细触发规则见 [`docs/VERIFICATION_POLICY.md`](docs/VERIFICATION_POLICY.md)。

CI 使用 `pyproject.toml` 作为依赖与工具配置单一事实源;`requirements.txt` 仅作为兼容安装清单并与核心依赖保持同步。

## 许可、安全与变更记录

- 项目许可:[`LICENSE`](LICENSE)
- 第三方组件说明:[`THIRD_PARTY_NOTICES.md`](THIRD_PARTY_NOTICES.md)
- 漏洞报告:[`SECURITY.md`](SECURITY.md)
- 发布历史与已知完整性限制:[`CHANGELOG.md`](CHANGELOG.md)
29 changes: 29 additions & 0 deletions SECURITY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Security Policy

## Supported versions

Security fixes are developed against the current `main` branch and the newest
published release, when one exists. The historical `v0.4.0` release is retained
for provenance but does not have complete checksum payload coverage. It must
not be treated as a fully integrity-verified distribution.

## Reporting a vulnerability

Do not open a public issue containing exploit details, credentials, personal
data, or private paths. Use GitHub's private security-advisory reporting for
this repository. If that facility is unavailable, open a minimal public issue
asking the maintainer to enable a private reporting channel, without including
the vulnerability details.

Include the affected version or commit, impact, reproduction preconditions,
and the smallest non-sensitive proof available. Never attach real credentials,
database contents, personal Vault data, or executable payloads.

## Release-security boundary

A successful build or CI run alone does not prove a public release. Release
claims require an exact main-commit tag, the required exact-SHA CI, an explicit
asset allowlist, checksum-manifest coverage, provider asset inventory readback,
downloaded SHA-256 verification, release-identity provenance, and installer
lifecycle verification. No release artifact is claimed to be cryptographically
signed unless a separate, verifiable signature and trust chain are published.
35 changes: 35 additions & 0 deletions THIRD_PARTY_NOTICES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Third-Party Notices

ArcheAxis OS / Cognitive-Loop-OS is licensed under the MIT License; see
[`LICENSE`](LICENSE). That license does not replace the licenses of third-party
packages, bundled binaries, fonts, or other components.

## Declared direct Python dependencies

The release dependency contract is `pyproject.toml` plus the exact resolved
`uv.lock`. At version 0.4.1 the direct runtime declarations are:

`fastapi`, `python-multipart`, `uvicorn`, `pydantic`, `numpy`, `requests`,
`pyyaml`, `beautifulsoup4`, `defusedxml`, `apscheduler`, `sqlite-vec`, `loguru`,
`structlog`, `markitdown`, `trafilatura`, `networkx`, `litellm`, `pillow`, and
`pytesseract`.

Optional or development groups additionally declare `setuptools`,
`playwright`, `httpx2`, `jinja2`, `jsonschema`, `pytest`, `ruff`, `tomli`,
`newspaper4k`, `readabilipy`, `youtube-transcript-api`, `mypy`, `pre-commit`,
`crawl4ai`, `langfuse`, and `promptfoo`. The desktop dependency contract is
`desktop/package.json`, `desktop/package-lock.json`, `desktop/src-tauri/Cargo.toml`,
and `desktop/src-tauri/Cargo.lock`.

The lockfiles, not this summary, are authoritative for exact names, versions,
and transitive packages. Each component remains subject to its own upstream
license and notices. A redistributor must preserve those terms and audit the
exact built artifact; this document does not claim that every optional package
is bundled into every distribution.

## External tools

Some development or verification paths can invoke separately installed tools
such as Git, GitHub CLI, Tesseract OCR, Node.js/npm, Rust/Cargo, and NSIS. They
are not relicensed by this repository. Their presence in a build log is not
proof that they are included in a published asset.
6 changes: 3 additions & 3 deletions app/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ async def core_runtime_lifespan(_: FastAPI):
app = FastAPI(
lifespan=core_runtime_lifespan,
title="Cognitive-Loop-OS",
version=str(config.get("app.version", "0.4.0")),
version=str(config.get("app.version", "0.4.1")),
description="AI cognitive runtime with an integrated Knowledge-Base. "
"Absorbs Obsidian, Tana, Notion, Logseq, Roam, Heptabase, GraphRAG, Zettelkasten.",
docs_url="/docs",
Expand Down Expand Up @@ -362,7 +362,7 @@ def health():
return {
"status": "ok",
"system": "cognitive-loop-os",
"version": str(config.get("app.version", "0.4.0")),
"version": str(config.get("app.version", "0.4.1")),
"endpoints": _http_route_counts(),
"stats": {
"documents": _c("kb_documents"),
Expand Down Expand Up @@ -649,7 +649,7 @@ def architecture():
Auth-->Router; Router-->Pipeline; Pipeline-->Search; Pipeline-->Garden
Search-->SQLite; Search-->VecDB; Garden-->GraphDB; Review-->SQLite; SQLite-->Backup
```""",
"version": str(config.get("app.version", "0.4.0")),
"version": str(config.get("app.version", "0.4.1")),
"measurement_note": "Module and test counts are intentionally not embedded.",
}

Expand Down
4 changes: 2 additions & 2 deletions app/release-manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"english_name": "ArcheAxis OS",
"workspace_name": "元枢·观心",
"workspace_english_name": "ArcheAxis Cognitive Workspace",
"version": "0.4.0",
"version": "0.4.1",
"requires_python": ">=3.11"
},
"release": {
Expand All @@ -23,7 +23,7 @@
"dependency_lock": {
"path": "uv.lock",
"algorithm": "sha256",
"digest": "59051acb00c9824e4c76d5ea1a69eb701d029565687b68dd683d50d2788a589c",
"digest": "10304d747de08eaefd2a6972ad0191bdc24c1ead3d42c3ca644194daeb4421c3",
"format_version": 1,
"revision": 3
},
Expand Down
2 changes: 1 addition & 1 deletion config/defaults.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Public, non-secret baseline for every runtime profile.
app:
name: "Cognitive-Loop-OS"
version: "0.4.0"
version: "0.4.1"
environment: "development"
port: 8000
host: "127.0.0.1"
Expand Down
2 changes: 1 addition & 1 deletion config/settings.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

app:
name: "Cognitive-Loop-OS"
version: "0.4.0"
version: "0.4.1"
release_version: ""
environment: "development"
port: 8000
Expand Down
4 changes: 2 additions & 2 deletions desktop/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion desktop/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "archeaxis-desktop-shell",
"private": true,
"version": "0.4.0",
"version": "0.4.1",
"scripts": {
"tauri": "tauri"
},
Expand Down
4 changes: 2 additions & 2 deletions desktop/scripts/verify_nsis_install.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -93,14 +93,14 @@ try {
$base = "http://127.0.0.1:$($normal.Listener.LocalPort)"
$workspaceStatus = (Invoke-WebRequest "$base/workspace" -UseBasicParsing).StatusCode
$status = Invoke-RestMethod "$base/workspace/api/status"
if ($workspaceStatus -ne 200 -or $status.release.version -ne '0.4.0') {
if ($workspaceStatus -ne 200 -or $status.release.version -ne '0.4.1') {
throw 'installed Workspace returned an invalid product response'
}
if ($RequireReleaseIdentity) {
$version = Invoke-RestMethod "$base/version"
if (
$version.release.status -ne 'released' -or
$version.release.tag -ne 'v0.4.0' -or
$version.release.tag -ne 'v0.4.1' -or
$version.capabilities.public_installer -ne 'available'
) {
throw 'installed runtime did not expose the verified public release identity'
Expand Down
2 changes: 1 addition & 1 deletion desktop/src-tauri/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion desktop/src-tauri/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "archeaxis-desktop-shell"
version = "0.4.0"
version = "0.4.1"
edition = "2024"
rust-version = "1.88"

Expand Down
2 changes: 1 addition & 1 deletion desktop/src-tauri/tauri.conf.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"$schema": "https://schema.tauri.app/config/2",
"productName": "ArcheAxis OS",
"version": "0.4.0",
"version": "0.4.1",
"identifier": "com.archeaxis.cognitive-workspace",
"build": {
"frontendDist": "../bootstrap"
Expand Down
Loading
Loading