fix: v0.2 migration blockers — queue fields, status endpoint, move auth, claim behavior - #99

Merged
joryirving merged 1 commit into
mainfrom
fix/issue-98-migration-v02
May 17, 2026
Merged

fix: v0.2 migration blockers — queue fields, status endpoint, move auth, claim behavior#99
joryirving merged 1 commit into
mainfrom
fix/issue-98-migration-v02

Conversation

@itsmiso-ai

Copy link
Copy Markdown
Contributor

Summary

Fixes all v0.2 migration blockers so Saffron can safely migrate. Addresses 5 problems identified in Issue #98.

Changes

1. Queue now includes issueId and repoFullName

  • GET /api/agents/[agentName]/queue issue items now include:
    • type: "issue" (PR-fix items keep type: "pr-review-fix")
    • issueId — the Prisma Issue ID
    • repoFullName — e.g. "org/repo"
  • PR-fix queue items remain first in the response
  • Lane=gpt deprecated alias preserved

2. New POST /api/issues/status endpoint

  • Bearer auth required (MISSION_CONTROL_AGENT_TOKEN)
  • Payload: { issueId, repoFullName, issueNumber, status, agentName?, actor? }
  • Replaces existing status/* labels with the requested status
  • Updates GitHub labels, Prisma cache, and writes AuditLog
  • Valid statuses: backlog, in-progress, in-review, done

3. POST /api/issues/move now requires bearer auth

  • Previously unauthenticated — now rejects without valid token
  • Workers should prefer the new /api/issues/status endpoint for status transitions
  • Supports optional actor field in body (defaults to "agent")

4. Claim behavior clarified and implemented

  • Claim only assigns — adds agent/* label, does NOT change status
  • Status transition is explicit via POST /api/issues/status
  • This separates assignment from state management

5. Worker migration docs updated

  • Fixed incorrect /api/issues/move payload (now shows oldLabels/newLabels)
  • Documents new /api/issues/status endpoint
  • Clarifies claim behavior in worker prompts

Tests

All 352 tests pass, including:

  • Queue returns issueId, repoFullName, and type: "issue"
  • PR-fix items remain first
  • Status endpoint replaces status labels safely
  • Status endpoint requires bearer auth
  • /api/issues/move requires bearer auth
  • Claim no longer auto-adds status/in-progress

Validation

  • npm ci
  • npx prisma generate
  • npm run lint
  • npm run typecheck
  • npm run test ✅ (352/352 passing)
  • npm run build

@its-miso

its-misoBot commented May 17, 2026

Copy link
Copy Markdown
Contributor

Automated recommendation: APPROVE

Analysis engine: anthropic/MiniMax-M2.7@https://litellm.jory.dev/v1 (anthropic)

PR Review: v0.2 Migration Blockers

Summary

This PR addresses v0.2 migration blockers for the Saffron agent, implementing 5 distinct changes across 10 files with comprehensive test coverage.


Change-by-Change Findings

1. Queue Endpoint Enhancement (src/app/api/agents/[agentName]/queue/route.ts)

  • Added: issueId and repoFullName fields to queue response items
  • Added: type: "issue" discriminator field on queue items
  • Impact: Workers can now identify issues without parsing URLs
  • Test coverage: 3 new tests covering issueId, repoFullName, type, and PR-fix ordering
  • Status: ✅ Correctly maps issue.id to issueId and issue.repository.fullName to repoFullName

2. New Status Endpoint (src/app/api/issues/status/route.ts)

  • New endpoint: POST /api/issues/status with bearer auth
  • Payload: { issueId, repoFullName, issueNumber, status, agentName?, actor? }
  • Valid statuses: backlog, in-progress, in-review, done
  • Behavior: Replaces existing status labels; writes AuditLog on both success/failure
  • Security: Returns 401 without valid MISSION_CONTROL_AGENT_TOKEN
  • Test coverage: 21 new tests covering auth, validation, business logic, and error handling
  • Status: ✅ Implements atomic label replacement; correctly skips GitHub calls when status unchanged

3. Move Endpoint Auth (src/app/api/issues/move/route.ts)

  • Added: Bearer auth requirement (previously unauthenticated)
  • Added: Optional actor field in body (defaults to "agent")
  • Security: Returns 401 when token missing or incorrect
  • Test coverage: 2 new auth tests; updated existing tests to include auth header
  • Status: ✅ Auth check at top of handler before any processing; audit actor now configurable

4. Claim Behavior Clarification (src/app/api/issues/claim/route.ts)

  • Changed: Claim now only adds agent/* label — no longer adds status/in-progress automatically
  • Impact: Status transitions require explicit POST /api/issues/status call
  • Rationale: Separates assignment from state management for worker control
  • Test coverage: 6 updated tests confirming status/in-progress is not added
  • Status: ✅ Correctly removes auto-status-in-progress logic; tests updated to match

5. Worker Migration Docs (docs/worker-cron-prompt-migration.md)

  • Updated: Queue response format documentation with type, issueId, repoFullName
  • Updated: Claim behavior section clearly stating "Claim only assigns"
  • Added: New /api/issues/status endpoint documentation with valid values
  • Fixed: Move endpoint payload (was incorrectly showing lane, now shows oldLabels/newLabels)
  • Updated: Migration checklist to reflect new workflow
  • Status: ✅ Documents all 5 PR changes accurately

Standards Compliance

StandardStatusNotes
Bearer auth (MISSION_CONTROL_AGENT_TOKEN)All mutation endpoints require token
AuditLog for state changesBoth move and status endpoints write audit entries
Proper HTTP status codes200, 400, 401, 404, 500 correctly used
Error handling (error instanceof Error)Used in catch blocks
No agent-specific names in docsUses generic agent/* patterns
Label conventions (status/*)Uses status/backlog, status/in-progress, etc.
PR-fix ordering preservedPR-fix items returned first

Linked Issue Fit

No linked issue context available. The PR body references "Issue #98" but no linked issue details were provided. The PR self-describes addressing 5 migration blockers, and all 5 are implemented:

  1. ✅ Queue includes issueId and repoFullName
  2. ✅ New POST /api/issues/status endpoint
  3. POST /api/issues/move requires auth
  4. ✅ Claim behavior clarified (assignment only)
  5. ✅ Worker migration docs updated

Evidence Provider Findings

No evidence providers configured.


Tool Harness Findings

Tool harness ran with 0 planned/executed requests — no external calls were made.


Unknowns / Needs Verification

  1. Token scoping: The status and move endpoints accept the same MISSION_CONTROL_AGENT_TOKEN for all agents. No per-agent scoping is implemented. This appears intentional based on existing patterns.

  2. Documentation mismatch potential: The docs/agent-workflow.md file contains a reference to claim "optionally moves it to status/in-progress" (line 86). This may need updating to reflect the new behavior, though this file was not modified in this PR.

  3. Breaking change notice: The removal of auto status/in-progress from claim is a behavior change. The migration docs address this, but existing workers may need updates before deploying this change.


Validation Results

From PR description:

  • npm ci
  • npx prisma generate
  • npm run lint
  • npm run typecheck
  • npm run test (352/352 passing)
  • npm run build

Recommendation

Approve. The PR correctly implements all 5 described migration blockers with comprehensive test coverage (352 tests passing). Code follows repository conventions, implements proper auth, writes audit logs, and maintains label conventions. The migration documentation accurately reflects the new behavior.

…th, claim behavior
- GET /api/agents/[agentName]/queue now returns issueId, repoFullName, and type:'issue' on issue items
- PR-fix items remain first in the queue response
- Added POST /api/issues/status with bearer auth for explicit status transitions
- Replaces existing status/* labels with requested status
- Updates GitHub labels, Prisma cache, and writes AuditLog
- Accepts agentName/actor as optional actor field
- Added MISSION_CONTROL_AGENT_TOKEN bearer auth to POST /api/issues/move
- Deprecated in favor of new /api/issues/status for workers
- Actor defaults to 'agent', can be overridden via body.actor
- Claim no longer auto-transitions to status/in-progress
- Claim only assigns agent/* label; status transitions are explicit via /status
- Updated worker-cron-prompt-migration.md with correct API payloads
- Documents new /api/issues/status endpoint
- Clarifies claim behavior (assign-only, explicit status)
- Fixes incorrect move payload example (shows oldLabels/newLabels)
- All 352 tests pass
@joryirving
joryirvingforce-pushed the fix/issue-98-migration-v02 branch from 49a919d to 80f3e19CompareMay 17, 2026 21:22
@joryirving
joryirving merged commit cf69a9d into mainMay 17, 2026
3 checks passed
@joryirving
joryirving deleted the fix/issue-98-migration-v02 branch May 17, 2026 21:50
joryirving added a commit that referenced this pull request Aug 5, 2026
… on them (#709)
* fix(pr-followup): skip informational bot comments instead of blocking on them
The comment path ingested every non-author comment on a bot PR as
REVIEW_FEEDBACK, so a CI bot posting a size-diff table became a work
item: classifyFeedback finds no actionable pattern in markdown, defaults
to needs_human, and the PR sits BLOCKED on a human forever.
Observed on misospace/llmkube-images#114 — a MERGEABLE, unreviewed PR
blocked since 2026-08-04 by an app-size-diff comment reporting +0 B
(+0%). Same cause on #46 and #99. The queue read 9 NEEDS_HUMAN items
when only informational noise and already-merged PRs were behind them.
Gate the comment descriptor on a new isInformationalComment(): sticky
comment markers (the sticky-pull-request-comment convention embeds one so
the action can update in place, which makes it a structural signal rather
than a prose guess) plus dispatch's own pr-fix-blocked notice. An
ai-pr-reviewer comment stays ingestible even when it carries a marker —
it ships structured findings and is genuine review feedback.
Does not address the stale-item half of the same symptom (#692): items
already queued when their PR merges are still never reaped.
Signed-off-by: Jory Irving <jory.irving@users.noreply.github.com>
* fix(test): import vi in pr-followup-ingestion tests
The informational-comment tests use vi.restoreAllMocks(); vitest globals
make that work at runtime, so the suite passed while tsc and next build
failed on TS2304.
Signed-off-by: Jory Irving <jory.irving@users.noreply.github.com>
---------
Signed-off-by: Jory Irving <jory.irving@users.noreply.github.com>
Co-authored-by: Jory Irving <jory.irving@users.noreply.github.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@itsmiso-ai@joryirving
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

fix: v0.2 migration blockers — queue fields, status endpoint, move auth, claim behavior - #99

Merged
joryirving merged 1 commit into
mainfrom
fix/issue-98-migration-v02
May 17, 2026
Merged

fix: v0.2 migration blockers — queue fields, status endpoint, move auth, claim behavior#99
joryirving merged 1 commit into
mainfrom
fix/issue-98-migration-v02

Conversation

@itsmiso-ai

Copy link
Copy Markdown
Contributor

Summary

Fixes all v0.2 migration blockers so Saffron can safely migrate. Addresses 5 problems identified in Issue #98.

Changes

1. Queue now includes issueId and repoFullName

  • GET /api/agents/[agentName]/queue issue items now include:
    • type: "issue" (PR-fix items keep type: "pr-review-fix")
    • issueId — the Prisma Issue ID
    • repoFullName — e.g. "org/repo"
  • PR-fix queue items remain first in the response
  • Lane=gpt deprecated alias preserved

2. New POST /api/issues/status endpoint

  • Bearer auth required (MISSION_CONTROL_AGENT_TOKEN)
  • Payload: { issueId, repoFullName, issueNumber, status, agentName?, actor? }
  • Replaces existing status/* labels with the requested status
  • Updates GitHub labels, Prisma cache, and writes AuditLog
  • Valid statuses: backlog, in-progress, in-review, done

3. POST /api/issues/move now requires bearer auth

  • Previously unauthenticated — now rejects without valid token
  • Workers should prefer the new /api/issues/status endpoint for status transitions
  • Supports optional actor field in body (defaults to "agent")

4. Claim behavior clarified and implemented

  • Claim only assigns — adds agent/* label, does NOT change status
  • Status transition is explicit via POST /api/issues/status
  • This separates assignment from state management

5. Worker migration docs updated

  • Fixed incorrect /api/issues/move payload (now shows oldLabels/newLabels)
  • Documents new /api/issues/status endpoint
  • Clarifies claim behavior in worker prompts

Tests

All 352 tests pass, including:

  • Queue returns issueId, repoFullName, and type: "issue"
  • PR-fix items remain first
  • Status endpoint replaces status labels safely
  • Status endpoint requires bearer auth
  • /api/issues/move requires bearer auth
  • Claim no longer auto-adds status/in-progress

Validation

  • npm ci
  • npx prisma generate
  • npm run lint
  • npm run typecheck
  • npm run test ✅ (352/352 passing)
  • npm run build

@its-miso

its-misoBot commented May 17, 2026

Copy link
Copy Markdown
Contributor

Automated recommendation: APPROVE

Analysis engine: anthropic/MiniMax-M2.7@https://litellm.jory.dev/v1 (anthropic)

PR Review: v0.2 Migration Blockers

Summary

This PR addresses v0.2 migration blockers for the Saffron agent, implementing 5 distinct changes across 10 files with comprehensive test coverage.


Change-by-Change Findings

1. Queue Endpoint Enhancement (src/app/api/agents/[agentName]/queue/route.ts)

  • Added: issueId and repoFullName fields to queue response items
  • Added: type: "issue" discriminator field on queue items
  • Impact: Workers can now identify issues without parsing URLs
  • Test coverage: 3 new tests covering issueId, repoFullName, type, and PR-fix ordering
  • Status: ✅ Correctly maps issue.id to issueId and issue.repository.fullName to repoFullName

2. New Status Endpoint (src/app/api/issues/status/route.ts)

  • New endpoint: POST /api/issues/status with bearer auth
  • Payload: { issueId, repoFullName, issueNumber, status, agentName?, actor? }
  • Valid statuses: backlog, in-progress, in-review, done
  • Behavior: Replaces existing status labels; writes AuditLog on both success/failure
  • Security: Returns 401 without valid MISSION_CONTROL_AGENT_TOKEN
  • Test coverage: 21 new tests covering auth, validation, business logic, and error handling
  • Status: ✅ Implements atomic label replacement; correctly skips GitHub calls when status unchanged

3. Move Endpoint Auth (src/app/api/issues/move/route.ts)

  • Added: Bearer auth requirement (previously unauthenticated)
  • Added: Optional actor field in body (defaults to "agent")
  • Security: Returns 401 when token missing or incorrect
  • Test coverage: 2 new auth tests; updated existing tests to include auth header
  • Status: ✅ Auth check at top of handler before any processing; audit actor now configurable

4. Claim Behavior Clarification (src/app/api/issues/claim/route.ts)

  • Changed: Claim now only adds agent/* label — no longer adds status/in-progress automatically
  • Impact: Status transitions require explicit POST /api/issues/status call
  • Rationale: Separates assignment from state management for worker control
  • Test coverage: 6 updated tests confirming status/in-progress is not added
  • Status: ✅ Correctly removes auto-status-in-progress logic; tests updated to match

5. Worker Migration Docs (docs/worker-cron-prompt-migration.md)

  • Updated: Queue response format documentation with type, issueId, repoFullName
  • Updated: Claim behavior section clearly stating "Claim only assigns"
  • Added: New /api/issues/status endpoint documentation with valid values
  • Fixed: Move endpoint payload (was incorrectly showing lane, now shows oldLabels/newLabels)
  • Updated: Migration checklist to reflect new workflow
  • Status: ✅ Documents all 5 PR changes accurately

Standards Compliance

StandardStatusNotes
Bearer auth (MISSION_CONTROL_AGENT_TOKEN)All mutation endpoints require token
AuditLog for state changesBoth move and status endpoints write audit entries
Proper HTTP status codes200, 400, 401, 404, 500 correctly used
Error handling (error instanceof Error)Used in catch blocks
No agent-specific names in docsUses generic agent/* patterns
Label conventions (status/*)Uses status/backlog, status/in-progress, etc.
PR-fix ordering preservedPR-fix items returned first

Linked Issue Fit

No linked issue context available. The PR body references "Issue #98" but no linked issue details were provided. The PR self-describes addressing 5 migration blockers, and all 5 are implemented:

  1. ✅ Queue includes issueId and repoFullName
  2. ✅ New POST /api/issues/status endpoint
  3. POST /api/issues/move requires auth
  4. ✅ Claim behavior clarified (assignment only)
  5. ✅ Worker migration docs updated

Evidence Provider Findings

No evidence providers configured.


Tool Harness Findings

Tool harness ran with 0 planned/executed requests — no external calls were made.


Unknowns / Needs Verification

  1. Token scoping: The status and move endpoints accept the same MISSION_CONTROL_AGENT_TOKEN for all agents. No per-agent scoping is implemented. This appears intentional based on existing patterns.

  2. Documentation mismatch potential: The docs/agent-workflow.md file contains a reference to claim "optionally moves it to status/in-progress" (line 86). This may need updating to reflect the new behavior, though this file was not modified in this PR.

  3. Breaking change notice: The removal of auto status/in-progress from claim is a behavior change. The migration docs address this, but existing workers may need updates before deploying this change.


Validation Results

From PR description:

  • npm ci
  • npx prisma generate
  • npm run lint
  • npm run typecheck
  • npm run test (352/352 passing)
  • npm run build

Recommendation

Approve. The PR correctly implements all 5 described migration blockers with comprehensive test coverage (352 tests passing). Code follows repository conventions, implements proper auth, writes audit logs, and maintains label conventions. The migration documentation accurately reflects the new behavior.

…th, claim behavior
- GET /api/agents/[agentName]/queue now returns issueId, repoFullName, and type:'issue' on issue items
- PR-fix items remain first in the queue response
- Added POST /api/issues/status with bearer auth for explicit status transitions
- Replaces existing status/* labels with requested status
- Updates GitHub labels, Prisma cache, and writes AuditLog
- Accepts agentName/actor as optional actor field
- Added MISSION_CONTROL_AGENT_TOKEN bearer auth to POST /api/issues/move
- Deprecated in favor of new /api/issues/status for workers
- Actor defaults to 'agent', can be overridden via body.actor
- Claim no longer auto-transitions to status/in-progress
- Claim only assigns agent/* label; status transitions are explicit via /status
- Updated worker-cron-prompt-migration.md with correct API payloads
- Documents new /api/issues/status endpoint
- Clarifies claim behavior (assign-only, explicit status)
- Fixes incorrect move payload example (shows oldLabels/newLabels)
- All 352 tests pass
@joryirving
joryirvingforce-pushed the fix/issue-98-migration-v02 branch from 49a919d to 80f3e19CompareMay 17, 2026 21:22
@joryirving
joryirving merged commit cf69a9d into mainMay 17, 2026
3 checks passed
@joryirving
joryirving deleted the fix/issue-98-migration-v02 branch May 17, 2026 21:50
joryirving added a commit that referenced this pull request Aug 5, 2026
… on them (#709)
* fix(pr-followup): skip informational bot comments instead of blocking on them
The comment path ingested every non-author comment on a bot PR as
REVIEW_FEEDBACK, so a CI bot posting a size-diff table became a work
item: classifyFeedback finds no actionable pattern in markdown, defaults
to needs_human, and the PR sits BLOCKED on a human forever.
Observed on misospace/llmkube-images#114 — a MERGEABLE, unreviewed PR
blocked since 2026-08-04 by an app-size-diff comment reporting +0 B
(+0%). Same cause on #46 and #99. The queue read 9 NEEDS_HUMAN items
when only informational noise and already-merged PRs were behind them.
Gate the comment descriptor on a new isInformationalComment(): sticky
comment markers (the sticky-pull-request-comment convention embeds one so
the action can update in place, which makes it a structural signal rather
than a prose guess) plus dispatch's own pr-fix-blocked notice. An
ai-pr-reviewer comment stays ingestible even when it carries a marker —
it ships structured findings and is genuine review feedback.
Does not address the stale-item half of the same symptom (#692): items
already queued when their PR merges are still never reaped.
Signed-off-by: Jory Irving <jory.irving@users.noreply.github.com>
* fix(test): import vi in pr-followup-ingestion tests
The informational-comment tests use vi.restoreAllMocks(); vitest globals
make that work at runtime, so the suite passed while tsc and next build
failed on TS2304.
Signed-off-by: Jory Irving <jory.irving@users.noreply.github.com>
---------
Signed-off-by: Jory Irving <jory.irving@users.noreply.github.com>
Co-authored-by: Jory Irving <jory.irving@users.noreply.github.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@itsmiso-ai@joryirving
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix: v0.2 migration blockers — queue fields, status endpoint, move auth, claim behavior - #99

Merged
joryirving merged 1 commit into
mainfrom
fix/issue-98-migration-v02
May 17, 2026
Merged

fix: v0.2 migration blockers — queue fields, status endpoint, move auth, claim behavior#99
joryirving merged 1 commit into
mainfrom
fix/issue-98-migration-v02

Conversation

@itsmiso-ai

Copy link
Copy Markdown
Contributor

Summary

Fixes all v0.2 migration blockers so Saffron can safely migrate. Addresses 5 problems identified in Issue #98.

Changes

1. Queue now includes issueId and repoFullName

  • GET /api/agents/[agentName]/queue issue items now include:
    • type: "issue" (PR-fix items keep type: "pr-review-fix")
    • issueId — the Prisma Issue ID
    • repoFullName — e.g. "org/repo"
  • PR-fix queue items remain first in the response
  • Lane=gpt deprecated alias preserved

2. New POST /api/issues/status endpoint

  • Bearer auth required (MISSION_CONTROL_AGENT_TOKEN)
  • Payload: { issueId, repoFullName, issueNumber, status, agentName?, actor? }
  • Replaces existing status/* labels with the requested status
  • Updates GitHub labels, Prisma cache, and writes AuditLog
  • Valid statuses: backlog, in-progress, in-review, done

3. POST /api/issues/move now requires bearer auth

  • Previously unauthenticated — now rejects without valid token
  • Workers should prefer the new /api/issues/status endpoint for status transitions
  • Supports optional actor field in body (defaults to "agent")

4. Claim behavior clarified and implemented

  • Claim only assigns — adds agent/* label, does NOT change status
  • Status transition is explicit via POST /api/issues/status
  • This separates assignment from state management

5. Worker migration docs updated

  • Fixed incorrect /api/issues/move payload (now shows oldLabels/newLabels)
  • Documents new /api/issues/status endpoint
  • Clarifies claim behavior in worker prompts

Tests

All 352 tests pass, including:

  • Queue returns issueId, repoFullName, and type: "issue"
  • PR-fix items remain first
  • Status endpoint replaces status labels safely
  • Status endpoint requires bearer auth
  • /api/issues/move requires bearer auth
  • Claim no longer auto-adds status/in-progress

Validation

  • npm ci
  • npx prisma generate
  • npm run lint
  • npm run typecheck
  • npm run test ✅ (352/352 passing)
  • npm run build

@its-miso

its-misoBot commented May 17, 2026

Copy link
Copy Markdown
Contributor

Automated recommendation: APPROVE

Analysis engine: anthropic/MiniMax-M2.7@https://litellm.jory.dev/v1 (anthropic)

PR Review: v0.2 Migration Blockers

Summary

This PR addresses v0.2 migration blockers for the Saffron agent, implementing 5 distinct changes across 10 files with comprehensive test coverage.


Change-by-Change Findings

1. Queue Endpoint Enhancement (src/app/api/agents/[agentName]/queue/route.ts)

  • Added: issueId and repoFullName fields to queue response items
  • Added: type: "issue" discriminator field on queue items
  • Impact: Workers can now identify issues without parsing URLs
  • Test coverage: 3 new tests covering issueId, repoFullName, type, and PR-fix ordering
  • Status: ✅ Correctly maps issue.id to issueId and issue.repository.fullName to repoFullName

2. New Status Endpoint (src/app/api/issues/status/route.ts)

  • New endpoint: POST /api/issues/status with bearer auth
  • Payload: { issueId, repoFullName, issueNumber, status, agentName?, actor? }
  • Valid statuses: backlog, in-progress, in-review, done
  • Behavior: Replaces existing status labels; writes AuditLog on both success/failure
  • Security: Returns 401 without valid MISSION_CONTROL_AGENT_TOKEN
  • Test coverage: 21 new tests covering auth, validation, business logic, and error handling
  • Status: ✅ Implements atomic label replacement; correctly skips GitHub calls when status unchanged

3. Move Endpoint Auth (src/app/api/issues/move/route.ts)

  • Added: Bearer auth requirement (previously unauthenticated)
  • Added: Optional actor field in body (defaults to "agent")
  • Security: Returns 401 when token missing or incorrect
  • Test coverage: 2 new auth tests; updated existing tests to include auth header
  • Status: ✅ Auth check at top of handler before any processing; audit actor now configurable

4. Claim Behavior Clarification (src/app/api/issues/claim/route.ts)

  • Changed: Claim now only adds agent/* label — no longer adds status/in-progress automatically
  • Impact: Status transitions require explicit POST /api/issues/status call
  • Rationale: Separates assignment from state management for worker control
  • Test coverage: 6 updated tests confirming status/in-progress is not added
  • Status: ✅ Correctly removes auto-status-in-progress logic; tests updated to match

5. Worker Migration Docs (docs/worker-cron-prompt-migration.md)

  • Updated: Queue response format documentation with type, issueId, repoFullName
  • Updated: Claim behavior section clearly stating "Claim only assigns"
  • Added: New /api/issues/status endpoint documentation with valid values
  • Fixed: Move endpoint payload (was incorrectly showing lane, now shows oldLabels/newLabels)
  • Updated: Migration checklist to reflect new workflow
  • Status: ✅ Documents all 5 PR changes accurately

Standards Compliance

StandardStatusNotes
Bearer auth (MISSION_CONTROL_AGENT_TOKEN)All mutation endpoints require token
AuditLog for state changesBoth move and status endpoints write audit entries
Proper HTTP status codes200, 400, 401, 404, 500 correctly used
Error handling (error instanceof Error)Used in catch blocks
No agent-specific names in docsUses generic agent/* patterns
Label conventions (status/*)Uses status/backlog, status/in-progress, etc.
PR-fix ordering preservedPR-fix items returned first

Linked Issue Fit

No linked issue context available. The PR body references "Issue #98" but no linked issue details were provided. The PR self-describes addressing 5 migration blockers, and all 5 are implemented:

  1. ✅ Queue includes issueId and repoFullName
  2. ✅ New POST /api/issues/status endpoint
  3. POST /api/issues/move requires auth
  4. ✅ Claim behavior clarified (assignment only)
  5. ✅ Worker migration docs updated

Evidence Provider Findings

No evidence providers configured.


Tool Harness Findings

Tool harness ran with 0 planned/executed requests — no external calls were made.


Unknowns / Needs Verification

  1. Token scoping: The status and move endpoints accept the same MISSION_CONTROL_AGENT_TOKEN for all agents. No per-agent scoping is implemented. This appears intentional based on existing patterns.

  2. Documentation mismatch potential: The docs/agent-workflow.md file contains a reference to claim "optionally moves it to status/in-progress" (line 86). This may need updating to reflect the new behavior, though this file was not modified in this PR.

  3. Breaking change notice: The removal of auto status/in-progress from claim is a behavior change. The migration docs address this, but existing workers may need updates before deploying this change.


Validation Results

From PR description:

  • npm ci
  • npx prisma generate
  • npm run lint
  • npm run typecheck
  • npm run test (352/352 passing)
  • npm run build

Recommendation

Approve. The PR correctly implements all 5 described migration blockers with comprehensive test coverage (352 tests passing). Code follows repository conventions, implements proper auth, writes audit logs, and maintains label conventions. The migration documentation accurately reflects the new behavior.

…th, claim behavior
- GET /api/agents/[agentName]/queue now returns issueId, repoFullName, and type:'issue' on issue items
- PR-fix items remain first in the queue response
- Added POST /api/issues/status with bearer auth for explicit status transitions
- Replaces existing status/* labels with requested status
- Updates GitHub labels, Prisma cache, and writes AuditLog
- Accepts agentName/actor as optional actor field
- Added MISSION_CONTROL_AGENT_TOKEN bearer auth to POST /api/issues/move
- Deprecated in favor of new /api/issues/status for workers
- Actor defaults to 'agent', can be overridden via body.actor
- Claim no longer auto-transitions to status/in-progress
- Claim only assigns agent/* label; status transitions are explicit via /status
- Updated worker-cron-prompt-migration.md with correct API payloads
- Documents new /api/issues/status endpoint
- Clarifies claim behavior (assign-only, explicit status)
- Fixes incorrect move payload example (shows oldLabels/newLabels)
- All 352 tests pass
@joryirving
joryirvingforce-pushed the fix/issue-98-migration-v02 branch from 49a919d to 80f3e19CompareMay 17, 2026 21:22
@joryirving
joryirving merged commit cf69a9d into mainMay 17, 2026
3 checks passed
@joryirving
joryirving deleted the fix/issue-98-migration-v02 branch May 17, 2026 21:50
joryirving added a commit that referenced this pull request Aug 5, 2026
… on them (#709)
* fix(pr-followup): skip informational bot comments instead of blocking on them
The comment path ingested every non-author comment on a bot PR as
REVIEW_FEEDBACK, so a CI bot posting a size-diff table became a work
item: classifyFeedback finds no actionable pattern in markdown, defaults
to needs_human, and the PR sits BLOCKED on a human forever.
Observed on misospace/llmkube-images#114 — a MERGEABLE, unreviewed PR
blocked since 2026-08-04 by an app-size-diff comment reporting +0 B
(+0%). Same cause on #46 and #99. The queue read 9 NEEDS_HUMAN items
when only informational noise and already-merged PRs were behind them.
Gate the comment descriptor on a new isInformationalComment(): sticky
comment markers (the sticky-pull-request-comment convention embeds one so
the action can update in place, which makes it a structural signal rather
than a prose guess) plus dispatch's own pr-fix-blocked notice. An
ai-pr-reviewer comment stays ingestible even when it carries a marker —
it ships structured findings and is genuine review feedback.
Does not address the stale-item half of the same symptom (#692): items
already queued when their PR merges are still never reaped.
Signed-off-by: Jory Irving <jory.irving@users.noreply.github.com>
* fix(test): import vi in pr-followup-ingestion tests
The informational-comment tests use vi.restoreAllMocks(); vitest globals
make that work at runtime, so the suite passed while tsc and next build
failed on TS2304.
Signed-off-by: Jory Irving <jory.irving@users.noreply.github.com>
---------
Signed-off-by: Jory Irving <jory.irving@users.noreply.github.com>
Co-authored-by: Jory Irving <jory.irving@users.noreply.github.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@itsmiso-ai@joryirving
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix: v0.2 migration blockers — queue fields, status endpoint, move auth, claim behavior - #99

Merged
joryirving merged 1 commit into
mainfrom
fix/issue-98-migration-v02
May 17, 2026
Merged

fix: v0.2 migration blockers — queue fields, status endpoint, move auth, claim behavior#99
joryirving merged 1 commit into
mainfrom
fix/issue-98-migration-v02

Conversation

@itsmiso-ai

Copy link
Copy Markdown
Contributor

Summary

Fixes all v0.2 migration blockers so Saffron can safely migrate. Addresses 5 problems identified in Issue #98.

Changes

1. Queue now includes issueId and repoFullName

  • GET /api/agents/[agentName]/queue issue items now include:
    • type: "issue" (PR-fix items keep type: "pr-review-fix")
    • issueId — the Prisma Issue ID
    • repoFullName — e.g. "org/repo"
  • PR-fix queue items remain first in the response
  • Lane=gpt deprecated alias preserved

2. New POST /api/issues/status endpoint

  • Bearer auth required (MISSION_CONTROL_AGENT_TOKEN)
  • Payload: { issueId, repoFullName, issueNumber, status, agentName?, actor? }
  • Replaces existing status/* labels with the requested status
  • Updates GitHub labels, Prisma cache, and writes AuditLog
  • Valid statuses: backlog, in-progress, in-review, done

3. POST /api/issues/move now requires bearer auth

  • Previously unauthenticated — now rejects without valid token
  • Workers should prefer the new /api/issues/status endpoint for status transitions
  • Supports optional actor field in body (defaults to "agent")

4. Claim behavior clarified and implemented

  • Claim only assigns — adds agent/* label, does NOT change status
  • Status transition is explicit via POST /api/issues/status
  • This separates assignment from state management

5. Worker migration docs updated

  • Fixed incorrect /api/issues/move payload (now shows oldLabels/newLabels)
  • Documents new /api/issues/status endpoint
  • Clarifies claim behavior in worker prompts

Tests

All 352 tests pass, including:

  • Queue returns issueId, repoFullName, and type: "issue"
  • PR-fix items remain first
  • Status endpoint replaces status labels safely
  • Status endpoint requires bearer auth
  • /api/issues/move requires bearer auth
  • Claim no longer auto-adds status/in-progress

Validation

  • npm ci
  • npx prisma generate
  • npm run lint
  • npm run typecheck
  • npm run test ✅ (352/352 passing)
  • npm run build

@its-miso

its-misoBot commented May 17, 2026

Copy link
Copy Markdown
Contributor

Automated recommendation: APPROVE

Analysis engine: anthropic/MiniMax-M2.7@https://litellm.jory.dev/v1 (anthropic)

PR Review: v0.2 Migration Blockers

Summary

This PR addresses v0.2 migration blockers for the Saffron agent, implementing 5 distinct changes across 10 files with comprehensive test coverage.


Change-by-Change Findings

1. Queue Endpoint Enhancement (src/app/api/agents/[agentName]/queue/route.ts)

  • Added: issueId and repoFullName fields to queue response items
  • Added: type: "issue" discriminator field on queue items
  • Impact: Workers can now identify issues without parsing URLs
  • Test coverage: 3 new tests covering issueId, repoFullName, type, and PR-fix ordering
  • Status: ✅ Correctly maps issue.id to issueId and issue.repository.fullName to repoFullName

2. New Status Endpoint (src/app/api/issues/status/route.ts)

  • New endpoint: POST /api/issues/status with bearer auth
  • Payload: { issueId, repoFullName, issueNumber, status, agentName?, actor? }
  • Valid statuses: backlog, in-progress, in-review, done
  • Behavior: Replaces existing status labels; writes AuditLog on both success/failure
  • Security: Returns 401 without valid MISSION_CONTROL_AGENT_TOKEN
  • Test coverage: 21 new tests covering auth, validation, business logic, and error handling
  • Status: ✅ Implements atomic label replacement; correctly skips GitHub calls when status unchanged

3. Move Endpoint Auth (src/app/api/issues/move/route.ts)

  • Added: Bearer auth requirement (previously unauthenticated)
  • Added: Optional actor field in body (defaults to "agent")
  • Security: Returns 401 when token missing or incorrect
  • Test coverage: 2 new auth tests; updated existing tests to include auth header
  • Status: ✅ Auth check at top of handler before any processing; audit actor now configurable

4. Claim Behavior Clarification (src/app/api/issues/claim/route.ts)

  • Changed: Claim now only adds agent/* label — no longer adds status/in-progress automatically
  • Impact: Status transitions require explicit POST /api/issues/status call
  • Rationale: Separates assignment from state management for worker control
  • Test coverage: 6 updated tests confirming status/in-progress is not added
  • Status: ✅ Correctly removes auto-status-in-progress logic; tests updated to match

5. Worker Migration Docs (docs/worker-cron-prompt-migration.md)

  • Updated: Queue response format documentation with type, issueId, repoFullName
  • Updated: Claim behavior section clearly stating "Claim only assigns"
  • Added: New /api/issues/status endpoint documentation with valid values
  • Fixed: Move endpoint payload (was incorrectly showing lane, now shows oldLabels/newLabels)
  • Updated: Migration checklist to reflect new workflow
  • Status: ✅ Documents all 5 PR changes accurately

Standards Compliance

StandardStatusNotes
Bearer auth (MISSION_CONTROL_AGENT_TOKEN)All mutation endpoints require token
AuditLog for state changesBoth move and status endpoints write audit entries
Proper HTTP status codes200, 400, 401, 404, 500 correctly used
Error handling (error instanceof Error)Used in catch blocks
No agent-specific names in docsUses generic agent/* patterns
Label conventions (status/*)Uses status/backlog, status/in-progress, etc.
PR-fix ordering preservedPR-fix items returned first

Linked Issue Fit

No linked issue context available. The PR body references "Issue #98" but no linked issue details were provided. The PR self-describes addressing 5 migration blockers, and all 5 are implemented:

  1. ✅ Queue includes issueId and repoFullName
  2. ✅ New POST /api/issues/status endpoint
  3. POST /api/issues/move requires auth
  4. ✅ Claim behavior clarified (assignment only)
  5. ✅ Worker migration docs updated

Evidence Provider Findings

No evidence providers configured.


Tool Harness Findings

Tool harness ran with 0 planned/executed requests — no external calls were made.


Unknowns / Needs Verification

  1. Token scoping: The status and move endpoints accept the same MISSION_CONTROL_AGENT_TOKEN for all agents. No per-agent scoping is implemented. This appears intentional based on existing patterns.

  2. Documentation mismatch potential: The docs/agent-workflow.md file contains a reference to claim "optionally moves it to status/in-progress" (line 86). This may need updating to reflect the new behavior, though this file was not modified in this PR.

  3. Breaking change notice: The removal of auto status/in-progress from claim is a behavior change. The migration docs address this, but existing workers may need updates before deploying this change.


Validation Results

From PR description:

  • npm ci
  • npx prisma generate
  • npm run lint
  • npm run typecheck
  • npm run test (352/352 passing)
  • npm run build

Recommendation

Approve. The PR correctly implements all 5 described migration blockers with comprehensive test coverage (352 tests passing). Code follows repository conventions, implements proper auth, writes audit logs, and maintains label conventions. The migration documentation accurately reflects the new behavior.

…th, claim behavior
- GET /api/agents/[agentName]/queue now returns issueId, repoFullName, and type:'issue' on issue items
- PR-fix items remain first in the queue response
- Added POST /api/issues/status with bearer auth for explicit status transitions
- Replaces existing status/* labels with requested status
- Updates GitHub labels, Prisma cache, and writes AuditLog
- Accepts agentName/actor as optional actor field
- Added MISSION_CONTROL_AGENT_TOKEN bearer auth to POST /api/issues/move
- Deprecated in favor of new /api/issues/status for workers
- Actor defaults to 'agent', can be overridden via body.actor
- Claim no longer auto-transitions to status/in-progress
- Claim only assigns agent/* label; status transitions are explicit via /status
- Updated worker-cron-prompt-migration.md with correct API payloads
- Documents new /api/issues/status endpoint
- Clarifies claim behavior (assign-only, explicit status)
- Fixes incorrect move payload example (shows oldLabels/newLabels)
- All 352 tests pass
@joryirving
joryirvingforce-pushed the fix/issue-98-migration-v02 branch from 49a919d to 80f3e19CompareMay 17, 2026 21:22
@joryirving
joryirving merged commit cf69a9d into mainMay 17, 2026
3 checks passed
@joryirving
joryirving deleted the fix/issue-98-migration-v02 branch May 17, 2026 21:50
joryirving added a commit that referenced this pull request Aug 5, 2026
… on them (#709)
* fix(pr-followup): skip informational bot comments instead of blocking on them
The comment path ingested every non-author comment on a bot PR as
REVIEW_FEEDBACK, so a CI bot posting a size-diff table became a work
item: classifyFeedback finds no actionable pattern in markdown, defaults
to needs_human, and the PR sits BLOCKED on a human forever.
Observed on misospace/llmkube-images#114 — a MERGEABLE, unreviewed PR
blocked since 2026-08-04 by an app-size-diff comment reporting +0 B
(+0%). Same cause on #46 and #99. The queue read 9 NEEDS_HUMAN items
when only informational noise and already-merged PRs were behind them.
Gate the comment descriptor on a new isInformationalComment(): sticky
comment markers (the sticky-pull-request-comment convention embeds one so
the action can update in place, which makes it a structural signal rather
than a prose guess) plus dispatch's own pr-fix-blocked notice. An
ai-pr-reviewer comment stays ingestible even when it carries a marker —
it ships structured findings and is genuine review feedback.
Does not address the stale-item half of the same symptom (#692): items
already queued when their PR merges are still never reaped.
Signed-off-by: Jory Irving <jory.irving@users.noreply.github.com>
* fix(test): import vi in pr-followup-ingestion tests
The informational-comment tests use vi.restoreAllMocks(); vitest globals
make that work at runtime, so the suite passed while tsc and next build
failed on TS2304.
Signed-off-by: Jory Irving <jory.irving@users.noreply.github.com>
---------
Signed-off-by: Jory Irving <jory.irving@users.noreply.github.com>
Co-authored-by: Jory Irving <jory.irving@users.noreply.github.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@itsmiso-ai@joryirving
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

fix: v0.2 migration blockers — queue fields, status endpoint, move auth, claim behavior - #99

Merged
joryirving merged 1 commit into
mainfrom
fix/issue-98-migration-v02
May 17, 2026
Merged

fix: v0.2 migration blockers — queue fields, status endpoint, move auth, claim behavior#99
joryirving merged 1 commit into
mainfrom
fix/issue-98-migration-v02

Conversation

@itsmiso-ai

Copy link
Copy Markdown
Contributor

Summary

Fixes all v0.2 migration blockers so Saffron can safely migrate. Addresses 5 problems identified in Issue #98.

Changes

1. Queue now includes issueId and repoFullName

  • GET /api/agents/[agentName]/queue issue items now include:
    • type: "issue" (PR-fix items keep type: "pr-review-fix")
    • issueId — the Prisma Issue ID
    • repoFullName — e.g. "org/repo"
  • PR-fix queue items remain first in the response
  • Lane=gpt deprecated alias preserved

2. New POST /api/issues/status endpoint

  • Bearer auth required (MISSION_CONTROL_AGENT_TOKEN)
  • Payload: { issueId, repoFullName, issueNumber, status, agentName?, actor? }
  • Replaces existing status/* labels with the requested status
  • Updates GitHub labels, Prisma cache, and writes AuditLog
  • Valid statuses: backlog, in-progress, in-review, done

3. POST /api/issues/move now requires bearer auth

  • Previously unauthenticated — now rejects without valid token
  • Workers should prefer the new /api/issues/status endpoint for status transitions
  • Supports optional actor field in body (defaults to "agent")

4. Claim behavior clarified and implemented

  • Claim only assigns — adds agent/* label, does NOT change status
  • Status transition is explicit via POST /api/issues/status
  • This separates assignment from state management

5. Worker migration docs updated

  • Fixed incorrect /api/issues/move payload (now shows oldLabels/newLabels)
  • Documents new /api/issues/status endpoint
  • Clarifies claim behavior in worker prompts

Tests

All 352 tests pass, including:

  • Queue returns issueId, repoFullName, and type: "issue"
  • PR-fix items remain first
  • Status endpoint replaces status labels safely
  • Status endpoint requires bearer auth
  • /api/issues/move requires bearer auth
  • Claim no longer auto-adds status/in-progress

Validation

  • npm ci
  • npx prisma generate
  • npm run lint
  • npm run typecheck
  • npm run test ✅ (352/352 passing)
  • npm run build

@its-miso

its-misoBot commented May 17, 2026

Copy link
Copy Markdown
Contributor

Automated recommendation: APPROVE

Analysis engine: anthropic/MiniMax-M2.7@https://litellm.jory.dev/v1 (anthropic)

PR Review: v0.2 Migration Blockers

Summary

This PR addresses v0.2 migration blockers for the Saffron agent, implementing 5 distinct changes across 10 files with comprehensive test coverage.


Change-by-Change Findings

1. Queue Endpoint Enhancement (src/app/api/agents/[agentName]/queue/route.ts)

  • Added: issueId and repoFullName fields to queue response items
  • Added: type: "issue" discriminator field on queue items
  • Impact: Workers can now identify issues without parsing URLs
  • Test coverage: 3 new tests covering issueId, repoFullName, type, and PR-fix ordering
  • Status: ✅ Correctly maps issue.id to issueId and issue.repository.fullName to repoFullName

2. New Status Endpoint (src/app/api/issues/status/route.ts)

  • New endpoint: POST /api/issues/status with bearer auth
  • Payload: { issueId, repoFullName, issueNumber, status, agentName?, actor? }
  • Valid statuses: backlog, in-progress, in-review, done
  • Behavior: Replaces existing status labels; writes AuditLog on both success/failure
  • Security: Returns 401 without valid MISSION_CONTROL_AGENT_TOKEN
  • Test coverage: 21 new tests covering auth, validation, business logic, and error handling
  • Status: ✅ Implements atomic label replacement; correctly skips GitHub calls when status unchanged

3. Move Endpoint Auth (src/app/api/issues/move/route.ts)

  • Added: Bearer auth requirement (previously unauthenticated)
  • Added: Optional actor field in body (defaults to "agent")
  • Security: Returns 401 when token missing or incorrect
  • Test coverage: 2 new auth tests; updated existing tests to include auth header
  • Status: ✅ Auth check at top of handler before any processing; audit actor now configurable

4. Claim Behavior Clarification (src/app/api/issues/claim/route.ts)

  • Changed: Claim now only adds agent/* label — no longer adds status/in-progress automatically
  • Impact: Status transitions require explicit POST /api/issues/status call
  • Rationale: Separates assignment from state management for worker control
  • Test coverage: 6 updated tests confirming status/in-progress is not added
  • Status: ✅ Correctly removes auto-status-in-progress logic; tests updated to match

5. Worker Migration Docs (docs/worker-cron-prompt-migration.md)

  • Updated: Queue response format documentation with type, issueId, repoFullName
  • Updated: Claim behavior section clearly stating "Claim only assigns"
  • Added: New /api/issues/status endpoint documentation with valid values
  • Fixed: Move endpoint payload (was incorrectly showing lane, now shows oldLabels/newLabels)
  • Updated: Migration checklist to reflect new workflow
  • Status: ✅ Documents all 5 PR changes accurately

Standards Compliance

StandardStatusNotes
Bearer auth (MISSION_CONTROL_AGENT_TOKEN)All mutation endpoints require token
AuditLog for state changesBoth move and status endpoints write audit entries
Proper HTTP status codes200, 400, 401, 404, 500 correctly used
Error handling (error instanceof Error)Used in catch blocks
No agent-specific names in docsUses generic agent/* patterns
Label conventions (status/*)Uses status/backlog, status/in-progress, etc.
PR-fix ordering preservedPR-fix items returned first

Linked Issue Fit

No linked issue context available. The PR body references "Issue #98" but no linked issue details were provided. The PR self-describes addressing 5 migration blockers, and all 5 are implemented:

  1. ✅ Queue includes issueId and repoFullName
  2. ✅ New POST /api/issues/status endpoint
  3. POST /api/issues/move requires auth
  4. ✅ Claim behavior clarified (assignment only)
  5. ✅ Worker migration docs updated

Evidence Provider Findings

No evidence providers configured.


Tool Harness Findings

Tool harness ran with 0 planned/executed requests — no external calls were made.


Unknowns / Needs Verification

  1. Token scoping: The status and move endpoints accept the same MISSION_CONTROL_AGENT_TOKEN for all agents. No per-agent scoping is implemented. This appears intentional based on existing patterns.

  2. Documentation mismatch potential: The docs/agent-workflow.md file contains a reference to claim "optionally moves it to status/in-progress" (line 86). This may need updating to reflect the new behavior, though this file was not modified in this PR.

  3. Breaking change notice: The removal of auto status/in-progress from claim is a behavior change. The migration docs address this, but existing workers may need updates before deploying this change.


Validation Results

From PR description:

  • npm ci
  • npx prisma generate
  • npm run lint
  • npm run typecheck
  • npm run test (352/352 passing)
  • npm run build

Recommendation

Approve. The PR correctly implements all 5 described migration blockers with comprehensive test coverage (352 tests passing). Code follows repository conventions, implements proper auth, writes audit logs, and maintains label conventions. The migration documentation accurately reflects the new behavior.

…th, claim behavior
- GET /api/agents/[agentName]/queue now returns issueId, repoFullName, and type:'issue' on issue items
- PR-fix items remain first in the queue response
- Added POST /api/issues/status with bearer auth for explicit status transitions
- Replaces existing status/* labels with requested status
- Updates GitHub labels, Prisma cache, and writes AuditLog
- Accepts agentName/actor as optional actor field
- Added MISSION_CONTROL_AGENT_TOKEN bearer auth to POST /api/issues/move
- Deprecated in favor of new /api/issues/status for workers
- Actor defaults to 'agent', can be overridden via body.actor
- Claim no longer auto-transitions to status/in-progress
- Claim only assigns agent/* label; status transitions are explicit via /status
- Updated worker-cron-prompt-migration.md with correct API payloads
- Documents new /api/issues/status endpoint
- Clarifies claim behavior (assign-only, explicit status)
- Fixes incorrect move payload example (shows oldLabels/newLabels)
- All 352 tests pass
@joryirving
joryirvingforce-pushed the fix/issue-98-migration-v02 branch from 49a919d to 80f3e19CompareMay 17, 2026 21:22
@joryirving
joryirving merged commit cf69a9d into mainMay 17, 2026
3 checks passed
@joryirving
joryirving deleted the fix/issue-98-migration-v02 branch May 17, 2026 21:50
joryirving added a commit that referenced this pull request Aug 5, 2026
… on them (#709)
* fix(pr-followup): skip informational bot comments instead of blocking on them
The comment path ingested every non-author comment on a bot PR as
REVIEW_FEEDBACK, so a CI bot posting a size-diff table became a work
item: classifyFeedback finds no actionable pattern in markdown, defaults
to needs_human, and the PR sits BLOCKED on a human forever.
Observed on misospace/llmkube-images#114 — a MERGEABLE, unreviewed PR
blocked since 2026-08-04 by an app-size-diff comment reporting +0 B
(+0%). Same cause on #46 and #99. The queue read 9 NEEDS_HUMAN items
when only informational noise and already-merged PRs were behind them.
Gate the comment descriptor on a new isInformationalComment(): sticky
comment markers (the sticky-pull-request-comment convention embeds one so
the action can update in place, which makes it a structural signal rather
than a prose guess) plus dispatch's own pr-fix-blocked notice. An
ai-pr-reviewer comment stays ingestible even when it carries a marker —
it ships structured findings and is genuine review feedback.
Does not address the stale-item half of the same symptom (#692): items
already queued when their PR merges are still never reaped.
Signed-off-by: Jory Irving <jory.irving@users.noreply.github.com>
* fix(test): import vi in pr-followup-ingestion tests
The informational-comment tests use vi.restoreAllMocks(); vitest globals
make that work at runtime, so the suite passed while tsc and next build
failed on TS2304.
Signed-off-by: Jory Irving <jory.irving@users.noreply.github.com>
---------
Signed-off-by: Jory Irving <jory.irving@users.noreply.github.com>
Co-authored-by: Jory Irving <jory.irving@users.noreply.github.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@itsmiso-ai@joryirving
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix: v0.2 migration blockers — queue fields, status endpoint, move auth, claim behavior - #99

Merged
joryirving merged 1 commit into
mainfrom
fix/issue-98-migration-v02
May 17, 2026
Merged

fix: v0.2 migration blockers — queue fields, status endpoint, move auth, claim behavior#99
joryirving merged 1 commit into
mainfrom
fix/issue-98-migration-v02

Conversation

@itsmiso-ai

Copy link
Copy Markdown
Contributor

Summary

Fixes all v0.2 migration blockers so Saffron can safely migrate. Addresses 5 problems identified in Issue #98.

Changes

1. Queue now includes issueId and repoFullName

  • GET /api/agents/[agentName]/queue issue items now include:
    • type: "issue" (PR-fix items keep type: "pr-review-fix")
    • issueId — the Prisma Issue ID
    • repoFullName — e.g. "org/repo"
  • PR-fix queue items remain first in the response
  • Lane=gpt deprecated alias preserved

2. New POST /api/issues/status endpoint

  • Bearer auth required (MISSION_CONTROL_AGENT_TOKEN)
  • Payload: { issueId, repoFullName, issueNumber, status, agentName?, actor? }
  • Replaces existing status/* labels with the requested status
  • Updates GitHub labels, Prisma cache, and writes AuditLog
  • Valid statuses: backlog, in-progress, in-review, done

3. POST /api/issues/move now requires bearer auth

  • Previously unauthenticated — now rejects without valid token
  • Workers should prefer the new /api/issues/status endpoint for status transitions
  • Supports optional actor field in body (defaults to "agent")

4. Claim behavior clarified and implemented

  • Claim only assigns — adds agent/* label, does NOT change status
  • Status transition is explicit via POST /api/issues/status
  • This separates assignment from state management

5. Worker migration docs updated

  • Fixed incorrect /api/issues/move payload (now shows oldLabels/newLabels)
  • Documents new /api/issues/status endpoint
  • Clarifies claim behavior in worker prompts

Tests

All 352 tests pass, including:

  • Queue returns issueId, repoFullName, and type: "issue"
  • PR-fix items remain first
  • Status endpoint replaces status labels safely
  • Status endpoint requires bearer auth
  • /api/issues/move requires bearer auth
  • Claim no longer auto-adds status/in-progress

Validation

  • npm ci
  • npx prisma generate
  • npm run lint
  • npm run typecheck
  • npm run test ✅ (352/352 passing)
  • npm run build

@its-miso

its-misoBot commented May 17, 2026

Copy link
Copy Markdown
Contributor

Automated recommendation: APPROVE

Analysis engine: anthropic/MiniMax-M2.7@https://litellm.jory.dev/v1 (anthropic)

PR Review: v0.2 Migration Blockers

Summary

This PR addresses v0.2 migration blockers for the Saffron agent, implementing 5 distinct changes across 10 files with comprehensive test coverage.


Change-by-Change Findings

1. Queue Endpoint Enhancement (src/app/api/agents/[agentName]/queue/route.ts)

  • Added: issueId and repoFullName fields to queue response items
  • Added: type: "issue" discriminator field on queue items
  • Impact: Workers can now identify issues without parsing URLs
  • Test coverage: 3 new tests covering issueId, repoFullName, type, and PR-fix ordering
  • Status: ✅ Correctly maps issue.id to issueId and issue.repository.fullName to repoFullName

2. New Status Endpoint (src/app/api/issues/status/route.ts)

  • New endpoint: POST /api/issues/status with bearer auth
  • Payload: { issueId, repoFullName, issueNumber, status, agentName?, actor? }
  • Valid statuses: backlog, in-progress, in-review, done
  • Behavior: Replaces existing status labels; writes AuditLog on both success/failure
  • Security: Returns 401 without valid MISSION_CONTROL_AGENT_TOKEN
  • Test coverage: 21 new tests covering auth, validation, business logic, and error handling
  • Status: ✅ Implements atomic label replacement; correctly skips GitHub calls when status unchanged

3. Move Endpoint Auth (src/app/api/issues/move/route.ts)

  • Added: Bearer auth requirement (previously unauthenticated)
  • Added: Optional actor field in body (defaults to "agent")
  • Security: Returns 401 when token missing or incorrect
  • Test coverage: 2 new auth tests; updated existing tests to include auth header
  • Status: ✅ Auth check at top of handler before any processing; audit actor now configurable

4. Claim Behavior Clarification (src/app/api/issues/claim/route.ts)

  • Changed: Claim now only adds agent/* label — no longer adds status/in-progress automatically
  • Impact: Status transitions require explicit POST /api/issues/status call
  • Rationale: Separates assignment from state management for worker control
  • Test coverage: 6 updated tests confirming status/in-progress is not added
  • Status: ✅ Correctly removes auto-status-in-progress logic; tests updated to match

5. Worker Migration Docs (docs/worker-cron-prompt-migration.md)

  • Updated: Queue response format documentation with type, issueId, repoFullName
  • Updated: Claim behavior section clearly stating "Claim only assigns"
  • Added: New /api/issues/status endpoint documentation with valid values
  • Fixed: Move endpoint payload (was incorrectly showing lane, now shows oldLabels/newLabels)
  • Updated: Migration checklist to reflect new workflow
  • Status: ✅ Documents all 5 PR changes accurately

Standards Compliance

StandardStatusNotes
Bearer auth (MISSION_CONTROL_AGENT_TOKEN)All mutation endpoints require token
AuditLog for state changesBoth move and status endpoints write audit entries
Proper HTTP status codes200, 400, 401, 404, 500 correctly used
Error handling (error instanceof Error)Used in catch blocks
No agent-specific names in docsUses generic agent/* patterns
Label conventions (status/*)Uses status/backlog, status/in-progress, etc.
PR-fix ordering preservedPR-fix items returned first

Linked Issue Fit

No linked issue context available. The PR body references "Issue #98" but no linked issue details were provided. The PR self-describes addressing 5 migration blockers, and all 5 are implemented:

  1. ✅ Queue includes issueId and repoFullName
  2. ✅ New POST /api/issues/status endpoint
  3. POST /api/issues/move requires auth
  4. ✅ Claim behavior clarified (assignment only)
  5. ✅ Worker migration docs updated

Evidence Provider Findings

No evidence providers configured.


Tool Harness Findings

Tool harness ran with 0 planned/executed requests — no external calls were made.


Unknowns / Needs Verification

  1. Token scoping: The status and move endpoints accept the same MISSION_CONTROL_AGENT_TOKEN for all agents. No per-agent scoping is implemented. This appears intentional based on existing patterns.

  2. Documentation mismatch potential: The docs/agent-workflow.md file contains a reference to claim "optionally moves it to status/in-progress" (line 86). This may need updating to reflect the new behavior, though this file was not modified in this PR.

  3. Breaking change notice: The removal of auto status/in-progress from claim is a behavior change. The migration docs address this, but existing workers may need updates before deploying this change.


Validation Results

From PR description:

  • npm ci
  • npx prisma generate
  • npm run lint
  • npm run typecheck
  • npm run test (352/352 passing)
  • npm run build

Recommendation

Approve. The PR correctly implements all 5 described migration blockers with comprehensive test coverage (352 tests passing). Code follows repository conventions, implements proper auth, writes audit logs, and maintains label conventions. The migration documentation accurately reflects the new behavior.

…th, claim behavior
- GET /api/agents/[agentName]/queue now returns issueId, repoFullName, and type:'issue' on issue items
- PR-fix items remain first in the queue response
- Added POST /api/issues/status with bearer auth for explicit status transitions
- Replaces existing status/* labels with requested status
- Updates GitHub labels, Prisma cache, and writes AuditLog
- Accepts agentName/actor as optional actor field
- Added MISSION_CONTROL_AGENT_TOKEN bearer auth to POST /api/issues/move
- Deprecated in favor of new /api/issues/status for workers
- Actor defaults to 'agent', can be overridden via body.actor
- Claim no longer auto-transitions to status/in-progress
- Claim only assigns agent/* label; status transitions are explicit via /status
- Updated worker-cron-prompt-migration.md with correct API payloads
- Documents new /api/issues/status endpoint
- Clarifies claim behavior (assign-only, explicit status)
- Fixes incorrect move payload example (shows oldLabels/newLabels)
- All 352 tests pass
@joryirving
joryirvingforce-pushed the fix/issue-98-migration-v02 branch from 49a919d to 80f3e19CompareMay 17, 2026 21:22
@joryirving
joryirving merged commit cf69a9d into mainMay 17, 2026
3 checks passed
@joryirving
joryirving deleted the fix/issue-98-migration-v02 branch May 17, 2026 21:50
joryirving added a commit that referenced this pull request Aug 5, 2026
… on them (#709)
* fix(pr-followup): skip informational bot comments instead of blocking on them
The comment path ingested every non-author comment on a bot PR as
REVIEW_FEEDBACK, so a CI bot posting a size-diff table became a work
item: classifyFeedback finds no actionable pattern in markdown, defaults
to needs_human, and the PR sits BLOCKED on a human forever.
Observed on misospace/llmkube-images#114 — a MERGEABLE, unreviewed PR
blocked since 2026-08-04 by an app-size-diff comment reporting +0 B
(+0%). Same cause on #46 and #99. The queue read 9 NEEDS_HUMAN items
when only informational noise and already-merged PRs were behind them.
Gate the comment descriptor on a new isInformationalComment(): sticky
comment markers (the sticky-pull-request-comment convention embeds one so
the action can update in place, which makes it a structural signal rather
than a prose guess) plus dispatch's own pr-fix-blocked notice. An
ai-pr-reviewer comment stays ingestible even when it carries a marker —
it ships structured findings and is genuine review feedback.
Does not address the stale-item half of the same symptom (#692): items
already queued when their PR merges are still never reaped.
Signed-off-by: Jory Irving <jory.irving@users.noreply.github.com>
* fix(test): import vi in pr-followup-ingestion tests
The informational-comment tests use vi.restoreAllMocks(); vitest globals
make that work at runtime, so the suite passed while tsc and next build
failed on TS2304.
Signed-off-by: Jory Irving <jory.irving@users.noreply.github.com>
---------
Signed-off-by: Jory Irving <jory.irving@users.noreply.github.com>
Co-authored-by: Jory Irving <jory.irving@users.noreply.github.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@itsmiso-ai@joryirving
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix: v0.2 migration blockers — queue fields, status endpoint, move auth, claim behavior - #99

Merged
joryirving merged 1 commit into
mainfrom
fix/issue-98-migration-v02
May 17, 2026
Merged

fix: v0.2 migration blockers — queue fields, status endpoint, move auth, claim behavior#99
joryirving merged 1 commit into
mainfrom
fix/issue-98-migration-v02

Conversation

@itsmiso-ai

Copy link
Copy Markdown
Contributor

Summary

Fixes all v0.2 migration blockers so Saffron can safely migrate. Addresses 5 problems identified in Issue #98.

Changes

1. Queue now includes issueId and repoFullName

  • GET /api/agents/[agentName]/queue issue items now include:
    • type: "issue" (PR-fix items keep type: "pr-review-fix")
    • issueId — the Prisma Issue ID
    • repoFullName — e.g. "org/repo"
  • PR-fix queue items remain first in the response
  • Lane=gpt deprecated alias preserved

2. New POST /api/issues/status endpoint

  • Bearer auth required (MISSION_CONTROL_AGENT_TOKEN)
  • Payload: { issueId, repoFullName, issueNumber, status, agentName?, actor? }
  • Replaces existing status/* labels with the requested status
  • Updates GitHub labels, Prisma cache, and writes AuditLog
  • Valid statuses: backlog, in-progress, in-review, done

3. POST /api/issues/move now requires bearer auth

  • Previously unauthenticated — now rejects without valid token
  • Workers should prefer the new /api/issues/status endpoint for status transitions
  • Supports optional actor field in body (defaults to "agent")

4. Claim behavior clarified and implemented

  • Claim only assigns — adds agent/* label, does NOT change status
  • Status transition is explicit via POST /api/issues/status
  • This separates assignment from state management

5. Worker migration docs updated

  • Fixed incorrect /api/issues/move payload (now shows oldLabels/newLabels)
  • Documents new /api/issues/status endpoint
  • Clarifies claim behavior in worker prompts

Tests

All 352 tests pass, including:

  • Queue returns issueId, repoFullName, and type: "issue"
  • PR-fix items remain first
  • Status endpoint replaces status labels safely
  • Status endpoint requires bearer auth
  • /api/issues/move requires bearer auth
  • Claim no longer auto-adds status/in-progress

Validation

  • npm ci
  • npx prisma generate
  • npm run lint
  • npm run typecheck
  • npm run test ✅ (352/352 passing)
  • npm run build

@its-miso

its-misoBot commented May 17, 2026

Copy link
Copy Markdown
Contributor

Automated recommendation: APPROVE

Analysis engine: anthropic/MiniMax-M2.7@https://litellm.jory.dev/v1 (anthropic)

PR Review: v0.2 Migration Blockers

Summary

This PR addresses v0.2 migration blockers for the Saffron agent, implementing 5 distinct changes across 10 files with comprehensive test coverage.


Change-by-Change Findings

1. Queue Endpoint Enhancement (src/app/api/agents/[agentName]/queue/route.ts)

  • Added: issueId and repoFullName fields to queue response items
  • Added: type: "issue" discriminator field on queue items
  • Impact: Workers can now identify issues without parsing URLs
  • Test coverage: 3 new tests covering issueId, repoFullName, type, and PR-fix ordering
  • Status: ✅ Correctly maps issue.id to issueId and issue.repository.fullName to repoFullName

2. New Status Endpoint (src/app/api/issues/status/route.ts)

  • New endpoint: POST /api/issues/status with bearer auth
  • Payload: { issueId, repoFullName, issueNumber, status, agentName?, actor? }
  • Valid statuses: backlog, in-progress, in-review, done
  • Behavior: Replaces existing status labels; writes AuditLog on both success/failure
  • Security: Returns 401 without valid MISSION_CONTROL_AGENT_TOKEN
  • Test coverage: 21 new tests covering auth, validation, business logic, and error handling
  • Status: ✅ Implements atomic label replacement; correctly skips GitHub calls when status unchanged

3. Move Endpoint Auth (src/app/api/issues/move/route.ts)

  • Added: Bearer auth requirement (previously unauthenticated)
  • Added: Optional actor field in body (defaults to "agent")
  • Security: Returns 401 when token missing or incorrect
  • Test coverage: 2 new auth tests; updated existing tests to include auth header
  • Status: ✅ Auth check at top of handler before any processing; audit actor now configurable

4. Claim Behavior Clarification (src/app/api/issues/claim/route.ts)

  • Changed: Claim now only adds agent/* label — no longer adds status/in-progress automatically
  • Impact: Status transitions require explicit POST /api/issues/status call
  • Rationale: Separates assignment from state management for worker control
  • Test coverage: 6 updated tests confirming status/in-progress is not added
  • Status: ✅ Correctly removes auto-status-in-progress logic; tests updated to match

5. Worker Migration Docs (docs/worker-cron-prompt-migration.md)

  • Updated: Queue response format documentation with type, issueId, repoFullName
  • Updated: Claim behavior section clearly stating "Claim only assigns"
  • Added: New /api/issues/status endpoint documentation with valid values
  • Fixed: Move endpoint payload (was incorrectly showing lane, now shows oldLabels/newLabels)
  • Updated: Migration checklist to reflect new workflow
  • Status: ✅ Documents all 5 PR changes accurately

Standards Compliance

StandardStatusNotes
Bearer auth (MISSION_CONTROL_AGENT_TOKEN)All mutation endpoints require token
AuditLog for state changesBoth move and status endpoints write audit entries
Proper HTTP status codes200, 400, 401, 404, 500 correctly used
Error handling (error instanceof Error)Used in catch blocks
No agent-specific names in docsUses generic agent/* patterns
Label conventions (status/*)Uses status/backlog, status/in-progress, etc.
PR-fix ordering preservedPR-fix items returned first

Linked Issue Fit

No linked issue context available. The PR body references "Issue #98" but no linked issue details were provided. The PR self-describes addressing 5 migration blockers, and all 5 are implemented:

  1. ✅ Queue includes issueId and repoFullName
  2. ✅ New POST /api/issues/status endpoint
  3. POST /api/issues/move requires auth
  4. ✅ Claim behavior clarified (assignment only)
  5. ✅ Worker migration docs updated

Evidence Provider Findings

No evidence providers configured.


Tool Harness Findings

Tool harness ran with 0 planned/executed requests — no external calls were made.


Unknowns / Needs Verification

  1. Token scoping: The status and move endpoints accept the same MISSION_CONTROL_AGENT_TOKEN for all agents. No per-agent scoping is implemented. This appears intentional based on existing patterns.

  2. Documentation mismatch potential: The docs/agent-workflow.md file contains a reference to claim "optionally moves it to status/in-progress" (line 86). This may need updating to reflect the new behavior, though this file was not modified in this PR.

  3. Breaking change notice: The removal of auto status/in-progress from claim is a behavior change. The migration docs address this, but existing workers may need updates before deploying this change.


Validation Results

From PR description:

  • npm ci
  • npx prisma generate
  • npm run lint
  • npm run typecheck
  • npm run test (352/352 passing)
  • npm run build

Recommendation

Approve. The PR correctly implements all 5 described migration blockers with comprehensive test coverage (352 tests passing). Code follows repository conventions, implements proper auth, writes audit logs, and maintains label conventions. The migration documentation accurately reflects the new behavior.

…th, claim behavior
- GET /api/agents/[agentName]/queue now returns issueId, repoFullName, and type:'issue' on issue items
- PR-fix items remain first in the queue response
- Added POST /api/issues/status with bearer auth for explicit status transitions
- Replaces existing status/* labels with requested status
- Updates GitHub labels, Prisma cache, and writes AuditLog
- Accepts agentName/actor as optional actor field
- Added MISSION_CONTROL_AGENT_TOKEN bearer auth to POST /api/issues/move
- Deprecated in favor of new /api/issues/status for workers
- Actor defaults to 'agent', can be overridden via body.actor
- Claim no longer auto-transitions to status/in-progress
- Claim only assigns agent/* label; status transitions are explicit via /status
- Updated worker-cron-prompt-migration.md with correct API payloads
- Documents new /api/issues/status endpoint
- Clarifies claim behavior (assign-only, explicit status)
- Fixes incorrect move payload example (shows oldLabels/newLabels)
- All 352 tests pass
@joryirving
joryirvingforce-pushed the fix/issue-98-migration-v02 branch from 49a919d to 80f3e19CompareMay 17, 2026 21:22
@joryirving
joryirving merged commit cf69a9d into mainMay 17, 2026
3 checks passed
@joryirving
joryirving deleted the fix/issue-98-migration-v02 branch May 17, 2026 21:50
joryirving added a commit that referenced this pull request Aug 5, 2026
… on them (#709)
* fix(pr-followup): skip informational bot comments instead of blocking on them
The comment path ingested every non-author comment on a bot PR as
REVIEW_FEEDBACK, so a CI bot posting a size-diff table became a work
item: classifyFeedback finds no actionable pattern in markdown, defaults
to needs_human, and the PR sits BLOCKED on a human forever.
Observed on misospace/llmkube-images#114 — a MERGEABLE, unreviewed PR
blocked since 2026-08-04 by an app-size-diff comment reporting +0 B
(+0%). Same cause on #46 and #99. The queue read 9 NEEDS_HUMAN items
when only informational noise and already-merged PRs were behind them.
Gate the comment descriptor on a new isInformationalComment(): sticky
comment markers (the sticky-pull-request-comment convention embeds one so
the action can update in place, which makes it a structural signal rather
than a prose guess) plus dispatch's own pr-fix-blocked notice. An
ai-pr-reviewer comment stays ingestible even when it carries a marker —
it ships structured findings and is genuine review feedback.
Does not address the stale-item half of the same symptom (#692): items
already queued when their PR merges are still never reaped.
Signed-off-by: Jory Irving <jory.irving@users.noreply.github.com>
* fix(test): import vi in pr-followup-ingestion tests
The informational-comment tests use vi.restoreAllMocks(); vitest globals
make that work at runtime, so the suite passed while tsc and next build
failed on TS2304.
Signed-off-by: Jory Irving <jory.irving@users.noreply.github.com>
---------
Signed-off-by: Jory Irving <jory.irving@users.noreply.github.com>
Co-authored-by: Jory Irving <jory.irving@users.noreply.github.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@itsmiso-ai@joryirving
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

fix: v0.2 migration blockers — queue fields, status endpoint, move auth, claim behavior - #99

Merged
joryirving merged 1 commit into
mainfrom
fix/issue-98-migration-v02
May 17, 2026
Merged

fix: v0.2 migration blockers — queue fields, status endpoint, move auth, claim behavior#99
joryirving merged 1 commit into
mainfrom
fix/issue-98-migration-v02

Conversation

@itsmiso-ai

Copy link
Copy Markdown
Contributor

Summary

Fixes all v0.2 migration blockers so Saffron can safely migrate. Addresses 5 problems identified in Issue #98.

Changes

1. Queue now includes issueId and repoFullName

  • GET /api/agents/[agentName]/queue issue items now include:
    • type: "issue" (PR-fix items keep type: "pr-review-fix")
    • issueId — the Prisma Issue ID
    • repoFullName — e.g. "org/repo"
  • PR-fix queue items remain first in the response
  • Lane=gpt deprecated alias preserved

2. New POST /api/issues/status endpoint

  • Bearer auth required (MISSION_CONTROL_AGENT_TOKEN)
  • Payload: { issueId, repoFullName, issueNumber, status, agentName?, actor? }
  • Replaces existing status/* labels with the requested status
  • Updates GitHub labels, Prisma cache, and writes AuditLog
  • Valid statuses: backlog, in-progress, in-review, done

3. POST /api/issues/move now requires bearer auth

  • Previously unauthenticated — now rejects without valid token
  • Workers should prefer the new /api/issues/status endpoint for status transitions
  • Supports optional actor field in body (defaults to "agent")

4. Claim behavior clarified and implemented

  • Claim only assigns — adds agent/* label, does NOT change status
  • Status transition is explicit via POST /api/issues/status
  • This separates assignment from state management

5. Worker migration docs updated

  • Fixed incorrect /api/issues/move payload (now shows oldLabels/newLabels)
  • Documents new /api/issues/status endpoint
  • Clarifies claim behavior in worker prompts

Tests

All 352 tests pass, including:

  • Queue returns issueId, repoFullName, and type: "issue"
  • PR-fix items remain first
  • Status endpoint replaces status labels safely
  • Status endpoint requires bearer auth
  • /api/issues/move requires bearer auth
  • Claim no longer auto-adds status/in-progress

Validation

  • npm ci
  • npx prisma generate
  • npm run lint
  • npm run typecheck
  • npm run test ✅ (352/352 passing)
  • npm run build

@its-miso

its-misoBot commented May 17, 2026

Copy link
Copy Markdown
Contributor

Automated recommendation: APPROVE

Analysis engine: anthropic/MiniMax-M2.7@https://litellm.jory.dev/v1 (anthropic)

PR Review: v0.2 Migration Blockers

Summary

This PR addresses v0.2 migration blockers for the Saffron agent, implementing 5 distinct changes across 10 files with comprehensive test coverage.


Change-by-Change Findings

1. Queue Endpoint Enhancement (src/app/api/agents/[agentName]/queue/route.ts)

  • Added: issueId and repoFullName fields to queue response items
  • Added: type: "issue" discriminator field on queue items
  • Impact: Workers can now identify issues without parsing URLs
  • Test coverage: 3 new tests covering issueId, repoFullName, type, and PR-fix ordering
  • Status: ✅ Correctly maps issue.id to issueId and issue.repository.fullName to repoFullName

2. New Status Endpoint (src/app/api/issues/status/route.ts)

  • New endpoint: POST /api/issues/status with bearer auth
  • Payload: { issueId, repoFullName, issueNumber, status, agentName?, actor? }
  • Valid statuses: backlog, in-progress, in-review, done
  • Behavior: Replaces existing status labels; writes AuditLog on both success/failure
  • Security: Returns 401 without valid MISSION_CONTROL_AGENT_TOKEN
  • Test coverage: 21 new tests covering auth, validation, business logic, and error handling
  • Status: ✅ Implements atomic label replacement; correctly skips GitHub calls when status unchanged

3. Move Endpoint Auth (src/app/api/issues/move/route.ts)

  • Added: Bearer auth requirement (previously unauthenticated)
  • Added: Optional actor field in body (defaults to "agent")
  • Security: Returns 401 when token missing or incorrect
  • Test coverage: 2 new auth tests; updated existing tests to include auth header
  • Status: ✅ Auth check at top of handler before any processing; audit actor now configurable

4. Claim Behavior Clarification (src/app/api/issues/claim/route.ts)

  • Changed: Claim now only adds agent/* label — no longer adds status/in-progress automatically
  • Impact: Status transitions require explicit POST /api/issues/status call
  • Rationale: Separates assignment from state management for worker control
  • Test coverage: 6 updated tests confirming status/in-progress is not added
  • Status: ✅ Correctly removes auto-status-in-progress logic; tests updated to match

5. Worker Migration Docs (docs/worker-cron-prompt-migration.md)

  • Updated: Queue response format documentation with type, issueId, repoFullName
  • Updated: Claim behavior section clearly stating "Claim only assigns"
  • Added: New /api/issues/status endpoint documentation with valid values
  • Fixed: Move endpoint payload (was incorrectly showing lane, now shows oldLabels/newLabels)
  • Updated: Migration checklist to reflect new workflow
  • Status: ✅ Documents all 5 PR changes accurately

Standards Compliance

StandardStatusNotes
Bearer auth (MISSION_CONTROL_AGENT_TOKEN)All mutation endpoints require token
AuditLog for state changesBoth move and status endpoints write audit entries
Proper HTTP status codes200, 400, 401, 404, 500 correctly used
Error handling (error instanceof Error)Used in catch blocks
No agent-specific names in docsUses generic agent/* patterns
Label conventions (status/*)Uses status/backlog, status/in-progress, etc.
PR-fix ordering preservedPR-fix items returned first

Linked Issue Fit

No linked issue context available. The PR body references "Issue #98" but no linked issue details were provided. The PR self-describes addressing 5 migration blockers, and all 5 are implemented:

  1. ✅ Queue includes issueId and repoFullName
  2. ✅ New POST /api/issues/status endpoint
  3. POST /api/issues/move requires auth
  4. ✅ Claim behavior clarified (assignment only)
  5. ✅ Worker migration docs updated

Evidence Provider Findings

No evidence providers configured.


Tool Harness Findings

Tool harness ran with 0 planned/executed requests — no external calls were made.


Unknowns / Needs Verification

  1. Token scoping: The status and move endpoints accept the same MISSION_CONTROL_AGENT_TOKEN for all agents. No per-agent scoping is implemented. This appears intentional based on existing patterns.

  2. Documentation mismatch potential: The docs/agent-workflow.md file contains a reference to claim "optionally moves it to status/in-progress" (line 86). This may need updating to reflect the new behavior, though this file was not modified in this PR.

  3. Breaking change notice: The removal of auto status/in-progress from claim is a behavior change. The migration docs address this, but existing workers may need updates before deploying this change.


Validation Results

From PR description:

  • npm ci
  • npx prisma generate
  • npm run lint
  • npm run typecheck
  • npm run test (352/352 passing)
  • npm run build

Recommendation

Approve. The PR correctly implements all 5 described migration blockers with comprehensive test coverage (352 tests passing). Code follows repository conventions, implements proper auth, writes audit logs, and maintains label conventions. The migration documentation accurately reflects the new behavior.

…th, claim behavior
- GET /api/agents/[agentName]/queue now returns issueId, repoFullName, and type:'issue' on issue items
- PR-fix items remain first in the queue response
- Added POST /api/issues/status with bearer auth for explicit status transitions
- Replaces existing status/* labels with requested status
- Updates GitHub labels, Prisma cache, and writes AuditLog
- Accepts agentName/actor as optional actor field
- Added MISSION_CONTROL_AGENT_TOKEN bearer auth to POST /api/issues/move
- Deprecated in favor of new /api/issues/status for workers
- Actor defaults to 'agent', can be overridden via body.actor
- Claim no longer auto-transitions to status/in-progress
- Claim only assigns agent/* label; status transitions are explicit via /status
- Updated worker-cron-prompt-migration.md with correct API payloads
- Documents new /api/issues/status endpoint
- Clarifies claim behavior (assign-only, explicit status)
- Fixes incorrect move payload example (shows oldLabels/newLabels)
- All 352 tests pass
@joryirving
joryirvingforce-pushed the fix/issue-98-migration-v02 branch from 49a919d to 80f3e19CompareMay 17, 2026 21:22
@joryirving
joryirving merged commit cf69a9d into mainMay 17, 2026
3 checks passed
@joryirving
joryirving deleted the fix/issue-98-migration-v02 branch May 17, 2026 21:50
joryirving added a commit that referenced this pull request Aug 5, 2026
… on them (#709)
* fix(pr-followup): skip informational bot comments instead of blocking on them
The comment path ingested every non-author comment on a bot PR as
REVIEW_FEEDBACK, so a CI bot posting a size-diff table became a work
item: classifyFeedback finds no actionable pattern in markdown, defaults
to needs_human, and the PR sits BLOCKED on a human forever.
Observed on misospace/llmkube-images#114 — a MERGEABLE, unreviewed PR
blocked since 2026-08-04 by an app-size-diff comment reporting +0 B
(+0%). Same cause on #46 and #99. The queue read 9 NEEDS_HUMAN items
when only informational noise and already-merged PRs were behind them.
Gate the comment descriptor on a new isInformationalComment(): sticky
comment markers (the sticky-pull-request-comment convention embeds one so
the action can update in place, which makes it a structural signal rather
than a prose guess) plus dispatch's own pr-fix-blocked notice. An
ai-pr-reviewer comment stays ingestible even when it carries a marker —
it ships structured findings and is genuine review feedback.
Does not address the stale-item half of the same symptom (#692): items
already queued when their PR merges are still never reaped.
Signed-off-by: Jory Irving <jory.irving@users.noreply.github.com>
* fix(test): import vi in pr-followup-ingestion tests
The informational-comment tests use vi.restoreAllMocks(); vitest globals
make that work at runtime, so the suite passed while tsc and next build
failed on TS2304.
Signed-off-by: Jory Irving <jory.irving@users.noreply.github.com>
---------
Signed-off-by: Jory Irving <jory.irving@users.noreply.github.com>
Co-authored-by: Jory Irving <jory.irving@users.noreply.github.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@itsmiso-ai@joryirving