Files
acdl/docs/codeartifact-provisioning.md
Jon Chery 3a09ca8ec1 docs(P01): CodeArtifact provisioning check + fallback (REQ-323, backend-engineer)
CodeArtifact provisioning check in account 581513795199 could not
complete — no AWS credentials available in the P1 execute environment
("Unable to locate credentials"). Per the task spec, provisioning is NOT
attempted (requires codeartifact:* IAM grants not confirmed for the
execute principal). Documented as a P1 blocker for the CodeArtifact mode
of the publish workflow's wheel-upload step.

docs/codeartifact-provisioning.md records:
- (a) the attempted commands (list-domains, describe-repository,
  list-repositories) + the credentials-not-found error
- (b) the required IAM grants for a follow-up provisioning task:
  codeartifact:CreateDomain, CreateRepository, GetRepositoryEndpoint,
  GetAuthorizationToken, ReadFromRepository, PublishPackageToRepository
  + ssm:PutParameter (CAP-035) + lambda:PublishLayerVersion
- (c) the fallback: a private wheel index selected at deploy time via
  the NOVA_WHEEL_INDEX env var (consumers / composite action) and
  TWINE_REPOSITORY_URL + TWINE_USERNAME + TWINE_PASSWORD (publish step).
  The workflow supports both CodeArtifact mode (NOVA_CODEARTIFACT_DOMAIN
  set) and fallback-index mode (unset) — no single hostname is baked
  into the synced workflow files.

CAP-035 invariant (SSM /nova/layer/nova-cli/version = <wheel-version>:
<layer-arn>) is unaffected by the index choice and is recorded
atomically after both the wheel upload + layer publish succeed.

---ci---
project: acdl
phase: 1
milestone: v1.28
status: execute
persona: backend-engineer
---/ci---
2026-08-19 22:34:02 +00:00

6.3 KiB

CodeArtifact Provisioning — Status + Fallback (REQ-323, CAP-035)

Phase P1 (cli-substrate), milestone v1.28. Owner: backend-engineer. This document records the CodeArtifact provisioning check outcome for the nova-cli wheel + Lambda layer publish pipeline (REQ-323), the required IAM grants, and the fallback wheel-index mode the publish workflow supports when CodeArtifact is not yet provisioned.

1. Provisioning check (best-effort, P1 Wave 4 gate)

Target account: 581513795199 (the Nova platform account).

Attempted commands:

aws codeartifact list-domains --region us-east-1
aws codeartifact describe-repository --domain nova --repository nova-pypi --region us-east-1
aws codeartifact list-repositories --domain nova --region us-east-1

Result: the check could not complete — no AWS credentials were available in the P1 execute environment (Unable to locate credentials. You can configure credentials by running aws configure.). This is the "fail gracefully" path documented in the task spec: provisioning is not attempted from this environment because the required IAM grants are not confirmed for the execute principal.

Classification: P1 blocker for the CodeArtifact mode of the publish workflow's wheel-upload step. The workflow ships with a fallback mode (see §3) so the pipeline is not blocked on CodeArtifact provisioning — it can publish to a private wheel index instead.

2. Required IAM grants (for a follow-up provisioning task)

To provision + use CodeArtifact as the wheel index, the principal that runs the publish workflow (OIDC role nova-publish-* or the spike runner) needs the following grants in account 581513795199:

