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.
- package/CHANGELOG.md +8 -0
- package/README.md +77 -22
- package/agent-manifest.json +50 -0
- package/dist/alt_lift/index.d.ts +7 -0
- package/dist/alt_lift/index.js +101 -0
- package/dist/bit_engine/index.d.ts +8 -0
- package/dist/bit_engine/index.js +213 -0
- package/dist/cli/main.js +2106 -162
- package/dist/index.d.ts +5 -0
- package/dist/index.js +1611 -16
- package/dist/phase_lab/index.d.ts +26 -0
- package/dist/phase_lab/index.js +1124 -0
- package/dist/sqot_controller/index.d.ts +8 -0
- package/dist/sqot_controller/index.js +141 -0
- package/dist/trc_adapter/index.d.ts +6 -0
- package/dist/trc_adapter/index.js +86 -0
- package/docs/alt-ecpt-lift.md +32 -0
- package/docs/bit-inversion-engine.md +32 -0
- package/docs/cli-reference.md +68 -0
- package/docs/effective-packet-graph.md +35 -0
- package/docs/for-agents.md +44 -0
- package/docs/phase-ecology-lab.md +46 -0
- package/docs/sqot-queue-sovereignty.md +31 -0
- package/docs/threshold-certificates.md +30 -0
- package/docs/trc-trace-adapter.md +30 -0
- package/docs/v050-audit.md +126 -0
- package/examples/alt_lift/alt_ecpt_lift.example.json +27 -0
- package/examples/bit_engine/bottlenecks.example.json +38 -0
- package/examples/bit_engine/inversion_candidates.example.json +55 -0
- package/examples/packet_exchange/packet_envelope.example.json +51 -0
- package/examples/packet_exchange/packet_merge_report.example.json +60 -0
- package/examples/phase_lab/certificate_abstain.example.json +39 -0
- package/examples/phase_lab/closure_report.example.json +41 -0
- package/examples/phase_lab/effective_graph.example.json +112 -0
- package/examples/phase_lab/executable_paths.example.json +20 -0
- package/examples/phase_lab/phase_window_observation.example.json +61 -0
- package/examples/phase_lab/runtime_report_1.json +19 -0
- package/examples/phase_lab/runtime_report_2.json +16 -0
- package/examples/phase_lab/threshold_status.example.json +31 -0
- package/examples/sqot_controller/queue_report.example.json +30 -0
- package/examples/sqot_controller/rebalance_plan.example.json +14 -0
- package/examples/thresholds/asi_proxy_development.json +15 -0
- package/examples/trc_adapter/tool_trace_input.example.json +17 -0
- package/examples/trc_adapter/typed_trace.example.json +64 -0
- package/fixtures/portability_conformance_v050/certificate_abstain.example.json +39 -0
- package/fixtures/portability_conformance_v050/closure_report.example.json +39 -0
- package/fixtures/portability_conformance_v050/effective_graph.example.json +112 -0
- package/fixtures/portability_conformance_v050/executable_paths.example.json +20 -0
- package/fixtures/portability_conformance_v050/manifest.json +55 -0
- package/fixtures/portability_conformance_v050/phase_lab_event_1.json +51 -0
- package/fixtures/portability_conformance_v050/phase_lab_event_2.json +55 -0
- package/fixtures/portability_conformance_v050/phase_window_observation.example.json +61 -0
- package/fixtures/portability_conformance_v050/runtime_report_1.json +19 -0
- package/fixtures/portability_conformance_v050/runtime_report_2.json +14 -0
- package/fixtures/portability_conformance_v050/threshold_status.example.json +29 -0
- package/fixtures/python_v044_cli/agent_autonomy_audit.json +4 -3
- package/fixtures/python_v044_cli/agent_manifest.json +2 -1
- package/fixtures/python_v044_cli/agent_runbook.json +2 -1
- package/fixtures/python_v044_cli/demo_installed_smoke.json +86 -86
- package/fixtures/python_v044_demo/manifest.json +2 -1
- package/fixtures/python_v050_cli/alt_capital_impact.json +30 -0
- package/fixtures/python_v050_cli/alt_ecpt_lift.json +85 -0
- package/fixtures/python_v050_cli/alt_liquidity_to_paths.json +85 -0
- package/fixtures/python_v050_cli/alt_receiver_lift.json +15 -0
- package/fixtures/python_v050_cli/bit_certificate.json +15 -0
- package/fixtures/python_v050_cli/bit_compare_baseline.json +24 -0
- package/fixtures/python_v050_cli/bit_diagnose.json +95 -0
- package/fixtures/python_v050_cli/bit_invert.json +235 -0
- package/fixtures/python_v050_cli/bit_mec.json +18 -0
- package/fixtures/python_v050_cli/ecology_effective_graph.json +178 -0
- package/fixtures/python_v050_cli/ecology_execution_available_paths.json +88 -0
- package/fixtures/python_v050_cli/manifest.json +48 -0
- package/fixtures/python_v050_cli/phase_lab_certify.json +443 -0
- package/fixtures/python_v050_cli/phase_lab_closure.json +85 -0
- package/fixtures/python_v050_cli/phase_lab_compare_window.json +24 -0
- package/fixtures/python_v050_cli/phase_lab_executable_paths.json +88 -0
- package/fixtures/python_v050_cli/phase_lab_graph.json +178 -0
- package/fixtures/python_v050_cli/phase_lab_ingest_1.json +105 -0
- package/fixtures/python_v050_cli/phase_lab_ingest_2.json +109 -0
- package/fixtures/python_v050_cli/phase_lab_init.json +20 -0
- package/fixtures/python_v050_cli/phase_lab_list_windows.json +63 -0
- package/fixtures/python_v050_cli/phase_lab_observe.json +108 -0
- package/fixtures/python_v050_cli/phase_lab_threshold_status.json +164 -0
- package/fixtures/python_v050_cli/sqot_diagnose_queue.json +38 -0
- package/fixtures/python_v050_cli/sqot_quarantine.json +7 -0
- package/fixtures/python_v050_cli/sqot_rebalance.json +19 -0
- package/fixtures/python_v050_cli/sqot_reserve_check.json +20 -0
- package/fixtures/python_v050_cli/sqot_salience_obstruction.json +19 -0
- package/fixtures/python_v050_cli/trc_action_boundary.json +451 -0
- package/fixtures/python_v050_cli/trc_tool_trace.json +221 -0
- package/fixtures/python_v050_cli/trc_trace_adapter.json +221 -0
- package/fixtures/python_v050_demo/asi_proxy_development.json +15 -0
- package/fixtures/python_v050_demo/certificate_abstain.example.json +39 -0
- package/fixtures/python_v050_demo/closure_report.example.json +39 -0
- package/fixtures/python_v050_demo/effective_graph.example.json +112 -0
- package/fixtures/python_v050_demo/executable_paths.example.json +20 -0
- package/fixtures/python_v050_demo/phase_window_observation.example.json +61 -0
- package/fixtures/python_v050_demo/runtime_report_1.json +19 -0
- package/fixtures/python_v050_demo/runtime_report_2.json +14 -0
- package/fixtures/python_v050_demo/threshold_status.example.json +29 -0
- package/fixtures/python_v050_snapshots/manifest.json +39 -0
- package/fixtures/python_v050_snapshots/snapshot_list.json +112 -0
- package/fixtures/python_v050_snapshots/snapshot_routes.json +926 -0
- package/fixtures/python_v050_snapshots/snapshot_show_alt.json +6830 -0
- package/fixtures/python_v050_snapshots/snapshot_show_bit.json +594 -0
- package/fixtures/python_v050_snapshots/snapshot_show_ecpt.json +2894 -0
- package/fixtures/python_v050_snapshots/snapshot_show_sqot.json +2392 -0
- package/fixtures/python_v050_snapshots/snapshot_show_trc.json +3037 -0
- package/fixtures/python_v050_snapshots/snapshot_verify_alt.json +10 -0
- package/fixtures/python_v050_snapshots/snapshot_verify_bit.json +10 -0
- package/fixtures/python_v050_snapshots/snapshot_verify_ecpt.json +10 -0
- package/fixtures/python_v050_snapshots/snapshot_verify_sqot.json +10 -0
- package/fixtures/python_v050_snapshots/snapshot_verify_trc.json +10 -0
- package/package.json +45 -3
- package/schemas/ASIProxyThresholdSpec.schema.json +72 -0
- package/schemas/ASIProxyThresholdStatus.schema.json +512 -0
- package/schemas/ActionBoundaryRequirement.schema.json +28 -0
- package/schemas/ActivationGainEstimate.schema.json +41 -0
- package/schemas/AltEcptLiftReport.schema.json +400 -0
- package/schemas/AltLiftBlocker.schema.json +34 -0
- package/schemas/AttentionBudgetLedger.schema.json +41 -0
- package/schemas/AutocatalyticClosureReport.schema.json +408 -0
- package/schemas/AutocatalyticClosureWitness.schema.json +22 -139
- package/schemas/BasinReachabilityProxy.schema.json +21 -0
- package/schemas/BottleneckClassDiagnosis.schema.json +115 -0
- package/schemas/BottleneckInversionCandidate.schema.json +249 -0
- package/schemas/BottleneckInversionReport.schema.json +499 -0
- package/schemas/CapabilityExpressionPath.schema.json +45 -0
- package/schemas/CapitalToPathContribution.schema.json +53 -0
- package/schemas/ClosureAbstentionReason.schema.json +25 -0
- package/schemas/ClosureCertificateCandidate.schema.json +109 -0
- package/schemas/ClosureDefect.schema.json +28 -0
- package/schemas/ClosureSupportHyperpath.schema.json +44 -0
- package/schemas/CollectivePhaseAbstentionReport.schema.json +591 -0
- package/schemas/CollectivePhaseCertificateCandidate.schema.json +688 -0
- package/schemas/CrossContextTransferWitness.schema.json +46 -0
- package/schemas/DiagnosticReserveReport.schema.json +87 -0
- package/schemas/DownstreamSearchCostDelta.schema.json +46 -0
- package/schemas/EcologyAutocatalyticClosureWitness.schema.json +187 -0
- package/schemas/EffectiveGraphResidualSummary.schema.json +38 -0
- package/schemas/EffectivePacketEdge.schema.json +135 -0
- package/schemas/EffectivePacketEligibility.schema.json +84 -0
- package/schemas/EffectivePacketGraph.schema.json +461 -0
- package/schemas/EffectivePacketGraphBuildReport.schema.json +521 -0
- package/schemas/EffectivePacketNode.schema.json +199 -0
- package/schemas/ExecutableClosureWitness.schema.json +47 -0
- package/schemas/ExecutablePathDensityReport.schema.json +314 -0
- package/schemas/ExecutionAuthorityStatus.schema.json +28 -0
- package/schemas/ExecutionAvailableHyperpath.schema.json +201 -0
- package/schemas/ExecutionPathDefect.schema.json +28 -0
- package/schemas/ExecutionPathWitness.schema.json +44 -0
- package/schemas/FalseLiquidityLoad.schema.json +21 -0
- package/schemas/GeneralIntakePolicy.schema.json +1 -1
- package/schemas/InversionCertificate.schema.json +56 -0
- package/schemas/LiquidityToClosureContribution.schema.json +53 -0
- package/schemas/MinimalEnablingCondition.schema.json +48 -0
- package/schemas/PacketContributionStatus.schema.json +32 -0
- package/schemas/PacketQuarantineDecision.schema.json +50 -0
- package/schemas/PhaseCertificateDefect.schema.json +33 -0
- package/schemas/PhaseComponentObservation.schema.json +39 -0
- package/schemas/PhaseLabEvent.schema.json +123 -0
- package/schemas/PhaseLabExportManifest.schema.json +127 -0
- package/schemas/PhaseLabIngestReport.schema.json +344 -0
- package/schemas/PhaseLabStoreManifest.schema.json +73 -0
- package/schemas/PhaseLabWindowIndex.schema.json +78 -0
- package/schemas/PhaseThresholdStatus.schema.json +51 -0
- package/schemas/PhaseWindow.schema.json +31 -0
- package/schemas/PhaseWindowComparison.schema.json +67 -0
- package/schemas/PhaseWindowObservation.schema.json +353 -0
- package/schemas/PostInversionAuditPlan.schema.json +38 -0
- package/schemas/ProductiveClosureWitness.schema.json +49 -0
- package/schemas/ProvenanceManifest.schema.json +1 -1
- package/schemas/QueueOccupationReport.schema.json +156 -0
- package/schemas/QueueRebalancePlan.schema.json +114 -0
- package/schemas/ReceiverContextSupport.schema.json +23 -0
- package/schemas/ReceiverLiquidityLift.schema.json +58 -0
- package/schemas/ReleaseArtifactManifest.schema.json +1 -1
- package/schemas/ReversibleSalienceSovereigntyCertificate.schema.json +53 -0
- package/schemas/RollbackOrDeactivationPlan.schema.json +38 -0
- package/schemas/SBOMManifest.schema.json +1 -1
- package/schemas/SalienceObstructionDiagnosis.schema.json +55 -0
- package/schemas/SalienceObstructionLoad.schema.json +21 -0
- package/schemas/SemanticEdgeEvidence.schema.json +40 -0
- package/schemas/TraceAdapterReport.schema.json +405 -0
- package/schemas/TraceFrontierDebt.schema.json +43 -0
- package/schemas/TraceNormalForm.schema.json +181 -0
- package/schemas/TraceToleranceLedger.schema.json +29 -0
- package/schemas/TypedActionBoundary.schema.json +58 -0
- package/schemas/TypedAgentTrace.schema.json +328 -0
- package/schemas/TypedToolCallTrace.schema.json +76 -0
- package/schemas/VerificationQueuePressure.schema.json +41 -0
- package/schemas/VerificationThroughputWindow.schema.json +21 -0
- package/schemas/WasteLoad.schema.json +21 -0
- package/schemas/WebFetchPolicy.schema.json +1 -1
- package/schemas/bundle.schema.json +11854 -2075
- package/schemas/index.json +445 -0
- package/schemas/schema-digest.json +733 -289
|
@@ -0,0 +1,1124 @@
|
|
|
1
|
+
// src/phase_lab/index.ts
|
|
2
|
+
import { createHash } from "crypto";
|
|
3
|
+
import {
|
|
4
|
+
existsSync,
|
|
5
|
+
mkdirSync,
|
|
6
|
+
readFileSync,
|
|
7
|
+
readdirSync,
|
|
8
|
+
writeFileSync
|
|
9
|
+
} from "fs";
|
|
10
|
+
import { basename, join } from "path";
|
|
11
|
+
|
|
12
|
+
// src/core/json.ts
|
|
13
|
+
function sortJson(value) {
|
|
14
|
+
if (Array.isArray(value)) {
|
|
15
|
+
return value.map((item) => sortJson(item));
|
|
16
|
+
}
|
|
17
|
+
if (value && typeof value === "object") {
|
|
18
|
+
const input = value;
|
|
19
|
+
const output = {};
|
|
20
|
+
for (const key of Object.keys(input).sort()) {
|
|
21
|
+
const child = input[key];
|
|
22
|
+
if (child !== void 0) {
|
|
23
|
+
output[key] = sortJson(child);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return output;
|
|
27
|
+
}
|
|
28
|
+
return value;
|
|
29
|
+
}
|
|
30
|
+
function stableStringify(value) {
|
|
31
|
+
return `${JSON.stringify(sortJson(value), null, 2)}
|
|
32
|
+
`;
|
|
33
|
+
}
|
|
34
|
+
function parseJsonObject(text, label = "JSON") {
|
|
35
|
+
const parsed = JSON.parse(text);
|
|
36
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
37
|
+
throw new Error(`${label} must be a JSON object`);
|
|
38
|
+
}
|
|
39
|
+
return parsed;
|
|
40
|
+
}
|
|
41
|
+
function dedupeSorted(values) {
|
|
42
|
+
return [
|
|
43
|
+
...new Set([...values].filter((item) => Boolean(item)))
|
|
44
|
+
].sort();
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// src/phase_lab/index.ts
|
|
48
|
+
var PHASE_LAB_SAFETY = [
|
|
49
|
+
"phase lab stores local report data only",
|
|
50
|
+
"phase lab never executes report or packet content",
|
|
51
|
+
"phase lab diagnostics do not settle claims",
|
|
52
|
+
"raw packet volume is diagnostic only"
|
|
53
|
+
];
|
|
54
|
+
var GRAPH_SAFETY = [
|
|
55
|
+
"raw packet volume is diagnostic only",
|
|
56
|
+
"candidate-only nodes do not improve positive phase components",
|
|
57
|
+
"graph construction does not execute packet content",
|
|
58
|
+
"graph construction does not settle claims"
|
|
59
|
+
];
|
|
60
|
+
function sha256Json(data) {
|
|
61
|
+
return createHash("sha256").update(JSON.stringify(sortJson(data)), "utf8").digest("hex");
|
|
62
|
+
}
|
|
63
|
+
function asRecord(value) {
|
|
64
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
|
|
65
|
+
}
|
|
66
|
+
function asRecords(value) {
|
|
67
|
+
return Array.isArray(value) ? value.filter((item) => Boolean(asRecord(item))) : [];
|
|
68
|
+
}
|
|
69
|
+
function stringList(value) {
|
|
70
|
+
if (value === void 0 || value === null) return [];
|
|
71
|
+
if (Array.isArray(value)) return value.map(String).sort();
|
|
72
|
+
if (value instanceof Set) return [...value].map(String).sort();
|
|
73
|
+
return [String(value)];
|
|
74
|
+
}
|
|
75
|
+
function numeric(value) {
|
|
76
|
+
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
77
|
+
const parsed = Number(value);
|
|
78
|
+
return Number.isFinite(parsed) ? parsed : 0;
|
|
79
|
+
}
|
|
80
|
+
function numericDict(value) {
|
|
81
|
+
const record = asRecord(value);
|
|
82
|
+
if (!record) return {};
|
|
83
|
+
return Object.fromEntries(
|
|
84
|
+
Object.entries(record).map(([key, item]) => [key, numeric(item)]).sort(([a], [b]) => a.localeCompare(b))
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
function residualSummary(payload) {
|
|
88
|
+
const direct = asRecord(payload.residual_summary) ?? asRecord(payload.residual_ledger_summary);
|
|
89
|
+
if (direct) return numericDict(direct);
|
|
90
|
+
const coordinates = asRecord(asRecord(payload.residual_ledger)?.coordinates);
|
|
91
|
+
if (!coordinates) return {};
|
|
92
|
+
const summary = {};
|
|
93
|
+
for (const coordinate of Object.values(coordinates)) {
|
|
94
|
+
const item = asRecord(coordinate);
|
|
95
|
+
if (!item) continue;
|
|
96
|
+
const kind = String(item.kind ?? "residual");
|
|
97
|
+
summary[kind] = (summary[kind] ?? 0) + numeric(item.value);
|
|
98
|
+
}
|
|
99
|
+
return Object.fromEntries(
|
|
100
|
+
Object.entries(summary).sort(([a], [b]) => a.localeCompare(b))
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
function residualDebt(summary) {
|
|
104
|
+
return Object.values(summary).reduce((total, value) => total + value, 0);
|
|
105
|
+
}
|
|
106
|
+
function inferSchemaHint(payload) {
|
|
107
|
+
if ("packet_id" in payload && "content_digest" in payload && "content" in payload) {
|
|
108
|
+
return "PacketExchangeEnvelope";
|
|
109
|
+
}
|
|
110
|
+
if ("report_id" in payload && "registry" in payload)
|
|
111
|
+
return "RuntimeStepReport";
|
|
112
|
+
if ("graph_id" in payload && "nodes" in payload && "edges" in payload) {
|
|
113
|
+
return "EffectivePacketGraph";
|
|
114
|
+
}
|
|
115
|
+
if ("message_id" in payload) return "AgentMessageEnvelope";
|
|
116
|
+
if ("decision_id" in payload && "packet_id" in payload)
|
|
117
|
+
return "ALTAdmissionDecision";
|
|
118
|
+
if ("accepted" in payload && "workflow_usable" in payload)
|
|
119
|
+
return "AgentCheckReport";
|
|
120
|
+
return String(payload.schema_hint ?? payload.schema ?? "UnknownPICReport");
|
|
121
|
+
}
|
|
122
|
+
function inferSourceKind(payload, schemaHint) {
|
|
123
|
+
if (typeof payload.source_kind === "string") return payload.source_kind;
|
|
124
|
+
const mapping = {
|
|
125
|
+
AgentCheckReport: "agent-check",
|
|
126
|
+
AgentMessageEnvelope: "agent-message",
|
|
127
|
+
ALTAdmissionDecision: "alt-admission",
|
|
128
|
+
EffectivePacketGraph: "effective-graph",
|
|
129
|
+
PacketExchangeEnvelope: "packet-exchange",
|
|
130
|
+
RuntimeStepReport: "runtime-step-report"
|
|
131
|
+
};
|
|
132
|
+
return mapping[schemaHint] ?? "unknown-report";
|
|
133
|
+
}
|
|
134
|
+
function unsafeReasons(payload, missing, candidateOnlyReasons, settledBlockers) {
|
|
135
|
+
const text = JSON.stringify(payload).toLowerCase();
|
|
136
|
+
const reasons = [];
|
|
137
|
+
if ([
|
|
138
|
+
"npm install",
|
|
139
|
+
"npx",
|
|
140
|
+
"node ",
|
|
141
|
+
"docker run",
|
|
142
|
+
"kubectl",
|
|
143
|
+
"curl ",
|
|
144
|
+
"bash ",
|
|
145
|
+
"powershell",
|
|
146
|
+
"safe_commands"
|
|
147
|
+
].some((marker) => text.includes(marker))) {
|
|
148
|
+
reasons.push("embedded command-like text remains inert");
|
|
149
|
+
}
|
|
150
|
+
if (missing.length > 0) reasons.push("missing obligations remain visible");
|
|
151
|
+
if (candidateOnlyReasons.length > 0)
|
|
152
|
+
reasons.push("candidate-only reasons remain visible");
|
|
153
|
+
if (settledBlockers.length > 0)
|
|
154
|
+
reasons.push("settlement blockers remain visible");
|
|
155
|
+
return dedupeSorted(reasons);
|
|
156
|
+
}
|
|
157
|
+
function eventFromPayload(payload, windowId, sequence, sourcePath, sourceKindOverride) {
|
|
158
|
+
const digest = sha256Json(payload);
|
|
159
|
+
const schemaHint = inferSchemaHint(payload);
|
|
160
|
+
const sourceKind = sourceKindOverride ?? inferSourceKind(payload, schemaHint);
|
|
161
|
+
const missing = dedupeSorted([
|
|
162
|
+
...stringList(payload.missing_obligations),
|
|
163
|
+
...stringList(payload.unresolved_obligations)
|
|
164
|
+
]);
|
|
165
|
+
const candidateOnlyReasons = dedupeSorted(
|
|
166
|
+
stringList(payload.candidate_only_reasons)
|
|
167
|
+
);
|
|
168
|
+
const settledBlockers = dedupeSorted([
|
|
169
|
+
...stringList(payload.settled_blockers),
|
|
170
|
+
...payload.settled === true ? ["source-settled-ignored-by-phase-lab"] : []
|
|
171
|
+
]);
|
|
172
|
+
const accepted = payload.accepted === true;
|
|
173
|
+
const candidateOnly = payload.candidate_only === true || candidateOnlyReasons.length > 0 || !accepted || [
|
|
174
|
+
"packet-exchange",
|
|
175
|
+
"general-intake",
|
|
176
|
+
"raw-external",
|
|
177
|
+
"phase-dashboard"
|
|
178
|
+
].includes(sourceKind);
|
|
179
|
+
const reasons = unsafeReasons(
|
|
180
|
+
payload,
|
|
181
|
+
missing,
|
|
182
|
+
candidateOnlyReasons,
|
|
183
|
+
settledBlockers
|
|
184
|
+
);
|
|
185
|
+
const positiveContributionAllowed = accepted && !candidateOnly && reasons.length === 0 && missing.length === 0;
|
|
186
|
+
return {
|
|
187
|
+
accepted,
|
|
188
|
+
candidate_only: candidateOnly,
|
|
189
|
+
candidate_only_reasons: candidateOnlyReasons,
|
|
190
|
+
content_digest: digest,
|
|
191
|
+
event_id: `phase-lab-event:${sequence}:${digest.slice(0, 12)}`,
|
|
192
|
+
missing_obligations: missing,
|
|
193
|
+
operationally_usable: payload.operationally_usable === true,
|
|
194
|
+
payload,
|
|
195
|
+
positive_contribution_allowed: positiveContributionAllowed,
|
|
196
|
+
reasons: dedupeSorted([
|
|
197
|
+
"event content is stored as inert data",
|
|
198
|
+
...reasons,
|
|
199
|
+
...candidateOnly ? ["candidate-only event cannot improve phase metrics"] : []
|
|
200
|
+
]),
|
|
201
|
+
residual_summary: residualSummary(payload),
|
|
202
|
+
safety_boundary: PHASE_LAB_SAFETY,
|
|
203
|
+
schema_hint: schemaHint,
|
|
204
|
+
settled: false,
|
|
205
|
+
settled_blockers: settledBlockers,
|
|
206
|
+
source_kind: sourceKind,
|
|
207
|
+
source_path: sourcePath ? basename(sourcePath) : null,
|
|
208
|
+
window_id: windowId,
|
|
209
|
+
workflow_usable: payload.workflow_usable === true
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
function readJsonFile(path, label = "JSON") {
|
|
213
|
+
if (!path.toLowerCase().endsWith(".json")) {
|
|
214
|
+
throw new Error(
|
|
215
|
+
`${label} must be a JSON file; YAML input is not enabled in PIC-TS v0.5.0`
|
|
216
|
+
);
|
|
217
|
+
}
|
|
218
|
+
return parseJsonObject(readFileSync(path, "utf8"), label);
|
|
219
|
+
}
|
|
220
|
+
function storePaths(storeDir) {
|
|
221
|
+
return {
|
|
222
|
+
events: join(storeDir, "events.jsonl"),
|
|
223
|
+
manifest: join(storeDir, "manifest.json"),
|
|
224
|
+
windows: join(storeDir, "windows")
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
function windowFileName(windowId) {
|
|
228
|
+
return `${windowId.replace(/[^A-Za-z0-9_.-]/g, "_")}.json`;
|
|
229
|
+
}
|
|
230
|
+
function readEvents(storeDir) {
|
|
231
|
+
const eventsPath = storePaths(storeDir).events;
|
|
232
|
+
if (!existsSync(eventsPath)) return [];
|
|
233
|
+
return readFileSync(eventsPath, "utf8").split(/\r?\n/).filter(Boolean).map((line) => parseJsonObject(line, "phase lab event"));
|
|
234
|
+
}
|
|
235
|
+
function writeJson(path, data) {
|
|
236
|
+
writeFileSync(path, stableStringify(data), "utf8");
|
|
237
|
+
}
|
|
238
|
+
function windowIndex(windowId, sequence, events) {
|
|
239
|
+
const residual = events.reduce(
|
|
240
|
+
(total, event) => total + residualDebt(numericDict(event.residual_summary)),
|
|
241
|
+
0
|
|
242
|
+
);
|
|
243
|
+
return {
|
|
244
|
+
accepted: true,
|
|
245
|
+
accepted_event_count: events.filter((event) => event.accepted === true).length,
|
|
246
|
+
candidate_only_event_count: events.filter(
|
|
247
|
+
(event) => event.candidate_only === true
|
|
248
|
+
).length,
|
|
249
|
+
event_count: events.length,
|
|
250
|
+
event_ids: events.map((event) => String(event.event_id)),
|
|
251
|
+
missing_obligation_count: events.reduce(
|
|
252
|
+
(total, event) => total + stringList(event.missing_obligations).length,
|
|
253
|
+
0
|
|
254
|
+
),
|
|
255
|
+
positive_contribution_event_count: events.filter(
|
|
256
|
+
(event) => event.positive_contribution_allowed === true
|
|
257
|
+
).length,
|
|
258
|
+
reasons: ["window index preserves event residuals without settling claims"],
|
|
259
|
+
residual_debt: residual,
|
|
260
|
+
sequence,
|
|
261
|
+
settled: false,
|
|
262
|
+
settled_event_count: 0,
|
|
263
|
+
window_id: windowId
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
function readWindowIndexes(storeDir) {
|
|
267
|
+
const windowsDir = storePaths(storeDir).windows;
|
|
268
|
+
if (!existsSync(windowsDir)) return [];
|
|
269
|
+
return readdirSync(windowsDir).filter((name) => name !== "latest.json" && name.endsWith(".json")).sort().map(
|
|
270
|
+
(name) => parseJsonObject(readFileSync(join(windowsDir, name), "utf8"), "window")
|
|
271
|
+
);
|
|
272
|
+
}
|
|
273
|
+
function selectWindow(storeDir, selector = "latest") {
|
|
274
|
+
const windows = readWindowIndexes(storeDir);
|
|
275
|
+
if (windows.length === 0) throw new Error("phase lab store has no windows");
|
|
276
|
+
let selected;
|
|
277
|
+
if (selector === "latest" || selector === "all") {
|
|
278
|
+
selected = windows[windows.length - 1];
|
|
279
|
+
} else if (selector === "previous") {
|
|
280
|
+
selected = windows.length > 1 ? windows[windows.length - 2] : windows[windows.length - 1];
|
|
281
|
+
} else {
|
|
282
|
+
selected = windows.find((window) => window.window_id === selector);
|
|
283
|
+
}
|
|
284
|
+
if (!selected)
|
|
285
|
+
throw new Error(`unknown phase lab window ${JSON.stringify(selector)}`);
|
|
286
|
+
const selectedId = String(selected.window_id);
|
|
287
|
+
const events = selector === "all" ? readEvents(storeDir) : readEvents(storeDir).filter((event) => event.window_id === selectedId);
|
|
288
|
+
return { index: selected, events };
|
|
289
|
+
}
|
|
290
|
+
function writeManifest(storeDir) {
|
|
291
|
+
const paths = storePaths(storeDir);
|
|
292
|
+
mkdirSync(paths.windows, { recursive: true });
|
|
293
|
+
const windows = readWindowIndexes(storeDir);
|
|
294
|
+
const events = readEvents(storeDir);
|
|
295
|
+
const manifest = {
|
|
296
|
+
accepted: true,
|
|
297
|
+
database_path: "events.jsonl",
|
|
298
|
+
event_count: events.length,
|
|
299
|
+
latest_window_id: windows.length > 0 ? String(windows[windows.length - 1]?.window_id ?? "") : null,
|
|
300
|
+
reasons: ["phase lab store is local and non-executing"],
|
|
301
|
+
safety_invariants: PHASE_LAB_SAFETY,
|
|
302
|
+
schema_version: "phase-lab-store-v1",
|
|
303
|
+
settled: false,
|
|
304
|
+
store_id: "phase-lab-store",
|
|
305
|
+
store_path: basename(storeDir),
|
|
306
|
+
window_count: windows.length
|
|
307
|
+
};
|
|
308
|
+
writeJson(paths.manifest, manifest);
|
|
309
|
+
return manifest;
|
|
310
|
+
}
|
|
311
|
+
function initPhaseLabStore(outputDir) {
|
|
312
|
+
const paths = storePaths(outputDir);
|
|
313
|
+
mkdirSync(paths.windows, { recursive: true });
|
|
314
|
+
if (!existsSync(paths.events)) writeFileSync(paths.events, "", "utf8");
|
|
315
|
+
return writeManifest(outputDir);
|
|
316
|
+
}
|
|
317
|
+
function ingestPayloads(storeDir, payloads) {
|
|
318
|
+
initPhaseLabStore(storeDir);
|
|
319
|
+
const sequence = readWindowIndexes(storeDir).length;
|
|
320
|
+
const offset = readEvents(storeDir).length;
|
|
321
|
+
const windowId = `phase-window:${String(sequence).padStart(4, "0")}`;
|
|
322
|
+
const events = payloads.map(
|
|
323
|
+
(item, index2) => eventFromPayload(
|
|
324
|
+
item.payload,
|
|
325
|
+
windowId,
|
|
326
|
+
offset + index2,
|
|
327
|
+
item.path,
|
|
328
|
+
item.sourceKind
|
|
329
|
+
)
|
|
330
|
+
);
|
|
331
|
+
const index = windowIndex(windowId, sequence, events);
|
|
332
|
+
const paths = storePaths(storeDir);
|
|
333
|
+
const append = events.map((event) => JSON.stringify(sortJson(event))).join("\n");
|
|
334
|
+
if (append) {
|
|
335
|
+
writeFileSync(paths.events, `${append}
|
|
336
|
+
`, { encoding: "utf8", flag: "a" });
|
|
337
|
+
}
|
|
338
|
+
writeJson(join(paths.windows, windowFileName(windowId)), index);
|
|
339
|
+
writeJson(join(paths.windows, "latest.json"), index);
|
|
340
|
+
const manifest = writeManifest(storeDir);
|
|
341
|
+
return {
|
|
342
|
+
accepted: events.length > 0,
|
|
343
|
+
content_treated_as_data: true,
|
|
344
|
+
executed_command_count: 0,
|
|
345
|
+
ingested_events: events,
|
|
346
|
+
reasons: [
|
|
347
|
+
"ingested files were stored as inert local data",
|
|
348
|
+
"no embedded command, safe_command, network, repository, or model action was executed"
|
|
349
|
+
],
|
|
350
|
+
rejected_paths: [],
|
|
351
|
+
report_id: `phase-lab-ingest:${windowId}`,
|
|
352
|
+
settled: false,
|
|
353
|
+
store_manifest: manifest,
|
|
354
|
+
window: index,
|
|
355
|
+
workflow_usable: true
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
function ingestPhaseLabReport(storeDir, reportPath) {
|
|
359
|
+
return ingestPayloads(storeDir, [
|
|
360
|
+
{ payload: readJsonFile(reportPath, "phase lab report"), path: reportPath }
|
|
361
|
+
]);
|
|
362
|
+
}
|
|
363
|
+
function ingestPhaseLabPacket(storeDir, packetPath) {
|
|
364
|
+
return ingestPayloads(storeDir, [
|
|
365
|
+
{
|
|
366
|
+
payload: readJsonFile(packetPath, "phase lab packet"),
|
|
367
|
+
path: packetPath,
|
|
368
|
+
sourceKind: "packet-exchange"
|
|
369
|
+
}
|
|
370
|
+
]);
|
|
371
|
+
}
|
|
372
|
+
function ingestPhaseLabFiles(storeDir, reportPaths = [], packetPaths = []) {
|
|
373
|
+
const payloads = [
|
|
374
|
+
...reportPaths.map((path) => ({
|
|
375
|
+
payload: readJsonFile(path, "phase lab report"),
|
|
376
|
+
path
|
|
377
|
+
})),
|
|
378
|
+
...packetPaths.map((path) => ({
|
|
379
|
+
payload: readJsonFile(path, "phase lab packet"),
|
|
380
|
+
path,
|
|
381
|
+
sourceKind: "packet-exchange"
|
|
382
|
+
}))
|
|
383
|
+
];
|
|
384
|
+
if (payloads.length === 0) {
|
|
385
|
+
throw new Error("provide at least one Phase Lab report or packet");
|
|
386
|
+
}
|
|
387
|
+
return ingestPayloads(storeDir, payloads);
|
|
388
|
+
}
|
|
389
|
+
function ingestPhaseLabDirectory(storeDir, directory) {
|
|
390
|
+
if (!existsSync(directory))
|
|
391
|
+
throw new Error(`phase lab directory does not exist: ${directory}`);
|
|
392
|
+
const payloads = readdirSync(directory).filter((name) => name.toLowerCase().endsWith(".json")).sort().map((name) => {
|
|
393
|
+
const path = join(directory, name);
|
|
394
|
+
return { payload: readJsonFile(path, "phase lab directory item"), path };
|
|
395
|
+
});
|
|
396
|
+
return ingestPayloads(storeDir, payloads);
|
|
397
|
+
}
|
|
398
|
+
function listPhaseLabWindows(storeDir) {
|
|
399
|
+
return {
|
|
400
|
+
settled: false,
|
|
401
|
+
store_manifest: writeManifest(storeDir),
|
|
402
|
+
windows: readWindowIndexes(storeDir)
|
|
403
|
+
};
|
|
404
|
+
}
|
|
405
|
+
function eligibilityBlockers(event) {
|
|
406
|
+
const joined = [
|
|
407
|
+
event.source_kind,
|
|
408
|
+
...stringList(event.missing_obligations),
|
|
409
|
+
...stringList(event.candidate_only_reasons),
|
|
410
|
+
...stringList(event.settled_blockers),
|
|
411
|
+
...stringList(event.reasons)
|
|
412
|
+
].join(" ").toLowerCase();
|
|
413
|
+
const blockers = [];
|
|
414
|
+
const markers = {
|
|
415
|
+
"authority-invalid": [
|
|
416
|
+
"authority-invalid",
|
|
417
|
+
"missing authority",
|
|
418
|
+
"authority"
|
|
419
|
+
],
|
|
420
|
+
"candidate-only": ["candidate-only"],
|
|
421
|
+
"hash-invalid": ["hash-invalid", "digest mismatch"],
|
|
422
|
+
"raw-external-volume": ["general-intake", "raw-external"],
|
|
423
|
+
"rollback-missing": ["rollback", "safe abort"],
|
|
424
|
+
"salience-obstruction": ["salience", "queue occupation"],
|
|
425
|
+
stale: ["stale", "expired"],
|
|
426
|
+
"verification-blocked": [
|
|
427
|
+
"missing evidence",
|
|
428
|
+
"missing verifier",
|
|
429
|
+
"verification"
|
|
430
|
+
]
|
|
431
|
+
};
|
|
432
|
+
for (const [blocker, needles] of Object.entries(markers)) {
|
|
433
|
+
if (needles.some((needle) => joined.includes(needle)))
|
|
434
|
+
blockers.push(blocker);
|
|
435
|
+
}
|
|
436
|
+
if (event.candidate_only === true) blockers.push("candidate-only");
|
|
437
|
+
return dedupeSorted(blockers);
|
|
438
|
+
}
|
|
439
|
+
function nodeFromEvent(event) {
|
|
440
|
+
const blockers = eligibilityBlockers(event);
|
|
441
|
+
const eligible = event.positive_contribution_allowed === true && blockers.length === 0;
|
|
442
|
+
const status = eligible ? "accepted" : event.candidate_only === true ? "candidate-only" : "diagnostic";
|
|
443
|
+
return {
|
|
444
|
+
accepted: event.accepted === true,
|
|
445
|
+
content_digest: String(event.content_digest ?? ""),
|
|
446
|
+
contribution: {
|
|
447
|
+
candidate_only: !eligible,
|
|
448
|
+
non_contributing_reason: eligible ? "" : "eligibility blockers prevent positive contribution",
|
|
449
|
+
positive_contribution: eligible,
|
|
450
|
+
settled: false,
|
|
451
|
+
status
|
|
452
|
+
},
|
|
453
|
+
eligibility: {
|
|
454
|
+
accepted_or_certificate_admissible: event.accepted === true,
|
|
455
|
+
agent_text_not_treated_as_evidence: event.source_kind !== "agent-text-only",
|
|
456
|
+
authority_valid: !blockers.includes("authority-invalid"),
|
|
457
|
+
blockers,
|
|
458
|
+
eligible,
|
|
459
|
+
hash_valid: !blockers.includes("hash-invalid"),
|
|
460
|
+
not_raw_external_volume: !blockers.includes("raw-external-volume"),
|
|
461
|
+
not_registry_metadata_only: event.source_kind !== "registry-metadata",
|
|
462
|
+
not_salience_blocked: !blockers.includes("salience-obstruction"),
|
|
463
|
+
not_stale: !blockers.includes("stale"),
|
|
464
|
+
not_verification_blocked: !blockers.includes("verification-blocked"),
|
|
465
|
+
residuals_preserved: true,
|
|
466
|
+
retrievable: Boolean(event.content_digest),
|
|
467
|
+
rollback_available_or_not_required: !blockers.includes("rollback-missing"),
|
|
468
|
+
within_validity_domain: true
|
|
469
|
+
},
|
|
470
|
+
missing_obligations: stringList(event.missing_obligations),
|
|
471
|
+
node_id: `node:${String(event.content_digest ?? "").slice(0, 12)}`,
|
|
472
|
+
operationally_usable: event.operationally_usable === true,
|
|
473
|
+
reasons: stringList(event.reasons),
|
|
474
|
+
residual_summary: numericDict(event.residual_summary),
|
|
475
|
+
schema_hint: String(event.schema_hint ?? "UnknownPICReport"),
|
|
476
|
+
settled: false,
|
|
477
|
+
source_event_id: String(event.event_id ?? ""),
|
|
478
|
+
source_kind: String(event.source_kind ?? "unknown-report"),
|
|
479
|
+
workflow_usable: event.workflow_usable === true
|
|
480
|
+
};
|
|
481
|
+
}
|
|
482
|
+
function extractEdges(payload) {
|
|
483
|
+
const edges = [];
|
|
484
|
+
for (const key of ["edges", "edge_witnesses", "edge_certificates"]) {
|
|
485
|
+
edges.push(...asRecords(payload[key]));
|
|
486
|
+
}
|
|
487
|
+
const registry = asRecord(payload.registry);
|
|
488
|
+
if (registry) edges.push(...extractEdges(registry));
|
|
489
|
+
const content = asRecord(payload.content);
|
|
490
|
+
if (content) edges.push(...extractEdges(content));
|
|
491
|
+
return edges;
|
|
492
|
+
}
|
|
493
|
+
function nodeIdForRef(ref, nodes) {
|
|
494
|
+
if (!ref) return void 0;
|
|
495
|
+
return nodes.map((node) => String(node.node_id)).find((nodeId) => {
|
|
496
|
+
const node = nodes.find((item) => item.node_id === nodeId);
|
|
497
|
+
return node && [
|
|
498
|
+
node.node_id,
|
|
499
|
+
node.content_digest,
|
|
500
|
+
String(node.content_digest).slice(0, 12),
|
|
501
|
+
node.source_event_id
|
|
502
|
+
].map(String).includes(ref);
|
|
503
|
+
});
|
|
504
|
+
}
|
|
505
|
+
function nodePositive(nodeId, nodes) {
|
|
506
|
+
const node = nodes.find((item) => item.node_id === nodeId);
|
|
507
|
+
return asRecord(node?.contribution)?.positive_contribution === true;
|
|
508
|
+
}
|
|
509
|
+
function edgesFromEvents(nodes, events) {
|
|
510
|
+
const edges = [];
|
|
511
|
+
events.forEach((event, eventIndex) => {
|
|
512
|
+
const node = nodes[eventIndex];
|
|
513
|
+
if (!node) return;
|
|
514
|
+
extractEdges(asRecord(event.payload) ?? {}).forEach((edge, index) => {
|
|
515
|
+
const sourceIds = stringList(edge.source_packet_ids).map((ref) => nodeIdForRef(ref, nodes)).filter((item) => Boolean(item));
|
|
516
|
+
const target = nodeIdForRef(String(edge.target_packet_id ?? ""), nodes) ?? String(node.node_id);
|
|
517
|
+
const evidenceRefs = stringList(edge.evidence_refs);
|
|
518
|
+
const accepted = edge.accepted === true || event.accepted === true;
|
|
519
|
+
const evidenceSupported = accepted && evidenceRefs.length > 0;
|
|
520
|
+
const positive = evidenceSupported && sourceIds.every((source) => nodePositive(source, nodes)) && nodePositive(target, nodes);
|
|
521
|
+
const edgeId = String(
|
|
522
|
+
edge.edge_id ?? `edge:${String(node.node_id)}:${index}`
|
|
523
|
+
);
|
|
524
|
+
edges.push({
|
|
525
|
+
accepted,
|
|
526
|
+
contribution: {
|
|
527
|
+
candidate_only: !positive,
|
|
528
|
+
non_contributing_reason: positive ? "" : "edge lacks accepted evidence support",
|
|
529
|
+
positive_contribution: positive,
|
|
530
|
+
settled: false,
|
|
531
|
+
status: positive ? "accepted" : "diagnostic"
|
|
532
|
+
},
|
|
533
|
+
edge_id: edgeId,
|
|
534
|
+
evidence: {
|
|
535
|
+
edge_certificate_refs: stringList(edge.edge_certificate_refs),
|
|
536
|
+
evidence_refs: evidenceRefs,
|
|
537
|
+
evidence_supported: evidenceSupported,
|
|
538
|
+
missing_evidence: evidenceSupported ? [] : ["edge evidence refs required"],
|
|
539
|
+
verifier_resolution_refs: stringList(edge.verifier_resolution_refs)
|
|
540
|
+
},
|
|
541
|
+
reasons: ["edge extracted from inert report data"],
|
|
542
|
+
relation_type: String(
|
|
543
|
+
edge.edge_type ?? edge.relation_type ?? "semantic-dependency"
|
|
544
|
+
),
|
|
545
|
+
residual_summary: numericDict(event.residual_summary),
|
|
546
|
+
settled: false,
|
|
547
|
+
source_node_ids: sourceIds.length > 0 ? sourceIds : [String(node.node_id)],
|
|
548
|
+
target_node_id: target
|
|
549
|
+
});
|
|
550
|
+
});
|
|
551
|
+
});
|
|
552
|
+
return edges;
|
|
553
|
+
}
|
|
554
|
+
function buildEffectivePacketGraph(input) {
|
|
555
|
+
const events = Array.isArray(input) ? input : Array.isArray(input.events) ? input.events : [];
|
|
556
|
+
const graphId = Array.isArray(input) ? "effective-packet-graph" : String(input.graph_id ?? "effective-packet-graph");
|
|
557
|
+
const sourceWindowId = Array.isArray(input) ? "adhoc" : String(input.source_window_id ?? "adhoc");
|
|
558
|
+
const normalized = events.map(
|
|
559
|
+
(event, index) => event.event_id ? event : eventFromPayload(event, sourceWindowId, index, void 0, void 0)
|
|
560
|
+
);
|
|
561
|
+
const nodes = normalized.map(nodeFromEvent);
|
|
562
|
+
const edges = edgesFromEvents(nodes, normalized);
|
|
563
|
+
const nodeCountByStatus = {};
|
|
564
|
+
for (const node of nodes) {
|
|
565
|
+
const status = String(asRecord(node.contribution)?.status ?? "diagnostic");
|
|
566
|
+
nodeCountByStatus[status] = (nodeCountByStatus[status] ?? 0) + 1;
|
|
567
|
+
}
|
|
568
|
+
const edgeCountByRelation = {};
|
|
569
|
+
for (const edge of edges) {
|
|
570
|
+
const relation = String(edge.relation_type ?? "semantic-dependency");
|
|
571
|
+
edgeCountByRelation[relation] = (edgeCountByRelation[relation] ?? 0) + 1;
|
|
572
|
+
}
|
|
573
|
+
const mergedResidual = {};
|
|
574
|
+
for (const node of nodes) {
|
|
575
|
+
for (const [key, value] of Object.entries(
|
|
576
|
+
numericDict(node.residual_summary)
|
|
577
|
+
)) {
|
|
578
|
+
mergedResidual[key] = (mergedResidual[key] ?? 0) + value;
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
const acceptedPacketCapital = nodes.filter(
|
|
582
|
+
(node) => asRecord(node.contribution)?.positive_contribution === true
|
|
583
|
+
).length;
|
|
584
|
+
return {
|
|
585
|
+
accepted: nodes.length > 0,
|
|
586
|
+
accepted_packet_capital: acceptedPacketCapital,
|
|
587
|
+
candidate_only_packets: nodes.filter(
|
|
588
|
+
(node) => asRecord(node.contribution)?.candidate_only === true
|
|
589
|
+
).length,
|
|
590
|
+
edge_count_by_relation: Object.fromEntries(
|
|
591
|
+
Object.entries(edgeCountByRelation).sort()
|
|
592
|
+
),
|
|
593
|
+
edges,
|
|
594
|
+
graph_id: graphId,
|
|
595
|
+
graph_safety_boundary: GRAPH_SAFETY,
|
|
596
|
+
missing_edge_evidence: edges.filter(
|
|
597
|
+
(edge) => edge.accepted === true && asRecord(edge.evidence)?.evidence_supported !== true
|
|
598
|
+
).map((edge) => String(edge.edge_id)),
|
|
599
|
+
node_count_by_status: Object.fromEntries(
|
|
600
|
+
Object.entries(nodeCountByStatus).sort()
|
|
601
|
+
),
|
|
602
|
+
nodes,
|
|
603
|
+
non_contributing_volume: nodes.filter(
|
|
604
|
+
(node) => asRecord(node.contribution)?.positive_contribution !== true
|
|
605
|
+
).length,
|
|
606
|
+
operationally_usable: acceptedPacketCapital > 0,
|
|
607
|
+
reasons: [
|
|
608
|
+
"effective graph separates positive contribution from diagnostic volume",
|
|
609
|
+
"raw packet count does not increase positive phase metrics"
|
|
610
|
+
],
|
|
611
|
+
rejected_or_quarantined_packets: nodes.filter(
|
|
612
|
+
(node) => ["rejected", "quarantined"].includes(
|
|
613
|
+
String(asRecord(node.contribution)?.status ?? "")
|
|
614
|
+
)
|
|
615
|
+
).length,
|
|
616
|
+
residual_summary: {
|
|
617
|
+
candidate_only_reasons: dedupeSorted(
|
|
618
|
+
normalized.flatMap((event) => stringList(event.candidate_only_reasons))
|
|
619
|
+
),
|
|
620
|
+
missing_obligation_count: nodes.reduce(
|
|
621
|
+
(total, node) => total + stringList(node.missing_obligations).length,
|
|
622
|
+
0
|
|
623
|
+
),
|
|
624
|
+
residual_debt: residualDebt(mergedResidual),
|
|
625
|
+
residual_summary: Object.fromEntries(
|
|
626
|
+
Object.entries(mergedResidual).sort()
|
|
627
|
+
),
|
|
628
|
+
settled_blockers: dedupeSorted(
|
|
629
|
+
normalized.flatMap((event) => [
|
|
630
|
+
...stringList(event.settled_blockers),
|
|
631
|
+
...stringList(event.missing_obligations)
|
|
632
|
+
])
|
|
633
|
+
)
|
|
634
|
+
},
|
|
635
|
+
semantic_edge_witnesses: edges.map((edge) => asRecord(edge.evidence)).filter(
|
|
636
|
+
(evidence) => Boolean(evidence?.evidence_supported)
|
|
637
|
+
),
|
|
638
|
+
settled: false,
|
|
639
|
+
source_window_id: sourceWindowId,
|
|
640
|
+
stale_or_unsafe_packets: nodes.filter(
|
|
641
|
+
(node) => stringList(asRecord(node.eligibility)?.blockers).length > 0
|
|
642
|
+
).map((node) => String(node.node_id)),
|
|
643
|
+
workflow_usable: true
|
|
644
|
+
};
|
|
645
|
+
}
|
|
646
|
+
function positiveEdges(graph) {
|
|
647
|
+
return asRecords(graph.edges).filter(
|
|
648
|
+
(edge) => asRecord(edge.contribution)?.positive_contribution === true && asRecord(edge.evidence)?.evidence_supported === true
|
|
649
|
+
);
|
|
650
|
+
}
|
|
651
|
+
function observePhaseWindow(window, events, graph) {
|
|
652
|
+
const effectiveNodeCount = numeric(graph.accepted_packet_capital);
|
|
653
|
+
const effectiveEdgeCount = positiveEdges(graph).length;
|
|
654
|
+
const executionAvailablePathCount = detectExecutionAvailablePaths(graph).accepted_path_count;
|
|
655
|
+
const closureWitnessCount = asRecords(
|
|
656
|
+
detectAutocatalyticClosure(graph).closure_witnesses
|
|
657
|
+
).length;
|
|
658
|
+
const total = Math.max(1, events.length);
|
|
659
|
+
const acceptedPacketCount = events.filter(
|
|
660
|
+
(event) => event.accepted === true
|
|
661
|
+
).length;
|
|
662
|
+
const missingObligationCount = events.reduce(
|
|
663
|
+
(sum, event) => sum + stringList(event.missing_obligations).length,
|
|
664
|
+
0
|
|
665
|
+
);
|
|
666
|
+
const residual = numeric(asRecord(graph.residual_summary)?.residual_debt);
|
|
667
|
+
const candidateOnlyCount = events.filter(
|
|
668
|
+
(event) => event.candidate_only === true
|
|
669
|
+
).length;
|
|
670
|
+
const observation = {
|
|
671
|
+
accepted: events.length > 0,
|
|
672
|
+
accepted_packet_count: acceptedPacketCount,
|
|
673
|
+
alt_certified_capital_count: events.filter(
|
|
674
|
+
(event) => String(event.source_kind).includes("alt") && event.positive_contribution_allowed === true
|
|
675
|
+
).length,
|
|
676
|
+
alt_liquidity_candidate_count: events.filter(
|
|
677
|
+
(event) => String(event.source_kind).includes("alt")
|
|
678
|
+
).length,
|
|
679
|
+
autocatalytic_closure_score: effectiveNodeCount > 0 ? closureWitnessCount / effectiveNodeCount : 0,
|
|
680
|
+
basin_reachability_proxy: {
|
|
681
|
+
effective_node_count: effectiveNodeCount,
|
|
682
|
+
execution_available_path_count: executionAvailablePathCount,
|
|
683
|
+
reachability_proxy: executionAvailablePathCount / Math.max(1, effectiveNodeCount)
|
|
684
|
+
},
|
|
685
|
+
bottleneck_count_by_type: Object.fromEntries(
|
|
686
|
+
asRecords(graph.nodes).flatMap((node) => stringList(asRecord(node.eligibility)?.blockers)).reduce((map, blocker) => {
|
|
687
|
+
map.set(blocker, (map.get(blocker) ?? 0) + 1);
|
|
688
|
+
return map;
|
|
689
|
+
}, /* @__PURE__ */ new Map()).entries()
|
|
690
|
+
),
|
|
691
|
+
candidate_only_packet_count: candidateOnlyCount,
|
|
692
|
+
closure_witness_count: closureWitnessCount,
|
|
693
|
+
components: [
|
|
694
|
+
{
|
|
695
|
+
component: "accepted_packet_count",
|
|
696
|
+
diagnostic_only: false,
|
|
697
|
+
distance: 0,
|
|
698
|
+
positive_contribution_source: "effective-graph-only",
|
|
699
|
+
threshold: 0,
|
|
700
|
+
value: acceptedPacketCount
|
|
701
|
+
},
|
|
702
|
+
{
|
|
703
|
+
component: "raw_volume",
|
|
704
|
+
diagnostic_only: true,
|
|
705
|
+
distance: 0,
|
|
706
|
+
positive_contribution_source: "diagnostic-only",
|
|
707
|
+
threshold: 0,
|
|
708
|
+
value: events.length
|
|
709
|
+
}
|
|
710
|
+
],
|
|
711
|
+
effective_edge_count: effectiveEdgeCount,
|
|
712
|
+
effective_node_count: effectiveNodeCount,
|
|
713
|
+
execution_available_path_count: executionAvailablePathCount,
|
|
714
|
+
false_liquidity_load: {
|
|
715
|
+
candidate_count: candidateOnlyCount,
|
|
716
|
+
certified_count: 0,
|
|
717
|
+
load: candidateOnlyCount / total
|
|
718
|
+
},
|
|
719
|
+
missing_obligation_count: missingObligationCount,
|
|
720
|
+
observation_id: "phase-window-observation",
|
|
721
|
+
operationally_usable: effectiveNodeCount > 0,
|
|
722
|
+
oracle_truth_proven: false,
|
|
723
|
+
packet_candidate_count: events.length,
|
|
724
|
+
phase_gap_vector: {
|
|
725
|
+
closure: Math.max(0, 1 - closureWitnessCount),
|
|
726
|
+
effective_edges: Math.max(0, 1 - effectiveEdgeCount),
|
|
727
|
+
effective_nodes: Math.max(0, 1 - effectiveNodeCount),
|
|
728
|
+
execution_paths: Math.max(0, 1 - executionAvailablePathCount)
|
|
729
|
+
},
|
|
730
|
+
physical_truth_proven: false,
|
|
731
|
+
proves_physical_or_oracle_truth: false,
|
|
732
|
+
proves_real_asi: false,
|
|
733
|
+
protocol_relative: true,
|
|
734
|
+
protocol_relative_only: true,
|
|
735
|
+
raw_external_volume_diagnostic_only: true,
|
|
736
|
+
real_asi_proof: false,
|
|
737
|
+
reasons: [
|
|
738
|
+
"window observation is protocol-relative only",
|
|
739
|
+
"raw external volume is diagnostic only"
|
|
740
|
+
],
|
|
741
|
+
residual_debt: residual,
|
|
742
|
+
salience_obstruction_load: {
|
|
743
|
+
blocked_count: candidateOnlyCount,
|
|
744
|
+
load: candidateOnlyCount / total,
|
|
745
|
+
total_count: events.length
|
|
746
|
+
},
|
|
747
|
+
settled: false,
|
|
748
|
+
settled_packet_count: 0,
|
|
749
|
+
threshold_distance: Math.max(0, 1 - effectiveNodeCount) + Math.max(0, 1 - effectiveEdgeCount) + Math.max(0, 1 - closureWitnessCount) + Math.max(0, 1 - executionAvailablePathCount),
|
|
750
|
+
verification_backlog: missingObligationCount,
|
|
751
|
+
verification_throughput: {
|
|
752
|
+
accepted_count: acceptedPacketCount,
|
|
753
|
+
backlog_count: missingObligationCount,
|
|
754
|
+
throughput_ratio: acceptedPacketCount / total
|
|
755
|
+
},
|
|
756
|
+
waste_load: {
|
|
757
|
+
load: numeric(graph.non_contributing_volume) / total,
|
|
758
|
+
non_contributing_volume: numeric(graph.non_contributing_volume),
|
|
759
|
+
total_volume: events.length
|
|
760
|
+
},
|
|
761
|
+
window: {
|
|
762
|
+
event_count: numeric(window.event_count),
|
|
763
|
+
event_ids: stringList(window.event_ids),
|
|
764
|
+
sequence: numeric(window.sequence),
|
|
765
|
+
window_id: String(window.window_id ?? "phase-window")
|
|
766
|
+
},
|
|
767
|
+
workflow_usable: true,
|
|
768
|
+
workflow_usable_packet_count: events.filter(
|
|
769
|
+
(event) => event.workflow_usable === true
|
|
770
|
+
).length
|
|
771
|
+
};
|
|
772
|
+
return observation;
|
|
773
|
+
}
|
|
774
|
+
function comparePhaseWindows(baseline, candidate) {
|
|
775
|
+
const metricDelta = {
|
|
776
|
+
closure_witness_count: numeric(candidate.closure_witness_count) - numeric(baseline.closure_witness_count),
|
|
777
|
+
effective_edge_count: numeric(candidate.effective_edge_count) - numeric(baseline.effective_edge_count),
|
|
778
|
+
effective_node_count: numeric(candidate.effective_node_count) - numeric(baseline.effective_node_count),
|
|
779
|
+
execution_available_path_count: numeric(candidate.execution_available_path_count) - numeric(baseline.execution_available_path_count),
|
|
780
|
+
residual_debt: numeric(candidate.residual_debt) - numeric(baseline.residual_debt)
|
|
781
|
+
};
|
|
782
|
+
return {
|
|
783
|
+
accepted: true,
|
|
784
|
+
baseline_window_id: String(asRecord(baseline.window)?.window_id ?? ""),
|
|
785
|
+
candidate_window_id: String(asRecord(candidate.window)?.window_id ?? ""),
|
|
786
|
+
comparison_id: "phase-window-comparison",
|
|
787
|
+
diagnostic_only_components: ["packet_candidate_count", "raw_volume"],
|
|
788
|
+
metric_delta: metricDelta,
|
|
789
|
+
positive_progress_components: Object.entries(metricDelta).filter(([key, value]) => key !== "residual_debt" && value > 0).map(([key]) => key),
|
|
790
|
+
reasons: ["comparison preserves protocol-relative diagnostic status"],
|
|
791
|
+
settled: false,
|
|
792
|
+
workflow_usable: true
|
|
793
|
+
};
|
|
794
|
+
}
|
|
795
|
+
function detectAutocatalyticClosure(graph) {
|
|
796
|
+
const closureWitnesses = [];
|
|
797
|
+
const defects = [];
|
|
798
|
+
for (const edge of positiveEdges(graph)) {
|
|
799
|
+
const sources = stringList(edge.source_node_ids);
|
|
800
|
+
const target = String(edge.target_node_id ?? "");
|
|
801
|
+
if (sources.includes(target)) {
|
|
802
|
+
const witnessId = `closure-witness:${String(edge.edge_id)}`;
|
|
803
|
+
closureWitnesses.push({
|
|
804
|
+
accepted: true,
|
|
805
|
+
edge_ids: [String(edge.edge_id)],
|
|
806
|
+
evidence_supported: true,
|
|
807
|
+
execution_available: false,
|
|
808
|
+
packet_ids: dedupeSorted([...sources, target]),
|
|
809
|
+
productive: true,
|
|
810
|
+
protocol_relative_only: true,
|
|
811
|
+
reasons: [
|
|
812
|
+
"witness is evidence-supported within the effective graph",
|
|
813
|
+
"witness remains diagnostic until finite threshold checks pass"
|
|
814
|
+
],
|
|
815
|
+
settled: false,
|
|
816
|
+
witness_id: witnessId,
|
|
817
|
+
witness_kind: "autocatalytic-closure"
|
|
818
|
+
});
|
|
819
|
+
}
|
|
820
|
+
}
|
|
821
|
+
for (const edge of asRecords(graph.edges)) {
|
|
822
|
+
if (edge.accepted === true && asRecord(edge.evidence)?.evidence_supported !== true) {
|
|
823
|
+
defects.push({
|
|
824
|
+
defect_id: `closure-defect:${String(edge.edge_id)}`,
|
|
825
|
+
defect_type: "missing-edge-evidence",
|
|
826
|
+
packet_or_edge_id: String(edge.edge_id),
|
|
827
|
+
residual_preserved: true
|
|
828
|
+
});
|
|
829
|
+
}
|
|
830
|
+
}
|
|
831
|
+
const status = closureWitnesses.length > 0 && defects.length === 0 ? "candidate" : "abstain";
|
|
832
|
+
return {
|
|
833
|
+
accepted: status === "candidate",
|
|
834
|
+
certificate_candidate: {
|
|
835
|
+
abstention_reasons: closureWitnesses.length > 0 ? [] : [
|
|
836
|
+
{
|
|
837
|
+
missing_evidence_refs: [],
|
|
838
|
+
reason: "closure requires evidence-supported accepted edges",
|
|
839
|
+
reason_id: "closure-abstain:no-evidence-supported-cycle"
|
|
840
|
+
}
|
|
841
|
+
],
|
|
842
|
+
accepted: status === "candidate",
|
|
843
|
+
certificate_id: "closure-certificate-candidate",
|
|
844
|
+
certificate_status: status,
|
|
845
|
+
defects,
|
|
846
|
+
reasons: [
|
|
847
|
+
"closure candidate is not automatically settled",
|
|
848
|
+
"candidate-only cycles do not count"
|
|
849
|
+
],
|
|
850
|
+
settled: false,
|
|
851
|
+
witness_ids: closureWitnesses.map(
|
|
852
|
+
(witness) => String(witness.witness_id)
|
|
853
|
+
)
|
|
854
|
+
},
|
|
855
|
+
closure_score: closureWitnesses.length / Math.max(1, asRecords(graph.nodes).length),
|
|
856
|
+
closure_witnesses: closureWitnesses,
|
|
857
|
+
defects,
|
|
858
|
+
executable_witnesses: [],
|
|
859
|
+
graph_id: String(graph.graph_id ?? "effective-packet-graph"),
|
|
860
|
+
operationally_usable: status === "candidate",
|
|
861
|
+
productive_witnesses: closureWitnesses.map((witness) => ({
|
|
862
|
+
accepted: true,
|
|
863
|
+
packet_ids: witness.packet_ids,
|
|
864
|
+
productive_edge_ids: witness.edge_ids,
|
|
865
|
+
productivity_lower_bound: 0.1,
|
|
866
|
+
reasons: [
|
|
867
|
+
"self-supporting evidence edge is productive in declared scope"
|
|
868
|
+
],
|
|
869
|
+
settled: false,
|
|
870
|
+
witness_id: `productive:${String(witness.witness_id)}`
|
|
871
|
+
})),
|
|
872
|
+
reasons: ["closure detection does not execute or settle paths"],
|
|
873
|
+
report_id: "autocatalytic-closure-report",
|
|
874
|
+
settled: false,
|
|
875
|
+
support_hyperpaths: [],
|
|
876
|
+
workflow_usable: true
|
|
877
|
+
};
|
|
878
|
+
}
|
|
879
|
+
function detectExecutionAvailablePaths(graph) {
|
|
880
|
+
const paths = positiveEdges(graph).map((edge) => {
|
|
881
|
+
const pathId = `execution-path:${String(edge.edge_id)}`;
|
|
882
|
+
const reasons = [
|
|
883
|
+
"execution authority is not granted by PIC-TS",
|
|
884
|
+
"receiver context and action boundary remain diagnostic"
|
|
885
|
+
];
|
|
886
|
+
return {
|
|
887
|
+
accepted: false,
|
|
888
|
+
action_boundary_requirements: [
|
|
889
|
+
{
|
|
890
|
+
requirement_id: `${pathId}:authority`,
|
|
891
|
+
requirement_type: "explicit-scope-bounded-authority",
|
|
892
|
+
residual: "host runtime authority required",
|
|
893
|
+
satisfied: false
|
|
894
|
+
}
|
|
895
|
+
],
|
|
896
|
+
authority_status: {
|
|
897
|
+
authority_status: "not-granted",
|
|
898
|
+
explicit_scope_bounded: false,
|
|
899
|
+
grants_execution: false,
|
|
900
|
+
reasons
|
|
901
|
+
},
|
|
902
|
+
blocked: true,
|
|
903
|
+
candidate_only: true,
|
|
904
|
+
edge_ids: [String(edge.edge_id)],
|
|
905
|
+
not_executed: true,
|
|
906
|
+
packet_ids: dedupeSorted([
|
|
907
|
+
...stringList(edge.source_node_ids),
|
|
908
|
+
String(edge.target_node_id ?? "")
|
|
909
|
+
]),
|
|
910
|
+
path_id: pathId,
|
|
911
|
+
reasons,
|
|
912
|
+
receiver_context: {
|
|
913
|
+
evidence_refs: [],
|
|
914
|
+
present: false,
|
|
915
|
+
receiver_context_id: "receiver-context:missing"
|
|
916
|
+
},
|
|
917
|
+
settled: false,
|
|
918
|
+
witness: {
|
|
919
|
+
accepted: false,
|
|
920
|
+
edge_ids: [String(edge.edge_id)],
|
|
921
|
+
packet_ids: dedupeSorted([
|
|
922
|
+
...stringList(edge.source_node_ids),
|
|
923
|
+
String(edge.target_node_id ?? "")
|
|
924
|
+
]),
|
|
925
|
+
reasons,
|
|
926
|
+
settled: false,
|
|
927
|
+
witness_id: `execution-witness:${String(edge.edge_id)}`
|
|
928
|
+
}
|
|
929
|
+
};
|
|
930
|
+
});
|
|
931
|
+
return {
|
|
932
|
+
accepted: paths.length > 0,
|
|
933
|
+
accepted_path_count: 0,
|
|
934
|
+
authority_requirements: ["explicit-scope-bounded-authority"],
|
|
935
|
+
blocked_path_count: paths.length,
|
|
936
|
+
blocker_reason_by_path: Object.fromEntries(
|
|
937
|
+
paths.map((path) => [String(path.path_id), stringList(path.reasons)])
|
|
938
|
+
),
|
|
939
|
+
candidate_only_path_count: paths.length,
|
|
940
|
+
executed_path_count: 0,
|
|
941
|
+
execution_authority_granted: false,
|
|
942
|
+
graph_id: String(graph.graph_id ?? "effective-packet-graph"),
|
|
943
|
+
operationally_usable: false,
|
|
944
|
+
path_count: paths.length,
|
|
945
|
+
path_density: 0,
|
|
946
|
+
paths,
|
|
947
|
+
reasons: ["execution-available path detection never executes paths"],
|
|
948
|
+
report_id: "execution-available-path-density",
|
|
949
|
+
residual_carry_forward: stringList(
|
|
950
|
+
asRecord(graph.residual_summary)?.settled_blockers
|
|
951
|
+
),
|
|
952
|
+
rollback_requirements: ["rollback-or-safe-abort"],
|
|
953
|
+
settled: false,
|
|
954
|
+
workflow_usable: true
|
|
955
|
+
};
|
|
956
|
+
}
|
|
957
|
+
function buildPhaseThresholdStatus(observation, threshold) {
|
|
958
|
+
const pathDensity = numeric(
|
|
959
|
+
asRecord(observation.basin_reachability_proxy)?.reachability_proxy
|
|
960
|
+
);
|
|
961
|
+
const checks = {
|
|
962
|
+
maximum_false_liquidity_load: numeric(asRecord(observation.false_liquidity_load)?.load) <= numeric(threshold.maximum_false_liquidity_load ?? 0.5),
|
|
963
|
+
maximum_residual_debt: numeric(observation.residual_debt) <= numeric(threshold.maximum_residual_debt ?? 0),
|
|
964
|
+
maximum_salience_obstruction: numeric(asRecord(observation.salience_obstruction_load)?.load) <= numeric(threshold.maximum_salience_obstruction ?? 0.5),
|
|
965
|
+
minimum_accepted_packet_count: numeric(observation.accepted_packet_count) >= numeric(threshold.minimum_accepted_packet_count ?? 1),
|
|
966
|
+
minimum_alt_to_ecpt_lift_count: numeric(observation.alt_certified_capital_count) >= numeric(threshold.minimum_alt_to_ecpt_lift_count ?? 0),
|
|
967
|
+
minimum_closure_witness_count: numeric(observation.closure_witness_count) >= numeric(threshold.minimum_closure_witness_count ?? 1),
|
|
968
|
+
minimum_effective_edge_count: numeric(observation.effective_edge_count) >= numeric(threshold.minimum_effective_edge_count ?? 1),
|
|
969
|
+
minimum_execution_available_path_density: pathDensity >= numeric(threshold.minimum_execution_available_path_density ?? 0.1),
|
|
970
|
+
minimum_verification_throughput: numeric(
|
|
971
|
+
asRecord(observation.verification_throughput)?.throughput_ratio
|
|
972
|
+
) >= numeric(threshold.minimum_verification_throughput ?? 0.1)
|
|
973
|
+
};
|
|
974
|
+
const failed = Object.entries(checks).filter(([, passed]) => !passed).map(([key]) => key).sort();
|
|
975
|
+
const status = failed.length === 0 ? "candidate" : "abstain";
|
|
976
|
+
return {
|
|
977
|
+
accepted: status === "candidate",
|
|
978
|
+
abstention_reasons: failed.map(
|
|
979
|
+
(component) => `missing finite threshold component: ${component}`
|
|
980
|
+
),
|
|
981
|
+
certificate_status: status,
|
|
982
|
+
component_status: Object.fromEntries(Object.entries(checks).sort()),
|
|
983
|
+
failed_components: failed,
|
|
984
|
+
oracle_truth_proven: false,
|
|
985
|
+
physical_truth_proven: false,
|
|
986
|
+
protocol_relative: true,
|
|
987
|
+
protocol_relative_only: true,
|
|
988
|
+
real_asi_proof: false,
|
|
989
|
+
reasons: [
|
|
990
|
+
"threshold status is protocol-relative only",
|
|
991
|
+
"threshold status does not prove real ASI"
|
|
992
|
+
],
|
|
993
|
+
rejection_reasons: [],
|
|
994
|
+
settled: false,
|
|
995
|
+
status_id: "asi-proxy-threshold-status",
|
|
996
|
+
threshold,
|
|
997
|
+
threshold_distance: failed.length,
|
|
998
|
+
observation
|
|
999
|
+
};
|
|
1000
|
+
}
|
|
1001
|
+
function buildCollectivePhaseCertificateCandidate(thresholdStatus, graph) {
|
|
1002
|
+
const status = String(thresholdStatus.certificate_status ?? "abstain");
|
|
1003
|
+
const defects = stringList(thresholdStatus.failed_components).map(
|
|
1004
|
+
(component) => ({
|
|
1005
|
+
component,
|
|
1006
|
+
defect_id: `phase-defect:${component}`,
|
|
1007
|
+
defect_type: "threshold-component-missing",
|
|
1008
|
+
required_remediation: `provide finite evidence for ${component}`,
|
|
1009
|
+
residual_preserved: true
|
|
1010
|
+
})
|
|
1011
|
+
);
|
|
1012
|
+
return {
|
|
1013
|
+
accepted: status === "candidate",
|
|
1014
|
+
abstention_report: status === "candidate" ? null : {
|
|
1015
|
+
defects,
|
|
1016
|
+
protocol_relative_only: true,
|
|
1017
|
+
reasons: ["certificate abstains when finite evidence is missing"],
|
|
1018
|
+
report_id: "collective-phase-abstention",
|
|
1019
|
+
settled: false,
|
|
1020
|
+
threshold_status: thresholdStatus
|
|
1021
|
+
},
|
|
1022
|
+
certificate_id: "collective-phase-certificate-candidate",
|
|
1023
|
+
certificate_status: status,
|
|
1024
|
+
defects,
|
|
1025
|
+
execution_authority_granted: false,
|
|
1026
|
+
finite_requirements_passed: status === "candidate",
|
|
1027
|
+
graph_id: String(graph.graph_id ?? ""),
|
|
1028
|
+
observation_id: String(
|
|
1029
|
+
asRecord(thresholdStatus.observation)?.observation_id ?? ""
|
|
1030
|
+
),
|
|
1031
|
+
operationally_usable: status === "candidate",
|
|
1032
|
+
oracle_truth_proven: false,
|
|
1033
|
+
physical_truth_proven: false,
|
|
1034
|
+
protocol_relative_only: true,
|
|
1035
|
+
proves_physical_or_oracle_truth: false,
|
|
1036
|
+
proves_real_asi: false,
|
|
1037
|
+
reasons: [
|
|
1038
|
+
"certificate candidate is protocol-relative only",
|
|
1039
|
+
"certificate candidate does not prove real ASI",
|
|
1040
|
+
"certificate candidate does not settle diagnostic reports"
|
|
1041
|
+
],
|
|
1042
|
+
settled: false,
|
|
1043
|
+
threshold_status: thresholdStatus,
|
|
1044
|
+
workflow_usable: true
|
|
1045
|
+
};
|
|
1046
|
+
}
|
|
1047
|
+
function loadPhaseLabObservation(storeDir, window = "latest") {
|
|
1048
|
+
const selected = selectWindow(storeDir, window);
|
|
1049
|
+
const graph = buildEffectivePacketGraph({
|
|
1050
|
+
events: selected.events,
|
|
1051
|
+
graph_id: `effective-graph:${String(selected.index.window_id ?? "window")}`,
|
|
1052
|
+
source_window_id: String(selected.index.window_id ?? "window")
|
|
1053
|
+
});
|
|
1054
|
+
return {
|
|
1055
|
+
observation: observePhaseWindow(selected.index, selected.events, graph),
|
|
1056
|
+
graph
|
|
1057
|
+
};
|
|
1058
|
+
}
|
|
1059
|
+
function loadPhaseLabGraph(storeDir, window = "all") {
|
|
1060
|
+
const selected = selectWindow(storeDir, window);
|
|
1061
|
+
return buildEffectivePacketGraph({
|
|
1062
|
+
events: selected.events,
|
|
1063
|
+
graph_id: `effective-graph:${String(selected.index.window_id ?? "window")}`,
|
|
1064
|
+
source_window_id: String(selected.index.window_id ?? "window")
|
|
1065
|
+
});
|
|
1066
|
+
}
|
|
1067
|
+
function exportPhaseLabStore(storeDir, outputDir) {
|
|
1068
|
+
mkdirSync(outputDir, { recursive: true });
|
|
1069
|
+
const manifest = writeManifest(storeDir);
|
|
1070
|
+
const events = readEvents(storeDir);
|
|
1071
|
+
const graph = buildEffectivePacketGraph({
|
|
1072
|
+
events,
|
|
1073
|
+
graph_id: "phase-lab-export-effective-graph",
|
|
1074
|
+
source_window_id: String(manifest.latest_window_id ?? "adhoc")
|
|
1075
|
+
});
|
|
1076
|
+
const files = [];
|
|
1077
|
+
const write = (name, data) => {
|
|
1078
|
+
writeJson(join(outputDir, name), data);
|
|
1079
|
+
files.push(name);
|
|
1080
|
+
};
|
|
1081
|
+
write("manifest.json", manifest);
|
|
1082
|
+
write("events.json", {
|
|
1083
|
+
absolute_paths_sanitized: true,
|
|
1084
|
+
events,
|
|
1085
|
+
settled: false
|
|
1086
|
+
});
|
|
1087
|
+
write("effective_graph.json", graph);
|
|
1088
|
+
write("windows.json", {
|
|
1089
|
+
settled: false,
|
|
1090
|
+
windows: readWindowIndexes(storeDir)
|
|
1091
|
+
});
|
|
1092
|
+
if (events.length > 0) {
|
|
1093
|
+
const { observation } = loadPhaseLabObservation(storeDir, "latest");
|
|
1094
|
+
write("phase_window_observation.json", observation);
|
|
1095
|
+
}
|
|
1096
|
+
return {
|
|
1097
|
+
accepted: true,
|
|
1098
|
+
absolute_paths_sanitized: true,
|
|
1099
|
+
export_id: "phase-lab-export",
|
|
1100
|
+
files: files.sort(),
|
|
1101
|
+
output_dir: basename(outputDir),
|
|
1102
|
+
reasons: ["phase lab export sanitizes local paths and preserves residuals"],
|
|
1103
|
+
settled: false,
|
|
1104
|
+
store_manifest: manifest
|
|
1105
|
+
};
|
|
1106
|
+
}
|
|
1107
|
+
export {
|
|
1108
|
+
buildCollectivePhaseCertificateCandidate,
|
|
1109
|
+
buildEffectivePacketGraph,
|
|
1110
|
+
buildPhaseThresholdStatus,
|
|
1111
|
+
comparePhaseWindows,
|
|
1112
|
+
detectAutocatalyticClosure,
|
|
1113
|
+
detectExecutionAvailablePaths,
|
|
1114
|
+
exportPhaseLabStore,
|
|
1115
|
+
ingestPhaseLabDirectory,
|
|
1116
|
+
ingestPhaseLabFiles,
|
|
1117
|
+
ingestPhaseLabPacket,
|
|
1118
|
+
ingestPhaseLabReport,
|
|
1119
|
+
initPhaseLabStore,
|
|
1120
|
+
listPhaseLabWindows,
|
|
1121
|
+
loadPhaseLabGraph,
|
|
1122
|
+
loadPhaseLabObservation,
|
|
1123
|
+
observePhaseWindow
|
|
1124
|
+
};
|