# User Service Delivery Policy

This document owns the default delivery path for UniDesk user services registered in `config.json.microservices[]`, together with the paired frontend verification expectations for those services. It does not replace `docs/reference/deploy.md`, `docs/reference/ci.md`, `docs/reference/dev-environment.md`, or `docs/reference/microservices.md`; it states the default release order that future user-service work should follow unless a service-specific exception is documented.

## Scope

User services are non-core business services mounted onto the UniDesk platform. They must remain deliverable without changing the base platform strategy. The default policy here applies to user services that are expected to reach production after validation, including the UniDesk user-service UI artifact (`frontend`), main-server direct services such as Baidu Netdisk, NC01-managed k8s services such as Decision Center and Todo Note, D601-managed k3s services such as MDTODO and ClaudeQQ, and D601 direct Docker/Compose services such as FindJob and Pipeline. Code Queue is a special dev-only artifact consumer in this policy; its production execution plane must not be deployed by the user-service artifact consumer.

This policy does not apply to:

- core platform services;
- CI/CD infrastructure itself;
- provider-gateway;
- `k3sctl-adapter`;
- `release/v1` governance;
- one-off infrastructure repair actions.
- production Code Queue artifact deploy or rollout.

`todo-note` is a UniDesk-vendored NC01 service with a service-specific Pipelines-as-Code producer and Argo CD consumer. It is intentionally outside the generic D601 `ci publish-user-service` and `deploy apply --env ...` flow.

## Default Release Flow

The default release flow for a user-service change is:

1. CI builds the user-service image on D601 from a pushed Git commit.
2. CI publishes the commit-pinned image to the D601 host-managed registry.
3. The dev environment runs automated validation against that same commit-pinned artifact.
4. CD on the production side pulls the registry artifact and deploys it without rebuilding the source.
5. Manual acceptance is performed after the live deployment has been verified.

## Operating Rules

