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
343 changes: 302 additions & 41 deletions .github/workflows/theme_momentum_snapshot.yml

Large diffs are not rendered by default.

60 changes: 60 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,66 @@ python -m pip install -e .
python -m pytest -q
```

## Theme snapshot workflow and draft PR boundary

`.github/workflows/theme_momentum_snapshot.yml` normally builds
`data/output/theme_momentum_snapshot.json` and retains it as an Actions artifact.
The weekly schedule is artifact-only. The legacy `commit_outputs` input is
**deprecated and ignored**; it never pushes to `main` or authorizes a PR.

The source includes a restricted, **production-disabled** draft publisher:

- `identity_only=true` is the existing manual-main identity diagnostic. It does
not collect, generate, or publish data. Combining it with `publish_draft_pr=true`
fails before any token mint or generation.
- `publish_draft_pr` is a manual boolean, default `false`. Even `true` is not
content authorization: `PUBLICATION_CONTENT_APPROVED = False` in
`scripts/publish_theme_snapshot_pr.py` blocks publication requests immediately
after checkout, before installation, collection, generation, or production mint.
- Enabling a future run requires explicit approval of the source/provider and
derived-data publication scope, a reviewed source-policy change, and the
explicit manual-main flag. Publicly readable input, repository MIT licensing,
and an App installation do not establish redistribution rights. No scheduled
publication is authorized by this implementation.

Normal generation preserves `as_of`, optional `prices_path`, and
`strict_downloads`. Publication policy separately constrains eligible inputs;
operator-supplied CSVs do not receive implied publication approval. The only
future data-PR path is `data/output/theme_momentum_snapshot.json`; raw prices,
AI signal/manifest pairs, history, configuration, and all other files are excluded.

The build job records the actual generation interval, prepares an exact JSON plus
`publication-package.json` receipt, and passes artifact ID/digest and both raw
SHA-256 hashes through same-run job outputs. The isolated publisher checks out
the fixed run SHA with credentials persistence disabled, downloads only that
current-run artifact ID into runner temporary storage, and validates the package,
source/config/run provenance, content policy, and unchanged expected `main` before
minting a production token. It does not install or execute artifact content.

`GITHUB_TOKEN` has only `contents: read`; there is no Actions read permission or
cross-run retrieval. The dedicated App token requests only Contents and Pull
requests write for this repository and is revoked by the official action's
normal post step. The diagnostic token remains isolated to the identity-only
branch; the production token is passed only to the restricted publish helper.
All workflow action dependencies are pinned to full commit SHAs.

Future writes use a run-bound immutable branch, a single-parent/single-file
commit, and a draft PR. Exact existing drafts may be reused; moved `main`, changed
branches, and closed/merged/non-draft PRs fail closed. There is no force-push,
`main` write, automatic merge, protection bypass, old App fallback, or silent
success after remote failure. Sanitized receipts distinguish artifact generation,
package readiness, draft creation, and failure. A created draft still reports
`published=false`: human review and merge are still required.

Local source/mock validation (no provider calls, App mint, dispatch, or data PR):

```bash
python -m pip install -e '.[test]'
python -m pytest -q tests/test_theme_momentum_snapshot_workflow.py tests/test_publish_theme_snapshot_pr.py
python -m pytest -q
git diff --check
```

## Useful docs

- [`docs/architecture.md`](docs/architecture.md)
Expand Down
49 changes: 49 additions & 0 deletions README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,55 @@ python -m pip install -e .
python -m pytest -q
```

## 主题快照 workflow 与草稿 PR 边界

`.github/workflows/theme_momentum_snapshot.yml` 默认生成
`data/output/theme_momentum_snapshot.json` 并保留为 Actions artifact。
每周定时任务仅生成 artifact。旧 `commit_outputs` 输入已**弃用且忽略**,
不会向 `main` 推送,也不代表 PR 发布授权。

源码包含受限且**尚未启用生产发布**的草稿 publisher:

