@akagilnc/pi-workflow-roles 0.1.5375 → 0.1.5382

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.
Files changed (43) hide show
  1. package/dist/acp-host/production-host.js +479 -425
  2. package/dist/collector-tool-schemas.js +18 -0
  3. package/dist/diarist-contracts.js +26 -0
  4. package/dist/filed-submission.js +28 -0
  5. package/dist/gatekeeper-role.js +6 -10
  6. package/dist/gleaner-left-contracts.js +16 -0
  7. package/dist/headless-host/production-host.js +495 -441
  8. package/dist/judge-role.js +8 -16
  9. package/dist/migrate-book-topology.js +262 -7
  10. package/dist/package-contracts/reviewer-output.js +16 -0
  11. package/dist/package-contracts/worker-output.js +18 -2
  12. package/dist/public-cli/instruction-seat-run.js +9 -12
  13. package/dist/public-cli/main.js +283 -26
  14. package/dist/role-submission-declarations.js +131 -0
  15. package/dist/secretariat-contracts.js +23 -1
  16. package/dist/submission-gate.js +5 -8
  17. package/package.json +1 -1
  18. package/src/auditor-role.ts +2 -8
  19. package/src/collector-role.ts +5 -28
  20. package/src/countersign-role.ts +2 -7
  21. package/src/diarist-contracts.ts +37 -0
  22. package/src/diarist-role.ts +4 -44
  23. package/src/doctor-role.ts +16 -11
  24. package/src/filed-submission.ts +44 -0
  25. package/src/gatekeeper-role.ts +6 -14
  26. package/src/gleaner-left-contracts.ts +26 -1
  27. package/src/gleaner-left-role.ts +4 -32
  28. package/src/inspector-role.ts +2 -7
  29. package/src/judge-role.ts +12 -24
  30. package/src/merger-role.ts +5 -8
  31. package/src/navigator-role.ts +2 -8
  32. package/src/notary-role.ts +5 -20
  33. package/src/package-contracts/reviewer-output.ts +25 -0
  34. package/src/package-contracts/worker-output.ts +43 -5
  35. package/src/public-cli/instruction-seat-run.ts +10 -13
  36. package/src/reviewer-role.ts +7 -35
  37. package/src/role-runtime.ts +7 -35
  38. package/src/role-submission-declarations.ts +143 -0
  39. package/src/secretariat-contracts.ts +35 -0
  40. package/src/secretariat-role.ts +4 -40
  41. package/src/submission-gate.ts +8 -9
  42. package/src/worker-role.ts +62 -79
  43. package/src/worker-submission-gates.ts +3 -0
@@ -8611,11 +8611,26 @@ var init_judge_output = __esm({
8611
8611
  });
8612
8612
 
8613
8613
  // src/package-contracts/reviewer-output.ts
8614
- var REVIEWER_OUTPUT_TOOL_NAME;
8614
+ var REVIEWER_OUTPUT_TOOL_NAME, REVIEWER_AMENDMENTS_DESCRIPTION, REVIEWER_STATUS_DESCRIPTION, reviewerOutputObject, reviewerOutputSchema;
8615
8615
  var init_reviewer_output = __esm({
8616
8616
  "src/package-contracts/reviewer-output.ts"() {
8617
8617
  "use strict";
8618
+ init_build();
8619
+ init_open_tool_schema();
8620
+ init_terminating_infrastructure();
8618
8621
  REVIEWER_OUTPUT_TOOL_NAME = "ak_reviewer_output";
8622
+ REVIEWER_AMENDMENTS_DESCRIPTION = "\u5DF2\u8FD0\u884C lens \u7684 amendments \u627F\u8F7D candidates\u3001\u9010\u6761\u5904\u7F6E\u4E0E verdict \u7684\u5B8C\u6574\u62A5\u544A\uFF08\u975E\u4EC5 verdict \u884C\uFF09\uFF1B\u663E\u5F0F\u5355\u8F74\u65F6\u53E6\u4E00\u8F74\u53EF\u7701\u7565\uFF08completeness / correctness\uFF09\u3002hard-stop\uFF0Fusage error \u4E3A refused \u65F6\uFF0C\u5DF2\u4EA7\u51FA\u62A5\u544A\u4ECD\u7167\u5F55\u5BF9\u5E94 lens \u5B57\u6BB5\u3002";
8623
+ REVIEWER_STATUS_DESCRIPTION = "completed | refused\u3002\u4E24\u79CD\u6B63\u5E38 lens verdict\uFF08completeness / correctness\uFF09\u5747 completed\uFF1Bhard-stop \u4E0E usage error \u4E3A refused\uFF08\u5DF2\u4EA7\u51FA\u62A5\u544A\u4ECD\u7167\u5F55\u8FDB\u6240\u9009 lens amendments\uFF09\u3002";
8624
+ reviewerOutputObject = typebox_exports.Object({
8625
+ status: typebox_exports.Unknown({ description: REVIEWER_STATUS_DESCRIPTION }),
8626
+ amendments: typebox_exports.Unknown({ description: REVIEWER_AMENDMENTS_DESCRIPTION }),
8627
+ diagnostic: typebox_exports.Unknown({
8628
+ description: "\u62D2\u7EDD\u8BCA\u65AD\u8BF4\u660E\uFF1Bhard-stop\uFF0Fusage error \u539F\u56E0\u8FDB\u6B64\u5B57\u6BB5\uFF0C\u5DF2\u4EA7\u51FA\u62A5\u544A\u53E6\u7167\u5F55 amendments"
8629
+ })
8630
+ });
8631
+ reviewerOutputSchema = withTerminatingOutputDeclarations(
8632
+ openToolObject(reviewerOutputObject)
8633
+ );
8619
8634
  }
8620
8635
  });
8621
8636
 
@@ -14644,14 +14659,28 @@ var init_fixer_packet = __esm({
14644
14659
  });
14645
14660
 
14646
14661
  // src/package-contracts/worker-output.ts
