@amsterdamdatalabs/adl-agent-control-linux-x64 0.1.10 → 0.1.12
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/bin/adl +2 -2
- package/bin/git +1 -1
- package/bin/git-ado +2 -2
- package/bin/lib/bun-compile-build.sh +1 -1
- package/bin/lib/fleet-host.sh +59 -0
- package/bin/lib/lean-ctx-observe-hooks.sh +9 -9
- package/bin/reconcile +222 -249
- package/bin/reconcile-host +111 -0
- package/bin/setup +216 -0
- package/bin/sync-and-reconcile +52 -39
- package/bin/validate-manifest +15 -44
- package/package.json +1 -3
- package/packages/agent-hooks/package.json +1 -2
- package/packages/agent-hooks/src/rules/impl/fs-trash.ts +2 -2
- package/packages/agent-settings/assets/GLOBAL-AGENTS.md +4 -2
- package/packages/agent-settings/src/global-surface-sweep.ts +5 -15
- package/packages/agent-skills/package.json +1 -1
- package/packages/azdo/package.json +1 -2
- package/packages/fleet/manifest.json +5 -24
- package/packages/fleet/manifest.schema.json +8 -58
- package/packages/fleet/src/install-embedding-model.ts +1 -1
- package/packages/fleet/src/repo-maintain.ts +403 -0
- package/packages/fleet/src/scratch-reap.ts +1 -1
- package/packages/repo-controls/package.json +0 -1
- package/packages/fleet/jobs/git-maintain/src/main.ts +0 -848
- package/packages/fleet/systemd/adl-azure-agent-update.service +0 -13
- package/packages/fleet/systemd/adl-azure-agent-update.timer +0 -10
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
*
|
|
8
8
|
* The original's eighth predicate -- any path with an `.agents` segment --
|
|
9
9
|
* was dropped by owner decision on 2026-09-15. `.agents/` is reconciled
|
|
10
|
-
* centrally every
|
|
11
|
-
* surfaces in every managed repo), so a trashed copy is restored rather than
|
|
10
|
+
* centrally every 12 hours (`adl reconcile`'s repository step runs `adl install --repo`,
|
|
11
|
+
* which refreshes repo-local surfaces in every managed repo), so a trashed copy is restored rather than
|
|
12
12
|
* lost, and `trash(1)` is itself recoverable from ~/.Trash. Protecting it here
|
|
13
13
|
* blocked routine work to guard against something the fleet already repairs.
|
|
14
14
|
*
|
|
@@ -9,7 +9,7 @@ repo's own `AGENTS.md`.
|
|
|
9
9
|
- If a task is ambiguous, ask exactly one clarifying question.
|
|
10
10
|
|
|
11
11
|
## Truthfulness (non-negotiable)
|
|
12
|
-
- **No fake-green tests
|
|
12
|
+
- **No fake-green tests.** A test changes only when the intended behaviour changes, never to make unintended behaviour pass. Red is honest.
|
|
13
13
|
- **No silent fallback or degrade** — if the real path fails, fail loud and stop.
|
|
14
14
|
- **No silent drops** — no `|| true`, no swallowed errors, no skipped gates.
|
|
15
15
|
- **No fakes** — no stubs, placeholders or TODOs passed off as done.
|
|
@@ -69,7 +69,9 @@ repo's own `AGENTS.md`.
|
|
|
69
69
|
|
|
70
70
|
## Tests
|
|
71
71
|
- For features, bugfixes and non-trivial refactors: **tests first**, confirmed failing for the right reason; then minimal code to pass; then a separate review pass.
|
|
72
|
-
- Every change ships a **new** test.
|
|
72
|
+
- Every change ships a **new** test.
|
|
73
|
+
- When a change deliberately alters behaviour, rework the existing tests that assert the old behaviour, in the same change. Name each reworked test and the decision that changed it.
|
|
74
|
+
- **Never fake green.** Don't loosen, skip or delete an assertion, or set an expectation to whatever the code returns, to hide a failure you didn't intend.
|
|
73
75
|
- Skip for pure config, docs and trivial one-liners.
|
|
74
76
|
|
|
75
77
|
## Delegation & parallelism
|
|
@@ -29,7 +29,6 @@ import {
|
|
|
29
29
|
import { dirname, isAbsolute, join, relative, resolve, sep } from 'node:path'
|
|
30
30
|
import { fileURLToPath } from 'node:url'
|
|
31
31
|
import { BEGIN as KIMI_BEGIN, END as KIMI_END } from './kimi-hooks.ts'
|
|
32
|
-
import { declaredLaunchAgentPlists } from '../../../packages/fleet/src/launch-agents.ts'
|
|
33
32
|
|
|
34
33
|
const LAUNCH_AGENTS_DIR = 'Library/LaunchAgents'
|
|
35
34
|
|
|
@@ -40,8 +39,6 @@ const LAUNCH_AGENTS_DIR = 'Library/LaunchAgents'
|
|
|
40
39
|
* these strings verbatim) contain, case-insensitively, one of these agent
|
|
41
40
|
* tool tokens. Everything else (GoogleUpdater, Keystone, other application
|
|
42
41
|
* updaters) is not an agent surface and is neither a candidate nor reported.
|
|
43
|
-
* LaunchAgents enact-vps declares in fleet/manifest.json are always in
|
|
44
|
-
* scope and protected by identity (see loadProtectionList).
|
|
45
42
|
*/
|
|
46
43
|
export const AGENT_TOOL_TOKENS = [
|
|
47
44
|
'lean-ctx',
|
|
@@ -295,7 +292,6 @@ export const EMPTY_PROTECTION: ProtectionList = {
|
|
|
295
292
|
}
|
|
296
293
|
|
|
297
294
|
export const DEFAULT_PROTECTION_PATH = fileURLToPath(new URL('../protected.json', import.meta.url))
|
|
298
|
-
export const DEFAULT_MANIFEST_PATH = fileURLToPath(new URL('../../fleet/manifest.json', import.meta.url))
|
|
299
295
|
|
|
300
296
|
export interface SweepNote {
|
|
301
297
|
readonly level: 'warn' | 'ok'
|
|
@@ -605,18 +601,12 @@ export function decodeProtectionList(value: unknown): ProtectionList {
|
|
|
605
601
|
}
|
|
606
602
|
|
|
607
603
|
/**
|
|
608
|
-
* The checked-in protection list
|
|
609
|
-
*
|
|
610
|
-
*
|
|
604
|
+
* The checked-in protection list. (It used to add every LaunchAgent the fleet
|
|
605
|
+
* manifest declared; the manifest declares none since git-maintain was retired
|
|
606
|
+
* on 2026-09-30, so nothing is derived from it any more.)
|
|
611
607
|
*/
|
|
612
|
-
export function loadProtectionList(path = DEFAULT_PROTECTION_PATH
|
|
613
|
-
|
|
614
|
-
const declared = declaredLaunchAgentPlists(JSON.parse(readFileSync(manifestPath, 'utf8')))
|
|
615
|
-
const listed = new Set(list.paths.map((entry) => entry.path))
|
|
616
|
-
const derived = declared
|
|
617
|
-
.filter((entry) => !listed.has(entry.path))
|
|
618
|
-
.map((entry) => ({ path: entry.path, reason: `LaunchAgent shipped by enact-vps (fleet/manifest.json ${entry.declaredAt})` }))
|
|
619
|
-
return { ...list, paths: [...list.paths, ...derived] }
|
|
608
|
+
export function loadProtectionList(path = DEFAULT_PROTECTION_PATH): ProtectionList {
|
|
609
|
+
return decodeProtectionList(JSON.parse(readFileSync(path, 'utf8')))
|
|
620
610
|
}
|
|
621
611
|
|
|
622
612
|
function tomlHeaderName(header: string): string {
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"scripts": {
|
|
16
16
|
"build": "rm -rf dist && tsc -p tsconfig.build.json",
|
|
17
17
|
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
18
|
-
"test": "bun run typecheck && bun test"
|
|
18
|
+
"test": "bun run typecheck && bun test --coverage"
|
|
19
19
|
},
|
|
20
20
|
"dependencies": {
|
|
21
21
|
"@iarna/toml": "^2.2.5",
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"schema": 1,
|
|
4
4
|
"repository": "https://dev.azure.com/amsterdamdatalabs/Infrastructure-AzDo/_git/adl-agent-control",
|
|
5
5
|
"branch": "main",
|
|
6
|
-
"interval_seconds":
|
|
6
|
+
"interval_seconds": 43200,
|
|
7
7
|
"update_policy": "latest-stable",
|
|
8
8
|
"allow_major_updates": true,
|
|
9
9
|
"remove_deleted_entries": true,
|
|
@@ -33,12 +33,6 @@
|
|
|
33
33
|
"git_global_config": {
|
|
34
34
|
"lfs.ssh://ssh.dev.azure.com/.sshtransfer": "never",
|
|
35
35
|
"lfs.https://ssh.dev.azure.com/.locksverify": "false"
|
|
36
|
-
},
|
|
37
|
-
"azure_agents": {
|
|
38
|
-
"organization": "amsterdamdatalabs",
|
|
39
|
-
"pool_id": 1,
|
|
40
|
-
"coordinator": "hostinger-vps-1",
|
|
41
|
-
"enabled_agents": ["mac-m5-ci", "hostinger-vps-1-agent-1", "hostinger-vps-1-agent-2"]
|
|
42
36
|
}
|
|
43
37
|
},
|
|
44
38
|
"mac": {
|
|
@@ -70,21 +64,6 @@
|
|
|
70
64
|
"shfmt": {"manager": "brew", "package": "shfmt", "executable": "shfmt"},
|
|
71
65
|
"uv": {"manager": "brew", "package": "uv", "executable": "uv"},
|
|
72
66
|
"yq": {"manager": "brew", "package": "yq", "executable": "yq"}
|
|
73
|
-
},
|
|
74
|
-
"launch_agents": {
|
|
75
|
-
"git-maintain": {
|
|
76
|
-
"label": "com.adl.git-maintain",
|
|
77
|
-
"source": "packages/fleet/jobs/git-maintain",
|
|
78
|
-
"entry": "src/main.ts",
|
|
79
|
-
"start_interval_seconds": 86400,
|
|
80
|
-
"run_at_load": true,
|
|
81
|
-
"repo_scope": {"root": "Documents", "glob": "*", "recursive": true},
|
|
82
|
-
"environment": {
|
|
83
|
-
"PATH": "/usr/local/bin:/opt/homebrew/bin:/usr/bin:/bin:/usr/sbin:/sbin"
|
|
84
|
-
},
|
|
85
|
-
"log": "Library/Logs/adl/git-maintain.log",
|
|
86
|
-
"replaces": [".local/bin/git-maintain.sh"]
|
|
87
|
-
}
|
|
88
67
|
}
|
|
89
68
|
},
|
|
90
69
|
"devices": {
|
|
@@ -94,6 +73,7 @@
|
|
|
94
73
|
"home": "/Users/tarunrana",
|
|
95
74
|
"minimum_free_gib": 20,
|
|
96
75
|
"schedule_minute": 5,
|
|
76
|
+
"repo_location": "/Users/tarunrana/Documents/Repos",
|
|
97
77
|
"brew_upgrade_all": true,
|
|
98
78
|
"surface_clis": [
|
|
99
79
|
{"name": "claude", "manager": "native", "command": "claude", "update_args": ["update"]},
|
|
@@ -114,6 +94,7 @@
|
|
|
114
94
|
"home": "/Users/ranahome",
|
|
115
95
|
"minimum_free_gib": 20,
|
|
116
96
|
"schedule_minute": 35,
|
|
97
|
+
"repo_location": "/Users/ranahome/Documents",
|
|
117
98
|
"brew_upgrade_all": true,
|
|
118
99
|
"surface_clis": [
|
|
119
100
|
{"name": "claude", "manager": "native", "command": "claude", "update_args": ["update"]},
|
|
@@ -169,7 +150,7 @@
|
|
|
169
150
|
"minimum_free_gib": 25,
|
|
170
151
|
"schedule_minute": 50,
|
|
171
152
|
"scratch_repos": ["/root/enact-webview"],
|
|
172
|
-
"
|
|
153
|
+
"repo_location": "/root/workspace",
|
|
173
154
|
"brew_upgrade_all": true,
|
|
174
155
|
"surface_clis": [
|
|
175
156
|
{"name": "claude", "manager": "native", "command": "claude", "update_args": ["update"]},
|
|
@@ -190,7 +171,7 @@
|
|
|
190
171
|
"minimum_free_gib": 25,
|
|
191
172
|
"schedule_minute": 20,
|
|
192
173
|
"scratch_repos": ["/root/enact-webview"],
|
|
193
|
-
"
|
|
174
|
+
"repo_location": "/root/workspace",
|
|
194
175
|
"brew_upgrade_all": true,
|
|
195
176
|
"surface_clis": [
|
|
196
177
|
{"name": "opencode", "manager": "npm", "command": "opencode", "update_args": ["upgrade"]},
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"properties": {
|
|
9
9
|
"config": {
|
|
10
10
|
"type": "object",
|
|
11
|
-
"required": ["schema", "repository", "branch", "interval_seconds", "update_policy", "allow_major_updates", "remove_deleted_entries", "global_surface_sweep", "kimi_hooks", "surface_policy", "global_agents", "vscode_settings", "scratch_reap", "protected_tools", "git_global_config"
|
|
11
|
+
"required": ["schema", "repository", "branch", "interval_seconds", "update_policy", "allow_major_updates", "remove_deleted_entries", "global_surface_sweep", "kimi_hooks", "surface_policy", "global_agents", "vscode_settings", "scratch_reap", "protected_tools", "git_global_config"],
|
|
12
12
|
"properties": {
|
|
13
13
|
"global_surface_sweep": {
|
|
14
14
|
"type": "object",
|
|
@@ -72,20 +72,8 @@
|
|
|
72
72
|
}
|
|
73
73
|
}
|
|
74
74
|
},
|
|
75
|
-
"mac": {
|
|
76
|
-
|
|
77
|
-
"properties": {
|
|
78
|
-
"common": {"properties": {"launch_agents": {"$ref": "#/$defs/launch_agents"}}},
|
|
79
|
-
"devices": {"additionalProperties": {"properties": {"launch_agents": {"$ref": "#/$defs/launch_agents"}}}}
|
|
80
|
-
}
|
|
81
|
-
},
|
|
82
|
-
"linux": {
|
|
83
|
-
"allOf": [{"$ref": "#/$defs/platform"}],
|
|
84
|
-
"properties": {
|
|
85
|
-
"common": {"not": {"required": ["launch_agents"]}},
|
|
86
|
-
"devices": {"additionalProperties": {"not": {"required": ["launch_agents"]}}}
|
|
87
|
-
}
|
|
88
|
-
}
|
|
75
|
+
"mac": {"$ref": "#/$defs/platform"},
|
|
76
|
+
"linux": {"$ref": "#/$defs/platform"}
|
|
89
77
|
},
|
|
90
78
|
"$defs": {
|
|
91
79
|
"tool": {
|
|
@@ -157,7 +145,6 @@
|
|
|
157
145
|
"type": "object",
|
|
158
146
|
"additionalProperties": {"$ref": "#/$defs/tool"}
|
|
159
147
|
},
|
|
160
|
-
"relative_path": {"type": "string", "pattern": "^(?!/)(?!.*(^|/)\\.\\.(/|$)).+$"},
|
|
161
148
|
"surface_cli": {
|
|
162
149
|
"type": "object",
|
|
163
150
|
"additionalProperties": false,
|
|
@@ -197,46 +184,13 @@
|
|
|
197
184
|
}
|
|
198
185
|
]
|
|
199
186
|
},
|
|
200
|
-
"launch_agent": {
|
|
201
|
-
"type": "object",
|
|
202
|
-
"additionalProperties": false,
|
|
203
|
-
"required": ["label", "source", "entry", "start_interval_seconds", "run_at_load", "environment", "log"],
|
|
204
|
-
"properties": {
|
|
205
|
-
"label": {"type": "string", "pattern": "^[A-Za-z0-9][A-Za-z0-9._-]*$"},
|
|
206
|
-
"source": {"$ref": "#/$defs/relative_path", "description": "Checkout-relative job directory; reconcile compiles it to a dedicated signed binary, rebuilt when its content hash changes."},
|
|
207
|
-
"entry": {"$ref": "#/$defs/relative_path", "description": "TypeScript entry file relative to source."},
|
|
208
|
-
"start_interval_seconds": {"type": "integer", "minimum": 60},
|
|
209
|
-
"run_at_load": {"type": "boolean"},
|
|
210
|
-
"repo_scope": {
|
|
211
|
-
"type": "object",
|
|
212
|
-
"additionalProperties": false,
|
|
213
|
-
"required": ["root", "glob", "recursive"],
|
|
214
|
-
"properties": {
|
|
215
|
-
"root": {"$ref": "#/$defs/relative_path", "description": "Repository scan root relative to the device administrator's home."},
|
|
216
|
-
"glob": {"type": "string", "minLength": 1},
|
|
217
|
-
"recursive": {"const": true}
|
|
218
|
-
}
|
|
219
|
-
},
|
|
220
|
-
"environment": {
|
|
221
|
-
"type": "object",
|
|
222
|
-
"propertyNames": {"pattern": "^[A-Z_][A-Z0-9_]*$"},
|
|
223
|
-
"additionalProperties": {"type": "string"}
|
|
224
|
-
},
|
|
225
|
-
"log": {"$ref": "#/$defs/relative_path"},
|
|
226
|
-
"replaces": {"type": "array", "items": {"$ref": "#/$defs/relative_path"}}
|
|
227
|
-
}
|
|
228
|
-
},
|
|
229
|
-
"launch_agents": {
|
|
230
|
-
"description": "User LaunchAgents enact-vps installs for the device administrator (macOS only).",
|
|
231
|
-
"type": "object",
|
|
232
|
-
"additionalProperties": {"$ref": "#/$defs/launch_agent"}
|
|
233
|
-
},
|
|
234
187
|
"platform": {
|
|
235
188
|
"type": "object",
|
|
236
189
|
"required": ["common", "devices"],
|
|
237
190
|
"properties": {
|
|
238
191
|
"common": {
|
|
239
192
|
"type": "object",
|
|
193
|
+
"additionalProperties": false,
|
|
240
194
|
"required": ["tools"],
|
|
241
195
|
"properties": {
|
|
242
196
|
"os_upgrade": {"type": "boolean"},
|
|
@@ -274,14 +228,10 @@
|
|
|
274
228
|
"items": {"type": "string", "pattern": "^/[^\\s]*[^/\\s]$"},
|
|
275
229
|
"uniqueItems": true
|
|
276
230
|
},
|
|
277
|
-
"
|
|
278
|
-
"type": "
|
|
279
|
-
"description": "
|
|
280
|
-
"
|
|
281
|
-
"type": "string",
|
|
282
|
-
"pattern": "^/(?!$)(?!.*\\s)(?!.*/$)(?!.*\\.\\.)(?!.*[aA][zZ][aA][gG][eE][nN][tT])(?!.*[vV][sS][tT][sS]\\.[aA][gG][eE][nN][tT]).+$"
|
|
283
|
-
},
|
|
284
|
-
"uniqueItems": true
|
|
231
|
+
"repo_location": {
|
|
232
|
+
"type": "string",
|
|
233
|
+
"description": "One absolute directory on this host. `adl reconcile` maintains (fetch --prune, fast-forward integration and main, safe branch prune, then `adl install --repo`) every IMMEDIATE child of it that carries adl-config.toml and is a git top-level, as the device administrator. It is the entire scope of that step: nothing outside it is scanned or touched, and a child that resolves outside it is refused. A missing or unreadable location fails the run; a host that declares none skips the step with a log line. The case-insensitive azagent/vsts.agent ban keeps it away from Azure Pipelines agent installs (JSON Schema `pattern` has no case-insensitive flag, so the classes are spelled out).",
|
|
234
|
+
"pattern": "^/(?!$)(?!.*\\s)(?!.*/$)(?!.*\\.\\.)(?!.*[aA][zZ][aA][gG][eE][nN][tT])(?!.*[vV][sS][tT][sS]\\.[aA][gG][eE][nN][tT]).+$"
|
|
285
235
|
},
|
|
286
236
|
"tools": {"$ref": "#/$defs/tools"}
|
|
287
237
|
}
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
* bytes because they merely arrived over HTTPS. `revision` is then recorded
|
|
33
33
|
* in the installed `manifest.json` so the next run can skip the rebuild
|
|
34
34
|
* (network round-trip to resolve latest + a local file read) instead of
|
|
35
|
-
* re-downloading and re-verifying multi-hundred-MB files on every
|
|
35
|
+
* re-downloading and re-verifying multi-hundred-MB files on every 12-hour
|
|
36
36
|
* reconcile just to reach the same answer.
|
|
37
37
|
*
|
|
38
38
|
* `manifest.json`'s `source`, `vocab_limit`, and `dim` come from
|