Connector Summary Synthesis Extraction Plan
Date: 2026-06-17
Status: implementation plan for step 2 of maintain-connector-summary-read-model
Scope
Extract a pure synthesizeConnectorSummary tail from
projectConnectorSummaryForInstance without changing behavior.
This step SHALL NOT switch /_ref/connectors to the maintained read model,
change ListConnectorSummariesOptions, alter cache behavior, persist
freshness/health/verdict/copy, or route scoped diagnostics through shallow
overview evidence.
Current Boundary
reference-implementation/server/ref-control.ts currently has the relevant
boundaries:
projectConnectorSummaryForInstanceperforms eligibility checks, async evidence reads, schedule/run/detail/outbox/attention/local/acquisition gathering, collection-rate read, and final summary synthesis.computeConnectorSummariesmaps dashboard connection rows throughprojectConnectorSummaryForInstance.getConnectorSummaryForRouteresolves exactly one connection, loads deep deps withincludeRunSummaries: true, and then callsprojectConnectorSummaryForInstance.getOwnerConnectionDiagnosticsdepends ongetConnectorSummaryForRoute.
The extraction must leave the first three bullets true. It is a construction refactor, not a read-path switch.
Extraction Shape
Add a local pure helper in ref-control.ts:
function synthesizeConnectorSummary(input: ConnectorSummarySynthesisInput): ConnectorSummary
projectConnectorSummaryForInstance keeps all IO and time capture:
- manifest/public-connector eligibility
connectorId/connectorInstanceIdderivationhydrateRunSummariesdecision- record projection reads
- schedule, run, successful-run, detail-gap, outbox, attention, browser-surface, local-coverage, acquisition-coverage reads
- refresh-policy derivation
nowIsocapture- collection-rate read
Only the deterministic tail moves:
- local-device progress projection
- local-device heartbeat freshness eligibility
buildConnectorFreshnessprojectConnectorSummaryConnectionHealthprojectCollectionReport- display-name fallback
- recovered-detail-gap count
buildRenderedVerdictForSummary- final
ConnectorSummaryobject construction
The pure helper must not call storage/controller methods, cache invalidation,
dirty markers, telemetry/audit functions, or new Date().
High-Risk Fields
Preserve these exactly:
freshness: samenowIso, run, record, refresh-policy, and local-device heartbeat rules. Do not move time capture into the helper.connection_health: same detail-gap counts, outbox cause, attention, remote-surface, local/acquisition coverage, collection-rate, refresh-policy, schedule, and unreliable-source aggregation.collection_report: samelastRun,connectionHealth, manifest streams, pending detail gaps, and refresh-policy inputs.rendered_verdict: same collection report, health, freshness, recovered-detail-gap, local-device-backed, manifest, observed-time, refresh-policy, retained-count, runtime, and schedule inputs.- Identity:
connection_idandconnector_instance_idremain the selectedconnectorInstanceId;connector_idremains the canonical connector id. - Record fields:
livestill comes from the current record projection path; retained bytes and stream summaries remain derived from thatliveobject.
Characterization Test
Before or in the extraction commit, add a scoped deep-path characterization
test, preferably near existing tests in
reference-implementation/test/ref-connectors-connection-projection.test.js.
The test should seed sibling connections for the same connector, give the target
connection run/detail/outbox/local-device/record evidence, call
getConnectorSummaryForRoute, and assert:
connection_idandconnector_instance_idequal the target connection id.last_runandlast_successful_runare hydrated on the scoped path.connection_healthcarries target-only detail/outbox evidence.collection_reportandrendered_verdictare present.- Sibling run/detail evidence does not leak.
If synthesizeConnectorSummary is exported for reuse in the same commit, add a
direct fixed-nowIso unit. Do not export solely for testing.
Validation
Run at minimum:
node --test --test-timeout=30000 --import tsx \
reference-implementation/test/ref-connectors-connection-projection.test.js \
reference-implementation/test/ref-connectors-list-connection-scope.test.js \
reference-implementation/test/owner-connection-diagnostics.test.js \
reference-implementation/test/ref-connectors-list-operation.test.js
pnpm --dir reference-implementation run typecheck
openspec validate maintain-connector-summary-read-model --strict
git diff --check
Then grep/read back the changed ref-control.ts hunk for:
synthesizeConnectorSummaryprojectConnectorSummaryForInstanceincludeRunSummariesgetOwnerConnectionDiagnosticsgetConnectorSummaryForRoute
Confirm scoped/detail diagnostics still use the deep route path.