| event_payload |
{"ref":"refs/heads/main","befo {"ref":"refs/heads/main","before":"614681e6e78d0385bbf043ef964bd444d8e5958b","after":"832f9b2e5ab646a48adbf37b80db1d41092f2f7e","compare_url":"https://gitea.g-hi.com/luoanwu/digital-employee-os/compare/614681e6e78d0385bbf043ef964bd444d8e5958b...832f9b2e5ab646a48adbf37b80db1d41092f2f7e","commits":[{"id":"832f9b2e5ab646a48adbf37b80db1d41092f2f7e","message":"chore(reports): tenant.ts 拆分第三步的十三份静态门禁证据 回绑 @ a0a9f1a\n\n十三份全部 clean 绑定(worktreeDirty:false):naming / schema-sync / validation-source /\ncontract-consumers / dual-backend-parity / kernel-boundaries / kernel-packages /\nkernel-downstream / kernel-extensions / statemachine-write-guard / list-bounds /\nfork-readiness 十二绿;kernel-admission 仍是引入时那 8 处(K3 一处 + K4 七处),\n与三步拆分前逐条一致——全程未引入新红,也未消除旧红。\n\n三步各自撞到的门禁都如实红过再修,没有一处是先改门禁再做变更:\n第一步 K1(导出归属漂移);第二步 K1 + kernel-packages P7(公开面变更须伴随版本上调)\n+ kernel-downstream D1(下游安装版本随之重签);第三步同上两处 P7 / D1。\n\n工作区内三份 reports/ui-*.latest.json 的改动早于本批次,未提交也未还原。\n\nCo-Authored-By: Claude Opus 5 \u003cnoreply@anthropic.com\u003e\n","url":"https://gitea.g-hi.com/luoanwu/digital-employee-os/commit/832f9b2e5ab646a48adbf37b80db1d41092f2f7e","author":{"name":"juhailaoluo pro","email":"hillao@juhailaoluodeMacBook-Pro.local","username":""},"committer":{"name":"juhailaoluo pro","email":"hillao@juhailaoluodeMacBook-Pro.local","username":""},"verification":null,"timestamp":"2026-09-18T01:12:22-07:00","added":[],"removed":[],"modified":["reports/contract-consumers.latest.json","reports/dual-backend-parity.latest.json","reports/fork-readiness.latest.json","reports/kernel-admission.latest.json","reports/kernel-boundaries.latest.json","reports/kernel-downstream.latest.json","reports/kernel-extensions.latest.json","reports/kernel-packages.latest.json","reports/list-bounds.latest.json","reports/naming.latest.json","reports/schema-sync.latest.json","reports/statemachine-write-guard.latest.json","reports/validation-source.latest.json"]},{"id":"a0a9f1aa5d77ac7d1c9b74a3e445a323a205f5b6","message":"refactor(contracts): tenant.ts 拆分第三步——自建权限改名 authorization.ts,tenant 之名腾空\n\n第一步迁出 work 域判定、第二步迁出自建身份之后,tenant.ts 剩下的 22 个导出整体就是\n「自建权限」一类。因此第三步不是搬符号,是给文件正名。\n\n packages/contracts/src/tenant.ts → packages/contracts/src/authorization.ts\n\n改名本身的价值不只是可读性:OS 的 tenant.ts 与框架 @juhai/kernel 的同名文件**共有导出 0 个**,\n框架那份是租户解析策略(normalizeTenantId / tenantIdFromClaims / decideTenantResolution /\nresolveAuthMode / AUTH_MODES),OS 一个都没有。两个同名不同义的文件是「形似而神不同」漂移\n最典型的载体。改名之后 tenant.ts 这个名字腾空,留给内核退回 pin 时由 @juhai/kernel 提供的\n真正租户原语——顺带补上 OS 现在缺的 tenantId 形状与长度校验(当前主口径是无上限的\nz.string().min(1),另有两处 .max(128) 与 employment-projection.ts 的 ^ten_.+$,三套并存)。\n\n同步改动:\n\n- 六处 import 改指:identity.ts / outcome.ts / task.ts / index.ts / kernel.ts / contracts.test.ts。\n- check-dual-backend-parity.mjs 的 C52 两条断言(权限目录与角色默认值、ALLOW/DENY 优先级)\n 改指 authorization.ts。C52 没有专用负向探针,但 expectSource 对缺失文件计 missing file\n 违规(fail-closed),门禁绿即证明两条断言在新路径上真实命中,不是指向不存在文件的假绿。\n- kernel.boundaries.json:CORE 的 contractModules 由 tenant.ts 改为 authorization.ts。\n- check-kernel-admission.mjs 头部叙述里的 tenant.ts 改为历史表述,不再指向已不存在的路径。\n- @repo/contracts 1.17.0 → 1.18.0(根与 kernel 两个 barrel 的 export 行都变了,P7 要求公开面\n 变更伴随版本上调);kernel.packages.lock.json / kernel.downstream.lock.json /\n kernel.exports.lock.json 三把锁随之重签。\n\n本步**未**把自建权限移出 @repo/contracts/kernel 子路径。按同一套理由(铁律三:平台拥有规则)\n它和自建身份一样不属于跨产品必需的内核契约,但从已声明的稳定子路径上摘除符号是**破坏性\n收窄**,应单独裁定并走主版本号,不随改名夹带。实测当前 kernel 子路径的唯一消费者是下游夹具\n的命名空间导入,产品侧零具名消费——真要摘,成本主要在版本语义而非调用方。\n\n三步累计:tenant.ts 1075 行 / 65 导出 → authorization.ts 273 行 / 22 导出\n+ identity.ts 818 行 / 23 导出 + task.ts / outcome.ts 各收 3 / 1 个 + 17 个降私有。\n\n验证:@repo/contracts 24 文件 312/312(三步前后四次逐次一致,行为中性);typecheck 13/13;\nnaming / schema / validation / contract-consumers / dual-backend / kernel-boundaries /\nkernel-packages / kernel-downstream / kernel-extensions / write-guard / list-bounds /\nfork-readiness 十二门全绿;kernel-admission 仍是引入时那 8 处,未引入新红。\n\nCo-Authored-By: Claude Opus 5 \u003cnoreply@anthropic.com\u003e\n","url":"https://gitea.g-hi.com/luoanwu/digital-employee-os/commit/a0a9f1aa5d77ac7d1c9b74a3e445a323a205f5b6","author":{"name":"juhailaoluo pro","email":"hillao@juhailaoluodeMacBook-Pro.local","username":""},"committer":{"name":"juhailaoluo pro","email":"hillao@juhailaoluodeMacBook-Pro.local","username":""},"verification":null,"timestamp":"2026-09-18T01:11:37-07:00","added":["packages/contracts/src/authorization.ts"],"removed":["packages/contracts/src/tenant.ts"],"modified":["kernel.boundaries.json","kernel.downstream.lock.json","kernel.exports.lock.json","kernel.packages.json","kernel.packages.lock.json","packages/contracts/package.json","packages/contracts/src/contracts.test.ts","packages/contracts/src/identity.ts","packages/contracts/src/index.ts","packages/contracts/src/kernel.ts","packages/contracts/src/outcome.ts","packages/contracts/src/task.ts","scripts/check-dual-backend-parity.mjs","scripts/check-kernel-admission.mjs"]},{"id":"d7c932b537561ae02bcc860d506fea7c1d878b30","message":"chore(reports): tenant.ts 拆分第二步的十份静态门禁证据 回绑 @ 439c6f7\n\n十份全部 clean 绑定(worktreeDirty:false):naming / schema-sync / validation-source /\ncontract-consumers / dual-backend-parity / kernel-boundaries / kernel-packages /\nkernel-downstream / kernel-extensions 九绿;kernel-admission 仍是引入时那 8 处\n(K3 一处 + K4 七处),与两步拆分前逐条一致——未引入新红,也未消除旧红。\n\n本步中 kernel-packages 的 P7 与 kernel-downstream 的 D1 都如实报过红:前者要求根 barrel\n新增导出必须伴随版本上调(@repo/contracts 1.16.0 → 1.17.0),后者要求下游夹具的安装版本\n随之重签。两处都是设计内的「变更即复核」,不是绕过。\n\n工作区内三份 reports/ui-*.latest.json 的改动早于本批次,未提交也未还原。\n\nCo-Authored-By: Claude Opus 5 \u003cnoreply@anthropic.com\u003e\n","url":"https://gitea.g-hi.com/luoanwu/digital-employee-os/commit/d7c932b537561ae02bcc860d506fea7c1d878b30","author":{"name":"juhailaoluo pro","email":"hillao@juhailaoluodeMacBook-Pro.local","username":""},"committer":{"name":"juhailaoluo pro","email":"hillao@juhailaoluodeMacBook-Pro.local","username":""},"verification":null,"timestamp":"2026-09-18T01:08:09-07:00","added":[],"removed":[],"modified":["reports/contract-consumers.latest.json","reports/dual-backend-parity.latest.json","reports/kernel-admission.latest.json","reports/kernel-boundaries.latest.json","reports/kernel-downstream.latest.json","reports/kernel-extensions.latest.json","reports/kernel-packages.latest.json","reports/naming.latest.json","reports/schema-sync.latest.json","reports/validation-source.latest.json"]},{"id":"439c6f7e34f48f718f18479aa1dd2e9a9e3fcfe1","message":"refactor(contracts): tenant.ts 拆分第二步——自建身份迁出 identity.ts\n\n框架 @juhai/kernel 的 tenant.ts 在 0.4.0—0.7.0 之间把边界写死为「本文件只做策略,\n不做验签」:验签需要密钥/JWKS,而契约包被 web 直接 import,密钥语义不能泄漏进浏览器包。\nOS 分叉于框架 0.1.0,没见过这条边界,于是策略、验签、自建权限、work 域判定四类长进了\n同一个文件。第一步已迁出 work 域判定,本步迁出身份一类。\n\n packages/contracts/src/identity.ts(新增,818 行 / 23 导出)\n 验签原语(注入式,契约包自身不 import node:crypto)、JWKS 密钥库、\n 浏览器身份与会话、OIDC PKCE 三组 schema、启动姿态门、实时连接过期、\n 鉴权入口 resolveTenantAuth,以及 token 解码/比对等私有管道\n\n packages/contracts/src/tenant.ts(273 行 / 22 导出,原 1042 行 / 44 导出)\n 只剩自建权限一类:角色与权限词汇表、ALLOW/DENY 判定、授权 DTO、审计载荷\n\n两处归属判断值得记下:\n\n- bindAuditActorSubject / AuditActorBinding 一并迁入 identity.ts。它绑定的是**已验签的\n sub**,属身份来源而非授权判定;留在 tenant.ts 会让授权侧反向依赖 TenantAuthPosture,\n identity ↔ tenant 成环。\n- roleFromClaim 留在 tenant.ts 并升为导出。它是角色词汇表的一部分(claim → 合法角色),\n 两侧都要用;反过来把它搬进 identity 会让 resolveEffectiveRole 反向依赖,同样成环。\n\n依赖方向单向:identity → tenant(借 TENANT_ROLES / TenantRole / roleFromClaim),\ntenant 不反向依赖 identity。切分前已用脚本枚举 75 个顶层声明的引用图逐条验证无反向边。\n\nidentity.ts **不进 @repo/contracts/kernel 子路径**,只经根 barrel 导出:自建身份不是跨产品\n必需的内核契约,后续应换成企业 IdP 的 client-identity。\n\n同步改动:\n\n- check-dual-backend-parity.mjs 三处按路径钉在 tenant.ts 的断言改指 identity.ts——\n C51(启动姿态判定与断言)、C181(实时过期策略)、C73(已验签 sub 的审计主体绑定)。\n 改完用门禁自带负向探针验活:DUAL_BACKEND_NEGATIVE_PROBE=missing-realtime-auth-expiry\n 与 =missing-audit-actor-binding 均如期转红,断言不是改成了指向不存在文件的假绿。\n C52 两条仍在 tenant.ts(权限目录与 ALLOW/DENY 优先级未动)。\n- kernel.boundaries.json:identity.ts 登记进 CORE 的 contractModules(30 → 31)。\n- @repo/contracts 1.16.0 → 1.17.0。check:kernel-packages 的 P7 要求公开面变更必须伴随\n 版本上调;根 barrel 新增一行 export * 是加法变更,取次版本。kernel.packages.json 与\n kernel.packages.lock.json / kernel.downstream.lock.json 随之重签(后者只改版本号一行)。\n\n顺带修正上一笔提交里的说法,方向不变但更准确:check:kernel-packages 的 apiDigest 只哈希\nrequiredExports 入口的 .d.ts,而入口就是 barrel——它看得见「根 barrel 多了一行 export *」,\n看不见任何具体符号的增删。上一步降私有 17 个符号它全绿,正是这个原因。\n\n验证:@repo/contracts 24 文件 312/312(三次拆分前后逐次一致,行为中性);typecheck 13/13;\nnaming / schema / validation / contract-consumers / dual-backend / kernel-boundaries /\nkernel-packages / kernel-downstream / kernel-extensions 九门全绿;kernel-admission 仍是\n引入时那 8 处(K3 一处 + K4 七处),未引入新红。kernel.exports.lock.json 重签为\n39 个模块 / 763 个导出。\n\nCo-Authored-By: Claude Opus 5 \u003cnoreply@anthropic.com\u003e\n","url":"https://gitea.g-hi.com/luoanwu/digital-employee-os/commit/439c6f7e34f48f718f18479aa1dd2e9a9e3fcfe1","author":{"name":"juhailaoluo pro","email":"hillao@juhailaoluodeMacBook-Pro.local","username":""},"committer":{"name":"juhailaoluo pro","email":"hillao@juhailaoluodeMacBook-Pro.local","username":""},"verification":null,"timestamp":"2026-09-18T01:07:27-07:00","added":["packages/contracts/src/identity.ts"],"removed":[],"modified":["kernel.boundaries.json","kernel.downstream.lock.json","kernel.exports.lock.json","kernel.packages.json","kernel.packages.lock.json","packages/contracts/package.json","packages/contracts/src/contracts.test.ts","packages/contracts/src/index.ts","packages/contracts/src/tenant.ts","scripts/check-dual-backend-parity.mjs"]}],"total_commits":0,"head_commit":{"id":"832f9b2e5ab646a48adbf37b80db1d41092f2f7e","message":"chore(reports): tenant.ts 拆分第三步的十三份静态门禁证据 回绑 @ a0a9f1a\n\n十三份全部 clean 绑定(worktreeDirty:false):naming / schema-sync / validation-source /\ncontract-consumers / dual-backend-parity / kernel-boundaries / kernel-packages /\nkernel-downstream / kernel-extensions / statemachine-write-guard / list-bounds /\nfork-readiness 十二绿;kernel-admission 仍是引入时那 8 处(K3 一处 + K4 七处),\n与三步拆分前逐条一致——全程未引入新红,也未消除旧红。\n\n三步各自撞到的门禁都如实红过再修,没有一处是先改门禁再做变更:\n第一步 K1(导出归属漂移);第二步 K1 + kernel-packages P7(公开面变更须伴随版本上调)\n+ kernel-downstream D1(下游安装版本随之重签);第三步同上两处 P7 / D1。\n\n工作区内三份 reports/ui-*.latest.json 的改动早于本批次,未提交也未还原。\n\nCo-Authored-By: Claude Opus 5 \u003cnoreply@anthropic.com\u003e\n","url":"https://gitea.g-hi.com/luoanwu/digital-employee-os/commit/832f9b2e5ab646a48adbf37b80db1d41092f2f7e","author":{"name":"juhailaoluo pro","email":"hillao@juhailaoluodeMacBook-Pro.local","username":""},"committer":{"name":"juhailaoluo pro","email":"hillao@juhailaoluodeMacBook-Pro.local","username":""},"verification":null,"timestamp":"2026-09-18T01:12:22-07:00","added":[],"removed":[],"modified":["reports/contract-consumers.latest.json","reports/dual-backend-parity.latest.json","reports/fork-readiness.latest.json","reports/kernel-admission.latest.json","reports/kernel-boundaries.latest.json","reports/kernel-downstream.latest.json","reports/kernel-extensions.latest.json","reports/kernel-packages.latest.json","reports/list-bounds.latest.json","reports/naming.latest.json","reports/schema-sync.latest.json","reports/statemachine-write-guard.latest.json","reports/validation-source.latest.json"]},"repository":{"id":76,"owner":{"id":5,"login":"luoanwu","login_name":"","source_id":0,"full_name":"","email":"law@g-hi.com","avatar_url":"https://gitea.g-hi.com/avatar/627574a890388a2aadc80ab38d22f3a0","html_url":"https://gitea.g-hi.com/luoanwu","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2026-01-30T16:28:30+08:00","restricted":false,"active":false,"prohibit_login":false,"location":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"luoanwu"},"name":"digital-employee-os","full_name":"luoanwu/digital-employee-os","description":"","empty":false,"private":false,"fork":false,"template":false,"mirror":false,"size":85288,"language":"","languages_url":"https://gitea.g-hi.com/api/v1/repos/luoanwu/digital-employee-os/languages","html_url":"https://gitea.g-hi.com/luoanwu/digital-employee-os","url":"https://gitea.g-hi.com/api/v1/repos/luoanwu/digital-employee-os","link":"","ssh_url":"git@gitea.g-hi.com:luoanwu/digital-employee-os.git","clone_url":"https://gitea.g-hi.com/luoanwu/digital-employee-os.git","original_url":"","website":"","stars_count":0,"forks_count":1,"watchers_count":1,"branch_count":3,"open_issues_count":0,"open_pr_counter":0,"release_counter":0,"default_branch":"main","archived":false,"created_at":"2026-08-20T14:46:28+08:00","updated_at":"2026-09-18T16:02:12+08:00","archived_at":"1970-01-01T08:00:00+08:00","permissions":{"admin":true,"push":true,"pull":true},"has_code":true,"has_issues":true,"internal_tracker":{"enable_time_tracker":true,"allow_only_contributors_to_track_time":true,"enable_issue_dependencies":true},"has_wiki":true,"has_pull_requests":true,"has_projects":true,"projects_mode":"all","has_releases":true,"has_packages":true,"has_actions":true,"ignore_whitespace_conflicts":false,"allow_merge_commits":true,"allow_rebase":true,"allow_rebase_explicit":true,"allow_squash_merge":true,"allow_fast_forward_only_merge":true,"allow_rebase_update":true,"allow_manual_merge":false,"autodetect_manual_merge":false,"default_delete_branch_after_merge":false,"default_merge_style":"merge","default_allow_maintainer_edit":true,"avatar_url":"","internal":false,"mirror_interval":"","object_format_name":"sha1","mirror_updated":"0001-01-01T00:00:00Z","topics":[],"licenses":[]},"pusher":{"id":5,"login":"luoanwu","login_name":"","source_id":0,"full_name":"","email":"5+luoanwu@noreply.localhost","avatar_url":"https://gitea.g-hi.com/avatar/627574a890388a2aadc80ab38d22f3a0","html_url":"https://gitea.g-hi.com/luoanwu","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2026-01-30T16:28:30+08:00","restricted":false,"active":false,"prohibit_login":false,"location":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"luoanwu"},"sender":{"id":5,"login":"luoanwu","login_name":"","source_id":0,"full_name":"","email":"5+luoanwu@noreply.localhost","avatar_url":"https://gitea.g-hi.com/avatar/627574a890388a2aadc80ab38d22f3a0","html_url":"https://gitea.g-hi.com/luoanwu","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2026-01-30T16:28:30+08:00","restricted":false,"active":false,"prohibit_login":false,"location":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"luoanwu"}}... |