TenantIngestionModel.md pull-mode operator section |
Discussion #11782 Step-Back consumer sweep + ADR 0014 tenant-repo amendment |
Add a dedicated server-side pull section covering tenantRepos[], credential-reference rules, periodic/manual triggers, mirror volume, redeploy posture, and push-vs-pull coexistence. |
Cross-link from the existing push-mode model so operators see the pull path as additive, not a push replacement. |
TenantIngestionModel.md + cloud-deployment overview links |
Markdown link check or targeted doc grep proving every sibling sub is linked |
| Deployed health/readiness payload |
#11791 AC2 + existing HealthService.recordTaskOutcome() / healthcheck.orchestrator.tasks pattern |
Surface per-repo freshness through the existing Memory Core healthcheck orchestrator task block, e.g. orchestrator.tasks['tenant-repo-sync'].details.repos[] with {tenantId, repoSlug, lastIngestedRev, lastSyncAt, status, lastErrorCode?, lastSyncDeletedCount?}. |
Empty tenantRepos[] -> repos: [], not omitted; scheduler unavailable -> task status skipped or failed with details explaining unavailable state; no raw Chroma reads. |
Health payload JSDoc + TenantIngestionModel.md verification section |
Unit test for recordTaskOutcome('tenant-repo-sync', ..., details) projection and payload shape |
| Repo freshness status enum |
#11791 AC2 + #11790 scheduler state |
active = normal cadence and last success; disabled = operator-disabled config; degraded = last cycle failed but retry budget remains; quarantined = backoff threshold exceeded and operator action is needed. |
Recovery after success returns to active; transient per-tick states are not persisted as long-lived health status. |
JSDoc on enum + operator runbook |
Unit test for success/failure/backoff threshold transitions |
| Operator logging output for refresh cycles |
#11791 AC3 + Orchestrator write-log pattern + #11787 redaction helper |
Emit one per-repo refresh summary with tenant/repo, result, short head revision, duration, changed-file count, deleted count, and stable error code when failed. |
Credential material and git stderr pass through redactTenantRepoSecrets() before logging; degraded retryable failures use warning-level logs unless the lane itself is unhealthy. |
JSDoc on log format + operator log-reading section |
Unit test for success, skipped, and failed log lines; fake secret absent |
| Deployment compose / mirror volume operator note |
Discussion #11782 Step-Back consumer sweep + #11788 compose addition |
Document the tenant-repo-mirrors named volume and NEO_TENANT_REPO_MIRROR_ROOT mount as the persistent mirror store used by server-side pull ingestion. |
Missing/unmounted mirror root -> service reports degraded/disabled state without crashing the Orchestrator; operator docs point to the volume and env var. |
TenantIngestionModel.md + DeploymentCookbook.md tenant repo boundary |
Doc-presence check for volume/env names |
| Backup / redeploy survival posture |
Step-Back consumer sweep + #11788 mirror volume contract |
Document the chosen posture: mirrors are reproducible cache from upstream git unless implementation intentionally includes the volume in a backup bundle; redeploy recovery re-clones missing mirrors through GitMirror.cloneIfMissing() on the next sync. |
If operator wants faster recovery, docs may name the volume for optional external backup, but must not imply Chroma/MC backup requires mirror bytes for correctness. |
Cloud-deployment backup/redeploy section |
Doc check; runtime test only if backup code is changed |
| Tenant config storage operator note |
Step-Back consumer sweep + #11787 tenantRepos[] contract |
Document how tenantRepos[] is persisted through KnowledgeBaseIngestionService.setTenantConfig({tenantId, config}) or any operator surface implemented by the PR; do not claim an existing MCP tool unless the implementation adds one. |
Cross-tenant config writes remain rejected by the existing RLS gate; missing/invalid credentialRef or credential-bearing cloneUrl surfaces #11787 stable errors. |
Configuration.md + TenantIngestionModel.md |
Doc check; existing #11787 tests cover normalization/RLS unless a new operator surface is added |
| Parser/source-family cross-link |
Step-Back consumer sweep + existing Source/Parser docs |
Clarify that pull-mode repo files enter the same parser/source-family model as push/bulk ingestion; no new parser contract is introduced by server-side Git acquisition. |
If a source family is unsupported, docs route to existing customSources / customParsers guidance instead of defining a pull-specific parser path. |
CustomSources.md, CustomParsers.md, TenantIngestionModel.md |
Doc link check |
| Deletion telemetry surfacing |
Step-Back consumer sweep + existing ingestSourceFiles({deleted, manifestSnapshot, baseRevision, headRevision}) contract |
Surface deletion count in operator logs and the health payload details (lastSyncDeletedCount) based on the ingestion summary for the sync run. |
Partial ingest or manifest update failure leaves revision state unchanged so the next cycle re-detects and retries deletion idempotently. |
JSDoc + operator section on deleted files |
Unit test simulating deleted path count in service summary and health/log projection |
| Upstream dependency boundary |
#11789 / #11790 Contract Ledgers |
#11791 consumes the final scheduler/envelope contract; it does not invent scheduler state fields before #11790 defines them. If implemented before #11790 merges, the PR must explicitly target a stacked branch and declare the stack. |
Upstream contract drift -> update this ledger before PR open rather than papering over mismatch in review. |
PR body dependency declaration |
Live PR base/head evidence + ledger audit in review |
Context
Sub 6 of Epic #11731 (Server-side tenant-repo ingestion for cloud Agent OS deployments), graduated from Discussion #11782. This sub makes the new pull-based mode operable + observable.
The Problem
A deployment operator needs to (a) configure tenant repos for server-side ingestion, and (b) see repo-freshness without reading raw Chroma rows. Discussion #11782's §5.2 Step-Back sweep flagged the consumer surfaces this mode touches.
The Fix
learn/agentos/cloud-deployment/TenantIngestionModel.mdand adjacent) for the server-side pull mode — config, the credentialed-reference contract, the periodic/manual triggers, the repo-mirror volume.Acceptance Criteria
Out of Scope
Contract Ledger
Per the Contract Completeness Gate for tickets introducing public or consumed surfaces. #11791 introduces operator-visible docs plus health/telemetry surfaces that consume #11787 tenant config, #11788 mirror state, #11789 envelope semantics, and #11790 scheduler state. Contract surface is enumerated below.
TenantIngestionModel.mdpull-mode operator sectiontenantRepos[], credential-reference rules, periodic/manual triggers, mirror volume, redeploy posture, and push-vs-pull coexistence.TenantIngestionModel.md+ cloud-deployment overview linksHealthService.recordTaskOutcome()/healthcheck.orchestrator.taskspatternorchestrator.tasks['tenant-repo-sync'].details.repos[]with{tenantId, repoSlug, lastIngestedRev, lastSyncAt, status, lastErrorCode?, lastSyncDeletedCount?}.tenantRepos[]->repos: [], not omitted; scheduler unavailable -> task statusskippedorfailedwith details explaining unavailable state; no raw Chroma reads.TenantIngestionModel.mdverification sectionrecordTaskOutcome('tenant-repo-sync', ..., details)projection and payload shapeactive= normal cadence and last success;disabled= operator-disabled config;degraded= last cycle failed but retry budget remains;quarantined= backoff threshold exceeded and operator action is needed.active; transient per-tick states are not persisted as long-lived health status.redactTenantRepoSecrets()before logging; degraded retryable failures use warning-level logs unless the lane itself is unhealthy.tenant-repo-mirrorsnamed volume andNEO_TENANT_REPO_MIRROR_ROOTmount as the persistent mirror store used by server-side pull ingestion.TenantIngestionModel.md+DeploymentCookbook.mdtenant repo boundaryGitMirror.cloneIfMissing()on the next sync.tenantRepos[]contracttenantRepos[]is persisted throughKnowledgeBaseIngestionService.setTenantConfig({tenantId, config})or any operator surface implemented by the PR; do not claim an existing MCP tool unless the implementation adds one.credentialRefor credential-bearingcloneUrlsurfaces #11787 stable errors.Configuration.md+TenantIngestionModel.mdcustomSources/customParsersguidance instead of defining a pull-specific parser path.CustomSources.md,CustomParsers.md,TenantIngestionModel.mdingestSourceFiles({deleted, manifestSnapshot, baseRevision, headRevision})contractlastSyncDeletedCount) based on the ingestion summary for the sync run.Behavioral invariants:
quarantinedmust be operator-actionable and point to a runbook section, not just a label.Out of contract scope:
Related
Origin Session ID
39185c66-a107-46ea-b0bf-eb4fa1137257