Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/managed-release-canary.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ on:
project_readiness_targets:
description: Comma-separated parent issues to reflect project 17 readiness
required: true
default: equaltoai/lesser#658,equaltoai/lesser-body#98,equaltoai/lesser-host#109,equaltoai/lesser-host#110
default: equaltoai/lesser#658,equaltoai/lesser-body#106,equaltoai/lesser-host#129
type: string
control_plane_base_url:
description: lesser-host base URL
Expand Down
53 changes: 52 additions & 1 deletion cdk/lib/provision-runner-buildspec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,36 @@ export function renderProvisionRunnerBuildCommands(): string {
' BODY_LAMBDA_PATH=$(jq -r \'.artifacts.lambda_zip.path // empty\' "$body_release_dir/lesser-body-release.json")',
' test "$BODY_LAMBDA_PATH" = "lesser-body.zip" || fail "unexpected lesser-body lambda zip path: $BODY_LAMBDA_PATH"',
'}',
'upload_optional_artifact() {',
' artifact_path="$1"',
' artifact_key="$2"',
' if [ -n "$artifact_key" ] && [ -f "$artifact_path" ]; then',
' aws s3 cp "$artifact_path" "s3://$ARTIFACT_BUCKET/$artifact_key" >/dev/null 2>&1 || true',
' fi',
'}',
'write_lesser_body_artifact() {',
' artifact_path="$1"',
' status="$2"',
' release_version="$3"',
' template_path="$4"',
' stack_name="$5"',
' verification_mode="$6"',
' detail_path="$7"',
' detail=""',
' if [ -f "$detail_path" ]; then',
' detail=$(tail -n 40 "$detail_path")',
' fi',
' jq -n --arg status "$status" --arg release_version "$release_version" --arg template_path "$template_path" --arg stack_name "$stack_name" --arg verification_mode "$verification_mode" --arg detail "$detail" --arg verified_at "$(date -u +"%Y-%m-%dT%H:%M:%SZ")" \'{version:1,status:$status,lesser_body_version:$release_version,template_path:$template_path,stack_name:$stack_name,verification_mode:$verification_mode,detail:$detail,verified_at:$verified_at}\' > "$artifact_path"',
'}',
'run_lesser_body_helper_with_capture() {',
' log_path="$1"',
' shift',
' : > "$log_path"',
' if "$@" > >(tee -a "$log_path") 2> >(tee -a "$log_path" >&2); then',
' return 0',
' fi',
' return 1',
'}',
'TAG_NORMALIZED=$(printf "%s" "$TAG" | tr "[:upper:]" "[:lower:]")',
'if [ -z "$TAG" ] || [ "$TAG_NORMALIZED" = "latest" ]; then',
' echo "Resolving latest Lesser release..."',
Expand Down Expand Up @@ -296,9 +326,30 @@ export function renderProvisionRunnerBuildCommands(): string {
' echo "Using lesser-body release: $BODY_TAG"',
' BODY_RELEASE_DIR="$(pwd)/lesser-body-release"',
' prepare_lesser_body_release_dir "$BODY_RELEASE_DIR" "$BODY_OWNER" "$BODY_REPO" "$BODY_TAG" "$STAGE"',
' BODY_STACK_NAME="$APP_SLUG-$STAGE-lesser-body"',
' BODY_TEMPLATE_PATH="lesser-body-managed-$STAGE.template.json"',
' BODY_ASSET_BUCKET="cdk-hnb659fds-assets-$TARGET_ACCOUNT_ID-$TARGET_REGION"',
' BODY_ASSET_PREFIX="managed/lesser-body/$APP_SLUG/$STAGE/$BODY_TAG"',
' AWS_PROFILE=managed bash "$BODY_RELEASE_DIR/deploy-lesser-body-from-release.sh" --stack-name "$APP_SLUG-$STAGE-lesser-body" --asset-bucket "$BODY_ASSET_BUCKET" --asset-prefix "$BODY_ASSET_PREFIX" --app "$APP_SLUG" --stage "$STAGE" --base-domain "$BASE_DOMAIN"',
' BODY_TEMPLATE_CERT_PATH="$STATE_DIR/body-template-certification.json"',
' BODY_FAILURE_PATH="$STATE_DIR/body-failure.json"',
' BODY_TEMPLATE_CERT_LOG="$STATE_DIR/body-template-certification.log"',
' BODY_DEPLOY_LOG="$STATE_DIR/body-deploy.log"',
' rm -f "$BODY_TEMPLATE_CERT_PATH" "$BODY_FAILURE_PATH" "$BODY_TEMPLATE_CERT_LOG" "$BODY_DEPLOY_LOG"',
' if run_lesser_body_helper_with_capture "$BODY_TEMPLATE_CERT_LOG" env AWS_PROFILE=managed bash "$BODY_RELEASE_DIR/deploy-lesser-body-from-release.sh" --stack-name "$BODY_STACK_NAME" --asset-bucket "$BODY_ASSET_BUCKET" --asset-prefix "$BODY_ASSET_PREFIX" --app "$APP_SLUG" --stage "$STAGE" --base-domain "$BASE_DOMAIN" --no-execute-changeset; then',
' write_lesser_body_artifact "$BODY_TEMPLATE_CERT_PATH" "passed" "$BODY_TAG" "$BODY_TEMPLATE_PATH" "$BODY_STACK_NAME" "cloudformation_deploy_no_execute_changeset" "$BODY_TEMPLATE_CERT_LOG"',
' upload_optional_artifact "$BODY_TEMPLATE_CERT_PATH" "${BODY_TEMPLATE_CERT_S3_KEY:-}"',
' else',
' write_lesser_body_artifact "$BODY_TEMPLATE_CERT_PATH" "failed" "$BODY_TAG" "$BODY_TEMPLATE_PATH" "$BODY_STACK_NAME" "cloudformation_deploy_no_execute_changeset" "$BODY_TEMPLATE_CERT_LOG"',
' upload_optional_artifact "$BODY_TEMPLATE_CERT_PATH" "${BODY_TEMPLATE_CERT_S3_KEY:-}"',
' write_lesser_body_artifact "$BODY_FAILURE_PATH" "failed" "$BODY_TAG" "$BODY_TEMPLATE_PATH" "$BODY_STACK_NAME" "cloudformation_deploy_no_execute_changeset" "$BODY_TEMPLATE_CERT_LOG"',
' upload_optional_artifact "$BODY_FAILURE_PATH" "${BODY_FAILURE_S3_KEY:-}"',
' fail "lesser-body template certification failed for $BODY_TEMPLATE_PATH"',
' fi',
' if ! run_lesser_body_helper_with_capture "$BODY_DEPLOY_LOG" env AWS_PROFILE=managed bash "$BODY_RELEASE_DIR/deploy-lesser-body-from-release.sh" --stack-name "$BODY_STACK_NAME" --asset-bucket "$BODY_ASSET_BUCKET" --asset-prefix "$BODY_ASSET_PREFIX" --app "$APP_SLUG" --stage "$STAGE" --base-domain "$BASE_DOMAIN"; then',
' write_lesser_body_artifact "$BODY_FAILURE_PATH" "failed" "$BODY_TAG" "$BODY_TEMPLATE_PATH" "$BODY_STACK_NAME" "cloudformation_deploy" "$BODY_DEPLOY_LOG"',
' upload_optional_artifact "$BODY_FAILURE_PATH" "${BODY_FAILURE_S3_KEY:-}"',
' fail "lesser-body deploy helper failed for $BODY_TEMPLATE_PATH"',
' fi',
' BODY_PARAM="/$APP_SLUG/$STAGE/lesser-body/exports/v1/mcp_lambda_arn"',
' BODY_LAMBDA_ARN=$(aws ssm get-parameter --profile managed --name "$BODY_PARAM" --query "Parameter.Value" --output text)',
' test -n "$BODY_LAMBDA_ARN" && test "$BODY_LAMBDA_ARN" != "null"',
Expand Down
5 changes: 5 additions & 0 deletions cdk/test/provision-runner-buildspec.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ test('RUN_MODE=lesser uses verified Lesser release assets', () => {
test('RUN_MODE=lesser-body uses the release helper instead of a source checkout', () => {
assert.match(buildCommands, /prepare_lesser_body_release_dir/);
assert.match(buildCommands, /deploy-lesser-body-from-release\.sh/);
assert.match(buildCommands, /--no-execute-changeset/);
assert.match(buildCommands, /BODY_TEMPLATE_CERT_S3_KEY/);
assert.match(buildCommands, /BODY_FAILURE_S3_KEY/);
assert.match(buildCommands, /body-template-certification\.json/);
assert.match(buildCommands, /body-failure\.json/);
assert.match(buildCommands, /BODY_ASSET_BUCKET="cdk-hnb659fds-assets-\$TARGET_ACCOUNT_ID-\$TARGET_REGION"/);
assert.doesNotMatch(buildCommands, /lesser-body-src/);
assert.doesNotMatch(buildCommands, /npx cdk deploy --all/);
Expand Down
8 changes: 5 additions & 3 deletions docs/lesser-body-release-contract.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,11 @@ The runner:

1. downloads the published `lesser-body` release assets into a clean release directory
2. verifies the release manifest, deploy manifest path, stage template path, and checksum coverage
3. executes `deploy-lesser-body-from-release.sh` against the managed instance account
4. reads the instance-scoped SSM export `/${app}/${stage}/lesser-body/exports/v1/mcp_lambda_arn`
5. writes the managed receipt and uploads it back to the host artifacts bucket
3. runs `deploy-lesser-body-from-release.sh --no-execute-changeset` against the managed instance account to certify the
published stage template through the real CloudFormation consumer path
4. executes `deploy-lesser-body-from-release.sh` for the actual managed body deploy
5. reads the instance-scoped SSM export `/${app}/${stage}/lesser-body/exports/v1/mcp_lambda_arn`
6. writes the managed receipt and uploads it back to the host artifacts bucket

The managed runner does not require a `lesser-body` source checkout or `npm install` in the happy path.

Expand Down
7 changes: 7 additions & 0 deletions docs/managed-release-certification.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@ The managed release is only certified when every required check passes.
- required when the certification run includes `lesser-body` or MCP follow-on wiring
- `lesser_body_compatibility_contract_valid`
- required when the certification run includes `lesser-body` or MCP follow-on wiring
- `lesser_body_template_preflight_valid`
- required when the certification run includes `lesser-body` or MCP follow-on wiring
- `lesser_body_template_changeset_valid`
- required when the certification run includes `lesser-body`
- the body runner must prove the published template passed `deploy-lesser-body-from-release.sh --no-execute-changeset`
- `lesser_body_completed`
- required when the certification run includes `lesser-body`
- `lesser_body_runner_visibility_present`
Expand Down Expand Up @@ -105,10 +110,12 @@ The report records:

- requested Lesser and `lesser-body` versions
- the explicit `lesser-body` release-selection and compatibility result for body-enabled certification runs
- the explicit lesser-body template path that passed preflight and the real consumer-path change-set check
- target `lesser-host` base URL and managed instance slug
- every certification check and its pass/fail status
- phase-level evidence for Lesser, `lesser-body`, and MCP, even when those phases share one managed update job id
- canonical managed receipt keys
- lesser-body template certification pointers (`template_path`, `template_certification_key`, `template_verification_mode`) in the body job evidence
- rollout summary (`overall_status`)

## Canonical managed receipt keys
Expand Down
7 changes: 5 additions & 2 deletions docs/managed-release-readiness.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ The derived readiness bundle is written alongside it:
- rollout readiness is `blocked`

Blocking readiness is driven by explicit failed certification checks, not by whether implementation issues have merged.
For body-enabled rollout, readiness also requires the body evidence bundle to carry the certified template path and the
template-certification evidence key from the real consumer-path change-set check.

## Project 17 issue surface

Expand All @@ -39,6 +41,7 @@ comment with:
- project number
- requested Lesser and `lesser-body` versions
- `lesser-body` certification status from the canonical body evidence bundle
- the certified `lesser-body` template path and template-certification evidence key when body-enabled rollout is in scope
- current certification status
- rollout readiness
- blocking certification checks
Expand All @@ -54,8 +57,8 @@ That makes the project distinguish:
The managed release canary workflow can target multiple parent issues, for example:

- `equaltoai/lesser#658`
- `equaltoai/lesser-body#91`
- `equaltoai/lesser-host#96`
- `equaltoai/lesser-body#106`
- `equaltoai/lesser-host#129`

When certification is blocked:

Expand Down
3 changes: 2 additions & 1 deletion docs/managed-update-recovery.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,8 @@ of trying to infer failure type from free-form text.
- Expected evidence:
- `failed_phase=body`
- `body_status=failed`
- `body_error` and `error_message` describe the sanitized terminal runner failure
- `body_error` and `error_message` preserve the best available sanitized helper or CloudFormation failure detail;
template-validation failures should remain visible instead of collapsing to only `exit status 1`
- `body_run_url` and `run_url` preserve the CodeBuild deep link when one was observed
- Recovery: inspect the preserved CodeBuild link, fix the release or configuration problem, and submit a new update
job. No DynamoDB edits are required.
Expand Down
4 changes: 3 additions & 1 deletion docs/portal.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,9 @@ For `body_only` updates, portal and operator surfaces should present the `error_
- `body_release_preflight_failed`: the requested `lesser-body` release was rejected before CodeBuild started. Expect
`failed_phase=body`, `body_status=failed`, and usually no `body_run_url`.
- `body_deploy_failed`: the `lesser-body` runner reached a terminal CodeBuild failure. Expect `failed_phase=body`,
`body_status=failed`, and a preserved `body_run_url` / `run_url` when the runner deep link was observed.
`body_status=failed`, a preserved `body_run_url` / `run_url` when the runner deep link was observed, and
`body_error` / `error_message` that keep the underlying helper or CloudFormation validation detail when the runner
uploaded it.
- `body_receipt_load_failed`: the body runner may have completed, but receipt ingest failed afterward. Expect
`failed_phase=body`, `body_status=failed`, and a `body_error` / `error_message` that names receipt loading.

Expand Down
15 changes: 14 additions & 1 deletion docs/spec/managed-release-body-certification.example.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,16 @@
"status": "pass",
"detail": "requested lesser-body release matches the published lesser-host managed compatibility contract"
},
{
"id": "lesser_body_template_preflight_valid",
"status": "pass",
"detail": "published template lesser-body-managed-dev.template.json passed lesser-host managed body template preflight"
},
{
"id": "lesser_body_template_changeset_valid",
"status": "pass",
"detail": "published template lesser-body-managed-dev.template.json passed cloudformation_deploy_no_execute_changeset and is recorded at managed/updates/simulacrum/job-update-1/body-template-certification.json"
},
{
"id": "lesser_body_completed",
"status": "pass",
Expand All @@ -48,7 +58,10 @@
"run_url": "https://console.aws.amazon.com/codebuild/home?#/builds/job-update-1-body/view/new",
"body_run_url": "https://console.aws.amazon.com/codebuild/home?#/builds/job-update-1-body/view/new",
"receipt_key": "managed/updates/simulacrum/job-update-1/body-state.json",
"requested_version": "v0.2.3"
"requested_version": "v0.2.3",
"template_path": "lesser-body-managed-dev.template.json",
"template_certification_key": "managed/updates/simulacrum/job-update-1/body-template-certification.json",
"template_verification_mode": "cloudformation_deploy_no_execute_changeset"
},
"overall_status": "pass"
}
25 changes: 24 additions & 1 deletion docs/spec/managed-release-certification.example.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,31 @@
"status": "pass",
"detail": "requested lesser-body release matches the published lesser-host managed compatibility contract"
},
{
"id": "lesser_body_template_preflight_valid",
"status": "pass",
"detail": "published template lesser-body-managed-dev.template.json passed lesser-host managed body template preflight"
},
{
"id": "lesser_body_template_changeset_valid",
"status": "pass",
"detail": "published template lesser-body-managed-dev.template.json passed cloudformation_deploy_no_execute_changeset and is recorded at managed/updates/simulacrum/job-update-1/body-template-certification.json"
},
{
"id": "hosted_update_completed",
"status": "pass",
"detail": "Lesser update job completed through lesser-host"
},
{
"id": "receipt_key_defined",
"status": "pass",
"detail": "managed/updates/simulacrum/job-update-1/state.json"
},
{
"id": "runner_visibility_present",
"status": "pass",
"detail": "https://console.aws.amazon.com/codebuild/home?#/builds/job-update-1-deploy/view/new"
},
{
"id": "lesser_body_completed",
"status": "pass",
Expand Down Expand Up @@ -70,7 +90,10 @@
"run_url": "https://console.aws.amazon.com/codebuild/home?#/builds/job-update-1-body/view/new",
"body_run_url": "https://console.aws.amazon.com/codebuild/home?#/builds/job-update-1-body/view/new",
"receipt_key": "managed/updates/simulacrum/job-update-1/body-state.json",
"requested_version": "v0.2.3"
"requested_version": "v0.2.3",
"template_path": "lesser-body-managed-dev.template.json",
"template_certification_key": "managed/updates/simulacrum/job-update-1/body-template-certification.json",
"template_verification_mode": "cloudformation_deploy_no_execute_changeset"
},
{
"kind": "mcp",
Expand Down
9 changes: 9 additions & 0 deletions docs/spec/managed-release-certification.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,15 @@
},
"requested_version": {
"type": "string"
},
"template_path": {
"type": "string"
},
"template_certification_key": {
"type": "string"
},
"template_verification_mode": {
"type": "string"
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,16 @@
"status": "pass",
"detail": "requested lesser-body release matches the published lesser-host managed compatibility contract"
},
{
"id": "lesser_body_template_preflight_valid",
"status": "pass",
"detail": "published template lesser-body-managed-dev.template.json passed lesser-host managed body template preflight"
},
{
"id": "lesser_body_template_changeset_valid",
"status": "pass",
"detail": "published template lesser-body-managed-dev.template.json passed cloudformation_deploy_no_execute_changeset and is recorded at managed/updates/simulacrum/job-update-1/body-template-certification.json"
},
{
"id": "lesser_body_completed",
"status": "pass",
Expand All @@ -48,7 +58,10 @@
"run_url": "https://console.aws.amazon.com/codebuild/home?#/builds/job-update-1-body/view/new",
"body_run_url": "https://console.aws.amazon.com/codebuild/home?#/builds/job-update-1-body/view/new",
"receipt_key": "managed/updates/simulacrum/job-update-1/body-state.json",
"requested_version": "v0.2.3"
"requested_version": "v0.2.3",
"template_path": "lesser-body-managed-dev.template.json",
"template_certification_key": "managed/updates/simulacrum/job-update-1/body-template-certification.json",
"template_verification_mode": "cloudformation_deploy_no_execute_changeset"
},
"overall_status": "pass"
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@

- `lesser_body_version_selected`: `pass` - requested lesser-body release v0.2.3 will be validated for managed certification
- `lesser_body_compatibility_contract_valid`: `pass` - requested lesser-body release matches the published lesser-host managed compatibility contract
- `lesser_body_template_preflight_valid`: `pass` - published template lesser-body-managed-dev.template.json passed lesser-host managed body template preflight
- `lesser_body_template_changeset_valid`: `pass` - published template lesser-body-managed-dev.template.json passed cloudformation_deploy_no_execute_changeset and is recorded at managed/updates/simulacrum/job-update-1/body-template-certification.json
- `lesser_body_completed`: `pass` - lesser-body managed deploy completed
- `lesser_body_runner_visibility_present`: `pass` - https://console.aws.amazon.com/codebuild/home?#/builds/job-update-1-body/view/new
- `lesser_body_receipt_key_defined`: `pass` - managed/updates/simulacrum/job-update-1/body-state.json
Expand All @@ -20,4 +22,7 @@
- `lesser-body` `job-update-1`: status=`ok` step=`done` version=`v0.2.3` receipt=`managed/updates/simulacrum/job-update-1/body-state.json`
run_url: https://console.aws.amazon.com/codebuild/home?#/builds/job-update-1-body/view/new
body_run_url: https://console.aws.amazon.com/codebuild/home?#/builds/job-update-1-body/view/new
template_path: lesser-body-managed-dev.template.json
template_certification_key: managed/updates/simulacrum/job-update-1/body-template-certification.json
template_verification_mode: cloudformation_deploy_no_execute_changeset
note: lesser-body updated
Loading
Loading