Build a real PTP cascade inside one multi-NIC Linux host. Observe every hop. Compare every PHC. Change servos live. Measure holdover. Repeat.
Hosted demo · Install · Research · Architecture · Hardware · Experiments · API
PTPBox is a modern revival of the original namespace-based timing experiment.
It turns one Linux server into a physical chain of isolated PTP clocks using
real NICs, one network namespace per card, one ptp4l boundary clock per stage,
and a separate read-only PHC comparison pipeline. The Precision Observatory is
the control room: live topology, raw timing traces, per-hop error, selectable
servos, measured holdover, hardware-backed PPS/ts2phc experiments, hardware
inventory, notifications, and guarded start/stop control.
Every graph can also be captured as a timestamped PNG and collected in a
shared, accessible Observatory album.
The reference system is not a simulation: seven NVIDIA ConnectX-6 Dx adapters provide fourteen 100G timing ports, with a separate Intel X550 management link. The same application can still run in an explicitly labeled hardware-model mode when a live agent is unavailable.
Important
The web UI is safe to explore immediately. Starting the physical cascade moves
the NICs declared in agent/topology.json into network namespaces. Review that
file carefully and keep every management interface in
management_interfaces before running ptpboxctl setup or start.
This capture comes from the running seven-card host. It shows the ordered BC1→BC7 topology, per-node lock state, direct PHC differences, endpoint nanosecond RMS, and the unsmoothed BC1-relative trace updating together. The animated values are live measurements, not a prerecorded simulation dataset.
The first viewport is the experiment: BC1 grandmaster to BC7 ordinary clock, with five boundary clocks in between. Select a node to inspect its direct PHC difference from BC1, previous-hop delta, raw LinuxPTP servo RMS, path delay, frequency adjustment, comparison error bound, servo type, and holdover drift.
Note
Every control-room screenshot in this README was captured from the running seven-card reference host. Values are live and will change from sample to sample. The traces are not cosmetically smoothed.
Every graph panel has a Capture action. A capture preserves the complete instrument panel—not just its plotted pixels—so the graph title, evidence labels, operating mode, and timestamp travel with the image. Captures are written to the PTPBox host and appear for every connected operator in the Album page, where they can be opened full-size, downloaded as PNG files, or deleted.
When a hosted or development UI cannot reach the appliance album, the same action falls back to browser-local IndexedDB and labels the image This browser. Host and local captures are presented together in chronological order without confusing one storage location for the other.
Each rod is one physical hop, from BC2 through BC7. Its angle is the current previous-hop PHC delta minus a robust learned equilibrium: positive residuals swing right and negative residuals swing left. The visual scale follows the P95 swing envelope so nanosecond motion remains legible without smoothing the measurements. A large coherent phase shift is re-zeroed only after five confirming samples beyond the adaptive MAD threshold; Zero now establishes an operator-selected equilibrium immediately. The ledger below the pendulum keeps the raw hop delta, equilibrium, residual, envelope, and regime visible.
This is a measurement mapping, not a gravity simulation. It is designed to make stable jitter, a changing equilibrium, and downstream amplification apparent at a glance while preserving the exact values for analysis.
The covariance lab aligns all six previous-hop measurements by their common PHC comparison cycle, calculates each phase-change rate in ns/s, and analyzes a selectable 12, 24, or 48-change rolling window. Switch between the dimensional covariance matrix and normalized correlation, select any hop pair, and follow all fifteen unique relationships through time. The eigen spectrum shows how much matrix trace each orthogonal mode explains, while signed λ1 loadings expose which hops move together and which move against the dominant cascade mode.
The computation uses raw previous-hop differences before visualization zeroing. Constant equilibrium subtraction therefore cancels naturally and cannot manufacture correlation.
The Attractor Observatory reconstructs hidden state from the raw endpoint PHC
offset using Takens delay coordinates. It chooses the delay from the first local
minimum of average mutual information, falling back to the autocorrelation
1/e crossing when the finite record has no usable minimum. A false-nearest-
neighbor curve then selects the smallest sufficient embedding dimension. The
main trajectory shows x(t) against x(t − τ), preserves sample order, encodes
local occupancy, and marks repeatedly visited high-density regions as
recurrent-core candidates.
The page does not turn a visually appealing orbit into a chaos claim. Its evidence ledger independently checks embedding sufficiency, recurrent geometry, Grassberger–Procaccia correlation-dimension convergence, a Rosenstein-style early-time local-divergence fit, and stationarity of the current regime. The stronger “candidate attractor” label appears only when all five gates agree. A successive-maxima return map, the empirical multivariate Poincaré section, modal time traces, and rolling covariance eigenvalues remain visible so apparent structure can be cross-checked against the six-hop dynamics.
The live path uses at most the latest 384 raw endpoint samples, standardizes
only the reconstruction coordinates, excludes temporally adjacent neighbors
with a Theiler window, performs no interpolation, writes no clock, and reports
the complete method and finite-record limitations through /api/research.
The implementation follows the original work on
delay-coordinate reconstruction,
average-mutual-information lag selection,
false nearest neighbors, and
small-record Lyapunov estimation.
The dedicated Holdover mode turns a manual servo stop into a repeatable
experiment. Select one clock or the downstream chain, choose the qualification
dwell and capture duration, and arm the run. PTPBox first restores every
selected node's saved servo, then requires fresh PHC observations and
continuous LinuxPTP s2 lock inside the release gate. Any excursion resets the
dwell.
At release, each clock is zeroed against the median of its final qualified
BC1-relative PHC window. Clock adjustment changes to LinuxPTP free_running 1;
PTP messages, direct PHC monitoring, and the SQLite recorder continue. The
dominant graph shows unsmoothed accumulated time error from that baseline,
while the node ledger reports current wander, peak magnitude, RMS, raw sample
count, and least-squares rate error. Because 1 ns/s equals 1 ppb, the slope
directly exposes the free-running fractional-frequency error.
The original mixed servo assignment is preserved per node and restored automatically at the configured duration or immediately with Resume synchronization. Browser refreshes do not lose the run: the state machine is host-persistent, every raw row remains exportable, and long chart viewports are uniformly decimated without changing the stored dataset.
The metrology workbench renders two shared-scale clock-stability atlases from the same raw endpoint phase record. ADEV, MDEV, HDEV, PDEV, TOTDEV, and Theo1 remain dimensionless fractional-frequency deviations; TDEV, MTIE, and TIE RMS remain in nanoseconds. It reports the number of usable terms with every point, uses Theo1's effective averaging time (0.75m\tau_0), and never fills missing live samples or invents a pair-count confidence percentage. A weighted least-squares factor graph fuses direct BC1 comparisons, adjacent-hop constraints, and a common PPS edge when the hardware exposes one. The ensemble clock uses covariance-regularized inverse weighting, while the error budget separates cross-timestamp uncertainty, servo noise, observed path motion, and holdover prediction. Cascade uncertainty is propagated through the measured hop covariance instead of assuming that every stage is independent.
The path microscope records LinuxPTP slave-event-monitor TLVs for every
adjacent Sync/Follow_Up and Delay_Req/Delay_Resp exchange. t1 through t4,
both sequence IDs, and correction fields are retained as decimal strings so
nanosecond precision is not lost to JSON floating point. The directional
timestamp residual is intentionally labeled apparent: without a common
external timebase, it contains twice the inter-clock phase offset as well as
path asymmetry. PTPBox does not mislabel that observable as calibrated one-way
delay.
The Cascade Dynamics Observatory brings clock, network, servo, and oscillator evidence into one qualification-aware page:
- sliding ADEV/MDEV and first-difference FTU/ADEVS atlases expose stability regime changes instead of collapsing the complete run into one curve;
- Welch cross-spectral matrices show frequency-by-hop amplification, adjacent-hop coherence, phase, and dominant spatial modes, with multiresolution log-frequency coherent bands;
- servo-state transitions, dwell time, local pole estimates, Kalman NIS/innovation-whiteness checks, and ARX information eigenvalues reveal estimator health and identifiability;
- holdover reachability tubes estimate time-to-mask risk, while N-cornered clock decomposition remains gated until the clocks are genuinely independent in holdover;
- timing OAM separates constant time error, dynamic time error, peak-to-peak error, and measured hop accumulation;
- paired Sync/Delay observations classify round-trip congestion and directional imbalance without calling the result calibrated path asymmetry; and
- bicoherence, delay-embedding Betti curves, multiscale sample entropy, and lagged predictive dependence expose nonlinear structure without turning it into a chaos or causality claim.
The passive cascade map is intentionally not labeled formal string stability. That claim requires an independent persistently exciting input. For a PTPBox Kalman-family servo, the page can run a bounded random-phase multisine frequency experiment with a hard peak correction, fixed duration, and raw-offset abort limit. Instrumental cross spectra then publish plant and open-loop estimates, (S), (T), (KS), Nyquist geometry, a coherence-gated balanced disk margin, and a frequency-dependent plant-scatter/IQC-style envelope.
Caution
BC1-referenced adjacent-hop PHC differences telescope algebraically to the direct endpoint difference. PTPBox never presents that zero as a measured transfer-noise floor. FTU and ADEVS remain explicitly labeled clock + transfer composite until an independent loopback, common-edge, or calibrated residual is connected.
These panels are estimators and diagnostic instruments, not autonomous decision makers. Gain optimization evaluates captured samples only and stages a recommendation for operator review; it never explores gains on the live cascade. Hardware claims remain capability-gated, and profile checks are configuration guardrails rather than standards certification.
The nonlinear workbench now moves directly between the recurrence plot and a gain-parameter bifurcation map. For each multiplier from 0.25× to 2.50×, it replays the captured endpoint PHC phase through the configured PI gains, discards controller-state transients, and plots extrema from the settled tail. The 1.00× configured PI baseline and the first replay safety-bound crossing are marked on the same axes. When the endpoint is running another servo, such as adaptive Kalman, the line says PI baseline instead of implying that PI is live. The ledger keeps the active-controller provenance, base gains, settled RMS, response-band count, and regime visible.
This is intentionally labeled a replay bifurcation map and reports
live_changes: 0. It is a screening instrument for fixed, multi-band, and
divergent response regions—not proof that the physical clock cascade underwent
a mathematical bifurcation. That stronger claim requires a controlled hardware
gain sweep with adequate dwell and settled observations at every step.
The same nonlinear workbench includes a Fractal analysis view with three complementary finite-record diagnostics:
- Grassberger–Procaccia correlation dimension (D_2) reconstructs delayed endpoint-phase states at embedding dimensions 2 through 5, excludes temporal neighbors with a Theiler window, highlights the selected log–log scaling interval, and reports whether the estimate actually converges as embedding dimension increases.
- Higuchi graph dimension (D_H) measures the roughness of endpoint phase versus sample index and publishes the regression (R^2), sample count, and maximum interval (k). It is deliberately labeled as trace dimension rather than attractor dimension.
- MF-DFA estimates generalized Hurst exponents from (q=-4) through (q=4) and reports the spectrum width (\Delta h). Six deterministic shuffled surrogates preserve the phase-value distribution while breaking temporal order, helping distinguish correlation-driven width from a broad marginal distribution.
Higuchi starts at 32 endpoint samples, correlation dimension at 64, and MF-DFA
at 128. Every value comes from raw captured endpoint PHC phase without
interpolation and reports live_changes: 0. A non-integer dimension, high fit
quality, or broad multifractal spectrum is not by itself evidence of
deterministic chaos, exact self-similarity, or a strange attractor.
| Surface | Purpose |
|---|---|
| Cascade overview | See the physically verified topology, direct PHC differences, per-hop deltas, path delay, frequency correction, and servo state. |
| Multi-pendulum | Turn every previous-hop PHC residual into a connected rod angle, with robust equilibrium learning, regime-shift auto-zeroing, and a per-hop swing ledger. |
| Covariance lab | Compare synchronized phase-change rates as covariance or correlation, follow every pair through time, and inspect eigenvalues plus dominant-mode loadings. |
| Attractor Observatory | Reconstruct endpoint dynamics with Takens coordinates, choose lag with AMI, check embedding with false nearest neighbors, locate recurrent-core candidates, inspect return/Poincaré maps, estimate local divergence, gate on regime stationarity, and require corroborating evidence before showing a candidate-attractor label. |
| Metrology | Compare ADEV, MDEV, HDEV, PDEV, TOTDEV, and Theo1 on a shared fractional-frequency scale; compare TDEV, MTIE, and TIE RMS on a shared time-error scale; inspect drift and local noise-slope candidates; fuse redundant offset constraints; build an ensemble clock; and propagate a covariance-aware error budget. |
| Path microscope | Inspect preserved t1/t2/t3/t4 exchange timestamps, correction fields, independent sequence IDs, and scientifically qualified directional residuals. |
| Control intelligence | Estimate phase/frequency/drift, switch among quiet/dynamic/holdover models, predict thermal holdover, identify loop dynamics, detect changes, rank replay-safe PI gains, inspect settled response branches, and compare correlation, Higuchi, and multifractal scaling. |
| Cascade Dynamics Observatory | Follow dynamic stability, coherent spatial modes, passive hop amplification, estimator consistency, identifiability, timing OAM, holdover reachability, nonlinear structure, and evidence-gated active loop identification from one surface. |
| Holdover chamber | Qualify continuous lock, capture a per-node release baseline, stop adjustment without stopping observation, plot raw wander, report rate error, and restore the exact saved servos. |
| Resilience lab | Validate profile preset fields, expose kernel DPLL/SyncE state without inference, configure message authentication, and inject automatically expiring one-hop faults. |
| Analytics | Compare unsmoothed read-only PHC measurements, inspect the endpoint distribution, and export raw timestamped samples. |
| Durable experiments | Capture configuration and raw PHC samples in a SQLite/WAL run ledger, stop without losing data, and export an immutable CSV by run ID. |
| Servo & holdover control | Select native PI/linear-regression/null-frequency discipline, classic Kalman, adaptive phase/frequency/drift Kalman, or quiet/dynamic/holdover IMM per clock; change discipline while read-only monitoring stays live. |
PPS & ts2phc control |
Select a PHC or external PPS source, configure pins and ts2phc, or compare two or more PHCs against one physical PPS edge in strictly measurement-only mode. |
| Lifecycle control | Start or stop the real namespace cascade from the UI after the guarded host helper is installed. |
| Hardware inventory | Discover NICs, PCI addresses, drivers, link rates, PHCs, and hardware timestamping capability. |
| Notifications & event stream | Follow measurement health, lock state, active servo mix, threshold events, and operator actions. |
| Command palette | Press ⌘ K or Ctrl K to search every observatory page, clock, measurement surface, and live control, then open it without leaving the keyboard. |
| Graph album | Capture any graph as an evidence-rich PNG, review host-shared and browser-local images together, open a full-size preview, download, or delete. |
| Demo mode | Use an explicitly labeled deterministic fallback only when the live agent is unavailable. |
![]() |
![]() |
| Stability analytics Raw trace selection, endpoint density, window RMS, frequency correction, and CSV export. |
Repeatable experiments Step response, holdover, wander, and gain-sweep recipes. |
The inventory above is read from the host: sixteen PTP-capable ports, fourteen active 100G timing links, PHC device providers, PCI functions, drivers, and hardware timestamp capability.
This serves the complete UI, discovers the host, reads LinuxPTP logs, and stages configuration without moving interfaces or starting privileged processes.
git clone https://github.com/ahmadexp/PTPBox.git
cd PTPBox
npm ci
npm run build:standalone
PTPBOX_ROOT="$PWD" \
PTPBOX_WEB_ROOT="$PWD/dist-standalone" \
python3 agent/ptpbox_agent.pyOpen http://localhost:8090. If the agent cannot find live measurements, the Observatory labels itself as a hardware model and keeps every visualization interactive.
# 1. Map this machine's PTP ports and protect its management links.
$EDITOR agent/topology.json
# 2. Build, install, and start the persistent web agent.
npm ci
npm run build:standalone
sudo PTPBOX_USER="$(id -un)" PTPBOX_ROOT="$PWD" bash scripts/install-host.sh
# 3. Validate before moving any NIC.
sudo ptpboxctl discover
sudo ptpboxctl status
# 4. Start from the CLI, or use Start cascade in the Observatory.
sudo ptpboxctl startThe UI is then available at http://<ptpbox-host>:8090. See the complete
installation and upgrade guide before starting the data
plane.
flowchart LR
Browser["Precision Observatory\nReact UI"]
Agent["PTPBox agent\nPython · unprivileged"]
Inventory["sysfs · ethtool\nNIC / PHC inventory"]
Logs["LinuxPTP logs\ntelemetry parser"]
PHCs["/dev/ptp*\nread-only comparisons"]
Helper["ptpboxctl\nfixed privileged verbs"]
Research["Metrology engine\nstability · fusion · modes"]
Store["SQLite/WAL\nruns + raw samples"]
Events["LinuxPTP monitor TLVs\nt1 · t2 · t3 · t4"]
Kalman["PTPBox servo worker\nclassic · adaptive · IMM"]
NS["BC1 … BC7\nnetwork namespaces"]
PTP["one ptp4l per NIC\nhardware boundary clocks"]
Browser <-->|"HTTP · :8090"| Agent
Agent --> Inventory
Agent --> Logs
Agent --> PHCs
Agent --> Events
Agent --> Research
Agent --> Store
Agent -. "sudo: fixed lifecycle + servo verbs" .-> Helper
Helper --> NS
NS --> PTP
PTP -. "raw offset / delay" .-> Kalman
Kalman -. "bounded PHC frequency" .-> NS
Helper -. "guarded PPS config" .-> PPS["optional ts2phc\nPHC PPS out / in"]
The agent runs as the operator, not root. Observation stays unprivileged. Lifecycle, servo, and bounded-fault control cross a narrow sudo boundary that accepts six fixed operations and no arbitrary command line. See Architecture and Security.
The Configuration page also exposes a safe-off-by-default PPS lab: select a PHC
source or external PPS, choose PPS input clocks, pins, edge, pulse width, phase,
correction, and the ts2phc servo. Apply validates the real periodic-output and
external-timestamp capabilities before a managed process is started. The
Overview reports each clock's actual PPS role, connector function, and runtime
state from sysfs and the managed process table.
- Common-epoch PHC difference for each NIC relative to BC1, using the best of nine kernel cross timestamps and an interpolated BC1 reference, sampled at the applied 0.5–8 Hz protocol-valid Sync cadence
- Raw LinuxPTP servo-offset RMS in nanoseconds, separate from PHC comparison dispersion and its reported error bound
- Overlapping ADEV, MDEV, HDEV, PDEV, TOTDEV, and Theo1 fractional-frequency stability plus TDEV, MTIE, and TIE RMS time-error stability across supported averaging intervals, including usable-term counts, detrended phase RMS, frequency bias/drift, and explicitly qualified local MDEV noise-slope candidates
- Read-only previous-hop delta and cumulative cascade error
- LinuxPTP master offset, mean path delay, and frequency adjustment
- Preserved
t1/t2/t3/t4timestamp-exchange records and qualified apparent directional residuals - Classic and adaptive Kalman phase/frequency/drift estimates, covariance-derived uncertainty, innovation acceptance, rejected-sample count, and applied bounded correction
- IMM quiet/dynamic/holdover probabilities and the active regime
- Temperature-aware holdover prediction with uncertainty
- ARX actuation-to-phase model with poles, fit, residual, settling estimate, measured Bode magnitude/phase, Nyquist geometry, direct Jury/Schur digital stability, and a bilinear-equivalent Routh–Hurwitz array
- Replay-only Gaussian-process PI recommendation with the evaluated safe frontier and zero live exploratory changes
- Lock/tracking state and recovery events
- Holdover qualification progress, per-node release baselines, elapsed free-run time, current/peak/RMS wander, and frequency drift from the continuing raw PHC trace
- Offset distribution, P95, skew, and contribution share
- Weighted factor-graph residuals, covariance-regularized ensemble weights, and correlated-versus-independent cascade uncertainty
- Rolling phase-change covariance/correlation, full pair timelines, eigenvalues, explained trace, effective rank, and dominant eigenvector loadings
- Delay-coordinate endpoint reconstruction, AMI lag selection, false-nearest- neighbor curves, recurrent-core occupancy, successive-maxima return maps, finite-record local divergence, empirical Poincaré crossings, modal coordinates, and rolling eigenvalue shares
- Recurrence rate/determinism, Koopman/DMD amplification, and Bayesian online change probability
- NIC carrier, speed, driver, PCI bus, PHC, and timestamp capability
- Per-node PPS availability, configured in/out role, live PHC pin function,
channel, connector, and managed
ts2phcstate - Experiment metadata, servo constants, and capture lifecycle
The live agent reads mapped PHCs without changing them and separately parses native LinuxPTP output. Missing data is never silently presented as live; the UI switches to its deterministic hardware-model mode.
When the Observatory says LIVE · RAW · UNSMOOTHED, the plotted points come
from the installed machine. Each PHC comparison uses Linux
PTP_SYS_OFFSET_EXTENDED cross timestamps and selects the lowest-error reading
from a nine-sample measurement burst. That improves the error bound of one
measurement; it does not average or smooth the time series.
Servo RMS is calculated separately from native LinuxPTP master-offset samples
reported by ptp4l. The UI never substitutes PHC-comparison dispersion for
servo RMS. During holdover, observation continues while only the selected clock
discipline is disabled, so drift remains measurable. If either raw source is
missing or stale, the interface says so instead of manufacturing a live value.
The path microscope is raw in a different sense: it preserves the exchange timestamps exported by LinuxPTP's event monitor. Its apparent forward/reverse residual is not a one-way path calibration because the two PHCs are not already on a common timebase. A shared external PPS edge can provide an independent multi-PHC comparison when the NICs expose external-timestamp pins, but it also remains read-only.
The current reference host uses seven dual-port ConnectX-6 Dx adapters with all fourteen timing links at 100G, plus a separate Intel X550 management adapter. Each timing adapter is isolated in its own namespace. PTPBox never hides a split-clock card with a local synchronization loop: if its ports do not share or hardware-synchronize a PHC, the direct comparison exposes that difference as part of the experiment.
ConnectX cards must have device-wide real-time clock mode enabled and loaded by a supported firmware reset. The hardware guide includes the verified setting, reset sequence, current PCI/PHC map, and cable-probe workflow.
![]() |
![]() |
| The original seven-NIC PTPBox host | The original namespace cascade concept |
Read the hardware and topology guide for discovery commands, shared-PHC behavior, interface mapping, and a preflight checklist.
app/ Precision Observatory UI
agent/ Read-only host API, topology, systemd template
scripts/ Safe lifecycle, install, and uninstall helpers
standalone/ Static-host entrypoint for the on-box agent
docs/ Installation, research, architecture, API, hardware, experiments
tests/ Rendered-product checks
.github/workflows/ CI for UI, Python, shell, and standalone builds
npm ci
npm run dev # local application server
make check # lint, tests, both builds, Python and shell validationThe main application uses React 19, TypeScript, Vinext/Vite, and Canvas-based telemetry charts. The host agent uses only the Python standard library.
The complete Precision Observatory is running on the seven-NIC reference host: the ordered namespace cascade, common-epoch PHC comparison, raw LinuxPTP telemetry, selectable native/Kalman/adaptive/IMM servos, measured holdover, packet-path capture, stability metrology, factor fusion, ensemble time, covariance-aware error budgets, nonlinear-dynamics diagnostics, guarded profiles/security/faults, PPS common-edge comparison, and durable experiment storage are implemented. Hardware-dependent instruments say not exposed instead of inferring state when the driver or kernel lacks the required API. See CHANGELOG.md.
The implementations are dependency-free and intentionally compact so they can run on the appliance, but their definitions and operational boundaries follow primary references:
- NIST SP 1065, Handbook of Frequency Stability Analysis for Allan-family, time-deviation, MTIE, and Theo statistics;
- IEEE 1139-2022 for frequency-and-time metrology terminology, and the primary PVAR paper for parabolic deviation;
- Linux kernel PTP hardware clock infrastructure for PHC clocks, cross timestamps, EXTS, and periodic outputs;
- Linux kernel DPLL subsystem for capability-gated physical-frequency state;
- LinuxPTP servo configuration
and
ts2phcfor native servos, PPS, and Authentication TLVs; - NIST, Steering a Time Scale for weighted ensemble-clock design;
- Adams and MacKay, Bayesian Online Changepoint Detection for causal regime-change probability;
- Schmid, Dynamic Mode Decomposition of Numerical and Experimental Data for the snapshot-based dynamics operator;
- Snoek, Larochelle, and Adams, Practical Bayesian Optimization for Gaussian-process expected-improvement search.
See Architecture for the exact implementation and interpretation limits.
This project modernizes the public Time Appliances Project PTPBox prototype, created by Ahmad Byagowi. The namespace architecture, seven-node cascade, and hardware photographs come from that work.
Bug reports, hardware profiles, measurement ideas, and UI improvements are welcome. Start with CONTRIBUTING.md and keep hardware safety front and center. Contributions grant Ahmad Byagowi the right to incorporate and commercially license the submitted work as part of PTPBox; see the contribution terms before submitting.
PTPBox is source-available under the PTPBox Noncommercial Source License 1.0.
You may use, study, modify, and redistribute PTPBox for noncommercial purposes, subject to the license terms. Any commercial use requires prior, express written approval from Ahmad Byagowi. The author reserves all commercial rights exclusively; an approved third-party use is only a limited exception within the scope of its written agreement.
© 2026 Ahmad Byagowi. All rights reserved except as stated in the license.















