leerness 1.36.183 → 1.36.185

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.
@@ -0,0 +1,411 @@
1
+ # Role / Agent / Routing v2 — compatibility design draft
2
+
3
+ Status: schema foundation implemented and tested; no runtime migration, public v2 CLI, automatic dispatch, or v2 store write is enabled yet.
4
+
5
+ Reviewed inputs:
6
+ - Current implementation in `lib/role-catalog.js`, `lib/agent-registry.js`, `lib/routing.js`, `lib/agents.js` and `.leerness/agent-roles.json` handling.
7
+ - Provider observation and exact-file lease work from `T-0165` and `T-0166`.
8
+ - User-supplied ChatGPT project conversation “추가 개발 직위 추천”, reviewed 2026-09-03.
9
+
10
+ ## 1. Design model
11
+
12
+ Leerness should represent four different concepts explicitly:
13
+
14
+ ```text
15
+ Model = provider/model capability and observed availability
16
+ Role = responsibilities, permissions, required inputs and outputs
17
+ Agent = one role-bearing execution instance with a model and session identity
18
+ Task = bounded work assigned to an Agent with scope and evidence
19
+ ```
20
+
21
+ The user-facing workflow should default to `Auto`, but `Auto` means a small Router proposes a pipeline. It does not mean Leerness silently invokes paid models or grants write permissions.
22
+
23
+ ## 2. Existing implementation inventory
24
+
25
+ | Area | Current state | Useful foundation | Missing for v2 |
26
+ |---|---|---|---|
27
+ | Role catalog | Seven built-ins: commander, reviewer, coder, architect, designer, debugger, dispatcher | Model-independent role IDs and aliases already exist | No tester/security/release/observer/router; responsibility and permission contracts are mostly descriptive strings |
28
+ | Role assignment | `.leerness/agent-roles.json` maps one role to one provider/model | Existing CLI and persisted user mappings must be preserved | Cannot represent multiple workers, agent identity, concurrency, budget or fallback |
29
+ | Provider registry | Ten built-ins plus project overrides | Installation/enablement/auth observation and provider metadata | Provider is still treated as the dispatch target rather than one component of an Agent instance |
30
+ | Routing | `tiny`, `normal`, `high-risk` classification and hard-coded role sets | Deterministic rules, explicit confirmation, human approval and reviewer independence already exist | No project routing policy document, review-only route, tester stage, fallback chain, budget or lease preflight |
31
+ | Dispatch | `agents dispatch --role` resolves role to provider/model | Explicit execution path and role-based targeting | No Agent-instance selector, no task envelope, no multi-worker allocation |
32
+ | Session state | session presence and session-scoped evidence | Stable session identity and evidence attribution | Agent registry is not linked to sessions as a first-class contract |
33
+ | Coordination | exact-file TTL lease CLI/MCP | Synchronous conflict evidence and fail-closed path handling | Not yet a dispatch precondition for mutating Agents |
34
+ | Verification | tester-like command execution, reviewer personas, verify-claim and gate | Strong completion and evidence primitives | Tester and Reviewer are not explicit lifecycle roles with separate state transitions |
35
+
36
+ ## 3. Compatibility strategy
37
+
38
+ ### 3.1 Preserve current identifiers
39
+
40
+ The first v2 implementation must not invalidate existing projects.
41
+
42
+ | Existing ID | v2 semantic label | Compatibility rule |
43
+ |---|---|---|
44
+ | `commander` | orchestrator | Keep as accepted persisted ID and CLI alias |
45
+ | `coder` | implementer / worker | Keep as accepted persisted ID and CLI alias |
46
+ | `dispatcher` | assignment dispatcher | Do not silently reinterpret as the request-classification Router |
47
+ | `reviewer` | reviewer | Preserve |
48
+ | `architect` | architect | Preserve |
49
+ | `designer` | designer | Preserve as optional specialist |
50
+ | `debugger` | debugger | Preserve as optional specialist |
51
+
52
+ New IDs should initially be additive: `router`, `tester`, `security`, `release`, `observer`, and optionally `director`.
53
+
54
+ ### 3.2 Preserve `.leerness/agent-roles.json`
55
+
56
+ The current file is a one-role-to-one-model assignment store. It should remain readable and writable during migration.
57
+
58
+ Candidate migration behavior:
59
+ 1. Load v2 stores if present and valid.
60
+ 2. If v2 is absent, load `agent-roles.json` and project each mapping into one deterministic Agent instance.
61
+ 3. Do not rewrite the legacy store on read.
62
+ 4. An explicit migration command writes v2 stores atomically and records source provenance.
63
+ 5. During a compatibility window, `roles set/unset` updates both the v2 assignment projection and legacy file under one lock.
64
+ 6. Unknown fields, schema mismatch, an existing empty file, or corruption fail closed and preserve original bytes.
65
+ 7. Only the original seven v1 persisted IDs map directly to built-in roles. A legacy custom key such as `implementer`, `worker`, `tester`, or `orchestrator` remains a deterministic custom role; new v2 aliases never silently reinterpret old user data.
66
+ 8. A disabled v2 Agent cannot be projected as a primary legacy assignment because v1 has no disabled-state field; projection fails closed instead of silently re-enabling it.
67
+
68
+ ## 4. Three logical configuration layers
69
+
70
+ The linked conversation proposed `roles.yaml`, `agents.yaml`, and `routing.yaml`. The separation is accepted, but canonical storage should initially remain JSON because Leerness guarantees zero runtime dependencies and already has strict JSON corruption handling.
71
+
72
+ The schema foundation freezes the following canonical filenames. No command writes them yet.
73
+
74
+ ### 4.1 Role Registry — `.leerness/role-definitions.json`
75
+
76
+ ```json
77
+ {
78
+ "schemaVersion": 2,
79
+ "kind": "role-definitions",
80
+ "roles": {
81
+ "coder": {
82
+ "label": { "ko": "작업자", "en": "Implementer" },
83
+ "responsibilities": ["implement bounded changes", "write relevant tests"],
84
+ "requiredTier": "project-write",
85
+ "codeWrite": true,
86
+ "approve": false,
87
+ "release": false,
88
+ "forbidden": ["approve-own-work", "merge", "release"],
89
+ "requiredInputs": ["task", "allowedFiles", "doneWhen"],
90
+ "requiredOutputs": ["changedFiles", "summary", "tests", "issues", "evidence"],
91
+ "contextPolicy": "assigned-files-and-contract",
92
+ "defaultBudget": { "inputTokens": null, "outputTokens": null, "retries": 1 }
93
+ }
94
+ },
95
+ "source": { "kind": "project-config", "file": "role-definitions.json" }
96
+ }
97
+ ```
98
+
99
+ Rules:
100
+ - No provider or model IDs in Role definitions.
101
+ - `requiredTier` and explicit write/approve/release booleans use existing Leerness policy semantics instead of a parallel permission vocabulary.
102
+ - `responsibilities`, `forbidden`, required inputs/outputs, and budgets are machine-validated contracts, not documentation-only prose.
103
+ - Project overrides may narrow permissions but may not silently widen a built-in role without explicit confirmation.
104
+
105
+ ### 4.2 Agent Registry — `.leerness/agent-instances.json`
106
+
107
+ ```json
108
+ {
109
+ "schemaVersion": 2,
110
+ "kind": "agent-instances",
111
+ "agents": [
112
+ {
113
+ "id": "backend-worker-01",
114
+ "role": "coder",
115
+ "provider": "qwen",
116
+ "model": "project-selected-model",
117
+ "enabled": true,
118
+ "maxConcurrency": 1,
119
+ "sessionKeyPolicy": "required-for-write",
120
+ "budget": { "inputTokens": null, "outputTokens": null, "retries": 1 },
121
+ "fallback": ["backend-worker-02"],
122
+ "tags": ["backend", "typescript"]
123
+ }
124
+ ],
125
+ "source": { "kind": "project-config", "file": "agent-instances.json" }
126
+ }
127
+ ```
128
+
129
+ Rules:
130
+ - Multiple Agents may use the same Role and Model.
131
+ - Agent IDs are stable project identifiers, not process IDs.
132
+ - A mutating Agent needs a stable session key and exact-file scope before dispatch.
133
+ - `budget` values may be unknown; unknown must not be represented as zero or unlimited.
134
+ - Fallback references Agent IDs, not raw model names, so permissions and role remain stable.
135
+
136
+ ### 4.3 Routing Policy — `.leerness/routing-policy.json`
137
+
138
+ ```json
139
+ {
140
+ "schemaVersion": 2,
141
+ "kind": "routing-policy",
142
+ "defaultMode": "suggest",
143
+ "pipelines": {
144
+ "tiny": ["coder", "tester"],
145
+ "normal": ["commander", "coder", "tester", "reviewer"],
146
+ "high-risk": ["architect", "commander", "coder", "tester", "reviewer"],
147
+ "review-only": ["reviewer"]
148
+ },
149
+ "requirements": {
150
+ "tiny": {
151
+ "humanApproval": false,
152
+ "independentReviewer": false,
153
+ "verifyClaim": true,
154
+ "gate": false,
155
+ "leaseForWrites": true
156
+ },
157
+ "normal": {
158
+ "humanApproval": false,
159
+ "independentReviewer": true,
160
+ "verifyClaim": true,
161
+ "gate": true,
162
+ "leaseForWrites": true
163
+ },
164
+ "high-risk": {
165
+ "humanApproval": true,
166
+ "independentReviewer": true,
167
+ "verifyClaim": true,
168
+ "gate": true,
169
+ "leaseForWrites": true
170
+ },
171
+ "review-only": {
172
+ "humanApproval": false,
173
+ "independentReviewer": false,
174
+ "verifyClaim": false,
175
+ "gate": false,
176
+ "leaseForWrites": false
177
+ }
178
+ },
179
+ "source": { "kind": "project-config", "file": "routing-policy.json" }
180
+ }
181
+ ```
182
+
183
+ Rules:
184
+ - Every pipeline has an explicit requirement block; missing safety requirements are invalid rather than defaulted.
185
+ - Named pipelines are non-empty and retain their minimum stages in safety order; an `independentReviewer` requirement without a Reviewer stage is invalid.
186
+ - Classification remains deterministic and explainable.
187
+ - `suggest` performs no provider command and no model call.
188
+ - `confirm` may validate configured providers but still does not imply the work executed.
189
+ - Actual execution is a separate dispatch action with explicit permission and cost boundary.
190
+ - Schema validity and execution readiness are separate facts. A structurally valid bundle may expose `assignmentGaps` when a pipeline role has no enabled Agent. `assignmentReady` means only that configured enabled Agent assignments cover the pipelines; provider authentication, model entitlement, capacity, and live callability are not checked and must not be presented as executable-ready.
191
+
192
+ ## 5. Role lifecycle
193
+
194
+ ### 5.1 Minimal normal pipeline
195
+
196
+ ```text
197
+ requested
198
+ → routed
199
+ → decomposed by orchestrator
200
+ → assigned to implementer
201
+ → implementation-reported
202
+ → tested by tester
203
+ → reviewed by reviewer
204
+ → evidence-verified
205
+ → done
206
+ ```
207
+
208
+ A task may move backwards on `test-failed`, `review-rejected`, `lease-conflict`, `provider-unavailable`, or `evidence-incomplete`.
209
+
210
+ ### 5.2 Self-approval prohibition
211
+
212
+ The following must not be treated as independent verification:
213
+ - Same Agent instance implements and approves.
214
+ - Same run/session writes code and records the Reviewer verdict.
215
+ - High-risk Implementer and Reviewer resolve to the same provider. Provider separation and recognizable different concrete model families are both required; an override does not manufacture independence.
216
+ - Tester only repeats the Implementer’s asserted pass count without executing or reading evidence.
217
+
218
+ ### 5.3 Conditional roles
219
+
220
+ - Security is inserted for auth, payment, PII, secrets, permissions, public API and deployment-risk signals.
221
+ - Release is inserted only when merge, migration, deployment or rollback is in scope.
222
+ - Observer is post-release/read-only and should not receive project-write permission.
223
+ - Director is invoked only when policy or reviewer/architect conclusions conflict; it is not in every pipeline.
224
+
225
+ ## 6. Fallback policy
226
+
227
+ Fallback may react only to observed conditions:
228
+ - CLI not installed.
229
+ - Provider disabled by project policy.
230
+ - Authentication explicitly observed as unavailable.
231
+ - Non-interactive dispatch failed with a structured reason.
232
+ - A verified official adapter reports capacity unavailable.
233
+ - Agent is at its configured concurrency limit.
234
+
235
+ Fallback must not react to guesses about model intelligence, entitlement, account tier or remaining quota.
236
+
237
+ Fail-closed conditions:
238
+ - Candidate fallback has a different Role.
239
+ - Candidate requires a higher permission tier.
240
+ - High-risk Reviewer fallback loses provider independence.
241
+ - Agent config or routing store is corrupt.
242
+ - Required file scope is missing for a write task.
243
+ - Exact-file lease preflight conflicts.
244
+
245
+ Every fallback result should include:
246
+
247
+ ```json
248
+ {
249
+ "fromAgent": "backend-worker-01",
250
+ "toAgent": "backend-worker-02",
251
+ "reasonCode": "provider_disabled",
252
+ "observed": true,
253
+ "permissionsPreserved": true,
254
+ "rolePreserved": true,
255
+ "reviewerIndependencePreserved": null,
256
+ "executed": false
257
+ }
258
+ ```
259
+
260
+ ## 7. Context and token control
261
+
262
+ The Orchestrator is potentially the most expensive role because it can repeatedly ingest every worker’s context. The default report path must therefore use a bounded envelope instead of full source files.
263
+
264
+ ```json
265
+ {
266
+ "task": "T-XXXX",
267
+ "agent": "backend-worker-01",
268
+ "status": "completed",
269
+ "changedFiles": ["src/example.ts"],
270
+ "summary": "bounded implementation summary",
271
+ "tests": { "passed": 12, "failed": 0, "command": "npm test -- example" },
272
+ "issues": [],
273
+ "evidence": ["commit-or-diff-reference"],
274
+ "contextTruncated": false
275
+ }
276
+ ```
277
+
278
+ Role-specific context policy:
279
+ - Router: request text plus minimal project metadata.
280
+ - Architect: project boundaries, contracts and dependency graph; no implementation output by default.
281
+ - Orchestrator: task graph and bounded reports; source only on demand.
282
+ - Implementer: allowed files, relevant contract and done-when.
283
+ - Tester: target behavior, test entry points, logs and changed files.
284
+ - Reviewer: request, architecture, diff and executed-test evidence.
285
+ - Release: release checklist, migrations, gate status and rollback contract.
286
+
287
+ Tests should measure that adding more Worker output does not linearly inject full source into the Orchestrator prompt.
288
+
289
+ ## 8. Exact-file lease integration
290
+
291
+ Before a mutating Agent is dispatched:
292
+ 1. The task must name exact allowed files.
293
+ 2. The Agent must have a stable session key.
294
+ 3. Leerness checks and acquires short TTL leases for those files.
295
+ 4. Any peer conflict rejects dispatch synchronously with owner/session/expiry evidence.
296
+ 5. The Agent report lists the actually changed files.
297
+ 6. Files changed outside the lease set become scope-creep evidence.
298
+ 7. Leases are released after accepted report or expire automatically.
299
+
300
+ This remains advisory. Leerness does not claim it can prevent a user, IDE or unintegrated process from editing the file.
301
+
302
+ ## 9. Proposed surfaces
303
+
304
+ These names are candidates, not yet public commitments.
305
+
306
+ CLI:
307
+ - `leerness role-definitions list|show|validate`
308
+ - `leerness agents instances list|show|validate`
309
+ - `leerness routing policy show|validate|plan`
310
+ - Existing `roles` commands remain compatibility assignment commands.
311
+ - Existing `agents route` remains suggestion/confirmation until v2 execution is separately approved.
312
+
313
+ MCP:
314
+ - Separate read-only schema/snapshot tools from safe-write assignment tools.
315
+ - `additionalProperties: false` on new input schemas.
316
+ - Permission tiers must match CLI mutation classification.
317
+
318
+ UI:
319
+ - First release is read-only.
320
+ - Show Provider, Role, Agent, Routing, Session, Lease, Task, Review and Gate on one snapshot.
321
+ - Later configuration writes require schema validation, diff preview and rollback.
322
+
323
+ ## 10. Acceptance test matrix
324
+
325
+ ### Schema and migration
326
+ - Valid v1 `agent-roles.json` produces deterministic v2 Agent projections.
327
+ - Migration is byte-preserving on refusal/failure.
328
+ - Repeated migration is idempotent.
329
+ - Corrupt v1/v2 stores fail closed and remain byte-exact.
330
+ - Unknown fields and unsupported versions are distinct machine errors.
331
+ - Original v1 canonical IDs round-trip; later alias-like legacy custom keys remain custom and round-trip without semantic rewriting.
332
+
333
+ ### Agent and routing
334
+ - Multiple implementers on one model retain distinct IDs and sessions.
335
+ - Tiny (UI label: simple), normal, high-risk and review-only routes are deterministic.
336
+ - Suggestion executes zero provider processes.
337
+ - High-risk route rejects missing Architect/Tester/Reviewer assignments.
338
+ - High-risk route rejects non-independent Reviewer.
339
+ - Fallback preserves role and permissions.
340
+ - Unknown availability does not trigger speculative fallback.
341
+
342
+ ### Coordination and evidence
343
+ - Mutating dispatch without exact files is rejected.
344
+ - Lease conflict blocks only the conflicting Agent, not read-only review.
345
+ - Changed files outside the lease set are surfaced.
346
+ - Tester execution and Reviewer verdict are stored separately.
347
+ - Done remains impossible without required evidence and gate policy.
348
+
349
+ ### Read-only and privacy
350
+ - Schema/list/snapshot calls create no workspace/cache/telemetry files.
351
+ - Provider credentials, account identity, raw chat text and hidden model state are absent.
352
+ - English/Korean human output and canonical JSON remain consistent.
353
+
354
+ ## 11. Non-goals for the first implementation
355
+
356
+ - YAML as canonical persistence.
357
+ - Silent automatic paid-model calls.
358
+ - Autonomous merge/deploy.
359
+ - Directory-wide inferred ownership or ambient collision warnings.
360
+ - Claiming exact quota without a verified official adapter.
361
+ - Replacing external agent CLIs with a new Leerness execution engine.
362
+
363
+ ## 12. Decisions frozen for the schema foundation
364
+
365
+ 1. Persisted compatibility IDs remain canonical: `commander`, `coder`, `dispatcher`, `reviewer`, `architect`, `designer`, and `debugger`. `orchestrator` and `implementer` are input/display aliases, not silent persisted rewrites. New role IDs are additive.
366
+ 2. The v2 store filenames are `role-definitions.json`, `agent-instances.json`, and `routing-policy.json`. `agent-roles.json` remains the legacy compatibility assignment store.
367
+ 3. Role definitions support built-ins plus strict, narrow project definitions/overrides. Provider and model IDs are forbidden from Role definitions.
368
+ 4. Fallback chains reference Agent IDs only. Provider/model templates are rejected because they would bypass Role and permission contracts.
369
+ 5. The first integrated visualization will extend the existing read-only dashboard snapshot rather than create another state authority.
370
+ 6. Configuration UI is deferred until schema validation, migration, diff preview, rollback, and execution permission boundaries are stable.
371
+
372
+ ## 13. Implemented schema foundation
373
+
374
+ `lib/role-agent-schema.js` is a zero-dependency, side-effect-free CommonJS module. Requiring or calling its validation/projection functions does not read or write files, inspect environment credentials, spawn providers, call a clock, or dispatch work.
375
+
376
+ Implemented contracts:
377
+ - Strict v2 validation for Role definitions, Agent instances, Routing policy, and the cross-document bundle.
378
+ - Distinct errors for invalid JSON, invalid shape, unknown fields, unsupported schema versions, and alias collisions.
379
+ - Deterministic legacy projection with one stable Agent per legacy role assignment.
380
+ - Reverse projection into a supplied legacy document while preserving the original legacy role key and unknown top-level/per-role fields.
381
+ - Existing forced custom legacy role keys, including keys that are not valid v2 IDs, receive deterministic generated v2 IDs and conservative read-only Role definitions. No write authority is inferred.
382
+ - `null` token budgets remain unknown; they are not converted to zero or unlimited.
383
+ - Multiple Agents may share a Role/provider/model while retaining distinct Agent IDs.
384
+ - Cross-document rejection of missing fallback targets, different-Role fallback, self-fallback, fallback cycles, missing Role inheritance targets, Role inheritance cycles, unknown Agent/Pipeline roles, and weakened tiny/normal/high-risk minimum requirements.
385
+ - Tiny requires verify-claim and write leases; normal additionally requires independent review and gate; high-risk additionally requires Architect and human approval.
386
+ - Assignment coverage is reported as `assignmentReady`/`assignmentGaps` with `providerReadinessChecked: false`; provider readiness remains a separate observation surface.
387
+
388
+ `scripts/role-agent-schema-probe.js` exercises an adversarial matrix, including an existing-CLI compatibility fixture proving that `roles list --json` still reads a valid legacy file without executing a provider and without changing the legacy bytes.
389
+
390
+ The probe is wired into `test`, `test:core`, `test:fast`, and the dedicated `test:role-agent-schema` script.
391
+
392
+ ## 14. Implemented legacy runtime compatibility guard
393
+
394
+ The v2 documents remain inactive, but the existing legacy runtime now has a bounded, fail-closed authority boundary:
395
+
396
+ - `.leerness/agent-roles.json` remains schema version 1. Compatible `primary`, `candidates`, `fallbackPolicy`, and `requirements` fields are retained as legacy extension fields; they do not turn this file into a fourth v2 store.
397
+ - `roles validate` observes missing/valid/invalid state and a read-only v2 projection without rewriting source bytes or checking provider readiness.
398
+ - Every role read/write/route/dispatch rejects corrupt, empty, invalid-UTF-8, unsupported-schema, malformed, oversized, linked, or non-regular legacy stores before provider execution.
399
+ - `agents resolve|fallback` and role-bound `dispatch` use explicit fallback choices. A choice is committed only if both the legacy store content revision and the semantic availability revision still match the resolution snapshot.
400
+ - Invalid fallback presets, invisible approvers, unapproved high-risk tier downgrades, stale policy snapshots, and unproven high-risk reviewer independence fail closed.
401
+ - Provider-wide and exact-model observations share ledger order; the newest applicable value wins for each axis, so a newer provider-wide denial overrides an older exact-model allow.
402
+ - Role-bound `multi --execute` and `bench` are rejected because provider-default fan-out cannot prove one selected model contract. No automatic fallback or paid model invocation was introduced.
403
+ - Terminal execution/review/validation records require attributable task, attempt, executor, evidence, and applicable parent links; duplicate terminal attempts are rejected under the ledger lock.
404
+
405
+ ## 15. Remaining before v2 runtime migration
406
+
407
+ - Add an explicit, atomic migration command that writes the three v2 stores only after validation, lock acquisition, preview/confirmation, and rollback preparation.
408
+ - Define the compatibility-window write rule for updating legacy and v2 projections under one lock.
409
+ - Add dedicated read-only CLI/MCP validation surfaces for the three native v2 documents; the current `roles validate` projection covers only legacy input.
410
+ - Re-run installed-package, full regression, multi-runtime, and independent adversarial review before any public runtime activation.
411
+ - Keep automatic fallback, model invocation, configuration UI, and dashboard writes disabled until their later milestones.