agent-conveyor 0.1.16 → 0.1.18
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
CHANGED
|
@@ -324,7 +324,14 @@ tmux attach -t codex-live-test
|
|
|
324
324
|
asset receipt counts.
|
|
325
325
|
- `campaign dashboard --name C [--json]` —
|
|
326
326
|
Show a manager-oriented campaign aggregate: worker slot lifecycle states,
|
|
327
|
-
blockers, approval counts, and the next recommended manager action.
|
|
327
|
+
blockers, approval counts, and the next recommended manager action. This is
|
|
328
|
+
also the supported way to inspect asset receipts and per-slot receipt counts;
|
|
329
|
+
there is no separate `campaign assets` subcommand.
|
|
330
|
+
- `campaign closeout --name C [--failure-mode TEXT] [--json]` —
|
|
331
|
+
Produce a read-only closeout report from the campaign dashboard, including
|
|
332
|
+
verdict, worker thread ids, blockers, receipt counts by assignment, proof
|
|
333
|
+
checks, and the strongest realistic failure mode evidence to carry into a
|
|
334
|
+
manager/operator handoff.
|
|
328
335
|
|
|
329
336
|
Creative Ops Campaign manager loop:
|
|
330
337
|
|
|
@@ -608,6 +615,9 @@ stay out of receipts.
|
|
|
608
615
|
permissions, expected tools, epilogues, evidence gates, cleanup behavior,
|
|
609
616
|
disallowed actions, locked setup summary template, and suggested
|
|
610
617
|
`manager-config` command. Use this before cutting a manager loose.
|
|
618
|
+
`campaign-duplicate-guard-dogfood` is the recipe for visible creative
|
|
619
|
+
campaign dogfoods that prove accidental duplicate assignment receipts are
|
|
620
|
+
rejected unless a worker explicitly uses `--allow-additional-receipt`.
|
|
611
621
|
- `worker-ack <task> --from-stdin|--json [--correlation-id ID]` /
|
|
612
622
|
`manager-ack <task> --from-stdin|--json [--correlation-id ID]` — Persist or
|
|
613
623
|
read the latest structured acknowledgement from the worker or manager. Acks
|
|
@@ -384,7 +384,11 @@ function commandHelpText(program, command) {
|
|
|
384
384
|
` ${program} finish-task my-task --reason "Accepted criteria satisfied" --require-criteria-audit --path /tmp/work/workerctl.db --json`,
|
|
385
385
|
],
|
|
386
386
|
campaign: [
|
|
387
|
-
`usage: ${program} campaign
|
|
387
|
+
`usage: ${program} campaign <${campaignActionsUsage()}> --name <campaign> [options] ${path} [--json]`,
|
|
388
|
+
"",
|
|
389
|
+
`Supported subcommands: ${campaignActionsUsage()}`,
|
|
390
|
+
"",
|
|
391
|
+
"Use `dashboard` to list campaign assets and slot receipt counts; there is no separate `assets` subcommand.",
|
|
388
392
|
"",
|
|
389
393
|
"Examples:",
|
|
390
394
|
` ${program} campaign create --name launch --objective "Create launch assets" --metadata-json '{"owner":"ops"}' --json`,
|
|
@@ -398,6 +402,7 @@ function commandHelpText(program, command) {
|
|
|
398
402
|
` ${program} campaign asset --name launch --slot campaign-slot-id --assignment campaign-assignment-id --asset-type copy --title "Hooks v2" --allow-additional-receipt --json`,
|
|
399
403
|
` ${program} campaign status --name launch --json`,
|
|
400
404
|
` ${program} campaign dashboard --name launch --json`,
|
|
405
|
+
` ${program} campaign closeout --name launch --failure-mode "hidden duplicate receipt" --json`,
|
|
401
406
|
],
|
|
402
407
|
"manager-ack": [
|
|
403
408
|
`usage: ${program} manager-ack <task> --from-stdin ${path}`,
|
|
@@ -472,7 +477,8 @@ function commandHelpText(program, command) {
|
|
|
472
477
|
};
|
|
473
478
|
return linesByCommand[command] ?? [`usage: ${program} ${command} [-h] [options]`];
|
|
474
479
|
}
|
|
475
|
-
const
|
|
480
|
+
const CAMPAIGN_ACTION_NAMES = ["create", "add-slot", "attach-slot", "rotate-slot", "archive-slot", "brief", "assign", "asset", "status", "dashboard", "closeout"];
|
|
481
|
+
const CAMPAIGN_ACTIONS = new Set(CAMPAIGN_ACTION_NAMES);
|
|
476
482
|
const CAMPAIGN_STRING_FLAGS = {
|
|
477
483
|
"--artifact-path": "artifactPath",
|
|
478
484
|
"--asset-type": "assetType",
|
|
@@ -480,6 +486,7 @@ const CAMPAIGN_STRING_FLAGS = {
|
|
|
480
486
|
"--brief-json": "briefJson",
|
|
481
487
|
"--channel": "channel",
|
|
482
488
|
"--expected-thread-id": "expectedThreadId",
|
|
489
|
+
"--failure-mode": "failureMode",
|
|
483
490
|
"--instructions": "instructions",
|
|
484
491
|
"--objective": "objective",
|
|
485
492
|
"--prompt-summary": "promptSummary",
|
|
@@ -3022,7 +3029,7 @@ function parseRuntimeArgs(args, env) {
|
|
|
3022
3029
|
}
|
|
3023
3030
|
else if (command === "campaign" && flags.action === null) {
|
|
3024
3031
|
if (!CAMPAIGN_ACTIONS.has(arg)) {
|
|
3025
|
-
return { command, enabled, error:
|
|
3032
|
+
return { command, enabled, error: unsupportedCampaignActionMessage(arg), explicit, flags, task };
|
|
3026
3033
|
}
|
|
3027
3034
|
flags.action = arg;
|
|
3028
3035
|
}
|
|
@@ -6253,12 +6260,25 @@ function runCampaignCommand(parsed, options) {
|
|
|
6253
6260
|
const dashboard = campaignDashboardSync(database, campaign);
|
|
6254
6261
|
return campaignResult(parsed, dashboard, renderCampaignDashboardText(dashboard));
|
|
6255
6262
|
}
|
|
6256
|
-
|
|
6263
|
+
if (action === "closeout") {
|
|
6264
|
+
const dashboard = campaignDashboardSync(database, campaign);
|
|
6265
|
+
const closeout = campaignCloseoutReport(dashboard, {
|
|
6266
|
+
failureMode: parsed.flags.failureMode,
|
|
6267
|
+
});
|
|
6268
|
+
return campaignResult(parsed, closeout, renderCampaignCloseoutText(closeout));
|
|
6269
|
+
}
|
|
6270
|
+
return errorResult(unsupportedCampaignActionMessage(action));
|
|
6257
6271
|
}
|
|
6258
6272
|
finally {
|
|
6259
6273
|
database.close();
|
|
6260
6274
|
}
|
|
6261
6275
|
}
|
|
6276
|
+
function campaignActionsUsage() {
|
|
6277
|
+
return CAMPAIGN_ACTION_NAMES.join("|");
|
|
6278
|
+
}
|
|
6279
|
+
function unsupportedCampaignActionMessage(action) {
|
|
6280
|
+
return `Unsupported campaign action: ${action ?? "<missing>"}; expected one of: ${CAMPAIGN_ACTION_NAMES.join(", ")}. Use \`conveyor campaign dashboard --name <campaign> --json\` to list assets and receipt counts.`;
|
|
6281
|
+
}
|
|
6262
6282
|
function campaignResult(parsed, payload, lines) {
|
|
6263
6283
|
return parsed.flags.json ? jsonResult(payload) : textResult(lines);
|
|
6264
6284
|
}
|
|
@@ -6331,6 +6351,107 @@ function renderCampaignDashboardText(dashboard) {
|
|
|
6331
6351
|
}
|
|
6332
6352
|
return lines;
|
|
6333
6353
|
}
|
|
6354
|
+
function campaignCloseoutReport(dashboard, options = {}) {
|
|
6355
|
+
const receiptCountsByAssignment = campaignReceiptCountsByAssignment(dashboard);
|
|
6356
|
+
const activeSlots = dashboard.slots.filter((slot) => slot.state !== "archived");
|
|
6357
|
+
const slotsMissingReceipts = activeSlots.filter((slot) => slot.assignments.length > 0 && slot.asset_receipts === 0);
|
|
6358
|
+
const duplicateAssignmentCounts = receiptCountsByAssignment.filter((item) => item.receipt_count > 1);
|
|
6359
|
+
const failureMode = options.failureMode
|
|
6360
|
+
?? "A hidden duplicate or missing worker receipt could make the campaign look closed while dashboard receipt counts are wrong.";
|
|
6361
|
+
const receiptEvidence = dashboard.slots
|
|
6362
|
+
.map((slot) => `${slot.slot_key}:assignments=${slot.assignments.length},receipts=${slot.asset_receipts}`)
|
|
6363
|
+
.join("; ");
|
|
6364
|
+
return {
|
|
6365
|
+
action: "closeout",
|
|
6366
|
+
approvals: dashboard.approvals,
|
|
6367
|
+
blockers: dashboard.blockers,
|
|
6368
|
+
campaign: dashboard.campaign,
|
|
6369
|
+
failure_mode: {
|
|
6370
|
+
evidence: `dashboard asset_total=${dashboard.summary.asset_total}; assignment_total=${dashboard.summary.assignment_total}; ${receiptEvidence}`,
|
|
6371
|
+
strongest_realistic_failure_mode: failureMode,
|
|
6372
|
+
},
|
|
6373
|
+
next_manager_action: dashboard.next_manager_action,
|
|
6374
|
+
proof_checks: [
|
|
6375
|
+
{
|
|
6376
|
+
check: "dashboard_loaded",
|
|
6377
|
+
evidence: `campaign_id=${dashboard.campaign.id}; updated_at=${dashboard.campaign.updated_at}`,
|
|
6378
|
+
status: "passed",
|
|
6379
|
+
},
|
|
6380
|
+
{
|
|
6381
|
+
check: "blockers_absent",
|
|
6382
|
+
evidence: `blockers=${dashboard.blockers.length}`,
|
|
6383
|
+
status: dashboard.blockers.length === 0 ? "passed" : "failed",
|
|
6384
|
+
},
|
|
6385
|
+
{
|
|
6386
|
+
check: "active_worker_slots_have_receipts",
|
|
6387
|
+
evidence: slotsMissingReceipts.length === 0
|
|
6388
|
+
? "all active slots with assignments have at least one receipt"
|
|
6389
|
+
: `missing_receipt_slots=${slotsMissingReceipts.map((slot) => slot.slot_key).join(",")}`,
|
|
6390
|
+
status: slotsMissingReceipts.length === 0 ? "passed" : "attention",
|
|
6391
|
+
},
|
|
6392
|
+
{
|
|
6393
|
+
check: "assignment_receipt_counts",
|
|
6394
|
+
evidence: duplicateAssignmentCounts.length === 0
|
|
6395
|
+
? "no assignment has more than one receipt"
|
|
6396
|
+
: `additional_receipt_assignments=${duplicateAssignmentCounts.map((item) => `${item.assignment_id}:${item.receipt_count}`).join(",")}`,
|
|
6397
|
+
status: duplicateAssignmentCounts.length === 0 ? "passed" : "attention",
|
|
6398
|
+
},
|
|
6399
|
+
{
|
|
6400
|
+
check: "human_review_gate",
|
|
6401
|
+
evidence: `needs_review=${dashboard.approvals.needs_review}; approved=${dashboard.approvals.approved}; published=${dashboard.approvals.published}`,
|
|
6402
|
+
status: dashboard.approvals.needs_review > 0 && dashboard.approvals.published === 0 ? "passed" : "attention",
|
|
6403
|
+
},
|
|
6404
|
+
],
|
|
6405
|
+
receipt_counts_by_assignment: receiptCountsByAssignment,
|
|
6406
|
+
summary: dashboard.summary,
|
|
6407
|
+
verdict: campaignCloseoutVerdict(dashboard),
|
|
6408
|
+
workers: dashboard.slots.map((slot) => ({
|
|
6409
|
+
active_assignments: slot.active_assignments,
|
|
6410
|
+
asset_receipts: slot.asset_receipts,
|
|
6411
|
+
blockers: slot.blockers,
|
|
6412
|
+
channel: slot.channel,
|
|
6413
|
+
codex_app_thread_id: slot.codex_app_thread_id,
|
|
6414
|
+
codex_app_thread_title: slot.codex_app_thread_title,
|
|
6415
|
+
lifecycle_state: slot.lifecycle.state,
|
|
6416
|
+
receipt_ids: slot.assets.map((asset) => asset.id),
|
|
6417
|
+
slot_key: slot.slot_key,
|
|
6418
|
+
state: slot.state,
|
|
6419
|
+
})),
|
|
6420
|
+
};
|
|
6421
|
+
}
|
|
6422
|
+
function campaignReceiptCountsByAssignment(dashboard) {
|
|
6423
|
+
return dashboard.slots.flatMap((slot) => slot.assignments.map((assignment) => ({
|
|
6424
|
+
assignment_id: assignment.id,
|
|
6425
|
+
receipt_count: slot.assets.filter((asset) => asset.assignment_id === assignment.id).length,
|
|
6426
|
+
slot_key: slot.slot_key,
|
|
6427
|
+
})));
|
|
6428
|
+
}
|
|
6429
|
+
function campaignCloseoutVerdict(dashboard) {
|
|
6430
|
+
if (dashboard.blockers.length > 0 || dashboard.summary.blocked_assignments > 0 || dashboard.summary.blocked_slots > 0 || dashboard.summary.stale_slots > 0) {
|
|
6431
|
+
return "blocked";
|
|
6432
|
+
}
|
|
6433
|
+
if (dashboard.next_manager_action.action === "close_campaign") {
|
|
6434
|
+
return "ready_to_close";
|
|
6435
|
+
}
|
|
6436
|
+
if (dashboard.approvals.needs_review > 0 || dashboard.approvals.rejected > 0) {
|
|
6437
|
+
return "needs_review";
|
|
6438
|
+
}
|
|
6439
|
+
return "needs_work";
|
|
6440
|
+
}
|
|
6441
|
+
function renderCampaignCloseoutText(report) {
|
|
6442
|
+
return [
|
|
6443
|
+
`campaign ${report.campaign.name} ${report.campaign.status}`,
|
|
6444
|
+
`closeout verdict ${report.verdict}`,
|
|
6445
|
+
`next ${report.next_manager_action.action}: ${report.next_manager_action.reason}`,
|
|
6446
|
+
`summary slots=${report.summary.active_slots}/${report.summary.archived_slots} assignments=${report.summary.assignment_total} assets=${report.summary.asset_total} blockers=${report.blockers.length}`,
|
|
6447
|
+
`approvals needs_review=${report.approvals.needs_review} approved=${report.approvals.approved} rejected=${report.approvals.rejected} published=${report.approvals.published}`,
|
|
6448
|
+
`failure_mode ${report.failure_mode.strongest_realistic_failure_mode}`,
|
|
6449
|
+
`failure_mode_evidence ${report.failure_mode.evidence}`,
|
|
6450
|
+
...report.proof_checks.map((check) => `proof ${check.status} ${check.check}: ${check.evidence}`),
|
|
6451
|
+
...report.receipt_counts_by_assignment.map((item) => `assignment_receipts ${item.slot_key} ${item.assignment_id}=${item.receipt_count}`),
|
|
6452
|
+
...report.workers.slice(0, 8).map((worker) => `worker ${worker.slot_key} ${worker.state}/${worker.lifecycle_state} assignments=${worker.active_assignments} receipts=${worker.asset_receipts} thread=${worker.codex_app_thread_id ?? "none"}`),
|
|
6453
|
+
];
|
|
6454
|
+
}
|
|
6334
6455
|
function statusCountsText(counts) {
|
|
6335
6456
|
return Object.entries(counts).map(([status, count]) => `${status}=${count}`).join(" ");
|
|
6336
6457
|
}
|
|
@@ -17212,6 +17333,45 @@ const MANAGER_RECIPES = {
|
|
|
17212
17333
|
supportPatterns: ["Inbox / No-Tmux App Loop", "Recovery / Resume / Handoff"],
|
|
17213
17334
|
tools: ["verification.run_tests", "context.fetch_prs"],
|
|
17214
17335
|
},
|
|
17336
|
+
"campaign-duplicate-guard-dogfood": {
|
|
17337
|
+
acceptance: [
|
|
17338
|
+
"The campaign dashboard shows exactly one normal asset receipt for each active assignment before the duplicate probe.",
|
|
17339
|
+
"A worker visibly attempts an accidental duplicate `campaign asset` receipt without --allow-additional-receipt and records the expected non-zero failure.",
|
|
17340
|
+
"Manager independently verifies the post-probe dashboard still has the original asset_total, the probed slot still has one receipt, and blockers are empty.",
|
|
17341
|
+
],
|
|
17342
|
+
cleanup: "off by default; archive or rotate only campaign-owned worker slots with exact expected thread ids",
|
|
17343
|
+
description: "Dogfood creative campaign workers while proving assignment-scoped duplicate receipts are blocked unless explicitly allowed.",
|
|
17344
|
+
disallowedActions: [
|
|
17345
|
+
"Do not use --allow-additional-receipt for the accidental duplicate probe.",
|
|
17346
|
+
"Do not treat the worker's duplicate-failure claim as proof until the manager verifies the dashboard.",
|
|
17347
|
+
"Do not publish, schedule, contact external services, inspect private content, edit product/content files, or commit during the dogfood.",
|
|
17348
|
+
"Do not archive or rotate a worker thread unless the campaign slot owns that exact thread id.",
|
|
17349
|
+
],
|
|
17350
|
+
displayName: "Campaign Duplicate-Guard Dogfood",
|
|
17351
|
+
epilogues: [],
|
|
17352
|
+
evidenceGates: [
|
|
17353
|
+
"campaign_dashboard_pre_probe",
|
|
17354
|
+
"visible_worker_duplicate_failure",
|
|
17355
|
+
"duplicate_failure_exit_code",
|
|
17356
|
+
"post_probe_dashboard_no_extra_asset",
|
|
17357
|
+
"manager_duplicate_guard_decision",
|
|
17358
|
+
],
|
|
17359
|
+
finalReportRequirements: [
|
|
17360
|
+
"Report the manager thread id, worker thread ids, assignment ids, original receipt ids, duplicate error text, pre/post dashboard counts, and residual cleanup status.",
|
|
17361
|
+
],
|
|
17362
|
+
guidelines: [
|
|
17363
|
+
"Keep manager and worker sessions visibly chatty with CONVEYOR RECEIVED, WORK, and CONVEYOR SEND sections.",
|
|
17364
|
+
"Use `campaign dashboard --name <campaign> --json` as the supported receipt-listing surface.",
|
|
17365
|
+
"Ask exactly one worker to perform the missing-override duplicate probe, then require manager-side dashboard verification before closeout.",
|
|
17366
|
+
],
|
|
17367
|
+
loopTemplate: null,
|
|
17368
|
+
mode: "strict",
|
|
17369
|
+
name: "campaign-duplicate-guard-dogfood",
|
|
17370
|
+
objective: "Supervise a visible campaign dogfood that proves duplicate assignment receipts fail closed without --allow-additional-receipt.",
|
|
17371
|
+
permissions: [],
|
|
17372
|
+
supportPatterns: ["Creative Ops Campaign", "Inbox / No-Tmux App Loop", "Recovery / Resume / Handoff"],
|
|
17373
|
+
tools: ["campaign.dashboard", "codex_app.send_message_to_thread"],
|
|
17374
|
+
},
|
|
17215
17375
|
"nudge-whats-next": {
|
|
17216
17376
|
acceptance: [
|
|
17217
17377
|
"Accepted criteria are satisfied or explicitly deferred.",
|
|
@@ -17370,6 +17530,10 @@ const MANAGER_RECIPES = {
|
|
|
17370
17530
|
},
|
|
17371
17531
|
};
|
|
17372
17532
|
const MANAGER_RECIPE_ALIASES = {
|
|
17533
|
+
"campaign duplicate guard": "campaign-duplicate-guard-dogfood",
|
|
17534
|
+
"campaign duplicate guard dogfood": "campaign-duplicate-guard-dogfood",
|
|
17535
|
+
"creative duplicate guard": "campaign-duplicate-guard-dogfood",
|
|
17536
|
+
"duplicate guard dogfood": "campaign-duplicate-guard-dogfood",
|
|
17373
17537
|
"goalbuddy conveyor": "goalbuddy-conveyor",
|
|
17374
17538
|
goalbuddy: "goalbuddy-conveyor",
|
|
17375
17539
|
"nudge / what's next manager": "nudge-whats-next",
|