Context
A cloud deployment investigation found an empty Knowledge Base collection while the deployed KB and MC MCP servers reported healthy Chroma connectivity. A code-level sweep of the orchestrator path found a narrower substrate inconsistency: tenant-repo-sync has no single, reliable scheduler classification across current code, accepted/planned scheduler docs, and cloud-ingestion docs.
This ticket is intentionally client-neutral. It does not name any deployment or tenant.
Duplicate sweep: checked the latest 30 open GitHub issues on 2026-07-01; no equivalent scheduler-classification ticket was found. #13432 is related but broader: required deployment env-var validation. A2A in-flight sweep checked the latest 40 messages and found no competing lane-claim for this scheduler-classification scope. KB ticket sweep for tenant-repo-sync classified continuous instead of heavy scheduler lease DEFAULT_HEAVY_MAINTENANCE_TASK_NAMES ADR 0022 found historical context but no current open duplicate. Local resources/content/issues / resources/content/discussions exact sweep found historical discussion/ticket artifacts with conflicting language, which reinforces the need for this ticket rather than replacing it.
The Problem
The current substrate says two different things about the same lane:
ai/daemons/orchestrator/scheduling/registry.mjs:171 defines tenant-repo-sync as a service-runner, but maintenanceClass: 'continuous' and backpressure: 'none'.
ai/daemons/orchestrator/services/MaintenanceBackpressureService.mjs:19 through :29 defines DEFAULT_HEAVY_MAINTENANCE_TASK_NAMES without tenant-repo-sync, so acquireLeaseAndExecute() executes it without the heavy-maintenance lease.
ai/daemons/orchestrator/scheduling/pipeline.mjs:15 through :23 explicitly excludes tenant-repo-sync from staleness metadata as a lightweight/health/continuous lane, which leaves it on registry-order fallback.
learn/agentos/decisions/0022-heavy-maintenance-scheduling-fairness.md:50 says tenant-repo-sync is a resource-mutex task that contends for the heavy-maintenance lease.
learn/agentos/decisions/0022-heavy-maintenance-scheduling-fairness.md:93 says tenant-repo-sync must not be part of cheap off-lease multi-dispatch and should drain on the lease.
Older discussion/ticket artifacts found by KB search describe the lane as periodic/continuous/off-lease in some places. The current source of authority is therefore not self-consistent enough for agents or operators to know whether the code or docs are wrong.
This matters operationally because tenant-repo-sync owns server-side pull ingestion for tenant repositories. If it is meant to be heavy, the current code can run clone/fetch/envelope/KB ingest work outside the heavy lease and outside staleness fairness. If it is meant to be continuous/off-lease, ADR-0022 and cloud-ingestion docs are misleading, and future scheduler work may incorrectly move it into the heavy lane.
The Architectural Reality
tenant-repo-sync is scheduled by the orchestrator descriptor registry and dispatched through executeServiceRunnerCandidate() into TenantRepoSyncService.runTask().
The task itself can be a no-op when no effective repo config exists: ai/daemons/orchestrator/services/TenantRepoSyncService.mjs:314 through :317 returns status: 'skipped' with reason: 'no-tenant-repos-configured'. TaskStateService.markSkipped() does not treat that as a success (ai/daemons/orchestrator/services/TaskStateService.mjs:213 through :223), while markStarted() still advances lastRunAt before the skip. That makes the scheduler/diagnostic contract important: a cloud deployment can repeatedly run a configured-but-empty pull lane without the current public diagnostics making the reason obvious.
This ticket does not decide the final classification up front. It requires the implementation to choose one classification and update all owning surfaces coherently.
The Fix
Resolve the contract across code, tests, and docs:
- Decide whether
tenant-repo-sync is:
- resource-mutex/heavy, lease-gated, staleness-fair with other heavy lanes; or
- continuous/off-lease, intentionally outside the heavy-maintenance lease and staleness-ratio set.
- Make
TASK_REGISTRY, TASK_STALENESS_CADENCE_KEY, and DEFAULT_HEAVY_MAINTENANCE_TASK_NAMES reflect that decision consistently.
- Update ADR/cloud-ingestion docs or code accordingly. Do not leave ADR-0022 and scheduler code disagreeing.
- Add tests that prove the classification at both picker policy and execution/lease boundary.
- Ensure the no-config path remains observable as
no-tenant-repos-configured and does not masquerade as healthy ingestion progress.
Contract Ledger Matrix
| Target Surface |
Source of Authority |
Proposed Behavior |
Fallback / Edge Case |
Docs |
Evidence |
TASK_REGISTRY descriptor for tenant-repo-sync |
This ticket plus ADR-0022 / successor clarification |
Descriptor classification matches the chosen scheduler contract |
If classified non-heavy, docs must explicitly say why pull-mode ingest is off-lease-safe |
Yes |
Unit test asserts descriptor maintenanceClass and backpressure |
DEFAULT_HEAVY_MAINTENANCE_TASK_NAMES |
Heavy-maintenance lease contract |
Membership includes tenant-repo-sync iff it is classified resource-mutex/heavy |
If omitted, tests prove tenant-repo-sync intentionally bypasses acquireLeaseFn |
Yes |
Unit test around MaintenanceBackpressureService.acquireLeaseAndExecute() |
TASK_STALENESS_CADENCE_KEY |
ADR-0022 fairness model or amended successor |
Staleness metadata includes tenant-repo-sync iff it competes as a heavy/resource-mutex lane |
If omitted, docs/tests prove registry-order fallback is intentional and safe |
Yes |
Picker/pipeline unit test with competing due candidates |
TenantRepoSyncService no-config outcome |
Cloud-ingestion operational contract |
no-tenant-repos-configured remains a visible skipped outcome, not silent success |
Empty config should not populate KB and should be diagnosable without reading logs |
Yes |
Unit test / diagnostic assertion for skipped outcome details |
Decision Record Impact
Requires ADR-0022 clarification or amendment. The current ADR text classifies tenant-repo-sync as resource-mutex/heavy, while the current scheduler code classifies it as continuous/off-lease. If implementation chooses the current code direction, amend docs/ADR language. If implementation chooses the ADR direction, update scheduler code and tests.
Acceptance Criteria
Out of Scope
- Adding new tenant-repo diagnostic MCP tools.
- Solving all deployment env-var validation. That belongs to related fail-loud config validation work.
- Changing tenant repo credential semantics.
- Mentioning any client or tenant by name.
Related
Origin Session ID: unavailable from this harness turn.
Retrieval Hint: tenant-repo-sync scheduler classification drift continuous heavy lease ADR 0022 DEFAULT_HEAVY_MAINTENANCE_TASK_NAMES
Context
A cloud deployment investigation found an empty Knowledge Base collection while the deployed KB and MC MCP servers reported healthy Chroma connectivity. A code-level sweep of the orchestrator path found a narrower substrate inconsistency:
tenant-repo-synchas no single, reliable scheduler classification across current code, accepted/planned scheduler docs, and cloud-ingestion docs.This ticket is intentionally client-neutral. It does not name any deployment or tenant.
Duplicate sweep: checked the latest 30 open GitHub issues on 2026-07-01; no equivalent scheduler-classification ticket was found.
#13432is related but broader: required deployment env-var validation. A2A in-flight sweep checked the latest 40 messages and found no competing lane-claim for this scheduler-classification scope. KB ticket sweep fortenant-repo-sync classified continuous instead of heavy scheduler lease DEFAULT_HEAVY_MAINTENANCE_TASK_NAMES ADR 0022found historical context but no current open duplicate. Localresources/content/issues/resources/content/discussionsexact sweep found historical discussion/ticket artifacts with conflicting language, which reinforces the need for this ticket rather than replacing it.The Problem
The current substrate says two different things about the same lane:
ai/daemons/orchestrator/scheduling/registry.mjs:171definestenant-repo-syncas aservice-runner, butmaintenanceClass: 'continuous'andbackpressure: 'none'.ai/daemons/orchestrator/services/MaintenanceBackpressureService.mjs:19through:29definesDEFAULT_HEAVY_MAINTENANCE_TASK_NAMESwithouttenant-repo-sync, soacquireLeaseAndExecute()executes it without the heavy-maintenance lease.ai/daemons/orchestrator/scheduling/pipeline.mjs:15through:23explicitly excludestenant-repo-syncfrom staleness metadata as a lightweight/health/continuous lane, which leaves it on registry-order fallback.learn/agentos/decisions/0022-heavy-maintenance-scheduling-fairness.md:50saystenant-repo-syncis a resource-mutex task that contends for the heavy-maintenance lease.learn/agentos/decisions/0022-heavy-maintenance-scheduling-fairness.md:93saystenant-repo-syncmust not be part of cheap off-lease multi-dispatch and should drain on the lease.Older discussion/ticket artifacts found by KB search describe the lane as periodic/continuous/off-lease in some places. The current source of authority is therefore not self-consistent enough for agents or operators to know whether the code or docs are wrong.
This matters operationally because
tenant-repo-syncowns server-side pull ingestion for tenant repositories. If it is meant to be heavy, the current code can run clone/fetch/envelope/KB ingest work outside the heavy lease and outside staleness fairness. If it is meant to be continuous/off-lease, ADR-0022 and cloud-ingestion docs are misleading, and future scheduler work may incorrectly move it into the heavy lane.The Architectural Reality
tenant-repo-syncis scheduled by the orchestrator descriptor registry and dispatched throughexecuteServiceRunnerCandidate()intoTenantRepoSyncService.runTask().The task itself can be a no-op when no effective repo config exists:
ai/daemons/orchestrator/services/TenantRepoSyncService.mjs:314through:317returnsstatus: 'skipped'withreason: 'no-tenant-repos-configured'.TaskStateService.markSkipped()does not treat that as a success (ai/daemons/orchestrator/services/TaskStateService.mjs:213through:223), whilemarkStarted()still advanceslastRunAtbefore the skip. That makes the scheduler/diagnostic contract important: a cloud deployment can repeatedly run a configured-but-empty pull lane without the current public diagnostics making the reason obvious.This ticket does not decide the final classification up front. It requires the implementation to choose one classification and update all owning surfaces coherently.
The Fix
Resolve the contract across code, tests, and docs:
tenant-repo-syncis:TASK_REGISTRY,TASK_STALENESS_CADENCE_KEY, andDEFAULT_HEAVY_MAINTENANCE_TASK_NAMESreflect that decision consistently.no-tenant-repos-configuredand does not masquerade as healthy ingestion progress.Contract Ledger Matrix
TASK_REGISTRYdescriptor fortenant-repo-syncmaintenanceClassandbackpressureDEFAULT_HEAVY_MAINTENANCE_TASK_NAMEStenant-repo-synciff it is classified resource-mutex/heavytenant-repo-syncintentionally bypassesacquireLeaseFnMaintenanceBackpressureService.acquireLeaseAndExecute()TASK_STALENESS_CADENCE_KEYtenant-repo-synciff it competes as a heavy/resource-mutex laneTenantRepoSyncServiceno-config outcomeno-tenant-repos-configuredremains a visible skipped outcome, not silent successDecision Record Impact
Requires ADR-0022 clarification or amendment. The current ADR text classifies
tenant-repo-syncas resource-mutex/heavy, while the current scheduler code classifies it as continuous/off-lease. If implementation chooses the current code direction, amend docs/ADR language. If implementation chooses the ADR direction, update scheduler code and tests.Acceptance Criteria
tenant-repo-synchas one explicit scheduler classification acrossTASK_REGISTRY,TASK_STALENESS_CADENCE_KEY, andDEFAULT_HEAVY_MAINTENANCE_TASK_NAMES.tenant-repo-synccompetes with at least one heavy lane and one graph/light lane.tenant-repo-syncacquires or bypasses the heavy-maintenance lease according to the chosen contract.no-tenant-repos-configuredskip remains a structured, observable outcome.Out of Scope
Related
Origin Session ID: unavailable from this harness turn.
Retrieval Hint:
tenant-repo-sync scheduler classification drift continuous heavy lease ADR 0022 DEFAULT_HEAVY_MAINTENANCE_TASK_NAMES