From c3ce56cb7a927416267220c8c70ff8cf29f2fd38 Mon Sep 17 00:00:00 2001 From: monkey1sai <26239865+monkey1sai@users.noreply.github.com> Date: Fri, 24 Jul 2026 14:36:05 +0800 Subject: [PATCH 1/3] fix(openspec): restore unfinished deferred changes Restore four non-terminal changes from the completed archive, freeze overlapping ownership, and add a lifecycle gate that prevents deferred or unchecked changes from being newly archived. --- .github/workflows/agent-governance.yml | 5 + docs/contracts/structured-log-schema.md | 2 +- ...0\250\210\346\226\207\344\273\266.dc.html" | 8 +- docs/plans/NOW.md | 27 ++- openspec/AGENTS.md | 3 + .../a4-semantic-search-model-qa/design.md | 2 +- .../a4-semantic-search-model-qa/proposal.md | 2 +- .../design.md | 0 .../proposal.md | 2 + .../agent-operability-governance/spec.md | 0 .../specs/demo-fast-mvp-orchestration/spec.md | 0 .../documentation-source-of-truth/spec.md | 0 .../specs/unified-governance-console/spec.md | 0 .../tasks.md | 0 .../.openspec.yaml | 0 .../design.md | 0 .../proposal.md | 4 + .../spec.md | 0 .../tasks.md | 4 +- .../migrate-console-to-hifi-design/design.md | 6 +- .../proposal.md | 4 +- .../console-design-token-authority/spec.md | 6 +- .../proposal.md | 2 + .../specs/minio-fileserver-source/spec.md | 0 .../specs/minio-watch-auto-intake/spec.md | 0 .../tasks.md | 0 .../.openspec.yaml | 0 .../contracts/README.md | 0 ...d-lineage-publication-mysql8-reference.sql | 0 ...lineage-publication-request-v1.schema.json | 0 ...ineage-publication-response-v1.schema.json | 0 ...-colon-publication-identity-component.json | 0 .../invalid-cross-site-health-locator.json | 0 .../invalid-csv-valid-exceeds-total.json | 0 ...invalid-edge-site-authority-character.json | 0 .../examples/invalid-error-event-id.json | 0 ...d-full-lineage-below-set-intersection.json | 0 ...invalid-full-lineage-exceeds-ifc-usdc.json | 0 .../invalid-full-lineage-exceeds-rvt-ifc.json | 0 .../examples/invalid-incomplete-ack.json | 0 ...invalid-inconsistent-alignment-counts.json | 0 .../invalid-inconsistent-ifc-only-count.json | 0 .../invalid-inconsistent-ifc-usdc-counts.json | 0 .../invalid-inconsistent-rvt-ifc-counts.json | 0 ...nvalid-leap-second-health-observed-at.json | 0 .../invalid-lowercase-presigned-locator.json | 0 ...valid-mismatched-publication-identity.json | 0 .../invalid-nonretryable-transient-error.json | 0 .../invalid-offset-ack-stored-at.json | 0 .../invalid-offset-health-observed-at.json | 0 .../examples/invalid-offset-occurred-at.json | 0 .../examples/invalid-offset-published-at.json | 0 ...valid-out-of-range-health-observed-at.json | 0 .../invalid-presigned-health-locator.json | 0 ...invalid-retryable-deterministic-error.json | 0 ...lid-submicrosecond-health-observed-at.json | 0 ...invalid-tombstone-id-on-non-tombstone.json | 0 .../valid-auth-error-without-event-id.json | 0 .../examples/valid-conflict-error.json | 0 .../contracts/examples/valid-created-ack.json | 0 .../valid-lineage-result-health-changed.json | 0 .../valid-lineage-result-published.json | 0 .../valid-lineage-result-tombstoned.json | 0 .../examples/valid-transient-error.json | 0 .../design.md | 0 .../proposal.md | 2 + .../specs/cloud-lineage-publication/spec.md | 0 .../conversion-attempt-publication/spec.md | 0 .../conversion-runtime-admission/spec.md | 0 .../specs/lineage-governance-console/spec.md | 0 .../specs/minio-model-version-bundle/spec.md | 0 .../specs/rvt-ifc-usdc-lineage/spec.md | 0 .../tasks.md | 0 .../governance-throughput-budget/spec.md | 2 +- .../specs/minio-fileserver-source/spec.md | 2 +- .../specs/minio-watch-auto-intake/spec.md | 2 +- scripts/tests/test-agent-governance-check.ps1 | 7 +- scripts/tests/verify-openspec-lifecycle.ps1 | 189 ++++++++++++++++++ 78 files changed, 249 insertions(+), 32 deletions(-) rename openspec/changes/{archive/2026-07-22-align-frontend-design-system-reference => align-frontend-design-system-reference}/design.md (100%) rename openspec/changes/{archive/2026-07-22-align-frontend-design-system-reference => align-frontend-design-system-reference}/proposal.md (88%) rename openspec/changes/{archive/2026-07-22-align-frontend-design-system-reference => align-frontend-design-system-reference}/specs/agent-operability-governance/spec.md (100%) rename openspec/changes/{archive/2026-07-22-align-frontend-design-system-reference => align-frontend-design-system-reference}/specs/demo-fast-mvp-orchestration/spec.md (100%) rename openspec/changes/{archive/2026-07-22-align-frontend-design-system-reference => align-frontend-design-system-reference}/specs/documentation-source-of-truth/spec.md (100%) rename openspec/changes/{archive/2026-07-22-align-frontend-design-system-reference => align-frontend-design-system-reference}/specs/unified-governance-console/spec.md (100%) rename openspec/changes/{archive/2026-07-22-align-frontend-design-system-reference => align-frontend-design-system-reference}/tasks.md (100%) rename openspec/changes/{archive/2026-05-27-cross-service-structured-log-baseline => cross-service-structured-log-baseline}/.openspec.yaml (100%) rename openspec/changes/{archive/2026-05-27-cross-service-structured-log-baseline => cross-service-structured-log-baseline}/design.md (100%) rename openspec/changes/{archive/2026-05-27-cross-service-structured-log-baseline => cross-service-structured-log-baseline}/proposal.md (90%) rename openspec/changes/{archive/2026-05-27-cross-service-structured-log-baseline => cross-service-structured-log-baseline}/specs/cross-service-structured-log-baseline/spec.md (100%) rename openspec/changes/{archive/2026-05-27-cross-service-structured-log-baseline => cross-service-structured-log-baseline}/tasks.md (97%) rename openspec/changes/{archive/2026-07-22-minio-folderview-and-baseline-disclosure => minio-folderview-and-baseline-disclosure}/proposal.md (94%) rename openspec/changes/{archive/2026-07-22-minio-folderview-and-baseline-disclosure => minio-folderview-and-baseline-disclosure}/specs/minio-fileserver-source/spec.md (100%) rename openspec/changes/{archive/2026-07-22-minio-folderview-and-baseline-disclosure => minio-folderview-and-baseline-disclosure}/specs/minio-watch-auto-intake/spec.md (100%) rename openspec/changes/{archive/2026-07-22-minio-folderview-and-baseline-disclosure => minio-folderview-and-baseline-disclosure}/tasks.md (100%) rename openspec/changes/{archive/2026-07-22-rvt-ifc-usdc-lineage => rvt-ifc-usdc-lineage}/.openspec.yaml (100%) rename openspec/changes/{archive/2026-07-22-rvt-ifc-usdc-lineage => rvt-ifc-usdc-lineage}/contracts/README.md (100%) rename openspec/changes/{archive/2026-07-22-rvt-ifc-usdc-lineage => rvt-ifc-usdc-lineage}/contracts/cloud-lineage-publication-mysql8-reference.sql (100%) rename openspec/changes/{archive/2026-07-22-rvt-ifc-usdc-lineage => rvt-ifc-usdc-lineage}/contracts/cloud-lineage-publication-request-v1.schema.json (100%) rename openspec/changes/{archive/2026-07-22-rvt-ifc-usdc-lineage => rvt-ifc-usdc-lineage}/contracts/cloud-lineage-publication-response-v1.schema.json (100%) rename openspec/changes/{archive/2026-07-22-rvt-ifc-usdc-lineage => rvt-ifc-usdc-lineage}/contracts/examples/invalid-colon-publication-identity-component.json (100%) rename openspec/changes/{archive/2026-07-22-rvt-ifc-usdc-lineage => rvt-ifc-usdc-lineage}/contracts/examples/invalid-cross-site-health-locator.json (100%) rename openspec/changes/{archive/2026-07-22-rvt-ifc-usdc-lineage => rvt-ifc-usdc-lineage}/contracts/examples/invalid-csv-valid-exceeds-total.json (100%) rename openspec/changes/{archive/2026-07-22-rvt-ifc-usdc-lineage => rvt-ifc-usdc-lineage}/contracts/examples/invalid-edge-site-authority-character.json (100%) rename openspec/changes/{archive/2026-07-22-rvt-ifc-usdc-lineage => rvt-ifc-usdc-lineage}/contracts/examples/invalid-error-event-id.json (100%) rename openspec/changes/{archive/2026-07-22-rvt-ifc-usdc-lineage => rvt-ifc-usdc-lineage}/contracts/examples/invalid-full-lineage-below-set-intersection.json (100%) rename openspec/changes/{archive/2026-07-22-rvt-ifc-usdc-lineage => rvt-ifc-usdc-lineage}/contracts/examples/invalid-full-lineage-exceeds-ifc-usdc.json (100%) rename openspec/changes/{archive/2026-07-22-rvt-ifc-usdc-lineage => rvt-ifc-usdc-lineage}/contracts/examples/invalid-full-lineage-exceeds-rvt-ifc.json (100%) rename openspec/changes/{archive/2026-07-22-rvt-ifc-usdc-lineage => rvt-ifc-usdc-lineage}/contracts/examples/invalid-incomplete-ack.json (100%) rename openspec/changes/{archive/2026-07-22-rvt-ifc-usdc-lineage => rvt-ifc-usdc-lineage}/contracts/examples/invalid-inconsistent-alignment-counts.json (100%) rename openspec/changes/{archive/2026-07-22-rvt-ifc-usdc-lineage => rvt-ifc-usdc-lineage}/contracts/examples/invalid-inconsistent-ifc-only-count.json (100%) rename openspec/changes/{archive/2026-07-22-rvt-ifc-usdc-lineage => rvt-ifc-usdc-lineage}/contracts/examples/invalid-inconsistent-ifc-usdc-counts.json (100%) rename openspec/changes/{archive/2026-07-22-rvt-ifc-usdc-lineage => rvt-ifc-usdc-lineage}/contracts/examples/invalid-inconsistent-rvt-ifc-counts.json (100%) rename openspec/changes/{archive/2026-07-22-rvt-ifc-usdc-lineage => rvt-ifc-usdc-lineage}/contracts/examples/invalid-leap-second-health-observed-at.json (100%) rename openspec/changes/{archive/2026-07-22-rvt-ifc-usdc-lineage => rvt-ifc-usdc-lineage}/contracts/examples/invalid-lowercase-presigned-locator.json (100%) rename openspec/changes/{archive/2026-07-22-rvt-ifc-usdc-lineage => rvt-ifc-usdc-lineage}/contracts/examples/invalid-mismatched-publication-identity.json (100%) rename openspec/changes/{archive/2026-07-22-rvt-ifc-usdc-lineage => rvt-ifc-usdc-lineage}/contracts/examples/invalid-nonretryable-transient-error.json (100%) rename openspec/changes/{archive/2026-07-22-rvt-ifc-usdc-lineage => rvt-ifc-usdc-lineage}/contracts/examples/invalid-offset-ack-stored-at.json (100%) rename openspec/changes/{archive/2026-07-22-rvt-ifc-usdc-lineage => rvt-ifc-usdc-lineage}/contracts/examples/invalid-offset-health-observed-at.json (100%) rename openspec/changes/{archive/2026-07-22-rvt-ifc-usdc-lineage => rvt-ifc-usdc-lineage}/contracts/examples/invalid-offset-occurred-at.json (100%) rename openspec/changes/{archive/2026-07-22-rvt-ifc-usdc-lineage => rvt-ifc-usdc-lineage}/contracts/examples/invalid-offset-published-at.json (100%) rename openspec/changes/{archive/2026-07-22-rvt-ifc-usdc-lineage => rvt-ifc-usdc-lineage}/contracts/examples/invalid-out-of-range-health-observed-at.json (100%) rename openspec/changes/{archive/2026-07-22-rvt-ifc-usdc-lineage => rvt-ifc-usdc-lineage}/contracts/examples/invalid-presigned-health-locator.json (100%) rename openspec/changes/{archive/2026-07-22-rvt-ifc-usdc-lineage => rvt-ifc-usdc-lineage}/contracts/examples/invalid-retryable-deterministic-error.json (100%) rename openspec/changes/{archive/2026-07-22-rvt-ifc-usdc-lineage => rvt-ifc-usdc-lineage}/contracts/examples/invalid-submicrosecond-health-observed-at.json (100%) rename openspec/changes/{archive/2026-07-22-rvt-ifc-usdc-lineage => rvt-ifc-usdc-lineage}/contracts/examples/invalid-tombstone-id-on-non-tombstone.json (100%) rename openspec/changes/{archive/2026-07-22-rvt-ifc-usdc-lineage => rvt-ifc-usdc-lineage}/contracts/examples/valid-auth-error-without-event-id.json (100%) rename openspec/changes/{archive/2026-07-22-rvt-ifc-usdc-lineage => rvt-ifc-usdc-lineage}/contracts/examples/valid-conflict-error.json (100%) rename openspec/changes/{archive/2026-07-22-rvt-ifc-usdc-lineage => rvt-ifc-usdc-lineage}/contracts/examples/valid-created-ack.json (100%) rename openspec/changes/{archive/2026-07-22-rvt-ifc-usdc-lineage => rvt-ifc-usdc-lineage}/contracts/examples/valid-lineage-result-health-changed.json (100%) rename openspec/changes/{archive/2026-07-22-rvt-ifc-usdc-lineage => rvt-ifc-usdc-lineage}/contracts/examples/valid-lineage-result-published.json (100%) rename openspec/changes/{archive/2026-07-22-rvt-ifc-usdc-lineage => rvt-ifc-usdc-lineage}/contracts/examples/valid-lineage-result-tombstoned.json (100%) rename openspec/changes/{archive/2026-07-22-rvt-ifc-usdc-lineage => rvt-ifc-usdc-lineage}/contracts/examples/valid-transient-error.json (100%) rename openspec/changes/{archive/2026-07-22-rvt-ifc-usdc-lineage => rvt-ifc-usdc-lineage}/design.md (100%) rename openspec/changes/{archive/2026-07-22-rvt-ifc-usdc-lineage => rvt-ifc-usdc-lineage}/proposal.md (93%) rename openspec/changes/{archive/2026-07-22-rvt-ifc-usdc-lineage => rvt-ifc-usdc-lineage}/specs/cloud-lineage-publication/spec.md (100%) rename openspec/changes/{archive/2026-07-22-rvt-ifc-usdc-lineage => rvt-ifc-usdc-lineage}/specs/conversion-attempt-publication/spec.md (100%) rename openspec/changes/{archive/2026-07-22-rvt-ifc-usdc-lineage => rvt-ifc-usdc-lineage}/specs/conversion-runtime-admission/spec.md (100%) rename openspec/changes/{archive/2026-07-22-rvt-ifc-usdc-lineage => rvt-ifc-usdc-lineage}/specs/lineage-governance-console/spec.md (100%) rename openspec/changes/{archive/2026-07-22-rvt-ifc-usdc-lineage => rvt-ifc-usdc-lineage}/specs/minio-model-version-bundle/spec.md (100%) rename openspec/changes/{archive/2026-07-22-rvt-ifc-usdc-lineage => rvt-ifc-usdc-lineage}/specs/rvt-ifc-usdc-lineage/spec.md (100%) rename openspec/changes/{archive/2026-07-22-rvt-ifc-usdc-lineage => rvt-ifc-usdc-lineage}/tasks.md (100%) create mode 100644 scripts/tests/verify-openspec-lifecycle.ps1 diff --git a/.github/workflows/agent-governance.yml b/.github/workflows/agent-governance.yml index 0900ba74f..0b2371065 100644 --- a/.github/workflows/agent-governance.yml +++ b/.github/workflows/agent-governance.yml @@ -20,6 +20,7 @@ jobs: uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 with: persist-credentials: false + fetch-depth: 0 - name: Setup Node.js for PNG recomputation tests uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 @@ -41,6 +42,10 @@ jobs: shell: pwsh run: pwsh -NoProfile -NonInteractive -File scripts/tests/test-agent-governance-check.ps1 + - name: Verify OpenSpec lifecycle state + shell: pwsh + run: pwsh -NoProfile -NonInteractive -File scripts/tests/verify-openspec-lifecycle.ps1 -BaseRef '${{ github.event.pull_request.base.sha }}' + - name: Run PR body evidence tests shell: pwsh run: pwsh -NoProfile -NonInteractive -File scripts/tests/test-pr-body-evidence.ps1 diff --git a/docs/contracts/structured-log-schema.md b/docs/contracts/structured-log-schema.md index bcb2496b1..833357a07 100644 --- a/docs/contracts/structured-log-schema.md +++ b/docs/contracts/structured-log-schema.md @@ -1,7 +1,7 @@ # Structured Log Schema — Contract > **Source of truth** for the cross-service structured log baseline. -> Capability spec: `openspec/specs/cross-service-structured-log-baseline/` (post-archive). +> Capability spec: `openspec/specs/cross-service-structured-log-baseline/`(已同步 canonical;active change 只剩 deferred runtime-evidence closeout)。 > Design rationale: `docs/superpowers/specs/2026-05-26-cross-service-structured-log-baseline-design.md`. > JSON Schema artifact: `tests/contracts/structured-log/schema.json` (draft-07). diff --git "a/docs/plans/AI-BIM \345\211\215\345\276\214\347\253\257\350\250\255\350\250\210\346\226\207\344\273\266.dc.html" "b/docs/plans/AI-BIM \345\211\215\345\276\214\347\253\257\350\250\255\350\250\210\346\226\207\344\273\266.dc.html" index c1fbbf4af..b4f58ff28 100644 --- "a/docs/plans/AI-BIM \345\211\215\345\276\214\347\253\257\350\250\255\350\250\210\346\226\207\344\273\266.dc.html" +++ "b/docs/plans/AI-BIM \345\211\215\345\276\214\347\253\257\350\250\255\350\250\210\346\226\207\344\273\266.dc.html" @@ -322,7 +322,7 @@ 現行防護=blocklist(FORBIDDEN_KEYS+USDC magic/長度啟發),可被非黑名單 key 繞過;強化為 allowlist=follow-up metadata-allowlist:planned(class: in-repo-fullstack-pending);鐵律語意不變。
-
CLOUD API ONLYlineage-publication · cloud-lineage-publication/v1deferred archive · openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/contracts/(--skip-specs、non-canonical)
+
CLOUD API ONLYlineage-publication · cloud-lineage-publication/v1frozen deferred · openspec/changes/rvt-ifc-usdc-lineage/contracts/(non-canonical、non-owner)
edge bim-review-coordinator → [external] company-cloud bim-control → cloud MySQL
 POST /api/v1/lineage-publications
 events: lineage_result_published | lineage_result_health_changed
