diff --git a/.gitmodules b/.gitmodules
index 9fec85b..8407e81 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -4,3 +4,7 @@
[submodule "supertensor"]
path = supertensor
url = ssh://git@ssh.gitea.mygoband.com:2222/carrydela/SuperTensor.git
+
+[submodule "superderive"]
+ path = superderive
+ url = ssh://git@ssh.gitea.mygoband.com:2222/carrydela/SuperDerive.git
diff --git a/README.md b/README.md
index 2998867..69fb022 100644
--- a/README.md
+++ b/README.md
@@ -10,14 +10,14 @@ superpaper/ this repo (orchestration)
├── SKILL.md document-layer skill
├── superfig/ submodule — architecture / pipeline / flow
├── supertensor/ submodule — tensor faces / axes / shards
-└── superderive/ later — stepwise rewrite figures
+└── superderive/ submodule — stepwise rewrite figures
```
| 子仓库 | 画什么 | 远程 |
|---|---|---|
| [`superfig`](superfig/) | 节点、边、分组、机制框图 | `carrydela/SuperFig` |
| [`supertensor`](supertensor/) | 形状对齐的张量公式图 | `carrydela/SuperTensor` |
-| `superderive` | 逐步代数改写图 | 尚未建 |
+| [`superderive`](superderive/) | 逐步代数改写图 | `carrydela/SuperDerive` |
## Clone
@@ -41,13 +41,14 @@ symlinks into this repo:
skills/superpaper/ SuperPaper
skills/superfig -> superpaper/superfig
skills/supertensor -> superpaper/supertensor
+skills/superderive -> superpaper/superderive
```
## Status
-v1 notes scaffold is in this repo: ledger schema, router, lint, ingest,
-and three `--work` examples (`excerpt-toy`, `pipeline-delegate`,
-`tensor-delegate`). `superderive` is still phase 2.
+v1 notes scaffold plus v2 `superderive` (phase default 2). Examples:
+`excerpt-toy` (`align`), `pipeline-delegate`, `tensor-delegate`,
+`derive-delegate`.
```bash
python3 -m venv .venv && .venv/bin/pip install -r requirements.txt
diff --git a/SKILL.md b/SKILL.md
index 685f3cc..fa94a46 100644
--- a/SKILL.md
+++ b/SKILL.md
@@ -35,7 +35,7 @@ video.
|---|---|---|
| 架构 / 流水线 / 数据流 / 状态 / 依赖 / 谁吃谁 | `superfig` | `superfig/SKILL.md` |
| 轴、形状、转置、broadcast、gather、分片、收缩 | `supertensor` | `supertensor/SKILL.md` |
-| 必须被看见的逐步改写 | v1:笔记 `align`;v2:`superderive` | — |
+| 必须被看见的逐步改写 | `superderive`(≤4 步且无 cancel/subst 仍用 `align`) | `superderive/SKILL.md` |
| 数值曲线 / 柱状 / 散点 | screenshot 或 matplotlib | 本家族不画 |
| 表 / 照片 / 装置 / UI | screenshot | — |
diff --git a/examples/derive-delegate/ledger.yaml b/examples/derive-delegate/ledger.yaml
new file mode 100644
index 0000000..a6a6e6b
--- /dev/null
+++ b/examples/derive-delegate/ledger.yaml
@@ -0,0 +1,46 @@
+schema: superpaper.ledger/v1
+retired_ids: []
+paper:
+ id: derive-delegate
+ title: Scaled attention
+ authors: ["Fixture"]
+ notes_language: zh
+ source: {kind: excerpt}
+coverage:
+ mode: excerpt
+questions:
+ - {id: Q1, text: "缩放从哪来?", source: "excerpt"}
+claims:
+ - id: C1
+ text: "1/√d_k 是改写,不是新算子"
+ kind: theoretical
+ status: core
+ supports: [Q1]
+definitions: []
+assumptions: []
+lemmas: []
+symbols:
+ - {name: Q, latex: "Q", meaning: "query", kind: value}
+ - {name: K, latex: "K", meaning: "key", kind: value}
+ - {name: dk, latex: "d_k", meaning: "key 维", kind: "shape parameter"}
+derivations:
+ - id: DER1
+ claim: C1
+ title: "缩放"
+ expand: true
+ figure: F3
+ steps:
+ - {id: S1, from: "QK^{\\top}", to: "QK^{\\top}/\\sqrt{d_k}", rule: scale}
+figures:
+ - id: F3
+ claim: C1
+ title: "缩放来自方差"
+ grammar: derivation
+ toolkit: superderive
+ signals: [rewrite-figure]
+ request: figures/F3/F3.request.md
+ include: figures/F3/build/F3.pdf
+ status: included
+evidence: []
+terms: []
+source_assets: []
diff --git a/examples/derive-delegate/notes/figures/F3/F3-mechanism.md b/examples/derive-delegate/notes/figures/F3/F3-mechanism.md
new file mode 100644
index 0000000..7d2989d
--- /dev/null
+++ b/examples/derive-delegate/notes/figures/F3/F3-mechanism.md
@@ -0,0 +1 @@
+$QK^\top \to QK^\top/\sqrt{d_k}$。缩放压方差,避免 softmax 饱和。
diff --git a/examples/derive-delegate/notes/figures/F3/F3.request.md b/examples/derive-delegate/notes/figures/F3/F3.request.md
new file mode 100644
index 0000000..fe7e184
--- /dev/null
+++ b/examples/derive-delegate/notes/figures/F3/F3.request.md
@@ -0,0 +1,14 @@
+# Figure request F3
+toolkit: superderive
+language: cjk
+claim: 1/√d_k 是改写,不是新算子
+grammar: derivation
+work_rel_dir: figures/F3
+
+## Flow
+stage: {name: D1, text: "缩放来自方差,不是装饰"}
+row: {name: R1}
+in_row:
+ - {macro: sdstep, name: s1, role: rewrite,
+ lhs: "QK^{\\top}", rhs: "QK^{\\top}/\\sqrt{d_k}"}
+ - {macro: sdreason, name: s1, text: "§3.2.1,避免 softmax 饱和"}
diff --git a/examples/derive-delegate/notes/figures/F3/F3.tex b/examples/derive-delegate/notes/figures/F3/F3.tex
new file mode 100644
index 0000000..2f5c551
--- /dev/null
+++ b/examples/derive-delegate/notes/figures/F3/F3.tex
@@ -0,0 +1,20 @@
+% Golden example -- a scale rewrite that must be seen, not just aligned.
+% ../scripts/build.sh rewrite-cancel.tex
+\documentclass[border=10pt]{standalone}
+\usepackage[cjk]{superderive}
+
+\begin{document}
+\begin{tikzpicture}
+\sdstage{D1}{缩放来自方差,不是装饰}
+\sdrow{R1}
+ \sdstep[role=rewrite]{s1}{QK^{\top}}{QK^{\top}/\sqrt{d_k}}
+ \sdreason{s1}{§3.2.1,避免 softmax 饱和}
+\sdrowend
+\sdbbox{all}
+\sdtopformula{F}{$\mathrm{Attention}(Q,K,V)=\mathrm{softmax}(QK^{\top}/\sqrt{d_k})V$}
+\sdmeaningbox{mb}{120mm}{all}
+ {点积方差随 $d_k$ 线性涨}
+ {缩放是改写,不是新算子}
+ {没有缩放,softmax 进饱和区,梯度消失}
+\end{tikzpicture}
+\end{document}
diff --git a/examples/derive-delegate/notes/figures/F3/build/F3-alpha.png b/examples/derive-delegate/notes/figures/F3/build/F3-alpha.png
new file mode 100644
index 0000000..e367a59
Binary files /dev/null and b/examples/derive-delegate/notes/figures/F3/build/F3-alpha.png differ
diff --git a/examples/derive-delegate/notes/figures/F3/build/F3-thumb.png b/examples/derive-delegate/notes/figures/F3/build/F3-thumb.png
new file mode 100644
index 0000000..249d402
Binary files /dev/null and b/examples/derive-delegate/notes/figures/F3/build/F3-thumb.png differ
diff --git a/examples/derive-delegate/notes/figures/F3/build/F3.pdf b/examples/derive-delegate/notes/figures/F3/build/F3.pdf
new file mode 100644
index 0000000..d1a4e30
Binary files /dev/null and b/examples/derive-delegate/notes/figures/F3/build/F3.pdf differ
diff --git a/examples/derive-delegate/notes/figures/F3/build/F3.png b/examples/derive-delegate/notes/figures/F3/build/F3.png
new file mode 100644
index 0000000..39d5088
Binary files /dev/null and b/examples/derive-delegate/notes/figures/F3/build/F3.png differ
diff --git a/examples/derive-delegate/notes/figures/F3/build/F3.svg b/examples/derive-delegate/notes/figures/F3/build/F3.svg
new file mode 100644
index 0000000..42f3f62
--- /dev/null
+++ b/examples/derive-delegate/notes/figures/F3/build/F3.svg
@@ -0,0 +1,517 @@
+
+
diff --git a/examples/derive-delegate/notes/notes.tex b/examples/derive-delegate/notes/notes.tex
new file mode 100644
index 0000000..e910f80
--- /dev/null
+++ b/examples/derive-delegate/notes/notes.tex
@@ -0,0 +1,14 @@
+\documentclass[a4paper]{article}
+\input{notes-macros}
+\renewcommand{\notetitle}{缩放来自方差}
+\renewcommand{\notepaper}{Scaled attention}
+\begin{document}
+\tableofcontents
+\newpage
+\input{sections/sec-01.tex}
+\input{sections/sec-02.tex}
+\input{sections/sec-03.tex}
+\appendix
+\section{符号表}
+\input{sections/symbols.tex}
+\end{document}
diff --git a/examples/derive-delegate/notes/sections/sec-01.tex b/examples/derive-delegate/notes/sections/sec-01.tex
new file mode 100644
index 0000000..1345846
--- /dev/null
+++ b/examples/derive-delegate/notes/sections/sec-01.tex
@@ -0,0 +1,2 @@
+\section{这篇论文在问什么}
+注意力里的 $1/\sqrt{d_k}$ 是装饰,还是一次必须看见的改写?
diff --git a/examples/derive-delegate/notes/sections/sec-02.tex b/examples/derive-delegate/notes/sections/sec-02.tex
new file mode 100644
index 0000000..0b623b7
--- /dev/null
+++ b/examples/derive-delegate/notes/sections/sec-02.tex
@@ -0,0 +1,8 @@
+\section{主张与贡献}
+\splabel{C1}
+点积方差随 $d_k$ 涨。除掉 $\sqrt{d_k}$ 是改写,不是新算子。
+
+\spfig{F3}{缩放来自方差。}{fixture;toolkit: \texttt{superderive};ledger id: F3。}
+
+\subsection{本章小结}
+这一步必须被看见,所以走 superderive,而不是笔记里的 \texttt{align}。
diff --git a/examples/derive-delegate/notes/sections/sec-03.tex b/examples/derive-delegate/notes/sections/sec-03.tex
new file mode 100644
index 0000000..a1f226b
--- /dev/null
+++ b/examples/derive-delegate/notes/sections/sec-03.tex
@@ -0,0 +1,2 @@
+\section{总结与延伸}
+四步以内、没有消项或代入要画出来时,仍然用 \texttt{align}。
diff --git a/examples/derive-delegate/outline.md b/examples/derive-delegate/outline.md
new file mode 100644
index 0000000..2ce96f5
--- /dev/null
+++ b/examples/derive-delegate/outline.md
@@ -0,0 +1,14 @@
+# Outline: Scaled attention
+
+## Lecture map
+
+| file | lecture_title | paper_sections | ledger_ids |
+|---|---|---|---|
+| sec-01.tex | 这篇论文在问什么 | 1 | Q1 |
+| sec-02.tex | 主张与贡献 | 1 | C1, F3 |
+| sec-03.tex | 总结与延伸 | 1 | C1 |
+| sec-app-a.tex | 符号表 | — | |
+
+## Locked
+- 首节标题必须是「这篇论文在问什么」
+- 末节(appendix 前)必须是「总结与延伸」
diff --git a/references/figure-request.md b/references/figure-request.md
index ba20b10..b2d4278 100644
--- a/references/figure-request.md
+++ b/references/figure-request.md
@@ -4,6 +4,8 @@ Sibling figure agents see only `notes/figures/F*/F*.request.md` plus that siblin
- superfig: `\sfnode` keys `role, level, gap, bracket, at=`. `\sfconn` has no endpoints. `at` must be TikZ calc with `($…$)`.
- supertensor: every `ststack` / `stface` / `stglyph` has `coord: ""`.
+- superderive: `\sdstep` / `\sdreason` / `\sdcancel` / `\sdsubst`; one `\sdcol` max.
+
- `allow-raw-tikz` must also appear as `% superfig-lint: allow-raw-tikz` in the `.tex`.
- Build: `superfig/scripts/build.sh F1.tex F1/build` (second arg is the outdir).
- Screenshots: `scripts/screenshot.sh --work --id F2` (`pdftoppm -r 200`, then optional `crop_bbox`).
diff --git a/references/router.md b/references/router.md
index 7747568..efb15e9 100644
--- a/references/router.md
+++ b/references/router.md
@@ -8,7 +8,7 @@ Authority: `scripts/router.py`. `suggest()` returns a **class**, not a toolkit.
| `raster` | table, photo, apparatus, ui | screenshot |
| `tensor` | axis, shape, transpose, broadcast, gather, shard, contraction, face | supertensor |
| `fig` | architecture, pipeline, data-flow, state, time, dependency, what-eats-what, argument-map | superfig |
-| `derive` | rewrite-figure, cancel-visual, subst-visual | v1: align |
+| `derive` | rewrite-figure, cancel-visual, subst-visual | align, superderive (phase ≥ 2) |
| `none` | otherwise | none |
Mixed classes on one row → `SP011`. Split with the next integer ids. Default: do not draw.
diff --git a/scripts/lint.py b/scripts/lint.py
index 406ae14..c0784a9 100755
--- a/scripts/lint.py
+++ b/scripts/lint.py
@@ -171,7 +171,7 @@ def lint(
if code:
errors.append(f"{code} {fid}")
if toolkit == "superderive" and phase < 2:
- errors.append(f"SP022 {fid} toolkit superderive is v2; use align")
+ errors.append(f"SP022 {fid} toolkit superderive is off; set SUPERPAPER_PHASE=2 or use align")
if toolkit in SIBLING and status != "dropped" and disk:
req = fig.get("request")
req_path = (work / "notes" / req) if (work and req) else None
diff --git a/scripts/router.py b/scripts/router.py
index e33495d..b9a20b1 100755
--- a/scripts/router.py
+++ b/scripts/router.py
@@ -93,8 +93,8 @@ def check_row(
def phase_from_env() -> int:
import os
- raw = os.environ.get("SUPERPAPER_PHASE", "1")
+ raw = os.environ.get("SUPERPAPER_PHASE", "2")
try:
return int(raw)
except ValueError:
- return 1
+ return 2
diff --git a/scripts/test.sh b/scripts/test.sh
index 8c47b1c..8a6674d 100755
--- a/scripts/test.sh
+++ b/scripts/test.sh
@@ -42,7 +42,6 @@ for spec in \
"align-has-include.yaml:SP014" \
"included-null-include.yaml:SP015" \
"screenshot-bad-include.yaml:SP016" \
- "superderive-v1.yaml:SP022" \
"retired-reuse.yaml:SP023" \
"dangling-claim.yaml:SP024"
do
@@ -73,7 +72,8 @@ for dir in \
"$ROOT/tests/notes-smoke" \
"$ROOT/examples/excerpt-toy" \
"$ROOT/examples/pipeline-delegate" \
- "$ROOT/examples/tensor-delegate"
+ "$ROOT/examples/tensor-delegate" \
+ "$ROOT/examples/derive-delegate"
do
name="$(basename "$dir")"
if "$ROOT/scripts/build.sh" --work "$dir" >/dev/null 2>&1; then
diff --git a/superderive b/superderive
new file mode 160000
index 0000000..9f635d3
--- /dev/null
+++ b/superderive
@@ -0,0 +1 @@
+Subproject commit 9f635d358b694c8bafda960a8d495e96f220cda5
diff --git a/tests/router_test.py b/tests/router_test.py
index 203250c..9c45f67 100755
--- a/tests/router_test.py
+++ b/tests/router_test.py
@@ -22,6 +22,7 @@ expect(
)
expect(check_row({"rewrite-figure"}, "align", phase=1) is None, "align ok")
expect(check_row({"rewrite-figure"}, "superderive", phase=1) == "SP010", "derive v1")
+expect(check_row({"rewrite-figure"}, "superderive", phase=2) is None, "derive v2")
expect(suggest(set()) == "none", "empty")
expect(suggest({"notation"}) == "none", "notation")
expect(check_row(set(), "none", status="included") == "SP013", "none included")