docs: arch-review remediation — component docs sweep, execution log, residuals register

Final consistency sweep per plan §6: verified component docs against shipped
WP1-WP3 + adversarial-review-fix state, corrected drift found in SiteRuntime
(recursion-exempt run cap, stale ScriptExecutionActor/AlarmExecutionActor
references), TemplateEngine (BundleImporter watermark path), DeploymentManager
(phase-2 PendingDeployment staging), CentralUI (shared KPI cache, dedup'd alarm
poll, render coalescing), StoreAndForward (rate-limited drop logging), and
ConfigurationDatabase (documented DbContext-pooling non-adoption). Updated the
docs/components/ developer-reference set (SiteRuntime, SiteEventLogging,
InboundAPI) to drop the deleted per-run actor classes. Amended one known-issue
for the superseding MaxBatchSize:64 read-page pin. Added CLAUDE.md bullets for
stream graceful-completion reconnect, the required site audit DB path, honest
CLI HTTP timeouts, bulk DeploySiteAsync, and LocalDb 0.2.1. New execution log
records the phase→commit map, gate results, adversarial-review tally, the
three test-flake root causes, and the nine-item residuals register.
This commit is contained in:
Joseph Doherty
2026-08-15 01:30:59 -04:00
parent a9ca51e008
commit 7804fe7958
12 changed files with 244 additions and 49 deletions
@@ -150,17 +150,22 @@ It runs the ordinary deployment pipeline in three phases, of which only the midd
one is parallel:
1. **Prepare (serial).** Validate transition, take the operation lock, flatten +
validate, run query-before-redeploy reconciliation, stage the
`PendingDeployment`, insert the `InProgress` record. Every step here touches the
scoped, non-thread-safe `DbContext`, so the phase is strictly serial. All
instances share ONE `FlattenSession`, so a template chain common to N instances
is walked once and the session-global queries (shared scripts, schema library,
the site's data connections) run once for the batch.
2. **Send (bounded parallel).** The `RefreshDeploymentCommand` round-trips run
concurrently up to `SiteDeploymentMaxParallelism` (default 4), each under a
`SiteDeploymentTimeoutPerInstance` deadline (default 120 s). This phase touches
no repository — that is exactly why it is the only phase allowed to run in
parallel. Shape mirrors `ArtifactDeploymentService.DeployCoreAsync`.
validate, run query-before-redeploy reconciliation, insert the `InProgress`
record. Every step here touches the scoped, non-thread-safe `DbContext`, so the
phase is strictly serial. All instances share ONE `FlattenSession`, so a
template chain common to N instances is walked once and the session-global
queries (shared scripts, schema library, the site's data connections) run once
for the batch.
2. **Send (bounded parallel).** Concurrently up to `SiteDeploymentMaxParallelism`
(default 4), each under a `SiteDeploymentTimeoutPerInstance` deadline
(default 120 s): stage the `PendingDeployment` row **immediately before** that
instance's `RefreshDeploymentCommand` round-trip, not upfront in phase 1 —
`PendingDeployment` carries a 5-minute TTL, and staging every instance in the
batch serially in phase 1 would burn a chunk of that TTL for the tail
instances before their round-trip even starts (review fix, commit
`e0e4b246`). Staging touches the repository but is scoped per-instance, so it
does not reintroduce serialization. Shape mirrors
`ArtifactDeploymentService.DeployCoreAsync`.
3. **Finalize (serial).** Commit terminal statuses, apply post-success side
effects, write audit rows, release each operation lock.
@@ -170,6 +175,15 @@ reported as a failed row while the rest proceed, and is individually retryable v
the ordinary single-instance deploy. This matches the artifact-deployment policy:
successful targets are never rolled back because another target failed.
**Cancellation is lock-safe (review fix, commit `e0e4b246`).** A cancelled bulk
deploy no longer leaks the per-instance operation lock of any instance that had
already taken one — a leaked lock is a wedged semaphore that never releases for
the life of the process. Phase 2 does not throw on cancellation; each in-flight
instance is instead recorded with a `Failed` outcome so phase 3 (finalize) still
runs for it. An escape from phase 1 or phase 3 unwinds every not-yet-finalised
entry the same way: `Failed` status plus lock release, so no instance touched by
a cancelled bulk deploy can be left holding its lock.
`DeployInstanceAsync` is composed from the same three phase helpers with a batch of
one, so the two entry points cannot drift on deployment identity, idempotency, lock
coverage, or optimistic concurrency.