@quolu/lattice 0.52.0 → 0.52.2
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/LICENSE +147 -147
- package/README.ja.md +355 -355
- package/README.md +258 -258
- package/bin/lattice-mcp.mjs +0 -0
- package/bin/lattice-scripted-adapter.mjs +0 -0
- package/bin/lattice-scripted-worker.mjs +0 -0
- package/bin/lattice-work-order-adapter.mjs +0 -0
- package/bin/lattice.mjs +0 -0
- package/docs/bridge-setup.md +132 -132
- package/docs/schemas/lattice.executor_packet.v1.schema.json +57 -57
- package/docs/schemas/lattice.executor_receipt.v1.schema.json +66 -66
- package/docs/schemas/lattice.phase_todo_revision.v3.schema.json +360 -360
- package/docs/schemas/lattice.plan_create_input.v1.schema.json +56 -56
- package/docs/schemas/lattice.plan_create_input.v2.schema.json +72 -72
- package/docs/schemas/lattice.plan_create_input.v3.schema.json +81 -81
- package/docs/schemas/lattice.plan_create_input.v4.schema.json +85 -85
- package/docs/schemas/lattice.run_request.v1.schema.json +238 -238
- package/docs/schemas/lattice.runtime_adapter_capabilities.v2.schema.json +55 -55
- package/docs/schemas/lattice.runtime_adapter_registration_input.v1.schema.json +78 -78
- package/docs/schemas/lattice.runtime_adapter_registration_input.v2.schema.json +86 -86
- package/docs/schemas/lattice.todo_extraction.v2.schema.json +298 -298
- package/docs/schemas/lattice.todo_extraction.v3.schema.json +146 -146
- package/docs/schemas/lattice.todo_revision.v2.schema.json +260 -260
- package/docs/schemas/lattice.todo_revision_set.v3.schema.json +363 -363
- package/package.json +103 -103
- package/sensor/LICENSE +21 -21
- package/sensor/NOTICE +19 -19
- package/sensor/dist/bin/lattice-sensor.js +9 -9
- package/sensor/dist/db/index.js +24 -24
- package/sensor/dist/db/migrations.js +41 -41
- package/sensor/dist/db/queries.js +164 -164
- package/sensor/dist/db/schema.sql +205 -205
- package/sensor/dist/directory.js +5 -5
- package/sensor/dist/extraction/wasm/tree-sitter-c_sharp.wasm +0 -0
- package/sensor/dist/extraction/wasm/tree-sitter-cfml.wasm +0 -0
- package/sensor/dist/extraction/wasm/tree-sitter-cfquery.wasm +0 -0
- package/sensor/dist/extraction/wasm/tree-sitter-cfscript.wasm +0 -0
- package/sensor/dist/extraction/wasm/tree-sitter-cobol.wasm +0 -0
- package/sensor/dist/extraction/wasm/tree-sitter-erlang.wasm +0 -0
- package/sensor/dist/extraction/wasm/tree-sitter-go.wasm +0 -0
- package/sensor/dist/extraction/wasm/tree-sitter-java.wasm +0 -0
- package/sensor/dist/extraction/wasm/tree-sitter-javascript.wasm +0 -0
- package/sensor/dist/extraction/wasm/tree-sitter-nix.wasm +0 -0
- package/sensor/dist/extraction/wasm/tree-sitter-pascal.wasm +0 -0
- package/sensor/dist/extraction/wasm/tree-sitter-python.wasm +0 -0
- package/sensor/dist/extraction/wasm/tree-sitter-tsx.wasm +0 -0
- package/sensor/dist/extraction/wasm/tree-sitter-typescript.wasm +0 -0
- package/sensor/dist/extraction/wasm/tree-sitter-vbnet.wasm +0 -0
- package/sensor/dist/mcp/liveness-watchdog.js +53 -53
- package/sensor/dist/mcp/server-instructions.js +95 -95
- package/sensor/package.json +56 -56
- package/src/artifact-contracts-v2.mjs +325 -325
- package/src/artifact-contracts.mjs +895 -895
- package/src/boundary-compiler.mjs +712 -712
- package/src/boundary-observation-compiler-v2.mjs +344 -344
- package/src/bounded-seam.mjs +230 -230
- package/src/bridge-address.mjs +107 -107
- package/src/bridge-cli.mjs +297 -297
- package/src/bridge-config.mjs +346 -346
- package/src/bridge-daemon.mjs +378 -378
- package/src/bridge-launch-agent.mjs +323 -323
- package/src/bridge-registrar.mjs +102 -102
- package/src/bridge-server.mjs +376 -376
- package/src/cli-help.mjs +308 -308
- package/src/cli-stdio.mjs +40 -40
- package/src/control-compiler.mjs +532 -532
- package/src/dag-chain.mjs +261 -261
- package/src/factory-diagnostics.mjs +188 -188
- package/src/hash-chain.mjs +76 -76
- package/src/hooks-cli.mjs +1057 -1053
- package/src/isolation-runner.mjs +409 -409
- package/src/node-version-guard.mjs +44 -44
- package/src/project-cli.mjs +697 -697
- package/src/project-identity.mjs +130 -130
- package/src/rc1-black-box-oracle.mjs +906 -906
- package/src/rc1-comparison.mjs +154 -154
- package/src/rc1-evidence-bundle.mjs +456 -456
- package/src/rc1-v4-campaign.mjs +708 -708
- package/src/rc1-v4-transform.mjs +467 -467
- package/src/rc1-v5-artifact-set.mjs +855 -855
- package/src/rc1-v5-behavior-evidence.mjs +594 -594
- package/src/rc1-v5-campaign.mjs +797 -797
- package/src/rc1-v5-transform.mjs +421 -421
- package/src/rc1-v6-artifact-set.mjs +807 -807
- package/src/rc1-v6-behavior-evidence.mjs +273 -273
- package/src/rc1-v6-campaign.mjs +623 -623
- package/src/rc1-v6-causal-binding.mjs +473 -473
- package/src/rc1-v6-measurement.mjs +313 -313
- package/src/rc2-artifact-set.mjs +1584 -1584
- package/src/rc2-campaign.mjs +1506 -1502
- package/src/rc2-delivery-policy-front-end.mjs +1079 -1079
- package/src/rc2-delivery-policy-oracle.mjs +134 -134
- package/src/rc2-delivery-policy-transform.mjs +1127 -1127
- package/src/rc2-rc1-transfer-front-end.mjs +511 -511
- package/src/rc3-actual-dogfood.mjs +652 -652
- package/src/rc3-dogfood-scaffold.mjs +315 -315
- package/src/rc3-scripted-campaign.mjs +1383 -1383
- package/src/rc4-stage1-dogfood.mjs +673 -673
- package/src/runtime-adapter-registry.mjs +524 -520
- package/src/runtime-cli.mjs +4588 -4584
- package/src/runtime-contracts.mjs +824 -824
- package/src/runtime-control-store.mjs +604 -600
- package/src/runtime-controller-protocol.mjs +587 -587
- package/src/runtime-decision-verifier.mjs +701 -701
- package/src/runtime-diff-observer.mjs +361 -361
- package/src/runtime-direct-os-observer.mjs +301 -301
- package/src/runtime-driver-state.mjs +166 -162
- package/src/runtime-engine.mjs +779 -779
- package/src/runtime-errors.mjs +356 -356
- package/src/runtime-event-store.mjs +189 -189
- package/src/runtime-front-end.mjs +925 -925
- package/src/runtime-gate-store.mjs +481 -477
- package/src/runtime-hold-recompile.mjs +916 -916
- package/src/runtime-io-sentinel.mjs +391 -391
- package/src/runtime-lifecycle-lock.mjs +294 -290
- package/src/runtime-managed-supervisor.mjs +1490 -1490
- package/src/runtime-multi-epoch-store.mjs +838 -834
- package/src/runtime-projection.mjs +269 -269
- package/src/runtime-pull-intake.mjs +1192 -1188
- package/src/runtime-scripted-adapter-controller.mjs +1160 -1156
- package/src/runtime-scripted-executor.mjs +163 -163
- package/src/runtime-scripted-worktree.mjs +104 -104
- package/src/runtime-seam-resolve.mjs +428 -428
- package/src/runtime-seam-treatment.mjs +173 -173
- package/src/runtime-socket-owner.mjs +125 -125
- package/src/runtime-work-order-contracts.mjs +91 -91
- package/src/runtime-work-order-controller.mjs +1171 -1167
- package/src/runtime-worktree-executor.mjs +199 -199
- package/src/schedulability-compiler-v2.mjs +303 -303
- package/src/schedulability-verifier-v2.mjs +317 -317
- package/src/seam-apply.mjs +549 -549
- package/src/seam-commit-shared.mjs +22 -22
- package/src/seam-commit-transform.mjs +81 -81
- package/src/seam-commit.mjs +18 -18
- package/src/seam-cost.mjs +322 -322
- package/src/seam-derivation.mjs +188 -188
- package/src/seam-gate.mjs +146 -146
- package/src/seam-proposal-contracts.mjs +446 -446
- package/src/seam-proposal-queries.mjs +521 -521
- package/src/seam-proposal.mjs +2011 -2011
- package/src/seam-ref.mjs +33 -33
- package/src/seam-rewrite.mjs +286 -286
- package/src/seam-transform.mjs +554 -554
- package/src/seam-verification.mjs +260 -260
- package/src/sensor-adapter.mjs +432 -432
- package/src/sensor-cli.mjs +139 -139
- package/src/sensor-diff.mjs +661 -661
- package/src/sensor-node-runtime.mjs +53 -53
- package/src/sensor-runtime.mjs +52 -52
- package/src/timestamp-contract.mjs +8 -8
- package/src/todo-audit-pending.mjs +91 -91
- package/src/todo-chain.mjs +178 -178
- package/src/todo-cli.mjs +3141 -3126
- package/src/todo-contracts.mjs +728 -728
- package/src/todo-dashboard-registry.mjs +573 -573
- package/src/todo-dispatch-shape.mjs +190 -190
- package/src/todo-gantt-html-independence.mjs +239 -239
- package/src/todo-gantt-html-shared.mjs +226 -226
- package/src/todo-gantt-html-style.mjs +131 -131
- package/src/todo-gantt-html.mjs +248 -248
- package/src/todo-gantt-layout.mjs +974 -974
- package/src/todo-gantt-live.mjs +361 -361
- package/src/todo-gantt-nested.mjs +263 -263
- package/src/todo-gantt-presentation.mjs +217 -217
- package/src/todo-gantt-scope.mjs +123 -123
- package/src/todo-gantt-svg.mjs +353 -353
- package/src/todo-independence-contracts.mjs +595 -595
- package/src/todo-independence-guidance.mjs +322 -322
- package/src/todo-independence.mjs +640 -640
- package/src/todo-markdown-renderer.mjs +260 -260
- package/src/todo-migration.mjs +448 -448
- package/src/todo-narrative-anchor.mjs +130 -130
- package/src/todo-note-store.mjs +629 -625
- package/src/todo-parallel-candidates.mjs +114 -114
- package/src/todo-revision.mjs +995 -995
- package/src/todo-split.mjs +472 -472
- package/src/todo-status.mjs +690 -690
- package/src/todo-store-git-transaction.mjs +418 -418
- package/src/todo-store.mjs +4322 -4314
- package/src/treatment-compiler.mjs +728 -728
- package/src/treatment-runner.mjs +656 -656
- package/src/witness-scaffold.mjs +180 -180
package/docs/bridge-setup.md
CHANGED
|
@@ -1,132 +1,132 @@
|
|
|
1
|
-
# Optional network bridge
|
|
2
|
-
|
|
3
|
-
Latticeのproject dashboardは既定でloopbackだけにbindし、bridge用socketや設定を作らない。
|
|
4
|
-
LAN上のreverse proxyなどから閲覧する時だけ、利用者がlisten IPを明示してbridgeを有効化する。
|
|
5
|
-
`postinstall`では質問やnetwork公開を行わない。
|
|
6
|
-
|
|
7
|
-
TTYでは`lattice bridge setup`で安全側既定の対話wizardを開始できる。最初の公開確認は既定で無効を選び、
|
|
8
|
-
cancelした場合は設定を変更しない。非TTYではhangせず、次の非対話commandを案内する。
|
|
9
|
-
portを省略するか`auto`にすると、49152–65535から候補を重複なく選び、
|
|
10
|
-
実際のexclusive bindとhealth確認に成功したportだけを保存する。
|
|
11
|
-
|
|
12
|
-
```bash
|
|
13
|
-
lattice bridge setup --listen 192.168.1.50 --port auto --dashboard --allow-host lattice.example.com --json
|
|
14
|
-
```
|
|
15
|
-
|
|
16
|
-
`--dashboard`は現在のlocal dashboard descriptorをrequestごとに解決するため、dashboard再起動でportが変わっても
|
|
17
|
-
bridge設定はstaleにならない。固定upstreamを使う場合だけ`--upstream http://127.0.0.1:4318`を指定する。
|
|
18
|
-
listen IPは常に許可Hostへ入り、reverse proxyで公開するhostnameは`--allow-host`を反復して追加する。
|
|
19
|
-
許可されていないHostは421となるため、DNS rebinding originへ工程情報を返さない。
|
|
20
|
-
|
|
21
|
-
```bash
|
|
22
|
-
lattice bridge status --json
|
|
23
|
-
lattice bridge reconfigure --listen 192.168.1.50 --port auto --dashboard --json
|
|
24
|
-
lattice bridge disable --json
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
設定は`~/.lattice/bridge.json`へmode 0600でatomic保存する。`setup`/`reconfigure`は実bridge daemonが
|
|
28
|
-
選択socketをexclusive bindしhealthを返すまで成功にしない。起動に失敗した場合は旧設定へ戻す。
|
|
29
|
-
`disable`もbridge socketの停止確認後に成功し、loopbackのlocal dashboardは停止しない。
|
|
30
|
-
configまたはdaemon descriptorが壊れている場合、`disable`は公開socketのfail-closed停止を優先して破損control
|
|
31
|
-
fileを除去し、JSON結果の`recovery`へ処置を明示する。その後は`setup`で再設定できる。
|
|
32
|
-
|
|
33
|
-
自動化・隔離testではabsoluteな`LATTICE_CONFIG_DIR`で設定rootを変更できる。無効な設定、低いport、
|
|
34
|
-
使用中の明示port、危険なrequest target、到達不能upstreamはsilent fallbackせずtyped errorを返す。
|
|
35
|
-
|
|
36
|
-
## listen IPがDHCPで動く場合
|
|
37
|
-
|
|
38
|
-
設定したlisten IPがホストから消えると、古いsocketは死んだアドレスへ取り残され、LANから到達できなくなる。
|
|
39
|
-
daemonは各reconcileで実効アドレスを解決し直し、同一subnet(IPv4 /24、IPv6 /64)に生きたアドレスがあれば
|
|
40
|
-
そこへbindし直す。VPNや別NICなど異なるnetworkのアドレスは採用せず、候補が無ければ
|
|
41
|
-
`BRIDGE_LISTEN_ADDRESS_ABSENT`で公開socketをfail-closedにする。再bind先は許可Hostへ自動で加わる。
|
|
42
|
-
|
|
43
|
-
`LATTICE_BRIDGE_REGISTRAR_SSH_HOST`と`LATTICE_BRIDGE_REGISTRAR_SCRIPT`を両方設定すると、新しいbindingを
|
|
44
|
-
張るたびに`ssh <host> <script> <port>`でreverse proxy hostへ自己登録する。アドレスは送らず、remote側が
|
|
45
|
-
ssh送信元から決めるため、各hostは自分自身しか登録できない。登録の失敗はbridgeを落とさずstderrへ
|
|
46
|
-
typedに報告する。この配線が無いと、Caddy等が持つリテラルはlease変更のたびに黙って陳腐化する。
|
|
47
|
-
|
|
48
|
-
## reverse proxyへ逆トンネルで繋ぐ(LAN bindを使わない)
|
|
49
|
-
|
|
50
|
-
reverse proxy hostへsshで到達できるなら、LANへbindせずloopbackだけで公開できる。bridgeが動くhostから
|
|
51
|
-
接続しに行くため、そのhostのLAN addressはreverse proxyのどこにも現れず、追従も自己登録も不要になる。
|
|
52
|
-
|
|
53
|
-
```bash
|
|
54
|
-
lattice bridge setup --listen 127.0.0.1 --port 53939 --dashboard --allow-host lattice.example.com --json
|
|
55
|
-
ssh -N -o ExitOnForwardFailure=yes -o ServerAliveInterval=30 \
|
|
56
|
-
-R 172.18.0.1:53939:127.0.0.1:53939 proxy-host
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
reverse proxyはこの固定endpointだけを見る。転送口のbind先は、reverse proxyが到達できるaddressにする。
|
|
60
|
-
Docker上のreverse proxyでは、containerの`127.0.0.1`はcontainer自身のloopbackでありhostのそれではないため、
|
|
61
|
-
hostのloopbackへ開いた口には届かない。対象networkのgateway(`docker network inspect`の`Gateway`)へbindする。
|
|
62
|
-
|
|
63
|
-
sshdは既定の`GatewayPorts no`だと`127.0.0.1`にしかbindできない。`clientspecified`にすると、clientが明示した
|
|
64
|
-
addressだけにbindする(`yes`と違い全interfaceへは晒さない)。host firewallがINPUTをDROPしている場合は、
|
|
65
|
-
その1 portだけを許可する。`ExitOnForwardFailure=yes`は、転送口を開けないまま接続だけ生かす状態を防ぐ。
|
|
66
|
-
常駐はprocess supervisorのKeepAliveに任せ、切断時は張り直す。
|
|
67
|
-
|
|
68
|
-
## Docker Caddy/Cloudflare Tunnelへ接続する
|
|
69
|
-
|
|
70
|
-
bridgeを有効化したMacとreverse proxy hostの間で、まず許可Hostを付けたLAN到達を確認する。
|
|
71
|
-
この段階が失敗している時はDNSやTunnelを追加しない。
|
|
72
|
-
|
|
73
|
-
```bash
|
|
74
|
-
curl --fail --header 'Host: lattice.example.com' \
|
|
75
|
-
http://MAC_LAN_IP:BRIDGE_PORT/projects/
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
Caddyは既存のDocker networkと証明書運用を維持し、Lattice用siteだけを追加する。
|
|
79
|
-
|
|
80
|
-
```caddyfile
|
|
81
|
-
lattice.example.com {
|
|
82
|
-
reverse_proxy MAC_LAN_IP:BRIDGE_PORT {
|
|
83
|
-
flush_interval -1
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
本番反映はcontainer内で`caddy validate`を通してから`caddy reload`する。Caddyfileを単一ファイルで
|
|
89
|
-
bind mountしている構成では、atomic renameでhost側fileを置換するとcontainerが旧inodeを参照し続ける。
|
|
90
|
-
更新前backupを残し、inodeを維持するin-place更新を使うか、directory bind mountへ変更する。
|
|
91
|
-
|
|
92
|
-
remote-managed Cloudflare Tunnelでは、Tunnel実行tokenを設定APIの代用にしない。Cloudflareの正規管理面で
|
|
93
|
-
public hostname `lattice.kitepon.dev` を次のoriginへ対応付ける。
|
|
94
|
-
|
|
95
|
-
- Service: `https://caddy:443`
|
|
96
|
-
- TLS Origin Server Name: `lattice.kitepon.dev`(管理面に同等の設定がある場合は`Match SNI to Host`でもよい)
|
|
97
|
-
|
|
98
|
-
`http://caddy:80`は選ばない。CaddyのHTTPからHTTPSへのredirectをTunnelがorigin応答として返す構成は、
|
|
99
|
-
外部requestが同じ公開URLへ戻るredirect loopになり得るためである。外部gateではredirectを追って200にせず、
|
|
100
|
-
最初の応答がHTTPSの200であることを確認する。
|
|
101
|
-
|
|
102
|
-
受入は次の3 gateを独立して記録し、後段の成功で前段を代用しない。
|
|
103
|
-
|
|
104
|
-
1. **LAN bridge**: reverse proxy hostから許可Host付きで`http://MAC_LAN_IP:BRIDGE_PORT/projects/`が200。
|
|
105
|
-
2. **Docker Caddy**: Caddyへ`Host: lattice.kitepon.dev`を付けたHTTPS requestが200。証明書検証を省略する
|
|
106
|
-
内部probeを外部公開成功の証拠にはしない。
|
|
107
|
-
3. **Cloudflare public HTTPS**: `https://lattice.kitepon.dev/projects/`がredirectなしで200となり、一覧から開いた
|
|
108
|
-
`/projects/<project_id>/`のHTML titleが`Lattice — <project名> 依存工程図`である。
|
|
109
|
-
|
|
110
|
-
公開viewerの404も、ブラウザとAPIの両契約を別々に確認する。未知URLへ`Accept: text/html`を
|
|
111
|
-
付けたrequestはHTTP 404かつ`Content-Type: text/html`で、`noindex, nofollow`と
|
|
112
|
-
`/projects/`、`https://kitepon.dev/`への戻り先を持つ。`Accept: application/json`では
|
|
113
|
-
HTTP 404かつ`Content-Type: application/json`で、既存の
|
|
114
|
-
`lattice.todo_gantt_http_error.v1`を返す。
|
|
115
|
-
|
|
116
|
-
```bash
|
|
117
|
-
curl --silent --show-error --include --header 'Accept: text/html' \
|
|
118
|
-
https://lattice.kitepon.dev/unknown
|
|
119
|
-
curl --silent --show-error --include --header 'Accept: application/json' \
|
|
120
|
-
https://lattice.kitepon.dev/unknown
|
|
121
|
-
```
|
|
122
|
-
|
|
123
|
-
外部gateはHTMLだけで閉じず、各projectの
|
|
124
|
-
`https://lattice.kitepon.dev/projects/<project_id>/events`も確認する。応答は200かつ
|
|
125
|
-
`Content-Type: text/event-stream`で、接続直後に`event: state`と現在の`head_digest`を返さなければならない。
|
|
126
|
-
接続を開いたまま正規のTodo更新を行い、新しい`state`が同じstreamへ届くことを確認する。切断後に再接続しても
|
|
127
|
-
再び初回`state`が届き、そのdigestが最新headと一致することまでを継続・再接続gateとする。
|
|
128
|
-
|
|
129
|
-
```bash
|
|
130
|
-
curl --fail --show-error --include --no-buffer --max-time 15 \
|
|
131
|
-
https://lattice.kitepon.dev/projects/PROJECT_ID/events
|
|
132
|
-
```
|
|
1
|
+
# Optional network bridge
|
|
2
|
+
|
|
3
|
+
Latticeのproject dashboardは既定でloopbackだけにbindし、bridge用socketや設定を作らない。
|
|
4
|
+
LAN上のreverse proxyなどから閲覧する時だけ、利用者がlisten IPを明示してbridgeを有効化する。
|
|
5
|
+
`postinstall`では質問やnetwork公開を行わない。
|
|
6
|
+
|
|
7
|
+
TTYでは`lattice bridge setup`で安全側既定の対話wizardを開始できる。最初の公開確認は既定で無効を選び、
|
|
8
|
+
cancelした場合は設定を変更しない。非TTYではhangせず、次の非対話commandを案内する。
|
|
9
|
+
portを省略するか`auto`にすると、49152–65535から候補を重複なく選び、
|
|
10
|
+
実際のexclusive bindとhealth確認に成功したportだけを保存する。
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
lattice bridge setup --listen 192.168.1.50 --port auto --dashboard --allow-host lattice.example.com --json
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
`--dashboard`は現在のlocal dashboard descriptorをrequestごとに解決するため、dashboard再起動でportが変わっても
|
|
17
|
+
bridge設定はstaleにならない。固定upstreamを使う場合だけ`--upstream http://127.0.0.1:4318`を指定する。
|
|
18
|
+
listen IPは常に許可Hostへ入り、reverse proxyで公開するhostnameは`--allow-host`を反復して追加する。
|
|
19
|
+
許可されていないHostは421となるため、DNS rebinding originへ工程情報を返さない。
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
lattice bridge status --json
|
|
23
|
+
lattice bridge reconfigure --listen 192.168.1.50 --port auto --dashboard --json
|
|
24
|
+
lattice bridge disable --json
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
設定は`~/.lattice/bridge.json`へmode 0600でatomic保存する。`setup`/`reconfigure`は実bridge daemonが
|
|
28
|
+
選択socketをexclusive bindしhealthを返すまで成功にしない。起動に失敗した場合は旧設定へ戻す。
|
|
29
|
+
`disable`もbridge socketの停止確認後に成功し、loopbackのlocal dashboardは停止しない。
|
|
30
|
+
configまたはdaemon descriptorが壊れている場合、`disable`は公開socketのfail-closed停止を優先して破損control
|
|
31
|
+
fileを除去し、JSON結果の`recovery`へ処置を明示する。その後は`setup`で再設定できる。
|
|
32
|
+
|
|
33
|
+
自動化・隔離testではabsoluteな`LATTICE_CONFIG_DIR`で設定rootを変更できる。無効な設定、低いport、
|
|
34
|
+
使用中の明示port、危険なrequest target、到達不能upstreamはsilent fallbackせずtyped errorを返す。
|
|
35
|
+
|
|
36
|
+
## listen IPがDHCPで動く場合
|
|
37
|
+
|
|
38
|
+
設定したlisten IPがホストから消えると、古いsocketは死んだアドレスへ取り残され、LANから到達できなくなる。
|
|
39
|
+
daemonは各reconcileで実効アドレスを解決し直し、同一subnet(IPv4 /24、IPv6 /64)に生きたアドレスがあれば
|
|
40
|
+
そこへbindし直す。VPNや別NICなど異なるnetworkのアドレスは採用せず、候補が無ければ
|
|
41
|
+
`BRIDGE_LISTEN_ADDRESS_ABSENT`で公開socketをfail-closedにする。再bind先は許可Hostへ自動で加わる。
|
|
42
|
+
|
|
43
|
+
`LATTICE_BRIDGE_REGISTRAR_SSH_HOST`と`LATTICE_BRIDGE_REGISTRAR_SCRIPT`を両方設定すると、新しいbindingを
|
|
44
|
+
張るたびに`ssh <host> <script> <port>`でreverse proxy hostへ自己登録する。アドレスは送らず、remote側が
|
|
45
|
+
ssh送信元から決めるため、各hostは自分自身しか登録できない。登録の失敗はbridgeを落とさずstderrへ
|
|
46
|
+
typedに報告する。この配線が無いと、Caddy等が持つリテラルはlease変更のたびに黙って陳腐化する。
|
|
47
|
+
|
|
48
|
+
## reverse proxyへ逆トンネルで繋ぐ(LAN bindを使わない)
|
|
49
|
+
|
|
50
|
+
reverse proxy hostへsshで到達できるなら、LANへbindせずloopbackだけで公開できる。bridgeが動くhostから
|
|
51
|
+
接続しに行くため、そのhostのLAN addressはreverse proxyのどこにも現れず、追従も自己登録も不要になる。
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
lattice bridge setup --listen 127.0.0.1 --port 53939 --dashboard --allow-host lattice.example.com --json
|
|
55
|
+
ssh -N -o ExitOnForwardFailure=yes -o ServerAliveInterval=30 \
|
|
56
|
+
-R 172.18.0.1:53939:127.0.0.1:53939 proxy-host
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
reverse proxyはこの固定endpointだけを見る。転送口のbind先は、reverse proxyが到達できるaddressにする。
|
|
60
|
+
Docker上のreverse proxyでは、containerの`127.0.0.1`はcontainer自身のloopbackでありhostのそれではないため、
|
|
61
|
+
hostのloopbackへ開いた口には届かない。対象networkのgateway(`docker network inspect`の`Gateway`)へbindする。
|
|
62
|
+
|
|
63
|
+
sshdは既定の`GatewayPorts no`だと`127.0.0.1`にしかbindできない。`clientspecified`にすると、clientが明示した
|
|
64
|
+
addressだけにbindする(`yes`と違い全interfaceへは晒さない)。host firewallがINPUTをDROPしている場合は、
|
|
65
|
+
その1 portだけを許可する。`ExitOnForwardFailure=yes`は、転送口を開けないまま接続だけ生かす状態を防ぐ。
|
|
66
|
+
常駐はprocess supervisorのKeepAliveに任せ、切断時は張り直す。
|
|
67
|
+
|
|
68
|
+
## Docker Caddy/Cloudflare Tunnelへ接続する
|
|
69
|
+
|
|
70
|
+
bridgeを有効化したMacとreverse proxy hostの間で、まず許可Hostを付けたLAN到達を確認する。
|
|
71
|
+
この段階が失敗している時はDNSやTunnelを追加しない。
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
curl --fail --header 'Host: lattice.example.com' \
|
|
75
|
+
http://MAC_LAN_IP:BRIDGE_PORT/projects/
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Caddyは既存のDocker networkと証明書運用を維持し、Lattice用siteだけを追加する。
|
|
79
|
+
|
|
80
|
+
```caddyfile
|
|
81
|
+
lattice.example.com {
|
|
82
|
+
reverse_proxy MAC_LAN_IP:BRIDGE_PORT {
|
|
83
|
+
flush_interval -1
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
本番反映はcontainer内で`caddy validate`を通してから`caddy reload`する。Caddyfileを単一ファイルで
|
|
89
|
+
bind mountしている構成では、atomic renameでhost側fileを置換するとcontainerが旧inodeを参照し続ける。
|
|
90
|
+
更新前backupを残し、inodeを維持するin-place更新を使うか、directory bind mountへ変更する。
|
|
91
|
+
|
|
92
|
+
remote-managed Cloudflare Tunnelでは、Tunnel実行tokenを設定APIの代用にしない。Cloudflareの正規管理面で
|
|
93
|
+
public hostname `lattice.kitepon.dev` を次のoriginへ対応付ける。
|
|
94
|
+
|
|
95
|
+
- Service: `https://caddy:443`
|
|
96
|
+
- TLS Origin Server Name: `lattice.kitepon.dev`(管理面に同等の設定がある場合は`Match SNI to Host`でもよい)
|
|
97
|
+
|
|
98
|
+
`http://caddy:80`は選ばない。CaddyのHTTPからHTTPSへのredirectをTunnelがorigin応答として返す構成は、
|
|
99
|
+
外部requestが同じ公開URLへ戻るredirect loopになり得るためである。外部gateではredirectを追って200にせず、
|
|
100
|
+
最初の応答がHTTPSの200であることを確認する。
|
|
101
|
+
|
|
102
|
+
受入は次の3 gateを独立して記録し、後段の成功で前段を代用しない。
|
|
103
|
+
|
|
104
|
+
1. **LAN bridge**: reverse proxy hostから許可Host付きで`http://MAC_LAN_IP:BRIDGE_PORT/projects/`が200。
|
|
105
|
+
2. **Docker Caddy**: Caddyへ`Host: lattice.kitepon.dev`を付けたHTTPS requestが200。証明書検証を省略する
|
|
106
|
+
内部probeを外部公開成功の証拠にはしない。
|
|
107
|
+
3. **Cloudflare public HTTPS**: `https://lattice.kitepon.dev/projects/`がredirectなしで200となり、一覧から開いた
|
|
108
|
+
`/projects/<project_id>/`のHTML titleが`Lattice — <project名> 依存工程図`である。
|
|
109
|
+
|
|
110
|
+
公開viewerの404も、ブラウザとAPIの両契約を別々に確認する。未知URLへ`Accept: text/html`を
|
|
111
|
+
付けたrequestはHTTP 404かつ`Content-Type: text/html`で、`noindex, nofollow`と
|
|
112
|
+
`/projects/`、`https://kitepon.dev/`への戻り先を持つ。`Accept: application/json`では
|
|
113
|
+
HTTP 404かつ`Content-Type: application/json`で、既存の
|
|
114
|
+
`lattice.todo_gantt_http_error.v1`を返す。
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
curl --silent --show-error --include --header 'Accept: text/html' \
|
|
118
|
+
https://lattice.kitepon.dev/unknown
|
|
119
|
+
curl --silent --show-error --include --header 'Accept: application/json' \
|
|
120
|
+
https://lattice.kitepon.dev/unknown
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
外部gateはHTMLだけで閉じず、各projectの
|
|
124
|
+
`https://lattice.kitepon.dev/projects/<project_id>/events`も確認する。応答は200かつ
|
|
125
|
+
`Content-Type: text/event-stream`で、接続直後に`event: state`と現在の`head_digest`を返さなければならない。
|
|
126
|
+
接続を開いたまま正規のTodo更新を行い、新しい`state`が同じstreamへ届くことを確認する。切断後に再接続しても
|
|
127
|
+
再び初回`state`が届き、そのdigestが最新headと一致することまでを継続・再接続gateとする。
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
curl --fail --show-error --include --no-buffer --max-time 15 \
|
|
131
|
+
https://lattice.kitepon.dev/projects/PROJECT_ID/events
|
|
132
|
+
```
|
|
@@ -1,57 +1,57 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
-
"$id": "https://github.com/kitepon-rgb/Lattice/blob/main/docs/schemas/lattice.executor_packet.v1.schema.json",
|
|
4
|
-
"title": "lattice.executor_packet.v1",
|
|
5
|
-
"description": "The single context packet issued at dispatch. It is the machine record of the context an executor received.",
|
|
6
|
-
"$comment": "Runtime validation additionally enforces canonical JSON bytes, the self-digest rule for `packet_digest`, and that `context_content_digest` equals the SHA-256 of the canonical JSON projection of exactly {todo_id, task_ref, scope, base_sha, verifier_refs, forbidden_operations} — plan attribution fields are excluded so that an epoch rebind is provably content-preserving.",
|
|
7
|
-
"type": "object",
|
|
8
|
-
"additionalProperties": false,
|
|
9
|
-
"required": [
|
|
10
|
-
"schema",
|
|
11
|
-
"packet_id",
|
|
12
|
-
"todo_id",
|
|
13
|
-
"task_ref",
|
|
14
|
-
"scope",
|
|
15
|
-
"base_sha",
|
|
16
|
-
"plan_ref",
|
|
17
|
-
"plan_epoch",
|
|
18
|
-
"verifier_refs",
|
|
19
|
-
"forbidden_operations",
|
|
20
|
-
"context_content_digest",
|
|
21
|
-
"packet_digest"
|
|
22
|
-
],
|
|
23
|
-
"properties": {
|
|
24
|
-
"schema": { "const": "lattice.executor_packet.v1" },
|
|
25
|
-
"packet_id": { "$ref": "#/$defs/identifier" },
|
|
26
|
-
"todo_id": {
|
|
27
|
-
"$ref": "#/$defs/identifier",
|
|
28
|
-
"$comment": "Carried through from `run_request.v1`. It is not qualified by any TODO store project/plan/revision identity."
|
|
29
|
-
},
|
|
30
|
-
"task_ref": { "$ref": "#/$defs/identifier" },
|
|
31
|
-
"scope": { "type": "object" },
|
|
32
|
-
"base_sha": { "$ref": "#/$defs/gitSha" },
|
|
33
|
-
"plan_ref": { "$ref": "#/$defs/identifier" },
|
|
34
|
-
"plan_epoch": { "type": "integer", "minimum": 0 },
|
|
35
|
-
"verifier_refs": {
|
|
36
|
-
"type": "array",
|
|
37
|
-
"maxItems": 256,
|
|
38
|
-
"items": { "type": "string" }
|
|
39
|
-
},
|
|
40
|
-
"forbidden_operations": {
|
|
41
|
-
"type": "array",
|
|
42
|
-
"minItems": 1,
|
|
43
|
-
"maxItems": 256,
|
|
44
|
-
"items": { "type": "string" }
|
|
45
|
-
},
|
|
46
|
-
"context_content_digest": { "$ref": "#/$defs/digest" },
|
|
47
|
-
"packet_digest": { "$ref": "#/$defs/digest" }
|
|
48
|
-
},
|
|
49
|
-
"$defs": {
|
|
50
|
-
"identifier": {
|
|
51
|
-
"type": "string",
|
|
52
|
-
"pattern": "^[0-9A-Za-z](?:[0-9A-Za-z._-]{0,127})$"
|
|
53
|
-
},
|
|
54
|
-
"digest": { "type": "string", "pattern": "^[0-9a-f]{64}$" },
|
|
55
|
-
"gitSha": { "type": "string", "pattern": "^[0-9a-f]{40}$" }
|
|
56
|
-
}
|
|
57
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://github.com/kitepon-rgb/Lattice/blob/main/docs/schemas/lattice.executor_packet.v1.schema.json",
|
|
4
|
+
"title": "lattice.executor_packet.v1",
|
|
5
|
+
"description": "The single context packet issued at dispatch. It is the machine record of the context an executor received.",
|
|
6
|
+
"$comment": "Runtime validation additionally enforces canonical JSON bytes, the self-digest rule for `packet_digest`, and that `context_content_digest` equals the SHA-256 of the canonical JSON projection of exactly {todo_id, task_ref, scope, base_sha, verifier_refs, forbidden_operations} — plan attribution fields are excluded so that an epoch rebind is provably content-preserving.",
|
|
7
|
+
"type": "object",
|
|
8
|
+
"additionalProperties": false,
|
|
9
|
+
"required": [
|
|
10
|
+
"schema",
|
|
11
|
+
"packet_id",
|
|
12
|
+
"todo_id",
|
|
13
|
+
"task_ref",
|
|
14
|
+
"scope",
|
|
15
|
+
"base_sha",
|
|
16
|
+
"plan_ref",
|
|
17
|
+
"plan_epoch",
|
|
18
|
+
"verifier_refs",
|
|
19
|
+
"forbidden_operations",
|
|
20
|
+
"context_content_digest",
|
|
21
|
+
"packet_digest"
|
|
22
|
+
],
|
|
23
|
+
"properties": {
|
|
24
|
+
"schema": { "const": "lattice.executor_packet.v1" },
|
|
25
|
+
"packet_id": { "$ref": "#/$defs/identifier" },
|
|
26
|
+
"todo_id": {
|
|
27
|
+
"$ref": "#/$defs/identifier",
|
|
28
|
+
"$comment": "Carried through from `run_request.v1`. It is not qualified by any TODO store project/plan/revision identity."
|
|
29
|
+
},
|
|
30
|
+
"task_ref": { "$ref": "#/$defs/identifier" },
|
|
31
|
+
"scope": { "type": "object" },
|
|
32
|
+
"base_sha": { "$ref": "#/$defs/gitSha" },
|
|
33
|
+
"plan_ref": { "$ref": "#/$defs/identifier" },
|
|
34
|
+
"plan_epoch": { "type": "integer", "minimum": 0 },
|
|
35
|
+
"verifier_refs": {
|
|
36
|
+
"type": "array",
|
|
37
|
+
"maxItems": 256,
|
|
38
|
+
"items": { "type": "string" }
|
|
39
|
+
},
|
|
40
|
+
"forbidden_operations": {
|
|
41
|
+
"type": "array",
|
|
42
|
+
"minItems": 1,
|
|
43
|
+
"maxItems": 256,
|
|
44
|
+
"items": { "type": "string" }
|
|
45
|
+
},
|
|
46
|
+
"context_content_digest": { "$ref": "#/$defs/digest" },
|
|
47
|
+
"packet_digest": { "$ref": "#/$defs/digest" }
|
|
48
|
+
},
|
|
49
|
+
"$defs": {
|
|
50
|
+
"identifier": {
|
|
51
|
+
"type": "string",
|
|
52
|
+
"pattern": "^[0-9A-Za-z](?:[0-9A-Za-z._-]{0,127})$"
|
|
53
|
+
},
|
|
54
|
+
"digest": { "type": "string", "pattern": "^[0-9a-f]{64}$" },
|
|
55
|
+
"gitSha": { "type": "string", "pattern": "^[0-9a-f]{40}$" }
|
|
56
|
+
}
|
|
57
|
+
}
|
|
@@ -1,66 +1,66 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
-
"$id": "https://github.com/kitepon-rgb/Lattice/blob/main/docs/schemas/lattice.executor_receipt.v1.schema.json",
|
|
4
|
-
"title": "lattice.executor_receipt.v1",
|
|
5
|
-
"description": "The receipt an executor returns for one dispatched packet. `packet_digest` is what attributes it to the packet it received.",
|
|
6
|
-
"$comment": "Runtime validation additionally enforces canonical JSON bytes and the self-digest rule for `receipt_digest`. Acceptance is decided by event order, not by the receipt's own claims: the binding is checked against the `executor_dispatched` / `epoch_rebound` event that recorded the handle, worktree and packet digest for that TODO.",
|
|
7
|
-
"type": "object",
|
|
8
|
-
"additionalProperties": false,
|
|
9
|
-
"required": [
|
|
10
|
-
"schema",
|
|
11
|
-
"receipt_id",
|
|
12
|
-
"executor_handle",
|
|
13
|
-
"worktree_id",
|
|
14
|
-
"base_sha",
|
|
15
|
-
"plan_epoch",
|
|
16
|
-
"packet_digest",
|
|
17
|
-
"todo_id",
|
|
18
|
-
"checkpoint_digest",
|
|
19
|
-
"observed_diff",
|
|
20
|
-
"receipt_digest"
|
|
21
|
-
],
|
|
22
|
-
"properties": {
|
|
23
|
-
"schema": { "const": "lattice.executor_receipt.v1" },
|
|
24
|
-
"receipt_id": { "$ref": "#/$defs/identifier" },
|
|
25
|
-
"executor_handle": { "$ref": "#/$defs/identifier" },
|
|
26
|
-
"worktree_id": { "$ref": "#/$defs/identifier" },
|
|
27
|
-
"base_sha": { "$ref": "#/$defs/gitSha" },
|
|
28
|
-
"plan_epoch": { "type": "integer", "minimum": 0 },
|
|
29
|
-
"packet_digest": {
|
|
30
|
-
"$ref": "#/$defs/digest",
|
|
31
|
-
"$comment": "Attribution to the received `executor_packet.v1`. This is the only link back to the dispatch."
|
|
32
|
-
},
|
|
33
|
-
"todo_id": {
|
|
34
|
-
"$ref": "#/$defs/identifier",
|
|
35
|
-
"$comment": "Carried through from `run_request.v1`. It is not qualified by any TODO store project/plan/revision identity, so a receipt alone does not prove which TODO store task it belongs to."
|
|
36
|
-
},
|
|
37
|
-
"checkpoint_digest": { "$ref": "#/$defs/digest" },
|
|
38
|
-
"observed_diff": {
|
|
39
|
-
"type": "array",
|
|
40
|
-
"maxItems": 256,
|
|
41
|
-
"items": {
|
|
42
|
-
"type": "object",
|
|
43
|
-
"additionalProperties": false,
|
|
44
|
-
"required": ["path", "change"],
|
|
45
|
-
"properties": {
|
|
46
|
-
"path": { "$ref": "#/$defs/repoRelativePath" },
|
|
47
|
-
"change": { "enum": ["added", "modified", "deleted"] }
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
},
|
|
51
|
-
"receipt_digest": { "$ref": "#/$defs/digest" }
|
|
52
|
-
},
|
|
53
|
-
"$defs": {
|
|
54
|
-
"identifier": {
|
|
55
|
-
"type": "string",
|
|
56
|
-
"pattern": "^[0-9A-Za-z](?:[0-9A-Za-z._-]{0,127})$"
|
|
57
|
-
},
|
|
58
|
-
"digest": { "type": "string", "pattern": "^[0-9a-f]{64}$" },
|
|
59
|
-
"gitSha": { "type": "string", "pattern": "^[0-9a-f]{40}$" },
|
|
60
|
-
"repoRelativePath": {
|
|
61
|
-
"type": "string",
|
|
62
|
-
"minLength": 1,
|
|
63
|
-
"pattern": "^(?!/)(?!.*(?:^|/)\\.\\.?(?:/|$))[^\\u0000-\\u001f\\u007f\\\\]+$"
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://github.com/kitepon-rgb/Lattice/blob/main/docs/schemas/lattice.executor_receipt.v1.schema.json",
|
|
4
|
+
"title": "lattice.executor_receipt.v1",
|
|
5
|
+
"description": "The receipt an executor returns for one dispatched packet. `packet_digest` is what attributes it to the packet it received.",
|
|
6
|
+
"$comment": "Runtime validation additionally enforces canonical JSON bytes and the self-digest rule for `receipt_digest`. Acceptance is decided by event order, not by the receipt's own claims: the binding is checked against the `executor_dispatched` / `epoch_rebound` event that recorded the handle, worktree and packet digest for that TODO.",
|
|
7
|
+
"type": "object",
|
|
8
|
+
"additionalProperties": false,
|
|
9
|
+
"required": [
|
|
10
|
+
"schema",
|
|
11
|
+
"receipt_id",
|
|
12
|
+
"executor_handle",
|
|
13
|
+
"worktree_id",
|
|
14
|
+
"base_sha",
|
|
15
|
+
"plan_epoch",
|
|
16
|
+
"packet_digest",
|
|
17
|
+
"todo_id",
|
|
18
|
+
"checkpoint_digest",
|
|
19
|
+
"observed_diff",
|
|
20
|
+
"receipt_digest"
|
|
21
|
+
],
|
|
22
|
+
"properties": {
|
|
23
|
+
"schema": { "const": "lattice.executor_receipt.v1" },
|
|
24
|
+
"receipt_id": { "$ref": "#/$defs/identifier" },
|
|
25
|
+
"executor_handle": { "$ref": "#/$defs/identifier" },
|
|
26
|
+
"worktree_id": { "$ref": "#/$defs/identifier" },
|
|
27
|
+
"base_sha": { "$ref": "#/$defs/gitSha" },
|
|
28
|
+
"plan_epoch": { "type": "integer", "minimum": 0 },
|
|
29
|
+
"packet_digest": {
|
|
30
|
+
"$ref": "#/$defs/digest",
|
|
31
|
+
"$comment": "Attribution to the received `executor_packet.v1`. This is the only link back to the dispatch."
|
|
32
|
+
},
|
|
33
|
+
"todo_id": {
|
|
34
|
+
"$ref": "#/$defs/identifier",
|
|
35
|
+
"$comment": "Carried through from `run_request.v1`. It is not qualified by any TODO store project/plan/revision identity, so a receipt alone does not prove which TODO store task it belongs to."
|
|
36
|
+
},
|
|
37
|
+
"checkpoint_digest": { "$ref": "#/$defs/digest" },
|
|
38
|
+
"observed_diff": {
|
|
39
|
+
"type": "array",
|
|
40
|
+
"maxItems": 256,
|
|
41
|
+
"items": {
|
|
42
|
+
"type": "object",
|
|
43
|
+
"additionalProperties": false,
|
|
44
|
+
"required": ["path", "change"],
|
|
45
|
+
"properties": {
|
|
46
|
+
"path": { "$ref": "#/$defs/repoRelativePath" },
|
|
47
|
+
"change": { "enum": ["added", "modified", "deleted"] }
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
"receipt_digest": { "$ref": "#/$defs/digest" }
|
|
52
|
+
},
|
|
53
|
+
"$defs": {
|
|
54
|
+
"identifier": {
|
|
55
|
+
"type": "string",
|
|
56
|
+
"pattern": "^[0-9A-Za-z](?:[0-9A-Za-z._-]{0,127})$"
|
|
57
|
+
},
|
|
58
|
+
"digest": { "type": "string", "pattern": "^[0-9a-f]{64}$" },
|
|
59
|
+
"gitSha": { "type": "string", "pattern": "^[0-9a-f]{40}$" },
|
|
60
|
+
"repoRelativePath": {
|
|
61
|
+
"type": "string",
|
|
62
|
+
"minLength": 1,
|
|
63
|
+
"pattern": "^(?!/)(?!.*(?:^|/)\\.\\.?(?:/|$))[^\\u0000-\\u001f\\u007f\\\\]+$"
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|