@quolu/lattice 0.12.27 → 0.12.29
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 +8 -0
- package/docs/bridge-setup.md +12 -0
- package/package.json +1 -1
- package/src/bridge-server.mjs +20 -6
- package/src/todo-store.mjs +2 -0
package/README.md
CHANGED
|
@@ -3,6 +3,14 @@
|
|
|
3
3
|
Latticeは、codebaseの境界を観測・変換し、multi-agent開発の並列TODO graphを生成する
|
|
4
4
|
schedulability compilerです。
|
|
5
5
|
|
|
6
|
+
## 開発工場での位置づけ
|
|
7
|
+
|
|
8
|
+
Latticeは[dotagents開発工場](https://github.com/kitepon-rgb/dotagents)が管理する
|
|
9
|
+
自作コア10製品の一つです。本repoはplan/ToDo/run store、sensor、schema、migration、
|
|
10
|
+
release、diagnosticsを所有し、dotagentsは製品横断の工程利用・導入・host統合を所有します。
|
|
11
|
+
廃止済みの前身sensorは独立製品として配線せず、Lattice sensorだけを現役面とします。
|
|
12
|
+
MarkItDownは別区分の第三者CLIです。
|
|
13
|
+
|
|
6
14
|
現在の工程状態と完了証拠の正本は、このrepoのLattice storeです。文書の役割と現行導線は
|
|
7
15
|
[docs/README.md](docs/README.md)、製品思想は[PLAN.md](PLAN.md)、公開contractは
|
|
8
16
|
[docs/00_product-contract.md](docs/00_product-contract.md)を参照してください。
|
package/docs/bridge-setup.md
CHANGED
|
@@ -33,6 +33,18 @@ fileを除去し、JSON結果の`recovery`へ処置を明示する。その後
|
|
|
33
33
|
自動化・隔離testではabsoluteな`LATTICE_CONFIG_DIR`で設定rootを変更できる。無効な設定、低いport、
|
|
34
34
|
使用中の明示port、危険なrequest target、到達不能upstreamはsilent fallbackせずtyped errorを返す。
|
|
35
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
|
+
|
|
36
48
|
## Docker Caddy/Cloudflare Tunnelへ接続する
|
|
37
49
|
|
|
38
50
|
bridgeを有効化したMacとreverse proxy hostの間で、まず許可Hostを付けたLAN到達を確認する。
|
package/package.json
CHANGED
package/src/bridge-server.mjs
CHANGED
|
@@ -308,6 +308,7 @@ export function bridgeRuntimeController({
|
|
|
308
308
|
env = process.env, instanceToken = null,
|
|
309
309
|
register = registerBridgeUpstream,
|
|
310
310
|
report = (line) => process.stderr.write(`${line}\n`),
|
|
311
|
+
readInterfaces = () => networkInterfaces(),
|
|
311
312
|
} = {}) {
|
|
312
313
|
let active = null;
|
|
313
314
|
let fingerprint = null;
|
|
@@ -329,23 +330,36 @@ export function bridgeRuntimeController({
|
|
|
329
330
|
async reconcile() {
|
|
330
331
|
const config = await readBridgeConfig({ env });
|
|
331
332
|
const next = config === null || !config.enabled ? null : JSON.stringify(config);
|
|
332
|
-
|
|
333
|
+
// The config is not the only thing that can change under a live binding.
|
|
334
|
+
// A DHCP lease change removes the bound address from the host without
|
|
335
|
+
// touching a byte of config, and the socket lingers on an address nothing
|
|
336
|
+
// can route to. Resolve the effective address on every pass, from the
|
|
337
|
+
// interfaces as they are now, so the binding follows the host rather than
|
|
338
|
+
// only the file. One snapshot serves both the comparison and the bind, so
|
|
339
|
+
// a lease that changes mid-reconcile cannot land them on different
|
|
340
|
+
// addresses.
|
|
341
|
+
const interfaces = next === null ? null : readInterfaces();
|
|
342
|
+
const effective = next === null ? null
|
|
343
|
+
: resolveBridgeListenAddress({ configured: config.listen.address, interfaces }).effective;
|
|
344
|
+
if (next === fingerprint && (active === null || active.address === effective)) return active;
|
|
333
345
|
if (next === null) {
|
|
334
346
|
await active?.close();
|
|
335
347
|
active = null;
|
|
336
348
|
fingerprint = null;
|
|
337
349
|
return null;
|
|
338
350
|
}
|
|
339
|
-
//
|
|
340
|
-
//
|
|
341
|
-
//
|
|
351
|
+
// The binding is reused while it still serves the same configuration AND
|
|
352
|
+
// still sits on the address that configuration resolves to today. The
|
|
353
|
+
// effective address is stable for an unchanged host, so this compares
|
|
354
|
+
// equal on every quiet pass and only forces a rebind when the ground has
|
|
355
|
+
// actually moved.
|
|
342
356
|
if (active !== null && active.configured_address === config.listen.address
|
|
343
|
-
&& active.port === config.listen.port) {
|
|
357
|
+
&& active.port === config.listen.port && active.address === effective) {
|
|
344
358
|
active.updateConfig(config);
|
|
345
359
|
fingerprint = next;
|
|
346
360
|
return active;
|
|
347
361
|
}
|
|
348
|
-
const replacement = await startBridgeServer({ config, env, instanceToken });
|
|
362
|
+
const replacement = await startBridgeServer({ config, env, instanceToken, interfaces });
|
|
349
363
|
const previous = active;
|
|
350
364
|
active = replacement;
|
|
351
365
|
fingerprint = next;
|
package/src/todo-store.mjs
CHANGED
|
@@ -3143,6 +3143,8 @@ export async function applyTodoRevision(options = {}) {
|
|
|
3143
3143
|
journal_ref: journalRef, snapshot_ref: snapshotRef,
|
|
3144
3144
|
topology_digest: revision.desired_plan.topology_digest,
|
|
3145
3145
|
journal_head_digest: genesis.event_digest,
|
|
3146
|
+
...(currentManifest.schema === 'lattice.todo_manifest.v2'
|
|
3147
|
+
? { active_revision_digest: revision.revision_digest } : {}),
|
|
3146
3148
|
});
|
|
3147
3149
|
currentManifest.manifest_digest = todoSelfDigest(currentManifest, 'manifest_digest');
|
|
3148
3150
|
await atomicWrite(path.resolve(repoRoot, MANIFEST_REF), canonicalLine(currentManifest));
|