track: 新增 OpenWork / Orca / Maka 三项目,样本达到 4 个

样本
- openwork (different-ai/openwork) 23.2k★ 能力分发层,DCO + evals + worlds
- orca (stablyai/orca) 58.8k★ 并行编排外壳,5000 issue 实为团队自开任务板
- maka (apache/maka) 4.4k★ 执行记录层,Apache 孵化但无正式 release

档案
- 三份五维档案填完,risk.claim_vs_reality 均已核实到证据
- ipollowork 象限坐标从占位 9/9/9/9 校准为 8/7/7/7(与新样本同一标尺)

文章
- 新增横评文《四个 Agent 工作台的路线分野:把「多引擎中立」拆开看》(emlog id=99)
- 总纲文回填四项目矩阵 + 双视图象限图 (emlog id=98)

镜像
- gitinbox/maka 已推送(public,source-only 快照 12 MB)
- openwork(291MB) / orca(671MB) 受 50KB/s 带宽约束,档案标 mode: pending

规则
- license-tiers.yaml 新增「目录切分许可」降级流程(OpenWork 判例:
  排除 ee/ 后为纯 MIT → public,完整镜像 → private)
- registry.yaml openwork 可见性改 public + mirror_excludes: ["ee/"]

脚本修复
- _common.py 新增 upsert_block:手工整块覆盖 ecosystem 删掉 metrics 时能自愈
- mirror_sync.sh:SOURCE_ONLY 未初始化(set -u 下偶发炸);
  浅仓推送被服务端拒绝 → 自动 --unshallow,失败降级快照;
  量体积前先 repack(此前新 commit 全是 loose object,恒打印 0 MB)
- build_matrix.py:成熟度长文本移出表格(新增 maturity_level 短标签);
  象限图标签靠右时翻转到左侧防溢出;SVG 加 max-width 防窄屏溢出;
  文章索引改为自动生成(原先手抄,横评文发了索引里却没有)
- publish_emlog.py:ID 回写按「有无同名档案」分流,
  00-* 跨项目文章落到 articles/<id>.meta.yaml(此前 ID 无处可写)
