@biaoo/tiangong-wiki 0.2.2 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +106 -1
- package/README.zh-CN.md +106 -1
- package/dist/commands/create.js +3 -0
- package/dist/commands/sync.js +3 -0
- package/dist/commands/template.js +3 -0
- package/dist/core/codex-workflow.js +37 -15
- package/dist/core/db.js +19 -0
- package/dist/core/onboarding.js +35 -1
- package/dist/core/page-source.js +25 -0
- package/dist/core/paths.js +10 -0
- package/dist/core/workflow-result.js +5 -0
- package/dist/daemon/audit-log.js +18 -0
- package/dist/daemon/client.js +1 -1
- package/dist/daemon/git-journal.js +114 -0
- package/dist/daemon/server.js +446 -124
- package/dist/daemon/write-actor.js +60 -0
- package/dist/daemon/write-queue.js +360 -0
- package/dist/operations/dashboard.js +4 -9
- package/dist/operations/write.js +93 -5
- package/mcp-server/dist/daemon-client.js +90 -0
- package/mcp-server/dist/index.js +26 -0
- package/mcp-server/dist/server.js +525 -0
- package/package.json +11 -5
- package/references/centralized-service-deployment.md +482 -0
- package/references/examples/centralized-service/centralized.env.example +25 -0
- package/references/examples/centralized-service/nginx-centralized-wiki.conf +68 -0
- package/references/examples/centralized-service/tiangong-wiki-daemon.service +17 -0
- package/references/examples/centralized-service/tiangong-wiki-mcp.service +18 -0
- package/references/troubleshooting.md +22 -0
|
@@ -0,0 +1,482 @@
|
|
|
1
|
+
# Centralized Service Deployment
|
|
2
|
+
|
|
3
|
+
Single-host deployment guide for running Tiangong Wiki as a centralized service with:
|
|
4
|
+
|
|
5
|
+
- a local daemon (`tiangong-wiki daemon run`)
|
|
6
|
+
- a local MCP adapter (`mcp-server/dist/index.js`)
|
|
7
|
+
- an Nginx reverse proxy handling TLS, static Bearer tokens, and trusted actor headers
|
|
8
|
+
|
|
9
|
+
This guide is the V1 baseline for issue `#040`. It assumes Linux + `systemd` and intentionally does not cover HA, load balancing, or cloud-vendor-specific templates.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Topology
|
|
14
|
+
|
|
15
|
+
```text
|
|
16
|
+
Remote MCP client
|
|
17
|
+
-> HTTPS /mcp (Nginx)
|
|
18
|
+
-> local MCP service (127.0.0.1:9400)
|
|
19
|
+
-> local daemon (127.0.0.1:8787)
|
|
20
|
+
-> pages/ + index.db + templates/ + audit.ndjson + local Git repo
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Rules for V1:
|
|
24
|
+
|
|
25
|
+
- Do not expose the daemon directly to the public internet.
|
|
26
|
+
- Only the reverse proxy should terminate TLS and validate Bearer tokens.
|
|
27
|
+
- The proxy must overwrite actor headers before traffic reaches MCP.
|
|
28
|
+
- MCP stays a thin adapter and must not write files directly.
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## Directory Layout
|
|
33
|
+
|
|
34
|
+
Recommended server layout:
|
|
35
|
+
|
|
36
|
+
```text
|
|
37
|
+
/srv/tiangong-wiki/
|
|
38
|
+
├── current/ # checked-out tiangong-wiki repo + built artifacts
|
|
39
|
+
├── workspace/
|
|
40
|
+
│ ├── pages/
|
|
41
|
+
│ ├── templates/
|
|
42
|
+
│ ├── wiki.config.json
|
|
43
|
+
│ ├── index.db
|
|
44
|
+
│ └── .queue-artifacts/
|
|
45
|
+
├── vault/
|
|
46
|
+
└── .wiki-runtime/
|
|
47
|
+
└── audit.ndjson
|
|
48
|
+
|
|
49
|
+
/etc/tiangong-wiki/
|
|
50
|
+
└── centralized.env
|
|
51
|
+
|
|
52
|
+
/etc/systemd/system/
|
|
53
|
+
├── tiangong-wiki-daemon.service
|
|
54
|
+
└── tiangong-wiki-mcp.service
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Recommended ownership:
|
|
58
|
+
|
|
59
|
+
- application repo: `root:root`
|
|
60
|
+
- runtime workspace and vault: `tiangong-wiki:tiangong-wiki`
|
|
61
|
+
- `systemd` services run as `tiangong-wiki`
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## Build and Bootstrap
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
git clone <repo-url> /srv/tiangong-wiki/current
|
|
69
|
+
cd /srv/tiangong-wiki/current
|
|
70
|
+
npm ci
|
|
71
|
+
npm run build
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Initialize the workspace once:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
mkdir -p /srv/tiangong-wiki/workspace/pages
|
|
78
|
+
mkdir -p /srv/tiangong-wiki/workspace/templates
|
|
79
|
+
mkdir -p /srv/tiangong-wiki/vault
|
|
80
|
+
|
|
81
|
+
cat >/etc/tiangong-wiki/centralized.env <<'EOF'
|
|
82
|
+
WIKI_PATH=/srv/tiangong-wiki/workspace/pages
|
|
83
|
+
WIKI_DB_PATH=/srv/tiangong-wiki/workspace/index.db
|
|
84
|
+
WIKI_CONFIG_PATH=/srv/tiangong-wiki/workspace/wiki.config.json
|
|
85
|
+
WIKI_TEMPLATES_PATH=/srv/tiangong-wiki/workspace/templates
|
|
86
|
+
VAULT_PATH=/srv/tiangong-wiki/vault
|
|
87
|
+
|
|
88
|
+
WIKI_SYNC_INTERVAL=300
|
|
89
|
+
WIKI_DAEMON_PORT=8787
|
|
90
|
+
|
|
91
|
+
WIKI_MCP_HOST=127.0.0.1
|
|
92
|
+
WIKI_MCP_PORT=9400
|
|
93
|
+
WIKI_MCP_PATH=/mcp
|
|
94
|
+
WIKI_DAEMON_BASE_URL=http://127.0.0.1:8787
|
|
95
|
+
|
|
96
|
+
WIKI_GIT_AUTO_PUSH=true
|
|
97
|
+
WIKI_GIT_PUSH_REMOTE=origin
|
|
98
|
+
WIKI_GIT_PUSH_DELAY_MS=3000
|
|
99
|
+
EOF
|
|
100
|
+
|
|
101
|
+
cd /srv/tiangong-wiki/current
|
|
102
|
+
env $(grep -v '^#' /etc/tiangong-wiki/centralized.env | xargs) node dist/index.js init
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
An example env file is also provided at [references/examples/centralized-service/centralized.env.example](./examples/centralized-service/centralized.env.example).
|
|
106
|
+
|
|
107
|
+
Important:
|
|
108
|
+
|
|
109
|
+
- Bearer tokens are not part of `centralized.env`
|
|
110
|
+
- Bearer token validation belongs to Nginx, not the daemon or MCP process
|
|
111
|
+
- Keep real tokens in a private Nginx include file such as `/etc/nginx/snippets/wiki-auth-tokens.conf`
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
## Required Environment Variables
|
|
116
|
+
|
|
117
|
+
### Core runtime
|
|
118
|
+
|
|
119
|
+
- `WIKI_PATH`
|
|
120
|
+
- `WIKI_DB_PATH`
|
|
121
|
+
- `WIKI_CONFIG_PATH`
|
|
122
|
+
- `WIKI_TEMPLATES_PATH`
|
|
123
|
+
- `VAULT_PATH`
|
|
124
|
+
- `WIKI_SYNC_INTERVAL`
|
|
125
|
+
|
|
126
|
+
### Daemon
|
|
127
|
+
|
|
128
|
+
- `WIKI_DAEMON_PORT`
|
|
129
|
+
|
|
130
|
+
Notes:
|
|
131
|
+
|
|
132
|
+
- the daemon bind host is currently fixed to `127.0.0.1`
|
|
133
|
+
- the daemon should stay loopback-only in production
|
|
134
|
+
|
|
135
|
+
### MCP adapter
|
|
136
|
+
|
|
137
|
+
- `WIKI_MCP_HOST`
|
|
138
|
+
- `WIKI_MCP_PORT`
|
|
139
|
+
- `WIKI_MCP_PATH`
|
|
140
|
+
- `WIKI_DAEMON_BASE_URL`
|
|
141
|
+
|
|
142
|
+
Recommended values:
|
|
143
|
+
|
|
144
|
+
- `WIKI_MCP_HOST=127.0.0.1`
|
|
145
|
+
- `WIKI_MCP_PORT=9400`
|
|
146
|
+
- `WIKI_MCP_PATH=/mcp`
|
|
147
|
+
- `WIKI_DAEMON_BASE_URL=http://127.0.0.1:8787`
|
|
148
|
+
|
|
149
|
+
### Optional Git push batching
|
|
150
|
+
|
|
151
|
+
- `WIKI_GIT_AUTO_PUSH=true|false`
|
|
152
|
+
- `WIKI_GIT_PUSH_REMOTE`
|
|
153
|
+
- `WIKI_GIT_PUSH_DELAY_MS`
|
|
154
|
+
|
|
155
|
+
V1 decision:
|
|
156
|
+
|
|
157
|
+
- local Git commit is part of the write transaction
|
|
158
|
+
- async push batching stays inside the daemon process
|
|
159
|
+
- external cron is not required for the primary path
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
## Git Repository Setup
|
|
164
|
+
|
|
165
|
+
The centralized service assumes the wiki workspace itself is a real Git repository.
|
|
166
|
+
|
|
167
|
+
Current behavior:
|
|
168
|
+
|
|
169
|
+
- every successful write attempts a local Git commit
|
|
170
|
+
- optional remote push is triggered asynchronously when `WIKI_GIT_AUTO_PUSH=true`
|
|
171
|
+
- push failure does not roll back a successful local write
|
|
172
|
+
|
|
173
|
+
Initialize the workspace repo:
|
|
174
|
+
|
|
175
|
+
```bash
|
|
176
|
+
cd /srv/tiangong-wiki/workspace
|
|
177
|
+
|
|
178
|
+
git init -b main
|
|
179
|
+
git config user.name "tiangong-wiki"
|
|
180
|
+
git config user.email "tiangong-wiki@local"
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
Notes:
|
|
184
|
+
|
|
185
|
+
- daemon-generated commits override author/committer identity from the write actor
|
|
186
|
+
- the local repo still should have basic Git config for operator workflows
|
|
187
|
+
|
|
188
|
+
Configure the GitHub remote:
|
|
189
|
+
|
|
190
|
+
```bash
|
|
191
|
+
cd /srv/tiangong-wiki/workspace
|
|
192
|
+
git remote add origin git@github.com:YOUR_ORG/YOUR_REPO.git
|
|
193
|
+
git remote -v
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
If the remote already exists:
|
|
197
|
+
|
|
198
|
+
```bash
|
|
199
|
+
git remote set-url origin git@github.com:YOUR_ORG/YOUR_REPO.git
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
Recommended authentication model:
|
|
203
|
+
|
|
204
|
+
- run the daemon as a dedicated system user such as `tiangong-wiki`
|
|
205
|
+
- give that user an SSH key dedicated to this deployment
|
|
206
|
+
- register the public key in GitHub as a deploy key, bot account key, or GitHub App-managed key
|
|
207
|
+
|
|
208
|
+
Example SSH bootstrap:
|
|
209
|
+
|
|
210
|
+
```bash
|
|
211
|
+
sudo -u tiangong-wiki mkdir -p /home/tiangong-wiki/.ssh
|
|
212
|
+
sudo -u tiangong-wiki ssh-keygen -t ed25519 -f /home/tiangong-wiki/.ssh/id_ed25519 -N ""
|
|
213
|
+
sudo -u tiangong-wiki ssh-keyscan github.com >> /home/tiangong-wiki/.ssh/known_hosts
|
|
214
|
+
chmod 600 /home/tiangong-wiki/.ssh/known_hosts
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
Do not store GitHub personal access tokens in `centralized.env`. Prefer SSH deploy keys.
|
|
218
|
+
|
|
219
|
+
Before enabling daemon-side auto push, verify Git access as the actual service user:
|
|
220
|
+
|
|
221
|
+
```bash
|
|
222
|
+
sudo -u tiangong-wiki git -C /srv/tiangong-wiki/workspace status
|
|
223
|
+
sudo -u tiangong-wiki git -C /srv/tiangong-wiki/workspace remote -v
|
|
224
|
+
sudo -u tiangong-wiki git -C /srv/tiangong-wiki/workspace push origin HEAD
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
If this manual push fails, daemon-side auto push will fail too.
|
|
228
|
+
|
|
229
|
+
Operational constraints:
|
|
230
|
+
|
|
231
|
+
- do not leave unrelated unstaged changes in the workspace repo
|
|
232
|
+
- ensure the target branch policy matches service behavior if you enable auto push
|
|
233
|
+
- if GitHub branch protection forbids direct push to the target branch, the current V1 service should push to an allowed branch or keep auto push disabled
|
|
234
|
+
|
|
235
|
+
---
|
|
236
|
+
|
|
237
|
+
## `systemd` Units
|
|
238
|
+
|
|
239
|
+
Example unit files are provided under [references/examples/centralized-service/](./examples/centralized-service/).
|
|
240
|
+
|
|
241
|
+
Install them:
|
|
242
|
+
|
|
243
|
+
```bash
|
|
244
|
+
cp /srv/tiangong-wiki/current/references/examples/centralized-service/tiangong-wiki-daemon.service /etc/systemd/system/
|
|
245
|
+
cp /srv/tiangong-wiki/current/references/examples/centralized-service/tiangong-wiki-mcp.service /etc/systemd/system/
|
|
246
|
+
|
|
247
|
+
systemctl daemon-reload
|
|
248
|
+
systemctl enable --now tiangong-wiki-daemon
|
|
249
|
+
systemctl enable --now tiangong-wiki-mcp
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
Startup order:
|
|
253
|
+
|
|
254
|
+
1. Build the repo (`npm ci && npm run build`)
|
|
255
|
+
2. Initialize the workspace (`node dist/index.js init`)
|
|
256
|
+
3. Start `tiangong-wiki-daemon`
|
|
257
|
+
4. Verify daemon health
|
|
258
|
+
5. Start `tiangong-wiki-mcp`
|
|
259
|
+
6. Verify MCP health
|
|
260
|
+
7. Reload Nginx
|
|
261
|
+
|
|
262
|
+
---
|
|
263
|
+
|
|
264
|
+
## Nginx Reverse Proxy
|
|
265
|
+
|
|
266
|
+
V1 authentication model:
|
|
267
|
+
|
|
268
|
+
- Nginx validates a static Bearer token
|
|
269
|
+
- Nginx maps token -> actor identity
|
|
270
|
+
- Nginx injects:
|
|
271
|
+
- `X-Wiki-Actor-Id`
|
|
272
|
+
- `X-Wiki-Actor-Type`
|
|
273
|
+
- `X-Request-Id`
|
|
274
|
+
- MCP forwards these headers to the daemon on write requests
|
|
275
|
+
|
|
276
|
+
Important:
|
|
277
|
+
|
|
278
|
+
- never trust client-supplied actor headers directly
|
|
279
|
+
- always overwrite actor headers in the proxy
|
|
280
|
+
- clear `Authorization` before passing traffic upstream
|
|
281
|
+
|
|
282
|
+
Example config: [references/examples/centralized-service/nginx-centralized-wiki.conf](./examples/centralized-service/nginx-centralized-wiki.conf)
|
|
283
|
+
|
|
284
|
+
Recommended token placement:
|
|
285
|
+
|
|
286
|
+
1. Create a private include file, for example `/etc/nginx/snippets/wiki-auth-tokens.conf`
|
|
287
|
+
2. Move the `map $http_authorization ...` blocks into that file
|
|
288
|
+
3. `include` that file from your main Nginx config inside the `http {}` scope
|
|
289
|
+
4. Keep only placeholder tokens in repo-tracked example configs
|
|
290
|
+
|
|
291
|
+
This keeps static Bearer tokens out of the service env file and out of the checked-in site config.
|
|
292
|
+
|
|
293
|
+
Recommended exposure model:
|
|
294
|
+
|
|
295
|
+
- public: `/mcp` and `/mcp/health`
|
|
296
|
+
- private/admin only: daemon health and daemon HTTP routes
|
|
297
|
+
|
|
298
|
+
Because MCP uses streamable HTTP/SSE, keep:
|
|
299
|
+
|
|
300
|
+
- `proxy_http_version 1.1`
|
|
301
|
+
- `proxy_buffering off`
|
|
302
|
+
- generous read/send timeouts
|
|
303
|
+
|
|
304
|
+
---
|
|
305
|
+
|
|
306
|
+
## Health Checks
|
|
307
|
+
|
|
308
|
+
### Local daemon
|
|
309
|
+
|
|
310
|
+
```bash
|
|
311
|
+
curl http://127.0.0.1:8787/health
|
|
312
|
+
curl http://127.0.0.1:8787/status
|
|
313
|
+
curl http://127.0.0.1:8787/write-queue/summary
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
### Local MCP
|
|
317
|
+
|
|
318
|
+
```bash
|
|
319
|
+
curl http://127.0.0.1:9400/health
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
### Through Nginx
|
|
323
|
+
|
|
324
|
+
```bash
|
|
325
|
+
curl -H "Authorization: Bearer <token>" https://wiki.example.com/mcp/health
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
### `systemd`
|
|
329
|
+
|
|
330
|
+
```bash
|
|
331
|
+
systemctl status tiangong-wiki-daemon
|
|
332
|
+
systemctl status tiangong-wiki-mcp
|
|
333
|
+
|
|
334
|
+
journalctl -u tiangong-wiki-daemon -f
|
|
335
|
+
journalctl -u tiangong-wiki-mcp -f
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
---
|
|
339
|
+
|
|
340
|
+
## Runtime Contracts You Must Expect
|
|
341
|
+
|
|
342
|
+
These behaviors are intentional and should be documented to operators and MCP clients.
|
|
343
|
+
|
|
344
|
+
### Revision conflicts
|
|
345
|
+
|
|
346
|
+
- daemon returns HTTP `409`
|
|
347
|
+
- MCP returns a structured tool error with `code=revision_conflict`
|
|
348
|
+
- callers must re-read the page and retry intentionally
|
|
349
|
+
|
|
350
|
+
### Queue full
|
|
351
|
+
|
|
352
|
+
- daemon returns HTTP `503`
|
|
353
|
+
- cause: write queue depth exceeded the configured limit
|
|
354
|
+
- operators should inspect `/write-queue/summary`
|
|
355
|
+
|
|
356
|
+
### Degraded Git commit failure
|
|
357
|
+
|
|
358
|
+
- the write may already be applied locally
|
|
359
|
+
- daemon returns a degraded error with `code=git_commit_failed`
|
|
360
|
+
- inspect `audit.ndjson`, local Git state, and journal output before retrying
|
|
361
|
+
|
|
362
|
+
### Sync failure
|
|
363
|
+
|
|
364
|
+
- daemon does not commit to Git when sync fails
|
|
365
|
+
- audit log records `sync_failed`
|
|
366
|
+
|
|
367
|
+
### Audit and journal locations
|
|
368
|
+
|
|
369
|
+
- audit log: `/srv/tiangong-wiki/.wiki-runtime/audit.ndjson` in the recommended layout
|
|
370
|
+
- Git journal: local repo commit history in `/srv/tiangong-wiki/workspace` or your chosen wiki root repo
|
|
371
|
+
|
|
372
|
+
---
|
|
373
|
+
|
|
374
|
+
## Backup and Push Strategy
|
|
375
|
+
|
|
376
|
+
V1 baseline:
|
|
377
|
+
|
|
378
|
+
- every successful write attempts a local Git commit
|
|
379
|
+
- optional async push is handled by the daemon when `WIKI_GIT_AUTO_PUSH=true`
|
|
380
|
+
- async push failure does not roll back the successful local write
|
|
381
|
+
|
|
382
|
+
Recommended operator practice:
|
|
383
|
+
|
|
384
|
+
- keep the workspace as a real Git repository with a configured `origin`
|
|
385
|
+
- snapshot both the workspace and `/etc/tiangong-wiki/centralized.env`
|
|
386
|
+
- monitor daemon logs for `git push failed`
|
|
387
|
+
|
|
388
|
+
Manual recovery after push failure:
|
|
389
|
+
|
|
390
|
+
```bash
|
|
391
|
+
cd /srv/tiangong-wiki/workspace
|
|
392
|
+
git status
|
|
393
|
+
git log --oneline -n 5
|
|
394
|
+
git push origin HEAD
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
---
|
|
398
|
+
|
|
399
|
+
## Recovery Playbook
|
|
400
|
+
|
|
401
|
+
### Daemon is down
|
|
402
|
+
|
|
403
|
+
```bash
|
|
404
|
+
systemctl restart tiangong-wiki-daemon
|
|
405
|
+
curl http://127.0.0.1:8787/health
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
If it still fails:
|
|
409
|
+
|
|
410
|
+
- inspect `journalctl -u tiangong-wiki-daemon -n 200`
|
|
411
|
+
- verify `index.db`, `wiki.config.json`, and Git repo status
|
|
412
|
+
|
|
413
|
+
### MCP is down but daemon is healthy
|
|
414
|
+
|
|
415
|
+
```bash
|
|
416
|
+
systemctl restart tiangong-wiki-mcp
|
|
417
|
+
curl http://127.0.0.1:9400/health
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
Check:
|
|
421
|
+
|
|
422
|
+
- `WIKI_DAEMON_BASE_URL`
|
|
423
|
+
- `WIKI_MCP_PORT`
|
|
424
|
+
- Nginx upstream target
|
|
425
|
+
|
|
426
|
+
### Queue remains full
|
|
427
|
+
|
|
428
|
+
Check:
|
|
429
|
+
|
|
430
|
+
```bash
|
|
431
|
+
curl http://127.0.0.1:8787/write-queue/summary | jq
|
|
432
|
+
```
|
|
433
|
+
|
|
434
|
+
Look for:
|
|
435
|
+
|
|
436
|
+
- a long-running active job
|
|
437
|
+
- repeated failing jobs
|
|
438
|
+
- vault queue pressure caused by large `sync --process` workloads
|
|
439
|
+
|
|
440
|
+
### Revision conflict reported by clients
|
|
441
|
+
|
|
442
|
+
This is expected behavior, not an outage.
|
|
443
|
+
|
|
444
|
+
Action:
|
|
445
|
+
|
|
446
|
+
1. re-read the page
|
|
447
|
+
2. merge user intent with the latest revision
|
|
448
|
+
3. retry with the new `ifRevision`
|
|
449
|
+
|
|
450
|
+
### Degraded Git commit failure
|
|
451
|
+
|
|
452
|
+
Check:
|
|
453
|
+
|
|
454
|
+
```bash
|
|
455
|
+
journalctl -u tiangong-wiki-daemon -n 200
|
|
456
|
+
tail -n 50 /srv/tiangong-wiki/.wiki-runtime/audit.ndjson
|
|
457
|
+
cd /srv/tiangong-wiki/workspace && git status
|
|
458
|
+
```
|
|
459
|
+
|
|
460
|
+
Typical causes:
|
|
461
|
+
|
|
462
|
+
- workspace is not a Git repo
|
|
463
|
+
- Git identity or hooks are broken
|
|
464
|
+
- permissions do not allow commit creation
|
|
465
|
+
|
|
466
|
+
### Actor metadata missing
|
|
467
|
+
|
|
468
|
+
If MCP returns `missing_actor`:
|
|
469
|
+
|
|
470
|
+
- verify Nginx is overwriting the three actor headers
|
|
471
|
+
- verify the client is calling the proxied `/mcp` endpoint, not the loopback service directly
|
|
472
|
+
|
|
473
|
+
---
|
|
474
|
+
|
|
475
|
+
## What V1 Does Not Cover
|
|
476
|
+
|
|
477
|
+
- multi-host deployments
|
|
478
|
+
- active/active daemon replicas
|
|
479
|
+
- cloud-specific Terraform or Helm modules
|
|
480
|
+
- alternate reverse proxy examples beyond Nginx
|
|
481
|
+
|
|
482
|
+
If those are needed later, treat them as follow-up work after the single-host contract is stable.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Core workspace
|
|
2
|
+
WIKI_PATH=/srv/tiangong-wiki/workspace/pages
|
|
3
|
+
WIKI_DB_PATH=/srv/tiangong-wiki/workspace/index.db
|
|
4
|
+
WIKI_CONFIG_PATH=/srv/tiangong-wiki/workspace/wiki.config.json
|
|
5
|
+
WIKI_TEMPLATES_PATH=/srv/tiangong-wiki/workspace/templates
|
|
6
|
+
VAULT_PATH=/srv/tiangong-wiki/vault
|
|
7
|
+
|
|
8
|
+
# Daemon
|
|
9
|
+
WIKI_SYNC_INTERVAL=300
|
|
10
|
+
WIKI_DAEMON_PORT=8787
|
|
11
|
+
|
|
12
|
+
# MCP adapter
|
|
13
|
+
WIKI_MCP_HOST=127.0.0.1
|
|
14
|
+
WIKI_MCP_PORT=9400
|
|
15
|
+
WIKI_MCP_PATH=/mcp
|
|
16
|
+
WIKI_DAEMON_BASE_URL=http://127.0.0.1:8787
|
|
17
|
+
|
|
18
|
+
# Bearer tokens are NOT configured here.
|
|
19
|
+
# Put them in your reverse proxy config instead, for example:
|
|
20
|
+
# /etc/nginx/snippets/wiki-auth-tokens.conf
|
|
21
|
+
|
|
22
|
+
# Optional async Git push batching
|
|
23
|
+
WIKI_GIT_AUTO_PUSH=true
|
|
24
|
+
WIKI_GIT_PUSH_REMOTE=origin
|
|
25
|
+
WIKI_GIT_PUSH_DELAY_MS=3000
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# Put the `map` blocks in the `http {}` scope.
|
|
2
|
+
# These token values are placeholders only.
|
|
3
|
+
# In production, move them to a private include such as:
|
|
4
|
+
# /etc/nginx/snippets/wiki-auth-tokens.conf
|
|
5
|
+
|
|
6
|
+
map $http_authorization $wiki_access_allowed {
|
|
7
|
+
default 0;
|
|
8
|
+
"Bearer codex-prod-token" 1;
|
|
9
|
+
"Bearer claude-prod-token" 1;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
map $http_authorization $wiki_actor_id {
|
|
13
|
+
default "";
|
|
14
|
+
"Bearer codex-prod-token" "agent:codex";
|
|
15
|
+
"Bearer claude-prod-token" "agent:claude";
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
map $http_authorization $wiki_actor_type {
|
|
19
|
+
default "";
|
|
20
|
+
"Bearer codex-prod-token" "agent";
|
|
21
|
+
"Bearer claude-prod-token" "agent";
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
server {
|
|
25
|
+
listen 443 ssl http2;
|
|
26
|
+
server_name wiki.example.com;
|
|
27
|
+
|
|
28
|
+
ssl_certificate /etc/letsencrypt/live/wiki.example.com/fullchain.pem;
|
|
29
|
+
ssl_certificate_key /etc/letsencrypt/live/wiki.example.com/privkey.pem;
|
|
30
|
+
|
|
31
|
+
proxy_http_version 1.1;
|
|
32
|
+
proxy_buffering off;
|
|
33
|
+
proxy_read_timeout 360s;
|
|
34
|
+
proxy_send_timeout 360s;
|
|
35
|
+
|
|
36
|
+
location = /mcp/health {
|
|
37
|
+
if ($wiki_access_allowed = 0) { return 401; }
|
|
38
|
+
|
|
39
|
+
proxy_set_header Authorization "";
|
|
40
|
+
proxy_pass http://127.0.0.1:9400/health;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
location /mcp {
|
|
44
|
+
if ($wiki_access_allowed = 0) { return 401; }
|
|
45
|
+
|
|
46
|
+
proxy_set_header Authorization "";
|
|
47
|
+
proxy_set_header X-Wiki-Actor-Id $wiki_actor_id;
|
|
48
|
+
proxy_set_header X-Wiki-Actor-Type $wiki_actor_type;
|
|
49
|
+
proxy_set_header X-Request-Id $request_id;
|
|
50
|
+
|
|
51
|
+
proxy_pass http://127.0.0.1:9400;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
# Optional admin-only daemon routes.
|
|
55
|
+
# Keep them private or behind an internal allowlist / VPN.
|
|
56
|
+
location /daemon/ {
|
|
57
|
+
allow 127.0.0.1;
|
|
58
|
+
deny all;
|
|
59
|
+
|
|
60
|
+
proxy_set_header Authorization "";
|
|
61
|
+
proxy_set_header X-Wiki-Actor-Id "system:proxy-admin";
|
|
62
|
+
proxy_set_header X-Wiki-Actor-Type "system";
|
|
63
|
+
proxy_set_header X-Request-Id $request_id;
|
|
64
|
+
|
|
65
|
+
rewrite ^/daemon/(.*)$ /$1 break;
|
|
66
|
+
proxy_pass http://127.0.0.1:8787;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
[Unit]
|
|
2
|
+
Description=Tiangong Wiki daemon
|
|
3
|
+
After=network-online.target
|
|
4
|
+
Wants=network-online.target
|
|
5
|
+
|
|
6
|
+
[Service]
|
|
7
|
+
Type=simple
|
|
8
|
+
User=tiangong-wiki
|
|
9
|
+
Group=tiangong-wiki
|
|
10
|
+
WorkingDirectory=/srv/tiangong-wiki/current
|
|
11
|
+
EnvironmentFile=/etc/tiangong-wiki/centralized.env
|
|
12
|
+
ExecStart=/usr/bin/env node /srv/tiangong-wiki/current/dist/index.js daemon run
|
|
13
|
+
Restart=always
|
|
14
|
+
RestartSec=5
|
|
15
|
+
|
|
16
|
+
[Install]
|
|
17
|
+
WantedBy=multi-user.target
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
[Unit]
|
|
2
|
+
Description=Tiangong Wiki MCP adapter
|
|
3
|
+
After=network-online.target tiangong-wiki-daemon.service
|
|
4
|
+
Wants=network-online.target
|
|
5
|
+
Requires=tiangong-wiki-daemon.service
|
|
6
|
+
|
|
7
|
+
[Service]
|
|
8
|
+
Type=simple
|
|
9
|
+
User=tiangong-wiki
|
|
10
|
+
Group=tiangong-wiki
|
|
11
|
+
WorkingDirectory=/srv/tiangong-wiki/current
|
|
12
|
+
EnvironmentFile=/etc/tiangong-wiki/centralized.env
|
|
13
|
+
ExecStart=/usr/bin/env node /srv/tiangong-wiki/current/mcp-server/dist/index.js
|
|
14
|
+
Restart=always
|
|
15
|
+
RestartSec=5
|
|
16
|
+
|
|
17
|
+
[Install]
|
|
18
|
+
WantedBy=multi-user.target
|
|
@@ -34,6 +34,21 @@ All configuration is managed through `.wiki.env` (created by `tiangong-wiki setu
|
|
|
34
34
|
| `WIKI_TEMPLATES_PATH` | Yes | Path to the templates directory |
|
|
35
35
|
| `WIKI_SYNC_INTERVAL` | No | Auto-sync interval in seconds (default: `86400`) |
|
|
36
36
|
|
|
37
|
+
### Daemon and MCP
|
|
38
|
+
|
|
39
|
+
| Variable | Required | Description |
|
|
40
|
+
| --- | --- | --- |
|
|
41
|
+
| `WIKI_DAEMON_PORT` | No | Loopback daemon port |
|
|
42
|
+
| `WIKI_MCP_HOST` | No | MCP bind host (recommended: `127.0.0.1`) |
|
|
43
|
+
| `WIKI_MCP_PORT` | No | MCP bind port |
|
|
44
|
+
| `WIKI_MCP_PATH` | No | MCP HTTP path (default: `/mcp`) |
|
|
45
|
+
| `WIKI_DAEMON_BASE_URL` | For MCP service | Daemon base URL used by the MCP adapter |
|
|
46
|
+
| `WIKI_GIT_AUTO_PUSH` | No | Enable daemon-side async Git push batching |
|
|
47
|
+
| `WIKI_GIT_PUSH_REMOTE` | No | Git remote name for async push (default: `origin`) |
|
|
48
|
+
| `WIKI_GIT_PUSH_DELAY_MS` | No | Delay before async push (default: `3000`) |
|
|
49
|
+
|
|
50
|
+
For the full single-host deployment baseline, see [centralized-service-deployment.md](./centralized-service-deployment.md).
|
|
51
|
+
|
|
37
52
|
### Vault
|
|
38
53
|
|
|
39
54
|
| Variable | Required | Description |
|
|
@@ -73,8 +88,11 @@ The agent uses [Codex SDK](https://www.npmjs.com/package/@openai/codex-sdk) to p
|
|
|
73
88
|
| `WIKI_AGENT_API_KEY` | If enabled | API key for the LLM provider |
|
|
74
89
|
| `WIKI_AGENT_MODEL` | No | Model name (e.g. `gpt-5.4`, `Qwen/Qwen3.5-397B-A17B-GPTQ-Int4`) |
|
|
75
90
|
| `WIKI_AGENT_BATCH_SIZE` | No | Max concurrent vault items per batch (default: `5`) |
|
|
91
|
+
| `WIKI_AGENT_SANDBOX_MODE` | No | Codex sandbox mode: `danger-full-access` (default) or `workspace-write` |
|
|
76
92
|
| `WIKI_PARSER_SKILLS` | No | Comma-separated parser skill list (e.g. `pdf,docx,pptx,xlsx`) |
|
|
77
93
|
|
|
94
|
+
`tiangong-wiki setup` now prompts for `WIKI_AGENT_SANDBOX_MODE` when automatic vault processing is enabled. The default is `danger-full-access`, and the setup wizard highlights that this mode grants full runtime access.
|
|
95
|
+
|
|
78
96
|
---
|
|
79
97
|
|
|
80
98
|
## Common Issues
|
|
@@ -102,6 +120,10 @@ Always run `tiangong-wiki lint --path <page-id> --format json` after mutations.
|
|
|
102
120
|
|
|
103
121
|
Parser skills must be installed under `<workspace-root>/.agents/skills/`. Run `tiangong-wiki skill` to inspect installed skills. Use `tiangong-wiki skill update --all` to update.
|
|
104
122
|
|
|
123
|
+
### Codex workflow sandbox fails to initialize
|
|
124
|
+
|
|
125
|
+
If the agent workflow fails with `bwrap`, `unshare`, `uid_map`, or similar sandbox startup errors, switch `WIKI_AGENT_SANDBOX_MODE` to `danger-full-access`. Use `workspace-write` only when you explicitly want that sandbox mode and know the host supports it.
|
|
126
|
+
|
|
105
127
|
---
|
|
106
128
|
|
|
107
129
|
## LLM Provider Setup
|