Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
15 commits
Select commit Hold shift + click to select a range
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
13 changes: 13 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE/catalog.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Catalog submission

- Versioned wheel URL and attached preflight.json:
- Source/build and usage/test evidence:
- First submission: ownership and code/asset rights links (updates may reuse them):
- Update: changes and any access/configuration/data migration steps (or none):

Please revise this same PR. Do not fill invented reviewer/approval fields.
Existing README, release notes and logs are sufficient evidence formats.

<!-- Maintainer only: assign one contact, link the checklist/review and exact head,
then prepare/link the separate publication PR and its delivery receipt. Existing
PR review states suffice; labels are optional. Authors need no second submission. -->
57 changes: 57 additions & 0 deletions .github/workflows/catalog-admission.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
name: Catalog admission
on:
pull_request_target:
types: [opened, synchronize, reopened, ready_for_review]
permissions:
contents: read
jobs:
catalog-admission:
runs-on: windows-2025
timeout-minutes: 20
steps:
- uses: actions/checkout@v7
with:
ref: ${{ github.event.pull_request.base.sha }}
path: trusted
fetch-depth: 0
persist-credentials: false
- uses: actions/checkout@v7
with:
repository: ${{ github.event.pull_request.head.repo.full_name }}
ref: ${{ github.event.pull_request.head.sha }}
path: proposal
fetch-depth: 0
persist-credentials: false
- uses: actions/setup-python@v7
with:
python-version: '3.12.10'
- uses: actions/checkout@v7
with:
repository: Code-Amadeus/Amadeus
ref: 1840c8e4f646992ddaebea3139c8895f29743a8f
path: host
persist-credentials: false
- name: Create private environments from trusted hashed requirements
shell: pwsh
run: |
python -I -m venv admission-env
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
admission-env/Scripts/python.exe -I -m pip install --require-hashes -r trusted/requirements-dev.txt
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
python -I -m venv checker-env
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
checker-env/Scripts/python.exe -I -m pip install --require-hashes -r host/tools/requirements-extension-authoring.txt
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
- name: Inspect proposal only as data with protected-base tools
shell: pwsh
env:
CATALOG_BASE: ${{ github.event.pull_request.base.sha }}
run: |
admission-env/Scripts/python.exe trusted/tools/check_catalog_ci.py --proposal proposal --base $env:CATALOG_BASE --host host --python checker-env/Scripts/python.exe --artifacts artifacts --evidence evidence
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
- uses: actions/upload-artifact@v7
if: always()
with:
name: catalog-admission-evidence
path: evidence/*.json
if-no-files-found: ignore
47 changes: 47 additions & 0 deletions .github/workflows/validate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,50 @@ jobs:
first, second = (path.read_bytes() for path in wheels)
assert first == second, 'Windows and Linux SDK wheels differ'
print(f'{wheels[0].name} sha256={hashlib.sha256(first).hexdigest()}')

catalog-contracts:
runs-on: windows-2025
timeout-minutes: 20
permissions:
contents: read
steps:
- uses: actions/checkout@v7
with:
path: proposal
fetch-depth: 0
- uses: actions/setup-python@v7
with:
python-version: '3.12.10'
- uses: actions/checkout@v7
with:
repository: Code-Amadeus/Amadeus
# Reviewed D1 checker. Publish this commit before enabling the remote job.
ref: 1840c8e4f646992ddaebea3139c8895f29743a8f
path: host
- name: Install catalog tests and fixed static checker
shell: pwsh
run: |
python -m pip install --require-hashes -r proposal/requirements-dev.txt
python -m venv host/build/catalog-checker
host/build/catalog-checker/Scripts/python.exe -m pip install --require-hashes -r host/tools/requirements-extension-authoring.txt
- name: Build only the pinned Host reference packages
shell: pwsh
run: |
New-Item -ItemType Directory -Force host/build/extension-authoring-review-wheels | Out-Null
$destination = (Resolve-Path host/build/extension-authoring-review-wheels).Path
foreach ($project in Get-ChildItem host/examples/extensions -Directory) {
Push-Location $project.FullName
python -I -c 'from setuptools.build_meta import build_wheel; import sys; build_wheel(sys.argv[1])' $destination
$result = $LASTEXITCODE
Pop-Location
if ($result -ne 0) { exit $result }
}
- name: Test catalog and local admission separation
working-directory: proposal
shell: pwsh
run: |
$env:AMADEUS_CATALOG_HOST = (Resolve-Path ../host).Path
$env:AMADEUS_CATALOG_PYTHON = (Resolve-Path ../host/build/catalog-checker/Scripts/python.exe).Path
python -m pytest -q tests/test_catalog.py tests/test_catalog_submission.py
# Admission runs independently from protected-base workflow/code.
# This job executes proposal tests only; it must never gate publication.
4 changes: 4 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,7 @@ The build tool canonicalizes SDK text/ZIP metadata and recalculates RECORD per
CI compares artifacts built independently on Windows and Linux. Do not replace
that cross-platform comparison with two builds on the same machine. The Host's
pinned wheel must match this canonical artifact; runtime support remains >=3.11.


For author preflight, ownership/transfer, review invalidation, PR responsibilities,
revision and verified distribution, follow the [submission workflow](catalog/SUBMISSION.md).
13 changes: 12 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ Public design direction and discussion for the Amadeus extension system.

> **Status: Draft specification v0.1**
>
> A first draft of the extension protocol is available for discussion. Unmerged Amadeus experiments implement TTS/MCP/Skill lifecycle and data-only desktop themes; no stable SDK has been released. Interfaces and compatibility guarantees may change until 1.0.
> A first draft of the extension protocol is available for discussion. Amadeus main implements an experimental subset with TTS/MCP/Skill lifecycle and data-only desktop themes; no stable SDK has been released. Interfaces and compatibility guarantees may change until 1.0.

The implemented Host subset is documented in the [Host profile](https://github.com/Code-Amadeus/Amadeus/blob/fd17e707d8793480003f929bc8c78a8d134e41b5/docs/extension_host_profile_v0.1.md).
Manifest validation here is not a claim that every draft contribution can run.

## Why this repository exists

Expand Down Expand Up @@ -51,6 +54,14 @@ python tools/validate_manifest.py examples/mimo-tts
python -m pytest
```

## Curated catalog experiment

See [catalog tooling and review policy](catalog/README.md). The empty bootstrap
contains no reviewed packages. The Host experiment implements store browsing, downloads,
manual updates and durable safety, with a complete local Git/HTTPS/desktop demonstration;
these branches have not been released publicly. Start with the
[submission and publication guide](catalog/SUBMISSION.md).

## Current design direction

### Capability discovery within a prompt budget
Expand Down
161 changes: 161 additions & 0 deletions catalog/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
# Curated catalog v1 (experimental, no public store yet)

This directory defines distribution facts, not new extension execution rights.
The sole official index URL will be
`https://raw.githubusercontent.com/Code-Amadeus/Amadeus-Extensions/main/catalog/v1/index.json`
on protected main. There is no signature in v1: repository access,
branch protection, independent review, maintainer 2FA and least-privilege Actions
are the trust root. These publication controls must be verified before S3.
No real package is reviewed or published by the empty sequence-0 bootstrap.

## Inputs and review

Put one JSON file per artifact below `packages/`. Hand-maintained keys are exactly:

```json
{
"wheel": {"url": "https://example.invalid/package-1.0.0-py3-none-any.whl", "sha256": "<64 lowercase hex>"},
"publisher": {"id": "publisher", "maintainers": ["author"], "package_ids": ["org.example.package"], "evidence": "https://..."},
"review": {"sha256": "<same artifact digest>", "policy": "curated-v1", "reviewer": "independent-reviewer", "date": "2026-10-21", "evidence": "https://..."},
"withdrawal": null
}
```

A reviewer must verify the ownership evidence and independently inspect the
actual wheel using [the public checklist](REVIEW_CHECKLIST.md). Reviewer/maintainer identities are GitHub logins, compared without case. These JSON strings
are review records, not authentication; protected-branch PR approval establishes
their authority. Maintainer examples follow the same independent-review rule.
Every new version is reviewed, including when the source repository appears unchanged.
Never enter a review record merely because automated checks passed.

The generator derives identity, size, author/license/homepage/description, Host
and Python constraints, platform list, dependencies and contribution summaries
from that artifact. It never modifies or adds catalog fields to the manifest.
`policy.json` is the single v1 admission policy used by the catalog tooling.
Fish Audio remains valid for local installation but its third-party dependencies
exclude it from this first catalog. A future dependency closure must pin every
transitive wheel URL/hash and install offline with `--no-index --find-links`
plus `--require-hashes --only-binary=:all:`; this is not implemented in v1.

Artifacts are stored locally as `<sha256>/<original-wheel-filename>`. The optional
`--fetch` path allows HTTPS, system TLS verification, bounded redirects, time and
size, no URL credentials/cookies. It only downloads bytes. Host S1 downloads must
use Electron net; this maintenance tool is not a replacement Host downloader.
Artifact mirrors may supply the same digest-pinned bytes; index mirrors require
future signatures. Never replace the official index trust root with a mirror.

## Fixed checker and publication

`toolchain.json` fixes Host commit, Windows, CPython 3.12.10 and the hash of the
Host's generated minimal dependency list. Obtain that exact Host checkout; the
tools reject a different or modified checker. Install its minimal environment
with `pip --require-hashes`. The Host pin is currently a local experimental commit
and must be pushed/reviewed before GitHub Actions can retrieve it. No SDK or Host
protocol pin is changed by this catalog work.

1. Commit proposed artifact/review/ownership facts. CI uses protected-base tools
to inspect their bytes without importing or installing package code. Human
review must finish before the input PR merges into main.
2. A separate publication PR selects an already merged input commit. Select an
already reviewed generator commit. The generator tree must be clean.
3. Run the fixed generator from that commit, with the current main index as
`--previous` and the next integer sequence. Source time comes from the input
commit, never the wall clock. Repeat builds yield identical bytes.

```powershell
python tools/build_catalog.py --source-repo . --source-commit <merged-input-sha> --approved-ref origin/main --sequence <previous-plus-one> --previous <current-main-index.json> --host <pinned-host> --python <minimal-python> --artifacts <artifact-cache> --output catalog/v1/index.json --fetch
python tools/check_catalog.py --index catalog/v1/index.json --previous <current-main-index.json>
python tools/check_catalog.py --wheel <current-wheel> --previous-wheel <previous-reviewed-wheel> --output <review-diff.json>
```

`check_catalog.py` emits additions/removals/changes, text diffs and binary hashes;
initial review emits the whole file inventory. Truncated text diffs are marked:
review the full artifact for those files. Manifest, METADATA/dependencies and
startup scripts appear in the same content diff. Do not treat a diff as approval.

4. Immediately before merging, CI rechecks against current protected main.
Concurrent publication PRs must rebase and obtain review again. No workflow
pushes to main or executes submitted plugin code with publication privileges.
The bootstrap is a separately reviewed code change admitting only an empty
index; subsequent catalog PRs execute protected-base tooling. Generator changes
are reviewed before a later PR selects them for publication.

An unchanged index may be rebuilt exactly. A changed index must increment by one,
including content rollback. An existing ID/version cannot disappear or acquire
new bytes; retain it and mark withdrawal. Unchanged reviewed facts may be reused
from the previous protected-main index at the same Host/policy pin. This preserves
security publication when an old download is unavailable; the download/display
cache is never used as authority. New bytes/reviews/ownership or a changed checker
pin still require artifact inspection.

## Withdrawal, safety and future clients

`withdrawal` is null or `{ "reason": "maintainer" | "copyright", "evidence": "https://..." }`.
It stops catalog installation/recommendation, not execution of existing local copies.
`security.json` retains one explicit latest decision per ID/version/SHA-256:
`status` is `blocked` or `allowed`, `reason` is `security` or `security-resolved`,
with evidence and the publication sequence that changed the decision. A known
fact cannot disappear; explicit unban requires a higher publication sequence.
Safety applies to both local and catalog installations. The Host experiment now implements durable settings,
backup recovery and activation enforcement; see its `docs/extension_catalog.md`.
These local changes still require Host integration and release qualification.

Stable index structure is validated without running the full manifest validator.
Unknown contribution kind, role, contract, runtime or delivery makes that entire
package incompatible; compatible neighbors remain visible. Mixed packages are not
partially installed. Security structure is parsed independently of those entries.
Unknown format major, invalid safety structure or identity conflicts reject the
new snapshot, retaining prior safety/high-water facts in S1. Shared examples are
in `fixtures/compatibility.json`; the Python compatibility function specifies the
capability part only. Host API/Python/platform/dependency checks and main-process
installation rechecks are implemented by the Host experiment, separately from this publisher.

Display strings are untrusted plain text. The experimental S2 client renders no remote images and
validates HTTPS homepage links in main before opening an external browser.
Host S3 preparation records fixed old-reader cross-checks; this repository alone
does not certify a released Electron client.

S2 detail views consume generated `display.access`: declared OS access and TTS/MCP deployment, command/arguments or endpoint templates. Configuration defaults, bearer tokens and environment values are excluded. Older entries without this optional display fact remain readable and must show that access details are unavailable until wheel inspection. This does not change catalog format or runtime contracts.


## First catalog review preparation

[Candidate review materials](review-candidates/README.md) inventory exact reference
wheel bytes and static checks. They are not catalog entries or approvals. Keep the
bootstrap empty until independent review, public artifacts, protected publication
and final release qualification are complete. The Host experimental S3 checklist
is `docs/verification/extensions/store-v1.md`; no release is implied by this material.


For author preflight, ownership/transfer, review invalidation, PR responsibilities,
revision and verified distribution, follow the [submission workflow](SUBMISSION.md).

## Versioned delivery and independent admission

The v1 public path is permanent: catalog/v1/index.json always retains the strict
amadeus.catalog/v1 format. A new wire format uses another path. Maintainers must
continue publishing understood safety facts and increasing sequences on supported
older paths; switching v2 clients does not retire v1 safety delivery. Retirement
requires an explicit client-support decision, never silently replacing v1 bytes
with v2. There is no unversioned redirect used by clients.

Proposal tests run in validate.yml and confer no admission authority. The separate
catalog-admission.yml runs from the protected base via pull_request_target with
read-only permissions, fresh private Python environments and base-pinned hashed
dependencies. Proposal files are data only: its requirements, tests, workflow,
sitecustomize and .pth files are never installed or executed by admission. No
cache or artifacts from proposal jobs are reused.

This first empty bootstrap requires human review of the workflow itself: the
trusted workflow cannot certify its own introduction before it exists on main.
After bootstrap, require the catalog-admission check from GitHub Actions before
accepting any package/publication PR, and verify a deliberately invalid proposal
is rejected on that protected path. Do not treat proposal unit tests or a local
job simulation as that governance check.

The fixed Host commit is retained by the annotated tag
[extension-catalog-checker-d1](https://github.com/Code-Amadeus/Amadeus/tree/extension-catalog-checker-d1).
This is a Git retention ref, not a Release or catalog publication. The toolchain
still verifies the immutable commit hash, never a movable tag. After the Host
prototype reaches main, requalify its checker there (including real v1 icon wheels)
before updating the toolchain. Until then, the fixed checker rejects icon manifests.
Loading