Action Scope (example) Purpose
codeartifact:CreateDomain arn:aws:codeartifact:us-east-1:581513795199:domain/nova create the nova domain
codeartifact:CreateRepository arn:aws:codeartifact:us-east-1:581513795199:repository/nova/* create nova-pypi (pypi-format)
codeartifact:GetRepositoryEndpoint arn:aws:codeartifact:us-east-1:581513795199:repository/nova/nova-pypi get the twine/pip endpoint
codeartifact:GetAuthorizationToken arn:aws:codeartifact:us-east-1:581513795199:domain/nova/* mint short-lived upload token
codeartifact:ReadFromRepository arn:aws:codeartifact:us-east-1:581513795199:repository/nova/nova-pypi pip install (consumers + the composite action)
codeartifact:PublishPackageToRepository arn:aws:codeartifact:us-east-1:581513795199:repository/nova/nova-pypi twine upload
ssm:PutParameter / ssm:GetParameter arn:aws:ssm:us-east-1:581513795199:parameter/nova/layer/* CAP-035 version↔ARN mapping
lambda:PublishLayerVersion arn:aws:lambda:us-east-1:581513795199:layer:nova-cli Lambda layer publish
iam:CreateRole / iam:PassRole (already held) only if a dedicated publish OIDC role must be created

The domain + repository to provision:

  • Domain: nova
  • Repository: nova-pypi (format: pypi)
  • Endpoint (twine/pip): https://nova-581513795199.d.codeartifact.us-east-1.amazonaws.com/pypi/nova-pypi/

Once provisioned, set the repository secret NOVA_CODEARTIFACT_DOMAIN=nova on both forges and the publish workflow + composite action will switch to CodeArtifact mode automatically (see §3).

3. Fallback: private wheel index (NOVA_WHEEL_INDEX)

Both the publish workflow (.github/workflows/publish.yml and its byte-identical mirror on the dev forge) and the composite action (.github/actions/nova-cli/action.yml) support a fallback mode that does not require CodeArtifact. The selection is env/secret driven:

Mode Trigger Upload target Install source
CodeArtifact NOVA_CODEARTIFACT_DOMAIN env/secret is set aws codeartifact login --tool twine → twine uploads to the CodeArtifact pypi endpoint aws codeartifact login --tool pippip install nova==<ver>
Fallback index NOVA_CODEARTIFACT_DOMAIN unset; TWINE_REPOSITORY_URL + TWINE_USERNAME + TWINE_PASSWORD set twine upload to TWINE_REPOSITORY_URL pip install --index-url $NOVA_WHEEL_INDEX nova==<ver>

The fallback index can be any PEP 503-compliant simple index — e.g. a private package registry hosted on the dev forge, a self-hosted pypiserver, or a static S3-backed index. The workflow does not hardcode the index URL; it is supplied via the NOVA_WHEEL_INDEX env var (for consumers / the composite action) and TWINE_REPOSITORY_URL (for the publish step). This keeps the forge/registry choice deployment-specific and avoids baking any single hostname into the synced workflow files.

3.1 Fallback index shape (when self-hosted)

A minimal PEP 503 simple index served from a private registry is sufficient. The only required layout per package:

/nova/
  index.html                         # links to each version's page
  /nova-<version>-py3-none-any.whl   # the wheel (publish workflow uploads this)

The publish workflow uploads dist/nova-<version>-*.whl via twine upload to TWINE_REPOSITORY_URL; consumers install via pip install --index-url "$NOVA_WHEEL_INDEX" nova==<version>.

4. CAP-035 invariant (unaffected by the index choice)

Regardless of which wheel index is used, the Lambda layer ARN ↔ wheel version mapping is recorded in SSM and is the source of truth for CAP-035:

/nova/layer/nova-cli/version = "<wheel-version>:<layer-arn>"

e.g. 1.14.0:arn:aws:lambda:us-east-1:581513795199:layer:nova-cli:3. The publish workflow writes this parameter atomically after both the wheel upload and the layer publish succeed; if either fails the job fails (merge blocked, REQ-323 AC).

5. Open follow-ups

  1. Provision CodeArtifact domain nova + repository nova-pypi in 581513795199 once the codeartifact:* grants in §2 are attached to the publish OIDC role. Update this document with the confirmed ARN + endpoint.
  2. Set the NOVA_CODEARTIFACT_DOMAIN repository secret on both forges to switch the publish workflow + composite action from fallback-index mode to CodeArtifact mode.
  3. Until §1 is done, the fallback index must be provisioned out of band and its URL exposed to consumers via the NOVA_WHEEL_INDEX env var (and to the publish workflow via the TWINE_* secrets).