xytara 2.1.0 → 2.3.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/.env.example +5 -1
- package/ADAPTER_START_HERE.md +56 -0
- package/CARRIED_HANDOFF_DEMO.md +60 -0
- package/EXAMPLE_PATHS.md +53 -0
- package/OPERATIONS_RUNBOOK.md +65 -0
- package/OPERATOR_START_HERE.md +63 -0
- package/PARTNER_READY_PATH.md +71 -0
- package/PROGRAM_COMPLETE_RELEASE.md +63 -0
- package/PROGRAM_STATUS.md +57 -0
- package/PUBLIC_DEMO_SCRIPT.md +78 -0
- package/PUBLISH_PLAN.md +7 -5
- package/README.md +66 -0
- package/RELEASE_CHECKLIST.md +8 -2
- package/RELEASE_NOTES.md +19 -8
- package/START_HERE.md +32 -0
- package/SUPABASE_RUNTIME_STATE_SETUP.md +61 -0
- package/WHY_XYTARA_XOONYA.md +63 -0
- package/adapters/examples/minimal-third-party-execution-adapter.js +61 -0
- package/adapters/examples/minimal-third-party-execution-adapter.manifest.json +79 -0
- package/adapters/examples/minimal-third-party-execution-registration.record.json +26 -0
- package/adapters/examples/minimal-third-party-execution.certification-pack.json +22 -0
- package/adapters/examples/minimal-third-party-execution.submission-bundle.json +126 -0
- package/bin/xytara-release.js +1251 -1
- package/examples/adapter_review_walkthrough.js +53 -0
- package/examples/export_carried_handoff.js +80 -0
- package/examples/funded_runtime_walkthrough.js +70 -0
- package/examples/partner_launch_walkthrough.js +43 -0
- package/examples/quickstart.js +3255 -0
- package/index.js +7 -1
- package/lib/adapter_pack.js +118 -0
- package/lib/adapter_partner_pack.js +89 -0
- package/lib/adapter_promotion_pack.js +89 -0
- package/lib/commerce_client.js +38 -0
- package/lib/commerce_economics.js +304 -0
- package/lib/operator_intelligence.js +90 -0
- package/lib/outreach_copy_pack.js +51 -0
- package/lib/outreach_message_pack.js +71 -0
- package/lib/outreach_target_pack.js +60 -0
- package/lib/partner_intelligence.js +105 -0
- package/lib/phase_10_closeout_pack.js +45 -0
- package/lib/phase_10_completion_pack.js +76 -0
- package/lib/phase_10_decision_record_pack.js +54 -0
- package/lib/phase_10_decision_resolution_pack.js +53 -0
- package/lib/phase_10_demand_signal_adapters_runtime_pack.js +74 -0
- package/lib/phase_10_ecosystem_backlog_triage_runtime_pack.js +74 -0
- package/lib/phase_10_freeze_baseline_pack.js +67 -0
- package/lib/phase_10_freeze_review_pack.js +64 -0
- package/lib/phase_10_gate_pack.js +57 -0
- package/lib/phase_10_long_tail_continuity_pack.js +80 -0
- package/lib/phase_10_long_tail_ecosystem_pack.js +66 -0
- package/lib/phase_10_niche_extension_registry_runtime_pack.js +74 -0
- package/lib/phase_1_claude_mcp_pack.js +60 -0
- package/lib/phase_1_claude_mcp_runtime_pack.js +52 -0
- package/lib/phase_1_ecosystem_pack.js +67 -0
- package/lib/phase_1_openai_codex_pack.js +60 -0
- package/lib/phase_1_openai_codex_runtime_pack.js +52 -0
- package/lib/phase_2_base_runtime_pack.js +71 -0
- package/lib/phase_2_base_usdc_runtime_pack.js +72 -0
- package/lib/phase_2_closeout_pack.js +65 -0
- package/lib/phase_2_completion_pack.js +113 -0
- package/lib/phase_2_decision_record_pack.js +66 -0
- package/lib/phase_2_decision_resolution_pack.js +69 -0
- package/lib/phase_2_eth_runtime_pack.js +70 -0
- package/lib/phase_2_evm_base_runtime_pack.js +73 -0
- package/lib/phase_2_evm_runtime_pack.js +71 -0
- package/lib/phase_2_flip_preview_pack.js +60 -0
- package/lib/phase_2_freeze_review_pack.js +99 -0
- package/lib/phase_2_gate_pack.js +77 -0
- package/lib/phase_2_payment_rails_pack.js +71 -0
- package/lib/phase_2_usdc_runtime_pack.js +71 -0
- package/lib/phase_3_brc_runtime_pack.js +81 -0
- package/lib/phase_3_bsv_teranode_runtime_pack.js +83 -0
- package/lib/phase_3_closeout_pack.js +62 -0
- package/lib/phase_3_completion_pack.js +94 -0
- package/lib/phase_3_decision_record_pack.js +64 -0
- package/lib/phase_3_decision_resolution_pack.js +69 -0
- package/lib/phase_3_freeze_baseline_pack.js +67 -0
- package/lib/phase_3_freeze_review_pack.js +80 -0
- package/lib/phase_3_gate_pack.js +76 -0
- package/lib/phase_3_metanet_runtime_pack.js +81 -0
- package/lib/phase_3_native_bsv_pack.js +91 -0
- package/lib/phase_3_native_continuity_pack.js +82 -0
- package/lib/phase_4_attestation_runtime_pack.js +75 -0
- package/lib/phase_4_closeout_pack.js +45 -0
- package/lib/phase_4_completion_pack.js +94 -0
- package/lib/phase_4_decision_record_pack.js +54 -0
- package/lib/phase_4_decision_resolution_pack.js +45 -0
- package/lib/phase_4_erc8004_runtime_pack.js +76 -0
- package/lib/phase_4_freeze_baseline_pack.js +67 -0
- package/lib/phase_4_freeze_review_pack.js +68 -0
- package/lib/phase_4_gate_pack.js +58 -0
- package/lib/phase_4_identity_registry_runtime_pack.js +75 -0
- package/lib/phase_4_identity_trust_pack.js +73 -0
- package/lib/phase_4_trust_continuity_pack.js +86 -0
- package/lib/phase_5_antelope_runtime_pack.js +76 -0
- package/lib/phase_5_closeout_pack.js +44 -0
- package/lib/phase_5_completion_pack.js +82 -0
- package/lib/phase_5_decision_record_pack.js +54 -0
- package/lib/phase_5_decision_resolution_pack.js +45 -0
- package/lib/phase_5_freeze_baseline_pack.js +67 -0
- package/lib/phase_5_freeze_review_pack.js +68 -0
- package/lib/phase_5_gate_pack.js +58 -0
- package/lib/phase_5_major_rails_continuity_pack.js +86 -0
- package/lib/phase_5_major_rails_pack.js +74 -0
- package/lib/phase_5_proton_xpr_runtime_pack.js +76 -0
- package/lib/phase_5_solana_runtime_pack.js +76 -0
- package/lib/phase_6_autogen_runtime_pack.js +72 -0
- package/lib/phase_6_closeout_pack.js +46 -0
- package/lib/phase_6_completion_pack.js +77 -0
- package/lib/phase_6_decision_record_pack.js +54 -0
- package/lib/phase_6_decision_resolution_pack.js +53 -0
- package/lib/phase_6_framework_continuity_pack.js +81 -0
- package/lib/phase_6_framework_runtime_pack.js +68 -0
- package/lib/phase_6_freeze_baseline_pack.js +68 -0
- package/lib/phase_6_freeze_review_pack.js +65 -0
- package/lib/phase_6_gate_pack.js +59 -0
- package/lib/phase_6_langchain_runtime_pack.js +72 -0
- package/lib/phase_6_langgraph_runtime_pack.js +72 -0
- package/lib/phase_6_semantic_kernel_runtime_pack.js +72 -0
- package/lib/phase_7_closeout_pack.js +45 -0
- package/lib/phase_7_completion_pack.js +85 -0
- package/lib/phase_7_decision_record_pack.js +53 -0
- package/lib/phase_7_decision_resolution_pack.js +53 -0
- package/lib/phase_7_event_system_continuity_pack.js +89 -0
- package/lib/phase_7_event_system_pack.js +76 -0
- package/lib/phase_7_freeze_baseline_pack.js +74 -0
- package/lib/phase_7_freeze_review_pack.js +65 -0
- package/lib/phase_7_gate_pack.js +58 -0
- package/lib/phase_7_kafka_runtime_pack.js +74 -0
- package/lib/phase_7_mqtt_runtime_pack.js +74 -0
- package/lib/phase_7_nats_runtime_pack.js +74 -0
- package/lib/phase_7_webhook_event_bus_runtime_pack.js +74 -0
- package/lib/phase_8_closeout_pack.js +46 -0
- package/lib/phase_8_completion_pack.js +82 -0
- package/lib/phase_8_decision_record_pack.js +54 -0
- package/lib/phase_8_decision_resolution_pack.js +53 -0
- package/lib/phase_8_external_receipt_import_runtime_pack.js +74 -0
- package/lib/phase_8_external_result_import_runtime_pack.js +74 -0
- package/lib/phase_8_freeze_baseline_pack.js +71 -0
- package/lib/phase_8_freeze_review_pack.js +64 -0
- package/lib/phase_8_gate_pack.js +58 -0
- package/lib/phase_8_proof_bridge_continuity_pack.js +86 -0
- package/lib/phase_8_proof_bridges_pack.js +72 -0
- package/lib/phase_8_proof_bundle_normalization_runtime_pack.js +74 -0
- package/lib/phase_9_closeout_pack.js +46 -0
- package/lib/phase_9_completion_pack.js +82 -0
- package/lib/phase_9_custody_refs_runtime_pack.js +74 -0
- package/lib/phase_9_decision_record_pack.js +54 -0
- package/lib/phase_9_decision_resolution_pack.js +53 -0
- package/lib/phase_9_freeze_baseline_pack.js +71 -0
- package/lib/phase_9_freeze_review_pack.js +64 -0
- package/lib/phase_9_gate_pack.js +58 -0
- package/lib/phase_9_operator_accounting_bridges_runtime_pack.js +74 -0
- package/lib/phase_9_treasury_connectivity_pack.js +72 -0
- package/lib/phase_9_treasury_continuity_pack.js +86 -0
- package/lib/phase_9_treasury_destinations_runtime_pack.js +74 -0
- package/lib/phase_program_pack.js +120 -0
- package/lib/release_center.js +970 -0
- package/lib/release_history.js +1 -1
- package/lib/runtime_state_store.js +212 -27
- package/lib/soft_launch_pack.js +78 -0
- package/package.json +13 -1
- package/server.js +2110 -235
|
@@ -478,6 +478,113 @@ function buildCreditBalanceSummary(state, accountId) {
|
|
|
478
478
|
};
|
|
479
479
|
}
|
|
480
480
|
|
|
481
|
+
function buildWalletSummary(state, accountId) {
|
|
482
|
+
const balance = buildCreditBalanceSummary(state, accountId);
|
|
483
|
+
const allocations = listAllocationEventsForAccount(state, accountId);
|
|
484
|
+
const usageMeters = listUsageMetersForAccount(state, accountId);
|
|
485
|
+
const reserveUnits = allocations
|
|
486
|
+
.filter((entry) => entry && entry.direction === "reserve")
|
|
487
|
+
.reduce((sum, entry) => sum + Number(entry.units || 0), 0);
|
|
488
|
+
const committedUnits = allocations
|
|
489
|
+
.filter((entry) => entry && entry.direction === "commit")
|
|
490
|
+
.reduce((sum, entry) => sum + Number(entry.units || 0), 0);
|
|
491
|
+
const releasedUnits = allocations
|
|
492
|
+
.filter((entry) => entry && entry.direction === "release")
|
|
493
|
+
.reduce((sum, entry) => sum + Number(entry.units || 0), 0);
|
|
494
|
+
const reversedUnits = allocations
|
|
495
|
+
.filter((entry) => entry && entry.direction === "reverse")
|
|
496
|
+
.reduce((sum, entry) => sum + Number(entry.units || 0), 0);
|
|
497
|
+
const reserveCount = allocations.filter((entry) => entry && entry.direction === "reserve").length;
|
|
498
|
+
const walletState = balance.available_units <= 0
|
|
499
|
+
? "depleted"
|
|
500
|
+
: balance.entitlement_summary.low_entitlement_count > 0
|
|
501
|
+
? "low_balance"
|
|
502
|
+
: "healthy";
|
|
503
|
+
|
|
504
|
+
return {
|
|
505
|
+
wallet_version: "xytara-machine-wallet-summary-v1",
|
|
506
|
+
wallet_id: `wallet_${accountId}`,
|
|
507
|
+
account_id: accountId,
|
|
508
|
+
canonical_unit: "usage_units",
|
|
509
|
+
wallet_state: walletState,
|
|
510
|
+
issued_units: balance.issued_units,
|
|
511
|
+
available_units: balance.available_units,
|
|
512
|
+
reserved_units: reserveUnits,
|
|
513
|
+
committed_units: committedUnits,
|
|
514
|
+
released_units: releasedUnits,
|
|
515
|
+
reversed_units: reversedUnits,
|
|
516
|
+
consumed_units: balance.consumed_units,
|
|
517
|
+
reserve_count: reserveCount,
|
|
518
|
+
entitlement_count: balance.entitlement_summary.entitlement_count,
|
|
519
|
+
active_entitlement_count: balance.entitlement_summary.active_entitlement_count,
|
|
520
|
+
usage_meter_count: usageMeters.length,
|
|
521
|
+
replenishment_posture: balance.replenishment_summary.depleted_count > 0
|
|
522
|
+
? "replenishment_required"
|
|
523
|
+
: balance.replenishment_summary.low_balance_count > 0
|
|
524
|
+
? "replenishment_recommended"
|
|
525
|
+
: "sufficient_capacity",
|
|
526
|
+
linked_surfaces: {
|
|
527
|
+
credit_balance_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/credit-balance`,
|
|
528
|
+
entitlements_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/entitlements`,
|
|
529
|
+
usage_meters_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/usage-meters`,
|
|
530
|
+
wallet_ledger_summary_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/wallet-ledger-summary`
|
|
531
|
+
},
|
|
532
|
+
generated_at_iso: nowIso()
|
|
533
|
+
};
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
function buildWalletLedgerSummary(state, accountId) {
|
|
537
|
+
const wallet = buildWalletSummary(state, accountId);
|
|
538
|
+
const allocations = listAllocationEventsForAccount(state, accountId);
|
|
539
|
+
const spends = listCreditSpendsForAccount(state, accountId);
|
|
540
|
+
const railCredits = listRailCreditsForAccount(state, accountId);
|
|
541
|
+
const consequences = {
|
|
542
|
+
mint_count: allocations.filter((entry) => entry && entry.direction === "mint").length + railCredits.length,
|
|
543
|
+
reserve_count: allocations.filter((entry) => entry && entry.direction === "reserve").length,
|
|
544
|
+
commit_count: allocations.filter((entry) => entry && entry.direction === "commit").length + spends.length,
|
|
545
|
+
release_count: allocations.filter((entry) => entry && entry.direction === "release").length,
|
|
546
|
+
reverse_count: allocations.filter((entry) => entry && entry.direction === "reverse").length
|
|
547
|
+
};
|
|
548
|
+
|
|
549
|
+
return {
|
|
550
|
+
summary_version: "xytara-wallet-ledger-summary-v1",
|
|
551
|
+
wallet_id: wallet.wallet_id,
|
|
552
|
+
account_id: accountId,
|
|
553
|
+
canonical_truth_posture: "allocation_and_consequence_records_with_materialized_wallet_summary",
|
|
554
|
+
canonical_unit: wallet.canonical_unit,
|
|
555
|
+
wallet_state: wallet.wallet_state,
|
|
556
|
+
wallet_summary: {
|
|
557
|
+
issued_units: wallet.issued_units,
|
|
558
|
+
available_units: wallet.available_units,
|
|
559
|
+
reserved_units: wallet.reserved_units,
|
|
560
|
+
committed_units: wallet.committed_units,
|
|
561
|
+
released_units: wallet.released_units,
|
|
562
|
+
reversed_units: wallet.reversed_units,
|
|
563
|
+
consumed_units: wallet.consumed_units
|
|
564
|
+
},
|
|
565
|
+
ledger_lifecycle_counts: consequences,
|
|
566
|
+
source_record_counts: {
|
|
567
|
+
allocation_count: allocations.length,
|
|
568
|
+
rail_credit_count: railCredits.length,
|
|
569
|
+
credit_spend_count: spends.length,
|
|
570
|
+
entitlement_count: wallet.entitlement_count,
|
|
571
|
+
usage_meter_count: wallet.usage_meter_count
|
|
572
|
+
},
|
|
573
|
+
translation_boundary: {
|
|
574
|
+
public_commercial_shell: "credits",
|
|
575
|
+
canonical_hidden_unit: "usage_units",
|
|
576
|
+
canonical_wallet_truth: "hidden_machine_wallet",
|
|
577
|
+
materialized_projection: "wallet_summary"
|
|
578
|
+
},
|
|
579
|
+
linked_surfaces: {
|
|
580
|
+
wallet_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/wallet`,
|
|
581
|
+
ledger_export_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/ledger-export`,
|
|
582
|
+
reconciliation_pack_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/reconciliation-pack`
|
|
583
|
+
},
|
|
584
|
+
generated_at_iso: nowIso()
|
|
585
|
+
};
|
|
586
|
+
}
|
|
587
|
+
|
|
481
588
|
function getWorkflowTaskRefs(workflowRef) {
|
|
482
589
|
const workflow = findWorkflow(workflowRef);
|
|
483
590
|
if (!workflow || !Array.isArray(workflow.tasks)) return [];
|
|
@@ -922,6 +1029,199 @@ function buildTreasurySummary(state, accountId) {
|
|
|
922
1029
|
};
|
|
923
1030
|
}
|
|
924
1031
|
|
|
1032
|
+
function selectRecommendedCreditPack(totalUnits, usageMeterCount) {
|
|
1033
|
+
if (totalUnits >= 1500 || usageMeterCount >= 20) return "credits.fleet";
|
|
1034
|
+
if (totalUnits >= 500 || usageMeterCount >= 10) return "credits.agent";
|
|
1035
|
+
if (totalUnits >= 100 || usageMeterCount >= 3) return "credits.builder";
|
|
1036
|
+
if (totalUnits > 0 || usageMeterCount > 0) return "credits.starter";
|
|
1037
|
+
return null;
|
|
1038
|
+
}
|
|
1039
|
+
|
|
1040
|
+
function buildEconomicsIntelligenceSummary(state, accountId) {
|
|
1041
|
+
const balanceSummary = buildCreditBalanceSummary(state, accountId);
|
|
1042
|
+
const meteringSummary = buildUsageMeteringSummary(state, accountId);
|
|
1043
|
+
const replenishmentSummary = buildEntitlementReplenishmentSummary(state, accountId);
|
|
1044
|
+
const treasurySummary = buildTreasurySummary(state, accountId);
|
|
1045
|
+
|
|
1046
|
+
const usageMeterCount = Number(meteringSummary.usage_meter_count || 0);
|
|
1047
|
+
const totalUnits = Number(meteringSummary.total_units || 0);
|
|
1048
|
+
const availableUnits = Number(balanceSummary.available_units || 0);
|
|
1049
|
+
const consumedUnits = Number(balanceSummary.consumed_units || 0);
|
|
1050
|
+
const lowBalanceCount = Number(replenishmentSummary.low_balance_count || 0);
|
|
1051
|
+
const depletedCount = Number(replenishmentSummary.depleted_count || 0);
|
|
1052
|
+
const mintedUnits = Number(treasurySummary.treasury && treasurySummary.treasury.minted_units || 0);
|
|
1053
|
+
const settledAmountMinor = Number(treasurySummary.treasury && treasurySummary.treasury.settled_amount_minor || 0);
|
|
1054
|
+
const budgetCount = Number(treasurySummary.budgets && treasurySummary.budgets.total || 0);
|
|
1055
|
+
|
|
1056
|
+
let recommendedFundingPosture = "direct_pay_first";
|
|
1057
|
+
if (availableUnits > 0 || consumedUnits > 0 || usageMeterCount > 0) {
|
|
1058
|
+
recommendedFundingPosture = "credits_first";
|
|
1059
|
+
}
|
|
1060
|
+
if (availableUnits <= 0 && (usageMeterCount > 0 || consumedUnits > 0)) {
|
|
1061
|
+
recommendedFundingPosture = "pack_backed_credits_first";
|
|
1062
|
+
}
|
|
1063
|
+
|
|
1064
|
+
const recommendedPackId = replenishmentSummary.recommended_pack_ids[0] || selectRecommendedCreditPack(totalUnits, usageMeterCount);
|
|
1065
|
+
|
|
1066
|
+
let replenishmentRiskState = "low";
|
|
1067
|
+
if (lowBalanceCount > 0) replenishmentRiskState = "watch";
|
|
1068
|
+
if (depletedCount > 0 || (availableUnits > 0 && availableUnits <= Math.max(8, totalUnits))) {
|
|
1069
|
+
replenishmentRiskState = "high";
|
|
1070
|
+
}
|
|
1071
|
+
|
|
1072
|
+
let treasuryHealthState = "healthy";
|
|
1073
|
+
if (mintedUnits === 0 && settledAmountMinor === 0 && usageMeterCount === 0) {
|
|
1074
|
+
treasuryHealthState = "pre_funding";
|
|
1075
|
+
} else if (availableUnits <= 0 && (consumedUnits > 0 || usageMeterCount > 0)) {
|
|
1076
|
+
treasuryHealthState = "constrained";
|
|
1077
|
+
} else if (lowBalanceCount > 0 || budgetCount > 0) {
|
|
1078
|
+
treasuryHealthState = "watch";
|
|
1079
|
+
}
|
|
1080
|
+
|
|
1081
|
+
let nextBestAction = "continue_current_posture";
|
|
1082
|
+
if (recommendedFundingPosture === "direct_pay_first") {
|
|
1083
|
+
nextBestAction = "start_with_direct_pay";
|
|
1084
|
+
}
|
|
1085
|
+
if (recommendedFundingPosture === "credits_first" && recommendedPackId && usageMeterCount >= 3) {
|
|
1086
|
+
nextBestAction = "consider_pack_funding";
|
|
1087
|
+
}
|
|
1088
|
+
if (replenishmentRiskState === "watch") {
|
|
1089
|
+
nextBestAction = "prepare_replenishment";
|
|
1090
|
+
}
|
|
1091
|
+
if (replenishmentRiskState === "high") {
|
|
1092
|
+
nextBestAction = "replenish_credits";
|
|
1093
|
+
}
|
|
1094
|
+
if (treasuryHealthState === "constrained") {
|
|
1095
|
+
nextBestAction = "restore_runtime_balance";
|
|
1096
|
+
}
|
|
1097
|
+
|
|
1098
|
+
return {
|
|
1099
|
+
account_id: accountId,
|
|
1100
|
+
category: "machine-commerce-account-economics-intelligence-summary",
|
|
1101
|
+
recommended_funding_posture: recommendedFundingPosture,
|
|
1102
|
+
recommended_pack_id: recommendedPackId,
|
|
1103
|
+
replenishment_risk_state: replenishmentRiskState,
|
|
1104
|
+
treasury_health_state: treasuryHealthState,
|
|
1105
|
+
next_best_action: nextBestAction,
|
|
1106
|
+
explanation_signals: {
|
|
1107
|
+
available_units: availableUnits,
|
|
1108
|
+
consumed_units: consumedUnits,
|
|
1109
|
+
usage_meter_count: usageMeterCount,
|
|
1110
|
+
metered_units: totalUnits,
|
|
1111
|
+
low_balance_count: lowBalanceCount,
|
|
1112
|
+
depleted_count: depletedCount,
|
|
1113
|
+
recommended_replenishment_pack_ids: replenishmentSummary.recommended_pack_ids,
|
|
1114
|
+
pricing_bands: meteringSummary.pricing_bands,
|
|
1115
|
+
minted_units: mintedUnits,
|
|
1116
|
+
settled_amount_minor: settledAmountMinor,
|
|
1117
|
+
budget_count: budgetCount
|
|
1118
|
+
},
|
|
1119
|
+
linked_surfaces: {
|
|
1120
|
+
credit_balance_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/credit-balance`,
|
|
1121
|
+
metering_summary_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/metering-summary`,
|
|
1122
|
+
entitlement_replenishment_summary_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/entitlements/replenishment-summary`,
|
|
1123
|
+
treasury_summary_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/treasury-summary`,
|
|
1124
|
+
operator_dashboard_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/operator-dashboard`
|
|
1125
|
+
},
|
|
1126
|
+
generated_at_iso: nowIso()
|
|
1127
|
+
};
|
|
1128
|
+
}
|
|
1129
|
+
|
|
1130
|
+
function buildTreasuryIntelligenceSummary(state, accountId) {
|
|
1131
|
+
const treasurySummary = buildTreasurySummary(state, accountId);
|
|
1132
|
+
const treasuryDrilldown = buildTreasuryDrilldown(state, accountId);
|
|
1133
|
+
const reconciliationPack = buildReconciliationPack(state, accountId);
|
|
1134
|
+
const meteringSummary = buildUsageMeteringSummary(state, accountId);
|
|
1135
|
+
const balanceSummary = buildCreditBalanceSummary(state, accountId);
|
|
1136
|
+
const railSummary = buildRailSummary(state, accountId);
|
|
1137
|
+
|
|
1138
|
+
const mintedUnits = Number(treasurySummary.treasury.minted_units || 0);
|
|
1139
|
+
const consumedUnits = Number(treasurySummary.treasury.consumed_units || 0);
|
|
1140
|
+
const availableUnits = Number(treasurySummary.treasury.available_units || 0);
|
|
1141
|
+
const settledAmountMinor = Number(treasurySummary.treasury.settled_amount_minor || 0);
|
|
1142
|
+
const usageMeterCount = Number(meteringSummary.usage_meter_count || 0);
|
|
1143
|
+
const pendingTransactions = Number(treasuryDrilldown.unresolved_flags.pending_transactions || 0);
|
|
1144
|
+
const pendingReceipts = Number(treasuryDrilldown.unresolved_flags.pending_receipts || 0);
|
|
1145
|
+
const disputedReceipts = Number(reconciliationPack.unresolved_state.disputed_receipt_count || 0);
|
|
1146
|
+
const escalatedReceipts = Number(reconciliationPack.unresolved_state.escalated_receipt_count || 0);
|
|
1147
|
+
const paymentLedgerCount = Number(treasurySummary.payment_ledger_count || 0);
|
|
1148
|
+
const railCreditEventCount = Number(railSummary.credit_event_count || 0);
|
|
1149
|
+
|
|
1150
|
+
let treasuryEfficiencyState = "healthy";
|
|
1151
|
+
if (mintedUnits === 0 && settledAmountMinor === 0 && usageMeterCount === 0) {
|
|
1152
|
+
treasuryEfficiencyState = "pre_funding";
|
|
1153
|
+
} else if (availableUnits <= 0 && (consumedUnits > 0 || usageMeterCount > 0)) {
|
|
1154
|
+
treasuryEfficiencyState = "constrained";
|
|
1155
|
+
} else if (pendingTransactions > 0 || pendingReceipts > 0) {
|
|
1156
|
+
treasuryEfficiencyState = "watch";
|
|
1157
|
+
}
|
|
1158
|
+
|
|
1159
|
+
let valueCaptureState = "aligned";
|
|
1160
|
+
if (usageMeterCount === 0 && paymentLedgerCount === 0 && railCreditEventCount === 0) {
|
|
1161
|
+
valueCaptureState = "pre_conversion";
|
|
1162
|
+
} else if (usageMeterCount >= 3 && paymentLedgerCount <= 1 && consumedUnits > 0) {
|
|
1163
|
+
valueCaptureState = "repeat_use_ready";
|
|
1164
|
+
} else if (consumedUnits > mintedUnits && mintedUnits > 0) {
|
|
1165
|
+
valueCaptureState = "leaking";
|
|
1166
|
+
}
|
|
1167
|
+
|
|
1168
|
+
let reconciliationRiskState = "low";
|
|
1169
|
+
if (pendingTransactions > 0 || pendingReceipts > 0) reconciliationRiskState = "watch";
|
|
1170
|
+
if (disputedReceipts > 0 || escalatedReceipts > 0) reconciliationRiskState = "high";
|
|
1171
|
+
|
|
1172
|
+
let replenishmentFatigueState = "low";
|
|
1173
|
+
if (railCreditEventCount >= 2 && availableUnits <= Math.max(8, meteringSummary.total_units || 0)) {
|
|
1174
|
+
replenishmentFatigueState = "watch";
|
|
1175
|
+
}
|
|
1176
|
+
if (railCreditEventCount >= 3 && balanceSummary.replenishment_summary.low_balance_count > 0) {
|
|
1177
|
+
replenishmentFatigueState = "high";
|
|
1178
|
+
}
|
|
1179
|
+
|
|
1180
|
+
let nextBestAction = "continue_treasury_posture";
|
|
1181
|
+
if (treasuryEfficiencyState === "pre_funding") {
|
|
1182
|
+
nextBestAction = "establish_runtime_funding";
|
|
1183
|
+
} else if (treasuryEfficiencyState === "constrained") {
|
|
1184
|
+
nextBestAction = "restore_runtime_balance";
|
|
1185
|
+
} else if (reconciliationRiskState === "high") {
|
|
1186
|
+
nextBestAction = "review_reconciliation_pack";
|
|
1187
|
+
} else if (reconciliationRiskState === "watch") {
|
|
1188
|
+
nextBestAction = "inspect_treasury_drilldown";
|
|
1189
|
+
} else if (replenishmentFatigueState === "high" || valueCaptureState === "repeat_use_ready") {
|
|
1190
|
+
nextBestAction = "recommend_larger_pack_posture";
|
|
1191
|
+
}
|
|
1192
|
+
|
|
1193
|
+
return {
|
|
1194
|
+
account_id: accountId,
|
|
1195
|
+
category: "machine-commerce-account-treasury-intelligence-summary",
|
|
1196
|
+
treasury_efficiency_state: treasuryEfficiencyState,
|
|
1197
|
+
value_capture_state: valueCaptureState,
|
|
1198
|
+
reconciliation_risk_state: reconciliationRiskState,
|
|
1199
|
+
replenishment_fatigue_state: replenishmentFatigueState,
|
|
1200
|
+
next_best_action: nextBestAction,
|
|
1201
|
+
explanation_signals: {
|
|
1202
|
+
minted_units: mintedUnits,
|
|
1203
|
+
consumed_units: consumedUnits,
|
|
1204
|
+
available_units: availableUnits,
|
|
1205
|
+
settled_amount_minor: settledAmountMinor,
|
|
1206
|
+
usage_meter_count: usageMeterCount,
|
|
1207
|
+
payment_ledger_count: paymentLedgerCount,
|
|
1208
|
+
rail_credit_event_count: railCreditEventCount,
|
|
1209
|
+
pending_transaction_count: pendingTransactions,
|
|
1210
|
+
pending_receipt_count: pendingReceipts,
|
|
1211
|
+
disputed_receipt_count: disputedReceipts,
|
|
1212
|
+
escalated_receipt_count: escalatedReceipts
|
|
1213
|
+
},
|
|
1214
|
+
linked_surfaces: {
|
|
1215
|
+
treasury_summary_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/treasury-summary`,
|
|
1216
|
+
treasury_drilldown_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/treasury-drilldown`,
|
|
1217
|
+
reconciliation_pack_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/reconciliation-pack`,
|
|
1218
|
+
metering_summary_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/metering-summary`,
|
|
1219
|
+
rail_summary_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/rail-summary`
|
|
1220
|
+
},
|
|
1221
|
+
generated_at_iso: nowIso()
|
|
1222
|
+
};
|
|
1223
|
+
}
|
|
1224
|
+
|
|
925
1225
|
function buildLedgerExport(state, accountId) {
|
|
926
1226
|
return {
|
|
927
1227
|
export_version: "xytara-economics-ledger-export-v1",
|
|
@@ -1402,6 +1702,10 @@ module.exports = {
|
|
|
1402
1702
|
previewRailCredits,
|
|
1403
1703
|
applyRailCredits,
|
|
1404
1704
|
buildCreditBalanceSummary,
|
|
1705
|
+
buildWalletSummary,
|
|
1706
|
+
buildWalletLedgerSummary,
|
|
1707
|
+
buildEconomicsIntelligenceSummary,
|
|
1708
|
+
buildTreasuryIntelligenceSummary,
|
|
1405
1709
|
buildTreasurySummary,
|
|
1406
1710
|
buildLedgerExport,
|
|
1407
1711
|
buildTreasuryDrilldown,
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const { buildEconomicsIntelligenceSummary } = require("./commerce_economics");
|
|
4
|
+
const { buildPartnerIntelligencePack } = require("./partner_intelligence");
|
|
5
|
+
|
|
6
|
+
function buildOperatorIntelligencePack(state, input) {
|
|
7
|
+
const payload = input && typeof input === "object" && !Array.isArray(input) ? input : {};
|
|
8
|
+
const accountId = String(payload.account_id || "acct_demo").trim() || "acct_demo";
|
|
9
|
+
const economicsIntelligence = buildEconomicsIntelligenceSummary(state, accountId);
|
|
10
|
+
const partnerIntelligence = buildPartnerIntelligencePack();
|
|
11
|
+
|
|
12
|
+
const actionQueue = [];
|
|
13
|
+
|
|
14
|
+
if (economicsIntelligence.next_best_action && economicsIntelligence.next_best_action !== "continue_current_posture") {
|
|
15
|
+
actionQueue.push({
|
|
16
|
+
lane: "runtime_economics",
|
|
17
|
+
priority: economicsIntelligence.replenishment_risk_state === "high" ? "high" : "medium",
|
|
18
|
+
action: economicsIntelligence.next_best_action,
|
|
19
|
+
reason: `funding posture is ${economicsIntelligence.recommended_funding_posture} with ${economicsIntelligence.replenishment_risk_state} replenishment risk`
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (partnerIntelligence.next_best_action) {
|
|
24
|
+
actionQueue.push({
|
|
25
|
+
lane: "partner_adoption",
|
|
26
|
+
priority: partnerIntelligence.onboarding_friction_state === "low" ? "medium" : "high",
|
|
27
|
+
action: partnerIntelligence.next_best_action,
|
|
28
|
+
reason: `partner readiness is ${partnerIntelligence.partner_readiness_state} and onboarding friction is ${partnerIntelligence.onboarding_friction_state}`
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (actionQueue.length === 0) {
|
|
33
|
+
actionQueue.push({
|
|
34
|
+
lane: "operator_posture",
|
|
35
|
+
priority: "low",
|
|
36
|
+
action: "continue_current_posture",
|
|
37
|
+
reason: "runtime economics and partner posture are both stable enough to continue current operation"
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return {
|
|
42
|
+
ok: true,
|
|
43
|
+
account_id: accountId,
|
|
44
|
+
category: "machine-commerce-operator-intelligence-pack",
|
|
45
|
+
overall_operator_state: {
|
|
46
|
+
runtime_economics_state: economicsIntelligence.treasury_health_state,
|
|
47
|
+
partner_adoption_state: partnerIntelligence.partner_readiness_state,
|
|
48
|
+
top_priority: actionQueue[0].priority
|
|
49
|
+
},
|
|
50
|
+
recommended_operator_motion: actionQueue[0].action,
|
|
51
|
+
next_action_queue: actionQueue,
|
|
52
|
+
intelligence_refs: {
|
|
53
|
+
economics_intelligence_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/intelligence-summary`,
|
|
54
|
+
partner_intelligence_ref: "/v1/partner-intelligence",
|
|
55
|
+
operator_dashboard_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/operator-dashboard`
|
|
56
|
+
},
|
|
57
|
+
explanation_signals: {
|
|
58
|
+
runtime_next_best_action: economicsIntelligence.next_best_action,
|
|
59
|
+
runtime_funding_posture: economicsIntelligence.recommended_funding_posture,
|
|
60
|
+
runtime_replenishment_risk_state: economicsIntelligence.replenishment_risk_state,
|
|
61
|
+
runtime_treasury_health_state: economicsIntelligence.treasury_health_state,
|
|
62
|
+
partner_next_best_action: partnerIntelligence.next_best_action,
|
|
63
|
+
partner_readiness_state: partnerIntelligence.partner_readiness_state,
|
|
64
|
+
partner_onboarding_friction_state: partnerIntelligence.onboarding_friction_state,
|
|
65
|
+
partner_promotion_readiness_state: partnerIntelligence.promotion_readiness_state
|
|
66
|
+
},
|
|
67
|
+
generated_from: {
|
|
68
|
+
economics_category: economicsIntelligence.category,
|
|
69
|
+
partner_category: partnerIntelligence.category
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function summarizeOperatorIntelligencePack(state, input) {
|
|
75
|
+
const pack = buildOperatorIntelligencePack(state, input);
|
|
76
|
+
return {
|
|
77
|
+
ok: true,
|
|
78
|
+
account_id: pack.account_id,
|
|
79
|
+
category: pack.category,
|
|
80
|
+
recommended_operator_motion: pack.recommended_operator_motion,
|
|
81
|
+
queue_length: pack.next_action_queue.length,
|
|
82
|
+
runtime_economics_state: pack.overall_operator_state.runtime_economics_state,
|
|
83
|
+
partner_adoption_state: pack.overall_operator_state.partner_adoption_state
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
module.exports = {
|
|
88
|
+
buildOperatorIntelligencePack,
|
|
89
|
+
summarizeOperatorIntelligencePack
|
|
90
|
+
};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const packageJson = require("../package.json");
|
|
4
|
+
|
|
5
|
+
function buildOutreachCopyPack() {
|
|
6
|
+
return {
|
|
7
|
+
ok: true,
|
|
8
|
+
product: packageJson.name,
|
|
9
|
+
category: "machine-commerce-outreach-copy-pack",
|
|
10
|
+
short_post: {
|
|
11
|
+
headline: "xytara is live",
|
|
12
|
+
body: "xytara is a machine-commerce spine for builders who need quote, pay, execute, inspect, and continue into proof without stitching together separate systems. It supports direct paid execution, reusable credits, adapter-first extension, and proof-aware followthrough."
|
|
13
|
+
},
|
|
14
|
+
direct_message: {
|
|
15
|
+
subject: "xytara: paid execution plus proof-aware followthrough",
|
|
16
|
+
body: "We built xytara for agent builders, tool authors, and runtime teams that need a real machine-commerce path instead of patchwork glue. If you want, start with `xytara-release --center --summary` and then run one paid path with `xytara-run`."
|
|
17
|
+
},
|
|
18
|
+
adapter_partner_message: {
|
|
19
|
+
subject: "xytara adapter partner path",
|
|
20
|
+
body: "If you build tools or integrations, xytara now has a public third-party adapter starter, promotion path, and partner path. You can copy the minimal starter, validate it locally, inspect the promotion workflow, and see exactly what still blocks broader trust."
|
|
21
|
+
},
|
|
22
|
+
first_links: [
|
|
23
|
+
"/v1/release-center/summary",
|
|
24
|
+
"/v1/soft-launch/summary",
|
|
25
|
+
"/v1/adapter-partners/summary",
|
|
26
|
+
"/v1/outreach-proof/summary"
|
|
27
|
+
],
|
|
28
|
+
first_ctas: [
|
|
29
|
+
"run xytara-release --center --summary",
|
|
30
|
+
"run one direct paid path with xytara-run",
|
|
31
|
+
"inspect the adapter partner path if you build integrations"
|
|
32
|
+
]
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function summarizeOutreachCopyPack() {
|
|
37
|
+
const pack = buildOutreachCopyPack();
|
|
38
|
+
return {
|
|
39
|
+
ok: true,
|
|
40
|
+
product: pack.product,
|
|
41
|
+
category: pack.category,
|
|
42
|
+
link_count: pack.first_links.length,
|
|
43
|
+
cta_count: pack.first_ctas.length,
|
|
44
|
+
headline: pack.short_post.headline
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
module.exports = {
|
|
49
|
+
buildOutreachCopyPack,
|
|
50
|
+
summarizeOutreachCopyPack
|
|
51
|
+
};
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const packageJson = require("../package.json");
|
|
4
|
+
|
|
5
|
+
function buildOutreachMessagePack() {
|
|
6
|
+
return {
|
|
7
|
+
ok: true,
|
|
8
|
+
product: packageJson.name,
|
|
9
|
+
category: "machine-commerce-outreach-message-pack",
|
|
10
|
+
messages: [
|
|
11
|
+
{
|
|
12
|
+
message_ref: "public_launch_post",
|
|
13
|
+
audience_ref: "general_builder",
|
|
14
|
+
channel: "public_post",
|
|
15
|
+
subject: "xytara is live",
|
|
16
|
+
body: "xytara is live. It is a machine-commerce spine for builders who need quote, pay, execute, inspect, and continue into proof without stitching together separate systems. Start with `/v1/release-center/summary` or run `xytara-release --center --summary`."
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
message_ref: "agent_builder_intro",
|
|
20
|
+
audience_ref: "agent_builder",
|
|
21
|
+
channel: "direct_message",
|
|
22
|
+
subject: "xytara for paid agent execution",
|
|
23
|
+
body: "If you need a real paid capability path for agents, xytara now gives you quote, pay, execute, inspect, and proof-aware followthrough on one public spine. Best first step: run `xytara-run` once, then inspect `/v1/release-center/summary`."
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
message_ref: "adapter_partner_intro",
|
|
27
|
+
audience_ref: "adapter_author",
|
|
28
|
+
channel: "direct_message",
|
|
29
|
+
subject: "xytara adapter partner path",
|
|
30
|
+
body: "If you build tools or integrations, xytara now has a public third-party adapter starter, promotion path, and partner path. You can copy the minimal starter, validate it locally, inspect promotion workflow, and see what still blocks broader trust."
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
message_ref: "runtime_team_intro",
|
|
34
|
+
audience_ref: "proof_aware_runtime_team",
|
|
35
|
+
channel: "direct_message",
|
|
36
|
+
subject: "xytara for runtime-to-proof followthrough",
|
|
37
|
+
body: "If your runtime results currently stop at logs, xytara gives you a machine-commerce path that can continue into proof review cleanly. Best first check: `/v1/outreach-proof/summary` and `xytara-release --outreach-proof --summary`."
|
|
38
|
+
}
|
|
39
|
+
],
|
|
40
|
+
first_artifacts: [
|
|
41
|
+
"/v1/release-center/summary",
|
|
42
|
+
"/v1/adapter-partners/summary",
|
|
43
|
+
"/v1/outreach-proof/summary",
|
|
44
|
+
"/v1/soft-launch/summary"
|
|
45
|
+
],
|
|
46
|
+
first_commands: [
|
|
47
|
+
"xytara-release --center --summary",
|
|
48
|
+
"xytara-release --adapter-partners --summary",
|
|
49
|
+
"xytara-release --outreach-proof --summary",
|
|
50
|
+
"xytara-run --url https://xytara.onrender.com --account acct_demo --command \"cli-run\" --task trust.verify --body-json '{\"subject_id\":\"subject-1\"}' --wallet-id merchant_wallet_main --wallet-secret YOUR_LOCAL_SIGNED_SECRET --txid YOUR_BSV_TXID"
|
|
51
|
+
]
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function summarizeOutreachMessagePack() {
|
|
56
|
+
const pack = buildOutreachMessagePack();
|
|
57
|
+
return {
|
|
58
|
+
ok: true,
|
|
59
|
+
product: pack.product,
|
|
60
|
+
category: pack.category,
|
|
61
|
+
message_count: pack.messages.length,
|
|
62
|
+
artifact_count: pack.first_artifacts.length,
|
|
63
|
+
command_count: pack.first_commands.length,
|
|
64
|
+
first_message: pack.messages[0] ? pack.messages[0].message_ref : null
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
module.exports = {
|
|
69
|
+
buildOutreachMessagePack,
|
|
70
|
+
summarizeOutreachMessagePack
|
|
71
|
+
};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const packageJson = require("../package.json");
|
|
4
|
+
|
|
5
|
+
function buildOutreachTargetPack() {
|
|
6
|
+
return {
|
|
7
|
+
ok: true,
|
|
8
|
+
product: packageJson.name,
|
|
9
|
+
category: "machine-commerce-outreach-target-pack",
|
|
10
|
+
target_groups: [
|
|
11
|
+
{
|
|
12
|
+
target_ref: "agent_builders",
|
|
13
|
+
why_now: "need a first paid capability path with governed execution and proof-aware followthrough",
|
|
14
|
+
first_artifact: "/v1/release-center/summary",
|
|
15
|
+
first_cli: "xytara-run --url https://xytara.onrender.com --account acct_demo --command \"cli-run\" --task trust.verify --body-json '{\"subject_id\":\"subject-1\"}' --wallet-id merchant_wallet_main --wallet-secret YOUR_LOCAL_SIGNED_SECRET --txid YOUR_BSV_TXID"
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
target_ref: "adapter_authors",
|
|
19
|
+
why_now: "need a public starter plus a visible promotion path",
|
|
20
|
+
first_artifact: "/v1/adapter-partners/summary",
|
|
21
|
+
first_cli: "xytara-release --adapter-partners --summary"
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
target_ref: "tool_and_marketplace_authors",
|
|
25
|
+
why_now: "need a machine-commerce layer without stitching together payment, execution, and review",
|
|
26
|
+
first_artifact: "/v1/launch-narrative/summary",
|
|
27
|
+
first_cli: "xytara-release --launch --summary"
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
target_ref: "proof_aware_runtime_teams",
|
|
31
|
+
why_now: "need runtime results that continue cleanly into proof instead of stopping at logs",
|
|
32
|
+
first_artifact: "/v1/outreach-proof/summary",
|
|
33
|
+
first_cli: "xytara-release --outreach-proof --summary"
|
|
34
|
+
}
|
|
35
|
+
],
|
|
36
|
+
first_wave_guidance: [
|
|
37
|
+
"start with a small technically strong set, not a broad audience",
|
|
38
|
+
"lead each target to one first artifact, not the whole surface map",
|
|
39
|
+
"watch which first cli or route they actually use",
|
|
40
|
+
"tighten language before expanding beyond the first wave"
|
|
41
|
+
]
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function summarizeOutreachTargetPack() {
|
|
46
|
+
const pack = buildOutreachTargetPack();
|
|
47
|
+
return {
|
|
48
|
+
ok: true,
|
|
49
|
+
product: pack.product,
|
|
50
|
+
category: pack.category,
|
|
51
|
+
target_count: pack.target_groups.length,
|
|
52
|
+
first_target: pack.target_groups[0] ? pack.target_groups[0].target_ref : null,
|
|
53
|
+
guidance_count: pack.first_wave_guidance.length
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
module.exports = {
|
|
58
|
+
buildOutreachTargetPack,
|
|
59
|
+
summarizeOutreachTargetPack
|
|
60
|
+
};
|