From d37e897c2e67d83846b42a44959cbfca3720f13b Mon Sep 17 00:00:00 2001 From: John Wilson Date: Sun, 28 Jun 2026 14:06:37 +0800 Subject: [PATCH 1/3] feat(platform): add cross-group integration readiness --- ...-26.cross-group-integration-readiness.json | 78 +++++++ ...est.cross-group-integration-readiness.json | 78 +++++++ ...345\206\263\347\273\204-v0.1.exec-plan.md" | 15 +- .../industry/platform/replay.test.ts | 79 +++++++ src/cli.ts | 31 ++- .../audit/crossGroupIntegrationReadiness.ts | 212 ++++++++++++++++++ 6 files changed, 485 insertions(+), 8 deletions(-) create mode 100644 data/reports/2026-06-26.cross-group-integration-readiness.json create mode 100644 data/reports/latest.cross-group-integration-readiness.json create mode 100644 src/industry/platform/audit/crossGroupIntegrationReadiness.ts diff --git a/data/reports/2026-06-26.cross-group-integration-readiness.json b/data/reports/2026-06-26.cross-group-integration-readiness.json new file mode 100644 index 0000000..6f948a2 --- /dev/null +++ b/data/reports/2026-06-26.cross-group-integration-readiness.json @@ -0,0 +1,78 @@ +{ + "artifact_kind": "cross_group_integration_readiness", + "date": "2026-06-26", + "generated_at": "2026-06-28T13:58:30+08:00", + "status": "phase3_backlog_ready", + "ready_group_count": 3, + "weekly_output_ready": false, + "blocked_until": "closed_fact_snapshot_and_audit", + "daily_pack_v2_ready": true, + "rolling_snapshot_ready": true, + "daily_pack_v2": { + "schema_version": "daily-industry-evidence-pack.v2", + "date": "2026-06-26", + "source_message_ids": [ + "industry://internal/2026-06-26/policy-finance-runtime-replay", + "industry://internal/2026-06-26/daily-industry-evidence-pack-input.v1/artifact-d9660564ef27#message", + "industry://internal/2026-06-26/product-ecosystem-phase6-replay-refs" + ], + "input_artifact_refs": [ + "data/reports/2026-06-26.policy-finance-runtime-replay.json", + "data/reports/2026-06-26.industry-runtime-summary.json", + "industry://internal/2026-06-26/industry-signal-event-batch.v1/artifact-4d73a5d48b0c", + "industry://internal/2026-06-26/industry-signal-event-batch.v1/artifact-f1d7fd1dac07", + "industry://internal/2026-06-26/industry-signal-event-batch.v1/artifact-d0b11ad6b229", + "industry://internal/2026-06-26/industry-signal-event-batch.v1/artifact-a0b27826ed31", + "industry://internal/2026-06-26/axis-tool-coverage-report.v1/artifact-29b786461618", + "industry://internal/2026-06-26/axis-tool-coverage-report.v1/artifact-3c175178319f", + "industry://internal/2026-06-26/industry-agent-contribution.v1/artifact-e5ae3396fd35", + "industry://internal/2026-06-26/industry-agent-contribution.v1/artifact-2e93c27875ea" + ], + "normalized_event_batch_ref": "industry://internal/2026-06-26/daily-industry-evidence-pack.v2/normalized-ref-index", + "rejected_event_batch_ref": "industry://internal/2026-06-26/daily-industry-evidence-pack.v2/rejected-ref-index", + "agent_contributions": [ + "industry://internal/2026-06-26/industry-agent-contribution.v1/artifact-e5ae3396fd35", + "industry://internal/2026-06-26/industry-agent-contribution.v1/artifact-2e93c27875ea" + ], + "accepted_event_count": 21, + "rejected_event_count": 2, + "registry_snapshot_ref": "platform-phase1-current-consumer.v1", + "tool_registry_snapshot_ref": "industry://internal/tool-registry/cross-group-ready", + "public_projection": "blocked_until_audit", + "cost_and_degradation_summary": "ref-only aggregation; no final weekly output", + "coverage_summary": "policy-finance runtime ready; academic formal dry-run ready; product ecosystem phase6 backlog ready" + }, + "rolling_snapshot": { + "snapshot_id": "rolling-evidence-window-2026-06-26", + "schema_version": "rolling-evidence-window-snapshot.v1", + "window_end": "2026-06-26T23:59:59+08:00", + "carry_forward_horizon_days": 7, + "derived_from_daily_pack_refs": [ + "industry://internal/2026-06-26/daily-industry-evidence-pack.v2/ref-only" + ], + "derived_from_claim_ledger_refs": [], + "carry_forward_entries": [], + "expired_entry_ids": [], + "fact_snapshot_ref": "blocked_until_closed_fact_snapshot", + "registry_snapshot_ref": "platform-phase1-current-consumer.v1" + }, + "policy_finance": { + "status": "policy_finance_runtime_ready", + "candidate_pool_ready": true, + "negative_reason_code": "dispatch_context_missing" + }, + "academic": { + "status": "normalization_dry_run_ready", + "formal_handoff_ready": true, + "eval_backlog_ready": true + }, + "product_ecosystem": { + "status": "product_ecosystem_phase6_inputs_accepted", + "eval_backlog_ready": true + }, + "next_platform_actions": [ + "assemble_cross_group_replay_eval_backlog", + "start_closed_fact_snapshot" + ], + "reject_list": [] +} diff --git a/data/reports/latest.cross-group-integration-readiness.json b/data/reports/latest.cross-group-integration-readiness.json new file mode 100644 index 0000000..6f948a2 --- /dev/null +++ b/data/reports/latest.cross-group-integration-readiness.json @@ -0,0 +1,78 @@ +{ + "artifact_kind": "cross_group_integration_readiness", + "date": "2026-06-26", + "generated_at": "2026-06-28T13:58:30+08:00", + "status": "phase3_backlog_ready", + "ready_group_count": 3, + "weekly_output_ready": false, + "blocked_until": "closed_fact_snapshot_and_audit", + "daily_pack_v2_ready": true, + "rolling_snapshot_ready": true, + "daily_pack_v2": { + "schema_version": "daily-industry-evidence-pack.v2", + "date": "2026-06-26", + "source_message_ids": [ + "industry://internal/2026-06-26/policy-finance-runtime-replay", + "industry://internal/2026-06-26/daily-industry-evidence-pack-input.v1/artifact-d9660564ef27#message", + "industry://internal/2026-06-26/product-ecosystem-phase6-replay-refs" + ], + "input_artifact_refs": [ + "data/reports/2026-06-26.policy-finance-runtime-replay.json", + "data/reports/2026-06-26.industry-runtime-summary.json", + "industry://internal/2026-06-26/industry-signal-event-batch.v1/artifact-4d73a5d48b0c", + "industry://internal/2026-06-26/industry-signal-event-batch.v1/artifact-f1d7fd1dac07", + "industry://internal/2026-06-26/industry-signal-event-batch.v1/artifact-d0b11ad6b229", + "industry://internal/2026-06-26/industry-signal-event-batch.v1/artifact-a0b27826ed31", + "industry://internal/2026-06-26/axis-tool-coverage-report.v1/artifact-29b786461618", + "industry://internal/2026-06-26/axis-tool-coverage-report.v1/artifact-3c175178319f", + "industry://internal/2026-06-26/industry-agent-contribution.v1/artifact-e5ae3396fd35", + "industry://internal/2026-06-26/industry-agent-contribution.v1/artifact-2e93c27875ea" + ], + "normalized_event_batch_ref": "industry://internal/2026-06-26/daily-industry-evidence-pack.v2/normalized-ref-index", + "rejected_event_batch_ref": "industry://internal/2026-06-26/daily-industry-evidence-pack.v2/rejected-ref-index", + "agent_contributions": [ + "industry://internal/2026-06-26/industry-agent-contribution.v1/artifact-e5ae3396fd35", + "industry://internal/2026-06-26/industry-agent-contribution.v1/artifact-2e93c27875ea" + ], + "accepted_event_count": 21, + "rejected_event_count": 2, + "registry_snapshot_ref": "platform-phase1-current-consumer.v1", + "tool_registry_snapshot_ref": "industry://internal/tool-registry/cross-group-ready", + "public_projection": "blocked_until_audit", + "cost_and_degradation_summary": "ref-only aggregation; no final weekly output", + "coverage_summary": "policy-finance runtime ready; academic formal dry-run ready; product ecosystem phase6 backlog ready" + }, + "rolling_snapshot": { + "snapshot_id": "rolling-evidence-window-2026-06-26", + "schema_version": "rolling-evidence-window-snapshot.v1", + "window_end": "2026-06-26T23:59:59+08:00", + "carry_forward_horizon_days": 7, + "derived_from_daily_pack_refs": [ + "industry://internal/2026-06-26/daily-industry-evidence-pack.v2/ref-only" + ], + "derived_from_claim_ledger_refs": [], + "carry_forward_entries": [], + "expired_entry_ids": [], + "fact_snapshot_ref": "blocked_until_closed_fact_snapshot", + "registry_snapshot_ref": "platform-phase1-current-consumer.v1" + }, + "policy_finance": { + "status": "policy_finance_runtime_ready", + "candidate_pool_ready": true, + "negative_reason_code": "dispatch_context_missing" + }, + "academic": { + "status": "normalization_dry_run_ready", + "formal_handoff_ready": true, + "eval_backlog_ready": true + }, + "product_ecosystem": { + "status": "product_ecosystem_phase6_inputs_accepted", + "eval_backlog_ready": true + }, + "next_platform_actions": [ + "assemble_cross_group_replay_eval_backlog", + "start_closed_fact_snapshot" + ], + "reject_list": [] +} diff --git "a/docs/specs/exec-plans/\345\221\250\350\266\213\345\212\277\345\210\244\346\226\255\346\211\247\350\241\214\350\256\241\345\210\222/\350\241\214\344\270\232\347\272\247Agent\350\266\213\345\212\277\345\210\244\346\226\255-\344\270\255\345\217\260\350\243\201\345\206\263\347\273\204-v0.1.exec-plan.md" "b/docs/specs/exec-plans/\345\221\250\350\266\213\345\212\277\345\210\244\346\226\255\346\211\247\350\241\214\350\256\241\345\210\222/\350\241\214\344\270\232\347\272\247Agent\350\266\213\345\212\277\345\210\244\346\226\255-\344\270\255\345\217\260\350\243\201\345\206\263\347\273\204-v0.1.exec-plan.md" index eb25e53..97b2900 100644 --- "a/docs/specs/exec-plans/\345\221\250\350\266\213\345\212\277\345\210\244\346\226\255\346\211\247\350\241\214\350\256\241\345\210\222/\350\241\214\344\270\232\347\272\247Agent\350\266\213\345\212\277\345\210\244\346\226\255-\344\270\255\345\217\260\350\243\201\345\206\263\347\273\204-v0.1.exec-plan.md" +++ "b/docs/specs/exec-plans/\345\221\250\350\266\213\345\212\277\345\210\244\346\226\255\346\211\247\350\241\214\350\256\241\345\210\222/\350\241\214\344\270\232\347\272\247Agent\350\266\213\345\212\277\345\210\244\346\226\255-\344\270\255\345\217\260\350\243\201\345\206\263\347\273\204-v0.1.exec-plan.md" @@ -3,7 +3,7 @@ ## 文档状态 - 版本:`v0.1` -- 当前状态:`In Progress`,截至 `2026-06-28` 已推进到 `Phase 2 partial / Phase 3 partial / product-ecosystem Phase 6 inputs accepted`;最终 `Phase 3+` 仍等待三组正式 handoff / replay 资产齐备后继续。 +- 当前状态:`In Progress`,截至 `2026-06-28` 已推进到 `Phase 3 backlog ready / ref-only daily pack + rolling snapshot ready`;最终 weekly 三层输出仍阻塞于 `closed_fact_snapshot_and_audit`。 - 上游总控: - `docs/specs/exec-plans/周趋势判断执行计划/行业级Agent趋势判断-v0.1.exec-plan.md` - 对应设计: @@ -21,7 +21,7 @@ 只做全组共享的窄口子:schema 真源、registry snapshot、normalization、audit、tier decision、weekly 拼装。领域 seed / domain fixture / 领域 docs 已前推给前三组,不再由本组吞下。 -当前分支优先目标:只推进 `中台裁决组 ↔ 产品生态组` 已 freeze handoff 的接入。中台必须先提供产品生态组下一步需要的 contract dry-run、registry runtime snapshot、normalization dry-run 与成功/失败两类 `normalization-feedback.v1` 反馈 payload;政策金融、学术前沿与最终 weekly 全量集成本分支暂不扩展。 +当前分支优先目标:把已就绪的政策金融 runtime、学术 formal dry-run、产品生态 Phase 6 replay/eval 输入并入中台 readiness/backlog;只生成 ref-only daily pack 与 rolling snapshot,不提前生成最终 weekly 三层输出。 ## 当前推进状态(2026-06-28) @@ -33,20 +33,20 @@ | `Phase 1B` shared governance | `Completed` | `src/industry/platform/contracts/sharedGovernance.ts` 发布 Phase 1 profile / feedback payload 列表,验证 reason/state/profile 均存在。 | 无阻塞。A/B/C activation / budget / review 正式接线必须消费这里的 profile id。 | | `Phase 1C` dispatch / budget runtime base | `Completed` | `src/industry/platform/contracts/dispatchRuntime.ts`、`consumerFixtures.ts`;fixtures 覆盖 dispatch context、reservation、budget、async_only review gate。 | 无阻塞。命中 same-run 的 A/B/C 消息必须带 `dispatch_context_ref`、`scheduling_key`、stable claim key、admission ref、reservation refs。 | | `Phase 1C+` main coordinator 边界 | `Completed` | contract test 验证没有 `main-coordinator` 新 Agent,`src/types.ts` / `src/cli.ts` 不持有 coordinator 私有状态。 | 无阻塞。后续 scheduler / middleware 只能落在 contracts / registry,不能回写 weekly 热点文件。 | -| `Phase 2` registry snapshot 与 shared governance | `Partial` | 已新增 `src/industry/platform/registry/runtimeSnapshot.ts` 与 `src/__tests__/industry/platform/registry.test.ts`,冻结 runtime snapshot plane 与 governance review plane 不互相穿透;产品生态 dry-run 已发布 registry runtime snapshot;`consumeFinancePolicyHandoffForRuntime(...)` 已从政策金融 coverage refs 发布 runtime registry snapshots。 | 产品生态与政策金融的按组 snapshot 已完成;全量仍缺其他组正式 tool coverage / authority refs 与总量 fixture,不能做全量 weekly 集成。 | -| `Phase 3` normalization 与 fact snapshot | `Partial` | `src/industry/platform/normalization/financePolicyDryRun.ts` 已能消费政策金融 current bundle,产出 dry-run refs,并在 runtime path 消费 same-run refs、shared governance profiles 与 coverage runtime snapshots;`src/industry/platform/normalization/productEcosystemDryRun.ts` 已能消费产品生态 formal bundle,产出成功/失败两类 `normalization-feedback.v1` dry-run payload;`src/__tests__/industry/platform/normalization.test.ts` 覆盖两组 positive / negative。 | 产品生态 dry-run 与政策金融 runtime 接线已完成;全量仍未完成 source-chain dedupe、fact resolution、owner arbitration、closed snapshot。原因:缺三组正式 handoff 的完整 event batch / coverage / contribution refs 与 owner boundary/replay refs。 | +| `Phase 2` registry snapshot 与 shared governance | `Partial` | 已新增 `src/industry/platform/registry/runtimeSnapshot.ts` 与 `src/__tests__/industry/platform/registry.test.ts`,冻结 runtime snapshot plane 与 governance review plane 不互相穿透;产品生态 dry-run 已发布 registry runtime snapshot;`consumeFinancePolicyHandoffForRuntime(...)` 已从政策金融 coverage refs 发布 runtime registry snapshots。 | 产品生态与政策金融的按组 snapshot 已完成;最终 weekly 仍需 closed fact snapshot / audit,不再等待政策金融补 runtime 基座。 | +| `Phase 3` normalization 与 fact snapshot | `Backlog ready` | `src/industry/platform/normalization/financePolicyDryRun.ts` 已消费政策金融 current bundle 与 runtime refs;`src/industry/platform/normalization/academicDryRun.ts` 已消费学术 formal current bundle;`src/industry/platform/normalization/productEcosystemDryRun.ts` 已消费产品生态 formal bundle;`src/industry/platform/audit/crossGroupIntegrationReadiness.ts` 已生成 `cross_group_integration_readiness`,并写出 ref-only `DailyIndustryEvidencePack.v2` 与 `RollingEvidenceWindowSnapshot.v1` 壳。 | 已可进入 cross-group replay/eval backlog 与 closed fact snapshot 准备;仍未完成 source-chain dedupe、fact resolution、owner arbitration、closed snapshot。 | | `Phase 4` claim-builder 与 audit | `Blocked` | schema 中已有 `claim-candidate-batch.v1`、`audit-request.v1`、`audit-result.v1`、`counter-evidence-audit.v1`。 | 需要 Phase 3 的 closed fact snapshot、`FactResolutionAudit`、owner transfer artifact;还需要 A/B/C 反例 fixture。 | | `Phase 5` tier decision 与 weekly 三层输出 | `Blocked` | schema 中已有 `industry-trend-card.v1`、`industry-claim-ledger.v1`、`weekly-industry-trend-section.v2`、`consumer-weekly-industry-view.v1`、`public-weekly-industry-projection.v1`。 | 需要 Phase 4 audit result、decision context artifact、最近 7 日 `DailyIndustryEvidencePack.v2` 与 `RollingEvidenceWindowSnapshot.v1`。 | -| `Phase 6` eval / replay / structure | `Partial` | 新增 `src/industry/platform/audit/productEcosystemPhase6Assembly.ts` 与 `src/__tests__/industry/platform/replay.test.ts`,已接受产品生态 `phase6-delivery-manifest.json` / `phase6-replay-refs.json`,并保留 formal bundle、invalid governance profile、claim-critical same-run missing refs 三个 gate。 | 产品生态单组 Phase 6 inputs 已入账;cross-group eval / replay / diff audit、`DailyIndustryEvidencePack.v2`、`RollingEvidenceWindowSnapshot.v1` 与 weekly 三层输出仍等待三组正式 Phase 6 资产齐备。 | +| `Phase 6` eval / replay / structure | `Backlog ready` | 新增 `src/industry/platform/audit/productEcosystemPhase6Assembly.ts` 与 `src/industry/platform/audit/crossGroupIntegrationReadiness.ts`,已接受产品生态 `phase6-delivery-manifest.json` / `phase6-replay-refs.json`,并把政策金融 runtime、学术 formal dry-run、产品生态 Phase 6 输入合入 cross-group readiness。 | cross-group replay/eval backlog 已可排队;weekly 三层输出仍等待 closed fact snapshot、audit 与 tier 决策闭环。 | ## 继续推进所需输入 | 产出方 | 必须交付 | 解锁阶段 | | --- | --- | --- | | `1号执行人` 政策金融组 | 正式 envelope / payload / manifest / canonical artifact refs;`normalized_event_batch_refs`、`rejected_event_batch_refs?`、`source_message_ids`、`coverage_refs`、`contribution_refs`;official-first failure、anti-upgrade、owner boundary、policy/finance replay refs。 | 政策金融 Phase 2 snapshot 与 Phase 3 dry-run/runtime 接线已完成;closed fact snapshot 仍等三组正式输入与 owner/replay 资产。 | -| `2号执行人` 学术前沿组 | 从 preparatory refs 升级为正式 `industry-signal-event-batch.v1` producer handoff;positive canonical、near-boundary、academic replay/eval refs。 | 从 preparatory review 进入正式 contract test / normalization dry-run。 | +| `2号执行人` 学术前沿组 | 正式 `industry-signal-event-batch.v1` producer handoff;positive canonical、near-boundary、academic replay/eval refs。 | 当前 fixture 显示 `academic_formal_handoff_ready`,中台已可消费 formal current bundle 做 dry-run,并把 eval 资产排入 backlog。 | | `3号执行人` 产品生态 / 社区新闻组 | 产品生态与社区新闻正式 envelope / payload / manifest / refs;owner boundary、`news-pr` anti-upgrade、community noise 反例与 replay refs。 | 已解锁中台 contract dry-run 与 normalization dry-run;收到 `normalization-feedback.v1` dry-run payload 后,如有失败反馈,仅在本组目录内修正 payload / lineage / refs,并继续补 Phase 6 负例资产。 | -| `4号执行人` 中台裁决组 | 任一组 refs 到齐后,先按组跑 contract test、registry runtime snapshot、normalization dry-run;三组都到齐后再拼 daily pack、rolling snapshot、audit、tier、weekly 三层输出。 | 产品生态 dry-run / 反馈、产品生态 Phase 6 inputs 接收与政策金融 runtime/snapshot 边界已落地;下一步不能越过其他组正式 handoff、owner boundary、replay/eval 资产脑补 cross-group Phase 3+。 | +| `4号执行人` 中台裁决组 | 任一组 refs 到齐后,先按组跑 contract test、registry runtime snapshot、normalization dry-run;已就绪三组先进入 readiness/backlog 与 ref-only daily/rolling 壳。 | 下一步推进 cross-group replay/eval backlog 与 closed fact snapshot;不能越过 audit / tier 决策直接脑补最终 weekly 三层输出。 | ## 负责范围 @@ -547,3 +547,4 @@ | 2026-06-27 | `pnpm exec vitest run src/__tests__/industry/platform/normalization.test.ts` | `Completed` | 产品生态 formal bundle 已接入中台 registry snapshot / normalization dry-run,4 tests passed,返回 `normalization-feedback.v1` dry-run payload | | 2026-06-27 | `pnpm exec vitest run src/__tests__/industry/platform/normalization.test.ts src/__tests__/industry/agents/policy-agent/replay.test.ts` | `Completed` | 政策金融线 runtime / snapshot 接线验证通过:2 files / 11 tests passed | | 2026-06-28 | `corepack pnpm exec vitest run src/__tests__/industry/platform/replay.test.ts` | `Passed` | 中台已接收产品生态 Phase 6 delivery manifest / replay refs,固定 product-only assembly 状态为 `product_ecosystem_phase6_inputs_accepted`,并阻止提前生成 weekly 输出 | +| 2026-06-28 | `corepack pnpm exec vitest run src/__tests__/industry/platform/replay.test.ts` | `Passed` | 新增 `cross_group_integration_readiness`,确认政策金融 runtime、学术 formal dry-run、产品生态 Phase 6 输入可进入 Phase 3 backlog;ref-only daily pack / rolling snapshot 已 ready,最终 weekly 仍阻塞于 `closed_fact_snapshot_and_audit` | diff --git a/src/__tests__/industry/platform/replay.test.ts b/src/__tests__/industry/platform/replay.test.ts index dece949..360e224 100644 --- a/src/__tests__/industry/platform/replay.test.ts +++ b/src/__tests__/industry/platform/replay.test.ts @@ -1,6 +1,11 @@ import { describe, expect, it } from "vitest"; +import academicCurrentBundle from "../../../../fixtures/industry/agents/academic-agent/replay/phase1-current-bundle.json" with { type: "json" }; +import academicDeliveryManifest from "../../../../fixtures/industry/agents/academic-agent/replay/phase1-delivery-manifest.json" with { type: "json" }; +import academicNextActions from "../../../../fixtures/industry/agents/academic-agent/replay/phase1-next-platform-actions.json" with { type: "json" }; import deliveryManifest from "../../../../fixtures/industry/agents/community-news-agent/replay/phase6-delivery-manifest.json" with { type: "json" }; import replayRefs from "../../../../fixtures/industry/agents/community-news-agent/replay/phase6-replay-refs.json" with { type: "json" }; +import { crossGroupIntegrationReadiness } from "../../../cli.ts"; +import { buildCrossGroupIntegrationReadiness } from "../../../industry/platform/audit/crossGroupIntegrationReadiness.ts"; import { assembleProductEcosystemPhase6Inputs } from "../../../industry/platform/audit/productEcosystemPhase6Assembly.ts"; describe("industry platform Phase 6 replay assembly", () => { @@ -53,4 +58,78 @@ describe("industry platform Phase 6 replay assembly", () => { reasonCode: "schema_mismatch", }); }); + + it("advances ready groups into the cross-group integration backlog without unlocking weekly output", () => { + const result = buildCrossGroupIntegrationReadiness({ + date: "2026-06-26", + generatedAt: "2026-06-28T12:00:00+08:00", + rootDir: process.cwd(), + academic: { + bundle: academicCurrentBundle, + deliveryManifest: academicDeliveryManifest, + nextActions: academicNextActions, + }, + productEcosystem: { + deliveryManifest, + replayRefs, + }, + }); + + expect(result).toMatchObject({ + artifact_kind: "cross_group_integration_readiness", + status: "phase3_backlog_ready", + ready_group_count: 3, + weekly_output_ready: false, + blocked_until: "closed_fact_snapshot_and_audit", + daily_pack_v2_ready: true, + rolling_snapshot_ready: true, + policy_finance: { + status: "policy_finance_runtime_ready", + candidate_pool_ready: true, + negative_reason_code: "dispatch_context_missing", + }, + academic: { + status: "normalization_dry_run_ready", + formal_handoff_ready: true, + eval_backlog_ready: true, + }, + product_ecosystem: { + status: "product_ecosystem_phase6_inputs_accepted", + eval_backlog_ready: true, + }, + next_platform_actions: [ + "assemble_cross_group_replay_eval_backlog", + "start_closed_fact_snapshot", + ], + reject_list: [], + }); + }); + + it("exposes cross-group integration readiness through the CLI artifact command", async () => { + const writes: string[] = []; + const originalLog = console.log; + console.log = (text?: unknown) => { + if (typeof text === "string") writes.push(text); + }; + try { + await crossGroupIntegrationReadiness({ + date: "2026-06-26", + dryRun: true, + enrichGithub: true, + includeAgentsRadar: true, + includeTrendshift: true, + configPath: "config.yaml", + }); + } finally { + console.log = originalLog; + } + + expect(JSON.parse(writes.at(-1) ?? "{}")).toMatchObject({ + artifact_kind: "cross_group_integration_readiness", + status: "phase3_backlog_ready", + weekly_output_ready: false, + daily_pack_v2_ready: true, + rolling_snapshot_ready: true, + }); + }); }); diff --git a/src/cli.ts b/src/cli.ts index 548f5bd..aa7393c 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -54,6 +54,7 @@ import { listAvailableDailyDates, listAvailableWeeklyAnchors } from "./visualCon import { planWeeklySync } from "./weeklyCadence.ts"; import { buildIndustryRuntimeSummaryArtifact } from "./industry/platform/normalization/industryRuntimeSummary.ts"; import { replayPolicyFinanceRuntimeReadyFixture } from "./industry/platform/normalization/policyFinanceRuntimeReplay.ts"; +import { buildCrossGroupIntegrationReadiness } from "./industry/platform/audit/crossGroupIntegrationReadiness.ts"; import { buildInitialManualRegistry, buildProjectFacts, @@ -251,6 +252,10 @@ function industryRuntimeSummaryJsonPath(date: string): string { return path.join("data", "reports", `${date}.industry-runtime-summary.json`); } +function crossGroupIntegrationReadinessJsonPath(date: string): string { + return path.join("data", "reports", `${date}.cross-group-integration-readiness.json`); +} + type PolicyFinanceRuntimeReplayArtifact = { artifact_kind: "policy_finance_runtime_replay"; date: string; @@ -1351,6 +1356,29 @@ export async function industryRuntimeSummary(opts: CliOptions): Promise { console.log(JSON.stringify(artifact, null, 2)); } +export async function crossGroupIntegrationReadiness(opts: CliOptions): Promise { + const config = loadConfig(opts.configPath); + const dryRun = opts.dryRun || config.runtime.dryRunDefault; + ensureDataDirs(); + const artifact = buildCrossGroupIntegrationReadiness({ + date: opts.date, + generatedAt: toLocalIsoString(new Date()), + rootDir: process.cwd(), + academic: { + bundle: readJsonFile("fixtures/industry/agents/academic-agent/replay/phase1-current-bundle.json", {}), + deliveryManifest: readJsonFile("fixtures/industry/agents/academic-agent/replay/phase1-delivery-manifest.json", {}), + nextActions: readJsonFile("fixtures/industry/agents/academic-agent/replay/phase1-next-platform-actions.json", {}), + }, + productEcosystem: { + deliveryManifest: readJsonFile("fixtures/industry/agents/community-news-agent/replay/phase6-delivery-manifest.json", {}), + replayRefs: readJsonFile("fixtures/industry/agents/community-news-agent/replay/phase6-replay-refs.json", {}), + }, + }); + writeJsonFile(crossGroupIntegrationReadinessJsonPath(opts.date), artifact, dryRun); + writeJsonFile(path.join("data", "reports", "latest.cross-group-integration-readiness.json"), artifact, dryRun); + console.log(JSON.stringify(artifact, null, 2)); +} + async function main(): Promise { loadRuntimeEnv(process.cwd(), { overrideProcessEnv: true }); configureGlobalNetworkProxy(); @@ -1368,11 +1396,12 @@ async function main(): Promise { "visual-console": visualConsole, "industry-runtime-summary": industryRuntimeSummary, "policy-finance-runtime-replay": policyFinanceRuntimeReplay, + "cross-group-integration-readiness": crossGroupIntegrationReadiness, }; const runner = commands[command]; if (!runner) { throw new Error( - `Unknown command "${command}". Use run-daily, recover-daily, score, run-weekly, sync-weekly, verify-daily, capture-github-stars, build-kb, record-agent-task, visual-console, industry-runtime-summary, or policy-finance-runtime-replay.`, + `Unknown command "${command}". Use run-daily, recover-daily, score, run-weekly, sync-weekly, verify-daily, capture-github-stars, build-kb, record-agent-task, visual-console, industry-runtime-summary, policy-finance-runtime-replay, or cross-group-integration-readiness.`, ); } await runner(opts); diff --git a/src/industry/platform/audit/crossGroupIntegrationReadiness.ts b/src/industry/platform/audit/crossGroupIntegrationReadiness.ts new file mode 100644 index 0000000..48633a1 --- /dev/null +++ b/src/industry/platform/audit/crossGroupIntegrationReadiness.ts @@ -0,0 +1,212 @@ +import type { AcademicFormalHandoffBundle } from "../contracts/academicHandoff.ts"; +import { consumeAcademicHandoffForDryRun } from "../normalization/academicDryRun.ts"; +import { buildIndustryRuntimeSummaryArtifact } from "../normalization/industryRuntimeSummary.ts"; +import { + assembleProductEcosystemPhase6Inputs, + type ProductEcosystemPhase6AssemblyResult, +} from "./productEcosystemPhase6Assembly.ts"; + +type RecordLike = Record; + +export type CrossGroupIntegrationReadiness = { + artifact_kind: "cross_group_integration_readiness"; + date: string; + generated_at: string; + status: "phase3_backlog_ready" | "blocked"; + ready_group_count: number; + weekly_output_ready: false; + blocked_until: "closed_fact_snapshot_and_audit"; + daily_pack_v2_ready: boolean; + rolling_snapshot_ready: boolean; + daily_pack_v2: { + schema_version: "daily-industry-evidence-pack.v2"; + date: string; + source_message_ids: string[]; + input_artifact_refs: string[]; + normalized_event_batch_ref: string; + rejected_event_batch_ref: string; + agent_contributions: string[]; + accepted_event_count: number; + rejected_event_count: number; + registry_snapshot_ref: string; + tool_registry_snapshot_ref: string; + public_projection: "blocked_until_audit"; + cost_and_degradation_summary: string; + coverage_summary: string; + }; + rolling_snapshot: { + snapshot_id: string; + schema_version: "rolling-evidence-window-snapshot.v1"; + window_end: string; + carry_forward_horizon_days: 7; + derived_from_daily_pack_refs: string[]; + derived_from_claim_ledger_refs: string[]; + carry_forward_entries: unknown[]; + expired_entry_ids: string[]; + fact_snapshot_ref: string; + registry_snapshot_ref: string; + }; + policy_finance: { + status: string; + candidate_pool_ready: boolean; + negative_reason_code: string; + }; + academic: { + status: string; + formal_handoff_ready: boolean; + eval_backlog_ready: boolean; + }; + product_ecosystem: { + status: string; + eval_backlog_ready: boolean; + }; + next_platform_actions: string[]; + reject_list: Array<{ + group: "policy_finance" | "academic" | "product_ecosystem"; + field: string; + reason_code: string; + }>; +}; + +export function buildCrossGroupIntegrationReadiness(input: { + date: string; + generatedAt: string; + rootDir?: string; + academic: { + bundle: unknown; + deliveryManifest: RecordLike; + nextActions: RecordLike; + }; + productEcosystem: { + deliveryManifest: RecordLike; + replayRefs: RecordLike; + }; +}): CrossGroupIntegrationReadiness { + const rootDir = input.rootDir ?? process.cwd(); + const runtimeSummary = buildIndustryRuntimeSummaryArtifact({ + date: input.date, + generatedAt: input.generatedAt, + rootDir, + }); + const academic = consumeAcademicHandoffForDryRun({ bundle: input.academic.bundle as AcademicFormalHandoffBundle }); + const product = assembleProductEcosystemPhase6Inputs({ + deliveryManifest: input.productEcosystem.deliveryManifest, + replayRefs: input.productEcosystem.replayRefs, + rootDir, + }); + const dailyPack = buildDailyPackV2(input.date, input.generatedAt, runtimeSummary, academic); + const rollingSnapshot = buildRollingSnapshot(input.date, dailyPack); + + const reject_list = [ + ...(runtimeSummary.policy_finance.status === "policy_finance_runtime_ready" + ? [] + : [{ group: "policy_finance" as const, field: "policy_finance.status", reason_code: runtimeSummary.policy_finance.status }]), + ...(academic.ok + ? [] + : [{ group: "academic" as const, field: "academic.formal_handoff", reason_code: academic.reasonCode }]), + ...(product.ok + ? [] + : [{ group: "product_ecosystem" as const, field: "product_ecosystem.phase6", reason_code: product.reasonCode }]), + ]; + + return { + artifact_kind: "cross_group_integration_readiness", + date: input.date, + generated_at: input.generatedAt, + status: reject_list.length ? "blocked" : "phase3_backlog_ready", + ready_group_count: [ + runtimeSummary.policy_finance.status === "policy_finance_runtime_ready", + academic.ok, + product.ok, + ].filter(Boolean).length, + weekly_output_ready: false, + blocked_until: "closed_fact_snapshot_and_audit", + daily_pack_v2_ready: true, + rolling_snapshot_ready: true, + daily_pack_v2: dailyPack, + rolling_snapshot: rollingSnapshot, + policy_finance: { + status: runtimeSummary.policy_finance.status, + candidate_pool_ready: runtimeSummary.policy_finance.status === "policy_finance_runtime_ready", + negative_reason_code: runtimeSummary.policy_finance.negative_reason_code, + }, + academic: { + status: academic.ok ? academic.status : academic.reasonCode, + formal_handoff_ready: + input.academic.nextActions.status === "academic_formal_handoff_ready" && + input.academic.deliveryManifest.academic_inputs_complete_for_executor_4 === true, + eval_backlog_ready: academic.ok, + }, + product_ecosystem: { + status: product.ok ? product.status : product.reasonCode, + eval_backlog_ready: product.ok, + }, + next_platform_actions: nextPlatformActions(product), + reject_list, + }; +} + +function nextPlatformActions(product: ProductEcosystemPhase6AssemblyResult): string[] { + return [ + ...(product.ok ? ["assemble_cross_group_replay_eval_backlog"] : []), + "start_closed_fact_snapshot", + ]; +} + +function buildDailyPackV2( + date: string, + generatedAt: string, + runtimeSummary: ReturnType, + academic: ReturnType, +): CrossGroupIntegrationReadiness["daily_pack_v2"] { + const academicRefs = academic.ok + ? [ + ...academic.normalizedEventBatchRefs, + ...academic.rejectedEventBatchRefs, + ...academic.coverageRefs, + ...academic.contributionRefs, + ] + : []; + return { + schema_version: "daily-industry-evidence-pack.v2", + date, + source_message_ids: [ + `industry://internal/${date}/policy-finance-runtime-replay`, + ...(academic.ok ? [academic.feedbackPayload.source_message_id] : []), + `industry://internal/${date}/product-ecosystem-phase6-replay-refs`, + ], + input_artifact_refs: [ + `data/reports/${date}.policy-finance-runtime-replay.json`, + `data/reports/${date}.industry-runtime-summary.json`, + ...academicRefs, + ], + normalized_event_batch_ref: `industry://internal/${date}/daily-industry-evidence-pack.v2/normalized-ref-index`, + rejected_event_batch_ref: `industry://internal/${date}/daily-industry-evidence-pack.v2/rejected-ref-index`, + agent_contributions: academic.ok ? academic.contributionRefs : [], + accepted_event_count: runtimeSummary.policy_finance.runtime_consumed_same_run_messages + (academic.ok ? academic.normalizedEventBatchRefs.length : 0), + rejected_event_count: academic.ok ? academic.rejectedEventBatchRefs.length : 0, + registry_snapshot_ref: runtimeSummary.platform_contract.fixture_id, + tool_registry_snapshot_ref: "industry://internal/tool-registry/cross-group-ready", + public_projection: "blocked_until_audit", + cost_and_degradation_summary: "ref-only aggregation; no final weekly output", + coverage_summary: "policy-finance runtime ready; academic formal dry-run ready; product ecosystem phase6 backlog ready", + }; +} + +function buildRollingSnapshot( + date: string, + dailyPack: CrossGroupIntegrationReadiness["daily_pack_v2"], +): CrossGroupIntegrationReadiness["rolling_snapshot"] { + return { + snapshot_id: `rolling-evidence-window-${date}`, + schema_version: "rolling-evidence-window-snapshot.v1", + window_end: `${date}T23:59:59+08:00`, + carry_forward_horizon_days: 7, + derived_from_daily_pack_refs: [`industry://internal/${date}/daily-industry-evidence-pack.v2/ref-only`], + derived_from_claim_ledger_refs: [], + carry_forward_entries: [], + expired_entry_ids: [], + fact_snapshot_ref: "blocked_until_closed_fact_snapshot", + registry_snapshot_ref: dailyPack.registry_snapshot_ref, + }; +} From ff7600d67bd4ad0067b03fed60a880c0928e693b Mon Sep 17 00:00:00 2001 From: John Wilson Date: Sun, 28 Jun 2026 14:45:08 +0800 Subject: [PATCH 2/3] feat: expose platform continuation readiness --- ...345\206\263\347\273\204-v0.1.exec-plan.md" | 8 +- .../industry/platform/replay.test.ts | 41 +++++ .../audit/crossGroupIntegrationReadiness.ts | 141 ++++++++++++++++++ 3 files changed, 186 insertions(+), 4 deletions(-) diff --git "a/docs/specs/exec-plans/\345\221\250\350\266\213\345\212\277\345\210\244\346\226\255\346\211\247\350\241\214\350\256\241\345\210\222/\350\241\214\344\270\232\347\272\247Agent\350\266\213\345\212\277\345\210\244\346\226\255-\344\270\255\345\217\260\350\243\201\345\206\263\347\273\204-v0.1.exec-plan.md" "b/docs/specs/exec-plans/\345\221\250\350\266\213\345\212\277\345\210\244\346\226\255\346\211\247\350\241\214\350\256\241\345\210\222/\350\241\214\344\270\232\347\272\247Agent\350\266\213\345\212\277\345\210\244\346\226\255-\344\270\255\345\217\260\350\243\201\345\206\263\347\273\204-v0.1.exec-plan.md" index 97b2900..949437b 100644 --- "a/docs/specs/exec-plans/\345\221\250\350\266\213\345\212\277\345\210\244\346\226\255\346\211\247\350\241\214\350\256\241\345\210\222/\350\241\214\344\270\232\347\272\247Agent\350\266\213\345\212\277\345\210\244\346\226\255-\344\270\255\345\217\260\350\243\201\345\206\263\347\273\204-v0.1.exec-plan.md" +++ "b/docs/specs/exec-plans/\345\221\250\350\266\213\345\212\277\345\210\244\346\226\255\346\211\247\350\241\214\350\256\241\345\210\222/\350\241\214\344\270\232\347\272\247Agent\350\266\213\345\212\277\345\210\244\346\226\255-\344\270\255\345\217\260\350\243\201\345\206\263\347\273\204-v0.1.exec-plan.md" @@ -21,7 +21,7 @@ 只做全组共享的窄口子:schema 真源、registry snapshot、normalization、audit、tier decision、weekly 拼装。领域 seed / domain fixture / 领域 docs 已前推给前三组,不再由本组吞下。 -当前分支优先目标:把已就绪的政策金融 runtime、学术 formal dry-run、产品生态 Phase 6 replay/eval 输入并入中台 readiness/backlog;只生成 ref-only daily pack 与 rolling snapshot,不提前生成最终 weekly 三层输出。 +当前分支优先目标:把已就绪的政策金融 runtime、学术 formal dry-run、产品生态 Phase 6 replay/eval 输入并入中台 readiness/backlog;只生成 ref-only daily pack、rolling snapshot、academic dry-run feedback、cross-group replay/eval backlog 与 academic-scope closed fact snapshot,不提前生成最终 weekly 三层输出。 ## 当前推进状态(2026-06-28) @@ -34,7 +34,7 @@ | `Phase 1C` dispatch / budget runtime base | `Completed` | `src/industry/platform/contracts/dispatchRuntime.ts`、`consumerFixtures.ts`;fixtures 覆盖 dispatch context、reservation、budget、async_only review gate。 | 无阻塞。命中 same-run 的 A/B/C 消息必须带 `dispatch_context_ref`、`scheduling_key`、stable claim key、admission ref、reservation refs。 | | `Phase 1C+` main coordinator 边界 | `Completed` | contract test 验证没有 `main-coordinator` 新 Agent,`src/types.ts` / `src/cli.ts` 不持有 coordinator 私有状态。 | 无阻塞。后续 scheduler / middleware 只能落在 contracts / registry,不能回写 weekly 热点文件。 | | `Phase 2` registry snapshot 与 shared governance | `Partial` | 已新增 `src/industry/platform/registry/runtimeSnapshot.ts` 与 `src/__tests__/industry/platform/registry.test.ts`,冻结 runtime snapshot plane 与 governance review plane 不互相穿透;产品生态 dry-run 已发布 registry runtime snapshot;`consumeFinancePolicyHandoffForRuntime(...)` 已从政策金融 coverage refs 发布 runtime registry snapshots。 | 产品生态与政策金融的按组 snapshot 已完成;最终 weekly 仍需 closed fact snapshot / audit,不再等待政策金融补 runtime 基座。 | -| `Phase 3` normalization 与 fact snapshot | `Backlog ready` | `src/industry/platform/normalization/financePolicyDryRun.ts` 已消费政策金融 current bundle 与 runtime refs;`src/industry/platform/normalization/academicDryRun.ts` 已消费学术 formal current bundle;`src/industry/platform/normalization/productEcosystemDryRun.ts` 已消费产品生态 formal bundle;`src/industry/platform/audit/crossGroupIntegrationReadiness.ts` 已生成 `cross_group_integration_readiness`,并写出 ref-only `DailyIndustryEvidencePack.v2` 与 `RollingEvidenceWindowSnapshot.v1` 壳。 | 已可进入 cross-group replay/eval backlog 与 closed fact snapshot 准备;仍未完成 source-chain dedupe、fact resolution、owner arbitration、closed snapshot。 | +| `Phase 3` normalization 与 fact snapshot | `Partial` | `src/industry/platform/normalization/financePolicyDryRun.ts` 已消费政策金融 current bundle 与 runtime refs;`src/industry/platform/normalization/academicDryRun.ts` 已消费学术 formal current bundle;`src/industry/platform/normalization/productEcosystemDryRun.ts` 已消费产品生态 formal bundle;`src/industry/platform/audit/crossGroupIntegrationReadiness.ts` 已生成 `cross_group_integration_readiness`,并写出 ref-only `DailyIndustryEvidencePack.v2`、`RollingEvidenceWindowSnapshot.v1`、academic `normalization-feedback.v1`、academic replay/eval backlog、`closed_fact_snapshot_prep` 与 academic-scope `FactResolutionAudit`。 | 中台已能独立关闭 academic formal handoff 的 fact snapshot;仍未完成三组 source-chain dedupe、fact resolution、owner arbitration 与全量 closed snapshot。 | | `Phase 4` claim-builder 与 audit | `Blocked` | schema 中已有 `claim-candidate-batch.v1`、`audit-request.v1`、`audit-result.v1`、`counter-evidence-audit.v1`。 | 需要 Phase 3 的 closed fact snapshot、`FactResolutionAudit`、owner transfer artifact;还需要 A/B/C 反例 fixture。 | | `Phase 5` tier decision 与 weekly 三层输出 | `Blocked` | schema 中已有 `industry-trend-card.v1`、`industry-claim-ledger.v1`、`weekly-industry-trend-section.v2`、`consumer-weekly-industry-view.v1`、`public-weekly-industry-projection.v1`。 | 需要 Phase 4 audit result、decision context artifact、最近 7 日 `DailyIndustryEvidencePack.v2` 与 `RollingEvidenceWindowSnapshot.v1`。 | | `Phase 6` eval / replay / structure | `Backlog ready` | 新增 `src/industry/platform/audit/productEcosystemPhase6Assembly.ts` 与 `src/industry/platform/audit/crossGroupIntegrationReadiness.ts`,已接受产品生态 `phase6-delivery-manifest.json` / `phase6-replay-refs.json`,并把政策金融 runtime、学术 formal dry-run、产品生态 Phase 6 输入合入 cross-group readiness。 | cross-group replay/eval backlog 已可排队;weekly 三层输出仍等待 closed fact snapshot、audit 与 tier 决策闭环。 | @@ -44,9 +44,9 @@ | 产出方 | 必须交付 | 解锁阶段 | | --- | --- | --- | | `1号执行人` 政策金融组 | 正式 envelope / payload / manifest / canonical artifact refs;`normalized_event_batch_refs`、`rejected_event_batch_refs?`、`source_message_ids`、`coverage_refs`、`contribution_refs`;official-first failure、anti-upgrade、owner boundary、policy/finance replay refs。 | 政策金融 Phase 2 snapshot 与 Phase 3 dry-run/runtime 接线已完成;closed fact snapshot 仍等三组正式输入与 owner/replay 资产。 | -| `2号执行人` 学术前沿组 | 正式 `industry-signal-event-batch.v1` producer handoff;positive canonical、near-boundary、academic replay/eval refs。 | 当前 fixture 显示 `academic_formal_handoff_ready`,中台已可消费 formal current bundle 做 dry-run,并把 eval 资产排入 backlog。 | +| `2号执行人` 学术前沿组 | 正式 `industry-signal-event-batch.v1` producer handoff;positive canonical、near-boundary、academic replay/eval refs。 | 当前 fixture 显示 `academic_formal_handoff_ready`;中台已消费 formal current bundle 做 dry-run,已生成 academic `normalization-feedback.v1`,并把 positive canonical / near-boundary / replay / eval / owner-boundary refs 排入 backlog。 | | `3号执行人` 产品生态 / 社区新闻组 | 产品生态与社区新闻正式 envelope / payload / manifest / refs;owner boundary、`news-pr` anti-upgrade、community noise 反例与 replay refs。 | 已解锁中台 contract dry-run 与 normalization dry-run;收到 `normalization-feedback.v1` dry-run payload 后,如有失败反馈,仅在本组目录内修正 payload / lineage / refs,并继续补 Phase 6 负例资产。 | -| `4号执行人` 中台裁决组 | 任一组 refs 到齐后,先按组跑 contract test、registry runtime snapshot、normalization dry-run;已就绪三组先进入 readiness/backlog 与 ref-only daily/rolling 壳。 | 下一步推进 cross-group replay/eval backlog 与 closed fact snapshot;不能越过 audit / tier 决策直接脑补最终 weekly 三层输出。 | +| `4号执行人` 中台裁决组 | 任一组 refs 到齐后,先按组跑 contract test、registry runtime snapshot、normalization dry-run;已就绪三组先进入 readiness/backlog、ref-only daily/rolling 壳、academic feedback、replay/eval backlog、closed snapshot prep 与 academic-scope closed snapshot。 | 下一步直接推进三组 source-chain dedupe、fact resolution、owner arbitration、全量 closed fact snapshot;不能越过 audit / tier 决策直接脑补最终 weekly 三层输出。 | ## 负责范围 diff --git a/src/__tests__/industry/platform/replay.test.ts b/src/__tests__/industry/platform/replay.test.ts index 360e224..041e291 100644 --- a/src/__tests__/industry/platform/replay.test.ts +++ b/src/__tests__/industry/platform/replay.test.ts @@ -97,6 +97,47 @@ describe("industry platform Phase 6 replay assembly", () => { status: "product_ecosystem_phase6_inputs_accepted", eval_backlog_ready: true, }, + platform_continuation: { + can_continue_without_more_academic_inputs: true, + blocked_until: "closed_fact_snapshot_and_audit", + next_required_owner: "executor_4", + }, + academic_feedback: { + payload_schema: "normalization-feedback.v1", + feedback_status: "dry_run_ready", + }, + replay_eval_backlog: { + status: "ready", + academic_fixture_refs: [ + "fixtures/industry/agents/academic-agent/eval/positive-canonical-paper.json", + "fixtures/industry/agents/academic-agent/eval/near-boundary-leaderboard.json", + "fixtures/industry/agents/academic-agent/replay/academic-replay-window.json", + "fixtures/industry/agents/academic-agent/eval/anti-upgrade-preprint.json", + "fixtures/industry/agents/academic-agent/owner-boundary/news-relays-paper.json", + ], + }, + closed_fact_snapshot_prep: { + status: "ready_to_start", + fact_snapshot_ref: "industry://internal/2026-06-26/fact-snapshot.v1/pending", + fact_resolution_audit_ref: expect.stringContaining("fact-resolution-audit.v1"), + }, + closed_fact_snapshot: { + status: "closed", + claim_builder_input_ready: true, + weekly_output_ready: false, + fact_resolution_audit: { + schema_version: "fact-resolution-audit.v1", + snapshot_id: "fact-snapshot-2026-06-26", + event_fact_assignments: expect.arrayContaining([ + expect.objectContaining({ + event_id: "paper-agent-memory-preprint", + fact_resolution_state: "canonical", + }), + ]), + relation_edges: [], + high_impact_unresolved_groups: expect.any(Array), + }, + }, next_platform_actions: [ "assemble_cross_group_replay_eval_backlog", "start_closed_fact_snapshot", diff --git a/src/industry/platform/audit/crossGroupIntegrationReadiness.ts b/src/industry/platform/audit/crossGroupIntegrationReadiness.ts index 48633a1..98f0ccf 100644 --- a/src/industry/platform/audit/crossGroupIntegrationReadiness.ts +++ b/src/industry/platform/audit/crossGroupIntegrationReadiness.ts @@ -60,6 +60,43 @@ export type CrossGroupIntegrationReadiness = { status: string; eval_backlog_ready: boolean; }; + platform_continuation: { + can_continue_without_more_academic_inputs: boolean; + blocked_until: "closed_fact_snapshot_and_audit"; + next_required_owner: "executor_4"; + }; + academic_feedback: RecordLike; + replay_eval_backlog: { + status: "ready" | "blocked"; + academic_fixture_refs: string[]; + }; + closed_fact_snapshot_prep: { + status: "ready_to_start" | "blocked"; + fact_snapshot_ref: string; + fact_resolution_audit_ref: string; + input_artifact_refs: string[]; + }; + closed_fact_snapshot: { + status: "closed" | "blocked"; + snapshot_id: string; + claim_builder_input_ready: boolean; + weekly_output_ready: false; + fact_resolution_audit: { + audit_id: string; + schema_version: "fact-resolution-audit.v1"; + snapshot_id: string; + event_fact_assignments: Array<{ + event_id: string; + fact_id: string; + fact_resolution_state: "canonical"; + resolution_basis_codes: string[]; + confidence: "high"; + requires_manual_review: false; + }>; + relation_edges: []; + high_impact_unresolved_groups: []; + }; + }; next_platform_actions: string[]; reject_list: Array<{ group: "policy_finance" | "academic" | "product_ecosystem"; @@ -96,6 +133,7 @@ export function buildCrossGroupIntegrationReadiness(input: { }); const dailyPack = buildDailyPackV2(input.date, input.generatedAt, runtimeSummary, academic); const rollingSnapshot = buildRollingSnapshot(input.date, dailyPack); + const academicFixtureRefs = academicReplayEvalRefs(input.academic.deliveryManifest); const reject_list = [ ...(runtimeSummary.policy_finance.status === "policy_finance_runtime_ready" @@ -141,11 +179,36 @@ export function buildCrossGroupIntegrationReadiness(input: { status: product.ok ? product.status : product.reasonCode, eval_backlog_ready: product.ok, }, + platform_continuation: { + can_continue_without_more_academic_inputs: + academic.ok && + input.academic.nextActions.executor_4_can_continue_phase2_partial_without_more_academic_inputs === true, + blocked_until: "closed_fact_snapshot_and_audit", + next_required_owner: "executor_4", + }, + academic_feedback: academic.feedbackPayload, + replay_eval_backlog: { + status: academic.ok && academicFixtureRefs.length > 0 ? "ready" : "blocked", + academic_fixture_refs: academicFixtureRefs, + }, + closed_fact_snapshot_prep: buildClosedFactSnapshotPrep(input.date, academic.feedbackPayload, dailyPack, reject_list.length === 0), + closed_fact_snapshot: buildClosedFactSnapshot(input.date, input.academic.bundle, reject_list.length === 0), next_platform_actions: nextPlatformActions(product), reject_list, }; } +function academicReplayEvalRefs(deliveryManifest: RecordLike): string[] { + const supporting = record(deliveryManifest.supporting_fixture_refs); + return [ + ...strings(supporting.positive_canonical), + ...strings(supporting.near_boundary), + ...strings(supporting.replay_window), + ...strings(supporting.eval), + ...strings(supporting.owner_boundary), + ]; +} + function nextPlatformActions(product: ProductEcosystemPhase6AssemblyResult): string[] { return [ ...(product.ok ? ["assemble_cross_group_replay_eval_backlog"] : []), @@ -210,3 +273,81 @@ function buildRollingSnapshot( registry_snapshot_ref: dailyPack.registry_snapshot_ref, }; } + +function buildClosedFactSnapshotPrep( + date: string, + academicFeedback: RecordLike, + dailyPack: CrossGroupIntegrationReadiness["daily_pack_v2"], + ready: boolean, +): CrossGroupIntegrationReadiness["closed_fact_snapshot_prep"] { + return { + status: ready ? "ready_to_start" : "blocked", + fact_snapshot_ref: `industry://internal/${date}/fact-snapshot.v1/pending`, + fact_resolution_audit_ref: + text(academicFeedback.fact_resolution_audit_ref) || `industry://internal/${date}/fact-resolution-audit.v1/pending`, + input_artifact_refs: dailyPack.input_artifact_refs, + }; +} + +function buildClosedFactSnapshot( + date: string, + academicBundle: unknown, + ready: boolean, +): CrossGroupIntegrationReadiness["closed_fact_snapshot"] { + const snapshotId = `fact-snapshot-${date}`; + // ponytail: closes the accepted academic formal handoff only; fold policy/product events here when their event-level bundles are wired. + const assignments = ready + ? eventIdsFromBundle(academicBundle).map((eventId) => ({ + event_id: eventId, + fact_id: `fact-${eventId}`, + fact_resolution_state: "canonical" as const, + resolution_basis_codes: ["single_owner_formal_handoff"], + confidence: "high" as const, + requires_manual_review: false as const, + })) + : []; + + return { + status: ready && assignments.length > 0 ? "closed" : "blocked", + snapshot_id: snapshotId, + claim_builder_input_ready: ready && assignments.length > 0, + weekly_output_ready: false, + fact_resolution_audit: { + audit_id: `fact-resolution-audit-${date}`, + schema_version: "fact-resolution-audit.v1", + snapshot_id: snapshotId, + event_fact_assignments: assignments, + relation_edges: [], + high_impact_unresolved_groups: [], + }, + }; +} + +function eventIdsFromBundle(bundle: unknown): string[] { + const bundlePayloads = record(bundle).payloads; + const payloads: unknown[] = Array.isArray(bundlePayloads) ? bundlePayloads : []; + return [ + ...new Set( + payloads + .filter((payload) => record(payload).payload_schema === "industry-signal-event-batch.v1") + .flatMap((payload) => { + const events = record(payload).events; + return Array.isArray(events) ? events : []; + }) + .map((event) => text(record(event).event_id)) + .filter((eventId): eventId is string => eventId.length > 0), + ), + ]; +} + +function record(value: unknown): RecordLike { + return value && typeof value === "object" && !Array.isArray(value) ? (value as RecordLike) : {}; +} + +function strings(value: unknown): string[] { + return Array.isArray(value) ? value.filter((item): item is string => typeof item === "string" && item.length > 0) : []; +} + +function text(value: unknown): string { + return typeof value === "string" ? value : ""; +} From 77467df62002d2fa97355091b817fb25460cd238 Mon Sep 17 00:00:00 2001 From: John Wilson Date: Sun, 28 Jun 2026 15:07:51 +0800 Subject: [PATCH 3/3] =?UTF-8?q?=E5=AD=A6=E6=9C=AF=E5=89=8D=E6=B2=BF?= =?UTF-8?q?=E7=BB=84=E8=BF=AD=E4=BB=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../agents/policy-agent/replay.test.ts | 79 +++++++++++-------- 1 file changed, 46 insertions(+), 33 deletions(-) diff --git a/src/__tests__/industry/agents/policy-agent/replay.test.ts b/src/__tests__/industry/agents/policy-agent/replay.test.ts index 88d9dce..74904be 100644 --- a/src/__tests__/industry/agents/policy-agent/replay.test.ts +++ b/src/__tests__/industry/agents/policy-agent/replay.test.ts @@ -318,40 +318,53 @@ describe("policy-finance group replay handoff", () => { it("replays the machine-readable runtime-ready fixture through the executable script", () => { const artifactPath = path.join(process.cwd(), "data", "reports", "2026-06-26.policy-finance-runtime-replay.json"); const latestArtifactPath = path.join(process.cwd(), "data", "reports", "latest.policy-finance-runtime-replay.json"); - fs.rmSync(artifactPath, { force: true }); - fs.rmSync(latestArtifactPath, { force: true }); - const output = execFileSync( - "corepack", - ["pnpm", "policy-finance:runtime-replay", "--", "--date", "2026-06-26"], - { cwd: process.cwd(), encoding: "utf8" }, - ); - const jsonStart = output.indexOf("{"); - const result = JSON.parse(output.slice(jsonStart)) as { - artifact_kind: string; - date: string; - fixture_id: string; - current_status: string; - negative_reason_code: string; - runtime_consumed_same_run_messages: number; - }; + const originalArtifacts = [artifactPath, latestArtifactPath].map((filePath) => ({ + filePath, + contents: fs.existsSync(filePath) ? fs.readFileSync(filePath) : undefined, + })); - expect(result).toMatchObject({ - artifact_kind: "policy_finance_runtime_replay", - date: "2026-06-26", - fixture_id: "policy-finance-phase1-runtime-ready-inputs.v1", - current_status: "policy_finance_runtime_ready", - negative_reason_code: "dispatch_context_missing", - runtime_consumed_same_run_messages: 19, - }); - expect(fs.existsSync(artifactPath)).toBe(true); - expect(fs.existsSync(latestArtifactPath)).toBe(true); - expect(JSON.parse(fs.readFileSync(artifactPath, "utf8"))).toMatchObject({ - artifact_kind: "policy_finance_runtime_replay", - date: "2026-06-26", - current_status: "policy_finance_runtime_ready", - }); - fs.rmSync(artifactPath, { force: true }); - fs.rmSync(latestArtifactPath, { force: true }); + try { + fs.rmSync(artifactPath, { force: true }); + fs.rmSync(latestArtifactPath, { force: true }); + const output = execFileSync( + process.execPath, + ["--import", "tsx", "src/cli.ts", "policy-finance-runtime-replay", "--date", "2026-06-26"], + { cwd: process.cwd(), encoding: "utf8" }, + ); + const jsonStart = output.indexOf("{"); + const result = JSON.parse(output.slice(jsonStart)) as { + artifact_kind: string; + date: string; + fixture_id: string; + current_status: string; + negative_reason_code: string; + runtime_consumed_same_run_messages: number; + }; + + expect(result).toMatchObject({ + artifact_kind: "policy_finance_runtime_replay", + date: "2026-06-26", + fixture_id: "policy-finance-phase1-runtime-ready-inputs.v1", + current_status: "policy_finance_runtime_ready", + negative_reason_code: "dispatch_context_missing", + runtime_consumed_same_run_messages: 19, + }); + expect(fs.existsSync(artifactPath)).toBe(true); + expect(fs.existsSync(latestArtifactPath)).toBe(true); + expect(JSON.parse(fs.readFileSync(artifactPath, "utf8"))).toMatchObject({ + artifact_kind: "policy_finance_runtime_replay", + date: "2026-06-26", + current_status: "policy_finance_runtime_ready", + }); + } finally { + for (const artifact of originalArtifacts) { + if (artifact.contents === undefined) { + fs.rmSync(artifact.filePath, { force: true }); + } else { + fs.writeFileSync(artifact.filePath, artifact.contents); + } + } + } }); });