# พยานอิสระ

Canonical page: https://phishdestroy.github.io/TgWitness/th/docs/reference/witness/

เรียกใช้ witness ด้วยกุญแจและบอทของตัวเอง เผยแพร่จุดตรวจสอบที่ลงนามแล้วไปยังช่อง และตรวจสอบการส่งออกข้อมูลกับจุดตรวจสอบดังกล่าว

[การตั้งค่าบอทและพร็อกซีในภาษารัสเซีย](https://github.com/phishdestroy/TgWitness/blob/main/docs/ru/WITNESS.md)

ผู้เก็บข้อมูลจะลงนามในบันทึกของตนเอง ดังนั้นผู้ใดก็ตามที่ควบคุมผู้เก็บข้อมูลและกุญแจของมัน ก็สามารถ ในหลักการ เขียนใหม่หรือตัดทอนบันทึกและลงนามใหม่ได้ Witness ทำให้สิ่งนั้น สามารถตรวจพบได้ นี่เป็นกระบวนการแยกต่างหาก — คอนเทนเนอร์อีกตัว หรือดีกว่าคือเซิร์ฟเวอร์ที่บุคคลอื่น ดำเนินการ — ซึ่งจะดึงส่วนหัวของบันทึกที่ลงนามจากเครื่องมือเก็บข้อมูลทุกไม่กี่นาที ลงนามสิ่งที่ มันเห็นด้วยกุญแจของตัวเอง เก็บไว้ในบันทึกของตัวเอง และโพสต์ไปยังช่อง Telegram

แผนผังกระบวนการ · Collector → Witness (จุดตรวจสอบที่ลงนาม: จำนวนบันทึก + ค่าแฮชส่วนหัว); Witness → สมุดบันทึกพยาน, กุญแจส่วนตัว; Witness → ช่อง Telegram (โพสต์ที่ลงนามผ่านบอทของระบบเอง); ไฟล์ ZIP ของหลักฐาน → verify.py; สมุดบันทึกพยาน, กุญแจส่วนตัว → verify.py; ช่อง Telegram → verify.py (หน้าส่งออก Telegram Desktop หรือ t.me/s) · Collector · Witness · สมุดบันทึกพยาน,กุญแจส่วนตัว · ช่อง Telegram · ไฟล์ ZIP ของหลักฐาน · verify.py · จุดตรวจสอบที่ลงนาม: · จำนวนบันทึก + ค่าแฮชส่วนหัว · โพสต์ที่ลงนามผ่านบอทของระบบเ · อง · หน้าส่งออก Telegram Desktop · หรือ t.me/s

**แผนภาพในรูปแบบข้อความ**

1. Collector → Witness (จุดตรวจสอบที่ลงนาม: จำนวนบันทึก + ค่าแฮชส่วนหัว)
2. Witness → สมุดบันทึกพยาน, กุญแจส่วนตัว
3. Witness → ช่อง Telegram (โพสต์ที่ลงนามผ่านบอทของระบบเอง)
4. ไฟล์ ZIP ของหลักฐาน → verify.py
5. สมุดบันทึกพยาน, กุญแจส่วนตัว → verify.py
6. ช่อง Telegram → verify.py (หน้าส่งออก Telegram Desktop หรือ t.me/s)

## สิ่งที่ TgWitness สามารถทำได้ และสิ่งที่มันทำไม่ได้

| TgWitness มี | พยานไม่เคย |
| --- | --- |
| **โทเค็นพยาน**แบบอ่านอย่างเดียวสำหรับพื้นที่ทำงานหนึ่งแห่ง | เซสชัน Telegram หรือข้อมูลรับรอง API ของผู้เก็บข้อมูล |
| กุญแจ Ed25519 และบันทึกของตัวเอง | ห้องเก็บรักษาข้อมูลของระบบเก็บรวบรวม, กุญแจลงนาม หรือ โทเค็นแผงควบคุม |
| โทเค็นบอท Telegram ของตัวเอง | เนื้อหาข้อความ: ส่วนหัวประกอบด้วยจำนวนบันทึกและค่าแฮช |

โทเค็นถูกสร้างขึ้นบนหน้า **Witness** ของแผงควบคุม แสดงขึ้นเพียงครั้งเดียว และถูกเก็บไว้เพียงในรูปแบบ SHA-256 เท่านั้น มันเปิดจุดปลายทาง (endpoint) เพียงหนึ่งจุดเท่านั้น คือ `GET /api/witness/head` ซึ่งส่งคืน จุดตรวจสอบ (checkpoint) ที่เพิ่งลงนาม พร้อมตัวนับการเก็บข้อมูลที่ไม่มีเนื้อหา (content-free) ที่ลงนามแล้ว และสถานะการทำงาน มันไม่สามารถเปิดแผงควบคุม อ่านเนื้อหาข้อความ หรือเปลี่ยนการตั้งค่าได้ และ โทเค็นของแผงควบคุมไม่ได้รับการยอมรับที่นั่น สามารถเพิกถอนโทเค็นได้บนหน้าเดียวกัน เครื่องมือเก็บข้อมูลจะบันทึก เมื่อกุญแจพยานใหม่เริ่มตรวจสอบ (`witness.seen`) และแสดงการตรวจสอบครั้งสุดท้ายต่อโทเค็น; พยานที่ยังไม่ตรวจสอบภายใน 2.5 ช่วงเวลากำหนดจะถูกทำเครื่องหมายว่าเกินกำหนด

พยานใหม่จะส่งคำท้าแบบสุ่มใน การโหวตแต่ละครั้ง; คำสั่งบันทึกจะสะท้อนคำท้าดังกล่าวภายใต้ลายเซ็นของผู้รวบรวม ตัวนับ ถูกผูกกับจุดตรวจสอบที่แม่นยำและถูกรวมไว้ในโพสต์ของพยานที่ลงนามแล้ว พยานรุ่นเก่า ยังคงได้รับการยอมรับจากพยานแบบสแตนด์อโลน การเพิ่มขนาดของบันทึกเพียงอย่างเดียวจะไม่ถูกนับเป็นข้อความใหม่

## สิ่งที่ระบบตรวจสอบและบันทึก

ทุกช่วงเวลา (ค่าเริ่มต้นคือ 10 นาที) TgWitness จะ:

1. ดึงส่วนหัวมาเอง (ผู้รวบรวมข้อมูลไม่สามารถส่งหรือข้ามส่วนหัวนี้ได้);
2. ตรวจสอบลายเซ็นของผู้เก็บข้อมูล, กุญแจผู้เก็บข้อมูลที่ถูกตรึง (`--collector-fingerprint`, หรือกุญแจแรกที่พบ), จำนวนที่ไม่ลดลง และส่วนหัวที่ไม่เปลี่ยนแปลงที่จำนวนที่ไม่เปลี่ยนแปลง;
3. เพิ่มบันทึกที่ลงนามแล้วลงในบันทึกของตนเอง: `witness.anchor` ด้วยสถานะ `ok`, `key_changed`, `rollback` (จำนวนบันทึกน้อยกว่าเดิม), `fork` (ความยาวเท่ากัน แต่ส่วนหัวต่างกัน ) หรือ `invalid` (คำตอบไม่ผ่านการตรวจสอบ), หรือ `witness.no_response` เมื่อ ผู้รวบรวมข้อมูลไม่ตอบกลับ;
4. ส่งผลลัพธ์ไปยังช่อง (channel) พร้อมลายเซ็น รวมถึงข้อความ "no answer" ในขณะที่ TgWitness กำลังทำงานและสามารถเข้าถึง Bot API ได้ ID ของการโพสต์ถูกบันทึกไว้ (`witness.posted`), รวมถึงการโพสต์ที่ล้มเหลวด้วย (`witness.post_failed`).

โพสต์มีลักษณะดังนี้; บรรทัดสุดท้ายมีข้อความที่ลงนาม:

```
TgWitness witness #42 · journal head
Collector 3fa9c2d1e0b4a7f6: 18234 records
Head 9b1f…c07e
2026-10-28T19:40:00.123+00:00
TGW1.eyJhdCI6…<statement>.<signature>
```

## Run a witness

คุณจำเป็นต้องมีบอต Telegram (สร้างบอตด้วย @BotFather), ช่องที่บอตดังกล่าวเป็น ผู้ดูแลระบบ และที่อยู่ของผู้เก็บข้อมูลที่สามารถเข้าถึงได้จากผู้ให้คำพยาน — ผ่าน HTTPS นอก เครือข่ายส่วนตัว (ดูโปรไฟล์ HTTPS ใน[ส่วนการติดตั้ง](https://phishdestroy.github.io/TgWitness/th/docs/reference/deployment/))

เปิด **Extras → บอทในช่องของคุณ → ตั้งค่าบอท** ในแผงควบคุม สามขั้นตอน ได้แก่ สิทธิ์การเข้าถึงแบบอ่านอย่างเดียว, ช่องของคุณ และช่วงเวลา จากนั้นจึงเริ่มใช้งาน witness นโยบายการเผยแพร่ พร็อกซี HTTP/SOCKS5 (เลือกได้) และที่อยู่ API บอทที่กำหนดเอง อยู่ในส่วนการตั้งค่า**ขั้นสูง** แบบฟอร์ม จะดาวน์โหลด `witness.json` พร้อมกุญแจผู้เก็บข้อมูล (collector key) ของพื้นที่ทำงานนี้ที่ถูกตรึงไว้ ดาวน์โหลด โทเค็นอ่านอย่างเดียวที่สร้างขึ้นใหม่โดยใช้ตัวเลือก **“บันทึกไฟล์การเข้าถึง** เป็น `witness-token.txt` ” และวางมันพร้อมกับ `bot-token.txt` ที่สร้างขึ้นบนโฮสต์ของ witness ข้างๆ ไฟล์ JSON นั้น ผู้เก็บข้อมูลจะไม่ได้รับโทเค็นของบอทเลย การดาวน์โหลดไม่เริ่มบริการหรือเผยแพร่ข้อความ ไม่มีพยานโครงการที่โฮสต์ ถูกลงทะเบียนโดยอัตโนมัติ

```
python -m tgwitness.witness run --config witness.json --check-config
python -m tgwitness.witness run --config witness.json
python -m tgwitness.witness fingerprint --config witness.json
```

คำสั่งแรกตรวจสอบไฟล์การตั้งค่าและไฟล์ลับโดยไม่มีการส่งคำขอผ่านเครือข่ายหรือการสร้าง กุญแจ เส้นทางใน JSON เป็นเส้นทางสัมพัทธ์กับไฟล์นั้น ส่วนเส้นทาง CLI/สภาพแวดล้อมเป็นเส้นทางสัมพัทธ์กับ ไดเรกทอรีทำงาน เก็บลายนิ้วมือของพยานไว้ภายนอกโฮสต์ของมัน ตัวบ่งชี้ การสำรวจครั้งสุดท้ายของตัวเก็บข้อมูลยืนยันเพียงการร้องขอเท่านั้น; การเผยแพร่จะถูกรายงานโดย Proof หรือตรวจสอบ ในบันทึกพยานและช่องสื่อสาร

หากแผงควบคุมอยู่เบื้องหลังอุโมงค์ SSH ให้เปิดเผยเฉพาะจุดสิ้นสุดของ witness ที่กำหนดขอบเขตไว้บน ชื่อโฮสต์ HTTPS แยกต่างหาก โดยใช้[ตัวอย่าง Caddy นี้](https://github.com/phishdestroy/TgWitness/blob/main/deploy/Caddyfile.witness.example) พื้นที่ทำงานเริ่มต้นจะใช้ `https://witness.example.org` ส่วนพื้นที่ทำงานอื่น ๆ จะใช้ `https://witness.example.org/profiles/ID` โทเค็นยังคงจำเป็น; แผงควบคุมและ เส้นทาง API อื่น ๆ ของมันจะไม่ถูกส่งต่อโดยโฮสต์เสมือนนั้น

เลือก `all` สำหรับจุดตรวจสอบที่เผยแพร่เป็นประจำ ช่วงเวลา 5 นาที หมายถึงประมาณ 288 โพสต์ต่อพื้นที่ทำงานต่อวัน `changes`/`problems` ปล่อยให้จุดตรวจสอบบางส่วนไม่เผยแพร่โดยเจตนา MTProxy ใช้สำหรับไคลเอนต์ Telegram ของผู้รวบรวมข้อมูล การตรวจสอบ HTTP ของ Witness และ HTTPS Bot API ของ Telegram ใช้เส้นทางตรง/HTTP/SOCKS5 ของตนเอง ([Bot API](https://core.telegram.org/bots/api))

**ข้างๆ ตัวเก็บข้อมูล (collector) โดยใช้ Docker** (บนโฮสต์เดียวกัน — กระบวนการและกุญแจอิสระ แต่ ผู้ดำเนินการเดียวกัน): ใส่ค่าลงใน `.env` และเริ่มโปรไฟล์

```
TGWITNESS_WITNESS_TOKEN=tgww_...
TGWITNESS_WITNESS_BOT_TOKEN=123456:ABC...
TGWITNESS_WITNESS_CHANNEL=@your_witness_channel
# another workspace: TGWITNESS_WITNESS_COLLECTOR=http://tgwitness:8787/profiles/<workspace ID>

docker compose --profile witness up -d
docker compose logs witness     # prints the witness key fingerprint
```

หากใช้ภาพที่เผยแพร่แล้ว ให้ใช้`docker compose --project-directory . -f deploy/compose/compose.image.yaml --profile witness up -d`

**บนเซิร์ฟเวอร์ของผู้อื่น** (พยานอิสระที่แท้จริง): คัดลอกรีโพสิตอรีไปยังที่นั่น ตั้งค่า `TGWITNESS_WITNESS_COLLECTOR=https://your-collector.example.org` พร้อมทั้งค่าสามค่าข้างต้น ใน `.env` แล้ว

```
docker compose --project-directory . -f deploy/compose/compose.witness.yaml up -d
```

หรือโดยไม่ต้องใช้ Docker:

```
python -m tgwitness.witness run --collector https://your-collector.example.org \
    --token-file witness-token.txt --bot-token-file bot-token.txt --channel @your_witness_channel
```

### ตัวเลือก

| ตัวเลือก | สภาพแวดล้อม | ค่าเริ่มต้น | ความหมาย |
| --- | --- | --- | --- |
| `--interval` | `TGWITNESS_WITNESS_INTERVAL` | 10 | ระยะเวลาระหว่างการตรวจสอบ: 1–1440 นาที |
| `--timeout` | `_TIMEOUT` | 30 | เวลาที่ต้องรอตัวเก็บข้อมูลและ API ของ Bot: 5–600 วินาที |
| `--post` | `_POST` | `all` | `all`: ทุกการตรวจสอบ; `changes`: ปัญหาใหม่หรือหัวข้อใหม่; `problems`: มีแต่ปัญหาและคำตอบที่ขาดหายไป |
| `--title` | `_TITLE` | `TgWitness witness` | คำแรกๆ ของทุกโพสต์ในช่อง |
| `--collector-fingerprint` | `_COLLECTOR_FINGERPRINT` | – | ให้ปักคีย์ผู้เก็บข้อมูลไว้แทนที่จะเชื่อถือคำตอบแรก |
| `--proxy` | `_PROXY` | direct | `socks5://host:port` หรือ `http://host:port` |
| `--bot-api` | `_BOT_API` | `https://api.telegram.org` | ที่อยู่ API ของบอท เช่น เซิร์ฟเวอร์ API ของบอทในท้องถิ่น |
| `--data-dir` | `_DATA` | `witness-data` | กุญแจ Witness และบันทึก |
| `--config` | `_CONFIG` | – | ไฟล์ JSON พร้อมตัวเลือกใดก็ตามข้างต้น |

ที่อยู่ผู้รวบรวม โทเค็น และช่องมาจาก `--collector`, `--token` หรือ `--token-file`, `--bot-token` หรือ `--bot-token-file` และ `--channel`, หรือ `_COLLECTOR`, `_TOKEN`, `_TOKEN_FILE`, `_BOT_TOKEN`, `_BOT_TOKEN_FILE` และ `_CHANNEL` ซึ่งช่วยรักษาความลับไม่ให้ปรากฏใน รายการกระบวนการ

ไฟล์การตั้งค่าใช้ชื่อตัวเลือกที่มีขีดล่าง (underscore) พร้อมด้วย `texts` ซึ่งใช้แทนคำ ในโพสต์ของช่อง:

```
{"collector": "https://your-collector.example.org", "token_file": "witness-token.txt",
 "bot_token_file": "bot-token.txt", "channel": "@your_witness_channel",
 "interval": 5, "timeout": 30, "post": "changes", "title": "Partner witness",
 "texts": {"ok": "journal head", "no_response": "no answer from the collector", "records": "records"}}
```

กุญแจ `texts`: `ok`, `key_changed`, `rollback`, `fork`, `invalid`, `no_response`, `collector`, `records`, `head`. บรรทัดคำสั่งมีลำดับความสำคัญเหนือสภาพแวดล้อม และสภาพแวดล้อมมีลำดับความสำคัญเหนือไฟล์ ตัวเลือกหรือกุญแจข้อความที่ไม่รู้จักจะหยุดการทำงานของ witness พร้อมแสดงข้อความแจ้งเตือน แทนที่จะถูกละเลย คำที่ใช้ไม่เคยส่งผลต่อการตรวจสอบ: verify.py จะตรวจสอบโทเค็นที่ลงนามไว้ที่ท้ายทุก โพสต์ กับ `--post changes` หรือ `problems` การตรวจสอบที่ยังไม่ถูกโพสต์ยังคงอยู่ใน สมุดบันทึกพยาน และ `verify.py` จะแสดงรายการเหล่านั้นว่ายังไม่เคยถูกโพสต์; บันทึกเริ่มต้นจะระบุชื่อ นโยบาย การตรวจสอบทุกครั้งยังคงปรากฏในสมุดบันทึก ดังนั้นการโพสต์น้อยลงหมายถึงเวลา Telegram อิสระน้อยลง ไม่ใช่การตรวจสอบน้อยลง

แม้ไม่มีช่อง (channel) TgWitness ก็ยังคงเก็บบันทึกไว้ได้ เก็บลายนิ้วมือของกุญแจ TgWitness (`python -m tgwitness.witness fingerprint`) ไว้ที่อื่น

## ตรวจสอบ

สำหรับผู้ใช้ TgWitness สามารถส่งออกบันทึกได้ดังนี้:

```
python -m tgwitness.witness export --out witness.zip
# Docker (add -f deploy/compose/compose.witness.yaml on a witness server):
docker compose exec witness python -m tgwitness.witness export --out /witness/witness.zip
docker compose cp witness:/witness/witness.zip .
```

จากนั้น สามารถทำได้ทุกที่ โดยใช้ไฟล์ ZIP ที่ลงนามจากเครื่องมือเก็บข้อมูล และช่องสนทนาที่ส่งออกจาก Telegram Desktop (*ส่งออกประวัติการสนทนา* → JSON จะได้ `result.json` ) หรือหน้าสาธารณะ `https://t.me/s/…` ของมัน:

```
python verify.py tgwitness-evidence.zip --fingerprint COLLECTOR_SHA256 \
    --witness witness.zip --witness-fingerprint WITNESS_SHA256 --channel result.json
```

`verify.py` ตรวจสอบบันทึกของ Witness (ห่วงโซ่และลายเซ็น) จากนั้น**ตรวจสอบว่าทุกหัวข้อความที่ Witness ได้เห็นเป็นส่วนหนึ่งของบันทึกที่ส่งออก**: บันทึกที่ตำแหน่งนั้นต้องมี แฮชที่ตรงกันพอดี หัวข้อความที่ไม่ตรงกันจะผ่านการตรวจสอบไม่สำเร็จ — บันทึกถูกเปลี่ยนแปลงหลังจาก Witness ได้เห็นมัน นอกจากนี้ยังรายงานหัวข้อความที่เห็นหลังการส่งออก ความผิดปกติที่พยาน บันทึกไว้ คำตอบที่ล้มเหลว ช่วงเวลามีจุดตรวจสอบที่ตรงกันอยู่ใน การส่งออกนี้ ("ได้รับการยืนยันจาก X ถึง Y") และช่องว่าง จุดตรวจสอบที่ตามมาไม่ขยายช่วงเวลานั้น ผลลัพธ์รวมถึงหมายเลขบันทึกที่ตรงกันล่าสุดและจำนวนบันทึกที่ตามมา ที่ไม่มีจุดตรวจสอบที่ตรงกัน เฉพาะคำตอบที่ลงนามด้วยกุญแจของไฟล์ส่งออกเองเท่านั้นที่นับ: ไฟล์ส่งออกที่ลงนาม ด้วยกุญแจที่ผู้เป็นพยานไม่เคยเห็นจะถูกรายงานว่าไม่ได้รับการเป็นพยาน และหากไม่มี`--fingerprint` ผู้ ลงนามจะยังคงไม่ถูกตรึง ด้วย`--channel` ทุกโพสต์ที่ลงนามต้องตรงกับบันทึกในสมุดบันทึกของผู้เป็นพยาน บันทึกต่อบันทึก: โพสต์ที่เปลี่ยนแปลงจะล้มเหลวในการตรวจสอบ ส่วนโพสต์ที่ขาดหายไปจะถูกรายการไว้ วันที่ใน ไฟล์ส่งออก JSON ของ Telegram ที่ให้มา เป็นข้อมูลเมตาที่แก้ไขได้ ซึ่งอยู่นอกโทเค็นผู้เป็นพยานที่ลงนาม การตรงกับโทเค็นไม่ยืนยันวันที่เผยแพร่; ผลลัพธ์จะรายงานอย่างชัดเจน ว่าการตรวจสอบเวลาเผยแพร่ไม่ได้ดำเนินการ

### จำเป็นต้องมีขอบเขตการส่งออกที่มีผู้เป็นพยาน

สำหรับการส่งต่อข้อมูลที่ต้องรวมถึงบันทึกสุดท้ายที่มีพยานรับรอง ให้เพิ่ม `--require-witness`:

```
python verify.py tgwitness-evidence.zip --fingerprint COLLECTOR_SHA256 \
    --witness witness.zip --witness-fingerprint WITNESS_SHA256 --require-witness
```

สิ่งนี้ต้องการลายนิ้วมือของพยานที่เก็บรักษาไว้อย่างอิสระและจุดตรวจสอบที่ตรงกัน ที่จุดสิ้นสุดที่แม่นยำของการส่งออกนี้ จุดตรวจสอบที่ครอบคลุมเพียงส่วนนำหน้าก่อนหน้านี้ ไม่เพียงพอ ให้หยุดการเก็บข้อมูลชั่วคราว ให้พยานสังเกตสถานะสุดท้าย และส่งออก ก่อนที่จะมีการเขียนบันทึกเพิ่มเติม; หากบันทึกมีการเปลี่ยนแปลง ให้เก็บจุดตรวจสอบอีกจุดและ ส่งออกสถานะนั้น จุดตรวจสอบที่สร้างขึ้นภายหลังเพียงอย่างเดียวไม่สามารถตรวจสอบค่าแฮชสุดท้ายของการส่งออกที่สั้นกว่าได้ เมื่อมีการระบุ `--channel` ด้วย การขาดโพสต์ที่อ้างว่ามีอยู่หรือชุดการจับคู่ที่ว่างเปล่าจะทำให้การตรวจสอบ ที่เข้มงวดนี้ล้มเหลว หากไม่มีตัวบ่งชี้นี้ การตรวจสอบความสมบูรณ์แบบปกติจะยังคงรายงาน บันทึกที่ไม่มีพยานยืนยัน โดยไม่ปฏิเสธอาร์ไคฟ์ที่สมบูรณ์ในส่วนอื่น

ธงนี้ช่วยรักษาความสอดคล้องกับบันทึกพยานที่ได้รับการจัดเตรียมและตรึงไว้แล้ว ผู้ดำเนินการ ยังคงต้องยืนยันความเป็นอิสระของพยานและเก็บรักษาบันทึกของพยานไว้อย่างแยกต่างหาก ธงนี้ไม่ยืนยันความจริงของข้อความ การเก็บรวบรวมที่ครบถ้วน หรือระยะเวลาการทำงานที่วัดได้อย่างอิสระ

Witness แสดงให้เห็นว่าผู้เก็บข้อมูลได้รายงานอะไรในช่วงเวลาดังกล่าว และว่าการส่งออกข้อมูลในภายหลังสอดคล้อง กับข้อมูลนั้น มันไม่แสดงว่าผู้เก็บข้อมูลได้บันทึกทุกสิ่งที่ Telegram ส่งมา หรือ ว่าเนื้อหาของข้อความนั้นเป็นความจริง Witness ที่ถูกดำเนินการโดยผู้ดำเนินการเดียวกันบนเครื่องเดียวกันนั้น มีความน่าเชื่อถือต่ำกว่าเมื่อถูกดำเนินการโดยบุคคลอื่น

การเพิ่มจำนวนเพียงอย่างเดียวไม่สามารถยืนยันความต่อเนื่องแบบเพิ่มข้อมูลเท่านั้น (append-only) บนออนไลน์ได้: การเปรียบเทียบแบบออฟไลน์ ต้องตรวจสอบให้ตรงกันระหว่างแฮชของส่วนนำ (prefix hash) ที่เก็บไว้กับข้อมูลส่งออกทั้งหมดจากตัวเก็บรวบรวม ช่วงเวลาที่ Witness หยุดทำงานหรือการเผยแพร่ล้มเหลวจะทิ้งช่วงว่างที่ไม่มีจุดอ้างอิงจากภายนอก โพสต์ที่หายไป สามารถรายงานได้โดยเปรียบเทียบกับบันทึกของ Witness ที่เก็บรักษาไว้; ทั้งช่อง (channel) และเซิร์ฟเวอร์ ที่ควบคุมโดยผู้ดำเนินการเดียวกัน ล้วนไม่ใช่คลังข้อมูลของบุคคลที่สามที่ไม่สามารถเปลี่ยนแปลงได้
