overlord-cli 0.2605111118.0 → 0.2605111338.0
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 +1 -1
- package/bin/_cli/protocol.mjs +173 -1
- package/package.json +1 -1
- package/plugins/claude/skills/overlord-ticket/SKILL.md +19 -11
- package/plugins/cursor/skills/overlord-ticket/SKILL.md +114 -9
- package/plugins/overlord/scripts/overlord-mcp.mjs +46 -33
- package/plugins/overlord/skills/overlord-ticket/SKILL.md +41 -30
package/README.md
CHANGED
|
@@ -119,7 +119,7 @@ Agents can find docs here: https://www.ovld.ai/docs/for-agents
|
|
|
119
119
|
- `permission-request` - notify Overlord that the agent is requesting tool permission
|
|
120
120
|
- `read-context` - read shared persistent context for this ticket
|
|
121
121
|
- `write-context` - write shared persistent context for future sessions
|
|
122
|
-
- `deliver` -
|
|
122
|
+
- `deliver` - create a local JJ/Git checkpoint when available, send artifacts/rationales, and move the ticket to review
|
|
123
123
|
- `attachment-prepare-upload` - get a signed upload URL for an objective attachment
|
|
124
124
|
- `attachment-finalize-upload` - finalize an uploaded objective attachment row after storage upload
|
|
125
125
|
- `attachment-download-url` - get a signed download URL for an existing objective attachment
|
package/bin/_cli/protocol.mjs
CHANGED
|
@@ -359,6 +359,164 @@ async function resolveSnapshotContext(flags) {
|
|
|
359
359
|
return null;
|
|
360
360
|
}
|
|
361
361
|
|
|
362
|
+
/**
|
|
363
|
+
* Shallow-merge snapshot metadata: launch/env context first, then deliver payload
|
|
364
|
+
* (payload wins on duplicate keys) so agents can add jj ids without losing workspace
|
|
365
|
+
* paths from OVERLORD_SNAPSHOT_JSON.
|
|
366
|
+
* @param {Record<string, unknown> | null | undefined} fromEnvOrFlags
|
|
367
|
+
* @param {Record<string, unknown> | null | undefined} fromPayload
|
|
368
|
+
* @returns {Record<string, unknown> | null}
|
|
369
|
+
*/
|
|
370
|
+
function mergeDeliverSnapshot(fromEnvOrFlags, fromPayload) {
|
|
371
|
+
const base =
|
|
372
|
+
fromEnvOrFlags && typeof fromEnvOrFlags === 'object' && !Array.isArray(fromEnvOrFlags)
|
|
373
|
+
? { ...fromEnvOrFlags }
|
|
374
|
+
: {};
|
|
375
|
+
const overlay =
|
|
376
|
+
fromPayload && typeof fromPayload === 'object' && !Array.isArray(fromPayload)
|
|
377
|
+
? { ...fromPayload }
|
|
378
|
+
: {};
|
|
379
|
+
const merged = { ...base, ...overlay };
|
|
380
|
+
return Object.keys(merged).length > 0 ? merged : null;
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
function runLocalCommand(command, args, options = {}) {
|
|
384
|
+
return execFileSync(command, args, {
|
|
385
|
+
cwd: options.cwd,
|
|
386
|
+
encoding: 'utf8',
|
|
387
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
388
|
+
timeout: options.timeoutMs ?? 60000,
|
|
389
|
+
maxBuffer: 10 * 1024 * 1024
|
|
390
|
+
});
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
function commandSucceeds(command, args, cwd) {
|
|
394
|
+
try {
|
|
395
|
+
runLocalCommand(command, args, { cwd, timeoutMs: 15000 });
|
|
396
|
+
return true;
|
|
397
|
+
} catch {
|
|
398
|
+
return false;
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
function detectLocalCheckpointBackend(workspacePath, preference) {
|
|
403
|
+
if (!workspacePath || !fs.existsSync(workspacePath)) return null;
|
|
404
|
+
if (preference === 'jj') return 'jj';
|
|
405
|
+
if (preference === 'git') return 'git';
|
|
406
|
+
if (
|
|
407
|
+
fs.existsSync(path.join(workspacePath, '.jj')) ||
|
|
408
|
+
commandSucceeds('jj', ['--repository', workspacePath, 'root'], workspacePath)
|
|
409
|
+
) {
|
|
410
|
+
return 'jj';
|
|
411
|
+
}
|
|
412
|
+
if (commandSucceeds('git', ['-C', workspacePath, 'rev-parse', '--show-toplevel'], workspacePath)) {
|
|
413
|
+
return 'git';
|
|
414
|
+
}
|
|
415
|
+
return null;
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
function createLocalDeliveryCheckpoint(flags, snapshot) {
|
|
419
|
+
if (flags['skip-checkpoint']) return null;
|
|
420
|
+
|
|
421
|
+
const preference = String(flags['checkpoint-backend'] ?? 'auto').trim();
|
|
422
|
+
if (!['auto', 'jj', 'git'].includes(preference)) {
|
|
423
|
+
throw new Error('--checkpoint-backend must be one of: auto, jj, git');
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
const workspacePath = path.resolve(
|
|
427
|
+
String(snapshot?.workspacePath ?? process.env.OVERLORD_WORKSPACE_PATH ?? process.cwd())
|
|
428
|
+
);
|
|
429
|
+
if (!fs.existsSync(workspacePath)) return null;
|
|
430
|
+
|
|
431
|
+
const backend = detectLocalCheckpointBackend(workspacePath, preference);
|
|
432
|
+
if (!backend) return null;
|
|
433
|
+
|
|
434
|
+
if (backend === 'jj') {
|
|
435
|
+
try {
|
|
436
|
+
runLocalCommand('jj', ['--repository', workspacePath, 'util', 'snapshot'], {
|
|
437
|
+
cwd: workspacePath
|
|
438
|
+
});
|
|
439
|
+
const commit = runLocalCommand(
|
|
440
|
+
'jj',
|
|
441
|
+
['--repository', workspacePath, 'log', '-r', '@', '-T', 'change_id ++ " " ++ commit_id'],
|
|
442
|
+
{ cwd: workspacePath }
|
|
443
|
+
);
|
|
444
|
+
const operation = runLocalCommand(
|
|
445
|
+
'jj',
|
|
446
|
+
[
|
|
447
|
+
'--repository',
|
|
448
|
+
workspacePath,
|
|
449
|
+
'op',
|
|
450
|
+
'log',
|
|
451
|
+
'--at-op=@',
|
|
452
|
+
'--ignore-working-copy',
|
|
453
|
+
'-n',
|
|
454
|
+
'1',
|
|
455
|
+
'-T',
|
|
456
|
+
'id'
|
|
457
|
+
],
|
|
458
|
+
{ cwd: workspacePath }
|
|
459
|
+
);
|
|
460
|
+
const diffStat = runLocalCommand('jj', ['--repository', workspacePath, 'diff', '--stat'], {
|
|
461
|
+
cwd: workspacePath
|
|
462
|
+
});
|
|
463
|
+
const [jjChangeId = null, jjCommitId = null] = commit.trim().split(/\s+/, 2);
|
|
464
|
+
return {
|
|
465
|
+
checkpoint: {
|
|
466
|
+
diffStat: diffStat.trim() || null,
|
|
467
|
+
kind: 'delivery'
|
|
468
|
+
},
|
|
469
|
+
snapshot: {
|
|
470
|
+
backend: 'jj',
|
|
471
|
+
workspacePath,
|
|
472
|
+
workspaceName: snapshot?.workspaceName ?? path.basename(workspacePath),
|
|
473
|
+
jjChangeId,
|
|
474
|
+
jjCommitId,
|
|
475
|
+
jjOperationId: operation.trim() || null,
|
|
476
|
+
diffStat: diffStat.trim() || null
|
|
477
|
+
}
|
|
478
|
+
};
|
|
479
|
+
} catch (error) {
|
|
480
|
+
throw new Error(
|
|
481
|
+
`Failed to create JJ delivery checkpoint in ${workspacePath}: ${
|
|
482
|
+
error instanceof Error ? error.message : String(error)
|
|
483
|
+
}\nRe-run with --skip-checkpoint only if you intentionally want to deliver without local JJ provenance.`
|
|
484
|
+
);
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
if (preference === 'jj') {
|
|
489
|
+
throw new Error(`JJ checkpoint requested, but ${workspacePath} is not a JJ repository.`);
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
try {
|
|
493
|
+
const gitCommitId = runLocalCommand('git', ['-C', workspacePath, 'rev-parse', 'HEAD'], {
|
|
494
|
+
cwd: workspacePath
|
|
495
|
+
}).trim();
|
|
496
|
+
const diffStat = runLocalCommand('git', ['-C', workspacePath, 'diff', '--stat', 'HEAD'], {
|
|
497
|
+
cwd: workspacePath
|
|
498
|
+
}).trim();
|
|
499
|
+
return {
|
|
500
|
+
checkpoint: {
|
|
501
|
+
diffStat: diffStat || null,
|
|
502
|
+
kind: 'delivery'
|
|
503
|
+
},
|
|
504
|
+
snapshot: {
|
|
505
|
+
backend: 'git',
|
|
506
|
+
workspacePath,
|
|
507
|
+
workspaceName: snapshot?.workspaceName ?? path.basename(workspacePath),
|
|
508
|
+
gitCommitId: gitCommitId || null,
|
|
509
|
+
diffStat: diffStat || null
|
|
510
|
+
}
|
|
511
|
+
};
|
|
512
|
+
} catch {
|
|
513
|
+
if (preference === 'git') {
|
|
514
|
+
throw new Error(`Git checkpoint requested, but metadata could not be read in ${workspacePath}.`);
|
|
515
|
+
}
|
|
516
|
+
return null;
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
|
|
362
520
|
function normalizeRepoRelativeFilePath(filePath, repoRoot) {
|
|
363
521
|
if (typeof filePath !== 'string') return null;
|
|
364
522
|
|
|
@@ -853,7 +1011,14 @@ async function protocolDeliver(args) {
|
|
|
853
1011
|
|
|
854
1012
|
const changeRationales =
|
|
855
1013
|
deliverPayload?.changeRationales ?? (await resolveChangeRationales(flags));
|
|
856
|
-
|
|
1014
|
+
let snapshot = mergeDeliverSnapshot(
|
|
1015
|
+
await resolveSnapshotContext(flags),
|
|
1016
|
+
deliverPayload?.snapshot ?? null
|
|
1017
|
+
);
|
|
1018
|
+
const checkpointResult = createLocalDeliveryCheckpoint(flags, snapshot);
|
|
1019
|
+
if (checkpointResult) {
|
|
1020
|
+
snapshot = mergeDeliverSnapshot(snapshot, checkpointResult.snapshot);
|
|
1021
|
+
}
|
|
857
1022
|
validateDeliverFileChanges(flags, changeRationales);
|
|
858
1023
|
|
|
859
1024
|
const body = {
|
|
@@ -861,6 +1026,9 @@ async function protocolDeliver(args) {
|
|
|
861
1026
|
ticketId,
|
|
862
1027
|
summary,
|
|
863
1028
|
artifacts,
|
|
1029
|
+
...(checkpointResult?.checkpoint
|
|
1030
|
+
? { checkpoint: { ...checkpointResult.checkpoint, summary } }
|
|
1031
|
+
: {}),
|
|
864
1032
|
...(snapshot ? { snapshot } : {}),
|
|
865
1033
|
...(changeRationales.length > 0 ? { changeRationales } : {})
|
|
866
1034
|
};
|
|
@@ -1621,10 +1789,13 @@ deliver:
|
|
|
1621
1789
|
--artifacts-file <path|->
|
|
1622
1790
|
--change-rationales-json <json>
|
|
1623
1791
|
--change-rationales-file <path|->
|
|
1792
|
+
--checkpoint-backend <auto|jj|git> Backend for the local delivery checkpoint (default: auto)
|
|
1793
|
+
--skip-checkpoint Bypass automatic local checkpoint creation
|
|
1624
1794
|
--skip-file-change-check Bypass local git vs changeRationales validation
|
|
1625
1795
|
Notes:
|
|
1626
1796
|
Use --payload-file - to read the full delivery JSON from stdin without creating a scratch file.
|
|
1627
1797
|
Do not combine --payload-file with --artifacts-json/--artifacts-file or change-rationale flags.
|
|
1798
|
+
Deliver creates a local checkpoint before the API request when the current workspace is JJ- or Git-managed.
|
|
1628
1799
|
In a git workspace, deliver validates that changed files are represented by changeRationales unless skipped.
|
|
1629
1800
|
|
|
1630
1801
|
prompt:
|
|
@@ -1761,6 +1932,7 @@ Examples:
|
|
|
1761
1932
|
ovld protocol deliver --session-key <key> --ticket-id <ticket_id> --summary "Done" --artifacts-file ./artifacts.json
|
|
1762
1933
|
ovld protocol deliver --session-key <key> --ticket-id <ticket_id> --payload-file ./deliver.json
|
|
1763
1934
|
ovld protocol deliver --session-key <key> --ticket-id <ticket_id> --payload-file -
|
|
1935
|
+
ovld protocol deliver --session-key <key> --ticket-id <ticket_id> --summary "Done" --checkpoint-backend jj
|
|
1764
1936
|
ovld protocol deliver --session-key <key> --ticket-id <ticket_id> --summary "Done" --skip-file-change-check
|
|
1765
1937
|
ovld protocol deliver --session-key <key> --ticket-id <ticket_id> --summary "Done" --timeout 60000
|
|
1766
1938
|
`);
|
package/package.json
CHANGED
|
@@ -65,7 +65,7 @@ ovld protocol deliver --session-key <sessionKey> \
|
|
|
65
65
|
--change-rationales-json '[{"label":"Short reviewer title","file_path":"path/to/file.ts","summary":"What changed.","why":"Why it changed.","impact":"Behavioral impact.","hunks":[{"header":"@@ -10,6 +10,14 @@"}]}]'
|
|
66
66
|
```
|
|
67
67
|
|
|
68
|
-
For larger delivery payloads, prefer `--payload-file -` and stream the full JSON on stdin so no scratch file needs to be created or removed. If you use `--payload-file`, `--artifacts-file`, or `--change-rationales-file` with a real path, treat that file as ephemeral scratch data outside the repository and remove it after delivery.
|
|
68
|
+
`ovld protocol deliver` automatically creates a local checkpoint before the API request when the workspace is JJ- or Git-managed; use `--skip-checkpoint` only when intentionally bypassing local provenance. For larger delivery payloads, prefer `--payload-file -` and stream the full JSON on stdin so no scratch file needs to be created or removed. If you use `--payload-file`, `--artifacts-file`, or `--change-rationales-file` with a real path, treat that file as ephemeral scratch data outside the repository and remove it after delivery.
|
|
69
69
|
|
|
70
70
|
## Mode 2: Asked From Chat To Use Overlord
|
|
71
71
|
|
|
@@ -73,14 +73,15 @@ Use this mode when the conversation starts normally and the user asks Claude to
|
|
|
73
73
|
|
|
74
74
|
1. If the user wants to create tickets (and does not ask to start execution), run `ovld protocol create --agent claude-code --objective "..."`.
|
|
75
75
|
- When `--session-key` and `--ticket-id` are provided, it creates a follow-up draft.
|
|
76
|
-
- When session flags are omitted, it resolves the project by matching current working directory (or `--working-directory`) to
|
|
77
|
-
2. Default to `create` for new tickets. Only use `/overlord:
|
|
78
|
-
`
|
|
76
|
+
- When session flags are omitted, it resolves the project by matching current working directory (or `--working-directory`) to Overlord `local_working_directory`, then creates a standalone draft.
|
|
77
|
+
2. Default to `create` for new tickets. Only use `/overlord:prompt` or `ovld protocol prompt --agent claude-code --objective "..."` when the user explicitly asks to create and execute immediately.
|
|
78
|
+
`prompt` creates the ticket in `execute` status and attaches immediately.
|
|
79
79
|
3. If the user already has a ticket ID and only wants to inspect it, use `/overlord:load` or run `ovld protocol load-context --ticket-id <ticket_id>`.
|
|
80
80
|
4. If the user wants to route the current session onto an existing ticket by ID, use `/overlord:connect` or run `ovld protocol connect --ticket-id <ticket_id>`.
|
|
81
|
-
5. If the user wants to
|
|
82
|
-
6. If
|
|
83
|
-
7.
|
|
81
|
+
5. If the user wants to establish a persistent session with a ticket by ID, use `/overlord:attach` or run `ovld protocol attach --ticket-id <ticket_id>`.
|
|
82
|
+
6. If the user wants to find a ticket but does not know the ID, use `ovld attach` for interactive ticket search and agent launch, or run `ovld protocol search-tickets --query "..." --status next-up,execute` and ask the user to confirm.
|
|
83
|
+
7. If you need other lifecycle commands or flags, run `ovld protocol help` and use the real subcommand list instead of guessing.
|
|
84
|
+
8. Once you attach to a ticket, switch back to Mode 1 and follow the full ticket lifecycle.
|
|
84
85
|
|
|
85
86
|
## Change Rationales
|
|
86
87
|
|
|
@@ -108,7 +109,7 @@ Record only meaningful behavioral changes. Skip formatting-only noise.
|
|
|
108
109
|
|
|
109
110
|
When creating tickets from within a repository:
|
|
110
111
|
- Prefer `create` by default for draft ticket creation.
|
|
111
|
-
- Use `
|
|
112
|
+
- Use `prompt` only when the user explicitly asks to start execution immediately.
|
|
112
113
|
- Both commands can resolve the project from the current working directory; use `--working-directory` to override.
|
|
113
114
|
|
|
114
115
|
```bash
|
|
@@ -116,7 +117,7 @@ ovld protocol create --agent claude-code --objective "Capture follow-up work fro
|
|
|
116
117
|
```
|
|
117
118
|
|
|
118
119
|
```bash
|
|
119
|
-
ovld protocol
|
|
120
|
+
ovld protocol prompt --agent claude-code --objective "Implement feature X" --priority medium
|
|
120
121
|
```
|
|
121
122
|
|
|
122
123
|
To inspect project resolution explicitly:
|
|
@@ -148,6 +149,14 @@ ovld protocol attachment-download-url --session-key <sessionKey> --ticket-id $TI
|
|
|
148
149
|
|
|
149
150
|
The `attach` and `load-context` responses already include `attachments` and `objectives` arrays — use those for `<attachment-id>` and `<objective-id>` values. Run `attachment-list` mid-session if new files have been uploaded since attach.
|
|
150
151
|
|
|
152
|
+
## Defaults And Notes
|
|
153
|
+
|
|
154
|
+
- API requires `agentIdentifier` and `connectionMethod` on attach/connect/prompt. The CLI defaults them to `claude-code`/`cli`; the MCP tool defaults to `mcp`. Override with `--agent` / `--method` when calling from a different runtime.
|
|
155
|
+
- `permission-request` is invoked by the Claude Code permission hook installed by the bundle. Agents do not normally call it directly.
|
|
156
|
+
- `record_change_rationales` (MCP) and `ovld protocol record-change-rationales` (CLI) both write to the same `file_changes` table. The dedicated CLI route is `POST /api/protocol/record-change-rationales`.
|
|
157
|
+
- Objective attachment tools follow the `<verb>_<noun>` MCP naming: `list_attachments`, `prepare_attachment_upload`, `finalize_attachment_upload`, `get_attachment_download_url`, `upload_attachment_file`. CLI commands use `attachment-*` and require `--objective-id` for upload/finalize.
|
|
158
|
+
- "Artifacts" in `deliver` are the structured records an agent submits at delivery time (next_steps, test_results, migration, decision, note, url) — not user-uploaded files. Files attached by users live on objectives via the attachment tools above.
|
|
159
|
+
|
|
151
160
|
## Rules
|
|
152
161
|
|
|
153
162
|
- Always attach first and always deliver last once you are on a ticket.
|
|
@@ -155,10 +164,9 @@ The `attach` and `load-context` responses already include `attachments` and `obj
|
|
|
155
164
|
- Do not invent protocol subcommands. Use `ovld protocol help` when unsure.
|
|
156
165
|
- The `summary` in deliver is what the PM reads first, so write it as a narrative, not a command list.
|
|
157
166
|
- Use `write-context` for facts a future agent session should know.
|
|
158
|
-
- If `ovld` reports `OVERLORD_URL` is unreachable, request permission escalation or network access before retrying.
|
|
159
167
|
- If a protocol or MCP call fails with auth/session errors, run `ovld auth repair` yourself before asking the user to log in again or proceed without Overlord updates.
|
|
160
168
|
- If you must run `ovld auth login`, always include `--organization-id <id>` — use the organization ID from the ticket prompt context to select the organization non-interactively and avoid a blocking TTY prompt.
|
|
161
169
|
- Do not add or commit changes unless the user explicitly asks you to commit.
|
|
162
170
|
- Delivery is the concluding step. After delivering, stop unless the user follows up or the ticket is reopened.
|
|
163
171
|
|
|
164
|
-
<!-- version: 0.
|
|
172
|
+
<!-- version: 0.4.5 -->
|
|
@@ -17,17 +17,99 @@ Use this skill whenever Cursor needs to work with Overlord, whether the session
|
|
|
17
17
|
6. If blocked, call `ovld protocol ask` and stop.
|
|
18
18
|
7. Deliver last with `ovld protocol deliver`, including `changeRationales` for each meaningful behavioral file change.
|
|
19
19
|
|
|
20
|
+
### Mode 1 Reference
|
|
21
|
+
|
|
22
|
+
Attach:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
ovld protocol attach --ticket-id $TICKET_ID
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Update:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
ovld protocol update --session-key <sessionKey> --ticket-id $TICKET_ID --summary "What you did and why." --phase execute
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Supported `--phase` values:
|
|
35
|
+
- `draft`
|
|
36
|
+
- `execute`
|
|
37
|
+
- `review`
|
|
38
|
+
- `deliver`
|
|
39
|
+
- `complete`
|
|
40
|
+
- `blocked`
|
|
41
|
+
- `cancelled`
|
|
42
|
+
|
|
43
|
+
Event types:
|
|
44
|
+
- `update` for standard progress updates
|
|
45
|
+
- `user_follow_up` for human follow-up messages after the initial ticket
|
|
46
|
+
- `alert` for warnings or non-blocking issues
|
|
47
|
+
|
|
48
|
+
Ask when blocked:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
ovld protocol ask --session-key <sessionKey> --ticket-id $TICKET_ID --question "Specific question for the PM."
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Deliver:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
ovld protocol deliver --session-key <sessionKey> \
|
|
58
|
+
--ticket-id $TICKET_ID \
|
|
59
|
+
--summary "Narrative: what you did, next steps." \
|
|
60
|
+
--artifacts-json '[{"type":"next_steps","label":"Next steps","content":"..."}]' \
|
|
61
|
+
--change-rationales-json '[{"label":"Short reviewer title","file_path":"path/to/file.ts","summary":"What changed.","why":"Why it changed.","impact":"Behavioral impact.","hunks":[{"header":"@@ -10,6 +10,14 @@"}]}]'
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
`ovld protocol deliver` automatically creates a local checkpoint before the API request when the workspace is JJ- or Git-managed; use `--skip-checkpoint` only when intentionally bypassing local provenance. For larger delivery payloads, prefer `--payload-file -` and stream the full JSON on stdin so no scratch file needs to be created or removed.
|
|
65
|
+
|
|
20
66
|
## Mode 2: Asked From Chat To Use Overlord
|
|
21
67
|
|
|
22
68
|
1. If the user wants to create tickets (and does not ask to start execution), use `/create` or run `ovld protocol create --agent cursor --objective "..."`.
|
|
23
|
-
|
|
69
|
+
- When `--session-key` and `--ticket-id` are provided, it creates a follow-up draft.
|
|
70
|
+
- When session flags are omitted, it resolves the project by matching current working directory (or `--working-directory`) to Overlord `local_working_directory`, then creates a standalone draft.
|
|
71
|
+
2. Default to `create` for new tickets. Only use `/prompt` or `ovld protocol prompt --agent cursor --objective "..."` when the user explicitly asks to create and execute immediately.
|
|
24
72
|
3. If the user already has a ticket ID and only wants to inspect it, use `/load` or run `ovld protocol load-context --ticket-id <ticket_id>`.
|
|
25
73
|
4. If the user wants to route the current session onto an existing ticket by ID, use `/connect` or run `ovld protocol connect --ticket-id <ticket_id>`.
|
|
26
|
-
5. If the user wants to
|
|
27
|
-
6. If
|
|
28
|
-
7.
|
|
74
|
+
5. If the user wants to establish a persistent session with a ticket by ID, use `/attach` or run `ovld protocol attach --ticket-id <ticket_id>`.
|
|
75
|
+
6. If the user wants to find a ticket by keyword/status/project/creator/date, run `ovld protocol search-tickets --query "..." --status next-up,execute`.
|
|
76
|
+
7. If you need other lifecycle commands or flags, run `ovld protocol help` and use the real subcommand list instead of guessing.
|
|
77
|
+
8. Once you attach to a ticket, switch back to Mode 1 and follow the full ticket lifecycle.
|
|
78
|
+
|
|
79
|
+
## Change Rationales
|
|
80
|
+
|
|
81
|
+
Always include `changeRationales` when delivering. Optionally include them on updates during long-running work.
|
|
82
|
+
|
|
83
|
+
Before delivering, make sure every meaningful git-tracked file change is represented in `changeRationales`; do not send `file_changes` as an artifact.
|
|
29
84
|
|
|
30
|
-
|
|
85
|
+
```bash
|
|
86
|
+
ovld protocol record-change-rationales --session-key <sessionKey> --ticket-id $TICKET_ID \
|
|
87
|
+
--summary "Recorded rationale details for the latest code changes." --phase execute \
|
|
88
|
+
--change-rationales-json '[{"label":"Add backoff","file_path":"lib/api.ts","summary":"Added retry.","why":"Transient failures.","impact":"Retries 3x.","hunks":[{"header":"@@ -22,4 +22,18 @@"}]}]'
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
ovld protocol update --session-key <sessionKey> --ticket-id $TICKET_ID \
|
|
93
|
+
--summary "Added retry logic." --phase execute \
|
|
94
|
+
--change-rationales-json '[{"label":"Add backoff","file_path":"lib/api.ts","summary":"Added retry.","why":"Transient failures.","impact":"Retries 3x.","hunks":[{"header":"@@ -22,4 +22,18 @@"}]}]'
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Record only meaningful behavioral changes. Skip formatting-only noise.
|
|
98
|
+
|
|
99
|
+
## Project Discovery And Ticket Creation
|
|
100
|
+
|
|
101
|
+
When creating tickets from within a repository:
|
|
102
|
+
- Prefer `create` by default for draft ticket creation.
|
|
103
|
+
- Use `prompt` only when the user explicitly asks to start execution immediately.
|
|
104
|
+
- Both commands resolve the project from the current working directory; use `--working-directory` to override or `--project-id` to be explicit.
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
ovld protocol create --agent cursor --objective "Capture follow-up work from this repository"
|
|
108
|
+
ovld protocol prompt --agent cursor --objective "Implement feature X" --priority medium
|
|
109
|
+
ovld protocol discover-project
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### Choosing `--execution-target`
|
|
31
113
|
|
|
32
114
|
Pass `--execution-target agent` or `--execution-target human` (default: `human`) when creating tickets.
|
|
33
115
|
|
|
@@ -36,14 +118,37 @@ Pass `--execution-target agent` or `--execution-target human` (default: `human`)
|
|
|
36
118
|
|
|
37
119
|
When in doubt, ask yourself: *can this be done entirely inside a terminal or browser by an AI without human intervention?* If yes → `agent`. If it requires a human to log in, decide, or act in the real world → `human`.
|
|
38
120
|
|
|
121
|
+
## Context And Artifacts
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
ovld protocol read-context --session-key <sessionKey> --ticket-id $TICKET_ID
|
|
125
|
+
ovld protocol write-context --session-key <sessionKey> --ticket-id $TICKET_ID --key "key" --value '"json-value"'
|
|
126
|
+
ovld protocol attachment-list --session-key <sessionKey> --ticket-id $TICKET_ID
|
|
127
|
+
ovld protocol attachment-upload-file --session-key <sessionKey> --ticket-id $TICKET_ID --objective-id <objective-id> --file ./spec.pdf --content-type application/pdf
|
|
128
|
+
ovld protocol attachment-download-url --session-key <sessionKey> --ticket-id $TICKET_ID --attachment-id <attachment-id>
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
The `attach` and `load-context` responses already include `attachments` and `objectives` arrays — use those for `<attachment-id>` and `<objective-id>` values. Run `attachment-list` mid-session if new files have been uploaded since attach.
|
|
132
|
+
|
|
133
|
+
Objective attachment uploads also expose two-step variants — `attachment-prepare-upload` and `attachment-finalize-upload` — for callers that need a signed URL directly. Prefer `attachment-upload-file` for one-shot uploads.
|
|
134
|
+
|
|
135
|
+
"Artifacts" in `deliver` are the structured records an agent submits at delivery time (next_steps, test_results, migration, decision, note, url) — not user-uploaded files.
|
|
136
|
+
|
|
137
|
+
## Defaults And Notes
|
|
138
|
+
|
|
139
|
+
- The Overlord API requires `agentIdentifier` and `connectionMethod` on attach/connect/prompt, but the CLI defaults them to `cursor`/`cli` (override with `--agent` / `--method`). The MCP tools default to `mcp`.
|
|
140
|
+
- `permission-request` is invoked by the installed permission hook; agents normally do not call it directly.
|
|
141
|
+
- The `record_change_rationales` MCP tool and `ovld protocol record-change-rationales` CLI both write to the same `file_changes` table; pick whichever fits your runtime.
|
|
142
|
+
|
|
39
143
|
## Rules
|
|
40
144
|
|
|
41
145
|
- Always attach first and always deliver last once you are on a ticket.
|
|
42
146
|
- Use `ovld protocol` commands, the plugin commands, and the MCP tool instead of ad hoc scripts.
|
|
43
147
|
- Do not invent protocol subcommands. Use `ovld protocol help` when unsure.
|
|
44
|
-
- If `ovld` reports `OVERLORD_URL` is unreachable, request permission escalation or network access before retrying.
|
|
45
|
-
- If a protocol or MCP call fails with auth/session errors, run `ovld auth repair` yourself before asking the user to log in again or proceed without Overlord updates.
|
|
46
148
|
- Include at least one progress update before delivering.
|
|
47
|
-
-
|
|
149
|
+
- The `summary` in deliver is what the PM reads first, so write it as a narrative, not a command list.
|
|
150
|
+
- If a protocol or MCP call fails with auth/session errors, run `ovld auth repair` yourself before asking the user to log in again or proceed without Overlord updates.
|
|
151
|
+
- If you must run `ovld auth login`, always include `--organization-id <id>` — use the organization ID from the ticket prompt context to select the organization non-interactively and avoid a blocking TTY prompt.
|
|
152
|
+
- Delivery is the concluding step. After delivering, stop unless the user follows up or the ticket is reopened.
|
|
48
153
|
|
|
49
|
-
<!-- version: 0.
|
|
154
|
+
<!-- version: 0.4.5 -->
|
|
@@ -49,22 +49,18 @@ const tools = [
|
|
|
49
49
|
inputSchema: {
|
|
50
50
|
type: 'object',
|
|
51
51
|
properties: {
|
|
52
|
-
ticket_id: { type: 'string', description: '
|
|
52
|
+
ticket_id: { type: 'string', description: 'Ticket identifier (e.g. 1:899). Also accepts UUID.' },
|
|
53
53
|
agent: { type: 'string' },
|
|
54
|
-
model: { type: 'string' },
|
|
55
54
|
method: { type: 'string' },
|
|
56
|
-
external_session_id: { type: ['string', 'null'] }
|
|
57
|
-
metadata: { type: 'object' }
|
|
55
|
+
external_session_id: { type: ['string', 'null'] }
|
|
58
56
|
},
|
|
59
57
|
required: ['ticket_id']
|
|
60
58
|
},
|
|
61
59
|
toCliFlags: args => ({
|
|
62
60
|
'ticket-id': args.ticket_id,
|
|
63
61
|
agent: args.agent,
|
|
64
|
-
model: args.model,
|
|
65
62
|
method: args.method,
|
|
66
|
-
'external-session-id': args.external_session_id
|
|
67
|
-
'metadata-json': args.metadata
|
|
63
|
+
'external-session-id': args.external_session_id
|
|
68
64
|
}),
|
|
69
65
|
subcommand: 'attach'
|
|
70
66
|
},
|
|
@@ -74,7 +70,7 @@ const tools = [
|
|
|
74
70
|
inputSchema: {
|
|
75
71
|
type: 'object',
|
|
76
72
|
properties: {
|
|
77
|
-
ticket_id: { type: 'string' },
|
|
73
|
+
ticket_id: { type: 'string', description: 'Ticket identifier (e.g. 1:899). Also accepts UUID.' },
|
|
78
74
|
agent: { type: 'string' },
|
|
79
75
|
method: { type: 'string' }
|
|
80
76
|
},
|
|
@@ -103,8 +99,8 @@ const tools = [
|
|
|
103
99
|
subcommand: 'load-context'
|
|
104
100
|
},
|
|
105
101
|
{
|
|
106
|
-
name: '
|
|
107
|
-
description: 'Create a
|
|
102
|
+
name: 'prompt_ticket',
|
|
103
|
+
description: 'Create a ticket and attach to it immediately.',
|
|
108
104
|
inputSchema: {
|
|
109
105
|
type: 'object',
|
|
110
106
|
properties: {
|
|
@@ -120,8 +116,6 @@ const tools = [
|
|
|
120
116
|
parent_session_key: { type: 'string' },
|
|
121
117
|
parent_ticket_id: { type: 'string' },
|
|
122
118
|
agent: { type: 'string' },
|
|
123
|
-
model: { type: 'string' },
|
|
124
|
-
metadata: { type: 'object' },
|
|
125
119
|
method: { type: 'string' }
|
|
126
120
|
},
|
|
127
121
|
required: ['objective']
|
|
@@ -139,11 +133,9 @@ const tools = [
|
|
|
139
133
|
'parent-session-key': args.parent_session_key,
|
|
140
134
|
'parent-ticket-id': args.parent_ticket_id,
|
|
141
135
|
agent: args.agent,
|
|
142
|
-
model: args.model,
|
|
143
|
-
'metadata-json': args.metadata,
|
|
144
136
|
method: args.method
|
|
145
137
|
}),
|
|
146
|
-
subcommand: '
|
|
138
|
+
subcommand: 'prompt'
|
|
147
139
|
},
|
|
148
140
|
{
|
|
149
141
|
name: 'post_update',
|
|
@@ -152,7 +144,7 @@ const tools = [
|
|
|
152
144
|
type: 'object',
|
|
153
145
|
properties: {
|
|
154
146
|
session_key: { type: 'string' },
|
|
155
|
-
ticket_id: { type: 'string' },
|
|
147
|
+
ticket_id: { type: 'string', description: 'Ticket identifier (e.g. 1:899). Also accepts UUID.' },
|
|
156
148
|
summary: { type: 'string' },
|
|
157
149
|
phase: { type: 'string', enum: ['draft', 'execute', 'review', 'deliver', 'complete', 'blocked', 'cancelled'] },
|
|
158
150
|
event_type: { type: 'string', enum: ['update', 'user_follow_up', 'alert'] },
|
|
@@ -183,7 +175,7 @@ const tools = [
|
|
|
183
175
|
type: 'object',
|
|
184
176
|
properties: {
|
|
185
177
|
session_key: { type: 'string' },
|
|
186
|
-
ticket_id: { type: 'string' },
|
|
178
|
+
ticket_id: { type: 'string', description: 'Ticket identifier (e.g. 1:899). Also accepts UUID.' },
|
|
187
179
|
summary: { type: 'string' },
|
|
188
180
|
phase: { type: 'string', enum: ['draft', 'execute', 'review', 'deliver', 'complete', 'blocked', 'cancelled'] },
|
|
189
181
|
change_rationales: { type: 'array' }
|
|
@@ -206,7 +198,7 @@ const tools = [
|
|
|
206
198
|
type: 'object',
|
|
207
199
|
properties: {
|
|
208
200
|
session_key: { type: 'string' },
|
|
209
|
-
ticket_id: { type: 'string' },
|
|
201
|
+
ticket_id: { type: 'string', description: 'Ticket identifier (e.g. 1:899). Also accepts UUID.' },
|
|
210
202
|
question: { type: 'string' },
|
|
211
203
|
phase: { type: 'string', enum: ['draft', 'execute', 'review', 'deliver', 'complete', 'blocked', 'cancelled'] },
|
|
212
204
|
payload: { type: 'object' }
|
|
@@ -229,7 +221,7 @@ const tools = [
|
|
|
229
221
|
type: 'object',
|
|
230
222
|
properties: {
|
|
231
223
|
session_key: { type: 'string' },
|
|
232
|
-
ticket_id: { type: 'string' },
|
|
224
|
+
ticket_id: { type: 'string', description: 'Ticket identifier (e.g. 1:899). Also accepts UUID.' },
|
|
233
225
|
query: { type: 'string' },
|
|
234
226
|
limit: { type: 'number' }
|
|
235
227
|
},
|
|
@@ -250,7 +242,7 @@ const tools = [
|
|
|
250
242
|
type: 'object',
|
|
251
243
|
properties: {
|
|
252
244
|
session_key: { type: 'string' },
|
|
253
|
-
ticket_id: { type: 'string' },
|
|
245
|
+
ticket_id: { type: 'string', description: 'Ticket identifier (e.g. 1:899). Also accepts UUID.' },
|
|
254
246
|
key: { type: 'string' },
|
|
255
247
|
value: {},
|
|
256
248
|
tags: { type: 'array', items: { type: 'string' } }
|
|
@@ -274,10 +266,26 @@ const tools = [
|
|
|
274
266
|
type: 'object',
|
|
275
267
|
properties: {
|
|
276
268
|
session_key: { type: 'string' },
|
|
277
|
-
ticket_id: { type: 'string' },
|
|
269
|
+
ticket_id: { type: 'string', description: 'Ticket identifier (e.g. 1:899). Also accepts UUID.' },
|
|
278
270
|
summary: { type: 'string' },
|
|
279
271
|
artifacts: { type: 'array' },
|
|
280
272
|
change_rationales: { type: 'array' },
|
|
273
|
+
snapshot: {
|
|
274
|
+
type: 'object',
|
|
275
|
+
description:
|
|
276
|
+
'Optional snapshot metadata (jj/git-worktree, workspace, jj ids). Merged with OVERLORD_SNAPSHOT_JSON when both are set.'
|
|
277
|
+
},
|
|
278
|
+
checkpoint: {
|
|
279
|
+
type: 'object',
|
|
280
|
+
description:
|
|
281
|
+
'Optional checkpoint metadata. The local CLI creates this automatically for JJ/Git workspaces during deliver.'
|
|
282
|
+
},
|
|
283
|
+
checkpoint_backend: {
|
|
284
|
+
type: 'string',
|
|
285
|
+
enum: ['auto', 'jj', 'git'],
|
|
286
|
+
description: 'Backend for automatic local checkpointing when routed through the CLI.'
|
|
287
|
+
},
|
|
288
|
+
skip_checkpoint: { type: 'boolean' },
|
|
281
289
|
skip_file_change_check: { type: 'boolean' }
|
|
282
290
|
},
|
|
283
291
|
required: ['session_key', 'ticket_id', 'summary']
|
|
@@ -286,13 +294,18 @@ const tools = [
|
|
|
286
294
|
'session-key': args.session_key,
|
|
287
295
|
'ticket-id': args.ticket_id,
|
|
288
296
|
'payload-file': '-',
|
|
297
|
+
'checkpoint-backend': args.checkpoint_backend,
|
|
298
|
+
'skip-checkpoint': args.skip_checkpoint,
|
|
289
299
|
'skip-file-change-check': args.skip_file_change_check
|
|
290
300
|
}),
|
|
291
|
-
toCliStdin: args =>
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
301
|
+
toCliStdin: args =>
|
|
302
|
+
JSON.stringify({
|
|
303
|
+
summary: args.summary,
|
|
304
|
+
...(Array.isArray(args.artifacts) ? { artifacts: args.artifacts } : {}),
|
|
305
|
+
...(Array.isArray(args.change_rationales) ? { changeRationales: args.change_rationales } : {}),
|
|
306
|
+
...(args.snapshot && typeof args.snapshot === 'object' ? { snapshot: args.snapshot } : {}),
|
|
307
|
+
...(args.checkpoint && typeof args.checkpoint === 'object' ? { checkpoint: args.checkpoint } : {})
|
|
308
|
+
}),
|
|
296
309
|
subcommand: 'deliver'
|
|
297
310
|
},
|
|
298
311
|
{
|
|
@@ -303,7 +316,7 @@ const tools = [
|
|
|
303
316
|
type: 'object',
|
|
304
317
|
properties: {
|
|
305
318
|
session_key: { type: 'string' },
|
|
306
|
-
ticket_id: { type: 'string' },
|
|
319
|
+
ticket_id: { type: 'string', description: 'Ticket identifier (e.g. 1:899). Also accepts UUID.' },
|
|
307
320
|
objective_id: { type: 'string' }
|
|
308
321
|
},
|
|
309
322
|
required: ['session_key', 'ticket_id']
|
|
@@ -322,7 +335,7 @@ const tools = [
|
|
|
322
335
|
type: 'object',
|
|
323
336
|
properties: {
|
|
324
337
|
session_key: { type: 'string' },
|
|
325
|
-
ticket_id: { type: 'string' },
|
|
338
|
+
ticket_id: { type: 'string', description: 'Ticket identifier (e.g. 1:899). Also accepts UUID.' },
|
|
326
339
|
objective_id: { type: 'string' },
|
|
327
340
|
file_name: { type: 'string' },
|
|
328
341
|
label: { type: 'string' },
|
|
@@ -351,7 +364,7 @@ const tools = [
|
|
|
351
364
|
type: 'object',
|
|
352
365
|
properties: {
|
|
353
366
|
session_key: { type: 'string' },
|
|
354
|
-
ticket_id: { type: 'string' },
|
|
367
|
+
ticket_id: { type: 'string', description: 'Ticket identifier (e.g. 1:899). Also accepts UUID.' },
|
|
355
368
|
objective_id: { type: 'string' },
|
|
356
369
|
storage_path: { type: 'string' },
|
|
357
370
|
label: { type: 'string' },
|
|
@@ -380,7 +393,7 @@ const tools = [
|
|
|
380
393
|
type: 'object',
|
|
381
394
|
properties: {
|
|
382
395
|
session_key: { type: 'string' },
|
|
383
|
-
ticket_id: { type: 'string' },
|
|
396
|
+
ticket_id: { type: 'string', description: 'Ticket identifier (e.g. 1:899). Also accepts UUID.' },
|
|
384
397
|
objective_id: { type: 'string' },
|
|
385
398
|
attachment_id: { type: 'string' },
|
|
386
399
|
storage_path: { type: 'string' },
|
|
@@ -405,7 +418,7 @@ const tools = [
|
|
|
405
418
|
type: 'object',
|
|
406
419
|
properties: {
|
|
407
420
|
session_key: { type: 'string' },
|
|
408
|
-
ticket_id: { type: 'string' },
|
|
421
|
+
ticket_id: { type: 'string', description: 'Ticket identifier (e.g. 1:899). Also accepts UUID.' },
|
|
409
422
|
objective_id: { type: 'string' },
|
|
410
423
|
file: { type: 'string' },
|
|
411
424
|
file_name: { type: 'string' },
|
|
@@ -632,10 +645,10 @@ async function handleRequest(message) {
|
|
|
632
645
|
},
|
|
633
646
|
serverInfo: {
|
|
634
647
|
name: 'overlord',
|
|
635
|
-
version: '0.2
|
|
648
|
+
version: '0.1.2'
|
|
636
649
|
},
|
|
637
650
|
instructions:
|
|
638
|
-
'Use these tools to drive Overlord ticket workflows through the installed ovld CLI. Most operations expect a session key from attach or connect.
|
|
651
|
+
'Use these tools to drive Overlord ticket workflows through the installed ovld CLI. Most operations expect a session key from attach or connect.'
|
|
639
652
|
});
|
|
640
653
|
return;
|
|
641
654
|
}
|
|
@@ -63,18 +63,45 @@ ovld protocol deliver --session-key <sessionKey> \
|
|
|
63
63
|
--change-rationales-json '[{"label":"Short reviewer title","file_path":"path/to/file.ts","summary":"What changed.","why":"Why it changed.","impact":"Behavioral impact.","hunks":[{"header":"@@ -10,6 +10,14 @@"}]}]'
|
|
64
64
|
```
|
|
65
65
|
|
|
66
|
-
For larger delivery payloads, prefer `--payload-file -` and stream the full JSON on stdin so no scratch file needs to be created or removed. If you use `--payload-file`, `--artifacts-file`, or `--change-rationales-file` with a real path, treat that file as ephemeral scratch data outside the repository and remove it after delivery.
|
|
66
|
+
`ovld protocol deliver` automatically creates a local checkpoint before the API request when the workspace is JJ- or Git-managed; use `--skip-checkpoint` only when intentionally bypassing local provenance. For larger delivery payloads, prefer `--payload-file -` and stream the full JSON on stdin so no scratch file needs to be created or removed. If you use `--payload-file`, `--artifacts-file`, or `--change-rationales-file` with a real path, treat that file as ephemeral scratch data outside the repository and remove it after delivery.
|
|
67
67
|
|
|
68
68
|
## Mode 2: Asked From Chat To Use Overlord
|
|
69
69
|
|
|
70
70
|
1. If the user wants to create tickets (and does not ask to start execution), run `ovld protocol create --agent codex --objective "..."`.
|
|
71
|
-
|
|
71
|
+
- When `--session-key` and `--ticket-id` are provided, it creates a follow-up draft.
|
|
72
|
+
- When session flags are omitted, it resolves the project by matching current working directory (or `--working-directory`) to Overlord `local_working_directory`, then creates a standalone draft.
|
|
73
|
+
2. Default to `create` for new tickets. Only use `ovld protocol prompt --agent codex --objective "..."` when the user explicitly asks to create and execute immediately.
|
|
74
|
+
`prompt` creates the ticket in `execute` status and attaches immediately.
|
|
72
75
|
3. If the user wants to inspect an existing ticket without starting work, use `ovld protocol load-context --ticket-id <ticket_id>`.
|
|
73
|
-
4. If the user wants to work an existing ticket, attach with `ovld protocol attach --ticket-id <ticket_id>` and then switch to Mode 1.
|
|
74
|
-
5. If the user wants to find existing tickets by keyword or
|
|
75
|
-
6. If you need to understand project routing before
|
|
76
|
+
4. If the user wants to work an existing ticket, attach with `ovld protocol attach --ticket-id <ticket_id>` and then switch to Mode 1. Use `ovld protocol connect --ticket-id <ticket_id>` instead when you only need a session key without the full ticket payload.
|
|
77
|
+
5. If the user wants to find existing tickets by keyword, status, project, creator, or update window, run `ovld protocol search-tickets --query "..." --status next-up,execute --limit 10`. The MCP `search_tickets` tool exposes the same filters.
|
|
78
|
+
6. If you need to understand project routing before prompting, use `ovld protocol discover-project`.
|
|
76
79
|
7. If you need other lifecycle commands or flags, run `ovld protocol help` and use the real subcommand list instead of guessing.
|
|
77
80
|
|
|
81
|
+
## Project Discovery And Ticket Creation
|
|
82
|
+
|
|
83
|
+
When creating tickets from within a repository:
|
|
84
|
+
- Prefer `create` by default for draft ticket creation.
|
|
85
|
+
- Use `prompt` only when the user explicitly asks to start execution immediately.
|
|
86
|
+
- Both commands can resolve the project from the current working directory; use `--working-directory` to override.
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
ovld protocol create --agent codex --objective "Capture follow-up work from this repository"
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
ovld protocol prompt --agent codex --objective "Implement feature X" --priority medium
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### Choosing `--execution-target`
|
|
97
|
+
|
|
98
|
+
Pass `--execution-target agent` or `--execution-target human` (default: `human`) when creating tickets.
|
|
99
|
+
|
|
100
|
+
- **`agent`** — any task an AI agent can complete in a computer environment: coding, internet research, document editing, data analysis, automated testing, etc.
|
|
101
|
+
- **`human`** — any task requiring human presence or judgment: setting credentials or tokens in a third-party UI (e.g. Vercel, AWS), sending physical mail, making a product or business decision, physical-world actions.
|
|
102
|
+
|
|
103
|
+
When in doubt, ask yourself: *can this be done entirely inside a terminal or browser by an AI without human intervention?* If yes → `agent`. If it requires a human to log in, decide, or act in the real world → `human`.
|
|
104
|
+
|
|
78
105
|
## Change Rationales
|
|
79
106
|
|
|
80
107
|
Always include `changeRationales` when delivering. Optionally include them on updates during long-running work.
|
|
@@ -109,38 +136,22 @@ ovld protocol attachment-download-url --session-key <sessionKey> --ticket-id $TI
|
|
|
109
136
|
|
|
110
137
|
The `attach` and `load-context` responses already include `attachments` and `objectives` arrays — use those for `<attachment-id>` and `<objective-id>` values. Run `attachment-list` mid-session if new files have been uploaded since attach.
|
|
111
138
|
|
|
112
|
-
##
|
|
113
|
-
|
|
114
|
-
When creating tickets from within a repository:
|
|
115
|
-
- Prefer `create` by default for draft ticket creation.
|
|
116
|
-
- Use `spawn` only when the user explicitly asks to start execution immediately.
|
|
117
|
-
- Both commands can resolve the project from the current working directory; use `--working-directory` to override.
|
|
139
|
+
## Defaults And Notes
|
|
118
140
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
ovld protocol spawn --agent codex --objective "Implement feature X" --priority medium
|
|
125
|
-
```
|
|
126
|
-
|
|
127
|
-
### Choosing `--execution-target`
|
|
128
|
-
|
|
129
|
-
Pass `--execution-target agent` or `--execution-target human` (default: `human`) when creating tickets.
|
|
130
|
-
|
|
131
|
-
- **`agent`** — any task an AI agent can complete in a computer environment: coding, internet research, document editing, data analysis, automated testing, etc.
|
|
132
|
-
- **`human`** — any task requiring human presence or judgment: setting credentials or tokens in a third-party UI (e.g. Vercel, AWS), sending physical mail, making a product or business decision, physical-world actions.
|
|
133
|
-
|
|
134
|
-
When in doubt, ask yourself: *can this be done entirely inside a terminal or browser by an AI without human intervention?* If yes → `agent`. If it requires a human to log in, decide, or act in the real world → `human`.
|
|
141
|
+
- API requires `agentIdentifier` and `connectionMethod` on attach/connect/prompt. The CLI defaults them to `codex`/`cli`; the MCP tool defaults to `mcp`. Override with `--agent` / `--method` when calling from a different runtime.
|
|
142
|
+
- `permission-request` is invoked by the local Codex plugin's permission rules; agents do not normally call it directly.
|
|
143
|
+
- `record_change_rationales` (MCP) and `ovld protocol record-change-rationales` (CLI) both write to the `file_changes` table; the dedicated route is `POST /api/protocol/record-change-rationales`.
|
|
144
|
+
- Objective attachment MCP tools use `<verb>_<noun>` names — `list_attachments`, `prepare_attachment_upload`, `finalize_attachment_upload`, `get_attachment_download_url`, `upload_attachment_file`. CLI commands use `attachment-*` and require `--objective-id` for upload/finalize.
|
|
145
|
+
- "Artifacts" in `deliver` are the structured records an agent submits at delivery time (next_steps, test_results, migration, decision, note, url) — not user-uploaded files.
|
|
135
146
|
|
|
136
147
|
## Rules
|
|
137
148
|
|
|
138
149
|
- The authoritative lifecycle is the `ovld protocol` CLI once you are on a ticket.
|
|
139
150
|
- Always attach first and always deliver last once you are working a ticket.
|
|
140
|
-
- Prefer the installed `ovld` CLI and the plugin's MCP tools instead of ad hoc repo scripts.
|
|
151
|
+
- Prefer the installed `ovld protocol` CLI and the plugin's MCP tools instead of ad hoc repo scripts.
|
|
141
152
|
- Do not create or rely on a local Codex `AGENTS.md` bundle for Overlord.
|
|
142
|
-
- If `ovld` reports `OVERLORD_URL` is unreachable, request permission escalation or network access before retrying.
|
|
143
153
|
- When the ticket was launched by Overlord, the ticket prompt remains authoritative for the specific task objective and ticket-level constraints.
|
|
144
154
|
- If a protocol or MCP call fails with auth/session errors, run `ovld auth repair` yourself before asking the user to log in again or proceed without Overlord updates.
|
|
155
|
+
- If you must run `ovld auth login`, always include `--organization-id <id>` — use the organization ID from the ticket prompt context to select the organization non-interactively and avoid a blocking TTY prompt.
|
|
145
156
|
|
|
146
|
-
<!-- version: 0.
|
|
157
|
+
<!-- version: 0.4.5 -->
|