chenchen and Claude Opus 4.8
56a9b02a25
feat(swarm): adopt frozen agent_swarm contract v1 (read-side) (#45/#46)
...
按 agent_swarm#14/#15 冻结契约做 HM 读侧适配(客户端 #28 消费):
- 注册 6 类新事件(event-schema v1):swarm.completed/failed/stopped、approval.approved/rejected、
handoff.created(categories + requiredFields 两表;必填先最小集,待 agent_swarm PR #28 §4 精校)。
- AgentCallbackEvent 增 Sequence(per-swarm 严格递增序号),回调入库透传 envelope.sequence;
事件视图暴露 sequence 供客户端去重/排序。游标仍用稳定 id(next_after)避免 sequence 未全量
上线时回归。
- 脱敏键补 credential_ref/signing_secret_ref(envelope 按设计透传 azkv:// 引用,客户端视图剔除)。
- artifact.created → 扁平视图 {uri,checksum,task_id,size_bytes?,created_at}(无 secret_ref;
size 未知省略不伪造)。
- 状态展示映射 §4.1:display_status(blocked→degraded;不臆造 preparing/verifying)。
测试:状态映射、artifact 视图(脱敏 + size 省略)、6 类事件注册;controller+model 全回归通过,
go build/vet 干净。文档 §5.2 更新。
未含(下一 PR):stop 真实运行时接入(写路径,复用 agentRuntimeClientConfigForMode("swarm"))。
Affects: Manager only(只读查询契约适配)。AgentCallbackEvent 加列(AutoMigrate);无计费改动。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-06-10 18:01:32 +08:00
Fasthei and GitHub
3af911257f
Merge pull request #56 from xmindlab-heicode/feat/agent-endpoint-security-scheme
...
feat(agent): return A2A endpoint security scheme/profile (#55 )
2026-06-10 16:27:34 +08:00
chenchen and Claude Opus 4.8
2500f17189
feat(agent): return A2A endpoint security scheme/profile ( #55 )
...
客户端 #25/#55:A2A 直连方需 Manager 在 agent endpoint 元数据给出安全通道信息,才能在
生产强制 HTTPS。agent 对象(列表/详情/部署/状态返回)新增 security:
- scheme: http | https(从 subdomain 推断)
- security_profile: none | tls(显式 https→tls;http 或裸主机→none)
- secure: profile != none
保守口径:无法确证 TLS 即 none,宁可客户端在生产拒绝也不回传"看似安全"的明文端点。
客户端置 HEICODE_AGENT_REQUIRE_SECURE=1 即据此强制(secure=false→拒绝)。AM 上 HTTPS/mTLS
listener(azgy)后 profile 自动变 tls,客户端无需改包。元数据不含任何 secret_ref。
纯函数 agentEndpointSecurity + 单测;文档 §5/§6 更新。Manager only,无计费/审计改动。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-06-10 15:37:28 +08:00
Fasthei and GitHub
3823ffb81d
Merge pull request #51 from xmindlab-heicode/feat/preflight-confirm-audit-version
...
feat(preflight): confirm + audit + tamper-proof version check (#41 )
2026-06-10 15:36:42 +08:00
Fasthei and GitHub
33f60922cb
Merge branch 'main' into feat/preflight-confirm-audit-version
2026-06-10 15:36:14 +08:00
Fasthei and GitHub
88793b1066
Merge pull request #52 from xmindlab-heicode/feat/cloud-discovery-aws-gcp
...
feat(discovery): provider-agnostic cloud discovery — AWS + GCP adapters (#5 )
2026-06-10 15:33:58 +08:00
Fasthei and GitHub
2332749013
Merge pull request #53 from xmindlab-heicode/feat/hm-swarm-query-phase1
...
feat(swarm): HM-side Swarm Run read-only query — Phase1 (#45 )
2026-06-10 15:33:40 +08:00
chenchen and Claude Opus 4.8
19640b44f5
fix(preflight): address #41 review — persisted confirmation, deploy ready re-check, template-aware version
...
回应 Fasthei 复审(PR #51 CHANGES_REQUESTED):
1. 持久化确认记录(强一致):新增 model.PreflightConfirmation 表 + InsertPreflightConfirmation +
PreflightConfirmationExists。confirm 时落库(默认 TTL=HEICODE_PREFLIGHT_CONFIRMATION_TTL_SECONDS
=3600s,可设 0 不过期),写失败直接报错(非 best-effort)。部署侧要求该版本存在未过期确认记录
→ 杜绝直接拿 GET version 绕过 confirm/审计。
2. 部署重新校验 Ready:verifyDeployPreflight 增加 summary.Ready 检查 —— 预算/agent_slot 等
易变项不进版本哈希,故部署时重查,防 confirm 后余额耗尽/槽位占满仍启动。
3. 版本哈希纳入模板安全面:computePreflightVersion 加 tplDigest(definition+model+name 摘要),
管理员改同一 template_key 的 definition/model 后旧确认失效。补 TestComputePreflightVersion_ChangesOnTemplateEdit。
4. 审计降为附加流:强一致确认记录作为部署门禁;审计 preflight.confirmed 互补。
测试:PreflightConfirmationExists(命中/版本不符/跨用户/过期/不过期/空参)、PreflightBindingKey、
模板变更翻转版本。TestMain + 生产迁移注册 PreflightConfirmation。controller+model 全回归通过。
文档 §4.1.1 更新。
Affects: Manager only(新增 preflight_confirmations 表 + 部署门禁强化)。无计费改动。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-06-10 15:28:07 +08:00
chenchen
64ba58357f
Merge remote-tracking branch 'origin/main' into feat/preflight-confirm-audit-version
2026-06-10 15:21:37 +08:00
chenchen and Claude Opus 4.8
df8fa80eba
fix(discovery): address #5 review — no secret inheritance, GCP URL, tagged-only scope
...
回应 Fasthei 复审(PR #52 CHANGES_REQUESTED):
1. 发现出的子资源不再继承账号 secret_ref:抽出 DB 无关的 applyDiscoveredResourceFields,
恒置 SecretRef=""(避免账号级凭据引用经 resourceToResponse / grant manifest 扩散到每个
VM/S3/DB)。加 TestApplyDiscoveredResourceFields_NoSecretInheritance。
3. GCP searchAllResources URL 修正:gcpSearchAllResourcesURL 不再 PathEscape 整个 scope
(slash 是路径模板一部分),生成 /v1/projects/<id>:searchAllResources。加 TestGCPSearchAllResourcesURL。
2. AWS 覆盖范围据实声明:Resource Groups Tagging GetResources 仅覆盖 tagged/曾 tagged 资源,
不覆盖未打标签 EC2/RDS/S3;注释明确「tagged resources only」,#5 全量发现诉求不据此关闭。
controller 全套测试通过,go build/vet 干净。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-06-10 14:29:57 +08:00
chenchen
1e28ab1100
Merge remote-tracking branch 'origin/main' into feat/cloud-discovery-aws-gcp
2026-06-10 14:25:00 +08:00
chenchen and Claude Opus 4.8
b9d9eddf7b
fix(swarm): address #45 review — payload redaction, user-scoped events, no fake stop
...
回应 Fasthei 复审(PR #53 CHANGES_REQUESTED):
1. 事件 payload 脱敏:swarmEventView 经 sanitizeSwarmPayload —— 递归剔除
secret_ref/credentials/token/api_key/private_key/access_key/password 及 plan/payload/
permission_manifest/env 大字段,再跑 RedactText 兜底。绝不下发 azkv:// secret_ref 或
sk-/Bearer(approval.requested 等 envelope 携带的凭据引用)。加 TestSanitizeSwarmPayload_*。
2. user 作用域:model.ListSwarmCallbackEventsAfter 增加 userID 参数 + WHERE user_id,
controller 传入当前用户;防 runtime_swarm_id/deployment_id 碰撞或误写导致跨用户事件泄漏。
测试补 user 隔离用例。
3. stop 不伪造成功:移除「开关打开返回 accepted:true」路径;未启用→POLICY_REJECTED,
启用也→NOT_IMPLEMENTED(未转发运行时),直到 agent_swarm#2 冻结接上真实 stop。
文档 §5.2 同步(脱敏 / user 作用域 / stop 语义)。go build/vet 干净,controller+model 全回归通过。
Affects: Manager only(只读查询脱敏 + 写端点安全语义)。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-06-10 14:23:58 +08:00
Fasthei and GitHub
87c95e526b
Merge pull request #54 from xmindlab-heicode/docs/telemetry-prod-enablement-checklist
...
docs(telemetry): production enablement checklist 定稿 (#44 )
2026-06-10 13:54:05 +08:00
chenchen and Claude Opus 4.8
06f0971465
docs(telemetry): reframe enablement gate as privacy-disclosure-published, not legal signoff ( #44 )
...
去掉「法务/产品签字」「需真人」表述:开启遥测的前置是「隐私披露文档已发布且经 PR 评审通过」
这一文档/评审条件,不是人工法务签字。符合团队留言只写技术结论/条件的约定。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-06-10 13:42:53 +08:00
chenchen and Claude 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
chenchen and Claude Opus 4.8
59b13ba824
feat(swarm): HM-side Swarm Run read-only query — Phase1 ( #45 )
...
#45 Phase1 的只读查询(list/status/events?after/artifacts),全部基于 HM 已持久化的
运行时回调数据(Swarm → HM 带签名回调,见 agent_callback.go),**无需实时调 Swarm**,
因此不被 agent_swarm#2 契约冻结阻塞、返工风险低:
- GET /api/heicode/swarms — 列出当前用户的 swarm 运行(AgentDeployment, sub_mode=swarm 或有 runtime_swarm_id)
- GET /api/heicode/swarms/:id — 状态(:id = deployment_id/swarm_id/correlation_id 任一)
- GET /api/heicode/swarms/:id/events?after=&limit= — 事件增量拉取(id 游标 next_after,oldest-first)
新增 model.ListSwarmCallbackEventsAfter(按 deployment_id/swarm_id + id>after)
- GET /api/heicode/swarms/:id/artifacts — 从已存事件(event_type 含 artifact)派生
- POST /api/heicode/swarms/:id/stop — 唯一写操作;在 agent_swarm#2 冻结 + SWARM_RUNTIME_ENABLED=true
前默认关闭并明确提示(不臆造未冻结写接口)
字段口径对齐 agent_swarm/docs/integration/runtime-contract.md(deployment_id↔swarm_id↔
manager_deployment_id;状态机 waiting_approval→running→…)。所有查询按 user 作用域,视图脱敏
(不含 plan/payload 大字段与凭据)。
测试:TestListSwarmCallbackEventsAfter(游标/过滤/空标识);TestMain 迁移 AgentDeployment +
AgentCallbackEvent。go build/vet 干净,controller+model 全套回归通过。文档 §5.2。
Affects: Manager only(新增只读查询端点 + 一个 gated 写端点)。无计费/审计 schema 改动;
不依赖未冻结契约。stop 真实接入随 agent_swarm#2 冻结落地。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-06-10 13:24:34 +08:00
zsbgnw12 and GitHub
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
zsbgnw12 and GitHub
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
chenchen and Claude Opus 4.8
3fb07ad5fb
feat(discovery): provider-agnostic cloud discovery — AWS + GCP adapters ( #5 )
...
#5 三项 DoD 全部落地(纯 Go,无云 SDK,REST + std crypto,非 mock):
- 抽象 provider 接口(DoD #3 ):cloudDiscoveryProvider{ name, discover } + 统一
upsertDiscoveredCloudResources + 跨云一致分类 classifyCloudResourceType(vm/
database/blob/cloud_resource)。新增 dispatcher DiscoverCloudResources 按
account.Provider 路由 azure/aws/gcp。Azure 适配器复用既有 ARM 客户端,三家同抽象。
- AWS adapter(DoD #1 ):纯 Go AWS Signature V4(crypto/hmac+sha256)+ Resource
Groups Tagging API GetResources(分页)→ ARN 归一化。SigV4 实现以 AWS 官方
"get-vanilla" 测试向量验证签名正确(TestAWSSigV4_VanillaVector)。
- GCP adapter(DoD #2 ):服务账号 RS256 JWT 断言 → OAuth2 token → Cloud Asset
Inventory searchAllResources(分页)→ asset 归一化。JWT 以生成密钥 RS256 验签
roundtrip 验证(TestBuildGCPAssertion_RS256Roundtrip)。
路由:新增 POST /api/resources/:id/discover-cloud(按 provider 路由);保留既有
/:id/azure/discover 向后兼容。落库与 Azure 一致(resource_type=cloud_resource,
跨云类别入 metadata.classified_type),幂等 upsert(user+type+provider+external_id)。
测试:分类 / ARN 解析 / SigV4 官方向量 / GCP RS256 roundtrip;controller 全套通过,
go build/vet 干净。
Affects: Manager only(资源发现,新增只读发现端点 + 抽象层)。无计费/审计/部署改动;
凭据经既有 secret store 读取,不落明文。
Closes #5
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-06-10 13:07:48 +08:00
chenchen and Claude Opus 4.8
9a073e5b41
feat(preflight): confirm + audit + tamper-proof version check ( #41 )
...
完成 preflight EPIC(#29 )的最后一子项 #41 :
- POST /api/heicode/preflight/confirm:重算摘要 → 仅 ready 时可确认 → 派生防篡改
版本哈希 → 写审计事件 preflight.confirmed(谁/何时/哪个 version)→ 返回 version。
- 防篡改版本 computePreflightVersion:在**稳定安全面**(template + 资源
binding_id/type/provider/name/status/has_secret + 高危 enum + 必需缺失项)上做
sha256,刻意排除易变预算数字/agent_slot,避免版本无意义抖动。
- 部署校验:POST /api/heicode/agents 新增可选 preflight_version。默认仅在带了它时
校验(向后兼容);HEICODE_PREFLIGHT_REQUIRED=true 时强制。确认后资源/模板/高危面
漂移或被篡改 → 版本不匹配 → 部署拒绝。
- 重构:抽出 buildPreflightSummary(GET/confirm/deploy 共用);GET 现也回 version。
测试:版本确定性/稳定性(不随预算变)、资源篡改翻转版本、normalizeBindingIDs。
go build/vet 干净,controller preflight 测试全过。文档 §4.1/§4.1.1 更新。
Affects: Manager only(新增 confirm 端点 + 部署可选校验,默认向后兼容)。
无计费/审计 schema 改动(复用既有 agent_audit_events)。
Closes #41
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-06-10 12:55:40 +08:00
chenchen and Claude 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
Fasthei and GitHub
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
Fasthei and GitHub
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
Fasthei and GitHub
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
chenchen and Claude 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
chenchen and Claude 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
chenchen and Claude 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
chenchen and Claude 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
Fasthei and GitHub
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
Fasthei and GitHub
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
chenchen and Claude 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
chenchen and Claude 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
chenchen and Claude 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
Fasthei and GitHub
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
Fasthei and GitHub
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
chenchen and Claude 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
chenchen and Claude 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
Fasthei and GitHub
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
Fasthei and GitHub
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
zsbgnw12 and GitHub
9444cdb498
fix agent deploy caps
...
approved
2026-06-08 17:49:35 +08:00
Fasthei and GitHub
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
chenchen and Claude 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
chenchen and Claude 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
chenchen and Claude 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
chenchen and Claude 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