This commit is contained in:
gitea-publish
2026-09-01 19:27:21 +08:00
parent 78b87e8b2f
commit e5cdb1801e
18 changed files with 1771 additions and 114 deletions
+210 -51
View File
@@ -16,29 +16,35 @@ DISPLAY_URL="${GITEA_DISPLAY_URL:-https://gitea.apescale.com}"
ORG="${GITEA_ORG:-gitinbox}"
ID=""
DEPTH=""
# auto = 体积超限时自动降级为源码快照;no = 始终尝试完整镜像(超限会 413 失败)。
# 这两个变量必须在 set -u 之前就有值:下面体积闸门的条件里会引用它们,
# 而这个分支只在特定体积下才走到——不初始化就成了「偶尔才炸」的雷。
SOURCE_ONLY="auto"
SOURCE_ONLY_FORCE="no"
while [[ $# -gt 0 ]]; do
case "$1" in
--id) ID="$2"; shift 2;;
--org) ORG="$2"; shift 2;;
--url) GITEA_URL="$2"; shift 2;;
--depth) DEPTH="$2"; shift 2;;
--id) ID="$2"; shift 2;;
--org) ORG="$2"; shift 2;;
--url) GITEA_URL="$2"; shift 2;;
--depth) DEPTH="$2"; shift 2;;
--no-source-only) SOURCE_ONLY="no"; shift;;
*) echo "未知参数: $1" >&2; exit 1;;
esac
done
[[ -z "$ID" ]] && { echo "缺少 --id" >&2; exit 1; }
YAML="$ROOT/data/projects/$ID.yaml"
[[ -f "$YAML" ]] || { echo "档案不存在: $YAML" >&2; exit 1; }
[[ -z "${ID}" ]] && { echo "缺少 --id" >&2; exit 1; }
YAML="${ROOT}/data/projects/${ID}.yaml"
[[ -f "${YAML}" ]] || { echo "档案不存在: ${YAML}" >&2; exit 1; }
# ---- 从档案读取镜像配置(bash 不适合解析 YAML,借用 python 输出 shell 赋值) ----
# 用"写临时文件再 source"而不是 eval "$(...)":
# eval 会二次解析内容,YAML 里的括号/引号一旦漏转义就会变成难定位的
# syntax error,而且报错行号会偏移到完全无关的位置。
CONF_FILE="$(mktemp)"
trap 'rm -f "$CONF_FILE"' EXIT
trap 'rm -f "${CONF_FILE}"' EXIT
/Users/figmarlite/.workbuddy/binaries/python/envs/default/bin/python - "$YAML" > "$CONF_FILE" <<'PY'
/Users/figmarlite/.workbuddy/binaries/python/envs/default/bin/python - "${YAML}" > "${CONF_FILE}" <<'PY'
import sys, shlex
from pathlib import Path
sys.path.insert(0, str(Path(sys.argv[1]).resolve().parent.parent.parent / "scripts"))
@@ -56,81 +62,233 @@ print(f"LIC_NAME={shlex.quote(str(lic.get('name') or ''))}")
PY
# shellcheck disable=SC1090
source "$CONF_FILE"
source "${CONF_FILE}"
[[ -z "$UPSTREAM" ]] && { echo "档案缺少 mirror.upstream" >&2; exit 1; }
[[ -z "${UPSTREAM}" ]] && { echo "档案缺少 mirror.upstream" >&2; exit 1; }
echo "==> 镜像 $ID"
echo " 上游 : $UPSTREAM"
echo " 目标 : $ORG/$REPO_NAME"
echo " 许可证 : $LIC_LEVEL ($LIC_NAME)"
echo " 可见性 : $VISIBILITY"
if [[ "$VISIBILITY" == "private" ]]; then
echo "==> 镜像 ${ID}"
echo " 上游 : ${UPSTREAM}"
echo " 目标 : ${ORG}/${REPO_NAME}"
echo " 许可证 : ${LIC_LEVEL} (${LIC_NAME})"
echo " 可见性 : ${VISIBILITY}"
if [[ "${VISIBILITY}" == "private" ]]; then
echo " ⚠ L3 级 source-available,已强制私有。公开镜像可能构成未经授权的分发。"
fi
# ---- 凭据:优先环境变量,回退到 macOS 钥匙串 ----
if [[ -z "${GITEA_TOKEN:-}" ]]; then
CRED="$(printf "host=%s\nprotocol=https\n" "${DISPLAY_URL#*://}" | git credential-osxkeychain get 2>/dev/null || true)"
GITEA_USER="${GITEA_USER:-$(printf '%s' "$CRED" | sed -n 's/^username=//p')}"
GITEA_TOKEN="$(printf '%s' "$CRED" | sed -n 's/^password=//p')"
GITEA_USER="${GITEA_USER:-$(printf '%s' "${CRED}" | sed -n 's/^username=//p')}"
GITEA_TOKEN="$(printf '%s' "${CRED}" | sed -n 's/^password=//p')"
fi
[[ -z "${GITEA_TOKEN:-}" || -z "${GITEA_USER:-}" ]] && {
echo "未拿到 Gitea 凭据(设 GITEA_TOKEN/GITEA_USER,或存入钥匙串)" >&2; exit 1; }
# ---- 确保目标仓库存在(组织端点,不是 /user/repos) ----
API="$GITEA_URL/api/v1"
HTTP="$(curl -sS -o /dev/null -w '%{http_code}' -u "$GITEA_USER:$GITEA_TOKEN" "$API/repos/$ORG/$REPO_NAME" || echo 000)"
if [[ "$HTTP" == "200" ]]; then
API="${GITEA_URL}/api/v1"
HTTP="$(curl -sS -o /dev/null -w '%{http_code}' -u "${GITEA_USER}:${GITEA_TOKEN}" "${API}/repos/${ORG}/${REPO_NAME}" || echo 000)"
if [[ "${HTTP}" == "200" ]]; then
echo " 仓库已存在"
elif [[ "$HTTP" == "404" ]]; then
echo " 创建仓库 $ORG/$REPO_NAME (private=$([[ $VISIBILITY == private ]] && echo true || echo false)) ..."
CREATE="$(curl -sS -o /tmp/gitea_mirror_create.json -w '%{http_code}' -u "$GITEA_USER:$GITEA_TOKEN" \
-H 'Content-Type: application/json' -X POST "$API/org/$ORG/repos" \
-d "{\"name\":\"$REPO_NAME\",\"private\":$([[ $VISIBILITY == private ]] && echo true || echo false),\"auto_init\":false,\"description\":\"Mirror of $UPSTREAM (license: $LIC_NAME)\"}")"
[[ "$CREATE" =~ ^(200|201)$ ]] || {
echo "创建失败 (HTTP $CREATE):" >&2; cat /tmp/gitea_mirror_create.json >&2; exit 1; }
elif [[ "${HTTP}" == "404" ]]; then
echo " 创建仓库 ${ORG}/${REPO_NAME} (private=$([[ ${VISIBILITY} == private ]] && echo true || echo false)) ..."
CREATE="$(curl -sS -o /tmp/gitea_mirror_create.json -w '%{http_code}' -u "${GITEA_USER}:${GITEA_TOKEN}" \
-H 'Content-Type: application/json' -X POST "${API}/org/${ORG}/repos" \
-d "{\"name\":\"${REPO_NAME}\",\"private\":$([[ ${VISIBILITY} == private ]] && echo true || echo false),\"auto_init\":false,\"description\":\"Mirror of ${UPSTREAM} (license: ${LIC_NAME})\"}")"
[[ "${CREATE}" =~ ^(200|201)$ ]] || {
echo "创建失败 (HTTP ${CREATE}):" >&2; cat /tmp/gitea_mirror_create.json >&2; exit 1; }
echo " 已创建"
else
echo "查询仓库失败 (HTTP $HTTP)" >&2; exit 1
echo "查询仓库失败 (HTTP ${HTTP})" >&2; exit 1
fi
# 已存在的仓库若应为私有,显式修正(创建时的 private 对已存在仓库不生效)
if [[ "$VISIBILITY" == "private" ]]; then
curl -sS -o /dev/null -u "$GITEA_USER:$GITEA_TOKEN" -X PATCH \
-H 'Content-Type: application/json' -d '{"private":true}' "$API/repos/$ORG/$REPO_NAME" || true
if [[ "${VISIBILITY}" == "private" ]]; then
curl -sS -o /dev/null -u "${GITEA_USER}:${GITEA_TOKEN}" -X PATCH \
-H 'Content-Type: application/json' -d '{"private":true}' "${API}/repos/${ORG}/${REPO_NAME}" || true
fi
# ---- 同步 ----
MIRROR_DIR="$ROOT/.mirrors/$REPO_NAME.git"
mkdir -p "$ROOT/.mirrors"
MIRROR_DIR="${ROOT}/.mirrors/${REPO_NAME}.git"
mkdir -p "${ROOT}/.mirrors"
if [[ -d "$MIRROR_DIR" ]]; then
echo " 更新已有裸仓 ..."
git -C "$MIRROR_DIR" remote update --prune
else
echo " 首次全量镜像(大仓请耐心)..."
if [[ -n "$DEPTH" ]]; then
git clone --mirror --depth "$DEPTH" "$UPSTREAM" "$MIRROR_DIR"
DEEPEN_STEP="${DEEPEN_STEP:-100}"
# 注意:不能用 `rev-parse --git-dir` 判断仓库是否有效。git clone 会先建好
# 目录骨架再下载 pack,被中断的半成品照样能通过 rev-parse,于是被当成
# "已有仓库"走 fetch 分支,报出 "CONNECT tunnel failed" 这类误导性错误。
# 真正的判据是"里面有没有提交"。
repo_ok() {
[[ -d "${MIRROR_DIR}" ]] || return 1
git -C "${MIRROR_DIR}" rev-parse --git-dir >/dev/null 2>&1 || return 1
local n
n="$(git -C "${MIRROR_DIR}" rev-list --count --all 2>/dev/null || echo 0)"
[[ "${n}" -gt 0 ]]
}
is_shallow() { [[ "$(git -C "${MIRROR_DIR}" rev-parse --is-shallow-repository 2>/dev/null || echo false)" == "true" ]]; }
# clone/fetch 失败时清掉半成品,避免下次误判(脚本有 set -e,失败会直接退出)
cleanup_broken() {
if [[ -d "${MIRROR_DIR}" ]] && ! repo_ok; then
echo " 清理未完成的半成品裸仓 ..."
rm -rf "${MIRROR_DIR}"
fi
}
trap cleanup_broken EXIT
if [[ -d "${MIRROR_DIR}" ]] && ! repo_ok; then
echo " 清理上次中断的半成品裸仓 ..."
rm -rf "${MIRROR_DIR}"
fi
if repo_ok; then
if is_shallow && [[ -z "${DEPTH}" ]]; then
# 慢链路续传:分批 --deepen。每批成功即落盘,中断后重跑本脚本可继续,
# 不像 `git clone` 那样失败一次全部作废。
echo " 浅仓分批续传(每批 --deepen=${DEEPEN_STEP},中断可重跑)..."
while is_shallow; do
PRE="$(git -C "${MIRROR_DIR}" rev-list --count --all 2>/dev/null || echo 0)"
echo " 已有 ${PRE} 条历史,再加深 ${DEEPEN_STEP} ..."
if ! git -C "${MIRROR_DIR}" fetch --deepen="${DEEPEN_STEP}" origin; then
echo " ⚠ 本批中断;已落盘的 ${PRE} 条历史保留,重跑本脚本继续。"
break
fi
POST="$(git -C "${MIRROR_DIR}" rev-list --count --all 2>/dev/null || echo 0)"
[[ "${POST}" == "${PRE}" ]] && { echo " 已补齐完整历史"; break; }
done
elif is_shallow && [[ -n "${DEPTH}" ]]; then
echo " 浅仓加深到 depth=${DEPTH} ..."
git -C "${MIRROR_DIR}" fetch --depth="${DEPTH}" origin || \
echo " ⚠ 加深中断,已保留现有深度,重跑可继续"
else
git clone --mirror "$UPSTREAM" "$MIRROR_DIR"
echo " 更新已有裸仓 ..."
git -C "${MIRROR_DIR}" remote update --prune
fi
else
# 走沙箱代理时偶发 `CONNECT tunnel failed, response 502`,且 git clone
# 失败不保留已下载内容,所以首次克隆必须带重试。
CLONE_ARGS=(clone --mirror)
[[ -n "${DEPTH}" ]] && CLONE_ARGS+=(--depth "${DEPTH}")
if [[ -n "${DEPTH}" ]]; then
echo " 首次镜像(--depth ${DEPTH},只取近期历史)..."
else
echo " 首次全量镜像(大仓请耐心)..."
fi
for attempt in 1 2 3; do
if git "${CLONE_ARGS[@]}" "${UPSTREAM}" "${MIRROR_DIR}"; then
break
fi
echo " ⚠ 第 ${attempt} 次克隆失败,8s 后重试 ..."
rm -rf "${MIRROR_DIR}"
sleep 8
[[ ${attempt} -eq 3 ]] && { echo "克隆三次均失败,请检查网络/代理" >&2; exit 1; }
done
fi
# ---- 浅仓处理:服务端拒绝 shallow update,必须先补齐历史 ----
# Git 服务端默认 `receive.shallowUpdate = deny`,推送浅仓会被拒:
# ! [remote rejected] main -> main (shallow update not allowed)
# 而 --depth 是本脚本自己提供的选项,推不上去等于自相矛盾,所以在这里兜住:
# 先 --unshallow 补齐(增量下载,通常只比浅仓多几十 MB),失败再降级为快照。
UNSHALLOWED="no"
if is_shallow; then
echo " 浅仓无法直接推送(服务端拒绝 shallow update),先补齐完整历史 ..."
for attempt in 1 2 3; do
if git -C "${MIRROR_DIR}" fetch --unshallow origin 2>/dev/null; then
UNSHALLOWED="yes"; break
fi
echo " ⚠ 第 ${attempt} 次 unshallow 失败,10s 后重试 ..."
sleep 10
done
if [[ "${UNSHALLOWED}" == "yes" ]]; then
echo " 已补齐完整历史"
else
# 网络或体积原因补不齐 —— 退回快照模式,丢历史但至少把代码留下来。
echo " ⚠ 补齐失败,将降级为【源码快照】(会丢失提交历史)"
SOURCE_ONLY_FORCE="yes"
fi
fi
PROTO="${GITEA_URL%%://*}"
HOST="${GITEA_URL#*//}"
U_ENC="$(/Users/figmarlite/.workbuddy/binaries/python/envs/default/bin/python -c \
'import sys,urllib.parse;print(urllib.parse.quote(sys.argv[1],safe=""))' "$GITEA_USER")"
'import sys,urllib.parse;print(urllib.parse.quote(sys.argv[1],safe=""))' "${GITEA_USER}")"
P_ENC="$(/Users/figmarlite/.workbuddy/binaries/python/envs/default/bin/python -c \
'import sys,urllib.parse;print(urllib.parse.quote(sys.argv[1],safe=""))' "$GITEA_TOKEN")"
'import sys,urllib.parse;print(urllib.parse.quote(sys.argv[1],safe=""))' "${GITEA_TOKEN}")"
echo " 推送到 $ORG/$REPO_NAME ..."
git -C "$MIRROR_DIR" push --mirror "$PROTO://$U_ENC:$P_ENC@$HOST/$ORG/$REPO_NAME.git"
# ---- 体积闸门:Gitea 前置 nginx 有 client_max_body_size 上限 ----
# 实测 gitea.apescale.com:48 MB 放行、64 MB 拒绝(推算为 50m,宝塔常见默认值)。
# 超限推送会在传完全部对象后才收到 HTTP 413,白白浪费几十分钟下载。
# 所以推送前先量体积,超限则自动降级为「源码快照」:剔除图片/音视频/字体等
# 非源码素材——这些内容通常占一半以上体积,却不是"跟踪源码"要看的东西。
MAX_PUSH_MB="${MAX_PUSH_MB:-45}"
PACK_KB="$(git -C "${MIRROR_DIR}" count-objects -v | awk '/^size-pack:/{print $2}')"
PACK_MB=$(( PACK_KB / 1024 ))
MIRROR_MODE="full"
echo " 本地裸仓打包体积: ${PACK_MB} MB(推送上限 ${MAX_PUSH_MB} MB)"
if [[ ( "${PACK_MB}" -gt "${MAX_PUSH_MB}" || "${SOURCE_ONLY_FORCE}" == "yes" ) \
&& "${SOURCE_ONLY}" != "no" ]]; then
MIRROR_MODE="source-only"
if [[ "${SOURCE_ONLY_FORCE}" == "yes" ]]; then
echo " ⚠ 降级为【源码快照】:提交历史不完整,按快照提交(仍会剔除素材)"
else
echo " ⚠ 超出上限,降级为【源码快照】:剔除非源码素材后推送"
fi
SNAP="$(mktemp -d)"
# shellcheck disable=SC2064
trap "cleanup_broken; rm -rf '${SNAP}'" EXIT
git init -q "${SNAP}/repo"
git --git-dir="${MIRROR_DIR}" --work-tree="${SNAP}/repo" checkout HEAD -- . 2>/dev/null
find "${SNAP}/repo" -type f -not -path '*/.git/*' \( \
-iname '*.png' -o -iname '*.gif' -o -iname '*.jpg' -o -iname '*.jpeg' \
-o -iname '*.webp' -o -iname '*.ico' -o -iname '*.mp4' -o -iname '*.mov' \
-o -iname '*.webm' -o -iname '*.wav' -o -iname '*.mp3' -o -iname '*.glb' \
-o -iname '*.ttf' -o -iname '*.woff' -o -iname '*.woff2' -o -iname '*.eot' \
-o -iname '*.pdf' -o -iname '*.zip' \) -delete
cat > "${SNAP}/repo/MIRROR-NOTE.md" <<NOTE
# 镜像说明
- 上游:${UPSTREAM}
- 许可证:${LIC_NAME}(${LIC_LEVEL})
- 抓取日期:$(date +%F)
## 这不是完整保真镜像
本仓库只含**源码与文档**,已剔除图片、音视频、字体等非源码素材。
原因:Gitea 前置 nginx 的 \`client_max_body_size\` 上限约 ${MAX_PUSH_MB} MB,
完整裸仓打包 ${PACK_MB} MB 会被 HTTP 413 拒绝。
完整保真快照保留在追踪体系的本地裸仓 \`.mirrors/${REPO_NAME}.git\` 中。
把服务器 nginx 放开到 \`client_max_body_size 512m;\` 后即可推送完整版。
NOTE
PUSH_DIR="${SNAP}/repo"
( cd "${PUSH_DIR}" && git add -A \
&& git -c user.name='agent-radar' -c user.email='radar@local' \
commit -q -m "源码快照 @ $(date +%F) (source-only, 剔除非源码素材)" )
# 必须先 repack 再量:新 commit 出来的都是 loose object,
# size-pack 为 0,会打印出「源码快照体积: 0 MB」这种误导性输出。
# repack 顺带也把推送体积压下去(实测 iPolloWork:散装 57 MB → 打包 14 MB)。
git -C "${PUSH_DIR}" repack -a -d -q --window=50 --depth=50 2>/dev/null || true
SNAP_MB=$(( $(git -C "${PUSH_DIR}" count-objects -v | awk '/^size-pack:/{print $2}') / 1024 ))
echo " 源码快照体积: ${SNAP_MB} MB"
else
PUSH_DIR="${MIRROR_DIR}"
fi
echo " 推送到 ${ORG}/${REPO_NAME} ..."
if [[ "${MIRROR_MODE}" == "full" ]]; then
git -C "${PUSH_DIR}" push --mirror "${PROTO}://${U_ENC}:${P_ENC}@${HOST}/${ORG}/${REPO_NAME}.git"
else
git -C "${PUSH_DIR}" push "${PROTO}://${U_ENC}:${P_ENC}@${HOST}/${ORG}/${REPO_NAME}.git" HEAD:refs/heads/main
fi
# ---- 回写档案 ----
/Users/figmarlite/.workbuddy/binaries/python/envs/default/bin/python - "$YAML" "$VISIBILITY" "$REPO_NAME" <<'PY'
/Users/figmarlite/.workbuddy/binaries/python/envs/default/bin/python - "${YAML}" "${VISIBILITY}" "${REPO_NAME}" "${MIRROR_MODE}" <<'PY'
import sys
from datetime import datetime
from pathlib import Path
sys.path.insert(0, str(Path(sys.argv[1]).resolve().parent.parent.parent / "scripts"))
from _common import today, update_block
@@ -140,9 +298,10 @@ text = update_block(text, "mirror", {
"visibility": sys.argv[2],
"gitea_repo": f"{'gitinbox'}/{sys.argv[3]}",
"last_sync": today(),
"mode": sys.argv[4],
})
p.write_text(text, encoding="utf-8")
PY
SIZE="$(du -sh "$MIRROR_DIR" 2>/dev/null | cut -f1 || echo '?')"
echo "==> 完成。$DISPLAY_URL/$ORG/$REPO_NAME (本地裸仓 $SIZE)"
SIZE="$(du -sh "${MIRROR_DIR}" 2>/dev/null | cut -f1 || echo '?')"
echo "==> 完成。${DISPLAY_URL}/${ORG}/${REPO_NAME} (模式 ${MIRROR_MODE},本地裸仓 ${SIZE})"