14647
- var CODER_OUTPUT_TOOL_NAME;
14662
+ var CODER_OUTPUT_TOOL_NAME, CODER_STATUS_DESCRIPTION, coderOutputObject, coderOutputSchema;
14648
14663
  var init_worker_output = __esm({
14649
14664
  "src/package-contracts/worker-output.ts"() {
14650
14665
  "use strict";
14666
+ init_build();
14667
+ init_open_tool_schema();
14651
14668
  init_fixer_output();
14652
14669
  init_fixer_packet();
14653
- init_fixer_output();
14670
+ init_terminating_infrastructure();
14654
14671
  CODER_OUTPUT_TOOL_NAME = "ak_coder_output";
14672
+ CODER_STATUS_DESCRIPTION = `planned | completed | refused | partially_completed | unfinished\u3002unfinished\uFF1A\u7F3A\u524D\u7F6E\u6216\u8FDD\u5BAA\u7EA6\u675F\u81F4\u672C\u5C40\u672A\u5B8C\u6210\u3002${PARTIALLY_COMPLETED_DEFINITION}`;
14673
+ coderOutputObject = typebox_exports.Object({
14674
+ status: typebox_exports.Unknown({ description: CODER_STATUS_DESCRIPTION }),
14675
+ report: typebox_exports.Unknown({ description: "\u5982\u5B9E\u7ED3\u679C\u62A5\u544A" }),
14676
+ remainingScope: typebox_exports.Unknown({ description: "\u672C\u5C40\u540E\u5269\u4F59\u5DE5\u4F5C" }),
14677
+ reason: typebox_exports.Unknown({
14678
+ description: "\u963B\u65AD\u539F\u56E0\uFF1A\u7F3A\u524D\u7F6E\u6216\u8FDD\u5BAA\u7EA6\u675F\u3002\u7F3A\u5F85\u51B3 owner \u51B3\u5B9A\u6216\u7B54\u590D\u5C5E\u7F3A\u524D\u7F6E\u3002"
14679
+ })
14680
+ });
14681
+ coderOutputSchema = withTerminatingOutputDeclarations(
14682
+ openToolObject(coderOutputObject)
14683
+ );
14655
14684
  }
14656
14685
  });
14657
14686
 
@@ -14663,7 +14692,7 @@ var init_canonical_json = __esm({
14663
14692
  });
14664
14693
 
14665
14694
  // src/doctor-contracts.ts
