pomaster 0.5.2 → 0.6.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/dist/bin.js CHANGED
@@ -18526,6 +18526,284 @@ var init_evidence_spec_schema = __esm({
18526
18526
  }
18527
18527
  });
18528
18528
 
18529
+ // packages/schemas/dist/assets/22-design-tokens.schema.json
18530
+ var design_tokens_schema_default;
18531
+ var init_design_tokens_schema = __esm({
18532
+ "packages/schemas/dist/assets/22-design-tokens.schema.json"() {
18533
+ design_tokens_schema_default = {
18534
+ $schema: "http://json-schema.org/draft-07/schema#",
18535
+ $id: "https://pomaster.dev/schemas/design-tokens/v1-draft.json",
18536
+ title: "Design Tokens Contract\uFF08.pomaster/baseline/frontend/design-tokens.yaml \xB7 F-M1 \u6700\u5C0F\u5408\u540C\uFF0C09-10 R3 \u6279\uFF09",
18537
+ description: "Project Baseline \u539F\u6587 \xA716 design-tokens.yaml Contract \u7684\u673A\u5668\u5F62\u6001\uFF1A\u8BED\u4E49 token \u5355\u4E00\u5408\u540C\u9762\uFF08\u989C\u8272/\u5B57\u4F53/\u95F4\u8DDD/\u5706\u89D2/\u9634\u5F71/\u5C42\u7EA7/\u5BC6\u5EA6/\u5E03\u5C40/\u52A8\u6548/\u65AD\u70B9\u4E5D\u7EC4\uFF09\u2014\u2014UI \u53EA\u80FD\u4ECE\u672C\u5408\u540C\u7684\u8BED\u4E49 token \u4E0E\u6279\u51C6\u7EC4\u4EF6\u53D6\u5F97\u89C6\u89C9\u89C4\u5219\uFF0CAgent Context \u6D88\u8D39\u8BED\u4E49 token \u800C\u975E\u88F8\u6570\u503C\uFF08\xA717 \u8BBE\u8BA1\u539F\u5219\uFF09\u3002\n\u8D77\u6B65\u503C\u7EAA\u5F8B\uFF1A\u6570\u503C\u6765\u6E90\u4EC5\u4E24\u7C7B\u2014\u2014POMaster Default Design \u9884\u8BBE\u9ED8\u8BA4\u503C\uFF08origin=preset\uFF0Cadvisory \u6027\u8D28\uFF0COwner \u786E\u8BA4\u524D\u4E0D\u6784\u6210\u9879\u76EE\u4E8B\u5B9E\uFF09\u6216\u7559\u7A7A\uFF08\u8D77\u6B65\u503C UNKNOWN / null\uFF09\u5F85 Owner \u51B3\u7B56\uFF1B\u539F\u6587\u793A\u4F8B\u6570\u503C\u7981\u4F2A\u9020\u6210\u9879\u76EE\u4E8B\u5B9E\uFF08PRD \xA77.1 NON-AUTHORITATIVE\uFF09\u3002\n\u547D\u540D\u6536\u655B\u5B9A\u7A3F\uFF1A\u539F\u6587 \xA716 layout.section_gap vs \xA717 spacing.section_gap \u4E8C\u9009\u4E00\uFF0C\u5B9A\u7A3F = spacing.section_gap\uFF08\u95F4\u8DDD\u8BED\u4E49\u5F52 spacing \u7EC4\uFF1Blayout \u7EC4\u7559\u7ED9\u9875\u9762\u7ED3\u6784\u952E\uFF0C\u65AD\u70B9\u8BED\u4E49\u5F52 breakpoints \u7EC4\uFF09\u2014\u2014\u672C schema \u7684 layout \u7EC4\u952E\u96C6\u4E0D\u542B section_gap\u3002",
18538
+ "x-pomaster-file-role": "22-design-tokens.schema.json \u2014\u2014 Design Token \u5408\u540C\uFF08F-M1 \u6700\u5C0F\u5408\u540C\uFF0C09-10 R3 \u6279\uFF09\u3002\u843D\u76D8\u8F7D\u4F53 .pomaster/baseline/frontend/design-tokens.yaml\uFF08schema \u63CF\u8FF0\u5176 YAML \u540C\u6784\u5F62\u6001\u2014\u2014yaml \u88C5\u8F7D\u7ECF CLI baseline-tokens.ts \u8BFB\u53D6\u540E\u6821\u9A8C\uFF09\uFF1B\u540C\u65F6\u662F B6D \u6279\u64AD\u79CD\u5206\u6BCD\u589E\u91CF\uFF08seeds/manifest.json 26 \u4EF6\uFF09\u4E0E\u786E\u8BA4\u8D44\u4EA7\u6E05\u5355\u7B2C 25 \u6587\u4EF6\uFF08BASELINE_CONFIRM_TARGETS\u2014\u2014confirm digest \u5FEB\u7167/closeout \u6821\u9A8C/preset \u5FEB\u7167\u58F0\u660E\u4E09\u6D88\u8D39\u9762\u540C\u6E90\uFF0Cschema \u6821\u9A8C\u4E0E digest \u786E\u8BA4\u6B63\u4EA4\uFF1Adigest \u9762\u53EA\u770B\u5B57\u8282\uFF0C\u672C schema \u7BA1\u5F62\u72B6\uFF09\u3002",
18539
+ "x-pomaster-vocab-source": "Baseline PRD \u539F\u6587 \xA713-21\uFF08\xA716 \u5206\u7EC4\u9AA8\u67B6\u9010\u5B57 + \xA717 \u547D\u540D\u6536\u655B\u5B9A\u7A3F + \xA719 preset\u2192customize\u2192baseline \u901A\u8DEF + \xA775 UNKNOWN/\u6309\u9700\u589E\u957F\u5408\u6CD5\uFF09\u3002origin \u8BCD\u5F62\u95ED\u5305 preset|customized|owner \u4E3A\u672C\u6587\u4EF6\u672C\u5730\u95ED\u5305\uFF0820-sources-authority \u5F00\u653E\u7EF4\u5EA6\u8BCD\u5148\u4F8B\u540C\u6CD5\u2014\u2014\u96F6\u4E2D\u592E\u8BCD\u8868 PR\uFF1B\u8DE8\u5305\u6D88\u8D39\u65F6\u518D\u8D70\u8BCD\u6C47\u8868 PR \u5E73\u79FB\uFF09\u3002UNKNOWN \u8D77\u6B65\u8BCD\u5F62\u4E0E baseline/stack.yaml \u53F0\u8D26\u540C\u6E90\uFF08B6d \u64AD\u79CD\u7EAA\u5F8B\uFF09\u3002",
18540
+ "x-pomaster-contract": {
18541
+ local_origin_closure: "origin \u4E09\u503C\u672C\u5730\u95ED\u5305\uFF1Apreset\uFF08\u64AD\u79CD\u9AA8\u67B6/\u9884\u8BBE\u9ED8\u8BA4\uFF0Cadvisory\uFF09| customized\uFF08Owner \u5728 preset \u57FA\u7840\u4E0A\u5B9A\u5236\uFF09| owner\uFF08Owner \u5168\u6743\u81EA\u8457\uFF09\u3002meta.customized \u662F\u72EC\u7ACB\u673A\u5668\u4F4D\uFF08\u5E03\u5C14\uFF09\u2014\u2014origin \u8868\u6765\u6E90\uFF0Ccustomized \u8868\u5B9A\u5236\u4E8B\u5B9E\uFF1BP-D1 customize/diff/confirm \u5168\u6D41\u7A0B\uFF08\u542B per-token origin \u5143\u6570\u636E\uFF09\u5728\u540E\u7EED\u63D0\u6848\u6269\u4F4D\uFF0C\u672C\u5408\u540C\u53EA\u51BB\u7ED3 meta \u7EA7\u673A\u5668\u4F4D\u3002",
18542
+ advisory_preset_values: "origin=preset \u7684\u6570\u503C\u662F advisory\uFF08\u975E\u9879\u76EE\u4E8B\u5B9E\uFF09\uFF1A\u786E\u8BA4\uFF08baseline confirm\uFF09\u524D\u4E0D\u6784\u6210\u6743\u5A01\uFF1BP-D1 \u5B8C\u6574\u63D0\u6848\u524D\u672C\u5408\u540C\u4E0D\u5185\u7F6E\u4EFB\u4F55\u9884\u8BBE\u9ED8\u8BA4\u503C\u2014\u2014\u672C\u4ED3\u672A\u767B\u8BB0 POMaster Default Design \u6570\u503C\uFF0C\u64AD\u79CD\u9762\u5168\u53F6 UNKNOWN\u3002",
18543
+ confirm_target: "\u672C\u6587\u4EF6\u662F\u786E\u8BA4\u8D44\u4EA7\u6E05\u5355\u7B2C 25 \u6587\u4EF6\uFF1A\u4FEE\u6539/\u5220\u9664 = BASELINE_DRIFT\uFF08digest \u9762\u68C0\u51FA\uFF0C\u4E0E schema \u5F62\u72B6\u5224\u5377\u6B63\u4EA4\u2014\u2014\u5F62\u72B6\u8FDD\u89C4\u7531\u88C5\u8F7D\u9762 fail-closed \u62D2\u7EDD\uFF0C\u4E0D\u6DF7\u5165 digest \u6BD4\u5BF9\uFF09\u3002",
18544
+ not_governed_object: "\u672C\u5408\u540C\u4E0D\u662F governed object\uFF1A\u4E0D\u8FDB truth-index\u3001\u4E0D\u8D70 store \u4E8B\u52A1\u3001\u65E0 lifecycle/authority.owner \u4FE1\u5C01\u2014\u2014\u8BBE\u8BA1 token \u662F\u9879\u76EE\u5E73\u9762\u586B\u5199\u9762\uFF08\u4E0E 20-sources-authority registry \u540C\u57DF\uFF1A\u9879\u76EE\u53EF\u7F16\u8F91\u3001seed-once \u64AD\u79CD\u3001Owner \u5168\u6743\uFF09\u3002",
18545
+ groups_closed_keys_open: "\u4E5D\u7EC4\u8BCD\u5F62\u4E0E\u7EC4\u5185\u952E\u96C6\u6309 \xA716 \u9AA8\u67B6\u5C01\u95ED\uFF08\u952E\u96C6\u6F02\u79FB\u5373 schema \u5931\u8D25\u2014\u2014\u5355\u4E00\u8BCD\u5F62\u6E90\u7EAA\u5F8B\uFF0C\u4E0E stack.yaml \u952E\u96C6\u540C\u6CD5\uFF09\uFF1Btoken \u589E\u957F\u901A\u9053 = \u663E\u5F0F schema \u4FEE\u8BA2\uFF08\xA775\u300Cgrows only when the project earns the need\u300D\u2014\u2014\u7981 Owner \u5728\u7EC4\u5185\u81EA\u9020\u952E\u7ED5\u8FC7\u8BCD\u5F62\u6E90\uFF09\u3002"
18546
+ },
18547
+ type: "object",
18548
+ additionalProperties: false,
18549
+ required: ["meta"],
18550
+ properties: {
18551
+ meta: {
18552
+ type: "object",
18553
+ additionalProperties: false,
18554
+ required: ["origin", "customized"],
18555
+ properties: {
18556
+ origin: {
18557
+ enum: ["preset", "customized", "owner"],
18558
+ title: "\u6765\u6E90\u673A\u5668\u4F4D\uFF08\u672C\u5730\u4E09\u503C\u95ED\u5305\uFF09",
18559
+ description: "preset = \u64AD\u79CD\u9AA8\u67B6/\u9884\u8BBE\u9ED8\u8BA4\uFF08advisory\u2014\u2014Owner \u786E\u8BA4\u524D\u4E0D\u6784\u6210\u9879\u76EE\u4E8B\u5B9E\uFF09\uFF1Bcustomized = Owner \u5728 preset \u57FA\u7840\u4E0A\u5B9A\u5236\uFF1Bowner = Owner \u5168\u6743\u81EA\u8457\u3002"
18560
+ },
18561
+ customized: {
18562
+ type: "boolean",
18563
+ title: "Owner \u5B9A\u5236\u673A\u5668\u4F4D",
18564
+ description: "true = \u6587\u4EF6\u7ECF Owner \u5B9A\u5236\uFF08P-D1 customize/diff/confirm \u9762\u6D88\u8D39\uFF1B\u4E0E origin \u6B63\u4EA4\u2014\u2014origin \u8868\u6765\u6E90\uFF0Ccustomized \u8868\u5B9A\u5236\u4E8B\u5B9E\uFF09\u3002"
18565
+ }
18566
+ }
18567
+ },
18568
+ color: {
18569
+ $ref: "#/definitions/color_group",
18570
+ title: "\u989C\u8272\u8BED\u4E49 token\uFF08brand/surface/text/border/semantic\uFF09"
18571
+ },
18572
+ typography: {
18573
+ $ref: "#/definitions/typography_group",
18574
+ title: "\u5B57\u4F53\u8BED\u4E49 token\uFF08family/size/weight/line_height\uFF09"
18575
+ },
18576
+ spacing: {
18577
+ $ref: "#/definitions/spacing_group",
18578
+ title: "\u95F4\u8DDD token\uFF08xs..xxl + section_gap\u2014\u2014\u547D\u540D\u6536\u655B\u5B9A\u7A3F\u843D\u4F4D\uFF09"
18579
+ },
18580
+ radius: {
18581
+ $ref: "#/definitions/radius_group",
18582
+ title: "\u5706\u89D2 token\uFF08sm/md/lg\uFF09"
18583
+ },
18584
+ elevation: {
18585
+ $ref: "#/definitions/elevation_group",
18586
+ title: "\u9634\u5F71/\u5C42\u7EA7 token\uFF08card/popover/modal\uFF09"
18587
+ },
18588
+ density: {
18589
+ $ref: "#/definitions/density_group",
18590
+ title: "\u5BC6\u5EA6 token\uFF08\u63A7\u4EF6/\u8868\u683C\u884C\u9AD8\uFF09"
18591
+ },
18592
+ layout: {
18593
+ $ref: "#/definitions/layout_group",
18594
+ title: "\u5E03\u5C40\u7ED3\u6784 token\uFF08\u9875\u9762\u7EA7\uFF1B\u4E0D\u542B section_gap\u2014\u2014\u95F4\u8DDD\u8BED\u4E49\u5F52 spacing \u7EC4\uFF09"
18595
+ },
18596
+ motion: {
18597
+ $ref: "#/definitions/motion_group",
18598
+ title: "\u52A8\u6548\u65F6\u957F token\uFF08fast/normal/slow\uFF09"
18599
+ },
18600
+ breakpoints: {
18601
+ $ref: "#/definitions/breakpoints_group",
18602
+ title: "\u54CD\u5E94\u5F0F\u65AD\u70B9 token\uFF08sm/md/lg/xl\uFF09"
18603
+ }
18604
+ },
18605
+ definitions: {
18606
+ token_value: {
18607
+ description: "\u5355 token \u503C\uFF1A\u8D77\u6B65\u503C UNKNOWN\uFF08\u5B57\u7B26\u4E32\u5360\u4F4D\u2014\u2014\u4E0E baseline/stack.yaml \u540C\u6E90\u8BCD\u5F62\uFF09\u6216 null\uFF08\u7559\u7A7A\uFF09= \u5F85 Owner \u51B3\u7B56\uFF1BOwner \u56DE\u586B\u540E\u4E3A\u975E\u7A7A\u5B57\u7B26\u4E32\uFF08\u5982\u8272\u503C/\u5C3A\u5BF8\u8BCD\u5F62\uFF09\u6216\u6570\u503C\u3002\u793A\u4F8B\u6570\u503C\u7981\u5165\u64AD\u79CD\u9762\uFF08NON-AUTHORITATIVE\uFF09\u3002",
18608
+ anyOf: [
18609
+ {
18610
+ type: "string",
18611
+ minLength: 1,
18612
+ maxLength: 256
18613
+ },
18614
+ {
18615
+ type: "number"
18616
+ },
18617
+ {
18618
+ type: "null"
18619
+ }
18620
+ ]
18621
+ },
18622
+ color_group: {
18623
+ type: "object",
18624
+ additionalProperties: false,
18625
+ properties: {
18626
+ brand: {
18627
+ type: "object",
18628
+ additionalProperties: false,
18629
+ properties: {
18630
+ primary: { $ref: "#/definitions/token_value" },
18631
+ secondary: { $ref: "#/definitions/token_value" }
18632
+ },
18633
+ title: "\u54C1\u724C\u8272\uFF08primary/secondary\uFF09"
18634
+ },
18635
+ surface: {
18636
+ type: "object",
18637
+ additionalProperties: false,
18638
+ properties: {
18639
+ page: { $ref: "#/definitions/token_value" },
18640
+ container: { $ref: "#/definitions/token_value" },
18641
+ elevated: { $ref: "#/definitions/token_value" }
18642
+ },
18643
+ title: "\u8868\u9762\u8272\uFF08page/container/elevated\uFF09"
18644
+ },
18645
+ text: {
18646
+ type: "object",
18647
+ additionalProperties: false,
18648
+ properties: {
18649
+ primary: { $ref: "#/definitions/token_value" },
18650
+ secondary: { $ref: "#/definitions/token_value" },
18651
+ tertiary: { $ref: "#/definitions/token_value" },
18652
+ disabled: { $ref: "#/definitions/token_value" }
18653
+ },
18654
+ title: "\u6587\u672C\u8272\uFF08primary/secondary/tertiary/disabled\uFF09"
18655
+ },
18656
+ border: {
18657
+ type: "object",
18658
+ additionalProperties: false,
18659
+ properties: {
18660
+ default: { $ref: "#/definitions/token_value" },
18661
+ subtle: { $ref: "#/definitions/token_value" },
18662
+ strong: { $ref: "#/definitions/token_value" }
18663
+ },
18664
+ title: "\u8FB9\u6846\u8272\uFF08default/subtle/strong\uFF09"
18665
+ },
18666
+ semantic: {
18667
+ type: "object",
18668
+ additionalProperties: false,
18669
+ properties: {
18670
+ success: { $ref: "#/definitions/token_value" },
18671
+ warning: { $ref: "#/definitions/token_value" },
18672
+ error: { $ref: "#/definitions/token_value" },
18673
+ info: { $ref: "#/definitions/token_value" }
18674
+ },
18675
+ title: "\u8BED\u4E49\u72B6\u6001\u8272\uFF08success/warning/error/info\uFF09"
18676
+ }
18677
+ }
18678
+ },
18679
+ typography_group: {
18680
+ type: "object",
18681
+ additionalProperties: false,
18682
+ properties: {
18683
+ family: {
18684
+ type: "object",
18685
+ additionalProperties: false,
18686
+ properties: {
18687
+ sans: { $ref: "#/definitions/token_value" },
18688
+ mono: { $ref: "#/definitions/token_value" }
18689
+ },
18690
+ title: "\u5B57\u4F53\u65CF\uFF08sans/mono\uFF09"
18691
+ },
18692
+ size: {
18693
+ type: "object",
18694
+ additionalProperties: false,
18695
+ properties: {
18696
+ caption: { $ref: "#/definitions/token_value" },
18697
+ body: { $ref: "#/definitions/token_value" },
18698
+ body_large: { $ref: "#/definitions/token_value" },
18699
+ title_small: { $ref: "#/definitions/token_value" },
18700
+ title_medium: { $ref: "#/definitions/token_value" },
18701
+ title_large: { $ref: "#/definitions/token_value" }
18702
+ },
18703
+ title: "\u5B57\u53F7\uFF08caption/body/body_large/title_small/title_medium/title_large\uFF09"
18704
+ },
18705
+ weight: {
18706
+ type: "object",
18707
+ additionalProperties: false,
18708
+ properties: {
18709
+ regular: { $ref: "#/definitions/token_value" },
18710
+ medium: { $ref: "#/definitions/token_value" },
18711
+ semibold: { $ref: "#/definitions/token_value" }
18712
+ },
18713
+ title: "\u5B57\u91CD\uFF08regular/medium/semibold\uFF09"
18714
+ },
18715
+ line_height: {
18716
+ type: "object",
18717
+ additionalProperties: false,
18718
+ properties: {
18719
+ compact: { $ref: "#/definitions/token_value" },
18720
+ normal: { $ref: "#/definitions/token_value" },
18721
+ relaxed: { $ref: "#/definitions/token_value" }
18722
+ },
18723
+ title: "\u884C\u9AD8\uFF08compact/normal/relaxed\uFF09"
18724
+ }
18725
+ }
18726
+ },
18727
+ spacing_group: {
18728
+ type: "object",
18729
+ additionalProperties: false,
18730
+ properties: {
18731
+ xs: { $ref: "#/definitions/token_value" },
18732
+ sm: { $ref: "#/definitions/token_value" },
18733
+ md: { $ref: "#/definitions/token_value" },
18734
+ lg: { $ref: "#/definitions/token_value" },
18735
+ xl: { $ref: "#/definitions/token_value" },
18736
+ xxl: { $ref: "#/definitions/token_value" },
18737
+ section_gap: {
18738
+ $ref: "#/definitions/token_value",
18739
+ title: "\u8282\u95F4\u8DDD\uFF08\u547D\u540D\u6536\u655B\u5B9A\u7A3F\uFF1A\u539F\u6587 \xA717 spacing.section_gap \u9010\u5B57\uFF1B\xA716 layout.section_gap \u5E9F\u5F03\uFF09",
18740
+ description: "\u95F4\u8DDD\u8BED\u4E49\u5F52 spacing \u7EC4\uFF08\xA717 \u8BED\u4E49 token \u5148\u4F8B\uFF09\uFF1Blayout \u7EC4\u4E0D\u627F\u8F7D\u672C\u952E\u3002"
18741
+ }
18742
+ }
18743
+ },
18744
+ radius_group: {
18745
+ type: "object",
18746
+ additionalProperties: false,
18747
+ properties: {
18748
+ sm: { $ref: "#/definitions/token_value" },
18749
+ md: { $ref: "#/definitions/token_value" },
18750
+ lg: { $ref: "#/definitions/token_value" }
18751
+ }
18752
+ },
18753
+ elevation_group: {
18754
+ type: "object",
18755
+ additionalProperties: false,
18756
+ properties: {
18757
+ card: { $ref: "#/definitions/token_value" },
18758
+ popover: { $ref: "#/definitions/token_value" },
18759
+ modal: { $ref: "#/definitions/token_value" }
18760
+ }
18761
+ },
18762
+ density_group: {
18763
+ type: "object",
18764
+ additionalProperties: false,
18765
+ properties: {
18766
+ control_height: { $ref: "#/definitions/token_value" },
18767
+ compact_control_height: { $ref: "#/definitions/token_value" },
18768
+ table_row_height: { $ref: "#/definitions/token_value" },
18769
+ compact_table_row_height: { $ref: "#/definitions/token_value" }
18770
+ }
18771
+ },
18772
+ layout_group: {
18773
+ type: "object",
18774
+ additionalProperties: false,
18775
+ properties: {
18776
+ page_padding: { $ref: "#/definitions/token_value" },
18777
+ content_max_width: { $ref: "#/definitions/token_value" },
18778
+ sidebar_width: { $ref: "#/definitions/token_value" },
18779
+ header_height: { $ref: "#/definitions/token_value" }
18780
+ },
18781
+ title: "\u5E03\u5C40\u7ED3\u6784\u952E\uFF08page_padding/content_max_width/sidebar_width/header_height\u2014\u2014\xA716 \u952E\u96C6\u51CF section_gap\uFF09"
18782
+ },
18783
+ motion_group: {
18784
+ type: "object",
18785
+ additionalProperties: false,
18786
+ properties: {
18787
+ fast: { $ref: "#/definitions/token_value" },
18788
+ normal: { $ref: "#/definitions/token_value" },
18789
+ slow: { $ref: "#/definitions/token_value" }
18790
+ }
18791
+ },
18792
+ breakpoints_group: {
18793
+ type: "object",
18794
+ additionalProperties: false,
18795
+ properties: {
18796
+ sm: { $ref: "#/definitions/token_value" },
18797
+ md: { $ref: "#/definitions/token_value" },
18798
+ lg: { $ref: "#/definitions/token_value" },
18799
+ xl: { $ref: "#/definitions/token_value" }
18800
+ }
18801
+ }
18802
+ }
18803
+ };
18804
+ }
18805
+ });
18806
+
18529
18807
  // packages/schemas/dist/src/vocab.js
18530
18808
  var IR_SCHEMA_DIALECT, LIFECYCLE_VALUES, CONFIDENCE_VALUES, EVIDENCE_VALUES, CHANGE_VALUES, LIFECYCLE_TRANSITIONS, SOURCE_TYPE_ALL_VALUES, SOURCE_TYPE_FORBIDDEN_VALUES, GOVERNED_ID_PREFIXES, ALIASES_V0, TRUTH_BODY_KINDS, CATALOG_ENFORCEMENT_VALUES, CATALOG_CLASSIFICATION_VALUES, CATALOG_LANE_VALUES, CATALOG_CHANGE_CLASS_VALUES, CATALOG_GOVERNANCE_PROFILE_VALUES, RECONCILE_DELTA_KINDS, VERDICT_VALUES, ORIGIN_VALUES, VERIFICATION_VERDICT_VALUES, PRODUCER_KIND_VALUES, ACTOR_TYPE_VALUES, RUN_TRIGGER_VALUES, DENOMINATOR_STATUS_VALUES, DISCOVERY_CHAIN_VALUES, DISCOVERY_CHAIN_TRANSITIONS, DISCOVERY_PROMOTION_BASIS_VALUES, BLUEPRINT_ENVELOPE_STATUS_VALUES, RESEARCH_FINDING_CONFIDENCE_VALUES, RESEARCH_EVIDENCE_LEVEL_VALUES, RESEARCH_AUTHORITY_EFFECT_VALUES, RESEARCH_MODE_VALUES, EXCEPTION_CLASSIFICATION_VALUES, KNOWLEDGE_KIND_VALUES, KNOWLEDGE_STATUS_VALUES, KNOWLEDGE_TRANSITIONS, KNOWLEDGE_PROMOTION_AUTHORITY_VALUES, KNOWLEDGE_CONFIDENCE_VALUES, EXECUTION_RUNTIME_VALUES, EXECUTION_IDENTITY_KIND_VALUES, EXECUTION_ROLE_VALUES, LOCK_KIND_VALUES, AGENT_ROLE_POOL_VALUES, RUNTIME_CAPABILITY_VALUES, RUNTIME_DEGRADATION_RULE_IDS, WORD_FORM_DOMAIN_VALUES, EQUIVALENCE_STATUS_VALUES, PORTABILITY_CANONICAL_SET_VALUES, PORTABILITY_RUNTIME_REBUILD_VALUES, PORTABILITY_FORBIDDEN_DEPENDENCY_VALUES, MEMORY_DRIFT, HARVEST_BUCKET_VALUES, HARVEST_PRIMARY_BUCKETS, HARVEST_SPECIAL_EXIT_VALUES, MEMORY_CLASS_VALUES, REVIEW_STATE_VALUES, HARVEST_SOURCE_VALUES, HARVEST_CONFIDENCE_VALUES, MEMORY_CLI_ERROR_VALUES, OWNER_ESCALATION_REQUIRED, PHASE_TIMELINE_VALUES, PRODUCTION_SIGNAL_SOURCE_VALUES, DIAGNOSIS_KIND_VALUES, BAND_PREDICATE_OPERATOR_VALUES, CONTROL_BAND_EVALUATION_STATUS_VALUES, CAPABILITY_OUTCOME_METRIC_STATUS_VALUES, CAPABILITY_OUTCOME_METRIC_KEY_VALUES, SELF_IMPROVEMENT_SIGNAL_VALUES, SELF_IMPROVEMENT_SIGNAL_PRD_LABELS, POMASTER_SELF_IMPROVEMENT_CANDIDATE, DETECTED_BY_TOOL_SIGNAL, PRODUCTION_CLI_ERROR_VALUES, RELATION_TYPE_VALUES, RELATION_ORIGIN_VALUES, RELATION_ENDPOINT_DOMAIN_VALUES, RELATION_CONFIDENCE_VALUES, SUBSTRATE_LAYER_VALUES, RESOLUTION_MATCH_CLASS_VALUES, OBJECT_FAMILY_VALUES, CATALOG_KIND_VALUES;