- CI may carry heavier dependency resolution, build cache, and test cost than CD.
- CD must stay low-dependency and fast.
- No user-service artifact may rely on a third-party registry as source of truth.
- No production deploy may rebuild the source from a dirty worktree.
- Commit-pinned image tags are the deployment truth; mutable `latest` tags are not.
- Root `CI.json` is an artifact catalog only. It lists CI producer inputs such as `serviceId`, artifact kind, source repository, repo-relative Dockerfile, image repository naming, upstream image digest/mirror metadata and the required artifact summary fields; it must not carry runtime topology or replace `deploy.json`.
- `deploy.json` is the release-intent source for services owned by the generic deploy reconciler. NC01 YAML-first services use their service YAML and PaC/GitOps branch as desired-state truth instead; they must not be duplicated into `deploy.json` as an active consumer. The consolidation track is [GitHub issue #60](https://github.com/pikasTech/unidesk/issues/60).
- For artifacts whose `CI.json` producer is `ci publish-user-service`, the standard command is `bun scripts/cli.ts ci publish-user-service --service <id> --commit <full-sha>`. It accepts only a pushed Git commit and a service id registered to that producer, reads `source.repo` and `source.dockerfile` from the catalog, rejects ad hoc `--repo` overrides, and reports `serviceId`, `sourceCommit`, `sourceRepo`, `dockerfile`, `imageRef`, `tag`, `digest` and `digestRef`. Services owned by another producer are rejected before any remote action and the CLI names the owning entrypoint.
- The producer dry-run preflight is `bun scripts/cli.ts ci publish-user-service --service <id> --commit <full-sha> --dry-run`. It is read-only and reports detailed `missingChannels` plus stable `missingControlChannels` for `backend-core`, `database`, `provider` and `registry`; any missing control channel is `runnerDisposition=infra-blocked`. The `controlledPublish` field names D601 `unidesk-ci` as the only controlled environment for the subsequent real publish.
- The CI artifact producer is not a deploy executor. It must not mutate the production namespace, restart production services, or update `deploy.json`.
- `CI.json` may list `blocked` source-build entries when the source input is known but the publish/CD boundary is not yet reviewed. It may also list `upstream-image` entries for image-only services such as File Browser; those entries pin upstream digest and mirror intent but must not be treated as Dockerfile builds.
- Every production release must finish with a manual acceptance step after the automated checks pass.
- Multi-service delivery programs may use AgentRun Queue parallelization, but the supervisor must follow `docs/reference/code-queue-supervision.md`: tasks need self-contained prompts, isolated worktrees, bounded queue concurrency, explicit acceptance evidence, and infrastructure defects split into separate follow-up tasks when they block several lanes. Legacy Code Queue remains an archive/read-only troubleshooting surface for old tasks, not a new-task dispatch path.

## Upstream Image Services

Some registered user services are intentionally upstream-image consumers instead of source-built services. `filebrowser` and `filebrowser-d601` are in this class.

- They must be cataloged as `CI.json.artifacts[]` entries with `kind=upstream-image`, not as Dockerfile `source-build` producers.
- `ci publish-user-service` must return a structured blocked result for them; there is no UniDesk Dockerfile build for these services.
- The release input is an upstream manifest digest or a digest-verified mirror in the D601 registry, not a Git commit tag built by Tekton.
- CD must be pull-only and must verify the image identity, OCI labels and service health through the UniDesk private proxy.
- Until the upstream digest has been resolved and mirrored or pinned for a future mirror producer, File Browser remains a recovery/diagnostic image-only path rather than a standard release path.

The current catalog covers `frontend`, `baidu-netdisk`, `decision-center`, `project-manager`, `oa-event-flow`, `code-queue-mgr`, `findjob`, `pipeline`, `met-nonlinear`, `k3sctl-adapter`, `mdtodo` and `claudeqq` as supported `publish-user-service` source-build services. Todo Note remains a supported source build, but its producer is `platform-infra pipelines-as-code`. `k3sctl-adapter` is cataloged for artifact visibility, but it is not a user-service live deploy target in this policy. `code-queue` is cataloged but blocked by the D601 dev/prod boundary. `filebrowser` and `filebrowser-d601` are cataloged as pinned upstream images, not source builds.

## Frontend Pairing

Many user services are surfaced through the UniDesk frontend rather than through their own browser-exposed product. When a user-service backend has a paired UniDesk frontend page, the frontend change must be validated in the same dev/prod release window as the backend artifact. The frontend itself is also a reviewed artifact producer/consumer sample: its release unit is `127.0.0.1:5000/unidesk/frontend:<commit>`, and the live UI must expose the same requested commit through image labels and `/health.deploy.commit`.

The paired frontend's default route must continue to expose the real user workflow. Diagnostics or status surfaces may exist for verification and recovery, but they must stay explicit secondary routes and must not replace the default product entry. The traceability record for this boundary is `DC-DCSN-P0-2026-004`.

## Frontend

Frontend is the canonical user-service UI sample. It is not released by target-side source build as the standard path.

- The minimal standard artifact command is `bun scripts/cli.ts ci publish-user-service --service frontend --commit <full-sha> --wait-ms 1200000`.
- The expected artifact is `127.0.0.1:5000/unidesk/frontend:<commit>` plus its registry digest from the CI output.
- Lightweight closure evidence checks `deploy.json` dev/prod desired commits, the `CI.json` producer entry, the observed registry digest, dev/prod `/health.deploy.commit` and `deploy.requestedCommit`, producer dry-run readiness, and dev/prod CD dry-run no-build targets.
- Dev CD consumes the same artifact with `bun scripts/cli.ts deploy apply --env dev --service frontend`; it imports the image into D601 native k3s, rolls out `frontend-dev`, syncs auth/session metadata from main-server config, and verifies `/health.deploy.commit`.
- Production CD consumes the same artifact with `bun scripts/cli.ts deploy apply --env prod --service frontend`; it recreates only the master-server Compose `frontend` service with `--no-build --no-deps --force-recreate` and verifies image labels plus `/health.deploy.commit`.
- `server rebuild frontend` remains a maintenance/local rebuild path only. It is not the standard versioned release truth for frontend.
- Production acceptance must explicitly verify the public `/health` payload, the requested commit, the running image label, and the expected UI routes for the changed user-service pages.

## Baidu Netdisk

Baidu Netdisk is the canonical main-server direct user-service sample.

- The minimal standard artifact command is `bun scripts/cli.ts ci publish-user-service --service baidu-netdisk --commit <full-sha> --wait-ms 1200000`.
- The expected artifact is `127.0.0.1:5000/unidesk/baidu-netdisk:<commit>` plus its registry digest from the CI output.
- Dev validation consumes the same artifact with `bun scripts/cli.ts deploy apply --env dev --service baidu-netdisk`; this is a pull-only Compose validation path, not a source build on the master server.
- Production CD consumes the same artifact with `bun scripts/cli.ts deploy apply --env prod --service baidu-netdisk`; it recreates only `baidu-netdisk-backend` and verifies image labels plus `/health.deploy.commit`.
- `server rebuild baidu-netdisk` remains a maintenance/local rebuild path only. It is not the standard versioned release truth for Baidu Netdisk.
- Production acceptance must explicitly verify `microservice health baidu-netdisk`, `microservice proxy baidu-netdisk /api/transfers`, private `4244` exposure, and live commit / artifact information.

## Project Manager

Project Manager follows the same commit-pinned artifact flow as Baidu Netdisk, but the runtime target is the master-server Compose service `project-manager`.

- The minimal standard artifact command is `bun scripts/cli.ts ci publish-user-service --service project-manager --commit <full-sha> --wait-ms 1200000`.
- The expected artifact is `127.0.0.1:5000/unidesk/project-manager:<commit>` plus its registry digest from the CI output.
- Dev CD consumes the same artifact with `bun scripts/cli.ts deploy apply --env dev --service project-manager`; prod CD consumes it with `bun scripts/cli.ts deploy apply --env prod --service project-manager`.
- `server rebuild project-manager` remains a maintenance/local rebuild path only. It is not the standard versioned release truth for Project Manager.
- Production acceptance must explicitly verify `microservice health project-manager`, `microservice proxy project-manager /api/projects`, private `4233` exposure, and live commit / artifact information.

## OA Event Flow

OA Event Flow follows the same master-server Compose artifact flow as Project Manager.

- The minimal standard artifact command is `bun scripts/cli.ts ci publish-user-service --service oa-event-flow --commit <full-sha> --wait-ms 1200000`.
- The expected artifact is `127.0.0.1:5000/unidesk/oa-event-flow:<commit>` plus its registry digest from the CI output.
- Dev CD consumes the same artifact with `bun scripts/cli.ts deploy apply --env dev --service oa-event-flow`; prod CD consumes it with `bun scripts/cli.ts deploy apply --env prod --service oa-event-flow`.
- `server rebuild oa-event-flow` remains a maintenance/local rebuild path only. It is not the standard versioned release truth for OA Event Flow.
- Production acceptance must explicitly verify `microservice health oa-event-flow`, `microservice proxy oa-event-flow /api/diagnostics`, private `4255` exposure, and live commit / artifact information.

## Code Queue Manager

`code-queue-mgr` is the master-server internal sidecar control plane, so it follows artifact consumer validation but not unrestricted prod automation.

- The minimal standard artifact command is `bun scripts/cli.ts ci publish-user-service --service code-queue-mgr --commit <full-sha> --wait-ms 1200000`.
- The expected artifact is `127.0.0.1:5000/unidesk/code-queue-mgr:<commit>` plus its registry digest from the CI output.
- Dev validation uses `bun scripts/cli.ts deploy apply --env dev --service code-queue-mgr`; prod dry-run uses `bun scripts/cli.ts deploy apply --env prod --service code-queue-mgr --dry-run`.
- Live prod apply requires explicit supervisor confirmation and is not the worker default.
- `server rebuild code-queue-mgr` remains a maintenance/local rebuild path only. It is not the standard versioned release truth for Code Queue Manager.
- Production acceptance must explicitly verify `microservice health code-queue-mgr`, the Compose container image label, and the live health payload.

## Todo Note

Todo Note follows the same NC01 YAML-first and GitHub-backed operating model as Decision Center, while retaining its existing action/history API contract.

- Source is vendored at `src/components/microservices/todo-note`; `config/unidesk-host-k8s.yaml` is the runtime, Secret, storage and delivery source of truth.
- Production runs as private `unidesk/deployment/todo-note` and `unidesk/service/todo-note`. It has no NodePort, hostPort or separate public frontend.
- `CI.json` assigns the source build to `platform-infra pipelines-as-code`. `ci publish-user-service --service todo-note` must reject the request before contacting D601.
- The NC01 PaC consumer is `unidesk-host`, reusing Repository `sentinel-nc01-v03`; Tekton publishes a commit image, the GitOps branch pins its digest, and Argo CD owns the Todo Note Service/Deployment.
- Durable state is GitHub repo `pikasTech/decision-center-data`, branch `main`, base path `todo-note`. Decision Center keeps base path `data`, so the services share one repository without sharing object paths. PostgreSQL is an index/cache only.
- GitHub SSH credentials come only from the YAML-declared Secret sourceRef shared with Decision Center; CLI output exposes presence and fingerprints, never key material.
- Controlled release evidence is `platform-infra pipelines-as-code plan|apply|status|closeout --target NC01 --consumer unidesk-host`, followed by `microservice health todo-note` and storage diagnostics.
- CC01 migration completed through `POST /api/storage/import`: all six lists, 1167 history rows and the reminder-notification ledger were preserved; DB/Git hashes and a create/add/update/undo/redo/delete lifecycle passed before the old container and legacy Compose/deploy ownership were retired.

## D601 Direct Compose Consumers

FindJob and Pipeline are D601 direct Docker/Compose user services. They differ from k3s-managed services because the artifact consumer operates on the D601 Docker host and the existing Compose project, not on Kubernetes manifests, containerd imports, or Kubernetes API service proxies.

- `findjob` consumes `127.0.0.1:5000/unidesk/findjob:<commit>` and recreates only Compose service `server` in `/home/ubuntu/findjob`.
- `pipeline` consumes `127.0.0.1:5000/unidesk/pipeline:<commit>` and recreates only Compose service `pipeline-control` in `/home/ubuntu/pipeline`.
- Dev validation currently means D601 registry pull + required image labels + config/compose dry-run + health contract. It is not yet a separate parallel dev instance.
- Production CD is pull-only and no-build: it verifies the registry manifest and image labels, writes deploy env/labels, and runs `docker compose up -d --no-build --no-deps --force-recreate <service>`.
- `met-nonlinear` has the same dry-run/plan shape, but live deploy is blocked until the long-running `met-nonlinear-ts` image contract can prove the requested commit label independently from the ML image Dockerfile.
- `k3sctl-adapter` has an artifact consumer plan/dry-run only. Real production deployment of that infrastructure bridge requires supervisor confirmation outside this policy.

## Decision Center

Decision Center is the canonical example of a user service that doubles as a product workflow for requirements, decisions, and daily work diaries. Its current production truth is NC01 k8s plus GitHub repo storage; the older D601 artifact-consumer text is migration history only.

- Production deploy must use the YAML-first NC01 k8s path from `config/unidesk-host-k8s.yaml`; the live objects are `unidesk/deployment/decision-center` and `unidesk/service/decision-center`.
- Durable data must be stored in GitHub repo `pikasTech/decision-center-data` branch `main` under `data`; PostgreSQL is only an index/cache and must not be treated as the durable truth.
- GitHub SSH access must be distributed through YAML-declared Secret sourceRefs, with operator output limited to object/key presence and fingerprints.
- Requirements and follow-up items should be represented with structured records such as `goal`, `decision`, `blocker`, `debt`, and `experiment`, with linked evidence and goal references.
- The service should act as a demand-management surface for external goals that need to be decomposed into internal tasks, blockers, and decisions.
- The document-management surface must support the engineering document number format `DC-<TYPE>-<PRIORITY>-<YEAR>-<SEQ>` defined in `docs/reference/microservices.md`, including unique `docNo` storage, 4-letter document type codes, P-level priority, signing metadata, replacement links and list/detail filtering by document number.
- The work-diary surface should support creating today's diary entry automatically from the real current date.
- Historical diary entries should be editable by date, with the GitHub repo remaining the source of truth.
- The resulting product surface should stay structured and reviewable, not collapse into an untracked chat log.
- Before any production deploy, the dev gate must pass first with the focused Decision Center E2E set covering `microservice:decision-center-record-crud`, `microservice:decision-center-diary-lifecycle`, `frontend:decision-center-visible`, `frontend:decision-center-demand-management-visible`, and `frontend:decision-center-diary-visible`; this is an automated user-service validation gate, not a production deploy.
- Document-management changes must first land through the NC01 Decision Center lane and extend the focused E2E set with doc-number creation/upsert/list/detail uniqueness, GitHub storage migration/backfill, frontend visibility and temporary body-prefix compatibility before production rollout.
- Production acceptance is manual after the dev gate and must explicitly verify `health`, `records`, `diary editor`, the paired frontend page, no public business ports, and live commit / artifact information.
- Acceptance notes may cite diagnostics/status pages as evidence, but those pages must be labeled as diagnostics and not as the default user workflow.

Detailed service-level API and UI contracts remain in `docs/reference/microservices.md`.

## MDTODO

MDTODO is a k3s-managed user-service artifact consumer.

- The minimal standard artifact command is `bun scripts/cli.ts ci publish-user-service --service mdtodo --commit <full-sha> --wait-ms 1200000`.
- The expected artifact is `127.0.0.1:5000/unidesk/mdtodo:<commit>` plus its registry digest from the CI output.
- The selected commit must include the `UNIDESK_DEPLOY_*` health metadata surface; `/health.deploy` and `/live.deploy` are verified through service health or dry-run/live entry evidence, not through default contract tests.
- Dev CD must run before prod CD and lands in `unidesk-dev/mdtodo-dev`; production CD lands in `unidesk/mdtodo`.
- Both paths must verify Deployment metadata and `/health` or `/live` deploy commit through the Kubernetes API service proxy.
- No MDTODO release may add NodePort, hostPort, public business ports or provider-gateway direct business backends.

## ClaudeQQ

ClaudeQQ is a k3s-managed user-service artifact consumer built from the external `https://gitee.com/lyon1998/agent_skills` repository with UniDesk deployment assets overlaid.

- The minimal standard artifact command is `bun scripts/cli.ts ci publish-user-service --service claudeqq --commit <full-sha> --wait-ms 1200000`.
- The expected artifact is `127.0.0.1:5000/unidesk/claudeqq:<commit>` plus its registry digest from the CI output.
- Dev CD must run before prod CD and lands in `unidesk-dev/claudeqq-dev`; production CD lands in `unidesk/claudeqq`.
- Both paths must verify Deployment metadata and service health through the Kubernetes API service proxy.
- No ClaudeQQ release may expose NapCat or backend ports through NodePort, hostPort, public business ports or provider-gateway direct business backends.

## Code Queue

Code Queue is dev-only for this artifact-consumer policy.

- The minimal standard artifact command is `bun scripts/cli.ts ci publish-user-service --service code-queue --commit <full-sha> --wait-ms 1200000`.
- The expected artifact is `127.0.0.1:5000/unidesk/code-queue:<commit>` plus its registry digest from the CI output.
- Dev CD may be planned only with `deploy apply --env dev --service code-queue --dry-run` or the equivalent artifact-registry dry-run from a Code Queue task. The dry-run must expose `selfBootstrapGuard`, `requiresSupervisorApproval`, commit tag/digest provenance and pull-only/no-build behavior; any real DEV apply that updates `unidesk-dev` scheduler/read/write/provider-egress-proxy objects requires human operator or supervisor authorization outside the running Code Queue task.
- Production artifact deploy, production rollout and production manifest mutation for `code-queue` are unsupported and must fail visibly.
