percolation-inversion-compiler-ts 0.4.5 → 0.5.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.
Files changed (197) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/README.md +77 -22
  3. package/agent-manifest.json +50 -0
  4. package/dist/alt_lift/index.d.ts +7 -0
  5. package/dist/alt_lift/index.js +101 -0
  6. package/dist/bit_engine/index.d.ts +8 -0
  7. package/dist/bit_engine/index.js +213 -0
  8. package/dist/cli/main.js +2106 -162
  9. package/dist/index.d.ts +5 -0
  10. package/dist/index.js +1611 -16
  11. package/dist/phase_lab/index.d.ts +26 -0
  12. package/dist/phase_lab/index.js +1124 -0
  13. package/dist/sqot_controller/index.d.ts +8 -0
  14. package/dist/sqot_controller/index.js +141 -0
  15. package/dist/trc_adapter/index.d.ts +6 -0
  16. package/dist/trc_adapter/index.js +86 -0
  17. package/docs/alt-ecpt-lift.md +32 -0
  18. package/docs/bit-inversion-engine.md +32 -0
  19. package/docs/cli-reference.md +68 -0
  20. package/docs/effective-packet-graph.md +35 -0
  21. package/docs/for-agents.md +44 -0
  22. package/docs/phase-ecology-lab.md +46 -0
  23. package/docs/sqot-queue-sovereignty.md +31 -0
  24. package/docs/threshold-certificates.md +30 -0
  25. package/docs/trc-trace-adapter.md +30 -0
  26. package/docs/v050-audit.md +126 -0
  27. package/examples/alt_lift/alt_ecpt_lift.example.json +27 -0
  28. package/examples/bit_engine/bottlenecks.example.json +38 -0
  29. package/examples/bit_engine/inversion_candidates.example.json +55 -0
  30. package/examples/packet_exchange/packet_envelope.example.json +51 -0
  31. package/examples/packet_exchange/packet_merge_report.example.json +60 -0
  32. package/examples/phase_lab/certificate_abstain.example.json +39 -0
  33. package/examples/phase_lab/closure_report.example.json +41 -0
  34. package/examples/phase_lab/effective_graph.example.json +112 -0
  35. package/examples/phase_lab/executable_paths.example.json +20 -0
  36. package/examples/phase_lab/phase_window_observation.example.json +61 -0
  37. package/examples/phase_lab/runtime_report_1.json +19 -0
  38. package/examples/phase_lab/runtime_report_2.json +16 -0
  39. package/examples/phase_lab/threshold_status.example.json +31 -0
  40. package/examples/sqot_controller/queue_report.example.json +30 -0
  41. package/examples/sqot_controller/rebalance_plan.example.json +14 -0
  42. package/examples/thresholds/asi_proxy_development.json +15 -0
  43. package/examples/trc_adapter/tool_trace_input.example.json +17 -0
  44. package/examples/trc_adapter/typed_trace.example.json +64 -0
  45. package/fixtures/portability_conformance_v050/certificate_abstain.example.json +39 -0
  46. package/fixtures/portability_conformance_v050/closure_report.example.json +39 -0
  47. package/fixtures/portability_conformance_v050/effective_graph.example.json +112 -0
  48. package/fixtures/portability_conformance_v050/executable_paths.example.json +20 -0
  49. package/fixtures/portability_conformance_v050/manifest.json +55 -0
  50. package/fixtures/portability_conformance_v050/phase_lab_event_1.json +51 -0
  51. package/fixtures/portability_conformance_v050/phase_lab_event_2.json +55 -0
  52. package/fixtures/portability_conformance_v050/phase_window_observation.example.json +61 -0
  53. package/fixtures/portability_conformance_v050/runtime_report_1.json +19 -0
  54. package/fixtures/portability_conformance_v050/runtime_report_2.json +14 -0
  55. package/fixtures/portability_conformance_v050/threshold_status.example.json +29 -0
  56. package/fixtures/python_v044_cli/agent_autonomy_audit.json +4 -3
  57. package/fixtures/python_v044_cli/agent_manifest.json +2 -1
  58. package/fixtures/python_v044_cli/agent_runbook.json +2 -1
  59. package/fixtures/python_v044_cli/demo_installed_smoke.json +86 -86
  60. package/fixtures/python_v044_demo/manifest.json +2 -1
  61. package/fixtures/python_v050_cli/alt_capital_impact.json +30 -0
  62. package/fixtures/python_v050_cli/alt_ecpt_lift.json +85 -0
  63. package/fixtures/python_v050_cli/alt_liquidity_to_paths.json +85 -0
  64. package/fixtures/python_v050_cli/alt_receiver_lift.json +15 -0
  65. package/fixtures/python_v050_cli/bit_certificate.json +15 -0
  66. package/fixtures/python_v050_cli/bit_compare_baseline.json +24 -0
  67. package/fixtures/python_v050_cli/bit_diagnose.json +95 -0
  68. package/fixtures/python_v050_cli/bit_invert.json +235 -0
  69. package/fixtures/python_v050_cli/bit_mec.json +18 -0
  70. package/fixtures/python_v050_cli/ecology_effective_graph.json +178 -0
  71. package/fixtures/python_v050_cli/ecology_execution_available_paths.json +88 -0
  72. package/fixtures/python_v050_cli/manifest.json +48 -0
  73. package/fixtures/python_v050_cli/phase_lab_certify.json +443 -0
  74. package/fixtures/python_v050_cli/phase_lab_closure.json +85 -0
  75. package/fixtures/python_v050_cli/phase_lab_compare_window.json +24 -0
  76. package/fixtures/python_v050_cli/phase_lab_executable_paths.json +88 -0
  77. package/fixtures/python_v050_cli/phase_lab_graph.json +178 -0
  78. package/fixtures/python_v050_cli/phase_lab_ingest_1.json +105 -0
  79. package/fixtures/python_v050_cli/phase_lab_ingest_2.json +109 -0
  80. package/fixtures/python_v050_cli/phase_lab_init.json +20 -0
  81. package/fixtures/python_v050_cli/phase_lab_list_windows.json +63 -0
  82. package/fixtures/python_v050_cli/phase_lab_observe.json +108 -0
  83. package/fixtures/python_v050_cli/phase_lab_threshold_status.json +164 -0
  84. package/fixtures/python_v050_cli/sqot_diagnose_queue.json +38 -0
  85. package/fixtures/python_v050_cli/sqot_quarantine.json +7 -0
  86. package/fixtures/python_v050_cli/sqot_rebalance.json +19 -0
  87. package/fixtures/python_v050_cli/sqot_reserve_check.json +20 -0
  88. package/fixtures/python_v050_cli/sqot_salience_obstruction.json +19 -0
  89. package/fixtures/python_v050_cli/trc_action_boundary.json +451 -0
  90. package/fixtures/python_v050_cli/trc_tool_trace.json +221 -0
  91. package/fixtures/python_v050_cli/trc_trace_adapter.json +221 -0
  92. package/fixtures/python_v050_demo/asi_proxy_development.json +15 -0
  93. package/fixtures/python_v050_demo/certificate_abstain.example.json +39 -0
  94. package/fixtures/python_v050_demo/closure_report.example.json +39 -0
  95. package/fixtures/python_v050_demo/effective_graph.example.json +112 -0
  96. package/fixtures/python_v050_demo/executable_paths.example.json +20 -0
  97. package/fixtures/python_v050_demo/phase_window_observation.example.json +61 -0
  98. package/fixtures/python_v050_demo/runtime_report_1.json +19 -0
  99. package/fixtures/python_v050_demo/runtime_report_2.json +14 -0
  100. package/fixtures/python_v050_demo/threshold_status.example.json +29 -0
  101. package/fixtures/python_v050_snapshots/manifest.json +39 -0
  102. package/fixtures/python_v050_snapshots/snapshot_list.json +112 -0
  103. package/fixtures/python_v050_snapshots/snapshot_routes.json +926 -0
  104. package/fixtures/python_v050_snapshots/snapshot_show_alt.json +6830 -0
  105. package/fixtures/python_v050_snapshots/snapshot_show_bit.json +594 -0
  106. package/fixtures/python_v050_snapshots/snapshot_show_ecpt.json +2894 -0
  107. package/fixtures/python_v050_snapshots/snapshot_show_sqot.json +2392 -0
  108. package/fixtures/python_v050_snapshots/snapshot_show_trc.json +3037 -0
  109. package/fixtures/python_v050_snapshots/snapshot_verify_alt.json +10 -0
  110. package/fixtures/python_v050_snapshots/snapshot_verify_bit.json +10 -0
  111. package/fixtures/python_v050_snapshots/snapshot_verify_ecpt.json +10 -0
  112. package/fixtures/python_v050_snapshots/snapshot_verify_sqot.json +10 -0
  113. package/fixtures/python_v050_snapshots/snapshot_verify_trc.json +10 -0
  114. package/package.json +45 -3
  115. package/schemas/ASIProxyThresholdSpec.schema.json +72 -0
  116. package/schemas/ASIProxyThresholdStatus.schema.json +512 -0
  117. package/schemas/ActionBoundaryRequirement.schema.json +28 -0
  118. package/schemas/ActivationGainEstimate.schema.json +41 -0
  119. package/schemas/AltEcptLiftReport.schema.json +400 -0
  120. package/schemas/AltLiftBlocker.schema.json +34 -0
  121. package/schemas/AttentionBudgetLedger.schema.json +41 -0
  122. package/schemas/AutocatalyticClosureReport.schema.json +408 -0
  123. package/schemas/AutocatalyticClosureWitness.schema.json +22 -139
  124. package/schemas/BasinReachabilityProxy.schema.json +21 -0
  125. package/schemas/BottleneckClassDiagnosis.schema.json +115 -0
  126. package/schemas/BottleneckInversionCandidate.schema.json +249 -0
  127. package/schemas/BottleneckInversionReport.schema.json +499 -0
  128. package/schemas/CapabilityExpressionPath.schema.json +45 -0
  129. package/schemas/CapitalToPathContribution.schema.json +53 -0
  130. package/schemas/ClosureAbstentionReason.schema.json +25 -0
  131. package/schemas/ClosureCertificateCandidate.schema.json +109 -0
  132. package/schemas/ClosureDefect.schema.json +28 -0
  133. package/schemas/ClosureSupportHyperpath.schema.json +44 -0
  134. package/schemas/CollectivePhaseAbstentionReport.schema.json +591 -0
  135. package/schemas/CollectivePhaseCertificateCandidate.schema.json +688 -0
  136. package/schemas/CrossContextTransferWitness.schema.json +46 -0
  137. package/schemas/DiagnosticReserveReport.schema.json +87 -0
  138. package/schemas/DownstreamSearchCostDelta.schema.json +46 -0
  139. package/schemas/EcologyAutocatalyticClosureWitness.schema.json +187 -0
  140. package/schemas/EffectiveGraphResidualSummary.schema.json +38 -0
  141. package/schemas/EffectivePacketEdge.schema.json +135 -0
  142. package/schemas/EffectivePacketEligibility.schema.json +84 -0
  143. package/schemas/EffectivePacketGraph.schema.json +461 -0
  144. package/schemas/EffectivePacketGraphBuildReport.schema.json +521 -0
  145. package/schemas/EffectivePacketNode.schema.json +199 -0
  146. package/schemas/ExecutableClosureWitness.schema.json +47 -0
  147. package/schemas/ExecutablePathDensityReport.schema.json +314 -0
  148. package/schemas/ExecutionAuthorityStatus.schema.json +28 -0
  149. package/schemas/ExecutionAvailableHyperpath.schema.json +201 -0
  150. package/schemas/ExecutionPathDefect.schema.json +28 -0
  151. package/schemas/ExecutionPathWitness.schema.json +44 -0
  152. package/schemas/FalseLiquidityLoad.schema.json +21 -0
  153. package/schemas/GeneralIntakePolicy.schema.json +1 -1
  154. package/schemas/InversionCertificate.schema.json +56 -0
  155. package/schemas/LiquidityToClosureContribution.schema.json +53 -0
  156. package/schemas/MinimalEnablingCondition.schema.json +48 -0
  157. package/schemas/PacketContributionStatus.schema.json +32 -0
  158. package/schemas/PacketQuarantineDecision.schema.json +50 -0
  159. package/schemas/PhaseCertificateDefect.schema.json +33 -0
  160. package/schemas/PhaseComponentObservation.schema.json +39 -0
  161. package/schemas/PhaseLabEvent.schema.json +123 -0
  162. package/schemas/PhaseLabExportManifest.schema.json +127 -0
  163. package/schemas/PhaseLabIngestReport.schema.json +344 -0
  164. package/schemas/PhaseLabStoreManifest.schema.json +73 -0
  165. package/schemas/PhaseLabWindowIndex.schema.json +78 -0
  166. package/schemas/PhaseThresholdStatus.schema.json +51 -0
  167. package/schemas/PhaseWindow.schema.json +31 -0
  168. package/schemas/PhaseWindowComparison.schema.json +67 -0
  169. package/schemas/PhaseWindowObservation.schema.json +353 -0
  170. package/schemas/PostInversionAuditPlan.schema.json +38 -0
  171. package/schemas/ProductiveClosureWitness.schema.json +49 -0
  172. package/schemas/ProvenanceManifest.schema.json +1 -1
  173. package/schemas/QueueOccupationReport.schema.json +156 -0
  174. package/schemas/QueueRebalancePlan.schema.json +114 -0
  175. package/schemas/ReceiverContextSupport.schema.json +23 -0
  176. package/schemas/ReceiverLiquidityLift.schema.json +58 -0
  177. package/schemas/ReleaseArtifactManifest.schema.json +1 -1
  178. package/schemas/ReversibleSalienceSovereigntyCertificate.schema.json +53 -0
  179. package/schemas/RollbackOrDeactivationPlan.schema.json +38 -0
  180. package/schemas/SBOMManifest.schema.json +1 -1
  181. package/schemas/SalienceObstructionDiagnosis.schema.json +55 -0
  182. package/schemas/SalienceObstructionLoad.schema.json +21 -0
  183. package/schemas/SemanticEdgeEvidence.schema.json +40 -0
  184. package/schemas/TraceAdapterReport.schema.json +405 -0
  185. package/schemas/TraceFrontierDebt.schema.json +43 -0
  186. package/schemas/TraceNormalForm.schema.json +181 -0
  187. package/schemas/TraceToleranceLedger.schema.json +29 -0
  188. package/schemas/TypedActionBoundary.schema.json +58 -0
  189. package/schemas/TypedAgentTrace.schema.json +328 -0
  190. package/schemas/TypedToolCallTrace.schema.json +76 -0
  191. package/schemas/VerificationQueuePressure.schema.json +41 -0
  192. package/schemas/VerificationThroughputWindow.schema.json +21 -0
  193. package/schemas/WasteLoad.schema.json +21 -0
  194. package/schemas/WebFetchPolicy.schema.json +1 -1
  195. package/schemas/bundle.schema.json +11854 -2075
  196. package/schemas/index.json +445 -0
  197. package/schemas/schema-digest.json +733 -289
package/dist/cli/main.js CHANGED
@@ -3,13 +3,13 @@
3
3
  // src/cli/main.ts
4
4
  import {
5
5
  cpSync as cpSync2,
6
- existsSync as existsSync6,
7
- mkdirSync as mkdirSync4,
8
- readFileSync as readFileSync9,
9
- readdirSync as readdirSync2,
10
- writeFileSync as writeFileSync4
6
+ existsSync as existsSync7,
7
+ mkdirSync as mkdirSync5,
8
+ readFileSync as readFileSync10,
9
+ readdirSync as readdirSync3,
10
+ writeFileSync as writeFileSync5
11
11
  } from "fs";
12
- import { dirname as dirname5, join as join4 } from "path";
12
+ import { dirname as dirname5, join as join5 } from "path";
13
13
  import { Command } from "commander";
14
14
 
15
15
  // src/io/fixtures.ts
@@ -116,9 +116,9 @@ function portabilityManifest() {
116
116
  }
117
117
 
118
118
  // src/alt/index.ts
