Skip to content

fix: preserve legacy Architect clarification storage - #309

Merged
Joncallim merged 12 commits into
architecture/issue-179-context-packet-evidencefrom
codex/pr198-f1-legacy-clarification
Jul 30, 2026
Merged

fix: preserve legacy Architect clarification storage#309
Joncallim merged 12 commits into
architecture/issue-179-context-packet-evidencefrom
codex/pr198-f1-legacy-clarification

Conversation

@Joncallim

@Joncallim Joncallim commented Jul 30, 2026

Copy link
Copy Markdown
Owner

Source Issue

Issue: #179

Summary

  • keep legacy clarification question and answer text in one authenticated encrypted envelope on the existing legacy Architect artifact
  • expose that text only through the already-authorized task questions route and dashboard, while keeping task rows, Redis events, logs, checkpoints, and generic artifact projections content-free
  • answer legacy questions atomically, enqueue the existing answers worker, reload the durable artifact, and continue re-planning
  • preserve protected-mode history, source bindings, and dedicated answer routines unchanged

This child addresses PR #198 finding PRRT_kwDOS9dWe86U9jdu / discussion_r3679390466, including the follow-up lifecycle review.

Exact stack

Files

  • web/lib/mcps/legacy-clarification.ts
  • web/worker/orchestrator.ts
  • web/app/api/tasks/[id]/questions/route.ts
  • web/app/dashboard/tasks/[id]/page.tsx
  • web/db/migrations/0027_epic_172_s4_packet_context.sql
  • web/db/schema.ts
  • web/__tests__/api.test.ts
  • web/__tests__/architect-legacy-clarification.test.ts
  • web/__tests__/task-page-retry-handoff.test.ts

Validation

  • legacy lifecycle, API, and task-page focus: 229 passed
  • adjacent protected storage, leakage, and retry focus: 73 passed
  • full local unit run: 1,731 passed; the existing service-backed tests were skipped under the local convention
  • changed-file ESLint: passed
  • npx tsc --noEmit: passed
  • production build: passed
  • git diff --check: passed
  • mutation check: restoring legacy_unavailable made the focused lifecycle test fail at the required open state, then the restored tree passed

Hosted evidence

  • Web: run 30519224986, job 90795736915 — success
  • PR Contract: run 30558198109, job 90924049153 — success
  • GitGuardian: check 90795731401 — success

No parent review thread was replied to or resolved. This PR remains draft.

@Joncallim
Joncallim marked this pull request as ready for review July 30, 2026 17:02
@Joncallim
Joncallim merged commit b1c99d6 into architecture/issue-179-context-packet-evidence Jul 30, 2026
4 checks passed

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 94396441a5

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

const { updatedQuestions, allAnswered } = result

if (allAnswered) {
await redis.lpush('forge:answers', JSON.stringify({ taskId }))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Make the answer enqueue retry-safe

When Redis is transiently unavailable, the legacy transaction has already persisted the encrypted answers and marked the questions answered before this LPUSH fails. The request then returns 500 without creating the job that the Forge worker consumes; resubmitting is rejected because the envelope is already answered, leaving the task indefinitely in awaiting_answers. Use a durable outbox or allow an idempotent retry to enqueue an already-completed answer set.

AGENTS.md reference: AGENTS.md:L30-L32

Useful? React with 👍 / 👎.

claimLeaseFence.assertOwned()
const storage = architectPlanStorageConfiguration(process.env, runtimeMode)
const answeredQuestions = storage.mode === 'legacy'
? await legacyAnsweredQuestionSnapshot(taskId, existingQuestions, claimLeaseFence)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Handle legacy snapshot failures inside retry recovery

When legacy history cannot be loaded—for example, after a retryable replan inserted a newer artifact but failed before completing—the awaited snapshot throws before the recovery try block. Every subsequent attempt, including the final one, therefore bypasses the status handling below; the answers job can be dead-lettered while the task remains permanently awaiting_answers with no usable questions. Move this preparation into the guarded recovery path or apply equivalent terminal-state handling.

Useful? React with 👍 / 👎.

Comment on lines +837 to +840
: {
id: question.questionId,
taskId,
status: 'open' as const,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve answered legacy rows across replan retries

When a legacy replan reaches persistOpenQuestions, these rows have no answerReferenceId, so the function's existing null-reference deletion removes the prior answered projection before later operations complete. If workforce materialization, run completion, or another later step fails on a non-final attempt, recovery resets the task to awaiting_answers but does not restore those rows; the next retry either fails for having no questions or treats a newly generated unanswered round as the requested continuation. Make artifact/question replacement transactional or restore the prior answered projection and artifact binding.

Useful? React with 👍 / 👎.

@Joncallim
Joncallim deleted the codex/pr198-f1-legacy-clarification branch August 2, 2026 18:22
Sign up for free to 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.

1 participant