Prepare private Render hosting compatibility - #2914
Conversation
Document capture text bytes and pin reconciliation comparison
Add true card archive and restore lifecycle
…ection 2 Two reconciliations that had to wait for the pass to land. docs/STATUS.md gains the twenty-second block, covering c4cca76 to a0d05da: the canonical-document topology fixes, the agent-facing truth corrections in .codex/memories/00_ACTIVE.md and autodoc/AGENT_INDEX.md, the release-readiness re-measure, the three cutover sections measured but not ticked, and the twelve-PR control-plane disclosure now tracked as OUTSTANDING_TASKS section J.3. It records the tip run (34518563221, 17 jobs success, 1 skipped) as the proof rather than any per-merge run, because the three intermediate main runs were cancelled by the workflow's own concurrency group — the #2582 shape the release view describes. It also records, plainly, that the coordinator carried the alpha lane's #2918 on a mistaken reading that the lane had gone quiet. The gate was met and measured, but the lane was active, so the closed-session precedent did not apply and one-writer-per-seam was not honoured. docs/releases/V0_3_0_READINESS.md section 2 gains a dated preface. Its numbered narrative named #2506 as "the first open blocker on clause 5"; #2506 merged 2026-09-06 (79d7efd). The planner-error class it targeted is still live as #2562 with three observed triggers, the recall report on #2336 reads 7 of 42 usable and 0.0% recall with ready-for-selection no, and the landed-commit verifier still does not exist. Net effect for a lane: of #2327's two halves only the verifier is takeable, because the observation window cannot close before SC-6. The narrative below the preface keeps its 2026-09-04 measurement and the provenance table now says so per part. Verified: check-docs-governance and check-doc-links pass. Refs #2235.
…ership Keep Review request health separate from retained disclosures
Follow-up inside #3025. The append index has to match the list CardService.MoveCardAsync actually reorders, and that list is ICardRepository.GetByColumnIdAsync, which filters `!c.IsArchived`. The column navigation this handler reads (ColumnRepository.GetByIdWithCardsAsync) includes archived cards, so a plain Cards.Count over-counted a column holding archived cards and relied on the service's clamp to come back to the end of the list. An archived card is in fact the second live trigger for the same defect: it keeps its stored position so restore can return it to its original placement, so a column with one active card at 0 and an archived card at 1 has max(Position) + 1 = 2 against a one-card list. The new regression pins that case through the real CardService and fails against origin/main with ArgumentOutOfRangeException, as the sparse-position one does.
Review round 1 on #3032. The parent-field case set a board payload it no longer reads, and a comment that claimed the omitted-payload journey as its subject; the prop alone is what it proves, and the journey is covered in CardModal.spec.ts. The work-item type page now carries the archived-card exception that STATUS already recorded. No behaviour change.
…n move Review triage for #3025 (PR #3034), both LOW and both caused by this change: - LOW-1: the Moved audit row logged the REQUESTED position. Before the clamp those were always equal; a clamped request would now write a position the board never held into a trail operators read. It logs card.Position, read after the renumber loop. The `target_column=...; position=...` shape is unchanged, so BoardMetricsService and ForecastingService still parse it. - LOW-3: a proposal move into the card's OWN column is the one path where the append index still overshoots by design (the mover is counted in Column.Cards but excluded from the list CardService reorders), so the clamp is load-bearing there rather than insurance. It used to throw; it now sends the card to the bottom, which is what the preview projection has always assumed. Pinned by a test and spelled out in the comment.
…e-effect-copy fix(review): name restores in card side-effect disclosures
# Conflicts: # docs/STATUS.md
…terrupts a save A background board refetch that flips readOnly back to writable runs load(), which shares CardAssignmentField's single generation counter with save(). The in-flight PUT's finally then no-ops, so saving stays true, locked stays true and the saving-change the card editor reads to refuse every close affordance stays latched at true for the life of the mount. Both new specs fail against current main. Refs #3017
…nter CardAssignmentField shared one generation counter between load() and save(). The readOnly watcher is reachable while a PUT is unanswered - a background board refetch that re-reports write permission mid-save runs load() - and that bumped the shared counter, so the save's finally no-opped. saving stayed true, locked stayed true, and the saving-change the card editor reads to refuse every close affordance (#2977/#2981) stayed latched at true until navigation remounted the field, trapping the user in the editor. Split the counter per request kind. Each request still rejects its own stale body - a superseded save, a read left behind by a newer read - and the card-identity watcher and unmount bump both, so a receipt for a card the editor has left is still dropped. A read cannot invalidate a write it does not contend with: a non-refreshing load() only replaces the participant list, and the refreshing one is unreachable while saving holds. The #2982 permission lock, its release rules and load()'s stale-response rejection are unchanged. Closes #3017
…ew spec The spread of the Record-typed mock store loses its index signature through reactive(), so vue-tsc rejected the currentBoardCards read. Refs #3017
fix(proposals): apply a move into a sparse column instead of throwing at Insert
…uest-ownership fix(archive): keep dismissed confirmations closed across delayed responses
…nds after it Review of #3041 found the mirror of the #3017 overlap: with load() and save() on separate counters, the save's catch body now runs, so a reload that settles AFTER a refused PUT could clear the needsRefresh the refusal had just set. That withdrew the Refresh current assignments button while the alert still told the user to press it, and re-enabled Save against the version the 409 invalidated. load() clears saveFailure before it starts, so anything there when its body runs came from a save that settled during it. Yield needsRefresh in that case. The spec fails without the guard. Also correct the counter comment: the read body the split makes safe is the refreshing branch, which is unreachable while saving holds - not "only the participant list" - and name needsRefresh as the one shared piece of state. Refs #3017
…ssion-gates fix(cards): one server-authoritative permission read for every card editor write gate
# Conflicts: # docs/STATUS.md
…ettlement fix(assignments): settle an assignment save on its own generation counter (#3017)
…gnee-labels fix(import): reject conflicting assignee labels before preview or apply
|
Taking the existing inert hosting-preparation draft through its remaining repository checks and bounded independent review. This updates documentation qualification against current main only; no provisioning, deploy, credentials, hostname, purchase or activation is included. The existing Render/private-host/restore/capacity decisions stay tracked on #1772/#1777 and OUTSTANDING_TASKS.md. |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 4d39c6d3c1
ℹ️ 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".
|
Delivery is coordinated through integration PR #3050, which preserves this PR's exact source head and commits. It qualifies all reviewed product slices against main1931da65d after the Smart CI repair; no source merge-resolution changes were required. Local source evidence remains scoped to its recorded head, and the integration's hosted checks and bounded interaction review qualify the combined delivery. Existing review feedback is triaged once; this source PR will be reconciled after the integration lands. |
Add inert, reference-only hosting preparation for the requested Render Starter candidate. The manifest keeps activation_authorized false, and the runbook maps host selection, private-origin review, consistent backup/decrypt restore, capacity and runtime lifecycle work to existing #1772/#1777/#1226 gates.
Verified on current main f0eb7a3 plus the preserved original commits (head 4d39c6d): JSON parsing, docs governance, all 699 Markdown files with zero broken relative links, and git diff --check pass. A fresh-context independent review found no correctness or operational-authority blocker. The runbook preserves ADR-0061's existing host-selection boundary; this PR does not authorize provisioning or activation. Source diff is only .hosting/README.md and .hosting/manifest.json.
No application, hosted capacity, real origin-security, backup/decrypt restore or live-provider acceptance is claimed. No purchase, deploy, hostname, credential, database or repository-setting change is included. The existing staging workflow is manual and parked; publishing still requires separate release or deployment scope.
Refs #1772, #1777, #1226. Human actions remain in OUTSTANDING_TASKS.md.