119
- function altAdmit(packetId = "alt-packet:demo") {
119
+ function altAdmit(packetId2 = "alt-packet:demo") {
120
120
  const decision = structuredClone(fixtureJson("alt_admission_decision.json"));
121
- decision.packet_id = packetId;
121
+ decision.packet_id = packetId2;
122
122
  decision.accepted = Boolean(decision.accepted ?? false);
123
123
  decision.settled = false;
124
124
  decision.reasons = [
@@ -128,6 +128,102 @@ function altAdmit(packetId = "alt-packet:demo") {
128
128
  return decision;
129
129
  }
130
130
 
131
+ // src/alt_lift/index.ts
132
+ function record(value2) {
133
+ return value2 && typeof value2 === "object" && !Array.isArray(value2) ? value2 : void 0;
134
+ }
135
+ function records(value2) {
136
+ return Array.isArray(value2) ? value2.filter((item) => Boolean(record(item))) : [];
137
+ }
138
+ function packetId(packet2) {
139
+ return String(
140
+ packet2.packet_id ?? packet2.report_id ?? packet2.decision_id ?? "alt-packet"
141
+ );
142
+ }
143
+ function graphHasCapital(graph) {
144
+ return Number(graph.accepted_packet_capital ?? 0) > 0;
145
+ }
146
+ function verifyAltEcptLift(packets, graph) {
147
+ const positive = packets.filter(
148
+ (packet2) => packet2.accepted === true && packet2.positive_ecpt_component_lift === true && graphHasCapital(graph)
149
+ );
150
+ return {
151
+ accepted: true,
152
+ blockers: positive.length > 0 ? [] : [
153
+ {
154
+ blocker_id: "alt-lift:no-positive-ecpt-component",
155
+ blocker_type: "missing_alt_lift",
156
+ residual_preserved: true
157
+ }
158
+ ],
159
+ candidate_packet_count: packets.length,
160
+ capital_to_path_contributions: positive.map((packet2) => ({
161
+ contribution_id: `capital-to-path:${packetId(packet2)}`,
162
+ packet_id: packetId(packet2),
163
+ positive_path_contribution: false,
164
+ settled: false
165
+ })),
166
+ execution_authority_granted: false,
167
+ graph_id: String(graph.graph_id ?? ""),
168
+ lift_status: positive.length > 0 ? "candidate" : "diagnostic_only",
169
+ positive_ecpt_component_lift: positive.length > 0,
170
+ promotes_to_ecpt_capital: false,
171
+ reasons: [
172
+ "ALT liquidity does not automatically become ECPT packet capital",
173
+ "lift report is protocol-relative and diagnostic"
174
+ ],
175
+ report_id: "alt-ecpt-lift-report",
176
+ settled: false,
177
+ workflow_usable: true
178
+ };
179
+ }
180
+ function verifyReceiverLift(packet2, receiverContext) {
181
+ const present = receiverContext.accepted === true || receiverContext.present === true;
182
+ return {
183
+ accepted: true,
184
+ execution_authority_granted: false,
185
+ packet_id: packetId(packet2),
186
+ receiver_context_present: present,
187
+ receiver_lift_status: present ? "candidate" : "diagnostic_only",
188
+ reasons: present ? ["receiver context is present but does not settle lift"] : ["receiver context is missing or not accepted"],
189
+ settled: false,
190
+ workflow_usable: true
191
+ };
192
+ }
193
+ function mapLiquidityToPaths(packet2, graph) {
194
+ const pathCount = records(graph.edges).filter(
195
+ (edge) => edge.accepted === true
196
+ ).length;
197
+ return {
198
+ accepted: true,
199
+ execution_authority_granted: false,
200
+ mapped_path_count: 0,
201
+ packet_id: packetId(packet2),
202
+ positive_path_contribution: false,
203
+ reasons: [
204
+ `observed ${pathCount} graph edges`,
205
+ "liquidity-to-path mapping is diagnostic-only until execution path rules pass"
206
+ ],
207
+ settled: false,
208
+ workflow_usable: true
209
+ };
210
+ }
211
+ function estimateCapitalImpact(reports) {
212
+ const positive = reports.filter(
213
+ (report) => report.positive_ecpt_component_lift === true
214
+ ).length;
215
+ return {
216
+ accepted: true,
217
+ estimated_positive_lift_count: positive,
218
+ execution_authority_granted: false,
219
+ false_liquidity_risk: reports.length - positive,
220
+ report_count: reports.length,
221
+ report_id: "alt-capital-impact",
222
+ settled: false,
223
+ workflow_usable: true
224
+ };
225
+ }
226
+
131
227
  // src/core/ledger.ts
132
228
  function emptyLedger() {
133
229
  return { coordinates: {} };
@@ -827,7 +923,7 @@ function verifyAgentMessage(message2, options = {}) {
827
923
  }
828
924
  reasons.push(...identityReasons);
829
925
  const accepted = contract.accepted === true && reasons.length === 0;
830
- const packetId = `packet:agent-message:${String(message2.message_id ?? "unknown")}`;
926
+ const packetId2 = `packet:agent-message:${String(message2.message_id ?? "unknown")}`;
831
927
  const packets = contract.accepted === true ? [
832
928
  {
833
929
  authority_granted: false,
@@ -851,7 +947,7 @@ function verifyAgentMessage(message2, options = {}) {
851
947
  issuer_attestation_id: message2.issuer_attestation_id ?? null,
852
948
  issuer_public_key_id: message2.issuer_public_key_id ?? null,
853
949
  issuer_signature_ref: message2.signature_ref ?? null,
854
- packet_id: packetId,
950
+ packet_id: packetId2,
855
951
  receiver_family: Array.isArray(message2.declared_receiver_family) ? message2.declared_receiver_family.map(String) : ["agent", "verifier"],
856
952
  residual_charge: 0,
857
953
  reuse_context: "general",
@@ -910,15 +1006,15 @@ function verifyAgentMessage(message2, options = {}) {
910
1006
  };
911
1007
  }
912
1008
  function initAgentInbox(path, inboxId = "agent-inbox") {
913
- const record = {
1009
+ const record5 = {
914
1010
  inbox_id: inboxId,
915
1011
  messages: [],
916
1012
  peers: [],
917
1013
  seen_nonces: []
918
1014
  };
919
1015
  mkdirSync2(dirname2(path), { recursive: true });
920
- writeFileSync2(path, stableStringify(record), "utf8");
921
- return record;
1016
+ writeFileSync2(path, stableStringify(record5), "utf8");
1017
+ return record5;
922
1018
  }
923
1019
  function readAgentInbox(path) {
924
1020
  const text = readFileSync5(path, "utf8").trim();
@@ -1048,6 +1144,213 @@ function ecologyPolicy(profile = "controlled_web") {
1048
1144
  };
1049
1145
  }
1050
1146
 
1147
+ // src/bit_engine/index.ts
1148
+ var BOTTLENECK_CLASSES = [
1149
+ "missing_evidence",
1150
+ "missing_verifier_route",
1151
+ "missing_semantic_edge",
1152
+ "missing_rollback_support",
1153
+ "missing_authority",
1154
+ "missing_receiver_context",
1155
+ "identity_sybil_blocker",
1156
+ "stale_packet",
1157
+ "false_liquidity_blocker",
1158
+ "salience_obstruction",
1159
+ "queue_occupation",
1160
+ "missing_alt_lift",
1161
+ "trace_boundary_mismatch",
1162
+ "external_domain_obligation"
1163
+ ];
1164
+ function record2(value2) {
1165
+ return value2 && typeof value2 === "object" && !Array.isArray(value2) ? value2 : void 0;
1166
+ }
1167
+ function records2(value2) {
1168
+ return Array.isArray(value2) ? value2.filter((item) => Boolean(record2(item))) : [];
1169
+ }
1170
+ function strings(value2) {
1171
+ if (Array.isArray(value2)) return value2.map(String).sort();
1172
+ if (value2 === void 0 || value2 === null) return [];
1173
+ return [String(value2)];
1174
+ }
1175
+ function classForBlocker(blocker) {
1176
+ const normalized = blocker.replaceAll("-", "_");
1177
+ if (BOTTLENECK_CLASSES.includes(normalized)) return normalized;
1178
+ if (normalized.includes("evidence")) return "missing_evidence";
1179
+ if (normalized.includes("verification")) return "missing_verifier_route";
1180
+ if (normalized.includes("edge")) return "missing_semantic_edge";
1181
+ if (normalized.includes("rollback")) return "missing_rollback_support";
1182
+ if (normalized.includes("authority")) return "missing_authority";
1183
+ if (normalized.includes("receiver")) return "missing_receiver_context";
1184
+ if (normalized.includes("stale")) return "stale_packet";
1185
+ if (normalized.includes("salience")) return "salience_obstruction";
1186
+ if (normalized.includes("external")) return "external_domain_obligation";
1187
+ return "external_domain_obligation";
1188
+ }
1189
+ function minimalConditions(bottleneckId, bottleneckClass) {
1190
+ return [
1191
+ {
1192
+ condition_id: `mec:${bottleneckId}:evidence`,
1193
+ condition_kind: "finite-evidence",
1194
+ description: `provide finite evidence for ${bottleneckClass}`,
1195
+ execution_authority_granted: false,
1196
+ settled: false
1197
+ },
1198
+ {
1199
+ condition_id: `mec:${bottleneckId}:audit`,
1200
+ condition_kind: "post-check-audit",
1201
+ description: "preserve residuals and rerun the relevant checker",
1202
+ execution_authority_granted: false,
1203
+ settled: false
1204
+ }
1205
+ ];
1206
+ }
1207
+ function diagnoseBottlenecks(graph) {
1208
+ const diagnoses = [];
1209
+ for (const node of records2(graph.nodes)) {
1210
+ for (const blocker of strings(record2(node.eligibility)?.blockers)) {
1211
+ const bottleneckClass = classForBlocker(blocker);
1212
+ const bottleneckId = `bottleneck:${String(node.node_id)}:${bottleneckClass}`;
1213
+ diagnoses.push({
1214
+ accepted: true,
1215
+ bottleneck_class: bottleneckClass,
1216
+ bottleneck_id: bottleneckId,
1217
+ capability_expression_paths: [
1218
+ {
1219
+ accepted: false,
1220
+ path_id: `capability-path:${String(node.node_id)}`,
1221
+ reasons: [`blocked by ${blocker}`],
1222
+ settled: false
1223
+ }
1224
+ ],
1225
+ minimal_enabling_conditions: minimalConditions(
1226
+ bottleneckId,
1227
+ bottleneckClass
1228
+ ),
1229
+ node_id: String(node.node_id ?? ""),
1230
+ reasons: [`effective graph node is blocked by ${blocker}`],
1231
+ settled: false
1232
+ });
1233
+ }
1234
+ }
1235
+ for (const edgeId of strings(graph.missing_edge_evidence)) {
1236
+ const bottleneckId = `bottleneck:${edgeId}:missing_semantic_edge`;
1237
+ diagnoses.push({
1238
+ accepted: true,
1239
+ bottleneck_class: "missing_semantic_edge",
1240
+ bottleneck_id: bottleneckId,
1241
+ edge_id: edgeId,
1242
+ minimal_enabling_conditions: minimalConditions(
1243
+ bottleneckId,
1244
+ "missing_semantic_edge"
1245
+ ),
1246
+ reasons: ["edge lacks semantic evidence"],
1247
+ settled: false
1248
+ });
1249
+ }
1250
+ return {
1251
+ accepted: true,
1252
+ bottleneck_count: diagnoses.length,
1253
+ bottlenecks: diagnoses.sort(
1254
+ (a, b) => String(a.bottleneck_id).localeCompare(String(b.bottleneck_id))
1255
+ ),
1256
+ execution_authority_granted: false,
1257
+ graph_id: String(graph.graph_id ?? ""),
1258
+ report_id: "bottleneck-inversion-report",
1259
+ settled: false,
1260
+ workflow_usable: true
1261
+ };
1262
+ }
1263
+ function buildMinimalEnablingConditions(bottleneckId, report) {
1264
+ const found = records2(report?.bottlenecks).find(
1265
+ (item) => item.bottleneck_id === bottleneckId
1266
+ );
1267
+ if (found) return records2(found.minimal_enabling_conditions);
1268
+ return minimalConditions(bottleneckId, "external_domain_obligation");
1269
+ }
1270
+ function invertBottlenecks(report) {
1271
+ const candidates = records2(report.bottlenecks).map((bottleneck, index) => {
1272
+ const bottleneckId = String(
1273
+ bottleneck.bottleneck_id ?? `bottleneck:${index}`
1274
+ );
1275
+ const bottleneckClass = String(
1276
+ bottleneck.bottleneck_class ?? "external_domain_obligation"
1277
+ );
1278
+ return {
1279
+ accepted: true,
1280
+ bottleneck_class: bottleneckClass,
1281
+ bottleneck_id: bottleneckId,
1282
+ candidate_id: `inversion-candidate:${bottleneckId}`,
1283
+ expected_activation_gain: {
1284
+ gain_lower_bound: bottleneckClass === "missing_semantic_edge" ? 0.2 : 0.1,
1285
+ protocol_relative_only: true
1286
+ },
1287
+ execution_authority_granted: false,
1288
+ minimal_enabling_conditions: buildMinimalEnablingConditions(
1289
+ bottleneckId,
1290
+ report
1291
+ ),
1292
+ post_inversion_audit_plan: {
1293
+ audit_steps: ["rerun graph", "rerun observation", "preserve residuals"],
1294
+ settled: false
1295
+ },
1296
+ reasons: ["inversion candidate is recommendation-only"],
1297
+ risk_hazard_authority_notes: [
1298
+ "host runtime authority required before external effects"
1299
+ ],
1300
+ rollback_or_deactivation_plan: {
1301
+ plan_id: `rollback:${bottleneckId}`,
1302
+ required: true,
1303
+ settled: false
1304
+ },
1305
+ settled: false,
1306
+ verification_cost: 1,
1307
+ why_not_settled: "minimal enabling conditions are not discharged"
1308
+ };
1309
+ });
1310
+ return {
1311
+ accepted: true,
1312
+ candidate_count: candidates.length,
1313
+ candidates,
1314
+ execution_authority_granted: false,
1315
+ report_id: "bottleneck-inversion-candidates",
1316
+ settled: false,
1317
+ workflow_usable: true
1318
+ };
1319
+ }
1320
+ function buildInversionCertificate(candidate) {
1321
+ const selected = records2(candidate.inversion_candidates)[0] ?? records2(candidate.candidates)[0] ?? candidate;
1322
+ return {
1323
+ accepted: selected.accepted === true,
1324
+ candidate: selected,
1325
+ certificate_id: `inversion-certificate:${String(selected.candidate_id ?? "candidate")}`,
1326
+ certificate_status: "candidate",
1327
+ execution_authority_granted: false,
1328
+ finite_requirements_passed: false,
1329
+ reasons: [
1330
+ "inversion certificate is a candidate only",
1331
+ "post-inversion audit remains required"
1332
+ ],
1333
+ settled: false,
1334
+ workflow_usable: true
1335
+ };
1336
+ }
1337
+ function compareBottleneckBaseline(baseline, candidate) {
1338
+ const delta = {
1339
+ closure_witness_count: Number(candidate.closure_witness_count ?? 0) - Number(baseline.closure_witness_count ?? 0),
1340
+ effective_edge_count: Number(candidate.effective_edge_count ?? 0) - Number(baseline.effective_edge_count ?? 0),
1341
+ effective_node_count: Number(candidate.effective_node_count ?? 0) - Number(baseline.effective_node_count ?? 0),
1342
+ residual_debt: Number(candidate.residual_debt ?? 0) - Number(baseline.residual_debt ?? 0)
1343
+ };
1344
+ return {
1345
+ accepted: true,
1346
+ activation_gain_estimate: delta,
1347
+ execution_authority_granted: false,
1348
+ report_id: "bottleneck-baseline-comparison",
1349
+ settled: false,
1350
+ workflow_usable: true
1351
+ };
1352
+ }
1353
+
1051
1354
  // src/io/portability.ts
1052
1355
  import { createHash as createHash4 } from "crypto";
1053
1356
  import { existsSync as existsSync5, readFileSync as readFileSync6 } from "fs";
@@ -1295,14 +1598,14 @@ function readTypedJson(path, schema) {
1295
1598
  }
1296
1599
  return data;
1297
1600
  }
1298
- function residualCarryForward(reportId, residualSummary, missingObligations, candidateOnlyReasons, settledBlockers, accepted) {
1601
+ function residualCarryForward(reportId, residualSummary2, missingObligations, candidateOnlyReasons, settledBlockers, accepted) {
1299
1602
  return {
1300
1603
  accepted,
1301
1604
  candidate_only_reasons: candidateOnlyReasons,
1302
1605
  missing_obligations: missingObligations,
1303
1606
  reasons: ["residuals and blockers are preserved during packet export"],
1304
1607
  report_id: reportId,
1305
- residual_summary: residualSummary,
1608
+ residual_summary: residualSummary2,
1306
1609
  settled: false,
1307
1610
  settled_blockers: settledBlockers
1308
1611
  };
@@ -1310,7 +1613,7 @@ function residualCarryForward(reportId, residualSummary, missingObligations, can
1310
1613
  function packetEnvelopeFromRuntimeReport(report) {
1311
1614
  const digest = stableDigest(report);
1312
1615
  const missing = Array.isArray(report.missing_obligations) ? report.missing_obligations.map(String) : [];
1313
- const residualSummary = summarizeLedger(report.residual_ledger);
1616
+ const residualSummary2 = summarizeLedger(report.residual_ledger);
1314
1617
  const candidateOnlyReasons = [
1315
1618
  "runtime report is exported as diagnostic packet-exchange data",
1316
1619
  "packet exchange does not route promotion checks"
@@ -1344,13 +1647,13 @@ function packetEnvelopeFromRuntimeReport(report) {
1344
1647
  reasons: ["exported packet is diagnostic data and is not promoted"],
1345
1648
  residual_carry_forward: residualCarryForward(
1346
1649
  `residual-carry-forward:${reportId}`,
1347
- residualSummary,
1650
+ residualSummary2,
1348
1651
  missing,
1349
1652
  candidateOnlyReasons,
1350
1653
  settledBlockers,
1351
1654
  report.accepted === true
1352
1655
  ),
1353
- residual_ledger_summary: residualSummary,
1656
+ residual_ledger_summary: residualSummary2,
1354
1657
  safety_invariants: [
1355
1658
  "packet exchange treats content as inert data",
1356
1659
  "packet exchange does not execute embedded commands",
@@ -1415,7 +1718,7 @@ function mergePacketEnvelopes(envelopes) {
1415
1718
  const byDigest = /* @__PURE__ */ new Map();
1416
1719
  const duplicateIds = [];
1417
1720
  const duplicateDigests = [];
1418
- const residualSummary = {};
1721
+ const residualSummary2 = {};
1419
1722
  const missing = [];
1420
1723
  const candidateOnly = [];
1421
1724
  const blockers = [];
@@ -1430,7 +1733,7 @@ function mergePacketEnvelopes(envelopes) {
1430
1733
  for (const [key, value2] of Object.entries(
1431
1734
  envelope.residual_ledger_summary ?? {}
1432
1735
  )) {
1433
- residualSummary[key] = (residualSummary[key] ?? 0) + Number(value2);
1736
+ residualSummary2[key] = (residualSummary2[key] ?? 0) + Number(value2);
1434
1737
  }
1435
1738
  if (Array.isArray(envelope.missing_obligations)) {
1436
1739
  missing.push(...envelope.missing_obligations.map(String));
@@ -1457,7 +1760,7 @@ function mergePacketEnvelopes(envelopes) {
1457
1760
  report_id: "packet-merge-report",
1458
1761
  residual_carry_forward: residualCarryForward(
1459
1762
  "residual-carry-forward:packet-merge",
1460
- Object.fromEntries(Object.entries(residualSummary).sort()),
1763
+ Object.fromEntries(Object.entries(residualSummary2).sort()),
1461
1764
  sortedUnique2(missing),
1462
1765
  sortedUnique2(candidateOnly),
1463
1766
  sortedUnique2(blockers),
@@ -1469,12 +1772,12 @@ function mergePacketEnvelopes(envelopes) {
1469
1772
  }
1470
1773
  function packetLineageDigest(packetOrMerge) {
1471
1774
  const packets = Array.isArray(packetOrMerge.packets) ? packetOrMerge.packets : [packetOrMerge];
1472
- const residualSummary = {};
1775
+ const residualSummary2 = {};
1473
1776
  for (const packet2 of packets) {
1474
1777
  for (const [key, value2] of Object.entries(
1475
1778
  packet2.residual_ledger_summary ?? {}
1476
1779
  )) {
1477
- residualSummary[key] = (residualSummary[key] ?? 0) + Number(value2);
1780
+ residualSummary2[key] = (residualSummary2[key] ?? 0) + Number(value2);
1478
1781
  }
1479
1782
  }
1480
1783
  return {
@@ -1495,134 +1798,1190 @@ function packetLineageDigest(packetOrMerge) {
1495
1798
  "lineage digest is diagnostic-only and preserves candidate status"
1496
1799
  ],
1497
1800
  residual_summary: Object.fromEntries(
1498
- Object.entries(residualSummary).sort()
1801
+ Object.entries(residualSummary2).sort()
1499
1802
  ),
1500
1803
  settled: false,
1501
1804
  workflow_usable: packets.some((packet2) => packet2.workflow_usable === true)
1502
1805
  };
1503
1806
  }
1504
1807
 
1505
- // src/render/markdown.ts
1506
- import { mkdirSync as mkdirSync3, writeFileSync as writeFileSync3 } from "fs";
1507
- import { dirname as dirname4 } from "path";
1508
- function lang(language) {
1509
- return language?.toLowerCase().startsWith("ja") ? "ja" : "en";
1808
+ // src/phase_lab/index.ts
1809
+ import { createHash as createHash6 } from "crypto";
1810
+ import {
1811
+ existsSync as existsSync6,
1812
+ mkdirSync as mkdirSync3,
1813
+ readFileSync as readFileSync8,
1814
+ readdirSync as readdirSync2,
1815
+ writeFileSync as writeFileSync3
1816
+ } from "fs";
1817
+ import { basename as basename2, join as join4 } from "path";
1818
+ var PHASE_LAB_SAFETY = [
1819
+ "phase lab stores local report data only",
1820
+ "phase lab never executes report or packet content",
1821
+ "phase lab diagnostics do not settle claims",
1822
+ "raw packet volume is diagnostic only"
1823
+ ];
1824
+ var GRAPH_SAFETY = [
1825
+ "raw packet volume is diagnostic only",
1826
+ "candidate-only nodes do not improve positive phase components",
1827
+ "graph construction does not execute packet content",
1828
+ "graph construction does not settle claims"
1829
+ ];
1830
+ function sha256Json(data) {
1831
+ return createHash6("sha256").update(JSON.stringify(sortJson(data)), "utf8").digest("hex");
1510
1832
  }
1511
- function value(data, key) {
1512
- const raw = data[key];
1513
- if (raw === void 0 || raw === null) {
1514
- return "not-recorded";
1833
+ function asRecord(value2) {
1834
+ return value2 && typeof value2 === "object" && !Array.isArray(value2) ? value2 : void 0;
1835
+ }
1836
+ function asRecords(value2) {
1837
+ return Array.isArray(value2) ? value2.filter((item) => Boolean(asRecord(item))) : [];
1838
+ }
1839
+ function stringList(value2) {
1840
+ if (value2 === void 0 || value2 === null) return [];
1841
+ if (Array.isArray(value2)) return value2.map(String).sort();
1842
+ if (value2 instanceof Set) return [...value2].map(String).sort();
1843
+ return [String(value2)];
1844
+ }
1845
+ function numeric(value2) {
1846
+ if (typeof value2 === "number" && Number.isFinite(value2)) return value2;
1847
+ const parsed = Number(value2);
1848
+ return Number.isFinite(parsed) ? parsed : 0;
1849
+ }
1850
+ function numericDict(value2) {
1851
+ const record5 = asRecord(value2);
1852
+ if (!record5) return {};
1853
+ return Object.fromEntries(
1854
+ Object.entries(record5).map(([key, item]) => [key, numeric(item)]).sort(([a], [b]) => a.localeCompare(b))
1855
+ );
1856
+ }
1857
+ function residualSummary(payload) {
1858
+ const direct = asRecord(payload.residual_summary) ?? asRecord(payload.residual_ledger_summary);
1859
+ if (direct) return numericDict(direct);
1860
+ const coordinates = asRecord(asRecord(payload.residual_ledger)?.coordinates);
1861
+ if (!coordinates) return {};
1862
+ const summary = {};
1863
+ for (const coordinate of Object.values(coordinates)) {
1864
+ const item = asRecord(coordinate);
1865
+ if (!item) continue;
1866
+ const kind = String(item.kind ?? "residual");
1867
+ summary[kind] = (summary[kind] ?? 0) + numeric(item.value);
1515
1868
  }
1516
- if (typeof raw === "string" || typeof raw === "number") {
1517
- return String(raw);
1869
+ return Object.fromEntries(
1870
+ Object.entries(summary).sort(([a], [b]) => a.localeCompare(b))
1871
+ );
1872
+ }
1873
+ function residualDebt(summary) {
1874
+ return Object.values(summary).reduce((total, value2) => total + value2, 0);
1875
+ }
1876
+ function inferSchemaHint(payload) {
1877
+ if ("packet_id" in payload && "content_digest" in payload && "content" in payload) {
1878
+ return "PacketExchangeEnvelope";
1518
1879
  }
1519
- if (typeof raw === "boolean") {
1520
- return raw ? "true" : "false";
1880
+ if ("report_id" in payload && "registry" in payload)
1881
+ return "RuntimeStepReport";
1882
+ if ("graph_id" in payload && "nodes" in payload && "edges" in payload) {
1883
+ return "EffectivePacketGraph";
1521
1884
  }
1522
- return JSON.stringify(raw);
1885
+ if ("message_id" in payload) return "AgentMessageEnvelope";
1886
+ if ("decision_id" in payload && "packet_id" in payload)
1887
+ return "ALTAdmissionDecision";
1888
+ if ("accepted" in payload && "workflow_usable" in payload)
1889
+ return "AgentCheckReport";
1890
+ return String(payload.schema_hint ?? payload.schema ?? "UnknownPICReport");
1523
1891
  }
1524
- function count(data, key) {
1525
- const raw = data[key];
1526
- if (Array.isArray(raw)) {
1527
- return raw.length;
1528
- }
1529
- if (raw && typeof raw === "object") {
1530
- return Object.keys(raw).length;
1892
+ function inferSourceKind(payload, schemaHint) {
1893
+ if (typeof payload.source_kind === "string") return payload.source_kind;
1894
+ const mapping = {
1895
+ AgentCheckReport: "agent-check",
1896
+ AgentMessageEnvelope: "agent-message",
1897
+ ALTAdmissionDecision: "alt-admission",
1898
+ EffectivePacketGraph: "effective-graph",
1899
+ PacketExchangeEnvelope: "packet-exchange",
1900
+ RuntimeStepReport: "runtime-step-report"
1901
+ };
1902
+ return mapping[schemaHint] ?? "unknown-report";
1903
+ }
1904
+ function unsafeReasons(payload, missing, candidateOnlyReasons, settledBlockers) {
1905
+ const text = JSON.stringify(payload).toLowerCase();
1906
+ const reasons = [];
1907
+ if ([
1908
+ "npm install",
1909
+ "npx",
1910
+ "node ",
1911
+ "docker run",
1912
+ "kubectl",
1913
+ "curl ",
1914
+ "bash ",
1915
+ "powershell",
1916
+ "safe_commands"
1917
+ ].some((marker) => text.includes(marker))) {
1918
+ reasons.push("embedded command-like text remains inert");
1531
1919
  }
1532
- return 0;
1920
+ if (missing.length > 0) reasons.push("missing obligations remain visible");
1921
+ if (candidateOnlyReasons.length > 0)
1922
+ reasons.push("candidate-only reasons remain visible");
1923
+ if (settledBlockers.length > 0)
1924
+ reasons.push("settlement blockers remain visible");
1925
+ return dedupeSorted(reasons);
1533
1926
  }
1534
- function boolRows(data, keys) {
1535
- return keys.map((key) => `- \`${key}\`: ${value(data, key)}`).join("\n");
1927
+ function eventFromPayload(payload, windowId, sequence, sourcePath, sourceKindOverride) {
1928
+ const digest = sha256Json(payload);
1929
+ const schemaHint = inferSchemaHint(payload);
1930
+ const sourceKind = sourceKindOverride ?? inferSourceKind(payload, schemaHint);
1931
+ const missing = dedupeSorted([
1932
+ ...stringList(payload.missing_obligations),
1933
+ ...stringList(payload.unresolved_obligations)
1934
+ ]);
1935
+ const candidateOnlyReasons = dedupeSorted(
1936
+ stringList(payload.candidate_only_reasons)
1937
+ );
1938
+ const settledBlockers = dedupeSorted([
1939
+ ...stringList(payload.settled_blockers),
1940
+ ...payload.settled === true ? ["source-settled-ignored-by-phase-lab"] : []
1941
+ ]);
1942
+ const accepted = payload.accepted === true;
1943
+ const candidateOnly = payload.candidate_only === true || candidateOnlyReasons.length > 0 || !accepted || [
1944
+ "packet-exchange",
1945
+ "general-intake",
1946
+ "raw-external",
1947
+ "phase-dashboard"
1948
+ ].includes(sourceKind);
1949
+ const reasons = unsafeReasons(
1950
+ payload,
1951
+ missing,
1952
+ candidateOnlyReasons,
1953
+ settledBlockers
1954
+ );
1955
+ const positiveContributionAllowed = accepted && !candidateOnly && reasons.length === 0 && missing.length === 0;
1956
+ return {
1957
+ accepted,
1958
+ candidate_only: candidateOnly,
1959
+ candidate_only_reasons: candidateOnlyReasons,
1960
+ content_digest: digest,
1961
+ event_id: `phase-lab-event:${sequence}:${digest.slice(0, 12)}`,
1962
+ missing_obligations: missing,
1963
+ operationally_usable: payload.operationally_usable === true,
1964
+ payload,
1965
+ positive_contribution_allowed: positiveContributionAllowed,
1966
+ reasons: dedupeSorted([
1967
+ "event content is stored as inert data",
1968
+ ...reasons,
1969
+ ...candidateOnly ? ["candidate-only event cannot improve phase metrics"] : []
1970
+ ]),
1971
+ residual_summary: residualSummary(payload),
1972
+ safety_boundary: PHASE_LAB_SAFETY,
1973
+ schema_hint: schemaHint,
1974
+ settled: false,
1975
+ settled_blockers: settledBlockers,
1976
+ source_kind: sourceKind,
1977
+ source_path: sourcePath ? basename2(sourcePath) : null,
1978
+ window_id: windowId,
1979
+ workflow_usable: payload.workflow_usable === true
1980
+ };
1536
1981
  }
1537
- function safetyBoundary(language) {
1538
- if (lang(language) === "ja") {
1539
- return [
1540
- "## \u5B89\u5168\u5883\u754C",
1541
- "",
1542
- "- \u3053\u308C\u306F\u5B9F\u884C\u6A29\u9650\u3067\u306F\u3042\u308A\u307E\u305B\u3093\u3002",
1543
- "- \u5B9F ASI\u3001\u7269\u7406\u7D50\u679C\u3001\u5916\u90E8\u30AA\u30E9\u30AF\u30EB\u306E\u771F\u7406\u3092\u8A3C\u660E\u3057\u307E\u305B\u3093\u3002",
1544
- "- `settled=false` \u306F\u672A\u89E3\u6C7A\u306E\u78BA\u8A8D\u4E8B\u9805\u304C\u898B\u3048\u308B\u72B6\u614B\u3067\u6B8B\u308B\u3053\u3068\u3092\u610F\u5473\u3057\u307E\u3059\u3002",
1545
- "- packet \u306E\u5185\u5BB9\u3068 `safe_commands` \u306F\u691C\u67FB\u7528\u30C7\u30FC\u30BF\u3067\u3042\u308A\u3001\u81EA\u52D5\u5B9F\u884C\u3055\u308C\u307E\u305B\u3093\u3002"
1546
- ].join("\n");
1982
+ function readJsonFile(path, label = "JSON") {
1983
+ if (!path.toLowerCase().endsWith(".json")) {
1984
+ throw new Error(
1985
+ `${label} must be a JSON file; YAML input is not enabled in PIC-TS v0.5.0`
1986
+ );
1547
1987
  }
1548
- return [
1549
- "## Safety Boundary",
1550
- "",
1551
- "- This is not execution authority.",
1552
- "- This is not proof of real ASI, physical truth, or oracle truth.",
1553
- "- `settled=false` means unresolved obligations remain visible.",
1554
- "- Packet content and `safe_commands` are inspection data, not automatic actions."
1555
- ].join("\n");
1988
+ return parseJsonObject(readFileSync8(path, "utf8"), label);
1556
1989
  }
1557
- function writeTextOutput(text, outputPath) {
1558
- const finalText = text.endsWith("\n") ? text : `${text}
1559
- `;
1560
- if (outputPath) {
1561
- mkdirSync3(dirname4(outputPath), { recursive: true });
1562
- writeFileSync3(outputPath, finalText, "utf8");
1990
+ function storePaths(storeDir) {
1991
+ return {
1992
+ events: join4(storeDir, "events.jsonl"),
1993
+ manifest: join4(storeDir, "manifest.json"),
1994
+ windows: join4(storeDir, "windows")
1995
+ };
1996
+ }
1997
+ function windowFileName(windowId) {
1998
+ return `${windowId.replace(/[^A-Za-z0-9_.-]/g, "_")}.json`;
1999
+ }
2000
+ function readEvents(storeDir) {
2001
+ const eventsPath = storePaths(storeDir).events;
2002
+ if (!existsSync6(eventsPath)) return [];
2003
+ return readFileSync8(eventsPath, "utf8").split(/\r?\n/).filter(Boolean).map((line) => parseJsonObject(line, "phase lab event"));
2004
+ }
2005
+ function writeJson(path, data) {
2006
+ writeFileSync3(path, stableStringify(data), "utf8");
2007
+ }
2008
+ function windowIndex(windowId, sequence, events) {
2009
+ const residual = events.reduce(
2010
+ (total, event) => total + residualDebt(numericDict(event.residual_summary)),
2011
+ 0
2012
+ );
2013
+ return {
2014
+ accepted: true,
2015
+ accepted_event_count: events.filter((event) => event.accepted === true).length,
2016
+ candidate_only_event_count: events.filter(
2017
+ (event) => event.candidate_only === true
2018
+ ).length,
2019
+ event_count: events.length,
2020
+ event_ids: events.map((event) => String(event.event_id)),
2021
+ missing_obligation_count: events.reduce(
2022
+ (total, event) => total + stringList(event.missing_obligations).length,
2023
+ 0
2024
+ ),
2025
+ positive_contribution_event_count: events.filter(
2026
+ (event) => event.positive_contribution_allowed === true
2027
+ ).length,
2028
+ reasons: ["window index preserves event residuals without settling claims"],
2029
+ residual_debt: residual,
2030
+ sequence,
2031
+ settled: false,
2032
+ settled_event_count: 0,
2033
+ window_id: windowId
2034
+ };
2035
+ }
2036
+ function readWindowIndexes(storeDir) {
2037
+ const windowsDir = storePaths(storeDir).windows;
2038
+ if (!existsSync6(windowsDir)) return [];
2039
+ return readdirSync2(windowsDir).filter((name) => name !== "latest.json" && name.endsWith(".json")).sort().map(
2040
+ (name) => parseJsonObject(readFileSync8(join4(windowsDir, name), "utf8"), "window")
2041
+ );
2042
+ }
2043
+ function selectWindow(storeDir, selector = "latest") {
2044
+ const windows = readWindowIndexes(storeDir);
2045
+ if (windows.length === 0) throw new Error("phase lab store has no windows");
2046
+ let selected;
2047
+ if (selector === "latest" || selector === "all") {
2048
+ selected = windows[windows.length - 1];
2049
+ } else if (selector === "previous") {
2050
+ selected = windows.length > 1 ? windows[windows.length - 2] : windows[windows.length - 1];
1563
2051
  } else {
1564
- process.stdout.write(finalText);
2052
+ selected = windows.find((window) => window.window_id === selector);
1565
2053
  }
2054
+ if (!selected)
2055
+ throw new Error(`unknown phase lab window ${JSON.stringify(selector)}`);
2056
+ const selectedId = String(selected.window_id);
2057
+ const events = selector === "all" ? readEvents(storeDir) : readEvents(storeDir).filter((event) => event.window_id === selectedId);
2058
+ return { index: selected, events };
1566
2059
  }
1567
- function renderAdoptionPacketMarkdown(data, language) {
1568
- if (lang(language) === "ja") {
1569
- return [
1570
- "# \u30AA\u30DA\u30EC\u30FC\u30BF\u30FC\u63A1\u7528\u30D1\u30B1\u30C3\u30C8",
1571
- "",
1572
- "PIC-TS \u306F Node.js \u3067 AI agent \u306E\u51FA\u529B\u3092 JSON \u3068\u3057\u3066\u691C\u67FB\u3057\u3001\u672A\u89E3\u6C7A\u306E\u78BA\u8A8D\u4E8B\u9805\u3092\u96A0\u3055\u305A\u6B8B\u3057\u307E\u3059\u3002",
1573
- "",
1574
- "## \u6700\u521D\u306E\u30B3\u30DE\u30F3\u30C9",
1575
- "",
1576
- "```sh",
1577
- "npm install percolation-inversion-compiler-ts",
1578
- "npx pic-ts agent check --compact",
1579
- "```",
1580
- "",
1581
- "## \u72B6\u614B\u306E\u8AAD\u307F\u65B9",
1582
- "",
1583
- boolRows(data, ["accepted", "workflow_usable", "settled"]),
1584
- "- `residual_ledger`: \u6B8B\u3063\u3066\u3044\u308B\u78BA\u8A8D\u4F5C\u696D\u306E\u53F0\u5E33\u3067\u3059\u3002",
1585
- "- `safe_commands`: \u30AA\u30DA\u30EC\u30FC\u30BF\u30FC\u304C\u78BA\u8A8D\u3059\u308B\u305F\u3081\u306E\u5019\u88DC\u3067\u3042\u308A\u3001\u81EA\u52D5\u5B9F\u884C\u6A29\u9650\u3067\u306F\u3042\u308A\u307E\u305B\u3093\u3002",
1586
- "",
1587
- "## \u30EC\u30D3\u30E5\u30FC\u30C1\u30A7\u30C3\u30AF",
1588
- "",
1589
- "- packet \u3092\u4E3B workflow \u306E gate \u3068\u3057\u3066\u6271\u308F\u306A\u3044\u3002",
1590
- "- \u672A\u89E3\u6C7A obligation \u3092 `settled=true` \u306B\u6607\u683C\u3057\u306A\u3044\u3002",
1591
- "",
1592
- safetyBoundary(language)
1593
- ].join("\n");
1594
- }
1595
- return [
1596
- "# Operator Adoption Packet",
1597
- "",
1598
- "PIC-TS checks AI agent output for Node.js workflows and keeps unfinished verification work visible.",
1599
- "",
1600
- "## First Commands",
1601
- "",
1602
- "```sh",
1603
- "npm install percolation-inversion-compiler-ts",
1604
- "npx pic-ts agent check --compact",
1605
- "```",
1606
- "",
1607
- "## How To Read The Report",
1608
- "",
1609
- boolRows(data, ["accepted", "workflow_usable", "settled"]),
1610
- "- `residual_ledger`: remaining verification work that must stay visible.",
1611
- "- `safe_commands`: inspection hints for an operator, not permission to run actions.",
1612
- "",
1613
- "## Operator Review Checklist",
1614
- "",
1615
- "- Confirm adoption sidecars do not gate the main workflow.",
1616
- "- Confirm unresolved obligations are not promoted to settlement.",
1617
- "",
1618
- safetyBoundary(language)
1619
- ].join("\n");
2060
+ function writeManifest(storeDir) {
2061
+ const paths = storePaths(storeDir);
2062
+ mkdirSync3(paths.windows, { recursive: true });
2063
+ const windows = readWindowIndexes(storeDir);
2064
+ const events = readEvents(storeDir);
2065
+ const manifest = {
2066
+ accepted: true,
2067
+ database_path: "events.jsonl",
2068
+ event_count: events.length,
2069
+ latest_window_id: windows.length > 0 ? String(windows[windows.length - 1]?.window_id ?? "") : null,
2070
+ reasons: ["phase lab store is local and non-executing"],
2071
+ safety_invariants: PHASE_LAB_SAFETY,
2072
+ schema_version: "phase-lab-store-v1",
2073
+ settled: false,
2074
+ store_id: "phase-lab-store",
2075
+ store_path: basename2(storeDir),
2076
+ window_count: windows.length
2077
+ };
2078
+ writeJson(paths.manifest, manifest);
2079
+ return manifest;
1620
2080
  }
1621
- function renderAdoptionRequestMarkdown(data, language) {
1622
- if (lang(language) === "ja") {
1623
- return [
1624
- "# Agent \u304B\u3089 Operator \u3078\u306E\u30EA\u30AF\u30A8\u30B9\u30C8",
1625
- "",
2081
+ function initPhaseLabStore(outputDir) {
2082
+ const paths = storePaths(outputDir);
2083
+ mkdirSync3(paths.windows, { recursive: true });
2084
+ if (!existsSync6(paths.events)) writeFileSync3(paths.events, "", "utf8");
2085
+ return writeManifest(outputDir);
2086
+ }
2087
+ function ingestPayloads(storeDir, payloads) {
2088
+ initPhaseLabStore(storeDir);
2089
+ const sequence = readWindowIndexes(storeDir).length;
2090
+ const offset = readEvents(storeDir).length;
2091
+ const windowId = `phase-window:${String(sequence).padStart(4, "0")}`;
2092
+ const events = payloads.map(
2093
+ (item, index2) => eventFromPayload(
2094
+ item.payload,
2095
+ windowId,
2096
+ offset + index2,
2097
+ item.path,
2098
+ item.sourceKind
2099
+ )
2100
+ );
2101
+ const index = windowIndex(windowId, sequence, events);
2102
+ const paths = storePaths(storeDir);
2103
+ const append = events.map((event) => JSON.stringify(sortJson(event))).join("\n");
2104
+ if (append) {
2105
+ writeFileSync3(paths.events, `${append}
2106
+ `, { encoding: "utf8", flag: "a" });
2107
+ }
2108
+ writeJson(join4(paths.windows, windowFileName(windowId)), index);
2109
+ writeJson(join4(paths.windows, "latest.json"), index);
2110
+ const manifest = writeManifest(storeDir);
2111
+ return {
2112
+ accepted: events.length > 0,
2113
+ content_treated_as_data: true,
2114
+ executed_command_count: 0,
2115
+ ingested_events: events,
2116
+ reasons: [
2117
+ "ingested files were stored as inert local data",
2118
+ "no embedded command, safe_command, network, repository, or model action was executed"
2119
+ ],
2120
+ rejected_paths: [],
2121
+ report_id: `phase-lab-ingest:${windowId}`,
2122
+ settled: false,
2123
+ store_manifest: manifest,
2124
+ window: index,
2125
+ workflow_usable: true
2126
+ };
2127
+ }
2128
+ function ingestPhaseLabFiles(storeDir, reportPaths = [], packetPaths = []) {
2129
+ const payloads = [
2130
+ ...reportPaths.map((path) => ({
2131
+ payload: readJsonFile(path, "phase lab report"),
2132
+ path
2133
+ })),
2134
+ ...packetPaths.map((path) => ({
2135
+ payload: readJsonFile(path, "phase lab packet"),
2136
+ path,
2137
+ sourceKind: "packet-exchange"
2138
+ }))
2139
+ ];
2140
+ if (payloads.length === 0) {
2141
+ throw new Error("provide at least one Phase Lab report or packet");
2142
+ }
2143
+ return ingestPayloads(storeDir, payloads);
2144
+ }
2145
+ function ingestPhaseLabDirectory(storeDir, directory) {
2146
+ if (!existsSync6(directory))
2147
+ throw new Error(`phase lab directory does not exist: ${directory}`);
2148
+ const payloads = readdirSync2(directory).filter((name) => name.toLowerCase().endsWith(".json")).sort().map((name) => {
2149
+ const path = join4(directory, name);
2150
+ return { payload: readJsonFile(path, "phase lab directory item"), path };
2151
+ });
2152
+ return ingestPayloads(storeDir, payloads);
2153
+ }
2154
+ function listPhaseLabWindows(storeDir) {
2155
+ return {
2156
+ settled: false,
2157
+ store_manifest: writeManifest(storeDir),
2158
+ windows: readWindowIndexes(storeDir)
2159
+ };
2160
+ }
2161
+ function eligibilityBlockers(event) {
2162
+ const joined = [
2163
+ event.source_kind,
2164
+ ...stringList(event.missing_obligations),
2165
+ ...stringList(event.candidate_only_reasons),
2166
+ ...stringList(event.settled_blockers),
2167
+ ...stringList(event.reasons)
2168
+ ].join(" ").toLowerCase();
2169
+ const blockers = [];
2170
+ const markers = {
2171
+ "authority-invalid": [
2172
+ "authority-invalid",
2173
+ "missing authority",
2174
+ "authority"
2175
+ ],
2176
+ "candidate-only": ["candidate-only"],
2177
+ "hash-invalid": ["hash-invalid", "digest mismatch"],
2178
+ "raw-external-volume": ["general-intake", "raw-external"],
2179
+ "rollback-missing": ["rollback", "safe abort"],
2180
+ "salience-obstruction": ["salience", "queue occupation"],
2181
+ stale: ["stale", "expired"],
2182
+ "verification-blocked": [
2183
+ "missing evidence",
2184
+ "missing verifier",
2185
+ "verification"
2186
+ ]
2187
+ };
2188
+ for (const [blocker, needles] of Object.entries(markers)) {
2189
+ if (needles.some((needle) => joined.includes(needle)))
2190
+ blockers.push(blocker);
2191
+ }
2192
+ if (event.candidate_only === true) blockers.push("candidate-only");
2193
+ return dedupeSorted(blockers);
2194
+ }
2195
+ function nodeFromEvent(event) {
2196
+ const blockers = eligibilityBlockers(event);
2197
+ const eligible = event.positive_contribution_allowed === true && blockers.length === 0;
2198
+ const status = eligible ? "accepted" : event.candidate_only === true ? "candidate-only" : "diagnostic";
2199
+ return {
2200
+ accepted: event.accepted === true,
2201
+ content_digest: String(event.content_digest ?? ""),
2202
+ contribution: {
2203
+ candidate_only: !eligible,
2204
+ non_contributing_reason: eligible ? "" : "eligibility blockers prevent positive contribution",
2205
+ positive_contribution: eligible,
2206
+ settled: false,
2207
+ status
2208
+ },
2209
+ eligibility: {
2210
+ accepted_or_certificate_admissible: event.accepted === true,
2211
+ agent_text_not_treated_as_evidence: event.source_kind !== "agent-text-only",
2212
+ authority_valid: !blockers.includes("authority-invalid"),
2213
+ blockers,
2214
+ eligible,
2215
+ hash_valid: !blockers.includes("hash-invalid"),
2216
+ not_raw_external_volume: !blockers.includes("raw-external-volume"),
2217
+ not_registry_metadata_only: event.source_kind !== "registry-metadata",
2218
+ not_salience_blocked: !blockers.includes("salience-obstruction"),
2219
+ not_stale: !blockers.includes("stale"),
2220
+ not_verification_blocked: !blockers.includes("verification-blocked"),
2221
+ residuals_preserved: true,
2222
+ retrievable: Boolean(event.content_digest),
2223
+ rollback_available_or_not_required: !blockers.includes("rollback-missing"),
2224
+ within_validity_domain: true
2225
+ },
2226
+ missing_obligations: stringList(event.missing_obligations),
2227
+ node_id: `node:${String(event.content_digest ?? "").slice(0, 12)}`,
2228
+ operationally_usable: event.operationally_usable === true,
2229
+ reasons: stringList(event.reasons),
2230
+ residual_summary: numericDict(event.residual_summary),
2231
+ schema_hint: String(event.schema_hint ?? "UnknownPICReport"),
2232
+ settled: false,
2233
+ source_event_id: String(event.event_id ?? ""),
2234
+ source_kind: String(event.source_kind ?? "unknown-report"),
2235
+ workflow_usable: event.workflow_usable === true
2236
+ };
2237
+ }
2238
+ function extractEdges(payload) {
2239
+ const edges = [];
2240
+ for (const key of ["edges", "edge_witnesses", "edge_certificates"]) {
2241
+ edges.push(...asRecords(payload[key]));
2242
+ }
2243
+ const registry = asRecord(payload.registry);
2244
+ if (registry) edges.push(...extractEdges(registry));
2245
+ const content = asRecord(payload.content);
2246
+ if (content) edges.push(...extractEdges(content));
2247
+ return edges;
2248
+ }
2249
+ function nodeIdForRef(ref, nodes) {
2250
+ if (!ref) return void 0;
2251
+ return nodes.map((node) => String(node.node_id)).find((nodeId) => {
2252
+ const node = nodes.find((item) => item.node_id === nodeId);
2253
+ return node && [
2254
+ node.node_id,
2255
+ node.content_digest,
2256
+ String(node.content_digest).slice(0, 12),
2257
+ node.source_event_id
2258
+ ].map(String).includes(ref);
2259
+ });
2260
+ }
2261
+ function nodePositive(nodeId, nodes) {
2262
+ const node = nodes.find((item) => item.node_id === nodeId);
2263
+ return asRecord(node?.contribution)?.positive_contribution === true;
2264
+ }
2265
+ function edgesFromEvents(nodes, events) {
2266
+ const edges = [];
2267
+ events.forEach((event, eventIndex) => {
2268
+ const node = nodes[eventIndex];
2269
+ if (!node) return;
2270
+ extractEdges(asRecord(event.payload) ?? {}).forEach((edge, index) => {
2271
+ const sourceIds = stringList(edge.source_packet_ids).map((ref) => nodeIdForRef(ref, nodes)).filter((item) => Boolean(item));
2272
+ const target = nodeIdForRef(String(edge.target_packet_id ?? ""), nodes) ?? String(node.node_id);
2273
+ const evidenceRefs = stringList(edge.evidence_refs);
2274
+ const accepted = edge.accepted === true || event.accepted === true;
2275
+ const evidenceSupported = accepted && evidenceRefs.length > 0;
2276
+ const positive = evidenceSupported && sourceIds.every((source) => nodePositive(source, nodes)) && nodePositive(target, nodes);
2277
+ const edgeId = String(
2278
+ edge.edge_id ?? `edge:${String(node.node_id)}:${index}`
2279
+ );
2280
+ edges.push({
2281
+ accepted,
2282
+ contribution: {
2283
+ candidate_only: !positive,
2284
+ non_contributing_reason: positive ? "" : "edge lacks accepted evidence support",
2285
+ positive_contribution: positive,
2286
+ settled: false,
2287
+ status: positive ? "accepted" : "diagnostic"
2288
+ },
2289
+ edge_id: edgeId,
2290
+ evidence: {
2291
+ edge_certificate_refs: stringList(edge.edge_certificate_refs),
2292
+ evidence_refs: evidenceRefs,
2293
+ evidence_supported: evidenceSupported,
2294
+ missing_evidence: evidenceSupported ? [] : ["edge evidence refs required"],
2295
+ verifier_resolution_refs: stringList(edge.verifier_resolution_refs)
2296
+ },
2297
+ reasons: ["edge extracted from inert report data"],
2298
+ relation_type: String(
2299
+ edge.edge_type ?? edge.relation_type ?? "semantic-dependency"
2300
+ ),
2301
+ residual_summary: numericDict(event.residual_summary),
2302
+ settled: false,
2303
+ source_node_ids: sourceIds.length > 0 ? sourceIds : [String(node.node_id)],
2304
+ target_node_id: target
2305
+ });
2306
+ });
2307
+ });
2308
+ return edges;
2309
+ }
2310
+ function buildEffectivePacketGraph(input) {
2311
+ const events = Array.isArray(input) ? input : Array.isArray(input.events) ? input.events : [];
2312
+ const graphId = Array.isArray(input) ? "effective-packet-graph" : String(input.graph_id ?? "effective-packet-graph");
2313
+ const sourceWindowId = Array.isArray(input) ? "adhoc" : String(input.source_window_id ?? "adhoc");
2314
+ const normalized = events.map(
2315
+ (event, index) => event.event_id ? event : eventFromPayload(event, sourceWindowId, index, void 0, void 0)
2316
+ );
2317
+ const nodes = normalized.map(nodeFromEvent);
2318
+ const edges = edgesFromEvents(nodes, normalized);
2319
+ const nodeCountByStatus = {};
2320
+ for (const node of nodes) {
2321
+ const status = String(asRecord(node.contribution)?.status ?? "diagnostic");
2322
+ nodeCountByStatus[status] = (nodeCountByStatus[status] ?? 0) + 1;
2323
+ }
2324
+ const edgeCountByRelation = {};
2325
+ for (const edge of edges) {
2326
+ const relation = String(edge.relation_type ?? "semantic-dependency");
2327
+ edgeCountByRelation[relation] = (edgeCountByRelation[relation] ?? 0) + 1;
2328
+ }
2329
+ const mergedResidual = {};
2330
+ for (const node of nodes) {
2331
+ for (const [key, value2] of Object.entries(
2332
+ numericDict(node.residual_summary)
2333
+ )) {
2334
+ mergedResidual[key] = (mergedResidual[key] ?? 0) + value2;
2335
+ }
2336
+ }
2337
+ const acceptedPacketCapital = nodes.filter(
2338
+ (node) => asRecord(node.contribution)?.positive_contribution === true
2339
+ ).length;
2340
+ return {
2341
+ accepted: nodes.length > 0,
2342
+ accepted_packet_capital: acceptedPacketCapital,
2343
+ candidate_only_packets: nodes.filter(
2344
+ (node) => asRecord(node.contribution)?.candidate_only === true
2345
+ ).length,
2346
+ edge_count_by_relation: Object.fromEntries(
2347
+ Object.entries(edgeCountByRelation).sort()
2348
+ ),
2349
+ edges,
2350
+ graph_id: graphId,
2351
+ graph_safety_boundary: GRAPH_SAFETY,
2352
+ missing_edge_evidence: edges.filter(
2353
+ (edge) => edge.accepted === true && asRecord(edge.evidence)?.evidence_supported !== true
2354
+ ).map((edge) => String(edge.edge_id)),
2355
+ node_count_by_status: Object.fromEntries(
2356
+ Object.entries(nodeCountByStatus).sort()
2357
+ ),
2358
+ nodes,
2359
+ non_contributing_volume: nodes.filter(
2360
+ (node) => asRecord(node.contribution)?.positive_contribution !== true
2361
+ ).length,
2362
+ operationally_usable: acceptedPacketCapital > 0,
2363
+ reasons: [
2364
+ "effective graph separates positive contribution from diagnostic volume",
2365
+ "raw packet count does not increase positive phase metrics"
2366
+ ],
2367
+ rejected_or_quarantined_packets: nodes.filter(
2368
+ (node) => ["rejected", "quarantined"].includes(
2369
+ String(asRecord(node.contribution)?.status ?? "")
2370
+ )
2371
+ ).length,
2372
+ residual_summary: {
2373
+ candidate_only_reasons: dedupeSorted(
2374
+ normalized.flatMap((event) => stringList(event.candidate_only_reasons))
2375
+ ),
2376
+ missing_obligation_count: nodes.reduce(
2377
+ (total, node) => total + stringList(node.missing_obligations).length,
2378
+ 0
2379
+ ),
2380
+ residual_debt: residualDebt(mergedResidual),
2381
+ residual_summary: Object.fromEntries(
2382
+ Object.entries(mergedResidual).sort()
2383
+ ),
2384
+ settled_blockers: dedupeSorted(
2385
+ normalized.flatMap((event) => [
2386
+ ...stringList(event.settled_blockers),
2387
+ ...stringList(event.missing_obligations)
2388
+ ])
2389
+ )
2390
+ },
2391
+ semantic_edge_witnesses: edges.map((edge) => asRecord(edge.evidence)).filter(
2392
+ (evidence2) => Boolean(evidence2?.evidence_supported)
2393
+ ),
2394
+ settled: false,
2395
+ source_window_id: sourceWindowId,
2396
+ stale_or_unsafe_packets: nodes.filter(
2397
+ (node) => stringList(asRecord(node.eligibility)?.blockers).length > 0
2398
+ ).map((node) => String(node.node_id)),
2399
+ workflow_usable: true
2400
+ };
2401
+ }
2402
+ function positiveEdges(graph) {
2403
+ return asRecords(graph.edges).filter(
2404
+ (edge) => asRecord(edge.contribution)?.positive_contribution === true && asRecord(edge.evidence)?.evidence_supported === true
2405
+ );
2406
+ }
2407
+ function observePhaseWindow(window, events, graph) {
2408
+ const effectiveNodeCount = numeric(graph.accepted_packet_capital);
2409
+ const effectiveEdgeCount = positiveEdges(graph).length;
2410
+ const executionAvailablePathCount = detectExecutionAvailablePaths(graph).accepted_path_count;
2411
+ const closureWitnessCount = asRecords(
2412
+ detectAutocatalyticClosure(graph).closure_witnesses
2413
+ ).length;
2414
+ const total = Math.max(1, events.length);
2415
+ const acceptedPacketCount = events.filter(
2416
+ (event) => event.accepted === true
2417
+ ).length;
2418
+ const missingObligationCount = events.reduce(
2419
+ (sum, event) => sum + stringList(event.missing_obligations).length,
2420
+ 0
2421
+ );
2422
+ const residual = numeric(asRecord(graph.residual_summary)?.residual_debt);
2423
+ const candidateOnlyCount = events.filter(
2424
+ (event) => event.candidate_only === true
2425
+ ).length;
2426
+ const observation = {
2427
+ accepted: events.length > 0,
2428
+ accepted_packet_count: acceptedPacketCount,
2429
+ alt_certified_capital_count: events.filter(
2430
+ (event) => String(event.source_kind).includes("alt") && event.positive_contribution_allowed === true
2431
+ ).length,
2432
+ alt_liquidity_candidate_count: events.filter(
2433
+ (event) => String(event.source_kind).includes("alt")
2434
+ ).length,
2435
+ autocatalytic_closure_score: effectiveNodeCount > 0 ? closureWitnessCount / effectiveNodeCount : 0,
2436
+ basin_reachability_proxy: {
2437
+ effective_node_count: effectiveNodeCount,
2438
+ execution_available_path_count: executionAvailablePathCount,
2439
+ reachability_proxy: executionAvailablePathCount / Math.max(1, effectiveNodeCount)
2440
+ },
2441
+ bottleneck_count_by_type: Object.fromEntries(
2442
+ asRecords(graph.nodes).flatMap((node) => stringList(asRecord(node.eligibility)?.blockers)).reduce((map, blocker) => {
2443
+ map.set(blocker, (map.get(blocker) ?? 0) + 1);
2444
+ return map;
2445
+ }, /* @__PURE__ */ new Map()).entries()
2446
+ ),
2447
+ candidate_only_packet_count: candidateOnlyCount,
2448
+ closure_witness_count: closureWitnessCount,
2449
+ components: [
2450
+ {
2451
+ component: "accepted_packet_count",
2452
+ diagnostic_only: false,
2453
+ distance: 0,
2454
+ positive_contribution_source: "effective-graph-only",
2455
+ threshold: 0,
2456
+ value: acceptedPacketCount
2457
+ },
2458
+ {
2459
+ component: "raw_volume",
2460
+ diagnostic_only: true,
2461
+ distance: 0,
2462
+ positive_contribution_source: "diagnostic-only",
2463
+ threshold: 0,
2464
+ value: events.length
2465
+ }
2466
+ ],
2467
+ effective_edge_count: effectiveEdgeCount,
2468
+ effective_node_count: effectiveNodeCount,
2469
+ execution_available_path_count: executionAvailablePathCount,
2470
+ false_liquidity_load: {
2471
+ candidate_count: candidateOnlyCount,
2472
+ certified_count: 0,
2473
+ load: candidateOnlyCount / total
2474
+ },
2475
+ missing_obligation_count: missingObligationCount,
2476
+ observation_id: "phase-window-observation",
2477
+ operationally_usable: effectiveNodeCount > 0,
2478
+ oracle_truth_proven: false,
2479
+ packet_candidate_count: events.length,
2480
+ phase_gap_vector: {
2481
+ closure: Math.max(0, 1 - closureWitnessCount),
2482
+ effective_edges: Math.max(0, 1 - effectiveEdgeCount),
2483
+ effective_nodes: Math.max(0, 1 - effectiveNodeCount),
2484
+ execution_paths: Math.max(0, 1 - executionAvailablePathCount)
2485
+ },
2486
+ physical_truth_proven: false,
2487
+ proves_physical_or_oracle_truth: false,
2488
+ proves_real_asi: false,
2489
+ protocol_relative: true,
2490
+ protocol_relative_only: true,
2491
+ raw_external_volume_diagnostic_only: true,
2492
+ real_asi_proof: false,
2493
+ reasons: [
2494
+ "window observation is protocol-relative only",
2495
+ "raw external volume is diagnostic only"
2496
+ ],
2497
+ residual_debt: residual,
2498
+ salience_obstruction_load: {
2499
+ blocked_count: candidateOnlyCount,
2500
+ load: candidateOnlyCount / total,
2501
+ total_count: events.length
2502
+ },
2503
+ settled: false,
2504
+ settled_packet_count: 0,
2505
+ threshold_distance: Math.max(0, 1 - effectiveNodeCount) + Math.max(0, 1 - effectiveEdgeCount) + Math.max(0, 1 - closureWitnessCount) + Math.max(0, 1 - executionAvailablePathCount),
2506
+ verification_backlog: missingObligationCount,
2507
+ verification_throughput: {
2508
+ accepted_count: acceptedPacketCount,
2509
+ backlog_count: missingObligationCount,
2510
+ throughput_ratio: acceptedPacketCount / total
2511
+ },
2512
+ waste_load: {
2513
+ load: numeric(graph.non_contributing_volume) / total,
2514
+ non_contributing_volume: numeric(graph.non_contributing_volume),
2515
+ total_volume: events.length
2516
+ },
2517
+ window: {
2518
+ event_count: numeric(window.event_count),
2519
+ event_ids: stringList(window.event_ids),
2520
+ sequence: numeric(window.sequence),
2521
+ window_id: String(window.window_id ?? "phase-window")
2522
+ },
2523
+ workflow_usable: true,
2524
+ workflow_usable_packet_count: events.filter(
2525
+ (event) => event.workflow_usable === true
2526
+ ).length
2527
+ };
2528
+ return observation;
2529
+ }
2530
+ function comparePhaseWindows(baseline, candidate) {
2531
+ const metricDelta = {
2532
+ closure_witness_count: numeric(candidate.closure_witness_count) - numeric(baseline.closure_witness_count),
2533
+ effective_edge_count: numeric(candidate.effective_edge_count) - numeric(baseline.effective_edge_count),
2534
+ effective_node_count: numeric(candidate.effective_node_count) - numeric(baseline.effective_node_count),
2535
+ execution_available_path_count: numeric(candidate.execution_available_path_count) - numeric(baseline.execution_available_path_count),
2536
+ residual_debt: numeric(candidate.residual_debt) - numeric(baseline.residual_debt)
2537
+ };
2538
+ return {
2539
+ accepted: true,
2540
+ baseline_window_id: String(asRecord(baseline.window)?.window_id ?? ""),
2541
+ candidate_window_id: String(asRecord(candidate.window)?.window_id ?? ""),
2542
+ comparison_id: "phase-window-comparison",
2543
+ diagnostic_only_components: ["packet_candidate_count", "raw_volume"],
2544
+ metric_delta: metricDelta,
2545
+ positive_progress_components: Object.entries(metricDelta).filter(([key, value2]) => key !== "residual_debt" && value2 > 0).map(([key]) => key),
2546
+ reasons: ["comparison preserves protocol-relative diagnostic status"],
2547
+ settled: false,
2548
+ workflow_usable: true
2549
+ };
2550
+ }
2551
+ function detectAutocatalyticClosure(graph) {
2552
+ const closureWitnesses = [];
2553
+ const defects = [];
2554
+ for (const edge of positiveEdges(graph)) {
2555
+ const sources = stringList(edge.source_node_ids);
2556
+ const target = String(edge.target_node_id ?? "");
2557
+ if (sources.includes(target)) {
2558
+ const witnessId = `closure-witness:${String(edge.edge_id)}`;
2559
+ closureWitnesses.push({
2560
+ accepted: true,
2561
+ edge_ids: [String(edge.edge_id)],
2562
+ evidence_supported: true,
2563
+ execution_available: false,
2564
+ packet_ids: dedupeSorted([...sources, target]),
2565
+ productive: true,
2566
+ protocol_relative_only: true,
2567
+ reasons: [
2568
+ "witness is evidence-supported within the effective graph",
2569
+ "witness remains diagnostic until finite threshold checks pass"
2570
+ ],
2571
+ settled: false,
2572
+ witness_id: witnessId,
2573
+ witness_kind: "autocatalytic-closure"
2574
+ });
2575
+ }
2576
+ }
2577
+ for (const edge of asRecords(graph.edges)) {
2578
+ if (edge.accepted === true && asRecord(edge.evidence)?.evidence_supported !== true) {
2579
+ defects.push({
2580
+ defect_id: `closure-defect:${String(edge.edge_id)}`,
2581
+ defect_type: "missing-edge-evidence",
2582
+ packet_or_edge_id: String(edge.edge_id),
2583
+ residual_preserved: true
2584
+ });
2585
+ }
2586
+ }
2587
+ const status = closureWitnesses.length > 0 && defects.length === 0 ? "candidate" : "abstain";
2588
+ return {
2589
+ accepted: status === "candidate",
2590
+ certificate_candidate: {
2591
+ abstention_reasons: closureWitnesses.length > 0 ? [] : [
2592
+ {
2593
+ missing_evidence_refs: [],
2594
+ reason: "closure requires evidence-supported accepted edges",
2595
+ reason_id: "closure-abstain:no-evidence-supported-cycle"
2596
+ }
2597
+ ],
2598
+ accepted: status === "candidate",
2599
+ certificate_id: "closure-certificate-candidate",
2600
+ certificate_status: status,
2601
+ defects,
2602
+ reasons: [
2603
+ "closure candidate is not automatically settled",
2604
+ "candidate-only cycles do not count"
2605
+ ],
2606
+ settled: false,
2607
+ witness_ids: closureWitnesses.map(
2608
+ (witness) => String(witness.witness_id)
2609
+ )
2610
+ },
2611
+ closure_score: closureWitnesses.length / Math.max(1, asRecords(graph.nodes).length),
2612
+ closure_witnesses: closureWitnesses,
2613
+ defects,
2614
+ executable_witnesses: [],
2615
+ graph_id: String(graph.graph_id ?? "effective-packet-graph"),
2616
+ operationally_usable: status === "candidate",
2617
+ productive_witnesses: closureWitnesses.map((witness) => ({
2618
+ accepted: true,
2619
+ packet_ids: witness.packet_ids,
2620
+ productive_edge_ids: witness.edge_ids,
2621
+ productivity_lower_bound: 0.1,
2622
+ reasons: [
2623
+ "self-supporting evidence edge is productive in declared scope"
2624
+ ],
2625
+ settled: false,
2626
+ witness_id: `productive:${String(witness.witness_id)}`
2627
+ })),
2628
+ reasons: ["closure detection does not execute or settle paths"],
2629
+ report_id: "autocatalytic-closure-report",
2630
+ settled: false,
2631
+ support_hyperpaths: [],
2632
+ workflow_usable: true
2633
+ };
2634
+ }
2635
+ function detectExecutionAvailablePaths(graph) {
2636
+ const paths = positiveEdges(graph).map((edge) => {
2637
+ const pathId = `execution-path:${String(edge.edge_id)}`;
2638
+ const reasons = [
2639
+ "execution authority is not granted by PIC-TS",
2640
+ "receiver context and action boundary remain diagnostic"
2641
+ ];
2642
+ return {
2643
+ accepted: false,
2644
+ action_boundary_requirements: [
2645
+ {
2646
+ requirement_id: `${pathId}:authority`,
2647
+ requirement_type: "explicit-scope-bounded-authority",
2648
+ residual: "host runtime authority required",
2649
+ satisfied: false
2650
+ }
2651
+ ],
2652
+ authority_status: {
2653
+ authority_status: "not-granted",
2654
+ explicit_scope_bounded: false,
2655
+ grants_execution: false,
2656
+ reasons
2657
+ },
2658
+ blocked: true,
2659
+ candidate_only: true,
2660
+ edge_ids: [String(edge.edge_id)],
2661
+ not_executed: true,
2662
+ packet_ids: dedupeSorted([
2663
+ ...stringList(edge.source_node_ids),
2664
+ String(edge.target_node_id ?? "")
2665
+ ]),
2666
+ path_id: pathId,
2667
+ reasons,
2668
+ receiver_context: {
2669
+ evidence_refs: [],
2670
+ present: false,
2671
+ receiver_context_id: "receiver-context:missing"
2672
+ },
2673
+ settled: false,
2674
+ witness: {
2675
+ accepted: false,
2676
+ edge_ids: [String(edge.edge_id)],
2677
+ packet_ids: dedupeSorted([
2678
+ ...stringList(edge.source_node_ids),
2679
+ String(edge.target_node_id ?? "")
2680
+ ]),
2681
+ reasons,
2682
+ settled: false,
2683
+ witness_id: `execution-witness:${String(edge.edge_id)}`
2684
+ }
2685
+ };
2686
+ });
2687
+ return {
2688
+ accepted: paths.length > 0,
2689
+ accepted_path_count: 0,
2690
+ authority_requirements: ["explicit-scope-bounded-authority"],
2691
+ blocked_path_count: paths.length,
2692
+ blocker_reason_by_path: Object.fromEntries(
2693
+ paths.map((path) => [String(path.path_id), stringList(path.reasons)])
2694
+ ),
2695
+ candidate_only_path_count: paths.length,
2696
+ executed_path_count: 0,
2697
+ execution_authority_granted: false,
2698
+ graph_id: String(graph.graph_id ?? "effective-packet-graph"),
2699
+ operationally_usable: false,
2700
+ path_count: paths.length,
2701
+ path_density: 0,
2702
+ paths,
2703
+ reasons: ["execution-available path detection never executes paths"],
2704
+ report_id: "execution-available-path-density",
2705
+ residual_carry_forward: stringList(
2706
+ asRecord(graph.residual_summary)?.settled_blockers
2707
+ ),
2708
+ rollback_requirements: ["rollback-or-safe-abort"],
2709
+ settled: false,
2710
+ workflow_usable: true
2711
+ };
2712
+ }
2713
+ function buildPhaseThresholdStatus(observation, threshold) {
2714
+ const pathDensity = numeric(
2715
+ asRecord(observation.basin_reachability_proxy)?.reachability_proxy
2716
+ );
2717
+ const checks = {
2718
+ maximum_false_liquidity_load: numeric(asRecord(observation.false_liquidity_load)?.load) <= numeric(threshold.maximum_false_liquidity_load ?? 0.5),
2719
+ maximum_residual_debt: numeric(observation.residual_debt) <= numeric(threshold.maximum_residual_debt ?? 0),
2720
+ maximum_salience_obstruction: numeric(asRecord(observation.salience_obstruction_load)?.load) <= numeric(threshold.maximum_salience_obstruction ?? 0.5),
2721
+ minimum_accepted_packet_count: numeric(observation.accepted_packet_count) >= numeric(threshold.minimum_accepted_packet_count ?? 1),
2722
+ minimum_alt_to_ecpt_lift_count: numeric(observation.alt_certified_capital_count) >= numeric(threshold.minimum_alt_to_ecpt_lift_count ?? 0),
2723
+ minimum_closure_witness_count: numeric(observation.closure_witness_count) >= numeric(threshold.minimum_closure_witness_count ?? 1),
2724
+ minimum_effective_edge_count: numeric(observation.effective_edge_count) >= numeric(threshold.minimum_effective_edge_count ?? 1),
2725
+ minimum_execution_available_path_density: pathDensity >= numeric(threshold.minimum_execution_available_path_density ?? 0.1),
2726
+ minimum_verification_throughput: numeric(
2727
+ asRecord(observation.verification_throughput)?.throughput_ratio
2728
+ ) >= numeric(threshold.minimum_verification_throughput ?? 0.1)
2729
+ };
2730
+ const failed = Object.entries(checks).filter(([, passed]) => !passed).map(([key]) => key).sort();
2731
+ const status = failed.length === 0 ? "candidate" : "abstain";
2732
+ return {
2733
+ accepted: status === "candidate",
2734
+ abstention_reasons: failed.map(
2735
+ (component) => `missing finite threshold component: ${component}`
2736
+ ),
2737
+ certificate_status: status,
2738
+ component_status: Object.fromEntries(Object.entries(checks).sort()),
2739
+ failed_components: failed,
2740
+ oracle_truth_proven: false,
2741
+ physical_truth_proven: false,
2742
+ protocol_relative: true,
2743
+ protocol_relative_only: true,
2744
+ real_asi_proof: false,
2745
+ reasons: [
2746
+ "threshold status is protocol-relative only",
2747
+ "threshold status does not prove real ASI"
2748
+ ],
2749
+ rejection_reasons: [],
2750
+ settled: false,
2751
+ status_id: "asi-proxy-threshold-status",
2752
+ threshold,
2753
+ threshold_distance: failed.length,
2754
+ observation
2755
+ };
2756
+ }
2757
+ function buildCollectivePhaseCertificateCandidate(thresholdStatus, graph) {
2758
+ const status = String(thresholdStatus.certificate_status ?? "abstain");
2759
+ const defects = stringList(thresholdStatus.failed_components).map(
2760
+ (component) => ({
2761
+ component,
2762
+ defect_id: `phase-defect:${component}`,
2763
+ defect_type: "threshold-component-missing",
2764
+ required_remediation: `provide finite evidence for ${component}`,
2765
+ residual_preserved: true
2766
+ })
2767
+ );
2768
+ return {
2769
+ accepted: status === "candidate",
2770
+ abstention_report: status === "candidate" ? null : {
2771
+ defects,
2772
+ protocol_relative_only: true,
2773
+ reasons: ["certificate abstains when finite evidence is missing"],
2774
+ report_id: "collective-phase-abstention",
2775
+ settled: false,
2776
+ threshold_status: thresholdStatus
2777
+ },
2778
+ certificate_id: "collective-phase-certificate-candidate",
2779
+ certificate_status: status,
2780
+ defects,
2781
+ execution_authority_granted: false,
2782
+ finite_requirements_passed: status === "candidate",
2783
+ graph_id: String(graph.graph_id ?? ""),
2784
+ observation_id: String(
2785
+ asRecord(thresholdStatus.observation)?.observation_id ?? ""
2786
+ ),
2787
+ operationally_usable: status === "candidate",
2788
+ oracle_truth_proven: false,
2789
+ physical_truth_proven: false,
2790
+ protocol_relative_only: true,
2791
+ proves_physical_or_oracle_truth: false,
2792
+ proves_real_asi: false,
2793
+ reasons: [
2794
+ "certificate candidate is protocol-relative only",
2795
+ "certificate candidate does not prove real ASI",
2796
+ "certificate candidate does not settle diagnostic reports"
2797
+ ],
2798
+ settled: false,
2799
+ threshold_status: thresholdStatus,
2800
+ workflow_usable: true
2801
+ };
2802
+ }
2803
+ function loadPhaseLabObservation(storeDir, window = "latest") {
2804
+ const selected = selectWindow(storeDir, window);
2805
+ const graph = buildEffectivePacketGraph({
2806
+ events: selected.events,
2807
+ graph_id: `effective-graph:${String(selected.index.window_id ?? "window")}`,
2808
+ source_window_id: String(selected.index.window_id ?? "window")
2809
+ });
2810
+ return {
2811
+ observation: observePhaseWindow(selected.index, selected.events, graph),
2812
+ graph
2813
+ };
2814
+ }
2815
+ function loadPhaseLabGraph(storeDir, window = "all") {
2816
+ const selected = selectWindow(storeDir, window);
2817
+ return buildEffectivePacketGraph({
2818
+ events: selected.events,
2819
+ graph_id: `effective-graph:${String(selected.index.window_id ?? "window")}`,
2820
+ source_window_id: String(selected.index.window_id ?? "window")
2821
+ });
2822
+ }
2823
+ function exportPhaseLabStore(storeDir, outputDir) {
2824
+ mkdirSync3(outputDir, { recursive: true });
2825
+ const manifest = writeManifest(storeDir);
2826
+ const events = readEvents(storeDir);
2827
+ const graph = buildEffectivePacketGraph({
2828
+ events,
2829
+ graph_id: "phase-lab-export-effective-graph",
2830
+ source_window_id: String(manifest.latest_window_id ?? "adhoc")
2831
+ });
2832
+ const files = [];
2833
+ const write = (name, data) => {
2834
+ writeJson(join4(outputDir, name), data);
2835
+ files.push(name);
2836
+ };
2837
+ write("manifest.json", manifest);
2838
+ write("events.json", {
2839
+ absolute_paths_sanitized: true,
2840
+ events,
2841
+ settled: false
2842
+ });
2843
+ write("effective_graph.json", graph);
2844
+ write("windows.json", {
2845
+ settled: false,
2846
+ windows: readWindowIndexes(storeDir)
2847
+ });
2848
+ if (events.length > 0) {
2849
+ const { observation } = loadPhaseLabObservation(storeDir, "latest");
2850
+ write("phase_window_observation.json", observation);
2851
+ }
2852
+ return {
2853
+ accepted: true,
2854
+ absolute_paths_sanitized: true,
2855
+ export_id: "phase-lab-export",
2856
+ files: files.sort(),
2857
+ output_dir: basename2(outputDir),
2858
+ reasons: ["phase lab export sanitizes local paths and preserves residuals"],
2859
+ settled: false,
2860
+ store_manifest: manifest
2861
+ };
2862
+ }
2863
+
2864
+ // src/render/markdown.ts
2865
+ import { mkdirSync as mkdirSync4, writeFileSync as writeFileSync4 } from "fs";
2866
+ import { dirname as dirname4 } from "path";
2867
+ function lang(language) {
2868
+ return language?.toLowerCase().startsWith("ja") ? "ja" : "en";
2869
+ }
2870
+ function value(data, key) {
2871
+ const raw = data[key];
2872
+ if (raw === void 0 || raw === null) {
2873
+ return "not-recorded";
2874
+ }
2875
+ if (typeof raw === "string" || typeof raw === "number") {
2876
+ return String(raw);
2877
+ }
2878
+ if (typeof raw === "boolean") {
2879
+ return raw ? "true" : "false";
2880
+ }
2881
+ return JSON.stringify(raw);
2882
+ }
2883
+ function count(data, key) {
2884
+ const raw = data[key];
2885
+ if (Array.isArray(raw)) {
2886
+ return raw.length;
2887
+ }
2888
+ if (raw && typeof raw === "object") {
2889
+ return Object.keys(raw).length;
2890
+ }
2891
+ return 0;
2892
+ }
2893
+ function boolRows(data, keys) {
2894
+ return keys.map((key) => `- \`${key}\`: ${value(data, key)}`).join("\n");
2895
+ }
2896
+ function safetyBoundary(language) {
2897
+ if (lang(language) === "ja") {
2898
+ return [
2899
+ "## \u5B89\u5168\u5883\u754C",
2900
+ "",
2901
+ "- \u3053\u308C\u306F\u5B9F\u884C\u6A29\u9650\u3067\u306F\u3042\u308A\u307E\u305B\u3093\u3002",
2902
+ "- \u5B9F ASI\u3001\u7269\u7406\u7D50\u679C\u3001\u5916\u90E8\u30AA\u30E9\u30AF\u30EB\u306E\u771F\u7406\u3092\u8A3C\u660E\u3057\u307E\u305B\u3093\u3002",
2903
+ "- `settled=false` \u306F\u672A\u89E3\u6C7A\u306E\u78BA\u8A8D\u4E8B\u9805\u304C\u898B\u3048\u308B\u72B6\u614B\u3067\u6B8B\u308B\u3053\u3068\u3092\u610F\u5473\u3057\u307E\u3059\u3002",
2904
+ "- packet \u306E\u5185\u5BB9\u3068 `safe_commands` \u306F\u691C\u67FB\u7528\u30C7\u30FC\u30BF\u3067\u3042\u308A\u3001\u81EA\u52D5\u5B9F\u884C\u3055\u308C\u307E\u305B\u3093\u3002"
2905
+ ].join("\n");
2906
+ }
2907
+ return [
2908
+ "## Safety Boundary",
2909
+ "",
2910
+ "- This is not execution authority.",
2911
+ "- This is not proof of real ASI, physical truth, or oracle truth.",
2912
+ "- `settled=false` means unresolved obligations remain visible.",
2913
+ "- Packet content and `safe_commands` are inspection data, not automatic actions."
2914
+ ].join("\n");
2915
+ }
2916
+ function writeTextOutput(text, outputPath) {
2917
+ const finalText = text.endsWith("\n") ? text : `${text}
2918
+ `;
2919
+ if (outputPath) {
2920
+ mkdirSync4(dirname4(outputPath), { recursive: true });
2921
+ writeFileSync4(outputPath, finalText, "utf8");
2922
+ } else {
2923
+ process.stdout.write(finalText);
2924
+ }
2925
+ }
2926
+ function renderAdoptionPacketMarkdown(data, language) {
2927
+ if (lang(language) === "ja") {
2928
+ return [
2929
+ "# \u30AA\u30DA\u30EC\u30FC\u30BF\u30FC\u63A1\u7528\u30D1\u30B1\u30C3\u30C8",
2930
+ "",
2931
+ "PIC-TS \u306F Node.js \u3067 AI agent \u306E\u51FA\u529B\u3092 JSON \u3068\u3057\u3066\u691C\u67FB\u3057\u3001\u672A\u89E3\u6C7A\u306E\u78BA\u8A8D\u4E8B\u9805\u3092\u96A0\u3055\u305A\u6B8B\u3057\u307E\u3059\u3002",
2932
+ "",
2933
+ "## \u6700\u521D\u306E\u30B3\u30DE\u30F3\u30C9",
2934
+ "",
2935
+ "```sh",
2936
+ "npm install percolation-inversion-compiler-ts",
2937
+ "npx pic-ts agent check --compact",
2938
+ "```",
2939
+ "",
2940
+ "## \u72B6\u614B\u306E\u8AAD\u307F\u65B9",
2941
+ "",
2942
+ boolRows(data, ["accepted", "workflow_usable", "settled"]),
2943
+ "- `residual_ledger`: \u6B8B\u3063\u3066\u3044\u308B\u78BA\u8A8D\u4F5C\u696D\u306E\u53F0\u5E33\u3067\u3059\u3002",
2944
+ "- `safe_commands`: \u30AA\u30DA\u30EC\u30FC\u30BF\u30FC\u304C\u78BA\u8A8D\u3059\u308B\u305F\u3081\u306E\u5019\u88DC\u3067\u3042\u308A\u3001\u81EA\u52D5\u5B9F\u884C\u6A29\u9650\u3067\u306F\u3042\u308A\u307E\u305B\u3093\u3002",
2945
+ "",
2946
+ "## \u30EC\u30D3\u30E5\u30FC\u30C1\u30A7\u30C3\u30AF",
2947
+ "",
2948
+ "- packet \u3092\u4E3B workflow \u306E gate \u3068\u3057\u3066\u6271\u308F\u306A\u3044\u3002",
2949
+ "- \u672A\u89E3\u6C7A obligation \u3092 `settled=true` \u306B\u6607\u683C\u3057\u306A\u3044\u3002",
2950
+ "",
2951
+ safetyBoundary(language)
2952
+ ].join("\n");
2953
+ }
2954
+ return [
2955
+ "# Operator Adoption Packet",
2956
+ "",
2957
+ "PIC-TS checks AI agent output for Node.js workflows and keeps unfinished verification work visible.",
2958
+ "",
2959
+ "## First Commands",
2960
+ "",
2961
+ "```sh",
2962
+ "npm install percolation-inversion-compiler-ts",
2963
+ "npx pic-ts agent check --compact",
2964
+ "```",
2965
+ "",
2966
+ "## How To Read The Report",
2967
+ "",
2968
+ boolRows(data, ["accepted", "workflow_usable", "settled"]),
2969
+ "- `residual_ledger`: remaining verification work that must stay visible.",
2970
+ "- `safe_commands`: inspection hints for an operator, not permission to run actions.",
2971
+ "",
2972
+ "## Operator Review Checklist",
2973
+ "",
2974
+ "- Confirm adoption sidecars do not gate the main workflow.",
2975
+ "- Confirm unresolved obligations are not promoted to settlement.",
2976
+ "",
2977
+ safetyBoundary(language)
2978
+ ].join("\n");
2979
+ }
2980
+ function renderAdoptionRequestMarkdown(data, language) {
2981
+ if (lang(language) === "ja") {
2982
+ return [
2983
+ "# Agent \u304B\u3089 Operator \u3078\u306E\u30EA\u30AF\u30A8\u30B9\u30C8",
2984
+ "",
1626
2985
  "agent \u306F PIC-TS \u3092\u898B\u3064\u3051\u307E\u3057\u305F\u304C\u3001install \u3084 tool \u5B9F\u884C\u306E\u6A29\u9650\u306F operator \u306E\u78BA\u8A8D\u304C\u5FC5\u8981\u3067\u3059\u3002",
1627
2986
  "",
1628
2987
  "## \u4F9D\u983C",
@@ -1796,19 +3155,154 @@ function buildSalienceSchedule(profile = "production") {
1796
3155
  return report;
1797
3156
  }
1798
3157
 
3158
+ // src/sqot_controller/index.ts
3159
+ function record3(value2) {
3160
+ return value2 && typeof value2 === "object" && !Array.isArray(value2) ? value2 : void 0;
3161
+ }
3162
+ function records3(value2) {
3163
+ return Array.isArray(value2) ? value2.filter((item) => Boolean(record3(item))) : [];
3164
+ }
3165
+ function strings2(value2) {
3166
+ if (Array.isArray(value2)) return value2.map(String).sort();
3167
+ if (value2 === void 0 || value2 === null) return [];
3168
+ return [String(value2)];
3169
+ }
3170
+ function graphNodes(graph) {
3171
+ return records3(graph.nodes);
3172
+ }
3173
+ function candidateNodes(graph) {
3174
+ return graphNodes(graph).filter(
3175
+ (node) => record3(node.contribution)?.positive_contribution !== true
3176
+ );
3177
+ }
3178
+ function diagnoseQueueOccupation(graph, attentionBudget = 1) {
3179
+ const nodes = graphNodes(graph);
3180
+ const candidates = candidateNodes(graph);
3181
+ const occupied = nodes.length === 0 ? 0 : candidates.length / nodes.length;
3182
+ return {
3183
+ accepted: true,
3184
+ attention_budget_ledger: {
3185
+ attention_budget: attentionBudget,
3186
+ occupied,
3187
+ occupied_by_candidate_only: candidates.length,
3188
+ settled: false
3189
+ },
3190
+ candidate_only_count: candidates.length,
3191
+ execution_authority_granted: false,
3192
+ graph_id: String(graph.graph_id ?? ""),
3193
+ queue_occupation: occupied,
3194
+ report_id: "queue-occupation-report",
3195
+ settled: false,
3196
+ verification_queue_pressure: {
3197
+ missing_obligation_count: Number(
3198
+ record3(graph.residual_summary)?.missing_obligation_count ?? 0
3199
+ ),
3200
+ pressure: occupied,
3201
+ settled: false
3202
+ },
3203
+ workflow_usable: true
3204
+ };
3205
+ }
3206
+ function diagnoseSalienceObstruction(graph) {
3207
+ const blocked = graphNodes(graph).filter(
3208
+ (node) => strings2(record3(node.eligibility)?.blockers).some(
3209
+ (blocker) => [
3210
+ "candidate-only",
3211
+ "salience-obstruction",
3212
+ "stale",
3213
+ "raw-external-volume"
3214
+ ].includes(blocker)
3215
+ )
3216
+ );
3217
+ return {
3218
+ accepted: true,
3219
+ blocked_packet_ids: blocked.map((node) => String(node.node_id)),
3220
+ execution_authority_granted: false,
3221
+ graph_id: String(graph.graph_id ?? ""),
3222
+ obstruction_count: blocked.length,
3223
+ reasons: [
3224
+ "salience obstruction is diagnostic and does not mutate queue state"
3225
+ ],
3226
+ report_id: "salience-obstruction-diagnosis",
3227
+ settled: false,
3228
+ workflow_usable: true
3229
+ };
3230
+ }
3231
+ function buildQueueRebalancePlan(graph) {
3232
+ const actions = graphNodes(graph).map((node) => {
3233
+ const blockers = strings2(record3(node.eligibility)?.blockers);
3234
+ const action = blockers.length > 0 ? "preserve_residual" : "inspect";
3235
+ return {
3236
+ action,
3237
+ applied: false,
3238
+ deletes_packet: false,
3239
+ node_id: String(node.node_id ?? ""),
3240
+ reasons: blockers,
3241
+ settled: false
3242
+ };
3243
+ });
3244
+ return {
3245
+ accepted: true,
3246
+ actions,
3247
+ applied_action_count: 0,
3248
+ execution_authority_granted: false,
3249
+ graph_id: String(graph.graph_id ?? ""),
3250
+ plan_id: "queue-rebalance-plan",
3251
+ recommended_action_count: actions.length,
3252
+ settled: false,
3253
+ workflow_usable: true
3254
+ };
3255
+ }
3256
+ function buildPacketQuarantineDecisions(graph) {
3257
+ const decisions = candidateNodes(graph).map((node) => ({
3258
+ applied: false,
3259
+ decision: "quarantine",
3260
+ deletes_packet: false,
3261
+ node_id: String(node.node_id ?? ""),
3262
+ reasons: strings2(record3(node.eligibility)?.blockers),
3263
+ reversible: true,
3264
+ settled: false
3265
+ }));
3266
+ return {
3267
+ accepted: true,
3268
+ applied: false,
3269
+ deletes_packets: false,
3270
+ execution_authority_granted: false,
3271
+ quarantine_decisions: decisions,
3272
+ settled: false,
3273
+ workflow_usable: true
3274
+ };
3275
+ }
3276
+ function checkDiagnosticReserve(graph, attentionBudget = 1) {
3277
+ const queue = diagnoseQueueOccupation(graph, attentionBudget);
3278
+ const occupied = Number(queue.queue_occupation ?? 0);
3279
+ const reserveFraction = Math.max(0, 1 - occupied);
3280
+ return {
3281
+ accepted: true,
3282
+ diagnostic_reserve_available: reserveFraction > 0.1,
3283
+ execution_authority_granted: false,
3284
+ minimum_reserve_fraction: 0.1,
3285
+ reasons: reserveFraction > 0.1 ? ["diagnostic reserve remains available"] : ["diagnostic reserve is below threshold"],
3286
+ report_id: "diagnostic-reserve-report",
3287
+ reserve_fraction: reserveFraction,
3288
+ settled: false,
3289
+ workflow_usable: true
3290
+ };
3291
+ }
3292
+
1799
3293
  // src/trc/index.ts
1800
- import { readFileSync as readFileSync8 } from "fs";
3294
+ import { readFileSync as readFileSync9 } from "fs";
1801
3295
  function compileTrc(options = {}) {
1802
- let records = [];
3296
+ let records5 = [];
1803
3297
  const reasons = [];
1804
3298
  if (options.recordsPath) {
1805
3299
  const parsed = JSON.parse(
1806
- readFileSync8(options.recordsPath, "utf8")
3300
+ readFileSync9(options.recordsPath, "utf8")
1807
3301
  );
1808
- records = Array.isArray(parsed) ? parsed : Array.isArray(parsed.records) ? parsed.records : [];
3302
+ records5 = Array.isArray(parsed) ? parsed : Array.isArray(parsed.records) ? parsed.records : [];
1809
3303
  }
1810
- const invalidMainTrace = records.some((record) => {
1811
- const obj = record;
3304
+ const invalidMainTrace = records5.some((record5) => {
3305
+ const obj = record5;
1812
3306
  return obj.stratum === "main" && !obj.trace_id && !obj.trace;
1813
3307
  });
1814
3308
  if (invalidMainTrace) {
@@ -1822,7 +3316,7 @@ function compileTrc(options = {}) {
1822
3316
  accepted,
1823
3317
  operationally_usable: accepted && !invalidMainTrace,
1824
3318
  settled: false,
1825
- main_frontier_count: invalidMainTrace ? 0 : records.length,
3319
+ main_frontier_count: invalidMainTrace ? 0 : records5.length,
1826
3320
  diagnostic_count: invalidMainTrace ? 1 : 0,
1827
3321
  residual_ledger: invalidMainTrace ? {
1828
3322
  coordinates: {
@@ -1839,13 +3333,95 @@ function compileTrc(options = {}) {
1839
3333
  };
1840
3334
  }
1841
3335
 
3336
+ // src/trc_adapter/index.ts
3337
+ function record4(value2) {
3338
+ return value2 && typeof value2 === "object" && !Array.isArray(value2) ? value2 : void 0;
3339
+ }
3340
+ function records4(value2) {
3341
+ return Array.isArray(value2) ? value2.filter((item) => Boolean(record4(item))) : [];
3342
+ }
3343
+ function eventsFromTrace(input) {
3344
+ return records4(input.events).length > 0 ? records4(input.events) : records4(input.tool_calls).length > 0 ? records4(input.tool_calls) : [input];
3345
+ }
3346
+ function adaptTrcTrace(input) {
3347
+ const events = eventsFromTrace(input);
3348
+ const typedEvents = events.map((event, index) => ({
3349
+ action_kind: String(
3350
+ event.action_kind ?? event.type ?? event.name ?? "agent-event"
3351
+ ),
3352
+ authority_status: String(event.authority_status ?? "not-granted"),
3353
+ event_id: String(event.event_id ?? `trace-event:${index}`),
3354
+ evidence_refs: Array.isArray(event.evidence_refs) ? event.evidence_refs.map(String) : [],
3355
+ receiver: String(
3356
+ event.receiver ?? event.receiver_agent_id ?? "unknown-receiver"
3357
+ ),
3358
+ rollback_status: String(event.rollback_status ?? "unknown"),
3359
+ source: String(event.source ?? event.sender ?? "unknown-source"),
3360
+ settled: false
3361
+ }));
3362
+ return {
3363
+ accepted: true,
3364
+ executed_action_count: 0,
3365
+ execution_authority_granted: false,
3366
+ frontier_debt: {
3367
+ missing_physical_or_oracle_obligations: [
3368
+ "physical execution evidence",
3369
+ "oracle truth evidence"
3370
+ ],
3371
+ settled: false
3372
+ },
3373
+ normal_form: {
3374
+ event_count: typedEvents.length,
3375
+ normal_form_id: "trace-normal-form",
3376
+ settled: false
3377
+ },
3378
+ physical_truth_proven: false,
3379
+ reasons: ["trace content is typed data, not instruction"],
3380
+ report_id: "trace-adapter-report",
3381
+ settled: false,
3382
+ tolerance_ledger: {
3383
+ residual_tolerance: 1,
3384
+ settled: false
3385
+ },
3386
+ typed_trace: {
3387
+ events: typedEvents,
3388
+ trace_id: String(input.trace_id ?? "typed-agent-trace")
3389
+ },
3390
+ workflow_usable: true
3391
+ };
3392
+ }
3393
+ function adaptToolTrace(input) {
3394
+ const events = Array.isArray(input) ? input : eventsFromTrace(input);
3395
+ return adaptTrcTrace({ events, trace_id: "typed-tool-call-trace" });
3396
+ }
3397
+ function buildActionBoundaryReport(runtimeReport) {
3398
+ const commits = records4(runtimeReport.action_commits);
3399
+ return {
3400
+ accepted: runtimeReport.accepted === true,
3401
+ action_boundaries: commits.map((commit, index) => ({
3402
+ action_id: String(commit.action_id ?? `action:${index}`),
3403
+ authority_status: "not-granted",
3404
+ execution_authority_granted: false,
3405
+ rollback_required: true,
3406
+ settled: false
3407
+ })),
3408
+ executed_action_count: 0,
3409
+ execution_authority_granted: false,
3410
+ physical_truth_proven: false,
3411
+ reasons: ["runtime action boundaries are diagnostic and non-executing"],
3412
+ report_id: "action-boundary-report",
3413
+ settled: false,
3414
+ workflow_usable: runtimeReport.accepted === true
3415
+ };
3416
+ }
3417
+
1842
3418
  // src/cli/main.ts
1843
- var VERSION = "0.4.5";
3419
+ var VERSION = "0.5.0";
1844
3420
  function outputJson(data, output) {
1845
3421
  const text = stableStringify(data);
1846
3422
  if (output) {
1847
- mkdirSync4(dirname5(output), { recursive: true });
1848
- writeFileSync4(output, text, "utf8");
3423
+ mkdirSync5(dirname5(output), { recursive: true });
3424
+ writeFileSync5(output, text, "utf8");
1849
3425
  } else {
1850
3426
  process.stdout.write(text);
1851
3427
  }
@@ -1858,7 +3434,7 @@ function readText(options, fallback = "Candidate packet: preserve residuals.") {
1858
3434
  return options.text;
1859
3435
  }
1860
3436
  if (typeof options.textFile === "string") {
1861
- return readFileSync9(options.textFile, "utf8");
3437
+ return readFileSync10(options.textFile, "utf8");
1862
3438
  }
1863
3439
  return fallback;
1864
3440
  }
@@ -1928,7 +3504,19 @@ function boolOptionOrRequest(optionValue, requestValue) {
1928
3504
  return typeof optionValue === "boolean" ? optionValue : void 0;
1929
3505
  }
1930
3506
  function readPhaseRequest(path) {
1931
- return parseJsonObject(readFileSync9(path, "utf8"), "phase request");
3507
+ return parseJsonObject(readFileSync10(path, "utf8"), "phase request");
3508
+ }
3509
+ function readJsonPath(path, label = "JSON") {
3510
+ return parseJsonObject(readFileSync10(path, "utf8"), label);
3511
+ }
3512
+ function readJsonPaths(value2, label) {
3513
+ if (!value2) {
3514
+ return [];
3515
+ }
3516
+ const paths = Array.isArray(value2) ? value2 : [value2];
3517
+ return paths.flatMap(
3518
+ (item) => String(item).split(",").filter(Boolean).map((path) => readJsonPath(path, label))
3519
+ );
1932
3520
  }
1933
3521
  function phaseRequestFromCli(options) {
1934
3522
  if (typeof options.request === "string") {
@@ -1951,7 +3539,7 @@ function phaseRequestFromCli(options) {
1951
3539
  };
1952
3540
  }
1953
3541
  const runtimeReport = typeof options.runtimeReport === "string" ? parseJsonObject(
1954
- readFileSync9(options.runtimeReport, "utf8"),
3542
+ readFileSync10(options.runtimeReport, "utf8"),
1955
3543
  "runtime report"
1956
3544
  ) : void 0;
1957
3545
  return {
@@ -1997,7 +3585,7 @@ function addTextOptions(command) {
1997
3585
  }
1998
3586
  var program = new Command();
1999
3587
  program.name("pic").description(
2000
- "TypeScript port of percolation-inversion-compiler v0.4.4 public CLI contracts."
3588
+ "TypeScript-compatible port of percolation-inversion-compiler v0.5.0 public CLI contracts."
2001
3589
  ).version(VERSION);
2002
3590
  program.exitOverride();
2003
3591
  addOutputOptions(
@@ -2013,7 +3601,7 @@ addOutputOptions(
2013
3601
  )
2014
3602
  );
2015
3603
  addOutputOptions(
2016
- program.command("schema").description("Emit canonical Python v0.4.4 JSON Schema.")
3604
+ program.command("schema").description("Emit canonical Python v0.5.0-compatible JSON Schema.")
2017
3605
  ).option("--type <typeName>", "schema type", "Registry").option(
2018
3606
  "--all",
2019
3607
  "emit the schema bundle or copy all schemas when --output-dir is supplied"
@@ -2033,7 +3621,7 @@ addOutputOptions(
2033
3621
  )
2034
3622
  ).action((options) => {
2035
3623
  const registry = parseJsonObject(
2036
- readFileSync9(options.registry, "utf8"),
3624
+ readFileSync10(options.registry, "utf8"),
2037
3625
  "registry"
2038
3626
  );
2039
3627
  const result = validateByType(registry, "Registry");
@@ -2326,7 +3914,7 @@ addOutputOptions(
2326
3914
  profile: options.profile,
2327
3915
  identityContextPath: options.identityContext
2328
3916
  });
2329
- const inboxRecord = report.accepted === true ? appendAgentMessage(options.inbox, envelope) : existsSync6(options.inbox) ? readAgentInbox(options.inbox) : { inbox_id: "agent-inbox", messages: [], peers: [], seen_nonces: [] };
3917
+ const inboxRecord = report.accepted === true ? appendAgentMessage(options.inbox, envelope) : existsSync7(options.inbox) ? readAgentInbox(options.inbox) : { inbox_id: "agent-inbox", messages: [], peers: [], seen_nonces: [] };
2330
3918
  const delivery = deliveryReport(
2331
3919
  "send",
2332
3920
  options.inbox,
@@ -2491,6 +4079,146 @@ for (const name of ["benchmark-suite", "dashboard", "observe"]) {
2491
4079
  outputJson(data, options.output);
2492
4080
  });
2493
4081
  }
4082
+ var phaseLab = phase.command("lab").description("Run local Phase Ecology Lab diagnostics.");
4083
+ addOutputOptions(
4084
+ phaseLab.command("init").requiredOption(
4085
+ "--output-dir <dir>",
4086
+ "Directory for the local Phase Lab store"
4087
+ ).option("--format <format>", "output format", "json")
4088
+ ).action(
4089
+ (options) => outputJson(initPhaseLabStore(options.outputDir), options.output)
4090
+ );
4091
+ addOutputOptions(
4092
+ phaseLab.command("ingest").requiredOption("--store <dir>", "Phase Lab store directory").option("--report <path...>", "PIC report JSON. May repeat").option("--packet <path...>", "Packet JSON. May repeat").option("--directory <dir>", "Directory of JSON reports to ingest").option("--format <format>", "output format", "json")
4093
+ ).action((options) => {
4094
+ if (options.directory) {
4095
+ outputJson(
4096
+ ingestPhaseLabDirectory(options.store, options.directory),
4097
+ options.output
4098
+ );
4099
+ return;
4100
+ }
4101
+ const reports = Array.isArray(options.report) ? options.report : [];
4102
+ const packets = Array.isArray(options.packet) ? options.packet : [];
4103
+ if (reports.length === 0 && packets.length === 0) {
4104
+ throw new Error("provide --report, --packet, or --directory");
4105
+ }
4106
+ outputJson(
4107
+ ingestPhaseLabFiles(options.store, reports, packets),
4108
+ options.output
4109
+ );
4110
+ });
4111
+ addOutputOptions(
4112
+ phaseLab.command("list-windows").requiredOption("--store <dir>", "Phase Lab store directory").option("--format <format>", "output format", "json")
4113
+ ).action(
4114
+ (options) => outputJson(listPhaseLabWindows(options.store), options.output)
4115
+ );
4116
+ addOutputOptions(
4117
+ phaseLab.command("export").requiredOption("--store <dir>", "Phase Lab store directory").requiredOption("--output-dir <dir>", "Export directory").option("--format <format>", "output format", "json")
4118
+ ).action(
4119
+ (options) => outputJson(
4120
+ exportPhaseLabStore(options.store, options.outputDir),
4121
+ options.output
4122
+ )
4123
+ );
4124
+ addOutputOptions(
4125
+ phaseLab.command("observe").requiredOption("--store <dir>", "Phase Lab store directory").option(
4126
+ "--window <window>",
4127
+ "latest, previous, all, or window id",
4128
+ "latest"
4129
+ ).option("--format <format>", "output format", "json")
4130
+ ).action(
4131
+ (options) => outputJson(
4132
+ loadPhaseLabObservation(options.store, options.window).observation,
4133
+ options.output
4134
+ )
4135
+ );
4136
+ addOutputOptions(
4137
+ phaseLab.command("graph").requiredOption("--store <dir>", "Phase Lab store directory").option("--window <window>", "latest, previous, all, or window id", "all").option("--format <format>", "output format", "json")
4138
+ ).action(
4139
+ (options) => outputJson(loadPhaseLabGraph(options.store, options.window), options.output)
4140
+ );
4141
+ addOutputOptions(
4142
+ phaseLab.command("closure").requiredOption("--store <dir>", "Phase Lab store directory").option("--window <window>", "latest, previous, all, or window id", "all").option("--format <format>", "output format", "json")
4143
+ ).action(
4144
+ (options) => outputJson(
4145
+ detectAutocatalyticClosure(
4146
+ loadPhaseLabGraph(options.store, options.window)
4147
+ ),
4148
+ options.output
4149
+ )
4150
+ );
4151
+ addOutputOptions(
4152
+ phaseLab.command("executable-paths").requiredOption("--store <dir>", "Phase Lab store directory").option("--window <window>", "latest, previous, all, or window id", "all").option("--format <format>", "output format", "json")
4153
+ ).action(
4154
+ (options) => outputJson(
4155
+ detectExecutionAvailablePaths(
4156
+ loadPhaseLabGraph(options.store, options.window)
4157
+ ),
4158
+ options.output
4159
+ )
4160
+ );
4161
+ addOutputOptions(
4162
+ phaseLab.command("threshold-status").requiredOption("--store <dir>", "Phase Lab store directory").requiredOption("--threshold <path>", "ASIProxyThresholdSpec JSON").option("--window <window>", "latest, previous, or window id", "latest").option("--format <format>", "output format", "json")
4163
+ ).action((options) => {
4164
+ const { observation } = loadPhaseLabObservation(
4165
+ options.store,
4166
+ options.window
4167
+ );
4168
+ outputJson(
4169
+ buildPhaseThresholdStatus(
4170
+ observation,
4171
+ readJsonPath(options.threshold, "threshold")
4172
+ ),
4173
+ options.output
4174
+ );
4175
+ });
4176
+ addOutputOptions(
4177
+ phaseLab.command("certify").requiredOption("--store <dir>", "Phase Lab store directory").requiredOption("--threshold <path>", "ASIProxyThresholdSpec JSON").option("--window <window>", "latest, previous, or window id", "latest").option("--format <format>", "output format", "json")
4178
+ ).action((options) => {
4179
+ const { observation, graph } = loadPhaseLabObservation(
4180
+ options.store,
4181
+ options.window
4182
+ );
4183
+ const status = buildPhaseThresholdStatus(
4184
+ observation,
4185
+ readJsonPath(options.threshold, "threshold")
4186
+ );
4187
+ outputJson(
4188
+ buildCollectivePhaseCertificateCandidate(status, graph),
4189
+ options.output
4190
+ );
4191
+ });
4192
+ addOutputOptions(
4193
+ phaseLab.command("compare-window").requiredOption("--store <dir>", "Phase Lab store directory").requiredOption("--baseline <window>", "previous, latest, or window id").requiredOption("--candidate <window>", "latest or window id").option("--format <format>", "output format", "json")
4194
+ ).action((options) => {
4195
+ const baseline = loadPhaseLabObservation(
4196
+ options.store,
4197
+ options.baseline
4198
+ ).observation;
4199
+ const candidate = loadPhaseLabObservation(
4200
+ options.store,
4201
+ options.candidate
4202
+ ).observation;
4203
+ outputJson(comparePhaseWindows(baseline, candidate), options.output);
4204
+ });
4205
+ var phaseClosure = phase.command("closure").description("Find and certify effective graph closure candidates.");
4206
+ addOutputOptions(
4207
+ phaseClosure.command("find").requiredOption("--graph <path>", "EffectivePacketGraph JSON").option("--format <format>", "output format", "json")
4208
+ ).action(
4209
+ (options) => outputJson(
4210
+ detectAutocatalyticClosure(readJsonPath(options.graph, "effective graph")),
4211
+ options.output
4212
+ )
4213
+ );
4214
+ addOutputOptions(
4215
+ phaseClosure.command("certify").requiredOption("--graph <path>", "EffectivePacketGraph JSON").option("--format <format>", "output format", "json")
4216
+ ).action(
4217
+ (options) => outputJson(
4218
+ detectAutocatalyticClosure(readJsonPath(options.graph, "effective graph")).certificate_candidate,
4219
+ options.output
4220
+ )
4221
+ );
2494
4222
  var runtime = program.command("runtime").description("Run bounded local runtime loops.");
2495
4223
  addOutputOptions(
2496
4224
  addProfile(
@@ -2547,6 +4275,55 @@ compile.action(
2547
4275
  options.output
2548
4276
  )
2549
4277
  );
4278
+ var bit = program.command("bit").description("Run BIT bottleneck inversion diagnostics.");
4279
+ addOutputOptions(
4280
+ bit.command("diagnose").requiredOption("--graph <path>", "EffectivePacketGraph JSON")
4281
+ ).action(
4282
+ (options) => outputJson(
4283
+ diagnoseBottlenecks(readJsonPath(options.graph, "effective graph")),
4284
+ options.output
4285
+ )
4286
+ );
4287
+ addOutputOptions(
4288
+ bit.command("invert").requiredOption("--bottlenecks <path>", "BottleneckInversionReport JSON")
4289
+ ).action(
4290
+ (options) => outputJson(
4291
+ invertBottlenecks(readJsonPath(options.bottlenecks, "bottlenecks")),
4292
+ options.output
4293
+ )
4294
+ );
4295
+ addOutputOptions(
4296
+ bit.command("mec").requiredOption("--bottleneck <id>", "Bottleneck id").option("--bottlenecks <path>", "Optional BottleneckInversionReport JSON")
4297
+ ).action(
4298
+ (options) => outputJson(
4299
+ {
4300
+ minimal_enabling_conditions: buildMinimalEnablingConditions(
4301
+ options.bottleneck,
4302
+ options.bottlenecks ? readJsonPath(options.bottlenecks, "bottlenecks") : void 0
4303
+ )
4304
+ },
4305
+ options.output
4306
+ )
4307
+ );
4308
+ addOutputOptions(
4309
+ bit.command("certificate").requiredOption("--candidate <path>", "BottleneckInversionCandidate JSON")
4310
+ ).action(
4311
+ (options) => outputJson(
4312
+ buildInversionCertificate(readJsonPath(options.candidate, "candidate")),
4313
+ options.output
4314
+ )
4315
+ );
4316
+ addOutputOptions(
4317
+ bit.command("compare-baseline").requiredOption("--baseline <path>", "PhaseWindowObservation JSON").requiredOption("--candidate <path>", "PhaseWindowObservation JSON")
4318
+ ).action(
4319
+ (options) => outputJson(
4320
+ compareBottleneckBaseline(
4321
+ readJsonPath(options.baseline, "baseline observation"),
4322
+ readJsonPath(options.candidate, "candidate observation")
4323
+ ),
4324
+ options.output
4325
+ )
4326
+ );
2550
4327
  var sqot = program.command("sqot");
2551
4328
  addOutputOptions(
2552
4329
  addProfile(sqot.command("schedule").option("--packets <path>"))
@@ -2559,10 +4336,107 @@ addOutputOptions(sqot.command("audit").option("--source <path>")).action(
2559
4336
  options.output
2560
4337
  )
2561
4338
  );
4339
+ addOutputOptions(
4340
+ sqot.command("diagnose-queue").requiredOption("--graph <path>", "EffectivePacketGraph JSON").option(
4341
+ "--attention-budget <number>",
4342
+ "Finite diagnostic attention budget",
4343
+ "1"
4344
+ )
4345
+ ).action(
4346
+ (options) => outputJson(
4347
+ diagnoseQueueOccupation(
4348
+ readJsonPath(options.graph, "effective graph"),
4349
+ Number(options.attentionBudget ?? 1)
4350
+ ),
4351
+ options.output
4352
+ )
4353
+ );
4354
+ addOutputOptions(
4355
+ sqot.command("salience-obstruction").requiredOption("--graph <path>", "EffectivePacketGraph JSON")
4356
+ ).action(
4357
+ (options) => outputJson(
4358
+ diagnoseSalienceObstruction(readJsonPath(options.graph, "effective graph")),
4359
+ options.output
4360
+ )
4361
+ );
4362
+ addOutputOptions(
4363
+ sqot.command("rebalance").requiredOption("--graph <path>", "EffectivePacketGraph JSON")
4364
+ ).action(
4365
+ (options) => outputJson(
4366
+ buildQueueRebalancePlan(readJsonPath(options.graph, "effective graph")),
4367
+ options.output
4368
+ )
4369
+ );
4370
+ addOutputOptions(
4371
+ sqot.command("quarantine").requiredOption("--graph <path>", "EffectivePacketGraph JSON")
4372
+ ).action(
4373
+ (options) => outputJson(
4374
+ buildPacketQuarantineDecisions(
4375
+ readJsonPath(options.graph, "effective graph")
4376
+ ),
4377
+ options.output
4378
+ )
4379
+ );
4380
+ addOutputOptions(
4381
+ sqot.command("reserve-check").requiredOption("--graph <path>", "EffectivePacketGraph JSON").option(
4382
+ "--attention-budget <number>",
4383
+ "Finite diagnostic attention budget",
4384
+ "1"
4385
+ )
4386
+ ).action(
4387
+ (options) => outputJson(
4388
+ checkDiagnosticReserve(
4389
+ readJsonPath(options.graph, "effective graph"),
4390
+ Number(options.attentionBudget ?? 1)
4391
+ ),
4392
+ options.output
4393
+ )
4394
+ );
2562
4395
  var alt = program.command("alt");
2563
4396
  addOutputOptions(alt.command("admit").option("--packet <path>")).action(
2564
4397
  (options) => outputJson(altAdmit(options.packet ?? "alt-packet:demo"), options.output)
2565
4398
  );
4399
+ addOutputOptions(
4400
+ alt.command("ecpt-lift").requiredOption("--packets <path...>", "ALT packet/report JSON. May repeat").requiredOption("--graph <path>", "EffectivePacketGraph JSON")
4401
+ ).action(
4402
+ (options) => outputJson(
4403
+ verifyAltEcptLift(
4404
+ readJsonPaths(options.packets, "ALT packet"),
4405
+ readJsonPath(options.graph, "effective graph")
4406
+ ),
4407
+ options.output
4408
+ )
4409
+ );
4410
+ addOutputOptions(
4411
+ alt.command("receiver-lift").requiredOption("--packet <path>", "ALT packet/report JSON").requiredOption("--receiver-context <path>", "Receiver context JSON")
4412
+ ).action(
4413
+ (options) => outputJson(
4414
+ verifyReceiverLift(
4415
+ readJsonPath(options.packet, "ALT packet"),
4416
+ readJsonPath(options.receiverContext, "receiver context")
4417
+ ),
4418
+ options.output
4419
+ )
4420
+ );
4421
+ addOutputOptions(
4422
+ alt.command("liquidity-to-paths").requiredOption("--packet <path>", "ALT packet/report JSON").requiredOption("--graph <path>", "EffectivePacketGraph JSON")
4423
+ ).action(
4424
+ (options) => outputJson(
4425
+ mapLiquidityToPaths(
4426
+ readJsonPath(options.packet, "ALT packet"),
4427
+ readJsonPath(options.graph, "effective graph")
4428
+ ),
4429
+ options.output
4430
+ )
4431
+ );
4432
+ addOutputOptions(
4433
+ alt.command("capital-impact").requiredOption("--reports <path...>", "ALT report JSON. May repeat")
4434
+ ).action(
4435
+ (options) => outputJson(
4436
+ estimateCapitalImpact(readJsonPaths(options.reports, "ALT report")),
4437
+ options.output
4438
+ )
4439
+ );
2566
4440
  for (const name of [
2567
4441
  "audit",
2568
4442
  "tokenize",
@@ -2582,6 +4456,31 @@ for (const name of [
2582
4456
  (options) => outputJson(diagnostic(`alt:${name}`), options.output)
2583
4457
  );
2584
4458
  }
4459
+ var trc = program.command("trc").description("Adapt traces into typed TRC diagnostic data.");
4460
+ addOutputOptions(
4461
+ trc.command("trace-adapter").requiredOption("--input <path>", "Trace JSON")
4462
+ ).action(
4463
+ (options) => outputJson(
4464
+ adaptTrcTrace(readJsonPath(options.input, "trace input")),
4465
+ options.output
4466
+ )
4467
+ );
4468
+ addOutputOptions(
4469
+ trc.command("tool-trace").requiredOption("--events <path>", "JSON tool events")
4470
+ ).action(
4471
+ (options) => outputJson(
4472
+ adaptToolTrace(readJsonPath(options.events, "tool events")),
4473
+ options.output
4474
+ )
4475
+ );
4476
+ addOutputOptions(
4477
+ trc.command("action-boundary").requiredOption("--report <path>", "Runtime report JSON")
4478
+ ).action(
4479
+ (options) => outputJson(
4480
+ buildActionBoundaryReport(readJsonPath(options.report, "runtime report")),
4481
+ options.output
4482
+ )
4483
+ );
2585
4484
  var ecology = program.command("ecology");
2586
4485
  addOutputOptions(
2587
4486
  ecology.command("ingest").option("--source <source>").option("--kind <kind>", "kind", "local")
@@ -2600,6 +4499,24 @@ addOutputOptions(
2600
4499
  ).action(
2601
4500
  (options) => outputJson(ecologyPolicy(options.profile), options.output)
2602
4501
  );
4502
+ addOutputOptions(
4503
+ ecology.command("effective-graph").requiredOption("--reports <path...>", "PIC report JSON. May repeat")
4504
+ ).action(
4505
+ (options) => outputJson(
4506
+ buildEffectivePacketGraph(readJsonPaths(options.reports, "ecology report")),
4507
+ options.output
4508
+ )
4509
+ );
4510
+ addOutputOptions(
4511
+ ecology.command("execution-available-paths").requiredOption("--graph <path>", "EffectivePacketGraph JSON")
4512
+ ).action(
4513
+ (options) => outputJson(
4514
+ detectExecutionAvailablePaths(
4515
+ readJsonPath(options.graph, "effective graph")
4516
+ ),
4517
+ options.output
4518
+ )
4519
+ );
2603
4520
  for (const name of [
2604
4521
  "ingest-general",
2605
4522
  "discover-web",
@@ -2624,7 +4541,7 @@ addOutputOptions(
2624
4541
  identity.command("verify").requiredOption("--identity <path>")
2625
4542
  ).action((options) => {
2626
4543
  const data = parseJsonObject(
2627
- readFileSync9(options.identity, "utf8"),
4544
+ readFileSync10(options.identity, "utf8"),
2628
4545
  "identity"
2629
4546
  );
2630
4547
  const validation = validateByType(data, "CryptographicAgentIdentity");
@@ -2661,7 +4578,7 @@ addOutputOptions(
2661
4578
  identity.command("verify-attestation").requiredOption("--attestation <path>").requiredOption("--identities <path>")
2662
4579
  ).action((options) => {
2663
4580
  const attestation = parseJsonObject(
2664
- readFileSync9(options.attestation, "utf8"),
4581
+ readFileSync10(options.attestation, "utf8"),
2665
4582
  "attestation"
2666
4583
  );
2667
4584
  const validation = validateByType(attestation, "AgentIdentityAttestation");
@@ -2679,7 +4596,7 @@ addOutputOptions(
2679
4596
  identity.command("sybil-check").requiredOption("--population <path>")
2680
4597
  ).action((options) => {
2681
4598
  const population = parseJsonObject(
2682
- readFileSync9(options.population, "utf8"),
4599
+ readFileSync10(options.population, "utf8"),
2683
4600
  "population"
2684
4601
  );
2685
4602
  const validation = validateByType(population, "AgentPopulationState");
@@ -2717,7 +4634,7 @@ addOutputOptions(
2717
4634
  )
2718
4635
  ).action((options) => {
2719
4636
  const population = parseJsonObject(
2720
- readFileSync9(options.population, "utf8"),
4637
+ readFileSync10(options.population, "utf8"),
2721
4638
  "population"
2722
4639
  );
2723
4640
  const validation = validateByType(population, "AgentPopulationState");
@@ -2866,32 +4783,58 @@ addOutputOptions(
2866
4783
  options.output
2867
4784
  )
2868
4785
  );
4786
+ function nodeOnlyDemoCommands(demoDir = "pic-demo") {
4787
+ return [
4788
+ `pic-ts runtime step --state ${demoDir}/runtime_state.json --input ${demoDir}/runtime_step_input.json --output ${demoDir}/runtime_step_report.generated.json`,
4789
+ `pic-ts packet export --report ${demoDir}/runtime_step_report.generated.json --output ${demoDir}/packet.json`,
4790
+ `pic-ts packet inspect --packet ${demoDir}/packet.json`,
4791
+ `pic-ts phase lab init --output-dir ${demoDir}/phase-lab`,
4792
+ `pic-ts phase lab ingest --store ${demoDir}/phase-lab --report ${demoDir}/runtime_step_report.generated.json`,
4793
+ `pic-ts phase lab observe --store ${demoDir}/phase-lab --window latest`,
4794
+ `pic-ts phase lab graph --store ${demoDir}/phase-lab`,
4795
+ `pic-ts phase lab closure --store ${demoDir}/phase-lab`,
4796
+ `pic-ts phase lab executable-paths --store ${demoDir}/phase-lab`,
4797
+ `pic-ts phase lab certify --store ${demoDir}/phase-lab --threshold ${demoDir}/asi_proxy_development.json`,
4798
+ `pic-ts phase plan --request ${demoDir}/asi_proxy_phase_request.json --compact`,
4799
+ 'pic-ts agent accelerate --compact --text "Candidate packet: preserve residuals." --profile development'
4800
+ ];
4801
+ }
2869
4802
  var demo = program.command("demo");
2870
4803
  addOutputOptions(addProfile(demo.command("installed-smoke"))).action(
2871
- (options) => outputJson(
2872
- { ...pythonCliFixture("demo_installed_smoke"), profile: options.profile },
2873
- options.output
2874
- )
4804
+ (options) => {
4805
+ const report = {
4806
+ ...pythonCliFixture("demo_installed_smoke"),
4807
+ profile: options.profile,
4808
+ recommended_next_commands: nodeOnlyDemoCommands(),
4809
+ settled: false
4810
+ };
4811
+ outputJson(report, options.output);
4812
+ }
2875
4813
  );
2876
4814
  addOutputOptions(
2877
4815
  demo.command("bootstrap").requiredOption("--output-dir <dir>").option("--overwrite", "overwrite files")
2878
4816
  ).action((options) => {
2879
- mkdirSync4(options.outputDir, { recursive: true });
2880
- const demoDir = join4(fixtureRoot(), "python_v044_demo");
4817
+ mkdirSync5(options.outputDir, { recursive: true });
4818
+ const demoDir = join5(fixtureRoot(), "python_v044_demo");
2881
4819
  const copied = [];
2882
- for (const file of readdirSync2(demoDir).filter(
4820
+ for (const file of readdirSync3(demoDir).filter(
2883
4821
  (name) => [".json", ".txt"].some((suffix) => name.endsWith(suffix))
2884
4822
  )) {
2885
- cpSync2(join4(demoDir, file), join4(options.outputDir, file));
4823
+ cpSync2(join5(demoDir, file), join5(options.outputDir, file));
2886
4824
  copied.push(file);
2887
4825
  }
4826
+ cpSync2(
4827
+ join5(packageRoot(), "examples", "thresholds", "asi_proxy_development.json"),
4828
+ join5(options.outputDir, "asi_proxy_development.json")
4829
+ );
4830
+ copied.push("asi_proxy_development.json");
2888
4831
  for (const [file, fixture] of [
2889
4832
  ["agent_check_report.json", "agent_check_full"],
2890
4833
  ["phase_acceleration_plan.json", "phase_plan_full"],
2891
4834
  ["phase_acceleration_plan.compact.json", "phase_plan_compact"]
2892
4835
  ]) {
2893
- writeFileSync4(
2894
- join4(options.outputDir, file),
4836
+ writeFileSync5(
4837
+ join5(options.outputDir, file),
2895
4838
  stableStringify(pythonCliFixture(fixture)),
2896
4839
  "utf8"
2897
4840
  );
@@ -2902,6 +4845,7 @@ addOutputOptions(
2902
4845
  accepted: true,
2903
4846
  output_dir: options.outputDir,
2904
4847
  files: copied.sort(),
4848
+ recommended_next_commands: nodeOnlyDemoCommands(options.outputDir),
2905
4849
  settled: false
2906
4850
  },
2907
4851
  options.output