@@ -544,7 +544,7 @@
       
CallbackOutbox / LineagePublicationOutbox - workflow: conversion_result_ready|conversion_failed · metadata-only · pending→sent|dead-letter — 已實作
lineage: lineage_result_published|lineage_result_health_changed · stable event/digest · DISABLED|PENDING|RETRYING|DELIVERED|DEAD_LETTER|CONFLICT — planned(class: in-repo-fullstack-pending)——coordinator 現況僅 3 態 outbox,六態契約僅保留於 deferred archive openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/(--skip-specs、non-canonical、未實作);若要實作,須以當時 main 現況新開/調和 lineage-outbox-impl change
兩者contract/ACK分離;cloud delivery不阻擋edge READY/AVAILABLE
+ workflow: conversion_result_ready|conversion_failed · metadata-only · pending→sent|dead-letter — 已實作
lineage: lineage_result_published|lineage_result_health_changed · stable event/digest · DISABLED|PENDING|RETRYING|DELIVERED|DEAD_LETTER|CONFLICT — planned(class: in-repo-fullstack-pending)——coordinator 現況僅 3 態 outbox,六態契約保留於 frozen deferred change openspec/changes/rvt-ifc-usdc-lineage/(non-canonical、non-owner、未實作);若要實作,須先依 current main 完成 predecessor/successor crosswalk 並拆成不重疊 slices
兩者contract/ACK分離;cloud delivery不阻擋edge READY/AVAILABLE
@@ -625,7 +625,7 @@ A5–A10:僅 Concept 路由 + 概念稿,不做假後端;每一模組落地前先補 governance-service 對應 API 與契約測試 變更守則:gitnexus_impact → 修改 → 契約測試綠 → 變更留痕(OpenSpec change 目錄 openspec/changes/<id>/ + PR body 的 AI Coding Governance 表) CH-C 殘留:selectPrimsRequest/composeStageRequest 已於 Window.tsx 實作(fakeKit.ts harness 佐證);commandRejected(spectator / 權威拒絕回饋)仍待補,詳見 §04 - OpenSpec change align-frontend-design-system-reference 已於 2026-07-22 以 --skip-specs deferred archive;archive 中未完成 tasks/delta 僅為歷史留存、非現行權威。動前端視覺前應依本設計文件、canonical specs 與 manifest;若需補齊雙閘,先以當時 main 現況新開/調和 change。 + OpenSpec change align-frontend-design-system-reference 已於 2026-07-24 historical correction 恢復為 frozen deferred;未完成 tasks/delta 仍是 non-canonical、non-owner。動前端視覺前應依本設計文件、canonical specs 與 manifest;若需補齊雙閘,須先與 migrate-console-to-hifi-design 完成 requirement/successor crosswalk,不得平行 coding。
@@ -724,7 +724,7 @@
4
web-viewer-sample/scripts/capture-design-system-reference.mjs唯一受認可的 rebaseline 手段——必須帶 --rebaseline --confirm-rebaseline 兩旗標(單一旗標會被腳本拒絕)。禁止手動覆寫 golden 圖或繞過此腳本「順手」更新基準。
Hi-Fi 驅動的前端改動,「verify」= 讓上面第 2–3 步綠燈,不是自己截圖比對覺得像;沒跑這條鏈就宣稱完成,不滿足 R4 definition of done 的「Playwright E2E 截圖證據」項 - 此驗證鏈的既有工具仍可使用;OpenSpec change align-frontend-design-system-reference 已於 2026-07-22 以 --skip-specs deferred archive,archive tasks/delta 是 non-canonical 歷史工件,並非現行 implementation authority。動前端視覺前,AI coding agent 應依本設計文件、canonical specs 與 manifest;不要預設 gate 已全線接通,若需補齊先新開/調和 change。 + 此驗證鏈的既有工具仍可使用;OpenSpec change align-frontend-design-system-reference 已於 2026-07-24 historical correction 恢復為 frozen deferred,其 tasks/delta 是 non-canonical、non-owner,並非現行 implementation authority。動前端視覺前,AI coding agent 應依本設計文件、canonical specs 與 manifest;不要預設 gate 已全線接通,若需補齊須先與 migrate-console-to-hifi-design 完成 crosswalk。 diff --git a/docs/plans/NOW.md b/docs/plans/NOW.md index 56c8ad0ec..cd8b459f9 100644 --- a/docs/plans/NOW.md +++ b/docs/plans/NOW.md @@ -9,7 +9,7 @@ | 序 | 軌 | 目標 | 狀態 | |---|---|---|---| | **0** | 治理 WIP(#364) | active ≤2;defer 其餘;採納 throughput 預算 | ✅ #364 MERGED + `governance-throughput-budget` archived | -| **1** | 收口 | 把「code 已 merge、tasks 假開著」的 change archive | **已 archive 7 案**(2026-07-21/22) | +| **1** | 收口 | completed 才 archive;deferred 留在 changes 並 frozen | **4 個近期 completed 維持 archive;4 個 unfinished historical correction 恢復 deferred** | | **2** | A4 | 只走切片 PR(先 #365,再下一刀) | **#365 + #380 + #382 + #383 + #386 MERGED**;current = S4-B PR #384 final gate,next = S4-C | **並行規則:** 0 可與 1 同天;**2 與新功能不得再開第 3 條 active product change**。 @@ -21,15 +21,18 @@ | OQ | 題目 | **建議裁決** | |---|---|---| -| OQ-1 | 收斂後保留哪個 ≤2 大 active | ✅ **已採納**:保留 `a4-semantic-search-model-qa` + `migrate-console-to-hifi-design`;`rvt-ifc-usdc-lineage` 已 deferred archive | +| OQ-1 | 收斂後保留哪個 ≤2 大 active | ✅ **已採納**:保留 `a4-semantic-search-model-qa` + `migrate-console-to-hifi-design`;`rvt-ifc-usdc-lineage` 為 `Status: deferred`、frozen/non-owner | | OQ-2 | docs+chore ≤30% | ✅ **已採納**:首月 40% → 次月 30% | | OQ-3 | #364 自身是第 10 個 active | ✅ **已採納**:#364 merge 後 archive `governance-throughput-budget` | -已完成 deferred archive(與 #364 裁決一致;均以 `--skip-specs` 保留未落地 delta,不同步 canonical specs): +2026-07-24 historical correction:deferred 不再放 completed archive;下列 change 均恢復原 id、保留 `Status: deferred`,未落地 delta 仍不構成 canonical authority: -- `minio-folderview-and-baseline-disclosure` → `2026-07-22-minio-folderview-and-baseline-disclosure` -- `align-frontend-design-system-reference` → `2026-07-22-align-frontend-design-system-reference`(動視覺前再 thaw;本週 A4 切片以 `Full completion claimed: no` 可不綁 full design rebaseline) -- `rvt-ifc-usdc-lineage` → `2026-07-22-rvt-ifc-usdc-lineage` +- `openspec/changes/minio-folderview-and-baseline-disclosure/`(只允許 canonical closeout reconciliation,不重做 #259/#265 code) +- `openspec/changes/align-frontend-design-system-reference/`(與 migrate 的互斥需求完成 crosswalk 前不得 thaw) +- `openspec/changes/rvt-ifc-usdc-lineage/`(1/48;切片與 shared ownership 調和前不得 coding) +- `openspec/changes/cross-service-structured-log-baseline/`(只補 tasks 10.1–10.5 runtime evidence;不重套已同步 delta) + +Archive lexical audit 在本次恢復後仍有 44 個歷史目錄、696 個 unchecked checkbox;三層交叉裁決未把它們判為獨立、可繼續執行的 unfinished owner(主要是已落地但 task bookkeeping 過時、已被 successor 承接,或已退役 service 的歷史工作),因此不批次搬移,也不改寫 archive 歷史。這批屬 legacy audit debt;新增 lifecycle gate 只對本次之後的新 archive fail closed,禁止再產生 unchecked/deferred archive。 --- @@ -43,9 +46,10 @@ | `minio-trigger-lifecycle-backend` | ✅ archived `2026-07-21-minio-trigger-lifecycle-backend` | done | #259 | | `c-m4-runtime-command-bridge` | ✅ archived `2026-07-21-c-m4-runtime-command-bridge`(新建 capability spec) | done | #309 | | `minio-watch-key-structure` | ✅ archived `2026-07-21-minio-watch-key-structure`(`--skip-specs`;主線 scenario 已在 main) | 選 A deferred-evidence | #237 | -| `minio-folderview-and-baseline-disclosure` | ✅ deferred archive `2026-07-22-minio-folderview-and-baseline-disclosure`(`--skip-specs`) | 未完成 tasks 保留在 archive,non-canonical | #265 | -| `align-frontend-design-system-reference` | ✅ deferred archive `2026-07-22-align-frontend-design-system-reference`(`--skip-specs`) | 未完成 tasks/delta 保留在 archive,non-canonical | #363 | -| `rvt-ifc-usdc-lineage` | ✅ deferred archive `2026-07-22-rvt-ifc-usdc-lineage`(`--skip-specs`) | 未完成 tasks/6 個 new capability delta 保留在 archive,non-canonical | #354 | +| `cross-service-structured-log-baseline` | ↩ restored deferred、evidence-only | 只補真 4-service runtime evidence;不改 pipeline/code/canonical spec | #126 | +| `minio-folderview-and-baseline-disclosure` | ↩ restored deferred、frozen | 對帳 code/tests/tasks/canonical spec;禁止重做 code | #265 | +| `align-frontend-design-system-reference` | ↩ restored deferred、frozen | 先與 migrate 做 requirement/successor crosswalk;禁止平行 design coding | #363 | +| `rvt-ifc-usdc-lineage` | ↩ restored deferred、frozen(1/48) | 先切片與調和 shared ownership;禁止直接 apply | #354 | ### minio-watch task 5 @@ -53,8 +57,8 @@ ### 收口 DoD(軌 1) -- [x] 7 個 closeout change 進入 `openspec/changes/archive/2026-07-21-*` 或 `2026-07-22-*` -- [x] deferred archive:lineage / minio-folderview / align-frontend(`--skip-specs`;不計 active WIP) +- [x] 4 個近期 completed closeout change 維持 archive;4 個 unfinished change 已於 2026-07-24 從 archive 恢復原 id +- [x] lineage / minio-folderview / align-frontend / structured-log 保留 `Status: deferred`、frozen/non-owner,不計 active WIP - [x] #364 merge + `governance-throughput-budget` archive(OQ-3 出場) - [x] 本週 WIP focus 只保留 **A4 + migrate-console**;`implement-runtime-command-authority-and-rejection` 與 `add-single-gpu-session-ai-review-mvp` 的 retain/defer 另案裁決,不在本次 archive 範圍 - [ ] 過期 worktree 刪到 ≤5(人工/下一切可選) @@ -178,4 +182,5 @@ Done: 通過 DoD 所列測試;回報 verified / inferences / risks | 2026-07-21 | 採納建議/A/全做:#365 merge;4 change archive;deferred 三案;S2 成當前 outcome | | 2026-07-21 | #364 merge;archive governance-throughput-budget;OQ 全落地 | | 2026-07-22 | 使用者確認 deferred archive:`minio-folderview-and-baseline-disclosure`、`align-frontend-design-system-reference`、`rvt-ifc-usdc-lineage` 均以 `--skip-specs` archive;#380 merged,下一刀改為 S3。 | +| 2026-07-24 | 使用者改採嚴格 terminal rule:archive 僅限 completed/完整 successor;三個 7/22 deferred change 與 structured-log evidence 缺口 historical correction 恢復原 id,維持 frozen/non-owner。 | | 2026-07-23 | #382/#383/#386 merged;#386 先收斂 scoped A4 visible caller compatibility,S4-B coordinator session search proxy、安全 transport、host-kit dual-namespace seam 與 cold-scan timeout regression 由 PR #384 交付(狀態以 GitHub machine truth 為準),S4-C/D 仍 pending。 | diff --git a/openspec/AGENTS.md b/openspec/AGENTS.md index 6e964a99f..a619ca3cb 100644 --- a/openspec/AGENTS.md +++ b/openspec/AGENTS.md @@ -26,6 +26,8 @@ OpenSpec 入口:`npx openspec`(list / validate / show / archive / new)。 - MUST 把每個 OpenSpec change 隔離到 `codex/openspec/` branch + `.worktrees//` worktree;不得在 `main` 上開發 OpenSpec change。 - MUST 在 active change 寫好後 `npx openspec validate --strict` 通過再開 PR。 - MUST 在 PR merge 後跑 `npx openspec archive ` 落地 spec;archive 後 active change 目錄消失、`specs//spec.md` 出現。 +- MUST 將 deferred change 保留在 `openspec/changes//`,並在 `proposal.md` 頂部使用 canonical `Status: deferred <日期>` 標記、理由與重啟條件;deferred 不構成 active capability owner,也不得為了 WIP 計數移入 archive。`--skip-specs` 只會跳過 canonical spec 同步,**不是** deferred state。 +- MUST 僅 archive 已完成的 change:所有 task checkbox 均已結案;若原工作由明確、非重疊且已接受的 successor 完整承接,須先把原 checkbox 改成已勾選的 terminal disposition 並記錄 successor,不得留下 unchecked task。delta specs 已同步 canonical specs,或已由 successor 明確 supersede。單純 warning、known gap、使用者確認繼續或 `--skip-specs` 均不得把 unfinished/deferred change 重新分類為 completed。 - MUST 用繁體中文撰寫 proposal / design / tasks / spec;保留 OpenSpec parser 必要標頭(`## ADDED Requirements` / `## MODIFIED Requirements` / `### Requirement:` / `#### Scenario:` 等)為原文。 - MUST NOT 修改 `openspec/changes/archive/` 內任何檔案;歷史 correction 需獨立 PR 並在 PR 描述標示。 - MUST NOT 把 `openspec/AGENTS.md` 或 `openspec/CLAUDE.md` 視為 spec 或 change —— `npx openspec validate` scope 限 `changes/` 與 `specs/` 子目錄。 @@ -48,6 +50,7 @@ npx openspec validate --all --strict ## Done Criteria - 改動沒有越過 archive 邊界。 +- deferred change 不在 archive;archive 內沒有未被完整 successor 承接的 in-scope 未完成工作。 - `openspec validate --strict` 通過;新 capability 至少含一條 Requirement + 至少一個 Scenario。 - PR 描述附 `openspec validate` 輸出。 - 最終回覆列出 changed files、validation、known risks。 diff --git a/openspec/changes/a4-semantic-search-model-qa/design.md b/openspec/changes/a4-semantic-search-model-qa/design.md index 47473eda5..0a8d967c2 100644 --- a/openspec/changes/a4-semantic-search-model-qa/design.md +++ b/openspec/changes/a4-semantic-search-model-qa/design.md @@ -291,7 +291,7 @@ Semantic completion SHALL 另要求至少一次經 coordinator session route 的 ### D10 — Capability ownership、design baseline 與 legacy naming 需要明確 sequencing -本 change SHALL 不再修改 `unified-governance-console`;`align-frontend-design-system-reference` 已於 2026-07-22 以 `--skip-specs` deferred archive,其 retained delta 非 canonical authority,亦不形成 active capability owner。Canonical A4 route、live states、design gate 與 runtime evidence 全由 `a4-semantic-search` 擁有;A5–A10 roadmap 由 `edge-console-operator-frontend` 擁有。 +本 change SHALL 不再修改 `unified-governance-console`;`align-frontend-design-system-reference` 已於 2026-07-24 historical correction 恢復為 `Status: deferred` 的 frozen change,其 retained delta 非 canonical authority,亦不形成 active capability owner;完成與 `migrate-console-to-hifi-design` 的 requirement/successor crosswalk 前不得 thaw。Canonical A4 route、live states、design gate 與 runtime evidence 全由 `a4-semantic-search` 擁有;A5–A10 roadmap 由 `edge-console-operator-frontend` 擁有。 Active `migrate-console-to-hifi-design` 依 contract behavior-neutral,但會替換 console token authority 並 rebaseline 全部 approved screens,包括 `workspace.a4.default`。Implementation MAY parallel,但 maintainers SHALL 指定 final A4 golden capture owner。後續 design migration SHALL NOT 用 old fixture state 覆寫 A4 live baseline;後續 A4 rebaseline SHALL 使用 resulting token authority。Preferred closeout:先完成 visual migration,refresh A4 screen against resulting authority,最後只 implement/re-approve 一次 live A4。 diff --git a/openspec/changes/a4-semantic-search-model-qa/proposal.md b/openspec/changes/a4-semantic-search-model-qa/proposal.md index 194263097..7a3b71a90 100644 --- a/openspec/changes/a4-semantic-search-model-qa/proposal.md +++ b/openspec/changes/a4-semantic-search-model-qa/proposal.md @@ -40,5 +40,5 @@ - **API / data**:收斂 `POST /api/governance/search/model/for-session/:sessionId`;保留 `for-ifc-ready/:jobId` table-only;回應需有可驗證 query/interpretation/degradation/evidence、sanitized session binding、mapping status 與 highlight-eligibility 欄位。3D 經短效 coordinator handoff 進入 session viewer,實際 highlight ack 仍屬獨立 DataChannel evidence;A4 Issue 改走 session-scoped coordinator route,增加 source reference、含 primary artifact/active binding revision 的完整 snapshot hash、server-verifiable row proof 與 structured evidence snapshot。 - **Session / runtime**:完整流程依 active Review Session、server-resolved artifact/mapping/stage 及 primary viewer authority;highlight 經既有 WebRTC DataChannel,coordinator 僅做 session/control-plane resolve,不成為 IFC search 或 Issue authority。 - **Dependency / operations**:Ornith 是可選的 query interpreter 與 live-lab gate,不是 BIM/法規 truth,也不是 CI 必需依賴;exact local-lab location 與 credential source 是 operator-owned out-of-repo input,SHALL NOT 記錄在本 change。Runtime SHALL 由明確 server-side configuration 解析 URL/model/profile,token 僅由獨立 secret injection 載入;production semantic traffic SHALL 使用 TLS/mTLS/受信 tunnel,明文 HTTP 僅限明確 lab profile 與非敏感資料。 -- **Active-change coordination**:本 change 不再修改 `unified-governance-console`;`align-frontend-design-system-reference` 已於 2026-07-22 以 `--skip-specs` deferred archive,其 retained delta 非 canonical authority,亦不形成目前 capability owner。`migrate-console-to-hifi-design` 仍會重做包含 `workspace.a4.default` 的全域 baseline,必須指定 final A4 golden owner 並在最後一次視覺遷移後重跑 A4 semantic/visual gates。`c-m4-runtime-command-bridge` 及其後續 shared hardening change 擁有 mutator authorization/terminal rejection boundary;A4 只把 authentic lease 與可信 rejection 當作 full-completion dependency,不在本 change 修改 shared protocol producer。 +- **Active-change coordination**:本 change 不再修改 `unified-governance-console`;`align-frontend-design-system-reference` 已於 2026-07-24 historical correction 恢復為 `Status: deferred` 的 frozen change,其 retained delta 非 canonical authority,亦不形成目前 capability owner;完成與 `migrate-console-to-hifi-design` 的 requirement/successor crosswalk 前不得 thaw。`migrate-console-to-hifi-design` 仍會重做包含 `workspace.a4.default` 的全域 baseline,必須指定 final A4 golden owner 並在最後一次視覺遷移後重跑 A4 semantic/visual gates。`c-m4-runtime-command-bridge` 及其後續 shared hardening change 擁有 mutator authorization/terminal rejection boundary;A4 只把 authentic lease 與可信 rejection 當作 full-completion dependency,不在本 change 修改 shared protocol producer。 - **Boundary preservation**:governance-service 保有 search/Issue authority,coordinator 只 resolve/forward,streaming server/Kit 保有 runtime command authority,browser 不接觸 host path、mapping path或 model token,外部 cloud/IFC Worker 邊界不變。 diff --git a/openspec/changes/archive/2026-07-22-align-frontend-design-system-reference/design.md b/openspec/changes/align-frontend-design-system-reference/design.md similarity index 100% rename from openspec/changes/archive/2026-07-22-align-frontend-design-system-reference/design.md rename to openspec/changes/align-frontend-design-system-reference/design.md diff --git a/openspec/changes/archive/2026-07-22-align-frontend-design-system-reference/proposal.md b/openspec/changes/align-frontend-design-system-reference/proposal.md similarity index 88% rename from openspec/changes/archive/2026-07-22-align-frontend-design-system-reference/proposal.md rename to openspec/changes/align-frontend-design-system-reference/proposal.md index c2aa9e139..460e026ea 100644 --- a/openspec/changes/archive/2026-07-22-align-frontend-design-system-reference/proposal.md +++ b/openspec/changes/align-frontend-design-system-reference/proposal.md @@ -2,6 +2,8 @@ > **Status: deferred 2026-07-21**(**使用者已採納**/NOW 軌0;原 #364 deferred-proposed 升格)。不計入 active WIP;動前端 visual full gate 前再 thaw。A4 切片允許 `Full completion claimed: no` 而不強制本 change 全線接通。重啟時須重跑 `npx openspec validate align-frontend-design-system-reference --strict`。 +> **Historical correction 2026-07-24**:本 change 曾被誤作 completed archive;現依「deferred 留在 `openspec/changes/`」規則恢復原 change id。它仍是 frozen、non-canonical、non-owner,**不得直接 apply 或 coding**。解凍前 MUST 先與 `migrate-console-to-hifi-design` 建立逐 requirement disposition/successor crosswalk,裁決 HTML-only authority、repo 外唯讀 origin、mixed-change fail-closed 與 rebaseline ownership 的互斥設計;沒有 crosswalk 不得修改 production frontend、manifest、goldens 或 branch-protection gate。 + ## Why 2026-07-14~2026-07-15 的設計文件整併後,repo 已由兩份 Git-tracked `docs/plans/*.html` 承接設計與規格;但現行 active change、manifest、route inventory 與 capture flow 仍引用外部 `C:\Repos\design\desigin-system`、已刪除文件或舊 hash routes。這會形成平行 design authority,也無法證明每個 screen、state、route 與 golden 都可從目前 checkout 的 HTML 重建。 diff --git a/openspec/changes/archive/2026-07-22-align-frontend-design-system-reference/specs/agent-operability-governance/spec.md b/openspec/changes/align-frontend-design-system-reference/specs/agent-operability-governance/spec.md similarity index 100% rename from openspec/changes/archive/2026-07-22-align-frontend-design-system-reference/specs/agent-operability-governance/spec.md rename to openspec/changes/align-frontend-design-system-reference/specs/agent-operability-governance/spec.md diff --git a/openspec/changes/archive/2026-07-22-align-frontend-design-system-reference/specs/demo-fast-mvp-orchestration/spec.md b/openspec/changes/align-frontend-design-system-reference/specs/demo-fast-mvp-orchestration/spec.md similarity index 100% rename from openspec/changes/archive/2026-07-22-align-frontend-design-system-reference/specs/demo-fast-mvp-orchestration/spec.md rename to openspec/changes/align-frontend-design-system-reference/specs/demo-fast-mvp-orchestration/spec.md diff --git a/openspec/changes/archive/2026-07-22-align-frontend-design-system-reference/specs/documentation-source-of-truth/spec.md b/openspec/changes/align-frontend-design-system-reference/specs/documentation-source-of-truth/spec.md similarity index 100% rename from openspec/changes/archive/2026-07-22-align-frontend-design-system-reference/specs/documentation-source-of-truth/spec.md rename to openspec/changes/align-frontend-design-system-reference/specs/documentation-source-of-truth/spec.md diff --git a/openspec/changes/archive/2026-07-22-align-frontend-design-system-reference/specs/unified-governance-console/spec.md b/openspec/changes/align-frontend-design-system-reference/specs/unified-governance-console/spec.md similarity index 100% rename from openspec/changes/archive/2026-07-22-align-frontend-design-system-reference/specs/unified-governance-console/spec.md rename to openspec/changes/align-frontend-design-system-reference/specs/unified-governance-console/spec.md diff --git a/openspec/changes/archive/2026-07-22-align-frontend-design-system-reference/tasks.md b/openspec/changes/align-frontend-design-system-reference/tasks.md similarity index 100% rename from openspec/changes/archive/2026-07-22-align-frontend-design-system-reference/tasks.md rename to openspec/changes/align-frontend-design-system-reference/tasks.md diff --git a/openspec/changes/archive/2026-05-27-cross-service-structured-log-baseline/.openspec.yaml b/openspec/changes/cross-service-structured-log-baseline/.openspec.yaml similarity index 100% rename from openspec/changes/archive/2026-05-27-cross-service-structured-log-baseline/.openspec.yaml rename to openspec/changes/cross-service-structured-log-baseline/.openspec.yaml diff --git a/openspec/changes/archive/2026-05-27-cross-service-structured-log-baseline/design.md b/openspec/changes/cross-service-structured-log-baseline/design.md similarity index 100% rename from openspec/changes/archive/2026-05-27-cross-service-structured-log-baseline/design.md rename to openspec/changes/cross-service-structured-log-baseline/design.md diff --git a/openspec/changes/archive/2026-05-27-cross-service-structured-log-baseline/proposal.md b/openspec/changes/cross-service-structured-log-baseline/proposal.md similarity index 90% rename from openspec/changes/archive/2026-05-27-cross-service-structured-log-baseline/proposal.md rename to openspec/changes/cross-service-structured-log-baseline/proposal.md index f781edb9e..5207a40e4 100644 --- a/openspec/changes/archive/2026-05-27-cross-service-structured-log-baseline/proposal.md +++ b/openspec/changes/cross-service-structured-log-baseline/proposal.md @@ -1,5 +1,9 @@ # cross-service-structured-log-baseline — Proposal +> **Status: deferred 2026-07-24**:不計入 active WIP;code、contracts 與 canonical capability spec 已落地,只有 tasks 10.1–10.5 的真 4-service runtime evidence 尚未完成。`deepen-ifc-ready-conversion-pipeline` closeout 前不得為了 smoke 修改其 pipeline implementation。 + +> **Historical correction 2026-07-24**:本 change 曾在缺少 runtime evidence 時被 archive;現依嚴格 terminal rule 恢復原 change id。它目前只允許 execution/evidence closeout:跑 IFC-ready → conversion → session → close、驗四個 service JSONL/trace/env redaction,並落 durable evidence。既有 delta 已同步至 `openspec/specs/cross-service-structured-log-baseline/`,**不得重新套用或回滾 canonical spec,也不得重做已落地 adapters/contracts**。 + ## Why 目前 4 個執行單元(coordinator TypeScript、streaming-server Python/Kit、web-viewer-sample Browser、PowerShell scripts)各自用 `console.*` / `carb.log_*` / `Add-Content` / `kit-stdout.log` / `.run/*.log.err` 寫 log,沒有共用 schema、沒有跨服務 `trace_id`、沒有 env snapshot、沒有統一 retention 規則。agent 在跨服務 incident 追蹤時必須手動 join 多個格式不同的 log 來源;env 設定誤差只能靠口頭釐清;roadmap 候選 #8 `observability-audit-baseline`(Prometheus / Grafana / Loki)要等 Phase 6 才解凍,目前夾在「無基線」與「過早全套上 stack」之間。本 change 建立可給 #8 直接掃的 baseline,把 schema、trace_id 命名、env redaction、檔案佈局一次落定,後續 Loki promtail 接上不需改 schema。 diff --git a/openspec/changes/archive/2026-05-27-cross-service-structured-log-baseline/specs/cross-service-structured-log-baseline/spec.md b/openspec/changes/cross-service-structured-log-baseline/specs/cross-service-structured-log-baseline/spec.md similarity index 100% rename from openspec/changes/archive/2026-05-27-cross-service-structured-log-baseline/specs/cross-service-structured-log-baseline/spec.md rename to openspec/changes/cross-service-structured-log-baseline/specs/cross-service-structured-log-baseline/spec.md diff --git a/openspec/changes/archive/2026-05-27-cross-service-structured-log-baseline/tasks.md b/openspec/changes/cross-service-structured-log-baseline/tasks.md similarity index 97% rename from openspec/changes/archive/2026-05-27-cross-service-structured-log-baseline/tasks.md rename to openspec/changes/cross-service-structured-log-baseline/tasks.md index 9f19d6ffa..6e6c7edea 100644 --- a/openspec/changes/archive/2026-05-27-cross-service-structured-log-baseline/tasks.md +++ b/openspec/changes/cross-service-structured-log-baseline/tasks.md @@ -111,5 +111,5 @@ - [x] 11.6 GitNexus re-analyze 完成後(worktree 索引到 `c8a0723`,2 commits behind HEAD 但皆是 tests/docs):`gitnexus detect_changes` → 2 files changed / 0 changed_symbols / 0 affected processes / risk=LOW。對 `EventLog` (Class) + `createCoordinatorApp` (Function) 跑 `gitnexus_impact` upstream → 兩者都 risk=LOW / impactedCount=0,確認 backward-compatible additive args 沒影響任何 caller - [x] 11.7 每次 commit 前 `git diff --cached --check` exit=0 確認無 trailing whitespace - [x] 11.8 開 [PR #126](https://github.com/monkey1sai/AI-BIM-governance/pull/126),body 含 design / spec / tasks 對應、verification 摘要、capability change 摘要、smoke evidence deferred 註記。Draft → Ready-for-review transition 完成(`gh pr ready 126`) -- [ ] 11.9 等 GitHub Actions / PR Review Gate / CodeRabbit 通過(自動化階段) -- [ ] 11.10 Merge 後跑 OpenSpec sync/archive(依 `docs/agents/github-workflow.md`,merge 後動作) +- [x] 11.9 GitHub Actions / PR Review Gate / CodeRabbit 通過(PR #126,2026-05-27;本次 historical correction 以 `gh pr view 126` 重驗) +- [x] 11.10 Merge 後已完成 OpenSpec sync/archive;2026-07-24 僅因 runtime evidence 未完成而恢復 deferred,不回滾已同步 canonical spec diff --git a/openspec/changes/migrate-console-to-hifi-design/design.md b/openspec/changes/migrate-console-to-hifi-design/design.md index 5f9695f52..054be839d 100644 --- a/openspec/changes/migrate-console-to-hifi-design/design.md +++ b/openspec/changes/migrate-console-to-hifi-design/design.md @@ -20,7 +20,7 @@ UnifiedConsole 目前的視覺樣式來源分裂成三套,彼此互不相通 - 不變更 `edge-console-operator-frontend` 或 `unified-governance-console` 任何一條既有功能/API/provenance SHALL 條款。 - 不修正這兩份 spec 本身被發現的內部過時/不一致問題(見 proposal.md Known Risks)。 - 不擴大處理 A4–A10 願景頁以外的後端能力。 -- 不以已於 2026-07-22 deferred archive 的 `align-frontend-design-system-reference` tasks 2.4–2.8 當作前置。 +- 不以 frozen deferred `align-frontend-design-system-reference` 的 tasks 2.4–2.8 當作前置;兩案完成 requirement/successor crosswalk 前不得平行 coding。 - 不在本 change 內執行實際的 rebaseline 操作(golden baseline 擷取是 tasks.md 的實作步驟,時機在視覺程式碼落地「之後」,不在 propose 階段先跑)。 ## Decisions @@ -41,9 +41,9 @@ UnifiedConsole 目前的視覺樣式來源分裂成三套,彼此互不相通 **取捨**:查核發現 `unified-governance-console` spec.md(311 行)本身混雜至少兩三個不同時期的架構描述(primary-viewer-overlay 治理架構 vs. 英文寫的 grouped-navigation console shell),且兩份既有 spec 都**沒有規範任何具體顏色/CSS token 機制**——本次視覺遷移不牴觸其任何一條 SHALL。若順手一併 reconcile,範圍會從「換皮」爆炸成「重新盤點並修正兩份大型既有 spec 的內部一致性」,超出 grill-me 這次收斂的決策範圍。保守作法是新開一個正交 capability,把既有 spec 的內部問題記錄為 Known Risk,留給後續獨立處理。 -### D3:不以 deferred archive 的雙閘方案作為遷移前置 +### D3:不以 frozen deferred 的雙閘方案作為遷移前置 -**決策**:`align-frontend-design-system-reference` 已於 2026-07-22 以 `--skip-specs` deferred archive,其未完成的 tasks 2.4–2.8(branch-protection required check、11 個語意案例 approved state variants、獨立 review authority、runner/font fingerprint pin)不是 active 前置,也不是 canonical implementation authority。本 change 可重用現有驗證工具;若要補齊該方案,須依當時 main 現況新開/調和 change。 +**決策**:`align-frontend-design-system-reference` 已於 2026-07-24 historical correction 恢復為 `Status: deferred` 的 frozen change,其未完成的 tasks 2.4–2.8(branch-protection required check、11 個語意案例 approved state variants、獨立 review authority、runner/font fingerprint pin)不是 active 前置,也不是 canonical implementation authority。本 change 可重用現有驗證工具;若要補齊該方案,須先依 current main 完成兩案 requirement/successor crosswalk,再另行 thaw/調和,禁止平行 coding。 **理由**:archive 記錄的 pixel+semantic 雙閘**機制**(manifest schema、verify script、capture/rebaseline 工具、Playwright spec 結構)與被鎖定的視覺內容正交;既有工具對顏色系統無感知,換皮後直接用同一套工具重新 rebaseline 即可。archive 內容保留作歷史脈絡,不提供現行工作計畫或權威。 diff --git a/openspec/changes/migrate-console-to-hifi-design/proposal.md b/openspec/changes/migrate-console-to-hifi-design/proposal.md index e6e755d97..17b9e0255 100644 --- a/openspec/changes/migrate-console-to-hifi-design/proposal.md +++ b/openspec/changes/migrate-console-to-hifi-design/proposal.md @@ -25,10 +25,10 @@ - **受影響程式碼**:`web-viewer-sample/src/console/edge-console.css`(retire)、`web-viewer-sample/src/console/EdgeConsole.tsx`(移除主題切換邏輯)、`web-viewer-sample/src/console/unified/*.tsx`(inline hex → `--ab-*` token)、`web-viewer-sample/src/console/unified/unified.css`、`web-viewer-sample/src/console/governance/overlay.css`、`web-viewer-sample/src/console/viewer/*.css`、`web-viewer-sample/src/console/ConversionPage.tsx`。 - **受影響文件**:`docs/plans/AI-BIM 前後端設計文件.dc.html` §08、`docs/plans/design-system-reference.manifest.json`(golden baseline 需重新 rebaseline,13 screens × 2 viewports 全數視覺內容改變)。 - **不受影響**:`bim-review-coordinator`、`governance-service`、`bim-streaming-server`、任何 API/event/DB schema/session/conversion lifecycle。前端仍只打 coordinator `:8004`。`edge-console-operator-frontend` 與 `unified-governance-console` 定義的功能行為、provenance 標記、coordinator-only proxy 邊界逐字不變,只換視覺外觀。 -- **不受影響(機制重用,非新建)**:現有 pixel+semantic 雙閘工具(manifest schema、`scripts/lib/design-system-gate.ps1`、`scripts/tests/verify-design-system-reference.ps1`、`capture-design-system-reference.mjs`、`web-viewer-sample/e2e/design-system-visual.spec.ts` + `design-system-semantic-cases.ts`)可直接重用。`align-frontend-design-system-reference` 已於 2026-07-22 以 `--skip-specs` deferred archive;其 tasks/delta 僅為 non-canonical 歷史工件,並非平行中的 gate owner,遷移完成後仍使用現有工具重新 rebaseline。 +- **不受影響(機制重用,非新建)**:現有 pixel+semantic 雙閘工具(manifest schema、`scripts/lib/design-system-gate.ps1`、`scripts/tests/verify-design-system-reference.ps1`、`capture-design-system-reference.mjs`、`web-viewer-sample/e2e/design-system-visual.spec.ts` + `design-system-semantic-cases.ts`)可直接重用。`align-frontend-design-system-reference` 已於 2026-07-24 historical correction 恢復至 `openspec/changes/`,但仍是 `Status: deferred`、frozen、non-canonical、non-owner;本 change 與它完成 requirement/successor crosswalk 前,不得平行修改 HTML authority、manifest、goldens 或 gate。 ## Known Risks(記錄不處理,超出本 change 範圍) - `openspec/specs/edge-console-operator-frontend/spec.md` 描述的頁面結構(`CoordinatorPage`/`IntakePage`/`RuntimePage`/`AppsPage`/`OverviewPage` 等扁平頁)未反映 `#349`/`#350`(UnifiedConsole IA v2)後的新 IA 結構,本 change 不代為修正。 - `openspec/specs/unified-governance-console/spec.md`(311 行)內部混雜至少兩三種不同時期的架構描述(primary-viewer-overlay 治理架構 `GovernanceOverlay`/`HighlightBridge`/`MappingCache` vs. 英文寫的 grouped-navigation product console shell),且引用 `docs/frontend/frontend-design-guidelines.md`(另一份尚未查核的文件)。這份 spec 本身的內部一致性與是否反映當前實碼,超出本 change 查核範圍,本 change 只確認其未規範具體顏色/CSS token 機制、不因本次視覺遷移而牴觸。 -- `openspec/changes/archive/2026-07-22-align-frontend-design-system-reference/specs/documentation-source-of-truth/spec.md` 保留了已於 `#342` 刪除的 `docs/plans/TRUTH`/`TARGET`/`PROCESS`/`BACKLOG` 四檔案所有權模型;它是 `--skip-specs` 的 non-canonical 歷史工件。PR #353 已於 `docs/plans/AI-BIM 前後端設計文件.dc.html` §07 記錄此已知不一致,本 change 不把 archive 內容當作現行權威。 +- `openspec/changes/align-frontend-design-system-reference/specs/documentation-source-of-truth/spec.md` 保留了已於 `#342` 刪除的 `docs/plans/TRUTH`/`TARGET`/`PROCESS`/`BACKLOG` 四檔案所有權模型;它是 frozen deferred change 的 non-canonical delta。PR #353 已於 `docs/plans/AI-BIM 前後端設計文件.dc.html` §07 記錄此已知不一致,本 change 不把該 delta 當作現行權威。 diff --git a/openspec/changes/migrate-console-to-hifi-design/specs/console-design-token-authority/spec.md b/openspec/changes/migrate-console-to-hifi-design/specs/console-design-token-authority/spec.md index 78ba7cf36..182f74218 100644 --- a/openspec/changes/migrate-console-to-hifi-design/specs/console-design-token-authority/spec.md +++ b/openspec/changes/migrate-console-to-hifi-design/specs/console-design-token-authority/spec.md @@ -44,7 +44,7 @@ ### Requirement: 遷移落地後 SHALL 重用既有 pixel/semantic 雙閘機制重新 rebaseline -視覺遷移程式碼落地後,SHALL 使用既有 `web-viewer-sample/scripts/capture-design-system-reference.mjs`(帶 `--rebaseline --confirm-rebaseline` 雙旗標)重新擷取 `docs/plans/design-system-reference.manifest.json` 的 golden baseline(13 screens × 2 viewports),SHALL NOT 新建擷取機制或手動覆寫 golden 圖檔。重新擷取後 SHALL 以 `scripts/tests/verify-design-system-reference.ps1 -VerifyOrigin` 驗證通過。`align-frontend-design-system-reference` 已於 2026-07-22 以 `--skip-specs` deferred archive;其未完成 tasks 2.4–2.8 是 non-canonical 歷史工件,並非平行中的 gate owner。既有機制與視覺內容正交,無論鎖定何種視覺皆可重用。 +視覺遷移程式碼落地後,SHALL 使用既有 `web-viewer-sample/scripts/capture-design-system-reference.mjs`(帶 `--rebaseline --confirm-rebaseline` 雙旗標)重新擷取 `docs/plans/design-system-reference.manifest.json` 的 golden baseline(13 screens × 2 viewports),SHALL NOT 新建擷取機制或手動覆寫 golden 圖檔。重新擷取後 SHALL 以 `scripts/tests/verify-design-system-reference.ps1 -VerifyOrigin` 驗證通過。`align-frontend-design-system-reference` 已於 2026-07-24 historical correction 恢復為 `Status: deferred` 的 frozen change;其未完成 tasks 2.4–2.8 是 non-canonical delta,並非平行中的 gate owner。既有機制與視覺內容正交,無論鎖定何種視覺皆可重用;兩案完成 requirement/successor crosswalk 前不得平行修改相關 gate 資產。 #### Scenario: 視覺遷移後重新 rebaseline 且驗證通過 @@ -53,8 +53,8 @@ - **AND** 隨後執行 `pwsh scripts/tests/verify-design-system-reference.ps1 -VerifyOrigin` SHALL 通過 - **AND** SHALL NOT 手動編輯 `design-system-reference.manifest.json` 的 baseline hash 欄位或手動置換 golden PNG -#### Scenario: deferred archive 不阻塞視覺遷移 +#### Scenario: frozen deferred 不阻塞視覺遷移 -- **WHEN** `align-frontend-design-system-reference` 已 deferred archive,且其 tasks 2.4–2.8 未完成 +- **WHEN** `align-frontend-design-system-reference` 為 frozen deferred,且其 tasks 2.4–2.8 未完成 - **THEN** 本 change 的視覺遷移工作 SHALL NOT 因此被阻擋而無法開始或完成 - **AND** 本 change 的完成 SHALL NOT 要求 thaw 或實作該 non-canonical archive diff --git a/openspec/changes/archive/2026-07-22-minio-folderview-and-baseline-disclosure/proposal.md b/openspec/changes/minio-folderview-and-baseline-disclosure/proposal.md similarity index 94% rename from openspec/changes/archive/2026-07-22-minio-folderview-and-baseline-disclosure/proposal.md rename to openspec/changes/minio-folderview-and-baseline-disclosure/proposal.md index d94b3c1e5..fb8f772d5 100644 --- a/openspec/changes/archive/2026-07-22-minio-folderview-and-baseline-disclosure/proposal.md +++ b/openspec/changes/minio-folderview-and-baseline-disclosure/proposal.md @@ -1,5 +1,7 @@ > **Status: deferred 2026-07-21**(**使用者已採納**/NOW 軌0;原 #364 deferred-proposed 升格)。不計入 active WIP;解凍前不做實作。重啟時須先重驗 main 現況(#259 trigger、watcher ledger)再調和 tasks。 +> **Historical correction 2026-07-24**:本 change 曾以 `--skip-specs` 誤作 completed archive;現依 deferred state model 恢復原 change id。#259/#265 與現行 source/tests 已落地 raw-folder、ledger auto-enroll、trigger 與 UI/E2E 的大部分行為,因此此 change 目前只允許 **frozen closeout reconciliation**:對帳 tasks、現行 code/tests 與 canonical specs,禁止重做既有 production code。完成 canonical delta 調和、affected tests 與 strict validation 前,仍為 non-canonical、non-owner。 + ## Why 部署中 console 對真實 `bim-control` bucket 暴露兩個與直覺不符、且使 NOT BUILT 文件背離現實的現象(live coordinator `:8004` 2026-06-24 實測): diff --git a/openspec/changes/archive/2026-07-22-minio-folderview-and-baseline-disclosure/specs/minio-fileserver-source/spec.md b/openspec/changes/minio-folderview-and-baseline-disclosure/specs/minio-fileserver-source/spec.md similarity index 100% rename from openspec/changes/archive/2026-07-22-minio-folderview-and-baseline-disclosure/specs/minio-fileserver-source/spec.md rename to openspec/changes/minio-folderview-and-baseline-disclosure/specs/minio-fileserver-source/spec.md diff --git a/openspec/changes/archive/2026-07-22-minio-folderview-and-baseline-disclosure/specs/minio-watch-auto-intake/spec.md b/openspec/changes/minio-folderview-and-baseline-disclosure/specs/minio-watch-auto-intake/spec.md similarity index 100% rename from openspec/changes/archive/2026-07-22-minio-folderview-and-baseline-disclosure/specs/minio-watch-auto-intake/spec.md rename to openspec/changes/minio-folderview-and-baseline-disclosure/specs/minio-watch-auto-intake/spec.md diff --git a/openspec/changes/archive/2026-07-22-minio-folderview-and-baseline-disclosure/tasks.md b/openspec/changes/minio-folderview-and-baseline-disclosure/tasks.md similarity index 100% rename from openspec/changes/archive/2026-07-22-minio-folderview-and-baseline-disclosure/tasks.md rename to openspec/changes/minio-folderview-and-baseline-disclosure/tasks.md diff --git a/openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/.openspec.yaml b/openspec/changes/rvt-ifc-usdc-lineage/.openspec.yaml similarity index 100% rename from openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/.openspec.yaml rename to openspec/changes/rvt-ifc-usdc-lineage/.openspec.yaml diff --git a/openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/contracts/README.md b/openspec/changes/rvt-ifc-usdc-lineage/contracts/README.md similarity index 100% rename from openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/contracts/README.md rename to openspec/changes/rvt-ifc-usdc-lineage/contracts/README.md diff --git a/openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/contracts/cloud-lineage-publication-mysql8-reference.sql b/openspec/changes/rvt-ifc-usdc-lineage/contracts/cloud-lineage-publication-mysql8-reference.sql similarity index 100% rename from openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/contracts/cloud-lineage-publication-mysql8-reference.sql rename to openspec/changes/rvt-ifc-usdc-lineage/contracts/cloud-lineage-publication-mysql8-reference.sql diff --git a/openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/contracts/cloud-lineage-publication-request-v1.schema.json b/openspec/changes/rvt-ifc-usdc-lineage/contracts/cloud-lineage-publication-request-v1.schema.json similarity index 100% rename from openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/contracts/cloud-lineage-publication-request-v1.schema.json rename to openspec/changes/rvt-ifc-usdc-lineage/contracts/cloud-lineage-publication-request-v1.schema.json diff --git a/openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/contracts/cloud-lineage-publication-response-v1.schema.json b/openspec/changes/rvt-ifc-usdc-lineage/contracts/cloud-lineage-publication-response-v1.schema.json similarity index 100% rename from openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/contracts/cloud-lineage-publication-response-v1.schema.json rename to openspec/changes/rvt-ifc-usdc-lineage/contracts/cloud-lineage-publication-response-v1.schema.json diff --git a/openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/contracts/examples/invalid-colon-publication-identity-component.json b/openspec/changes/rvt-ifc-usdc-lineage/contracts/examples/invalid-colon-publication-identity-component.json similarity index 100% rename from openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/contracts/examples/invalid-colon-publication-identity-component.json rename to openspec/changes/rvt-ifc-usdc-lineage/contracts/examples/invalid-colon-publication-identity-component.json diff --git a/openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/contracts/examples/invalid-cross-site-health-locator.json b/openspec/changes/rvt-ifc-usdc-lineage/contracts/examples/invalid-cross-site-health-locator.json similarity index 100% rename from openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/contracts/examples/invalid-cross-site-health-locator.json rename to openspec/changes/rvt-ifc-usdc-lineage/contracts/examples/invalid-cross-site-health-locator.json diff --git a/openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/contracts/examples/invalid-csv-valid-exceeds-total.json b/openspec/changes/rvt-ifc-usdc-lineage/contracts/examples/invalid-csv-valid-exceeds-total.json similarity index 100% rename from openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/contracts/examples/invalid-csv-valid-exceeds-total.json rename to openspec/changes/rvt-ifc-usdc-lineage/contracts/examples/invalid-csv-valid-exceeds-total.json diff --git a/openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/contracts/examples/invalid-edge-site-authority-character.json b/openspec/changes/rvt-ifc-usdc-lineage/contracts/examples/invalid-edge-site-authority-character.json similarity index 100% rename from openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/contracts/examples/invalid-edge-site-authority-character.json rename to openspec/changes/rvt-ifc-usdc-lineage/contracts/examples/invalid-edge-site-authority-character.json diff --git a/openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/contracts/examples/invalid-error-event-id.json b/openspec/changes/rvt-ifc-usdc-lineage/contracts/examples/invalid-error-event-id.json similarity index 100% rename from openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/contracts/examples/invalid-error-event-id.json rename to openspec/changes/rvt-ifc-usdc-lineage/contracts/examples/invalid-error-event-id.json diff --git a/openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/contracts/examples/invalid-full-lineage-below-set-intersection.json b/openspec/changes/rvt-ifc-usdc-lineage/contracts/examples/invalid-full-lineage-below-set-intersection.json similarity index 100% rename from openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/contracts/examples/invalid-full-lineage-below-set-intersection.json rename to openspec/changes/rvt-ifc-usdc-lineage/contracts/examples/invalid-full-lineage-below-set-intersection.json diff --git a/openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/contracts/examples/invalid-full-lineage-exceeds-ifc-usdc.json b/openspec/changes/rvt-ifc-usdc-lineage/contracts/examples/invalid-full-lineage-exceeds-ifc-usdc.json similarity index 100% rename from openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/contracts/examples/invalid-full-lineage-exceeds-ifc-usdc.json rename to openspec/changes/rvt-ifc-usdc-lineage/contracts/examples/invalid-full-lineage-exceeds-ifc-usdc.json diff --git a/openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/contracts/examples/invalid-full-lineage-exceeds-rvt-ifc.json b/openspec/changes/rvt-ifc-usdc-lineage/contracts/examples/invalid-full-lineage-exceeds-rvt-ifc.json similarity index 100% rename from openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/contracts/examples/invalid-full-lineage-exceeds-rvt-ifc.json rename to openspec/changes/rvt-ifc-usdc-lineage/contracts/examples/invalid-full-lineage-exceeds-rvt-ifc.json diff --git a/openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/contracts/examples/invalid-incomplete-ack.json b/openspec/changes/rvt-ifc-usdc-lineage/contracts/examples/invalid-incomplete-ack.json similarity index 100% rename from openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/contracts/examples/invalid-incomplete-ack.json rename to openspec/changes/rvt-ifc-usdc-lineage/contracts/examples/invalid-incomplete-ack.json diff --git a/openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/contracts/examples/invalid-inconsistent-alignment-counts.json b/openspec/changes/rvt-ifc-usdc-lineage/contracts/examples/invalid-inconsistent-alignment-counts.json similarity index 100% rename from openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/contracts/examples/invalid-inconsistent-alignment-counts.json rename to openspec/changes/rvt-ifc-usdc-lineage/contracts/examples/invalid-inconsistent-alignment-counts.json diff --git a/openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/contracts/examples/invalid-inconsistent-ifc-only-count.json b/openspec/changes/rvt-ifc-usdc-lineage/contracts/examples/invalid-inconsistent-ifc-only-count.json similarity index 100% rename from openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/contracts/examples/invalid-inconsistent-ifc-only-count.json rename to openspec/changes/rvt-ifc-usdc-lineage/contracts/examples/invalid-inconsistent-ifc-only-count.json diff --git a/openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/contracts/examples/invalid-inconsistent-ifc-usdc-counts.json b/openspec/changes/rvt-ifc-usdc-lineage/contracts/examples/invalid-inconsistent-ifc-usdc-counts.json similarity index 100% rename from openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/contracts/examples/invalid-inconsistent-ifc-usdc-counts.json rename to openspec/changes/rvt-ifc-usdc-lineage/contracts/examples/invalid-inconsistent-ifc-usdc-counts.json diff --git a/openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/contracts/examples/invalid-inconsistent-rvt-ifc-counts.json b/openspec/changes/rvt-ifc-usdc-lineage/contracts/examples/invalid-inconsistent-rvt-ifc-counts.json similarity index 100% rename from openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/contracts/examples/invalid-inconsistent-rvt-ifc-counts.json rename to openspec/changes/rvt-ifc-usdc-lineage/contracts/examples/invalid-inconsistent-rvt-ifc-counts.json diff --git a/openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/contracts/examples/invalid-leap-second-health-observed-at.json b/openspec/changes/rvt-ifc-usdc-lineage/contracts/examples/invalid-leap-second-health-observed-at.json similarity index 100% rename from openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/contracts/examples/invalid-leap-second-health-observed-at.json rename to openspec/changes/rvt-ifc-usdc-lineage/contracts/examples/invalid-leap-second-health-observed-at.json diff --git a/openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/contracts/examples/invalid-lowercase-presigned-locator.json b/openspec/changes/rvt-ifc-usdc-lineage/contracts/examples/invalid-lowercase-presigned-locator.json similarity index 100% rename from openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/contracts/examples/invalid-lowercase-presigned-locator.json rename to openspec/changes/rvt-ifc-usdc-lineage/contracts/examples/invalid-lowercase-presigned-locator.json diff --git a/openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/contracts/examples/invalid-mismatched-publication-identity.json b/openspec/changes/rvt-ifc-usdc-lineage/contracts/examples/invalid-mismatched-publication-identity.json similarity index 100% rename from openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/contracts/examples/invalid-mismatched-publication-identity.json rename to openspec/changes/rvt-ifc-usdc-lineage/contracts/examples/invalid-mismatched-publication-identity.json diff --git a/openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/contracts/examples/invalid-nonretryable-transient-error.json b/openspec/changes/rvt-ifc-usdc-lineage/contracts/examples/invalid-nonretryable-transient-error.json similarity index 100% rename from openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/contracts/examples/invalid-nonretryable-transient-error.json rename to openspec/changes/rvt-ifc-usdc-lineage/contracts/examples/invalid-nonretryable-transient-error.json diff --git a/openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/contracts/examples/invalid-offset-ack-stored-at.json b/openspec/changes/rvt-ifc-usdc-lineage/contracts/examples/invalid-offset-ack-stored-at.json similarity index 100% rename from openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/contracts/examples/invalid-offset-ack-stored-at.json rename to openspec/changes/rvt-ifc-usdc-lineage/contracts/examples/invalid-offset-ack-stored-at.json diff --git a/openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/contracts/examples/invalid-offset-health-observed-at.json b/openspec/changes/rvt-ifc-usdc-lineage/contracts/examples/invalid-offset-health-observed-at.json similarity index 100% rename from openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/contracts/examples/invalid-offset-health-observed-at.json rename to openspec/changes/rvt-ifc-usdc-lineage/contracts/examples/invalid-offset-health-observed-at.json diff --git a/openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/contracts/examples/invalid-offset-occurred-at.json b/openspec/changes/rvt-ifc-usdc-lineage/contracts/examples/invalid-offset-occurred-at.json similarity index 100% rename from openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/contracts/examples/invalid-offset-occurred-at.json rename to openspec/changes/rvt-ifc-usdc-lineage/contracts/examples/invalid-offset-occurred-at.json diff --git a/openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/contracts/examples/invalid-offset-published-at.json b/openspec/changes/rvt-ifc-usdc-lineage/contracts/examples/invalid-offset-published-at.json similarity index 100% rename from openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/contracts/examples/invalid-offset-published-at.json rename to openspec/changes/rvt-ifc-usdc-lineage/contracts/examples/invalid-offset-published-at.json diff --git a/openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/contracts/examples/invalid-out-of-range-health-observed-at.json b/openspec/changes/rvt-ifc-usdc-lineage/contracts/examples/invalid-out-of-range-health-observed-at.json similarity index 100% rename from openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/contracts/examples/invalid-out-of-range-health-observed-at.json rename to openspec/changes/rvt-ifc-usdc-lineage/contracts/examples/invalid-out-of-range-health-observed-at.json diff --git a/openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/contracts/examples/invalid-presigned-health-locator.json b/openspec/changes/rvt-ifc-usdc-lineage/contracts/examples/invalid-presigned-health-locator.json similarity index 100% rename from openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/contracts/examples/invalid-presigned-health-locator.json rename to openspec/changes/rvt-ifc-usdc-lineage/contracts/examples/invalid-presigned-health-locator.json diff --git a/openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/contracts/examples/invalid-retryable-deterministic-error.json b/openspec/changes/rvt-ifc-usdc-lineage/contracts/examples/invalid-retryable-deterministic-error.json similarity index 100% rename from openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/contracts/examples/invalid-retryable-deterministic-error.json rename to openspec/changes/rvt-ifc-usdc-lineage/contracts/examples/invalid-retryable-deterministic-error.json diff --git a/openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/contracts/examples/invalid-submicrosecond-health-observed-at.json b/openspec/changes/rvt-ifc-usdc-lineage/contracts/examples/invalid-submicrosecond-health-observed-at.json similarity index 100% rename from openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/contracts/examples/invalid-submicrosecond-health-observed-at.json rename to openspec/changes/rvt-ifc-usdc-lineage/contracts/examples/invalid-submicrosecond-health-observed-at.json diff --git a/openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/contracts/examples/invalid-tombstone-id-on-non-tombstone.json b/openspec/changes/rvt-ifc-usdc-lineage/contracts/examples/invalid-tombstone-id-on-non-tombstone.json similarity index 100% rename from openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/contracts/examples/invalid-tombstone-id-on-non-tombstone.json rename to openspec/changes/rvt-ifc-usdc-lineage/contracts/examples/invalid-tombstone-id-on-non-tombstone.json diff --git a/openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/contracts/examples/valid-auth-error-without-event-id.json b/openspec/changes/rvt-ifc-usdc-lineage/contracts/examples/valid-auth-error-without-event-id.json similarity index 100% rename from openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/contracts/examples/valid-auth-error-without-event-id.json rename to openspec/changes/rvt-ifc-usdc-lineage/contracts/examples/valid-auth-error-without-event-id.json diff --git a/openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/contracts/examples/valid-conflict-error.json b/openspec/changes/rvt-ifc-usdc-lineage/contracts/examples/valid-conflict-error.json similarity index 100% rename from openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/contracts/examples/valid-conflict-error.json rename to openspec/changes/rvt-ifc-usdc-lineage/contracts/examples/valid-conflict-error.json diff --git a/openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/contracts/examples/valid-created-ack.json b/openspec/changes/rvt-ifc-usdc-lineage/contracts/examples/valid-created-ack.json similarity index 100% rename from openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/contracts/examples/valid-created-ack.json rename to openspec/changes/rvt-ifc-usdc-lineage/contracts/examples/valid-created-ack.json diff --git a/openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/contracts/examples/valid-lineage-result-health-changed.json b/openspec/changes/rvt-ifc-usdc-lineage/contracts/examples/valid-lineage-result-health-changed.json similarity index 100% rename from openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/contracts/examples/valid-lineage-result-health-changed.json rename to openspec/changes/rvt-ifc-usdc-lineage/contracts/examples/valid-lineage-result-health-changed.json diff --git a/openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/contracts/examples/valid-lineage-result-published.json b/openspec/changes/rvt-ifc-usdc-lineage/contracts/examples/valid-lineage-result-published.json similarity index 100% rename from openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/contracts/examples/valid-lineage-result-published.json rename to openspec/changes/rvt-ifc-usdc-lineage/contracts/examples/valid-lineage-result-published.json diff --git a/openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/contracts/examples/valid-lineage-result-tombstoned.json b/openspec/changes/rvt-ifc-usdc-lineage/contracts/examples/valid-lineage-result-tombstoned.json similarity index 100% rename from openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/contracts/examples/valid-lineage-result-tombstoned.json rename to openspec/changes/rvt-ifc-usdc-lineage/contracts/examples/valid-lineage-result-tombstoned.json diff --git a/openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/contracts/examples/valid-transient-error.json b/openspec/changes/rvt-ifc-usdc-lineage/contracts/examples/valid-transient-error.json similarity index 100% rename from openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/contracts/examples/valid-transient-error.json rename to openspec/changes/rvt-ifc-usdc-lineage/contracts/examples/valid-transient-error.json diff --git a/openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/design.md b/openspec/changes/rvt-ifc-usdc-lineage/design.md similarity index 100% rename from openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/design.md rename to openspec/changes/rvt-ifc-usdc-lineage/design.md diff --git a/openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/proposal.md b/openspec/changes/rvt-ifc-usdc-lineage/proposal.md similarity index 93% rename from openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/proposal.md rename to openspec/changes/rvt-ifc-usdc-lineage/proposal.md index 3034847d4..43ee0274f 100644 --- a/openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/proposal.md +++ b/openspec/changes/rvt-ifc-usdc-lineage/proposal.md @@ -1,5 +1,7 @@ > **Status: deferred 2026-07-21**(使用者裁決/NOW 軌0 OQ-1):本 change 暫不計入 active product WIP 上限;契約草稿保留,本週不排實作 PR。解凍條件:A4 切片 S1–S3 穩定或使用者明確 thaw。 +> **Historical correction 2026-07-24**:本 change 曾以 `--skip-specs` 誤作 completed archive;現因 tasks 僅 1/48 完成而恢復原 change id。它仍是 frozen、non-canonical、non-owner,**不得直接 apply 或 coding**。解凍前 MUST 先重驗 current main,完成 predecessor/successor crosswalk,並把 contract、coordinator、streaming/admission、cloud outbox、frontend/E2E 切成不重疊且可獨立驗證的 slices;在 `migrate-console-to-hifi-design`、conversion pipeline、runtime command/lease 與 single-GPU session ownership 未調和前不得進入實作。 + ## Why 目前 repo 已正式描述 IFC-ready intake、IFC→USDC conversion 與 `IFC GlobalId ↔ USD prim path`,但尚未把 2026-07-14~07-15 定案的 MinIO version bundle、`schedule.csv` RVT identity、三向 alignment、result publication、attempt/runtime admission 與治理操作收斂成可執行契約。缺少這層契約會讓同一版本的 RVT、IFC、USDC 與 mapping/report 各自成功,卻無法證明它們屬於同一條可稽核 lineage;現有legacy workflow callback也沒有versioned Cloud Ingest、HMAC、commit ACK、health history或「cloud只存result locator+summary」的MySQL邊界。 diff --git a/openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/specs/cloud-lineage-publication/spec.md b/openspec/changes/rvt-ifc-usdc-lineage/specs/cloud-lineage-publication/spec.md similarity index 100% rename from openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/specs/cloud-lineage-publication/spec.md rename to openspec/changes/rvt-ifc-usdc-lineage/specs/cloud-lineage-publication/spec.md diff --git a/openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/specs/conversion-attempt-publication/spec.md b/openspec/changes/rvt-ifc-usdc-lineage/specs/conversion-attempt-publication/spec.md similarity index 100% rename from openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/specs/conversion-attempt-publication/spec.md rename to openspec/changes/rvt-ifc-usdc-lineage/specs/conversion-attempt-publication/spec.md diff --git a/openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/specs/conversion-runtime-admission/spec.md b/openspec/changes/rvt-ifc-usdc-lineage/specs/conversion-runtime-admission/spec.md similarity index 100% rename from openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/specs/conversion-runtime-admission/spec.md rename to openspec/changes/rvt-ifc-usdc-lineage/specs/conversion-runtime-admission/spec.md diff --git a/openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/specs/lineage-governance-console/spec.md b/openspec/changes/rvt-ifc-usdc-lineage/specs/lineage-governance-console/spec.md similarity index 100% rename from openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/specs/lineage-governance-console/spec.md rename to openspec/changes/rvt-ifc-usdc-lineage/specs/lineage-governance-console/spec.md diff --git a/openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/specs/minio-model-version-bundle/spec.md b/openspec/changes/rvt-ifc-usdc-lineage/specs/minio-model-version-bundle/spec.md similarity index 100% rename from openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/specs/minio-model-version-bundle/spec.md rename to openspec/changes/rvt-ifc-usdc-lineage/specs/minio-model-version-bundle/spec.md diff --git a/openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/specs/rvt-ifc-usdc-lineage/spec.md b/openspec/changes/rvt-ifc-usdc-lineage/specs/rvt-ifc-usdc-lineage/spec.md similarity index 100% rename from openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/specs/rvt-ifc-usdc-lineage/spec.md rename to openspec/changes/rvt-ifc-usdc-lineage/specs/rvt-ifc-usdc-lineage/spec.md diff --git a/openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/tasks.md b/openspec/changes/rvt-ifc-usdc-lineage/tasks.md similarity index 100% rename from openspec/changes/archive/2026-07-22-rvt-ifc-usdc-lineage/tasks.md rename to openspec/changes/rvt-ifc-usdc-lineage/tasks.md diff --git a/openspec/specs/governance-throughput-budget/spec.md b/openspec/specs/governance-throughput-budget/spec.md index c6aeccf43..f97b29dc7 100644 --- a/openspec/specs/governance-throughput-budget/spec.md +++ b/openspec/specs/governance-throughput-budget/spec.md @@ -84,7 +84,7 @@ git log --since="14 days ago" --oneline origin/main -- ` | `minio-folderview-and-baseline-disclosure` | 0/7 未動工 | deferred | 重啟條件:active ≤ 2 有額度且需求回到當期優先;重啟時 SHALL 先重驗 main 現況(#259 trigger 端點、watcher ledger)再調和 tasks | | `align-frontend-design-system-reference` | 0/23 未動工(specs delta 已由 #363 PF-3 調和至 doc-first) | deferred | 重啟條件:active ≤ 2 有額度;重啟時 SHALL 重跑 `openspec validate --strict` 確認 delta 仍對準當時 main spec | | `a4-semantic-search-model-qa` | 0/64 未動工(8 節全空) | 留待 OQ-1 裁決 | — | -| `rvt-ifc-usdc-lineage` | 1/48(僅 8.1 contract-only) | 留待 OQ-1 裁決 | — | +| `rvt-ifc-usdc-lineage` | 1/48(僅 8.1 contract-only) | `Status: deferred`、frozen/non-owner;2026-07-24 historical correction 恢復原 id | 解凍前重驗 current main、完成 predecessor/successor crosswalk 並拆成不重疊 slices | | `migrate-console-to-hifi-design` | tasks 0/35 未勾,但 main #357 已落 1/2 product code | 留待 OQ-1 裁決(建議傾向優先收尾) | 先對帳 tasks.md 勾選與 main 實際落地,再裁 | - **Trigger**:本 change 被使用者採納且 OQ-1 裁決完成。 diff --git a/openspec/specs/minio-fileserver-source/spec.md b/openspec/specs/minio-fileserver-source/spec.md index 47275bda5..1d4719525 100644 --- a/openspec/specs/minio-fileserver-source/spec.md +++ b/openspec/specs/minio-fileserver-source/spec.md @@ -53,7 +53,7 @@ coordinator `governanceProxy` SHALL 提供白名單一條 `GET /api/governance/f ### Requirement: `#/minio` SHALL 顯示真實檔案庫樹(四態 + 可重試) -> Deferred archive(2026-07-22,`--skip-specs`):原 `minio-folderview-and-baseline-disclosure` change 的 raw-folder、ledger 與手動觸發提案保留在 `openspec/changes/archive/2026-07-22-minio-folderview-and-baseline-disclosure/`,但未合併至 canonical specs。因此 archive 內容僅為 non-canonical 歷史工件,**不** supersede 本 requirement;下方現行 `#/minio` requirement 仍是權威。若要重啟,MUST 先依當時 main 現況新開/調和 change,並重新驗證 UI/API contract。 +> Deferred change(2026-07-24 historical correction):`minio-folderview-and-baseline-disclosure` 已恢復至 `openspec/changes/minio-folderview-and-baseline-disclosure/`,其 raw-folder、ledger 與手動觸發 delta 尚未合併至 canonical specs,仍為 frozen、non-canonical、non-owner,**不**自動 supersede 本 requirement;下方現行 `#/minio` requirement 仍是權威。解凍前 MUST 先以現行 main source/tests 對帳 #259/#265 已落地行為、調和 tasks 與 delta,並重新驗證 UI/API contract;不得重做既有 production code。 `#/minio`(MinioDataPage)SHALL 經 `governanceClient.filesTree()` 取真樹並渲染 project/model/version(含 `source_kind` / `root` 誠實標示),SHALL 呈現 loading / error / empty / populated 四態:error 態 SHALL 誠實顯示「未連線後端」與錯誤原因並提供使用者可觸發的「重試」動作(重打同一條真實 fetch,SHALL NOT 要求整頁 reload);empty 態 SHALL 誠實顯示「檔案庫為空」。SHALL NOT 以寫死示意樹偽裝真資料;`model.usdc` 轉檔產物仍標 p1 待建。 diff --git a/openspec/specs/minio-watch-auto-intake/spec.md b/openspec/specs/minio-watch-auto-intake/spec.md index a25ab5905..3615c0a9c 100644 --- a/openspec/specs/minio-watch-auto-intake/spec.md +++ b/openspec/specs/minio-watch-auto-intake/spec.md @@ -5,7 +5,7 @@ TBD - created by archiving change minio-watch-auto-intake. Update Purpose after ## Requirements ### Requirement: coordinator SHALL 以輪詢自動偵測 MinIO 新 IFC 並觸發既有 intake 鏈(O4 定案) -> Deferred archive(2026-07-22,`--skip-specs`):原 `minio-folderview-and-baseline-disclosure` change 的 ledger 去重與手動觸發提案保留在 `openspec/changes/archive/2026-07-22-minio-folderview-and-baseline-disclosure/`,但未合併至 canonical specs。因此 archive 內容僅為 non-canonical 歷史工件,**不** supersede 本 requirement;若要重啟,MUST 先依當時 main 現況新開/調和 change,並重新驗證 watcher/intake contract。 +> Deferred change(2026-07-24 historical correction):`minio-folderview-and-baseline-disclosure` 已恢復至 `openspec/changes/minio-folderview-and-baseline-disclosure/`,其 ledger 去重與手動觸發 delta 尚未合併至 canonical specs,仍為 frozen、non-canonical、non-owner,**不**自動 supersede 本 requirement。解凍前 MUST 先以現行 main source/tests 對帳 #259/#265 已落地行為、調和 tasks 與 delta,並重新驗證 watcher/intake contract;不得重做既有 production code。 watcher SHALL 為 env opt-in(`MINIO_WATCH_ENABLED` 預設 false,未啟用時系統行為與無此功能完全一致)。啟用時 SHALL 以 `ListObjectsV2`(含 `IsTruncated`/`NextContinuationToken` 分頁)定時輪詢指定 bucket/prefix,僅對 key 以設定後綴(預設 `/model.ifc`)結尾者反應。首輪 SHALL 只登記 baseline 不觸發;後續輪的新 key 或同 key 新 etag SHALL 觸發對 loopback `POST /api/external/ifc-ready`(帶既有 webhook secret 與 presigned GET URL),由既有下載/sanitize/dispatch/callback 鏈處理。idempotency key SHALL 由 `bucket|key|etag` 確定性導出,重啟重掃同物件 SHALL 命中既有去重(idempotent_replay,不重複建 job)。輪詢間隔 SHALL 受下限保護且下限 SHALL 在 config overrides 合併後仍生效。單一物件的 intake 觸發失敗(presign / 網路 / 逾時 / HTTP error / 2xx 非 JSON)SHALL NOT 將該物件標記為已處理,watcher SHALL 於後續輪重試(漏抓自癒);key 層級不符(malformed)為確定性結果,SHALL 計數一次後跳過、不重試。惟重試若收到「已存在且 download 已失敗之 job」的 idempotent replay(replay 依既有 intake 規約不重下載、不重派工),watcher SHALL 將失敗連同 job id 誠實記入 status、SHALL NOT 計為成功觸發、並 SHALL 停止對該物件的無效重試(失敗 job 於 `#/conv` 可見;補救走手動 webhook intake 或重新上傳使 etag 改變)。非空 `MINIO_WATCH_PREFIX` SHALL 於 config 層 normalize 為以 `/` 結尾(含 overrides 合併後),避免 boundary-misaligned prefix 造成整批靜默 skip。 diff --git a/scripts/tests/test-agent-governance-check.ps1 b/scripts/tests/test-agent-governance-check.ps1 index e8376f839..6a37d14a4 100644 --- a/scripts/tests/test-agent-governance-check.ps1 +++ b/scripts/tests/test-agent-governance-check.ps1 @@ -38,6 +38,7 @@ try { '.github/PULL_REQUEST_TEMPLATE.md', 'scripts/tests/check-pr-body-evidence.ps1', 'scripts/tests/test-pr-body-evidence.ps1', + 'scripts/tests/verify-openspec-lifecycle.ps1', 'scripts/lib/design-system-gate.ps1', 'scripts/tests/verify-design-system-reference.ps1', 'scripts/tests/test-design-system-reference.ps1', @@ -59,7 +60,8 @@ try { '.codex/skills/spec-to-done/agents/openai.yaml', 'docs/agents/superpowers-invocation-policy.md', 'docs/PR_REVIEW_AGENT.md', - 'docs/superpowers/plans/2026-06-18-ai-coding-maturity-governance.md' + 'docs/superpowers/plans/2026-06-18-ai-coding-maturity-governance.md', + 'openspec/AGENTS.md' )) { Assert-True (Test-Path -LiteralPath $path -PathType Leaf) "$path exists" } @@ -73,6 +75,9 @@ try { Assert-FileContains '.github/ISSUE_TEMPLATE/governance-change.yml' 'agent-workflow' 'governance change template carries agent workflow label' Assert-FileContains '.github/CODEOWNERS' '@monkey1sai' 'CODEOWNERS names repository owner' + Assert-FileContains '.github/workflows/agent-governance.yml' 'verify-openspec-lifecycle\.ps1' 'agent governance runs OpenSpec lifecycle verification' + Assert-FileContains 'openspec/AGENTS.md' 'deferred change 保留在 `openspec/changes//`' 'OpenSpec instructions keep deferred changes outside completed archive' + Assert-FileContains 'openspec/AGENTS.md' '--skip-specs.*不是.*deferred state' 'OpenSpec instructions do not treat skip-specs as deferral' foreach ($ownedPath in @('/AGENTS.md', '/docs/agents/', '/docs/plans/', '/.github/', '/scripts/')) { Assert-FileContains '.github/CODEOWNERS' ([regex]::Escape($ownedPath)) "CODEOWNERS covers $ownedPath" } diff --git a/scripts/tests/verify-openspec-lifecycle.ps1 b/scripts/tests/verify-openspec-lifecycle.ps1 new file mode 100644 index 000000000..efc3a7ea9 --- /dev/null +++ b/scripts/tests/verify-openspec-lifecycle.ps1 @@ -0,0 +1,189 @@ +[CmdletBinding()] +param( + [string] $RepoRoot = '', + [string] $BaseRef = '' +) + +Set-StrictMode -Version Latest +$ErrorActionPreference = 'Stop' + +function Get-ProposalState { + param([Parameter(Mandatory = $true)][string] $ChangeDirectory) + + $proposalPath = Join-Path $ChangeDirectory 'proposal.md' + if (-not (Test-Path -LiteralPath $proposalPath -PathType Leaf)) { + return [pscustomobject]@{ + Exists = $false + IsDeferred = $false + HasCondition = $false + Content = '' + } + } + + $content = Get-Content -LiteralPath $proposalPath -Raw + return [pscustomobject]@{ + Exists = $true + IsDeferred = $content -match '(?m)^>\s*\*\*Status:\s*deferred\b' + HasCondition = $content -match '(重啟|解凍|thaw|closeout)' + Content = $content + } +} + +function Get-DiffTargetPaths { + param([Parameter(Mandatory = $true)][string] $Against) + + # Compare the base commit directly with the current tree. This works both in + # CI (where the PR diff is committed) and during a local pre-commit check. + $lines = @(git diff --name-status -M $Against --) + if ($LASTEXITCODE -ne 0) { + throw "Unable to diff lifecycle state against $Against" + } + + foreach ($line in $lines) { + if ([string]::IsNullOrWhiteSpace($line)) { continue } + $parts = @($line -split "`t") + if ($parts[0] -match '^R\d+$') { + if ($parts.Count -ge 3) { $parts[2] } + continue + } + if ($parts.Count -ge 2 -and $parts[0] -ne 'D') { $parts[1] } + } +} + +if ([string]::IsNullOrWhiteSpace($RepoRoot)) { + $RepoRoot = (Resolve-Path -LiteralPath (Join-Path $PSScriptRoot '..\..')).Path +} else { + $RepoRoot = (Resolve-Path -LiteralPath $RepoRoot).Path +} + +$failures = [System.Collections.Generic.List[string]]::new() +$warnings = [System.Collections.Generic.List[string]]::new() + +Push-Location $RepoRoot +try { + $changesRoot = Join-Path $RepoRoot 'openspec\changes' + $archiveRoot = Join-Path $changesRoot 'archive' + if (-not (Test-Path -LiteralPath $changesRoot -PathType Container)) { + throw "OpenSpec changes root not found: $changesRoot" + } + + $activeChanges = @(Get-ChildItem -LiteralPath $changesRoot -Directory | Where-Object Name -ne 'archive') + $deferredChanges = [System.Collections.Generic.List[string]]::new() + $nonDeferredChanges = [System.Collections.Generic.List[string]]::new() + $capabilityOwners = @{} + + foreach ($change in $activeChanges) { + $state = Get-ProposalState -ChangeDirectory $change.FullName + if ($state.IsDeferred) { + $deferredChanges.Add($change.Name) + if (-not $state.HasCondition) { + $failures.Add("deferred change lacks thaw/restart/closeout condition: $($change.Name)") + } + continue + } + + $nonDeferredChanges.Add($change.Name) + $specRoot = Join-Path $change.FullName 'specs' + if (-not (Test-Path -LiteralPath $specRoot -PathType Container)) { continue } + foreach ($capability in Get-ChildItem -LiteralPath $specRoot -Directory) { + if (-not $capabilityOwners.ContainsKey($capability.Name)) { + $capabilityOwners[$capability.Name] = [System.Collections.Generic.List[string]]::new() + } + $capabilityOwners[$capability.Name].Add($change.Name) + } + } + + foreach ($entry in $capabilityOwners.GetEnumerator()) { + if ($entry.Value.Count -gt 1) { + $failures.Add("non-deferred capability has multiple owners: $($entry.Key) => $($entry.Value -join ', ')") + } + } + + if ($nonDeferredChanges.Count -gt 2) { + $warnings.Add("existing non-deferred WIP is $($nonDeferredChanges.Count) > 2: $($nonDeferredChanges -join ', ')") + } + + # A deferred marker is never valid in completed archive, including legacy entries. + if (Test-Path -LiteralPath $archiveRoot -PathType Container) { + foreach ($archived in Get-ChildItem -LiteralPath $archiveRoot -Directory) { + $state = Get-ProposalState -ChangeDirectory $archived.FullName + if ($state.IsDeferred) { + $failures.Add("deferred change is stored in completed archive: $($archived.Name)") + } + } + } + + $hasBase = -not [string]::IsNullOrWhiteSpace($BaseRef) + if ($hasBase) { + git rev-parse --verify "$BaseRef^{commit}" *> $null + if ($LASTEXITCODE -ne 0) { + throw "BaseRef is not available locally: $BaseRef" + } + + $targetPaths = @(Get-DiffTargetPaths -Against $BaseRef) + $newArchiveIds = [System.Collections.Generic.HashSet[string]]::new([StringComparer]::OrdinalIgnoreCase) + $newChangeIds = [System.Collections.Generic.HashSet[string]]::new([StringComparer]::OrdinalIgnoreCase) + + foreach ($path in $targetPaths) { + $normalized = $path.Replace('\', '/') + if ($normalized -match '^openspec/changes/archive/([^/]+)/') { + [void] $newArchiveIds.Add($Matches[1]) + continue + } + if ($normalized -match '^openspec/changes/([^/]+)/') { + [void] $newChangeIds.Add($Matches[1]) + } + } + + foreach ($archiveId in $newArchiveIds) { + $directory = Join-Path $archiveRoot $archiveId + if (-not (Test-Path -LiteralPath $directory -PathType Container)) { continue } + $state = Get-ProposalState -ChangeDirectory $directory + if ($state.IsDeferred) { + $failures.Add("new archive contains deferred marker: $archiveId") + } + $tasksPath = Join-Path $directory 'tasks.md' + if (Test-Path -LiteralPath $tasksPath -PathType Leaf) { + $unchecked = @(Select-String -LiteralPath $tasksPath -Pattern '^\s*- \[ \]' -CaseSensitive).Count + if ($unchecked -gt 0) { + $failures.Add("new archive contains $unchecked unchecked tasks: $archiveId") + } + } + } + + # Historical corrections may add a change path while the repo is already over WIP. + # Such additions are safe only when the restored/new change is explicitly deferred. + if ($nonDeferredChanges.Count -gt 2) { + foreach ($changeId in $newChangeIds) { + if ($changeId -eq 'archive') { continue } + $directory = Join-Path $changesRoot $changeId + if (-not (Test-Path -LiteralPath $directory -PathType Container)) { continue } + + $baseProposal = @(git ls-tree -r --name-only $BaseRef -- "openspec/changes/$changeId/proposal.md") + if ($LASTEXITCODE -ne 0) { + throw "Unable to inspect $changeId at base $BaseRef" + } + $existedAtBase = $baseProposal.Count -gt 0 + if ($existedAtBase) { continue } + + $state = Get-ProposalState -ChangeDirectory $directory + if (-not $state.IsDeferred) { + $failures.Add("new non-deferred change increases an already-over-budget WIP set: $changeId") + } + } + } + } else { + $warnings.Add('BaseRef not supplied; changed-only archive completion checks were skipped') + } + + foreach ($warning in $warnings) { Write-Warning $warning } + if ($failures.Count -gt 0) { + $failures | ForEach-Object { Write-Error $_ -ErrorAction Continue } + throw "OpenSpec lifecycle verification failed with $($failures.Count) finding(s)." + } + + Write-Output ("openspec lifecycle OK: non_deferred={0}; deferred={1}; base_ref={2}" -f ` + $nonDeferredChanges.Count, $deferredChanges.Count, $(if ($hasBase) { $BaseRef } else { '' })) +} finally { + Pop-Location +} From 972d853472ef9f2571142e3de29588758a8c7299 Mon Sep 17 00:00:00 2001 From: monkey1sai <26239865+monkey1sai@users.noreply.github.com> Date: Fri, 24 Jul 2026 14:41:03 +0800 Subject: [PATCH 2/3] fix(governance): disambiguate OpenSpec change validation Pass --type change from the PR review agent so a restored change can coexist with its canonical spec without producing an ambiguous validation command. --- scripts/lib/pr-review-agent.ps1 | 2 +- scripts/tests/test-pr-review-agent.ps1 | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/lib/pr-review-agent.ps1 b/scripts/lib/pr-review-agent.ps1 index 51b543ecf..9a2872ee2 100644 --- a/scripts/lib/pr-review-agent.ps1 +++ b/scripts/lib/pr-review-agent.ps1 @@ -738,7 +738,7 @@ function Get-PrReviewValidationPlan { } foreach ($changeId in $OpenSpecChangeIds) { if ($added.Add("openspec:$changeId")) { - [void]$plans.Add((New-PrReviewCommandPlan -Name "openspec validate $changeId" -Owner 'openspec' -Cwd $RepoRoot -FileName 'openspec' -Arguments @('validate', $changeId))) + [void]$plans.Add((New-PrReviewCommandPlan -Name "openspec validate $changeId --type change" -Owner 'openspec' -Cwd $RepoRoot -FileName 'openspec' -Arguments @('validate', $changeId, '--type', 'change'))) } } diff --git a/scripts/tests/test-pr-review-agent.ps1 b/scripts/tests/test-pr-review-agent.ps1 index 62fd657de..285ea792f 100644 --- a/scripts/tests/test-pr-review-agent.ps1 +++ b/scripts/tests/test-pr-review-agent.ps1 @@ -86,7 +86,7 @@ $result1 = Invoke-PrReviewAgent -RepoRoot $repoRoot ` $loaded1 = Get-Content -LiteralPath $result1.json_path -Raw | ConvertFrom-Json Assert-True ($loaded1.schema_version -eq 'pr-review-agent/v1') 'schema version present' Assert-True ($loaded1.openspec_changes -contains 'add-pr-review-agent') 'OpenSpec change id detected' -Assert-True ($loaded1.validation_commands -contains 'openspec validate add-pr-review-agent') 'OpenSpec validation command planned' +Assert-True ($loaded1.validation_commands -contains 'openspec validate add-pr-review-agent --type change') 'OpenSpec change validation command is type-disambiguated' $optionalAiWarning = $loaded1.warnings | Where-Object { $_.kind -eq 'optional_ai_adapter_skipped' } | Select-Object -First 1 $optionalAiNote = $loaded1.human_review_notes | Where-Object { $_ -match 'Optional AI adapter' } | Select-Object -First 1 Assert-True ($null -eq $optionalAiWarning) 'optional AI skip is not a warning by default' @@ -110,7 +110,7 @@ $archivePlan = Get-PrReviewValidationPlan -RepoRoot $repoRoot ` -OpenSpecChangeIds $archiveIds $archiveCommands = @($archivePlan | ForEach-Object { $_.command }) Assert-True ($archiveCommands -contains 'openspec validate --specs --strict') 'archive/formal spec changes validate strict specs' -Assert-True (-not ($archiveCommands -contains 'openspec validate archive')) 'archive validation command is not planned' +Assert-True (-not ($archiveCommands -contains 'openspec validate archive --type change')) 'archive validation command is not planned' # Test 1b2: Archiving an active change does not validate the deleted change id at PR head. $tempArchiveGit = Join-Path ([System.IO.Path]::GetTempPath()) "pr-review-agent-archive-$([Guid]::NewGuid().ToString('N'))" @@ -143,7 +143,7 @@ try { $loaded1b2 = Get-Content -LiteralPath $result1b2.json_path -Raw | ConvertFrom-Json Assert-True (-not ($loaded1b2.openspec_changes -contains 'archive-me')) 'archive rename skips the deleted active change id' Assert-True ($loaded1b2.validation_commands -contains 'openspec validate --specs --strict') 'archive rename keeps strict canonical spec validation' - Assert-True (-not ($loaded1b2.validation_commands -contains 'openspec validate archive-me')) 'archive rename does not validate a deleted active change' + Assert-True (-not ($loaded1b2.validation_commands -contains 'openspec validate archive-me --type change')) 'archive rename does not validate a deleted active change' Remove-Item -LiteralPath $out1b2 -Recurse -Force } finally { Pop-Location From 68c034d439ee066a812202ea2d6ce6d2fd5da8b8 Mon Sep 17 00:00:00 2001 From: monkey1sai <26239865+monkey1sai@users.noreply.github.com> Date: Fri, 24 Jul 2026 14:51:02 +0800 Subject: [PATCH 3/3] feat(governance): raise OpenSpec WIP limit to six Apply the user-approved capacity change across the canonical throughput spec, NOW routing, lifecycle enforcement, and regression assertions without thawing deferred changes. --- docs/plans/NOW.md | 9 +++++---- .../governance-throughput-budget/spec.md | 20 +++++++++---------- scripts/tests/test-agent-governance-check.ps1 | 3 +++ scripts/tests/verify-openspec-lifecycle.ps1 | 7 ++++--- 4 files changed, 22 insertions(+), 17 deletions(-) diff --git a/docs/plans/NOW.md b/docs/plans/NOW.md index cd8b459f9..ee9942cf6 100644 --- a/docs/plans/NOW.md +++ b/docs/plans/NOW.md @@ -2,17 +2,17 @@ > 文件性質:working note;用於本週工作排序,不是 runtime/API contract 或完成證據。 > **AI / 人:只聽這份。** 與本檔衝突時,以使用者最新口令為準,其次本檔,再才是 OpenSpec / 設計正本。 -> 維護規則:每完成一個 outcome 就改狀態;禁止同時推進 >2 個 active OpenSpec product change。 +> 維護規則:每完成一個 outcome 就改狀態;禁止同時推進 >6 個 active OpenSpec product change。 ## 本週三軌(你已選 1/2/3) | 序 | 軌 | 目標 | 狀態 | |---|---|---|---| -| **0** | 治理 WIP(#364) | active ≤2;defer 其餘;採納 throughput 預算 | ✅ #364 MERGED + `governance-throughput-budget` archived | +| **0** | 治理 WIP(#364) | active ≤6;defer 其餘;採納 throughput 預算 | ✅ #364 MERGED;2026-07-24 使用者將上限由 2 調整為 6 | | **1** | 收口 | completed 才 archive;deferred 留在 changes 並 frozen | **4 個近期 completed 維持 archive;4 個 unfinished historical correction 恢復 deferred** | | **2** | A4 | 只走切片 PR(先 #365,再下一刀) | **#365 + #380 + #382 + #383 + #386 MERGED**;current = S4-B PR #384 final gate,next = S4-C | -**並行規則:** 0 可與 1 同天;**2 與新功能不得再開第 3 條 active product change**。 +**並行規則:** 0 可與 1 同天;所有軌與新功能合計不得超過 6 個 active product change;deferred/frozen 不因額度增加自動 thaw。 **本週不做:** A5–A10 全棧、`rvt-ifc-usdc-lineage` 實作、新 OpenSpec(除 archive/defer 註記)、整 repo 重掃。 --- @@ -21,7 +21,7 @@ | OQ | 題目 | **建議裁決** | |---|---|---| -| OQ-1 | 收斂後保留哪個 ≤2 大 active | ✅ **已採納**:保留 `a4-semantic-search-model-qa` + `migrate-console-to-hifi-design`;`rvt-ifc-usdc-lineage` 為 `Status: deferred`、frozen/non-owner | +| OQ-1 | 收斂後保留哪個 active | ✅ 2026-07-21 原採納上限 2;2026-07-24 使用者調整為 ≤6。既有 `rvt-ifc-usdc-lineage` 仍為 `Status: deferred`、frozen/non-owner,須另行滿足 thaw 條件 | | OQ-2 | docs+chore ≤30% | ✅ **已採納**:首月 40% → 次月 30% | | OQ-3 | #364 自身是第 10 個 active | ✅ **已採納**:#364 merge 後 archive `governance-throughput-budget` | @@ -183,4 +183,5 @@ Done: 通過 DoD 所列測試;回報 verified / inferences / risks | 2026-07-21 | #364 merge;archive governance-throughput-budget;OQ 全落地 | | 2026-07-22 | 使用者確認 deferred archive:`minio-folderview-and-baseline-disclosure`、`align-frontend-design-system-reference`、`rvt-ifc-usdc-lineage` 均以 `--skip-specs` archive;#380 merged,下一刀改為 S3。 | | 2026-07-24 | 使用者改採嚴格 terminal rule:archive 僅限 completed/完整 successor;三個 7/22 deferred change 與 structured-log evidence 缺口 historical correction 恢復原 id,維持 frozen/non-owner。 | +| 2026-07-24 | 使用者將 active OpenSpec WIP 上限由 2 調整為 6;新增額度不自動 thaw deferred/frozen change。 | | 2026-07-23 | #382/#383/#386 merged;#386 先收斂 scoped A4 visible caller compatibility,S4-B coordinator session search proxy、安全 transport、host-kit dual-namespace seam 與 cold-scan timeout regression 由 PR #384 交付(狀態以 GitHub machine truth 為準),S4-C/D 仍 pending。 | diff --git a/openspec/specs/governance-throughput-budget/spec.md b/openspec/specs/governance-throughput-budget/spec.md index f97b29dc7..251eac4d6 100644 --- a/openspec/specs/governance-throughput-budget/spec.md +++ b/openspec/specs/governance-throughput-budget/spec.md @@ -3,12 +3,12 @@ ## Purpose TBD - created by archiving change governance-throughput-budget. Update Purpose after archive. ## Requirements -### Requirement: active OpenSpec change 同時數量 SHALL 不超過 2(WIP 上限) +### Requirement: active OpenSpec change 同時數量 SHALL 不超過 6(WIP 上限) -(採納後生效)`openspec/changes/` 下之 active change——不含 `archive/`、不含 proposal.md 頂部帶 `Status: deferred` 系列標記者——同時 SHALL ≤ 2。deferred 標記格式 SHALL 為 proposal.md 頂部 blockquote:提案期 `Status: deferred-proposed <日期>`、使用者採納後改 `Status: deferred <日期>`,並各附理由與重啟條件;標記 SHALL 只加註不刪改原內容。 +(2026-07-24 使用者將原上限 2 調整為 6 後生效)`openspec/changes/` 下之 active change——不含 `archive/`、不含 proposal.md 頂部帶 `Status: deferred` 系列標記者——同時 SHALL ≤ 6。deferred 標記格式 SHALL 為 proposal.md 頂部 blockquote:提案期 `Status: deferred-proposed <日期>`、使用者採納後改 `Status: deferred <日期>`,並各附理由與重啟條件;標記 SHALL 只加註不刪改原內容。提高上限只增加可用 WIP 額度,不會自動 thaw 既有 deferred/frozen change;各 change 的重啟條件與 ownership crosswalk 仍須獨立滿足。 - **Trigger**:任何人或 agent 欲新建 active change(`/openspec new`、openspec-forge 產出落地前)。 -- **Action**:先計數 active change;已達 2 → SHALL NOT 新建,改為先 archive/close-out/defer 既有 change 騰出額度。緊急安全修補或誠實鐵律違規修正得暫時超額,但 SHALL 於同 PR body 揭露超額理由與回落計畫。 +- **Action**:先計數 active change;已達 6 → SHALL NOT 新建,改為先 archive/close-out/defer 既有 change 騰出額度。緊急安全修補或誠實鐵律違規修正得暫時超額,但 SHALL 於同 PR body 揭露超額理由與回落計畫。 - **Validation**(repo root,PowerShell): ```powershell @@ -18,11 +18,11 @@ TBD - created by archiving change governance-throughput-budget. Update Purpose a ).Count ``` -輸出 SHALL ≤ 2;或以 `npx openspec list` 人工核對。 +輸出 SHALL ≤ 6;或以 `npx openspec list` 人工核對。 -#### Scenario: 已有 2 個 active change 時新提案被擋下 +#### Scenario: 已有 6 個 active change 時新提案被擋下 -- **WHEN** active(非 deferred)change 數已達 2 且 agent 欲新建第 3 個 change +- **WHEN** active(非 deferred)change 數已達 6 且 agent 欲新建第 7 個 change - **THEN** agent SHALL 停止新建並回報現有 active 清單與收斂選項(archive/close-out/defer) - **AND** 僅在使用者裁決騰出額度或明文核准暫時超額後才得新建 @@ -81,19 +81,19 @@ git log --since="14 days ago" --oneline origin/main -- ` | `viewer-embed-a1-highlight` | 6/7 [x];僅餘 task 6 follow-up(明文不在本 change) | close-out → archive | follow-up 移 issue 追蹤後 archive | | `minio-trigger-lifecycle-backend` | 5/6 [x];僅餘 task 5 follow-up(明文不在本 change,含 PR #257 系列) | close-out → archive | follow-up 留 issue 對照後 archive | | `minio-watch-key-structure` | 4/5 [x];餘 task 5「P7 部署區 browser E2E」 | 條件式 close-out | 完成 P7 E2E 並附 evidence 後 archive;或使用者明文裁決記為 known gap(不是 pass)後 archive | -| `minio-folderview-and-baseline-disclosure` | 0/7 未動工 | deferred | 重啟條件:active ≤ 2 有額度且需求回到當期優先;重啟時 SHALL 先重驗 main 現況(#259 trigger 端點、watcher ledger)再調和 tasks | -| `align-frontend-design-system-reference` | 0/23 未動工(specs delta 已由 #363 PF-3 調和至 doc-first) | deferred | 重啟條件:active ≤ 2 有額度;重啟時 SHALL 重跑 `openspec validate --strict` 確認 delta 仍對準當時 main spec | +| `minio-folderview-and-baseline-disclosure` | 0/7 未動工 | deferred | 重啟條件:active < 6 有額度且需求回到當期優先;重啟時 SHALL 先重驗 main 現況(#259 trigger 端點、watcher ledger)再調和 tasks | +| `align-frontend-design-system-reference` | 0/23 未動工(specs delta 已由 #363 PF-3 調和至 doc-first) | deferred | 重啟條件:active < 6 有額度,且完成與 successor 的 requirement crosswalk;重啟時 SHALL 重跑 `openspec validate --strict` 確認 delta 仍對準當時 main spec | | `a4-semantic-search-model-qa` | 0/64 未動工(8 節全空) | 留待 OQ-1 裁決 | — | | `rvt-ifc-usdc-lineage` | 1/48(僅 8.1 contract-only) | `Status: deferred`、frozen/non-owner;2026-07-24 historical correction 恢復原 id | 解凍前重驗 current main、完成 predecessor/successor crosswalk 並拆成不重疊 slices | | `migrate-console-to-hifi-design` | tasks 0/35 未勾,但 main #357 已落 1/2 product code | 留待 OQ-1 裁決(建議傾向優先收尾) | 先對帳 tasks.md 勾選與 main 實際落地,再裁 | - **Trigger**:本 change 被使用者採納且 OQ-1 裁決完成。 - **Action**:依本 change tasks §3 逐項執行,每項附最小驗證;deferred 註記由 `deferred-proposed` 改為 `deferred`。 -- **Validation**:全部執行後,R1 之計數指令輸出 SHALL ≤ 2(另加本 change 自身於 archive 前的暫時 +1),且 `npx openspec validate --all --strict` 綠。 +- **Validation**:全部執行後,R1 之計數指令輸出 SHALL ≤ 6(另加本 change 自身於 archive 前的暫時 +1),且 `npx openspec validate --all --strict` 綠。 #### Scenario: 採納後執行收斂使 active 降至上限內 - **WHEN** 使用者採納本 change 並完成 OQ-1 裁決 -- **THEN** 執行收斂動作後 `openspec/changes/` 之 active(非 deferred)change 數 SHALL ≤ 2(不計本 change 自身 archive 前的暫時佔位) +- **THEN** 執行收斂動作後 `openspec/changes/` 之 active(非 deferred)change 數 SHALL ≤ 6(不計本 change 自身 archive 前的暫時佔位) - **AND** 每個被 archive 的 change SHALL 滿足:對應 PR 已 merge、剩餘 follow-up 有 issue 對照或明文 known gap 紀錄 diff --git a/scripts/tests/test-agent-governance-check.ps1 b/scripts/tests/test-agent-governance-check.ps1 index 6a37d14a4..0a9f5dd98 100644 --- a/scripts/tests/test-agent-governance-check.ps1 +++ b/scripts/tests/test-agent-governance-check.ps1 @@ -78,6 +78,9 @@ try { Assert-FileContains '.github/workflows/agent-governance.yml' 'verify-openspec-lifecycle\.ps1' 'agent governance runs OpenSpec lifecycle verification' Assert-FileContains 'openspec/AGENTS.md' 'deferred change 保留在 `openspec/changes//`' 'OpenSpec instructions keep deferred changes outside completed archive' Assert-FileContains 'openspec/AGENTS.md' '--skip-specs.*不是.*deferred state' 'OpenSpec instructions do not treat skip-specs as deferral' + Assert-FileContains 'openspec/specs/governance-throughput-budget/spec.md' 'active OpenSpec change 同時數量 SHALL 不超過 6' 'canonical OpenSpec WIP limit is six' + Assert-FileContains 'scripts/tests/verify-openspec-lifecycle.ps1' '\$wipLimit\s*=\s*6' 'OpenSpec lifecycle verifier enforces the canonical WIP limit' + Assert-FileContains 'docs/plans/NOW.md' '禁止同時推進 >6 個 active OpenSpec product change' 'NOW reflects the canonical OpenSpec WIP limit' foreach ($ownedPath in @('/AGENTS.md', '/docs/agents/', '/docs/plans/', '/.github/', '/scripts/')) { Assert-FileContains '.github/CODEOWNERS' ([regex]::Escape($ownedPath)) "CODEOWNERS covers $ownedPath" } diff --git a/scripts/tests/verify-openspec-lifecycle.ps1 b/scripts/tests/verify-openspec-lifecycle.ps1 index efc3a7ea9..873773f18 100644 --- a/scripts/tests/verify-openspec-lifecycle.ps1 +++ b/scripts/tests/verify-openspec-lifecycle.ps1 @@ -58,6 +58,7 @@ if ([string]::IsNullOrWhiteSpace($RepoRoot)) { $failures = [System.Collections.Generic.List[string]]::new() $warnings = [System.Collections.Generic.List[string]]::new() +$wipLimit = 6 Push-Location $RepoRoot try { @@ -99,8 +100,8 @@ try { } } - if ($nonDeferredChanges.Count -gt 2) { - $warnings.Add("existing non-deferred WIP is $($nonDeferredChanges.Count) > 2: $($nonDeferredChanges -join ', ')") + if ($nonDeferredChanges.Count -gt $wipLimit) { + $warnings.Add("existing non-deferred WIP is $($nonDeferredChanges.Count) > $($wipLimit): $($nonDeferredChanges -join ', ')") } # A deferred marker is never valid in completed archive, including legacy entries. @@ -153,7 +154,7 @@ try { # Historical corrections may add a change path while the repo is already over WIP. # Such additions are safe only when the restored/new change is explicitly deferred. - if ($nonDeferredChanges.Count -gt 2) { + if ($nonDeferredChanges.Count -gt $wipLimit) { foreach ($changeId in $newChangeIds) { if ($changeId -eq 'archive') { continue } $directory = Join-Path $changesRoot $changeId