Commit Graph
187 Commits
Author SHA1 Message Date
chenchenandClaude Opus 4.8 612cccecb7 docs(telemetry): production enablement checklist 定稿 (#44)
#44 的「生产开启 telemetry 前置 checklist 定稿」工程交付:
docs/integration/telemetry-production-enablement-checklist.md。

涵盖:① 代码侧控制核验(默认 off/410、白名单 #42、8KiB 上限、保留期 #43、服务端脱敏、
不计费)② 生产配置确认(HEICODE_TELEMETRY_ENABLED/RETENTION_DAYS 等)③ 隐私/法务
签字硬前置(设备 ID 可关联账号披露 + 法务签字,owner=文档/合规,口径 @Fasthei;跟踪 #34)
④ 上线/回滚验证(410 基线→开启→抽查脱敏→回滚演练)⑤ 结论门。docs README 已索引。

完成 #44 的 checklist 定稿 DoD;隐私披露(#34)与法务签字仍是开启的人工前置。Docs only。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-10 13:38:07 +08:00
zsbgnw12andGitHub da55285414 Merge pull request #50 from xmindlab-heicode/docs/hm-swarm-refresh-agent-swarm
docs(swarm): refresh HM-side swarm docs to current agent_swarm (repo name + model + contract)
2026-06-10 13:11:23 +08:00
zsbgnw12andGitHub 9ff0a7f9c5 Merge pull request #38 from xmindlab-heicode/docs/client-api-available-models-telemetry-usage
docs(client-api): available-models + config + telemetry + agent usage + #30 billing semantics (#35)
2026-06-10 13:11:19 +08:00
chenchenandClaude Opus 4.8 699fa5ef44 docs(swarm): refresh HM-side swarm docs to current agent_swarm state
HM 端文档里的蜂群描述还是旧的(错仓名 + 旧模型),据实更新为当前 agent_swarm:

- 仓名:`HeiCode-Swarm` → `agent_swarm`(GitHub xmindlab-heicode/agent_swarm;产品名 HeiCode Swarm)。
- 模型:旧「HM 主导编排 / 仅 /tasks」→ 当前 Master-Agent 编排(分解→派发专家并行→协作/移交→评审/重做→汇总;Orchestrator FastAPI + Redis + WebSocket + Prometheus)。
- 契约:agent_swarm 已起草正式契约 docs/integration/runtime-contract.md(对齐 heicode-am-contract),待 Manager Runtime Team 评审冻结;已实现 create/status/tasks/logs/events/metrics/workflow/diagnostics/stop/approvals(带 deployment_id)。
- issue 引用:`agent_swarm#1`(执行面缺口,已关闭)→ 活动 EPIC `agent_swarm#2`(主链路接入契约冻结);HM 侧前置 #45/#46。

文件:
- docs/integration/heicode-swarm-deferred.md:勘误抬头 + §1 模型/接入状态 + §2 归属表(仓名/契约/接口) + §4 收尾据实更新。
- heicode/docker-compose.azure-vm.yml:SWARM_RUNTIME_* 注释更正(agent_swarm,deferred,当前关闭)。
- Heicode-Manager-生产配置与账号交接清单.md §7 + Orchestrator 地址标签:加勘误 banner,保留 env 历史记录但标注为旧模型/当前关闭。
- docs/deployment/Heicode-Manager-更换部署服务配置清单.md §2.2:加勘误 banner。

HM 不实现 swarm runtime 的裁定不变;仅把"蜂群现状"事实对齐。未改 env 变量名/行为(SWARM_RUNTIME_* 仍 disabled),未动 legacy-teardown 历史记录。Docs/注释 only。

Affects: 文档/注释 only。无代码、无计费/审计/部署行为改动。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-10 12:15:57 +08:00
FastheiandGitHub c39ed6a070 Merge pull request #48 from xmindlab-heicode/feat/agent-preflight-checklist
feat(preflight): read-only preflight checklist + execution summary (#39, #40)
2026-06-10 12:08:51 +08:00
FastheiandGitHub a31745316b Merge pull request #49 from xmindlab-heicode/feat/agent-usage-budget-remaining
feat(usage): expose budget_remaining on agent usage endpoint (#9)
2026-06-10 12:08:23 +08:00
FastheiandGitHub b2f5f3c5ea Merge pull request #47 from xmindlab-heicode/test/telemetry-retention-purge-coverage
test(telemetry): cover retention purge deletion (#43)
2026-06-10 12:06:13 +08:00
chenchenandClaude Opus 4.8 df83588720 docs(client-api): add budget_remaining to agent usage §5.1 (#9)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-10 11:36:14 +08:00
chenchenandClaude Opus 4.8 46cc7293e2 feat(usage): expose budget_remaining on agent usage endpoint (#9)
#9 的最后一项 DoD「预算剩余」:GET /api/heicode/agents/:id/usage 新增
budget_remaining = 用户钱包剩余额度(int64;-1 表示读取失败,不阻断用量展示)。
Agent 模型调用经隐藏 token 计费到 user.Quota(#30),故"本任务预算剩余"= 用户剩余额度。
与既有 quota/quota_per_unit 同口径。

#9 的①审计脱敏(PR #11)+②deployment 维度用量(SumAgentUsage/usage 端点)此前已闭环,
本 PR 补齐 budget_remaining。文档 §5.1 随 PR #38 更新(usage 章节在该 PR)。

Affects: Manager only(usage 响应新增只读字段)。无计费/审计 schema 改动。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-10 11:34:24 +08:00
chenchenandClaude Opus 4.8 4502d6b5bc feat(preflight): read-only preflight checklist + execution summary (#39, #40)
新增 GET /api/heicode/preflight?template_id=&binding_ids=1,2,3 —— agent 启动前的统一
确认层(#29 EPIC 的 #39 缺失项检测 + #40 可读执行摘要):

- #39 缺失项检测:必需资源类别(git/sk/project_document/cloud_account)未绑定、budget
  (余额≤0)、agent_slot(在跑数达 tier 上限)。ready = missing 为空。
- #40 可读执行摘要:agent 角色、脱敏资源视图、高危操作、预算(剩余额度/quota_per_unit/
  tier 上限/当前在跑数)、审批策略。
  - 红线:resources 只暴露 type/provider/name/status/has_secret(布尔),绝不含
    secret_ref/channelId/base_url/price。
  - 高危操作固定 enum:production_deploy/db_write/cloud_resource_delete/
    production_secret/large_budget,由已绑资源类型推导,均 requires_approval。

判定逻辑抽为纯函数 computePreflight,单测覆盖:全缺失、就绪、槽位满、高危 enum、
敏感字段不泄露(序列化断言)。复用既有 ResourceBinding/模板/GetUserMaxAgents/部署门禁
口径,不改部署/计费逻辑。文档补 §4.1。

#41(confirm + 审计 + 防篡改版本校验)作为后续 POST /preflight/confirm 实现。

Affects: Manager only(新增只读端点)。无 Client/Swarm 代码改动,无计费/审计 schema 改动。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-10 11:29:34 +08:00
chenchenandClaude Opus 4.8 31bf13fc36 test(telemetry): cover retention purge deletion (#43)
#37 shipped the telemetry retention task + model.DeleteTelemetryEventsBefore but
lacked a test for the deletion itself. Add TestDeleteTelemetryEventsBefore
(strict-< cutoff, retains at/after, idempotent) and migrate TelemetryEvent in the
model TestMain so it has a table.

Closes the "测试覆盖过期清理" DoD item of #43. Test-only; no behavior change.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-10 10:37:44 +08:00
chenchen f1e0973103 Merge remote-tracking branch 'origin/main' into docs/client-api-available-models-telemetry-usage 2026-06-10 10:32:41 +08:00
FastheiandGitHub dc75485be8 Merge pull request #37 from xmindlab-heicode/feat/telemetry-retention-and-context-whitelist
feat(telemetry): retention purge + context field whitelist + size caps (#32)
2026-06-10 01:10:24 +08:00
FastheiandGitHub aea6b923d1 Merge pull request #36 from xmindlab-heicode/fix/agent-token-cryptosecret-and-purge-guard
fix(agent,secret): enforce CRYPTO_SECRET for agent deploy (#31) + guard unscoped vault purge (#33)
2026-06-10 01:08:45 +08:00
chenchenandClaude Opus 4.8 d2d9a22ae4 docs(client-api): add available-models, config, telemetry, agent usage + hidden-token billing semantics (#35, #30)
Bring docs/integration/heicode-desktop-client-api.md in lock-step with merged
endpoints:

- §3.1 /api/heicode/available-models: logged-in user model list is the single
  source of truth (no local presets / no CodeGW channel backend); exposes only
  model_id/display_name/default; forbidden fields enumerated.
- §5.1 /api/heicode/agents/{id}/usage: token-name aggregation, time window,
  empty-data semantics, relation to billing logs. Includes the #30 hidden agent
  model token billing-collection semantics: UnlimitedQuota only waives the
  token's own remaining-quota cap, it does NOT bypass user.Quota — HM still
  checks user quota and settles to wallet/subscription via the billing
  expression; token revoked on stop/delete; hidden from user UI but auditable.
- §7.1 /api/heicode/config: telemetry enabled/endpoint/max_batch/flush/retention_days.
- §7.2 /api/heicode/telemetry/events: default-off 410 kill switch, V2 device
  signature, top-level array 1-20 / <=256KB, server redaction, context field
  whitelist (#32), 4xx-drop/5xx-retry, retention; production enable-gate note.
- Updated §10 endpoint inventory.

Docs-only; no code change. heicodeDocs org-level sync tracked in #34.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-10 00:45:29 +08:00
chenchenandClaude Opus 4.8 2e37495133 feat(telemetry): retention purge + context field whitelist + size caps (#32)
Telemetry up-gating hardening (code portion of #32):

- Context field whitelist: telemetry `context` is filtered to a small set of
  non-content diagnostic keys (route/retryable/phase/exit_code/duration_ms/
  attempt) before persistence. Unknown keys — including potentially identifying
  ones (email, full file path, prompt, raw IP) — are dropped, so a client
  regression cannot land arbitrary JSON in the store. Empty/unparseable/no-allowed-key
  context is dropped to "".
- Per-field size cap: stack_top and context are truncated to 8KiB after
  redaction (backstop against unbounded blobs within batch limits).
- Retention: daily master-only task deletes telemetry rows older than
  HEICODE_TELEMETRY_RETENTION_DAYS (default 30; <=0 disables).
  HEICODE_TELEMETRY_RETENTION_INTERVAL_HOURS (default 24) sets cadence.
  model.DeleteTelemetryEventsBefore(cutoff) + controller.StartTelemetryRetentionTask()
  wired into main.go under IsMasterNode.
- GET /api/heicode/config telemetry block now surfaces retention_days for
  client/admin transparency.

Tests: whitelist drop/keep, size cap, redaction-within-allowed-key. go build/vet
clean; controller telemetry tests pass.

Affects: Manager only (telemetry ingest + retention). No billing/consume-log
change (telemetry still never bills). Privacy-doc disclosure + production
enable-checklist portions of #32 tracked in heicodeDocs sync (#34) / desktop
client API docs (#35).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-10 00:40:23 +08:00
chenchenandClaude Opus 4.8 8fe1f5e131 fix(agent,secret): enforce CRYPTO_SECRET for agent deploy (#31) and guard unscoped vault purge (#33)
#31: HeicodeDeployAgent now refuses to deploy unless CRYPTO_SECRET is explicitly
configured, so the per-agent access_token is sealed with a key that survives a
container restart. common.CryptoSecret is never literally "" (defaults to
uuid/SessionSecret), so the sealAgentToken plaintext fallback was effectively
unreachable; the real hazard is an ephemeral random seal key making tokens
undecryptable after restart. Dev-only override: HEICODE_ALLOW_PLAINTEXT_AGENT_TOKEN_IN_DEV=true.
Verified prod container has CRYPTO_SECRET set (64 chars) -> deploy stays allowed.

#33: StartSecretPurgeTask refuses to start a whole-vault purge when
HEICODE_SECRET_PURGE_NAME_PREFIX is empty unless HEICODE_SECRET_PURGE_VAULT_EXCLUSIVE=true,
so HM never permanently purges another tenant's soft-deleted secrets in a shared
vault. Logs the resolved purge scope at startup.

Both gates extracted into pure, unit-tested helpers (agentTokenSealKeyConfigured,
secretPurgeScopeAllowed). Affects: Manager only (Agent deploy + Secret lifecycle).
No Client/Swarm/billing/audit schema change.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-10 00:33:47 +08:00
818f1412d5 feat(heicode): 客户端错误遥测上报端点(默认关闭)(#24) (#27)
* feat(heicode): 客户端错误遥测上报端点(默认关闭)(#24)

按客户端 winos#23 契约 + 权威 schema 实现,结合 HM 入库逻辑:

- POST /api/heicode/telemetry/events,挂 UserOrV2DeviceAuth(设备配对鉴权)。
- 接收顶层 JSON 数组(非包裹),批量 1-20、<=256KB;校验 body client_id 等于已验签
  设备(X-Heicode-Device-Id),不一致 403;无设备身份拒绝。
- 真实 4xx/5xx 码(400 非数组、413 超限、403 设备、410 关闭),让客户端"4xx 丢弃"
  语义生效;2xx 返回 {accepted:n}。
- 独立表 telemetry_events,与计费完全隔离:不写 consume log、不碰 quota。
- 宽松入库(最大化采集):未知枚举 / 哨兵 app_version(0.0.0-heicode-local)/ 缺字段
  原样入库;schema_version 缺省 1;stack_top/context 存 TEXT(JSON);记 user_id 作
  device 到 account 关联 + 服务端 received_at。
- 默认 HEICODE_TELEMETRY_ENABLED=false 时返回 410(kill switch);隐私政策更新 +
  端点下发形态确认前不开启外发。

测试用客户端仿真夹具:parseTelemetryBatch / toModel 映射与默认 / 拒绝非数组,全过。

Refs #24(上线门槛:隐私政策 §2 如实披露 + 下发形态 + 去重;见工单评论)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* feat(heicode): GET /api/heicode/config 下发 telemetry 配置/kill-switch (#24)

按客户端 #24 拍板:选独立 config 端点(而非塞登录响应),便于 kill switch 在
会话内传导、不依赖重登录。返回 telemetry 块 {enabled, endpoint, max_batch,
flush_interval_sec};enabled 取 HEICODE_TELEMETRY_ENABLED(默认 false)。
未鉴权全局只读(同 capabilities 姿态)。

测试 heicode_config_test.go:enabled 反映 env、endpoint 与摄入路由一致、缺省 false。

Refs #24

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix(telemetry): 服务端二次脱敏 stack_top/context + 明确生产门槛 (#24 review)

按 Fasthei 复审意见补隐私门槛:

- 服务端纵深防御脱敏:新增导出 model.RedactText(包装已上线的 redactAuditSecrets,
  #11),在 telemetry 入库前对 stack_top / context 再脱敏一遍(sk-/Bearer/URL
  token/JSON 密钥字段),即便客户端漏脱敏也不会把明文密钥落库。
- 测试 TestTelemetryToModel_RedactsSecrets:stack_top 里的 sk-、context 里的
  Bearer token 被打码,非密钥内容保留。
- 端点默认 HEICODE_TELEMETRY_ENABLED=false,关时 410;隐私政策披露完成前生产
  不得开启外发(见 #24 评论记录产品/法务状态)。

go build / vet 干净;controller 测试通过。

Refs #24

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: chenchen <chenchen@xinghanlab.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 22:16:29 +08:00
FastheiandGitHub 758e2d0342 Merge pull request #26 from xmindlab-heicode/feat/heicode-available-models
feat(heicode): /api/heicode/available-models 客户端模型列表收口 (#25)
2026-06-09 16:29:35 +08:00
FastheiandGitHub 3e0c935ad0 Merge pull request #20 from xmindlab-heicode/fix/secret-lifecycle-purge-rotate-cleanup
fix(secret): 闭合 #4 secret 生命周期 — 账户停用全量清理 + 30天 purge + 显式轮换
2026-06-09 16:25:51 +08:00
chenchenandClaude Opus 4.8 79e0e8b7d1 feat(heicode): 新增 /api/heicode/available-models,客户端模型列表收口 (#25)
客户端需要 Manager 下发用户可用模型作唯一来源(里程碑04 收尾)。

- GET /api/heicode/available-models(挂 UserOrV2DeviceAuth,与 /api/heicode/self 同
  设备配对鉴权)。
- 服务端解析:user.Group → service.GetUserUsableGroups → model.GetGroupEnabledModels
  (与 GetUserModels 同源),去重排序。
- 客户端安全形状 {model_id, display_name, default}:绝不下发 channelId/base_url/
  api_key/provider_type/单价(buildAvailableModelItems 纯函数 + 测试断言不泄露)。
- default 标记取 defaultAgentModelID()。

可选字段 capabilities/context_window/cost_tier 暂不下发(HM 无可靠来源,避免臆造;
客户端按可选处理)。etag/updated_at 可作后续。

Fixes #25

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 15:51:21 +08:00
7d56b54324 feat(agent): 部署上限按订阅档动态化,闭合 #8 个人5/团队8 (#21)
沿用订阅体系现成先例 MaxPurchasePerUser,给 SubscriptionPlan 加 MaxAgents:

- model: SubscriptionPlan.MaxAgents(0=回退全局默认)+ GetUserMaxAgents(取用户
  active 订阅档最高 MaxAgents,无则回退默认)。
- HeicodeDeployAgent: 部署上限改 model.GetUserMaxAgents(userID, 环境默认5)。
  团队8=管理员把团队档配成8;个人5=默认;代码不硬编码 tier。
- subscription 控制器: Create/Update 校验 MaxAgents>=0;Update updateMap 补 max_agents。
- 前端管理端套餐表单(plan-form/types/drawer)加「Agent 部署上限」字段 + zh i18n。

测试 model/subscription_max_agents_test.go 全过(无订阅/团队档/0回退/过期/多档取最高/非法用户)。
go build、go vet、前端 tsc 干净。

Fixes #8

Co-authored-by: chenchen <chenchen@xinghanlab.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 14:28:19 +08:00
af094dde27 feat(agent): 按部署 agent 聚合模型用量,闭合 #9 用量聚合 (#22)
#9 的审计脱敏半部已由 PR#11 完成。据评审报告(L95 usage/billing 结构完整、
L112 监控 mock metrics 属 AM)核实:HM 侧通用用量聚合并不缺,真正缺的是
agent 维度用量视图。

- model.SumAgentUsage(userId, tokenName, start, end):按 agent 铸币 token 名
  'agent:<deployment_id>' 聚合 consume 日志(quota/prompt/completion/调用数),
  COALESCE+COUNT/SUM 跨 SQLite/MySQL/PG。
- GET /api/heicode/agents/:deployment_id/usage:返回该 agent 用量 + quota_per_unit
  (raw,调用方换算,与 /api/heicode/self 同契约),支持 ?start=&end= 时间窗。
- 测试 model/agent_usage_test.go:聚合正确、排除他人/非消费/不同 token、时间窗、空名。

go build/vet 干净;测试 PASS。

Refs #9 (审计脱敏半部 PR#11 已完成;监控 mock metrics 属 AM 侧)

Co-authored-by: chenchen <chenchen@xinghanlab.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 14:27:48 +08:00
aa4041f604 fix(web): 钱包余额直读 /api/user/self(去 502) + 部署完成提示/动画 (#23)
两处 HM web 前端修复(此前已热部署到 VM 验证):

1. 钱包 502:wallet 不再经 /api/heicode-auth → mcp-server 读余额(那条会触发
   HM GetUser 同级权限检查 → 502)。HM 本就是 new-api,直接读用户自己的
   /api/user/self(GetSelf,无角色检查)。
2. 异步部署无反馈:deploy-agent-page 加快轮询(启动中 3s/稳定 30s)+ 检测
   Pending→running 弹「✅ 部署完成,已就绪」(失败弹错误)+「启动中」徽章转圈脉冲。

tsc 干净。

Co-authored-by: chenchen <chenchen@xinghanlab.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 14:27:19 +08:00
chenchenandClaude Opus 4.8 57f475b15a fix(secret): 闭合 #4 secret 生命周期 — 账户停用全量清理 + 30天 purge + 显式轮换
承接 PR#13(撤销时删 KV secret)的剩余生命周期:

- 账户停用/删除全量清理:新增 revokeUserResourceSecrets(userID),撤销该用户全部
  带 secret_ref 的资源绑定并 best-effort 软删 KV 凭证材料(DB 标 revoked 为权威,
  KV 故障只记日志不阻塞)。接入 4 个账户路径:ManageUser disable/delete、
  DeleteUser(管理员硬删)、DeleteSelf(自助删)。
- 30天 purge:新增 listDeletedSecrets(GET /deletedsecrets 分页)+ secretExpired
  纯函数 + purgeExpiredVaultSecrets;StartSecretPurgeTask 每日(可配)purge 软删
  ≥30天(可配)的 secret,master 节点执行,KV 未配置则 no-op,purge-protection
  下安全 no-op(403 容错)。env:HEICODE_SECRET_PURGE_ENABLED/RETENTION_DAYS/
  INTERVAL_HOURS/NAME_PREFIX。
- 轮换显式化:UpsertResourceSecret 已有 secret 时改用 rotateSecret(同名新版本)
  并审计日志,而非每次 putSecret。

测试:parseDeletedSecretsPage / secretExpired / lastPathSegment 纯函数 +
revokeUserResourceSecrets 在 KV 未配置下仍正确标记 revoked、不误伤他人/无密钥绑定。

Refs #2 (secret_store delete/rotate/purge 部分;Manager↔Swarm 契约属 Swarm 侧)
Fixes #4

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 00:55:09 +08:00
FastheiandGitHub 03b9b24e45 Merge pull request #18 from xmindlab-heicode/fix/async-agent-deploy
fix(agent): 部署 agent 改异步,避免 Azure 网关 504 + 回滚
2026-06-08 18:08:17 +08:00
FastheiandGitHub 206fee1f78 Merge pull request #14 from xmindlab-heicode/feat/heicode-self-quota-display-type
feat(heicode-self): /api/heicode/self 返回 raw quota + quota_per_unit(与网页台同源换算)
2026-06-08 17:52:46 +08:00
zsbgnw12andGitHub 9444cdb498 fix agent deploy caps
approved
2026-06-08 17:49:35 +08:00
FastheiandGitHub 932b429a5d Merge pull request #15 from xmindlab-heicode/docs/hm-only-doc-sync
docs: 清理旧 HM 编排文档并新增蜂群 deferred 跟踪(HM-only 仓 + 模板 Agent 模型)
2026-06-08 17:42:43 +08:00
chenchenandClaude Opus 4.8 349957360d fix(heicode-self): quota_display_type 补 CUSTOM + 统一大写 + 加 displayQuota 测试
按 Mem0ried 复审:
- quotaDisplayUnitLabel 补 QuotaDisplayTypeCustom 分支(原落 default→"USD",
  导致自定义币种站点 display_quota 算对但 type 误报 USD、客户端配错符号)。
- tokens 标签由小写 "tokens" 改为规范常量 TOKENS,displayQuota 的判断同步用常量,
  对外 quota_display_type 统一大写(与 USD/CNY/CUSTOM 一致,客户端按常量比较不再 mismatch)。
- 新增表驱动测试 heicode_self_test.go:displayQuota 四模式(USD 除 / CNY·CUSTOM 乘 /
  TOKENS 原值)+ per_unit<=0 防除零;quotaDisplayUnitLabel 四模式(含 CUSTOM 回归)。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 17:34:03 +08:00
chenchenandClaude Opus 4.8 f6da9c541e fix(agent): 异步回填加 Pending 状态守卫,避免覆盖用户 stop/delete
按 Fasthei 复审意见修并发状态机边界:
- 成功/失败回填都加 WHERE deployment_id=? AND LOWER(status)='pending',
  让 Pending->running / Pending->failed 成为 own-or-nothing 转换。
- 成功但 0 行(用户在 AM 启动窗口内 stop/delete/cancel):重读记录记日志,
  删除 AM 刚起的 orphan runtime,绝不把记录改回 running。
- 失败仅在我方拥有 Pending->failed 转换时才 revoke model token;用户已 stop/delete
  时交给对应路径(delete 已 revoke、stop 有意保留 key),避免重复/遗漏。
- 补竞态测试 StoppedDuringStart_NoResurrect:AM 启动被 hold 到记录置 stopped 后才返回,
  断言记录保持 stopped、不回填 runtime_id、orphan runtime 被删除。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 17:17:40 +08:00
chenchenandClaude Opus 4.8 da854277d3 test(agent): 异步部署的确定性测试(不阻塞 + Pending→running / →failed)
- 慢 AM mock 验证 startTemplateAgentAsync 立即返回(不阻塞 30s)。
- Pending 记录在 AM 响应后自动回填 running + runtime_id + subdomain。
- AM 失败时记录标 failed + failure_reason,不卡在 Pending。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 16:48:29 +08:00
chenchenandClaude Opus 4.8 a1a5b6037b fix(agent): 部署 agent 改异步,避免网关 504 + 回滚
POST /api/heicode/agents 原本在请求里同步阻塞 ~30s 等 AM 起 agent。Azure 网关
~20s 超时 → 504 → 请求 context 被取消 → AM 调用中止 → 部署回滚(agent 建不出)。

改为:先把 agent 存为 Pending 立即返回;AM 启动放到 context.Background() 的后台
goroutine(脱离请求 context),成功回填 subdomain/runtime_id/status,失败标记
status=failed 并吊销已铸的模型 key。客户端经已合并的列表刷新看 Pending→running。

go build ./... 通过;controller vet 干净。

影响面:仅 Manager(HM) 部署路径。客户端契约:deploy 现在立即返回 Pending(原为
阻塞后 running 或 504);AM 失败在列表里表现为 status=failed(原为同步
RUNTIME_UNAVAILABLE)。客户端本就轮询列表等 running。不改计费/密钥/审计。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 16:43:46 +08:00
zsbgnw12andGitHub b3d864b29b fix(agent): refresh list status from AM
Refresh non-terminal agent statuses before returning /api/heicode/agents.
2026-06-08 16:22:21 +08:00
chenchenandClaude Opus 4.8 ce733defcb feat(heicode-self): complete quota contract for all display types (#14 review)
Returns raw quota + the full conversion params (quota_per_unit, quota_display_type,
usd_exchange_rate) AND server-computed display_quota / display_used_quota, so the
desktop client renders correctly in USD / CNY / tokens without a ×500000 hack or a
missing-exchange-rate bug. Contract of record (server applies it):
  USD    : raw / quota_per_unit
  CNY    : raw / quota_per_unit * usd_exchange_rate
  tokens : raw (no division)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 15:36:55 +08:00
cbbdd66c2e docs(reference): correct permission-modes precision per official en page (#16)
Verified against code.claude.com/docs/en/permission-modes and fixed 6 points:
1. acceptEdits: add PowerShell tool auto-approvals (Set-Content/Add-Content/
   Clear-Content/Remove-Item + aliases) and env-prefix/process-wrapper note.
2. Protected paths: .claude exception is ONLY .claude/worktrees (was wrongly
   widened to commands/agents/skills); add per-mode protected-write table.
3. defaultMode:"auto" ignored from project files since v2.1.142+.
4. dontAsk: read-only Bash commands also run without allow rules; explicit ask
   rules are denied (not prompted).
5. auto conversational boundary: stays in force until user lifts it; Claude's own
   judgment doesn't lift it; lost on context compaction; use deny rule for hard.
6. auto consecutive-failure fallback: 3-in-a-row / 20-total pauses & re-prompts;
   -p non-interactive aborts the session. Plus dropped broad allow-rules on entry.

Co-authored-by: chenchen <chenchen@xinghanlab.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 15:26:52 +08:00
efb0016f5c fix(secret): 撤销资源时删除 Key Vault 凭证材料 (#4) (#13)
#4:撤销资源此前只把 DB 状态置 "revoked",真凭证仍留在 Azure Key Vault。
现在 DeleteResource 同时删除 KV 中的 secret(best-effort:DB 撤销已提交,
外部 KV 失败只记日志、不阻塞响应)。

- secret_store.go:新增 deleteSecret / purgeSecret / rotateSecret
  (AKV REST,api-version=7.4,与 putSecret/getJSONSecret 同风格;404 幂等)。
  ※ 该文件受组织权限策略保护、自动化无读写权,本段由 HM owner 手动粘贴,
    审阅者请核对其与本意一致。
- resource.go:DeleteResource 在撤销事务提交后调用 deleteSecret(resource.SecretRef)。

本轮为 #4 最小修复(堵住"撤销后 KV 材料残留"的洞)。后续仍待:
purgeSecret 接入 30/90 天生命周期、轮换流程。

go build ./... 与 go vet 通过。

影响面(组织规则第 10 条):仅 Manager(HM) —— 涉密钥/安全/审计。
不影响 Client / Swarm / AM 契约 / CodeGW / 计费 / 发布链路。

Refs #4

Co-authored-by: chenchen <chenchen@xinghanlab.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 15:26:47 +08:00
chenchenandClaude Opus 4.8 09331752f2 docs: address review — add swarm-deferred tracking entry + migration mapping
Per Fasthei's CHANGES_REQUESTED on #15: deleting all sub/swarm docs left no
tracking entry for the still-in-development swarm capability. Adds
docs/integration/heicode-swarm-deferred.md stating HM does not implement swarm
runtime, the old HM-orchestrated sub/swarm model is deprecated, new swarm work
lives on AM/Swarm side, and a per-file migration mapping (deprecated / deferred
/ superseded) for all 11 deleted docs. Links it from docs/README.md so deletion
no longer drops context.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 15:19:17 +08:00
chenchenandClaude Opus 4.8 11f399826c docs: 删除已废弃的蜂群 / 旧计划文档
蜂群(swarm)旧版已弃、新版未出 → 删全部蜂群文档;附带删除旧执行/改造计划与旧项目交接稿(均为已废弃旧产物,由 HM owner 确认)。docs/README 当前索引不引用它们,无死链。

删除:
- docs/heicode-manager-sub-swarm-progress-checklist.md
- docs/heicode-manager-swarm-gap-analysis.md
- docs/heicode-manager-standalone-execution-plan.md
- docs/integration/agent-manager-swarm-runtime-change-request.md
- docs/integration/heicode-manager-swarm-runtime-env-template.md
- docs/integration/AgentManager蜂群Runtime接口实现要求.md
- docs/integration/AgentManager蜂群Runtime联调待确认与补充要求.md
- docs/integration/蜂群模式-AgentManager对接任务清单.md
- docs/Heicode-Manager-agent统一改造落地计划.md
- Heicode-Manager-项目说明与踩坑交接.md

影响面:仅文档。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 13:29:06 +08:00
chenchenandClaude Opus 4.8 c9767eb6bb docs: 同步文档到当前实际(HM-only 仓 + 模板 Agent 模型)
- 根 README/CLAUDE/AGENTS:本仓已从 monorepo 拆分,只剩 Heicode Manager(heicode/ Go 网关 + docs/)。重写仓库地图为 HM-only;客户端指向 heicode-{mac,win}os-release-dev 独立仓;移除指向已删文档的死链(vision/milestones/agent-platform-api-design/cc-haha-AGENTS);开发闭环改为 heicode/。
- 删除 docs/integration/agent-platform-request-contract.md(已被 AM 契约取代);docs/README 索引去掉该条。
- product-package 03/12:执行闭环去掉「Heicode 生成/判断子环节」旧编排说法,改为客户端直连 agent、agent 自驱、模型走 HM /v1。

影响面:仅文档。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 13:03:48 +08:00
chenchenandClaude Opus 4.8 9027f461c4 refactor(heicode-self): 返回 raw quota + quota_per_unit(与网页台同源换算)
按 HM owner 要求:客户端换算余额应与网页台完全一致。网页台用
raw_quota / quota_per_unit(web renderQuotaCompat,quotaPerUnit 默认 500000、
系统设置可配)。原 /api/heicode/self 预先除好(quotaToDisplayUnit)反而与网页台
不一致、并迫使客户端 ×500000 回推。

改为返回原始 quota/used_quota + quota_per_unit + quota_display_type,
客户端直接 quota / quota_per_unit 即可,和网页台同一公式,去掉所有缩放 hack。

移除不再使用的 quotaToDisplayUnit。go build/vet 通过。

影响面:仅 Manager(HM),服务桌面客户端余额展示(响应字段语义调整:quota 由
展示值改为原始值,新增 quota_per_unit)。需客户端同步按 quota/quota_per_unit 换算。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 11:26:52 +08:00
chenchenandClaude Opus 4.8 4476851286 feat(heicode-self): GET /api/heicode/self 返回 quota_display_type
桌面客户端余额查询应统一走 /api/heicode/self,其 quota/used_quota 已由
quotaToDisplayUnit 换算成展示单位(默认 USD = raw/QuotaPerUnit)。但响应未
告知客户端当前是哪种单位(USD/CNY/tokens),客户端易再除 500000 导致量级出错。

新增 quota_display_type 字段("USD" / "CNY" / "tokens"),客户端据此直接展示
quota、不再二次换算。

影响面:仅 Manager(HM),对客户端余额展示。新增响应字段、向后兼容;不影响
计费/密钥/审计/Swarm/AM。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 01:10:22 +08:00
zsbgnw12andGitHub 696dfecc9d docs(heicode): set Azure Key Vault as secret-store baseline
Align Manager docs with code-enforced azkv:// secret_ref baseline.

Reviewed: docs-only, no code/runtime impact. Follow-up required in heicodeDocs to remove OpenBao/vault:// drift.
2026-06-07 22:49:58 +08:00
zsbgnw12andGitHub 6d360454dd fix(relay): return errors instead of panic for Claude conversion stubs
Replace unimplemented ConvertClaudeRequest panic stubs with explicit not implemented errors across 11 relay adaptors.

Reviewed: narrow relay hardening only; no billing/secrets/Agent-Swarm/product semantic changes.
2026-06-07 19:59:21 +08:00
chenchenandClaude Opus 4.8 c220dc75da docs(reference): make Claude controls digest clearer & complete
Adds a reading guide, the full 6 permission modes (incl. dontAsk) + auto-mode
admin enablement toggle, confirmed role facts (UsageView roles; full matrix is
external; iam pages 404), deep permission-rule syntax (Bash spacing, Read/Edit
anchors, MCP/Agent), real MCP credential mechanisms (headersHelper/${VAR}/OAuth),
expanded usage/cost/attribution/analytics, plus two big appendices: verbatim
config examples (A1–A10) and step-by-step end-to-end flows (managed-settings
lifecycle, MCP allow/deny worked example, auto-mode force-push decision, auth
credential selection). Sourced from re-fetching the 6 core docs + permission-
modes/permissions/mcp/costs/monitoring-usage/analytics.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-05 17:04:29 +08:00
chenchenandClaude Opus 4.8 5dc99946f0 docs(design): HM product tiers (Individual/Teams/Enterprise) + commercialization boundaries
Aligns HM's capabilities to three tiers mirroring Claude's proven split, grounded
in HM's existing primitives. Defines positioning + billing per tier, a capability
× tier matrix (use layer = Individual; manage/allocate = Teams; compliance/hard-
enforcement/private = Enterprise) with HM code landing points, the Teams-hook vs
Enterprise-moat rationale, HM's differentiators over Claude (gateway-side hard
cost control, signed per-org policy push, server-side hard enforcement, native
agent catalog), a P0–P3 rollout mapping, and the open pricing decisions to settle.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-05 16:53:44 +08:00
chenchenandClaude Opus 4.8 12f3cf21df docs(reference): add Individual/Teams/Enterprise tier breakdown to Claude digest
Expands §1.2 into a proper three-tier section: positioning per tier, a
capability × tier table (with source + whether the doc is explicit), the
billing differences, and the documented contradiction (authentication lists
"managed policy settings" as Enterprise-only while the server-managed-settings
feature page says Teams+ can use it). Also flags that most controls hinge on
provider (Anthropic-direct + admin write access) rather than subscription tier.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-05 16:41:58 +08:00
chenchenandClaude Opus 4.8 edb7090055 docs(reference): faithful Claude Code enterprise controls digest (zh)
Standalone reading reference faithfully consolidating the six official Claude
docs (admin-setup, authentication, server-managed-settings, settings,
managed-mcp, auto-mode-config): auth methods + precedence, roles/seats/admin,
settings scope precedence & merge rules, server-managed-settings mechanism,
full managed-only/permissions/model/sandbox/MCP key reference, managed-mcp
seven modes + allow/deny evaluation, auto-mode classifier, usage/audit, and
quick-reference tables. No HM design — pure Claude reference for study.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-05 16:34:29 +08:00
chenchenandClaude Opus 4.8 88240dc79e docs(design): HM team-control design referencing Claude Code enterprise paradigm
Synthesizes Claude's admin-setup/authentication/server-managed-settings/settings/
managed-mcp/auto-mode docs into a team-management design for HM, mapped onto the
analogy (client≈Claude Code, HM≈Claude.ai admin console, AM≈cloud agent) and
grounded in HM's existing primitives (new-api users/groups/sk-token model-limits/
quota, plus our V2 device auth, resource bindings, agent templates, /v1 gateway).
Covers org/team/seat model, roles, allocation, managed-settings push over the V2
channel, managed agent/tool catalog, auth/SSO, auto-mode, audit, and a phased plan.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-05 16:27:50 +08:00
chenchenandClaude Opus 4.8 f4968b8072 fix(agent): review fixes — deployable-template gating, stopped-status guard, UI consistency
Backend:
- loadAgentTemplate now requires status='active' — a known template_key can no
  longer deploy a template an admin deactivated (matches the client list).
- refreshAgentStatus no longer lets AM's eventually-consistent live status
  resurrect a user-initiated "stopped" agent.
- HeicodeStopAgent persists via field-level Updates (not a stale full-row Save),
  matching refreshAgentStatus discipline.
- Drop dead amStartResult.AccessToken field (AM's token is never used; HM mints
  its own per-agent token).

Frontend:
- deploy-agent statusLabel: add the missing pending/starting → 启动中 branch so a
  just-deployed agent isn't shown as raw English fallback.
- cockpit 最近部署: map template_id → Chinese template name (consistent with the
  deploy/status pages) instead of showing the raw key.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-05 11:06:49 +08:00