Skip to content

test(aws-startup-advisor): pin Estimate and Generate AI contracts - #449

Merged
leon1418 merged 137 commits into
aws:mainfrom
herosjourney:feat/ai-estimate-generate-contracts
Oct 21, 2026
Merged

leon1418 merged 137 commits into
aws:mainfrom
herosjourney:feat/ai-estimate-generate-contracts

Conversation

@herosjourney

@herosjourney herosjourney commented Oct 14, 2026 •

Copy link
Copy Markdown
Contributor

Problem

There is no pinned target contract for the AI-authored fragments of the Estimate and Generate phases. estimation-ai.json and generation-ai.json — the AI slices of estimate.md and generate-artifacts-ai.md — have no JSON Schema, so nothing validates a future producer against them and there is no normalized shape for a shared AI engine (issue #389's extraction) to target downstream of #415's ai-workload-profile.json and #416's aws-design-ai.json. Without a pinned contract here, extracting the shared AI engine out of gcp-to-aws would have to invent the Estimate/Generate AI shapes from scratch instead of building against an already-reviewed target.

Fix

Add target-only JSON Schemas and canonical vendored docs for the Estimate-phase and Generate-phase AI fragments, plus nested fixtures and a contract-projection test suite, mirroring the pattern #415 and #416 established for ai-workload-profile.json and aws-design-ai.json.

  • New scripts/contracts/estimation-ai.schema.json and scripts/contracts/generation-ai.schema.json (Draft-07).
  • Canonical prose in skills/shared/ai/schema-estimate-ai.md and skills/shared/ai/schema-generate-ai.md, vendored byte-identically under gcp-to-aws and azure-to-aws with matching README table rows.
  • scripts/artifact-contracts.json's shared section gains entries for both artifacts, and validate-artifacts.py (plus tests/test_validate_artifacts.py) registers them so lint:artifacts discovers and self-checks the fixtures.
  • Nested fixtures under fixtures/estimation-ai/<case>/ and fixtures/generation-ai/<case>/, covering a multi-provider-direct case and an OpenRouter-gateway multi-upstream case.
  • New tests/test_estimation_ai_contracts.py and tests/test_generation_ai_contracts.py.

Scope

Target-only, matching #410/#415/#416. This PR does not wire anything into estimate.md or generate-artifacts-ai.md, add a producer for either artifact, or change any phase behavior, question text, model mapping, pricing value, or artifact name. Schema validity here does not imply an implemented detector, adapter, route, or runtime support of any kind. It affects only the two schemas, their canonical/vendored docs, the fixtures, the artifact-contract registration, and the contract tests.

Base note

The earlier stacking caveat is now resolved: #410, #415, and #416 have all merged, so this PR's base retargets to main and the diff has shrunk to just this PR's own 22 files (no inherited stack files remain). The branch is currently a few commits behind main (it predates #454 and #458); a main merge/rebase and a CI re-run on the fresh base are the only remaining step before merge — there is no conflict.

In code, for reviewers
  • scripts/contracts/estimation-ai.schema.json, scripts/contracts/generation-ai.schema.json — the two Draft-07 target schemas.
  • skills/shared/ai/schema-estimate-ai.md, skills/shared/ai/schema-generate-ai.md — canonical prose, with byte-identical vendored copies under gcp-to-aws/references/vendored/ai/ and azure-to-aws/references/vendored/ai/ and matching rows in all three README.md tables (vendored-parity gate).
  • scripts/artifact-contracts.json + scripts/validate-artifacts.py + tests/test_validate_artifacts.py — register and self-check the two artifacts under lint:artifacts.
  • fixtures/estimation-ai/{multi-provider-direct,openrouter-gateway-multi-upstream}/estimation-ai.json and the matching fixtures/generation-ai/... — positive fixtures, including an OpenRouter gateway multi-upstream case.
  • tests/test_estimation_ai_contracts.py, tests/test_generation_ai_contracts.py — contract-projection suites.

Validation

Validation recorded for current head dd810e147862449e45b01a90e4e6eb1d999689b4:

  • mise -C plugins/aws-startup-advisor run ci passed; GitHub Build, Startup advisor, CodeQL, dependency-review, and PR-title checks are green on this head.
  • pytest tests/test_estimation_ai_contracts.py tests/test_generation_ai_contracts.py — contract tests pass.
  • lint:artifacts, lint:vendored-parity, and lint:skill-refs pass (the two new artifacts are registered; vendored copies are byte-identical).

The green run was against the pre-#454/#458 base this branch currently sits on; it should be re-confirmed after the main merge. The tests validate the schemas/fixtures against the contract; there is no producer and no runtime path to exercise.

Type of Change

  • New plugin
  • New skill
  • Documentation update (target-only contract, schemas, docs)
  • CI/CD change
  • Other (new target-only contracts, fixtures, and tests; no runtime wiring)

Startup Advisor review checklist

By submitting this PR, I confirm that:

  • I have reviewed the full diff and understand all changes I am submitting.
  • I have tested my changes and confirmed they work as intended.
  • I have run mise -C plugins/aws-startup-advisor run ci and all checks pass.
  • I have disclosed any known issues, limitations, or untested scenarios.

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

Logan Kleier and others added 30 commits September 30, 2026 21:13
…artifacts against their published schemas

The migration skills pass ~17 JSON artifacts between phases, each with a
contract published as a schema-*.md "shape" block (JSON/JSONC example) or,
for two of them, a real JSON Schema under skills/shared/. Nothing checked
that a producer writes what the next phase reads: a key could be renamed,
emitted without being documented, or an enum widened, and every DSL
_assert still passed because the model that writes the artifact evaluates
the assertion. This is the precondition the backlog names for any engine
consolidation or AI-engine extraction — moves across adapters have no
drift detection without it.

scripts/validate-artifacts.py (stdlib, Python 3.9+)
- Parses each contract document's example blocks (JSONC comments, trailing
  commas, `...` ellipses, `a|b` enum strings, `// a | b | c` enum comments,
  `// REQUIRED` / `(REQUIRED)` markers, `"<placeholder>"` keys = open
  object, `"<key>": {...}` = template for every key) into a key-path
  contract; sub-section blocks (`## services[]`, `### metadata (REQUIRED)`)
  refine paths; manifest can pin a block by `@L<line>` anchor, merge other
  documents' additions (graviton, workshop), or declare a row-annotation
  vocabulary (azure preferences' source/reason/context/...).
- Validates real JSON Schemas with a draft-07 subset (type, required,
  properties, additionalProperties, enum, const, items, pattern, min/max,
  minItems, allOf/anyOf/oneOf, $ref).
- Findings: UNKNOWN_KEY, MISSING_REQUIRED, TYPE_MISMATCH, ENUM_VIOLATION,
  SCHEMA_VIOLATION, SCHEMA_PARSE (the contract itself is broken),
  NO_CONTRACT (info). `_`-prefixed keys are annotations.
- Modes: --self-check (contracts parse), --fixtures (CI; goldens against
  the baseline), --run-dir <.migration/run> --skill <name> (users).
- scripts/artifact-contracts.json maps artifact → contract per skill.
- scripts/artifact-contracts-baseline.json: 21 explained entries covering
  44 known gaps between what phases emit and what their contract documents
  say, each naming the document that must change. Stale entries are
  reported so the list only shrinks.

Contract documents fixed where the document contradicted itself (its own
prose named a key its example block omitted):
- gcp schema-preferences.md: the shape block was not JSON (`{ "value",
  "chosen_by" }` set notation); rewritten as a JSONC row template.
- gcp schema-estimate-infra.md: root block lacked complexity_tier, which
  estimation-infra.schema.json marks required.
- gcp schema-discover-iac.md § Live discovery extensions: block now shows
  the metadata/resources[] additions the prose above it documents.
- heroku schema-discover-heroku.md: resources[] example carries
  source/unmanaged_by_terraform/not_found_live (table at lines 93-95);
  addon config example carries the per-add-on and live-enrichment fields
  the bullets below it list.
- azure schema-design-aws.md: services[] block carries
  routing_provenance/sizing_provenance/sizing_source/is_compute_unit/
  hosted_app_azure_ids (the same document marks them REQUIRED); deferred[]
  carries routing_provenance.
- azure schema-discover-azure.md: clusters[] carries pattern_status
  (discover-assemble.md § Status).
- azure schema-preferences.md: top-level clarify_status (REQUIRED per
  clarify-assemble.md § clarify_status).

Fixture: gcp-decision-gate's estimation-infra.json stub gains the four
keys estimation-infra.schema.json requires; check_expected_decide.py
still passes.

Wiring: mise `lint:artifacts` task, added to `validate` (CI build runs it).
README scripts/ entry updated.

Tests: tests/test_validate_artifacts.py — 16 tests: JSONC stripping,
template inference (enum/required/placeholder/any-key), each finding
code, JSON Schema subset, baseline matching + stale detection, CLI
self-check and fixtures pass on the real repo, and two negatives: an
injected off-contract key and a schema enum violation both exit 1.
…(and reject unknown schema keywords); stale baseline fails

Review on aws#385, both should-fix findings valid:

1. [Propagation] phase-status.schema.json has `minProperties: 1` on `phases`;
   the draft-07 subset did not implement it, so `phases: {}` passed. Fixed
   the instance AND the class: the subset now enforces minProperties,
   maxProperties, exclusiveMinimum/Maximum, maxItems, uniqueItems,
   minLength/maxLength and `not`; and `unsupported_keywords()` walks every
   loaded JSON Schema at contract-build time and emits SCHEMA_PARSE for any
   validation keyword that is neither enforced nor a known annotation. A
   constraint can no longer be skipped silently — adding a keyword to a
   schema without teaching the validator fails the gate.

2. [Completeness] a baseline entry that matched nothing was printed as a
   warning and exited 0, so the burn-down list only shrank if someone read
   the log. STALE_BASELINE is now an error code: `--fixtures` (what
   `mise run lint:artifacts` runs) exits 1 on any stale entry.

Tests (19): empty `phases` fails with minProperties named; the two real
schemas use only enforced/annotation keywords and an invented
`contentEncoding` / `dependencies` schema is rejected; a never-matching
baseline entry exits 1 with STALE_BASELINE.
…ndored/ must match skills/shared/

Each migration skill is installable on its own (`npx skills add … --skill
gcp-to-aws`), so shared material (DSL interpreter, pricing caches, estimate
schemas, …) is vendored into skills/<skill>/references/vendored/ from the
canonical skills/shared/. The vendored READMEs said: "This repository has
no automated sync task for these copies — keeping them byte-identical is
part of the change that touches the canonical file." All 44 copies are
identical today; nothing stopped the next edit to skills/shared/ from
leaving a skill running stale logic.

- tools/sync-vendored.py (stdlib): same shape as sync-plugin-skills.py.
  Default mode copies skills/shared/<path> over every vendored copy that
  differs; --check exits 1 listing any copy that differs or has no
  canonical source (a vendored file nobody owns). README.md in a vendored
  dir is explanatory and skipped. The vendored tree is a subset of shared/,
  so files in shared/ that no skill vendors are fine.
- mise `lint:vendored-parity`, added to `validate` (the CI build runs it).
- The four vendored READMEs replace the manual cp + md5sum instructions
  with the tool and the CI rule.
- tools/test_sync_vendored.py: 4 tests on a throwaway tree — drift and
  orphan detection (README excluded), sync repairs drift and leaves orphans
  as errors, CLI exit codes — plus the real repository is in sync.

No skill content changes. Stacked on aws#385 only because both add a task to
the same `validate` depends line.
…t; deleted copies fail; READMEs say what the gate sees

Review on aws#386 (Contradictions / Completeness, should-fix): the three
migration READMEs claimed "a change to skills/shared/ that forgets the
copies cannot merge", but the check only walked files that still existed —
a deleted vendored copy, or a new shared file never vendored, passed.

Rather than only weakening the sentence, the gate now uses the record of
intent each vendored README already carries: its
`| Vendored path | Canonical source |` table.
- check: every row must exist on disk (deleted copy → FAIL), every file on
  disk must have a row (README stays honest), and each row's canonical
  path must be skills/shared/<same path>. A README with no table is an
  error.
- sync: restores a listed-but-missing copy from canonical before comparing.
- What the gate still cannot see — a NEW skills/shared/ file no skill
  vendors — is now stated in the tool docstring and in all four READMEs,
  with the instruction "add the copy AND a table row".

The three READMEs were already complete tables (gcp 14/14, heroku 8/8,
azure 21/21, agent-advisor 1/1); the real repo passes unchanged.

Tests (7): deleted copy caught via the table and restored by sync;
unlisted file and wrong canonical path caught; a new shared file nobody
vendors is NOT an error (pins the documented limit); CLI exit codes; real
repo in sync. Reviewer probes re-run on a throwaway copy of the plugin:
deleting agent-advisor's INTERPRETER.md → FAIL naming it; default mode
restores it; adding skills/shared/brand-new.md → no error, as documented.
…l mentions must exist

The skills are prose state machines: a phase file says "Load
`references/phases/design/design-ai.md`" or "run `python3
\"<SKILL_BASE>/scripts/x.py\"`" and the agent follows the string. Nothing
checked the target exists. A renamed or never-written file is a dead end
the user hits mid-migration, and any file move during consolidation would
break references silently. This is the third gate in the family
(validate-artifacts.py: artifact contracts; sync-vendored.py: vendored
parity) and the precondition for moving phase files between skills.

tools/check-skill-refs.py (stdlib)
- Scans skills/**/*.md and agents/*.md for path tokens into the skill
  tree (references/, knowledge/, scripts/, skills/, agents/, data/, and the
  agent-advisor short forms phases/, shared/, design-refs/) with optional
  $PLUGIN_ROOT / ${CLAUDE_PLUGIN_ROOT} / $SKILL_BASE / <SKILL_BASE> /
  $GCP_BASE / ./ / ../ prefixes.
- Resolution: explicit prefix → skill-relative → file-relative →
  skill/references/<short form> → plugin/repo-relative. Library-origin
  files (skills/shared/*, */references/vendored/*, */references/shared/*)
  speak from the consuming skill's point of view and resolve against
  skills/shared and every skill; agent-advisor and llm-to-bedrock may name
  gcp-to-aws's tree (documented inline execution); agents/ resolve against
  llm-to-bedrock.
- Skips run-artifact paths ($MIGRATION_DIR/…, .migration/…, <PLAN_DIR>/…),
  templated tokens (<slug>, NNN, *), URLs, and ./ or ../ tokens with no
  skill-tree root in them (generated outputs like ./deploy.sh).
- tools/skill-refs-baseline.json: `ignore` rules (permanent policy —
  scripts Generate writes into $MIGRATION_DIR/scripts/, an example path in
  the user's app) and `entries` (known dead references with the fix;
  STALE when they stop matching, failing the gate so the list only shrinks).

1118 references checked on the real repo; 7 dead ones baselined, each a
real user-facing defect: azure discover-iac.md points Bicep/ARM input at
extract-bicep.md / extract-arm.md that do not exist (so Bicep halts);
design-refs/patterns.md referenced from two azure files before it exists;
contextual-offers SKILL.md names references/offers.md unqualified when the
file lives in knowledge-base-for-startups; gcp design-ai.md:424 points at
shared/ai-model-lifecycle.md, which in gcp is vendored at
references/vendored/ai/.

mise `lint:skill-refs`, added to `validate`. Tests (8): each resolution
rule, each skip rule, library-origin resolution, gcp-dependent and agents
fallbacks, ignore vs entries vs stale, CLI exit codes, real repo PASS.
…inst llm-to-bedrock

Review on aws#387 (Completeness / Contradictions, should-fix): the agents/
branch of the resolver searched every skill and kept the first hit, so
agents/llm2bedrock-prompt-evaluator.md:233 `scripts/pyproject.toml`
resolved to skills/agent-advisor/scripts/pyproject.toml (sorts first) and a
tree with the file only under agent-advisor still passed — deleting the
llm-to-bedrock copy would not have failed the gate. The comment above the
loop said llm-to-bedrock; the loop did not.

- Agent references now resolve ONLY against skills/llm-to-bedrock
  (_AGENTS_OWNER), including the <BDD_DIR>-style rglob, which is scoped to
  that skill.
- Tests: scripts/pyproject.toml present only under agent-advisor is
  MISSING; present under llm-to-bedrock resolves to llm-to-bedrock's copy
  even when agent-advisor also has it; the fixture tree's agents/worker.md
  reference to another skill's file is now correctly MISSING.
- Real repo unchanged: 1118 references, 0 missing, 7 baselined.
…for --fixtures; enums survive example merges; required table headings; real estimate/graviton/workloads paths

Review round 2 on aws#385 (seven P2s, plus the Azure composite-source enum raised on
aws#386/aws#387 against the same code):

- The shipped baseline describes the fixture corpus (every glob is fixtures/...), so it
  now applies by default only to --fixtures. `--run-dir <run> --skill <s>` runs with no
  baseline unless --baseline names one, and then every entry must still match (a valid
  real run previously failed with 21 STALE_BASELINE errors).
- Node.merge keeps a declared enum when another example shows a concrete member
  (`"confidence": "full"` no longer erases `full|reduced`); a concrete token the document
  shows joins the set, only a free-text example clears it. Adopted children are copied,
  so refining `design_constraints.cpu_architecture` no longer widens the generic
  `<key>` template's `chosen_by`. GCP schema-preferences.md example now lists `derived`.
- `(or a "+"-joined set)` on an enum comment sets Node.enum_join: `live+terraform` is
  valid, `terraform+bogus` is not, closed enums elsewhere stay closed.
- Heading match is exact or word-boundary prefix: `graviton` no longer selects
  `graviton_profile`; the Azure design manifest names `graviton block` explicitly.
- Wrapped arrays (`{"workloads": [...]}` under a `workloads[]` heading) merge at the
  array level, so workload key/type drift is detected; bare item examples still merge
  into the item.
- `(REQUIRED)` headings are read from every heading, not only fenced ones: Heroku
  `metadata` / `apps[]` / `resources[]` are now required; OPTIONAL sections unchanged.
  Two baseline entries record the hand-authored Heroku seed inventories that lack them.
- GCP estimate: scenario_deltas, breakdown.observability, breakdown.security_baseline
  and breakdown.security_baseline_compliance bind to their object keys (line anchors
  separate the two Security Baseline blocks); nested drift inside them is still caught.
- Heroku workshop `preferences_subset` is the documented open knob map (open_paths).

15 regression tests added (unit + CLI against the real contracts); each fails on the
previous head. Fixture gate: 50 artifacts, 0 errors, 50 baselined, 0 stale.
… token; explicit bases are authoritative

Review round 2 on aws#387 (the two findings unique to this tool):

- The run-artifact skip looked 40 characters back, so an earlier, separate token
  (`$MIGRATION_DIR/`) swallowed the schema reference that followed it on the same line
  (azure design-ai.md:197) — renaming that schema passed CI. The skip now reads only the
  token's own contiguous prefix; `<run_dir>/…`, `.migration/<run>/…` and `$MIGRATION_DIR/…`
  forms are still skipped. Real repo: 1157 references (2 previously swallowed, both resolve).
- An explicit base (`<SKILL_BASE>/`, `$PLUGIN_ROOT/`, `$GCP_BASE/`, `./`, `../`) is now
  authoritative: no library-origin / gcp-dependent / agents fallbacks after it, so a
  same-named file under another skill cannot make a dead `<SKILL_BASE>/scripts/x.py` look
  alive. Unqualified references keep every fallback; `<SKILL_BASE>/../gcp-to-aws/SKILL.md`
  traversal still resolves.

Two regression tests added; each fails on the previous head. Real repo: PASS, 0 missing,
7 baselined, 0 stale.
Co-authored-by: Cursor <cursoragent@cursor.com>

# Conflicts:
#	plugins/aws-startup-advisor/skills/azure-to-aws/references/shared/schema-preferences.md
…y-gate

Keep clarify_status alongside the metadata block in the preferences example, and admit the unfired licensing stub keys the assembler already writes.

Co-authored-by: Cursor <cursoragent@cursor.com>
…ferences example

The fast-path fixture writes licensing as the N/A stub, and the artifact check was rejecting those keys.

Co-authored-by: Cursor <cursoragent@cursor.com>
An empty-array example no longer leaves the item typed as any, quoted comment enums are enforced, and a plugin without skills/ no longer crashes the vendored scan.

Co-authored-by: Cursor <cursoragent@cursor.com>
…relative prefixes

An empty example array kept item type any after a later object section, and a short relative path still matched the unprefixed file under the skill root.

Co-authored-by: Cursor <cursoragent@cursor.com>
…ck estimate snapshots

A standalone REQUIRED comment was dropped, so a discovery inventory without clarify_fast_path passed. Scenario estimate copies also skipped the active estimate shape, so an unknown pricing bucket failed on the live file and passed on the snapshot.

Co-authored-by: Cursor <cursoragent@cursor.com>
…d drift values

An AI-only preferences file was checked against the infra shape, numeric GCP drift failed as a string, and a plugin with no skills directory crashed the vendored-copy gate.
…y-gate

# Conflicts:
#	plugins/aws-startup-advisor/README.md
Logan Kleier added 2 commits October 13, 2026 17:41
…design-ai-contract

Conflicts resolved (5 files), zero functionality lost:
- plugins/aws-startup-advisor/README.md: kept HEAD's scripts/ bullet
  (superset of upstream's, includes aws-design-ai.schema.json sentence)
- plugins/aws-startup-advisor/fixtures/README.md: kept HEAD's new
  aws-design-ai/ bullet, placed after ai-workload-profiles/ and before
  heroku-workshop/
- plugins/aws-startup-advisor/scripts/artifact-contracts.json: kept
  HEAD's aws-design-ai.json shared-contract entry right after
  ai-workload-profile.json
- plugins/aws-startup-advisor/mise.toml: took HEAD's empty side in both
  conflict regions (HEAD already defines lint:skill-refs, tasks.ci, and
  lint:model-id elsewhere in the file, complete and matching upstream)
- plugins/aws-startup-advisor/tests/test_validate_artifacts.py: took
  upstream's stronger neutral_checked/neutral_findings/neutral_shared_count
  variant of test_neutral_matrix_shared_artifacts_extend_the_mapped_fixture_count,
  which calls va.validate_run_dir per unmapped fixture dir and asserts exact
  equality + zero findings, over HEAD's weaker count-only >= variant

Verification evidence:

1) mise.toml `^[tasks` grep — every task name exactly once, no duplicates:
   1 ci
   1 lint:artifacts
   1 lint:md
   1 lint:model-id
   1 lint:model-staleness
   1 lint:skill-refs
   1 lint:vendored-parity
   1 test
   1 test:heroku-source-review
   [tasks.ci].depends = ["lint:md","lint:model-id","lint:model-staleness",
   "lint:artifacts","lint:vendored-parity","lint:skill-refs","test",
   "test:heroku-source-review"] — complete, every name resolves to a real task.

2) python -m json.tool scripts/artifact-contracts.json — valid JSON, exit 0.

3) Isolated test (3 unmapped families: ai-migration-matrix,
   ai-workload-profiles, aws-design-ai):
   `pytest tests/test_validate_artifacts.py -k
   test_neutral_matrix_shared_artifacts_extend_the_mapped_fixture_count -v`
   -> 1 passed, 61 deselected.

4) Full plugin suite: `pytest tests/ -q` -> 391 passed.

5) `mise run build` (repo root): lint:manifests, lint:spec,
   lint:skill-parity, lint:md, security — all passed, exit 0.

6) `mise -C plugins/aws-startup-advisor run ci`: lint:vendored-parity
   (49 vendored files byte-identical), lint:artifacts (80 artifacts
   checked, 0 errors, 50 baselined, 14 info), lint:model-id, test
   (391 passed), lint:skill-refs (1293 refs checked, 0 missing),
   lint:md, test:heroku-source-review (44 passed) — all passed, exit 0.
Target-only, additive JSON Schemas for estimation-ai.json and
generation-ai.json, stacked on merged aws#415 (ai-workload-profile) and
aws#416 (aws-design-ai). cost_by_source[] / artifacts_by_source[] carry
the ai_sources[]/gateways[] traceability chain forward per-source,
per-model; model_observations[] intentionally not carried forward
(identity already resolved by Design). No runtime wiring, no producer
change — estimate-ai.md / generate-ai.md / generate-artifacts-ai.md
are untouched in both skills.

Added:
- scripts/contracts/estimation-ai.schema.json, generation-ai.schema.json
- skills/shared/ai/schema-estimate-ai.md, schema-generate-ai.md
  (vendored byte-identically into gcp-to-aws and azure-to-aws only)
- fixtures/estimation-ai/{multi-provider-direct,openrouter-gateway-multi-upstream}/estimation-ai.json
- fixtures/generation-ai/{multi-provider-direct,openrouter-gateway-multi-upstream}/generation-ai.json
- tests/test_estimation_ai_contracts.py, test_generation_ai_contracts.py
  (positive validation, malformed/duplicate/overlapping rejection,
  untraceable/dropped-model negatives, cross-phase projection into
  aws-design-ai.json and estimation-ai.json, vendored byte-identity)

Registered two 'shared' entries in artifact-contracts.json, two
fixture bullets in fixtures/README.md, two rows in
skills/shared/ai/README.md, and a scripts/ clause in README.md.

Verification run from plugins/aws-startup-advisor (all commands
executed for real, output below):

  uv run --with pytest python -m pytest tests/ -q
    -> 429 passed

  (from the worktree root) mise run build
    -> lint:manifests, lint:spec, lint:skill-parity, lint:md, security
       all PASS

  mise run ci
    -> lint:artifacts: PASS — 84 artifact(s) checked, 0 error(s)
       lint:vendored-parity: PASS — 53 vendored file(s) byte-identical
       lint:skill-refs: PASS — 1339 reference(s) checked, 0 missing
       lint:md: 0 error(s)
       lint:model-id: OK (18 retired IDs enforced)
       test: 429 passed
       test:heroku-source-review: 44 passed
Logan Kleier and others added 3 commits October 14, 2026 08:07
…nerate-contracts

# Conflicts:
#	plugins/aws-startup-advisor/README.md
#	plugins/aws-startup-advisor/fixtures/README.md
#	plugins/aws-startup-advisor/scripts/artifact-contracts.json
#	plugins/aws-startup-advisor/skills/azure-to-aws/references/vendored/README.md
#	plugins/aws-startup-advisor/skills/gcp-to-aws/references/vendored/README.md
#	plugins/aws-startup-advisor/skills/shared/ai/README.md
@herosjourney
herosjourney marked this pull request as ready for review October 19, 2026 04:33

@leon1418 leon1418 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[🤖 AI review 🤖] Reviewed a0a8867 with both required review perspectives. Requesting changes for two P2 contract issues:

  1. Keep the target schemas separate from current GCP/Azure run validation, with compatibility tests for both existing artifact shapes.
  2. Represent unknown costs and uncomputable differences explicitly, with missing-baseline/missing-rate tests and matching canonical/vendored documentation.

Validation on original source: 429 plugin tests passed; artifact validation checked 84 fixtures with no new errors; vendored parity, skill references and diff checks passed. The compatibility and unknown-cost probes reproduced the failures described inline. Current GitHub checks are successful; these findings concern cases the existing tests do not cover.

Comment thread plugins/aws-startup-advisor/scripts/artifact-contracts.json
Comment thread plugins/aws-startup-advisor/scripts/contracts/estimation-ai.schema.json Outdated
Keep target-only estimate and generate schemas out of named skill run validation while retaining neutral fixture and self-check coverage. Preserve unavailable estimate costs and dependent deltas as null, with synced documentation and regression coverage.

Verification:
- affected pytest modules: 87 passed
- startup-advisor artifact validation: 84 checked, 0 errors
- vendored parity: 53 files byte-identical
- startup-advisor CI: 435 Python tests passed; 57 Node tests passed; all lint and validation tasks passed
leon1418
leon1418 previously approved these changes Oct 20, 2026
@leon1418
leon1418 added this pull request to the merge queue Oct 21, 2026
Merged via the queue into aws:main with commit 0d36c50 Oct 21, 2026
10 checks passed
herosjourney pushed a commit to herosjourney/agent-toolkit-for-aws that referenced this pull request Oct 23, 2026
Addresses PR aws#483 review 5620455181 by vagmur-aws, comment 4353203474
(skills/shared/migration/bma-input-patterns.json:3 and closure.json):
4a51ac3 was a merge commit on the aws#449 branch, not an ancestor of main,
and predated aws#369.

- selected_base 4a51ac3
  -> 9ab5063 (upstream/main)
  git merge-base --is-ancestor 9ab5063 upstream/main -> exit 0
- Regenerated closure.json and both bootstrap manifests with the PR's own
  tooling (sync-runtime-copies.py, build-bma-closure.py).
- Verified every aws#369 hunk in the 7 adapted sources (clarify-ai-only,
  design-ai, discover-preview, estimate-ai, generate-ai,
  generate-artifacts-ai, openai-on-bedrock) is present in the BMA
  copies; no content drift to port. Vendored files pass lint:vendored-parity.
- New test test_selected_base_pins_agree_and_are_consistent asserts one
  selected_base across closure.json, both bootstrap manifests, all three
  bma-input-patterns.json copies, runtime-copy-manifest.json, both
  fixtures, and the BASE constant in the classifier copies and tools.

Hashes:
  closure.json file 7a58d70792bc363ab3d9e86156236dd3429905cc12ba9414c951bfa62717a783
  closure.json self 457c32fc8ca1b0e6c74975500a6f921e2464aba1eb4cba0dbd279a0e261fa5da
  bootstrap manifest file 267fe013d216f85dd8c272126099d3f3eb2b909901324d14ab1a47ee06751b02
  bootstrap manifest self 2447652f905ab40b2db3220883abb41c470106d118402f23b68fc6906624faab
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants