From 82131d409aa48ebfd27649c61964043b2af50160 Mon Sep 17 00:00:00 2001 From: quolu <226230081+quolu@users.noreply.github.com> Date: Sat, 3 Oct 2026 06:28:41 +0000 Subject: [PATCH] =?UTF-8?q?host=20profile=20`linux`=20=E3=81=AE=E7=AB=AF?= =?UTF-8?q?=E6=9C=AB=E3=81=A7runtime=20error=E3=81=AE=E5=8F=8E=E9=9B=86?= =?UTF-8?q?=E3=81=8C=E7=84=A1=E5=8A=B9=E3=81=AB=E3=81=AA=E3=81=A3=E3=81=A6?= =?UTF-8?q?=E3=81=84=E3=81=9F=E3=81=AE=E3=82=92=E7=9B=B4=E3=81=99=EF=BC=88?= =?UTF-8?q?0.72.1=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit rabbit(工場のLinux workstation)で `lattice runtime-errors diagnostics` が `collection: disabled` を返した。`factory-reporter.json` の `host.profile` は `linux` で、 dotagentsの契約(lib/factory/contract.mjs)が認める語だが、Latticeが受ける一覧に無かった。 一覧に無い語は設定全体を無効とみなすので、rabbitでは故障が1件も記録されていなかった。 dotagentsと同じ5語(server・mac・linux・wsl・windows-native)を受ける。 5語すべてで収集が有効になり、未知の語では無効になることを試験で固定する。 Windowsは変えない。storeの所有者と権限をPOSIXの形で確かめられないので、 書き込みは store_unsafe で止まる。 Co-Authored-By: Claude Opus 5.5 --- CHANGELOG.md | 12 ++++++++++++ package-lock.json | 4 ++-- package.json | 2 +- src/runtime-errors.mjs | 5 ++++- test/runtime-errors.test.mjs | 19 +++++++++++++++++++ 5 files changed, 38 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b9c441d1..beb756d7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,17 @@ # Changelog +## 0.72.1 — 2026-10-03 + +### 修正 + +- `factory-reporter.json` の `host.profile` が `linux` の端末で、runtime errorの収集が無効になっていた + (`lattice runtime-errors diagnostics` が `collection: disabled`)。Latticeが受ける語の一覧に `linux` が無く、 + 設定全体を無効とみなしていた。工場のLinux workstation(rabbit)では、故障が1件も記録されていなかった。 + dotagentsの契約と同じ5語(`server`・`mac`・`linux`・`wsl`・`windows-native`)を受ける。 +- 変わらないこと: Windowsでは収集しない。storeの所有者と権限をPOSIXの形で確かめられないので、 + 書き込みを `store_unsafe` で止めている。設定の置き場(`%LOCALAPPDATA%\dotagents\factory-reporter\config.json`)も + 読まない。`windows-native` の語は受けるが、記録は作られない。 + ## 0.72.0 — 2026-10-03 ### runtime error記録: 落ちた面と例外の分類(`safe_context`) diff --git a/package-lock.json b/package-lock.json index af219584..b8b2bb32 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@quolu/lattice", - "version": "0.72.0", + "version": "0.72.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@quolu/lattice", - "version": "0.72.0", + "version": "0.72.1", "license": "PolyForm-Noncommercial-1.0.0", "dependencies": { "@clack/prompts": "^1.3.0", diff --git a/package.json b/package.json index 3b66c34f..6f081be2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@quolu/lattice", - "version": "0.72.0", + "version": "0.72.1", "description": "Schedulability compiler for multi-agent development: observe real code boundaries, refactor the conflicting seam, recompile the plan for parallel execution", "author": { "name": "Quo / クオ at kitepon.dev", diff --git a/src/runtime-errors.mjs b/src/runtime-errors.mjs index 627244b6..9b538bfc 100644 --- a/src/runtime-errors.mjs +++ b/src/runtime-errors.mjs @@ -45,6 +45,9 @@ const COMMAND_KIND = /^[a-z][a-z0-9-]*(?:\.[a-z][a-z0-9-]*)?$/; const COMMAND_KIND_MAX = 48; // Nodeが付けるerror code(ENOENT・ERR_MODULE_NOT_FOUND等)だけを通す。Lattice自身のcodeや任意文字列は`none`。 const CAUSE_CODE = /^(?:E[A-Z0-9]{2,15}|ERR_[A-Z0-9_]{1,60})$/; +// 工場の`factory-reporter.json`が名乗る端末の種類。dotagentsの契約(lib/factory/contract.mjs)と同じ語を +// 受ける——ここに無い語の端末は設定全体が無効とみなされ、故障を1件も記録しない。 +const HOST_PROFILES = Object.freeze(['server', 'mac', 'linux', 'wsl', 'windows-native']); const plain = (value) => typeof value === 'object' && value !== null && !Array.isArray(value); const exact = (value, keys) => Object.keys(value).length === keys.length && keys.every((key) => Object.hasOwn(value, key)); @@ -83,7 +86,7 @@ function collectionEnabled(options = {}) { return plain(config) && exact(config, ['schema_version', 'host', 'collection', 'reporting']) && config.schema_version === '1.0' && plain(config.host) && exact(config.host, ['id', 'profile']) && typeof config.host.id === 'string' && /^[a-z0-9][a-z0-9._-]{0,63}$/.test(config.host.id) - && ['server', 'mac', 'wsl', 'windows-native'].includes(config.host.profile) + && HOST_PROFILES.includes(config.host.profile) && plain(config.collection) && exact(config.collection, ['enabled']) && config.collection.enabled === true && canonicalReporting(config.reporting); } catch { diff --git a/test/runtime-errors.test.mjs b/test/runtime-errors.test.mjs index cde77a3c..7c1b430e 100644 --- a/test/runtime-errors.test.mjs +++ b/test/runtime-errors.test.mjs @@ -73,6 +73,25 @@ test('config欠落・malformed・disabledでは収集せずstateへ一切触れ } }); +test('工場が名乗るhost profileはすべて収集を有効にし、未知の語は無効にする', async () => { + // dotagentsの契約(lib/factory/contract.mjs)が認める語。`linux`を落とすと、その端末は故障を1件も記録しない。 + for (const profile of ['server', 'mac', 'linux', 'wsl', 'windows-native']) { + const workspace = await makeWorkspace({ ...VALID_CONFIG, host: { id: 'test-host', profile } }); + try { + assert.equal(runtimeCollectionEnabled(process.env, workspace.configPath), true, profile); + assert.equal(runtimeErrorsDiagnostics(workspace.options).collection, 'enabled', profile); + } finally { + await rm(workspace.root, { recursive: true, force: true }); + } + } + const unknown = await makeWorkspace({ ...VALID_CONFIG, host: { id: 'test-host', profile: 'linux-native' } }); + try { + assert.equal(runtimeCollectionEnabled(process.env, unknown.configPath), false); + } finally { + await rm(unknown.root, { recursive: true, force: true }); + } +}); + test('同一原因はfingerprint集約でcount/last_seen/sequenceと発生版が進む', async () => { const workspace = await makeWorkspace(); try {