tibet-report 0.1.0__tar.gz

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.
@@ -0,0 +1,147 @@
1
+ # Secrets & env
2
+ .env
3
+ *.env
4
+ *.secret
5
+
6
+ # Keys & certs
7
+ *.key
8
+ *.pem
9
+ certs/
10
+ secrets/
11
+
12
+ # Databases & dumps
13
+ *.db
14
+ *.sqlite
15
+ *.sql
16
+ dump_*/
17
+
18
+ # EXCEPT: Allow database schemas (needed for server rebuild)
19
+ !database-schemas/*.sql
20
+
21
+ # Logs & runtime data
22
+ logs/
23
+ *.log
24
+ __pycache__/
25
+ *.pyc
26
+ venv/
27
+ .venv/
28
+ **/venv/
29
+ **/.venv/
30
+
31
+ # Configs met secrets (we gebruiken straks templates)
32
+ config/
33
+ brain_api/provisioning.local.json
34
+ brain_api/provisioning.json
35
+
36
+ # Landing pages (privé - niet open source)
37
+ landing-pages/
38
+ humotica.com/
39
+ jtel.nl/
40
+
41
+ # Social media posts (strategie - niet open source)
42
+ SOCIAL-MEDIA-POSTS.md
43
+ HN-POST-UNDER-4000.md
44
+ STRATO-DEPLOY-HUMOTICA.md
45
+
46
+ # Endorsement outreach (privaat contact)
47
+ ARXIV-ENDORSEMENT-OUTREACH.md
48
+
49
+ # Deployment secrets
50
+ DEPLOYMENT-GUIDE.md
51
+
52
+ # R Project files (Dirty Data Challenge)
53
+ .Rproj.user
54
+ .Rhistory
55
+ .RData
56
+ .Ruserdata
57
+ *.zip
58
+ .mural_tokens.json
59
+ auth.json
60
+ gen-lang-client*.json
61
+ *.credentials.json
62
+
63
+ # Rust build artifacts
64
+ **/target/
65
+ *.whl
66
+
67
+ # Compiled binaries (build locally)
68
+ jis-router/jis-router
69
+ sentinel-rs/sentinel-rs
70
+
71
+ # Build distribution
72
+ sandbox/ai/codex/dist/
73
+ sandbox_backup/
74
+ did-jis-core
75
+
76
+ # =============================================================================
77
+ # Eigen repos — hebben hun eigen git remotes, niet dubbel opslaan
78
+ # =============================================================================
79
+
80
+ # Packages (elk een eigen repo)
81
+ packages/jis-iam-bridge/
82
+ packages/rapid-rag/
83
+ packages/reflux/
84
+ packages/sema-protocol/
85
+ packages/tibet-anticheat/
86
+ packages/tibet-ci/
87
+ packages/tibet-claw/
88
+ packages/tibet-context/
89
+ packages/tibet-core/
90
+ packages/tibet-db/
91
+ packages/tibet-edge/
92
+ packages/tibet-forge/
93
+ packages/tibet-iot/
94
+ packages/tibet-jawbreaker/
95
+ packages/tibet-ledger/
96
+ packages/tibet-marketplace/
97
+ packages/tibet-mesh/
98
+ packages/tibet-mirror/
99
+ packages/tibet-nis2/
100
+ packages/tibet-overlay/
101
+ packages/tibet-phantom/
102
+ packages/tibet-phantom-mcp/
103
+ packages/tibet-ping/
104
+ packages/tibet-pol/
105
+ packages/tibet-pqc/
106
+ packages/tibet-sbom/
107
+ packages/tibet-snap/
108
+ packages/tibet-soc/
109
+ packages/tibet-spiffe/
110
+ packages/tibet-tools/
111
+ packages/tibet-trail/
112
+ packages/tibet-triage/
113
+ packages/tibet-triage-mcp/
114
+ packages/tibet-twin/
115
+ packages/tibet-workload/
116
+ packages/tibet-y2k38/
117
+ packages/tlex-edge/
118
+ packages/tibet-tail/
119
+ packages/tibet-nc/
120
+
121
+ # Sub-projects met eigen repos
122
+ bunq7/
123
+ humotica-core/
124
+ jis-core/
125
+ JTm-dev/
126
+ kit-package/
127
+ symbAIon/
128
+ tibet-audit/
129
+ tibet-audit-npm/
130
+ tibet-core/
131
+ tibetclaw/
132
+ snaft/
133
+
134
+ # MCP servers (eigen repos)
135
+ mcp-servers/aidrac/
136
+ mcp-servers/ainternet/
137
+ mcp-servers/mcp-server-jis/
138
+ mcp-servers/sensory/
139
+ mcp-servers/tibet/
140
+
141
+ # Hackathon sub-repos
142
+ hackaway2026/clawmetry/
143
+
144
+ # Private memory (eigen repo)
145
+ .root_ai_memory/
146
+ .root_ai_thoughts/
147
+ brain_api/static/*.apk
@@ -0,0 +1,41 @@
1
+ # Enterprise Support
2
+
3
+ This package is part of the [TIBET ecosystem](https://pypi.org/project/tibet/) by [Humotica](https://humotica.com) — provenance, identity, and trust infrastructure for AI systems.
4
+
5
+ ## Contact
6
+
7
+ | Channel | Address | Use case |
8
+ |---------|---------|----------|
9
+ | **Enterprise** | enterprise@humotica.com | Private hub, SLA, dedicated support, integration partnerships |
10
+ | **Support** | support@humotica.com | Technical support, bug reports, feature requests |
11
+ | **Security** | security@humotica.com | Vulnerability disclosure (coordinated disclosure preferred) |
12
+
13
+ ## What we offer
14
+
15
+ - **Private Hub** — self-hosted .aint domain registry and I-Poll messaging for your organization
16
+ - **Dedicated Support** — direct engineering support with SLA
17
+ - **Custom Integration** — help integrating TIBET provenance into your existing CI/CD, compliance, or audit workflows
18
+ - **Compliance Mapping** — guidance on EU AI Act, NIS2, and DORA alignment using TIBET tokens
19
+
20
+ ## Compliance
21
+
22
+ The TIBET ecosystem provides building blocks for compliance with:
23
+
24
+ - **EU AI Act** (Art. 12) — logging and traceability via TIBET tokens
25
+ - **NIS2** (Art. 21) — supply chain security via cryptographic provenance
26
+ - **DORA** — ICT risk management via audit trails and sealed snapshots
27
+
28
+ > TIBET is compliance-enabling, not compliance-certifying. It provides the technical controls; your legal team maps them to your obligations.
29
+
30
+ ## Stats
31
+
32
+ - 105,000+ PyPI downloads across 112 countries
33
+ - 90+ packages in the ecosystem
34
+ - Used in enterprise mirrors, CI/CD pipelines, and production workflows
35
+
36
+ ## Links
37
+
38
+ - [AInternet](https://ainternet.org) — the AI network
39
+ - [Documentation](https://ainternet.org/docs/)
40
+ - [PyPI ecosystem](https://pypi.org/project/tibet/)
41
+ - [GitHub](https://github.com/Humotica)
@@ -0,0 +1,105 @@
1
+ Metadata-Version: 2.4
2
+ Name: tibet-report
3
+ Version: 0.1.0
4
+ Summary: Audit dossier assembler — verifiable remediation reports from TIBET provenance chains
5
+ Project-URL: Homepage, https://ainternet.org
6
+ Project-URL: Repository, https://github.com/Humotica/tibet-report
7
+ Project-URL: TIBET Ecosystem, https://pypi.org/project/tibet/
8
+ Author-email: Jasper van de Meent <jasper@humotica.com>, Root AI <root_idd@humotica.nl>
9
+ License-Expression: MIT
10
+ Keywords: audit,dossier,provenance,remediation,report,security,tibet
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Operating System :: OS Independent
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Topic :: Security
16
+ Requires-Python: >=3.10
17
+ Requires-Dist: tibet-core>=0.3.0
18
+ Provides-Extra: full
19
+ Requires-Dist: tibet-pol>=0.1.0; extra == 'full'
20
+ Requires-Dist: tibet-wayback>=0.1.0; extra == 'full'
21
+ Provides-Extra: pol
22
+ Requires-Dist: tibet-pol>=0.1.0; extra == 'pol'
23
+ Provides-Extra: wayback
24
+ Requires-Dist: tibet-wayback>=0.1.0; extra == 'wayback'
25
+ Description-Content-Type: text/markdown
26
+
27
+ # tibet-report
28
+
29
+ Audit dossier assembler with TIBET provenance — verifiable remediation reports.
30
+
31
+ Part of the [TIBET ecosystem](https://pypi.org/project/tibet/) by [Humotica](https://humotica.com).
32
+
33
+ ## What it does
34
+
35
+ `tibet-report` assembles evidence from TIBET token chains, wayback seals, pol health checks, and Phantom sessions into a single verifiable audit dossier.
36
+
37
+ The report is not the proof — the chain of tokens, seals, and manifests is. `tibet-report` makes that chain readable for humans and verifiable for auditors.
38
+
39
+ ## Install
40
+
41
+ ```bash
42
+ pip install tibet-report
43
+ ```
44
+
45
+ ## Quick start
46
+
47
+ ```python
48
+ from tibet_report import ReportSession, build_dossier
49
+
50
+ session = ReportSession(
51
+ report_id="RPT-001",
52
+ title="Security Remediation — Example Corp",
53
+ customer="Example Corp",
54
+ created_by="Jasper van de Meent — Humotica",
55
+ )
56
+
57
+ session.add_finding("SSL chain broken", "Intermediate cert missing")
58
+ session.add_action("Added intermediate cert to nginx", status="fixed")
59
+ session.add_verification("SSL verified with openssl", status="verified")
60
+
61
+ report_path, manifest = build_dossier(session, output_dir="./reports")
62
+ ```
63
+
64
+ ## CLI
65
+
66
+ ```bash
67
+ # Build a dossier
68
+ tibet-report build \
69
+ --customer "Example Corp" \
70
+ --assessor "Jasper van de Meent" \
71
+ --tokens remediation_chain.json \
72
+ --pre-seal pre_fix.json \
73
+ --post-seal post_fix.json \
74
+ --out ./reports
75
+
76
+ # Verify dossier integrity
77
+ tibet-report verify reports/RPT-001.md --manifest reports/RPT-001.manifest.json
78
+ ```
79
+
80
+ ## Chain of custody
81
+
82
+ Every dossier includes a manifest that binds the report to its source evidence:
83
+
84
+ - SHA256 hashes of all input artifacts (tokens, seals, pol runs)
85
+ - SHA256 hash of the generated report
86
+ - Chain-of-custody hash combining all above
87
+ - Optional TIBET dossier token for provenance
88
+
89
+ Tampering with the report after generation is detectable via `tibet-report verify`.
90
+
91
+ ## Input sources
92
+
93
+ | Source | Package | What it provides |
94
+ |--------|---------|-----------------|
95
+ | TIBET tokens | `tibet-core` | Step-by-step provenance chain |
96
+ | Wayback seals | `tibet-wayback` | Pre/post system state snapshots |
97
+ | Wayback diffs | `tibet-wayback` | What changed between states |
98
+ | Pol runs | `tibet-pol` | Health check results |
99
+ | Phantom sessions | `phantom` | Session context (who/when/where) |
100
+
101
+ ## Output
102
+
103
+ - **Markdown** — readable, diffable, git-friendly
104
+ - **HTML** — formatted for clients and auditors
105
+ - **JSON manifest** — machine-readable chain-of-custody
@@ -0,0 +1,79 @@
1
+ # tibet-report
2
+
3
+ Audit dossier assembler with TIBET provenance — verifiable remediation reports.
4
+
5
+ Part of the [TIBET ecosystem](https://pypi.org/project/tibet/) by [Humotica](https://humotica.com).
6
+
7
+ ## What it does
8
+
9
+ `tibet-report` assembles evidence from TIBET token chains, wayback seals, pol health checks, and Phantom sessions into a single verifiable audit dossier.
10
+
11
+ The report is not the proof — the chain of tokens, seals, and manifests is. `tibet-report` makes that chain readable for humans and verifiable for auditors.
12
+
13
+ ## Install
14
+
15
+ ```bash
16
+ pip install tibet-report
17
+ ```
18
+
19
+ ## Quick start
20
+
21
+ ```python
22
+ from tibet_report import ReportSession, build_dossier
23
+
24
+ session = ReportSession(
25
+ report_id="RPT-001",
26
+ title="Security Remediation — Example Corp",
27
+ customer="Example Corp",
28
+ created_by="Jasper van de Meent — Humotica",
29
+ )
30
+
31
+ session.add_finding("SSL chain broken", "Intermediate cert missing")
32
+ session.add_action("Added intermediate cert to nginx", status="fixed")
33
+ session.add_verification("SSL verified with openssl", status="verified")
34
+
35
+ report_path, manifest = build_dossier(session, output_dir="./reports")
36
+ ```
37
+
38
+ ## CLI
39
+
40
+ ```bash
41
+ # Build a dossier
42
+ tibet-report build \
43
+ --customer "Example Corp" \
44
+ --assessor "Jasper van de Meent" \
45
+ --tokens remediation_chain.json \
46
+ --pre-seal pre_fix.json \
47
+ --post-seal post_fix.json \
48
+ --out ./reports
49
+
50
+ # Verify dossier integrity
51
+ tibet-report verify reports/RPT-001.md --manifest reports/RPT-001.manifest.json
52
+ ```
53
+
54
+ ## Chain of custody
55
+
56
+ Every dossier includes a manifest that binds the report to its source evidence:
57
+
58
+ - SHA256 hashes of all input artifacts (tokens, seals, pol runs)
59
+ - SHA256 hash of the generated report
60
+ - Chain-of-custody hash combining all above
61
+ - Optional TIBET dossier token for provenance
62
+
63
+ Tampering with the report after generation is detectable via `tibet-report verify`.
64
+
65
+ ## Input sources
66
+
67
+ | Source | Package | What it provides |
68
+ |--------|---------|-----------------|
69
+ | TIBET tokens | `tibet-core` | Step-by-step provenance chain |
70
+ | Wayback seals | `tibet-wayback` | Pre/post system state snapshots |
71
+ | Wayback diffs | `tibet-wayback` | What changed between states |
72
+ | Pol runs | `tibet-pol` | Health check results |
73
+ | Phantom sessions | `phantom` | Session context (who/when/where) |
74
+
75
+ ## Output
76
+
77
+ - **Markdown** — readable, diffable, git-friendly
78
+ - **HTML** — formatted for clients and auditors
79
+ - **JSON manifest** — machine-readable chain-of-custody
@@ -0,0 +1,45 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "tibet-report"
7
+ version = "0.1.0"
8
+ description = "Audit dossier assembler — verifiable remediation reports from TIBET provenance chains"
9
+ readme = "README.md"
10
+ license = "MIT"
11
+ requires-python = ">=3.10"
12
+ authors = [
13
+ {name = "Jasper van de Meent", email = "jasper@humotica.com"},
14
+ {name = "Root AI", email = "root_idd@humotica.nl"},
15
+ ]
16
+ keywords = ["tibet", "audit", "report", "dossier", "provenance", "security", "remediation"]
17
+ classifiers = [
18
+ "Development Status :: 3 - Alpha",
19
+ "Intended Audience :: Developers",
20
+ "Operating System :: OS Independent",
21
+ "Programming Language :: Python :: 3",
22
+ "Topic :: Security",
23
+ ]
24
+ dependencies = [
25
+ "tibet-core>=0.3.0",
26
+ ]
27
+
28
+ [project.optional-dependencies]
29
+ wayback = ["tibet-wayback>=0.1.0"]
30
+ pol = ["tibet-pol>=0.1.0"]
31
+ full = ["tibet-wayback>=0.1.0", "tibet-pol>=0.1.0"]
32
+
33
+ [project.scripts]
34
+ tibet-report = "tibet_report.cli:main"
35
+
36
+ [project.urls]
37
+ Homepage = "https://ainternet.org"
38
+ Repository = "https://github.com/Humotica/tibet-report"
39
+ "TIBET Ecosystem" = "https://pypi.org/project/tibet/"
40
+
41
+ [tool.hatch.build.targets.wheel]
42
+ packages = ["src/tibet_report"]
43
+
44
+ [tool.pytest.ini_options]
45
+ asyncio_mode = "auto"
@@ -0,0 +1,41 @@
1
+ """tibet-report: Audit dossier assembler with TIBET provenance.
2
+
3
+ Build verifiable remediation reports from TIBET token chains,
4
+ wayback seals, pol health checks, and Phantom session context.
5
+
6
+ Usage:
7
+ from tibet_report import ReportSession, build_dossier
8
+
9
+ session = ReportSession(
10
+ report_id="RPT-001",
11
+ title="Security Remediation — Emigreen.eu",
12
+ customer="Emigreen",
13
+ created_by="Jasper van de Meent — Humotica",
14
+ )
15
+ session.add_finding("SSL chain broken", "Intermediate cert missing")
16
+ session.add_action("Added intermediate cert to nginx", status="fixed")
17
+ session.add_verification("SSL chain verified with openssl", status="verified")
18
+
19
+ report_path, manifest = build_dossier(session, output_dir="./reports")
20
+
21
+ CLI:
22
+ tibet-report build --customer "Emigreen" --assessor "Jasper" --out ./reports
23
+ tibet-report verify report.md --manifest report.manifest.json
24
+ """
25
+
26
+ __version__ = "0.1.0"
27
+
28
+ from .model import ReportSession, ReportStep, EvidenceRef, ReportManifest
29
+ from .dossier import build_dossier, verify_dossier
30
+ from .render import render_markdown, render_html
31
+
32
+ __all__ = [
33
+ "ReportSession",
34
+ "ReportStep",
35
+ "EvidenceRef",
36
+ "ReportManifest",
37
+ "build_dossier",
38
+ "verify_dossier",
39
+ "render_markdown",
40
+ "render_html",
41
+ ]
@@ -0,0 +1,3 @@
1
+ """Allow running as python -m tibet_report."""
2
+ from .cli import main
3
+ main()
@@ -0,0 +1,174 @@
1
+ """CLI for tibet-report — build and verify audit dossiers."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import argparse
6
+ import json
7
+ import sys
8
+
9
+ from .model import ReportSession
10
+ from .dossier import build_dossier, verify_dossier
11
+ from .loader import (
12
+ load_token_chain,
13
+ tokens_to_steps,
14
+ load_wayback_seal,
15
+ load_wayback_diff,
16
+ wayback_seal_to_evidence,
17
+ wayback_diff_to_evidence,
18
+ load_pol_run,
19
+ pol_to_summary,
20
+ pol_run_to_evidence,
21
+ )
22
+
23
+
24
+ def cmd_build(args):
25
+ """Build a dossier from CLI arguments and optional input files."""
26
+ # Start session
27
+ session = ReportSession(
28
+ report_id=args.report_id or f"RPT-{args.customer.replace(' ', '_')[:20]}",
29
+ title=args.title or f"Security Remediation — {args.customer}",
30
+ customer=args.customer,
31
+ created_by=args.assessor,
32
+ scope=args.scope or "",
33
+ environment=args.environment or "",
34
+ phantom_session_id=args.session or "",
35
+ )
36
+
37
+ # Load wayback seals
38
+ if args.pre_seal:
39
+ seal_data = load_wayback_seal(args.pre_seal)
40
+ if seal_data:
41
+ session.pre_seal_id = seal_data.get("seal_id", seal_data.get("id", args.pre_seal))
42
+ else:
43
+ session.pre_seal_id = args.pre_seal # Use as raw ID
44
+
45
+ if args.post_seal:
46
+ seal_data = load_wayback_seal(args.post_seal)
47
+ if seal_data:
48
+ session.post_seal_id = seal_data.get("seal_id", seal_data.get("id", args.post_seal))
49
+ else:
50
+ session.post_seal_id = args.post_seal
51
+
52
+ # Load wayback diff
53
+ if args.diff:
54
+ diff_data = load_wayback_diff(args.diff)
55
+ if diff_data:
56
+ session.wayback_diff = diff_data
57
+
58
+ # Load pol runs
59
+ if args.pre_pol:
60
+ pol_data = load_pol_run(args.pre_pol)
61
+ if pol_data:
62
+ session.pre_pol_summary = pol_to_summary(pol_data)
63
+
64
+ if args.post_pol:
65
+ pol_data = load_pol_run(args.post_pol)
66
+ if pol_data:
67
+ session.post_pol_summary = pol_to_summary(pol_data)
68
+
69
+ # Load tokens and convert to steps
70
+ if args.tokens:
71
+ tokens = load_token_chain(args.tokens)
72
+ if tokens:
73
+ steps = tokens_to_steps(tokens)
74
+ session.steps.extend(steps)
75
+
76
+ # Load session from JSON (overrides/supplements above)
77
+ if args.input:
78
+ with open(args.input) as f:
79
+ data = json.load(f)
80
+ loaded = ReportSession.from_dict(data)
81
+ # Merge steps
82
+ session.steps.extend(loaded.steps)
83
+ # Use loaded fields if not set via CLI
84
+ if not session.scope and loaded.scope:
85
+ session.scope = loaded.scope
86
+ if not session.residual_risks and loaded.residual_risks:
87
+ session.residual_risks = loaded.residual_risks
88
+ if not session.recommendations and loaded.recommendations:
89
+ session.recommendations = loaded.recommendations
90
+
91
+ # Build
92
+ fmt = "html" if args.html else "markdown"
93
+ report_path, manifest = build_dossier(
94
+ session,
95
+ output_dir=args.out,
96
+ format=fmt,
97
+ mint_token=not args.no_token,
98
+ )
99
+
100
+ print(f"Dossier generated: {report_path}")
101
+ print(f"Manifest: {report_path.rsplit('.', 1)[0]}.manifest.json")
102
+ print(f"Chain-of-custody hash: {manifest.chain_of_custody_hash[:16]}...")
103
+ if manifest.dossier_token_id:
104
+ print(f"TIBET dossier token: {manifest.dossier_token_id}")
105
+
106
+
107
+ def cmd_verify(args):
108
+ """Verify a dossier against its manifest."""
109
+ result = verify_dossier(args.report, args.manifest)
110
+
111
+ if result["valid"]:
112
+ print("VALID — dossier integrity confirmed")
113
+ else:
114
+ print("INVALID — dossier integrity check failed")
115
+
116
+ for check in result["checks"]:
117
+ status = check["status"]
118
+ icon = "ok" if status == "ok" else "FAIL"
119
+ print(f" [{icon}] {check['check']}")
120
+
121
+ for error in result["errors"]:
122
+ print(f" ERROR: {error}")
123
+
124
+ if args.json:
125
+ print(json.dumps(result, indent=2))
126
+
127
+ sys.exit(0 if result["valid"] else 1)
128
+
129
+
130
+ def main():
131
+ parser = argparse.ArgumentParser(
132
+ prog="tibet-report",
133
+ description="TIBET audit dossier assembler — verifiable remediation reports",
134
+ )
135
+ sub = parser.add_subparsers(dest="command")
136
+
137
+ # ── build ─────────────────────────────────────────────────────
138
+ build = sub.add_parser("build", help="Build an audit dossier")
139
+ build.add_argument("--customer", required=True, help="Customer name")
140
+ build.add_argument("--assessor", default="", help="Assessor name")
141
+ build.add_argument("--title", default="", help="Report title")
142
+ build.add_argument("--report-id", default="", help="Report ID")
143
+ build.add_argument("--scope", default="", help="Engagement scope description")
144
+ build.add_argument("--environment", default="", help="Target environment")
145
+ build.add_argument("--session", default="", help="Phantom session ID")
146
+ build.add_argument("--pre-seal", default="", help="Pre-fix wayback seal (JSON file or ID)")
147
+ build.add_argument("--post-seal", default="", help="Post-fix wayback seal (JSON file or ID)")
148
+ build.add_argument("--diff", default="", help="Wayback diff JSON file")
149
+ build.add_argument("--pre-pol", default="", help="Pre-fix pol run JSON file")
150
+ build.add_argument("--post-pol", default="", help="Post-fix pol run JSON file")
151
+ build.add_argument("--tokens", default="", help="TIBET token chain JSON file")
152
+ build.add_argument("--input", default="", help="Session JSON file (full or partial)")
153
+ build.add_argument("--out", default=".", help="Output directory")
154
+ build.add_argument("--html", action="store_true", help="Generate HTML instead of Markdown")
155
+ build.add_argument("--no-token", action="store_true", help="Skip TIBET dossier token")
156
+ build.set_defaults(func=cmd_build)
157
+
158
+ # ── verify ────────────────────────────────────────────────────
159
+ verify = sub.add_parser("verify", help="Verify dossier integrity")
160
+ verify.add_argument("report", help="Path to the report file")
161
+ verify.add_argument("--manifest", required=True, help="Path to the manifest JSON")
162
+ verify.add_argument("--json", action="store_true", help="Output result as JSON")
163
+ verify.set_defaults(func=cmd_verify)
164
+
165
+ args = parser.parse_args()
166
+ if not args.command:
167
+ parser.print_help()
168
+ sys.exit(1)
169
+
170
+ args.func(args)
171
+
172
+
173
+ if __name__ == "__main__":
174
+ main()