How the fork is published
The three-tier model that lets this repo be an open fork without leaking the proprietary deployment code — and the rules that route every file.
Tier C — private deploy repo publication plan (Repo 3)
This document covers the single squashed PR that publishes the Tier C subset to the private deploy / marketplace repository (Repo 3 in the three-repo topology).
What Repo 3 IS
Repo 3 is pure deployment infrastructure:
- Azure Bicep templates and parameter files.
- PowerShell deploy + health-check scripts.
- PowerShell operator scripts that companion the
/installroute in the application image (Entra app registration, AOAI provisioning, role assignments). - Shell scripts for CI / supply-chain plumbing (GitHub OIDC bootstrap, ACR image mirroring).
- Deployment-specific design docs and runbooks.
- Marketplace packaging metadata (createUiDefinition.json, mainTemplate.json wrappers, when those land).
What Repo 3 IS NOT
Repo 3 contains zero Mike application code. Specifically:
- No
backend/directory. - No
frontend/directory. - No
Dockerfile,docker-compose.dev.yml, or.dockerignore. - No
package.jsonorpackage-lock.json. - No
.ts/.tsx/.js/.jsxfiles. - No SQL migrations.
- No application-layer documentation (provider design, schema rationale, local-stack runbooks — those all ship to Repo 2).
A clone of Repo 3 cannot be built into an application image. It provisions infrastructure to run an image; the image itself is built from Repo 2 (the public AGPL fork) or pulled from our distribution ACR. That is the entire point of the separation.
For Tier B (application code, Azure adapters, local-dev stack) see
03-fork-publication.md. For the
rationale of why each Tier C item belongs in Repo 3 rather than
Repo 2, see 04-proprietary-retention.md.
Why a separate repo
We could keep Tier C in this dev repo (Repo 1) and just never publish it. Three reasons not to:
- Marketplace audit trail. The Azure Marketplace listing has its own commit history that tracks "which Bicep version produced which marketplace package version." Mixing app-code commits into that history makes it noisy.
- Permission separation. People who maintain marketplace templates don't need read access to application code, and vice-versa. A separate repo lets us scope GitHub team access more tightly.
- Future external collaborators. If we ever bring in a third-party Azure consultant to help with Bicep, we can grant access to Repo 3 without exposing the application source. (Yes, they could read it from Repo 2 — but Repo 2 is the public AGPL fork, not our active development branch.)
Decision: squash, don't replay
Same rationale as Repo 2 — see
03-fork-publication.md.
Each release window produces one squashed commit on Repo 3.
Target repository
Create a new private repository: Altien/Mike-Deploy (name TBC).
Standalone repo (not a GitHub fork of anything). Branch lifecycle
mirrors Repo 2: main carries the canonical squashed commits,
release work happens on feat/deploy-<date> branches.
Relationship to Repo 2
The Bicep templates in Repo 3 reference a Docker image built from Repo 2's source. That image is the only runtime artefact that crosses the Repo 2 ↔ Repo 3 boundary. No source code is shared.
How the image gets there is a deployment-pipeline question:
- For internal dev/prod deployments, our existing CI builds the
image from Repo 1 (where Tier B and Tier C live together) and
pushes to ACR. Repo 3's
deploy.ps1references that image tag. - For marketplace customers, the marketplace package will pin a specific image tag (built from the corresponding Repo 2 commit) and the customer's deployment pulls it from a public registry or from our distribution ACR.
Repo 3 itself does not need to build the image, and a clone of Repo 3 alone cannot produce one. That is by design — the deployment templates are useless without the published application image, and the application image is shipped through Repo 2 (publicly) or our distribution ACR (privately for marketplace).
Branch structure on the private fork
main ← clean baseline (empty, or just README)
├── feat/deploy-2026-05 ← single squashed commit applying entire
Tier C delta from Repo 1's release head
After the first publication, main carries the squashed commit and
is the default branch. Subsequent updates land as additional
squashed commits, one per release window.
Commit shape
Single commit message per release window:
feat: <release-window-name> deploy templates and marketplace package
This commit publishes the Tier C subset of Altien/MikeAzureDev as
of internal head <SHA>: Bicep templates, deploy automation, install
operator scripts, and marketplace packaging.
Companion application image: <image-tag-from-Repo-2-build>
Major contents:
* Bicep templates (infra/) provisioning the Container Apps
Environment, internal-only PostgREST, backend Container App,
migrate Container App Job, Postgres Flexible Server, Storage
Account, Container Registry, Key Vault, Managed Identity,
network topology.
* One-command deploy script (deploy.ps1) that runs the full
provisioning sequence end-to-end: az group create → Bicep
deploy → KV role assignment → KV secret seeding → image build
or import → migrate job run → backend revision promotion.
* Read-only health check (check-azure.ps1).
* Operator install scripts (scripts/install/*.ps1) — companions
to the /install configurator route in the application image.
Each runs locally with the operator's az login to do work the
Container App's Managed Identity cannot do (Entra app creation,
AOAI Foundry deployment, role assignment to the deployer).
* CI / supply-chain automation (scripts/setup-github-oidc.sh,
scripts/mirror-postgrest.sh).
* Tier-C documentation (docs/infra/, docs/install/scripts.md,
docs/azure-production-hardening.md, docs/runbook-dev-deployment.md,
and the Tier-C subset of docs/issues/azure-migration/).
For the application source these templates deploy, see the public
AGPL fork at <Repo 2 URL>.
The commit must be authored as Altien's organizational identity.
What gets published to Repo 3
Everything in Tier C from
01-classification.md — Bicep, deploy
scripts, install scripts, CI/supply-chain plumbing, deployment-
specific documentation.
What does NOT get published to Repo 3
- Everything in Tier B from
01-classification.md. The application code lives in Repo 2. - This
docs/migration/directory — internal planning, stays only in Repo 1. - The
.claude/directory — internal agent harness. - Build artefacts:
dist/,node_modules/,out/. - The frontend's
package-lock.jsonand any other Tier B file — Repo 3 is template-and-script-only; it does not need to know the application's dependency tree.
README for Repo 3
Replace any default README with:
# Mike — Azure deploy templates
Private repository. Bicep templates and operator scripts that
deploy the [Mike application](<Repo 2 URL>) to an Azure tenant.
This repo is the source of the Altien Azure Marketplace listing.
It contains no application code; it provisions the infrastructure
required to run a published Mike application image.
## Repository contents
- `infra/` — Bicep templates (one main.bicep, a parameters file
per environment, per-resource modules under `modules/`).
- `deploy.ps1` — one-command full deployment script.
- `check-azure.ps1` — read-only health check.
- `scripts/install/*.ps1` — operator-run scripts for one-time
setup (Entra app registration, AOAI provisioning, role
assignments).
- `scripts/setup-github-oidc.sh` — bootstraps GitHub Actions
federated identity for CI deployments.
- `scripts/mirror-postgrest.sh` — mirrors the upstream PostgREST
image into our distribution ACR.
- `docs/` — deployment runbooks, infra design docs, install
script reference.
## Deploying
```pwsh
.\deploy.ps1 -Environment dev
See docs/runbook-dev-deployment.md for prerequisites and the full sequence.
Application source
The application image these templates deploy is built from <Repo 2 URL> (public AGPL fork) or pulled from our distribution ACR. This repository never contains application source.
License
Proprietary. Altien internal use.
## Sanitization
Repo 3 is private — sanitization requirements are looser than Repo
2, but a few values still need review before each publication
window:
- **Replace concrete tenant IDs that aren't ours.** If Bicep
parameter files contain customer-specific GUIDs from a previous
customer engagement, scrub them.
- **Confirm `frontend/.env.production` is absent.** That file should
no longer exist anywhere (issue 032), but defence-in-depth.
- **Confirm no application source is staged.** A `find . -name
"*.ts" -not -path "./node_modules/*"` should produce nothing.
Any `.ts` file in Repo 3 is a misclassification.
The pre-publication regex from
[`05-config-extraction.md`](./05-config-extraction.md) is **not**
required for Repo 3 — `rg-mike-dev` and friends are appropriate
references in the deploy templates because Repo 3 is the source of
those templates.
## Per-publication self-test the agent must run
Before pushing to Repo 3, on a clean clone of the publication
branch:
1. **No application source.** Each of these must return nothing —
any match means application code leaked into Tier C and must be
removed before pushing:
```sh
find . -name "*.ts" -not -path "./node_modules/*"
find . -name "*.tsx" -not -path "./node_modules/*"
find . -name "*.sql" -not -path "./node_modules/*"
find . -name "package.json" -not -path "./node_modules/*"
find . -name "Dockerfile*"
find . -name "docker-compose*.yml"
find . -type d \( -name backend -o -name frontend \)
find infra -name "*.bicep" | wc -l— must match the file count from Repo 1'sinfra/. (Sanity check that we didn't drop modules.)pwsh -Command "Get-Command -Syntax ./deploy.ps1"— confirms the deploy script parses cleanly without trying to execute.- Optional but recommended:
bicep build infra/main.bicep— the Bicep CLI's compile-only mode validates every module reference without contacting Azure.
If any step fails, stop. Do not push.
Branch lifecycle on Repo 3
- Initial publication: create the private repo, push the empty
baseline (or a README-only commit) to
main, push the squashed Tier C commit tofeat/deploy-2026-05, internal review, merge. - Subsequent updates:
feat/deploy-<date>branches with new squashed commits, merged tomain. - Cadence: roughly aligned with Repo 2 release windows so the templates reference image tags that actually exist. Mismatch is recoverable (Repo 3 templates can reference older image tags) but best avoided.
Failure handling
Same as Repo 2 — see
03-fork-publication.md.
The only Repo-3-specific failure mode is classification drift:
a file that was Tier B in classification but Tier C in the agent
runbook (or vice-versa). When this happens, fix the classification
in 01-classification.md first, then re-run the runbook from the
top — never push a publication branch that disagrees with the
master classification.