LearnNewsExamplesServices
Frontmatter
id14400
titleResolve tenant-repo-sync scheduler classification drift
stateClosed
labels
bugaiarchitecture
assigneesneo-gpt
createdAtJul 1, 2026, 6:34 PM
updatedAtJul 1, 2026, 7:14 PM
githubUrlhttps://github.com/neomjs/neo/issues/14400
authorneo-gpt
commentsCount0
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[]
closedAtJul 1, 2026, 7:14 PM

Resolve tenant-repo-sync scheduler classification drift

Closed v13.1.0/archive-v13-1-0-chunk-8 bugaiarchitecture
neo-gpt
neo-gpt commented on Jul 1, 2026, 6:34 PM

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:

  1. 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.
  2. Make TASK_REGISTRY, TASK_STALENESS_CADENCE_KEY, and DEFAULT_HEAVY_MAINTENANCE_TASK_NAMES reflect that decision consistently.
  3. Update ADR/cloud-ingestion docs or code accordingly. Do not leave ADR-0022 and scheduler code disagreeing.
  4. Add tests that prove the classification at both picker policy and execution/lease boundary.
  5. 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

  • tenant-repo-sync has one explicit scheduler classification across TASK_REGISTRY, TASK_STALENESS_CADENCE_KEY, and DEFAULT_HEAVY_MAINTENANCE_TASK_NAMES.
  • Tests cover due-candidate ordering when tenant-repo-sync competes with at least one heavy lane and one graph/light lane.
  • Tests cover whether tenant-repo-sync acquires or bypasses the heavy-maintenance lease according to the chosen contract.
  • Docs/ADR/cloud-ingestion text no longer contradict the implementation.
  • The no-tenant-repos-configured skip remains a structured, observable outcome.
  • The PR body explicitly states whether the lane is heavy/resource-mutex or continuous/off-lease and why.

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

tobiu closed this issue on Jul 1, 2026, 7:14 PM
tobiu referenced in commit 07ae97d - "fix(ai): classify tenant-repo-sync as heavy maintenance (#14400) (#14401)" on Jul 1, 2026, 7:14 PM