14666
- var DOCTOR_OUTPUT_TOOL_NAME, DOCTOR_AUDIT_TOOL_NAME, DOCTOR_TARGET_KINDS, DOCTOR_DISPOSITIONS, DOCTOR_PRESCRIPTION_KINDS, biteActual, biteNone, DOCTOR_BITE_KINDS, DOCTOR_STATUS_DESCRIPTION, doctorSubmissionObject, doctorSubmissionSchema, doctorEvidenceReadSchema;
14695
+ var DOCTOR_OUTPUT_TOOL_NAME, DOCTOR_AUDIT_TOOL_NAME, DOCTOR_OUTPUT_TOOL_DESCRIPTION, DOCTOR_TARGET_KINDS, DOCTOR_DISPOSITIONS, DOCTOR_PRESCRIPTION_KINDS, biteActual, biteNone, DOCTOR_BITE_KINDS, DOCTOR_STATUS_DESCRIPTION, doctorSubmissionObject, doctorSubmissionSchema, doctorEvidenceReadSchema;
14667
14696
  var init_doctor_contracts = __esm({
14668
14697
  "src/doctor-contracts.ts"() {
14669
14698
  "use strict";
@@ -14674,6 +14703,7 @@ var init_doctor_contracts = __esm({
14674
14703
  init_unknown_value();
14675
14704
  DOCTOR_OUTPUT_TOOL_NAME = "ak_doctor_output";
14676
14705
  DOCTOR_AUDIT_TOOL_NAME = "ak_doctor_audit_decision";
14706
+ DOCTOR_OUTPUT_TOOL_DESCRIPTION = "\u63D0\u4EA4\u552F\u4E00\u7EC8\u5C40\u5355\u6848\u8BC1\u8BCD\uFF1Bcompleted \u5141\u8BB8\u7A7A findings\u3002";
14677
14707
  DOCTOR_TARGET_KINDS = ["law", "gate", "template", "station", "seat"];
14678
14708
  DOCTOR_DISPOSITIONS = ["keep", "thin", "delete"];
14679
14709
  DOCTOR_PRESCRIPTION_KINDS = ["retain", "delete", "simplify", "patch", "addMechanism"];
@@ -14811,12 +14841,27 @@ var init_countersign_contracts = __esm({
14811
14841
  });
14812
14842
 
14813
14843
  // src/gleaner-left-contracts.ts
14814
- var GLEANER_LEFT_OUTPUT_TOOL_NAME;
14844
+ var GLEANER_LEFT_OUTPUT_TOOL_NAME, gleanerLeftOutputSchema;
14815
14845
  var init_gleaner_left_contracts = __esm({
14816
14846
  "src/gleaner-left-contracts.ts"() {
14817
14847
  "use strict";
14848
+ init_build();
14849
+ init_open_tool_schema();
14850
+ init_terminating_infrastructure();
14818
14851
  init_unknown_value();
14819
14852
  GLEANER_LEFT_OUTPUT_TOOL_NAME = "ak_gleaner_left_output";
14853
+ gleanerLeftOutputSchema = withTerminatingOutputDeclarations(
14854
+ openToolObject(
14855
+ typebox_exports.Object({
14856
+ status: typebox_exports.Unknown({
14857
+ description: "completed"
14858
+ }),
14859
+ findings: typebox_exports.Unknown({
14860
+ description: "\u5F39\u7AE0\u5217\u8868\uFF1B\u6BCF\u6761\u53EF\u542B pointer\uFF08\u6587\u4EF6/\u884C\u6307\u9488\uFF09\u4E0E statement\uFF08\u7591\u70B9\u9648\u8FF0\uFF09\uFF0C\u539F\u6837\u7559\u5B58\u3002\u7A7A\u5217\u8868\u5408\u6CD5\u5B8C\u5C40\uFF1B\u673A\u5668\u4E0D\u5224\u5F39\u7AE0\u662F\u5426\u6210\u7ACB\u3002"
14861
+ })
14862
+ })
14863
+ )
14864
+ );
14820
14865
  }
14821
14866
  });
14822
14867
 
@@ -14853,23 +14898,69 @@ var init_ticket_provenance_contracts = __esm({
14853
14898
  });
14854
14899
 
14855
14900
  // src/diarist-contracts.ts
14856
- var DIARIST_OUTPUT_TOOL_NAME;
14901
+ var DIARIST_OUTPUT_TOOL_NAME, DIARIST_SESSIONS_DESCRIPTION, diaristOutputSchema;
14857
14902
  var init_diarist_contracts = __esm({
14858
14903
  "src/diarist-contracts.ts"() {
14859
14904
  "use strict";
14905
+ init_build();
14906
+ init_open_tool_schema();
14907
+ init_terminating_infrastructure();
14860
14908
  init_ticket_provenance_contracts();
14861
14909
  init_run_ticket_number();
14862
14910
  init_unknown_value();
14863
14911
  DIARIST_OUTPUT_TOOL_NAME = "ak_diarist_output";
14912
+ DIARIST_SESSIONS_DESCRIPTION = "\u5BF9\u8BDD\u8FB9\u754C\u3002\u6BCF\u5377\u542B path\uFF08\u4F1A\u8BDD\u5377\u7EDD\u5BF9\u6216\u53EF\u8BFB\u8DEF\u5F84\uFF09\u4E0E ranges\uFF08\u672C\u5377\u672C\u8F6E\u5404\u533A\u95F4\uFF09\u3002\u6BCF\u6BB5\u533A\u95F4\u542B from / to\uFF1B\u8D77\u70B9\u4E0E\u7EC8\u70B9\u5404\u5199 id\uFF08\u539F\u751F id\uFF09\u6216 line\uFF08\u672C\u8F6E\u884C\u53F7\uFF09\uFF0C\u4E8C\u9009\u4E00\u3002\u7A7A\u5217\u8868\uFF1D\u672C\u8F6E\u65E0\u5BF9\u8BDD\u53EF\u5212\u3002\u7AEF\u70B9\u65E0\u6CD5\u6307\u540D\u65F6\u8D70 reask\uFF0C\u4E0D\u4E2D\u6B62\u3002";
14913
+ diaristOutputSchema = withTerminatingOutputDeclarations(
14914
+ openToolObject(
14915
+ typebox_exports.Object({
14916
+ status: typebox_exports.Unknown({
14917
+ description: "completed | escalate"
14918
+ }),
14919
+ ticketNumber: typebox_exports.Optional(
14920
+ typebox_exports.Unknown({
14921
+ description: "\u672C\u5EAD\u5BF9\u8C61\u7968\u53F7\uFF08\u6B63\u6574\u6570\uFF09\u6216 null/\u7701\u7565\uFF1D\u771F\u65E0\u7968\uFF1B\u4E0B\u6E38\u8D70 typed \u952E\uFF1B\u8BA4\u4E0D\u51FA\u7528 status=escalate\uFF0C\u4E0D\u6D17\u6210\u65E0\u5F55\u3002\u673A\u68B0\u5C42\u4E0D\u91CD\u5224\u3002"
14922
+ })
14923
+ ),
14924
+ reason: typebox_exports.Unknown({
14925
+ description: "status \u4E3A escalate \u65F6\uFF1A\u8BA4\u4E0D\u51FA\u672C\u5EAD\u5BF9\u8C61\u7684\u539F\u56E0"
14926
+ }),
14927
+ sessions: typebox_exports.Optional(typebox_exports.Unknown({ description: DIARIST_SESSIONS_DESCRIPTION })),
14928
+ ticketSessions: typebox_exports.Unknown({
14929
+ description: `\u591A\u7968\u5EAD\u9010\u7968\u5BF9\u8BDD\u8FB9\u754C\uFF1B\u6BCF\u7968\u542B ticketNumber\uFF08\u672C\u6761\u8FB9\u754C\u6240\u5F52\u7968\u53F7\uFF0C\u6B63\u6574\u6570\uFF09\u4E0E sessions\uFF08${DIARIST_SESSIONS_DESCRIPTION}\uFF09\u3002\u4E00\u6B21\u4EA4\u5377\u5404\u7968\u5404\u81EA\u5206\u5F55\u3002\u4E0E\u5355\u7968 sessions \u4E8C\u9009\u4E00\u3002`
14930
+ })
14931
+ })
14932
+ )
14933
+ );
14864
14934
  }
14865
14935
  });
14866
14936
 
14867
14937
  // src/secretariat-contracts.ts
14868
- var SECRETARIAT_OUTPUT_TOOL_NAME, SECRETARIAT_GATE_OFFICER_ENTRY_TYPE, SECRETARIAT_COUNTERSIGN_TERMINAL_FACT_KEY;
14938
+ var SECRETARIAT_OUTPUT_TOOL_NAME, secretariatVerdictSchema, SECRETARIAT_GATE_OFFICER_ENTRY_TYPE, SECRETARIAT_COUNTERSIGN_TERMINAL_FACT_KEY;
14869
14939
  var init_secretariat_contracts = __esm({
14870
14940
  "src/secretariat-contracts.ts"() {
14871
14941
  "use strict";
14942
+ init_build();
14943
+ init_terminating_infrastructure();
14872
14944
  SECRETARIAT_OUTPUT_TOOL_NAME = "ak_secretariat_output";
14945
+ secretariatVerdictSchema = withTerminatingOutputDeclarations(
14946
+ typebox_exports.Object(
14947
+ {
14948
+ secretariatStatus: typebox_exports.Unknown({
14949
+ description: "converged | escalate"
14950
+ }),
14951
+ ticketNumber: typebox_exports.Optional(
14952
+ typebox_exports.Unknown({ description: "\u672C\u7968\u53F7\uFF1B\u7F72\u65F6\u6307\u5411\u6700\u7EC8\u6B63\u6587\u6240\u5728\u7968" })
14953
+ ),
14954
+ note: typebox_exports.Unknown({ description: "\u9644\u6CE8" }),
14955
+ evidence: typebox_exports.Optional(typebox_exports.Unknown({ description: "\u7559\u5B58\u8BC1\u636E" })),
14956
+ decisionGate: typebox_exports.Unknown({
14957
+ description: "\u9700\u965B\u4E0B\u5904\u7F6E\u7684\u95EE\u9898\u4E0E\u9009\u9879\uFF1B\u53EF\u5199 question \u4E0E options\uFF0C\u539F\u6837\u7559\u5B58\u3002"
14958
+ })
14959
+ },
14960
+ { additionalProperties: true }
14961
+ )
14962
+ );
14963
+ secretariatVerdictSchema.required = [];
14873
14964
  SECRETARIAT_GATE_OFFICER_ENTRY_TYPE = "ak-secretariat-gate-officer";
14874
14965
  SECRETARIAT_COUNTERSIGN_TERMINAL_FACT_KEY = "countersignTerminal";
14875
14966
  }
@@ -16866,6 +16957,161 @@ var init_submission_errors = __esm({
16866
16957
  }
16867
16958
  });
16868
16959
 
16960
+ // src/collector-tool-schemas.ts
16961
+ var collectorOutputBaseSchema, collectorOutputArgsSchema;
16962
+ var init_collector_tool_schemas = __esm({
16963
+ "src/collector-tool-schemas.ts"() {
16964
+ "use strict";
16965
+ init_build();
16966
+ init_open_tool_schema();
16967
+ init_terminating_infrastructure();
16968
+ collectorOutputBaseSchema = openToolObject(
16969
+ typebox_exports.Object({
16970
+ groups: typebox_exports.Unsafe({
16971
+ description: "\u6309\u673A\u5668\u8EAB\u4EFD\u5F52\u7EC4\u7684\u51FA\u5E2D\u3001\u6750\u6599\u4E0E\u9010\u6761 findings\uFF08LLM \u81EA\u884C\u4ECE\u5BBF\u4E3B CLI \u53D6\u8BC1\u6574\u7406\uFF1B\u4EE3\u7801\u4E0D\u4EE3\u6536\u4E0D\u5F52\u5E76\uFF09\u3002"
16972
+ }),
16973
+ unfinishedReasons: typebox_exports.Unknown({
16974
+ description: "\u672A\u5B8C\u6210\u539F\u56E0\uFF1B\u53D6\u8BC1\u53D7\u9650\u65F6\u5982\u5B9E\u62A5\u544A\u3002"
16975
+ })
16976
+ })
16977
+ );
16978
+ collectorOutputArgsSchema = withTerminatingOutputDeclarations(
16979
+ collectorOutputBaseSchema
16980
+ );
16981
+ }
16982
+ });
16983
+
16984
+ // src/role-submission-declarations.ts
16985
+ function roleSubmissionDeclaration(role) {
16986
+ const name = packagedRoleOutputTool(role);
16987
+ if (name === void 0) throw new Error(`${role} output tool is not declared`);
16988
+ const face = SUBMISSION_FACE[role];
16989
+ return {
16990
+ role,
16991
+ name,
16992
+ label: face.label,
16993
+ description: face.description,
16994
+ ..."promptSnippet" in face ? { promptSnippet: face.promptSnippet } : {},
16995
+ parameters: face.parameters
16996
+ };
16997
+ }
16998
+ var SUBMISSION_FACE;
16999
+ var init_role_submission_declarations = __esm({
17000
+ "src/role-submission-declarations.ts"() {
17001
+ "use strict";
17002
+ init_packaged_role_registry();
17003
+ init_review_submission();
17004
+ init_collector_tool_schemas();
17005
+ init_diarist_contracts();
17006
+ init_doctor_contracts();
17007
+ init_fixer_output();
17008
+ init_gatekeeper_output();
17009
+ init_gleaner_left_contracts();
17010
+ init_merger_contracts();
17011
+ init_navigator_output();
17012
+ init_reviewer_output();
17013
+ init_secretariat_contracts();
17014
+ init_worker_output();
17015
+ SUBMISSION_FACE = {
17016
+ judge: {
17017
+ label: "\u5927\u7406\u5BFA\u8F93\u51FA",
17018
+ description: "\u63D0\u4EA4\u5927\u7406\u5BFA\u7EC8\u5C40\u5224\u8BCD\uFF1B\u4EA4\u5377\u8C03\u7528\u7ED3\u675F\u540E\uFF0C\u7531\u516C\u5F00\u8C03\u7528\u63A5\u7F1D\u6309\u5224\u8BCD\u72B6\u6001\u6267\u884C\u9002\u7528\u5BA1\u6838\u3002",
17019
+ promptSnippet: "\u63D0\u4EA4\u5927\u7406\u5BFA\u7EC8\u5C40\u5224\u8BCD",
17020
+ parameters: reviewSubmissionSchema
17021
+ },
17022
+ fixer: {
17023
+ label: "\u4FEE\u5185\u53F8\u8F93\u51FA",
17024
+ description: "\u63D0\u4EA4\u4FEE\u5185\u53F8\u7EC8\u5C40\u56DE\u6267\u3002",
17025
+ promptSnippet: "\u63D0\u4EA4\u4FEE\u5185\u53F8\u7EC8\u5C40\u56DE\u6267",
17026
+ parameters: fixerOutputSchema
17027
+ },
17028
+ coder: {
17029
+ label: "\u5C06\u4F5C\u76D1\u8F93\u51FA",
17030
+ description: "\u63D0\u4EA4\u5C06\u4F5C\u76D1\u7EC8\u5C40\u56DE\u6267\u3002",
17031
+ promptSnippet: "\u63D0\u4EA4\u5C06\u4F5C\u76D1\u7EC8\u5C40\u56DE\u6267",
17032
+ parameters: coderOutputSchema
17033
+ },
17034
+ reviewer: {
17035
+ label: "\u5FA1\u53F2\u53F0\u8F93\u51FA",
17036
+ description: "\u63D0\u4EA4\u5FA1\u53F2\u53F0\u7EC8\u5C40\u56DE\u6267\u3002",
17037
+ promptSnippet: "\u63D0\u4EA4\u5FA1\u53F2\u53F0\u7EC8\u5C40\u56DE\u6267",
17038
+ parameters: reviewerOutputSchema
17039
+ },
17040
+ collector: {
17041
+ label: "\u901A\u8FDB\u53F8\u8F93\u51FA",
17042
+ description: "\u63D0\u4EA4\u901A\u8FDB\u53F8\u56DE\u6267\u3002",
17043
+ promptSnippet: "\u63D0\u4EA4\u901A\u8FDB\u53F8\u56DE\u6267",
17044
+ parameters: collectorOutputArgsSchema
17045
+ },
17046
+ doctor: {
17047
+ label: "\u592A\u533B\u7F72\u8F93\u51FA",
17048
+ description: DOCTOR_OUTPUT_TOOL_DESCRIPTION,
17049
+ parameters: doctorSubmissionSchema
17050
+ },
17051
+ merger: {
17052
+ label: "\u5408\u5E76\u8F93\u51FA",
17053
+ description: "\u63D0\u4EA4\u5408\u5E76\u7ED3\u679C\uFF1B\u8F93\u51FA\u5206\u652F\u4E3A completed \u4E0E escalate\u3002",
17054
+ promptSnippet: "\u63D0\u4EA4\u5408\u5E76\u7ED3\u679C",
17055
+ parameters: mergerOutputSchema
17056
+ },
17057
+ notary: {
17058
+ label: "\u7B26\u5B9D\u90CE\u8F93\u51FA",
17059
+ description: "\u63D0\u4EA4\u5F15\u6587\u4FDD\u771F\u4E0E\u7968\u9762\u5BF9\u9F50\u7684 converged/continue/escalate \u51B3\u8BAE\u3002",
17060
+ promptSnippet: "\u63D0\u4EA4\u7B26\u5B9D\u90CE\u51B3\u8BAE",
17061
+ parameters: reviewSubmissionSchema
17062
+ },
17063
+ countersign: {
17064
+ label: "\u7ED9\u4E8B\u4E2D\u8F93\u51FA",
17065
+ description: "\u7ED9\u4E8B\u4E2D\u51B3\u8BAE\u3002",
17066
+ promptSnippet: "\u7ED9\u4E8B\u4E2D\u51B3\u8BAE",
17067
+ parameters: reviewSubmissionSchema
17068
+ },
17069
+ secretariat: {
17070
+ label: "\u4E2D\u4E66\u7701\u8F93\u51FA",
17071
+ description: "\u4E2D\u4E66\u7701\u7EC8\u5C40\u56DE\u6267\u3002",
17072
+ promptSnippet: "\u4E2D\u4E66\u7701\u7EC8\u5C40\u56DE\u6267",
17073
+ parameters: secretariatVerdictSchema
17074
+ },
17075
+ "gleaner-left": {
17076
+ label: "\u5DE6\u62FE\u9057\u8F93\u51FA",
17077
+ description: "\u5DE6\u62FE\u9057\u5F39\u7AE0\u3002",
17078
+ promptSnippet: "\u5DE6\u62FE\u9057\u5F39\u7AE0",
17079
+ parameters: gleanerLeftOutputSchema
17080
+ },
17081
+ inspector: {
17082
+ label: "\u53F0\u9662\u8F93\u51FA",
17083
+ description: "\u53F0\u9662\u7EC8\u5C40\u56DE\u6267\uFF0C\u72B6\u6001\u4E3A converged\u3001continue \u6216 escalate\u3002",
17084
+ promptSnippet: "\u53F0\u9662\u7EC8\u5C40\u56DE\u6267",
17085
+ parameters: reviewSubmissionSchema
17086
+ },
17087
+ gatekeeper: {
17088
+ label: "\u95E8\u4E0B\u7701\u51B3\u8BAE",
17089
+ description: "\u95E8\u4E0B\u7701\u7EC8\u5C40\u51B3\u8BAE\u3002status \u4E3A dispatch \u6216 pass\u3002",
17090
+ promptSnippet: "\u95E8\u4E0B\u7701\u51B3\u8BAE",
17091
+ parameters: gatekeeperOutputSchema
17092
+ },
17093
+ navigator: {
17094
+ label: "\u6E38\u5955\u4F7F\u5EFA\u8BAE",
17095
+ description: "\u6E38\u5955\u4F7F\u7EC8\u5C40\u56DE\u6267\uFF1A\u6563\u6587\u5EFA\u8BAE\uFF0C\u539F\u6837\u5448\u73B0\u3002",
17096
+ promptSnippet: "\u6E38\u5955\u4F7F\u5EFA\u8BAE",
17097
+ parameters: navigatorOutputSchema
17098
+ },
17099
+ auditor: {
17100
+ label: "\u5BA1\u5211\u9662\u8F93\u51FA",
17101
+ description: "\u5BA1\u5211\u9662\u7EC8\u5C40\u56DE\u6267\uFF0Cstatus \u4E3A converged\u3001continue \u6216 escalate\u3002",
17102
+ promptSnippet: "\u5BA1\u5211\u9662\u7EC8\u5C40\u56DE\u6267",
17103
+ parameters: reviewSubmissionSchema
17104
+ },
17105
+ diarist: {
17106
+ label: "\u8D77\u5C45\u90CE\u8F93\u51FA",
17107
+ description: "\u8D77\u5C45\u90CE\u4EA4\u5355\u7968 sessions \u6216\u591A\u7968\u9010\u7968 ticketSessions \u8FB9\u754C\uFF1B\u8BA4\u4E0D\u51FA\u672C\u5EAD\u5BF9\u8C61\u5219 escalate\u3002",
17108
+ promptSnippet: "\u8D77\u5C45\u90CE\u4EA4\u8FB9\u754C",
17109
+ parameters: diaristOutputSchema
17110
+ }
17111
+ };
17112
+ }
17113
+ });
17114
+
16869
17115
  // src/run-terminal-artifacts.ts
16870
17116
  var run_terminal_artifacts_exports = {};
16871
17117
  __export(run_terminal_artifacts_exports, {
@@ -17052,7 +17298,7 @@ function reviewQueueStatus(status) {
17052
17298
  function projectOfficerDecision(officer, decision, fallbackStatus) {
17053
17299
  const receipt = retainedReceipt(decision);
17054
17300
  const record = isRecord(decision) ? decision : void 0;
17055
- const status = (record !== void 0 && typeof record.status === "string" ? record.status : void 0) ?? fallbackStatus;
17301
+ const status = record !== void 0 && Object.hasOwn(record, "status") ? receivedDiscriminator(record, "status") : fallbackStatus;
17056
17302
  const queueStatus = typeof status === "string" ? reviewQueueStatus(status) : void 0;
17057
17303
  if (queueStatus === "converged") {
17058
17304
  return { status: "converged", officer, receipt };
@@ -17195,7 +17441,7 @@ async function projectGatekeeperRun(options) {
17195
17441
  summoned
17196
17442
  };
17197
17443
  }
17198
- var GATE_OFFICER_BY_SUBJECT;
17444
+ var GATE_OFFICER_BY_SUBJECT, GATEKEEPER_TOOL_SPEC;
17199
17445
  var init_gatekeeper_role = __esm({
17200
17446
  "src/gatekeeper-role.ts"() {
17201
17447
  "use strict";
@@ -17205,6 +17451,7 @@ var init_gatekeeper_role = __esm({
17205
17451
  init_inspector_contracts();
17206
17452
  init_review_submission();
17207
17453
  init_gatekeeper_output();
17454
+ init_role_submission_declarations();
17208
17455
  init_run_terminal_artifacts();
17209
17456
  init_unknown_value();
17210
17457
  init_submission_errors();
@@ -17215,6 +17462,7 @@ var init_gatekeeper_role = __esm({
17215
17462
  countersign_verdict: "notary",
17216
17463
  secretariat_verdict: "countersign"
17217
17464
  };
17465
+ GATEKEEPER_TOOL_SPEC = roleSubmissionDeclaration("gatekeeper");
17218
17466
  }
17219
17467
  });
17220
17468
 
@@ -24681,16 +24929,24 @@ var init_doctor_auditor = __esm({
24681
24929
  }
24682
24930
  });
24683
24931
 
24932
+ // src/filed-submission.ts
24933
+ var init_filed_submission = __esm({
24934
+ "src/filed-submission.ts"() {
24935
+ "use strict";
24936
+ }
24937
+ });
24938
+
24684
24939
  // src/judge-role.ts
24685
24940
  async function runJudgeGates(input) {
24686
24941
  const passes = [];
24687
24942
  for (const subject of JUDGE_GATES) {
24688
24943
  if (await input.gateAlreadyConverged(subject)) continue;
24689
24944
  const pass = await input.runGate(subject);
24690
- const status = pass?.status;
24691
- if (pass === void 0 || status !== "converged" && status !== "continue" && status !== "escalate") {
24945
+ const received = pass?.status;
24946
+ if (pass === void 0 || typeof received !== "string" || !REVIEW_QUEUE_STATUSES.has(received)) {
24692
24947
  throw new Error("judge gate returned no conclusion");
24693
24948
  }
24949
+ const status = received;
24694
24950
  passes.push({
24695
24951
  subject,
24696
24952
  status,
@@ -24708,6 +24964,8 @@ var init_judge_role = __esm({
24708
24964
  "use strict";
24709
24965
  init_host_contracts();
24710
24966
  init_review_submission();
24967
+ init_filed_submission();
24968
+ init_role_submission_declarations();
24711
24969
  init_gatekeeper_role();
24712
24970
  init_judge_output();
24713
24971
  JUDGE_GATES = [
@@ -24736,11 +24994,10 @@ function latestQueueStatus(terminal) {
24736
24994
  if (outcome.kind === "audit_escalation") return "escalate";
24737
24995
  if (outcome.kind !== "accepted") return void 0;
24738
24996
  const latest = outcome.payloads?.[outcome.payloads.length - 1];
24739
- if (isRecord(latest)) {
24740
- const status = latest.status;
24741
- if (typeof status === "string" && status.trim() !== "") return status;
24997
+ if (isRecord(latest) && Object.hasOwn(latest, "status")) {
24998
+ return receivedDiscriminator(latest, "status");
24742
24999
  }
24743
- return typeof outcome.status === "string" && outcome.status.trim() !== "" ? outcome.status : void 0;
25000
+ return outcome.status;
24744
25001
  }
24745
25002
  function latestQueuePayload(terminal) {
24746
25003
  const outcome = terminal?.roleOutcome;
@@ -24857,6 +25114,7 @@ var init_submission_gate = __esm({
24857
25114
  "use strict";
24858
25115
  init_archivist_record_pointer();
24859
25116
  init_gatekeeper_role();
25117
+ init_submission_errors();
24860
25118
  init_session_assistant_usage();
24861
25119
  init_unknown_value();
24862
25120
  }
@@ -25105,8 +25363,8 @@ function unreadablePostSubmissionStatus(admitted, terminal) {
25105
25363
  const route = POST_SUBMISSION_ROUTING[admitted.role];
25106
25364
  if (route === void 0) return void 0;
25107
25365
  const payload = terminal.roleOutcome.payloads?.at(-1);
25108
- const status = isRecord(payload) ? payload.status : void 0;
25109
- return typeof status === "string" && route.statuses.has(status) ? void 0 : route.reask;
25366
+ const status = receivedDiscriminator(payload, "status");
25367
+ return typeof status === "string" && route.statuses.has(status) ? void 0 : route.reask ?? officerConclusionReask(status);
25110
25368
  }
25111
25369
  async function reaskUnreadablePostSubmissionStatus(admitted, terminal, env, io) {
25112
25370
  const message = unreadablePostSubmissionStatus(admitted, terminal);
@@ -25723,7 +25981,7 @@ async function queueConclusionFromChild(child, env, io) {
25723
25981
  void 0
25724
25982
  );
25725
25983
  const status = latestQueueStatus(terminal);
25726
- if (terminal !== void 0 && status !== void 0 && QUEUE_CONCLUSIONS.has(status)) {
25984
+ if (terminal !== void 0 && typeof status === "string" && REVIEW_QUEUE_STATUSES.has(status)) {
25727
25985
  return { admitted: current, terminal, status };
25728
25986
  }
25729
25987
  const reasked = await runPublicInstructionSeatResume({
@@ -25734,7 +25992,7 @@ async function queueConclusionFromChild(child, env, io) {
25734
25992
  return { stop: reasked };
25735
25993
  }
25736
25994
  const reaskedStatus = latestQueueStatus(reasked.terminal);
25737
- if (reaskedStatus !== void 0 && QUEUE_CONCLUSIONS.has(reaskedStatus)) {
25995
+ if (typeof reaskedStatus === "string" && REVIEW_QUEUE_STATUSES.has(reaskedStatus)) {
25738
25996
  return { admitted: reasked.admitted, terminal: reasked.terminal, status: reaskedStatus };
25739
25997
  }
25740
25998
  if (latestPayloadEscalated(reasked.terminal.roleOutcome)) return { stop: reasked };
@@ -25781,9 +26039,9 @@ async function auditSubmittedRole(turn, env, io, passedOfficer, passedReceipt, p
25781
26039
  io
25782
26040
  );
25783
26041
  }
25784
- if (admitted.role === "countersign" && (typeof status !== "string" || !QUEUE_CONCLUSIONS.has(status))) {
26042
+ if (admitted.role === "countersign" && (typeof status !== "string" || !REVIEW_QUEUE_STATUSES.has(status))) {
25785
26043
  return runPublicInstructionSeatResume(
25786
- { runId: admitted.runId, message: COUNTERSIGN_STATUS_REASK },
26044
+ { runId: admitted.runId, message: officerConclusionReask(status) },
25787
26045
  { ...env, autoResumeLimit: 0 },
25788
26046
  io
25789
26047
  );
@@ -25960,7 +26218,7 @@ async function auditSubmittedRole(turn, env, io, passedOfficer, passedReceipt, p
25960
26218
  io.stdout(formatTerminalResult(terminal));
25961
26219
  return turn;
25962
26220
  }
25963
- var AUDITED_ROLES, SECRETARIAT_STATUS_REASK, COUNTERSIGN_STATUS_REASK, WORKER_ROUTING_STATUSES, WORKER_STATUS_REASK, DOCTOR_ROUTING_STATUSES, DOCTOR_STATUS_REASK, POST_SUBMISSION_ROUTING, QUEUE_CONCLUSIONS, GATE_CHILD_ROLES;
26221
+ var AUDITED_ROLES, SECRETARIAT_STATUS_REASK, WORKER_ROUTING_STATUSES, WORKER_STATUS_REASK, DOCTOR_ROUTING_STATUSES, DOCTOR_STATUS_REASK, POST_SUBMISSION_ROUTING, GATE_CHILD_ROLES;
25964
26222
  var init_instruction_seat_run = __esm({
25965
26223
  "src/public-cli/instruction-seat-run.ts"() {
25966
26224
  "use strict";
@@ -25969,6 +26227,8 @@ var init_instruction_seat_run = __esm({
25969
26227
  init_archivist_record_pointer();
25970
26228
  init_doctor_auditor();
25971
26229
  init_gatekeeper_role();
26230
+ init_submission_errors();
26231
+ init_review_submission();
25972
26232
  init_judge_role();
25973
26233
  init_worker_submission_contracts();
25974
26234
  init_secretariat_contracts();
@@ -25997,7 +26257,6 @@ var init_instruction_seat_run = __esm({
25997
26257
  init_unknown_value();
25998
26258
  AUDITED_ROLES = /* @__PURE__ */ new Set(["judge", "fixer", "coder", "secretariat", "countersign", "doctor"]);
25999
26259
  SECRETARIAT_STATUS_REASK = "secretariatStatus \u4E0D\u662F converged\u3001escalate \u4E4B\u4E00\u3002\u8BF7\u91CD\u65B0\u4EA4\u5377\uFF0CsecretariatStatus \u5199\u660E\u5176\u4E00\u3002";
26000
- COUNTERSIGN_STATUS_REASK = "status \u4E0D\u662F converged\u3001continue\u3001escalate \u4E09\u6001\u4E4B\u4E00\u3002\u8BF7\u91CD\u65B0\u4EA4\u5377\uFF0Cstatus \u5199\u660E\u5176\u4E00\u3002";
26001
26260
  WORKER_ROUTING_STATUSES = /* @__PURE__ */ new Set([
26002
26261
  "planned",
26003
26262
  "completed",
@@ -26010,8 +26269,7 @@ var init_instruction_seat_run = __esm({
26010
26269
  DOCTOR_STATUS_REASK = "status \u4E0D\u662F completed\u3001refused \u4E4B\u4E00\u3002\u8BF7\u91CD\u65B0\u4EA4\u5377\uFF0Cstatus \u5199\u660E\u5176\u4E00\u3002";
26011
26270
  POST_SUBMISSION_ROUTING = {
26012
26271
  judge: {
26013
- statuses: /* @__PURE__ */ new Set(["converged", "continue", "escalate"]),
26014
- reask: "status \u4E0D\u662F converged\u3001continue\u3001escalate \u4E09\u6001\u4E4B\u4E00\u3002\u8BF7\u91CD\u65B0\u4EA4\u5377\uFF0Cstatus \u5199\u660E\u5176\u4E00\u3002"
26272
+ statuses: REVIEW_QUEUE_STATUSES
26015
26273
  },
26016
26274
  coder: {
26017
26275
  statuses: WORKER_ROUTING_STATUSES,
@@ -26032,7 +26290,6 @@ var init_instruction_seat_run = __esm({
26032
26290
  reask: DOCTOR_STATUS_REASK
26033
26291
  }
26034
26292
  };
26035
- QUEUE_CONCLUSIONS = /* @__PURE__ */ new Set(["converged", "continue", "escalate"]);
26036
26293
  GATE_CHILD_ROLES = /* @__PURE__ */ new Set(["notary", "auditor", "inspector", "countersign"]);
26037
26294
  }
26038
26295
  });
@@ -0,0 +1,131 @@
1
+ /**
2
+ * Field guidance for each public seat's submission tool (#1031).
3
+ * The tool name is the role registry's outputTool. This module does not restate it.
4
+ * Review seats keep the #1028 schema. Other seats keep their own field guidance.
5
+ * Execute lives in filed-submission.ts.
6
+ */
7
+ import { packagedRoleOutputTool } from "./packaged-role-registry.js";
8
+ import { reviewSubmissionSchema } from "./review-submission.js";
9
+ import { collectorOutputArgsSchema } from "./collector-tool-schemas.js";
10
+ import { diaristOutputSchema } from "./diarist-contracts.js";
11
+ import { doctorSubmissionSchema, DOCTOR_OUTPUT_TOOL_DESCRIPTION } from "./doctor-contracts.js";
12
+ import { fixerOutputSchema } from "./package-contracts/fixer-output.js";
13
+ import { gatekeeperOutputSchema } from "./package-contracts/gatekeeper-output.js";
14
+ import { gleanerLeftOutputSchema } from "./gleaner-left-contracts.js";
15
+ import { mergerOutputSchema } from "./merger-contracts.js";
16
+ import { navigatorOutputSchema } from "./package-contracts/navigator-output.js";
17
+ import { reviewerOutputSchema } from "./package-contracts/reviewer-output.js";
18
+ import { secretariatVerdictSchema } from "./secretariat-contracts.js";
19
+ import { coderOutputSchema } from "./package-contracts/worker-output.js";
20
+ const SUBMISSION_FACE = {
21
+ judge: {
22
+ label: "大理寺输出",
23
+ description: "提交大理寺终局判词;交卷调用结束后,由公开调用接缝按判词状态执行适用审核。",
24
+ promptSnippet: "提交大理寺终局判词",
25
+ parameters: reviewSubmissionSchema,
26
+ },
27
+ fixer: {
28
+ label: "修内司输出",
29
+ description: "提交修内司终局回执。",
30
+ promptSnippet: "提交修内司终局回执",
31
+ parameters: fixerOutputSchema,
32
+ },
33
+ coder: {
34
+ label: "将作监输出",
35
+ description: "提交将作监终局回执。",
36
+ promptSnippet: "提交将作监终局回执",
37
+ parameters: coderOutputSchema,
38
+ },
39
+ reviewer: {
40
+ label: "御史台输出",
41
+ description: "提交御史台终局回执。",
42
+ promptSnippet: "提交御史台终局回执",
43
+ parameters: reviewerOutputSchema,
44
+ },
45
+ collector: {
46
+ label: "通进司输出",
47
+ description: "提交通进司回执。",
48
+ promptSnippet: "提交通进司回执",
49
+ parameters: collectorOutputArgsSchema,
50
+ },
51
+ doctor: {
52
+ label: "太医署输出",
53
+ description: DOCTOR_OUTPUT_TOOL_DESCRIPTION,
54
+ parameters: doctorSubmissionSchema,
55
+ },
56
+ merger: {
57
+ label: "合并输出",
58
+ description: "提交合并结果;输出分支为 completed 与 escalate。",
59
+ promptSnippet: "提交合并结果",
60
+ parameters: mergerOutputSchema,
61
+ },
62
+ notary: {
63
+ label: "符宝郎输出",
64
+ description: "提交引文保真与票面对齐的 converged/continue/escalate 决议。",
65
+ promptSnippet: "提交符宝郎决议",
66
+ parameters: reviewSubmissionSchema,
67
+ },
68
+ countersign: {
69
+ label: "给事中输出",
70
+ description: "给事中决议。",
71
+ promptSnippet: "给事中决议",
72
+ parameters: reviewSubmissionSchema,
73
+ },
74
+ secretariat: {
75
+ label: "中书省输出",
76
+ description: "中书省终局回执。",
77
+ promptSnippet: "中书省终局回执",
78
+ parameters: secretariatVerdictSchema,
79
+ },
80
+ "gleaner-left": {
81
+ label: "左拾遗输出",
82
+ description: "左拾遗弹章。",
83
+ promptSnippet: "左拾遗弹章",
84
+ parameters: gleanerLeftOutputSchema,
85
+ },
86
+ inspector: {
87
+ label: "台院输出",
88
+ description: "台院终局回执,状态为 converged、continue 或 escalate。",
89
+ promptSnippet: "台院终局回执",
90
+ parameters: reviewSubmissionSchema,
91
+ },
92
+ gatekeeper: {
93
+ label: "门下省决议",
94
+ description: "门下省终局决议。status 为 dispatch 或 pass。",
95
+ promptSnippet: "门下省决议",
96
+ parameters: gatekeeperOutputSchema,
97
+ },
98
+ navigator: {
99
+ label: "游奕使建议",
100
+ description: "游奕使终局回执:散文建议,原样呈现。",
101
+ promptSnippet: "游奕使建议",
102
+ parameters: navigatorOutputSchema,
103
+ },
104
+ auditor: {
105
+ label: "审刑院输出",
106
+ description: "审刑院终局回执,status 为 converged、continue 或 escalate。",
107
+ promptSnippet: "审刑院终局回执",
108
+ parameters: reviewSubmissionSchema,
109
+ },
110
+ diarist: {
111
+ label: "起居郎输出",
112
+ description: "起居郎交单票 sessions 或多票逐票 ticketSessions 边界;认不出本庭对象则 escalate。",
113
+ promptSnippet: "起居郎交边界",
114
+ parameters: diaristOutputSchema,
115
+ },
116
+ };
117
+ /** Tool name comes from the registry record. Label and schema stay on this face. */
118
+ export function roleSubmissionDeclaration(role) {
119
+ const name = packagedRoleOutputTool(role);
120
+ if (name === undefined)
121
+ throw new Error(`${role} output tool is not declared`);
122
+ const face = SUBMISSION_FACE[role];
123
+ return {
124
+ role,
125
+ name,
126
+ label: face.label,
127
+ description: face.description,
128
+ ...("promptSnippet" in face ? { promptSnippet: face.promptSnippet } : {}),
129
+ parameters: face.parameters,
130
+ };
131
+ }
@@ -1,8 +1,30 @@
1
+ import { Type } from "typebox";
2
+ import { withTerminatingOutputDeclarations } from "./package-contracts/terminating-infrastructure.js";
1
3
  const SECRETARIAT_OUTPUT_TOOL_NAME = "ak_secretariat_output";
4
+ const secretariatVerdictSchema = withTerminatingOutputDeclarations(
5
+ Type.Object(
6
+ {
7
+ secretariatStatus: Type.Unknown({
8
+ description: "converged | escalate"
9
+ }),
10
+ ticketNumber: Type.Optional(
11
+ Type.Unknown({ description: "\u672C\u7968\u53F7\uFF1B\u7F72\u65F6\u6307\u5411\u6700\u7EC8\u6B63\u6587\u6240\u5728\u7968" })
12
+ ),
13
+ note: Type.Unknown({ description: "\u9644\u6CE8" }),
14
+ evidence: Type.Optional(Type.Unknown({ description: "\u7559\u5B58\u8BC1\u636E" })),
15
+ decisionGate: Type.Unknown({
16
+ description: "\u9700\u965B\u4E0B\u5904\u7F6E\u7684\u95EE\u9898\u4E0E\u9009\u9879\uFF1B\u53EF\u5199 question \u4E0E options\uFF0C\u539F\u6837\u7559\u5B58\u3002"
17
+ })
18
+ },
19
+ { additionalProperties: true }
20
+ )
21
+ );
22
+ secretariatVerdictSchema.required = [];
2
23
  const SECRETARIAT_GATE_OFFICER_ENTRY_TYPE = "ak-secretariat-gate-officer";
3
24
  const SECRETARIAT_COUNTERSIGN_TERMINAL_FACT_KEY = "countersignTerminal";
4
25
  export {
5
26
  SECRETARIAT_COUNTERSIGN_TERMINAL_FACT_KEY,
6
27
  SECRETARIAT_GATE_OFFICER_ENTRY_TYPE,
7
- SECRETARIAT_OUTPUT_TOOL_NAME
28
+ SECRETARIAT_OUTPUT_TOOL_NAME,
29
+ secretariatVerdictSchema
8
30
  };