18531
18809
  var init_vocab = __esm({
@@ -19059,7 +19337,7 @@ function performanceBudgetPropertyNames() {
19059
19337
  }
19060
19338
  return Object.keys(properties).sort();
19061
19339
  }
19062
- var TRUTH_INDEX_ID, OBJECT_ENVELOPE_ID, GATE_RESULT_ID, KEYBINDING_ID, DENOMINATOR_ID, PRODUCER_ID, EVIDENCE_RECORDS_ID, DISCOVERY_STATE_CHAIN_ID, MSD_UNCERTAINTY_ID, RESEARCH_ARTIFACT_ID, EXCEPTION_LEDGER_ID, KNOWLEDGE_ENTRY_ID, EQUIVALENCE_REGISTRY_ID, MEMORY_HARVEST_ID, PRODUCTION_BAND_ID, EXECUTION_TRACE_ID, PERCEPTION_RECEIPTS_ID, DECISION_GRAPH_ID, SOFTWARE_GRAPH_RELATIONS_ID, SOURCES_AUTHORITY_ID, EVIDENCE_SPEC_ID, truthIndexSchema, objectEnvelopeSchema, gateResultSchema, keybindingSchema, denominatorSchema, producerSchema, evidenceRecordsSchema, discoveryStateChainSchema, msdUncertaintySchema, researchArtifactSchema, exceptionLedgerSchema, knowledgeEntrySchema, equivalenceRegistrySchema, memoryHarvestSchema, productionBandSchema, executionTraceSchema, perceptionReceiptsSchema, decisionGraphSchema, softwareGraphRelationsSchema, sourcesAuthoritySchema, evidenceSpecSchema, allSchemas, performanceBudgetDefinition, PERFORMANCE_BUDGET_FIELDS;
19340
+ var TRUTH_INDEX_ID, OBJECT_ENVELOPE_ID, GATE_RESULT_ID, KEYBINDING_ID, DENOMINATOR_ID, PRODUCER_ID, EVIDENCE_RECORDS_ID, DISCOVERY_STATE_CHAIN_ID, MSD_UNCERTAINTY_ID, RESEARCH_ARTIFACT_ID, EXCEPTION_LEDGER_ID, KNOWLEDGE_ENTRY_ID, EQUIVALENCE_REGISTRY_ID, MEMORY_HARVEST_ID, PRODUCTION_BAND_ID, EXECUTION_TRACE_ID, PERCEPTION_RECEIPTS_ID, DECISION_GRAPH_ID, SOFTWARE_GRAPH_RELATIONS_ID, SOURCES_AUTHORITY_ID, EVIDENCE_SPEC_ID, DESIGN_TOKENS_ID, truthIndexSchema, objectEnvelopeSchema, gateResultSchema, keybindingSchema, denominatorSchema, producerSchema, evidenceRecordsSchema, discoveryStateChainSchema, msdUncertaintySchema, researchArtifactSchema, exceptionLedgerSchema, knowledgeEntrySchema, equivalenceRegistrySchema, memoryHarvestSchema, productionBandSchema, executionTraceSchema, perceptionReceiptsSchema, decisionGraphSchema, softwareGraphRelationsSchema, sourcesAuthoritySchema, evidenceSpecSchema, designTokensSchema, allSchemas, performanceBudgetDefinition, PERFORMANCE_BUDGET_FIELDS;
19063
19341
  var init_src = __esm({
19064
19342
  "packages/schemas/dist/src/index.js"() {
19065
19343
  "use strict";
@@ -19084,6 +19362,7 @@ var init_src = __esm({
19084
19362
  init_software_graph_relations_schema();
19085
19363
  init_sources_authority_schema();
19086
19364
  init_evidence_spec_schema();
19365
+ init_design_tokens_schema();
19087
19366
  init_vocab();
19088
19367
  TRUTH_INDEX_ID = "https://pomaster.dev/schemas/truth-index/v1-draft.json";
19089
19368
  OBJECT_ENVELOPE_ID = "https://pomaster.dev/schemas/object-envelope/v1-draft.json";
@@ -19106,6 +19385,7 @@ var init_src = __esm({
19106
19385
  SOFTWARE_GRAPH_RELATIONS_ID = "https://pomaster.dev/schemas/software-graph-relations/v1-draft.json";
19107
19386
  SOURCES_AUTHORITY_ID = "https://pomaster.dev/schemas/sources-authority/v1-draft.json";
19108
19387
  EVIDENCE_SPEC_ID = "https://pomaster.dev/schemas/evidence-spec/v1-draft.json";
19388
+ DESIGN_TOKENS_ID = "https://pomaster.dev/schemas/design-tokens/v1-draft.json";
19109
19389
  truthIndexSchema = asSchema(truth_index_schema_default, TRUTH_INDEX_ID);
19110
19390
  objectEnvelopeSchema = asSchema(object_envelope_schema_default, OBJECT_ENVELOPE_ID);
19111
19391
  gateResultSchema = asSchema(gate_result_schema_default, GATE_RESULT_ID);
@@ -19127,6 +19407,7 @@ var init_src = __esm({
19127
19407
  softwareGraphRelationsSchema = asSchema(software_graph_relations_schema_default, SOFTWARE_GRAPH_RELATIONS_ID);
19128
19408
  sourcesAuthoritySchema = asSchema(sources_authority_schema_default, SOURCES_AUTHORITY_ID);
19129
19409
  evidenceSpecSchema = asSchema(evidence_spec_schema_default, EVIDENCE_SPEC_ID);
19410
+ designTokensSchema = asSchema(design_tokens_schema_default, DESIGN_TOKENS_ID);
19130
19411
  allSchemas = {
19131
19412
  truthIndex: truthIndexSchema,
19132
19413
  objectEnvelope: objectEnvelopeSchema,
@@ -19148,7 +19429,8 @@ var init_src = __esm({
19148
19429
  decisionGraph: decisionGraphSchema,
19149
19430
  softwareGraphRelations: softwareGraphRelationsSchema,
19150
19431
  sourcesAuthority: sourcesAuthoritySchema,
19151
- evidenceSpec: evidenceSpecSchema
19432
+ evidenceSpec: evidenceSpecSchema,
19433
+ designTokens: designTokensSchema
19152
19434
  };
19153
19435
  performanceBudgetDefinition = definitionOf(objectEnvelopeSchema, "PerformanceBudget");
19154
19436
  PERFORMANCE_BUDGET_FIELDS = performanceBudgetPropertyNames();
@@ -24576,7 +24858,7 @@ function assertAuthorityBoundaries(paths, raw, tx) {
24576
24858
  }
24577
24859
  }
24578
24860
  if (denies.length > 0) {
24579
- throw new GovernanceError("AUTHORITY_BOUNDARY_DENY", `\u6743\u5A01\u7EF4\u5EA6\u95F8\u963B\u65AD\uFF08D-4\uFF09\uFF1A\u672C\u4E8B\u52A1\u5B58\u5728\u975E\u6743\u5A01\u6765\u6E90\u9A71\u52A8\u7684\u89E6\u53CA\u7EF4\u5EA6\u2014\u2014${denies.length} \u9879\u8D8A\u754C\uFF1A${denies.join("\uFF1B")}`, "\u6539\u7531\u5BF9\u8BE5\u7EF4\u5EA6 authoritative \u7684\u6765\u6E90\u9A71\u52A8\u672C\u53D8\u66F4\uFF08sources/index.yaml \u53CC\u8F74\u7533\u62A5\uFF09\uFF1B\u6216\u7531 Owner \u4FEE\u8BA2 authority.json map/boundary_rules \u7684\u7EF4\u5EA6\u5F52\u5C5E\uFF08\u63A8\u7FFB\u8FB9\u754C=Owner \u88C1\u5B9A\uFF0C\u7559\u75D5 owner-adjudications \u53F0\u8D26\uFF09\u3002\u672C\u4E8B\u52A1\u96F6\u843D\u76D8\u3002", {
24861
+ throw new GovernanceError("AUTHORITY_BOUNDARY_DENY", `\u6743\u5A01\u7EF4\u5EA6\u95F8\u963B\u65AD\uFF08D-4\uFF09\uFF1A\u672C\u4E8B\u52A1\u5B58\u5728\u975E\u6743\u5A01\u6765\u6E90\u9A71\u52A8\u7684\u89E6\u53CA\u7EF4\u5EA6\u2014\u2014${denies.length} \u9879\u8D8A\u754C\uFF1A${denies.join("\uFF1B")}`, "\u6539\u7531\u5BF9\u8BE5\u7EF4\u5EA6 authoritative \u7684\u6765\u6E90\u9A71\u52A8\u672C\u53D8\u66F4\uFF08sources/index.yaml \u53CC\u8F74\u7533\u62A5\uFF09\uFF1B\u6216\u7531 Owner \u4FEE\u8BA2 authority.json map/boundary_rules \u7684\u7EF4\u5EA6\u5F52\u5C5E\uFF08\u63A8\u7FFB\u8FB9\u754C=Owner \u88C1\u5B9A\uFF1B\u7559\u75D5\u4F4D\u7F6E\u7531 Owner \u58F0\u660E\u2014\u2014\u4EA7\u54C1\u4ED3 corpus/master/cutover/owner-adjudications.md \u53F0\u8D26\uFF08\u96F6\u7A0B\u5E8F\u8BFB\u5199\uFF09\u6216\u6D88\u8D39\u9879\u76EE\u5185 Owner \u81EA\u9009\u7559\u75D5\u5904\uFF09\u3002\u672C\u4E8B\u52A1\u96F6\u843D\u76D8\u3002", {
24580
24862
  denies,
24581
24863
  boundary_rules_deny: faces.boundary_rules.filter((rule) => rule.effect === "deny").length,
24582
24864
  sources_registry_present: registry !== null
@@ -37116,7 +37398,7 @@ var init_adapter_types = __esm({
37116
37398
  });
37117
37399
 
37118
37400
  // packages/gauntlet-lite/dist/detectors.js
37119
- import { statSync as statSync4, readFileSync as readFileSync12 } from "node:fs";
37401
+ import { statSync as statSync4, readFileSync as readFileSync13 } from "node:fs";
37120
37402
  import { join as pathJoin } from "node:path";
37121
37403
  function platformDetectorFacts(projectRoot) {
37122
37404
  const isWindows = process.platform === "win32";
@@ -37135,7 +37417,7 @@ function platformDetectorFacts(projectRoot) {
37135
37417
  },
37136
37418
  readTextFile: (absolutePath) => {
37137
37419
  try {
37138
- return readFileSync12(absolutePath, "utf8");
37420
+ return readFileSync13(absolutePath, "utf8");
37139
37421
  } catch {
37140
37422
  return null;
37141
37423
  }
@@ -37786,7 +38068,7 @@ var init_normalize_common = __esm({
37786
38068
 
37787
38069
  // packages/gauntlet-lite/dist/pytest-leg.js
37788
38070
  import { spawnSync as spawnSync2 } from "node:child_process";
37789
- import { mkdtempSync, readFileSync as readFileSync13, rmSync as rmSync4 } from "node:fs";
38071
+ import { mkdtempSync, readFileSync as readFileSync14, rmSync as rmSync5 } from "node:fs";
37790
38072
  import { tmpdir } from "node:os";
37791
38073
  import { join as join9 } from "node:path";
37792
38074
  import { performance as performance2 } from "node:perf_hooks";
@@ -37824,11 +38106,11 @@ function runPytestLeg(plan, spawnFn = pytestSpawn) {
37824
38106
  let stdout = run.stdout;
37825
38107
  if (reportDir !== null) {
37826
38108
  try {
37827
- stdout = readFileSync13(join9(reportDir, "junit.xml"), "utf8");
38109
+ stdout = readFileSync14(join9(reportDir, "junit.xml"), "utf8");
37828
38110
  } catch {
37829
38111
  }
37830
38112
  try {
37831
- rmSync4(reportDir, { recursive: true, force: true });
38113
+ rmSync5(reportDir, { recursive: true, force: true });
37832
38114
  } catch {
37833
38115
  }
37834
38116
  }
@@ -38894,7 +39176,7 @@ var init_browser_adapter = __esm({
38894
39176
 
38895
39177
  // packages/gauntlet-lite/dist/playwright-leg.js
38896
39178
  import { spawnSync as spawnSync5 } from "node:child_process";
38897
- import { existsSync as existsSync12, readFileSync as readFileSync14, rmSync as rmSync5 } from "node:fs";
39179
+ import { existsSync as existsSync13, readFileSync as readFileSync15, rmSync as rmSync6 } from "node:fs";
38898
39180
  import { isAbsolute as pathIsAbsolute, join as pathJoin2, relative as pathRelative, resolve as pathResolve } from "node:path";
38899
39181
  import { performance as performance5 } from "node:perf_hooks";
38900
39182
  function isPlainObject2(value) {
@@ -39035,10 +39317,10 @@ function runPlaywrightLeg(plan, spawnFn = playwrightSpawn, executableProbe = pla
39035
39317
  };
39036
39318
  }
39037
39319
  try {
39038
- rmSync5(reportAbs, { force: true });
39320
+ rmSync6(reportAbs, { force: true });
39039
39321
  } catch {
39040
39322
  }
39041
- if (existsSync12(reportAbs)) {
39323
+ if (existsSync13(reportAbs)) {
39042
39324
  return {
39043
39325
  plan,
39044
39326
  kind: "pre_run_failed",
@@ -39057,7 +39339,7 @@ function runPlaywrightLeg(plan, spawnFn = playwrightSpawn, executableProbe = pla
39057
39339
  });
39058
39340
  let reportText = null;
39059
39341
  try {
39060
- reportText = readFileSync14(reportAbs, "utf8");
39342
+ reportText = readFileSync15(reportAbs, "utf8");
39061
39343
  } catch {
39062
39344
  reportText = null;
39063
39345
  }
@@ -40049,7 +40331,7 @@ var init_oasdiff_leg = __esm({
40049
40331
 
40050
40332
  // packages/gauntlet-lite/dist/schemathesis-leg.js
40051
40333
  import { spawnSync as spawnSync7 } from "node:child_process";
40052
- import { existsSync as existsSync13, readFileSync as readFileSync15, rmSync as rmSync6 } from "node:fs";
40334
+ import { existsSync as existsSync14, readFileSync as readFileSync16, rmSync as rmSync7 } from "node:fs";
40053
40335
  import { isAbsolute as pathIsAbsolute2, join as pathJoin3, relative as pathRelative2, resolve as pathResolve2 } from "node:path";
40054
40336
  import { performance as performance8 } from "node:perf_hooks";
40055
40337
  function pathEscapesProjectRoot2(projectRoot, absolutePath) {
@@ -40114,10 +40396,10 @@ function runSchemathesisLeg(plan, spawnFn = schemathesisSpawn, executableProbe =
40114
40396
  };
40115
40397
  }
40116
40398
  try {
40117
- rmSync6(reportAbs, { force: true });
40399
+ rmSync7(reportAbs, { force: true });
40118
40400
  } catch {
40119
40401
  }
40120
- if (existsSync13(reportAbs)) {
40402
+ if (existsSync14(reportAbs)) {
40121
40403
  return {
40122
40404
  plan,
40123
40405
  kind: "pre_run_failed",
@@ -40136,7 +40418,7 @@ function runSchemathesisLeg(plan, spawnFn = schemathesisSpawn, executableProbe =
40136
40418
  });
40137
40419
  let reportText = null;
40138
40420
  try {
40139
- reportText = readFileSync15(reportAbs, "utf8");
40421
+ reportText = readFileSync16(reportAbs, "utf8");
40140
40422
  } catch {
40141
40423
  reportText = null;
40142
40424
  }
@@ -40443,7 +40725,7 @@ var init_schemathesis_leg = __esm({
40443
40725
  });
40444
40726
 
40445
40727
  // packages/gauntlet-lite/dist/contract-adapter.js
40446
- import { readFileSync as readFileSync16 } from "node:fs";
40728
+ import { readFileSync as readFileSync17 } from "node:fs";
40447
40729
  import { join as pathJoin4 } from "node:path";
40448
40730
  import { performance as performance9 } from "node:perf_hooks";
40449
40731
  function readContractConfig(facts) {
@@ -40817,7 +41099,7 @@ function createContractAdapter(options = {}) {
40817
41099
  }
40818
41100
  let text;
40819
41101
  try {
40820
- text = readFileSync16(pathJoin4(plan.projectRoot, plan.openapiPath ?? ""), "utf8");
41102
+ text = readFileSync17(pathJoin4(plan.projectRoot, plan.openapiPath ?? ""), "utf8");
40821
41103
  } catch {
40822
41104
  return {
40823
41105
  plan,
@@ -41350,7 +41632,7 @@ var init_import_linter_leg = __esm({
41350
41632
  });
41351
41633
 
41352
41634
  // packages/gauntlet-lite/dist/architecture-adapter.js
41353
- import { readdirSync as readdirSync18, readFileSync as readFileSync17 } from "node:fs";
41635
+ import { readdirSync as readdirSync18, readFileSync as readFileSync18 } from "node:fs";
41354
41636
  import { join as pathJoin5, sep as pathSep } from "node:path";
41355
41637
  import { performance as performance12 } from "node:perf_hooks";
41356
41638
  function readArchitectureConfig(facts) {
@@ -41742,7 +42024,7 @@ function createArchitectureAdapter(options = {}) {
41742
42024
  filesCovered++;
41743
42025
  let text;
41744
42026
  try {
41745
- text = readFileSync17(pathJoin5(plan.projectRoot, relative3), "utf8");
42027
+ text = readFileSync18(pathJoin5(plan.projectRoot, relative3), "utf8");
41746
42028
  } catch {
41747
42029
  continue;
41748
42030
  }
@@ -41885,7 +42167,7 @@ var init_architecture_adapter = __esm({
41885
42167
 
41886
42168
  // packages/gauntlet-lite/dist/coverage-leg.js
41887
42169
  import { spawnSync as spawnSync10 } from "node:child_process";
41888
- import { existsSync as existsSync14, readFileSync as readFileSync18, rmSync as rmSync7 } from "node:fs";
42170
+ import { existsSync as existsSync15, readFileSync as readFileSync19, rmSync as rmSync8 } from "node:fs";
41889
42171
  import { join as pathJoin6, dirname as pathDirname, isAbsolute as pathIsAbsolute3, relative as pathRelative3, resolve as pathResolve3 } from "node:path";
41890
42172
  import { performance as performance13 } from "node:perf_hooks";
41891
42173
  function resolveCoverageProvisionalThresholdsForTier(tier) {
@@ -41946,10 +42228,10 @@ function runCoverageLeg(plan, spawnFn = coverageSpawn, executableProbe = platfor
41946
42228
  };
41947
42229
  }
41948
42230
  try {
41949
- rmSync7(reportAbs, { force: true });
42231
+ rmSync8(reportAbs, { force: true });
41950
42232
  } catch {
41951
42233
  }
41952
- if (existsSync14(reportAbs)) {
42234
+ if (existsSync15(reportAbs)) {
41953
42235
  return {
41954
42236
  plan,
41955
42237
  kind: "pre_run_failed",
@@ -41969,7 +42251,7 @@ function runCoverageLeg(plan, spawnFn = coverageSpawn, executableProbe = platfor
41969
42251
  });
41970
42252
  let reportText = null;
41971
42253
  try {
41972
- reportText = readFileSync18(reportAbs, "utf8");
42254
+ reportText = readFileSync19(reportAbs, "utf8");
41973
42255
  } catch {
41974
42256
  reportText = null;
41975
42257
  }
@@ -42534,7 +42816,7 @@ var init_crap = __esm({
42534
42816
  });
42535
42817
 
42536
42818
  // packages/gauntlet-lite/dist/coverage-adapter.js
42537
- import { readFileSync as readFileSync19 } from "node:fs";
42819
+ import { readFileSync as readFileSync20 } from "node:fs";
42538
42820
  import { join as pathJoin7 } from "node:path";
42539
42821
  import { performance as performance14 } from "node:perf_hooks";
42540
42822
  function isPlainObject3(value) {
@@ -43007,7 +43289,7 @@ function createCrapGateAdapter() {
43007
43289
  }
43008
43290
  const readOrNull = (relative3) => {
43009
43291
  try {
43010
- return readFileSync19(pathJoin7(plan.projectRoot, relative3), "utf8");
43292
+ return readFileSync20(pathJoin7(plan.projectRoot, relative3), "utf8");
43011
43293
  } catch {
43012
43294
  return null;
43013
43295
  }
@@ -43052,7 +43334,7 @@ var init_coverage_adapter = __esm({
43052
43334
 
43053
43335
  // packages/gauntlet-lite/dist/mutation-leg.js
43054
43336
  import { spawnSync as spawnSync11 } from "node:child_process";
43055
- import { existsSync as existsSync15, readFileSync as readFileSync20, rmSync as rmSync8 } from "node:fs";
43337
+ import { existsSync as existsSync16, readFileSync as readFileSync21, rmSync as rmSync9 } from "node:fs";
43056
43338
  import { join as pathJoin8, isAbsolute as pathIsAbsolute4, relative as pathRelative4, resolve as pathResolve4 } from "node:path";
43057
43339
  import { performance as performance15 } from "node:perf_hooks";
43058
43340
  function runMutationLeg(plan, spawnFn = mutationSpawn, executableProbe = platformExecutableProbe) {
@@ -43104,10 +43386,10 @@ function runMutationLeg(plan, spawnFn = mutationSpawn, executableProbe = platfor
43104
43386
  };
43105
43387
  }
43106
43388
  try {
43107
- rmSync8(reportAbs, { force: true });
43389
+ rmSync9(reportAbs, { force: true });
43108
43390
  } catch {
43109
43391
  }
43110
- if (existsSync15(reportAbs)) {
43392
+ if (existsSync16(reportAbs)) {
43111
43393
  return {
43112
43394
  plan,
43113
43395
  kind: "pre_run_failed",
@@ -43126,7 +43408,7 @@ function runMutationLeg(plan, spawnFn = mutationSpawn, executableProbe = platfor
43126
43408
  });
43127
43409
  let reportText = null;
43128
43410
  try {
43129
- reportText = readFileSync20(reportAbs, "utf8");
43411
+ reportText = readFileSync21(reportAbs, "utf8");
43130
43412
  } catch {
43131
43413
  reportText = null;
43132
43414
  }
@@ -43881,7 +44163,7 @@ var init_mutation_adapter = __esm({
43881
44163
 
43882
44164
  // packages/gauntlet-lite/dist/performance-leg.js
43883
44165
  import { spawnSync as spawnSync12 } from "node:child_process";
43884
- import { existsSync as existsSync16, readFileSync as readFileSync21, rmSync as rmSync9 } from "node:fs";
44166
+ import { existsSync as existsSync17, readFileSync as readFileSync22, rmSync as rmSync10 } from "node:fs";
43885
44167
  import { isAbsolute as pathIsAbsolute5, join as pathJoin9, relative as pathRelative5, resolve as pathResolve5 } from "node:path";
43886
44168
  import { performance as performance17 } from "node:perf_hooks";
43887
44169
  function performanceCapabilityNote(runner) {
@@ -44114,10 +44396,10 @@ function runPerformanceLeg(plan, spawnFn = performanceSpawn, executableProbe = p
44114
44396
  };
44115
44397
  }
44116
44398
  try {
44117
- rmSync9(reportAbs, { force: true });
44399
+ rmSync10(reportAbs, { force: true });
44118
44400
  } catch {
44119
44401
  }
44120
- if (existsSync16(reportAbs)) {
44402
+ if (existsSync17(reportAbs)) {
44121
44403
  return {
44122
44404
  plan,
44123
44405
  kind: "pre_run_failed",
@@ -44136,7 +44418,7 @@ function runPerformanceLeg(plan, spawnFn = performanceSpawn, executableProbe = p
44136
44418
  });
44137
44419
  let reportText = null;
44138
44420
  try {
44139
- reportText = readFileSync21(reportAbs, "utf8");
44421
+ reportText = readFileSync22(reportAbs, "utf8");
44140
44422
  } catch {
44141
44423
  reportText = null;
44142
44424
  }
@@ -44945,7 +45227,7 @@ var init_performance_adapter = __esm({
44945
45227
 
44946
45228
  // packages/gauntlet-lite/dist/security-leg.js
44947
45229
  import { spawnSync as spawnSync13 } from "node:child_process";
44948
- import { existsSync as existsSync17, readFileSync as readFileSync22, rmSync as rmSync10 } from "node:fs";
45230
+ import { existsSync as existsSync18, readFileSync as readFileSync23, rmSync as rmSync11 } from "node:fs";
44949
45231
  import { isAbsolute as pathIsAbsolute6, join as pathJoin10, relative as pathRelative6, resolve as pathResolve6 } from "node:path";
44950
45232
  import { performance as performance19 } from "node:perf_hooks";
44951
45233
  function securityCapabilityNote(runner) {
@@ -45000,10 +45282,10 @@ function runSecurityLeg(plan, spawnFn = securitySpawn, executableProbe = platfor
45000
45282
  };
45001
45283
  }
45002
45284
  try {
45003
- rmSync10(reportAbs, { force: true });
45285
+ rmSync11(reportAbs, { force: true });
45004
45286
  } catch {
45005
45287
  }
45006
- if (existsSync17(reportAbs)) {
45288
+ if (existsSync18(reportAbs)) {
45007
45289
  return {
45008
45290
  plan,
45009
45291
  kind: "pre_run_failed",
@@ -45022,7 +45304,7 @@ function runSecurityLeg(plan, spawnFn = securitySpawn, executableProbe = platfor
45022
45304
  });
45023
45305
  let reportText = null;
45024
45306
  try {
45025
- reportText = readFileSync22(reportAbs, "utf8");
45307
+ reportText = readFileSync23(reportAbs, "utf8");
45026
45308
  } catch {
45027
45309
  reportText = null;
45028
45310
  }
@@ -46954,7 +47236,7 @@ function readCliPackageVersion() {
46954
47236
  }
46955
47237
  function resolveCliVersion() {
46956
47238
  if (true) {
46957
- return "0.5.2";
47239
+ return "0.6.0";
46958
47240
  }
46959
47241
  return readCliPackageVersion();
46960
47242
  }
@@ -48650,10 +48932,10 @@ async function runContextCompile(rootDir, role, deps, inputs, options) {
48650
48932
  applicability: applicabilityViewOf(inputs),
48651
48933
  verificationRefs
48652
48934
  });
48653
- const { mkdirSync: mkdirSync4, writeFileSync: writeFileSync6 } = await import("node:fs");
48935
+ const { mkdirSync: mkdirSync4, writeFileSync: writeFileSync7 } = await import("node:fs");
48654
48936
  try {
48655
48937
  mkdirSync4(contextsDirPath(rootDir), { recursive: true });
48656
- writeFileSync6(`${contextsDirPath(rootDir)}/${fileName}`, `${JSON.stringify(document, null, 2)}
48938
+ writeFileSync7(`${contextsDirPath(rootDir)}/${fileName}`, `${JSON.stringify(document, null, 2)}
48657
48939
  `, "utf8");
48658
48940
  manifestPath = relativePath;
48659
48941
  persisted = true;
@@ -48939,7 +49221,7 @@ var COMMAND_PANORAMA_LINES = [
48939
49221
  "pomaster doctor",
48940
49222
  "pomaster portability bootstrap/check",
48941
49223
  "pomaster update --check/--yes",
48942
- "pomaster baseline set/confirm # set = \u5355\u952E\u540E\u8865\u9500\u8D26\uFF1Bconfirm = \u57FA\u7EBF\u786E\u8BA4 gate\uFF0814 unknowns \u9500\u8D26\u540E digest \u5FEB\u7167\u2014\u2014closeout \u963B\u65AD\u7801\u4E0E doctor/status \u786E\u8BA4\u6001\u7684\u6D88\u8D39\u6E90\uFF09",
49224
+ "pomaster baseline set/confirm # set = \u5355\u952E\u540E\u8865\u9500\u8D26\uFF1Bconfirm = \u57FA\u7EBF\u786E\u8BA4 gate\uFF08\u963B\u585E\u96C6\u6E05\u96F6\u540E digest \u5FEB\u7167\u2014\u2014closeout \u963B\u65AD\u7801\u4E0E doctor/status \u786E\u8BA4\u6001\u7684\u6D88\u8D39\u6E90\uFF09",
48943
49225
  "",
48944
49226
  "# \u2460 DISCOVERY \u2014\u2014 \u9700\u6C42\u62F7\u95EE/\u95EE\u9898\u95F8/\u51B3\u8BAE\u56FE\uFF08Brainstorm/Question Gate\uFF1BD-5\uFF0C\u88C1\u51B3 18\uFF09",
48945
49227
  "pomaster brainstorm start/question-gate/status/decide/promote",
@@ -49554,10 +49836,10 @@ var FACET_DIR = {
49554
49836
  };
49555
49837
  async function countSeededAssets(rootDir) {
49556
49838
  const { readdir: readdir3 } = await import("node:fs/promises");
49557
- const { join: join16 } = await import("node:path");
49839
+ const { join: join17 } = await import("node:path");
49558
49840
  const pomasterDir = toPosix(buildStorePaths(rootDir).pomasterDir);
49559
49841
  async function countFiles(relative3) {
49560
- const absolute = join16(pomasterDir, ...relative3.split("/"));
49842
+ const absolute = join17(pomasterDir, ...relative3.split("/"));
49561
49843
  let entries;
49562
49844
  try {
49563
49845
  entries = await readdir3(absolute, { withFileTypes: true });
@@ -49587,11 +49869,11 @@ function seededAssetsHumanLine(counts) {
49587
49869
  }
49588
49870
  async function countLegacySpecFiles(rootDir) {
49589
49871
  const { readdir: readdir3 } = await import("node:fs/promises");
49590
- const { join: join16 } = await import("node:path");
49872
+ const { join: join17 } = await import("node:path");
49591
49873
  const pomasterDir = toPosix(buildStorePaths(rootDir).pomasterDir);
49592
49874
  const legacyDirs = ["specs/hard/frontend", "specs/hard/backend"];
49593
49875
  async function countFiles(relative3) {
49594
- const absolute = join16(pomasterDir, ...relative3.split("/"));
49876
+ const absolute = join17(pomasterDir, ...relative3.split("/"));
49595
49877
  let entries;
49596
49878
  try {
49597
49879
  entries = await readdir3(absolute, { withFileTypes: true });
@@ -49945,6 +50227,106 @@ function specPreplantHumanLine(presentation) {
49945
50227
  init_dist();
49946
50228
  import { writeFile } from "node:fs/promises";
49947
50229
 
50230
+ // packages/cli/dist/fs-cas.js
50231
+ import { existsSync as existsSync10, linkSync as linkSync2, readFileSync as readFileSync10, renameSync as renameSync3, rmSync as rmSync4, writeFileSync as writeFileSync4 } from "node:fs";
50232
+ var CLAIM_RETRY_DELAYS_MS = [20, 50, 100];
50233
+ function sleepSync2(ms) {
50234
+ if (ms <= 0)
50235
+ return;
50236
+ const buffer = new Int32Array(new SharedArrayBuffer(4));
50237
+ try {
50238
+ Atomics.wait(buffer, 0, 0, ms);
50239
+ } catch {
50240
+ const end = performance.now() + ms;
50241
+ while (performance.now() < end) {
50242
+ }
50243
+ }
50244
+ }
50245
+ function isNotFoundError2(error) {
50246
+ return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
50247
+ }
50248
+ function isTransientClaimError(error) {
50249
+ if (typeof error !== "object" || error === null || !("code" in error))
50250
+ return false;
50251
+ const code = error.code;
50252
+ return code === "EPERM" || code === "EACCES";
50253
+ }
50254
+ function renameWithLiarDefense(op, dst) {
50255
+ withBoundedRetry2(() => {
50256
+ try {
50257
+ op();
50258
+ } catch (error) {
50259
+ if (isNotFoundError2(error) && existsSync10(dst))
50260
+ return;
50261
+ throw error;
50262
+ }
50263
+ });
50264
+ }
50265
+ function removeBestEffort2(path) {
50266
+ try {
50267
+ rmSync4(path, { force: true });
50268
+ } catch {
50269
+ }
50270
+ }
50271
+ var casSequence = 0;
50272
+ function uniqueAdjacentPath2(target, tag) {
50273
+ casSequence += 1;
50274
+ return `${target}.${tag}-${process.pid}-${casSequence}`;
50275
+ }
50276
+ function withBoundedRetry2(op) {
50277
+ for (let attempt = 0; ; attempt += 1) {
50278
+ try {
50279
+ op();
50280
+ return;
50281
+ } catch (error) {
50282
+ if (attempt >= CLAIM_RETRY_DELAYS_MS.length || !isTransientClaimError(error))
50283
+ throw error;
50284
+ sleepSync2(CLAIM_RETRY_DELAYS_MS[attempt]);
50285
+ }
50286
+ }
50287
+ }
50288
+ function casSwapFile(target, expected, next) {
50289
+ const tmp = uniqueAdjacentPath2(target, "r1tmp");
50290
+ try {
50291
+ writeFileSync4(tmp, next, "utf8");
50292
+ } catch (error) {
50293
+ removeBestEffort2(tmp);
50294
+ throw error;
50295
+ }
50296
+ const claim = uniqueAdjacentPath2(target, "r1claim");
50297
+ try {
50298
+ renameWithLiarDefense(() => renameSync3(target, claim), claim);
50299
+ } catch (error) {
50300
+ removeBestEffort2(tmp);
50301
+ if (isNotFoundError2(error))
50302
+ return { kind: "absent" };
50303
+ throw error;
50304
+ }
50305
+ let claimedBytes = null;
50306
+ try {
50307
+ claimedBytes = readFileSync10(claim, "utf8");
50308
+ } catch {
50309
+ claimedBytes = null;
50310
+ }
50311
+ if (claimedBytes !== expected) {
50312
+ renameWithLiarDefense(() => renameSync3(claim, target), target);
50313
+ removeBestEffort2(tmp);
50314
+ return { kind: "conflict" };
50315
+ }
50316
+ try {
50317
+ linkSync2(tmp, target);
50318
+ } catch (error) {
50319
+ removeBestEffort2(tmp);
50320
+ if (error.code === "EEXIST") {
50321
+ return { kind: "conflict" };
50322
+ }
50323
+ throw error;
50324
+ }
50325
+ removeBestEffort2(tmp);
50326
+ removeBestEffort2(claim);
50327
+ return { kind: "swapped" };
50328
+ }
50329
+
49948
50330
  // packages/cli/dist/interactive-keys.js
49949
50331
  var CHECKLIST_KEYS = {
49950
50332
  /** ↑ */
@@ -50051,9 +50433,9 @@ function deniedReasonToCode(reason) {
50051
50433
  }
50052
50434
  }
50053
50435
  function parseActorArgv(raw) {
50054
- const sep2 = raw.indexOf(":");
50055
- const type2 = sep2 === -1 ? "" : raw.slice(0, sep2);
50056
- const name = sep2 === -1 ? "" : raw.slice(sep2 + 1);
50436
+ const sep3 = raw.indexOf(":");
50437
+ const type2 = sep3 === -1 ? "" : raw.slice(0, sep3);
50438
+ const name = sep3 === -1 ? "" : raw.slice(sep3 + 1);
50057
50439
  if (!ACTOR_TYPE_VALUES.includes(type2) || name.length === 0) {
50058
50440
  return {
50059
50441
  error: {
@@ -50735,54 +51117,28 @@ async function observePackageStack(rootDir) {
50735
51117
  }
50736
51118
  return { source: "package.json", values };
50737
51119
  }
50738
- async function applyStackObservations(rootDir, observation, files) {
50739
- let observed = 0;
50740
- let skippedResolved = 0;
51120
+ async function registerStackObservationCandidates(rootDir, observation) {
50741
51121
  const lane = "frontend";
50742
51122
  const laneKeys = STACK_KEYS[lane];
50743
- const stackRelative = baselineStackRelative(lane);
50744
- const stackFile = await readTextFile(`${rootDir}/${stackRelative}`);
51123
+ const stackFile = await readTextFile(`${rootDir}/${baselineStackRelative(lane)}`);
50745
51124
  if (stackFile.kind !== "ok")
50746
- return { observed, skipped_resolved: skippedResolved };
51125
+ return { observed: 0, skipped_resolved: 0, candidates: [] };
50747
51126
  const parse = parseStackYaml(stackFile.text, laneKeys);
50748
51127
  if (!parse.ok)
50749
- return { observed, skipped_resolved: skippedResolved };
50750
- const lines = stackFile.text.split("\n");
50751
- const wordForms = /* @__PURE__ */ new Set();
50752
- let stackChanged = false;
51128
+ return { observed: 0, skipped_resolved: 0, candidates: [] };
51129
+ const candidates = [];
51130
+ let skippedResolved = 0;
50753
51131
  for (const key of laneKeys) {
50754
51132
  const value = observation.values.get(key);
50755
51133
  if (value === void 0)
50756
51134
  continue;
50757
- const current = parse.parsed.values.get(key) ?? "";
50758
- if (isResolved(current)) {
51135
+ if (isResolved(parse.parsed.values.get(key) ?? "")) {
50759
51136
  skippedResolved += 1;
50760
51137
  continue;
50761
51138
  }
50762
- const lineIndex = parse.parsed.lineOf.get(key);
50763
- if (lineIndex === void 0)
50764
- continue;
50765
- lines[lineIndex] = `${key}: ${value} # ${OBSERVED_ANNOTATION}`;
50766
- wordForms.add(unknownsWordForm(lane, key));
50767
- observed += 1;
50768
- stackChanged = true;
50769
- }
50770
- if (stackChanged) {
50771
- const nextStack = lines.join("\n");
50772
- if (nextStack !== stackFile.text) {
50773
- await writeFile(`${rootDir}/${stackRelative}`, nextStack, "utf8");
50774
- files.push({ file: stackRelative, action: "updated" });
50775
- }
50776
- const manifestFile = await readTextFile(`${rootDir}/${BASELINE_MANIFEST_RELATIVE}`);
50777
- if (manifestFile.kind === "ok") {
50778
- const { next } = removeUnknownEntries(manifestFile.text, wordForms);
50779
- if (next !== manifestFile.text) {
50780
- await writeFile(`${rootDir}/${BASELINE_MANIFEST_RELATIVE}`, next, "utf8");
50781
- files.push({ file: BASELINE_MANIFEST_RELATIVE, action: "updated" });
50782
- }
50783
- }
51139
+ candidates.push({ lane, key, value, source: "package.json" });
50784
51140
  }
50785
- return { observed, skipped_resolved: skippedResolved };
51141
+ return { observed: candidates.length, skipped_resolved: skippedResolved, candidates };
50786
51142
  }
50787
51143
  function isStackValueResolved(value) {
50788
51144
  return isResolved(value);
@@ -50798,8 +51154,227 @@ async function loadLaneStackValues(rootDir, lane) {
50798
51154
  function unknownsWordForm(lane, key) {
50799
51155
  return `baseline/${lane}/stack.yaml:${key}`;
50800
51156
  }
50801
- var UNKNOWN_ENTRY_LINE = /^\s*-\s*(.+?)\s*$/;
50802
- var UNKNOWN_ENTRY_COUNT = /^\s*-\s*baseline\/(?:frontend|backend)\/stack\.yaml:[A-Za-z0-9_-]+\s*$/;
51157
+ var FLAT_ENTRY_LINE = /^\s*-\s*(\S.*?)\s*$/;
51158
+ var STRUCTURED_ENTRY_KEY_LINE = /^(\s*)-\s*key\s*:\s*(.*?)\s*$/;
51159
+ var STRUCTURED_FIELD_LINE = /^(\s*)([A-Za-z][A-Za-z0-9_-]*)\s*:\s*(.*)$/;
51160
+ var STACK_WORD_FORM_PATTERN = /^baseline\/(frontend|backend)\/stack\.yaml:([A-Za-z0-9_-]+)$/;
51161
+ var BASELINE_UNKNOWN_APPLICABILITY_VALUES = ["BLOCKING", "NOT_APPLICABLE", "DEFERRED"];
51162
+ var MSD_UNKNOWN_CLASSIFICATION_VALUES = [
51163
+ "BLOCKER_CANDIDATE",
51164
+ "HARD_BLOCKER",
51165
+ "SOFT_UNCERTAINTY",
51166
+ "ASSUMPTION",
51167
+ "DEFERRED_DECISION",
51168
+ "DISCOVERY_REQUIRED",
51169
+ "SUSPECTED_ISSUE",
51170
+ "NON_BLOCKING_GAP",
51171
+ "FUTURE_CONSIDERATION",
51172
+ "OUT_OF_SCOPE"
51173
+ ];
51174
+ var STRUCTURED_ROW_FIELD_KEYS = [
51175
+ "applicability",
51176
+ "statement",
51177
+ "classification",
51178
+ "resolution",
51179
+ "blocker_triage",
51180
+ "assumption_risk",
51181
+ "requires_authority"
51182
+ ];
51183
+ function leadingSpaces(line) {
51184
+ const match = /^[ \t]*/.exec(line);
51185
+ return match === null ? 0 : match[0].length;
51186
+ }
51187
+ function parseUnknownLedger(text) {
51188
+ const lines = text.split("\n");
51189
+ const block = confirmedBlockRange(lines);
51190
+ const entries = [];
51191
+ let damage = null;
51192
+ const setDamage = (detail) => {
51193
+ if (damage === null)
51194
+ damage = detail;
51195
+ };
51196
+ const registered = /* @__PURE__ */ new Map();
51197
+ for (let i = 0; i < lines.length; i += 1) {
51198
+ if (insideConfirmedBlock(i, block))
51199
+ continue;
51200
+ const line = lines[i] ?? "";
51201
+ if (line.trim() === "" || line.startsWith("#"))
51202
+ continue;
51203
+ const structured = STRUCTURED_ENTRY_KEY_LINE.exec(line);
51204
+ if (structured !== null) {
51205
+ const dashIndent = leadingSpaces(structured[1] ?? "");
51206
+ const wordForm = (structured[2] ?? "").trim();
51207
+ let end = i + 1;
51208
+ let fieldIndent = null;
51209
+ const fields = /* @__PURE__ */ new Map();
51210
+ while (end < lines.length) {
51211
+ const candidate = lines[end] ?? "";
51212
+ if (candidate.trim() === "" || candidate.startsWith("#")) {
51213
+ let peek = end + 1;
51214
+ while (peek < lines.length && ((lines[peek] ?? "").trim() === "" || (lines[peek] ?? "").startsWith("#"))) {
51215
+ peek += 1;
51216
+ }
51217
+ if (peek >= lines.length || leadingSpaces(lines[peek] ?? "") <= dashIndent)
51218
+ break;
51219
+ end = peek;
51220
+ continue;
51221
+ }
51222
+ const indent = leadingSpaces(candidate);
51223
+ if (indent <= dashIndent)
51224
+ break;
51225
+ if (fieldIndent === null)
51226
+ fieldIndent = indent;
51227
+ if (indent === fieldIndent) {
51228
+ const field = STRUCTURED_FIELD_LINE.exec(candidate);
51229
+ if (field === null) {
51230
+ setDamage(`\u7ED3\u6784\u5316\u884C\uFF08${wordForm === "" ? "<key \u7F3A\u5E2D>" : wordForm}\uFF09\u5B57\u6BB5\u884C\u4E0D\u53EF\u8BC6\u522B: ${candidate.trim()}`);
51231
+ } else if (!STRUCTURED_ROW_FIELD_KEYS.includes(field[2] ?? "")) {
51232
+ setDamage(`\u7ED3\u6784\u5316\u884C\u5B57\u6BB5\u51FA\u952E\u96C6\u95ED\u5305: ${field[2]}\uFF08\u5408\u6CD5\u5B57\u6BB5: ${STRUCTURED_ROW_FIELD_KEYS.join(" / ")}\u2014\u2014\u95ED\u5305\u6F14\u8FDB\u8D70\u63D0\u6848\u4FEE\u8BA2\u7981\u53E6\u9020\u8BCD\u5F62\uFF09`);
51233
+ } else if (fields.has(field[2] ?? "")) {
51234
+ setDamage(`\u7ED3\u6784\u5316\u884C\u5B57\u6BB5\u91CD\u590D: ${field[2]}`);
51235
+ } else {
51236
+ fields.set(field[2] ?? "", stripTrailingComment(field[3] ?? "").trim());
51237
+ }
51238
+ } else if (indent < fieldIndent) {
51239
+ setDamage(`\u7ED3\u6784\u5316\u884C\uFF08${wordForm === "" ? "<key \u7F3A\u5E2D>" : wordForm}\uFF09\u5B57\u6BB5\u7F29\u8FDB\u4E0D\u4E00\u81F4: ${candidate.trim()}`);
51240
+ }
51241
+ end += 1;
51242
+ }
51243
+ let shapeDetail = null;
51244
+ const fail6 = (detail) => {
51245
+ if (shapeDetail === null)
51246
+ shapeDetail = detail;
51247
+ };
51248
+ if (wordForm === "") {
51249
+ fail6("\u7ED3\u6784\u5316\u884C key \u8BCD\u5F62\u7F3A\u5E2D\uFF08\u5FC5\u586B\uFF09");
51250
+ } else {
51251
+ const stackMatch = STACK_WORD_FORM_PATTERN.exec(wordForm);
51252
+ if (stackMatch !== null && !STACK_KEYS[stackMatch[1]].includes(stackMatch[2] ?? "")) {
51253
+ fail6(`\u7ED3\u6784\u5316\u884C\u952E\u51FA 14 \u952E\u95ED\u5305: ${wordForm}\uFF08frontend/backend \u4E24 lane \u952E\u96C6\u95ED\u5305\u5F3A\u5236\u2014\u2014\u5F00\u653E\u57DF\u952E\u540D\u624D\u4E0D\u8BBE\u95ED\u5305\uFF09`);
51254
+ }
51255
+ }
51256
+ let applicability = "BLOCKING";
51257
+ const rawApplicability = fields.get("applicability");
51258
+ if (rawApplicability !== void 0) {
51259
+ if (!BASELINE_UNKNOWN_APPLICABILITY_VALUES.includes(rawApplicability)) {
51260
+ fail6(`\u7ED3\u6784\u5316\u884C applicability \u51FA\u4E09\u503C\u95ED\u5305: ${rawApplicability}\uFF08\u5408\u6CD5\u8BCD\u5F62: ${BASELINE_UNKNOWN_APPLICABILITY_VALUES.join(" | ")}\uFF09`);
51261
+ } else {
51262
+ applicability = rawApplicability;
51263
+ }
51264
+ }
51265
+ const statement = fields.get("statement") ?? null;
51266
+ if (statement === null || statement.length === 0) {
51267
+ fail6("\u7ED3\u6784\u5316\u884C\u7F3A statement\uFF08MSD unknown_item \u540C\u6784\u5FC5\u586B\uFF1BminLength 1 \u7981\u7A7A\u6CDB\u5360\u4F4D\uFF09");
51268
+ }
51269
+ const classification = fields.get("classification") ?? null;
51270
+ if (classification === null) {
51271
+ fail6("\u7ED3\u6784\u5316\u884C\u7F3A classification\uFF08MSD unknown_item \u540C\u6784\u5FC5\u586B\uFF09");
51272
+ } else if (!MSD_UNKNOWN_CLASSIFICATION_VALUES.includes(classification)) {
51273
+ fail6(`\u7ED3\u6784\u5316\u884C classification \u51FA\u5341\u5206\u7C7B\u95ED\u5305: ${classification}\uFF0809-msd-uncertainty unknown_classification \u9010\u5B57\u590D\u7528\uFF0C\u96F6\u65B0\u503C\uFF09`);
51274
+ }
51275
+ if (shapeDetail !== null)
51276
+ setDamage(shapeDetail);
51277
+ entries.push({
51278
+ wordForm,
51279
+ structured: true,
51280
+ applicability,
51281
+ statement,
51282
+ classification,
51283
+ lineStart: i,
51284
+ lineEnd: end
51285
+ });
51286
+ const seenStructured = registered.get(wordForm) ?? { flat: 0, structured: 0 };
51287
+ seenStructured.structured += 1;
51288
+ registered.set(wordForm, seenStructured);
51289
+ i = end - 1;
51290
+ continue;
51291
+ }
51292
+ const flat = FLAT_ENTRY_LINE.exec(line);
51293
+ if (flat === null)
51294
+ continue;
51295
+ const flatWordForm = stripTrailingComment(flat[1] ?? "").trim();
51296
+ entries.push({
51297
+ wordForm: flatWordForm,
51298
+ structured: false,
51299
+ applicability: "BLOCKING",
51300
+ statement: null,
51301
+ classification: null,
51302
+ lineStart: i,
51303
+ lineEnd: i + 1
51304
+ });
51305
+ const seenFlat = registered.get(flatWordForm) ?? { flat: 0, structured: 0 };
51306
+ seenFlat.flat += 1;
51307
+ registered.set(flatWordForm, seenFlat);
51308
+ }
51309
+ for (const [wordForm, kinds] of registered) {
51310
+ if (kinds.structured > 1) {
51311
+ setDamage(`\u952E\u91CD\u590D\u7ED3\u6784\u5316\u767B\u8BB0: ${wordForm}\uFF08\u8C41\u514D\u8BED\u4E49\u4E0D\u53EF\u5224\u2014\u2014\u4FDD\u7559\u4E00\u884C\u7ED3\u6784\u5316\u767B\u8BB0\uFF09`);
51312
+ } else if (kinds.structured === 1 && kinds.flat > 0) {
51313
+ setDamage(`\u952E flat+\u7ED3\u6784\u5316\u91CD\u590D\u767B\u8BB0: ${wordForm}\uFF08flat \u884C\u7F3A\u7701 BLOCKING \u4E0E\u8C41\u514D\u767B\u8BB0\u51B2\u7A81\u2014\u2014\u5220 flat \u884C\u6216\u964D\u7EA7\u7ED3\u6784\u5316\u884C\uFF09`);
51314
+ }
51315
+ }
51316
+ return { entries, damage };
51317
+ }
51318
+ function insideConfirmedBlock(index, block) {
51319
+ return block !== null && index >= block.start && index < block.end;
51320
+ }
51321
+ function removeUnknownEntries(text, wordForms) {
51322
+ const ledger = parseUnknownLedger(text);
51323
+ if (ledger.entries.length === 0)
51324
+ return { next: text, removed: 0 };
51325
+ const removeLines = /* @__PURE__ */ new Set();
51326
+ let removed = 0;
51327
+ for (const entry of ledger.entries) {
51328
+ if (!wordForms.has(entry.wordForm))
51329
+ continue;
51330
+ removed += 1;
51331
+ for (let i = entry.lineStart; i < entry.lineEnd; i += 1)
51332
+ removeLines.add(i);
51333
+ }
51334
+ if (removed === 0)
51335
+ return { next: text, removed: 0 };
51336
+ const lines = text.split("\n");
51337
+ return { next: lines.filter((_, index) => !removeLines.has(index)).join("\n"), removed };
51338
+ }
51339
+ function countUnknownEntries(text) {
51340
+ return parseUnknownLedger(text).entries.length;
51341
+ }
51342
+ function stackValueResolvedAt(wordForm, stackValues) {
51343
+ const match = STACK_WORD_FORM_PATTERN.exec(wordForm);
51344
+ if (match === null)
51345
+ return false;
51346
+ const lane = match[1];
51347
+ const key = match[2] ?? "";
51348
+ if (!STACK_KEYS[lane].includes(key))
51349
+ return false;
51350
+ return isResolved(stackValues.get(lane)?.get(key) ?? "");
51351
+ }
51352
+ function computeBlockingSet(ledger, stackValues) {
51353
+ if (ledger.damage !== null)
51354
+ return { ok: false, detail: ledger.damage };
51355
+ const blocking = /* @__PURE__ */ new Set();
51356
+ const rowWordForms = /* @__PURE__ */ new Set();
51357
+ const counts = { BLOCKING: 0, NOT_APPLICABLE: 0, DEFERRED: 0 };
51358
+ for (const entry of ledger.entries) {
51359
+ counts[entry.applicability] += 1;
51360
+ rowWordForms.add(entry.wordForm);
51361
+ if (entry.structured && entry.applicability !== "BLOCKING" && !stackValueResolvedAt(entry.wordForm, stackValues)) {
51362
+ continue;
51363
+ }
51364
+ blocking.add(entry.wordForm);
51365
+ }
51366
+ for (const lane of BASELINE_LANES) {
51367
+ for (const key of STACK_KEYS[lane]) {
51368
+ const wordForm = unknownsWordForm(lane, key);
51369
+ if (rowWordForms.has(wordForm))
51370
+ continue;
51371
+ if (!isResolved(stackValues.get(lane)?.get(key) ?? "")) {
51372
+ blocking.add(wordForm);
51373
+ }
51374
+ }
51375
+ }
51376
+ return { ok: true, blocking: [...blocking], applicability_counts: counts };
51377
+ }
50803
51378
  function confirmedBlockRange(lines) {
50804
51379
  const start = lines.findIndex((line) => CONFIRMED_KEY_LINE.test(line));
50805
51380
  if (start < 0)
@@ -50816,30 +51391,6 @@ function confirmedBlockRange(lines) {
50816
51391
  }
50817
51392
  return { start, end };
50818
51393
  }
50819
- function insideConfirmedBlock(index, block) {
50820
- return block !== null && index >= block.start && index < block.end;
50821
- }
50822
- function removeUnknownEntries(text, wordForms) {
50823
- const lines = text.split("\n");
50824
- const block = confirmedBlockRange(lines);
50825
- let removed = 0;
50826
- const kept = lines.filter((line, index) => {
50827
- if (insideConfirmedBlock(index, block))
50828
- return true;
50829
- const match = UNKNOWN_ENTRY_LINE.exec(line);
50830
- if (match !== null && wordForms.has(match[1] ?? "")) {
50831
- removed += 1;
50832
- return false;
50833
- }
50834
- return true;
50835
- });
50836
- return { next: kept.join("\n"), removed };
50837
- }
50838
- function countUnknownEntries(text) {
50839
- const lines = text.split("\n");
50840
- const block = confirmedBlockRange(lines);
50841
- return lines.filter((line, index) => !insideConfirmedBlock(index, block) && UNKNOWN_ENTRY_COUNT.test(line)).length;
50842
- }
50843
51394
  var BASELINE_CONFIRMED_PLACEHOLDER = /^confirmed\s*:/m;
50844
51395
  async function readTextFile(absolutePath) {
50845
51396
  try {
@@ -50874,7 +51425,13 @@ async function resolveRemainingQuestions(rootDir) {
50874
51425
  for (const lane of BASELINE_LANES) {
50875
51426
  const relative3 = baselineStackRelative(lane);
50876
51427
  const file = await readTextFile(`${rootDir}/${relative3}`);
50877
- const laneQuestions = STACK_QUESTIONS.filter((q) => q.lane === lane && !(lane === "frontend" && observation !== null && observation.values.has(q.key)));
51428
+ const laneQuestions = STACK_QUESTIONS.filter((q) => q.lane === lane).map((question) => {
51429
+ const observedValue = lane === "frontend" && observation !== null ? observation.values.get(question.key) : void 0;
51430
+ return observedValue === void 0 ? question : {
51431
+ ...question,
51432
+ observed: { lane, key: question.key, value: observedValue, source: "package.json" }
51433
+ };
51434
+ });
50878
51435
  if (file.kind === "absent") {
50879
51436
  questions.push(...laneQuestions);
50880
51437
  continue;
@@ -50894,9 +51451,14 @@ async function resolveRemainingQuestions(rootDir) {
50894
51451
  }
50895
51452
  return { kind: "ready", questions };
50896
51453
  }
51454
+ function observationCandidateLine(question) {
51455
+ return question.observed === void 0 ? null : ` \u89C2\u5BDF\u5019\u9009: ${question.observed.value} ${OBSERVED_ANNOTATION}\uFF08\u9009\u578B\u8BE5\u503C\u5373\u91C7\u7EB3\uFF1B\u672A\u91C7\u7EB3\u4FDD\u6301 UNKNOWN\uFF09`;
51456
+ }
50897
51457
  function renderQuestionFrame(question, cursor, buffer, progress, error) {
51458
+ const candidateLine = observationCandidateLine(question);
50898
51459
  const lines = [
50899
51460
  `? ${question.label}\uFF08${question.lane}.${question.key}\uFF1B\u2191\u2193\u9009\u62E9 / \u76F4\u63A5\u952E\u5165\u81EA\u5B9A\u4E49\u503C / \u56DE\u8F66\u786E\u8BA4 / Ctrl+C \u4E2D\u6B62\uFF09[${progress}]`,
51461
+ ...candidateLine === null ? [] : [candidateLine],
50900
51462
  ...question.options.map((option, i) => i === cursor ? `\u25C9 ${option}` : ` \u25EF ${option}`),
50901
51463
  `${cursor === question.options.length ? "" : " "}\u270E \u81EA\u5B9A\u4E49: ${buffer}`
50902
51464
  ];
@@ -50956,6 +51518,9 @@ async function promptQuestionNumbered(question, position, total, io) {
50956
51518
  const customIndex = question.options.length + 1;
50957
51519
  const renderBlock = () => {
50958
51520
  io.write(`[${position}/${total}] ${question.label}\uFF08${question.lane}.${question.key}\uFF09\uFF1A`);
51521
+ const candidateLine = observationCandidateLine(question);
51522
+ if (candidateLine !== null)
51523
+ io.write(candidateLine);
50959
51524
  question.options.forEach((option, i) => io.write(` ${i + 1}. ${option}`));
50960
51525
  io.write(` ${customIndex}. <\u76F4\u63A5\u952E\u5165\u81EA\u5B9A\u4E49\u503C>`);
50961
51526
  io.write("\u7F16\u53F7\u6216\u81EA\u5B9A\u4E49\u503C\uFF08\u5FC5\u7B54\u2014\u2014\u7A7A\u8F93\u5165\u4E0D\u4F5C\u9009\u62E9\uFF09\uFF1A");
@@ -51084,78 +51649,79 @@ function failBaselineSet(code, message, hint, input) {
51084
51649
  confirmation_invalidated: false
51085
51650
  }, [{ code, message, hint }], [`baseline set: FAILED \u2014 ${code}`, ` ${message}`, ` hint: ${hint}`]);
51086
51651
  }
51087
- async function runBaselineSet(rootDir, input) {
51088
- if (!BASELINE_LANES.includes(input.lane)) {
51089
- return failBaselineSet("SCHEMA_INVALID", `\u975E\u6CD5 lane \u8BCD\u5F62\uFF1A${input.lane}\uFF1B\u5408\u6CD5\u8BCD\u5F62\uFF1A${BASELINE_LANES.join(" | ")}`, "\u793A\u4F8B\uFF1Apomaster baseline set --lane frontend --key framework --value vue3", input);
51090
- }
51091
- const lane = input.lane;
51092
- const keys = STACK_KEYS[lane];
51093
- if (!keys.includes(input.key)) {
51094
- return failBaselineSet("SCHEMA_INVALID", `\u975E\u6CD5\u952E\u8BCD\u5F62\uFF1A${input.key}\uFF1B${lane} \u952E\u96C6\u95ED\u5305\uFF1A${keys.join(" | ")}`, `\u952E\u96C6\u4E0E ${baselineStackRelative(lane)} \u64AD\u79CD\u952E\u5E8F\u4E00\u4E00\u5BF9\u5E94\uFF08baseline-seeds \u9489\u5B9A\uFF09\u3002`, input);
51095
- }
51096
- if (input.value === "UNKNOWN") {
51097
- return failBaselineSet("SCHEMA_INVALID", "UNKNOWN \u662F\u8D77\u6B65\u7F3A\u5E2D\u8BCD\u5F62\uFF0C\u4E0D\u53EF\u4F5C\u4E3A\u9009\u578B\u503C", "\u663E\u5F0F\u9009\u578B\u503C\u7ECF init \u95EE\u5377\u6216\u672C\u547D\u4EE4\u5199\u5165\uFF1B\u56DE\u9000/\u64A4\u9500\u5DF2\u9500\u8D26\u952E\u8D70\u6CBB\u7406\u901A\u8DEF\u3002", input);
51098
- }
51099
- if (!STACK_VALUE_PATTERN.test(input.value)) {
51100
- return failBaselineSet("SCHEMA_INVALID", `\u503C\u8BCD\u5F62\u975E\u6CD5\uFF1A${input.value}\uFF08\u5141\u8BB8 [A-Za-z0-9] \u8D77\u59CB\u3001[A-Za-z0-9 _./+#()-]\u3001\u2264${STACK_VALUE_MAX_LENGTH} \u5B57\u7B26\uFF09`, "\u793A\u4F8B\uFF1A--value vue3\u3001--value 'Spring Boot'\u3001--value none", input);
51101
- }
51652
+ var BASELINE_SET_TX_ATTEMPTS = 4;
51653
+ var BASELINE_SET_TX_BACKOFF_MS = [20, 50, 100];
51654
+ function settled(outcome) {
51655
+ return { kind: "settled", outcome };
51656
+ }
51657
+ async function baselineSetAttempt(rootDir, input, lane, attempt) {
51102
51658
  const stackRelative = baselineStackRelative(lane);
51103
51659
  const stackFile = await readTextFile(`${rootDir}/${stackRelative}`);
51104
51660
  if (stackFile.kind !== "ok") {
51661
+ if (stackFile.kind === "absent") {
51662
+ if (attempt > 0) {
51663
+ return { kind: "contended", viaStackAbsent: true };
51664
+ }
51665
+ const manifestProbe = await readTextFile(`${rootDir}/${BASELINE_MANIFEST_RELATIVE}`);
51666
+ if (manifestProbe.kind === "ok") {
51667
+ return { kind: "contended", viaStackAbsent: true };
51668
+ }
51669
+ }
51105
51670
  const error = baselineFileError(stackRelative, stackFile);
51106
- return failBaselineSet(error.code, error.message, error.hint, input);
51671
+ return settled(failBaselineSet(error.code, error.message, error.hint, input));
51107
51672
  }
51108
51673
  const manifestFile = await readTextFile(`${rootDir}/${BASELINE_MANIFEST_RELATIVE}`);
51109
51674
  if (manifestFile.kind !== "ok") {
51675
+ if (attempt > 0 && manifestFile.kind === "absent") {
51676
+ return { kind: "contended" };
51677
+ }
51110
51678
  const error = baselineFileError(BASELINE_MANIFEST_RELATIVE, manifestFile);
51111
- return failBaselineSet(error.code, error.message, error.hint, input);
51679
+ return settled(failBaselineSet(error.code, error.message, error.hint, input));
51112
51680
  }
51113
51681
  const parse = parseStackYaml(stackFile.text, STACK_KEYS[lane]);
51114
51682
  if (!parse.ok) {
51115
- return failBaselineSet("INVALID_STATE", `${stackRelative} \u7ED3\u6784\u4E0D\u53EF\u89E3\u6790: ${parse.detail}`, "\u4FEE\u590D\u6216\u4ECE git \u6062\u590D\u8BE5\u6587\u4EF6\u540E\u91CD\u8BD5\uFF1B\u672C\u547D\u4EE4\u4E0D\u731C\u6D4B\u91CD\u5199\u9879\u76EE\u57FA\u7EBF\u6587\u4EF6\u3002", input);
51683
+ return settled(failBaselineSet("INVALID_STATE", `${stackRelative} \u7ED3\u6784\u4E0D\u53EF\u89E3\u6790: ${parse.detail}`, "\u4FEE\u590D\u6216\u4ECE git \u6062\u590D\u8BE5\u6587\u4EF6\u540E\u91CD\u8BD5\uFF1B\u672C\u547D\u4EE4\u4E0D\u731C\u6D4B\u91CD\u5199\u9879\u76EE\u57FA\u7EBF\u6587\u4EF6\u3002", input));
51116
51684
  }
51117
51685
  const confirmedWordFormPresent = BASELINE_CONFIRMED_PLACEHOLDER.test(manifestFile.text);
51118
51686
  const recordParse = parseConfirmedBlock(manifestFile.text);
51119
51687
  const recordValid = recordParse.kind === "ok";
51120
51688
  if (recordValid || confirmedWordFormPresent) {
51121
51689
  if (input.change === void 0) {
51122
- return failBaselineSet("BASELINE_ALREADY_CONFIRMED", recordValid ? recordParse.record.pending !== void 0 ? `baseline \u786E\u8BA4\u8BB0\u5F55\u5728\u5EA7\u4E14\u53D8\u66F4\u6279\u5728\u9014\uFF08pending-change\uFF1Bchange_ref=${recordParse.record.pending.change_ref}\uFF09\u2014\u2014\u7EE7\u7EED\u4FEE\u6539\u987B\u643A\u540C ref\uFF0C\u6216\u643A\u540C ref confirm \u7EC8\u7ED3` : "baseline \u5DF2\u786E\u8BA4\uFF08manifest \u5728\u5EA7\u786E\u8BA4\u8BB0\u5F55\uFF09\uFF1B\u786E\u8BA4\u540E\u9879\u76EE\u67B6\u6784\u4E0D\u5141\u8BB8\u76F4\u63A5\u4FEE\u6539" : "baseline \u786E\u8BA4\u8BB0\u5F55\u5728\u5EA7\uFF08\u7ED3\u6784\u635F\u574F\uFF09\u2014\u2014\u9879\u76EE\u67B6\u6784\u4E0D\u5141\u8BB8\u76F4\u63A5\u4FEE\u6539\uFF08\u635F\u574F\u5757\u4FEE\u590D\u8D70 confirm \u91CD\u5EFA\uFF09", "\u4FEE\u6539\u8D70\u6CBB\u7406\u901A\u8DEF\uFF1A\u5148\u7ACB CHANGE.* \u5BF9\u8C61\uFF0C\u518D pomaster baseline set --change <CHANGE-id>\uFF08\u5199\u5165\u8F6C pending-change\uFF09\uFF0C\u5B8C\u6210\u540E\u643A\u540C ref pomaster baseline confirm \u91CD\u786E\u8BA4\u3002", input);
51690
+ return settled(failBaselineSet("BASELINE_ALREADY_CONFIRMED", recordValid ? recordParse.record.pending !== void 0 ? `baseline \u786E\u8BA4\u8BB0\u5F55\u5728\u5EA7\u4E14\u53D8\u66F4\u6279\u5728\u9014\uFF08pending-change\uFF1Bchange_ref=${recordParse.record.pending.change_ref}\uFF09\u2014\u2014\u7EE7\u7EED\u4FEE\u6539\u987B\u643A\u540C ref\uFF0C\u6216\u643A\u540C ref confirm \u7EC8\u7ED3` : "baseline \u5DF2\u786E\u8BA4\uFF08manifest \u5728\u5EA7\u786E\u8BA4\u8BB0\u5F55\uFF09\uFF1B\u786E\u8BA4\u540E\u9879\u76EE\u67B6\u6784\u4E0D\u5141\u8BB8\u76F4\u63A5\u4FEE\u6539" : "baseline \u786E\u8BA4\u8BB0\u5F55\u5728\u5EA7\uFF08\u7ED3\u6784\u635F\u574F\uFF09\u2014\u2014\u9879\u76EE\u67B6\u6784\u4E0D\u5141\u8BB8\u76F4\u63A5\u4FEE\u6539\uFF08\u635F\u574F\u5757\u4FEE\u590D\u8D70 confirm \u91CD\u5EFA\uFF09", "\u4FEE\u6539\u8D70\u6CBB\u7406\u901A\u8DEF\uFF1A\u5148\u7ACB CHANGE.* \u5BF9\u8C61\uFF0C\u518D pomaster baseline set --change <CHANGE-id>\uFF08\u5199\u5165\u8F6C pending-change\uFF09\uFF0C\u5B8C\u6210\u540E\u643A\u540C ref pomaster baseline confirm \u91CD\u786E\u8BA4\u3002", input));
51123
51691
  }
51124
51692
  if (!recordValid) {
51125
- return failBaselineSet("INVALID_STATE", "manifest \u786E\u8BA4\u8BB0\u5F55\u7ED3\u6784\u635F\u574F\u2014\u2014set \u4E0D\u5728\u635F\u574F\u8BB0\u5F55\u4E0A\u6388\u6743\u5199\u76D8", "\u5148 pomaster baseline confirm \u91CD\u5EFA\u786E\u8BA4\u8BB0\u5F55\uFF08\u635F\u574F\u5757\u4FEE\u590D\u4E0D\u9700\u8981\u901A\u9053\uFF09\uFF0C\u518D\u8D70\u6CBB\u7406\u901A\u8DEF set --change\u3002", input);
51693
+ return settled(failBaselineSet("INVALID_STATE", "manifest \u786E\u8BA4\u8BB0\u5F55\u7ED3\u6784\u635F\u574F\u2014\u2014set \u4E0D\u5728\u635F\u574F\u8BB0\u5F55\u4E0A\u6388\u6743\u5199\u76D8", "\u5148 pomaster baseline confirm \u91CD\u5EFA\u786E\u8BA4\u8BB0\u5F55\uFF08\u635F\u574F\u5757\u4FEE\u590D\u4E0D\u9700\u8981\u901A\u9053\uFF09\uFF0C\u518D\u8D70\u6CBB\u7406\u901A\u8DEF set --change\u3002", input));
51126
51694
  }
51127
51695
  if (recordParse.record.pending !== void 0 && input.change !== recordParse.record.pending.change_ref) {
51128
- return failBaselineSet("SCHEMA_INVALID", `pending-change \u53D8\u66F4\u6279\u7531 ${recordParse.record.pending.change_ref} \u6301\u6709\u2014\u2014\u540C\u6279\u8FDE\u6539\u987B\u643A\u540C ref\uFF08\u6279\u5185 ${recordParse.record.pending.batch.length} \u952E\uFF09`, `\u7EE7\u7EED\u4FEE\u6539: pomaster baseline set --change ${recordParse.record.pending.change_ref}\uFF1B\u7EC8\u7ED3: pomaster baseline confirm --change ${recordParse.record.pending.change_ref}\u3002`, input);
51696
+ return settled(failBaselineSet("SCHEMA_INVALID", `pending-change \u53D8\u66F4\u6279\u7531 ${recordParse.record.pending.change_ref} \u6301\u6709\u2014\u2014\u540C\u6279\u8FDE\u6539\u987B\u643A\u540C ref\uFF08\u6279\u5185 ${recordParse.record.pending.batch.length} \u952E\uFF09`, `\u7EE7\u7EED\u4FEE\u6539: pomaster baseline set --change ${recordParse.record.pending.change_ref}\uFF1B\u7EC8\u7ED3: pomaster baseline confirm --change ${recordParse.record.pending.change_ref}\u3002`, input));
51129
51697
  }
51130
51698
  const changeError = await validateBaselineChangeRef(rootDir, input.change);
51131
51699
  if (changeError !== null) {
51132
- return failBaselineSet(changeError.code, changeError.message, changeError.hint, input);
51700
+ return settled(failBaselineSet(changeError.code, changeError.message, changeError.hint, input));
51133
51701
  }
51134
51702
  } else if (input.change !== void 0) {
51135
- return failBaselineSet("SCHEMA_INVALID", `--change \u4EC5\u5728\u5DF2\u786E\u8BA4\u57FA\u7EBF\u4E0A\u88AB\u6D88\u8D39\uFF08\u6CBB\u7406\u901A\u8DEF\u6388\u6743\u786E\u8BA4\u5FEB\u7167\u5185\u6587\u4EF6\u7684\u4FEE\u6539\uFF09\uFF1B\u5F53\u524D baseline \u65E0\u786E\u8BA4\u8BB0\u5F55`, "\u76F4\u63A5 set \u5373\u53EF\uFF08\u540E\u8865\u9500\u8D26\u901A\u8DEF\u4E0D\u8981\u6C42\u6388\u6743\uFF09\uFF1B\u786E\u8BA4\u8D70 pomaster baseline confirm\u3002", input);
51703
+ return settled(failBaselineSet("SCHEMA_INVALID", `--change \u4EC5\u5728\u5DF2\u786E\u8BA4\u57FA\u7EBF\u4E0A\u88AB\u6D88\u8D39\uFF08\u6CBB\u7406\u901A\u8DEF\u6388\u6743\u786E\u8BA4\u5FEB\u7167\u5185\u6587\u4EF6\u7684\u4FEE\u6539\uFF09\uFF1B\u5F53\u524D baseline \u65E0\u786E\u8BA4\u8BB0\u5F55`, "\u76F4\u63A5 set \u5373\u53EF\uFF08\u540E\u8865\u9500\u8D26\u901A\u8DEF\u4E0D\u8981\u6C42\u6388\u6743\uFF09\uFF1B\u786E\u8BA4\u8D70 pomaster baseline confirm\u3002", input));
51136
51704
  }
51137
51705
  const current = parse.parsed.values.get(input.key) ?? "";
51138
51706
  const fileReports = [];
51139
51707
  let change = "NO_CHANGE";
51140
51708
  let confirmationInvalidated = false;
51141
51709
  let nextManifest = manifestFile.text;
51710
+ let nextStack = stackFile.text;
51711
+ let stackTouched = false;
51142
51712
  let pendingRecord;
51143
51713
  if (current !== input.value) {
51714
+ stackTouched = true;
51144
51715
  if (isResolved(current) && !recordValid) {
51145
- return failBaselineSet("BASELINE_KEY_ALREADY_SET", `${stackRelative}:${input.key} \u5DF2\u9500\u8D26\u4E3A ${current}\uFF1Bset \u4E0D\u505A\u6539\u578B`, "answered \u7A33\u5B9A\u8BED\u4E49\uFF1A\u5DF2\u7B54\u952E\u7684\u6539\u578B\u8D70\u6CBB\u7406\u901A\u8DEF\u2014\u2014\u786E\u8BA4\u540E\u6301\u6709\u6548 --change \u91CD\u653E\u672C\u547D\u4EE4\uFF08\u5199\u5165\u8F6C pending-change\uFF09\uFF0C\u6216\u7ECF\u9879\u76EE\u81EA\u6709\u8BC4\u5BA1\u624B\u5DE5\u4FEE\u6539\u3002", input);
51716
+ return settled(failBaselineSet("BASELINE_KEY_ALREADY_SET", `${stackRelative}:${input.key} \u5DF2\u9500\u8D26\u4E3A ${current}\uFF1Bset \u4E0D\u505A\u6539\u578B`, "answered \u7A33\u5B9A\u8BED\u4E49\uFF1A\u5DF2\u7B54\u952E\u7684\u6539\u578B\u8D70\u6CBB\u7406\u901A\u8DEF\u2014\u2014\u786E\u8BA4\u540E\u6301\u6709\u6548 --change \u91CD\u653E\u672C\u547D\u4EE4\uFF08\u5199\u5165\u8F6C pending-change\uFF09\uFF0C\u6216\u7ECF\u9879\u76EE\u81EA\u6709\u8BC4\u5BA1\u624B\u5DE5\u4FEE\u6539\u3002", input));
51146
51717
  }
51147
51718
  const lines = stackFile.text.split("\n");
51148
51719
  const lineIndex = parse.parsed.lineOf.get(input.key);
51149
51720
  if (lineIndex === void 0) {
51150
- return failBaselineSet("INVALID_STATE", `${stackRelative} \u7F3A\u5C11\u952E\u884C\uFF1A${input.key}`, "\u57FA\u7EBF\u6587\u4EF6\u7ED3\u6784\u6F02\u79FB\u2014\u2014\u6062\u590D\u64AD\u79CD\u5F62\u6001\u6216\u624B\u5DE5\u5BF9\u9F50\u952E\u96C6\u540E\u91CD\u8BD5\u3002", input);
51721
+ return settled(failBaselineSet("INVALID_STATE", `${stackRelative} \u7F3A\u5C11\u952E\u884C\uFF1A${input.key}`, "\u57FA\u7EBF\u6587\u4EF6\u7ED3\u6784\u6F02\u79FB\u2014\u2014\u6062\u590D\u64AD\u79CD\u5F62\u6001\u6216\u624B\u5DE5\u5BF9\u9F50\u952E\u96C6\u540E\u91CD\u8BD5\u3002", input));
51151
51722
  }
51152
51723
  lines[lineIndex] = `${input.key}: ${input.value}`;
51153
- const nextStack = lines.join("\n");
51154
- if (nextStack !== stackFile.text) {
51155
- await writeFile(`${rootDir}/${stackRelative}`, nextStack, "utf8");
51156
- change = "UPDATED";
51157
- }
51158
- fileReports.push({ file: stackRelative, action: "updated" });
51724
+ nextStack = lines.join("\n");
51159
51725
  if (recordValid && input.change !== void 0 && nextStack !== stackFile.text) {
51160
51726
  const prior = recordParse.record.pending;
51161
51727
  const entry = unknownsWordForm(lane, input.key);
@@ -51163,19 +51729,36 @@ async function runBaselineSet(rootDir, input) {
51163
51729
  pendingRecord = { ...recordParse.record, pending: { change_ref: input.change, batch } };
51164
51730
  confirmationInvalidated = true;
51165
51731
  }
51166
- } else {
51167
- fileReports.push({ file: stackRelative, action: "unchanged" });
51168
51732
  }
51169
51733
  const { next: afterLedger, removed } = removeUnknownEntries(nextManifest, /* @__PURE__ */ new Set([unknownsWordForm(lane, input.key)]));
51170
51734
  nextManifest = afterLedger;
51171
51735
  if (pendingRecord !== void 0) {
51172
51736
  nextManifest = upsertConfirmedBlock(nextManifest, pendingRecord);
51173
51737
  }
51738
+ let manifestCommitted = false;
51174
51739
  if (nextManifest !== manifestFile.text) {
51175
- await writeFile(`${rootDir}/${BASELINE_MANIFEST_RELATIVE}`, nextManifest, "utf8");
51176
- fileReports.push({ file: BASELINE_MANIFEST_RELATIVE, action: "updated" });
51740
+ const cas = casSwapFile(`${rootDir}/${BASELINE_MANIFEST_RELATIVE}`, manifestFile.text, nextManifest);
51741
+ if (cas.kind !== "swapped") {
51742
+ return { kind: "contended" };
51743
+ }
51744
+ manifestCommitted = true;
51177
51745
  change = "UPDATED";
51178
51746
  }
51747
+ if (nextStack !== stackFile.text) {
51748
+ const cas = casSwapFile(`${rootDir}/${stackRelative}`, stackFile.text, nextStack);
51749
+ if (cas.kind !== "swapped") {
51750
+ return { kind: "contended" };
51751
+ }
51752
+ change = "UPDATED";
51753
+ }
51754
+ if (stackTouched) {
51755
+ fileReports.push({ file: stackRelative, action: "updated" });
51756
+ } else {
51757
+ fileReports.push({ file: stackRelative, action: "unchanged" });
51758
+ }
51759
+ if (manifestCommitted) {
51760
+ fileReports.push({ file: BASELINE_MANIFEST_RELATIVE, action: "updated" });
51761
+ }
51179
51762
  const result2 = {
51180
51763
  change,
51181
51764
  lane,
@@ -51190,7 +51773,40 @@ async function runBaselineSet(rootDir, input) {
51190
51773
  ...fileReports.map((report) => ` ${report.action.padEnd(10)} ${report.file}${removed > 0 && report.file === BASELINE_MANIFEST_RELATIVE ? `\uFF08\u9500\u8D26 ${removed} \u6761\uFF09` : ""}`),
51191
51774
  ` unknowns remaining: ${result2.unknowns_remaining}`
51192
51775
  ];
51193
- return okOutcome("baseline set", result2, human);
51776
+ return settled(okOutcome("baseline set", result2, human));
51777
+ }
51778
+ async function runBaselineSet(rootDir, input) {
51779
+ if (!BASELINE_LANES.includes(input.lane)) {
51780
+ return failBaselineSet("SCHEMA_INVALID", `\u975E\u6CD5 lane \u8BCD\u5F62\uFF1A${input.lane}\uFF1B\u5408\u6CD5\u8BCD\u5F62\uFF1A${BASELINE_LANES.join(" | ")}`, "\u793A\u4F8B\uFF1Apomaster baseline set --lane frontend --key framework --value vue3", input);
51781
+ }
51782
+ const lane = input.lane;
51783
+ const keys = STACK_KEYS[lane];
51784
+ if (!keys.includes(input.key)) {
51785
+ return failBaselineSet("SCHEMA_INVALID", `\u975E\u6CD5\u952E\u8BCD\u5F62\uFF1A${input.key}\uFF1B${lane} \u952E\u96C6\u95ED\u5305\uFF1A${keys.join(" | ")}`, `\u952E\u96C6\u4E0E ${baselineStackRelative(lane)} \u64AD\u79CD\u952E\u5E8F\u4E00\u4E00\u5BF9\u5E94\uFF08baseline-seeds \u9489\u5B9A\uFF09\u3002`, input);
51786
+ }
51787
+ if (input.value === "UNKNOWN") {
51788
+ return failBaselineSet("SCHEMA_INVALID", "UNKNOWN \u662F\u8D77\u6B65\u7F3A\u5E2D\u8BCD\u5F62\uFF0C\u4E0D\u53EF\u4F5C\u4E3A\u9009\u578B\u503C", "\u663E\u5F0F\u9009\u578B\u503C\u7ECF init \u95EE\u5377\u6216\u672C\u547D\u4EE4\u5199\u5165\uFF1B\u56DE\u9000/\u64A4\u9500\u5DF2\u9500\u8D26\u952E\u8D70\u6CBB\u7406\u901A\u8DEF\u3002", input);
51789
+ }
51790
+ if (!STACK_VALUE_PATTERN.test(input.value)) {
51791
+ return failBaselineSet("SCHEMA_INVALID", `\u503C\u8BCD\u5F62\u975E\u6CD5\uFF1A${input.value}\uFF08\u5141\u8BB8 [A-Za-z0-9] \u8D77\u59CB\u3001[A-Za-z0-9 _./+#()-]\u3001\u2264${STACK_VALUE_MAX_LENGTH} \u5B57\u7B26\uFF09`, "\u793A\u4F8B\uFF1A--value vue3\u3001--value 'Spring Boot'\u3001--value none", input);
51792
+ }
51793
+ let lastContendedViaStackAbsent = false;
51794
+ for (let attempt = 0; ; attempt += 1) {
51795
+ if (attempt >= BASELINE_SET_TX_ATTEMPTS) {
51796
+ if (lastContendedViaStackAbsent) {
51797
+ return failBaselineSet("BASELINE_WRITE_CONFLICT", `baseline \u5199\u5165\u94FE\u672A\u6536\u655B\uFF08${BASELINE_SET_TX_ATTEMPTS} \u8F6E\u6709\u754C\u91CD\u8BD5\u5185 ${baselineStackRelative(lane)} \u6301\u7EED\u7F3A\u5E2D\uFF09\uFF1A\u53EF\u80FD\u4E3A\u5E76\u53D1 CAS \u8BA4\u9886\u7A97\u53E3\u672A\u6536\u655B\uFF0C\u4E5F\u53EF\u80FD\u4E3A\u8BE5\u6587\u4EF6\u88AB\u771F\u5B9E\u5220\u9664\u2014\u2014\u7F3A\u5E2D\u4E0D\u731C\u6D4B\u91CD\u5199`, "\u7A0D\u540E\u91CD\u8DD1\u672C\u547D\u4EE4\u5373\u53EF\uFF1A\u8BA4\u9886\u7A97\u53E3\u6536\u655B\u540E\u91CD\u8DD1\u5728\u65B0\u9C9C\u76D8\u9762\u4E0A\u6309\u4E32\u884C\u8BED\u4E49\u843D\u76D8\uFF1B\u82E5\u91CD\u8DD1\u4ECD\u62A5\u672C\u9519\u8BEF\uFF0C\u8BE5\u6587\u4EF6\u5F88\u53EF\u80FD\u5DF2\u88AB\u771F\u5B9E\u5220\u9664\u2014\u2014\u4ECE git \u6062\u590D\u6216\u91CD\u8DD1 pomaster init \u64AD\u79CD\uFF08seed-once-missing-only\uFF09\u3002", input);
51798
+ }
51799
+ return failBaselineSet("BASELINE_WRITE_CONFLICT", `baseline \u5E76\u53D1\u5199\u5165\u51B2\u7A81\uFF08${BASELINE_SET_TX_ATTEMPTS} \u8F6E\u91CD\u8BFB\u91CD\u7B97\u540E\u4ECD\u4E0E\u4ED6\u4EBA\u5199\u5165\u4EA4\u9519\uFF1B${baselineStackRelative(lane)} \u4E0E ${BASELINE_MANIFEST_RELATIVE} \u7684\u8BFB-\u6539-\u5199\u94FE\uFF09`, "\u7A0D\u540E\u91CD\u8DD1\u672C\u547D\u4EE4\u5373\u53EF\uFF1A\u91CD\u8DD1\u5728\u65B0\u9C9C\u76D8\u9762\u4E0A\u91CD\u653E\u540C\u4E00\u5224\u5377\u94FE\uFF08\u5E76\u53D1\u4FEE\u6539\u6309\u4E32\u884C\u91CD\u8BD5\u6536\u655B\u2014\u2014\u5BA1\u8BA1 R1 \u4FEE\u590D\u8BED\u4E49\uFF09\u3002", input);
51800
+ }
51801
+ if (attempt > 0) {
51802
+ sleepSync2(BASELINE_SET_TX_BACKOFF_MS[Math.min(attempt - 1, BASELINE_SET_TX_BACKOFF_MS.length - 1)]);
51803
+ }
51804
+ const attemptOutcome = await baselineSetAttempt(rootDir, input, lane, attempt);
51805
+ if (attemptOutcome.kind === "settled") {
51806
+ return attemptOutcome.outcome;
51807
+ }
51808
+ lastContendedViaStackAbsent = attemptOutcome.viaStackAbsent === true;
51809
+ }
51194
51810
  }
51195
51811
  function renderBaselineQuizHumanLine(baseline) {
51196
51812
  if (baseline.skipped === "non_interactive") {
@@ -51235,10 +51851,12 @@ var BASELINE_MD_FACES = [
51235
51851
  `${stripStorePrefix(BASELINE_PLATFORM_DIR_RELATIVE)}/observability.md`,
51236
51852
  `${stripStorePrefix(BASELINE_PLATFORM_DIR_RELATIVE)}/delivery.md`
51237
51853
  ];
51854
+ var BASELINE_DESIGN_TOKENS_TARGET = `${stripStorePrefix(BASELINE_FRONTEND_DIR_RELATIVE)}/design-tokens.yaml`;
51238
51855
  var BASELINE_CONFIRM_TARGETS = [
51239
51856
  stripStorePrefix(baselineStackRelative("frontend")),
51240
51857
  stripStorePrefix(baselineStackRelative("backend")),
51241
- ...BASELINE_MD_FACES
51858
+ ...BASELINE_MD_FACES,
51859
+ BASELINE_DESIGN_TOKENS_TARGET
51242
51860
  ];
51243
51861
  function baselineConfirmTargetPath(rootDir, target) {
51244
51862
  return `${rootDir}/${POMASTER_DIR}/${target}`;
@@ -51435,11 +52053,6 @@ function upsertConfirmedBlock(text, record) {
51435
52053
  return stripped.endsWith("\n") ? stripped + block : `${stripped}
51436
52054
  ${block}`;
51437
52055
  }
51438
- function listUnknownEntries(text) {
51439
- const lines = text.split("\n");
51440
- const block = confirmedBlockRange(lines);
51441
- return lines.map((line, index) => insideConfirmedBlock(index, block) ? "" : UNKNOWN_ENTRY_LINE.exec(line)?.[1]?.trim() ?? "").filter((wordForm) => UNKNOWN_ENTRY_COUNT.test(`- ${wordForm}`));
51442
- }
51443
52056
  async function readGenerationSeq(rootDir) {
51444
52057
  try {
51445
52058
  const { readFile: readFile18 } = await import("node:fs/promises");
@@ -51505,7 +52118,8 @@ async function runBaselineConfirm(rootDir, input = {}) {
51505
52118
  return failBaselineConfirm(error.code, error.message, error.hint, -1);
51506
52119
  }
51507
52120
  const unknownsRemaining = countUnknownEntries(manifestFile.text);
51508
- const unsettled = new Set(listUnknownEntries(manifestFile.text));
52121
+ const ledger = parseUnknownLedger(manifestFile.text);
52122
+ const stackValuesByLane = /* @__PURE__ */ new Map();
51509
52123
  for (const lane of BASELINE_LANES) {
51510
52124
  const stackRelative = baselineStackRelative(lane);
51511
52125
  const stackFile = await readTextFile(`${rootDir}/${stackRelative}`);
@@ -51517,15 +52131,25 @@ async function runBaselineConfirm(rootDir, input = {}) {
51517
52131
  if (!parse.ok) {
51518
52132
  return failBaselineConfirm("INVALID_STATE", `${stackRelative} \u7ED3\u6784\u4E0D\u53EF\u89E3\u6790: ${parse.detail}`, "\u4FEE\u590D\u6216\u4ECE git \u6062\u590D\u8BE5\u6587\u4EF6\u540E\u91CD\u8BD5\uFF1Bconfirm \u4E0D\u731C\u6D4B\u91CD\u5199\u9879\u76EE\u57FA\u7EBF\u6587\u4EF6\u3002", unknownsRemaining);
51519
52133
  }
51520
- for (const key of STACK_KEYS[lane]) {
51521
- if (!isResolved(parse.parsed.values.get(key) ?? "")) {
51522
- unsettled.add(unknownsWordForm(lane, key));
51523
- }
51524
- }
52134
+ stackValuesByLane.set(lane, parse.parsed.values);
52135
+ }
52136
+ const blockingJudgement = computeBlockingSet(ledger, stackValuesByLane);
52137
+ if (!blockingJudgement.ok) {
52138
+ return failBaselineConfirm("INVALID_STATE", `${BASELINE_MANIFEST_RELATIVE} unknowns \u53F0\u8D26\u7ED3\u6784\u5316\u884C\u5F62\u72B6\u635F\u574F: ${blockingJudgement.detail}`, "\u4FEE\u590D\u6216\u4ECE git \u6062\u590D\u8BE5\u6587\u4EF6\u540E\u91CD\u8BD5\uFF1Bconfirm \u4E0D\u731C\u6D4B\u635F\u574F\u53F0\u8D26\u7684\u8BED\u4E49\uFF08\u5F62\u72B6\u95F8\u7981\u9759\u9ED8\u5FFD\u7565\u2014\u2014P-C1\uFF09\u3002", -1);
51525
52139
  }
51526
- if (unsettled.size > 0) {
51527
- const ordered = STACK_QUESTIONS.filter((question) => unsettled.has(unknownsWordForm(question.lane, question.key))).map((question) => unknownsWordForm(question.lane, question.key));
51528
- return failBaselineConfirm("BASELINE_UNKNOWNS_REMAINING", `unknowns \u672A\u5168\u9500\u8D26\uFF08${unsettled.size} \u952E\uFF09\uFF1A${ordered.join("\u3001")}${ordered.length < unsettled.size ? "\u3001<\u53F0\u8D26\u5916\u8BCD\u5F62>" : ""}`, "\u9010\u952E\u56DE\u586B\uFF1ATTY \u91CD\u8DD1 pomaster init \u95EE\u5377\uFF08\u5DF2\u7B54\u952E\u5E42\u7B49\u4E0D\u91CD\u590D\u95EE\uFF09\u6216 pomaster baseline set --lane <lane> --key <key> --value <value>\uFF1B\u5168\u90E8\u9500\u8D26\u540E\u518D confirm\u3002", unknownsRemaining);
52140
+ if (blockingJudgement.blocking.length > 0) {
52141
+ const blocking = new Set(blockingJudgement.blocking);
52142
+ const ordered = [];
52143
+ for (const question of STACK_QUESTIONS) {
52144
+ const wordForm = unknownsWordForm(question.lane, question.key);
52145
+ if (blocking.delete(wordForm))
52146
+ ordered.push(wordForm);
52147
+ }
52148
+ for (const entry of ledger.entries) {
52149
+ if (blocking.delete(entry.wordForm))
52150
+ ordered.push(entry.wordForm);
52151
+ }
52152
+ return failBaselineConfirm("BASELINE_UNKNOWNS_REMAINING", `\u963B\u585E\u96C6\u672A\u9500\u8D26\uFF08${blockingJudgement.blocking.length} \u952E\uFF09\uFF1A${ordered.join("\u3001")}`, "\u963B\u585E\u952E\u9010\u952E\u56DE\u586B\uFF1ATTY \u91CD\u8DD1 pomaster init \u95EE\u5377\uFF08\u5DF2\u7B54\u952E\u5E42\u7B49\u4E0D\u91CD\u590D\u95EE\uFF09\u6216 pomaster baseline set --lane <lane> --key <key> --value <value>\uFF1B\u4E0D\u963B\u585E\u5F53\u524D\u589E\u91CF\u7684\u952E\u7531 Owner \u624B\u7F16 manifest \u767B\u8BB0\u8C41\u514D\uFF08\u7ED3\u6784\u5316\u884C applicability: NOT_APPLICABLE/DEFERRED + statement/classification\uFF09\u2014\u2014\u963B\u585E\u96C6\u6E05\u96F6\u540E\u518D confirm\u3002", unknownsRemaining);
51529
52153
  }
51530
52154
  const snapshot = await computeConfirmDigests(rootDir);
51531
52155
  if (!snapshot.ok) {
@@ -51703,7 +52327,7 @@ async function baselineGateErrors(rootDir) {
51703
52327
  {
51704
52328
  code: "BASELINE_NOT_CONFIRMED",
51705
52329
  message: `baseline \u672A\u786E\u8BA4${detail}\u2014\u2014\u9879\u76EE\u67B6\u6784\u672A\u7ECF Owner \u786E\u8BA4\uFF08confirm gate\uFF1AR-L\uFF09`,
51706
- hint: "pomaster baseline confirm\uFF08\u524D\u63D0\uFF1A14 unknowns \u5168\u9500\u8D26\uFF09\u2014\u2014\u786E\u8BA4\u8BB0\u5F55\u4E0E digest \u5FEB\u7167\u5199\u5165 baseline/manifest.yaml \u540E\u91CD\u8DD1 closeout\u3002"
52330
+ hint: "pomaster baseline confirm\uFF08\u524D\u63D0\uFF1A\u963B\u585E\u96C6\u6E05\u96F6\u2014\u2014\u8C41\u514D\u767B\u8BB0\u884C\u4E0D\u963B\u585E\uFF09\u2014\u2014\u786E\u8BA4\u8BB0\u5F55\u4E0E digest \u5FEB\u7167\u5199\u5165 baseline/manifest.yaml \u540E\u91CD\u8DD1 closeout\u3002"
51707
52331
  }
51708
52332
  ];
51709
52333
  }
@@ -51728,17 +52352,45 @@ async function baselineGateErrors(rootDir) {
51728
52352
  }
51729
52353
  return [];
51730
52354
  }
52355
+ async function readBaselineBlockingPresentation(rootDir) {
52356
+ const manifestFile = await readTextFile(`${rootDir}/${BASELINE_MANIFEST_RELATIVE}`);
52357
+ if (manifestFile.kind !== "ok")
52358
+ return { remaining: null };
52359
+ const stackValues = /* @__PURE__ */ new Map();
52360
+ for (const lane of BASELINE_LANES) {
52361
+ const loaded = await loadLaneStackValues(rootDir, lane);
52362
+ if (!loaded.ok)
52363
+ return { remaining: null };
52364
+ stackValues.set(lane, loaded.values);
52365
+ }
52366
+ const judgement = computeBlockingSet(parseUnknownLedger(manifestFile.text), stackValues);
52367
+ if (!judgement.ok)
52368
+ return { remaining: null };
52369
+ return { remaining: judgement.blocking.length, applicability_summary: judgement.applicability_counts };
52370
+ }
51731
52371
  async function readBaselineConfirmationPresentation(rootDir) {
51732
52372
  const read = await readBaselineConfirmation(rootDir);
51733
52373
  if (read.kind === "manifest-absent" || read.kind === "manifest-unreadable")
51734
52374
  return null;
52375
+ const blocking = await readBaselineBlockingPresentation(rootDir);
52376
+ const blockingFields = {
52377
+ blocking_remaining: blocking.remaining,
52378
+ ...blocking.applicability_summary !== void 0 ? { applicability_summary: blocking.applicability_summary } : {}
52379
+ };
51735
52380
  if (read.kind === "record-invalid") {
51736
- return { state: "unconfirmed", unknowns_remaining: read.unknowns_remaining, at_seq: null, drifted_files: [] };
52381
+ return {
52382
+ state: "unconfirmed",
52383
+ unknowns_remaining: read.unknowns_remaining,
52384
+ ...blockingFields,
52385
+ at_seq: null,
52386
+ drifted_files: []
52387
+ };
51737
52388
  }
51738
52389
  const driftedFiles = read.mismatches.map((mismatch) => `${mismatch.target}${mismatch.note !== null ? `\uFF08${mismatch.note}\uFF09` : ""}`);
51739
52390
  return {
51740
52391
  state: read.state,
51741
52392
  unknowns_remaining: read.unknowns_remaining,
52393
+ ...blockingFields,
51742
52394
  at_seq: read.record.at_seq,
51743
52395
  drifted_files: driftedFiles,
51744
52396
  ...read.record.pending !== void 0 ? { pending_change: { change_ref: read.record.pending.change_ref, batch: read.record.pending.batch } } : {},
@@ -51746,7 +52398,7 @@ async function readBaselineConfirmationPresentation(rootDir) {
51746
52398
  };
51747
52399
  }
51748
52400
  function baselineConfirmationHumanLine(presentation) {
51749
- const unknowns = `unknowns remaining: ${presentation.unknowns_remaining}`;
52401
+ const unknowns = `unknowns remaining: ${presentation.unknowns_remaining}` + (presentation.blocking_remaining === null ? "\uFF08\u963B\u585E \u4E0D\u53EF\u5224\uFF09" : `\uFF08\u963B\u585E ${presentation.blocking_remaining}\uFF09`);
51750
52402
  if (presentation.state === "confirmed") {
51751
52403
  const ackNote = presentation.ack !== void 0 ? `\uFF1B\u4E0A\u6B21\u786E\u8BA4\u4E3A\u624B\u6539\u58F0\u660E\uFF08ack note: ${presentation.ack.note}\uFF09` : "";
51752
52404
  return ` baseline gate: \u5DF2\u786E\u8BA4\uFF08at_seq=${presentation.at_seq}${ackNote}\uFF1B${unknowns}\uFF09\u2014\u2014closeout \u6536\u53E3\u5224\u5377\u5728\u5EA7`;
@@ -51757,7 +52409,7 @@ function baselineConfirmationHumanLine(presentation) {
51757
52409
  if (presentation.state === "drifted") {
51758
52410
  return ` baseline gate: \u5DF2\u6F02\u79FB\uFF08at_seq=${presentation.at_seq}\uFF1B${presentation.drifted_files.length} \u6587\u4EF6\u4E0E\u786E\u8BA4\u5FEB\u7167\u4E0D\u7B26\uFF1A${presentation.drifted_files.join("\u3001")}\uFF09\u2014\u2014\u91CD\u786E\u8BA4: pomaster baseline confirm --change <CHANGE-id> \u6216 --ack-drifted --note "<\u7406\u7531>"\uFF08\u88F8\u91CD\u786E\u8BA4\u62D2\u7EDD\uFF1BAI \u4EE3\u8DD1 ack \u987B\u6301 Owner \u6307\u793A\uFF09`;
51759
52411
  }
51760
- return ` baseline gate: \u672A\u786E\u8BA4\uFF08${unknowns}\uFF09\u2014\u2014\u786E\u8BA4: pomaster baseline confirm\uFF0814 unknowns \u5168\u9500\u8D26\u540E\uFF09`;
52412
+ return ` baseline gate: \u672A\u786E\u8BA4\uFF08${unknowns}\uFF09\u2014\u2014\u786E\u8BA4: pomaster baseline confirm\uFF08\u963B\u585E\u96C6\u6E05\u96F6\u540E\uFF09`;
51761
52413
  }
51762
52414
  var BASELINE_CHANGE_ID_PATTERN = /^CHANGE\.[A-Za-z0-9][A-Za-z0-9_-]*$/;
51763
52415
  var BASELINE_CHANGE_ACTIVE_LIFECYCLES = ["PROPOSED", "CURRENT"];
@@ -53189,11 +53841,11 @@ async function runInit(rootDir, options = {}) {
53189
53841
  const packageObservation = await observePackageStack(rootDir);
53190
53842
  let observation = ZERO_OBSERVATION;
53191
53843
  if (packageObservation !== null) {
53192
- const applied = await applyStackObservations(rootDir, packageObservation, files);
53844
+ const registered = await registerStackObservationCandidates(rootDir, packageObservation);
53193
53845
  observation = {
53194
53846
  source: packageObservation.source,
53195
- observed: applied.observed,
53196
- skipped_resolved: applied.skipped_resolved
53847
+ observed: registered.observed,
53848
+ skipped_resolved: registered.skipped_resolved
53197
53849
  };
53198
53850
  }
53199
53851
  let baseline;
@@ -53312,7 +53964,7 @@ async function runInit(rootDir, options = {}) {
53312
53964
  }
53313
53965
  const entryLine = heavy ? " entry: \u91CD\u5165\u53E3\u9ED8\u8BA4\uFF08skills \u5E93 + hooks \u6CE8\u5165\uFF1B\u4FEE\u590D/\u91CD\u5EFA = \u91CD\u8DD1 pomaster init\uFF09" : " entry: \u6700\u5C0F\u5F62\u6001\uFF08--platforms none\uFF1A\u96F6\u5E73\u53F0\u4EA7\u7269\uFF0C\u65E0\u91CD\u5165\u53E3\u5B89\u88C5\u7269\uFF09";
53314
53966
  const baselineLine = renderBaselineQuizHumanLine(baseline);
53315
- const observationLine = observation.source === null ? " observation: package.json \u89C2\u5BDF\u9762\u7F3A\u5E2D\uFF08\u7F3A\u5E2D/\u4E0D\u53EF\u89E3\u6790\uFF09\u2014\u2014\u6280\u672F\u6808 UNKNOWN \u4FDD\u6301\uFF0C\u95EE\u5377\u5206\u6BCD\u4E0D\u53D7\u51CF" : ` observation: package.json \u2192 stack \u89C2\u5BDF\u56DE\u586B ${String(observation.observed)} \u952E\uFF08[Observed: package.json] \u6CE8\u8BB0\uFF1B${String(observation.skipped_resolved)} \u952E\u5DF2\u9500\u8D26\u8DF3\u8FC7\uFF09`;
53967
+ const observationLine = observation.source === null ? " observation: package.json \u89C2\u5BDF\u9762\u7F3A\u5E2D\uFF08\u7F3A\u5E2D/\u4E0D\u53EF\u89E3\u6790\uFF09\u2014\u2014\u6280\u672F\u6808 UNKNOWN \u4FDD\u6301\uFF0C\u95EE\u5377\u5206\u6BCD\u4E0D\u53D7\u51CF" : ` observation: package.json \u2192 \u89C2\u5BDF\u5019\u9009\u767B\u8BB0 ${String(observation.observed)} \u952E\uFF08[Observed: package.json] \u6CE8\u8BB0\u968F\u95EE\u5377\u5448\u73B0\uFF0Cadoption \u524D\u4E0D\u5165\u57FA\u7EBF\uFF1B${String(observation.skipped_resolved)} \u952E\u5DF2\u91C7\u7EB3\u5206\u8D26\u51FA\u5C40\uFF09`;
53316
53968
  const presetLine = renderBaselinePresetHumanLine(presetDraft);
53317
53969
  const human = [
53318
53970
  ...INIT_LOGO_LINES,
@@ -53456,7 +54108,7 @@ async function readCapabilityTipsEnabled(rootDir) {
53456
54108
  }
53457
54109
 
53458
54110
  // packages/cli/dist/next-action.js
53459
- import { existsSync as existsSync10, readdirSync as readdirSync16, readFileSync as readFileSync10 } from "node:fs";
54111
+ import { existsSync as existsSync11, readdirSync as readdirSync16, readFileSync as readFileSync11 } from "node:fs";
53460
54112
  import { join as join6 } from "node:path";
53461
54113
  var NEXT_ACTION_SNAPSHOT_INCOMPLETE = "NEXT_ACTION_SNAPSHOT_INCOMPLETE";
53462
54114
  var ACTIVE_LIFECYCLE_VALUES = ["PROPOSED", "CURRENT"];
@@ -53490,6 +54142,7 @@ function emptySnapshot(initialized) {
53490
54142
  task_execution_active: false,
53491
54143
  baseline_gate_codes: [],
53492
54144
  baseline_unknowns_remaining: null,
54145
+ baseline_blocking_remaining: null,
53493
54146
  baseline_pending_change_ref: null
53494
54147
  };
53495
54148
  }
@@ -53506,7 +54159,7 @@ function parseLedgerRow(row2) {
53506
54159
  };
53507
54160
  }
53508
54161
  function evidenceDirCounts(dir, pattern) {
53509
- if (!existsSync10(dir))
54162
+ if (!existsSync11(dir))
53510
54163
  return 0;
53511
54164
  let count = 0;
53512
54165
  try {
@@ -53594,7 +54247,7 @@ async function collectNextActionSnapshot(rootDir, warnings) {
53594
54247
  boundRefs = [...expiredBoundRefs, ...activeBoundRefs].sort();
53595
54248
  }
53596
54249
  const firstTask = activeTasks[0];
53597
- const taskManifestPresent = firstTask !== void 0 ? existsSync10(contextsManifestPath(rootDir, firstTask.id)) : false;
54250
+ const taskManifestPresent = firstTask !== void 0 ? existsSync11(contextsManifestPath(rootDir, firstTask.id)) : false;
53598
54251
  let taskManifestFreshness = "absent";
53599
54252
  let taskManifestRole = null;
53600
54253
  if (firstTask !== void 0 && taskManifestPresent) {
@@ -53682,6 +54335,7 @@ async function collectNextActionSnapshot(rootDir, warnings) {
53682
54335
  task_execution_active: taskExecutionActive,
53683
54336
  baseline_gate_codes: baselineGateCodeList,
53684
54337
  baseline_unknowns_remaining: baselinePresentation?.unknowns_remaining ?? null,
54338
+ baseline_blocking_remaining: baselinePresentation?.blocking_remaining ?? null,
53685
54339
  baseline_pending_change_ref: baselinePresentation?.pending_change?.change_ref ?? null
53686
54340
  };
53687
54341
  }
@@ -53694,7 +54348,7 @@ function scanTaskExecutionActive(rootDir, taskId, warnings) {
53694
54348
  if (taskId === void 0)
53695
54349
  return false;
53696
54350
  const dir = executionsDirPath(rootDir);
53697
- if (!existsSync10(dir))
54351
+ if (!existsSync11(dir))
53698
54352
  return false;
53699
54353
  let names;
53700
54354
  try {
@@ -53712,7 +54366,7 @@ function scanTaskExecutionActive(rootDir, taskId, warnings) {
53712
54366
  continue;
53713
54367
  let parsed;
53714
54368
  try {
53715
- parsed = JSON.parse(readFileSync10(join6(dir, name), "utf8"));
54369
+ parsed = JSON.parse(readFileSync11(join6(dir, name), "utf8"));
53716
54370
  } catch {
53717
54371
  warnings.push({
53718
54372
  code: NEXT_ACTION_SNAPSHOT_INCOMPLETE,
@@ -53769,12 +54423,13 @@ var NEXT_ACTION_ROUTE_TABLE = [
53769
54423
  })
53770
54424
  },
53771
54425
  {
53772
- // T2 R5:baseline 未确认(或已漂移)且 unknowns 全销账时,收口前的唯一缺口就是
53773
- // 确认仪式——此刻任何任务内推进(closeout 判卷会被 BASELINE_NOT_CONFIRMED/
53774
- // BASELINE_DRIFT 阻断)都先还这笔账。unknowns_remaining>0 时问卷分母未销账,
53775
- // 指 confirm 只会被 confirm 自身闸拒——不路由(诚实缺席)。
54426
+ // T2 R5 + P-C1 T13:baseline 未确认(或已漂移)且阻塞集清零时,收口前的唯一缺口
54427
+ // 就是确认仪式——此刻任何任务内推进(closeout 判卷会被 BASELINE_NOT_CONFIRMED/
54428
+ // BASELINE_DRIFT 阻断)都先还这笔账。判据 = blocking_remaining(§6.9):豁免登记行
54429
+ // 在册(unknowns 总口径 > 0 而阻塞 0)照常路由;阻塞键在册时指 confirm 只会被
54430
+ // confirm 自身闸拒——不路由(诚实缺席);null 不可判 fail-closed 不路由。
53776
54431
  id: "R_BASELINE_NOT_READY",
53777
- when: (s) => s.baseline_unknowns_remaining === 0 && (s.baseline_gate_codes.includes("BASELINE_NOT_CONFIRMED") || s.baseline_gate_codes.includes("BASELINE_DRIFT")) ? true : false,
54432
+ when: (s) => s.baseline_blocking_remaining === 0 && (s.baseline_gate_codes.includes("BASELINE_NOT_CONFIRMED") || s.baseline_gate_codes.includes("BASELINE_DRIFT")) ? true : false,
53778
54433
  render: (s) => {
53779
54434
  if (s.baseline_gate_codes.includes("BASELINE_DRIFT")) {
53780
54435
  return {
@@ -53793,7 +54448,7 @@ var NEXT_ACTION_ROUTE_TABLE = [
53793
54448
  return {
53794
54449
  beat: "0",
53795
54450
  command: "pomaster baseline confirm",
53796
- reason: "baseline \u672A\u786E\u8BA4\uFF08unknowns \u5DF2\u5168\u9500\u8D26\u2014\u2014\u786E\u8BA4\u662F\u552F\u4E00\u5269\u4F59\u7F3A\u53E3\uFF1Bcloseout \u5224\u5377\u4F1A\u88AB BASELINE_NOT_CONFIRMED \u963B\u65AD\uFF09"
54451
+ reason: "baseline \u672A\u786E\u8BA4\uFF08\u963B\u585E\u96C6\u5DF2\u6E05\u96F6\u2014\u2014\u786E\u8BA4\u662F\u552F\u4E00\u5269\u4F59\u7F3A\u53E3\uFF1Bcloseout \u5224\u5377\u4F1A\u88AB BASELINE_NOT_CONFIRMED \u963B\u65AD\uFF09"
53797
54452
  };
53798
54453
  }
53799
54454
  },
@@ -54875,7 +55530,7 @@ function runtimeStorePaths(store) {
54875
55530
  }
54876
55531
 
54877
55532
  // packages/cli/dist/view.js
54878
- import { existsSync as existsSync11, readFileSync as readFileSync11, readdirSync as readdirSync17 } from "node:fs";
55533
+ import { existsSync as existsSync12, readFileSync as readFileSync12, readdirSync as readdirSync17 } from "node:fs";
54879
55534
  import { join as join7 } from "node:path";
54880
55535
  init_dist();
54881
55536
 
@@ -55419,18 +56074,18 @@ async function runViewTask(rootDir, input) {
55419
56074
  var DECISION_GRAPH_SIDECAR_FILENAME = "decision-graph.json";
55420
56075
  function scanConflictReviewItems(rootDir) {
55421
56076
  const baseDir = discoveryScratchpadsDirPath(rootDir);
55422
- if (!existsSync11(baseDir))
56077
+ if (!existsSync12(baseDir))
55423
56078
  return { items: [] };
55424
56079
  const items = [];
55425
56080
  for (const dirent of readdirSync17(baseDir, { withFileTypes: true })) {
55426
56081
  if (!dirent.isDirectory())
55427
56082
  continue;
55428
56083
  const sidecarPath = join7(discoveryScratchpadDirPath(rootDir, dirent.name), DECISION_GRAPH_SIDECAR_FILENAME);
55429
- if (!existsSync11(sidecarPath))
56084
+ if (!existsSync12(sidecarPath))
55430
56085
  continue;
55431
56086
  let graph;
55432
56087
  try {
55433
- graph = JSON.parse(readFileSync11(sidecarPath, "utf8"));
56088
+ graph = JSON.parse(readFileSync12(sidecarPath, "utf8"));
55434
56089
  } catch (err) {
55435
56090
  return {
55436
56091
  error: {
@@ -55636,7 +56291,7 @@ async function runViewDecision(rootDir, input) {
55636
56291
  }, emptyResult6);
55637
56292
  }
55638
56293
  const padDir = discoveryScratchpadDirPath(rootDir, input.discoveryId);
55639
- if (!existsSync11(padDir)) {
56294
+ if (!existsSync12(padDir)) {
55640
56295
  return failView(command, {
55641
56296
  code: "SCRATCHPAD_NOT_FOUND",
55642
56297
  message: `scratchpad \u4E0D\u5B58\u5728: ${toPosix(`${DISCOVERY_SCRATCHPADS_RELATIVE}/${input.discoveryId}`)}`,
@@ -55644,7 +56299,7 @@ async function runViewDecision(rootDir, input) {
55644
56299
  }, emptyResult6);
55645
56300
  }
55646
56301
  const sidecarPath = join7(padDir, "decision-graph.json");
55647
- if (!existsSync11(sidecarPath)) {
56302
+ if (!existsSync12(sidecarPath)) {
55648
56303
  return failView(command, {
55649
56304
  code: "DECISION_GRAPH_NOT_FOUND",
55650
56305
  message: `scratchpad ${input.discoveryId} \u65E0 decision-graph sidecar\uFF08${toPosix(`${DISCOVERY_SCRATCHPADS_RELATIVE}/${input.discoveryId}/decision-graph.json`)} \u7F3A\u5E2D\uFF09`,
@@ -55653,7 +56308,7 @@ async function runViewDecision(rootDir, input) {
55653
56308
  }
55654
56309
  let graph;
55655
56310
  try {
55656
- graph = JSON.parse(readFileSync11(sidecarPath, "utf8"));
56311
+ graph = JSON.parse(readFileSync12(sidecarPath, "utf8"));
55657
56312
  } catch (err) {
55658
56313
  return failView(command, {
55659
56314
  code: "SCHEMA_INVALID",
@@ -57886,7 +58541,7 @@ ${" ".repeat(18)}note: ${row2.note}`}`)
57886
58541
 
57887
58542
  // packages/cli/dist/exec-guard.js
57888
58543
  init_dist();
57889
- import { readFileSync as readFileSync23 } from "node:fs";
58544
+ import { readFileSync as readFileSync24 } from "node:fs";
57890
58545
  import { readFile as readFile12 } from "node:fs/promises";
57891
58546
  function isFATALCode(err) {
57892
58547
  return typeof err === "object" && err !== null && (err.reason === "unknown_prefix" || err.reason === "grammar");
@@ -57963,7 +58618,7 @@ async function runExecGuard(rootDir, input) {
57963
58618
  let text;
57964
58619
  if (input.attempt === "-") {
57965
58620
  try {
57966
- text = readFileSync23(0, "utf8");
58621
+ text = readFileSync24(0, "utf8");
57967
58622
  } catch (err) {
57968
58623
  return malformed("ATTEMPT_MALFORMED", `stdin \u8BFB\u53D6\u5931\u8D25\uFF1A${err instanceof Error ? err.message : String(err)}`, "stdin \u5F62\u6001\u8981\u6C42\u7BA1\u9053\u4F20\u5165 attempt JSON\uFF08echo \u2026 | pomaster exec-guard --attempt -\uFF09\u3002");
57969
58624
  }
@@ -58135,9 +58790,801 @@ async function runReconcile(rootDir, input) {
58135
58790
  ], [summary, ` hint: ${RECONCILE_DIRTY_HINT}`]);
58136
58791
  }
58137
58792
 
58793
+ // packages/cli/dist/recon.js
58794
+ init_dist2();
58795
+ init_dist();
58796
+ import { spawnSync as spawnSync14 } from "node:child_process";
58797
+ import { existsSync as existsSync19, mkdtempSync as mkdtempSync2, readdirSync as readdirSync19, readFileSync as readFileSync25, rmSync as rmSync12 } from "node:fs";
58798
+ import { tmpdir as tmpdir2 } from "node:os";
58799
+ import { join as join10, sep as sep2 } from "node:path";
58800
+ import { performance as performance21 } from "node:perf_hooks";
58801
+ var RECON_IMPORT_GRAPH_SENSOR_CAPABILITY = "SENSOR.BUILD.STATIC";
58802
+ var RECON_IMPORT_GRAPH_OPERATION = "scan_import_graph";
58803
+ var RECON_IMPORT_GRAPH_ADAPTER = "pomaster-cli";
58804
+ if (!SENSOR_ID_PATTERN.test(RECON_IMPORT_GRAPH_SENSOR_CAPABILITY)) {
58805
+ throw new Error(`RECON_IMPORT_GRAPH_SENSOR_CAPABILITY \u8BCD\u5F62\u6F02\u79FB\uFF08\u987B SENSOR.<DOMAIN>.<KIND>\uFF09\uFF1A${RECON_IMPORT_GRAPH_SENSOR_CAPABILITY}`);
58806
+ }
58807
+ var RECON_SOURCE_EXTENSIONS = /* @__PURE__ */ new Set([
58808
+ ".ts",
58809
+ ".tsx",
58810
+ ".js",
58811
+ ".jsx",
58812
+ ".mjs",
58813
+ ".cjs",
58814
+ ".vue"
58815
+ ]);
58816
+ var RECON_SKIP_DIRS = /* @__PURE__ */ new Set([
58817
+ "node_modules",
58818
+ "dist",
58819
+ ".git",
58820
+ "coverage",
58821
+ ".pomaster"
58822
+ ]);
58823
+ var RECON_UNMAPPED_PRESENTATION_CAP = 20;
58824
+ function collectReconSourceFiles(rootDir, dir, out) {
58825
+ let entries;
58826
+ try {
58827
+ entries = readdirSync19(dir, { withFileTypes: true });
58828
+ } catch {
58829
+ return;
58830
+ }
58831
+ for (const entry of entries) {
58832
+ const full = join10(dir, entry.name);
58833
+ if (entry.isDirectory()) {
58834
+ if (RECON_SKIP_DIRS.has(entry.name))
58835
+ continue;
58836
+ collectReconSourceFiles(rootDir, full, out);
58837
+ continue;
58838
+ }
58839
+ if (!entry.isFile())
58840
+ continue;
58841
+ const dot = entry.name.lastIndexOf(".");
58842
+ if (dot === -1 || !RECON_SOURCE_EXTENSIONS.has(entry.name.slice(dot)))
58843
+ continue;
58844
+ const relative3 = full.slice(rootDir.length).split(sep2).join("/").replace(/^\//, "");
58845
+ out.push(relative3);
58846
+ }
58847
+ }
58848
+ function allocateObservationId(observationsDir) {
58849
+ let max = 0;
58850
+ let names;
58851
+ try {
58852
+ names = readdirSync19(observationsDir);
58853
+ } catch {
58854
+ names = [];
58855
+ }
58856
+ for (const name of names) {
58857
+ const match = /^OBS-([0-9]+)\.json$/.exec(name);
58858
+ if (match !== null) {
58859
+ const value = Number(match[1]);
58860
+ if (Number.isFinite(value) && value > max)
58861
+ max = value;
58862
+ }
58863
+ }
58864
+ return `OBS-${String(max + 1).padStart(4, "0")}`;
58865
+ }
58866
+ function emptyReconResult() {
58867
+ return {
58868
+ observation: null,
58869
+ observation_id: null,
58870
+ receipt_path: null,
58871
+ source_files: null,
58872
+ objects_resolved: null,
58873
+ external_imports: null,
58874
+ unmapped_count: null,
58875
+ confidence: null,
58876
+ captured_at_seq: null,
58877
+ report_blob: null,
58878
+ unmapped_stdout_capped: false
58879
+ };
58880
+ }
58881
+ function reconFail(error) {
58882
+ return failOutcome("recon import-graph", emptyReconResult(), [error], [`recon import-graph: FAILED \u2014 ${error.code}
58883
+ hint: ${error.hint}`]);
58884
+ }
58885
+ var RECON_EMPTY_MAPPING = {};
58886
+ function observationRecordOf(receipt) {
58887
+ return {
58888
+ record_type: "observation_receipt",
58889
+ ...receipt,
58890
+ artifact_refs: artifactRefsToSnake(receipt.artifact_refs)
58891
+ };
58892
+ }
58893
+ async function runReconImportGraph(rootDir, input) {
58894
+ const executionResolution = resolveExecutionId(input.executionId, void 0);
58895
+ if ("fail" in executionResolution || executionResolution.executionId === null) {
58896
+ return reconFail({
58897
+ code: "SCHEMA_INVALID",
58898
+ message: "fail" in executionResolution ? executionResolution.fail : `execution_id \u7F3A\u5E2D\uFF08OBS \u56DE\u6267 execution_id \u5FC5\u586B\u2014\u2014\xA76.13 \u8BC1\u660E\u4E49\u52A1\uFF09`,
58899
+ hint: "\u5148 pomaster execution begin \u767B\u8BB0\u6267\u884C\u8EAB\u4EFD\uFF08AGX-n\uFF09\uFF0C\u518D\u4EE5 --execution-id \u4F20\u5165\uFF08S1 \u7981\u81EA\u9020\u8EAB\u4EFD\uFF09\u3002"
58900
+ });
58901
+ }
58902
+ const executionId = executionResolution.executionId;
58903
+ const initialized = await requireInitialized(rootDir);
58904
+ if ("error" in initialized)
58905
+ return reconFail(initialized.error);
58906
+ if (!existsSync19(`${executionsDirPath(rootDir)}/${executionId}.json`)) {
58907
+ return reconFail({
58908
+ code: "EXECUTION_NOT_FOUND",
58909
+ message: `execution_id \u672A\u767B\u8BB0\uFF08executions/ \u6863\u6848\u7F3A\u5931\uFF09\uFF1A${executionId}`,
58910
+ hint: "\u5148 pomaster execution begin \u767B\u8BB0\u6267\u884C\u8EAB\u4EFD\uFF08.pomaster/executions/AGX-*.json \u662F\u8EAB\u4EFD\u552F\u4E00\u4E8B\u5B9E\u6E90\uFF09\uFF1B\u5DF2\u5C01\u53E3\u6267\u884C\u5141\u8BB8\u4E8B\u540E\u8865\u5F55\u3002"
58911
+ });
58912
+ }
58913
+ const paths = buildStorePaths(rootDir);
58914
+ const rawFiles = [];
58915
+ collectReconSourceFiles(rootDir, rootDir, rawFiles);
58916
+ rawFiles.sort((a, b) => a < b ? -1 : a > b ? 1 : 0);
58917
+ const files = [];
58918
+ const readFailures = [];
58919
+ for (const relative3 of rawFiles) {
58920
+ try {
58921
+ files.push({ path: relative3, content: readFileSync25(join10(rootDir, relative3), "utf8") });
58922
+ } catch (error) {
58923
+ readFailures.push(`${relative3}: unreadable (${error instanceof Error ? error.message : String(error)})`);
58924
+ }
58925
+ }
58926
+ if (files.length === 0) {
58927
+ try {
58928
+ const observationId = allocateObservationId(paths.observationsDir);
58929
+ const receipt = buildObservationReceipt({
58930
+ observationId,
58931
+ executionId,
58932
+ sensorCapability: RECON_IMPORT_GRAPH_SENSOR_CAPABILITY,
58933
+ adapter: RECON_IMPORT_GRAPH_ADAPTER,
58934
+ operation: RECON_IMPORT_GRAPH_OPERATION,
58935
+ surface: "STRUCTURAL_REALITY",
58936
+ result: "INCONCLUSIVE",
58937
+ capturedAtSeq: initialized.seq,
58938
+ artifactRefs: [],
58939
+ normalizedFacts: [
58940
+ "recon_surface: import-graph",
58941
+ "source_files: 0",
58942
+ "zero_denominator: true"
58943
+ ]
58944
+ });
58945
+ const persisted = persistObservationRecord(paths.evidenceDir, observationRecordOf(receipt));
58946
+ const receiptPath = `${POMASTER_DIR}/evidence/${persisted.relativePath}`;
58947
+ return failOutcome("recon import-graph", {
58948
+ ...emptyReconResult(),
58949
+ observation: "INCONCLUSIVE",
58950
+ observation_id: receipt.observation_id,
58951
+ receipt_path: receiptPath,
58952
+ source_files: 0,
58953
+ captured_at_seq: initialized.seq
58954
+ }, [
58955
+ {
58956
+ code: "RECON_INCONCLUSIVE",
58957
+ message: `\u96F6\u6E90\u6587\u4EF6\uFF08\u96F6\u5206\u6BCD\uFF09\u2014\u2014INCONCLUSIVE \u8D1F\u503C\u515C\u5E95\u843D\u8D26\uFF0C\u4E0D\u4F2A\u9020\u7EFF\uFF1A${receiptPath}`,
58958
+ hint: "\u679A\u4E3E\u95ED\u5305 .ts/.tsx/.js/.jsx/.mjs/.cjs/.vue\uFF08\u8DF3\u8FC7 node_modules/dist/.git/coverage/.pomaster\uFF09\u2014\u2014\u786E\u8BA4\u5BBF\u4E3B\u6E90\u7801\u6839\u975E\u7A7A\u540E\u91CD\u8DD1\uFF1B\u96F6\u5206\u6BCD\u7981\u5F53\u6EE1\u5206\u3002"
58959
+ }
58960
+ ], [
58961
+ "recon import-graph: INCONCLUSIVE \u2014 \u96F6\u6E90\u6587\u4EF6\uFF08\u96F6\u5206\u6BCD\u7981\u5F53\u6EE1\u5206\uFF0C\u4E0D\u4F2A\u9020\u7EFF\uFF09",
58962
+ `observation receipt: ${receiptPath}\uFF08result=INCONCLUSIVE\uFF1Bartifact_refs \u7A7A\u2014\u2014\u65E0\u62A5\u544A blob \u53EF\u80CC\u4E66\uFF09`,
58963
+ "\u679A\u4E3E\u95ED\u5305\uFF1A.ts/.tsx/.js/.jsx/.mjs/.cjs/.vue\uFF08\u8DF3\u8FC7 node_modules/dist/.git/coverage/.pomaster\uFF09"
58964
+ ]);
58965
+ } catch (error) {
58966
+ if (error instanceof GovernanceError)
58967
+ return reconFail(governanceErrorToCliError(error));
58968
+ throw error;
58969
+ }
58970
+ }
58971
+ try {
58972
+ const sourceSha = sha256OfCanonical(files.map((file) => ({ path: file.path, content: file.content })));
58973
+ const analysis = analyzeImportGraph({
58974
+ files,
58975
+ mapping: RECON_EMPTY_MAPPING,
58976
+ sourceSha
58977
+ });
58978
+ const reportBytes = Buffer.from(`${JSON.stringify({
58979
+ recon_surface: "import-graph",
58980
+ report: analysis.report,
58981
+ external_imports: analysis.externalImports,
58982
+ unmapped: analysis.unmapped,
58983
+ scanned_files: files.map((file) => file.path),
58984
+ source_read_failures: readFailures
58985
+ }, null, 2)}
58986
+ `, "utf8");
58987
+ const blob = persistEvidenceArtifact(paths.evidenceDir, { media: "json", bytes: reportBytes });
58988
+ const observationId = allocateObservationId(paths.observationsDir);
58989
+ const receipt = buildObservationReceipt({
58990
+ observationId,
58991
+ executionId,
58992
+ sensorCapability: RECON_IMPORT_GRAPH_SENSOR_CAPABILITY,
58993
+ adapter: RECON_IMPORT_GRAPH_ADAPTER,
58994
+ operation: RECON_IMPORT_GRAPH_OPERATION,
58995
+ surface: "STRUCTURAL_REALITY",
58996
+ result: "OBSERVED",
58997
+ capturedAtSeq: initialized.seq,
58998
+ artifactRefs: [
58999
+ {
59000
+ sha256: blob.sha256,
59001
+ media: blob.media,
59002
+ byteSize: blob.byteSize,
59003
+ storagePath: blob.storagePath
59004
+ }
59005
+ ],
59006
+ normalizedFacts: [
59007
+ "recon_surface: import-graph",
59008
+ `source_files: ${String(files.length)}`,
59009
+ `objects_resolved: ${String(analysis.report.objects_resolved)}`,
59010
+ `external_imports: ${String(analysis.externalImports)}`,
59011
+ `unmapped: ${String(analysis.unmapped.length)}`,
59012
+ `edge_proposals_not_registered: ${String(analysis.edges.length)}`,
59013
+ `confidence: ${analysis.report.confidence}`,
59014
+ ...readFailures.length > 0 ? [`source_read_failures: ${String(readFailures.length)}`] : []
59015
+ ]
59016
+ });
59017
+ const persisted = persistObservationRecord(paths.evidenceDir, observationRecordOf(receipt));
59018
+ const receiptPath = `${POMASTER_DIR}/evidence/${persisted.relativePath}`;
59019
+ const human = [
59020
+ `recon import-graph: OBSERVED \u2014 ${String(files.length)} \u4E2A\u6E90\u6587\u4EF6\uFF08confidence ${analysis.report.confidence}\uFF09`,
59021
+ `mapping \u547D\u4E2D\uFF08objects_resolved\uFF09: ${String(analysis.report.objects_resolved)} \u2014\u2014 mapping \u6052\u7A7A\uFF08\u8001\u9879\u76EE\u65E0 governed id \u5206\u6BCD\uFF1Bunmapped \u6E05\u5355\u5373\u4EA7\u51FA\uFF09`,
59022
+ `externalImports\uFF08\u88F8\u5305\u540D import \u8BA1\u6570\uFF09: ${String(analysis.externalImports)}`,
59023
+ `unmapped: ${String(analysis.unmapped.length)} \u6761\uFF08\u7981\u9759\u9ED8\u4E22\u5F03\uFF1B\u5B8C\u6574\u6E05\u5355\u89C1 report blob\uFF09`
59024
+ ];
59025
+ for (const row2 of analysis.unmapped.slice(0, RECON_UNMAPPED_PRESENTATION_CAP)) {
59026
+ human.push(` - ${row2.source} -> ${row2.specifier} (${row2.reason})`);
59027
+ }
59028
+ if (analysis.unmapped.length > RECON_UNMAPPED_PRESENTATION_CAP) {
59029
+ human.push(` \u2026\uFF08\u5176\u4F59 ${String(analysis.unmapped.length - RECON_UNMAPPED_PRESENTATION_CAP)} \u6761\u89C1 report blob ${blob.storagePath}\uFF09`);
59030
+ }
59031
+ human.push(`report blob: ${blob.storagePath}\uFF08${blob.sha256}\uFF1Bmedia=json\uFF09`);
59032
+ human.push(`observation receipt: ${receiptPath}\uFF08result=OBSERVED\uFF1Bsurface=STRUCTURAL_REALITY\uFF1Bcaptured_at_seq=${String(initialized.seq)}\uFF09`);
59033
+ human.push(`CALLS \u8FB9\u63D0\u6848 ${String(analysis.edges.length)} \u6761\u96F6\u843D\u76D8\uFF08\u767B\u8BB0\u5F52\u6D88\u8D39\u65B9 relations.registerRelation\u2014\u2014\u672C\u6279\u4E0D\u8C03\u7528\uFF09`);
59034
+ const warnings = [];
59035
+ if (readFailures.length > 0) {
59036
+ warnings.push({
59037
+ code: "RECON_SOURCE_UNREADABLE",
59038
+ message: `${String(readFailures.length)} \u4E2A\u767B\u8BB0\u5728\u518C\u7684\u6E90\u6587\u4EF6\u8BFB\u53D6\u5931\u8D25\uFF08\u5DF2\u62AB\u9732\u975E\u9759\u9ED8\u8DF3\u8FC7\uFF1B\u4E0D\u8BA1\u5165\u626B\u63CF\u5206\u6BCD\uFF09\uFF1A${readFailures.join("; ")}`,
59039
+ hint: "\u6838\u67E5\u6587\u4EF6\u6743\u9650/\u5360\u7528\u540E\u91CD\u8DD1\uFF1B\u8BFB\u5931\u8D25\u6E05\u5355\u5DF2\u968F report blob \u843D\u76D8\uFF08source_read_failures\uFF09\u3002"
59040
+ });
59041
+ }
59042
+ return okOutcome("recon import-graph", {
59043
+ observation: "OBSERVED",
59044
+ observation_id: receipt.observation_id,
59045
+ receipt_path: receiptPath,
59046
+ source_files: files.length,
59047
+ objects_resolved: analysis.report.objects_resolved,
59048
+ external_imports: analysis.externalImports,
59049
+ unmapped_count: analysis.unmapped.length,
59050
+ confidence: analysis.report.confidence,
59051
+ captured_at_seq: initialized.seq,
59052
+ report_blob: {
59053
+ sha256: blob.sha256,
59054
+ storage_path: blob.storagePath,
59055
+ byte_size: blob.byteSize
59056
+ },
59057
+ unmapped_stdout_capped: analysis.unmapped.length > RECON_UNMAPPED_PRESENTATION_CAP
59058
+ }, human, warnings);
59059
+ } catch (error) {
59060
+ if (error instanceof GovernanceError)
59061
+ return reconFail(governanceErrorToCliError(error));
59062
+ throw error;
59063
+ }
59064
+ }
59065
+ var RECON_MIGRATION_STACKS = [
59066
+ "prisma",
59067
+ "flyway",
59068
+ "liquibase",
59069
+ "alembic",
59070
+ "django_style"
59071
+ ];
59072
+ var RECON_MIGRATION_STACK_WORD_FORMS = {
59073
+ prisma: "prisma/migrations/ + migration_lock.toml + <14\u4F4D\u65F6\u95F4\u6233>_<name> \u5B50\u76EE\u5F55",
59074
+ flyway: "db/migration/ + V*__*.sql",
59075
+ liquibase: "db.changelog.{xml,yaml,json} + changelog \u76EE\u5F55",
59076
+ alembic: "alembic/versions/ + alembic.ini",
59077
+ django_style: "migrations/ \u76EE\u5F55\uFF08\u6392\u9664 prisma/migrations \u8BCD\u5F62\u2014\u2014\u540C\u4E00\u7269\u7406\u76EE\u5F55\u7981\u53CC\u6808\u53CC\u8BA1\uFF09"
59078
+ };
59079
+ var RECON_PRISMA_MIGRATION_DIR = /^[0-9]{14}_.+/;
59080
+ var RECON_FLYWAY_FILE = /^V.+__.+\.sql$/;
59081
+ var RECON_LIQUIBASE_MARKER_BASENAMES = /* @__PURE__ */ new Set([
59082
+ "db.changelog.xml",
59083
+ "db.changelog.yaml",
59084
+ "db.changelog.json"
59085
+ ]);
59086
+ var RECON_MIGRATIONS_SKIP_DIRS = /* @__PURE__ */ new Set([
59087
+ ...RECON_SKIP_DIRS,
59088
+ ".venv",
59089
+ "venv",
59090
+ "vendor",
59091
+ "target",
59092
+ "build"
59093
+ ]);
59094
+ function scanHostTree(rootDir) {
59095
+ const files = [];
59096
+ const dirs = [];
59097
+ const unreadableDirs = [];
59098
+ const walk = (dir, relative3) => {
59099
+ let entries;
59100
+ try {
59101
+ entries = readdirSync19(dir, { withFileTypes: true });
59102
+ } catch {
59103
+ unreadableDirs.push(relative3 === "" ? "." : relative3);
59104
+ return;
59105
+ }
59106
+ for (const entry of entries) {
59107
+ const full = join10(dir, entry.name);
59108
+ const rel = relative3 === "" ? entry.name : `${relative3}/${entry.name}`;
59109
+ if (entry.isDirectory()) {
59110
+ if (RECON_MIGRATIONS_SKIP_DIRS.has(entry.name))
59111
+ continue;
59112
+ dirs.push(rel);
59113
+ walk(full, rel);
59114
+ continue;
59115
+ }
59116
+ if (!entry.isFile())
59117
+ continue;
59118
+ files.push(rel);
59119
+ }
59120
+ };
59121
+ walk(rootDir, "");
59122
+ const byAsc = (a, b) => a < b ? -1 : a > b ? 1 : 0;
59123
+ return {
59124
+ files: [...files].sort(byAsc),
59125
+ dirs: [...dirs].sort(byAsc),
59126
+ unreadableDirs: [...unreadableDirs].sort(byAsc)
59127
+ };
59128
+ }
59129
+ function basenameOf(posixPath) {
59130
+ const index = posixPath.lastIndexOf("/");
59131
+ return index === -1 ? posixPath : posixPath.slice(index + 1);
59132
+ }
59133
+ function parentOf(posixPath) {
59134
+ const index = posixPath.lastIndexOf("/");
59135
+ return index === -1 ? "" : posixPath.slice(0, index);
59136
+ }
59137
+ function isSuffixWordForm(dirPath, wordForm) {
59138
+ return dirPath === wordForm || dirPath.endsWith(`/${wordForm}`);
59139
+ }
59140
+ function filesUnderDir(files, dirPrefix) {
59141
+ const prefix = `${dirPrefix}/`;
59142
+ return files.filter((file) => file.startsWith(prefix));
59143
+ }
59144
+ function sortedUnique(values) {
59145
+ return [...new Set(values)].sort((a, b) => a < b ? -1 : a > b ? 1 : 0);
59146
+ }
59147
+ function detectMigrationStacks(scan) {
59148
+ const prismaRoots = scan.dirs.filter((dir) => isSuffixWordForm(dir, "prisma/migrations"));
59149
+ const prismaMarkers = scan.files.filter((file) => prismaRoots.includes(parentOf(file)) && basenameOf(file) === "migration_lock.toml");
59150
+ const prismaMigrationDirs = prismaRoots.flatMap((root) => scan.dirs.filter((dir) => dir.startsWith(`${root}/`) && RECON_PRISMA_MIGRATION_DIR.test(basenameOf(dir))));
59151
+ const prismaFiles = prismaMigrationDirs.flatMap((dir) => filesUnderDir(scan.files, dir));
59152
+ const flywayRoots = scan.dirs.filter((dir) => isSuffixWordForm(dir, "db/migration"));
59153
+ const flywayFiles = flywayRoots.flatMap((root) => filesUnderDir(scan.files, root).filter((file) => RECON_FLYWAY_FILE.test(basenameOf(file))));
59154
+ const liquibaseMarkers = scan.files.filter((file) => RECON_LIQUIBASE_MARKER_BASENAMES.has(basenameOf(file)));
59155
+ const liquibaseDirs = scan.dirs.filter((dir) => basenameOf(dir) === "changelog");
59156
+ const liquibaseFiles = liquibaseDirs.flatMap((dir) => filesUnderDir(scan.files, dir)).filter((file) => !liquibaseMarkers.includes(file));
59157
+ const alembicMarkers = scan.files.filter((file) => basenameOf(file) === "alembic.ini");
59158
+ const alembicVersionDirs = scan.dirs.filter((dir) => isSuffixWordForm(dir, "alembic/versions"));
59159
+ const alembicFiles = alembicVersionDirs.flatMap((dir) => filesUnderDir(scan.files, dir));
59160
+ const djangoDirs = scan.dirs.filter((dir) => basenameOf(dir) === "migrations" && !isSuffixWordForm(dir, "prisma/migrations"));
59161
+ const djangoFiles = djangoDirs.flatMap((dir) => filesUnderDir(scan.files, dir));
59162
+ const row2 = (stack, detected, migrationFiles, markerFiles) => ({
59163
+ stack,
59164
+ detected,
59165
+ migration_files: sortedUnique(migrationFiles),
59166
+ marker_files: sortedUnique(markerFiles)
59167
+ });
59168
+ return [
59169
+ row2("prisma", prismaRoots.length > 0, prismaFiles, prismaMarkers),
59170
+ row2("flyway", flywayRoots.length > 0, flywayFiles, []),
59171
+ row2("liquibase", liquibaseMarkers.length > 0 || liquibaseDirs.length > 0, liquibaseFiles, liquibaseMarkers),
59172
+ row2("alembic", alembicMarkers.length > 0 || alembicVersionDirs.length > 0, alembicFiles, alembicMarkers),
59173
+ row2("django_style", djangoDirs.length > 0, djangoFiles, [])
59174
+ ];
59175
+ }
59176
+ function allocateEnvironmentReceiptId(observationsDir) {
59177
+ let max = 0;
59178
+ let names;
59179
+ try {
59180
+ names = readdirSync19(observationsDir);
59181
+ } catch {
59182
+ names = [];
59183
+ }
59184
+ for (const name of names) {
59185
+ const match = /^ENVREC-([0-9]+)\.json$/.exec(name);
59186
+ if (match !== null) {
59187
+ const value = Number(match[1]);
59188
+ if (Number.isFinite(value) && value > max)
59189
+ max = value;
59190
+ }
59191
+ }
59192
+ return `ENVREC-${String(max + 1).padStart(4, "0")}`;
59193
+ }
59194
+ function emptyReconMigrationsResult() {
59195
+ return {
59196
+ observation: null,
59197
+ receipt_id: null,
59198
+ receipt_path: null,
59199
+ captured_at_seq: null,
59200
+ stacks: [],
59201
+ detected_stacks: null,
59202
+ scanned_files: null,
59203
+ scanned_dirs: null,
59204
+ unreadable_dirs: []
59205
+ };
59206
+ }
59207
+ function reconMigrationsFail(error) {
59208
+ return failOutcome("recon migrations", emptyReconMigrationsResult(), [error], [`recon migrations: FAILED \u2014 ${error.code}
59209
+ hint: ${error.hint}`]);
59210
+ }
59211
+ function scanDenominatorLine(scan) {
59212
+ return `\u626B\u63CF\u5206\u6BCD: ${String(scan.files.length)} \u6587\u4EF6/${String(scan.dirs.length)} \u76EE\u5F55\uFF08\u8DF3\u8FC7 node_modules/dist/.git/coverage/.pomaster + .venv/venv/vendor/target/build \u4F9D\u8D56\u4E0E\u6784\u5EFA\u4EA7\u7269\uFF09`;
59213
+ }
59214
+ function stackWordFormLines() {
59215
+ return RECON_MIGRATION_STACKS.map((stack) => ` - ${stack}: ${RECON_MIGRATION_STACK_WORD_FORMS[stack]}`);
59216
+ }
59217
+ function unreadableWarnings(scan) {
59218
+ if (scan.unreadableDirs.length === 0)
59219
+ return [];
59220
+ return [
59221
+ {
59222
+ code: "RECON_SCAN_UNREADABLE",
59223
+ message: `${String(scan.unreadableDirs.length)} \u4E2A\u76EE\u5F55\u4E0D\u53EF\u8BFB\uFF08\u5DF2\u62AB\u9732\u975E\u9759\u9ED8\u8DF3\u8FC7\uFF1B\u5176\u5185\u5BB9\u7F3A\u5E2D\u4E8E\u76D8\u70B9\u5206\u6BCD\uFF09\uFF1A${scan.unreadableDirs.join("; ")}`,
59224
+ hint: "\u6838\u67E5\u76EE\u5F55\u6743\u9650/\u5360\u7528\u540E\u91CD\u8DD1\uFF1B\u4E0D\u53EF\u8BFB\u6E05\u5355\u5DF2\u968F result.unreadable_dirs \u643A\u5E26\u3002"
59225
+ }
59226
+ ];
59227
+ }
59228
+ async function runReconMigrations(rootDir, input) {
59229
+ const executionResolution = resolveExecutionId(input.executionId, void 0);
59230
+ if ("fail" in executionResolution || executionResolution.executionId === null) {
59231
+ return reconMigrationsFail({
59232
+ code: "SCHEMA_INVALID",
59233
+ message: "fail" in executionResolution ? executionResolution.fail : `execution_id \u7F3A\u5E2D\uFF08ENVREC \u56DE\u6267 execution_id \u5FC5\u586B\u2014\u2014\xA76.7 \u901A\u8DEF\u951A\uFF09`,
59234
+ hint: "\u5148 pomaster execution begin \u767B\u8BB0\u6267\u884C\u8EAB\u4EFD\uFF08AGX-n\uFF09\uFF0C\u518D\u4EE5 --execution-id \u4F20\u5165\uFF08S1 \u7981\u81EA\u9020\u8EAB\u4EFD\uFF09\u3002"
59235
+ });
59236
+ }
59237
+ const executionId = executionResolution.executionId;
59238
+ const initialized = await requireInitialized(rootDir);
59239
+ if ("error" in initialized)
59240
+ return reconMigrationsFail(initialized.error);
59241
+ if (!existsSync19(`${executionsDirPath(rootDir)}/${executionId}.json`)) {
59242
+ return reconMigrationsFail({
59243
+ code: "EXECUTION_NOT_FOUND",
59244
+ message: `execution_id \u672A\u767B\u8BB0\uFF08executions/ \u6863\u6848\u7F3A\u5931\uFF09\uFF1A${executionId}`,
59245
+ hint: "\u5148 pomaster execution begin \u767B\u8BB0\u6267\u884C\u8EAB\u4EFD\uFF08.pomaster/executions/AGX-*.json \u662F\u8EAB\u4EFD\u552F\u4E00\u4E8B\u5B9E\u6E90\uFF09\uFF1B\u5DF2\u5C01\u53E3\u6267\u884C\u5141\u8BB8\u4E8B\u540E\u8865\u5F55\u3002"
59246
+ });
59247
+ }
59248
+ const paths = buildStorePaths(rootDir);
59249
+ const scan = scanHostTree(rootDir);
59250
+ const stacks = detectMigrationStacks(scan);
59251
+ const detectedStacks = stacks.filter((row2) => row2.detected).length;
59252
+ if (detectedStacks === 0) {
59253
+ return failOutcome("recon migrations", {
59254
+ ...emptyReconMigrationsResult(),
59255
+ observation: "NOT_RUN",
59256
+ stacks,
59257
+ detected_stacks: 0,
59258
+ scanned_files: scan.files.length,
59259
+ scanned_dirs: scan.dirs.length,
59260
+ unreadable_dirs: scan.unreadableDirs
59261
+ }, [
59262
+ {
59263
+ code: "RECON_MIGRATIONS_NOT_RUN",
59264
+ message: "\u4E94\u6808 migration \u8BCD\u5F62\u9762\u5168\u7F3A\u5E2D\uFF08prisma/flyway/liquibase/alembic/django_style\uFF09\u2014\u2014\u672C\u8DD1\u96F6\u76D8\u70B9\u4EA7\u51FA\uFF08\u4E0D\u4F2A\u9020\u7A7A\u8DD1\u7EFF\uFF09",
59265
+ hint: "\u82E5\u9879\u76EE\u786E\u6709 migration\uFF0C\u591A\u534A\u7ECF\u8BCD\u5F62\u9762\u5916\u6808\u627F\u8F7D\uFF08knex/typeorm/golang-migrate/rails db/migrate \u7B49\u2014\u2014\u672C\u6279\u6E05\u5355\u4E3A\u5C01\u95ED\u679A\u4E3E\uFF09\uFF1B\u7F3A\u5E2D = \u65E0\u76D8\u70B9\u4EA7\u51FA\uFF0C\u4E0D\u662F\u300C\u65E0 migration\u300D\u65AD\u8A00\u3002\u786E\u8BA4\u5BBF\u4E3B\u6839\u540E\u91CD\u8DD1\u3002"
59266
+ }
59267
+ ], [
59268
+ "recon migrations: NOT_RUN \u2014 \u4E94\u6808\u8BCD\u5F62\u9762\u5168\u7F3A\u5E2D\uFF08\u96F6\u76D8\u70B9\u4EA7\u51FA\uFF0C\u4E0D\u4F2A\u9020\u7A7A\u8DD1\u7EFF\uFF09",
59269
+ scanDenominatorLine(scan),
59270
+ ...stackWordFormLines(),
59271
+ "\u96F6\u843D\u76D8\uFF1A\u65E0 ENVREC \u56DE\u6267\u4EA7\u51FA\uFF08NOT_RUN \u65E0\u8DD1\u8BED\u4E49\u2014\u2014memory-harvest \u76EE\u5F55\u7F3A\u5E2D\u5148\u4F8B\u540C\u65CF\uFF09"
59272
+ ], unreadableWarnings(scan));
59273
+ }
59274
+ try {
59275
+ const receipt = buildEnvironmentReceipt({
59276
+ // observed 侧:repository_ref 是唯一诚实在场项(被盘点的 worktree 身份);
59277
+ // 其余六项实测未确认 → null 显式缺席(禁占位词冒充——Case H 诚实形态)。
59278
+ environment_ref: null,
59279
+ repository_ref: toPosix(rootDir),
59280
+ revision_ref: null,
59281
+ build_identity: null,
59282
+ runtime_instance: null,
59283
+ base_url: null,
59284
+ dataset_ref: null,
59285
+ auth_role: null,
59286
+ feature_flags: null
59287
+ }, executionId, "WRONG_OR_UNVERIFIED_INSTANCE");
59288
+ const recordId = allocateEnvironmentReceiptId(paths.observationsDir);
59289
+ const persisted = persistObservationRecord(paths.evidenceDir, { record_type: "environment_receipt", ...receipt }, { recordId });
59290
+ const receiptPath = `${POMASTER_DIR}/evidence/${persisted.relativePath}`;
59291
+ const human = [
59292
+ `recon migrations: OBSERVED \u2014 ${String(detectedStacks)}/${String(RECON_MIGRATION_STACKS.length)} \u6808\u8BCD\u5F62\u9762\u5728\u573A\uFF08ENVREC ${recordId}\uFF09`,
59293
+ scanDenominatorLine(scan)
59294
+ ];
59295
+ for (const row2 of stacks) {
59296
+ if (!row2.detected) {
59297
+ human.push(` ${row2.stack}: \u8BCD\u5F62\u7F3A\u5E2D\uFF08${RECON_MIGRATION_STACK_WORD_FORMS[row2.stack]}\uFF09`);
59298
+ continue;
59299
+ }
59300
+ const markerNote = row2.marker_files.length > 0 ? ` + ${String(row2.marker_files.length)} \u6807\u8BB0\uFF08${row2.marker_files.join(", ")}\uFF09` : "";
59301
+ human.push(` ${row2.stack}: \u547D\u4E2D \u2014 ${String(row2.migration_files.length)} migration \u5355\u5143${markerNote}`);
59302
+ for (const file of row2.migration_files)
59303
+ human.push(` - ${file}`);
59304
+ }
59305
+ human.push(`receipt: ${receiptPath}\uFF08record_type=environment_receipt\uFF1Bdoctor_verdict=WRONG_OR_UNVERIFIED_INSTANCE\u2014\u2014\u7EAF\u8BFB\u76D8\u76D8\u70B9\u4E0D\u786E\u8BA4 runtime \u5B9E\u4F8B\u8EAB\u4EFD\uFF0C\xA76.7 \u5B9E\u6D4B null \u539F\u6837\u4FDD\u7559\uFF09`);
59306
+ human.push("\u76D8\u70B9\u4E0D\u78B0 stack \u5206\u6BCD\uFF1A\u540E\u7AEF\u6808\u952E\u4ECD Owner \u95EE\u5377\u9762\uFF08\u96F6 stack.yaml \u5199\u53E3\u2014\u2014\u5B57\u8282\u5FEB\u7167\u6D4B\u8BD5\u9489\uFF09");
59307
+ human.push("\u4E94\u6808\u5206\u6BCD\u6052\u5168\u5448\u73B0\uFF1B\u8BCD\u5F62\u7F3A\u5E2D \u2260 migration \u7F3A\u5E2D\uFF08knex/typeorm/golang-migrate \u7B49\u8BCD\u5F62\u9762\u5916\u6808\u4E0D\u5728\u672C\u6279\u6E05\u5355\u2014\u2014\u76D8\u70B9\u662F\u8BCD\u5F62\u679A\u4E3E\u975E stack \u65AD\u8A00\uFF09");
59308
+ return okOutcome("recon migrations", {
59309
+ observation: "OBSERVED",
59310
+ receipt_id: recordId,
59311
+ receipt_path: receiptPath,
59312
+ captured_at_seq: initialized.seq,
59313
+ stacks,
59314
+ detected_stacks: detectedStacks,
59315
+ scanned_files: scan.files.length,
59316
+ scanned_dirs: scan.dirs.length,
59317
+ unreadable_dirs: scan.unreadableDirs
59318
+ }, human, unreadableWarnings(scan));
59319
+ } catch (error) {
59320
+ if (error instanceof GovernanceError)
59321
+ return reconMigrationsFail(governanceErrorToCliError(error));
59322
+ throw error;
59323
+ }
59324
+ }
59325
+ var RECON_SBOM_TOOL = "cdxgen";
59326
+ var RECON_SBOM_INSTALL_HINT = "npm install -g @cyclonedx/cdxgen\uFF08Apache-2.0\uFF09\u540E\u91CD\u8DD1\uFF1B\u6216\u786E\u8BA4 PATH \u542B cdxgen \u53EF\u6267\u884C\u4F53";
59327
+ var RECON_SBOM_SENSOR_CAPABILITY = "SENSOR.BUILD.STATIC";
59328
+ var RECON_SBOM_OPERATION = "scan_sbom";
59329
+ var RECON_SBOM_ADAPTER = "cdxgen";
59330
+ var RECON_SBOM_TIMEOUT_MS = 3e5;
59331
+ var CYCLONEDX_BOM_FORMAT = "CycloneDX";
59332
+ if (!SENSOR_ID_PATTERN.test(RECON_SBOM_SENSOR_CAPABILITY)) {
59333
+ throw new Error(`RECON_SBOM_SENSOR_CAPABILITY \u8BCD\u5F62\u6F02\u79FB\uFF08\u987B SENSOR.<DOMAIN>.<KIND>\uFF09\uFF1A${RECON_SBOM_SENSOR_CAPABILITY}`);
59334
+ }
59335
+ var reconSbomSpawn = (command, options) => {
59336
+ const startedAt = performance21.now();
59337
+ const res = spawnSync14(command, {
59338
+ shell: true,
59339
+ cwd: options.cwd,
59340
+ timeout: options.timeoutMs,
59341
+ encoding: "utf8",
59342
+ maxBuffer: SPAWN_MAX_BUFFER_BYTES,
59343
+ windowsHide: true,
59344
+ env: stripQuotesFromPathEnv({ ...process.env })
59345
+ });
59346
+ const externalMs = Math.max(0, Math.round(performance21.now() - startedAt));
59347
+ return {
59348
+ status: res.status,
59349
+ stdout: res.stdout ?? "",
59350
+ stderr: res.stderr ?? "",
59351
+ error: res.error?.message ?? null,
59352
+ externalMs
59353
+ };
59354
+ };
59355
+ function parseCycloneDxBom(bytes) {
59356
+ let root;
59357
+ try {
59358
+ root = JSON.parse(bytes.toString("utf8"));
59359
+ } catch {
59360
+ return null;
59361
+ }
59362
+ if (root === null || typeof root !== "object" || Array.isArray(root))
59363
+ return null;
59364
+ const record = root;
59365
+ if (record["bomFormat"] !== CYCLONEDX_BOM_FORMAT)
59366
+ return null;
59367
+ const specVersion = record["specVersion"];
59368
+ if (typeof specVersion !== "string" || /^[0-9]+\.[0-9]+/.test(specVersion) === false)
59369
+ return null;
59370
+ const components = record["components"];
59371
+ const dependencies = record["dependencies"];
59372
+ if (!Array.isArray(components) || !Array.isArray(dependencies))
59373
+ return null;
59374
+ return {
59375
+ bom_format: CYCLONEDX_BOM_FORMAT,
59376
+ spec_version: specVersion,
59377
+ components,
59378
+ dependencies
59379
+ };
59380
+ }
59381
+ function emptyReconSbomResult() {
59382
+ return {
59383
+ observation: null,
59384
+ observation_id: null,
59385
+ receipt_path: null,
59386
+ bom_format: null,
59387
+ spec_version: null,
59388
+ components: null,
59389
+ dependencies: null,
59390
+ tool_exit: null,
59391
+ tool_path: null,
59392
+ captured_at_seq: null,
59393
+ bom_blob: null
59394
+ };
59395
+ }
59396
+ function reconSbomFail(error) {
59397
+ return failOutcome("recon sbom", emptyReconSbomResult(), [error], [`recon sbom: FAILED \u2014 ${error.code}
59398
+ hint: ${error.hint}`]);
59399
+ }
59400
+ async function runReconSbom(rootDir, input) {
59401
+ const executionResolution = resolveExecutionId(input.executionId, void 0);
59402
+ if ("fail" in executionResolution || executionResolution.executionId === null) {
59403
+ return reconSbomFail({
59404
+ code: "SCHEMA_INVALID",
59405
+ message: "fail" in executionResolution ? executionResolution.fail : `execution_id \u7F3A\u5E2D\uFF08OBS \u56DE\u6267 execution_id \u5FC5\u586B\u2014\u2014\xA76.13 \u8BC1\u660E\u4E49\u52A1\uFF09`,
59406
+ hint: "\u5148 pomaster execution begin \u767B\u8BB0\u6267\u884C\u8EAB\u4EFD\uFF08AGX-n\uFF09\uFF0C\u518D\u4EE5 --execution-id \u4F20\u5165\uFF08S1 \u7981\u81EA\u9020\u8EAB\u4EFD\uFF09\u3002"
59407
+ });
59408
+ }
59409
+ const executionId = executionResolution.executionId;
59410
+ const initialized = await requireInitialized(rootDir);
59411
+ if ("error" in initialized)
59412
+ return reconSbomFail(initialized.error);
59413
+ if (!existsSync19(`${executionsDirPath(rootDir)}/${executionId}.json`)) {
59414
+ return reconSbomFail({
59415
+ code: "EXECUTION_NOT_FOUND",
59416
+ message: `execution_id \u672A\u767B\u8BB0\uFF08executions/ \u6863\u6848\u7F3A\u5931\uFF09\uFF1A${executionId}`,
59417
+ hint: "\u5148 pomaster execution begin \u767B\u8BB0\u6267\u884C\u8EAB\u4EFD\uFF08.pomaster/executions/AGX-*.json \u662F\u8EAB\u4EFD\u552F\u4E00\u4E8B\u5B9E\u6E90\uFF09\uFF1B\u5DF2\u5C01\u53E3\u6267\u884C\u5141\u8BB8\u4E8B\u540E\u8865\u5F55\u3002"
59418
+ });
59419
+ }
59420
+ const paths = buildStorePaths(rootDir);
59421
+ const probe = input.inject?.executableProbe ?? ((executable) => findExecutableOnPath(executable, platformDetectorFacts(rootDir)));
59422
+ const spawnFn = input.inject?.spawnFn ?? reconSbomSpawn;
59423
+ const toolPath = probe(RECON_SBOM_TOOL);
59424
+ if (toolPath === null) {
59425
+ return failOutcome("recon sbom", emptyReconSbomResult(), [
59426
+ {
59427
+ code: "RECON_SBOM_NOT_INSTALLED",
59428
+ message: `${RECON_SBOM_TOOL} \u4E0D\u5728 PATH\uFF08SBOM \u91C7\u96C6\u817F\u5DE5\u5177\u7F3A\u5E2D\u2014\u2014\u663E\u5F0F\u7F3A\u5E2D\u4E0D\u4F2A\u9020\u7A7A\u8DD1\uFF09`,
59429
+ hint: RECON_SBOM_INSTALL_HINT
59430
+ }
59431
+ ], [
59432
+ "recon sbom: NOT_INSTALLED \u2014 cdxgen \u4E0D\u5728 PATH\uFF08\u5DE5\u5177\u7F3A\u5E2D\u663E\u5F0F\u5448\u73B0\uFF0C\u4E0D\u4F2A\u9020\uFF09",
59433
+ `install: ${RECON_SBOM_INSTALL_HINT}`
59434
+ ]);
59435
+ }
59436
+ const tmpDir = mkdtempSync2(join10(tmpdir2(), "pomaster-recon-sbom-"));
59437
+ try {
59438
+ const outPath = join10(tmpDir, "bom.json");
59439
+ const command = `${RECON_SBOM_TOOL} -r -o "${outPath}" "${rootDir}"`;
59440
+ const run = spawnFn(command, { cwd: rootDir, timeoutMs: RECON_SBOM_TIMEOUT_MS });
59441
+ const stderrSnippet = run.stderr.trim().slice(0, 200);
59442
+ if (run.error !== null || run.status === null) {
59443
+ return failOutcome("recon sbom", { ...emptyReconSbomResult(), tool_exit: run.status, tool_path: toolPath }, [
59444
+ {
59445
+ code: "RECON_SBOM_NOT_RUN",
59446
+ message: `${RECON_SBOM_TOOL} \u5B50\u8FDB\u7A0B\u672A\u80FD\u6267\u884C\uFF08status=${String(run.status)}, error=${run.error ?? "unknown"}\uFF09\u2014\u2014\u5DE5\u5177\u6267\u884C\u5931\u8D25\u96F6\u843D\u76D8\uFF08\u4E0D\u4F2A\u9020\u7A7A\u8DD1\u7EFF\uFF09${stderrSnippet.length > 0 ? `\uFF1Bstderr \u6458\u5F55\uFF1A${stderrSnippet}` : ""}`,
59447
+ hint: "\u6838\u67E5 cdxgen \u53EF\u7528\u6027\uFF08cdxgen --version\uFF09\u540E\u91CD\u8DD1\uFF1B\u8D85\u65F6\u4E0A\u754C 300s\u2014\u2014\u5927\u578B\u4ED3\u53EF\u91CD\u8DD1\u4E00\u6B21\u6392\u9664\u5076\u53D1\u3002"
59448
+ }
59449
+ ], [
59450
+ `recon sbom: NOT_RUN \u2014 ${RECON_SBOM_TOOL} \u5B50\u8FDB\u7A0B\u672A\u80FD\u6267\u884C\uFF1B\u96F6\u843D\u76D8\u4E0D\u4F2A\u9020\u7A7A\u8DD1\u7EFF`,
59451
+ ...stderrSnippet.length > 0 ? [`stderr \u6458\u5F55: ${stderrSnippet}`] : []
59452
+ ]);
59453
+ }
59454
+ if (run.status !== 0) {
59455
+ return failOutcome("recon sbom", { ...emptyReconSbomResult(), tool_exit: run.status, tool_path: toolPath }, [
59456
+ {
59457
+ code: "RECON_SBOM_NOT_RUN",
59458
+ message: `${RECON_SBOM_TOOL} \u6267\u884C\u5931\u8D25\uFF08exit=${String(run.status)}\uFF09\u2014\u2014\u5DE5\u5177\u6267\u884C\u9519\u8BEF\u96F6\u843D\u76D8\uFF08\u4E0D\u4F2A\u9020\u7A7A\u8DD1\u7EFF\uFF09${stderrSnippet.length > 0 ? `\uFF1Bstderr \u6458\u5F55\uFF1A${stderrSnippet}` : ""}`,
59459
+ hint: "\u6838\u67E5 cdxgen \u53EF\u7528\u6027\uFF08cdxgen --version\uFF09\u4E0E\u5BBF\u4E3B\u9879\u76EE\u53EF\u8BFB\u6027\u540E\u91CD\u8DD1\uFF1B\u8D85\u65F6\u4E0A\u754C 300s\u3002"
59460
+ }
59461
+ ], [
59462
+ `recon sbom: NOT_RUN \u2014 ${RECON_SBOM_TOOL} exit ${String(run.status)}\uFF08\u5DE5\u5177\u6267\u884C\u9519\u8BEF\uFF09\uFF1B\u96F6\u843D\u76D8\u4E0D\u4F2A\u9020\u7A7A\u8DD1\u7EFF`,
59463
+ ...stderrSnippet.length > 0 ? [`stderr \u6458\u5F55: ${stderrSnippet}`] : []
59464
+ ]);
59465
+ }
59466
+ if (!existsSync19(outPath)) {
59467
+ return failOutcome("recon sbom", { ...emptyReconSbomResult(), tool_exit: run.status, tool_path: toolPath }, [
59468
+ {
59469
+ code: "RECON_SBOM_NOT_RUN",
59470
+ message: `${RECON_SBOM_TOOL} exit 0 \u4F46 BOM \u4EA7\u51FA\u6587\u4EF6\u7F3A\u5E2D\uFF08-o ${outPath} \u672A\u843D\u76D8\uFF09\u2014\u2014\u96F6\u89C2\u5BDF\u53EF\u505A\uFF0C\u96F6\u843D\u76D8\uFF08\u4E0D\u4F2A\u9020\u7A7A\u8DD1\u7EFF\uFF09`,
59471
+ hint: "\u6838\u67E5 cdxgen \u7248\u672C\u5BF9 `-r -o <file> <root>` \u8BCD\u5F62\u7684\u517C\u5BB9\u6027\u540E\u91CD\u8DD1\u3002"
59472
+ }
59473
+ ], [`recon sbom: NOT_RUN \u2014 exit 0 \u4F46 BOM \u4EA7\u51FA\u6587\u4EF6\u7F3A\u5E2D\uFF1B\u96F6\u843D\u76D8\u4E0D\u4F2A\u9020\u7A7A\u8DD1\u7EFF`]);
59474
+ }
59475
+ let bomBytes = null;
59476
+ try {
59477
+ bomBytes = readFileSync25(outPath);
59478
+ } catch {
59479
+ bomBytes = null;
59480
+ }
59481
+ const bom = bomBytes === null ? null : parseCycloneDxBom(bomBytes);
59482
+ if (bomBytes === null || bom === null) {
59483
+ const receipt2 = buildObservationReceipt({
59484
+ observationId: allocateObservationId(paths.observationsDir),
59485
+ executionId,
59486
+ sensorCapability: RECON_SBOM_SENSOR_CAPABILITY,
59487
+ adapter: RECON_SBOM_ADAPTER,
59488
+ operation: RECON_SBOM_OPERATION,
59489
+ surface: "STRUCTURAL_REALITY",
59490
+ result: "INCONCLUSIVE",
59491
+ capturedAtSeq: initialized.seq,
59492
+ artifactRefs: [],
59493
+ normalizedFacts: [
59494
+ "recon_surface: sbom",
59495
+ ...bomBytes === null ? ["bom_unreadable: true"] : ["bom_parse_failed: true", `bom_byte_size: ${String(bomBytes.length)}`],
59496
+ `tool_exit: ${String(run.status)}`,
59497
+ "stack_candidates_not_registered: true"
59498
+ ]
59499
+ });
59500
+ const persisted2 = persistObservationRecord(paths.evidenceDir, observationRecordOf(receipt2));
59501
+ const receiptPath2 = `${POMASTER_DIR}/evidence/${persisted2.relativePath}`;
59502
+ return failOutcome("recon sbom", {
59503
+ ...emptyReconSbomResult(),
59504
+ observation: "INCONCLUSIVE",
59505
+ observation_id: receipt2.observation_id,
59506
+ receipt_path: receiptPath2,
59507
+ tool_exit: run.status,
59508
+ tool_path: toolPath,
59509
+ captured_at_seq: initialized.seq
59510
+ }, [
59511
+ {
59512
+ code: "RECON_SBOM_INCONCLUSIVE",
59513
+ message: `BOM \u56DE\u8BFB\u5931\u8D25\uFF08${bomBytes === null ? "\u4EA7\u51FA\u6587\u4EF6\u4E0D\u53EF\u8BFB" : "\u89E3\u6790\u5931\u8D25/\u8BCD\u5F62\u6F02\u79FB"}\uFF09\u2014\u2014INCONCLUSIVE \u8D1F\u503C\u515C\u5E95\u843D\u8D26\uFF0C\u4E0D\u4F2A\u9020\u7EFF\uFF1A${receiptPath2}`,
59514
+ hint: "\u6838\u67E5 cdxgen \u7248\u672C\u4EA7\u51FA\u8BCD\u5F62\uFF08bomFormat=CycloneDX + specVersion + components[]/dependencies[] \u6570\u7EC4\u4F4D\uFF09\u540E\u91CD\u8DD1\uFF1B\u6B8B\u7F3A\u4EA7\u51FA\u4E0D\u6309\u9ED8\u8BA4\u503C\u8BA1\u6570\u3002"
59515
+ }
59516
+ ], [
59517
+ "recon sbom: INCONCLUSIVE \u2014 BOM \u56DE\u8BFB\u5931\u8D25\uFF08\u89E3\u6790\u5931\u8D25/\u8BCD\u5F62\u6F02\u79FB\uFF0C\u8D1F\u503C\u515C\u5E95\u843D\u8D26\u4E0D\u4F2A\u9020\u7EFF\uFF09",
59518
+ `observation receipt: ${receiptPath2}\uFF08result=INCONCLUSIVE\uFF1Bartifact_refs \u7A7A\u2014\u2014\u6B8B\u7F3A\u4EA7\u51FA\u4E0D\u662F\u8BC1\u636E\uFF0C\u65E0 blob \u53EF\u80CC\u4E66\uFF09`
59519
+ ]);
59520
+ }
59521
+ const blob = persistEvidenceArtifact(paths.evidenceDir, { media: "json", bytes: bomBytes });
59522
+ const observationId = allocateObservationId(paths.observationsDir);
59523
+ const receipt = buildObservationReceipt({
59524
+ observationId,
59525
+ executionId,
59526
+ sensorCapability: RECON_SBOM_SENSOR_CAPABILITY,
59527
+ adapter: RECON_SBOM_ADAPTER,
59528
+ operation: RECON_SBOM_OPERATION,
59529
+ surface: "STRUCTURAL_REALITY",
59530
+ result: "OBSERVED",
59531
+ capturedAtSeq: initialized.seq,
59532
+ artifactRefs: [
59533
+ {
59534
+ sha256: blob.sha256,
59535
+ media: blob.media,
59536
+ byteSize: blob.byteSize,
59537
+ storagePath: blob.storagePath
59538
+ }
59539
+ ],
59540
+ normalizedFacts: [
59541
+ "recon_surface: sbom",
59542
+ "bom_format: CycloneDX",
59543
+ `spec_version: ${bom.spec_version}`,
59544
+ `components: ${String(bom.components.length)}`,
59545
+ `dependencies: ${String(bom.dependencies.length)}`,
59546
+ `tool_exit: ${String(run.status)}`,
59547
+ "stack_candidates_not_registered: true"
59548
+ ]
59549
+ });
59550
+ const persisted = persistObservationRecord(paths.evidenceDir, observationRecordOf(receipt));
59551
+ const receiptPath = `${POMASTER_DIR}/evidence/${persisted.relativePath}`;
59552
+ const human = [
59553
+ `recon sbom: OBSERVED \u2014 CycloneDX BOM\uFF08specVersion ${bom.spec_version}\uFF1Bcomponents ${String(bom.components.length)} / dependencies ${String(bom.dependencies.length)}\uFF09`,
59554
+ `tool: ${RECON_SBOM_TOOL}\uFF08PATH \u547D\u4E2D: ${toolPath}\uFF1Bexit ${String(run.status)}\uFF09`,
59555
+ `bom blob: ${blob.storagePath}\uFF08${blob.sha256}\uFF1Bmedia=json\u2014\u2014cdxgen \u4EA7\u51FA\u539F\u6837\u5B57\u8282\u96F6\u6539\u5199\uFF09`,
59556
+ `observation receipt: ${receiptPath}\uFF08result=OBSERVED\uFF1Bsurface=STRUCTURAL_REALITY\uFF1Bcaptured_at_seq=${String(initialized.seq)}\uFF09`,
59557
+ "stack \u5019\u9009\u5316\u4E0D\u5728\u672C\u6279\uFF08Proposal \u524D\u7F6E\uFF09\uFF1A\u4EA7\u7269\u53EA\u5230 sidecar \u5448\u73B0\u2014\u2014\u96F6 StackObservationCandidate \u767B\u8BB0\u3001\u96F6 stack.yaml \u5199\u53E3\uFF08\u5B57\u8282\u5FEB\u7167\u6D4B\u8BD5\u9489\uFF09"
59558
+ ];
59559
+ return okOutcome("recon sbom", {
59560
+ observation: "OBSERVED",
59561
+ observation_id: receipt.observation_id,
59562
+ receipt_path: receiptPath,
59563
+ bom_format: bom.bom_format,
59564
+ spec_version: bom.spec_version,
59565
+ components: bom.components.length,
59566
+ dependencies: bom.dependencies.length,
59567
+ tool_exit: run.status,
59568
+ tool_path: toolPath,
59569
+ captured_at_seq: initialized.seq,
59570
+ bom_blob: {
59571
+ sha256: blob.sha256,
59572
+ storage_path: blob.storagePath,
59573
+ byte_size: blob.byteSize
59574
+ }
59575
+ }, human);
59576
+ } catch (error) {
59577
+ if (error instanceof GovernanceError)
59578
+ return reconSbomFail(governanceErrorToCliError(error));
59579
+ throw error;
59580
+ } finally {
59581
+ rmSync12(tmpDir, { recursive: true, force: true });
59582
+ }
59583
+ }
59584
+
58138
59585
  // packages/cli/dist/record.js
58139
59586
  init_dist();
58140
- import { existsSync as existsSync18, readFileSync as readFileSync24 } from "node:fs";
59587
+ import { existsSync as existsSync20, readFileSync as readFileSync26 } from "node:fs";
58141
59588
  function emptyGateRunResult() {
58142
59589
  return {
58143
59590
  grn: null,
@@ -58156,7 +59603,7 @@ function gateRunFail(error) {
58156
59603
  }
58157
59604
  function readFromBytes(path) {
58158
59605
  try {
58159
- return { bytes: readFileSync24(path, "utf8") };
59606
+ return { bytes: readFileSync26(path, "utf8") };
58160
59607
  } catch (err) {
58161
59608
  return {
58162
59609
  code: EVIDENCE_MALFORMED_CODE,
@@ -58238,7 +59685,7 @@ async function runRecordGateRun(rootDir, input) {
58238
59685
  });
58239
59686
  }
58240
59687
  const executionId = executionResolution.executionId;
58241
- if (executionId !== null && !existsSync18(`${executionsDirPath(rootDir)}/${executionId}.json`)) {
59688
+ if (executionId !== null && !existsSync20(`${executionsDirPath(rootDir)}/${executionId}.json`)) {
58242
59689
  return gateRunFail({
58243
59690
  code: "EXECUTION_NOT_FOUND",
58244
59691
  message: `execution_id \u672A\u767B\u8BB0\uFF08executions/ \u6863\u6848\u7F3A\u5931\uFF09\uFF1A${executionId}`,
@@ -58294,7 +59741,7 @@ async function runRecordGateRun(rootDir, input) {
58294
59741
  grn = input.grn;
58295
59742
  let targetBytes = null;
58296
59743
  try {
58297
- targetBytes = readFileSync24(`${runsDir}/${grn}.json`, "utf8");
59744
+ targetBytes = readFileSync26(`${runsDir}/${grn}.json`, "utf8");
58298
59745
  } catch {
58299
59746
  targetBytes = null;
58300
59747
  }
@@ -58489,7 +59936,7 @@ async function runRecordClaim(rootDir, input) {
58489
59936
  });
58490
59937
  }
58491
59938
  const executionId = executionResolution.executionId;
58492
- if (executionId !== null && !existsSync18(`${executionsDirPath(rootDir)}/${executionId}.json`)) {
59939
+ if (executionId !== null && !existsSync20(`${executionsDirPath(rootDir)}/${executionId}.json`)) {
58493
59940
  return claimFail({
58494
59941
  code: "EXECUTION_NOT_FOUND",
58495
59942
  message: `execution_id \u672A\u767B\u8BB0\uFF08executions/ \u6863\u6848\u7F3A\u5931\uFF09\uFF1A${executionId}`,
@@ -58516,7 +59963,7 @@ async function runRecordClaim(rootDir, input) {
58516
59963
  clm = input.clm;
58517
59964
  let targetBytes = null;
58518
59965
  try {
58519
- targetBytes = readFileSync24(`${claimsDir}/${clm}.json`, "utf8");
59966
+ targetBytes = readFileSync26(`${claimsDir}/${clm}.json`, "utf8");
58520
59967
  } catch {
58521
59968
  targetBytes = null;
58522
59969
  }
@@ -58630,7 +60077,7 @@ async function runRecordVerification(rootDir, input) {
58630
60077
  const claimPath = `${claimsDirPath(rootDir)}/${input.clm}.json`;
58631
60078
  let bytes = null;
58632
60079
  try {
58633
- bytes = readFileSync24(claimPath, "utf8");
60080
+ bytes = readFileSync26(claimPath, "utf8");
58634
60081
  } catch {
58635
60082
  bytes = null;
58636
60083
  }
@@ -58679,7 +60126,7 @@ async function runRecordVerification(rootDir, input) {
58679
60126
  });
58680
60127
  }
58681
60128
  const executionId = executionResolution.executionId;
58682
- if (executionId !== null && !existsSync18(`${executionsDirPath(rootDir)}/${executionId}.json`)) {
60129
+ if (executionId !== null && !existsSync20(`${executionsDirPath(rootDir)}/${executionId}.json`)) {
58683
60130
  return verificationFail({
58684
60131
  code: "EXECUTION_NOT_FOUND",
58685
60132
  message: `execution_id \u672A\u767B\u8BB0\uFF08executions/ \u6863\u6848\u7F3A\u5931\uFF09\uFF1A${executionId}`,
@@ -58737,9 +60184,9 @@ async function runRecordVerification(rootDir, input) {
58737
60184
  // packages/cli/dist/closeout.js
58738
60185
  init_dist();
58739
60186
  init_src();
58740
- import { readdirSync as readdirSync19 } from "node:fs";
60187
+ import { readdirSync as readdirSync20 } from "node:fs";
58741
60188
  import { readFile as readFile13 } from "node:fs/promises";
58742
- import { join as join10 } from "node:path";
60189
+ import { join as join11 } from "node:path";
58743
60190
  function emptyResult4(task) {
58744
60191
  return {
58745
60192
  task,
@@ -58804,7 +60251,7 @@ function grnOrdinal(grn) {
58804
60251
  var GRN_SIDECAR_PATTERN = /^GRN-[0-9]+(?:\..+)?$/;
58805
60252
  function listGrnSidecarFiles(runsDir) {
58806
60253
  try {
58807
- return readdirSync19(runsDir).filter((name) => GRN_SIDECAR_PATTERN.test(name) && !name.endsWith(".json")).sort();
60254
+ return readdirSync20(runsDir).filter((name) => GRN_SIDECAR_PATTERN.test(name) && !name.endsWith(".json")).sort();
58808
60255
  } catch {
58809
60256
  return [];
58810
60257
  }
@@ -58812,7 +60259,7 @@ function listGrnSidecarFiles(runsDir) {
58812
60259
  async function readRunRecord(runsDir, fileName) {
58813
60260
  let parsed;
58814
60261
  try {
58815
- parsed = JSON.parse(await readFile13(join10(runsDir, fileName), "utf8"));
60262
+ parsed = JSON.parse(await readFile13(join11(runsDir, fileName), "utf8"));
58816
60263
  } catch (err) {
58817
60264
  return { damage: `evidence/runs/${fileName}: JSON \u65E0\u6CD5\u89E3\u6790 \u2014 ${err instanceof Error ? err.message : String(err)}` };
58818
60265
  }
@@ -58833,7 +60280,7 @@ async function readRunRecord(runsDir, fileName) {
58833
60280
  async function readClaimRecord(claimsDir, fileName) {
58834
60281
  let bytes;
58835
60282
  try {
58836
- bytes = await readFile13(join10(claimsDir, fileName), "utf8");
60283
+ bytes = await readFile13(join11(claimsDir, fileName), "utf8");
58837
60284
  } catch {
58838
60285
  return { missing: true };
58839
60286
  }
@@ -58896,7 +60343,7 @@ async function runCloseout(rootDir, input) {
58896
60343
  hint: "change \u7684\u5B8C\u6210\u5224\u5377\u7ECF\u7531\u5176 affected TASKs \u9010\u4EFB\u52A1 closeout\uFF1Bkind \u8BCD\u5F62\u89C1 02b kind-payloads\u3002"
58897
60344
  }, withKind);
58898
60345
  }
58899
- const bodyPath = join10(rootDir, POMASTER_DIR, ...row2.bodyRef.split("/"));
60346
+ const bodyPath = join11(rootDir, POMASTER_DIR, ...row2.bodyRef.split("/"));
58900
60347
  let bodyRaw;
58901
60348
  try {
58902
60349
  bodyRaw = await readFile13(bodyPath, "utf8");
@@ -59033,7 +60480,7 @@ async function runCloseout(rootDir, input) {
59033
60480
  const claimsDirForSpec = claimsDirPath(rootDir);
59034
60481
  const specRows = index.objects.filter((row3) => row3.id.startsWith("SPEC."));
59035
60482
  for (const specRow of specRows) {
59036
- const specBodyPath = join10(rootDir, POMASTER_DIR, ...specRow.bodyRef.split("/"));
60483
+ const specBodyPath = join11(rootDir, POMASTER_DIR, ...specRow.bodyRef.split("/"));
59037
60484
  let specRaw;
59038
60485
  try {
59039
60486
  specRaw = await readFile13(specBodyPath, "utf8");
@@ -59418,8 +60865,8 @@ function kernelErrorOf2(err) {
59418
60865
 
59419
60866
  // packages/cli/dist/catalog.js
59420
60867
  init_dist();
59421
- import { writeFileSync as writeFileSync4 } from "node:fs";
59422
- import { join as join11 } from "node:path";
60868
+ import { writeFileSync as writeFileSync5 } from "node:fs";
60869
+ import { join as join12 } from "node:path";
59423
60870
  function emptyMaterial() {
59424
60871
  return {
59425
60872
  title_zh: null,
@@ -59637,7 +61084,7 @@ async function runCatalogRelock(deps) {
59637
61084
  try {
59638
61085
  catalogRoot = catalogRootOf(deps);
59639
61086
  report = relockCatalog(catalogRoot);
59640
- writeFileSync4(join11(catalogRoot, LOCK_FILE_NAME), `${JSON.stringify(report.next, null, 2)}
61087
+ writeFileSync5(join12(catalogRoot, LOCK_FILE_NAME), `${JSON.stringify(report.next, null, 2)}
59641
61088
  `, "utf8");
59642
61089
  verification = verifyCatalogLock(catalogRoot);
59643
61090
  } catch (error) {
@@ -59986,227 +61433,28 @@ async function runGraph(input) {
59986
61433
  }
59987
61434
 
59988
61435
  // packages/cli/dist/eval.js
59989
- import { existsSync as existsSync19, readFileSync as readFileSync25 } from "node:fs";
61436
+ import { existsSync as existsSync21, readFileSync as readFileSync27 } from "node:fs";
59990
61437
  import { fileURLToPath as fileURLToPath4 } from "node:url";
59991
-
59992
- // packages/cli/dist/triage.js
59993
- var TRIAGE_TTL_HOURS = 168;
59994
- var TRIAGE_ESCALATION_KEYWORDS = [
59995
- "contract",
59996
- "\u5951\u7EA6",
59997
- "openapi",
59998
- "api_req",
59999
- "\u8DE8\u57DF",
60000
- "cross-domain",
60001
- "global"
60002
- ];
60003
- var TRIAGE_COPY_STYLE_KEYWORDS = [
60004
- "\u6587\u6848",
60005
- "\u6837\u5F0F",
60006
- "\u914D\u8272",
60007
- "\u5B57\u4F53",
60008
- "\u989C\u8272",
60009
- "\u95F4\u8DDD",
60010
- "\u56FE\u6807",
60011
- "\u6CE8\u91CA",
60012
- "copy",
60013
- "style",
60014
- "css",
60015
- "comment",
60016
- "typo"
60017
- ];
60018
- var TRIAGE_ABSENT_SIGNALS = [
60019
- "declared_paths",
60020
- "path_class",
60021
- "contract_surface_registry",
60022
- "dependency_manifest_hit",
60023
- "migration_hit",
60024
- "test_only_hit",
60025
- "diff_stat",
60026
- "governed_object_hits"
60027
- ];
60028
- function includesKeyword(lowerText, keyword) {
60029
- return lowerText.includes(keyword.toLowerCase());
60030
- }
60031
- function collectKeywords(text, keywords) {
60032
- const lowerText = text.toLowerCase();
60033
- const hits = [];
60034
- for (const keyword of keywords) {
60035
- if (includesKeyword(lowerText, keyword) && !hits.includes(keyword)) {
60036
- hits.push(keyword);
60037
- }
60038
- }
60039
- return hits;
60040
- }
60041
- function triageRequest(request) {
60042
- const escalationHits = collectKeywords(request, TRIAGE_ESCALATION_KEYWORDS);
60043
- if (escalationHits.length > 0) {
60044
- return {
60045
- profile: "STANDARD",
60046
- evidence_grade: "INFERRED",
60047
- absent_signals: TRIAGE_ABSENT_SIGNALS,
60048
- ttl_hours: TRIAGE_TTL_HOURS,
60049
- matched_rule: "E_CONTRACT_KEYWORD",
60050
- matched_keywords: escalationHits
60051
- };
60052
- }
60053
- const copyStyleHits = collectKeywords(request, TRIAGE_COPY_STYLE_KEYWORDS);
60054
- if (copyStyleHits.length > 0) {
60055
- return {
60056
- profile: "MINIMAL",
60057
- evidence_grade: "MEASURED",
60058
- absent_signals: TRIAGE_ABSENT_SIGNALS,
60059
- ttl_hours: TRIAGE_TTL_HOURS,
60060
- matched_rule: "F_COPY_STYLE_ONLY",
60061
- matched_keywords: copyStyleHits
60062
- };
60063
- }
60064
- return {
60065
- profile: "LIGHT",
60066
- evidence_grade: "NOT_CONFIGURED",
60067
- absent_signals: TRIAGE_ABSENT_SIGNALS,
60068
- ttl_hours: TRIAGE_TTL_HOURS,
60069
- matched_rule: "DEFAULT_NO_SIGNAL",
60070
- matched_keywords: []
60071
- };
60072
- }
60073
-
60074
- // packages/cli/dist/triage-rule-v0.js
60075
- var PROFILE_LADDER = ["MINIMAL", "LIGHT", "STANDARD"];
60076
- var FAN_OUT_STANDARD_MIN = 6;
60077
- var DEFAULT_FLOOR = "MINIMAL";
60078
- function rank(p) {
60079
- return PROFILE_LADDER.indexOf(p);
60080
- }
60081
- function maxProfile(a, b) {
60082
- return rank(a) >= rank(b) ? a : b;
60083
- }
60084
- function globMatch(pattern, candidate) {
60085
- const escaped = pattern.replace(/[.+?^${}()|[\]\\]/g, "\\$&");
60086
- const body = escaped.replace(/\*\*\//g, "\0").replace(/\*\*/g, "").replace(/\*/g, "[^/]*").replace(/\u0000/g, "(?:.*/)?").replace(/\u0001/g, ".*");
60087
- return new RegExp(`^${body}$`).test(candidate);
60088
- }
60089
- var isDocPath = (p) => globMatch("docs/**", p) || globMatch("**/*.md", p);
60090
- var isTestPath = (p) => globMatch("tests/**", p) || globMatch("**/*.test.ts", p) || globMatch("**/*.spec.ts", p);
60091
- function triageRuleV0(req) {
60092
- const paths = req.declaredPaths ?? [];
60093
- const hasAnySignal = paths.length > 0 || typeof req.declaredType === "string" || req.contractSurfaceHit === true || req.reversibilityHard === true || req.sensitivityHit === true || typeof req.blastRadius === "number";
60094
- if (!hasAnySignal) {
60095
- return {
60096
- outcome: "NO_CHANGE",
60097
- recommendedProfile: null,
60098
- effectiveProfile: null,
60099
- fastPathHit: null,
60100
- triggerHits: [],
60101
- floorApplied: null,
60102
- overrideBelowFloorRejected: false,
60103
- overrideOverpoweredByEscalation: false,
60104
- fastLane: false,
60105
- ceilingCandidates: [],
60106
- blindspots: {
60107
- notApplicableRules: [],
60108
- note: "\u96F6\u4FE1\u53F7\u8F93\u5165\u2014\u2014\u65E0\u53D8\u66F4\u53EF\u5224\u6863\uFF0CNO_CHANGE \u4E3A\u5408\u6CD5\u6210\u529F\uFF08GOLDEN-L8-1 \u5224\u636E\uFF09"
60109
- }
60110
- };
60111
- }
60112
- const triggerHits = [];
60113
- const notApplicableRules = [];
60114
- let atLeast = null;
60115
- const raise = (p) => {
60116
- atLeast = atLeast === null ? p : maxProfile(atLeast, p);
60117
- };
60118
- if (req.contractSurfaceHit === true) {
60119
- triggerHits.push("E_CONTRACT");
60120
- raise("STANDARD");
60121
- }
60122
- if (typeof req.blastRadius === "number") {
60123
- if (req.blastRadius >= FAN_OUT_STANDARD_MIN) {
60124
- triggerHits.push("E_BLAST");
60125
- raise("STANDARD");
60126
- }
60127
- } else {
60128
- notApplicableRules.push("E_BLAST");
60129
- }
60130
- if (req.reversibilityHard === true) {
60131
- triggerHits.push("E_IRREVERS");
60132
- raise("STANDARD");
60133
- }
60134
- if (req.sensitivityHit === true) {
60135
- triggerHits.push("E_SENSITIVE");
60136
- raise("STANDARD");
60137
- }
60138
- const escalations = atLeast;
60139
- let fastPathHit = null;
60140
- let base = req.projectLegacyMaster === true ? "LIGHT" : "MINIMAL";
60141
- if (paths.length > 0 && paths.every(isDocPath) && req.contractSurfaceHit !== true) {
60142
- fastPathHit = "DOC_ONLY";
60143
- base = "MINIMAL";
60144
- } else if (paths.length > 0 && paths.every(isTestPath)) {
60145
- fastPathHit = "TEST_ONLY";
60146
- base = "MINIMAL";
60147
- }
60148
- let fastLane = false;
60149
- if (req.declaredType === "hotfix") {
60150
- base = maxProfile(base, "LIGHT");
60151
- fastLane = true;
60152
- }
60153
- const recommendedProfile = escalations ? maxProfile(base, escalations) : base;
60154
- let floor = DEFAULT_FLOOR;
60155
- let floorApplied = null;
60156
- for (const o of req.floorOverrides ?? []) {
60157
- if (o.whenPath.some((pattern) => paths.some((declared) => globMatch(pattern, declared))) && rank(o.floor) > rank(floor)) {
60158
- floor = o.floor;
60159
- floorApplied = o.whenPath.join(",");
60160
- }
60161
- }
60162
- let effectiveProfile = recommendedProfile;
60163
- let overrideBelowFloorRejected = false;
60164
- let overrideOverpoweredByEscalation = false;
60165
- if (req.requestedProfileOverride !== void 0) {
60166
- const want = req.requestedProfileOverride;
60167
- effectiveProfile = want;
60168
- if (escalations !== null && rank(want) < rank(escalations)) {
60169
- overrideOverpoweredByEscalation = true;
60170
- }
60171
- }
60172
- if (escalations !== null) {
60173
- effectiveProfile = maxProfile(effectiveProfile, escalations);
60174
- }
60175
- if (rank(effectiveProfile) < rank(floor)) {
60176
- effectiveProfile = floor;
60177
- if (req.requestedProfileOverride !== void 0) {
60178
- overrideBelowFloorRejected = true;
60179
- }
60180
- }
60181
- return {
60182
- outcome: "TRIAGED",
60183
- recommendedProfile,
60184
- effectiveProfile,
60185
- fastPathHit,
60186
- triggerHits,
60187
- floorApplied,
60188
- overrideBelowFloorRejected,
60189
- overrideOverpoweredByEscalation,
60190
- fastLane,
60191
- ceilingCandidates: [],
60192
- blindspots: {
60193
- notApplicableRules,
60194
- note: notApplicableRules.length > 0 ? "\u5B58\u5728\u56E0 NOT_CONFIGURED \u4FE1\u53F7\u672A\u8BC4\u4F30\u7684\u89C4\u5219\uFF08R-B\uFF1A\u4E0D\u6309 false/true \u5904\u7406\uFF0C\u7F3A\u5E2D\u663E\u5F0F\u5165\u8D26\uFF09" : "\u65E0\u672A\u8BC4\u4F30\u89C4\u5219"
60195
- }
60196
- };
60197
- }
60198
-
60199
- // packages/cli/dist/eval.js
61438
+ init_dist();
60200
61439
  var EVAL_SUITES = ["behavioral"];
60201
61440
  var BEHAVIORAL_SEEDS_PATH = fileURLToPath4(new URL("../../../tests/behavioral/seeds.json", import.meta.url));
60202
- var L5_FAMILIES = ["A", "B", "C", "D", "E", "F", "G", "X"];
60203
- var L5_EVALUATORS = ["cli_keyword", "rule_v0"];
61441
+ var L5_FAMILIES = ["A", "B", "C", "D", "E", "F", "G"];
61442
+ var L5_EVALUATORS = ["question_gate", "next_action"];
61443
+ var GATE_ANSWERABLE_KEYS = [
61444
+ "q1_current_truth",
61445
+ "q2_existing_docs",
61446
+ "q3_repo_code",
61447
+ "q4_existing_evidence",
61448
+ "q5_knowledge_default",
61449
+ "q6_research",
61450
+ "q7_blocking_increment"
61451
+ ];
60204
61452
  function loadSeeds(seedsPath = BEHAVIORAL_SEEDS_PATH) {
60205
61453
  const lower = seedsPath.toLowerCase();
60206
61454
  if (lower.endsWith(".yaml") || lower.endsWith(".yml")) {
60207
61455
  throw new Error(`eval \u547D\u4EE4\u6D88\u8D39\u9762\u4E3A seeds.json\uFF0C\u4E0D\u63A5\u53D7 yaml \u8F7D\u7269\uFF08${seedsPath}\uFF09\u3002PRD \xA794.2 yaml \u8F7D\u7269\uFF08tests/behavioral/eval-cases.yaml\uFF09\u662F\u767B\u8BB0\u5F62\u6001\uFF1Aschema \u6821\u9A8C\u4E0E json \u540C\u6784\u951A\u5B9A\u5728 tests/behavioral/eval-carrier.spec.ts\uFF08js-yaml devDependency + ajv\uFF0Ctests \u9762\uFF09\uFF1B\u5224\u5377\u8BF7\u6CE8\u5165 seeds.json \u6216\u7701\u7565 seedsPath \u7528\u4ED3\u5E93\u7F3A\u7701\u8D26\u672C\u3002`);
60208
61456
  }
60209
- const raw = JSON.parse(readFileSync25(seedsPath, "utf8"));
61457
+ const raw = JSON.parse(readFileSync27(seedsPath, "utf8"));
60210
61458
  const file = raw;
60211
61459
  if (!Array.isArray(file.seeds)) {
60212
61460
  throw new Error(`seeds.json \u5F62\u6001\u975E\u6CD5\uFF1A\u7F3A seeds \u6570\u7EC4\uFF08${seedsPath}\uFF09`);
@@ -60251,6 +61499,31 @@ function loadSeeds(seedsPath = BEHAVIORAL_SEEDS_PATH) {
60251
61499
  if (s.expect === void 0 || typeof s.expect !== "object" || s.expect === null) {
60252
61500
  problems.push(`${s.id}: expect \u7F3A\u5931\u6216\u975E\u5BF9\u8C61`);
60253
61501
  }
61502
+ if (s.evaluator === "question_gate") {
61503
+ const gate = s.input?.gate;
61504
+ if (typeof gate !== "object" || gate === null) {
61505
+ problems.push(`${s.id}: question_gate seed \u7F3A input.gate \u5BF9\u8C61`);
61506
+ } else {
61507
+ const answerable = gate.answerable;
61508
+ if (typeof answerable !== "object" || answerable === null) {
61509
+ problems.push(`${s.id}: input.gate.answerable \u7F3A\u5931\uFF08\u4E03\u5173\u5224\u5B9A\u8F93\u5165\uFF09`);
61510
+ } else {
61511
+ for (const key of GATE_ANSWERABLE_KEYS) {
61512
+ if (typeof answerable[key] !== "boolean") {
61513
+ problems.push(`${s.id}: input.gate.answerable.${key} \u987B\u4E3A boolean\uFF08\u4E03\u5173\u952E\u9010\u5B57\uFF09`);
61514
+ }
61515
+ }
61516
+ }
61517
+ if (typeof gate.category !== "string") {
61518
+ problems.push(`${s.id}: input.gate.category \u7F3A\u5931\uFF08\u7533\u62A5\u5206\u7C7B\u8BCD\u5F62\uFF09`);
61519
+ }
61520
+ }
61521
+ } else if (s.evaluator === "next_action") {
61522
+ const snapshot = s.input?.snapshot;
61523
+ if (typeof snapshot !== "object" || snapshot === null || Array.isArray(snapshot)) {
61524
+ problems.push(`${s.id}: next_action seed \u7F3A input.snapshot \u5FEB\u7167\u5BF9\u8C61\uFF08NextActionSnapshot \u5F62\u6001\uFF09`);
61525
+ }
61526
+ }
60254
61527
  }
60255
61528
  if (problems.length > 0) {
60256
61529
  throw new Error(`seeds.json \u7ED3\u6784\u7EAA\u5F8B\u8FDD\u53CD\uFF08fail-closed\uFF09\uFF1A
@@ -60262,71 +61535,37 @@ function loadSeeds(seedsPath = BEHAVIORAL_SEEDS_PATH) {
60262
61535
  seeds: file.seeds
60263
61536
  };
60264
61537
  }
60265
- function checkCliKeywordResult(label, result2, expect) {
61538
+ function checkQuestionGateResult(label, outcome, expect) {
60266
61539
  const problems = [];
60267
- if (JSON.stringify(result2.absent_signals) !== JSON.stringify(TRIAGE_ABSENT_SIGNALS)) {
60268
- problems.push(`${label}: absent_signals \u5E94\u5168\u7B49 TRIAGE_ABSENT_SIGNALS \u516B\u9879\u95ED\u8868\uFF08\u7F3A\u5E2D\u663E\u5F0F\u5316\u673A\u5668\u65AD\u8A00\uFF09\uFF0C\u5B9E\u9645 ${JSON.stringify(result2.absent_signals)}`);
60269
- }
60270
- if (expect.profile !== void 0 && result2.profile !== expect.profile) {
60271
- problems.push(`${label}: \u671F\u671B profile=${expect.profile}\uFF0C\u5B9E\u9645 ${result2.profile}`);
61540
+ if (expect.verdict !== void 0 && outcome.verdict !== expect.verdict) {
61541
+ problems.push(`${label}: \u671F\u671B verdict=${expect.verdict}\uFF0C\u5B9E\u9645 ${outcome.verdict}`);
60272
61542
  }
60273
- if (expect.matched_rule !== void 0 && result2.matched_rule !== expect.matched_rule) {
60274
- problems.push(`${label}: \u671F\u671B matched_rule=${expect.matched_rule}\uFF0C\u5B9E\u9645 ${result2.matched_rule}`);
61543
+ if (expect.mayAskHuman !== void 0 && outcome.mayAskHuman !== expect.mayAskHuman) {
61544
+ problems.push(`${label}: \u671F\u671B mayAskHuman=${String(expect.mayAskHuman)}\uFF0C\u5B9E\u9645 ${String(outcome.mayAskHuman)}`);
60275
61545
  }
60276
- if (expect.evidence_grade !== void 0 && result2.evidence_grade !== expect.evidence_grade) {
60277
- problems.push(`${label}: \u671F\u671B evidence_grade=${expect.evidence_grade}\uFF0C\u5B9E\u9645 ${result2.evidence_grade}`);
61546
+ if (expect.stoppedAtGate !== void 0 && outcome.stoppedAtGate !== expect.stoppedAtGate) {
61547
+ problems.push(`${label}: \u671F\u671B stoppedAtGate=${String(expect.stoppedAtGate)}\uFF0C\u5B9E\u9645 ${String(outcome.stoppedAtGate)}`);
60278
61548
  }
60279
- for (const kw of expect.matched_keywords_contains ?? []) {
60280
- if (!result2.matched_keywords.includes(kw)) {
60281
- problems.push(`${label}: matched_keywords \u5E94\u542B "${kw}"\uFF0C\u5B9E\u9645 ${JSON.stringify(result2.matched_keywords)}`);
60282
- }
60283
- }
60284
- if (expect.matched_keywords_equals !== void 0 && JSON.stringify(result2.matched_keywords) !== JSON.stringify(expect.matched_keywords_equals)) {
60285
- problems.push(`${label}: matched_keywords \u5E94\u5168\u7B49 ${JSON.stringify(expect.matched_keywords_equals)}\uFF0C\u5B9E\u9645 ${JSON.stringify(result2.matched_keywords)}`);
61549
+ if (expect.declaredConsistent !== void 0 && outcome.declaredConsistent !== expect.declaredConsistent) {
61550
+ problems.push(`${label}: \u671F\u671B declaredConsistent=${String(expect.declaredConsistent)}\uFF0C\u5B9E\u9645 ${String(outcome.declaredConsistent)}`);
60286
61551
  }
60287
61552
  return problems;
60288
61553
  }
60289
- function profileRank(p) {
60290
- return PROFILE_LADDER.indexOf(p);
60291
- }
60292
- function checkRuleV0Decision(label, decision, expect) {
61554
+ function checkNextActionResult(label, nextAction, expect) {
60293
61555
  const problems = [];
60294
- if (expect.outcome !== void 0 && decision.outcome !== expect.outcome) {
60295
- problems.push(`${label}: \u671F\u671B outcome=${expect.outcome}\uFF0C\u5B9E\u9645 ${decision.outcome}`);
61556
+ if (expect.route_id !== void 0 && nextAction.route_id !== expect.route_id) {
61557
+ problems.push(`${label}: \u671F\u671B route_id=${expect.route_id}\uFF0C\u5B9E\u9645 ${nextAction.route_id}`);
60296
61558
  }
60297
- if (expect.effectiveProfile !== void 0 && decision.effectiveProfile !== expect.effectiveProfile) {
60298
- problems.push(`${label}: \u671F\u671B effectiveProfile=${String(expect.effectiveProfile)}\uFF0C\u5B9E\u9645 ${String(decision.effectiveProfile)}`);
61559
+ if (expect.beat !== void 0 && nextAction.beat !== expect.beat) {
61560
+ problems.push(`${label}: \u671F\u671B beat=${String(expect.beat)}\uFF0C\u5B9E\u9645 ${String(nextAction.beat)}`);
60299
61561
  }
60300
- if (expect.effectiveProfileAtLeast !== void 0) {
60301
- const actual = decision.effectiveProfile;
60302
- if (actual === null || profileRank(actual) < profileRank(expect.effectiveProfileAtLeast)) {
60303
- problems.push(`${label}: effectiveProfile \u5E94 \u2265 ${expect.effectiveProfileAtLeast}\uFF0C\u5B9E\u9645 ${String(actual)}`);
61562
+ for (const fragment of expect.commandContains ?? []) {
61563
+ if (nextAction.command === null || !nextAction.command.includes(fragment)) {
61564
+ problems.push(`${label}: command \u5E94\u542B "${fragment}"\uFF0C\u5B9E\u9645 ${JSON.stringify(nextAction.command)}`);
60304
61565
  }
60305
61566
  }
60306
- for (const t of expect.triggerHitsContains ?? []) {
60307
- if (!decision.triggerHits.includes(t)) {
60308
- problems.push(`${label}: triggerHits \u5E94\u542B ${t}\uFF0C\u5B9E\u9645 [${decision.triggerHits.join(",")}]`);
60309
- }
60310
- }
60311
- if (expect.fastPathHit !== void 0 && decision.fastPathHit !== expect.fastPathHit) {
60312
- problems.push(`${label}: \u671F\u671B fastPathHit=${String(expect.fastPathHit)}\uFF0C\u5B9E\u9645 ${String(decision.fastPathHit)}`);
60313
- }
60314
- if (expect.fastLane !== void 0 && decision.fastLane !== expect.fastLane) {
60315
- problems.push(`${label}: \u671F\u671B fastLane=${String(expect.fastLane)}\uFF0C\u5B9E\u9645 ${String(decision.fastLane)}`);
60316
- }
60317
- if (expect.floorApplied !== void 0 && decision.floorApplied !== expect.floorApplied) {
60318
- problems.push(`${label}: \u671F\u671B floorApplied=${String(expect.floorApplied)}\uFF0C\u5B9E\u9645 ${String(decision.floorApplied)}`);
60319
- }
60320
- if (expect.overrideBelowFloorRejected !== void 0 && decision.overrideBelowFloorRejected !== expect.overrideBelowFloorRejected) {
60321
- problems.push(`${label}: \u671F\u671B overrideBelowFloorRejected=${String(expect.overrideBelowFloorRejected)}\uFF0C\u5B9E\u9645 ${String(decision.overrideBelowFloorRejected)}`);
60322
- }
60323
- if (expect.overrideOverpoweredByEscalation !== void 0 && decision.overrideOverpoweredByEscalation !== expect.overrideOverpoweredByEscalation) {
60324
- problems.push(`${label}: \u671F\u671B overrideOverpoweredByEscalation=${String(expect.overrideOverpoweredByEscalation)}\uFF0C\u5B9E\u9645 ${String(decision.overrideOverpoweredByEscalation)}`);
60325
- }
60326
- for (const r of expect.notApplicableRulesContains ?? []) {
60327
- if (!decision.blindspots.notApplicableRules.includes(r)) {
60328
- problems.push(`${label}: blindspots.notApplicableRules \u5E94\u542B ${r}\uFF0C\u5B9E\u9645 [${decision.blindspots.notApplicableRules.join(",")}]`);
60329
- }
61567
+ if (expect.commandEquals !== void 0 && nextAction.command !== expect.commandEquals) {
61568
+ problems.push(`${label}: \u671F\u671B command=${JSON.stringify(expect.commandEquals)}\uFF0C\u5B9E\u9645 ${JSON.stringify(nextAction.command)}`);
60330
61569
  }
60331
61570
  return problems;
60332
61571
  }
@@ -60336,7 +61575,7 @@ function seedFailed(seed, problems, actualDump) {
60336
61575
  family: seed.family,
60337
61576
  evaluator: seed.evaluator,
60338
61577
  status: "failed",
60339
- // 可诊断 diff:期望 vs 实际路由 + 完整实际结果(契约任务书要求,非裸 assert)。
61578
+ // 可诊断 diff:期望 vs 实际判定 + 完整实际结果(契约任务书要求,非裸 assert)。
60340
61579
  detail: `${problems.join("\uFF1B")}\uFF5C\u5B9E\u9645 ${actualDump}`
60341
61580
  };
60342
61581
  }
@@ -60349,9 +61588,6 @@ function seedPassed(seed, summary) {
60349
61588
  detail: summary
60350
61589
  };
60351
61590
  }
60352
- function isTriageRequestInput(v) {
60353
- return typeof v === "object" && v !== null && !Array.isArray(v);
60354
- }
60355
61591
  function runSeed(seed) {
60356
61592
  const retired = seed.retired ?? null;
60357
61593
  if (retired !== null) {
@@ -60379,45 +61615,35 @@ function runSeed(seed) {
60379
61615
  detail: pendingReason
60380
61616
  };
60381
61617
  }
60382
- if (seed.evaluator === "cli_keyword")
60383
- return runCliKeywordSeed(seed);
60384
- return runRuleV0Seed(seed);
61618
+ if (seed.evaluator === "question_gate")
61619
+ return runQuestionGateSeed(seed);
61620
+ return runNextActionSeed(seed);
60385
61621
  }
60386
- function runCliKeywordSeed(seed) {
61622
+ function runQuestionGateSeed(seed) {
60387
61623
  const expect = seed.expect;
60388
- const requests = seed.input.requests ?? (typeof seed.input.request === "string" ? [
60389
- {
60390
- replay_id: seed.provenance.replay_id ?? "",
60391
- request: seed.input.request
60392
- }
60393
- ] : []);
60394
- if (requests.length === 0) {
60395
- return seedFailed(seed, ["cli_keyword seed \u7F3A\u53EF\u6267\u884C\u8BF7\u6C42\uFF08input.request \u6587\u672C\u6216 input.requests \u7C07\uFF09"], "");
60396
- }
60397
- const runs = requests.map((r) => {
60398
- const label = `${seed.id}[${r.replay_id === "" ? "probe" : r.replay_id}]`;
60399
- return { label, request: r.request, result: triageRequest(r.request) };
60400
- });
60401
- const problems = [];
60402
- for (const run of runs) {
60403
- problems.push(...checkCliKeywordResult(run.label, run.result, expect));
61624
+ const gate = seed.input.gate;
61625
+ if (typeof gate !== "object" || gate === null) {
61626
+ return seedFailed(seed, ["question_gate seed \u7684 input.gate \u5FC5\u987B\u662F QuestionGateInput \u5BF9\u8C61\uFF08category + answerable \u4E03\u952E\uFF09"], `input=${JSON.stringify(seed.input ?? null)}`);
60404
61627
  }
61628
+ const outcome = evaluateQuestionGate(gate);
61629
+ const problems = checkQuestionGateResult(seed.id, outcome, expect);
60405
61630
  if (problems.length > 0) {
60406
- return seedFailed(seed, problems, runs.map((r) => `${r.label}: input=${JSON.stringify(r.request)} \u2192 ${JSON.stringify(r.result)}`).join("\uFF1B"));
61631
+ return seedFailed(seed, problems, `input=${JSON.stringify(gate)} \u2192 outcome=${JSON.stringify(outcome)}`);
60407
61632
  }
60408
- return seedPassed(seed, runs.map((r) => `${r.label}: profile=${r.result.profile} rule=${r.result.matched_rule} grade=${r.result.evidence_grade} keywords=${JSON.stringify(r.result.matched_keywords)}`).join("\uFF1B"));
61633
+ return seedPassed(seed, `verdict=${outcome.verdict} mayAskHuman=${String(outcome.mayAskHuman)} stoppedAtGate=${String(outcome.stoppedAtGate)} consistent=${String(outcome.declaredConsistent)}`);
60409
61634
  }
60410
- function runRuleV0Seed(seed) {
61635
+ function runNextActionSeed(seed) {
60411
61636
  const expect = seed.expect;
60412
- if (!isTriageRequestInput(seed.input.request)) {
60413
- return seedFailed(seed, ["rule_v0 seed \u7684 input.request \u5FC5\u987B\u662F TriageRequestInput \u4FE1\u53F7\u96C6\u5BF9\u8C61"], `input=${JSON.stringify(seed.input.request ?? null)}`);
61637
+ const snapshot = seed.input.snapshot;
61638
+ if (typeof snapshot !== "object" || snapshot === null) {
61639
+ return seedFailed(seed, ["next_action seed \u7684 input.snapshot \u5FC5\u987B\u662F NextActionSnapshot \u5FEB\u7167\u5BF9\u8C61"], `input=${JSON.stringify(seed.input ?? null)}`);
60414
61640
  }
60415
- const decision = triageRuleV0(seed.input.request);
60416
- const problems = checkRuleV0Decision(`${seed.id}`, decision, expect);
61641
+ const nextAction = evaluateNextAction(snapshot);
61642
+ const problems = checkNextActionResult(seed.id, nextAction, expect);
60417
61643
  if (problems.length > 0) {
60418
- return seedFailed(seed, problems, `input=${JSON.stringify(seed.input.request)} \u2192 decision=${JSON.stringify(decision)}`);
61644
+ return seedFailed(seed, problems, `snapshot=${JSON.stringify(snapshot)} \u2192 nextAction=${JSON.stringify(nextAction)}`);
60419
61645
  }
60420
- return seedPassed(seed, `outcome=${decision.outcome} effective=${String(decision.effectiveProfile)} hits=[${decision.triggerHits.join(",")}] fastPath=${String(decision.fastPathHit)} fastLane=${String(decision.fastLane)}`);
61646
+ return seedPassed(seed, `route=${nextAction.route_id} beat=${String(nextAction.beat)} command=${JSON.stringify(nextAction.command)}`);
60421
61647
  }
60422
61648
  function runAllSeeds(seeds) {
60423
61649
  const results = seeds.map((s) => runSeed(s));
@@ -60446,8 +61672,8 @@ function runAllSeeds(seeds) {
60446
61672
  pending: byStatus("pending"),
60447
61673
  retired: byStatus("retired"),
60448
61674
  evaluatorSummary: {
60449
- cli_keyword: results.filter((r) => r.status !== "pending" && r.status !== "retired" && r.evaluator === "cli_keyword").length,
60450
- rule_v0: results.filter((r) => r.status !== "pending" && r.status !== "retired" && r.evaluator === "rule_v0").length
61675
+ question_gate: results.filter((r) => r.status !== "pending" && r.status !== "retired" && r.evaluator === "question_gate").length,
61676
+ next_action: results.filter((r) => r.status !== "pending" && r.status !== "retired" && r.evaluator === "next_action").length
60451
61677
  },
60452
61678
  familySummary,
60453
61679
  results,
@@ -60469,7 +61695,7 @@ function zeroReport() {
60469
61695
  failed: 0,
60470
61696
  pending: 0,
60471
61697
  retired: 0,
60472
- evaluatorSummary: { cli_keyword: 0, rule_v0: 0 },
61698
+ evaluatorSummary: { question_gate: 0, next_action: 0 },
60473
61699
  familySummary: [],
60474
61700
  results: [],
60475
61701
  pendingList: [],
@@ -60488,7 +61714,7 @@ async function runEval(input) {
60488
61714
  ], [`eval: FAILED \u2014 EVAL_SUITE_UNKNOWN\uFF08${input.suite}\uFF09`]);
60489
61715
  }
60490
61716
  const seedsPath = input.seedsPath ?? BEHAVIORAL_SEEDS_PATH;
60491
- if (!existsSync19(seedsPath)) {
61717
+ if (!existsSync21(seedsPath)) {
60492
61718
  return failOutcome(command, { suite: input.suite, seeds_path: seedsPath, report: zeroReport() }, [
60493
61719
  {
60494
61720
  code: "SEEDS_NOT_AVAILABLE",
@@ -60523,7 +61749,7 @@ async function runEval(input) {
60523
61749
  }
60524
61750
  const human = [
60525
61751
  `eval: ${report.passed} passed / ${report.failed} failed / ${report.pending} pending\uFF08suite ${input.suite}\uFF1Bseeds \u6CE8\u518C ${report.total}\uFF0Cexecutable ${report.executable}\uFF0Cretired ${report.retired}\uFF09`,
60526
- ` evaluators: cli_keyword=${report.evaluatorSummary.cli_keyword} rule_v0=${report.evaluatorSummary.rule_v0}`,
61752
+ ` evaluators: question_gate=${report.evaluatorSummary.question_gate} next_action=${report.evaluatorSummary.next_action}`,
60527
61753
  ...report.pendingList.map((p) => ` pending\uFF08\u663E\u5F0F\u7F3A\u5E2D\uFF0C\u4E0D\u5192\u5145\u7EFF\uFF09: ${p.id} \u2014 ${p.reason}`),
60528
61754
  ...report.retiredList.map((r) => ` retired\uFF08\u663E\u5F0F\u9000\u5F79\uFF0C\u4E0D\u5192\u5145\u7EFF\u4E5F\u4E0D\u6EDE\u7559 pending\uFF09: ${r.id} \u2014 ${r.reason}`)
60529
61755
  ];
@@ -60533,7 +61759,7 @@ async function runEval(input) {
60533
61759
  {
60534
61760
  code: "EVAL_EXECUTABLE_FAILED",
60535
61761
  message: `executable seed \u5931\u8D25 ${report.failed} \u6761\uFF1A${failedIds.join(", ")}`,
60536
- hint: "\u53EF\u8BCA\u65AD diff \u89C1 --json result.report.results[].detail\uFF08\u671F\u671B vs \u5B9E\u9645\u8DEF\u7531 + \u5B8C\u6574\u8F93\u5165/\u7ED3\u679C JSON\uFF09\uFF1Bpending \u4E0E\u5931\u8D25\u662F\u4E24\u79CD\u72B6\u6001\uFF0C\u7981\u628A pending \u5F53\u5931\u8D25\u4FEE\uFF0C\u66F4\u7981\u628A\u5931\u8D25\u6807 pending\u3002"
61762
+ hint: "\u53EF\u8BCA\u65AD diff \u89C1 --json result.report.results[].detail\uFF08\u671F\u671B vs \u5B9E\u9645\u5224\u5B9A + \u5B8C\u6574\u8F93\u5165/\u7ED3\u679C JSON\uFF09\uFF1Bpending \u4E0E\u5931\u8D25\u662F\u4E24\u79CD\u72B6\u6001\uFF0C\u7981\u628A pending \u5F53\u5931\u8D25\u4FEE\uFF0C\u66F4\u7981\u628A\u5931\u8D25\u6807 pending\u3002"
60537
61763
  }
60538
61764
  ], [
60539
61765
  ...human,
@@ -60799,7 +62025,7 @@ async function runAuditTask(rootDir, input) {
60799
62025
  init_dist();
60800
62026
  init_src();
60801
62027
  import { readFile as readFile15 } from "node:fs/promises";
60802
- import { join as join12 } from "node:path";
62028
+ import { join as join13 } from "node:path";
60803
62029
  async function runLedgerRecord(rootDir, input, deps) {
60804
62030
  const emptyResult6 = {
60805
62031
  ledger_ref: "",
@@ -60888,7 +62114,7 @@ async function runLedgerRecord(rootDir, input, deps) {
60888
62114
  }
60889
62115
  async function runLedgerList(rootDir, input) {
60890
62116
  const classificationFilter = input.classification?.trim() ? input.classification.trim() : null;
60891
- const path = join12(rootDir, POMASTER_DIR, "state", "exception-ledger.json");
62117
+ const path = join13(rootDir, POMASTER_DIR, "state", "exception-ledger.json");
60892
62118
  let raw;
60893
62119
  try {
60894
62120
  raw = await readFile15(path, "utf8");
@@ -60977,31 +62203,31 @@ async function runLedgerList(rootDir, input) {
60977
62203
 
60978
62204
  // packages/cli/dist/knowledge.js
60979
62205
  init_dist();
60980
- import { existsSync as existsSync22 } from "node:fs";
60981
- import { join as join15 } from "node:path";
62206
+ import { existsSync as existsSync24 } from "node:fs";
62207
+ import { join as join16 } from "node:path";
60982
62208
 
60983
62209
  // packages/cli/dist/research.js
60984
62210
  init_src();
60985
62211
  init_dist();
60986
- import { existsSync as existsSync21 } from "node:fs";
62212
+ import { existsSync as existsSync23 } from "node:fs";
60987
62213
  import { mkdir as mkdir2, readFile as readFile17, readdir as readdir2, writeFile as writeFile5 } from "node:fs/promises";
60988
- import { join as join14 } from "node:path";
62214
+ import { join as join15 } from "node:path";
60989
62215
 
60990
62216
  // packages/cli/dist/brainstorm.js
60991
62217
  init_src();
60992
62218
  init_dist();
60993
- import { existsSync as existsSync20 } from "node:fs";
62219
+ import { existsSync as existsSync22 } from "node:fs";
60994
62220
  import { mkdir, readdir, readFile as readFile16, writeFile as writeFile4 } from "node:fs/promises";
60995
- import { isAbsolute, join as join13, relative as relative2, resolve as resolve2 } from "node:path";
62221
+ import { isAbsolute, join as join14, relative as relative2, resolve as resolve2 } from "node:path";
60996
62222
  var PROMOTE_TARGETS = ["CHANGE", "TASK"];
60997
62223
  function scratchpadRefOf(id) {
60998
62224
  return `.pomaster/discovery/scratchpads/${id}/`;
60999
62225
  }
61000
62226
  function stateFilePath(rootDir, id) {
61001
- return join13(discoveryScratchpadDirPath(rootDir, id), "state.json");
62227
+ return join14(discoveryScratchpadDirPath(rootDir, id), "state.json");
61002
62228
  }
61003
62229
  function metaFilePath(rootDir, id) {
61004
- return join13(discoveryScratchpadDirPath(rootDir, id), "meta.json");
62230
+ return join14(discoveryScratchpadDirPath(rootDir, id), "meta.json");
61005
62231
  }
61006
62232
  function cliError(err) {
61007
62233
  if (err instanceof GovernedIdParseError) {
@@ -61018,7 +62244,7 @@ function cliError(err) {
61018
62244
  };
61019
62245
  }
61020
62246
  async function readJsonFile(path) {
61021
- if (!existsSync20(path))
62247
+ if (!existsSync22(path))
61022
62248
  return null;
61023
62249
  try {
61024
62250
  return JSON.parse(await readFile16(path, "utf8"));
@@ -61093,7 +62319,7 @@ async function runBrainstormStart(rootDir, input) {
61093
62319
  ], [`brainstorm start: FAILED \u2014 id \u8BCD\u5F62\u975E\u6CD5\uFF08${id}\uFF09`]);
61094
62320
  }
61095
62321
  if (id === void 0) {
61096
- const existing = existsSync20(padsDir) ? await readdir(padsDir) : [];
62322
+ const existing = existsSync22(padsDir) ? await readdir(padsDir) : [];
61097
62323
  let seq2 = 1;
61098
62324
  while (existing.includes(`idea-${String(seq2).padStart(3, "0")}`))
61099
62325
  seq2 += 1;
@@ -61101,7 +62327,7 @@ async function runBrainstormStart(rootDir, input) {
61101
62327
  }
61102
62328
  const padDir = discoveryScratchpadDirPath(rootDir, id);
61103
62329
  const statePath = stateFilePath(rootDir, id);
61104
- if (existsSync20(padDir)) {
62330
+ if (existsSync22(padDir)) {
61105
62331
  const existingState = await readJsonFile(statePath);
61106
62332
  if (existingState !== null && typeof existingState === "object") {
61107
62333
  const file = existingState;
@@ -61190,7 +62416,7 @@ async function runBrainstormStart(rootDir, input) {
61190
62416
  }
61191
62417
  async function runBrainstormStatus(rootDir) {
61192
62418
  const padsDir = discoveryScratchpadsDirPath(rootDir);
61193
- if (!existsSync20(padsDir)) {
62419
+ if (!existsSync22(padsDir)) {
61194
62420
  return okOutcome("brainstorm status", { scratchpads: [] }, [
61195
62421
  "brainstorm status\uFF1A\u65E0\u6D3B\u8DC3 discovery\uFF08scratchpads \u76EE\u5F55\u4E0D\u5B58\u5728\u2014\u2014\u663E\u5F0F\u7A7A\uFF0C\u975E\u9759\u9ED8\uFF09",
61196
62422
  " \u5F00\u59CB\u4E00\u6B21\u8BA8\u8BBA\uFF1Apomaster brainstorm start [--ephemeral]"
@@ -61655,7 +62881,7 @@ async function runBrainstormPromote(rootDir, input) {
61655
62881
  return fail6(txOutError, [`brainstorm promote: FAILED \u2014 SCHEMA_INVALID (--tx-out)`]);
61656
62882
  }
61657
62883
  if (txPath === null) {
61658
- txPath = join13(discoveryScratchpadDirPath(rootDir, input.discoveryId), "promote-tx.json");
62884
+ txPath = join14(discoveryScratchpadDirPath(rootDir, input.discoveryId), "promote-tx.json");
61659
62885
  }
61660
62886
  try {
61661
62887
  await mkdir(discoveryScratchpadDirPath(rootDir, input.discoveryId), { recursive: true });
@@ -61782,11 +63008,11 @@ var UNKNOWN_TRIAGE_KEYS = [
61782
63008
  ];
61783
63009
  var DECISION_GRAPH_FILENAME = "decision-graph.json";
61784
63010
  function decisionGraphPath(rootDir, id) {
61785
- return join13(discoveryScratchpadDirPath(rootDir, id), DECISION_GRAPH_FILENAME);
63011
+ return join14(discoveryScratchpadDirPath(rootDir, id), DECISION_GRAPH_FILENAME);
61786
63012
  }
61787
63013
  var DECISION_INPUTS_FILENAME = "decision-inputs.json";
61788
63014
  function decisionInputsPath(rootDir, id) {
61789
- return join13(discoveryScratchpadDirPath(rootDir, id), DECISION_INPUTS_FILENAME);
63015
+ return join14(discoveryScratchpadDirPath(rootDir, id), DECISION_INPUTS_FILENAME);
61790
63016
  }
61791
63017
  async function loadDecisionGraph(rootDir, id) {
61792
63018
  const graphPath = decisionGraphPath(rootDir, id);
@@ -62531,7 +63757,7 @@ async function resolveResearchHost(rootDir, hostOption) {
62531
63757
  }
62532
63758
  };
62533
63759
  }
62534
- if (!existsSync21(join14(rootDir, ...host.split("/")))) {
63760
+ if (!existsSync23(join15(rootDir, ...host.split("/")))) {
62535
63761
  return {
62536
63762
  error: {
62537
63763
  code: "RESEARCH_HOST_NOT_FOUND",
@@ -62543,7 +63769,7 @@ async function resolveResearchHost(rootDir, hostOption) {
62543
63769
  return { host };
62544
63770
  }
62545
63771
  const padsDir = discoveryScratchpadsDirPath(rootDir);
62546
- if (!existsSync21(padsDir)) {
63772
+ if (!existsSync23(padsDir)) {
62547
63773
  return {
62548
63774
  error: {
62549
63775
  code: "RESEARCH_HOST_NOT_FOUND",
@@ -62556,7 +63782,7 @@ async function resolveResearchHost(rootDir, hostOption) {
62556
63782
  const active = [];
62557
63783
  for (const id of entries) {
62558
63784
  try {
62559
- const raw = JSON.parse(await readFile17(join14(padsDir, id, "state.json"), "utf8"));
63785
+ const raw = JSON.parse(await readFile17(join15(padsDir, id, "state.json"), "utf8"));
62560
63786
  if (typeof raw.state === "string" && (raw.state === "DISCOVERY" || raw.state === "READY_TO_PROMOTE")) {
62561
63787
  active.push(id);
62562
63788
  }
@@ -62584,7 +63810,7 @@ async function resolveResearchHost(rootDir, hostOption) {
62584
63810
  return { host: `.pomaster/discovery/scratchpads/${active[0]}/` };
62585
63811
  }
62586
63812
  async function readIndexYaml(indexPath) {
62587
- if (!existsSync21(indexPath))
63813
+ if (!existsSync23(indexPath))
62588
63814
  return null;
62589
63815
  try {
62590
63816
  return JSON.parse(await readFile17(indexPath, "utf8"));
@@ -62671,11 +63897,11 @@ async function runResearchStart(rootDir, input) {
62671
63897
  const created = [];
62672
63898
  const skipped = [];
62673
63899
  try {
62674
- const researchDir = join14(rootDir, ...artifactRoot.split("/"));
63900
+ const researchDir = join15(rootDir, ...artifactRoot.split("/"));
62675
63901
  await mkdir2(researchDir, { recursive: true });
62676
63902
  for (const fileName of RESEARCH_ARTIFACT_FILES) {
62677
- const filePath = join14(researchDir, fileName);
62678
- if (existsSync21(filePath)) {
63903
+ const filePath = join15(researchDir, fileName);
63904
+ if (existsSync23(filePath)) {
62679
63905
  skipped.push(`${artifactRoot}${fileName}`);
62680
63906
  continue;
62681
63907
  }
@@ -62746,8 +63972,8 @@ async function runResearchList(rootDir, hostArg) {
62746
63972
  ], [`research list: FAILED \u2014 SCHEMA_INVALID`]);
62747
63973
  }
62748
63974
  const hostRef = normalizeDir(hostArg);
62749
- const hostDir = join14(rootDir, ...hostRef.split("/"));
62750
- if (!existsSync21(hostDir)) {
63975
+ const hostDir = join15(rootDir, ...hostRef.split("/"));
63976
+ if (!existsSync23(hostDir)) {
62751
63977
  return failOutcome("research list", { host_ref: hostRef, artifacts: [] }, [
62752
63978
  {
62753
63979
  code: "RESEARCH_HOST_NOT_FOUND",
@@ -62756,7 +63982,7 @@ async function runResearchList(rootDir, hostArg) {
62756
63982
  }
62757
63983
  ], [`research list: FAILED \u2014 RESEARCH_HOST_NOT_FOUND (${hostRef})`]);
62758
63984
  }
62759
- const indexPath = join14(hostDir, "research", "index.yaml");
63985
+ const indexPath = join15(hostDir, "research", "index.yaml");
62760
63986
  const index = await readIndexYaml(indexPath);
62761
63987
  const artifacts = [];
62762
63988
  if (index !== null) {
@@ -62813,8 +64039,8 @@ async function runResearchInspect(rootDir, researchId) {
62813
64039
  }
62814
64040
  ], [`research inspect: FAILED \u2014 SCHEMA_INVALID`]);
62815
64041
  }
62816
- const hostDir = join14(rootDir, ...hostRef.split("/"));
62817
- if (!existsSync21(hostDir)) {
64042
+ const hostDir = join15(rootDir, ...hostRef.split("/"));
64043
+ if (!existsSync23(hostDir)) {
62818
64044
  return failOutcome("research inspect", {
62819
64045
  research_id: researchId,
62820
64046
  artifact_root: artifactRoot,
@@ -62831,9 +64057,9 @@ async function runResearchInspect(rootDir, researchId) {
62831
64057
  }
62832
64058
  ], [`research inspect: FAILED \u2014 RESEARCH_HOST_NOT_FOUND (${hostRef})`]);
62833
64059
  }
62834
- const researchDir = join14(hostDir, "research");
62835
- const indexPath = join14(researchDir, "index.yaml");
62836
- if (!existsSync21(indexPath)) {
64060
+ const researchDir = join15(hostDir, "research");
64061
+ const indexPath = join15(researchDir, "index.yaml");
64062
+ if (!existsSync23(indexPath)) {
62837
64063
  return failOutcome("research inspect", {
62838
64064
  research_id: researchId,
62839
64065
  artifact_root: artifactRoot,
@@ -62887,7 +64113,7 @@ async function runResearchInspect(rootDir, researchId) {
62887
64113
  }
62888
64114
  const files = RESEARCH_ARTIFACT_FILES.map((f) => ({
62889
64115
  file: f,
62890
- present: existsSync21(join14(researchDir, f))
64116
+ present: existsSync23(join15(researchDir, f))
62891
64117
  }));
62892
64118
  const missing = files.filter((f) => !f.present).map((f) => f.file);
62893
64119
  const rawFindings = Array.isArray(index.findings) ? index.findings : [];
@@ -62996,8 +64222,8 @@ async function runResearchInspect(rootDir, researchId) {
62996
64222
  }, human, warnings);
62997
64223
  }
62998
64224
  async function scratchpadDiscoveryState(rootDir, id) {
62999
- const statePath = join14(discoveryScratchpadDirPath(rootDir, id), "state.json");
63000
- if (!existsSync21(statePath)) {
64225
+ const statePath = join15(discoveryScratchpadDirPath(rootDir, id), "state.json");
64226
+ if (!existsSync23(statePath)) {
63001
64227
  return {
63002
64228
  error: {
63003
64229
  code: "SCRATCHPAD_NOT_FOUND",
@@ -63045,7 +64271,7 @@ function requestsOfIndex(index) {
63045
64271
  async function mutateIndexRequests(indexPath, artifactRoot, hostRef, mutate) {
63046
64272
  let index;
63047
64273
  let created = false;
63048
- if (existsSync21(indexPath)) {
64274
+ if (existsSync23(indexPath)) {
63049
64275
  let parsed;
63050
64276
  try {
63051
64277
  parsed = JSON.parse(await readFile17(indexPath, "utf8"));
@@ -63072,7 +64298,7 @@ async function mutateIndexRequests(indexPath, artifactRoot, hostRef, mutate) {
63072
64298
  const changed = mutate(index);
63073
64299
  if (!changed && !created)
63074
64300
  return { created, changed: false };
63075
- await mkdir2(join14(indexPath, ".."), { recursive: true });
64301
+ await mkdir2(join15(indexPath, ".."), { recursive: true });
63076
64302
  await writeFile5(indexPath, `${JSON.stringify(index, null, 2)}
63077
64303
  `, "utf8");
63078
64304
  return { created, changed: true };
@@ -63141,9 +64367,9 @@ async function runResearchRequest(rootDir, input) {
63141
64367
  hint: `\u8DEF\u7531\u952E\u8BCD\u5F62\uFF1A${Object.keys(RESEARCH_MODE_ROUTE_HINTS).join(" | ")}\u3002`
63142
64368
  }, [`research request: FAILED \u2014 SCHEMA_INVALID (--gap)`]);
63143
64369
  }
63144
- const indexPath = join14(discoveryScratchpadDirPath(rootDir, input.discoveryId), "research", "index.yaml");
64370
+ const indexPath = join15(discoveryScratchpadDirPath(rootDir, input.discoveryId), "research", "index.yaml");
63145
64371
  let existingIndex = null;
63146
- if (existsSync21(indexPath)) {
64372
+ if (existsSync23(indexPath)) {
63147
64373
  try {
63148
64374
  existingIndex = JSON.parse(await readFile17(indexPath, "utf8"));
63149
64375
  } catch {
@@ -63386,7 +64612,7 @@ async function runResearchHandoff(rootDir, input) {
63386
64612
  }
63387
64613
  }
63388
64614
  }
63389
- const indexPath = join14(discoveryScratchpadDirPath(rootDir, input.discoveryId), "research", "index.yaml");
64615
+ const indexPath = join15(discoveryScratchpadDirPath(rootDir, input.discoveryId), "research", "index.yaml");
63390
64616
  const statusMap = /* @__PURE__ */ new Map();
63391
64617
  for (const id of handoff.answered_requests)
63392
64618
  statusMap.set(id, "answered");
@@ -63687,8 +64913,8 @@ async function loadResearchFinding(rootDir, researchId, findingNumber) {
63687
64913
  }
63688
64914
  };
63689
64915
  }
63690
- const indexPath = join15(rootDir, ...artifactRoot.split("/"), "index.yaml");
63691
- if (!existsSync22(indexPath)) {
64916
+ const indexPath = join16(rootDir, ...artifactRoot.split("/"), "index.yaml");
64917
+ if (!existsSync24(indexPath)) {
63692
64918
  return {
63693
64919
  error: {
63694
64920
  code: "RESEARCH_ARTIFACT_NOT_FOUND",
@@ -63903,7 +65129,7 @@ async function runKnowledgeDemote(rootDir, input, deps) {
63903
65129
 
63904
65130
  // packages/cli/dist/memory.js
63905
65131
  init_dist();
63906
- import { readFileSync as readFileSync26 } from "node:fs";
65132
+ import { readFileSync as readFileSync28 } from "node:fs";
63907
65133
  import { homedir as homedir3 } from "node:os";
63908
65134
  var [MEMORY_ENTRY_NOT_FOUND, MEMORY_ALREADY_REVIEWED, MEMORY_REVIEW_REQUIRED, MEMORY_ALREADY_PROMOTED, MEMORY_PROMOTE_OWNER_REQUIRED, MEMORY_CAPTURE_DUPLICATE, MEMORY_HARVEST_NOT_RUN] = MEMORY_CLI_ERROR_VALUES;
63909
65135
  function toCliError2(err, docSection) {
@@ -63972,7 +65198,7 @@ function readStdinText() {
63972
65198
  };
63973
65199
  }
63974
65200
  try {
63975
- return { text: readFileSync26(0, "utf8") };
65201
+ return { text: readFileSync28(0, "utf8") };
63976
65202
  } catch (err) {
63977
65203
  return {
63978
65204
  error: {
@@ -64550,7 +65776,7 @@ async function runMemoryAudit(rootDir, input) {
64550
65776
 
64551
65777
  // packages/cli/dist/production.js
64552
65778
  init_dist();
64553
- import { readFileSync as readFileSync27 } from "node:fs";
65779
+ import { readFileSync as readFileSync29 } from "node:fs";
64554
65780
  var [BAND_SCHEMA_INVALID, BAND_NOT_FOUND, OBSERVATION_NOT_EVALUABLE, CHALLENGE_REJECTED, EVIDENCE_NOT_FOUND] = PRODUCTION_CLI_ERROR_VALUES;
64555
65781
  var NO_AUTO_APPLY_NOTE = "\u5448\u62A5\u6001\u2014\u2014\u4E0D\u5F97\u81EA\u52A8\u5E94\u7528\uFF08PRD \xA790.4 L5695 \u9010\u5B57\uFF09\uFF1APOMASTER_SELF_IMPROVEMENT_CANDIDATE \u65E0\u4EFB\u4F55\u81EA\u52A8\u5E94\u7528\u901A\u8DEF\uFF0C\u300C\u5E94\u7528\u300D\u6C38\u8FDC\u662F\u4EBA/Owner \u7ECF\u6CBB\u7406\u9762\u7684\u663E\u5F0F\u52A8\u4F5C";
64556
65782
  function fail5(result2, command, error) {
@@ -64812,7 +66038,7 @@ async function runProductionEvaluate(rootDir, input) {
64812
66038
  const filePath = input.observationsFile.trim();
64813
66039
  let text;
64814
66040
  try {
64815
- text = readFileSync27(filePath, "utf8");
66041
+ text = readFileSync29(filePath, "utf8");
64816
66042
  } catch (err) {
64817
66043
  return fail5(empty, command, {
64818
66044
  code: OBSERVATION_NOT_EVALUABLE,
@@ -65396,7 +66622,7 @@ async function runTraceList(rootDir) {
65396
66622
 
65397
66623
  // packages/cli/dist/agents.js
65398
66624
  init_dist();
65399
- import { existsSync as existsSync23, readFileSync as readFileSync28, writeFileSync as writeFileSync5 } from "node:fs";
66625
+ import { existsSync as existsSync25, readFileSync as readFileSync30, writeFileSync as writeFileSync6 } from "node:fs";
65400
66626
  var GATEKEEPER_DRIFT_OBSERVED = "GATEKEEPER_DRIFT_OBSERVED";
65401
66627
  var SUPERVISOR_TRIGGER_OBSERVED = "SUPERVISOR_TRIGGER_OBSERVED";
65402
66628
  async function runAgentsStatus(rootDir, input = {}) {
@@ -65556,10 +66782,10 @@ var DISPATCH_PACK_WRITE_FAILED = "IO_WRITE_FAILED";
65556
66782
  async function referenceSection(rootDir, taskId, warnings) {
65557
66783
  const lines = [];
65558
66784
  const manifestPath = `${contextsDirPath(rootDir)}/${taskId}.context.json`;
65559
- if (existsSync23(manifestPath)) {
66785
+ if (existsSync25(manifestPath)) {
65560
66786
  let generatedAtSeq = null;
65561
66787
  try {
65562
- const parsed = JSON.parse(readFileSync28(manifestPath, "utf8"));
66788
+ const parsed = JSON.parse(readFileSync30(manifestPath, "utf8"));
65563
66789
  const seq2 = isRecord6(parsed) ? parsed.generated_at_seq : void 0;
65564
66790
  if (typeof seq2 === "number")
65565
66791
  generatedAtSeq = seq2;
@@ -65720,7 +66946,7 @@ async function runAgentsDispatchPack(rootDir, input) {
65720
66946
  let outFile = null;
65721
66947
  if (input.out !== void 0) {
65722
66948
  try {
65723
- writeFileSync5(input.out, `${packLines.join("\n")}
66949
+ writeFileSync6(input.out, `${packLines.join("\n")}
65724
66950
  `, "utf8");
65725
66951
  outFile = toPosix(input.out);
65726
66952
  } catch (err) {
@@ -65891,6 +67117,10 @@ async function runMigrateTrellisSpec(rootDir, input) {
65891
67117
  }
65892
67118
  }
65893
67119
 
67120
+ // packages/cli/dist/baseline-tokens.js
67121
+ init_js_yaml();
67122
+ init_src();
67123
+
65894
67124
  // packages/cli/dist/index.js
65895
67125
  var defaultIo = {
65896
67126
  stdout: (line) => process.stdout.write(`${line}
@@ -65939,7 +67169,7 @@ function createProgram(runs, io = defaultIo) {
65939
67169
  });
65940
67170
  record({ command: "init", outcome, asJson });
65941
67171
  });
65942
- const baseline = program2.command("baseline").description("Project Engineering Baseline \u9500\u8D26\u4E0E\u786E\u8BA4 gate \u901A\u8DEF\uFF08R-M/R-L\uFF09\uFF1Aset = \u5355\u952E\u663E\u5F0F\u5199\u5165 .pomaster/baseline/<lane>/stack.yaml \u5E76\u540C\u6B65\u9500\u8D26 manifest unknowns \u53F0\u8D26\uFF08TTY init \u6280\u672F\u6808\u95EE\u5377\u7684\u975E\u4EA4\u4E92\u5B6A\u751F\u2014\u2014CI/\u811A\u672C\u573A\u666F\uFF1B\u952E\u8BCD\u5F62 fail-closed\uFF1B\u5DF2\u7B54\u952E\u6539\u578B\u62D2\u7EDD\uFF09\uFF1Bconfirm = \u57FA\u7EBF\u786E\u8BA4\u65BD\u65AD\uFF0814 unknowns \u5168\u9500\u8D26\u540E manifest \u8BB0 confirmed digest \u5FEB\u7167\u2014\u201424 \u6587\u4EF6\u5355\u4E00\u8D44\u4EA7\u6E05\u5355\uFF1B\u91CD\u786E\u8BA4\u4E09\u901A\u9053 --change / --ack-drifted --note / \u88F8\u91CD\u786E\u8BA4\u62D2\u7EDD\uFF1Bcloseout/doctor/status \u6D88\u8D39\u786E\u8BA4\u6001\uFF09");
67172
+ const baseline = program2.command("baseline").description("Project Engineering Baseline \u9500\u8D26\u4E0E\u786E\u8BA4 gate \u901A\u8DEF\uFF08R-M/R-L\uFF09\uFF1Aset = \u5355\u952E\u663E\u5F0F\u5199\u5165 .pomaster/baseline/<lane>/stack.yaml \u5E76\u540C\u6B65\u9500\u8D26 manifest unknowns \u53F0\u8D26\uFF08TTY init \u6280\u672F\u6808\u95EE\u5377\u7684\u975E\u4EA4\u4E92\u5B6A\u751F\u2014\u2014CI/\u811A\u672C\u573A\u666F\uFF1B\u952E\u8BCD\u5F62 fail-closed\uFF1B\u5DF2\u7B54\u952E\u6539\u578B\u62D2\u7EDD\uFF09\uFF1Bconfirm = \u57FA\u7EBF\u786E\u8BA4\u65BD\u65AD\uFF08\u963B\u585E\u96C6\u6E05\u96F6\u540E manifest \u8BB0 confirmed digest \u5FEB\u7167\u2014\u201425 \u6587\u4EF6\u5355\u4E00\u8D44\u4EA7\u6E05\u5355\uFF1B\u91CD\u786E\u8BA4\u4E09\u901A\u9053 --change / --ack-drifted --note / \u88F8\u91CD\u786E\u8BA4\u62D2\u7EDD\uFF1Bcloseout/doctor/status \u6D88\u8D39\u786E\u8BA4\u6001\uFF09");
65943
67173
  baseline.command("set").description("\u5355\u952E\u540E\u8865\u9500\u8D26/\u6CBB\u7406\u901A\u8DEF\u4FEE\u6539\uFF1A--lane <frontend|backend> --key <lane \u952E\u96C6\u95ED\u5305> --value <\u9009\u578B\u503C>\uFF08UNKNOWN \u8D77\u6B65\u8BCD\u5F62\u4E0D\u53EF\u4F5C\u503C\uFF1B\u540C\u503C\u91CD\u653E\u5E42\u7B49 NO_CHANGE \u5E76\u81EA\u6108\u53F0\u8D26\u6F0F\u9500\uFF1B\u5F02\u503C\u6539\u578B BASELINE_KEY_ALREADY_SET \u663E\u5F0F\u62D2\u7EDD\uFF1B\u786E\u8BA4\u6001\u5728\u5EA7\u65E0 --change \u2192 BASELINE_ALREADY_CONFIRMED\uFF0C\u6301 --change <CHANGE-id> \u4E14\u5BF9\u8C61\u5728\u518C\u3001lifecycle \u5408\u6CD5 \u2192 \u5199\u5165\u5E76\u8F6C pending-change\u2014\u2014\u540C\u4E00 CHANGE \u8FDE\u6539\u591A\u952E\u5168\u7A0B\u5141\u8BB8\uFF0C\u643A\u540C ref confirm \u7EC8\u7ED3\uFF09").requiredOption("--lane <lane>", "\u6280\u672F\u6808 lane\uFF08frontend | backend\uFF09").requiredOption("--key <key>", "stack.yaml \u952E\uFF08lane \u952E\u96C6\u95ED\u5305\uFF1Afrontend framework|language|build|router|state|grid|ui|css|testing\uFF1Bbackend language|framework|persistence|database|cache\uFF09").requiredOption("--value <value>", "\u9009\u578B\u503C\uFF08\u4FDD\u5B88\u8BCD\u5F62\uFF1A[A-Za-z0-9] \u8D77\u59CB\u3001[A-Za-z0-9 _./+#()-]\u3001\u2264120 \u5B57\u7B26\uFF1BUNKNOWN \u4E0D\u53EF\u4F5C\u503C\uFF09").option("--change <change-id>", "\u6CBB\u7406\u901A\u8DEF\u6388\u6743\uFF08\u4EC5\u786E\u8BA4\u6001\u5728\u5EA7\u65F6\u88AB\u6D88\u8D39\uFF09\uFF1ACHANGE.* \u5BF9\u8C61\u5728\u518C\u4E14 lifecycle \u2208 PROPOSED|CURRENT\uFF08kernel \u6821\u9A8C\uFF09\uFF1B\u5F02\u503C\u5199\u5165\u8F6C pending-change\uFF08\u8BB0\u5F55\u4FDD\u7559\uFF09\uFF0C\u643A\u540C ref confirm \u7EC8\u7ED3").option("--json", "machine-readable JSON output (\xA745)").action(async (opts, command) => {
65944
67174
  const outcome = await runBaselineSet(resolveDir(command), {
65945
67175
  lane: opts.lane,
@@ -65953,7 +67183,7 @@ function createProgram(runs, io = defaultIo) {
65953
67183
  asJson: command.opts().json === true
65954
67184
  });
65955
67185
  });
65956
- baseline.command("confirm").description('\u57FA\u7EBF\u786E\u8BA4\u65BD\u65AD\uFF08R-L gate\uFF1Bverdict + exit code\uFF09\uFF1A\u524D\u63D0 = 14 unknowns \u5168\u9500\u8D26\uFF08BASELINE_UNKNOWNS_REMAINING fail-closed \u9010\u6761\u5217\u51FA\u7F3A\u952E\uFF09\uFF1B\u52A8\u4F5C = manifest.yaml \u5199 confirmed \u786E\u8BA4\u8BB0\u5F55\uFF08at_seq \u65F6\u70B9\u951A + 24 \u6587\u4EF6\u786E\u8BA4\u8D44\u4EA7\u6E05\u5355 sha256 \u5FEB\u7167 = 2 stack.yaml + 22 md\u2014\u2014N1 \u5355\u4E00\u5206\u6BCD\uFF0Cmanifest \u4E0D\u81EA\u5F15\u7528\uFF09\uFF1B\u521D\u6B21\u786E\u8BA4\u4E0D\u9700\u8981\u4EFB\u4F55\u901A\u9053\uFF1B\u5DF2\u786E\u8BA4\u4E14 digest \u65E0\u6F02\u79FB \u2192 NO_CHANGE \u96F6\u5199\u5165\uFF1B\u91CD\u786E\u8BA4\u4E09\u901A\u9053\uFF08N2/Owner 09-06 \u8865\u88C1\u5B9A\uFF09\uFF1A--change <CHANGE-id>\uFF08\u6CBB\u7406\u901A\u8DEF\uFF1Adrifted \u8986\u76D6 / pending \u540C ref \u7EC8\u7ED3\uFF09\u6216 --ack-drifted --note "<\u7406\u7531>"\uFF08Owner \u624B\u6539\u58F0\u660E\uFF1Ajournal BASELINE_ACK \u7559\u75D5 + \u8BB0\u5F55 ack \u6807\u8BB0\uFF1BAI \u4EE3\u8DD1\u987B\u6301 Owner \u6307\u793A\uFF09\uFF1B\u88F8\u91CD\u786E\u8BA4 = BASELINE_RECONFIRM_REQUIRES_CHANGE \u663E\u5F0F\u62D2\u7EDD\uFF1Bcloseout \u6D88\u8D39\uFF1ABASELINE_NOT_CONFIRMED / BASELINE_DRIFT \u4E24\u963B\u585E\u7801').option("--change <change-id>", "\u91CD\u786E\u8BA4\u901A\u9053 1\uFF08\u6CBB\u7406\u901A\u8DEF\uFF09\uFF1ACHANGE.* \u5BF9\u8C61\u5728\u518C\u4E14 lifecycle \u2208 PROPOSED|CURRENT\uFF1Bdrifted \u91CD\u786E\u8BA4\u7684\u6388\u6743\u8986\u76D6 / pending-change \u53D8\u66F4\u6279\u7684\u540C ref \u7EC8\u7ED3").option("--ack-drifted", "\u91CD\u786E\u8BA4\u901A\u9053 2\uFF08Owner \u624B\u6539\u58F0\u660E\uFF09\uFF1A\u663E\u5F0F\u58F0\u660E\u5F53\u524D\u6F02\u79FB\u4E3A\u6388\u6743\u624B\u6539\uFF0822 \u4EFD md \u65E0\u6CBB\u7406\u5199\u547D\u4EE4\u7684\u624B\u6539/\u8865\u6587\u6863\u901A\u8DEF\uFF09\uFF1B\u987B\u4E0E --note \u540C\u7528\uFF1Bjournal \u843D BASELINE_ACK \u7559\u75D5\uFF1BAI \u4EE3\u8DD1\u987B\u6301 Owner \u6307\u793A").option("--note <note>", "\u624B\u6539\u58F0\u660E\u7406\u7531\uFF08--ack-drifted \u5FC5\u586B\uFF1B\u5355\u884C \u2264200 \u5B57\u7B26\uFF1B\u5165 manifest ack \u6BB5\u4E0E journal\uFF09").option("--json", "machine-readable JSON output (\xA745)").action(async (_opts, command) => {
67186
+ baseline.command("confirm").description('\u57FA\u7EBF\u786E\u8BA4\u65BD\u65AD\uFF08R-L gate\uFF1Bverdict + exit code\uFF09\uFF1A\u524D\u63D0 = \u963B\u585E\u96C6\u6E05\u96F6\uFF08P-C1\uFF1Aunknowns \u53F0\u8D26\u53CC\u8BCD\u5F62\u2014\u2014\u8C41\u514D\u767B\u8BB0\u884C\u4E0D\u963B\u585E\uFF0C\u963B\u585E\u952E BASELINE_UNKNOWNS_REMAINING fail-closed \u9010\u6761\u5217\u51FA\uFF0C\u7ED3\u6784\u5316\u884C\u5F62\u72B6\u635F\u574F INVALID_STATE\uFF09\uFF1B\u52A8\u4F5C = manifest.yaml \u5199 confirmed \u786E\u8BA4\u8BB0\u5F55\uFF08at_seq \u65F6\u70B9\u951A + 25 \u6587\u4EF6\u786E\u8BA4\u8D44\u4EA7\u6E05\u5355 sha256 \u5FEB\u7167 = 2 stack.yaml + 22 md + 1 design-tokens.yaml\u2014\u2014N1 \u5355\u4E00\u5206\u6BCD\uFF0CADR-20 \u6269 25\uFF0Cmanifest \u4E0D\u81EA\u5F15\u7528\uFF09\uFF1B\u521D\u6B21\u786E\u8BA4\u4E0D\u9700\u8981\u4EFB\u4F55\u901A\u9053\uFF1B\u5DF2\u786E\u8BA4\u4E14 digest \u65E0\u6F02\u79FB \u2192 NO_CHANGE \u96F6\u5199\u5165\uFF1B\u91CD\u786E\u8BA4\u4E09\u901A\u9053\uFF08N2/Owner 09-06 \u8865\u88C1\u5B9A\uFF09\uFF1A--change <CHANGE-id>\uFF08\u6CBB\u7406\u901A\u8DEF\uFF1Adrifted \u8986\u76D6 / pending \u540C ref \u7EC8\u7ED3\uFF09\u6216 --ack-drifted --note "<\u7406\u7531>"\uFF08Owner \u624B\u6539\u58F0\u660E\uFF1Ajournal BASELINE_ACK \u7559\u75D5 + \u8BB0\u5F55 ack \u6807\u8BB0\uFF1BAI \u4EE3\u8DD1\u987B\u6301 Owner \u6307\u793A\uFF09\uFF1B\u88F8\u91CD\u786E\u8BA4 = BASELINE_RECONFIRM_REQUIRES_CHANGE \u663E\u5F0F\u62D2\u7EDD\uFF1Bcloseout \u6D88\u8D39\uFF1ABASELINE_NOT_CONFIRMED / BASELINE_DRIFT \u4E24\u963B\u585E\u7801').option("--change <change-id>", "\u91CD\u786E\u8BA4\u901A\u9053 1\uFF08\u6CBB\u7406\u901A\u8DEF\uFF09\uFF1ACHANGE.* \u5BF9\u8C61\u5728\u518C\u4E14 lifecycle \u2208 PROPOSED|CURRENT\uFF1Bdrifted \u91CD\u786E\u8BA4\u7684\u6388\u6743\u8986\u76D6 / pending-change \u53D8\u66F4\u6279\u7684\u540C ref \u7EC8\u7ED3").option("--ack-drifted", "\u91CD\u786E\u8BA4\u901A\u9053 2\uFF08Owner \u624B\u6539\u58F0\u660E\uFF09\uFF1A\u663E\u5F0F\u58F0\u660E\u5F53\u524D\u6F02\u79FB\u4E3A\u6388\u6743\u624B\u6539\uFF0822 \u4EFD md \u65E0\u6CBB\u7406\u5199\u547D\u4EE4\u7684\u624B\u6539/\u8865\u6587\u6863\u901A\u8DEF\uFF09\uFF1B\u987B\u4E0E --note \u540C\u7528\uFF1Bjournal \u843D BASELINE_ACK \u7559\u75D5\uFF1BAI \u4EE3\u8DD1\u987B\u6301 Owner \u6307\u793A").option("--note <note>", "\u624B\u6539\u58F0\u660E\u7406\u7531\uFF08--ack-drifted \u5FC5\u586B\uFF1B\u5355\u884C \u2264200 \u5B57\u7B26\uFF1B\u5165 manifest ack \u6BB5\u4E0E journal\uFF09").option("--json", "machine-readable JSON output (\xA745)").action(async (_opts, command) => {
65957
67187
  const opts = command.opts();
65958
67188
  const outcome = await runBaselineConfirm(resolveDir(command), {
65959
67189
  ...opts.change !== void 0 ? { change: opts.change } : {},
@@ -67031,6 +68261,37 @@ function createProgram(runs, io = defaultIo) {
67031
68261
  asJson: command.opts().json === true
67032
68262
  });
67033
68263
  });
68264
+ const recon = program2.command("recon").description("\u5BBF\u4E3B\u4EE3\u7801\u4E8B\u5B9E recon \u7F16\u6392\u58F3\uFF08F-M5 \u9996\u6279\u4E09\u4E59 B8/B4/B1\uFF1BB10 \u4E59\uFF09\uFF1A\u679A\u4E3E \u2192 \u5206\u6790/\u91C7\u96C6 \u2192 blob+17 \u89C2\u5BDF\u56DE\u6267 sidecar \u2192 \u5448\u73B0\u2014\u2014\u4EA7\u7269\u53EA\u843D evidence/{blobs,observations}/ sidecar \u5E73\u9762\uFF0C\u96F6\u6743\u5A01\u6587\u4EF6\u5199\u53E3\u96F6 store \u4E8B\u52A1\uFF08persistObservationRecord \u9996\u4E2A\u751F\u4EA7\u6D88\u8D39\u65B9\uFF09");
68265
+ recon.command("import-graph").description("\u5BBF\u4E3B\u6E90\u6587\u4EF6 import \u56FE\u9759\u6001\u626B\u63CF\uFF08B8 \u4E59\uFF09\uFF1AcollectSourceFiles \u5F62\u6001\u679A\u4E3E\uFF08\u8DF3\u8FC7 node_modules/dist/.git/coverage/.pomaster\uFF1B.ts/.tsx/.js/.jsx/.mjs/.cjs/.vue\uFF09\u2192 kernel analyzeImportGraph \u7EAF\u51FD\u6570\u76F4\u8C03\uFF08\u96F6\u7B2C\u4E8C\u5B9E\u73B0\uFF1Bmapping \u6052\u7A7A\u2014\u2014\u8001\u9879\u76EE\u65E0 governed id\uFF0Cunmapped \u6E05\u5355\u5373\u4EA7\u51FA\u7981\u9759\u9ED8\u4E22\u5F03\uFF09\u2192 \xA7148 \u62A5\u544A\u843D blob\uFF08persistEvidenceArtifact \u5185\u5BB9\u5BFB\u5740\uFF09\u2192 OBS \u56DE\u6267\u843D 17 sidecar\uFF08persistObservationRecord\uFF1Bresult=OBSERVED \u5E26 blob ref\u3001surface=STRUCTURAL_REALITY\u3001sensor=SENSOR.BUILD.STATIC\uFF09\u2192 \u5448\u73B0\uFF08mapping \u547D\u4E2D/externalImports/unmapped \u6E05\u5355/confidence\uFF09\uFF1B\u96F6\u6E90\u6587\u4EF6 \u2192 INCONCLUSIVE \u8D1F\u503C\u515C\u5E95\u843D\u8D26\u4E0D\u4F2A\u9020\u7EFF").requiredOption("--execution-id <AGX-n>", "\u6267\u884C\u8EAB\u4EFD\u951A\uFF08AGX-<\u5E74\u4EFD>-<\u5E8F\u53F7>\uFF1BOBS \u56DE\u6267 execution_id \u5FC5\u586B\u2014\u2014S1 \u7981\u81EA\u9020\u8EAB\u4EFD\uFF0C\u987B\u4E3A executions/ \u5DF2\u767B\u8BB0\u6863\u6848\uFF0C\u5DF2\u5C01\u53E3\u6267\u884C\u5141\u8BB8\u4E8B\u540E\u8865\u5F55\uFF09").option("--json", "machine-readable JSON output (\xA745)").action(async (opts, command) => {
68266
+ const outcome = await runReconImportGraph(resolveDir(command), {
68267
+ executionId: opts.executionId
68268
+ });
68269
+ record({
68270
+ command: "recon import-graph",
68271
+ outcome,
68272
+ asJson: command.opts().json === true
68273
+ });
68274
+ });
68275
+ recon.command("migrations").description("migration \u76EE\u5F55\u76D8\u70B9\uFF08B4 \u4E59\uFF09\uFF1A\u4E94\u6808\u8BCD\u5F62\u9762\u7EAF\u8BFB\u76D8\u679A\u4E3E\uFF08prisma/flyway/liquibase/alembic/django_style\u2014\u2014\u96F6\u5916\u90E8\u4F9D\u8D56\u96F6\u5DE5\u5177\u6267\u884C\uFF0Cliquibase/flyway \u5DE5\u5177\u672C\u4F53 license \u7EA2\u706F\u4E0D\u6267\u884C\uFF1B\u8DF3\u8FC7 node_modules/dist/.git/coverage/.pomaster/.venv/venv/vendor/target/build\uFF09\u2192 ENVREC \u56DE\u6267\u843D 17 sidecar\uFF08persistObservationRecord \u663E\u5F0F recordId\uFF1Bdoctor_verdict=WRONG_OR_UNVERIFIED_INSTANCE\u2014\u2014\u7EAF\u8BFB\u76D8\u76D8\u70B9\u4E0D\u786E\u8BA4\u5B9E\u4F8B\u8EAB\u4EFD\uFF09\u2192 \u5448\u73B0\uFF08\u5404\u6808\u547D\u4E2D\u8BA1\u6570 + \u6587\u4EF6\u6E05\u5355\u5168\u91CF\u96F6\u622A\u65AD\uFF09\uFF1B\u4E94\u6808\u8BCD\u5F62\u9762\u5168\u7F3A\u5E2D \u2192 NOT_RUN \u4E0D\u4F2A\u9020\u7A7A\u8DD1\u7EFF\uFF1B\u76D8\u70B9\u4E0D\u78B0 stack \u5206\u6BCD\uFF08\u96F6 stack.yaml \u5199\u53E3\uFF0C\u8BCD\u5F62\u76D8\u70B9\u975E stack \u65AD\u8A00\uFF09").requiredOption("--execution-id <AGX-n>", "\u6267\u884C\u8EAB\u4EFD\u951A\uFF08AGX-<\u5E74\u4EFD>-<\u5E8F\u53F7>\uFF1BENVREC \u56DE\u6267 execution_id \u5FC5\u586B\u2014\u2014S1 \u7981\u81EA\u9020\u8EAB\u4EFD\uFF0C\u987B\u4E3A executions/ \u5DF2\u767B\u8BB0\u6863\u6848\uFF0C\u5DF2\u5C01\u53E3\u6267\u884C\u5141\u8BB8\u4E8B\u540E\u8865\u5F55\uFF09").option("--json", "machine-readable JSON output (\xA745)").action(async (opts, command) => {
68276
+ const outcome = await runReconMigrations(resolveDir(command), {
68277
+ executionId: opts.executionId
68278
+ });
68279
+ record({
68280
+ command: "recon migrations",
68281
+ outcome,
68282
+ asJson: command.opts().json === true
68283
+ });
68284
+ });
68285
+ recon.command("sbom").description("SBOM \u4F9D\u8D56\u6E05\u5355\u91C7\u96C6\u817F\uFF08B1 \u4E59(a)\uFF0Ccdxgen Apache-2.0\uFF09\uFF1Adetect \u63A2 cdxgen \u5728 PATH\uFF08findExecutableOnPath \u5355\u4E00\u63A2\u6D4B\u9762\u2014\u2014\u7F3A\u5E2D \u2192 NOT_INSTALLED \u663E\u5F0F\u7F3A\u5E2D\u5E26 reason+installHint \u4E0D\u4F2A\u9020\uFF09\u2192 spawn `cdxgen -r -o <tmp>/bom.json <root>`\uFF08\u771F\u5B9E spawnSync\uFF1B64MB maxBuffer\uFF1BPATH \u5F15\u53F7\u6D88\u6BD2\uFF1Btmp \u7528 os.tmpdir \u6D3E\u751F\u8FD0\u884C\u540E\u6E05\u7406\uFF09\u2192 CycloneDX \u8BCD\u5F62\u6821\u9A8C\u56DE\u8BFB\uFF08bomFormat=CycloneDX + specVersion + components[]/dependencies[]\u2014\u2014\u89E3\u6790\u5931\u8D25/\u8BCD\u5F62\u6F02\u79FB \u2192 INCONCLUSIVE \u8D1F\u503C\u515C\u5E95\u843D\u8D26\u7981\u9ED8\u8BA4\u503C\uFF09\u2192 BOM \u539F\u6837\u5B57\u8282\u843D blob\uFF08persistEvidenceArtifact\uFF09\u2192 OBS \u56DE\u6267\u843D 17 sidecar\uFF08result=OBSERVED \u5E26 blob ref\uFF1Bsurface=STRUCTURAL_REALITY\u2014\u2014PRD \xA76.4 dependency graph \u2208 \u7ED3\u6784\u4E8B\u5B9E\u9762\uFF09\u2192 \u5448\u73B0\uFF08components/dependencies \u8BA1\u6570\uFF09\uFF1Bstack \u5019\u9009\u5316\u4E0D\u5728\u672C\u6279\uFF08Proposal \u524D\u7F6E\uFF09\u2014\u2014\u96F6 StackObservationCandidate \u89E6\u78B0\u96F6 stack.yaml \u5199\u53E3").requiredOption("--execution-id <AGX-n>", "\u6267\u884C\u8EAB\u4EFD\u951A\uFF08AGX-<\u5E74\u4EFD>-<\u5E8F\u53F7>\uFF1BOBS \u56DE\u6267 execution_id \u5FC5\u586B\u2014\u2014S1 \u7981\u81EA\u9020\u8EAB\u4EFD\uFF0C\u987B\u4E3A executions/ \u5DF2\u767B\u8BB0\u6863\u6848\uFF0C\u5DF2\u5C01\u53E3\u6267\u884C\u5141\u8BB8\u4E8B\u540E\u8865\u5F55\uFF09").option("--json", "machine-readable JSON output (\xA745)").action(async (opts, command) => {
68286
+ const outcome = await runReconSbom(resolveDir(command), {
68287
+ executionId: opts.executionId
68288
+ });
68289
+ record({
68290
+ command: "recon sbom",
68291
+ outcome,
68292
+ asJson: command.opts().json === true
68293
+ });
68294
+ });
67034
68295
  return program2;
67035
68296
  }
67036
68297
  function collectValues(value, previous) {