You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Part of Borrow, Prove, Restore (Azure/osdu-spi#158), Phase 2. Continues #130, whose trust half shipped in #174 and #179.
The source-policy half shipped in #274 (v0.21.0): items 1 to 3 and their docs. What remains is the declaration, items 4 and 5. Start it after #275 lands, since the refresh path it reconciles into gets its fork step there. It needs its own release and a run on the shared environment before it closes.
Problem
ADR-032 and ADR-033 describe a declaration format the code does not have. The declaration in src/spi/environment.py is the flat seven-key schema; it has no forks: list, spi up takes no --declaration, and the refresh and upgrade workflows reconcile nothing from it. An environment's forks exist only as the resource-group tags and federated credentials spi onboard wrote by hand, so no reviewed file says which forks an environment should follow, and nothing puts them back when they drift.
Required change
The decision records are the spec. Read ADR-032 (Declared intent wins, Onboarding plans by default), ADR-033 (Decision), ADR-029 (Identities belong to the lifecycle), and docs/design/fork-deployment.md before starting, and implement what they describe rather than redesigning it.
Source policy on the CLI. Done in feat(cli): canonical image source policy and spi service refresh #274. spi onboard <service> --repo <org>/<fork> --canonical-source fork|community writes the spi-source-<service> tag; --list reports source beside trust; --remove returns the service to community before revoking trust.
Resolution honors the source. Done in feat(cli): canonical image source policy and spi service refresh #274. The resolver accepts either package name a fork can publish and refuses a fork source that isn't the trusted repository. spi info --json carries the source per service; spi service list stays a list of pins. spi service refresh <service> moves one service without touching the rest.
Declaration forks:. Extend EnvironmentDeclaration with an optional forks list of {service, repo, canonicalSource} (canonicalSource defaults to community). repo unique across the list, service known to IMAGE_REGISTRY, forks invalid with any profile but core. spi up --declaration <owner>/<repo>:<path> loads the reviewed file from main, records the locator in the RG tag spi-environment-declaration, and refuses explicit flags that conflict with it. A later spi up without the option reads the retained locator.
Lifecycle reconciliation. On a declared environment, spi up bootstrap and the refresh path reconcile the deploy identity's federated credentials and the source tags to forks: before projecting into the lock, serially per identity with the backoff ADR-032 requires. spi onboard on a declared environment refuses an addition, removal, repository change, or source choice that disagrees with the declaration and says which file to change.
Docs. The --canonical-source mechanics shipped in feat(cli): canonical image source policy and spi service refresh #274. docs/design/fork-deployment.md still needs a forks: example, and docs/design/environment-lifecycle.md the reconcile order. ADRs need no change unless the implementation deviates; if it must, amend the record in the same PR and say why. No em dashes; follow docs/STYLE.md.
Acceptance
A declaration with forks: and profile: minimal fails validation; a duplicate repo fails validation; spi up --declaration on a fresh environment records the locator and leaves credentials and source tags matching the file.
spi onboard against a declared environment refuses an undeclared repository and names the declaration file.
A declared fork whose source tag or credential was removed by hand is restored by the next refresh.
Unit tests cover the planner rows for declaration reconciliation and declaration validation, in the style of tests/test_onboard.py (canned observed state, no simulated GitHub or Azure).
Verify
uv run pre-commit run --all-files
Report the result in the PR description. The end-to-end acceptance lines above need a real environment; state in the PR which of them you ran and which a maintainer must run on the shared environment.
Part of Borrow, Prove, Restore (Azure/osdu-spi#158), Phase 2. Continues #130, whose trust half shipped in #174 and #179.
The source-policy half shipped in #274 (v0.21.0): items 1 to 3 and their docs. What remains is the declaration, items 4 and 5. Start it after #275 lands, since the refresh path it reconciles into gets its fork step there. It needs its own release and a run on the shared environment before it closes.
Problem
ADR-032 and ADR-033 describe a declaration format the code does not have. The declaration in
src/spi/environment.pyis the flat seven-key schema; it has noforks:list,spi uptakes no--declaration, and the refresh and upgrade workflows reconcile nothing from it. An environment's forks exist only as the resource-group tags and federated credentialsspi onboardwrote by hand, so no reviewed file says which forks an environment should follow, and nothing puts them back when they drift.Required change
The decision records are the spec. Read ADR-032 (Declared intent wins, Onboarding plans by default), ADR-033 (Decision), ADR-029 (Identities belong to the lifecycle), and
docs/design/fork-deployment.mdbefore starting, and implement what they describe rather than redesigning it.spi onboard <service> --repo <org>/<fork> --canonical-source fork|communitywrites thespi-source-<service>tag;--listreports source beside trust;--removereturns the service to community before revoking trust.spi info --jsoncarries the source per service;spi service liststays a list of pins.spi service refresh <service>moves one service without touching the rest.-load, as the template'sload-imageaction publishes it (ADR-033 amended to match).forks:. ExtendEnvironmentDeclarationwith an optionalforkslist of{service, repo, canonicalSource}(canonicalSourcedefaults tocommunity).repounique across the list,serviceknown toIMAGE_REGISTRY,forksinvalid with any profile butcore.spi up --declaration <owner>/<repo>:<path>loads the reviewed file frommain, records the locator in the RG tagspi-environment-declaration, and refuses explicit flags that conflict with it. A laterspi upwithout the option reads the retained locator.spi upbootstrap and the refresh path reconcile the deploy identity's federated credentials and the source tags toforks:before projecting into the lock, serially per identity with the backoff ADR-032 requires.spi onboardon a declared environment refuses an addition, removal, repository change, or source choice that disagrees with the declaration and says which file to change.--canonical-sourcemechanics shipped in feat(cli): canonical image source policy and spi service refresh #274.docs/design/fork-deployment.mdstill needs aforks:example, anddocs/design/environment-lifecycle.mdthe reconcile order. ADRs need no change unless the implementation deviates; if it must, amend the record in the same PR and say why. No em dashes; followdocs/STYLE.md.Acceptance
forks:andprofile: minimalfails validation; a duplicaterepofails validation;spi up --declarationon a fresh environment records the locator and leaves credentials and source tags matching the file.spi onboardagainst a declared environment refuses an undeclared repository and names the declaration file.tests/test_onboard.py(canned observed state, no simulated GitHub or Azure).Verify
Report the result in the PR description. The end-to-end acceptance lines above need a real environment; state in the PR which of them you ran and which a maintainer must run on the shared environment.
Out of scope
ops/environments/shared.yamlto a fork declaration for the shared environment; that is a follow-up PR by a maintainer once this merges.Constraints
feat/declared-forks. Conventional Commits; PR titlefeat(cli): declared forks and lifecycle reconciliation.CONTRIBUTING.md.