pomaster 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +393 -396
- package/TRADEMARKS.md +2 -2
- package/catalog/archetypes/archetype.api.error.json +55 -0
- package/catalog/archetypes/archetype.api.pagination.json +68 -0
- package/catalog/archetypes/archetype.api.resource.json +45 -0
- package/catalog/archetypes/archetype.backend.approval_workflow.json +63 -0
- package/catalog/archetypes/archetype.backend.audit.json +44 -0
- package/catalog/archetypes/archetype.backend.crud_resource.json +56 -0
- package/catalog/archetypes/archetype.backend.export.json +40 -0
- package/catalog/archetypes/archetype.backend.external_integration.json +89 -0
- package/catalog/archetypes/archetype.backend.idempotent_command.json +65 -0
- package/catalog/archetypes/archetype.backend.import.json +47 -0
- package/catalog/archetypes/archetype.backend.master_data.json +45 -0
- package/catalog/archetypes/archetype.backend.outbox_event.json +80 -0
- package/catalog/archetypes/archetype.backend.query_resource.json +40 -0
- package/catalog/archetypes/archetype.backend.scheduled_job.json +69 -0
- package/catalog/archetypes/archetype.backend.transactional_write.json +79 -0
- package/catalog/archetypes/archetype.component.button.json +53 -0
- package/catalog/archetypes/archetype.component.data_grid.json +78 -0
- package/catalog/archetypes/archetype.component.dialog.json +52 -0
- package/catalog/archetypes/archetype.component.search_input.json +34 -0
- package/catalog/archetypes/archetype.component.search_select.json +77 -0
- package/catalog/archetypes/archetype.data.hierarchy.json +71 -0
- package/catalog/archetypes/archetype.data.ledger.json +40 -0
- package/catalog/archetypes/archetype.data.master_data.json +43 -0
- package/catalog/archetypes/archetype.data.transaction.json +42 -0
- package/catalog/archetypes/archetype.data.versioned.json +43 -0
- package/catalog/archetypes/archetype.frontend.error_taxonomy.json +99 -0
- package/catalog/archetypes/archetype.frontend.feature_oriented.json +59 -0
- package/catalog/archetypes/archetype.frontend.modular.json +37 -0
- package/catalog/archetypes/archetype.frontend.spa_layered.json +48 -0
- package/catalog/archetypes/archetype.page.analysis.json +39 -0
- package/catalog/archetypes/archetype.page.master_data.json +63 -0
- package/catalog/archetypes/archetype.runtime.environment_parity.json +178 -0
- package/catalog/archetypes/archetype.runtime.observability_binding.json +93 -0
- package/catalog/archetypes/archetype.state.async_command.json +63 -0
- package/catalog/archetypes/archetype.state.background_refresh.json +45 -0
- package/catalog/archetypes/archetype.state.form_edit.json +45 -0
- package/catalog/archetypes/archetype.state.optimistic_mutation.json +48 -0
- package/catalog/archetypes/archetype.state.selection.json +35 -0
- package/catalog/archetypes/archetype.state.server_query.json +60 -0
- package/catalog/archetypes/archetype.state.url_filter.json +47 -0
- package/catalog/archetypes/archetype.state.wizard.json +46 -0
- package/catalog/catalog-lock.draft.json +349 -5
- package/catalog/gates/gate.new-entity.checks.json +106 -0
- package/catalog/knowledge/knowledge.web.browser.mcp_eyes.json +99 -0
- package/catalog/sensors/sensor.browser.deterministic.json +17 -6
- package/catalog/sensors/sensor.browser.interactive.json +16 -6
- package/catalog/tools/materialize_v06_relock.py +218 -0
- package/catalog/tools/seed_v06_archetypes.py +283 -0
- package/catalog/tools/seed_v06_batch2_materials.py +504 -0
- package/catalog/tools/seed_v06_batch3_materials.py +756 -0
- package/catalog/tools/seed_v06_batch4_materials.py +353 -0
- package/dist/bin.js +2920 -331
- package/package.json +1 -1
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
{
|
|
2
|
+
"x-vocab-pr": {
|
|
3
|
+
"status": "vocab_pr_registered__source_type_append_only",
|
|
4
|
+
"finding": "knowledge_entry kind 已在 vocab-lock kinds_registry.truth_bodies;classification=ENGINEERING_PATTERN 是 §83.3 四类型词形(12-knowledge-entry knowledge_kind enum 在册);triggers 是 12-knowledge-entry 既有字段(§83.8 检索键承载);sources[].type=owner_directive 是 Owner 有意词形(Owner 指令 2026-09-03)——暂不在 SOURCE_TYPE_ALL_VALUES 九值来源闭包(packages/schemas/src/vocab.ts),复核确认零机器校验闸拒绝(12-knowledge-entry schema 无 sources/source_type 约束;catalog knowledge 物料无 loader 词形校验;lock 只锁 path+hash——2026-09-03 质检复核实测)",
|
|
5
|
+
"proposal": "vocab PR-0007 收编:source_types 轴 append-only 增值 owner_directive(主 agent 于批次 2.6 收尾处理);收编前本条目零机器闸依赖该词形,词表文件零改动(locked_vocab_untouched)",
|
|
6
|
+
"locked_vocab_untouched": true,
|
|
7
|
+
"resolution": "2026-09-03 vocab PR-0007 收编落地(vocab-lock@v0.6-resolved,三镜像同 commit):source_types 轴 append-only 增值 owner_directive(置于 human_directive 之后,all/allowed 同步增值、forbidden 两值不动)——上记 pending 注记就此转正;finding/proposal/locked_vocab_untouched 为批次 2.6 创建时点历史记录原样保留"
|
|
8
|
+
},
|
|
9
|
+
"x-advisory-gate-semantics": {
|
|
10
|
+
"advisory": true,
|
|
11
|
+
"gate_binding": "NEVER_FAIL",
|
|
12
|
+
"statement": "本条目为 advisory 知识:任何 gate 永不因本条目 FAIL;至多产生 WARN/HINT 或进入 Human Review 议程(§83.2 铁律「Knowledge 不能直接让 Gate FAIL」——knowledge 恒 ADVISORY 永不进 gate 判卷)"
|
|
13
|
+
},
|
|
14
|
+
"x-browser-eyes": {
|
|
15
|
+
"note": "浏览器双眼引导(P-v06 批次 2.6,Owner 指令 2026-09-03):观测与验证两眼分工显式化。架构锚=gauntlet BROWSER 双通道(packages/gauntlet-lite/src/browser-legs.ts BROWSER_LEG_ORDER:Playwright ∥ chrome-devtools MCP,两腿两记录无聚合 verdict)+ Sensor Capability Catalog 双眼登记(catalog/sensors/sensor.browser.interactive.json / sensor.browser.deterministic.json)。",
|
|
16
|
+
"eyes": {
|
|
17
|
+
"observe": "chrome-devtools-mcp=交互观测/诊断面(performance trace / network 瀑布 / console)——诊断『慢/报错/卡住』必须实测(Owner 纪律:禁只看代码推断)",
|
|
18
|
+
"verify": "@playwright/mcp=确定性 E2E smoke/交互验证(判卷锚=@playwright/test 官方 JSONReport 全量重算)"
|
|
19
|
+
},
|
|
20
|
+
"evidence_chain": "两眼产物作为证据链输入(既有消费面,零新增通路):MCP 侧经 browser-adapter 证据三件套(a11y_snapshot/screenshot/performance_trace)入 gauntlet BROWSER 腿 GRN 与 perception OBS receipt;playwright 侧经 playwright-adapter/playwright-leg 官方报告重算入账"
|
|
21
|
+
},
|
|
22
|
+
"id": "KNOWLEDGE.WEB.BROWSER.MCP_EYES",
|
|
23
|
+
"kind": "knowledge_entry",
|
|
24
|
+
"axis_profile": "knowledge_default",
|
|
25
|
+
"classification": "ENGINEERING_PATTERN",
|
|
26
|
+
"axes": {
|
|
27
|
+
"lifecycle": "PROPOSED",
|
|
28
|
+
"confidence": "UNRESOLVED",
|
|
29
|
+
"evidence": "PLANNED",
|
|
30
|
+
"change": "STABLE"
|
|
31
|
+
},
|
|
32
|
+
"title_zh": "浏览器双眼:chrome-devtools MCP 观测 + playwright MCP 验证",
|
|
33
|
+
"statement_zh": "遇到界面『慢/报错/卡住』时,必须用 chrome-devtools MCP 实测诊断(performance trace / network 瀑布 / console 观测,禁只看代码推断——Owner 纪律);需要 E2E smoke 或交互验证时,用 playwright MCP 确定性驱动(与 @playwright/test 官方报告腿同源判卷)。两眼不是替代关系:观测眼回答「实际发生了什么」,验证眼回答「行为是否仍然正确」;两眼产物(快照/截图/trace/console/network 观测/官方报告)都进入 BROWSER 双通道证据链,而不是停留在聊天记录里。",
|
|
34
|
+
"statement_en_keywords": [
|
|
35
|
+
"browser eyes",
|
|
36
|
+
"chrome-devtools mcp",
|
|
37
|
+
"playwright mcp",
|
|
38
|
+
"performance trace",
|
|
39
|
+
"network waterfall",
|
|
40
|
+
"console observation",
|
|
41
|
+
"e2e smoke",
|
|
42
|
+
"evidence chain"
|
|
43
|
+
],
|
|
44
|
+
"triggers": [
|
|
45
|
+
"页面慢",
|
|
46
|
+
"页面报错",
|
|
47
|
+
"页面卡住",
|
|
48
|
+
"慢",
|
|
49
|
+
"报错",
|
|
50
|
+
"卡住",
|
|
51
|
+
"性能追踪",
|
|
52
|
+
"性能诊断",
|
|
53
|
+
"网络瀑布",
|
|
54
|
+
"控制台",
|
|
55
|
+
"console",
|
|
56
|
+
"浏览器验证",
|
|
57
|
+
"浏览器诊断",
|
|
58
|
+
"e2e",
|
|
59
|
+
"smoke",
|
|
60
|
+
"交互验证",
|
|
61
|
+
"browser",
|
|
62
|
+
"chrome-devtools",
|
|
63
|
+
"playwright"
|
|
64
|
+
],
|
|
65
|
+
"applies_when": {
|
|
66
|
+
"lane": "frontend",
|
|
67
|
+
"condition": "浏览器侧诊断与端到端验证(页面慢/报错/卡住的实测诊断;E2E smoke/交互验证取证)",
|
|
68
|
+
"lanes": [
|
|
69
|
+
"frontend"
|
|
70
|
+
],
|
|
71
|
+
"applicability_note": "浏览器侧诊断与端到端验证"
|
|
72
|
+
},
|
|
73
|
+
"enforcement": "advisory",
|
|
74
|
+
"authority": {
|
|
75
|
+
"owner": "HUMAN_OWNER",
|
|
76
|
+
"delegates": [],
|
|
77
|
+
"write_policy": "EVOLUTION_CHANNEL",
|
|
78
|
+
"escalation_hint": "catalog-pilot-human-review"
|
|
79
|
+
},
|
|
80
|
+
"origin": "natural",
|
|
81
|
+
"sources": [
|
|
82
|
+
{
|
|
83
|
+
"type": "owner_directive",
|
|
84
|
+
"ref": "Owner 指令(2026-09-03):vNext 推荐/引导 AI 用 chrome-devtools MCP 与 playwright MCP 构建『眼睛』——chrome-devtools MCP=交互观测/诊断面,playwright MCP=确定性 E2E smoke/交互验证",
|
|
85
|
+
"captured_by": "agent:claude/p-v06-batch2.6-browser-eyes",
|
|
86
|
+
"locator": {
|
|
87
|
+
"section": "P-v06 批次 2.6 Browser Eyes 引导"
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
],
|
|
91
|
+
"review_notes": [
|
|
92
|
+
"ADVISORY 引导条目:只引导不判卷——gate_binding=NEVER_FAIL(§83.2 铁律);能力登记面见 SENSOR.BROWSER.INTERACTIVE / SENSOR.BROWSER.DETERMINISTIC(双眼的能力层),本条目是双眼的经验层引导"
|
|
93
|
+
],
|
|
94
|
+
"review": {
|
|
95
|
+
"disposition": "ACCEPT",
|
|
96
|
+
"seq": "p-v06-batch2.6-0001",
|
|
97
|
+
"ref": "P-v06 批次 2.6 Browser Eyes(Owner 指令 2026-09-03)"
|
|
98
|
+
}
|
|
99
|
+
}
|
|
@@ -8,8 +8,8 @@
|
|
|
8
8
|
},
|
|
9
9
|
"id": "SENSOR.BROWSER.DETERMINISTIC",
|
|
10
10
|
"kind": "sensor_capability",
|
|
11
|
-
"title_zh": "浏览器确定性回归 Sensor(
|
|
12
|
-
"statement_zh": "经 @playwright/test 官方 JSONReport 对用户界面做确定性回归观察:官方报告全量重算 + console/network 双维度完整性强制(缺维=not_run
|
|
11
|
+
"title_zh": "浏览器确定性回归 Sensor(playwright 首选 + MCP 双眼)",
|
|
12
|
+
"statement_zh": "经 @playwright/test 官方 JSONReport 对用户界面做确定性回归观察:官方报告全量重算 + console/network 双维度完整性强制(缺维=not_run)。双眼分工(P-v06 批次 2.6 Browser Eyes):playwright(@playwright/test 官方报告腿)=确定性 E2E smoke/交互验证首选;@playwright/mcp=确定性 smoke 的 MCP 形态;chrome-devtools-mcp=确定性快照/截图取证。与 MCP 交互观测腿互不替代(§6.6)、互不牵连(两腿两记录,无聚合 verdict 位)。",
|
|
13
13
|
"surfaces": [
|
|
14
14
|
"USER_SURFACE",
|
|
15
15
|
"INTERACTION_STATE",
|
|
@@ -33,7 +33,9 @@
|
|
|
33
33
|
"network_observation"
|
|
34
34
|
],
|
|
35
35
|
"implementations": [
|
|
36
|
-
"playwright"
|
|
36
|
+
"playwright",
|
|
37
|
+
"@playwright/mcp",
|
|
38
|
+
"chrome-devtools-mcp"
|
|
37
39
|
],
|
|
38
40
|
"availability_probe": {
|
|
39
41
|
"surface": "toolDetectors",
|
|
@@ -46,8 +48,17 @@
|
|
|
46
48
|
"fallback_note": "空数组=显式登记无降级(§6.6 明言 Browser MCP 与 Playwright 不是互相替代);@playwright/test 缺席 → not_run 显式,禁静默。",
|
|
47
49
|
"x-source-anchors": {
|
|
48
50
|
"adapter": "packages/gauntlet-lite/src/playwright-adapter.ts + playwright-leg.ts(确定性腿:官方 JSONReport 词形解析)",
|
|
49
|
-
"doctor_row": "packages/cli/src/doctor.ts playwright 探针行",
|
|
50
|
-
"detector": "packages/gauntlet-lite/src/index.ts toolDetectors.playwright(15 探测器单一事实源)"
|
|
51
|
+
"doctor_row": "packages/cli/src/doctor.ts playwright 探针行 + playwright_mcp 探针行(P-v06 批次 2.6 同款四态)",
|
|
52
|
+
"detector": "packages/gauntlet-lite/src/index.ts toolDetectors.playwright(15 探测器单一事实源)",
|
|
53
|
+
"eyes_knowledge": "catalog/knowledge/knowledge.web.browser.mcp_eyes.json(KNOWLEDGE.WEB.BROWSER.MCP_EYES——双眼分工的 ADVISORY 检索引导)"
|
|
51
54
|
},
|
|
52
|
-
"x-
|
|
55
|
+
"x-browser-eyes": {
|
|
56
|
+
"note": "浏览器双眼·确定性验证面(P-v06 批次 2.6 Browser Eyes 引导):E2E smoke/交互验证首选 playwright(@playwright/test 官方 JSONReport 全量重算);@playwright/mcp 可跑确定性 smoke 的 MCP 形态;chrome-devtools-mcp 提供确定性快照/截图取证。产物经 playwright-adapter/playwright-leg 官方报告重算入 gauntlet BROWSER 腿 GRN 证据链;与交互观测面(SENSOR.BROWSER.INTERACTIVE)互不替代(§6.6)。",
|
|
57
|
+
"eyes": {
|
|
58
|
+
"verify_first": "playwright(确定性 E2E smoke 首选——官方 JSONReport 全量重算)",
|
|
59
|
+
"verify_mcp": "@playwright/mcp(确定性 smoke 的 MCP 形态)",
|
|
60
|
+
"snapshot": "chrome-devtools-mcp(确定性快照/截图)"
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
"x-prd": "POMaster-vNext-PRD-v0.5.2 §6.5 + §14 P1-5;裁决 8(2026-09-01)D6=A/D7=A;P-v06 批次 2.6 Browser Eyes 双眼显式化(Owner 指令 2026-09-03)"
|
|
53
64
|
}
|
|
@@ -8,8 +8,8 @@
|
|
|
8
8
|
},
|
|
9
9
|
"id": "SENSOR.BROWSER.INTERACTIVE",
|
|
10
10
|
"kind": "sensor_capability",
|
|
11
|
-
"title_zh": "浏览器交互诊断 Sensor(MCP
|
|
12
|
-
"statement_zh": "
|
|
11
|
+
"title_zh": "浏览器交互诊断 Sensor(MCP 双眼·观测面)",
|
|
12
|
+
"statement_zh": "对运行中的用户界面做交互式诊断观察:进入/导航/点击/输入/快照/截图/网络与控制台检查/性能追踪。双眼分工(P-v06 批次 2.6 Browser Eyes):chrome-devtools MCP=交互观测/诊断面(snapshot/network/console/性能 trace——诊断『慢/报错/卡住』必须实测,禁只看代码推断);@playwright/mcp=交互驱动;playwright=库直驱交互。本条目只登记能力不绑定具体工具(§6.5 原则:POMaster reasons about capability / Runtime binds concrete tool——项目 Truth 禁写死 MCP);证据字节由编排方入 evidence pack,本条目为纯能力描述物料(§92.2:Catalog 不是第二套 Project Truth)。",
|
|
13
13
|
"surfaces": [
|
|
14
14
|
"USER_SURFACE",
|
|
15
15
|
"INTERACTION_STATE",
|
|
@@ -38,7 +38,8 @@
|
|
|
38
38
|
],
|
|
39
39
|
"implementations": [
|
|
40
40
|
"chrome-devtools-mcp",
|
|
41
|
-
"playwright"
|
|
41
|
+
"playwright",
|
|
42
|
+
"@playwright/mcp"
|
|
42
43
|
],
|
|
43
44
|
"availability_probe": {
|
|
44
45
|
"surface": "toolDetectors",
|
|
@@ -51,8 +52,17 @@
|
|
|
51
52
|
"fallback_note": "空数组=显式登记无降级(§6.6 明言 Browser MCP 与 Playwright 不是互相替代:MCP 适合探索/交互诊断,Playwright 适合确定性回归);未来 Sensor Resolution(P0.5-4)如需降级语义再扩。",
|
|
52
53
|
"x-source-anchors": {
|
|
53
54
|
"adapter": "packages/gauntlet-lite/src/browser-adapter.ts(MCP 交互腿 adapter:握手 smoke + 证据三件套判卷)",
|
|
54
|
-
"doctor_row": "packages/cli/src/doctor.ts chrome_devtools_mcp 探针行(D22 探测 +
|
|
55
|
-
"detector": "packages/gauntlet-lite/src/index.ts toolDetectors.chromeDevtoolsMcp(15 探测器单一事实源)"
|
|
55
|
+
"doctor_row": "packages/cli/src/doctor.ts chrome_devtools_mcp 探针行(D22 探测 + 一键引导)+ playwright_mcp 探针行(P-v06 批次 2.6 同款四态)",
|
|
56
|
+
"detector": "packages/gauntlet-lite/src/index.ts toolDetectors.chromeDevtoolsMcp(15 探测器单一事实源)",
|
|
57
|
+
"eyes_knowledge": "catalog/knowledge/knowledge.web.browser.mcp_eyes.json(KNOWLEDGE.WEB.BROWSER.MCP_EYES——双眼分工的 ADVISORY 检索引导)"
|
|
56
58
|
},
|
|
57
|
-
"x-
|
|
59
|
+
"x-browser-eyes": {
|
|
60
|
+
"note": "浏览器双眼·交互观测面(P-v06 批次 2.6 Browser Eyes 引导):诊断『慢/报错/卡住』必须 chrome-devtools MCP 实测(performance trace / network / console,禁只看代码推断——Owner 纪律);两眼产物(快照/截图/trace/console/network 观测)经 browser-adapter 证据三件套判卷,作为 gauntlet BROWSER 腿 GRN 与 perception OBS receipt 的证据链输入(既有消费面,本条目不新增通路)。与确定性面(SENSOR.BROWSER.DETERMINISTIC)互不替代(§6.6)。",
|
|
61
|
+
"eyes": {
|
|
62
|
+
"observe": "chrome-devtools-mcp(交互观测/诊断面:snapshot/network/console/性能 trace)",
|
|
63
|
+
"drive": "@playwright/mcp(交互驱动)",
|
|
64
|
+
"library": "playwright(库直驱交互)"
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
"x-prd": "POMaster-vNext-PRD-v0.5.2 §6.5 例文逐字 + §14 P1-5;裁决 8(2026-09-01)D6=A/D7=A;P-v06 批次 2.6 Browser Eyes 双眼显式化(Owner 指令 2026-09-03)"
|
|
58
68
|
}
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""P-v06:catalog 受控节全量重锁工具(批次 1/2 archetypes 分桶先例 → 批次 2.6 扩为全受控节扫描)。
|
|
3
|
+
|
|
4
|
+
职责(沿 materialize_catalog_pilot.py 合并重锁先例——基线零触碰,只做确定性重建;
|
|
5
|
+
语义对齐 kernel relockCatalog(P-v06 批次 2.5):物料字节是身份源,hash 恒重算;
|
|
6
|
+
provenance 是人类可维护的登记位,沿 previous 不重写历史,仅新登记物料给确定性缺省):
|
|
7
|
+
1. 全受控节扫描(archetypes/gates/knowledge/policies/sensors——kernel catalog.ts
|
|
8
|
+
CATALOG_SECTIONS 同名五节闭包)逐文件计算 content_sha256;
|
|
9
|
+
2. source_ref 分桶(历史分桶逻辑保留 + 本批增量):
|
|
10
|
+
- archetypes/*.json → 批次 1/2/3/4 按 id 前缀或精确 id 分桶(seed 工具
|
|
11
|
+
实抓锚,如实到批;批次 3 分桶精确到不失真——CRUD/QUERY/DATA.MASTER_DATA
|
|
12
|
+
仍归批次 1);
|
|
13
|
+
- gates/gate.new-entity.checks.json → 批次 1 relock 判卷定义锚;
|
|
14
|
+
- sensors/sensor.browser.{interactive,deterministic}.json → 批次 2.6 Browser Eyes 锚
|
|
15
|
+
(双眼 implementations 显式化,Owner 指令 2026-09-03);
|
|
16
|
+
- knowledge/knowledge.web.browser.mcp_eyes.json → 批次 2.6 Browser Eyes 锚
|
|
17
|
+
(KNOWLEDGE.WEB.BROWSER.MCP_EYES 新登记,gate_binding=NEVER_FAIL);
|
|
18
|
+
- 其余条目 → 沿 previous 同路径 source_ref(不重写历史);
|
|
19
|
+
previous 无此路径(理论上仅手工删除 lock 段的恢复场景)→ package://catalog/<path>。
|
|
20
|
+
3. lock 全量重锁:entries(按 id 排序)/ controlled_children allowed+required
|
|
21
|
+
(全部扫描路径——加删文件后三方自动对齐);
|
|
22
|
+
4. generated_by 追加批次注记(幂等:已含则不重复追加;批次 1/2/2.6/3/4 各一记,历史留痕)。
|
|
23
|
+
|
|
24
|
+
纪律:content_sha256 = sha256(utf-8 字节)(与 kernel verifyCatalogLock 同一算法,
|
|
25
|
+
producer 与对账端共用同一计算);幂等 byte-stable(DEF-POM-002 教训;A4 无时戳);
|
|
26
|
+
D24——lock 是 read-side 指纹,漂移 WARN+auto-regen 不拦写。
|
|
27
|
+
"""
|
|
28
|
+
import hashlib
|
|
29
|
+
import json
|
|
30
|
+
import os
|
|
31
|
+
import sys
|
|
32
|
+
|
|
33
|
+
try:
|
|
34
|
+
sys.stdout.reconfigure(encoding="utf-8")
|
|
35
|
+
except Exception:
|
|
36
|
+
pass
|
|
37
|
+
|
|
38
|
+
ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) # .../catalog
|
|
39
|
+
LOCK = os.path.join(ROOT, "catalog-lock.draft.json")
|
|
40
|
+
# 受控五节(kernel catalog.ts CATALOG_SECTIONS 同名闭包;tools/candidates/
|
|
41
|
+
# projection-presets 与 lock 自身不在管辖面——verifyCatalogLock 同口径)。
|
|
42
|
+
SECTIONS = ["archetypes", "gates", "knowledge", "policies", "sensors"]
|
|
43
|
+
NEW_GATE = "gates/gate.new-entity.checks.json"
|
|
44
|
+
GENERATED_BY_MARK = "catalog/tools/seed_v06_archetypes.py + materialize_v06_relock.py(P-v06 批次 1:archetypes 十条目 + GATE.NEW_ENTITY.CHECKS 登记,D-2/D-4 裁决)"
|
|
45
|
+
GENERATED_BY_MARK_BATCH2 = "catalog/tools/seed_v06_batch2_materials.py + materialize_v06_relock.py(P-v06 批次 2:STATE_ARCHETYPE 八态 + FRONTEND_ARCHETYPE 三型 + ERROR_TAXONOMY 十二条目,research frontend-state-references.md 2026-09-03 锚)"
|
|
46
|
+
GENERATED_BY_MARK_BATCH26 = "catalog/tools/materialize_v06_relock.py(P-v06 批次 2.6 Browser Eyes:SENSOR.BROWSER.* 双眼 implementations 显式化 + KNOWLEDGE.WEB.BROWSER.MCP_EYES 登记,Owner 指令 2026-09-03)"
|
|
47
|
+
GENERATED_BY_MARK_BATCH3 = "catalog/tools/seed_v06_batch3_materials.py + materialize_v06_relock.py(P-v06 批次 3:Backend/API/Data 原型十七条目,research backend-references.md 2026-09-03 锚)"
|
|
48
|
+
GENERATED_BY_MARK_BATCH4 = "catalog/tools/seed_v06_batch4_materials.py + materialize_v06_relock.py(P-v06 批次 4:RUNTIME 物料两条目 ENVIRONMENT_PARITY/OBSERVABILITY_BINDING,research runtime-references.md 2026-09-03 锚)"
|
|
49
|
+
|
|
50
|
+
# 批次 2 物料 id 前缀(provenance 如实到批:对应 research 报告不同,禁共用批次 1 词面)。
|
|
51
|
+
BATCH2_ID_PREFIXES = ("STATE_ARCHETYPE.", "FRONTEND_ARCHETYPE.")
|
|
52
|
+
SOURCE_REF_BATCH1 = "catalog/tools/seed_v06_archetypes.py(P-v06 批次 1;外部参照 external-design-references.md 2026-09-02 实抓锚)"
|
|
53
|
+
SOURCE_REF_BATCH2 = "catalog/tools/seed_v06_batch2_materials.py(P-v06 批次 2;外部参照 frontend-state-references.md 2026-09-03 实抓锚)"
|
|
54
|
+
|
|
55
|
+
# 批次 3 物料 id 分桶(provenance 如实到批:backend-references.md 2026-09-03 实抓锚)。
|
|
56
|
+
# 分桶精确到不失真:ARCHETYPE.BACKEND.CRUD_RESOURCE/QUERY_RESOURCE 与
|
|
57
|
+
# DATA_ARCHETYPE.MASTER_DATA 仍归批次 1(批次 1 物料,禁被批次 3 前缀吞并——
|
|
58
|
+
# 因此 backend 侧用精确 id 枚举而非 ARCHETYPE.BACKEND. 整段前缀,data 侧用
|
|
59
|
+
# TRANSACTION|VERSIONED|HIERARCHY|LEDGER 四精确 id 而非 DATA_ARCHETYPE. 整段前缀)。
|
|
60
|
+
BATCH3_BACKEND_IDS = (
|
|
61
|
+
"ARCHETYPE.BACKEND.MASTER_DATA",
|
|
62
|
+
"ARCHETYPE.BACKEND.TRANSACTIONAL_WRITE",
|
|
63
|
+
"ARCHETYPE.BACKEND.OUTBOX_EVENT",
|
|
64
|
+
"ARCHETYPE.BACKEND.IDEMPOTENT_COMMAND",
|
|
65
|
+
"ARCHETYPE.BACKEND.SCHEDULED_JOB",
|
|
66
|
+
"ARCHETYPE.BACKEND.EXTERNAL_INTEGRATION",
|
|
67
|
+
"ARCHETYPE.BACKEND.APPROVAL_WORKFLOW",
|
|
68
|
+
"ARCHETYPE.BACKEND.IMPORT",
|
|
69
|
+
"ARCHETYPE.BACKEND.EXPORT",
|
|
70
|
+
"ARCHETYPE.BACKEND.AUDIT",
|
|
71
|
+
)
|
|
72
|
+
BATCH3_API_PREFIX = "ARCHETYPE.API."
|
|
73
|
+
BATCH3_DATA_IDS = (
|
|
74
|
+
"DATA_ARCHETYPE.TRANSACTION",
|
|
75
|
+
"DATA_ARCHETYPE.VERSIONED",
|
|
76
|
+
"DATA_ARCHETYPE.HIERARCHY",
|
|
77
|
+
"DATA_ARCHETYPE.LEDGER",
|
|
78
|
+
)
|
|
79
|
+
SOURCE_REF_BATCH3 = "catalog/tools/seed_v06_batch3_materials.py(P-v06 批次 3;外部参照 backend-references.md 2026-09-03 实抓锚)"
|
|
80
|
+
|
|
81
|
+
# 批次 4 物料 id 分桶(provenance 如实到批:runtime-references.md 2026-09-03 实抓锚)。
|
|
82
|
+
# RUNTIME_ARCHETYPE. 前缀与批次 1/2/3 各桶零交集(批次 1 ARCHETYPE.BACKEND.*/API.*
|
|
83
|
+
# 精确枚举、批次 2 STATE_*/FRONTEND_* 前缀、批次 3 DATA_* 四精确 id)——整段前缀
|
|
84
|
+
# 分桶不吞并历史条目,不失真。
|
|
85
|
+
BATCH4_ID_PREFIXES = ("RUNTIME_ARCHETYPE.",)
|
|
86
|
+
SOURCE_REF_BATCH4 = "catalog/tools/seed_v06_batch4_materials.py(P-v06 批次 4;外部参照 runtime-references.md 2026-09-03 实抓锚)"
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def source_ref_for(entry_id):
|
|
90
|
+
if entry_id.startswith(BATCH4_ID_PREFIXES):
|
|
91
|
+
return SOURCE_REF_BATCH4
|
|
92
|
+
if entry_id in BATCH3_BACKEND_IDS or entry_id.startswith(BATCH3_API_PREFIX) or entry_id in BATCH3_DATA_IDS:
|
|
93
|
+
return SOURCE_REF_BATCH3
|
|
94
|
+
return (
|
|
95
|
+
SOURCE_REF_BATCH2
|
|
96
|
+
if entry_id.startswith(BATCH2_ID_PREFIXES)
|
|
97
|
+
else SOURCE_REF_BATCH1
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
# 批次 2.6 Browser Eyes 改动条目(双眼显式化 + knowledge 新登记;Owner 指令 2026-09-03)。
|
|
101
|
+
BROWSER_EYES_SENSORS = (
|
|
102
|
+
"sensors/sensor.browser.interactive.json",
|
|
103
|
+
"sensors/sensor.browser.deterministic.json",
|
|
104
|
+
)
|
|
105
|
+
BROWSER_EYES_KNOWLEDGE = "knowledge/knowledge.web.browser.mcp_eyes.json"
|
|
106
|
+
SOURCE_REF_BATCH26_SENSORS = (
|
|
107
|
+
"catalog/tools/materialize_v06_relock.py(P-v06 批次 2.6 Browser Eyes:SENSOR.BROWSER.* "
|
|
108
|
+
"双眼 implementations 显式化——chrome-devtools-mcp 观测 + @playwright/mcp 验证;Owner 指令 2026-09-03)"
|
|
109
|
+
)
|
|
110
|
+
SOURCE_REF_BATCH26_KNOWLEDGE = (
|
|
111
|
+
"catalog/tools/materialize_v06_relock.py(P-v06 批次 2.6 Browser Eyes:"
|
|
112
|
+
"KNOWLEDGE.WEB.BROWSER.MCP_EYES 新登记——浏览器双眼 ADVISORY 检索引导,"
|
|
113
|
+
"gate_binding=NEVER_FAIL;Owner 指令 2026-09-03)"
|
|
114
|
+
)
|
|
115
|
+
SOURCE_REF_BATCH26_GATE = "catalog/tools/materialize_v06_relock.py(P-v06 批次 1;v0.6.1 §75/§87 判卷定义锚)"
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def source_ref_for_path(path, body_id, previous_by_path):
|
|
119
|
+
"""本批增量分桶:Browser Eyes 改动条目 → 批次 2.6 锚;archetypes/NEW_GATE →
|
|
120
|
+
批次 1/2/3 既有分桶;其余沿 previous 同路径(provenance 不重写历史)。"""
|
|
121
|
+
if path in BROWSER_EYES_SENSORS:
|
|
122
|
+
return SOURCE_REF_BATCH26_SENSORS
|
|
123
|
+
if path == BROWSER_EYES_KNOWLEDGE:
|
|
124
|
+
return SOURCE_REF_BATCH26_KNOWLEDGE
|
|
125
|
+
if path.startswith("archetypes/"):
|
|
126
|
+
return source_ref_for(body_id)
|
|
127
|
+
if path == NEW_GATE:
|
|
128
|
+
return SOURCE_REF_BATCH26_GATE
|
|
129
|
+
previous = previous_by_path.get(path)
|
|
130
|
+
if previous is not None and previous.get("source_ref"):
|
|
131
|
+
return previous["source_ref"]
|
|
132
|
+
return f"package://catalog/{path}"
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
def sha256_of_file(path):
|
|
136
|
+
with open(path, "rb") as f:
|
|
137
|
+
return "sha256:" + hashlib.sha256(f.read()).hexdigest()
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
def scan_section(section):
|
|
141
|
+
"""扫描单节全部 *.json → (entries, paths)。逐文件读 id(缺 id 显式爆——
|
|
142
|
+
与 kernel relockCatalog 同口径:relock 以物料 id 重建 entries)。"""
|
|
143
|
+
dir_path = os.path.join(ROOT, section)
|
|
144
|
+
entries = []
|
|
145
|
+
paths = []
|
|
146
|
+
if not os.path.isdir(dir_path):
|
|
147
|
+
return entries, paths
|
|
148
|
+
for name in sorted(os.listdir(dir_path)):
|
|
149
|
+
if not name.endswith(".json"):
|
|
150
|
+
continue
|
|
151
|
+
path = f"{section}/{name}"
|
|
152
|
+
full = os.path.join(dir_path, name)
|
|
153
|
+
with open(full, encoding="utf-8") as f:
|
|
154
|
+
body = json.load(f)
|
|
155
|
+
entry_id = body.get("id")
|
|
156
|
+
if not isinstance(entry_id, str) or not entry_id:
|
|
157
|
+
raise SystemExit(f"[relock] catalog 物料缺 id 字段: {path}")
|
|
158
|
+
entries.append(
|
|
159
|
+
{
|
|
160
|
+
"id": entry_id,
|
|
161
|
+
"path": path,
|
|
162
|
+
"content_sha256": sha256_of_file(full),
|
|
163
|
+
}
|
|
164
|
+
)
|
|
165
|
+
paths.append(path)
|
|
166
|
+
return entries, paths
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
def main():
|
|
170
|
+
with open(LOCK, encoding="utf-8") as f:
|
|
171
|
+
lock = json.load(f)
|
|
172
|
+
previous_by_path = {
|
|
173
|
+
e.get("path"): e for e in lock.get("entries", []) if isinstance(e, dict)
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
# 1) 全受控节扫描(hash 恒重算——幂等重锁语义:物料字节是身份源)。
|
|
177
|
+
scanned = []
|
|
178
|
+
scanned_paths = []
|
|
179
|
+
seen_ids = set()
|
|
180
|
+
per_section = {}
|
|
181
|
+
for section in SECTIONS:
|
|
182
|
+
entries, paths = scan_section(section)
|
|
183
|
+
per_section[section] = len(entries)
|
|
184
|
+
for entry in entries:
|
|
185
|
+
if entry["id"] in seen_ids:
|
|
186
|
+
raise SystemExit(f"[relock] catalog 物料 id 跨节重复: {entry['id']}")
|
|
187
|
+
seen_ids.add(entry["id"])
|
|
188
|
+
entry["source_ref"] = source_ref_for_path(
|
|
189
|
+
entry["path"], entry["id"], previous_by_path
|
|
190
|
+
)
|
|
191
|
+
scanned.append(entry)
|
|
192
|
+
scanned_paths.extend(paths)
|
|
193
|
+
scanned.sort(key=lambda e: e["id"])
|
|
194
|
+
scanned_paths.sort()
|
|
195
|
+
|
|
196
|
+
# 2) entries 全量重建 + controlled_children allowed/required 三方对齐
|
|
197
|
+
# (batch-4 split-ledger 纪律;kernel relockCatalog 同口径)。
|
|
198
|
+
lock["entries"] = scanned
|
|
199
|
+
lock["controlled_children"]["allowed"] = list(scanned_paths)
|
|
200
|
+
lock["controlled_children"]["required"] = list(scanned_paths)
|
|
201
|
+
|
|
202
|
+
# 3) generated_by 注记(幂等追加;批次 1/2/2.6/3/4 各一记,历史留痕)。
|
|
203
|
+
for mark in (GENERATED_BY_MARK, GENERATED_BY_MARK_BATCH2, GENERATED_BY_MARK_BATCH26, GENERATED_BY_MARK_BATCH3, GENERATED_BY_MARK_BATCH4):
|
|
204
|
+
if mark not in lock.get("generated_by", ""):
|
|
205
|
+
lock["generated_by"] = lock.get("generated_by", "") + " + " + mark
|
|
206
|
+
|
|
207
|
+
with open(LOCK, "w", encoding="utf-8", newline="\n") as f:
|
|
208
|
+
json.dump(lock, f, ensure_ascii=False, indent=2)
|
|
209
|
+
f.write("\n")
|
|
210
|
+
sections_note = " ".join(f"{k}={v}" for k, v in per_section.items())
|
|
211
|
+
print(
|
|
212
|
+
f"relocked: entries={len(lock['entries'])} allowed={len(lock['controlled_children']['allowed'])} "
|
|
213
|
+
f"required={len(lock['controlled_children']['required'])} ({sections_note})"
|
|
214
|
+
)
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
if __name__ == "__main__":
|
|
218
|
+
main()
|