diff --git a/AGENTS.md b/AGENTS.md index 9173764..b9b68c5 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -28,10 +28,13 @@ scripts/validate-full.sh # or another bundle repo ``` It creates a private throwaway `uv` venv with `pip`, `hatchling`, `pyyaml`, a -prebuilt public Core 1.6.1 wheel, and the pinned public `amplifier-app-cli`. -Foundation is overridden in that venv through `uv pip --overrides` to -`f13d08168e14b5bc4720fbb06c40936eb1a7a7d1`; it is not supplied as a second -direct requirement. It then invokes that venv's `amplifier` executable explicitly. +latest compatible public Core wheel and canonical `amplifier-app-cli@main`. +Foundation follows canonical `main` through `uv pip --overrides`; it is not +supplied as a second direct requirement. `--upgrade` refreshes cached resolution +for each new runtime. The script emits `CI_VALIDATE_RUNTIME` with actual package +versions and resolved Git revisions; retain that output with the validation +results. Core uses the published-wheel channel, not Git main. The script then +invokes that venv's `amplifier` executable explicitly. PATH alone is insufficient because the CLI supplies its own interpreter to recipe shell steps. It preserves the caller's Amplifier settings identity, including `AMPLIFIER_HOME` when set. diff --git a/modules/tool-context-intelligence-transcript/pyproject.toml b/modules/tool-context-intelligence-transcript/pyproject.toml index 44827b7..dde9612 100644 --- a/modules/tool-context-intelligence-transcript/pyproject.toml +++ b/modules/tool-context-intelligence-transcript/pyproject.toml @@ -6,7 +6,7 @@ requires-python = ">=3.11" license = "MIT" dependencies = [ - "amplifier-bundle-context-intelligence @ git+https://github.com/microsoft/amplifier-bundle-context-intelligence@2818e0519f1c59c71d6a5b53eee50592853f8d7e", + "amplifier-bundle-context-intelligence @ git+https://github.com/microsoft/amplifier-bundle-context-intelligence@main", ] [project.entry-points."amplifier.modules"] diff --git a/scripts/validate-full.sh b/scripts/validate-full.sh index fd5a55b..3fa40ba 100755 --- a/scripts/validate-full.sh +++ b/scripts/validate-full.sh @@ -46,8 +46,8 @@ set -euo pipefail REPO_PATH="${1:-$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)}" -CLI_REF="14dc68eba05bf65b8c6dea28c3a2db93daa12d38" -FOUNDATION_REF="f13d08168e14b5bc4720fbb06c40936eb1a7a7d1" +CLI_REF="main" +FOUNDATION_REF="main" # Select before installing: never guess between cached recipe revisions. # The caller may choose a file explicitly without changing settings or caches. @@ -94,15 +94,16 @@ export PYTHONNOUSERSITE=1 echo ">> building isolated validation runtime: $VENV" uv venv --python 3.11 --allow-existing "$VENV" >/dev/null -# The public CLI declares Foundation@main; override that dependency rather than -# supplying a second, conflicting direct requirement. +# Refresh canonical Git main sources and the latest compatible published Core +# wheel for each new validation runtime. The CLI declares Foundation through +# tool.uv.sources; align it via an override rather than a conflicting direct URL. printf '%s\n' \ "amplifier-foundation @ git+https://github.com/microsoft/amplifier-foundation@$FOUNDATION_REF" \ > "$VENV/overrides.txt" -uv pip install --python "$VENV/bin/python" --quiet \ +uv pip install --python "$VENV/bin/python" --quiet --upgrade \ --only-binary amplifier-core \ --overrides "$VENV/overrides.txt" \ - pip hatchling pyyaml "amplifier-core==1.6.1" \ + pip hatchling pyyaml amplifier-core \ "amplifier-app-cli @ git+https://github.com/microsoft/amplifier-app-cli@$CLI_REF" if ! "$VENV/bin/python" -c 'import pip, hatchling, yaml, amplifier_core, amplifier_foundation'; then @@ -114,6 +115,17 @@ if [[ ! -x "$VENV/bin/amplifier" ]]; then exit 1 fi +# Emit only package versions and resolved Git revisions, never credentials or +# environment values. The temporary runtime is removed; retain this output with +# the validation results. Core uses the published wheel channel, not Git main. +"$VENV/bin/python" -c 'import importlib.metadata as metadata,json +packages={} +for name in ("amplifier-core", "amplifier-app-cli", "amplifier-foundation"): + dist=metadata.distribution(name) + direct=json.loads(dist.read_text("direct_url.json") or "{}") + packages[name]={"version":dist.version,"vcs":direct.get("vcs_info")} +print("CI_VALIDATE_RUNTIME="+json.dumps({"core_channel":"latest-published-wheel","packages":packages},sort_keys=True))' + # JSON encoding preserves spaces, quotes, and backslashes in the target path. CONTEXT="$("$VENV/bin/python" -c 'import json,sys; print(json.dumps({"repo_path": sys.argv[1], "enhance_diagrams": "false"}))' "$REPO_PATH")" diff --git a/tests/test_validate_full.py b/tests/test_validate_full.py index f5e7a8b..87f9645 100644 --- a/tests/test_validate_full.py +++ b/tests/test_validate_full.py @@ -13,8 +13,8 @@ REPO_ROOT = Path(__file__).parent.parent SCRIPT_PATH = REPO_ROOT / "scripts" / "validate-full.sh" -CLI_REF = "14dc68eba05bf65b8c6dea28c3a2db93daa12d38" -FOUNDATION_REF = "f13d08168e14b5bc4720fbb06c40936eb1a7a7d1" +CLI_REF = "main" +FOUNDATION_REF = "main" def _write_executable(path: Path, content: str) -> None: @@ -48,6 +48,10 @@ def _create_fake_uv(bin_dir: Path) -> None: [[ "${FAKE_FAIL_PRIVATE_IMPORTS:-}" != "1" ]] exit fi +if [[ "$*" == *"CI_VALIDATE_RUNTIME="* ]]; then + printf '%s\\n' 'CI_VALIDATE_RUNTIME={"core_channel":"latest-published-wheel","packages":{}}' + exit +fi if [[ "$*" == *"json.dumps"* ]]; then printf '%s\\n' "$2" > "$FAKE_JSON_CODE" printf '%s\\n' "$3" > "$FAKE_JSON_INPUT" @@ -78,7 +82,8 @@ def _create_fake_uv(bin_dir: Path) -> None: #!/usr/bin/env bash exec "VENV_PYTHON" "$0" "$@" AMPLIFIER - sed -i "s|VENV_PYTHON|$venv/bin/python|" "$venv/bin/amplifier" + sed "s|VENV_PYTHON|$venv/bin/python|" "$venv/bin/amplifier" > "$venv/bin/amplifier.tmp" + mv "$venv/bin/amplifier.tmp" "$venv/bin/amplifier" chmod +x "$venv/bin/amplifier" fi """, @@ -147,7 +152,7 @@ def _environment( return environment -def test_launches_pinned_private_cli_and_preserves_paths_with_spaces(tmp_path: Path) -> None: +def test_launches_latest_private_cli_and_preserves_paths_with_spaces(tmp_path: Path) -> None: """The wrapper launches private tools without relocating caller settings identity.""" caller_amplifier_home = str(tmp_path / "caller amplifier home") environment = _environment(tmp_path, caller_amplifier_home=caller_amplifier_home) @@ -183,7 +188,9 @@ def test_launches_pinned_private_cli_and_preserves_paths_with_spaces(tmp_path: P assert str(venv_path / "bin" / "python") in python_targets assert "pip" in uv_args assert "hatchling" in uv_args - assert "amplifier-core==1.6.1" in uv_args + assert "amplifier-core" in uv_args + assert "--upgrade" in uv_args + assert "CI_VALIDATE_RUNTIME=" in result.stdout # The CLI supplies Core/Foundation through its own dependency closure. # Repeating Foundation as a direct Git requirement conflicts with its # tool.uv.sources mapping during a real install. diff --git a/tests/test_validate_full_launcher.py b/tests/test_validate_full_launcher.py index feb8dd8..7785a9c 100644 --- a/tests/test_validate_full_launcher.py +++ b/tests/test_validate_full_launcher.py @@ -4,9 +4,9 @@ import json import os -from pathlib import Path import subprocess import sys +from pathlib import Path import pytest @@ -35,7 +35,9 @@ def launcher(tmp_path): " b=pathlib.Path(sys.argv[-1])/'bin'; b.mkdir()\n" " (b/'python').write_text('#!/bin/sh\\n" 'if [ "$2" = "import pip, hatchling, yaml, amplifier_core, amplifier_foundation" ]; ' - f'then exit 0; fi\\nexec {sys.executable} "$@"\\n\')\n' + f"then exit 0; fi\\n" + 'case "$2" in *CI_VALIDATE_RUNTIME=*) echo CI_VALIDATE_RUNTIME=\\"fake-resolved-receipt\\"; exit 0;; esac\\n' + f'exec {sys.executable} "$@"\\n\')\n' " (b/'python').chmod(0o755)\n" " (b/'amplifier').write_text('#!/bin/sh\\n" f"exec {sys.executable} \"'+os.environ['CLI_SPY']+'\" \"$@\"\\n')\n" @@ -81,6 +83,7 @@ def _run(launcher, **overrides): capture_output=True, text=True, timeout=15, + check=False, ) @@ -92,11 +95,10 @@ def test_runs_venv_cli_and_preserves_status_and_json_paths(launcher, status): calls = [json.loads(line) for line in Path(env["CALL_LOG"]).read_text().splitlines()] assert "--only-binary" in calls[1] assert "--overrides" in calls[1] - assert ( - "amplifier-foundation@f13d08168e14b5bc4720fbb06c40936eb1a7a7d1" - in Path(env["OVERRIDE_COPY"]).read_text() - ) - assert "amplifier-core==1.6.1" in calls[1] + assert "amplifier-foundation@main" in Path(env["OVERRIDE_COPY"]).read_text() + assert "amplifier-core" in calls[1] + assert "--upgrade" in calls[1] + assert "CI_VALIDATE_RUNTIME=" in result.stdout assert not any("amplifier-core@" in arg for arg in calls[1]) response = json.loads(Path(env["CLI_RESULT"]).read_text()) context = json.loads(next(arg[8:] for arg in response["args"] if arg.startswith("context=")))