xytara 2.7.0 → 2.9.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/README.md +1 -1
- package/RELEASE_NOTES.md +24 -0
- package/index.js +12 -0
- package/lib/announcement_pack.js +1 -1
- package/lib/ecosystem_entry.js +1 -1
- package/lib/framework_provider_promotion.js +235 -0
- package/lib/launch_narrative.js +1 -1
- package/lib/operator_intelligence.js +104 -1
- package/lib/outreach_message_pack.js +1 -1
- package/lib/outreach_proof.js +1 -1
- package/lib/outreach_target_pack.js +1 -1
- package/lib/phase_1_ecosystem_pack.js +1 -1
- package/lib/phase_1_openai_codex_pack.js +1 -1
- package/lib/phase_1_openai_codex_runtime_pack.js +1 -1
- package/lib/pricing_optimization_contract.js +221 -2
- package/lib/release_history.js +25 -0
- package/lib/release_pack.js +2 -2
- package/lib/soft_launch_pack.js +1 -1
- package/lib/treasury_destinations_contract.js +99 -1
- package/package.json +8 -4
- package/scripts/verify_framework_provider_promotion.js +152 -0
- package/scripts/verify_operator_observability_boundary.js +83 -0
- package/scripts/verify_pricing_experiment_plan.js +124 -0
- package/scripts/verify_release_candidate.js +5 -0
- package/scripts/verify_service.js +35 -0
- package/scripts/verify_treasury_public_boundary.js +97 -0
- package/server.js +27 -1
|
@@ -11,6 +11,27 @@ const PRICING_BAND_UNITS = {
|
|
|
11
11
|
trust_critical: 8
|
|
12
12
|
};
|
|
13
13
|
|
|
14
|
+
const PRICING_EXPERIMENT_REJECTION_CODES = [
|
|
15
|
+
"pricing_sample_too_sparse",
|
|
16
|
+
"experiment_not_registered",
|
|
17
|
+
"experiment_not_allowed_now",
|
|
18
|
+
"operator_approval_missing",
|
|
19
|
+
"baseline_metrics_missing",
|
|
20
|
+
"rollback_trigger_thresholds_missing",
|
|
21
|
+
"public_checkout_copy_review_missing",
|
|
22
|
+
"post_experiment_review_window_missing",
|
|
23
|
+
"target_surface_mismatch"
|
|
24
|
+
];
|
|
25
|
+
|
|
26
|
+
const PRICING_EXPERIMENT_LAUNCH_REQUIREMENTS = [
|
|
27
|
+
"operator_approval_recorded",
|
|
28
|
+
"sample_maturity_is_mature_live_signals",
|
|
29
|
+
"baseline_metrics_recorded_before_change",
|
|
30
|
+
"rollback_trigger_thresholds_recorded",
|
|
31
|
+
"public_checkout_copy_reviewed_for_accuracy",
|
|
32
|
+
"post_experiment_review_window_defined"
|
|
33
|
+
];
|
|
34
|
+
|
|
14
35
|
function normalizeAmount(value) {
|
|
15
36
|
const amount = Number(value || 0);
|
|
16
37
|
return Number.isFinite(amount) ? amount : 0;
|
|
@@ -466,6 +487,195 @@ function buildOptimizationRecommendations(state) {
|
|
|
466
487
|
};
|
|
467
488
|
}
|
|
468
489
|
|
|
490
|
+
function buildPricingExperimentPlan(state) {
|
|
491
|
+
const revenueSignals = buildRevenueSignalSummary(state);
|
|
492
|
+
const decisionGuardrail = buildPricingDecisionGuardrail(state);
|
|
493
|
+
const quoteCohorts = buildQuoteCohorts(state);
|
|
494
|
+
const sampleMaturity = revenueSignals.sample_maturity;
|
|
495
|
+
const experimentReady = decisionGuardrail.allow_price_change;
|
|
496
|
+
const candidateExperiments = [
|
|
497
|
+
{
|
|
498
|
+
experiment_id: "starter_api_pack_entry_price_test",
|
|
499
|
+
target_surface: "hosted_checkout_starter_api_pack",
|
|
500
|
+
hypothesis: "starter_entry_conversion_can_improve_without_degrading_refund_or_grant_success_rates",
|
|
501
|
+
required_segments: [
|
|
502
|
+
"first_purchase",
|
|
503
|
+
"hosted_checkout",
|
|
504
|
+
"starter_api_pack"
|
|
505
|
+
],
|
|
506
|
+
primary_metrics: [
|
|
507
|
+
"checkout_paid_rate",
|
|
508
|
+
"external_credit_grant_success_rate",
|
|
509
|
+
"execution_completion_rate"
|
|
510
|
+
],
|
|
511
|
+
rollback_triggers: [
|
|
512
|
+
"refund_or_chargeback_rate_increases",
|
|
513
|
+
"grant_failure_rate_increases",
|
|
514
|
+
"execution_completion_rate_decreases"
|
|
515
|
+
],
|
|
516
|
+
allowed_now: experimentReady
|
|
517
|
+
},
|
|
518
|
+
{
|
|
519
|
+
experiment_id: "utility_minimum_floor_test",
|
|
520
|
+
target_surface: "utility_pricing_band_minimum_charge_floor",
|
|
521
|
+
hypothesis: "utility_quote_abandonment_can_be_reduced_without_training_users_to_expect_free_execution",
|
|
522
|
+
required_segments: [
|
|
523
|
+
"pricing_band.utility",
|
|
524
|
+
"quote_created",
|
|
525
|
+
"quote_accepted_or_expired"
|
|
526
|
+
],
|
|
527
|
+
primary_metrics: [
|
|
528
|
+
"quote_conversion_rate",
|
|
529
|
+
"quote_abandonment_rate",
|
|
530
|
+
"revenue_capture_rate"
|
|
531
|
+
],
|
|
532
|
+
rollback_triggers: [
|
|
533
|
+
"revenue_capture_rate_decreases",
|
|
534
|
+
"support_or_refund_signal_increases",
|
|
535
|
+
"paid_execution_quality_decreases"
|
|
536
|
+
],
|
|
537
|
+
allowed_now: experimentReady
|
|
538
|
+
},
|
|
539
|
+
{
|
|
540
|
+
experiment_id: "trust_critical_premium_review",
|
|
541
|
+
target_surface: "trust_critical_premium_multiplier",
|
|
542
|
+
hypothesis: "high_consequence_work_may_support_higher_margin_when_conversion_is_already_strong",
|
|
543
|
+
required_segments: [
|
|
544
|
+
"pricing_band.trust_critical",
|
|
545
|
+
"converted_quotes",
|
|
546
|
+
"completed_transactions"
|
|
547
|
+
],
|
|
548
|
+
primary_metrics: [
|
|
549
|
+
"trust_critical_conversion_rate",
|
|
550
|
+
"completed_paid_execution_count",
|
|
551
|
+
"refund_or_dispute_rate"
|
|
552
|
+
],
|
|
553
|
+
rollback_triggers: [
|
|
554
|
+
"trust_critical_conversion_rate_decreases",
|
|
555
|
+
"refund_or_dispute_rate_increases",
|
|
556
|
+
"operator_quality_review_fails"
|
|
557
|
+
],
|
|
558
|
+
allowed_now: experimentReady
|
|
559
|
+
}
|
|
560
|
+
];
|
|
561
|
+
return {
|
|
562
|
+
experiment_plan_version: "xytara-pricing-experiment-plan-v1",
|
|
563
|
+
sample_maturity: sampleMaturity,
|
|
564
|
+
experiment_state: experimentReady ? "operator_reviewed_experiments_allowed" : "blocked_collect_more_live_data",
|
|
565
|
+
allow_experiment_launch: experimentReady,
|
|
566
|
+
required_minimum_live_sample: {
|
|
567
|
+
quote_count: 100,
|
|
568
|
+
payment_ledger_count: 20,
|
|
569
|
+
execution_transaction_count: 20,
|
|
570
|
+
refund_monitoring_required: true
|
|
571
|
+
},
|
|
572
|
+
current_evidence: {
|
|
573
|
+
counts: revenueSignals.counts,
|
|
574
|
+
rates: revenueSignals.rates,
|
|
575
|
+
pricing_band_cohorts: quoteCohorts.by_pricing_band
|
|
576
|
+
},
|
|
577
|
+
candidate_experiments: candidateExperiments,
|
|
578
|
+
launch_requirements: PRICING_EXPERIMENT_LAUNCH_REQUIREMENTS.slice(),
|
|
579
|
+
deterministic_rejection_codes: PRICING_EXPERIMENT_REJECTION_CODES.slice(),
|
|
580
|
+
launch_request_template: {
|
|
581
|
+
experiment_id: "starter_api_pack_entry_price_test",
|
|
582
|
+
target_surface: "hosted_checkout_starter_api_pack",
|
|
583
|
+
operator_approval_ref: "ops.pricing.approval.<date>",
|
|
584
|
+
baseline_metrics_ref: "ops.pricing.baseline.<date>",
|
|
585
|
+
rollback_trigger_thresholds: {
|
|
586
|
+
refund_or_chargeback_rate_increases: "operator_defined_threshold",
|
|
587
|
+
grant_failure_rate_increases: "operator_defined_threshold",
|
|
588
|
+
execution_completion_rate_decreases: "operator_defined_threshold"
|
|
589
|
+
},
|
|
590
|
+
public_checkout_copy_review_ref: "ops.pricing.copy_review.<date>",
|
|
591
|
+
post_experiment_review_window_days: 14
|
|
592
|
+
},
|
|
593
|
+
blocked_actions: experimentReady
|
|
594
|
+
? []
|
|
595
|
+
: [
|
|
596
|
+
"start_price_ab_test_from_sparse_signals",
|
|
597
|
+
"change_public_package_prices_without_operator_approval",
|
|
598
|
+
"change_minimum_floors_without_baseline_metrics",
|
|
599
|
+
"change_auto_topup_thresholds_without_repeat_usage_data"
|
|
600
|
+
],
|
|
601
|
+
allowed_actions: experimentReady
|
|
602
|
+
? [
|
|
603
|
+
"prepare_small_operator_reviewed_price_experiment",
|
|
604
|
+
"record_baseline_and_rollback_thresholds",
|
|
605
|
+
"run_one_surface_at_a_time"
|
|
606
|
+
]
|
|
607
|
+
: [
|
|
608
|
+
"collect_more_live_quote_payment_execution_and_refund_data",
|
|
609
|
+
"review_cohort_instrumentation",
|
|
610
|
+
"keep_current_public_prices_and_thresholds"
|
|
611
|
+
],
|
|
612
|
+
boundary: "pricing_experiments_are_operator_reviewed_and_data_gated_not_automatic_price_changes"
|
|
613
|
+
};
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
function validatePricingExperimentLaunchRequest(plan, request) {
|
|
617
|
+
const pricingPlan = plan || {};
|
|
618
|
+
const launchRequest = request || {};
|
|
619
|
+
const candidates = Array.isArray(pricingPlan.candidate_experiments)
|
|
620
|
+
? pricingPlan.candidate_experiments
|
|
621
|
+
: [];
|
|
622
|
+
const experimentId = launchRequest.experiment_id ? String(launchRequest.experiment_id) : "";
|
|
623
|
+
const candidate = candidates.find((entry) => entry && entry.experiment_id === experimentId) || null;
|
|
624
|
+
const rollbackThresholds = launchRequest.rollback_trigger_thresholds || {};
|
|
625
|
+
const missingRollbackThreshold = candidate
|
|
626
|
+
? (Array.isArray(candidate.rollback_triggers) ? candidate.rollback_triggers : [])
|
|
627
|
+
.some((trigger) => !rollbackThresholds || !rollbackThresholds[trigger])
|
|
628
|
+
: true;
|
|
629
|
+
const reviewWindowDays = Number(launchRequest.post_experiment_review_window_days || 0);
|
|
630
|
+
const rejectionCodes = [];
|
|
631
|
+
|
|
632
|
+
if (pricingPlan.allow_experiment_launch !== true || pricingPlan.sample_maturity !== "mature_live_signals") {
|
|
633
|
+
rejectionCodes.push("pricing_sample_too_sparse");
|
|
634
|
+
}
|
|
635
|
+
if (!candidate) {
|
|
636
|
+
rejectionCodes.push("experiment_not_registered");
|
|
637
|
+
} else {
|
|
638
|
+
if (candidate.allowed_now !== true) rejectionCodes.push("experiment_not_allowed_now");
|
|
639
|
+
if (launchRequest.target_surface && launchRequest.target_surface !== candidate.target_surface) {
|
|
640
|
+
rejectionCodes.push("target_surface_mismatch");
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
if (!launchRequest.operator_approval_ref) rejectionCodes.push("operator_approval_missing");
|
|
644
|
+
if (!launchRequest.baseline_metrics_ref) rejectionCodes.push("baseline_metrics_missing");
|
|
645
|
+
if (missingRollbackThreshold) rejectionCodes.push("rollback_trigger_thresholds_missing");
|
|
646
|
+
if (!launchRequest.public_checkout_copy_review_ref) rejectionCodes.push("public_checkout_copy_review_missing");
|
|
647
|
+
if (!Number.isFinite(reviewWindowDays) || reviewWindowDays < 1) {
|
|
648
|
+
rejectionCodes.push("post_experiment_review_window_missing");
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
return {
|
|
652
|
+
validation_version: "xytara-pricing-experiment-launch-validation-v1",
|
|
653
|
+
launch_allowed: rejectionCodes.length === 0,
|
|
654
|
+
experiment_id: experimentId || null,
|
|
655
|
+
sample_maturity: pricingPlan.sample_maturity || null,
|
|
656
|
+
rejection_codes: Array.from(new Set(rejectionCodes)),
|
|
657
|
+
required_requirements: PRICING_EXPERIMENT_LAUNCH_REQUIREMENTS.slice(),
|
|
658
|
+
boundary: "pricing_launch_validation_requires_mature_samples_operator_approval_baseline_metrics_and_rollback_thresholds"
|
|
659
|
+
};
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
function summarizePricingExperimentPlan(state) {
|
|
663
|
+
const plan = buildPricingExperimentPlan(state);
|
|
664
|
+
return {
|
|
665
|
+
product: "xytara",
|
|
666
|
+
category: "machine-commerce-pricing-experiment-plan-summary",
|
|
667
|
+
summary_version: "xytara-pricing-experiment-plan-summary-v1",
|
|
668
|
+
sample_maturity: plan.sample_maturity,
|
|
669
|
+
experiment_state: plan.experiment_state,
|
|
670
|
+
allow_experiment_launch: plan.allow_experiment_launch,
|
|
671
|
+
candidate_experiment_count: plan.candidate_experiments.length,
|
|
672
|
+
blocked_action_count: plan.blocked_actions.length,
|
|
673
|
+
launch_requirement_count: plan.launch_requirements.length,
|
|
674
|
+
deterministic_rejection_code_count: plan.deterministic_rejection_codes.length,
|
|
675
|
+
boundary: plan.boundary
|
|
676
|
+
};
|
|
677
|
+
}
|
|
678
|
+
|
|
469
679
|
function buildPricingOptimizationPack(state) {
|
|
470
680
|
const minimumChargeFloors = buildMinimumChargeFloors();
|
|
471
681
|
const starterPricing = buildStarterPricing();
|
|
@@ -476,6 +686,7 @@ function buildPricingOptimizationPack(state) {
|
|
|
476
686
|
const revenueSignalSummary = buildRevenueSignalSummary(state);
|
|
477
687
|
const pricingDecisionGuardrail = buildPricingDecisionGuardrail(state);
|
|
478
688
|
const packageThresholdRationale = buildPackageThresholdRationale(state);
|
|
689
|
+
const pricingExperimentPlan = buildPricingExperimentPlan(state);
|
|
479
690
|
return {
|
|
480
691
|
product: "xytara",
|
|
481
692
|
category: "machine-commerce-pricing-optimization-pack",
|
|
@@ -501,6 +712,7 @@ function buildPricingOptimizationPack(state) {
|
|
|
501
712
|
revenue_signal_summary: revenueSignalSummary,
|
|
502
713
|
pricing_decision_guardrail: pricingDecisionGuardrail,
|
|
503
714
|
package_threshold_rationale: packageThresholdRationale,
|
|
715
|
+
pricing_experiment_plan: pricingExperimentPlan,
|
|
504
716
|
optimization_recommendations: recommendations,
|
|
505
717
|
data_dependent_tuning: [
|
|
506
718
|
"conversion_test_starter_pack_pricing",
|
|
@@ -516,7 +728,9 @@ function buildPricingOptimizationPack(state) {
|
|
|
516
728
|
quote_cohorts_ref: "/v1/pricing-optimization/quote-cohorts",
|
|
517
729
|
recommendations_ref: "/v1/pricing-optimization/recommendations",
|
|
518
730
|
revenue_signal_summary_ref: "/v1/pricing-optimization/revenue-signal-summary",
|
|
519
|
-
decision_guardrail_ref: "/v1/pricing-optimization/decision-guardrail"
|
|
731
|
+
decision_guardrail_ref: "/v1/pricing-optimization/decision-guardrail",
|
|
732
|
+
experiment_plan_ref: "/v1/pricing-optimization/experiment-plan",
|
|
733
|
+
experiment_plan_summary_ref: "/v1/pricing-optimization/experiment-plan/summary"
|
|
520
734
|
}
|
|
521
735
|
};
|
|
522
736
|
}
|
|
@@ -541,6 +755,8 @@ function summarizePricingOptimizationPack(state) {
|
|
|
541
755
|
refund_count: pack.revenue_signal_summary.counts.refund_count,
|
|
542
756
|
execution_transaction_count: pack.revenue_signal_summary.counts.execution_transaction_count,
|
|
543
757
|
recommendation_count: pack.optimization_recommendations.recommendations.length,
|
|
758
|
+
candidate_experiment_count: pack.pricing_experiment_plan.candidate_experiments.length,
|
|
759
|
+
allow_experiment_launch: pack.pricing_experiment_plan.allow_experiment_launch,
|
|
544
760
|
linked_surfaces: pack.supported_surfaces
|
|
545
761
|
};
|
|
546
762
|
}
|
|
@@ -552,5 +768,8 @@ module.exports = {
|
|
|
552
768
|
buildQuoteCohorts,
|
|
553
769
|
buildRevenueSignalSummary,
|
|
554
770
|
buildPricingDecisionGuardrail,
|
|
555
|
-
buildOptimizationRecommendations
|
|
771
|
+
buildOptimizationRecommendations,
|
|
772
|
+
buildPricingExperimentPlan,
|
|
773
|
+
summarizePricingExperimentPlan,
|
|
774
|
+
validatePricingExperimentLaunchRequest
|
|
556
775
|
};
|
package/lib/release_history.js
CHANGED
|
@@ -10,6 +10,31 @@ function buildReleaseHistory() {
|
|
|
10
10
|
current_version: packageJson.version,
|
|
11
11
|
release_track: "public_release",
|
|
12
12
|
history: [
|
|
13
|
+
{
|
|
14
|
+
version: "2.9.0",
|
|
15
|
+
channel: "public_release",
|
|
16
|
+
maturity_posture: "public_polish",
|
|
17
|
+
headline: "public-polish release with canonical Naxytra product URLs and safer quote-first runtime first contact",
|
|
18
|
+
milestone_refs: [
|
|
19
|
+
"canonical_naxytra_product_url",
|
|
20
|
+
"standalone_product_domain_guard",
|
|
21
|
+
"quote_first_public_first_contact",
|
|
22
|
+
"release_summary_secretless_first_contact"
|
|
23
|
+
]
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
version: "2.8.0",
|
|
27
|
+
channel: "public_release",
|
|
28
|
+
maturity_posture: "release_boundary_hardened",
|
|
29
|
+
headline: "release-boundary hardening with provider promotion evidence gates, pricing experiment guardrails, treasury public-claim safety, and read-only operator observability boundaries",
|
|
30
|
+
milestone_refs: [
|
|
31
|
+
"framework_provider_promotion_evidence_gate",
|
|
32
|
+
"pricing_experiment_plan_gate",
|
|
33
|
+
"pricing_experiment_launch_gate",
|
|
34
|
+
"treasury_public_claim_boundary",
|
|
35
|
+
"operator_observability_read_only_boundary"
|
|
36
|
+
]
|
|
37
|
+
},
|
|
13
38
|
{
|
|
14
39
|
version: "2.7.0",
|
|
15
40
|
channel: "public_release",
|
package/lib/release_pack.js
CHANGED
|
@@ -172,7 +172,7 @@ function buildScenarioPack() {
|
|
|
172
172
|
"run xytara-run for trust.verify",
|
|
173
173
|
"inspect transaction, payment, and settlement records"
|
|
174
174
|
],
|
|
175
|
-
entrypoint: "xytara-run --
|
|
175
|
+
entrypoint: "xytara first-run --run-quote --account ACCOUNT_REF --pretty",
|
|
176
176
|
surfaces: [
|
|
177
177
|
"/v1/catalog/summary",
|
|
178
178
|
"/x402/commands/execute",
|
|
@@ -349,7 +349,7 @@ function buildReleasePack() {
|
|
|
349
349
|
},
|
|
350
350
|
first_contact: {
|
|
351
351
|
install: "npm install xytara",
|
|
352
|
-
direct_run_cli: "xytara-run --
|
|
352
|
+
direct_run_cli: "xytara first-run --run-quote --account ACCOUNT_REF --pretty",
|
|
353
353
|
discovery_surface: "/v1/catalog/summary",
|
|
354
354
|
transaction_center_surface: "/v1/transaction-center/summary",
|
|
355
355
|
economics_surface: "/v1/transaction-center/economics/summary",
|
package/lib/soft_launch_pack.js
CHANGED
|
@@ -39,7 +39,7 @@ function buildSoftLaunchPack() {
|
|
|
39
39
|
outreach_proof: "/v1/outreach-proof/summary",
|
|
40
40
|
adapter_partners: "/v1/adapter-partners/summary",
|
|
41
41
|
first_cli: "xytara-release --center --summary",
|
|
42
|
-
first_run_cli: "xytara-run --
|
|
42
|
+
first_run_cli: "xytara first-run --run-quote --account ACCOUNT_REF --pretty"
|
|
43
43
|
},
|
|
44
44
|
outreach_sequence: [
|
|
45
45
|
"send the short pitch and first proof path to a small builder set",
|
|
@@ -177,6 +177,30 @@ const RAIL_PROFILES = [
|
|
|
177
177
|
}
|
|
178
178
|
];
|
|
179
179
|
|
|
180
|
+
const TREASURY_PUBLIC_BOUNDARY_REJECTION_CODES = [
|
|
181
|
+
"public_custody_destination_leak",
|
|
182
|
+
"public_external_ref_leak",
|
|
183
|
+
"public_custody_ref_leak",
|
|
184
|
+
"public_reporting_ref_leak",
|
|
185
|
+
"public_wallet_ref_leak",
|
|
186
|
+
"public_provider_ref_leak",
|
|
187
|
+
"internal_rail_public_claimed",
|
|
188
|
+
"readiness_only_rail_public_claimed",
|
|
189
|
+
"claim_boundary_mismatch",
|
|
190
|
+
"unsupported_live_claim_rail",
|
|
191
|
+
"operator_visibility_rule_missing"
|
|
192
|
+
];
|
|
193
|
+
|
|
194
|
+
const SENSITIVE_PUBLIC_DESTINATION_FIELDS = [
|
|
195
|
+
"external_ref",
|
|
196
|
+
"custody_ref",
|
|
197
|
+
"reporting_ref",
|
|
198
|
+
"wallet_ref",
|
|
199
|
+
"provider_ref",
|
|
200
|
+
"merchant_address",
|
|
201
|
+
"merchant_paymail"
|
|
202
|
+
];
|
|
203
|
+
|
|
180
204
|
function classifyDestinationSource(profile, paymentConfig) {
|
|
181
205
|
const settlementMode = profile.settlement_mode;
|
|
182
206
|
const mapEntry = paymentConfig.treasury_destinations_by_settlement_mode[settlementMode];
|
|
@@ -432,6 +456,7 @@ function buildOperatorTreasuryDestinationsPack() {
|
|
|
432
456
|
? "claim_only_the_rails_with_real_configured_destinations_as_live_landing_paths"
|
|
433
457
|
: "no_multi-rail_operational_claims_until_real_destinations_exist",
|
|
434
458
|
custody_visibility_rule: "do_not_expose_real_external_refs_or_custody_refs_on_public_surfaces",
|
|
459
|
+
deterministic_rejection_codes: TREASURY_PUBLIC_BOUNDARY_REJECTION_CODES.slice(),
|
|
435
460
|
config_examples: Object.fromEntries(RAIL_PROFILES.map((profile) => [profile.settlement_mode, profile.config_template]))
|
|
436
461
|
};
|
|
437
462
|
}
|
|
@@ -458,6 +483,7 @@ function buildTreasuryDestinationsPack() {
|
|
|
458
483
|
operator_rule: operatorPack.operator_rule,
|
|
459
484
|
claim_discipline_rule: "unsupported_or_unconfigured_rails_may_be_listed_as_architecture_but_not_as_live_landing_paths",
|
|
460
485
|
privacy_rule: "public_surfaces_must_not_expose_real_treasury_landing_refs_or_custody_provider_refs",
|
|
486
|
+
deterministic_rejection_codes: TREASURY_PUBLIC_BOUNDARY_REJECTION_CODES.slice(),
|
|
461
487
|
config_examples: operatorPack.config_examples
|
|
462
488
|
};
|
|
463
489
|
}
|
|
@@ -475,6 +501,7 @@ function summarizeTreasuryDestinationsPack() {
|
|
|
475
501
|
readiness_only_profile_count: pack.readiness_summary.readiness_only_profile_count,
|
|
476
502
|
reporting_gap_count: pack.readiness_summary.reporting_gap_count,
|
|
477
503
|
internal_only_profile_count: pack.profiles.filter((entry) => entry.compliance_posture === "internal_only_policy_gated").length,
|
|
504
|
+
deterministic_rejection_code_count: pack.deterministic_rejection_codes.length,
|
|
478
505
|
public_claim_boundary: pack.public_claim_boundary,
|
|
479
506
|
linked_surfaces: pack.supported_surfaces
|
|
480
507
|
};
|
|
@@ -493,6 +520,7 @@ function summarizeOperatorTreasuryDestinationsPack() {
|
|
|
493
520
|
readiness_only_profile_count: pack.readiness_summary.readiness_only_profile_count,
|
|
494
521
|
reporting_gap_count: pack.readiness_summary.reporting_gap_count,
|
|
495
522
|
internal_only_profile_count: pack.profiles.filter((entry) => entry.compliance_posture === "internal_only_policy_gated").length,
|
|
523
|
+
deterministic_rejection_code_count: pack.deterministic_rejection_codes.length,
|
|
496
524
|
public_claim_boundary: pack.public_claim_boundary,
|
|
497
525
|
linked_surfaces: pack.supported_surfaces
|
|
498
526
|
};
|
|
@@ -534,10 +562,80 @@ function buildTreasuryDestinationValidationPreview(input) {
|
|
|
534
562
|
}
|
|
535
563
|
}
|
|
536
564
|
|
|
565
|
+
function arraysEqual(left, right) {
|
|
566
|
+
const leftSorted = (Array.isArray(left) ? left : []).slice().sort();
|
|
567
|
+
const rightSorted = (Array.isArray(right) ? right : []).slice().sort();
|
|
568
|
+
return leftSorted.length === rightSorted.length && leftSorted.every((entry, index) => entry === rightSorted[index]);
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
function validateTreasuryDestinationPublicBoundary(packInput) {
|
|
572
|
+
const pack = packInput || buildTreasuryDestinationsPack();
|
|
573
|
+
const profiles = Array.isArray(pack.profiles) ? pack.profiles : [];
|
|
574
|
+
const boundary = pack.public_claim_boundary || {};
|
|
575
|
+
const rejectionCodes = [];
|
|
576
|
+
const liveClaimableRails = profiles.filter((entry) => entry && entry.public_claim_allowed).map((entry) => entry.rail_id);
|
|
577
|
+
const internalOnlyRails = profiles
|
|
578
|
+
.filter((entry) => entry && entry.compliance_posture === "internal_only_policy_gated")
|
|
579
|
+
.map((entry) => entry.rail_id);
|
|
580
|
+
const readinessOnlyRails = profiles
|
|
581
|
+
.filter((entry) => entry && !entry.public_claim_allowed && entry.compliance_posture !== "internal_only_policy_gated")
|
|
582
|
+
.map((entry) => entry.rail_id);
|
|
583
|
+
|
|
584
|
+
for (const profile of profiles) {
|
|
585
|
+
if (!profile) continue;
|
|
586
|
+
if (profile.custody_destination != null) {
|
|
587
|
+
rejectionCodes.push("public_custody_destination_leak");
|
|
588
|
+
}
|
|
589
|
+
const visibility = profile.destination_visibility || {};
|
|
590
|
+
for (const fieldName of SENSITIVE_PUBLIC_DESTINATION_FIELDS) {
|
|
591
|
+
if (visibility[fieldName] != null) {
|
|
592
|
+
rejectionCodes.push(`public_${fieldName}_leak`);
|
|
593
|
+
}
|
|
594
|
+
if (profile[fieldName] != null) {
|
|
595
|
+
rejectionCodes.push(`public_${fieldName}_leak`);
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
if (profile.compliance_posture === "internal_only_policy_gated" && profile.public_claim_allowed === true) {
|
|
599
|
+
rejectionCodes.push("internal_rail_public_claimed");
|
|
600
|
+
}
|
|
601
|
+
if (boundary.readiness_only_rails && boundary.readiness_only_rails.includes(profile.rail_id) && profile.public_claim_allowed === true) {
|
|
602
|
+
rejectionCodes.push("readiness_only_rail_public_claimed");
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
const boundaryLiveRails = Array.isArray(boundary.live_claimable_rails) ? boundary.live_claimable_rails : [];
|
|
607
|
+
const boundaryReadinessRails = Array.isArray(boundary.readiness_only_rails) ? boundary.readiness_only_rails : [];
|
|
608
|
+
const boundaryInternalRails = Array.isArray(boundary.internal_only_rails) ? boundary.internal_only_rails : [];
|
|
609
|
+
if (
|
|
610
|
+
!arraysEqual(liveClaimableRails, boundaryLiveRails)
|
|
611
|
+
|| !arraysEqual(readinessOnlyRails, boundaryReadinessRails)
|
|
612
|
+
|| !arraysEqual(internalOnlyRails, boundaryInternalRails)
|
|
613
|
+
) {
|
|
614
|
+
rejectionCodes.push("claim_boundary_mismatch");
|
|
615
|
+
}
|
|
616
|
+
if (boundaryLiveRails.some((railId) => !profiles.some((entry) => entry && entry.rail_id === railId && entry.public_claim_allowed === true))) {
|
|
617
|
+
rejectionCodes.push("unsupported_live_claim_rail");
|
|
618
|
+
}
|
|
619
|
+
if (pack.category === "machine-commerce-operator-treasury-destinations-pack"
|
|
620
|
+
&& pack.custody_visibility_rule !== "do_not_expose_real_external_refs_or_custody_refs_on_public_surfaces") {
|
|
621
|
+
rejectionCodes.push("operator_visibility_rule_missing");
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
return {
|
|
625
|
+
validation_version: "xytara-treasury-public-boundary-validation-v1",
|
|
626
|
+
public_boundary_valid: rejectionCodes.length === 0,
|
|
627
|
+
rejection_codes: Array.from(new Set(rejectionCodes)),
|
|
628
|
+
deterministic_rejection_codes: TREASURY_PUBLIC_BOUNDARY_REJECTION_CODES.slice(),
|
|
629
|
+
public_claim_boundary: boundary,
|
|
630
|
+
boundary: "public_treasury_surfaces_must_not_expose_landing_or_custody_refs_and_must_match_claim_allowed_state"
|
|
631
|
+
};
|
|
632
|
+
}
|
|
633
|
+
|
|
537
634
|
module.exports = {
|
|
538
635
|
buildOperatorTreasuryDestinationsPack,
|
|
539
636
|
summarizeOperatorTreasuryDestinationsPack,
|
|
540
637
|
buildTreasuryDestinationsPack,
|
|
541
638
|
summarizeTreasuryDestinationsPack,
|
|
542
|
-
buildTreasuryDestinationValidationPreview
|
|
639
|
+
buildTreasuryDestinationValidationPreview,
|
|
640
|
+
validateTreasuryDestinationPublicBoundary
|
|
543
641
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "xytara",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.9.0",
|
|
4
4
|
"description": "Agent-commerce runtime for quote, pay, execute, deliver, meter, and integrate.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
|
@@ -10,10 +10,10 @@
|
|
|
10
10
|
},
|
|
11
11
|
"type": "commonjs",
|
|
12
12
|
"license": "Apache-2.0",
|
|
13
|
-
"homepage": "https://
|
|
13
|
+
"homepage": "https://naxytra.com/xytara",
|
|
14
14
|
"funding": {
|
|
15
15
|
"type": "individual",
|
|
16
|
-
"url": "https://
|
|
16
|
+
"url": "https://naxytra.com/xytara"
|
|
17
17
|
},
|
|
18
18
|
"keywords": [
|
|
19
19
|
"agent-commerce",
|
|
@@ -72,12 +72,16 @@
|
|
|
72
72
|
"verify:package": "node scripts/verify_all.js",
|
|
73
73
|
"verify:integrations": "node scripts/verify_integrations.js",
|
|
74
74
|
"verify:adapters": "node scripts/verify_adapters.js",
|
|
75
|
+
"verify:framework-provider-promotion": "node scripts/verify_framework_provider_promotion.js",
|
|
76
|
+
"verify:operator-observability-boundary": "node scripts/verify_operator_observability_boundary.js",
|
|
77
|
+
"verify:pricing-experiment-plan": "node scripts/verify_pricing_experiment_plan.js",
|
|
78
|
+
"verify:treasury-public-boundary": "node scripts/verify_treasury_public_boundary.js",
|
|
75
79
|
"verify:tooling": "node scripts/verify_tooling.js",
|
|
76
80
|
"verify:examples": "node scripts/verify_examples.js",
|
|
77
81
|
"verify:service": "node scripts/verify_service.js",
|
|
78
82
|
"verify:release-candidate": "node scripts/verify_release_candidate.js",
|
|
79
83
|
"verify:production-readiness": "node scripts/verify_production_readiness.js",
|
|
80
|
-
"verify:all": "node scripts/verify_all.js && node scripts/verify_integrations.js && node scripts/verify_adapters.js && node scripts/verify_tooling.js && node scripts/verify_examples.js && node scripts/verify_service.js",
|
|
84
|
+
"verify:all": "node scripts/verify_all.js && node scripts/verify_integrations.js && node scripts/verify_adapters.js && node scripts/verify_framework_provider_promotion.js && node scripts/verify_operator_observability_boundary.js && node scripts/verify_pricing_experiment_plan.js && node scripts/verify_treasury_public_boundary.js && node scripts/verify_tooling.js && node scripts/verify_examples.js && node scripts/verify_service.js",
|
|
81
85
|
"prepublishOnly": "npm run verify:release-candidate"
|
|
82
86
|
}
|
|
83
87
|
}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const assert = require("assert");
|
|
4
|
+
const {
|
|
5
|
+
FRAMEWORK_PROVIDER_CANDIDATES,
|
|
6
|
+
buildFrameworkProviderPromotionPack,
|
|
7
|
+
summarizeFrameworkProviderPromotionPack,
|
|
8
|
+
validateFrameworkProviderPromotionEvidence
|
|
9
|
+
} = require("../lib/framework_provider_promotion");
|
|
10
|
+
|
|
11
|
+
function normalizeUrl(baseUrl, healthPath) {
|
|
12
|
+
const url = new URL(baseUrl);
|
|
13
|
+
const normalizedPath = String(healthPath || "/health").startsWith("/")
|
|
14
|
+
? String(healthPath || "/health")
|
|
15
|
+
: `/${healthPath}`;
|
|
16
|
+
url.pathname = normalizedPath;
|
|
17
|
+
return url.toString();
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
async function checkHealth(candidate, env) {
|
|
21
|
+
const endpoint = env[candidate.endpoint_env];
|
|
22
|
+
const token = env[candidate.auth_env];
|
|
23
|
+
const healthPath = env[candidate.health_path_env] || "/health";
|
|
24
|
+
const started = Date.now();
|
|
25
|
+
const response = await fetch(normalizeUrl(endpoint, healthPath), {
|
|
26
|
+
method: "GET",
|
|
27
|
+
headers: {
|
|
28
|
+
Authorization: `Bearer ${token}`,
|
|
29
|
+
Accept: "application/json"
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
const latencyMs = Date.now() - started;
|
|
33
|
+
let body = null;
|
|
34
|
+
try {
|
|
35
|
+
body = await response.json();
|
|
36
|
+
} catch (_error) {
|
|
37
|
+
body = null;
|
|
38
|
+
}
|
|
39
|
+
return {
|
|
40
|
+
framework_id: candidate.framework_id,
|
|
41
|
+
adapter_id: candidate.adapter_id,
|
|
42
|
+
status_code: response.status,
|
|
43
|
+
latency_ms: latencyMs,
|
|
44
|
+
health_ok: response.ok && (!body || ["ok", "ready", "auth_required"].includes(String(body.status || body.readiness || "ok"))),
|
|
45
|
+
body_status: body && (body.status || body.readiness || null)
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function buildValidPromotionEvidence(candidateSummary) {
|
|
50
|
+
return {
|
|
51
|
+
framework_id: candidateSummary.framework_id,
|
|
52
|
+
adapter_id: candidateSummary.adapter_id,
|
|
53
|
+
task_ref: candidateSummary.task_ref,
|
|
54
|
+
operator_evidence_ref: `ops.framework_provider.${candidateSummary.framework_id}.2026-04-22`,
|
|
55
|
+
auth_boundary_ref: `ops.framework_provider.auth_boundary.${candidateSummary.framework_id}.2026-04-22`,
|
|
56
|
+
health_check: {
|
|
57
|
+
status_code: 200,
|
|
58
|
+
health_ok: true
|
|
59
|
+
},
|
|
60
|
+
latency_ms: 250,
|
|
61
|
+
latency_budget_ms: 2000,
|
|
62
|
+
failure_behavior_ref: `ops.framework_provider.failure_behavior.${candidateSummary.framework_id}.2026-04-22`,
|
|
63
|
+
proof_fact_shape_ref: `ops.framework_provider.proof_facts.${candidateSummary.framework_id}.2026-04-22`
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function assertRejected(pack, evidence, expectedCode) {
|
|
68
|
+
const validation = validateFrameworkProviderPromotionEvidence(pack, evidence);
|
|
69
|
+
assert.strictEqual(validation.promotion_allowed, false, `expected ${expectedCode} to block framework provider promotion`);
|
|
70
|
+
assert.strictEqual(
|
|
71
|
+
validation.rejection_codes.includes(expectedCode),
|
|
72
|
+
true,
|
|
73
|
+
`missing deterministic rejection code ${expectedCode}`
|
|
74
|
+
);
|
|
75
|
+
return validation;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
async function main() {
|
|
79
|
+
const pack = buildFrameworkProviderPromotionPack();
|
|
80
|
+
const summary = summarizeFrameworkProviderPromotionPack();
|
|
81
|
+
assert.strictEqual(pack.ok, true, "framework provider promotion pack failed");
|
|
82
|
+
assert.strictEqual(summary.framework_candidate_count, FRAMEWORK_PROVIDER_CANDIDATES.length, "framework candidate count mismatch");
|
|
83
|
+
assert.strictEqual(pack.promoted_provider_count, 0, "promotion pack must not auto-promote providers");
|
|
84
|
+
assert.strictEqual(pack.deterministic_rejection_codes.length >= 13, true, "framework promotion rejection codes missing");
|
|
85
|
+
assert.strictEqual(summary.deterministic_rejection_code_count, pack.deterministic_rejection_codes.length, "framework promotion summary rejection code count mismatch");
|
|
86
|
+
assert.strictEqual(
|
|
87
|
+
pack.strict_boundaries.includes("reference_framework_adapters_do_not_equal_live_provider_integrations"),
|
|
88
|
+
true,
|
|
89
|
+
"framework reference boundary missing"
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
assertRejected(pack, buildValidPromotionEvidence(pack.candidates[0]), "candidate_not_live_check_ready");
|
|
93
|
+
assertRejected(pack, { framework_id: "unknown_framework" }, "framework_not_registered");
|
|
94
|
+
|
|
95
|
+
const syntheticEnv = {
|
|
96
|
+
XYTARA_LANGGRAPH_PROVIDER_URL: "https://provider.example.test",
|
|
97
|
+
XYTARA_LANGGRAPH_PROVIDER_TOKEN: "configured-token-placeholder",
|
|
98
|
+
XYTARA_LANGGRAPH_PROVIDER_HEALTH_PATH: "/health"
|
|
99
|
+
};
|
|
100
|
+
const promotablePack = buildFrameworkProviderPromotionPack({ env: syntheticEnv });
|
|
101
|
+
const promotableCandidate = promotablePack.candidates.find((candidate) => candidate.framework_id === "langgraph");
|
|
102
|
+
const validEvidence = buildValidPromotionEvidence(promotableCandidate);
|
|
103
|
+
const validValidation = validateFrameworkProviderPromotionEvidence(promotablePack, validEvidence);
|
|
104
|
+
assert.strictEqual(promotableCandidate.state, "live_check_ready", "synthetic provider should be live-check ready");
|
|
105
|
+
assert.strictEqual(validValidation.promotion_allowed, true, "complete synthetic evidence should validate");
|
|
106
|
+
assert.deepStrictEqual(validValidation.rejection_codes, [], "complete synthetic evidence should not carry rejections");
|
|
107
|
+
|
|
108
|
+
assertRejected(promotablePack, { ...validEvidence, adapter_id: "wrong.adapter" }, "adapter_id_mismatch");
|
|
109
|
+
assertRejected(promotablePack, { ...validEvidence, task_ref: "wrong.task" }, "task_ref_mismatch");
|
|
110
|
+
assertRejected(promotablePack, { ...validEvidence, operator_evidence_ref: null }, "operator_evidence_missing");
|
|
111
|
+
assertRejected(promotablePack, { ...validEvidence, auth_boundary_ref: null }, "auth_boundary_evidence_missing");
|
|
112
|
+
assertRejected(promotablePack, { ...validEvidence, health_check: null }, "health_check_missing");
|
|
113
|
+
assertRejected(promotablePack, { ...validEvidence, health_check: { status_code: 503, health_ok: false } }, "health_check_failed");
|
|
114
|
+
assertRejected(promotablePack, { ...validEvidence, latency_ms: null }, "latency_measurement_missing");
|
|
115
|
+
assertRejected(promotablePack, { ...validEvidence, latency_ms: 3000, latency_budget_ms: 1000 }, "latency_budget_exceeded");
|
|
116
|
+
assertRejected(promotablePack, { ...validEvidence, failure_behavior_ref: null }, "failure_behavior_evidence_missing");
|
|
117
|
+
assertRejected(promotablePack, { ...validEvidence, proof_fact_shape_ref: null }, "proof_fact_shape_evidence_missing");
|
|
118
|
+
assertRejected(promotablePack, { ...validEvidence, provider_token: "sk_live_accidental_secret" }, "secret_material_forbidden");
|
|
119
|
+
|
|
120
|
+
const readyCandidates = pack.candidates.filter((candidate) => candidate.state === "live_check_ready");
|
|
121
|
+
if (pack.require_live) {
|
|
122
|
+
assert.strictEqual(readyCandidates.length > 0, true, "live provider promotion required but no endpoint/auth pair is configured");
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const live_checks = [];
|
|
126
|
+
for (const candidate of FRAMEWORK_PROVIDER_CANDIDATES) {
|
|
127
|
+
const candidateSummary = pack.candidates.find((entry) => entry.framework_id === candidate.framework_id);
|
|
128
|
+
if (!candidateSummary || candidateSummary.state !== "live_check_ready") continue;
|
|
129
|
+
const result = await checkHealth(candidate, process.env);
|
|
130
|
+
assert.strictEqual(result.health_ok, true, `${candidate.framework_id} live health check failed`);
|
|
131
|
+
live_checks.push(result);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
const result = {
|
|
135
|
+
ok: true,
|
|
136
|
+
product: "xytara",
|
|
137
|
+
category: "xytara-framework-provider-promotion-verification",
|
|
138
|
+
status: live_checks.length > 0 ? "live_provider_health_checks_passed" : "no_live_provider_evidence_configured",
|
|
139
|
+
live_check_count: live_checks.length,
|
|
140
|
+
promotion_allowed: false,
|
|
141
|
+
deterministic_rejection_code_count: pack.deterministic_rejection_codes.length,
|
|
142
|
+
adversarial_case_count: 13,
|
|
143
|
+
live_checks,
|
|
144
|
+
boundary: "this_verifier_checks_promotion_evidence_but_does_not_promote_reference_adapters_to_live_provider_claims"
|
|
145
|
+
};
|
|
146
|
+
process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
main().catch((error) => {
|
|
150
|
+
console.error(error && error.stack ? error.stack : error);
|
|
151
|
+
process.exit(1);
|
|
152
|
+
});
|