Commit Graph

206 Commits

Author SHA1 Message Date
5b6ea80f6b Pin tender-review team evidence-delivery release (#163)
Update the published team pointer to the reviewed team revision that
locks Lead and Evidence 0.1.1. Preview wording remains until
clean-install end-to-end acceptance is complete.

Co-authored-by: yige <yige@yigedeMacBook-Neo.local>
2026-09-11 04:59:53 -04:00
dabdcc4b99 Publish tender review team and usage docs
Publish the reviewed tender review team pointer, bilingual usage docs, and provenance sidecar after catalog/i18n/Copilot checks pass.
2026-09-10 16:42:52 -04:00
18f2f2243e feat: add tender review team preview (#160)
## What this changes

Adds the tender-review team and its onboarding entry to the official
Market catalog as an immutable source pointer, plus bilingual catalog
sidecars.

- `teams/biao-shu-lian-he-shen-cha/entry.json` points to the published
team commit `7ee5650b066cdee385288a722b8cbd8e1947d0fe`.
- `agents/tender-review-assistant/entry.json` points to assistant commit
`4b6855d2edb535f81c29847e06145c0da87942d0`.
- Both entries include bilingual descriptions, privacy boundaries and
`requiredClientVersion: 10.0.155`.
- The listing is deliberately `pointer` / preview. It does not claim the
v10.0.155 release is fully green or production-certified; newcomer
qualification remains pending.

## Validation

- `python3 scripts/catalog/validate_catalog_metadata.py --json` — 0
errors (existing catalog warnings unchanged).
- Market entry and both `catalog-metadata.v1.json` sidecars validate
against the current client/catalog schemas.
- Published source repositories and full commit pins were checked before
creating this branch.

---------

Co-authored-by: yige <yige@yigedeMacBook-Neo.local>
2026-09-10 15:45:40 -04:00
e111eb31f8 release: publish contract review team 0.1.26 (#159)
发布合同审查团队 v0.1.26 市场元数据。

团队版本、成员版本、来源提交和审阅引用均锁定至已合并的 Team 提交;发布时间和远端观测时间以可复核 Git 事实更新。

验证:catalog/i18n 校验通过,JSON 与空白检查通过;独立审阅 P0--P3 均为零。

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: yi-ge <6657330+yi-ge@users.noreply.github.com>
2026-09-08 07:56:50 -04:00
06929d16d6 release: publish contract review team 0.1.25 (#158)
问题:合同审查 Team 已发布 0.1.25 并锁定统筹官 1.0.13;市场仍指向 0.1.24,新用户无法安装经过推理兼容性修复的版本。

改动:将市场 entry 与 catalog sidecar 更新为 0.1.25,并以 Team 合并提交
0ce23190297d2b5918a91f2053a5ee2a9de264a7 作为唯一发布指针。

验证:JSON、catalog/i18n、镜像字段与公开信息扫描通过;独立 Terra review 通过。全局 collection
检查仍有4个未改外部集合陈旧项,和本发布无关,未将其记为通过。
2026-09-08 03:20:26 -04:00
8d0cedaeeb fix: publish contract review team 0.1.24 (#157)
## Why

The C02 newcomer test exposed a missing-material preflight defect in the
contract-review lead. The corrected team release is already merged as
0.1.24; this PR publishes the exact team ref to the market.

## What changed

- Update the market pointer and catalog sidecar to contract-review-team
0.1.24.
- Pin both metadata surfaces to
`e096a74a482b55266753b3b93e179f9cac2f0ecd`.
- Publish contract-review-lead 1.0.12 in the team roster.

## Validation

- Parsed both market JSON files.
- Verified pointer, provenance, and reviewed refs are identical.
- Verified the remote team `main` ref matches the published pointer.
- Ran the catalog and i18n validators successfully; they reported only
pre-existing catalog warnings outside this team.
- Ran `git diff --check`.

## 中文说明

将市场中的合同审查团队发布指针升级到 0.1.24,并锁定已合并的团队提交。该版本包含统筹官 1.0.12
的无材料零工具咨询修复;entry、sidecar 的来源与审阅提交已一致,市场校验通过。
2026-09-07 23:32:33 -04:00
4940c8a82d 发布合同审查团队 0.1.23
## 中文

### 背景
合同审查团队已发布 0.1.23,锁定 `contract-intake` 1.0.2 的 YAML 安全与解析声明治理修复。市场条目仍指向团队
0.1.22,导致新用户安装不到修复版本。

### 变更
- 市场条目 `latestVersion` 与 metadata release version 更新为 `0.1.23`。
- source、provenance 与 reviewedRef 更新为团队合并提交
`67805f39bae1e76a726fcbeef766c743cc020bc7`。
- 条目成员版本同步 `contract-intake` 1.0.2。
- 更新时间戳更新至本次团队发布。

### 验证
- 市场 i18n 校验:0 errors(既有 129 warnings)。
- catalog metadata 单元测试:47 tests,全部通过。
- collection generator 单元测试:4 tests,全部通过。
- catalog metadata validator:0 errors(既有 warning)。
- translate `--check`:通过。
- `git diff --check` 与凭据扫描:通过。
- `gen-collection-children.py --check` 发现 4 个既有外部 collection
stale(baoyu-skills、larksuite-cli、marketingskills、wecom-cli),本次未修改这些目录。

## English

### Background
Contract Review Team 0.1.23 is released with the `contract-intake` 1.0.2
YAML safety and parser-claim governance fix. The market listing still
pointed to 0.1.22, so new installs would miss the fix.

### Changes
- Update the market entry and metadata release version to `0.1.23`.
- Update source, provenance, and reviewedRef to team merge commit
`67805f39bae1e76a726fcbeef766c743cc020bc7`.
- Sync the entry member version for `contract-intake` to 1.0.2.
- Refresh release timestamps.

### Validation
- Market i18n validation: 0 errors (129 pre-existing warnings).
- Catalog metadata unit tests: 47 passed.
- Collection generator unit tests: 4 passed.
- Catalog metadata validator: 0 errors (pre-existing warnings).
- `translate --check`: passed.
- `git diff --check` and credential scan: passed.
- `gen-collection-children.py --check` reports four pre-existing stale
external collections; none are touched by this change.
2026-09-07 11:18:54 -04:00
d46d1a77d3 发布合同审查团队 0.1.22
市场校验、翻译检查与 Copilot review 全部通过。
2026-09-07 09:36:30 -04:00
12a70d4418 release: contract review team 0.1.21
Publish corrected member content hashes.
2026-09-06 21:59:08 -04:00
5934e479fd release: contract review team 0.1.20
Publish market metadata for team 0.1.20.
2026-09-06 21:36:13 -04:00
d4952e82f4 release: contract review team 0.1.19
GPT-Reserve review PASS; market validators and Copilot gate passed.
2026-09-06 20:25:50 -04:00
0683e1bf31 release: contract review team 0.1.18 (#151)
## Why
Publish the reviewed contract review team fix that was validated by a
fresh final18 real run. The prior run correctly fail-closed when
reporter artifacts escaped the lead case root and clauses.yaml was not
parseable.

## Changes
- bump marketplace entry/catalog to team 0.1.18
- point source/provenance/governance refs to merged team commit
6aa93bf11a6e37cc9d0444e3335ba953bee0a61f
- expose lead 1.0.10, clause 1.0.5, reporter 1.0.4 member versions
- retain legal disclaimer and source-pointer-only distribution

## Validation
- catalog validator exit 0
- i18n validator exit 0
- targeted JSON/ref assertions
- git diff --check
2026-09-06 19:20:54 -04:00
e9c1048a6a release: publish contract review team 0.1.15
Independent GPT-Reserve review passed; targeted validators and ref assertions passed.
2026-09-06 17:37:27 -04:00
3160e703d9 release: publish contract review team 0.1.14
Merged after independent GPT-Reserve review (P0/P1/P2/P3=0) and all market checks passed.
2026-09-06 16:32:55 -04:00
be1904d567 release: publish contract review team 0.1.13 (#148)
## 变更

- 更新合同审查团队市场条目至 `0.1.13`。
- `source.ref`、provenance content ref、governance reviewedRef 统一锁定团队合并提交
`91f576d8d5a30984d138752d32cc74929771a213`。
- roster 将 `review-reporter` 更新至 `1.0.2`。
- 对外说明评分回执的完整回读与 `REJECT-SCORECARD-YAML` fail-closed 闸门。

## 验证

- `uv run scripts/catalog/validate_catalog_metadata.py --json`:exit 0,0
errors(保留既有 warnings)。
- `uv run python scripts/catalog/test_validate_catalog_metadata.py`:47
passed。
- `uv run python scripts/i18n/test_validate_i18n.py`:19 passed。
- `uv run python scripts/catalog/test_collection_generator.py`:4 passed。
- entry/catalog JSON、ref/version 一致性断言与 `git diff --check` 通过。
- 团队 PR #26 与 reporter PR #3 已由 GPT-Reserve 独立复审并合并。
2026-09-06 14:50:12 -04:00
74466d1ac9 refactor(invoice-organizer): 迁出为独立仓库,条目转真 pointer / move to standalone repo (#140)
## 背景 / Background

`invoice-organizer` 是 market 里最后一个 inline 形态的第三方 Agent。它的
`provenance.content` 是指向 market 自身的 **self-pointer**(`url=market.git`,
`path=agents/invoice-organizer`)——治理字段已经按 pointer 写,内容却还在 market 里。本 PR
让两者一致。

## 改动 / Changes

内容迁到
**[desirecore-agent/invoice-organizer](https://github.com/desirecore-agent/invoice-organizer)**
@ `5ac1e29`,条目收敛为 3 个文件(`entry.json` + `catalog-metadata.v1.json` +
`assets/avatar.webp`)。

## pointer 形态的三处强制改动

`agent.json` 直接过 `agentConfigSchema`(根级 `additionalProperties:
false`),实测改完 `validateAgentConfig` 返回 `success: true`:

- **剥离 10 个市场字段**:`category` / `tags` / `updatedAt` / `maintainer` /
`installPolicy` / `updatePolicy` / `i18n` / `persona` / `changelog` /
`contentSource`
- **`id` 从 slug 换 UUID**
- **`avatar` 从 `{t,bg,image}` 换 `{char,color}`**:原 `bg` 是 `#34C759 →
#007AFF` 的绿蓝渐变,取起点绿色

## ⚠️ 一个必须补的兜底 / A gap this migration would otherwise open

原条目只有 `USAGE.zh-CN.md` 和 `USAGE.en-US.md`,**没有无后缀版本**。

pointer 形态下这两份都抓不到:

1. `fetchAgentRepoData` 总是抓无后缀 `USAGE.md`;`USAGE.<locale>.md` 的探测列表由
`extractDeclaredLocales` 从**上游 agent.json 的 `i18n.locales`** 得出
2. 而 pointer 的 `agent.json` 不能有 `i18n`——`agentConfigSchema` 顶层无此键且根级
`additionalProperties: false`
3. `readAgentDetailFromPointer` 调
`resolveUsageDocFromFiles(repoData.usage, locale)` 时**不传
localeHints**,回退链只剩 `locale → 无后缀`

不处理的话,使用说明会在详情页**彻底消失**。因此上游新增无后缀 `USAGE.md` 兜底(内容同
`zh-CN`,`source_locale` 就是 zh-CN),两份 locale 版本作为事实源保留。

**代价如实记录**:en-US 用户会从看到英文版降级为看到中文版。根因在平台侧,建议后续补齐
`readAgentDetailFromPointer` 的 locale hints,届时两份 locale 版本自动生效,无需再动条目。

## 准入 / Availability

**维持 `installable`**,证据六项自检全部通过:

```
content.ref == entry.source.ref                 ✅ 5ac1e29d3
compliance.reviewedRef == content.ref           ✅
timestamps.reviewedAt == compliance.reviewedAt  ✅ 2026-09-06
availability                                    ✅ installable
license known + licenseEvidencePath: LICENSE    ✅
provenance 不再指向 market 自身                  ✅
```

`LICENSE` 随内容迁到上游——与 `feishu-orchestrator` 一致,`licenseEvidencePath`
相对的是内容仓库而非条目目录。

## 已安装用户影响 / Impact on existing installs

`timestamps.releasePublishedAt` 是
2026-09-06(今天),实际安装量应为零。`provenance.content.url` 变更会影响已安装条目的 ownership
校验,但在这个时间窗内无实际影响。

## 结果 / Result

market 的 `agents/` 现在只剩官方 `desirecore` 一个 inline 条目,其余全部 pointer。
2026-09-06 14:17:21 -04:00
45cdff4923 release: publish contract review team 0.1.12 (#147)
Publish Contract Review Team 0.1.12. Update entry/catalog to the merged
team ref d85b9244244c3b69718b2525b8ef4b8b7296f144, lead 1.0.8, and
current timestamps. Focused validators: metadata 47 passed, i18n 19
passed, collection 4 passed, JSON parse and diff-check pass; existing
catalog warnings unchanged.
2026-09-06 13:27:44 -04:00
5025a7322f chore(contract-review-team): publish 0.1.11
GPT-Reserve review PASS (P0=0, P1=0, P2=0, P3=0). Metadata, i18n, collection, and Copilot checks passed.
2026-09-06 12:50:43 -04:00
377b7254dc docs(feishu-orchestrator): 补 USAGE.md 使用说明并重新 pin / add USAGE.md and repin (#137)
## 背景 / Background

主仓 [#2600](https://github.com/desirecore/desirecore/pull/2600)
给市场详情页加了「使用说明」区块,按约定文件名 `USAGE.md` 消费。飞书编排助手此前没有这个文件,详情页不渲染该区块——README
里的前置条件、授权步骤与边界,只有访问 GitHub 才看得到,而真正需要它的是市场里正准备安装的人。

The market detail page gained a Usage section in desirecore#2600,
sourced from a conventional `USAGE.md`. This agent had none, so the
section stayed hidden — its prerequisites, auth steps and limits were
reachable only by visiting GitHub.

## 改动 / Changes

- 上游新增
`USAGE.md`([desirecore-agent/feishu-orchestrator@6116ad4](6116ad4ac7))
- 本条目重新 pin 到该 commit,证据六项同步更新

## 为什么放上游而不是条目目录 / Why upstream

`sync/market.ts` 有两条读取路径,只有一条读本地条目目录:

| 方法 | 本地条目目录基线 | 远程 |
|---|---|---|
| `readAgentDetail`(inline 形态) | ✅ `readUsageDocFromDir` | 有则覆盖 |
| `readAgentDetailFromPointer`(**本条目**) | ❌ 无 | 仅远程 |

所以 pointer 条目的使用说明只能来自上游仓库。条目目录放 `USAGE.md` 对本条目无效。

## 为什么只有无后缀版本 / Why no locale variants

远程抓取时,`USAGE.<locale>.md` 的探测列表由 `extractDeclaredLocales` 从**上游
agent.json 的 `i18n.locales`** 得出;无后缀 `USAGE.md` 则总是被抓。

而 `agentConfigSchema` 顶层没有 `i18n`,根级 `additionalProperties: false`——给上游
agent.json 加这个字段会让 pointer 形态的安装校验直接失败。因此本条目只提供无后缀 `USAGE.md`。

## 内容 / Content

按 `usage-doc.ts` 的定位写「装之前该知道什么」,不是全量文档(3212 字符,上限
16000):第三方分发免责、四步授权、审批模式取舍、安全边界、已验证/未验证清单。各业务域的实测细节仍在上游 `docs/` 的 13 篇里。

两处与既有同类文档(`dingtalk-workspace/USAGE.md`)不同,是核对 `app/data/i18n/zh-CN.ts`
后的修正而非照搬:

- 审批模式是 **7 种**不是 6 种,补上 `allow-all`(全部放行)
- `ask-external` 的语义是「内置工具与命令放行,仅
MCP、HTTP、脚本等外部工具需审批」,**不是**「交给外部系统裁决」——两者含义相反,照搬会让用户以为自己收紧了,实际放宽了命令执行

## 验证 / Verification

证据六项一致性自检全部通过:

```
content.ref == entry.source.ref            ✅ 6116ad4ac
reviewedRef == content.ref                 ✅
timestamps.reviewedAt == compliance.reviewedAt  ✅ 2026-09-06
availability                               ✅ installable
license                                    ✅ known + LICENSE
requiredClientVersion                      ✅ 10.0.144
```
2026-09-06 12:19:03 -04:00
41c0badfcb chore(contract-review-team): publish 0.1.10 (#145)
## Change\n- publish contract-review-team 0.1.10\n- point source,
provenance, and governance review to team commit
1950e3b117e11b9208ed38fe6d64abfa87ea1adc\n- expose contract-review-lead
1.0.6\n\n## Validation\n- catalog metadata validator: 0 errors\n-
test_validate_catalog_metadata.py: 47 passed\n- git diff --check
passed\n- team PR #23 and lead PR #7 independently reviewed by
GPT-Reserve\n
2026-09-06 12:08:37 -04:00
31e4ca4611 chore(invoice-organizer): 1.0.3 —— 重新 pin 到已合并 commit (#144)
接 #138。那个 PR 只改技能内容,刻意没动版本号与 pin——contentSource.ref 必须
指向已合并的 commit,而那个 SHA 在合并前并不存在。这是同一条两步约束的第四次
(#117/#118、#120/#121、#127/#130 之后)。

- agent.json#contentSource.ref、sidecar 的 provenance.content.ref 与
  governance.compliance.reviewedRef 三处同步 pin 到 450be28
- 版本 1.0.2 → 1.0.3(agent.json 与 sidecar release.version 两处一致)
- 补 1.0.3 changelog(中英双语)

1.0.3 修的是:PDF 文本层在「两栏先输出全部标签、再输出全部取值」的版式下,
按「标签后紧跟的下一段文字」配对会把字段标签本身抽成销售方/购买方名称,且
所有形式勾稽都不会报错。新增硬校验:名称命中已知标签模式即判定提取失败,
先同页重定位、再整页视觉阅读,仍不能确定则按必填字段缺失隔离。

timestamps 三项已经是 2026-09-06,本次无需变更;结构化形态原样保持。
2026-09-06 11:24:13 -04:00
5750c48556 release: contract review team 0.1.9 market entry
All checks passed after rebasing onto market main; independent reserve review PASS, schema/i18n validation passed, and review conversation resolved.
2026-09-06 10:57:58 -04:00
450be28a2b fix(invoice-organizer): PDF 文本层名称字段标签污染防护 (#138)
PDF 的文本层顺序由生成它的开票系统决定,不保证等于版面阅读顺序。部分模板会把
「两栏的全部标签」连续输出完,再输出「两栏的全部取值」,按「标签后紧跟的下一段
文字」配对会把字段标签本身当成取值——一次真实批量整理里,某网约车平台开具的两张
「旅客运输服务」数电票的 sellerName 被抽成了字面的「统一社会信用代码/纳税人识别号:」。

新增「名称字段的标签污染防护(PDF 文本层)」一节:名称等于或主要由已知字段标签
组成时判定为提取失败,先在同页重新定位、再退到整页视觉阅读,仍不能确定则按技能
既定的「抽不齐必填字段就隔离」处理,不得从主题/文件名/相邻税号猜公司名。

明确标注这条只针对 PDF 文本层:OFD 页面文本按坐标重建阅读顺序、模板标签与取值
已合并到同一行,结构化来源更不依赖文本顺序,均不受此问题影响,OFD 章节未改动。
2026-09-06 10:46:46 -04:00
f1f38d7766 docs(wecom-assistant): 把能力边界落到技能侧并重新 pin / land capability boundaries in skills and repin (#143)
## 中文

上一个 PR(#136)把两条能力边界写进了 `USAGE.md`。但 `USAGE.md` **刻意不进模型上下文**(ADR-143,与
`fullDesc` 分开正是为了不占每轮 token)——也就是说运行时模型并不知道这些边界,遇到 `851003` 仍会当故障重试。本 PR
把它们落到技能侧。

重新 pin 到内容仓库

[`ebb1903`](ebb19035bb)。

### 三条改动

**1. `wecom-shared` 新增「零之四:企业人数改变机器人的身份」**

| 企业规模 | 模式 | 以谁的身份调用 | 能否读到真人的东西 |
| --- | --- | --- | --- |
| ≤ 10 人 | 小团队模式 | 授权真人 | 能,继承其文档权限 |
| > 10 人 | 企业模式 | 机器人独立身份 | **不能** |

写明了它与既有「零之一」的分工——零之一管**写**(任何规模下只能写机器人自己建的),本条管**读**(>10
人连读都不继承)。给出正确动作:说明边界 + 建议把文档显式分享给机器人,而不是重试。并标注**这条不可自查**:CLI
没有查企业人数的接口,`identity whoami` 也不返回规模,只能从实际返回反推。来源为上游 issue #64 维护者确认。

此前这个概念只藏在 `wecomcli-smartsheet/references/smart-sheet-webhook.md`
里,是局部知识,而且表述成「写入接口被限制」——真实机制是身份不继承,本 PR 一并修正。

**2. `wecom-shared` 易错点补「方法描述里也有不存在的参数」**

比既有的「服务描述里有不存在的能力」更隐蔽:方法真的存在,只是做不到描述承诺的事。实测三处,`--schema` 请求体里根本没有对应字段:

| 方法 | 描述承诺 | 请求体实际只有 |
| --- | --- | --- |
| `calendar schedules cancel` | 周期日程需指定编辑规则 | `schedule_id` |
| `calendar schedules update` | 同上 | 11 个字段,无一是周期规则 |
| `meeting cancel` | 周期会议取消单次需指定子会议 ID | `meeting_id` |

这解释了 `wecomcli-calendar` / `wecomcli-meeting` 为何禁止操作周期日程——**不是技能保守,是 CLI
没暴露参数**。顺带把 `calendar` 的「日历本列表查询」补进既有的服务描述清单。

**3. `smartsheet get` 是 `sheets list` 的别名**

两者官方描述逐字相同、返回同一份子表列表。此前 `smartsheet get` 在整个仓库零字面出现,模型只能靠 `--help`
自己摸到,然后在两者之间犹豫。

### vendor 纪律

第 3 条与 webhook 归因修正都落在 **vendor 自上游的 `wecomcli-smartsheet`**
上。脚本头注释明确「不要手工编辑 `skills/wecomcli-*`,改动会在下次重跑时被无声抹掉」,所以走
`patches/snippets/` + `injections.tsv` 注入,不手工改文件。

`bash scripts/vendor-official-skills.sh` **连跑两次 diff 不变**,幂等成立;注入计数 6 →
8,脚本摘要与 tsv 注释同步更新。

### 条目改动

三处 ref 一起改(这次用全文扫 40 位 hex 复核,只剩一个值),`releasePublishedAt` 不动——版本仍 1.0.0:

- `entry.source.ref`
- `provenance.content.ref`
- `governance.compliance.reviewedRef`

推之前本地跑过 `uv run scripts/catalog/validate_catalog_metadata.py
--require-complete`:**0 error**(129 warning 为全仓存量)。

---

## English

#136 put two capability limits into `USAGE.md`, which is **deliberately
kept out of model context** (ADR-143). At runtime the model therefore
still doesn't know them and retries `851003` as a failure. This PR lands
them in the skills.

1. **`wecom-shared` gains "rule zero-four": corporation size changes the
bot's identity.** ≤10 people — the bot calls *as the authorizing user*
and inherits their document permissions; >10 — it calls under its own
identity and inherits nothing. Spelled out against the existing "rule
zero-one" (that one governs *writes*; this one governs *reads*). Marked
as non-self-checkable: no API returns the corporation size, so it can
only be inferred from responses. Source: upstream issue #64.
2. **A new pitfall: method descriptions also promise parameters that
don't exist** — subtler than the existing service-level note, since the
method does exist. Three verified cases where `--schema` has no such
field, which is precisely why the calendar/meeting skills forbid
recurring-event operations.
3. **`smartsheet get` is an alias of `sheets list`** — identical
official descriptions, same payload.

Items 2–3 touch vendored upstream skills, so they go through
`patches/snippets/` + `injections.tsv` rather than hand edits; the
vendor script is idempotent across two consecutive runs. Catalog
validator reports 0 errors locally before pushing.
2026-09-06 10:37:08 -04:00
aa394e8bef refactor(dingtalk-workspace): 内联条目改为 pointer 形态 / convert inline entry to pointer (#141)
## 背景 / Context

钉钉工作台助手此前以**内联**形态登记(市场目录里直接放 24 个文件的完整正文)。这带来两个实际问题:

1. **同一份内容存在多个副本。** 上一次修正 `ask-external` 的审批模式文案时,同样的错误要在市场目录、Agent
私有目录、市场解压目录**四处**分别修改。
2. **与既有 Agent 形态不一致。** `wecom-assistant` / `feishu-orchestrator` 等都是
pointer 形态。

The DingTalk agent was registered inline (24 files of body content
inside the catalog). This duplicated the same content across several
copies — a single copy fix had to be applied in four places — and
diverged from every other agent, which use the pointer form.

## 改动 / Change

正文迁到
[desirecore-agent/dingtalk-workspace](https://github.com/desirecore-agent/dingtalk-workspace),市场侧只留两个文件:

```
agents/dingtalk-workspace/
├── entry.json                  ← pointer,source.ref 钉死上游 commit
└── catalog-metadata.v1.json    ← sidecar
```

**24 files → 2 files**(25 files changed, 72 insertions, 1781 deletions)

## 为什么必须删掉 agent.json 而非并存

`scripts/catalog/validate_catalog_metadata.py:253-261` 用
`inline_path.is_file() == pointer_path.is_file()`
判定——**两者必须恰好存在一个**,都有或都没有都会报 `fixed-sidecar-path` 并使条目掉出目录。

正文也一并清除,理由是另外两条:安装时会**整树复制**(排除清单只有
`upstream`/`.git`/`node_modules`/`.cache`),留下旧副本会与从上游拉取的正文形成两份可能不同步的内容;且与
`redistribution: source-pointer-only` 的声明自相矛盾。

## 证据六项 / Evidence

| 项 | 值 |
| --- | --- |
| `provenance.content` | https + 40 位 SHA
`9e5a4695b07d9d71921202a7a4072140c2135670` |
| `license` | `state: known` + `value: MIT` + `evidencePath: LICENSE` |
| `compliance` | 五项必填齐备 |
| `compliance.reviewedRef === provenance.content.ref` | ✅ |
| `timestamps.reviewedAt.value === compliance.reviewedAt` | ✅ |
| `governance.availability` | `installable` |

一致性比对的三处按既有约定处理:`entry.tags` 用英文 slug 且与 `presentation.tags` 逐字相同;entry
声明了 `license` 故 sidecar 必须 `known` 且 value 相等;`entry.maintainer` 映射到
sidecar 的 `upstreamMaintainer`。`redistribution` 用
`source-pointer-only`(pointer 不分发内容),非 inline 条目的 `allowed`。

## 上游仓库 / Upstream

内容仓库同步修正了审批模式文案(此前 `ask-external` 被写成「交给外部系统裁决」,实际含义是「内置工具与命令放行,仅
MCP、HTTP、脚本等外部工具需审批」,且漏掉 `allow-all`),现全部逐字引用平台内 i18n 文案。另补
`assets/avatar.webp` 与 `agent.json` 的 `avatar.image.path`,使 pointer
安装后仍有图片头像。

## 校验 / Verification

```
validate_catalog_metadata.py --require-complete   exit=0   0 error(s)
validate-i18n.py                                  exit=0   0 error
agents=5(条目未掉出目录)
```

上游可达性已独立验证:`git ls-remote` 取得 40 位 SHA,`git clone` 成功,27
个文件。**先推上游确认可达、再改市场卡片**,避免出现指向不存在 ref 的孤儿 entry。

Co-authored-by: yi-ge <jackyoncode@gmail.com>
2026-09-06 10:26:02 -04:00
b18073cb97 docs(wecom-assistant): 补使用说明并重新 pin / add USAGE.md and repin (#136)
## 中文

企业微信助手的市场详情页「使用说明」区此前为空。内容仓库

[`desirecore-agent/wecom-assistant@047928a`](047928afe1)
新增 `USAGE.md`,本 PR 把条目重新 pin 过去。

### 为什么要写这两条

它们都是**装之前**该知道、且**装完也改不了**的边界,正是 `USAGE.md` 的定位(ADR-143:与 `fullDesc`
分开,不进模型上下文)。

**1. 群聊历史目前仅对 ≤10 人企业开放。** 官方错误码 `853001` 的释义原文如此。实际触发返回相邻的 `853006`:

```
errcode: 853006
errmsg:  this tool is not available for your corporation
```

措辞是 **for your
corporation**,不是「机器人未开通某品类」——所以让用户去找管理员开通品类是无效动作。本机实测复现,同一凭证下其余 12
个服务域全部正常,`chat` 是唯一被拒的域。上游 `WecomTeam/wecom-cli` #106 / #107 / #132 三个
issue 都在追这件事,截至提交时全部 OPEN、官方未回复。

**2. 同一条命令在不同规模的企业行为不同,而且不报错。** 上游维护者在 issue #64 确认:≤10
人「小团队模式」机器人以**授权用户身份**调用、继承其文档权限;>10
人「企业模式」机器人以**独立身份**调用、不继承。后果是同事分享给你的文档,小公司读得到、大公司读同一份返回
`851003`。这不是故障,但不写出来必然被当成故障反复重试。

顺带记入第三条与规模无关的边界:`wecom-cli identity whoami`
返回原文「只能写入或修改机器人创建或拥有的数据」——这是邮件署名固定为「XXX的机器人」、用户对助手所建文档反而没有管理权的根因。

### 条目改动

pointer 条目的 `USAGE.md` 由客户端从内容仓库**按 pinned ref** 抓取(`sync/market.ts` 的
`pointerUsage` ← `code-repo/file-fetcher.ts`),所以只推内容仓库不改 ref
的话客户端看不到。四处一起改,保持 ADR-137 证据链自洽:

| 字段 | 旧 | 新 |
| --- | --- | --- |
| `entry.source.ref` | `665ab1d2` | `047928a` |
| `compliance.reviewedRef` | `665ab1d2` | `047928a` |
| `compliance.reviewedAt` | 2026-09-04 | 2026-09-06 |
| `timestamps.reviewedAt.value` | 2026-09-04 | 2026-09-06 |
| `timestamps.catalogUpdatedAt.value` | 2026-09-04 | 2026-09-06 |

`releasePublishedAt` **不动**——版本仍是 1.0.0,本次只增文档。

已核对:`reviewedRef === source.ref`、`timestamps.reviewedAt ===
compliance.reviewedAt`、`availability: installable`、`license.state:
known`、compliance 五项必填齐全、ref 为 40 位 SHA、`repoUrl` 在官方前缀内。

### 证据等级

| 结论 | 来源 |
| --- | --- |
| `853006` 错误原文与触发条件 | 本机实测复现 |
| 「仅对 ≤10 人企业开放」 | 官方错误码 `853001` 释义 |
| 小团队 / 企业模式身份差异 | 上游 issue #64 维护者确认 |
| 「只能写入机器人拥有的数据」 | `identity whoami` 返回原文 |
| 群聊 7 天限制 | `chat messages list` 的 `begin_time` 字段 schema |

**未核实**:`853006` 的具体判定标准(是否严格按人数、有无灰度名单)与开通路径,官方未公开、上游 issue
未获回复。`USAGE.md` 里已如实标注。


### 追加:一并修正 docs 的 853006 归因

同一 ref 里还带了内容仓库

[`047928a`](047928afe1)
的一处事实修正。原 docs 把 `853006` 写成「机器人未开通『群聊会话』品类」,并给出
「要让它可用:为机器人开通群聊会话品类」——**这是让用户去做一件做不成的事**。

改了 6 处(`04-群聊历史` 四处、`README` / `01-快速开始` / `99-风险与确认` 各处),
只纠正群聊这一处的归因,**不动「能力按品类逐项开通」这条通则**——那条对 `850002`
依然成立。技能侧(`wecom-shared` / `wecom-workflows` / `wecomcli-message`)本就写的是
「企业级不可用」,本次是让 docs 与技能口径一致。

---

## English

The agent detail page's "Usage" section was empty for the WeCom
assistant. The content repo now carries a `USAGE.md`; this PR repins the
listing to it.

It documents two limits that a reader needs **before** installing and
cannot change afterwards:

1. **Chat history is currently limited to corporations of 10 people or
fewer.** Official error `853001` states this; the actual response is
`853006 this tool is not available for your corporation` — the wording
is *corporation*, not *bot*, so asking an admin to enable a bot
capability is a dead end. Reproduced locally; all 12 other service
domains work under the same credential. Upstream issues #106 / #107 /
#132 all remain OPEN with no official response.
2. **The same command behaves differently by corporation size, without
erroring.** Per the upstream maintainer in issue #64, bots in ≤10-person
"small team mode" call **as the authorizing user** and inherit their
document permissions; in ">10 person" enterprise mode they call **under
their own identity** and do not. A doc shared with you is readable in a
small company and returns `851003` in a large one.

A pointer listing's `USAGE.md` is fetched from the content repo **at the
pinned ref**, so `source.ref` and the ref-bound compliance evidence are
updated together to keep the ADR-137 chain self-consistent.
`releasePublishedAt` is unchanged — still 1.0.0, docs only.
2026-09-06 10:11:20 -04:00
d3a81f1cb8 release: publish contract review team 0.1.8 (#135)
## Summary
- publish contract review team v0.1.8 from upstream team commit
98dcaf365c17fce25928dcdaf4a90739229617a5
- refresh the roster to match the team lock, including intake 1.0.1 and
risk 1.0.3
- preserve installable governance, privacy, and Work Context metadata

## Validation
- metadata validator: 0 errors (129 pre-existing warnings)
- metadata tests: 47 passed
- i18n tests: 19 passed
- collection tests: 4 passed
- JSON parse and git diff --check
- independent GPT-Reserve review: PASS (P0/P1/P2/P3 = 0)
2026-09-06 08:56:55 -04:00
18ce1c7798 fix(market): publish contract review team v0.1.6 (#134)
## Why / 背景

The market entry still pointed at team v0.1.5. Its pinned member lock
used stale agent manifests whose `command_authority.allowed_targets` did
not match the installed runtime IDs, so a fresh newcomer install could
pass catalog discovery but block the first delegation. The upstream team
main is now v0.1.6 with the corrected lock and member versions.

市场条目仍指向 v0.1.5。其成员锁引用了旧 Agent
manifest,`command_authority.allowed_targets` 与安装后的 runtime ID
不一致,导致新人实例虽然能发现团队,却会在首次委派时被阻断。上游团队 main 已更新到 v0.1.6,成员锁和版本已修正。

## What changed / 变更

- bump `latestVersion` and `release.version` to `0.1.6`;
- point entry source, catalog provenance, and compliance `reviewedRef`
to upstream team commit `3a4736e31ff5bf4299fde17fdde682a179d898b2`;
- align all six listed member versions with the upstream
`members.lock.json` (lead 1.0.4, intake 1.0.1, clause 1.0.2, risk 1.0.2,
jurisdiction 1.2.1, reporter 1.0.1);
- update release and upstream observation timestamps.

- 将 `latestVersion` 与 `release.version` 更新为 `0.1.6`;
- 将 entry source、catalog provenance 和 compliance `reviewedRef` 对齐上游团队
commit `3a4736e31ff5bf4299fde17fdde682a179d898b2`;
- 六名成员版本与上游 `members.lock.json` 对齐(统筹 1.0.4、输入 1.0.1、条款 1.0.2、风险
1.0.2、法域 1.2.1、报告 1.0.1);
- 更新发布时间与上游观察时间。

## Validation / 验证

- `uv run scripts/catalog/validate_catalog_metadata.py --json` — exit 0,
0 errors, 129 existing warnings;
- `uv run scripts/i18n/validate-i18n.py` — exit 0;
- `uv run scripts/catalog/test_validate_catalog_metadata.py` — 47
passed;
- `uv run scripts/i18n/test_validate_i18n.py` — 19 passed;
- `uv run scripts/catalog/test_collection_generator.py` — 4 passed;
- independent GPT-Reserve reviews — PASS, P0/P1/P2/P3=0;
- `git diff --check` — passed.

- `uv run scripts/catalog/validate_catalog_metadata.py --json`:exit 0,0
errors,129 个既有 warnings;
- `uv run scripts/i18n/validate-i18n.py`:exit 0;
- `uv run scripts/catalog/test_validate_catalog_metadata.py`:47 passed;
- `uv run scripts/i18n/test_validate_i18n.py`:19 passed;
- `uv run scripts/catalog/test_collection_generator.py`:4 passed;
- 两次独立 GPT-Reserve 复审:PASS,P0/P1/P2/P3=0;
- `git diff --check`:通过。
2026-09-06 08:07:04 -04:00
39258c79dd chore: publish contract review team 0.1.5 (#133)
## Changes\n- publish contract-review-team v0.1.5\n- point entry and
catalog metadata at merged team main commit
2a45d9fc031ba7d63d3ec15552ef0bc4c3a2b46e\n- align clause-extractor
roster version to 1.0.2\n- advance release timestamps to
2026-09-06T10:02:16Z, after team lock resolvedAt
2026-09-06T09:56:11.162Z\n- preserve Work Context description and all
unrelated metadata\n\n## Validation\n- team entry schema: PASS\n-
catalog metadata validator: PASS (existing repository warnings only)\n-
i18n validator: PASS (0 errors, 129 existing warnings)\n- collection
generator tests: 4 passed\n- git diff --check: PASS\n\nPlease review
independently; do not merge automatically.
2026-09-06 06:11:33 -04:00
e670a84b71 chore: publish contract review team 0.1.4
Publish team 0.1.4 with the merged lead manifest version/hash lock. Independent GPT-Reserve review PASS; Copilot approval recommended; market validators/tests PASS.
2026-09-06 04:14:18 -04:00
c5dc96c474 chore: publish contract review team 0.1.3
Publish contract review team 0.1.3 with Work Context orchestration compatibility and aligned publication provenance timestamps. Independent GPT-Reserve review PASS; market validators and tests PASS; Copilot concern resolved with timestamp fix.
2026-09-06 03:55:34 -04:00
84df5e7056 chore(invoice-organizer): 1.0.2 —— 重新 pin 到已合并 commit / repin to merged commit (#130)
## 背景 / Background

接 [#127](https://github.com/desirecore/market/pull/127)。那个 PR
只改了技能内容,**刻意没动版本号与 pin**——`contentSource.ref` 必须指向**已合并的 commit**,而那个
SHA 在合并前并不存在。先 bump 版本会让目录声称 1.0.2、却仍按指向 1.0.1 内容的 pin 去取文件,比不 bump 更糟。

这是 `#117`/`#118`、`#120`/`#121` 之后**第三次**走同一条两步约束——inline agent 声明为
`installable` 就必须 pin 到已存在的 commit,所以内容与 pin 永远得分两个 PR。

Third time through the same two-step constraint: an inline agent
declared `installable` must pin to an already-merged commit, so content
and pin can never land in one PR.

## 改动 / Changes

- `agent.json#contentSource.ref`、sidecar 的 `provenance.content.ref` 与
`governance.compliance.reviewedRef` **三处同步** pin 到 `406bc10`
- 版本 `1.0.1` → `1.0.2`(`agent.json` 与 sidecar `release.version` 两处一致)
- `reviewedAt` / `timestamps.reviewedAt` 同步到 `2026-09-06`
- 补 1.0.2 changelog(中英双语)

## 1.0.2 修了什么 / What 1.0.2 fixes

两条都来自真机对比两个版本产出的索引文件:

| 缺陷 | 现象 | 危害 |
| --- | --- | --- |
| 索引顶层结构没钉死 | 同一个 Agent 分别产出过 `{…, records:[…]}`(数组)与 `{…, invoices:{…},
suspectedDuplicates, quarantined}`(字典),`updatedAt` 也时有时无 |
台账、报告、幂等判据全部从索引派生,键名一漂,跨轮次和外部工具都对不上 |
| `emails.json` 的 key 有前缀歧义 | key 是 `<provider>:<email>:<mailId>`,而 IMAP
的 `mailId` 自带 `imap:` 前缀 → `imap:me@example.com:imap:123` | 服务端对裸 UID
也接受,所以某轮抄原值、某轮剥前缀,**同一封邮件产生两个 key,「已处理」判定失效、邮件被重复入账** |

两条的修法都是**只钉规则、不改语义**:旧形态原样沿用、不重写容器;key
用列表接口返回的原值、一个字符不改。因此**对任何已落盘的索引文件零影响**——改语义会让存量用户的已处理邮件全部失配、整个邮箱重新入账一遍。

Both fixes pin the rule without changing semantics, so existing on-disk
index files are unaffected.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-09-06 03:29:10 -04:00
435b338db3 fix: align jurisdiction member roster version (#129)
Align the market roster jurisdiction-auditor version with the published
team lock. Independent GPT-Reserve review passed; canonical market
validators and tests pass.
2026-09-06 03:09:10 -04:00
406bc10bcc fix(invoice-organizer): 钉死三个索引文件的顶层结构 / pin the index file schemas (#127)
## 问题 / Problem

真机对比同一个 Agent 两个版本产出的索引文件:

```
v1.0.0  ledger.json  {schemaVersion, updatedAt, records:[…]}                              数组
v1.0.1  ledger.json  {schemaVersion, invoices:{…}, suspectedDuplicates, quarantined}      字典

v1.0.0  files.json   {schemaVersion, updatedAt, files}      emails.json  {schemaVersion, updatedAt, emails, note}
v1.0.1  files.json   {schemaVersion, files}                 emails.json  {schemaVersion, emails}
```

技能原文只写了一句「`ledger.json` 发票主键 → 记录(主索引)」——**容器键名从未钉死**,于是同一个 Agent
在不同轮次产出了两种不兼容结构,`updatedAt` 也时有时无。

台账、报告、幂等判据**全部从索引派生**,键名一漂,跨轮次和外部工具就都对不上。这与已修的归档路径那条同源:**规格没说死的地方就会漂**。

The skill only said "`ledger.json` maps invoice key to record" — the
container key was never pinned, so the same agent produced two
incompatible shapes across runs. Everything (ledger spreadsheet, report,
idempotency) derives from these index files.

## 改动 / Changes

- 把三个索引文件的顶层形状写成 jsonc 范例,**容器键名与嵌套形态钉死**(`invoices` / `files` /
`emails` 都是字典,外加 `schemaVersion` 与 `updatedAt`;`ledger.json` 另有
`suspectedDuplicates` 与 `quarantined`)
- 明确 **「读到旧形态时不要重写容器」**:顶层出现 `records` 就一路沿用
`records`,只增改里面的条目。理由写进技能——容器一换,旧版写过、当前规格没覆盖的字段会**静默丢掉**,而用户毫无察觉
- 判据给成一句可照做的话:`records` → 沿用 `records`;`invoices` → 用 `invoices`;新建才用
`invoices`

## 为什么不做自动迁移 / Why no auto-migration

升级路径已实测(v1.0.0 目录被 v1.0.1 接手):Agent
**读得懂旧结构并原样保留**,台账记录数不变、幂等成立,还顺手修正了历史上错误的归档路径。既然读兼容已经成立,把容器强行规范化只会带来「丢字段」风险而没有收益。本
PR 把这个已被验证正确的行为**写成规则**,而不是引入新行为。

The upgrade path was verified in a real run: v1.0.1 reads the legacy
shape and preserves it, with zero duplicate ledger entries. This PR
codifies that verified behavior instead of introducing migration.

## 版本与 pin / Version and pin

同 #120 / #121 的两步发布约束:本 PR 只改技能内容,**不动版本号与 `contentSource.ref`**——pin
必须指向已合并的 commit,那个 SHA 在本 PR 合并前不存在。版本号、pin 与 changelog 留到后续 PR。

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-09-06 02:57:31 -04:00
ded3acbffe fix: publish contract review team authority targets (#128)
Publish contract review team 0.1.2 with runtime Agent IDs in command
authority and update the catalog metadata to the merged team lock
commit. Independent GPT-Reserve review passed; canonical market
validators report 0 errors.
2026-09-06 02:45:02 -04:00
a1a0901d08 fix(teams): align jurisdiction member with pinned release (#126)
## Why / 背景

The pinned team release `73cd87a9901cc548871927e9d5dbec8e4cc6c2b1`
contains `jurisdiction-auditor` version `1.0.0`, but the merged market
entry advertised `1.2.0`. That metadata mismatch makes a valid pinned
release fail exact roster validation during newcomer installation.

团队发布锁 `73cd87a9901cc548871927e9d5dbec8e4cc6c2b1` 中的
`jurisdiction-auditor` 实际版本为 `1.0.0`,已合并的市场条目却写成
`1.2.0`。该元数据不一致会让新人安装时的精确 roster 校验拒绝有效的 pinned release。

## What changed / 变更

- Set only the market roster version for `jurisdiction-auditor` back to
`1.0.0`.
- Keep the pinned source ref, member commits, content hashes, governance
sidecar, and all other members unchanged.

- 仅将市场 roster 中 `jurisdiction-auditor` 的版本恢复为 `1.0.0`。
- pinned source ref、成员 commit、content hash、治理 sidecar 与其他成员均保持不变。

## Validation / 验证

- `uv run scripts/catalog/validate_catalog_metadata.py --json` — 0
errors, 129 existing warnings
- `uv run scripts/catalog/test_validate_catalog_metadata.py` — 47 passed
- `uv run scripts/catalog/test_collection_generator.py` — 4 passed
- `uv run scripts/i18n/validate-i18n.py` — 0 errors, existing warnings
only
- public-tree sensitive-pattern scan — zero matches
2026-09-06 07:00:40 +08:00
a0f0d03878 fix(teams): match jurisdiction auditor release version (#125)
## Why

The team source lock declares `jurisdiction-auditor` at version `1.2.0`,
while the market roster still said `1.0.0`. DesireCore correctly
rejected the install because market member versions must match the
pinned team release.

## What changed

- update the market roster entry for `jurisdiction-auditor` to `1.2.0`;
- leave the pinned team source, commit, governance evidence, and all
other members unchanged.

## Validation

- `uv run scripts/catalog/validate_catalog_metadata.py --json` — 0
errors, 129 existing warnings
- public-tree sensitive-pattern scan — zero matches
2026-09-06 06:20:54 +08:00
6f8589ccda fix(teams): align contract review client compatibility (#124)
## Why

The published pointer advertises client version `10.0.137`, while the
current DesireCore release is `10.0.136`. The newcomer instance
therefore correctly blocks installation even though the team source is
compatible with the current client.

## What changed

- align the team pointer's `requiredClientVersion` with the current
client version;
- align the catalog sidecar's compatibility declaration with the same
version.

No source pointer, team member, capability, privacy, or governance claim
changed.

## Validation

- `uv run scripts/catalog/validate_catalog_metadata.py --json` — 0
errors, 129 existing warnings
- `uv run scripts/catalog/test_validate_catalog_metadata.py` — 47 passed
- `uv run scripts/catalog/test_collection_generator.py` — 4 passed
- public-tree sensitive-pattern scan — zero matches
2026-09-06 06:15:31 +08:00
00540f7d44 feat(teams): publish installable contract review team pointer (#123)
## Why

The contract review team already has a reproducible public Git source,
but its market pointer is still listing-only and uses the legacy
display-only shape. The current DesireCore client contract requires
explicit members, capabilities, privacy, an immutable source ref, and
installability evidence.

## What changed

- publish the contract review team as an installable,
source-pointer-only team entry;
- add the six-member roster, capability boundaries, privacy notice, and
update date;
- record review and license evidence in the catalog sidecar;
- keep the legacy team-entry schema branch while adding the current
client contract, so existing public pointers remain valid during
migration.

The source remains a public HTTPS Git pointer locked to commit
`73cd87a9901cc548871927e9d5dbec8e4cc6c2b1`. The team output is
supporting review material, not legal advice, and still requires
qualified human review.

## Validation

- `uv run scripts/catalog/validate_catalog_metadata.py --json` — 0
errors, 129 existing warnings
- `uv run scripts/catalog/test_validate_catalog_metadata.py` — 47 passed
- `uv run scripts/catalog/test_collection_generator.py` — 4 passed
- `uv run scripts/i18n/validate-i18n.py` — no errors; existing catalog
freshness warnings remain
- public-tree sensitive-pattern scan — zero matches
2026-09-06 06:09:14 +08:00
607045e44e chore: 移除误提交的 Python 字节码并新增 .gitignore / drop committed bytecode, add .gitignore (#122)
## 问题 / Problem


`scripts/catalog/__pycache__/validate_catalog_metadata.cpython-314.pyc`(60KB)在
#118 被误提交进仓库。

它是跑仓库校验脚本时的就地产物,**会随 `defaults/market.zip` 分发给每一个客户端**,而且只对生成它的那个 Python
版本(3.14)有效——换个版本就是纯粹的死重量。

本仓库此前**没有 `.gitignore`**,所以这类产物每次都得靠人眼发现。

A Python bytecode artifact was accidentally committed in #118. It ships
to every client inside `defaults/market.zip` and is only valid for the
exact Python version that produced it. The repository had no
`.gitignore` at all, so nothing prevented it.

## 改动 / Changes

- 删除该 `.pyc`
- 新增 `.gitignore`:`__pycache__/`、`*.py[cod]`、`.DS_Store`

## 与主仓库那道闸门的关系 / Relation to the upstream guard

desirecore/desirecore#2602 已让 `sync-market`
在同步目录不干净时拒绝打包——今天正是它拦下了我本机跑校验产生的 `cpython-310.pyc`:

```
Error: [sync-market] 同步目录存在未提交内容,拒绝打包:
    ?? scripts/catalog/__pycache__/validate_catalog_metadata.cpython-310.pyc
```

但那道断言只看**未提交内容**,拦不住已经进了仓库的 `cpython-314.pyc`。两处配合才完整:`.gitignore`
防止它被提交,洁净断言防止未提交残留被打包。

## 验证 / Verification

- `validate_catalog_metadata.py --require-complete`:0 error,75 sidecars
- `validate-i18n.py`:0 error
- 新增 `.gitignore` 后重跑校验,新产生的字节码不再出现在 `git status` 中

Co-authored-by: yi-ge <jackyoncode@gmail.com>
2026-09-05 15:34:34 +08:00
6963018829 feat(feishu-orchestrator): 改为 pointer 形态并声明可安装 / switch to pointer form and make it installable (#119)
## 为什么 / Why

条目此前是 inline + `listing-only`,详情页显示「仅收录,当前不能由 DesireCore 一键获取」。同期
#115(企微)与 #118(发票助手)都已 `installable`,**飞书是唯一装不了的第三方 Agent**。

inline 形态在这条路上无解:`installable` 要求内容有独立的不可变 ref,而 inline 内容随本仓库走,没有自己的制品
ref。

The listing was inline + `listing-only`, so the client showed it as
discovery-only. With WeCom (#115) and Invoice Organizer (#118) already
installable, this was the only third-party Agent users could not
acquire. Inline form cannot satisfy the installable evidence gate, which
requires content pinned to its own immutable ref.

## 顺带修掉一个错误的承诺 / An incorrect claim, fixed along the way

原 `agent.json` 用 `default_enabled.skills` 声明那 23 个 `lark-*`
技能。但该字段的语义是**「本地已有的技能默认启用」**,schema 明确限定 ID 需存在于 Agent 自带 `skills/` 或市场
`builtin-skills` 清单中 —— `lark-*` 两者都不在,**声明落空**。

真正负责「把技能取过来」的是 `required_skills`(desirecore/desirecore#2587)。也就是说,条目
`fullDesc` 里「随 Agent 一并安装 23 个技能,安装后即可使用」在原实现下**做不到**。

上游 `agent.json` 已改用 `required_skills.collections`,两个字段按 schema
的分工同时保留。逐项核对过:

| 检查项 | 结果 |
|---|---|
| 合集 `larksuite-cli` entry 与 children | 存在,28 个 |
| 声明的 23 个 ID 是否都在其中 | **全部命中,无缺失** |
| source | 公开 git + 固定 ref,可取 |
| 合集自身版本门槛 | 无 |
| `redistribution` | `allowed` |
| 合集是 `listing-only` 是否影响预置 | 否 —— 预置路径不检查 `availability` |

## 形态 / Form

内容移至
[desirecore-agent/feishu-orchestrator](https://github.com/desirecore-agent/feishu-orchestrator),pin
到 `d5b0a78`。market 侧只留 `entry.json` + sidecar + `assets/`。

上游 `agent.json` 已剥净市场卡片字段,并**单独跑过 `agentConfigSchema`** —— pointer 没有
`projectMarketAgentConfigToAgentFs` 那层投影兜底,`persona`
这类卡片字段留着就会让落盘配置非法(本次正是由该校验捕获并修掉的)。

**图片头像保留**:`assets/avatar.webp` 连同 `entry.avatar.image` 一起留在 market
侧,validator 接受 —— pointer 形态不必退回纯文字头像。

## 证据六项 / Acquisition evidence

- `provenance.content`:https + 40 位 SHA
- `license`:`known` + `MIT` + `evidencePath: LICENSE`
- `compliance`:六字段齐全(含 `noticePath: NOTICE`)
- `compliance.reviewedRef === provenance.content.ref`
- `timestamps.reviewedAt.value === compliance.reviewedAt`
- `availability: installable`

一致性:`entry.maintainer` → sidecar `upstreamMaintainer`;`tags` 用英文 slug 与
`presentation.tags` 逐字一致;`redistribution` 为
`source-pointer-only`;`entry.requiredClientVersion` 与
`compatibility.requiredClientVersion` 一致(`10.0.144`,即包含 #2587 的首个发布版本)。

## 校验 / Verification

| 命令 | 结果 |
|---|---|
| `validate_catalog_metadata.py --require-complete` | **0 error**,75
sidecars |
| `validate-i18n.py` | 0 error |
| `test_validate_catalog_metadata.py` | 47/47 |
| 上游 `agent.json` 过 `agentConfigSchema` | 通过(捕获并修掉了 `persona` 字段) |

Co-authored-by: yi-ge <jackyoncode@gmail.com>
2026-09-05 14:30:35 +08:00
1f9e0b0a03 chore(invoice-organizer): 1.0.1 —— 重新 pin 到已合并 commit / repin to merged commit (#121)
## 背景 / Background

接 [#120](https://github.com/desirecore/market/pull/120)。那个 PR
只改了技能内容,**刻意没动版本号与 pin**——`contentSource.ref` 必须指向**已合并的 commit**,而那个
SHA 在合并前并不存在。先 bump 版本会让目录声称 1.0.1、却仍按指向 1.0.0 内容的 pin 去取文件,比不 bump
更糟。这是 #117/#118 那次两步发布的同一条约束。

Follow-up to #120, which deliberately left the version and pin
untouched: `contentSource.ref` must point at an already-merged commit,
which did not exist until #120 landed.

## 改动 / Changes

- `agent.json#contentSource.ref`、sidecar 的 `provenance.content.ref` 与
`governance.compliance.reviewedRef` **三处同步** pin 到 `7560a58`
- 版本 `1.0.0` → `1.0.1`(`agent.json` 与 sidecar `release.version` 两处一致)
- 补 1.0.1 changelog(中英双语)

## 1.0.1 修了什么 / What 1.0.1 fixes

三条都是真机整理实测撞出来的 Agent 侧规格洞,不是模型不听话:

| 缺陷 | 实测现象 | 根因 |
| --- | --- | --- |
| 归档路径 | 五轮里有两轮归成 `<工作目录>/2022/11/增值税电子普通发票/2022-11-18_….pdf`——同时违反「缺
`归档/` 首层」「多插一层 `<发票类型>/`」「日期用 `YYYY-MM-DD` 而非八位连写」三条 |
原文只用一句散文说了路径,上下文压缩后凭印象重建就会漂 |
| 报告文件名 | 三轮全部写出 `报告/整理报告-<运行日期>.md` | 技能只定义了 `报告/<YYYY-MM>.md`,多月场景无从填写
|
| 台账表数量 | 只有 1 张发票时产出三张表(省了「按销售方汇总」) | 技能写了「四张表,顺序固定」但没说「即使为空也必须存在」 |

前两条的共同点:**只跑一遍、或只跑成功的那遍,都看不见**。归档路径在早期几轮全对,是在同一会话被压缩之后才走样的。

All three are spec gaps found by repeated real-machine runs, not model
disobedience — and the first two are only visible across multiple runs
in the same (compacted) conversation.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-09-04 12:22:39 -04:00
7560a58642 fix(invoice-organizer): 统一报告文件名约定 / unify report file naming (#120)
## 问题 / Problem

真机三轮整理实测:Agent 全部写出 `报告/整理报告-<运行日期>.md`,而技能里只定义了 `报告/<YYYY-MM>.md`。

**原因不是模型不听话。** 测试范围跨了 2020-08 到 2024-09 共十几个月,`<YYYY-MM>`
在多月场景下无从填写——技能没给出这种情况的文件名,Agent 只能自己发明一个。

**后果不是难看,而是会攒垃圾。** `invoice-automation` 的定时任务每月重建的是 `报告/<上月
YYYY-MM>.md`;与按运行日期命名的手工报告永远不会互相覆盖,用户目录里会留下一堆内容重叠、无从分辨新旧的报告。

Three real-machine runs all produced `报告/整理报告-<run date>.md`, while the
skills only define `报告/<YYYY-MM>.md`. The runs spanned 2020-08 through
2024-09, so `<YYYY-MM>` was unfillable and the agent improvised. Because
the scheduled monthly job rebuilds `报告/<last month YYYY-MM>.md`, the two
naming schemes never overwrite each other and the user's directory
accumulates overlapping reports with no way to tell which is current.

## 改动 / Changes

- `invoice-workflow` 第 7 步补一张表,把两种文件名钉死:

  | 本次覆盖 | 文件名 | 例 |
  | --- | --- | --- |
  | 恰好一个自然月 | `报告/<YYYY-MM>.md` | `报告/2024-08.md` |
  | 跨多个月 | `报告/<起始 YYYY-MM>_<结束 YYYY-MM>.md` | `报告/2020-08_2024-09.md` |

并写明月份按**开票日期**归属(与台账同口径)、同名直接覆盖(报告是从 `.index/ledger.json`
全量重建的派生产物,不像台账需要先备份)、以及**为什么不许用运行日期命名**
- `invoice-ledger` 与 `references/月度报告模板.md` 同步该约定
- 目录布局示例与中英 USAGE 一并标注跨月形态

## 为什么不在本 PR 里 bump 版本 / Why no version bump here

`contentSource` 的 `ref` 必须 pin 到**已合并的 commit**,本 PR 合并前拿不到那个 SHA。先 bump
版本会让目录声称 1.0.1、却仍按指向 1.0.0 内容的 pin 去取文件——比不 bump 更糟。版本号、pin 与 changelog
留到后续 PR 一起改。

The `contentSource` ref must pin to an already-merged commit, which does
not exist until this PR lands. Bumping the version now would advertise
1.0.1 while still serving 1.0.0 content. Version, pin and changelog
follow in a second PR.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---

## 追加:台账四张表必须全建 / Also: all four ledger sheets must always exist

真机压测(只有 1 张发票)产出的 `台账.xlsx` **只有三张表**——Agent 判定「按销售方汇总」在单一销售方下冗余而略过:

```
发票测试(23 张) → ['明细', '月度汇总', '按销售方汇总', '异常']
发票压测(1 张)  → ['明细', '月度汇总', '异常']          ← 少一张
```


技能写的是「四张表,顺序固定」,但没说「即使为空也必须存在」。台账是要被重复重建、被用户自己写公式引用、被下一次整理覆盖的产物;表的位置一旦随数据量浮动,「第
3 张是按销售方汇总」这类引用就会在下个月悄悄指错。已在 `invoice-ledger` 里把这条钉死。

A stress run with a single invoice produced only three sheets — the
agent judged the per-seller summary redundant. The skill said "four
sheets, fixed order" but never said "even when empty". Sheet positions
that float with row count silently break user formulas and rebuilds; now
pinned.
2026-09-04 11:56:48 -04:00
98251c9a1d feat: 新增飞书编排助手 Agent 市场条目 / add Feishu Orchestrator agent listing (#114)
## 这是什么 / What

把自然语言意图翻译成第三方飞书 CLI(`lark-cli`)的正确调用,覆盖云文档、Markdown
文件、电子表格、多维表格、云空间、知识库、幻灯片、画板、即时消息、邮箱、日历、视频会议与妙记、任务、审批、OKR、考勤、应用搭建与实时事件等业务域。

声明 23 个业务域技能依赖,安装后即可使用,无需手工拷贝技能目录。

An agent that turns natural-language intent into correct calls to the
third-party Feishu CLI, covering documents, sheets, Base tables, drive,
wiki, messaging, mail, calendar, meetings, tasks, approvals, OKR and
attendance. It declares 23 domain skill dependencies that install
together with the agent.

## 结构 / Layout

与仓库既有的 `dingtalk-workspace` / `wecom-assistant` 条目保持一致:

```
agents/feishu-orchestrator/
├── agent.json                 # 内联元数据(AgentFS 配置 ∪ 市场卡片,含 i18n 双语 + changelog)
├── catalog-metadata.v1.json   # sidecar,字段全部从 agent.json 派生
├── assets/avatar.webp         # 512×512 图片头像
├── persona.md / principles.md # L0/L1/L2 分层人格与硬规则
├── README.md                  # 条目总览 + 文档索引
└── docs/01..13-*.md           # 按业务域拆分的 13 篇功能文档
```

## 文档 / Docs

命令、参数约定与坑位**均来自真机验证**(2026-09-01,220 个已授权 scope)。未跑通的能力在
[`docs/13-能力边界.md`](agents/feishu-orchestrator/docs/13-能力边界.md)
中如实标注,不含任何租户、组织或个人标识。

其中固化了三处容易踩错的 CLI 契约:

| 契约 | 踩错的后果 |
|---|---|
| `auth status` 成功时**没有**顶层 `ok` 字段 | 按通用 `ok === true`
判据会把「已授权」误判成「未授权」,反复推用户重新扫码 |
| 身份不显式指定会落到 `bot` | bot 看不见用户的个人日历、云盘、邮箱,且返回**空成功**而非报错 |
| `--ranges`(复数)的 sheet 前缀要用 `sheet_name` | 用 `sheet_id` 会通过确认门禁、但在 API
层报 `Sheet not found`;而单数 `--range` 的约定**正好相反** |

## 治理 / Governance

- `governance.availability: listing-only` —— 与核心
Agent、钉钉、企微三个既有条目一致。inline agent 的内容随仓库走,没有独立制品 ref,无法满足 `installable`
分支「必须有不可变 ref 或 SHA-256 摘要」的门禁
- `governance.branding`:`independent-listing` / `nominative` / `logo
not-used` —— 飞书、Lark 为第三方商标,头像为抽象编排拓扑图,不使用任何第三方 logo
- `compatibility.requirements`:按仓库「外部依赖披露」规范声明运行时、权限、连接三类前置。DesireCore
不打包、不分发、不授权、不安装、不代付 `lark-cli` 及其背后的飞书产品

## 顺带修正 / Incidental

根 `README.md` 的 Agent 清单停留在 `2` 个(遗漏 `wecom-assistant`),一并补齐为准确的 4
个;`manifest.json#stats.totalAgents` 3 → 4。

## 校验 / Verification

| 校验 | 结果 |
|---|---|
| `validate_catalog_metadata.py --require-complete` | **0
error**,sidecars 74,本条目零 warning |
| `validate-i18n.py` | 0 error |
| `test_validate_catalog_metadata.py` | 47/47 |
| 发布前敏感信息扫描(邮箱 / 飞书真实 ID / 租户组织标识 / 带 ID 链接 / 密钥形态 / 隐藏文件,全工作树) |
**零命中** |
| 文档内部链接 | 13 个链接全部命中真实文件,无断链 |

## 依赖 / Dependency

`requiredClientVersion: 10.0.143` —— 自动装齐依赖技能的能力来自主仓库
desirecore/desirecore#2587,该值按其合入后的首个发布版本填写。**若 #2587 未能进入
10.0.143,此值需回填修正**,否则用户在缺少该能力的版本上装完 Agent 会没有技能。

---------

Co-authored-by: yi-ge <jackyoncode@gmail.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-09-04 10:38:37 -04:00
6c303ef21f feat(invoice-organizer): 声明为可安装并 pin 到已合并 commit / make Invoice Organizer installable (#118)
接 #117。那个 PR 只登记了条目本身(`availability: listing-only`),用户在市场里**看得到、装不了**。
本 PR 补齐可安装所需的证据链。

Follow-up to #117, which only listed the entry (`listing-only`) —
visible in the marketplace but
not installable. This PR supplies the evidence chain required for
installation.

## 改动 / Changes

- `agent.json` 新增 `contentSource`,pin 到 #117 的合并 commit `42a29e9`
- sidecar 的 `provenance.content` 与之**归一化后逐字一致**
(两侧字段名按各自 schema 写:agent.json 侧是 `repoUrl`(`marketPointerSchema`
的必填字段名),
sidecar 侧是 `url`;`normalizeContentSource` 里 `input.url ?? input.repoUrl`
把两者统一成 `url`,
  比对发生在归一化之后,取的是 `{kind, url, path, ref, sha256}` 五元组)
- `governance.compliance.reviewedRef` 绑定同一 commit;`reviewedAt` 与
  `timestamps.reviewedAt` 取同一天
- `governance.availability` 翻成 `installable`
- **移除** sidecar 的 `stewardship: "official"` 与 `branding.relationship:
"official"`

## 为什么移除 `stewardship: official`(这一条值得单独看)

`normalize/sidecar.ts` 只允许 `bundled-builtin` / `system-agent` /
`official-pointer`
三种受信来源自称 official。**inline agent 不在其中**,命中即
`catalog.sidecar-forbidden-provider-claim` —— **整份 sidecar 被丢弃**,
静默回落到 `agent.json` 派生的 legacy 默认值。

在 dev 实例上实测确认(同步到 `42a29e9` 之后):

```
客户端拿到的 governance:
  {"availability":"listing-only","license":{"state":"unknown"},
   "redistribution":"verify-package-terms","listingMaintainer":{...}}
sidecar 里写的却是:
  license: {state:"known", value:"MIT", evidencePath:"LICENSE"},  redistribution: "allowed"
catalogDiagnostics: null
```

也就是说:sidecar 被整份丢弃,而**维护者没有任何反馈**。

`dingtalk-workspace` 也有同样的 `stewardship: "official"`,它的 sidecar
**同样一直在被静默丢弃**
(实测它的客户端 governance 与本条目改之前完全一样)。这条不在本 PR 范围内,
建议单独处理;DesireCore 主仓库那边我另外记了一条「sidecar 被拒的诊断没有透出到任何 API」的缺口。

## 验证 / Verification

直接调用客户端的真实代码路径(不是照着文档推断):

```
hydrateCatalogSidecar                  success=true   diagnostics=[]
compareMarketCatalogConsistency        consistent=true  mismatches=[]
evaluateCatalogAcquisitionEligibility  allowed=true   reasons=[]

legacy  provenance.content: {"kind":"git","url":"https://github.com/desirecore/market.git",
                             "path":"agents/invoice-organizer","ref":"42a29e99a0…"}
sidecar provenance.content: {同上,逐字一致}
```

`compareMarketCatalogConsistency` 对 inline agent 会**逐字比对**
`provenance.content`;
不一致会让整份 sidecar 静默降级回 listing-only,而 Python 校验器对 inline 条目
直接跳过这项比对(`_validate_content_consistency` 对 inline 早退),抓不到。
所以这一项只能靠上面这条客户端侧的验证兜住。

## 校验 / Validation

```
validate_catalog_metadata.py --require-complete   0 error, 129 warning, agents=4, sidecars=74
validate-i18n.py                                  0 error, 129 warning
translate.py --check                              ok
gen-collection-children.py --check                ok
```
129 条 warning 全部来自 `skills/*` 的存量条目,`invoice-organizer` **零命中**。
2026-09-04 09:03:21 -04:00
42a29e99a0 feat(invoice-organizer): 新增发票整理助手 Agent / add Invoice Organizer agent (#117)
新增官方 inline Agent「发票整理助手」(`invoice-organizer`)。

Adds an official inline Agent, **Invoice Organizer**, that turns
invoices scattered across
mailboxes and local folders into a reconcilable, reusable ledger.

## 它做什么 / What it does

七步固定流程,每一步幂等:**接入检查 → 收集 → 解析 → 去重 → 归档 → 台账 → 报告**。

- **收集**:从已接入的邮箱(Gmail / Outlook / IMAP)找出候选发票邮件,附件用 `MailOperations` 的
  `save_to` 直接落盘,base64 不进模型上下文
- **解析**:OFD(三个结构化来源分别处理)、PDF 文字层、扫描件走视觉;每个字段带 `extractedBy` 与置信度
- **去重**:发票号码为主键,跨格式识别同一张票(PDF 与照片、重复下载);近重复不自动合并
- **归档**:`归档/年/月/YYYYMMDD_销售方_金额_发票号码.ext`,原件一个不动
- **台账**:xlsx 四张表(明细 / 月度汇总 / 按销售方汇总 / 异常),发票号码强制文本格式;
  装不上 openpyxl 时降级为 UTF-8 BOM CSV
- **报告**:Markdown 月度报告,收尾固定报五个计数(范围 / 候选 / 成功 / 待复核 / 失败)
- **自动化**:邮件规则 `agent_handle` + `ManageSchedule` 定时出账

## 明确的能力边界 / Explicit boundaries

- **不做发票真伪查验**,也不暗示做过——只做形式校验与勾稽校验,给出官方查验平台入口让用户自己核验
- **不删除、不移动、不转发用户的邮件**
- **票面内容不外流**:不外发、不代发、不上传第三方接口或在线查验站点
- **不做汇率换算**;不承诺「已找全」,只报「在给定范围内找到 N 封候选、成功解析 M 张」

## 结构 / Structure

```
agents/invoice-organizer/
├── agent.json  persona.md  principles.md  LICENSE
├── USAGE.zh-CN.md  USAGE.en-US.md
├── catalog-metadata.v1.json      # availability: listing-only(可安装化见下)
├── assets/avatar.webp
└── skills/
    ├── invoice-workflow/         # 七步总纲、目录布局、落盘顺序、去重主键、幂等
    ├── invoice-extract/          # 三种载体的解析细则、置信度分档、特殊票据
    │   └── references/票面文本形态.md
    ├── invoice-ledger/           # 台账结构、人民币约定(覆盖 xlsx 技能的默认口径)
    │   └── references/月度报告模板.md
    └── invoice-automation/       # 邮件规则与定时调度的参数模板与排查
```

`manifest.json` 的 `stats.totalAgents` 3 → 4。

## 事实性核对 / Fact-checking

技能里引用的**每一个**端点 / 工具名 / 参数名 / 返回字段都对着 DesireCore 主仓库实现逐条核对过,
并经过一轮对抗式 review。review 抓到的、已修正的主要事实错误:

- OFD 一节原本只覆盖 2020 年式样;已改为按**三个来源**分述
  (内嵌附件 / 2024 数电票的 `Tags/CustomTag.xml` 标引 / `DocInfo/CustomDatas`),
  键名从 `Buyer/BuyerName` 改为真实的点号路径 `Buyer.BuyerName`,置信度按来源分档
- **`DocInfo/CustomDatas` 的「合计金额」是不含税金额**,误当 `totalAmount` 会让每张 2024
数电票少记税额
  ——已写成硬规则
- Gmail 本地缓存搜索的 `q` **实际只按主题过滤**(正文过滤在主题收窄之后才跑),
  原文写成「搜主题与正文」会导致静默漏邮件
- 「轮询只覆盖收件箱」只对 IMAP 成立,Gmail / Outlook 是整个邮箱
- `POST /rules/{id}/test` 走另一份内联实现、**没有 `matches_regex` 分支**,
  不能用它验证正则规则
- 邮件列表项里 Gmail / IMAP **是带** `attachments[]` 的,只有 Outlook 不带;
  `labelIds` 是 Gmail 专有

## 真机验证 / Verified on a live instance

在 dev 实例上以一句话指令处理 31 个混合文件(数电票 / 旧版票 / OFD / 扫描件 / 行程单,
外加重复、近重复、作废、零额与 4 个非发票负样本):

- 23 张归档,字段与夹具 ground truth **逐条吻合**
- 4 个非发票**全部正确拒绝**并写明理由(施工许可证 / 对账单 / 技术服务合同 / 邮件通知)
- 4 个跨格式重复(3 张扫描件 + 1 次重复下载)**全部靠发票号码主键识破**,隔离而非删除
- 近重复正确未合并;作废票归档但不计入合计;低置信度定额发票标为待复核
- 台账 xlsx 四张表、报告含五个计数、`SendUserMessage` 带附件交付
- `待整理/` 31 个原件一个未动

## 校验 / Validation

```
validate_catalog_metadata.py --require-complete   0 error, agents=4, sidecars=74   exit=0
validate-i18n.py                                  0 error                          exit=0
translate.py --check                                                               exit=0
gen-collection-children.py --check                                                 exit=0
```
129 条 warning 全部来自 `skills/*` 的存量条目,改前改后一字不差,`invoice-organizer` 零命中。
另核实:`agent.json` 过 `marketAgentSchema`(详情页)与收窄后过
`agentConfigSchema`(安装),
persona / principles 的 6 个 canonical key 用平台真实解析器全部解得出,全树敏感信息扫描通过
(所有公司名 / 税号 / 银行账号均为 `示例`/`示范`/`虚构`/`样例` 前缀的合成值)。

## 后续 / Follow-up

本 PR 为 `availability: listing-only`。可安装化需要把 `agent.json#contentSource` 与
sidecar 的 `provenance.content` **逐字一致地** pin 到本 PR 的合并 commit,
并补 `governance.compliance` 与 `timestamps.reviewedAt`——那是紧接着的第二个 PR。
2026-09-04 07:28:03 -04:00
61c82782c4 fix(wecom-assistant): sidecar 显式声明 installPolicy/updatePolicy / declare install & update policy in sidecar (#116)
## 中文

sidecar 的 `spec` 未声明 `installPolicy` / `updatePolicy`,而 legacy 侧对双缺省派生为
`market` / `market`,导致 `compareMarketCatalogWithLegacy` 判定
`spec.agent.policy` 不一致,**整个 sidecar 被拒**(`sidecarRejected`)并回退
listing-only。

真机取证——客户端市场索引 `cache/market/index.json` 中该条目:

```json
"sidecarRejected": true,
"catalogDiagnostics": [
  {"code": "market.catalog-legacy-mismatch", "field": "governance.availability"},
  {"code": "market.catalog-legacy-mismatch", "field": "spec.agent.policy"}
]
```

本 PR 修掉其中的 `spec.agent.policy`。另一条 `governance.availability`
是**客户端侧的结构性缺陷**,不在本仓库范围:`market-agent-entry.client.schema.json` 等 5 个
market schema 均无 `availability` 字段且 `additionalProperties: false`,因此
pointer 条目的 legacy availability 恒为 `listing-only`,sidecar 声明
`installable` 必然 mismatch。主仓库已另开 PR 修复,客户端发版后本条目即可生效;在此之前旧客户端会降级为
listing-only 展示,不影响可用性。

校验:`validate_catalog_metadata.py` 0 error。

---

## English

The sidecar's `spec` omitted `installPolicy` / `updatePolicy`, while the
legacy side derives `market` / `market` from the double default.
`compareMarketCatalogWithLegacy` therefore flagged `spec.agent.policy`
as inconsistent and **rejected the whole sidecar**, falling back to
listing-only.

Verified against a live client's market index, which showed
`sidecarRejected: true` with diagnostics for both `spec.agent.policy`
and `governance.availability`.

This PR fixes the former. The latter is a **structural gap on the client
side**, outside this repository: none of the five market schemas carry
an `availability` field and all set `additionalProperties: false`, so a
pointer entry's legacy availability is always `listing-only` and any
sidecar declaring `installable` must mismatch. A separate PR in the main
repository addresses that; this entry becomes effective once the client
ships it. Older clients degrade to listing-only, which does not affect
usability.

Validation: 0 errors from `validate_catalog_metadata.py`.
2026-09-04 01:18:03 -04:00
2eebcd3d8c feat(wecom-assistant): 改为 pointer 形态并补齐获取证据 / switch to pointer form with full acquisition evidence (#115)
## 中文

把「企业微信助手」从 inline 形态改为 pointer 形态,并补齐严格证据门槛,使其成为**首个可一键安装的 Market
Agent**。

### 为什么改

此前该条目在市场详情页显示「仅收录 / 当前不能由 DesireCore 一键获取」。判定源是
`evaluateCatalogAcquisitionEligibility`:Agent 类条目**不享受** builtin Skill 的
`isTrustedBundledBuiltin` 快捷通道(该函数硬编码 `kind === 'skill'`),必须走 content
不可变 + license known + compliance 三重匹配的严格门槛。这与本仓库 README 的「Agent pointers
do not receive the built-in Skill exceptions」及 ADR-137 一致,是有意的设计而非缺陷。

inline 形态还存在自指问题:证据要求 `content` 指向不可变 commit,而 inline
内容就在本仓库里,条目无法预知自己将被合并进哪个 commit。现网 41 个 inline 条目全部没有 `content`,30 个
pointer 条目全部有——数据印证了这一点。

### 改了什么

**形态**:内容迁至 `desirecore-agent/wecom-assistant`,本仓库只保留 `entry.json` 与
sidecar。删除 53 个文件 / 16494 行,条目从 1.0M(全仓最大的 Agent 条目)降到数 KB。符合
ADR-038「market 仓库只放元数据、不放具体内容」。

**证据六项**:
| 项 | 值 |
|---|---|
| `provenance.content` | git + `665ab1d2…`(https + 40 位 SHA) |
| `governance.license` | `unknown` → `known` / MIT,`evidencePath:
LICENSE` |
| `governance.compliance` | 五项齐备,`reviewedRef` 等于 `content.ref` |
| `timestamps.reviewedAt` | 与 `compliance.reviewedAt` 逐字一致 |
| `availability` | `listing-only` → `installable` |
| `redistribution` | 与 `entry.json` 同为 `source-pointer-only` |

**内容侧**(在内容仓库中完成):13 个业务技能改为 vendor 企业微信官方
`WecomTeam/wecom-cli`(MIT,pinned `78c514b2`),自维护 `wecom-shared` /
`wecom-chat` / `wecom-workflows` 三个治理与增量技能。官方内容量为原自研版的 1.6 倍(21.6k vs
13.7k 行),并已修正官方 `meeting rooms search` 的 3
个失效参数名——`room_keyword`/`min_capacity`/`building_city` 在 CLI 1.2.0 已改名,而
CLI 对未知字段不校验、原样透传,会导致静默订错会议室。MIT 署名义务由内容仓库的 `NOTICE` 与
`third_party/wecom-cli/LICENSE` 履行。

### 校验

`validate_catalog_metadata.py` 0 error、`validate-i18n.py` 0
error、`gen-collection-children.py --check` 通过(wecom-cli 14 children)。129
个 warning 均为其他既有条目所有,本次未新增。

### 已知风险

市场 Agent 的安装链路此前**从未被真实用户走过**(现网 0 个 installable
agent,仅有单测覆盖)。合并后需真机验证安装、并重启客户端后再验一次卸载。

---

## English

Switches the WeCom Assistant entry from inline to pointer form and
supplies the full acquisition evidence, making it the **first
installable Market Agent**.

### Why

The entry previously rendered as listing-only. Agent items do **not**
receive the builtin-Skill fast path in
`evaluateCatalogAcquisitionEligibility` (`isTrustedBundledBuiltin`
hardcodes `kind === 'skill'`), so they must satisfy the strict gate:
immutable content, known license, and ref-bound compliance. That matches
this repo's README ("Agent pointers do not receive the built-in Skill
exceptions") and ADR-137 — it is deliberate, not a defect.

Inline form also has a self-reference problem: the gate requires
`content` to pin an immutable commit, but inline content lives in this
repository and cannot know which commit will carry it. All 41 inline
entries currently lack `content`; all 30 pointer entries have it.

### What changed

**Form**: content moved to `desirecore-agent/wecom-assistant`; only
`entry.json` and the sidecar remain here. 53 files / 16494 lines
removed, shrinking the entry from 1.0M (the largest Agent entry in the
repo) to a few KB, per ADR-038.

**Evidence**: `provenance.content` pins `665ab1d2…`; license becomes
known/MIT with `evidencePath`; compliance carries all five required
fields with `reviewedRef` equal to `content.ref`;
`timestamps.reviewedAt` matches `compliance.reviewedAt`; availability
becomes `installable`; redistribution aligns with `entry.json`.

**Content side**: 13 business skills are now vendored from the official
`WecomTeam/wecom-cli` (MIT, pinned `78c514b2`) — 1.6× the volume of the
previous in-house set — with three self-maintained skills for governance
and coverage gaps. Three stale meeting-room parameter names were
corrected; the CLI passes unknown fields through without validation, so
the stale names would silently book the wrong room. MIT attribution is
carried by `NOTICE` and `third_party/wecom-cli/LICENSE` in the content
repository.

### Validation

0 errors from the catalog and i18n validators; collection children check
passes. The 129 warnings all belong to pre-existing entries.

### Known risk

The Market Agent install path has never been exercised by a real user (0
installable agents in production; unit tests only). Post-merge, install
should be verified on a real client, and uninstall re-verified after a
restart.
2026-09-04 00:46:33 -04:00
a8361009b9 feat(dingtalk-workspace): add USAGE.md and wire feature docs into skill references (#113)
## 背景 / Background

`agents/dingtalk-workspace` 条目把 13 篇使用文档放在 `docs/` 目录,但**两侧都读不到**:

- 市场详情页只渲染 `agent.json` 的元数据字段,不扫描条目目录下的 `docs/`
- Agent 自身的上下文只挂载 `persona.md` / `principles.md` / `memory/` /
`skills/`,`docs/` 不在其中

The listing kept 13 usage documents under `docs/`, but nothing consumed
them: the
market detail page only projects `agent.json` metadata, and the agent's
own context
mounts `persona.md` / `principles.md` / `memory/` / `skills/` only.

## 变更 / Changes

配合 DesireCore 主仓库的 `USAGE.md` 平台约定(ADR-143)与既有技能 `references` 机制,分别解决两侧。
Pairs with the new `USAGE.md` platform convention (ADR-143) in the
DesireCore repo.

| 变更 / Change | 说明 / Detail |
| --- | --- |
| 新增 `USAGE.md` | 安装前该知道的内容:第三方 CLI 依赖声明、5
步快速开始、六种审批模式取舍、安全与已知边界。**刻意不含图片**——详情页的 markdown 渲染器会移除普通 `img src` |
| 新增私有技能 `dingtalk-guide` | 只做索引,正文用 `${SKILL_DIR}/references/` 绝对路径指向
13 篇文档,Agent 按需 `Read`。单产品问题(如「钉盘同步怎么用」)可触发查文档再作答,不占每轮上下文 |
| `docs/` → `dingtalk-guide/references/` | 整体移入并拍平。原 12
篇无交叉链接、无图片,移动无需改写正文 |
| `docs/README.md` 拆分 | 安装部分 → `USAGE.md`;界面与审批部分连同两张截图 →
`references/界面与审批.md` |
| `README.md` | 补 `USAGE.md` 约定说明与目录树条目 |
| `manifest.json` | 1.5.0 → 1.5.1(条目内容新增;计数不变,经校验器实跑确认) |

**单一真相源 / Single source of truth**:每篇文档只有一份,归 `dingtalk-guide` 技能所有;
不存在 `docs/` 与 `references/` 两份副本。`dingtalk-onboarding` 与
`dingtalk-workflows`
两个既有技能不变。

## 校验 / Validation

README 记录的 7 条 CI 校验命令全部实跑通过(改动前后各一轮):

```
scripts/i18n/test_validate_i18n.py                              exit=0
scripts/catalog/test_validate_catalog_metadata.py               exit=0
scripts/catalog/test_collection_generator.py                    exit=0
scripts/catalog/validate_catalog_metadata.py --require-complete  exit=0
scripts/i18n/validate-i18n.py                                   exit=0
scripts/i18n/translate.py --check                               exit=0
scripts/gen-collection-children.py --check                      exit=0
```

`manifest.json#stats` 由 `validate_catalog_metadata` 输出实跑确认(agents=3,
teams=1,
publishableSkills=69),非算术推导,故不变。

## 公开信息边界 / Public information boundary

全树扫描零命中:改动文件、新增路径名、分支名、commit 主题与正文、本 PR 文本均不含
租户/客户/伙伴/个人身份。两张截图已逐张目视复核——仅含 DesireCore 自身界面、Agent 名称与
通用 `dws` 命令,返回结果为空列表,不含组织名或任何组织形态。

Full-tree scan returned zero results. Both screenshots were reviewed
individually:
they show only DesireCore's own UI, the agent name, and generic `dws`
commands.

## 依赖 / Dependency

`USAGE.md` 的详情页渲染依赖 DesireCore 主仓库的配套 PR。在其发布前,本条目的
`USAGE.md` 仍是仓库内可读的普通文件,不影响现有行为。

Detail-page rendering depends on the companion PR in the DesireCore
repository.
Until it ships, `USAGE.md` is simply a readable file in the listing and
changes nothing.
2026-09-04 00:08:53 -04:00
aec2e7c28b feat: 新增企业微信助手 Agent,并修正 wecom-cli 条目 ref 漂移 (#112)
## 概述 / Overview

两件事:新增「企业微信助手」Agent(自带 15 个技能),并修正 `wecom-cli` 条目钉在 6 月快照的 ref 漂移。

Two changes: adds the **WeCom Assistant** agent (bundling 15 skills),
and fixes the `wecom-cli` entry whose pinned ref was stuck on a June
snapshot.

## 1. 新增企业微信助手 Agent

覆盖企业微信 **14 类服务、95
个方法**:消息、群聊历史、通讯录、日程、会议、待办、邮件、在线文档、在线表格、智能表格、智能文档、文档管理、微盘、媒体文件。

**采用内联形态 + 自带私有技能**:Agent 安装对 `agents/<id>/` 整目录递归复制且 `skills/`
不在排除集合里,因此装 Agent 即带全部技能,用户无需再单独获取技能合集。

### 技能集(15 个,约 5000 行)

- 基于上游 [wecom-cli](https://github.com/WecomTeam/wecom-cli) 官方
Skill(MIT,© WecomTeam)改写,每个技能末尾保留归属声明
- **新增 `wecom-chat`**:补齐上游零覆盖的群聊历史读取
- 补齐上游未覆盖的 `message.send`、`doc.create`,方法覆盖达 **95/95**
- 修正上游三处文档漂移:邮件能力描述与实际相反、会议室参数名已过时、`title_highlight` 字段不存在

### 相对上游的核心增量:风险治理

- 26 个对外可见或不可逆的方法逐个写明**执行前确认要求**
- 4 个条件升级方法给出**参数级判据**,而非按方法名一刀切
- 文档权限扩散两项加重处理,涉及**企业外可见**时单独再确认一次
- 内部标识禁止外露,不因用户索要而放宽
- 拒绝导出可识别到具体自然人的隐私字段

### 三条真机实测得出、上游未覆盖的硬约束

1. 机器人**只能写入/修改自己创建的数据**,真人创建的只能读
2. 每次响应携带的 `extra_identity_context` **禁止透露给用户**
3. 权限错误(`850002`/`851008`/`853006`)**不得重试**,须将 `help_message`
**逐字原样**转给用户

## 2. 修正 wecom-cli 条目 ref 漂移

`source.ref` 原钉在 2026-06-28 的 `72e14f7`,该快照只有 7
个子技能且用已废弃的旧命名(`msg`/`schedule`)。上游 v1.2.0 已扩展到 **14 个**技能。按旧 ref
安装的用户拿到的是三个月前的快照。

- `source.ref` → `78c514b2afee7c0d3d7be715628478421f37ee63`
- `children` 由 `scripts/gen-collection-children.py` 重新生成,**7 → 14**
- sidecar 同步 `provenance.content.ref`、`childCount` 与 `children`

## 验证 / Verification

**静态**
- 215 条示例命令追加 `--dry-run` 实跑,**215/215 退出码 0**
- 未知方法 0、未知参数 0、`--json` 未知字段 0、枚举违规 0
- 15 个 `SKILL.md` 的 frontmatter 经客户端 `skillFrontmatterSchema` 校验全部通过
- `validate_catalog_metadata.py --require-complete` 与
`gen-collection-children.py`:**0 error**

**真机(在真实企业微信账号上端到端)**
- **待办域 6/6 方法全通**(含 2 个 write-high),`items` 必填的隐蔽坑实测证实
- **日程域 5 个方法全通**(含 3 个 write-high)
- 消息发送、通讯录解析、微盘列表、邮件搜索、文档搜索、会议列表、智能表格创建均已实测通过
- 测试数据已全部清理,未污染真实账号

**尚未实测**:群聊历史(机器人未开通该品类)。相关文档已明确标注验证状态,未实测的能力不写「实际效果」段落。
2026-09-03 03:50:00 -04:00