- `identity_only=true` 保留现有的手动 main 身份诊断,不采集、生成或发布数据。
若同时设置 `publish_draft_pr=true`,在任何 token mint 或生成前拒绝。
- `publish_draft_pr` 是默认 `false` 的手动布尔输入。设为 `true` 仍不构成内容授权:
`scripts/publish_theme_snapshot_pr.py` 中的 `PUBLICATION_CONTENT_APPROVED = False`
会在 checkout 后立即阻止发布请求,早于安装、采集、生成和生产 token mint。
- 未来真实运行需要明确批准来源/provider 及派生数据的公开范围,经源码 review
修改内容政策,并显式开启手动 main 发布开关。公开可读取、仓库 MIT 许可证和 App
安装均不证明再分发权利。本实现不授权定时发布。

普通生成保留 `as_of`、可选 `prices_path` 和 `strict_downloads` 的原有行为。
发布政策另行约束允许的输入;用户提供 CSV 不代表获得公开许可。未来数据 PR
唯一允许的路径为 `data/output/theme_momentum_snapshot.json`,不包括原始价格、
AI signal/manifest pair、history、配置或任何其他文件。

build job 记录真实生成起止时间,准备精确 JSON 与 `publication-package.json`
回执,通过同 run 的 job outputs 传递 artifact ID/digest 和两个原始文件 SHA-256。
隔离 publisher checkout 当前 run 的固定 SHA,关闭凭据持久化,仅按该 run 的
artifact ID 下载到 runner 临时目录;在生产 mint 前验证 package、源码/配置/run
绑定、内容政策及 `main` 是否仍是预期基线。不会安装或执行 artifact 中的代码。

`GITHUB_TOKEN` 仅有 `contents: read`,没有 Actions read 权限或跨 run 检索。
专用 App token 仅申请本仓 Contents 与 Pull requests write,并由官方 action
默认 post step 撤销。诊断 token 只用于 identity-only 分支,生产 token 只传给
受限 publish helper。所有 workflow action 依赖均固定为完整 commit SHA。

未来写入使用绑定 run 的不可变分支、单 parent/单文件 commit 和草稿 PR。
完全匹配的现有草稿可复用;`main` 前进、分支被修改、PR 已关闭/合并/转为非草稿时
拒绝继续。没有 force-push、直接写 `main`、自动 merge、绕过保护、旧 App 回退,
也不会把远端失败静默当作成功。脱敏回执分别记录 artifact 生成、package 就绪、
草稿创建或失败;`published=false` 表明仍需人工审阅和合并。

本地源码/mock 验证,不调用 provider、不 mint、不 dispatch、不创建数据 PR:

```bash
python -m pip install -e '.[test]'
python -m pytest -q tests/test_theme_momentum_snapshot_workflow.py tests/test_publish_theme_snapshot_pr.py
python -m pytest -q
git diff --check
```

## 延伸文档

- [`docs/architecture.md`](docs/architecture.md)
Expand Down
13 changes: 11 additions & 2 deletions docs/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,17 @@ pipeline without changing that production boundary.

This repository is deliberately narrower than `AIAuditBridge`. It owns
research inputs, validation, saved artifacts, and replay harnesses. It does not
own model provider routing, API keys, GitHub App write orchestration, live
notifications, or execution behavior.
own model provider routing, API keys, cross-repository GitHub App write
orchestration, live notifications, or execution behavior.

A limited same-repository exception is the source-only, production-disabled
publisher for `data/output/theme_momentum_snapshot.json`. It can only transport
that exact file through a run-bound draft PR using the dedicated single-repository
App; it never writes `main`, merges, bypasses protection, or handles AI signal
pairs or other files. Content/source rights require explicit approval and a
reviewed source-policy change before a manual-main publication request can pass.
The schedule remains artifact-only. See the [English workflow boundary](../README.md#theme-snapshot-workflow-and-draft-pr-boundary)
and [中文说明](../README.zh-CN.md#主题快照-workflow-与草稿-pr-边界).

## Main Design Pressure

Expand Down
Loading
Loading