diff --git a/.changeset/config.json b/.changeset/config.json new file mode 100644 index 0000000..148bf98 --- /dev/null +++ b/.changeset/config.json @@ -0,0 +1,11 @@ +{ + "$schema": "https://unpkg.com/@changesets/config@3.1.2/schema.json", + "changelog": false, + "commit": false, + "fixed": [], + "linked": [], + "access": "public", + "baseBranch": "main", + "updateInternalDependencies": "patch", + "ignore": [] +} diff --git a/.changeset/graduate-yield.md b/.changeset/graduate-yield.md new file mode 100644 index 0000000..17a274f --- /dev/null +++ b/.changeset/graduate-yield.md @@ -0,0 +1,5 @@ +--- +"@operatorstack/yield": patch +--- + +Graduate Yield into its canonical repository and add supervised public npm release channels with provenance. diff --git a/.github/workflows/npm-publish.yml b/.github/workflows/npm-publish.yml new file mode 100644 index 0000000..93ef4b9 --- /dev/null +++ b/.github/workflows/npm-publish.yml @@ -0,0 +1,177 @@ +name: Publish Yield to npm + +on: + push: + branches: [main] + workflow_run: + workflows: ["Release Yield"] + types: [completed] + workflow_dispatch: + inputs: + version: + description: Existing stable tag version without the leading v + type: string + required: true + +permissions: + contents: read + id-token: write + +concurrency: + group: npm-${{ github.event_name == 'push' && 'canary' || 'stable' }} + cancel-in-progress: false + +jobs: + resolve: + if: >- + github.repository == 'operatorstack/yield' && + (github.event_name != 'workflow_run' || + (github.event.workflow_run.conclusion == 'success' && github.event.workflow_run.head_branch == 'main')) + runs-on: ubuntu-latest + outputs: + publish: ${{ steps.release.outputs.publish }} + channel: ${{ steps.release.outputs.channel }} + version: ${{ steps.release.outputs.version }} + dist_tag: ${{ steps.release.outputs.dist_tag }} + source_sha: ${{ steps.release.outputs.source_sha }} + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 + with: + fetch-depth: 0 + persist-credentials: false + ref: ${{ github.event_name == 'workflow_run' && github.event.workflow_run.head_sha || github.event_name == 'workflow_dispatch' && format('v{0}', inputs.version) || github.sha }} + - id: release + name: Resolve immutable source, version, and channel + env: + REQUESTED_VERSION: ${{ inputs.version }} + shell: bash + run: | + set -euo pipefail + source_sha="$(git rev-parse HEAD)" + if [[ "$GITHUB_EVENT_NAME" == push ]]; then + committed_at="$(git show -s --format=%cd --date=format:%Y%m%d%H%M%S HEAD)" + version="0.0.0-canary.${committed_at}.$(git rev-parse --short=12 HEAD)" + channel=canary + dist_tag=canary + else + if [[ "$GITHUB_EVENT_NAME" == workflow_run ]]; then + tag="$(git tag --points-at HEAD --list 'v[0-9]*' --sort=-v:refname | head -n 1)" + if [[ -z "$tag" ]]; then + echo "publish=false" >> "$GITHUB_OUTPUT" + echo "Release run created no tag; this was a dry run." + exit 0 + fi + version="${tag#v}" + else + version="$REQUESTED_VERSION" + tag="v${version}" + fi + [[ "$version" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]] + test "$(git rev-list -n 1 "v${version}")" = "$source_sha" + channel=stable + dist_tag=latest + fi + echo "publish=true" >> "$GITHUB_OUTPUT" + echo "channel=$channel" >> "$GITHUB_OUTPUT" + echo "version=$version" >> "$GITHUB_OUTPUT" + echo "dist_tag=$dist_tag" >> "$GITHUB_OUTPUT" + echo "source_sha=$source_sha" >> "$GITHUB_OUTPUT" + + publish: + needs: resolve + if: needs.resolve.outputs.publish == 'true' + runs-on: ubuntu-latest + environment: ${{ needs.resolve.outputs.channel == 'stable' && 'npm-production' || 'npm-canary' }} + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 + with: + fetch-depth: 0 + persist-credentials: false + ref: ${{ needs.resolve.outputs.source_sha }} + - uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7 + with: + go-version-file: go.mod + cache: true + - uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6 + with: + node-version: "24" + registry-url: https://registry.npmjs.org + package-manager-cache: false + - name: Pin npm trusted-publishing client + run: npm install --global npm@12.0.2 + - name: Verify source + run: | + go test ./... + node --test packaging/*.test.mjs sdk/typescript/bin/*.test.mjs + - name: Build immutable runtimes + env: + VERSION: ${{ needs.resolve.outputs.version }} + shell: bash + run: | + set -euo pipefail + mkdir -p dist/bin + for spec in darwin/amd64 darwin/arm64 linux/amd64 linux/arm64 windows/amd64 windows/arm64; do + goos="${spec%/*}" + goarch="${spec#*/}" + suffix="" + if [[ "$goos" == windows ]]; then suffix=.exe; fi + CGO_ENABLED=0 GOOS="$goos" GOARCH="$goarch" \ + go build -trimpath -ldflags "-s -w -X main.version=${VERSION}" \ + -o "dist/bin/yskill-${goos}-${goarch}${suffix}" ./cmd/yskill + done + node packaging/assemble.mjs --version "$VERSION" --binaries dist/bin --output dist/packages + - name: Inspect npm tarballs + shell: bash + run: | + set -euo pipefail + for directory in dist/packages/npm/*; do + (cd "$directory" && npm pack --dry-run) + done + - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 + with: + name: npm-${{ needs.resolve.outputs.version }}-release-unit + path: | + dist/packages/SHA256SUMS.json + dist/packages/npm/ + if-no-files-found: error + - name: Publish platform runtimes + env: + DIST_TAG: ${{ needs.resolve.outputs.dist_tag }} + VERSION: ${{ needs.resolve.outputs.version }} + shell: bash + run: | + set -euo pipefail + for directory in dist/packages/npm/darwin-* dist/packages/npm/linux-* dist/packages/npm/windows-*; do + package="$(node -p "require('./${directory}/package.json').name")" + if npm view "${package}@${VERSION}" version >/dev/null 2>&1; then + echo "${package}@${VERSION} already exists" + else + (cd "$directory" && npm publish --tag "$DIST_TAG") + fi + done + - name: Publish SDK and CLI + env: + DIST_TAG: ${{ needs.resolve.outputs.dist_tag }} + VERSION: ${{ needs.resolve.outputs.version }} + shell: bash + run: | + set -euo pipefail + if npm view "@operatorstack/yield@${VERSION}" version >/dev/null 2>&1; then + echo "@operatorstack/yield@${VERSION} already exists" + else + (cd dist/packages/npm/yield && npm publish --tag "$DIST_TAG") + fi + - name: Verify complete public release unit + env: + VERSION: ${{ needs.resolve.outputs.version }} + shell: bash + run: | + set -euo pipefail + for directory in dist/packages/npm/*; do + package="$(node -p "require('./${directory}/package.json').name")" + for attempt in {1..12}; do + if [[ "$(npm view "${package}@${VERSION}" version 2>/dev/null || true)" == "$VERSION" ]]; then break; fi + test "$attempt" -lt 12 + sleep 10 + done + done diff --git a/.github/workflows/private-registry.yml b/.github/workflows/private-registry.yml index c43af72..9251cf3 100644 --- a/.github/workflows/private-registry.yml +++ b/.github/workflows/private-registry.yml @@ -3,8 +3,6 @@ name: Publish SDKs to OperatorStack Registry on: pull_request: paths: [".github/workflows/private-registry.yml"] - push: - tags: ["v*"] workflow_run: workflows: ["Release Yield"] types: [completed] @@ -13,7 +11,7 @@ on: version: description: "Existing release version without the leading v" required: true - default: "0.1.8" + default: "0.1.29" type: string permissions: @@ -29,11 +27,11 @@ jobs: if: github.event_name == 'pull_request' runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - uses: actions/setup-go@v5 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 + - uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7 with: go-version: stable - - uses: actions/setup-node@v4 + - uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6 with: node-version: "24" - name: Verify the current release source @@ -47,28 +45,55 @@ jobs: grep -F 'packaging/assemble.mjs' .github/workflows/private-registry.yml grep -F 'Install and test all language packages' .github/workflows/private-registry.yml + gate: + if: github.event_name != 'pull_request' + runs-on: ubuntu-latest + outputs: + publish: ${{ steps.gate.outputs.publish }} + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 + with: + fetch-depth: 0 + persist-credentials: false + ref: ${{ github.event_name == 'workflow_run' && github.event.workflow_run.head_sha || format('v{0}', inputs.version) }} + - id: gate + shell: bash + run: | + if [[ "$GITHUB_EVENT_NAME" == workflow_run ]] && + [[ -z "$(git tag --points-at HEAD --list 'v[0-9]*' | head -n 1)" ]]; then + echo "publish=false" >> "$GITHUB_OUTPUT" + echo "Release run created no tag; this was a dry run." + else + echo "publish=true" >> "$GITHUB_OUTPUT" + fi + publish: - if: github.event_name != 'pull_request' && (github.event_name != 'workflow_run' || github.event.workflow_run.conclusion == 'success') + needs: gate + if: >- + needs.gate.outputs.publish == 'true' && + (github.event_name != 'workflow_run' || + (github.event.workflow_run.conclusion == 'success' && github.event.workflow_run.head_branch == 'main')) runs-on: ubuntu-latest + environment: private-production outputs: version: ${{ steps.version.outputs.version }} previous_version: ${{ steps.version.outputs.previous_version }} source_sha: ${{ steps.version.outputs.source_sha }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 with: fetch-depth: 0 ref: ${{ github.event_name == 'workflow_dispatch' && format('v{0}', inputs.version) || github.event_name == 'workflow_run' && github.event.workflow_run.head_sha || github.ref }} - - uses: actions/setup-go@v5 + - uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7 with: go-version: stable - - uses: actions/setup-node@v4 + - uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6 with: node-version: "24" - - uses: actions/setup-python@v5 + - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6 with: python-version: "3.11" - - uses: dtolnay/rust-toolchain@stable + - uses: dtolnay/rust-toolchain@4360b52568e2003a75bf9bc1d59f33a8e3fc893c - id: version name: Resolve published version @@ -100,11 +125,11 @@ jobs: echo "source_sha=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT" - id: auth - uses: google-github-actions/auth@v2 + uses: google-github-actions/auth@7c6bc770dae815cd3e89ee6cdf493a5fab2cc093 # v3 with: workload_identity_provider: ${{ vars.WIF_PROVIDER }} service_account: ${{ vars.DEPLOYER_SA_EMAIL }} - - uses: google-github-actions/setup-gcloud@v2 + - uses: google-github-actions/setup-gcloud@aa5489c8933f4cc7a4f7d45035b3b1440c9c10db # v3 with: install_components: package-go-module @@ -134,7 +159,7 @@ jobs: node packaging/assemble.mjs --version "$VERSION" --binaries dist/bin --output dist/packages - name: Keep runtime checksums with the release run - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 with: name: yskill-${{ steps.version.outputs.version }}-runtimes path: | @@ -302,16 +327,16 @@ jobs: runner: windows-11-arm runs-on: ${{ matrix.runner }} steps: - - uses: actions/setup-go@v5 + - uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7 with: go-version: stable - - uses: actions/setup-node@v4 + - uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6 with: node-version: "24" - - uses: actions/setup-python@v5 + - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6 with: python-version: "3.11" - - uses: dtolnay/rust-toolchain@stable + - uses: dtolnay/rust-toolchain@4360b52568e2003a75bf9bc1d59f33a8e3fc893c - name: Install and test all language packages shell: bash env: diff --git a/.github/workflows/release-finalize.yml b/.github/workflows/release-finalize.yml new file mode 100644 index 0000000..2cea106 --- /dev/null +++ b/.github/workflows/release-finalize.yml @@ -0,0 +1,99 @@ +name: Finalize Yield release + +on: + workflow_run: + workflows: ["Publish Yield to npm"] + types: [completed] + workflow_dispatch: + inputs: + version: + description: Existing stable version without the leading v + type: string + required: true + +permissions: + actions: read + contents: read + +concurrency: + group: finalize-yield-release + cancel-in-progress: false + +jobs: + resolve: + if: >- + github.repository == 'operatorstack/yield' && + (github.event_name == 'workflow_dispatch' || github.event.workflow_run.conclusion == 'success') + runs-on: ubuntu-latest + outputs: + finalize: ${{ steps.release.outputs.finalize }} + tag: ${{ steps.release.outputs.tag }} + source_sha: ${{ steps.release.outputs.source_sha }} + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 + with: + fetch-depth: 0 + persist-credentials: false + - id: release + env: + REQUESTED_VERSION: ${{ inputs.version }} + WORKFLOW_HEAD_SHA: ${{ github.event.workflow_run.head_sha }} + shell: bash + run: | + set -euo pipefail + if [[ "$GITHUB_EVENT_NAME" == workflow_dispatch ]]; then + [[ "$REQUESTED_VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]] + tag="v${REQUESTED_VERSION}" + sha="$(git rev-list -n 1 "$tag")" + else + sha="$WORKFLOW_HEAD_SHA" + tag="$(git tag --points-at "$sha" --list 'v[0-9]*' --sort=-v:refname | head -n 1)" + if [[ -z "$tag" ]]; then + echo "finalize=false" >> "$GITHUB_OUTPUT" + echo "Publisher run has no stable tag; nothing to finalize." + exit 0 + fi + fi + echo "finalize=true" >> "$GITHUB_OUTPUT" + echo "tag=$tag" >> "$GITHUB_OUTPUT" + echo "source_sha=$sha" >> "$GITHUB_OUTPUT" + + finalize: + needs: resolve + if: needs.resolve.outputs.finalize == 'true' + runs-on: ubuntu-latest + permissions: + actions: read + contents: write + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 + with: + fetch-depth: 0 + persist-credentials: false + ref: ${{ needs.resolve.outputs.source_sha }} + - uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6 + with: + node-version: "24" + registry-url: https://registry.npmjs.org + package-manager-cache: false + - name: Require matching successful publisher receipts + env: + GH_TOKEN: ${{ github.token }} + TAG: ${{ needs.resolve.outputs.tag }} + SOURCE_SHA: ${{ needs.resolve.outputs.source_sha }} + shell: bash + run: | + set -euo pipefail + version="${TAG#v}" + conclusion="$(gh api "/repos/${GITHUB_REPOSITORY}/actions/workflows/npm-publish.yml/runs?head_sha=${SOURCE_SHA}&status=completed&per_page=30" \ + --jq '[.workflow_runs[] | select(.event == "workflow_run" or .event == "workflow_dispatch")][0].conclusion // "missing"')" + test "$conclusion" = success + for package in \ + @operatorstack/yield \ + @operatorstack/yield-darwin-amd64 @operatorstack/yield-darwin-arm64 \ + @operatorstack/yield-linux-amd64 @operatorstack/yield-linux-arm64 \ + @operatorstack/yield-windows-amd64 @operatorstack/yield-windows-arm64; do + test "$(npm view "${package}@${version}" version)" = "$version" + done + test "$(git rev-list -n 1 "$TAG")" = "$SOURCE_SHA" + gh release edit "$TAG" --repo "$GITHUB_REPOSITORY" --draft=false diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 8900e12..8954e51 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,95 +1,132 @@ -# Generated by labkit (python -m labkit gen). Do not edit by hand. -# Edit labs//publish.config.json and regenerate; drift fails `labkit doctor`. -# Install into operatorstack/yield at .github/workflows/release.yml (bootstrap step). name: Release Yield on: - push: - branches: [main] workflow_dispatch: inputs: bump: - description: Version bump for a manual release + description: Changeset bump, or an explicit higher bump type: choice - options: [patch, minor, major] - default: patch + options: [auto, patch, minor, major] + default: auto + required: true + dry_run: + description: Resolve and verify without tagging or publishing + type: boolean + default: false + required: true permissions: - contents: write - pull-requests: read + contents: read concurrency: group: release-yield cancel-in-progress: false jobs: - release: + plan: + if: github.repository == 'operatorstack/yield' runs-on: ubuntu-latest + outputs: + version: ${{ steps.plan.outputs.version }} + tag: ${{ steps.plan.outputs.tag }} + source_sha: ${{ steps.plan.outputs.source_sha }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 with: fetch-depth: 0 - - name: Resolve release policy - id: policy - env: - GH_TOKEN: ${{ github.token }} - MANUAL_BUMP: ${{ inputs.bump }} + persist-credentials: false + - uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6 + with: + node-version: "24" + cache: npm + - uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7 + with: + go-version-file: go.mod + cache: true + - name: Bind dispatch to protected main shell: bash run: | - bump="${MANUAL_BUMP:-patch}" - skip="false" - if [[ "${GITHUB_EVENT_NAME}" == "push" ]]; then - labels="$(gh api \ - -H 'Accept: application/vnd.github+json' \ - "/repos/${GITHUB_REPOSITORY}/commits/${GITHUB_SHA}/pulls" \ - --jq '.[0].labels[].name' 2>/dev/null || true)" - if grep -qx 'skip-release' <<<"$labels"; then skip="true"; fi - if grep -qx 'major' <<<"$labels"; then - bump="major" - elif grep -qx 'minor' <<<"$labels"; then - bump="minor" - fi - fi - echo "bump=$bump" >> "$GITHUB_OUTPUT" - echo "skip=$skip" >> "$GITHUB_OUTPUT" - - name: Compute version - if: steps.policy.outputs.skip != 'true' - id: version + set -euo pipefail + test "$GITHUB_REF" = refs/heads/main + test "$(git rev-parse HEAD)" = "$GITHUB_SHA" + test "$(git rev-parse origin/main)" = "$GITHUB_SHA" + - run: npm ci --ignore-scripts + - name: Verify release controller and source + run: | + npm run test:release + node scripts/check-release-control.mjs + go test ./... + go build ./... + - id: plan + name: Resolve immutable release intent env: - BUMP: ${{ steps.policy.outputs.bump }} - shell: bash + REQUESTED_BUMP: ${{ inputs.bump }} + run: >- + node scripts/release-plan.mjs + --bump "$REQUESTED_BUMP" + --output "$GITHUB_OUTPUT" + --notes "$RUNNER_TEMP/release-notes.md" + - name: Report dry run + if: inputs.dry_run + env: + TAG: ${{ steps.plan.outputs.tag }} + VERSION: ${{ steps.plan.outputs.version }} run: | - latest="$(git tag --list 'v[0-9]*' --sort=-v:refname | head -n 1)" - if [[ -z "$latest" ]]; then - next="v0.1.0" - else - raw="${latest#v}" - IFS=. read -r major minor patch <<<"$raw" - case "$BUMP" in - major) major=$((major + 1)); minor=0; patch=0 ;; - minor) minor=$((minor + 1)); patch=0 ;; - patch) patch=$((patch + 1)) ;; - *) echo "Invalid bump: $BUMP" >&2; exit 2 ;; - esac - next="v${major}.${minor}.${patch}" - fi - echo "version=$next" >> "$GITHUB_OUTPUT" - - name: Publish release - if: steps.policy.outputs.skip != 'true' + echo "### Dry run: $TAG" >> "$GITHUB_STEP_SUMMARY" + echo "Version: $VERSION" >> "$GITHUB_STEP_SUMMARY" + cat "$RUNNER_TEMP/release-notes.md" >> "$GITHUB_STEP_SUMMARY" + release: + needs: plan + if: ${{ !inputs.dry_run }} + runs-on: ubuntu-latest + environment: release-control + permissions: + contents: write + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 + with: + fetch-depth: 0 + persist-credentials: false + ref: ${{ needs.plan.outputs.source_sha }} + - uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6 + with: + node-version: "24" + cache: npm + - run: npm ci --ignore-scripts + - id: confirm + name: Recompute release intent after approval + env: + REQUESTED_BUMP: ${{ inputs.bump }} + run: >- + node scripts/release-plan.mjs + --bump "$REQUESTED_BUMP" + --output "$GITHUB_OUTPUT" + --notes "$RUNNER_TEMP/release-notes.md" + - name: Refuse plan drift + env: + EXPECTED_TAG: ${{ needs.plan.outputs.tag }} + EXPECTED_VERSION: ${{ needs.plan.outputs.version }} + ACTUAL_TAG: ${{ steps.confirm.outputs.tag }} + ACTUAL_VERSION: ${{ steps.confirm.outputs.version }} + run: | + test "$ACTUAL_TAG" = "$EXPECTED_TAG" + test "$ACTUAL_VERSION" = "$EXPECTED_VERSION" + - name: Create immutable tag and draft release env: GH_TOKEN: ${{ github.token }} - VERSION: ${{ steps.version.outputs.version }} + TAG: ${{ steps.confirm.outputs.tag }} shell: bash run: | - if git rev-parse --verify --quiet "refs/tags/$VERSION"; then - echo "Tag $VERSION already exists; nothing to release." - exit 0 + set -euo pipefail + if git ls-remote --exit-code --tags origin "refs/tags/$TAG" >/dev/null 2>&1; then + echo "Tag $TAG already exists" >&2 + exit 1 fi - git tag "$VERSION" "$GITHUB_SHA" - git push origin "$VERSION" - gh release create "$VERSION" \ + git tag "$TAG" "$GITHUB_SHA" + git push origin "refs/tags/$TAG" + gh release create "$TAG" \ --repo "$GITHUB_REPOSITORY" \ - --title "$VERSION" \ - --generate-notes \ + --title "$TAG" \ + --notes-file "$RUNNER_TEMP/release-notes.md" \ --draft \ --verify-tag diff --git a/.github/workflows/repository-controls.yml b/.github/workflows/repository-controls.yml new file mode 100644 index 0000000..8dcdf3d --- /dev/null +++ b/.github/workflows/repository-controls.yml @@ -0,0 +1,26 @@ +name: Audit repository release controls + +on: + schedule: + - cron: "23 7 * * *" + workflow_dispatch: + +permissions: + contents: read + +jobs: + audit: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 + with: + persist-credentials: false + - uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6 + with: + node-version: "24" + cache: npm + - run: npm ci --ignore-scripts + - name: Refuse repository-policy drift + env: + GH_TOKEN: ${{ github.token }} + run: node scripts/audit-repository-controls.mjs diff --git a/.github/workflows/sync-upstream.yml b/.github/workflows/sync-upstream.yml deleted file mode 100644 index 1555204..0000000 --- a/.github/workflows/sync-upstream.yml +++ /dev/null @@ -1,134 +0,0 @@ -# Generated by labkit (python -m labkit gen). Do not edit by hand. -# Edit labs//publish.config.json and regenerate; drift fails `labkit doctor`. -# Install into operatorstack/yield at .github/workflows/sync-upstream.yml (bootstrap step). -name: Sync from Intelligence Flow - -on: - schedule: - - cron: "19 */6 * * *" - workflow_dispatch: - inputs: - source_commit: - description: Exact Intelligence Flow commit to project (defaults to main) - required: false - type: string - -permissions: - contents: write - pull-requests: write - -concurrency: - group: sync-intelligence-flow - cancel-in-progress: false - -jobs: - sync: - runs-on: ubuntu-latest - steps: - - name: Create Operator Stack Publisher token - id: app-token - uses: actions/create-github-app-token@v3 - with: - client-id: ${{ vars.OPERATOR_STACK_PUBLISHER_APP_CLIENT_ID || vars.BOATSTACK_APP_CLIENT_ID }} - private-key: ${{ secrets.OPERATOR_STACK_PUBLISHER_APP_PRIVATE_KEY || secrets.BOATSTACK_APP_PRIVATE_KEY }} - owner: operatorstack - repositories: | - intelligence-flow - yield - permission-contents: write - permission-pull-requests: write - - name: Check out Yield - uses: actions/checkout@v4 - with: - path: public-repo - token: ${{ steps.app-token.outputs.token }} - - name: Check out Intelligence Flow - uses: actions/checkout@v4 - with: - repository: operatorstack/intelligence-flow - ref: ${{ inputs.source_commit || 'main' }} - fetch-depth: 0 - path: intelligence-flow - token: ${{ steps.app-token.outputs.token }} - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - name: Install labkit - shell: bash - run: python3 -m pip install --quiet ./intelligence-flow/labkit - - name: Generate projection - id: generate - shell: bash - run: | - source_commit="$(git -C intelligence-flow log -1 --format=%H -- labs/22-yield)" - current_commit="$(jq -r '.source.commit // empty' public-repo/UPSTREAM.json 2>/dev/null || echo '')" - if [[ -n "$current_commit" ]] && - ! git -C intelligence-flow merge-base --is-ancestor "$current_commit" "$source_commit"; then - echo "Ignoring stale request; Yield already records $current_commit." - echo "stale=true" >> "$GITHUB_OUTPUT" - exit 0 - fi - python3 -m labkit project \ - --config intelligence-flow/labs/22-yield/publish.config.json \ - --repo public-repo \ - --source-commit "$source_commit" \ - --write - echo "source_commit=$source_commit" >> "$GITHUB_OUTPUT" - echo "stale=false" >> "$GITHUB_OUTPUT" - - name: Open generated pull request - if: steps.generate.outputs.stale != 'true' - env: - GH_TOKEN: ${{ steps.app-token.outputs.token }} - SOURCE_COMMIT: ${{ steps.generate.outputs.source_commit }} - shell: bash - run: | - cd public-repo - if [[ -z "$(git status --porcelain)" ]]; then - echo "Yield already matches Intelligence Flow." - exit 0 - fi - git add -A - rewritten=() - while IFS= read -r note; do rewritten+=("$note"); done < <( - git diff --cached --name-only --diff-filter=MD --no-renames -- 'release-notes/*.md') - if (( ${#rewritten[@]} > 0 )); then - echo "BLOCKED: Yield release notes are append-only:" >&2 - printf ' %s\n' "${rewritten[@]}" >&2 - exit 1 - fi - added=() - while IFS= read -r note; do added+=("$note"); done < <( - git diff --cached --name-only --diff-filter=A --no-renames -- 'release-notes/*.md' | LC_ALL=C sort) - if (( ${#added[@]} == 0 )); then - echo "BLOCKED: projected changes require a release note in release-notes/." >&2 - exit 1 - fi - body_file="$(mktemp)" - { - echo "## What this sync releases"; echo - for note in "${added[@]}"; do cat "$note"; echo; done - echo "
Projection provenance"; echo - echo "Generated from \`operatorstack/intelligence-flow@$SOURCE_COMMIT\`." - echo "Review provenance, tests, and examples before merging."; echo - echo "
" - } > "$body_file" - short="${SOURCE_COMMIT:0:12}" - branch="sync/intelligence-flow-$short" - existing="$(gh pr list --head "$branch" --state open --json url --jq '.[0].url')" - git config user.name "${{ steps.app-token.outputs.app-slug }}[bot]" - git config user.email "${{ steps.app-token.outputs.app-slug }}[bot]@users.noreply.github.com" - git switch -c "$branch" - git commit -m "Sync Yield from Intelligence Flow @ $short" - git push --force --set-upstream origin "$branch" - if [[ -z "$existing" ]]; then - pr_url="$(gh pr create --base main --head "$branch" \ - --title "Sync Yield from Intelligence Flow @ $short" \ - --body-file "$body_file")" - echo "Opened generated PR: $pr_url" - else - pr_url="$existing" - echo "Updated existing PR: $existing" - fi - gh pr merge "$pr_url" --auto --squash - echo "Native auto-merge requested; branch protection owns merge eligibility." diff --git a/.github/workflows/verify.yml b/.github/workflows/verify.yml index 7e16afa..ce844d8 100644 --- a/.github/workflows/verify.yml +++ b/.github/workflows/verify.yml @@ -1,7 +1,4 @@ -# Generated by labkit (python -m labkit gen). Do not edit by hand. -# Edit labs//publish.config.json and regenerate; drift fails `labkit doctor`. -# Install into operatorstack/yield at .github/workflows/verify.yml (bootstrap step). -name: Verify Yield distribution +name: Verify Yield on: pull_request: @@ -16,50 +13,78 @@ concurrency: cancel-in-progress: true jobs: - test: + go: + name: Go and agent registration (${{ matrix.os }}) strategy: fail-fast: false matrix: os: [ubuntu-latest, macos-latest, windows-latest] runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v4 - - uses: actions/setup-go@v7 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 + - uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7 with: go-version-file: go.mod cache: true + - run: go test ./cmd/yskill - run: go test ./... - run: go build ./... - packaging: + validate: + name: Release authority and full validation runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 + - uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7 + with: + go-version-file: go.mod + cache: true + - uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6 with: node-version: "24" - - run: node --test packaging/*.test.mjs - - verify-sync-provenance: - if: >- - github.event_name == 'pull_request' && - github.event.pull_request.head.repo.full_name == github.repository && - startsWith(github.head_ref, 'sync/intelligence-flow-') - needs: test - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 + cache: npm + - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6 with: - ref: ${{ github.event.pull_request.head.sha }} - - name: Verify generated projection provenance - env: - HEAD_BRANCH: ${{ github.head_ref }} - PR_AUTHOR: ${{ github.event.pull_request.user.login }} - shell: bash + python-version: "3.12" + - uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2 + with: + workspaces: | + sdk/rust + examples/data-migration + examples/library/rust + internal/conformance/testdata/skill-rs + - run: npm ci --ignore-scripts + - name: Verify release authority and package assembly + run: | + npm run test:release + node scripts/check-release-control.mjs + python -m unittest discover -s sdk/python -p 'test_*.py' + - name: Rerun first-party evaluations + working-directory: evals + run: | + npm ci + npm test + - name: Build and smoke-test the packed TypeScript SDK + working-directory: sdk/typescript + run: | + npm test + npm run build + tarball="$RUNNER_TEMP/$(npm pack --silent --pack-destination "$RUNNER_TEMP")" + smoke_dir="$(mktemp -d)" + cd "$smoke_dir" + npm init -y >/dev/null + npm install "$tarball" >/dev/null + node --input-type=module -e 'import { defineSkill } from "@operatorstack/yield"; if (typeof defineSkill !== "function") process.exit(1)' + - name: Vet and test four-language conformance + run: | + go vet ./... + go test ./... + - name: Run example workflow fixtures run: | - source_repo="$(jq -r '.source.repository' UPSTREAM.json)" - source_commit="$(jq -r '.source.commit' UPSTREAM.json)" - short="${source_commit:0:12}" - [[ "$PR_AUTHOR" == "operator-stack-publisher[bot]" ]] - [[ "$source_repo" == "operatorstack/intelligence-flow" ]] - [[ "$HEAD_BRANCH" == "sync/intelligence-flow-$short" ]] + go build -o "$RUNNER_TEMP/yskill" ./cmd/yskill + "$RUNNER_TEMP/yskill" test examples/investigate + "$RUNNER_TEMP/yskill" test examples/release-checklist + "$RUNNER_TEMP/yskill" test examples/env-doctor + "$RUNNER_TEMP/yskill" test examples/data-migration + YSKILL="$RUNNER_TEMP/yskill" "$RUNNER_TEMP/yskill" test examples/convert-skill + YSKILL="$RUNNER_TEMP/yskill" bash ./examples/library/test-all.sh diff --git a/.gitignore b/.gitignore index 8942527..cb75e09 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,8 @@ .yield/ +node_modules/ +dist/ +build/ +__pycache__/ +*.pyc target/ runs/ diff --git a/README.md b/README.md index 27249a7..ff2c04f 100644 --- a/README.md +++ b/README.md @@ -31,8 +31,8 @@ runtime. Go and Rust install the matching runtime under `.yield/bin` in the repository. Generated adapters never use a global `yskill` from `PATH`. ```bash -# TypeScript -npm install --save-exact @operatorstack/yield@0.1.29 --registry=https://get.operatorstack.systems/npm/ +# TypeScript (public npm) +npm install --save-exact @operatorstack/yield@0.1.29 npm exec -- yskill --version # Python, after creating and activating .venv @@ -192,8 +192,7 @@ Not guaranteed: that the agent performed *only* the requested operation, or that a schema-valid `agent_task` result is true — schema validity is not truth. `RunCommand` is the exception by construction: commands are executed by the Yield CLI, so exit codes and output enter the log as -observed fact. The formal analysis behind this line is in -`docs/locus-yield.md`. +observed fact. Runtime and conformance tests enforce these guarantees. ## What it is not @@ -203,6 +202,5 @@ security sandbox. --- -This repository is a one-directional projection of -`operatorstack/intelligence-flow` (`labs/22-yield`). Changes land via the -automated sync PR; do not edit files here directly. MIT licensed. +This is Yield's canonical source repository. Changes, verification, release +intent, and publishing control all live here. MIT licensed. diff --git a/UPSTREAM.json b/UPSTREAM.json deleted file mode 100644 index a678415..0000000 --- a/UPSTREAM.json +++ /dev/null @@ -1,344 +0,0 @@ -{ - "files": { - ".gitignore": "803c5f79d6da7f2c5a1dc0ce27c53b8e5c059309b165782831c4c472af058a4c", - "LICENSE": "fff261ce507eabd57666c283a621f33e183a3aedebda04c4ecbc6309a62f5edf", - "README.md": "0f700bd4f99740fd1fe1483308a37eb8afc92fc449db9c24f4bae67b68c8d8e6", - "cmd/yskill/agents.go": "8129c073b7b56ca7dcd50c5d90640ad80522c88822c629d1bdc79a386a31a8f4", - "cmd/yskill/agents_test.go": "d6202d208036be6b2b50f7d8f9c3a9b4c2b3eea9556477ef9ad4d56201c6b832", - "cmd/yskill/main.go": "5eefea8fdd3e040a940bde80aac793fb97c61c18586bd993dab0395f57e5a81f", - "cmd/yskill/main_test.go": "09e792e818a410906120225ff3d559adeccfb5288bcbbddfdf446149d5da852e", - "cmd/yskill/registry/README.md": "fab385921ee7972f76deb94a3b7ae41184735598ea4145c9d8ccdde2c2b876c4", - "cmd/yskill/registry/VERCEL_SKILLS_LICENSE": "779258e329008bdb9330e6c1daad644ff867f164d11c4cc4404350479f3e92ee", - "cmd/yskill/registry/agents.json": "6edfee31cdc0390516adbb107fc97fc3531eb02e1a28b9d62b5b86fdccaed7c1", - "cmd/yskill/scaffold.go": "a9d0572f7a139dcff478265c016c64038b03cbf9d123054e5274e3a352488e9a", - "cmd/yskill/skillmeta.go": "12b0c25689bf825d676404af7b3fb74fb92db3d9e222d4e553d8800d86aea45e", - "docs/README.md": "0b9ba72fd09a24ddc8dd708c040ba6688a57c8c03d927c054b8258ac2467cf98", - "docs/agent-plugins.md": "0882914a3316906579c3ad40a02fc28c47866bfb007307ed733787d8b0d0e846", - "docs/agent-setup.md": "72d2f7af6ca93b3865c8d7095479320127adc5edfdcce940494adf28f3abe7fc", - "docs/convert-existing-skill.md": "0dd538e908a1f2d3a1958e4b2cc1efede2a8e7a73341e32c1a75fec69a9acb8a", - "docs/examples.md": "f6ef194f1d321692873b5cf35751f369d8215084c5a754b4a6725480ab9b2e37", - "docs/locus-conformance.md": "a71fd5a72678dcad344afc71cd7a788090ef008a8e5e82d925da5a3db41af6a0", - "docs/locus-converter.md": "b8d1bdb63cb0283ace524f572fb13f0d1cb535b130c5ea3e112d2efae55a8681", - "docs/locus-yield.md": "c29d0c5801f32591828fc348385fb25c1850b39afc22770098eae0614fc3a417", - "docs/locus/convert-transcribed.json": "a43832bbaed492a45ec71e49878278950ccdf1db691908c5bcfb7d3a33c064fb", - "docs/locus/convert-verified.json": "02d96d55d4d932147d60ff31f44d835a67690afd835bd7a2056bde78db53b769", - "docs/locus/divergence-in-sdk.json": "b2ab352f3fafd6bf0e01fa2e4eb2aa15f508c0f7565a9af73edb9c3274b7b7dc", - "docs/locus/divergence-supervisor-only.json": "0fe361e7eacac8e285bf6d02bc9dc1d5604d32555eb2cfdcb945e1b2d965ca95", - "docs/locus/drv-998aecbcb0b652eeb2c966a86c871c2a187729f224435ebf9fe20e9eb7be788e.json": "ff2fab51682f58cfe22ff23ae566e359b9337d9f9cc7ee7452ed991538dfdf23", - "docs/locus/drv-ad50b13e9419f4beec8d7542352971f391515e3c17a2fbd68466d1f8a30d36a7.json": "44e5a0a589963e35cdbe91127497a9ad4adfd890238ce188a57550c1f4f2e78b", - "docs/locus/drv-db7bca98dc05ca24898e309e3d0eb89c3d812847490b9369cb006cf37625e3c6.json": "f3d25cbc8ee56b13df1083e75230b97c555c9497198d3804b858ae778dd6d471", - "docs/locus/protocol-rw.discharge.json": "166023ac8ee8abc434374a7f726c905092937e76f3f8f93d98427eb33c1b6fec", - "docs/locus/sdk-contract.json": "b717c764335c53ceee9f7b74c4bbf922389edf9221d54e4185bdea8bd94ac710", - "docs/locus/yield-diag-correlated.json": "9427e2135066d6a89999178b3c6467799153ceb155543e3d9777b39a27193c73", - "docs/locus/yield-diag-portable.json": "71f2880721196f42c82cc152c49dff6d0fd4ac71a84586c468f66442bc305051", - "docs/locus/yield-protocol.json": "82c3490000357d66bc1f35623176a9b0279800340684047d46696d2eb43677d2", - "docs/primitives/README.md": "fac74f3b860746c17d56bc55b07a2c6ddcce46d2c2cd471f237baa64b3bdeaa3", - "docs/primitives/agent-task.md": "89ec69ec7d83c4b78b8d71ee877dfc2b5cabb4fe5bee3f2ee1a524da40349b2d", - "docs/primitives/ask-user.md": "e76e59b5cb9105d1c55edb4d250162aeb4afe3aa424aee305fff476fc49fdf6e", - "docs/primitives/outcomes.md": "a584976fada6af3772894736e686f5deb466d3cc8fd1ecacf49f6b9042d6a232", - "docs/primitives/require.md": "1ea8c3a9ea11aa61e2baee01cf83fca8c872e846a47d7ef230cf6b76d04c90d8", - "docs/primitives/run-command.md": "af9bcc617f90fd2ee0086aeabb5c98854542efe81636a020699c2f688f8b3b8c", - "docs/quickstart.md": "73720df5fe910fed1f0c9abc0579ffa48423a870b556375d0eac452ea3d886e1", - "docs/reference/cli.md": "a36189229ebadf0c6b298f56b03013cb23720448bbe2f8c85297933111ef06ea", - "docs/reference/execution-model.md": "58365a7870a081f4ed9e9ba144aae77aa5a1d8676d2bbf6979483be4a06eca80", - "docs/reference/guarantees.md": "fce2006ad46a83c4ae34d221a83d68bc06a776e7c4f54d938bdcdac91977aa50", - "docs/reference/sdk-parity.md": "b8c3d6d6efad246b9212db760bb72cba7182b04da321cfd667783000ae75f733", - "docs/skill-workflows.md": "c0049f6b7db00fc45f15d649e56e381962ddf637dd5d20309a4f79801a28d80d", - "docs/testing-fixtures.md": "792d0129e072ff6718130e88b1214c53fbe1690d0da11d5aa35bc9e35da87b39", - "docs/tutorials/README.md": "f35641cab5aa9739b22a7f9c75a5fe7966b26f492879a70545c4cb6a780129b3", - "docs/tutorials/approval.md": "d0144288e12488627fce085d3053b1c9b79cc1dac2d45157c214062de3375a9c", - "docs/tutorials/bounded-debugging.md": "903b876fb13fa5bff6789c500f56c1b97c5ae1bc0059147d845a8f327d553340", - "docs/tutorials/code-review.md": "275d9be9eeb8b10c840a58cb861258803af7629a54c4379d0d0336a9e8678898", - "docs/tutorials/data-migration.md": "6699fc47cda84c4f46a3703ca4a69bcced7cc4a9df339a308e807ea3a99578bd", - "docs/tutorials/environment-repair.md": "289c9b261e3768c2c58d60d9ef7a09e85f89038438a08febb4b9c12ebada88d1", - "evals/.gitignore": "0d5020173666118bafe31c857b96aa325809f41d159ca51324ceaf239e043347", - "evals/README.md": "e8972b1f0bdc79df96f3bfdd81017462187b122221ab66c423f6d55a33e0fffd", - "evals/agent/README.md": "7936e06915bfc1ae755a9529d4a6c632a8d866b9c804e95af49a66cad6eb5038", - "evals/agent/cases.json": "98ae0ab3f099bd957739368de7bdb5b8b43997776ed6a11e406f81fd523c3130", - "evals/agent/fixtures/long/SKILL.md": "8826f89f40c17085c92d246043e3794565a230d578cc07de3b5f3c26ba661efe", - "evals/agent/fixtures/shared/.gitignore": "9a6da4f2c69a82d04438e358640bc5784d70b9e5dff9c6fdaaad62c38aa8b667", - "evals/agent/fixtures/shared/bin/record.mjs": "7def5e42bf55184c90cc8083473d283ba56bc4b1ce63ca7bc8a706862d8773a1", - "evals/agent/fixtures/shared/bin/step.mjs": "623824a2f06f9032af21a6f303e46904316e35e5630b662443d54f202fa16b30", - "evals/agent/fixtures/shared/bin/user-answer.mjs": "1e5e4d7c8690d8fffaa95081fe408cf4c9cf566573609de51f2b7048310cf7cc", - "evals/agent/fixtures/yield/SKILL.md": "71dc416eee6d23c01904694b765dc76eeaedb948ea41757044473bb9d652f78f", - "evals/agent/fixtures/yield/skills/release/main.ts": "197fa885b7e680f4d859fd091256d098799ee7a6ce2b8b323f6f24ee4e37b603", - "evals/agent/fixtures/yield/skills/release/skill.json": "5dd8e8c7532fc77aa07adc42ee212fbb48ed8ef179d1e47569eb07c9d6eb1773", - "evals/agent/scripts/run.mjs": "7df7429c897d0d1696326a0ae52e319b67926d9ccbbd40e346ba605046ac8d9a", - "evals/agent/scripts/validate.mjs": "4f31fb478919f1df400ad32f93ad4a0f9dd9a9f8e19139cbcf6aeb966133be67", - "evals/package-lock.json": "cfbd68d590e92b94233a807fd774e6667e9474096ab76e1c5cd037acfb4e3200", - "evals/package.json": "84ac7bd7d1c0d1db2233dab54754296195b267e5e907d9f6c402d0d44d569adb", - "evals/results/README.md": "65b74bfab83dfc51fc5b8a3a4824c37b722fb3a358a5dcfb217dc2af199f4801", - "evals/results/latest-agent.json": "1484174819ae29bbcffeb615036fa165518669525e6d664123f6a38ca3614b69", - "evals/results/latest.json": "6a370d1310695b0b5a104818ffc869ea292f553f5c23c667f9f3ee7c9b8d4685", - "evals/scripts/run.mjs": "17a62cd0f7fda73d84a9bfa21c9c3253ba52a4a23eece09523cfea244e3f9940", - "evals/scripts/validate.mjs": "42d51ea75f9418e45dd1797d1fe02cbc046752d3e3c37d41bc8d3a47d5865d4d", - "examples/convert-skill/SKILL.md": "e6376f34365d4ac030d316db55e91f0c606a501668099f4ecf1e27d43ec806a2", - "examples/convert-skill/fixtures/responses.json": "5b5f27b0ae5962360ac7b0e779992f430c655f352a38da37debb3505c32cd60a", - "examples/convert-skill/main.go": "d8b3ab134bb19066a1c137c0e226a071be19e8eaa7b9c8c6553622554bb03c7e", - "examples/convert-skill/skill.json": "cd9f5e46c623597dad1224735a03d1363b8a426f541bd00321752d1cf7d9b116", - "examples/data-migration/Cargo.lock": "e1bd35afbfdf0119c4accc8de657241b027c12b029f5117147349063ccb0d6c7", - "examples/data-migration/Cargo.toml": "f578e4084a0457c4027100bc99c7698c388356d8e893f9d12b8e49491fdb9705", - "examples/data-migration/SKILL.md": "da864f02e985982cfd73b4ccf2b250d53c0166cdd71adba24fac565e1182b02d", - "examples/data-migration/fixtures/responses.json": "9568d3cf9a7b0e25d562cdc77cf2b0d494dae342fcb60bb58c4dc7b502603200", - "examples/data-migration/skill.json": "e688478483ffdbac242d1d51a901bfc07a1eef098b38d54f85af2f1cce75621f", - "examples/data-migration/src/main.rs": "1cda13ca0eb9da954abbb82d1805a476d6d41d5bcf2d86cbee8ea0727c6b4295", - "examples/env-doctor/SKILL.md": "d146f3055b9baa15972582ff753f1d7085f8a50ceba1a034897c99d303ef15bd", - "examples/env-doctor/fixtures/responses.json": "1c4edc95d8c71966fe2e05b5ccfa39f73dbecef805a33a1cb60fdf60040d1691", - "examples/env-doctor/main.py": "e996ee895f8c1a3bee800d11c896e0383596e8e48a171dcc1757c3ca218db2fa", - "examples/env-doctor/skill.json": "a03efd4fe141e598a1ba57cdd14a561cc99ec2dd6f6106738c14b2f8391ddcc1", - "examples/investigate/SKILL.md": "401fc32bdfa594c8c2189723dbabf135365705281a3a75d6aee910d9126d297e", - "examples/investigate/fixtures/responses.json": "b17bde7104427926d120d14e2f989186a1834b78a0a039384f34a2847cbd787e", - "examples/investigate/main.go": "2e1a21e347791a0ecfc740f862631e7e6af6d518fb26fc4b0062d9170bcae44b", - "examples/investigate/skill.json": "cd9f5e46c623597dad1224735a03d1363b8a426f541bd00321752d1cf7d9b116", - "examples/library/README.md": "e3b87f40a42fa7fe86e882d069be5a38411a8ae1b469aa86823c5e650ad24507", - "examples/library/catalog.json": "1572538febe5f6cb610ac68df3fe5be5ee1aff1cf3e83398ab0d310d37088f82", - "examples/library/go/audit-security/SKILL.md": "3ca2a8ffdb4504854cc45879e4c8bb795fc073560c1994eaf20f3d42d00d62f1", - "examples/library/go/audit-security/fixtures/responses.json": "d738404c2e2912705de936c5948c4520ae4145bae0068d478f7689aae9aaedaa", - "examples/library/go/audit-security/skill.json": "1b5cbb34a60cb84c7cdf064458792da8889931da751e84ee74bfee6514b94269", - "examples/library/go/investigate-failure/SKILL.md": "73d7f356adee39ffac667659ff875c2e3632f1fe15a94a491e95e88d4a5ac110", - "examples/library/go/investigate-failure/fixtures/responses.json": "cd9fd2b16d636ba2098884b011f66008056439a2e34d68b1777f48010653192e", - "examples/library/go/investigate-failure/skill.json": "0ac20376f3d0bbb01b72b2f4b7d138c2098c08268553299d514c9527d99f948d", - "examples/library/go/migrate-database/SKILL.md": "1328621f6b19da12f642c379456ba24ced1827bd676bf35df1c5f616ff791575", - "examples/library/go/migrate-database/fixtures/responses.json": "e7114f5615a134e8afe151b6e9133cc601549392eae53b94a308fd3131b1d77a", - "examples/library/go/migrate-database/skill.json": "911a807870b8fb80b552ec756afc190236be9825e64cfed1c07719f4c6c0ef71", - "examples/library/go/publish-ios/SKILL.md": "1e2cd5e91ea0225793f15440b05e1cdd9f3582f7dfe6ea6346762ccd4ef73ad0", - "examples/library/go/publish-ios/fixtures/responses.json": "76721fc014a01ce76a30c804743be83af2299469a3640e6df095971214d2c2a3", - "examples/library/go/publish-ios/skill.json": "9220341bf4be4cca80c3a71ecc6da492ee4ee50011fd2351b768afa05e1b2c75", - "examples/library/go/qa-web-change/SKILL.md": "c04d21e12b3f05ccf20493088d4546d135b38196c43832a4d75773b6b465e2a4", - "examples/library/go/qa-web-change/fixtures/responses.json": "d12ea67b9fde2e179f7a1d4e64f3d341c64c230fbfb61b70bfbe9fc1c2ee2269", - "examples/library/go/qa-web-change/skill.json": "74b4a1490d997ee73d4b2fa3f4b7c38d531d9bb9f29ad566be819ecc7c2b8ea5", - "examples/library/go/release-package/SKILL.md": "c4666ba653113ee812a965960f3b591f9b316a97afaf5a1f80e70218e2bfcf3a", - "examples/library/go/release-package/fixtures/responses.json": "7aeb44594f14bd110dcfbe938d4efb0d71a4dc310646a7aaf03f5713574767da", - "examples/library/go/release-package/skill.json": "a5ad7688e3a9d3760ba0eb4306e23c998748dd7c9224b00ef3cef56ecd4f0fd4", - "examples/library/go/repair-ci/SKILL.md": "eb61f59ada1e1a4a591d87a4b80e921f274dea4fb8ff5657942e129f243f1820", - "examples/library/go/repair-ci/fixtures/responses.json": "b9cae86c313eb64033c04082ec40c98d5888ebd996391728373d03856cc90b10", - "examples/library/go/repair-ci/skill.json": "1991c9926e13371e713c63d6dfce28f6c290d37b6cb2c9ede10bcb0376155120", - "examples/library/go/review-branch/SKILL.md": "722716de93a060dde3453c05804a1c4d3b66af18e76c24f15fd0738510ee735b", - "examples/library/go/review-branch/fixtures/responses.json": "9de268b5b0f8ed4bc88901d8bdbd14cc5ff61a93ef01e26f28fae815fda45fac", - "examples/library/go/review-branch/skill.json": "9208838fdc88dec59a3ea02deb8151ea24439e5a2d9950d6ca0bfdd7e92dcbb7", - "examples/library/go/src/audit-security/main.go": "ebb7d56f941e7405c492e681027b198ce0d9f91ec8372ce9010ae2179ef2ced1", - "examples/library/go/src/investigate-failure/main.go": "7dc17697a7e6fbc77534fcc71f33dd9ff05d16268eca2f92f46d6b8a7421c1cb", - "examples/library/go/src/migrate-database/main.go": "f58de18f95e904ea156e3daddd38003340752c43de8b00f2c8b0cb0bfc4ad594", - "examples/library/go/src/publish-ios/main.go": "c60ede26985e5b81cc24ef78ca5a9c20dc90a62fd20bb4af366749d12101880d", - "examples/library/go/src/qa-web-change/main.go": "eb450d2b89668cde5c0d0d280ed1d367fa09eaf71a4eb150889f14ff750b77ca", - "examples/library/go/src/release-package/main.go": "2c02a99d03fe8c1211a2ec8f0fa000c14c880f0cc72bddfce272890e255501fd", - "examples/library/go/src/repair-ci/main.go": "2f837aeecc34d71f1d5af17926db2712368aac80f8a668562a02156fd3950fbd", - "examples/library/go/src/review-branch/main.go": "8776396cee5b3651f38306a1815a2570dda7f02f6d0edd8c681f4ad41f0d5b2b", - "examples/library/go/src/triage-issue/main.go": "8fe3933d2454e8272ca0dcd11b8283e33c355dd32c453d8a99ca3135502af6f4", - "examples/library/go/src/upgrade-dependency/main.go": "d5d25e271ce68efdff70b295d149d51e6e0dbc41f1f27825afacf90108d4632d", - "examples/library/go/triage-issue/SKILL.md": "a3a0c383196cd981e64c1fd311e608cb50facfe55409981d4f92d28a4b346862", - "examples/library/go/triage-issue/fixtures/responses.json": "68f36fb5a7723a5d2a5477bed3e8a245908e6157a7eeb9205a604a05c9e3998f", - "examples/library/go/triage-issue/skill.json": "7117c9c44ebc29cfa4c667da3787504ee20c14a09251f111ed4c55b43a6d6a21", - "examples/library/go/upgrade-dependency/SKILL.md": "11b6b4258640ff60af1446b97d907ea15d819a714de2736eda16621f5adbf186", - "examples/library/go/upgrade-dependency/fixtures/responses.json": "17eeef53bb7a4cc9ad70f0b24d50305db8266b4edb8c911570da7141830f2b9d", - "examples/library/go/upgrade-dependency/skill.json": "100c63e44dcc21ff657c4bf03f4779ff941e672bfd6f4942ba649f9a0cf11910", - "examples/library/python/audit-security/SKILL.md": "3ca2a8ffdb4504854cc45879e4c8bb795fc073560c1994eaf20f3d42d00d62f1", - "examples/library/python/audit-security/fixtures/responses.json": "d738404c2e2912705de936c5948c4520ae4145bae0068d478f7689aae9aaedaa", - "examples/library/python/audit-security/skill.json": "51c7cc438336c781bd9860d516ba81a77d11baa428b18a92ca715da036b0bdd0", - "examples/library/python/investigate-failure/SKILL.md": "73d7f356adee39ffac667659ff875c2e3632f1fe15a94a491e95e88d4a5ac110", - "examples/library/python/investigate-failure/fixtures/responses.json": "cd9fd2b16d636ba2098884b011f66008056439a2e34d68b1777f48010653192e", - "examples/library/python/investigate-failure/skill.json": "85cc911cd12eb5a0be3a13f803b9415371f5b9dcc6317b0b153ffcf23cce06e2", - "examples/library/python/migrate-database/SKILL.md": "1328621f6b19da12f642c379456ba24ced1827bd676bf35df1c5f616ff791575", - "examples/library/python/migrate-database/fixtures/responses.json": "e7114f5615a134e8afe151b6e9133cc601549392eae53b94a308fd3131b1d77a", - "examples/library/python/migrate-database/skill.json": "f3182e640a0a348ac5624450124a05616494dfd211dce95a80d8120b98e9f8d2", - "examples/library/python/publish-ios/SKILL.md": "1e2cd5e91ea0225793f15440b05e1cdd9f3582f7dfe6ea6346762ccd4ef73ad0", - "examples/library/python/publish-ios/fixtures/responses.json": "76721fc014a01ce76a30c804743be83af2299469a3640e6df095971214d2c2a3", - "examples/library/python/publish-ios/skill.json": "7e136a98c30fb38195f649033e5a84fc1409ba940004ad890cfbe25fa5694c16", - "examples/library/python/qa-web-change/SKILL.md": "c04d21e12b3f05ccf20493088d4546d135b38196c43832a4d75773b6b465e2a4", - "examples/library/python/qa-web-change/fixtures/responses.json": "d12ea67b9fde2e179f7a1d4e64f3d341c64c230fbfb61b70bfbe9fc1c2ee2269", - "examples/library/python/qa-web-change/skill.json": "735e69a1c02cbccba78f1b346e1043bc8cc186ae8ee2d68c491da5e069160354", - "examples/library/python/release-package/SKILL.md": "c4666ba653113ee812a965960f3b591f9b316a97afaf5a1f80e70218e2bfcf3a", - "examples/library/python/release-package/fixtures/responses.json": "7aeb44594f14bd110dcfbe938d4efb0d71a4dc310646a7aaf03f5713574767da", - "examples/library/python/release-package/skill.json": "7210b06a2de9e282e8cde3b48dd37e46ea3e56936ce8f2a79e479a7e1e41327d", - "examples/library/python/repair-ci/SKILL.md": "eb61f59ada1e1a4a591d87a4b80e921f274dea4fb8ff5657942e129f243f1820", - "examples/library/python/repair-ci/fixtures/responses.json": "b9cae86c313eb64033c04082ec40c98d5888ebd996391728373d03856cc90b10", - "examples/library/python/repair-ci/skill.json": "ceb25fca2a9496a4a71bd48186fbc569f899ed63724f5ff9142673f21ad2722c", - "examples/library/python/review-branch/SKILL.md": "722716de93a060dde3453c05804a1c4d3b66af18e76c24f15fd0738510ee735b", - "examples/library/python/review-branch/fixtures/responses.json": "9de268b5b0f8ed4bc88901d8bdbd14cc5ff61a93ef01e26f28fae815fda45fac", - "examples/library/python/review-branch/skill.json": "939cb32c9b989f076230d9d1a710a0257dc2eadee9ea27bbfe5aa5c6aa8130f5", - "examples/library/python/src/audit-security.py": "e1cdb9f0e1d3c757f3fc3495c14448f758d905ec8b4c125fa327e23900a38ba3", - "examples/library/python/src/investigate-failure.py": "114b6633554a8988e2a4416f7dc640ab49bb03a4e1953488947319ce383b5c04", - "examples/library/python/src/migrate-database.py": "ebbc5b4a2f8b76f07c949e223d5f29b3b708b8d30003129c103a9c00e3b3fc65", - "examples/library/python/src/publish-ios.py": "633546d28be9e0199cece3707aa5cb431882ba1913513363506a734e75d094d8", - "examples/library/python/src/qa-web-change.py": "8f686f45f5051c2eddb944dc86b3dfb2173d914fff25cc0454f7ef371cdc8b6c", - "examples/library/python/src/release-package.py": "70f78d446ca181ff44634d3c24b2eebcd450dbf1a7f3a18ada01898ec5f6e1a7", - "examples/library/python/src/repair-ci.py": "14e11ee64ca4c9061bd3bd1276fd9bbaa7ed210340711a22db15f02eec3621ec", - "examples/library/python/src/review-branch.py": "1115802d72543bf6785ade4404eaefec4582a5dad36b9cf751eddf0f02497475", - "examples/library/python/src/triage-issue.py": "8a2493ca56c310044cdc7643c410c759980de7296d639f635de106d5befa8874", - "examples/library/python/src/upgrade-dependency.py": "7201cb69871cdb1d5db9e3dc17da114c437e280fd8d04dcdc5df1ab3de68778c", - "examples/library/python/triage-issue/SKILL.md": "a3a0c383196cd981e64c1fd311e608cb50facfe55409981d4f92d28a4b346862", - "examples/library/python/triage-issue/fixtures/responses.json": "68f36fb5a7723a5d2a5477bed3e8a245908e6157a7eeb9205a604a05c9e3998f", - "examples/library/python/triage-issue/skill.json": "1fda27424f8bf5e98f692610168c72a716b8e1ef27bf9fe6002261464d7af8af", - "examples/library/python/upgrade-dependency/SKILL.md": "11b6b4258640ff60af1446b97d907ea15d819a714de2736eda16621f5adbf186", - "examples/library/python/upgrade-dependency/fixtures/responses.json": "17eeef53bb7a4cc9ad70f0b24d50305db8266b4edb8c911570da7141830f2b9d", - "examples/library/python/upgrade-dependency/skill.json": "8c330daaf4e1ed49e41ae2765735de0bb7e44e19f384ac8a11b39fe3e179d875", - "examples/library/rust/Cargo.lock": "1d053562f99eebfef5bba6897ae3714f699d3f0e262220d49572be112ff8669e", - "examples/library/rust/Cargo.toml": "126a839a0a41841aff8689b6c6e62a75f81387866714f4fe7d3fbbcb809af21f", - "examples/library/rust/audit-security/SKILL.md": "3ca2a8ffdb4504854cc45879e4c8bb795fc073560c1994eaf20f3d42d00d62f1", - "examples/library/rust/audit-security/fixtures/responses.json": "d738404c2e2912705de936c5948c4520ae4145bae0068d478f7689aae9aaedaa", - "examples/library/rust/audit-security/skill.json": "efa98ccee6993b0b33467bffe6f0e3b1f26dc142c8947d4780d22bd2874c5b0a", - "examples/library/rust/investigate-failure/SKILL.md": "73d7f356adee39ffac667659ff875c2e3632f1fe15a94a491e95e88d4a5ac110", - "examples/library/rust/investigate-failure/fixtures/responses.json": "cd9fd2b16d636ba2098884b011f66008056439a2e34d68b1777f48010653192e", - "examples/library/rust/investigate-failure/skill.json": "9299c81fc070c90c20af83f98a73cce569a232c417f34c36c56e724057f12b28", - "examples/library/rust/migrate-database/SKILL.md": "1328621f6b19da12f642c379456ba24ced1827bd676bf35df1c5f616ff791575", - "examples/library/rust/migrate-database/fixtures/responses.json": "e7114f5615a134e8afe151b6e9133cc601549392eae53b94a308fd3131b1d77a", - "examples/library/rust/migrate-database/skill.json": "73625614cc4f7e5f75ef9663bdb65453d898f834c2d100b4fd4514207fed759c", - "examples/library/rust/publish-ios/SKILL.md": "1e2cd5e91ea0225793f15440b05e1cdd9f3582f7dfe6ea6346762ccd4ef73ad0", - "examples/library/rust/publish-ios/fixtures/responses.json": "76721fc014a01ce76a30c804743be83af2299469a3640e6df095971214d2c2a3", - "examples/library/rust/publish-ios/skill.json": "b28e948368e0bef179cd51576e579904d85c9b6cad20959be98f69838b025be8", - "examples/library/rust/qa-web-change/SKILL.md": "c04d21e12b3f05ccf20493088d4546d135b38196c43832a4d75773b6b465e2a4", - "examples/library/rust/qa-web-change/fixtures/responses.json": "d12ea67b9fde2e179f7a1d4e64f3d341c64c230fbfb61b70bfbe9fc1c2ee2269", - "examples/library/rust/qa-web-change/skill.json": "d486777fc1553aae3dc42f3138767b99801bf9f08f62609da7e2a9d1d86cb8eb", - "examples/library/rust/release-package/SKILL.md": "c4666ba653113ee812a965960f3b591f9b316a97afaf5a1f80e70218e2bfcf3a", - "examples/library/rust/release-package/fixtures/responses.json": "7aeb44594f14bd110dcfbe938d4efb0d71a4dc310646a7aaf03f5713574767da", - "examples/library/rust/release-package/skill.json": "2590d1d4eb21809550ab1edca585e673699bef25b202ecfb613636689f5002d8", - "examples/library/rust/repair-ci/SKILL.md": "eb61f59ada1e1a4a591d87a4b80e921f274dea4fb8ff5657942e129f243f1820", - "examples/library/rust/repair-ci/fixtures/responses.json": "b9cae86c313eb64033c04082ec40c98d5888ebd996391728373d03856cc90b10", - "examples/library/rust/repair-ci/skill.json": "f89672490d25b54db95d55a0ad94d7cfbe1a72be2a8db22960a4a73b08e7af65", - "examples/library/rust/review-branch/SKILL.md": "722716de93a060dde3453c05804a1c4d3b66af18e76c24f15fd0738510ee735b", - "examples/library/rust/review-branch/fixtures/responses.json": "9de268b5b0f8ed4bc88901d8bdbd14cc5ff61a93ef01e26f28fae815fda45fac", - "examples/library/rust/review-branch/skill.json": "78923df686bb2a58183fb61a60872e648b1ac3112d5b8d526ac3bae9394cbcdc", - "examples/library/rust/src/bin/audit-security.rs": "682ab83b4a4d851c51b7577e56d0fb290185d25c247042db0d308c9b5a9ab277", - "examples/library/rust/src/bin/investigate-failure.rs": "9e272dc5f0d246d8a47a6782d2c4627f0fb8fb86641facc8b892e88e92a62f60", - "examples/library/rust/src/bin/migrate-database.rs": "64c5eae4a7658d7c4cbe02a6d74cd7c175dc84cf27f43e4658528ddac0b26cf5", - "examples/library/rust/src/bin/publish-ios.rs": "550a6c8ed6e18fcb49bfd4bf8e02e9883ab80bf0e25f8d8b312e22b011574851", - "examples/library/rust/src/bin/qa-web-change.rs": "631529c48cdd3ef62311a1984cf0bea711ada19c3167a2464032e50548148525", - "examples/library/rust/src/bin/release-package.rs": "5165a7798e0a12f04ecdbc23f4c5bda70886704298f743b3e26528ebb60e8fc4", - "examples/library/rust/src/bin/repair-ci.rs": "c6b762e06281b2ff0dd63e882c147045cacca71617174ac869e83c063c1ac6ac", - "examples/library/rust/src/bin/review-branch.rs": "c2a883876c5ce90045054f3b0d3ada5f882bbdcd397b6dfca5e508004f4476df", - "examples/library/rust/src/bin/triage-issue.rs": "1d06a0ba96f914300690731ea81a7371e73ebb2a9f25f80f8433718ee234711e", - "examples/library/rust/src/bin/upgrade-dependency.rs": "892d7dbfa430a032b1396b96d05b68c5b03aafe5d30a38a661846ad0a13427a7", - "examples/library/rust/triage-issue/SKILL.md": "a3a0c383196cd981e64c1fd311e608cb50facfe55409981d4f92d28a4b346862", - "examples/library/rust/triage-issue/fixtures/responses.json": "68f36fb5a7723a5d2a5477bed3e8a245908e6157a7eeb9205a604a05c9e3998f", - "examples/library/rust/triage-issue/skill.json": "f5ea171a771755f8a73a99e054494ab65e7aabe0730c3aeee5c4d7abfd329462", - "examples/library/rust/upgrade-dependency/SKILL.md": "11b6b4258640ff60af1446b97d907ea15d819a714de2736eda16621f5adbf186", - "examples/library/rust/upgrade-dependency/fixtures/responses.json": "17eeef53bb7a4cc9ad70f0b24d50305db8266b4edb8c911570da7141830f2b9d", - "examples/library/rust/upgrade-dependency/skill.json": "4d1a107ed7fb56c1ff125d13cc5d755d0faaaf33334a76d3a4f478c157209bff", - "examples/library/scripts/generate.mjs": "76df7c0bacd3f60345acbfa46d193abf19b2a4431d9c4857667183cedc0c48ce", - "examples/library/test-all.sh": "62ff63221fd6cfa87e31ec3145016410746ddc78e6210140d5c0217d8e1b838f", - "examples/library/typescript/audit-security/SKILL.md": "3ca2a8ffdb4504854cc45879e4c8bb795fc073560c1994eaf20f3d42d00d62f1", - "examples/library/typescript/audit-security/fixtures/responses.json": "d738404c2e2912705de936c5948c4520ae4145bae0068d478f7689aae9aaedaa", - "examples/library/typescript/audit-security/skill.json": "0fa2cb55ef17a4feab8594f686c0c8ee156e0e942968b3cd32023263066b6c1c", - "examples/library/typescript/investigate-failure/SKILL.md": "73d7f356adee39ffac667659ff875c2e3632f1fe15a94a491e95e88d4a5ac110", - "examples/library/typescript/investigate-failure/fixtures/responses.json": "cd9fd2b16d636ba2098884b011f66008056439a2e34d68b1777f48010653192e", - "examples/library/typescript/investigate-failure/skill.json": "8851fd3bfed8ade55a66a2352d5cb99254257fb2a2f9ffc22b49b50e336ee942", - "examples/library/typescript/migrate-database/SKILL.md": "1328621f6b19da12f642c379456ba24ced1827bd676bf35df1c5f616ff791575", - "examples/library/typescript/migrate-database/fixtures/responses.json": "e7114f5615a134e8afe151b6e9133cc601549392eae53b94a308fd3131b1d77a", - "examples/library/typescript/migrate-database/skill.json": "c958b5017fcb30e41b6cfbc3b919bc3db7fe02f4a398efa4b515031a2ded8d4b", - "examples/library/typescript/publish-ios/SKILL.md": "1e2cd5e91ea0225793f15440b05e1cdd9f3582f7dfe6ea6346762ccd4ef73ad0", - "examples/library/typescript/publish-ios/fixtures/responses.json": "76721fc014a01ce76a30c804743be83af2299469a3640e6df095971214d2c2a3", - "examples/library/typescript/publish-ios/skill.json": "28c597f6ac349d895e48635e4c813df864ca453a46aae1eaf01c5fe1b25203dc", - "examples/library/typescript/qa-web-change/SKILL.md": "c04d21e12b3f05ccf20493088d4546d135b38196c43832a4d75773b6b465e2a4", - "examples/library/typescript/qa-web-change/fixtures/responses.json": "d12ea67b9fde2e179f7a1d4e64f3d341c64c230fbfb61b70bfbe9fc1c2ee2269", - "examples/library/typescript/qa-web-change/skill.json": "6d552f2acce18d0b299d145984e221ca78242fbd563ac55980ee9eea5f2b3234", - "examples/library/typescript/release-package/SKILL.md": "c4666ba653113ee812a965960f3b591f9b316a97afaf5a1f80e70218e2bfcf3a", - "examples/library/typescript/release-package/fixtures/responses.json": "7aeb44594f14bd110dcfbe938d4efb0d71a4dc310646a7aaf03f5713574767da", - "examples/library/typescript/release-package/skill.json": "1bfb727e1d39e2b697f540055a343047be147952c0895aafd5aea110683c00ee", - "examples/library/typescript/repair-ci/SKILL.md": "eb61f59ada1e1a4a591d87a4b80e921f274dea4fb8ff5657942e129f243f1820", - "examples/library/typescript/repair-ci/fixtures/responses.json": "b9cae86c313eb64033c04082ec40c98d5888ebd996391728373d03856cc90b10", - "examples/library/typescript/repair-ci/skill.json": "e07ffae450c07e1ba63704c0805cd3e93814aa9e0815174f399981f61f6fd4bb", - "examples/library/typescript/review-branch/SKILL.md": "722716de93a060dde3453c05804a1c4d3b66af18e76c24f15fd0738510ee735b", - "examples/library/typescript/review-branch/fixtures/responses.json": "9de268b5b0f8ed4bc88901d8bdbd14cc5ff61a93ef01e26f28fae815fda45fac", - "examples/library/typescript/review-branch/skill.json": "80cab01cbdc3ed907ce53e44cc50e0cf2eb14a98b13052a4a53df55214f2fea2", - "examples/library/typescript/src/audit-security.ts": "2d82b50c698417597da913b1a67c0dbb56f0df80f2b346b709843102e521dbd5", - "examples/library/typescript/src/investigate-failure.ts": "bad0351af6d7e6b3f73c62b909d43ccb009b87320bfd1de1d2dc87900dd04d80", - "examples/library/typescript/src/migrate-database.ts": "ab3cabcfaa3a9a76b00b3ed6d3cbf6ca66e82f3d6ac4b333f8a5cf05d510f523", - "examples/library/typescript/src/publish-ios.ts": "abb54cbd93eba824e0607e4dc6af011814c861552f730fe23454b0e213557b05", - "examples/library/typescript/src/qa-web-change.ts": "283cbafc0c927107ab2890c910a0e3ca74a279190c53704e998f7ff9186915be", - "examples/library/typescript/src/release-package.ts": "df597fc0d8caf0fa929f4fed40a6034a496ffda2553cd056b1dd3a86bbc6b911", - "examples/library/typescript/src/repair-ci.ts": "de80b06dd4fc4c4fd3c36b09f7c7befcf1162508217f6e89f3770bc9264aaf60", - "examples/library/typescript/src/review-branch.ts": "4187f5de85c0dedc960dc1b0f206f655665148c9c7f7c75903df351b8653b53f", - "examples/library/typescript/src/triage-issue.ts": "8ba27b1dfc37086b329d6c0084ef2ac0a7e2fbfbc1fd5e1a870f67684bdb682a", - "examples/library/typescript/src/upgrade-dependency.ts": "fc499ea33ae71a9500c1c376b128696ecd6584f5f62e6602c9b6eaf26b619c72", - "examples/library/typescript/triage-issue/SKILL.md": "a3a0c383196cd981e64c1fd311e608cb50facfe55409981d4f92d28a4b346862", - "examples/library/typescript/triage-issue/fixtures/responses.json": "68f36fb5a7723a5d2a5477bed3e8a245908e6157a7eeb9205a604a05c9e3998f", - "examples/library/typescript/triage-issue/skill.json": "00fcf1ea7c0e0c91db7b8cb8677386ad38d7f1645aa8513feb89c713695d07f3", - "examples/library/typescript/upgrade-dependency/SKILL.md": "11b6b4258640ff60af1446b97d907ea15d819a714de2736eda16621f5adbf186", - "examples/library/typescript/upgrade-dependency/fixtures/responses.json": "17eeef53bb7a4cc9ad70f0b24d50305db8266b4edb8c911570da7141830f2b9d", - "examples/library/typescript/upgrade-dependency/skill.json": "7daf6a73c8bd25a030d71d4d545c864b43d2522ccccb9f23659329ef8a871aad", - "examples/release-checklist/SKILL.md": "cd9daf69e3cd347e0db46315267103884a6ccb22735901554d59b3f4aed7cf7a", - "examples/release-checklist/fixtures/responses.json": "9545c4795a5f0676e4b84303cc76911a701f1add94c3034f3c9a0695b2ec5a22", - "examples/release-checklist/main.ts": "c9a5c695835b0527378e1fe3aa69619b94ac7994c6456e1dec1ff0e5c5a74cec", - "examples/release-checklist/skill.json": "854fcb4bfd3254208233baf11d2762fddd4064ef55d641916a8b02f52612d18d", - "go.mod": "8e0a98ce35395a77a04190655556f3f9c19e13dcad31ed061d114435ad5e38f3", - "go.sum": "fc6d8a3de7b2f1ef51759974e48940328d8c10951833bcf4d6309daba3110b98", - "internal/conformance/conformance_test.go": "8dd828b3df9a4b0f6cd47a16db40619346a1476c1a85ee62950689d32e892603", - "internal/conformance/testdata/skill-go/main.go": "43631848a4d10f1e6faa555c288c38688ced70ccbf02219d3918367c708f4a24", - "internal/conformance/testdata/skill-py/main.py": "f34b3315491d0725bce17e8d77cd0b8eb218d2896b51d8c10a660dc658f1cc24", - "internal/conformance/testdata/skill-py/skill.json": "5207b98487b29a9914f3621d40daf8da3d1626a90a8fc0173ca0c7ee114b9764", - "internal/conformance/testdata/skill-rs/Cargo.lock": "69aa4e64c45fdc25526b1661e4964de1202afa70893689a02d5f558e3019492d", - "internal/conformance/testdata/skill-rs/Cargo.toml": "2f5dfff19c81065df7074bcab444e931509709f9c91b638a277fb6d1c0f02bf0", - "internal/conformance/testdata/skill-rs/skill.json": "4ae73a29cbaf4eab7561620b2e8e7d76e4f7d45e748f550e2b98c5198217af59", - "internal/conformance/testdata/skill-rs/src/main.rs": "b3101d7c1f7835cb0b22a2be8cfbfb1d8aee8a05e11b6dd11ffcabeeb3b8ccac", - "internal/conformance/testdata/skill-ts/main.ts": "621549e23e3f2d2fc07d6796a9b27676509e013c41517c2ea86bd41431dca28b", - "internal/conformance/testdata/skill-ts/skill.json": "90fe9e0312e05651ed176c27bfdc73dd7fb9989be9dd024fd46444b402750528", - "internal/engine/engine.go": "bcb7de4f68fd822b7c7a08c3e30b4feb51ad8d99f10f16c4c0afa165cb6c5905", - "internal/engine/engine_test.go": "45c4f37d8adf71fcd273eda6fcafc3a4404d4bd4781d110fa78d6907dd9b6590", - "internal/engine/testdata/skill-basic/main.go": "b2c0a732a29db321f3cfd5bf4a890893cfd06904ad159aaccf5c852286f2cd46", - "internal/engine/testdata/skill-envbranch/main.go": "7a41ffab373e7acc7754abb4c3c251a7f2c3ca594051a1b0a4860c2592f23b32", - "internal/engine/testdata/skill-reqfail/main.go": "163ad3c842b8a8f88e843e408b3ef701cea82933c8d48dd948b914c3f7e97f7b", - "internal/guard/guard.go": "2858211dc9f1c89b6b94510a110093aa316f7e3ed8752987718fad7bc67f9074", - "internal/guard/guard_test.go": "8e0ed25898e4c9892fe1f6fd0bdc3bdfae9ff9382c9ae436a99bdc2b90855dcf", - "internal/protocol/ir_test.go": "b8c0166fe5b4f5ab8b699df31368b37680a313b9da2dfdd25a7a46db8a23ca1a", - "internal/protocol/protocol.go": "27624f58e8194c3d08a2f94aacf3faedcc7bf7ae32adbccb197a9d2b0d9f2b2f", - "internal/protocol/protocol_test.go": "c26deb3486b62f29fff21dd83fcbc71696ee894168b92a545813721e6c0fe4f4", - "internal/runlog/runlog.go": "eedce24e718e37f018c0d7188c697ff12e80f9f440a97bd15f8bc18fd411ce11", - "internal/runlog/runlog_test.go": "35fc0478d9e50f6c474c0826beb8ca6c4d0ce7ef09b5d9239ce2bb46117539ec", - "ir/README.md": "26ec1d5e211e4d45da963dce44ec184341a4ef23b870f0c1e00134b642508e36", - "ir/yield.v1/journal.schema.json": "67fc5dd79d5a1642b01eb949c0a296fd98a38fbc3929742aed895c4d84fb44c0", - "ir/yield.v1/program-output.schema.json": "6b80f6a267cfeea3429cd95485195df037176726ff999e0d94bd20e07600051c", - "ir/yield.v1/request-envelope.schema.json": "2d5f34b04638450f1bd87ec1305ba7ecf0de2ec0ef6948365e6f46c2f2ee1c35", - "ir/yield.v1/response-envelope.schema.json": "698fc20510bf1362cac17f332b8ec4b4dd336d2bee4294b1949ed3257b535639", - "packaging/README.md": "57580fa789c4d61d7946722fc031ca885d982a116d00c403c7978700914dbbed", - "packaging/assemble.mjs": "295e0fa5adc9898cf64ff554524329dedcfe43843804b260173f34a778f3e5ab", - "packaging/cargo-index.mjs": "3c8845ab1b82a568c076229831580d8f3ad684dc6ccb74f4860d69637eb06735", - "packaging/cargo-index.test.mjs": "62a986e7f98d83007bd4b0ca14ed0e613c8ec4e240656da5af23521d7b69653c", - "packaging/rust-launcher.rs": "cc71e9ab4e471d593f7eaf818a3b9f62b599bc2e846d9c632c8aae4da69c17e8", - "packaging/rust-launcher.test.mjs": "27c04d2aa6b98ef14b507264ce1d215aa6421a8f3ce4a64110f1347c9a9e60d5", - "packaging/targets.mjs": "354e0700cf1c4f1a864e5eaa0fe951717559a381d50ad6e6c4f491449aeb526a", - "packaging/verify-registry-history.mjs": "ba43a9aeb6e80fe23ace41f23623f6d1526369e87489bd5b834991348ba80a6c", - "packaging/verify-registry-history.test.mjs": "c7a0b6a41aa8bdf9b2d2d486c40d14cc3224de7225dea3f6b48e66747e4496fa", - "release-notes/2026-08-01-agent-workflow-evaluation.md": "61fe8b5f893d21dac9dba9fa759818637c81ce2cd844571274e50f763ac72d00", - "release-notes/2026-08-01-docs-and-typescript-package.md": "93382375cb47187092aff9447b280853151c738b140879828c74576a109195b8", - "release-notes/2026-08-01-evaluation-case-guides.md": "570bc996eb4d2892456a02d938fb6299d106c431bb842ce726db1df550f779d7", - "release-notes/2026-08-01-evaluation-surface.md": "64fb5e2fdad3ccd41967e028cf4675c45939174000281c443f4b28d96dc07549", - "release-notes/2026-08-01-example-library.md": "14d6ca40529a6aeeb72872295e57bb0d7dcc7824df31e029e497602060ce4c97", - "release-notes/2026-08-01-first-party-evaluations.md": "9e74c48112343c409a88358138db80d731004f87900f1b23073f16c415163fcf", - "release-notes/2026-08-01-go-scaffold-first-run.md": "3852e7e4eb4289b0de21ed93c96bd217753ecc40b5afd8bcb865f99fa32991c7", - "release-notes/2026-08-01-initial-projection.md": "d38f0832b5552fb97237b30d19bb63369442ddde69e678b752ac07eedeb7ba3d", - "release-notes/2026-08-01-multi-language-and-converter.md": "d0cf62d191e6a58e827f3b35d442f88b83be4dde98aa25ad54e4ae3ff787a453", - "release-notes/2026-08-01-one-package-per-language.md": "6d0d55b4fdcef20332e98c34c1c42c8564aeeeac84647e9f76005b6842d0c91c", - "release-notes/2026-08-01-remove-stray-analysis-traces.md": "0567f78ee97ffd23b3f26b5c39606e9ff6659c50a3fdef04ed9b3aa86cfa99af", - "release-notes/2026-08-02-cross-agent-registration.md": "8f4296fae36468bda08370bad8d13b7fc1e893b682f8c73015311ab01ace853f", - "release-notes/2026-08-02-dx-hardening.md": "801d85ad760545140415000a95cbd6a681c32462f0578c1ac1ce802893bee303", - "release-notes/2026-08-02-final-dx-pass.md": "40c451db6ed72c0f0042b1184edb1dfb32a57076c453213326a43c5adf005f95", - "release-notes/2026-08-02-go-sdk-pin-detection.md": "d835d0a9efebba16ab782a7b5e8730a873545b395e644b6e7b21cf93bed7d1a4", - "release-notes/2026-08-02-skill-workflows.md": "8cd0cded1922387ef8e81b3e084c12e440f729aa778672f9ec91ffa153df5297", - "release-notes/2026-08-02-v0-1-23-dx.md": "538aaf62beeb15e132cfde35f47217edce7d1e4ef5c4036fd00ed96f8362b2b7", - "release-notes/2026-08-02-v0-1-26-dx.md": "b3fafa640e8969351dfb4897686594b2144f3d3609f82dbee4871279ada54735", - "release-notes/2026-08-07-public-developer-preview.md": "71df9abd9f58f34b28d67b356d918a0ae068cec04cfe504c3e9d67680a50191a", - "sdk/python/README.md": "e4fa279310fb7572f84c62735caf0ec2c414b58c13ec222209ca41284b0986e2", - "sdk/python/pyproject.toml": "0a36d0a22a29da6b8c42e3a5a91aed1b6f6d0813712a9e582ab08e8ce4290de6", - "sdk/python/test_cli.py": "829778867cb18d1be6a8737cd9b9ef51077aad84f30d32bcd80fd83b2b1469a6", - "sdk/python/yieldskill/__init__.py": "c43dbb2a25ed7e8537521561a16e2e5fc7921d60f913b22ac298255bd44fe60e", - "sdk/python/yieldskill/__main__.py": "2f2978db2ba5bf8034466902e0c0f5fa61d0961b262d776598ba0d9bb47d6b62", - "sdk/python/yieldskill/_cli.py": "3a3caa9008a4bf366bccbbea5d1c22ec86f7d48bc56cdf9c9e28e9ffa9e921a3", - "sdk/rust/Cargo.toml": "da29a554401a316f6a0e7ba53d166f4c3741ac9aefe1e3f2d66af1bfa3a2d88a", - "sdk/rust/src/lib.rs": "581882dca50cf4e27a8f2e05b013b2bc091802b6a20d89d58ffbcdf5c23372a7", - "sdk/typescript/bin/runtime.mjs": "909da102e8ed8ccc917cd17d88acc65869a0a2bdb6f875f76d763383999a2b57", - "sdk/typescript/bin/runtime.test.mjs": "db9c2dc1054d7f03139d69d3ffdb1e6fe5b65a71f4bdcca50fdefb2562831a2b", - "sdk/typescript/bin/yskill.mjs": "4ac8b13afc26fdc5b9192e6443dc121b83c7abfb9a4b80768f8344b8faaa4197", - "sdk/typescript/package.json": "b8805c31ce1bbf4b063efa5f69cfad8e1b0ec402607d7afceea6398057d95a6e", - "sdk/typescript/scripts/build.mjs": "1ba086bbdddb61226f3b6363e1fda0ffdd129ce90ea9da28ba71ecfb0f478e6d", - "sdk/typescript/src/index.ts": "bc91d43b8f6698a3139fd482077942a22beab950db74164d94422ecb38631a0b", - "sdk/yield/public_api_test.go": "30a94201355001d9fec04bd7d05c5745880cc5b8cf381301a3388c48a2dc0f3c", - "sdk/yield/yield.go": "0fde5e1370e7292f855087245690c36db76b85a675789b1a5864e8b3f489fd30" - }, - "generator": "operatorstack/yield:project", - "schema_version": 1, - "source": { - "commit": "cff8743e281219a397e78d6207ef5f0b8a46eb8c", - "path": "labs/22-yield", - "repository": "operatorstack/intelligence-flow" - } -} diff --git a/docs/convert-existing-skill.md b/docs/convert-existing-skill.md index 7027351..47fa094 100644 --- a/docs/convert-existing-skill.md +++ b/docs/convert-existing-skill.md @@ -61,6 +61,4 @@ Review the conversion as a policy change: - replay a completed run to check determinism; - keep performance or token-reduction claims separate from runtime correctness. -The implemented safety comparison is documented in -[`locus-converter.md`](locus-converter.md). Its narrow conclusion is that the -converter cannot report success before the generated fixture run passes. +The converter cannot report success before the generated fixture run passes. diff --git a/docs/locus-conformance.md b/docs/locus-conformance.md deleted file mode 100644 index 597bdaa..0000000 --- a/docs/locus-conformance.md +++ /dev/null @@ -1,78 +0,0 @@ -# Locus derivation — the SDK contract and the end-to-end conformance suite - -Companion to `locus-yield.md` (the run-lifecycle models). This document -covers the language-interface design and the conformance suite that -discharges the whole program's obligations. Models and derivations live in -`docs/locus/`. - -## Verdicts - -| model | operator | verdict | -|---|---|---| -| `sdk-contract.json` | verification.trace-refinement | **refines** — the SDK execution automaton's observable stream is included in the supervisor's expectation (exactly one of request/terminal/diverged, then exit) | -| `sdk-contract.json` | control.nonblockingness | **nonblocking** — every SDK execution reaches an emit | -| `divergence-in-sdk.json` vs `divergence-supervisor-only.json` | verification.safety-reachability (rival designs, `drv-ad50b13e…`) | **decided** — in-SDK per-step checking satisfies `forbidden-unreachable`; supervisor-only is rejected with the verbatim trace `op_drifts → consume_unchecked → CONSUMED_MISMATCHED` | - -The feature-extension boundary also passed -`practice.boundary-conformance`. Its control law is deliberately small: -SDK stdout becomes engine authority only after the protocol package admits -exactly one complete `request`, `terminal`, or `diverged` variant. Unknown -fields and malformed, missing, or ambiguous variants fail before dispatch. -The canonical IR uses the same exact-one shape, while TypeScript and Rust -encode it with closed surface types. - -The decided comparison is why per-step digest comparison is a MANDATORY -part of the SDK contract in every language, not an optional nicety: without -it, a drifted operation silently consumes a recorded response meant for a -different question, and every later step compounds the corruption. - -## The contract every SDK implements - -Go (`sdk/yield`), TypeScript (`sdk/typescript`), Python (`sdk/python`), -Rust (`sdk/rust`) each implement, and only implement, the certified -automaton: load journal → replay with per-step digest compare before -consuming → emit exactly one program output → exit. The canonical wire -surface is `ir/yield.v1/*.schema.json`; -`internal/protocol/ir_test.go` binds the Go reference types to the IR. - -## The conformance suite (`internal/conformance`) - -One IDENTICAL program in all four languages -(`testdata/skill-{go,ts,py,rs}`), driven through the real supervisor. The -scenario matrix and what each observes: - -| test | observes | -|---|---| -| `TestCrossLanguageTraceEquality` | the core claim: one program, any language, the same observable protocol trace (sequence/kind/id + terminal + requirement count); every envelope IR-validated; `run_command` results are observed output; replay reproduces the terminal | -| `TestRefusedTerminal` | `declare_refused` in every language | -| `TestBlockedTerminal` | `declare_blocked` in every language | -| `TestFailedRequirementNeverCompletes` | `complete_unproven` refused; `run.blocked`, never `run.completed` | -| `TestGuardRefusals` | schema-invalid, duplicate-rewrite, wrong-run refusals through the live engine | -| `TestDivergenceFailsLoudlyEverywhere` | the decided design: a tampered recorded operation is detected by every SDK at replay | - -`internal/protocol/ir_test.go` adds the feature-upgrade gate: positive and -negative outputs must receive the same decision from protocol admission and -the canonical schema. `internal/engine/engine_test.go` proves ambiguous SDK -output is refused at the real subprocess boundary. - -Languages whose toolchain is missing are skipped locally; CI provides all -four (`.github/workflows/yield-lab.yml`). - -## Discharge - -`docs/locus/protocol-rw.discharge.json` records mechanism + refusing test -for every supervisory obligation of the lifecycle theorem. Verified: - -``` -locus obligations --operator control.supervisory-rw \ - --model docs/locus/yield-protocol.json --check docs/locus/protocol-rw.discharge.json -→ complete: true, undischarged: [] -``` - -## Honest scope - -The conformance suite proves the protocol machinery end-to-end: typed -operations, replay, refusals, terminals, cross-language equivalence. It -does not (and cannot) prove that a live agent performed only the requested -operations — that is the portable-mode diagnosability gap certified in -`locus-yield.md`, and the correlated-adapter slice is its answer. diff --git a/docs/locus-converter.md b/docs/locus-converter.md deleted file mode 100644 index b43bb73..0000000 --- a/docs/locus-converter.md +++ /dev/null @@ -1,39 +0,0 @@ -# Locus derivation — the skill converter - -`examples/convert-skill` turns an existing prose `SKILL.md` into a Yield -program in the operator's chosen language (Go / TypeScript / Python / -Rust). The converter is itself a Yield skill — the pipeline that makes -skills reliable is the pipeline that converts them. - -## Verdicts (models in `docs/locus/`) - -| model | operator | verdict | -|---|---|---| -| `convert-verified.json` | control.supervisory-rw | **controllable**, no violations — shipping an unverified conversion is preventable | -| `convert-verified.json` | control.nonblockingness | **nonblocking** — every conversion ends at `SHIPPED_VERIFIED` or an honest `REPORTED_BLOCKED` | -| `convert-verified.json` vs `convert-transcribed.json` | verification.safety-reachability (rival designs, `drv-…`) | **decided** — the executed-verification design satisfies `forbidden-unreachable`; completing on the model's transcription is rejected with the verbatim trace `extract_flow → pick_language → generate_program → complete_untested → SHIPPED_UNVERIFIED` | - -The decided comparison is the design's spine: **a conversion that was -never executed is never "done".** `complete_untested` stays in the -alphabet with no transition — the program's `Require(test.exit_code == 0)` -is the refusing mechanism, and the two-attempt repair loop ends in an -honest `Blocked`, keeping the pipeline nonblocking. - -## Division of labor - -| code owns | model owns | -|---|---| -| pipeline order (read → extract → choose → generate → verify) | reading the prose and extracting the implicit flow | -| the language menu (`ask_user`, closed set) | writing the program, thin SKILL.md, runner manifest, fixtures | -| the repair bound (≤ 2 attempts) | repairing a failing generation | -| the evidence gate (`yskill test` exit code, observed by the supervisor) | — | - -## Verified end-to-end without a model - -`fixtures/responses.json` scripts a conversion whose destination is an -existing valid skill, so `yskill test examples/convert-skill` exercises -the full machinery — including the **nested** `yskill test` of the -"generated" skill (`${YSKILL:-yskill}` lets harnesses pin the binary). -What the scripted run cannot exercise is the model actually writing good -code; that is exactly the part the evidence gate exists to check at live -time. diff --git a/docs/locus-yield.md b/docs/locus-yield.md deleted file mode 100644 index e225bc3..0000000 --- a/docs/locus-yield.md +++ /dev/null @@ -1,61 +0,0 @@ -# Locus derivation — the Yield run lifecycle - -Formal grounding for the V1 architecture. Models and the candidate -derivation live in `docs/locus/`; they were fidelity-certified against the -design artifact before implementation, so every claim below is a theorem -about the design model, discharged into system claims by the tests named -here. - -## Models - -| model | operators | verdict | -|---|---|---| -| `yield-protocol.json` | control.supervisory-rw | **controllable** — violations: `[]` | -| `yield-protocol.json` | control.nonblockingness | **nonblocking** — blocking states: `[]` | -| `yield-diag-portable.json` | control.diagnosability | **not diagnosable** — witness below | -| `yield-diag-correlated.json` | control.diagnosability | **diagnosable** — no indistinguishable pairs | - -## What the theorems fixed in the design - -1. **Protocol integrity is supervisable.** With `accept_stale` and - `complete_unproven` modeled as controllable forbidden transitions, a - supervisor can always prevent stale-response acceptance and - completion-after-failed-requirement. The kernel's obligations name the - refusing mechanisms the implementation must own; they are discharged by - the refusing tests in `internal/guard/guard_test.go`: - - `disable-mechanism:accept_stale` → `TestRefusesStaleResponse`, - `TestRefusesDuplicateWithDifferentContent` - - `disable-mechanism:accept_response` → `TestRefusesSchemaInvalidResult` - - `disable-mechanism:complete_unproven` → - `TestRefusesCompletionAfterFailedRequirement`, - `engine.TestFailedRequirementBlocksRun` - - `disable-mechanism:complete` → `TestAllowsCompletionWithPassedRequirements` - -2. **Every run reaches an honest terminal — because the migrate verb - exists.** Nonblockingness holds only with two controllable exits from - `DIVERGED`: `migrate_digest` (`resume --accept-new-digest`) and - `declare_blocked`. Without the migrate verb the design blocks; it is - load-bearing, not a convenience. Discharged by - `engine.TestDigestMismatchRefusedThenMigrates` and - `engine.TestReplayDivergenceFailsLoudly`. - -3. **Portable mode is provably non-diagnosable for off-protocol agent - action.** Verbatim witness (indistinguishable pair): faulty - `OFF_PROTOCOL` vs normal `PENDING_OP` — a run where the agent acted - outside the yielded operation produces the same observable trace as an - honest one. This is why the README's "not guaranteed" column exists, - and why a correlated host adapter (same alphabet, `agent_off_protocol` - observable) is the principled post-V1 slice: the rival-design - derivation (`drv-998aec…`) shows it diagnosable with zero - indistinguishable pairs. - -## Claim scope - -The models were certified against the design description, not a running -system; the run lifecycle claims descend to the implementation exactly as -far as the named tests carry them. The remaining undischarged honesty gap -is recorded in each model's `unknowns`: a schema-valid `agent_task` result -can still be fabricated — schema validity is not truth. `run_command` is -the exception by construction: the engine executes commands itself, so -their results enter the log as observed fact -(`engine.TestEndToEndRunResumeComplete` asserts the observed output). diff --git a/docs/locus/convert-transcribed.json b/docs/locus/convert-transcribed.json deleted file mode 100644 index 7ca00a7..0000000 --- a/docs/locus/convert-transcribed.json +++ /dev/null @@ -1,161 +0,0 @@ -{ - "schema_version": 1, - "id": "convert-skill-transcribed-v1", - "subject": "Yield skill converter pipeline: extract flow from prose SKILL.md, operator picks the target language, the model generates the program, and the converter completes on the model's word that the code is correct.", - "evidence": [ - { - "path": "labs/22-yield/yield/cmd/yskill/main.go", - "note": "design B: no yskill test run; the generated program is returned as text and shipped on transcription" - } - ], - "states": [ - { - "id": "SOURCED" - }, - { - "id": "FLOW_EXTRACTED" - }, - { - "id": "LANG_CHOSEN" - }, - { - "id": "GENERATED" - }, - { - "id": "TEST_RUN" - }, - { - "id": "TEST_PASSED" - }, - { - "id": "TEST_FAILED" - }, - { - "id": "SHIPPED_VERIFIED", - "marked": true - }, - { - "id": "SHIPPED_UNVERIFIED" - }, - { - "id": "REPORTED_BLOCKED", - "marked": true - } - ], - "events": [ - { - "id": "read_prose", - "controllable": true, - "observable": true - }, - { - "id": "extract_flow", - "controllable": false, - "observable": true - }, - { - "id": "pick_language", - "controllable": false, - "observable": true - }, - { - "id": "generate_program", - "controllable": false, - "observable": true - }, - { - "id": "run_generated_test", - "controllable": true, - "observable": true - }, - { - "id": "test_passes", - "controllable": false, - "observable": true - }, - { - "id": "test_fails", - "controllable": false, - "observable": true - }, - { - "id": "regenerate", - "controllable": true, - "observable": true - }, - { - "id": "complete_with_evidence", - "controllable": true, - "observable": true - }, - { - "id": "complete_untested", - "controllable": true, - "observable": true - }, - { - "id": "declare_blocked", - "controllable": true, - "observable": true - }, - { - "id": "archive", - "controllable": false, - "observable": true - } - ], - "transitions": [ - { - "from": "SOURCED", - "event": "extract_flow", - "to": "FLOW_EXTRACTED", - "evidence": [ - 0 - ] - }, - { - "from": "FLOW_EXTRACTED", - "event": "pick_language", - "to": "LANG_CHOSEN", - "evidence": [ - 0 - ] - }, - { - "from": "LANG_CHOSEN", - "event": "generate_program", - "to": "GENERATED", - "evidence": [ - 0 - ] - }, - { - "from": "GENERATED", - "event": "complete_untested", - "to": "SHIPPED_UNVERIFIED", - "evidence": [ - 0 - ] - }, - { - "from": "SHIPPED_UNVERIFIED", - "event": "archive", - "to": "SHIPPED_UNVERIFIED", - "evidence": [ - 0 - ] - } - ], - "spec": { - "description": "A converted skill must never ship without its fixture run passing under the real supervisor.", - "forbidden_states": [ - "SHIPPED_UNVERIFIED" - ] - }, - "targets": { - "selector": "marked" - }, - "unknowns": [ - "Design B ships whatever the model asserts compiles; nothing observes the generated program executing." - ] -} \ No newline at end of file diff --git a/docs/locus/convert-verified.json b/docs/locus/convert-verified.json deleted file mode 100644 index 182cbe5..0000000 --- a/docs/locus/convert-verified.json +++ /dev/null @@ -1,57 +0,0 @@ -{ - "schema_version": 1, - "id": "convert-skill-verified-v1", - "subject": "Yield skill converter pipeline: extract flow from prose SKILL.md, operator picks the target language, the model generates the program, and the converter completes only after the generated skill passes its own fixture run under yskill test.", - "evidence": [ - { "path": "labs/22-yield/yield/cmd/yskill/main.go", "note": "yskill test: scripted fixture run of a skill directory; exit code is observed fact" }, - { "path": "labs/22-yield/yield/internal/guard/guard.go", "note": "evidence-bound completion: a failed requirement prevents run.completed" } - ], - "states": [ - { "id": "SOURCED" }, - { "id": "FLOW_EXTRACTED" }, - { "id": "LANG_CHOSEN" }, - { "id": "GENERATED" }, - { "id": "TEST_RUN" }, - { "id": "TEST_PASSED" }, - { "id": "TEST_FAILED" }, - { "id": "SHIPPED_VERIFIED", "marked": true }, - { "id": "SHIPPED_UNVERIFIED" }, - { "id": "REPORTED_BLOCKED", "marked": true } - ], - "events": [ - { "id": "read_prose", "controllable": true, "observable": true }, - { "id": "extract_flow", "controllable": false, "observable": true }, - { "id": "pick_language", "controllable": false, "observable": true }, - { "id": "generate_program", "controllable": false, "observable": true }, - { "id": "run_generated_test", "controllable": true, "observable": true }, - { "id": "test_passes", "controllable": false, "observable": true }, - { "id": "test_fails", "controllable": false, "observable": true }, - { "id": "regenerate", "controllable": true, "observable": true }, - { "id": "complete_with_evidence", "controllable": true, "observable": true }, - { "id": "complete_untested", "controllable": true, "observable": true }, - { "id": "declare_blocked", "controllable": true, "observable": true }, - { "id": "archive", "controllable": false, "observable": true } - ], - "transitions": [ - { "from": "SOURCED", "event": "extract_flow", "to": "FLOW_EXTRACTED", "evidence": [0] }, - { "from": "FLOW_EXTRACTED", "event": "pick_language", "to": "LANG_CHOSEN", "evidence": [0] }, - { "from": "LANG_CHOSEN", "event": "generate_program", "to": "GENERATED", "evidence": [0] }, - { "from": "GENERATED", "event": "run_generated_test", "to": "TEST_RUN", "evidence": [0] }, - { "from": "TEST_RUN", "event": "test_passes", "to": "TEST_PASSED", "evidence": [0] }, - { "from": "TEST_RUN", "event": "test_fails", "to": "TEST_FAILED", "evidence": [0] }, - { "from": "TEST_FAILED", "event": "regenerate", "to": "GENERATED", "evidence": [0] }, - { "from": "TEST_FAILED", "event": "declare_blocked", "to": "REPORTED_BLOCKED", "evidence": [1] }, - { "from": "TEST_PASSED", "event": "complete_with_evidence", "to": "SHIPPED_VERIFIED", "evidence": [1] }, - { "from": "SHIPPED_VERIFIED", "event": "archive", "to": "SHIPPED_VERIFIED", "evidence": [0] }, - { "from": "REPORTED_BLOCKED", "event": "archive", "to": "REPORTED_BLOCKED", "evidence": [0] } - ], - "spec": { - "description": "A converted skill must never ship without its fixture run passing under the real supervisor.", - "forbidden_states": ["SHIPPED_UNVERIFIED"] - }, - "targets": { "selector": "marked" }, - "unknowns": [ - "Design A refuses complete_untested structurally: the event is in the alphabet, but the converter program offers no transition — Require(test.exit_code == 0) stands between GENERATED and completion.", - "Regeneration is bounded by a retry counter in the converter program; the model treats the bound as data, not modeled state." - ] -} diff --git a/docs/locus/divergence-in-sdk.json b/docs/locus/divergence-in-sdk.json deleted file mode 100644 index 84258a0..0000000 --- a/docs/locus/divergence-in-sdk.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "schema_version": 1, - "id": "divergence-check-in-sdk-v1", - "subject": "Where divergence detection lives for Yield language SDKs: replay consumption of recorded responses under possible operation drift.", - "evidence": [ - { "path": "labs/22-yield/yield/sdk/yield/yield.go", "note": "design A: the SDK compares the produced request digest against the journal at EVERY replayed step before consuming the recorded response" } - ], - "states": [ - { "id": "STEP" }, - { "id": "PRODUCED" }, - { "id": "COMPARED_OK" }, - { "id": "HALTED_DIVERGED", "marked": true }, - { "id": "CONSUMED_MISMATCHED" }, - { "id": "CONSUMED_OK", "marked": true } - ], - "events": [ - { "id": "op_drifts", "controllable": false, "observable": false }, - { "id": "produce_op", "controllable": true, "observable": true }, - { "id": "compare_match", "controllable": true, "observable": true }, - { "id": "compare_mismatch", "controllable": true, "observable": true }, - { "id": "consume_response", "controllable": true, "observable": true }, - { "id": "consume_unchecked", "controllable": true, "observable": true } - ], - "transitions": [ - { "from": "STEP", "event": "op_drifts", "to": "PRODUCED", "evidence": [0] }, - { "from": "STEP", "event": "produce_op", "to": "PRODUCED", "evidence": [0] }, - { "from": "PRODUCED", "event": "compare_match", "to": "COMPARED_OK", "evidence": [0] }, - { "from": "PRODUCED", "event": "compare_mismatch", "to": "HALTED_DIVERGED", "evidence": [0] }, - { "from": "COMPARED_OK", "event": "consume_response", "to": "CONSUMED_OK", "evidence": [0] } - ], - "spec": { - "description": "A program must never consume a recorded response for an operation that does not match the journal (misaligned answers corrupt every later step).", - "forbidden_states": ["CONSUMED_MISMATCHED"] - }, - "unknowns": [ - "Design A refuses consume-after-mismatch structurally: consume_unchecked is in the alphabet but the SDK never offers the transition." - ] -} diff --git a/docs/locus/divergence-supervisor-only.json b/docs/locus/divergence-supervisor-only.json deleted file mode 100644 index 67a849e..0000000 --- a/docs/locus/divergence-supervisor-only.json +++ /dev/null @@ -1,108 +0,0 @@ -{ - "schema_version": 1, - "id": "divergence-check-supervisor-only-v1", - "subject": "Where divergence detection lives for Yield language SDKs: replay consumption of recorded responses under possible operation drift.", - "evidence": [ - { - "path": "labs/22-yield/yield/sdk/yield/yield.go", - "note": "design B: the SDK trusts the journal blindly and consumes responses without per-step comparison; the supervisor only checks the frontier" - } - ], - "states": [ - { - "id": "STEP" - }, - { - "id": "PRODUCED" - }, - { - "id": "COMPARED_OK" - }, - { - "id": "HALTED_DIVERGED", - "marked": true - }, - { - "id": "CONSUMED_MISMATCHED" - }, - { - "id": "CONSUMED_OK", - "marked": true - } - ], - "events": [ - { - "id": "op_drifts", - "controllable": false, - "observable": false - }, - { - "id": "produce_op", - "controllable": true, - "observable": true - }, - { - "id": "compare_match", - "controllable": true, - "observable": true - }, - { - "id": "compare_mismatch", - "controllable": true, - "observable": true - }, - { - "id": "consume_response", - "controllable": true, - "observable": true - }, - { - "id": "consume_unchecked", - "controllable": true, - "observable": true - } - ], - "transitions": [ - { - "from": "STEP", - "event": "op_drifts", - "to": "PRODUCED", - "evidence": [ - 0 - ] - }, - { - "from": "STEP", - "event": "produce_op", - "to": "PRODUCED", - "evidence": [ - 0 - ] - }, - { - "from": "PRODUCED", - "event": "consume_unchecked", - "to": "CONSUMED_MISMATCHED", - "evidence": [ - 0 - ] - }, - { - "from": "PRODUCED", - "event": "consume_response", - "to": "CONSUMED_OK", - "evidence": [ - 0 - ] - } - ], - "spec": { - "description": "A program must never consume a recorded response for an operation that does not match the journal (misaligned answers corrupt every later step).", - "forbidden_states": [ - "CONSUMED_MISMATCHED" - ] - }, - "unknowns": [ - "Design B: with no in-SDK comparison, nothing distinguishes a drifted operation from a faithful one at consumption time." - ] -} \ No newline at end of file diff --git a/docs/locus/drv-998aecbcb0b652eeb2c966a86c871c2a187729f224435ebf9fe20e9eb7be788e.json b/docs/locus/drv-998aecbcb0b652eeb2c966a86c871c2a187729f224435ebf9fe20e9eb7be788e.json deleted file mode 100644 index 2b8e2ab..0000000 --- a/docs/locus/drv-998aecbcb0b652eeb2c966a86c871c2a187729f224435ebf9fe20e9eb7be788e.json +++ /dev/null @@ -1,278 +0,0 @@ -{ - "schema_version": 1, - "id": "drv-998aecbcb0b652eeb2c966a86c871c2a187729f224435ebf9fe20e9eb7be788e", - "goal": "Decide whether off-protocol agent action is diagnosable from Yield's observation surface: portable run-log-only vs a correlated host adapter", - "subject": "Yield V1 observation surface for off-protocol agent action", - "variants": [ - { - "id": "yield-offprotocol-portable-v1", - "role": "design-candidate", - "model_id": "yield-offprotocol-portable-v1", - "model_sha256": "71f2880721196f42c82cc152c49dff6d0fd4ac71a84586c468f66442bc305051", - "basis": { - "observed": 23, - "inferred": 0, - "assumed": 18 - } - }, - { - "id": "yield-offprotocol-correlated-v1", - "role": "design-candidate", - "model_id": "yield-offprotocol-correlated-v1", - "model_sha256": "9427e2135066d6a89999178b3c6467799153ceb155543e3d9777b39a27193c73", - "basis": { - "observed": 23, - "inferred": 0, - "assumed": 18 - } - } - ], - "runs": [ - { - "operator_id": "control.diagnosability", - "operator_version": "0.1.0", - "variant_id": "yield-offprotocol-portable-v1", - "input_sha256": "71f2880721196f42c82cc152c49dff6d0fd4ac71a84586c468f66442bc305051", - "output_sha256": "fe6352801ce59ae07cb0678642fdd58531228f7011303e454f52323a05045ede", - "verdict": { - "operator_id": "control.diagnosability", - "operator_version": "0.1.0", - "model_id": "yield-offprotocol-portable-v1", - "decision": "applicable", - "satisfied": [ - { - "id": "automaton-states", - "check": "has-facet:states", - "description": "A discrete-event facet with declared states.", - "satisfied": true - }, - { - "id": "automaton-events", - "check": "has-facet:events", - "description": "A declared event alphabet.", - "satisfied": true - }, - { - "id": "automaton-transitions", - "check": "has-facet:transitions", - "description": "Plant transitions over the declared states and events.", - "satisfied": true - }, - { - "id": "observability-partition", - "check": "all-events-marked-observability", - "description": "Every event marked observable or unobservable (the observation mask).", - "satisfied": true, - "obtainable": true - }, - { - "id": "spec-present", - "check": "has-spec-forbidden", - "description": "A specification naming the fault: forbidden states or forbidden (state, event) transitions.", - "satisfied": true, - "obtainable": true - }, - { - "id": "transition-lineage", - "check": "evidence-present:transitions", - "description": "Transitions carry evidence references into the real system.", - "satisfied": true, - "obtainable": true - } - ] - }, - "output": { - "diagnosable": false, - "indistinguishable_pairs": [ - { - "faulty": "BLOCKED", - "normal": "BLOCKED" - }, - { - "faulty": "COMPLETED", - "normal": "COMPLETED" - }, - { - "faulty": "DIVERGED", - "normal": "DIVERGED" - }, - { - "faulty": "OFF_PROTOCOL", - "normal": "PENDING_OP" - }, - { - "faulty": "PENDING_OP", - "normal": "PENDING_OP" - }, - { - "faulty": "REFUSED", - "normal": "REFUSED" - }, - { - "faulty": "REPLAYING", - "normal": "REPLAYING" - }, - { - "faulty": "RUNNING", - "normal": "RUNNING" - }, - { - "faulty": "STALE_RECEIVED", - "normal": "STALE_RECEIVED" - }, - { - "faulty": "VALIDATING", - "normal": "VALIDATING" - } - ], - "witness": [ - "start", - "yield_op" - ] - }, - "verify": { - "schema_ok": true, - "invariants": [ - { - "invariant": "pairs-empty-iff-diagnosable", - "passed": true - } - ], - "accepted": true - }, - "claim_status": "theorem-only" - }, - { - "operator_id": "control.diagnosability", - "operator_version": "0.1.0", - "variant_id": "yield-offprotocol-correlated-v1", - "input_sha256": "9427e2135066d6a89999178b3c6467799153ceb155543e3d9777b39a27193c73", - "output_sha256": "ad7a0594ab20aae277f633c2a7f11633ebdbe518cf2946a10e18f72aab298b1e", - "verdict": { - "operator_id": "control.diagnosability", - "operator_version": "0.1.0", - "model_id": "yield-offprotocol-correlated-v1", - "decision": "applicable", - "satisfied": [ - { - "id": "automaton-states", - "check": "has-facet:states", - "description": "A discrete-event facet with declared states.", - "satisfied": true - }, - { - "id": "automaton-events", - "check": "has-facet:events", - "description": "A declared event alphabet.", - "satisfied": true - }, - { - "id": "automaton-transitions", - "check": "has-facet:transitions", - "description": "Plant transitions over the declared states and events.", - "satisfied": true - }, - { - "id": "observability-partition", - "check": "all-events-marked-observability", - "description": "Every event marked observable or unobservable (the observation mask).", - "satisfied": true, - "obtainable": true - }, - { - "id": "spec-present", - "check": "has-spec-forbidden", - "description": "A specification naming the fault: forbidden states or forbidden (state, event) transitions.", - "satisfied": true, - "obtainable": true - }, - { - "id": "transition-lineage", - "check": "evidence-present:transitions", - "description": "Transitions carry evidence references into the real system.", - "satisfied": true, - "obtainable": true - } - ] - }, - "output": { - "diagnosable": true, - "indistinguishable_pairs": [] - }, - "verify": { - "schema_ok": true, - "invariants": [ - { - "invariant": "pairs-empty-iff-diagnosable", - "passed": true - } - ], - "accepted": true - }, - "claim_status": "theorem-only" - } - ], - "comparisons": [ - { - "operator_id": "control.diagnosability", - "property": "diagnosable", - "status": "decided", - "satisfying": [ - "yield-offprotocol-correlated-v1" - ], - "rejected": [ - { - "variant_id": "yield-offprotocol-portable-v1", - "counterexample": [ - { - "faulty": "BLOCKED", - "normal": "BLOCKED" - }, - { - "faulty": "COMPLETED", - "normal": "COMPLETED" - }, - { - "faulty": "DIVERGED", - "normal": "DIVERGED" - }, - { - "faulty": "OFF_PROTOCOL", - "normal": "PENDING_OP" - }, - { - "faulty": "PENDING_OP", - "normal": "PENDING_OP" - }, - { - "faulty": "REFUSED", - "normal": "REFUSED" - }, - { - "faulty": "REPLAYING", - "normal": "REPLAYING" - }, - { - "faulty": "RUNNING", - "normal": "RUNNING" - }, - { - "faulty": "STALE_RECEIVED", - "normal": "STALE_RECEIVED" - }, - { - "faulty": "VALIDATING", - "normal": "VALIDATING" - } - ] - } - ], - "undetermined": [] - } - ], - "unknowns": [ - "The runtime is not yet implemented; this model is the design intent for labs/22-yield (Go), grounded only in the design artifact.", - "agent_task response content can be fabricated while schema-valid; schema_reject only rejects shape, not truth.", - "Whether run_command is executed by yskill itself (observed fact) or by the agent (transcription) is a design decision pending in the plan." - ] -} diff --git a/docs/locus/drv-ad50b13e9419f4beec8d7542352971f391515e3c17a2fbd68466d1f8a30d36a7.json b/docs/locus/drv-ad50b13e9419f4beec8d7542352971f391515e3c17a2fbd68466d1f8a30d36a7.json deleted file mode 100644 index b8ac7a8..0000000 --- a/docs/locus/drv-ad50b13e9419f4beec8d7542352971f391515e3c17a2fbd68466d1f8a30d36a7.json +++ /dev/null @@ -1,228 +0,0 @@ -{ - "schema_version": 1, - "id": "drv-ad50b13e9419f4beec8d7542352971f391515e3c17a2fbd68466d1f8a30d36a7", - "goal": "Decide where divergence detection must live in Yield language SDKs: in-SDK per-replayed-step comparison vs supervisor-only frontier check", - "subject": "Divergence-detection placement in the yield.v1 SDK contract", - "variants": [ - { - "id": "divergence-check-in-sdk-v1", - "role": "design-candidate", - "model_id": "divergence-check-in-sdk-v1", - "model_sha256": "b2ab352f3fafd6bf0e01fa2e4eb2aa15f508c0f7565a9af73edb9c3274b7b7dc", - "basis": { - "observed": 5, - "inferred": 0, - "assumed": 6 - } - }, - { - "id": "divergence-check-supervisor-only-v1", - "role": "design-candidate", - "model_id": "divergence-check-supervisor-only-v1", - "model_sha256": "0fe361e7eacac8e285bf6d02bc9dc1d5604d32555eb2cfdcb945e1b2d965ca95", - "basis": { - "observed": 4, - "inferred": 0, - "assumed": 6 - } - } - ], - "runs": [ - { - "operator_id": "verification.safety-reachability", - "operator_version": "0.1.0", - "variant_id": "divergence-check-in-sdk-v1", - "input_sha256": "b2ab352f3fafd6bf0e01fa2e4eb2aa15f508c0f7565a9af73edb9c3274b7b7dc", - "output_sha256": "31f41ff54b840eb006795355ea161827b4a254f1dad3b07ab43971ef7d1e1af7", - "verdict": { - "operator_id": "verification.safety-reachability", - "operator_version": "0.1.0", - "model_id": "divergence-check-in-sdk-v1", - "decision": "applicable", - "satisfied": [ - { - "id": "automaton-states", - "check": "has-facet:states", - "description": "A discrete-event facet with declared states.", - "satisfied": true - }, - { - "id": "automaton-events", - "check": "has-facet:events", - "description": "A declared event alphabet.", - "satisfied": true - }, - { - "id": "automaton-transitions", - "check": "has-facet:transitions", - "description": "Plant transitions over the declared states and events.", - "satisfied": true - }, - { - "id": "spec-present", - "check": "has-spec-forbidden", - "description": "A specification naming forbidden states or forbidden (state, event) transitions — safety must be named, not assumed.", - "satisfied": true, - "obtainable": true - }, - { - "id": "transition-lineage", - "check": "evidence-present:transitions", - "description": "Transitions carry evidence references into the real system.", - "satisfied": true, - "obtainable": true - } - ] - }, - "output": { - "reachable": false, - "violating_trace": [], - "reachable_states": [ - "COMPARED_OK", - "CONSUMED_OK", - "HALTED_DIVERGED", - "PRODUCED", - "STEP" - ] - }, - "verify": { - "schema_ok": true, - "invariants": [ - { - "invariant": "violating-trace-is-a-declared-path", - "passed": true - }, - { - "invariant": "violating-trace-ends-forbidden", - "passed": true - }, - { - "invariant": "reachable-iff-witness", - "passed": true - } - ], - "accepted": true - }, - "claim_status": "theorem-only" - }, - { - "operator_id": "verification.safety-reachability", - "operator_version": "0.1.0", - "variant_id": "divergence-check-supervisor-only-v1", - "input_sha256": "0fe361e7eacac8e285bf6d02bc9dc1d5604d32555eb2cfdcb945e1b2d965ca95", - "output_sha256": "7e3a80bd6da6c06c0e99019de1dd0dd7e7471b70e4b05acb15aaf1389d250288", - "verdict": { - "operator_id": "verification.safety-reachability", - "operator_version": "0.1.0", - "model_id": "divergence-check-supervisor-only-v1", - "decision": "applicable", - "satisfied": [ - { - "id": "automaton-states", - "check": "has-facet:states", - "description": "A discrete-event facet with declared states.", - "satisfied": true - }, - { - "id": "automaton-events", - "check": "has-facet:events", - "description": "A declared event alphabet.", - "satisfied": true - }, - { - "id": "automaton-transitions", - "check": "has-facet:transitions", - "description": "Plant transitions over the declared states and events.", - "satisfied": true - }, - { - "id": "spec-present", - "check": "has-spec-forbidden", - "description": "A specification naming forbidden states or forbidden (state, event) transitions — safety must be named, not assumed.", - "satisfied": true, - "obtainable": true - }, - { - "id": "transition-lineage", - "check": "evidence-present:transitions", - "description": "Transitions carry evidence references into the real system.", - "satisfied": true, - "obtainable": true - } - ] - }, - "output": { - "reachable": true, - "violating_trace": [ - { - "from": "STEP", - "event": "op_drifts", - "to": "PRODUCED" - }, - { - "from": "PRODUCED", - "event": "consume_unchecked", - "to": "CONSUMED_MISMATCHED" - } - ], - "reachable_states": [ - "CONSUMED_MISMATCHED", - "CONSUMED_OK", - "PRODUCED", - "STEP" - ] - }, - "verify": { - "schema_ok": true, - "invariants": [ - { - "invariant": "violating-trace-is-a-declared-path", - "passed": true - }, - { - "invariant": "violating-trace-ends-forbidden", - "passed": true - }, - { - "invariant": "reachable-iff-witness", - "passed": true - } - ], - "accepted": true - }, - "claim_status": "theorem-only" - } - ], - "comparisons": [ - { - "operator_id": "verification.safety-reachability", - "property": "forbidden-unreachable", - "status": "decided", - "satisfying": [ - "divergence-check-in-sdk-v1" - ], - "rejected": [ - { - "variant_id": "divergence-check-supervisor-only-v1", - "counterexample": [ - { - "from": "STEP", - "event": "op_drifts", - "to": "PRODUCED" - }, - { - "from": "PRODUCED", - "event": "consume_unchecked", - "to": "CONSUMED_MISMATCHED" - } - ] - } - ], - "undetermined": [] - } - ], - "unknowns": [ - "Design A refuses consume-after-mismatch structurally: consume_unchecked is in the alphabet but the SDK never offers the transition.", - "Design B: with no in-SDK comparison, nothing distinguishes a drifted operation from a faithful one at consumption time." - ] -} diff --git a/docs/locus/drv-db7bca98dc05ca24898e309e3d0eb89c3d812847490b9369cb006cf37625e3c6.json b/docs/locus/drv-db7bca98dc05ca24898e309e3d0eb89c3d812847490b9369cb006cf37625e3c6.json deleted file mode 100644 index c95a6ef..0000000 --- a/docs/locus/drv-db7bca98dc05ca24898e309e3d0eb89c3d812847490b9369cb006cf37625e3c6.json +++ /dev/null @@ -1,254 +0,0 @@ -{ - "schema_version": 1, - "id": "drv-db7bca98dc05ca24898e309e3d0eb89c3d812847490b9369cb006cf37625e3c6", - "goal": "Decide whether the Yield skill converter must verify generated skills by executing them under yskill test before completing", - "subject": "Converter completion evidence: executed fixture run vs model transcription", - "variants": [ - { - "id": "convert-skill-verified-v1", - "role": "design-candidate", - "model_id": "convert-skill-verified-v1", - "model_sha256": "02d96d55d4d932147d60ff31f44d835a67690afd835bd7a2056bde78db53b769", - "basis": { - "observed": 11, - "inferred": 0, - "assumed": 12 - } - }, - { - "id": "convert-skill-transcribed-v1", - "role": "design-candidate", - "model_id": "convert-skill-transcribed-v1", - "model_sha256": "a43832bbaed492a45ec71e49878278950ccdf1db691908c5bcfb7d3a33c064fb", - "basis": { - "observed": 5, - "inferred": 0, - "assumed": 12 - } - } - ], - "runs": [ - { - "operator_id": "verification.safety-reachability", - "operator_version": "0.1.0", - "variant_id": "convert-skill-verified-v1", - "input_sha256": "02d96d55d4d932147d60ff31f44d835a67690afd835bd7a2056bde78db53b769", - "output_sha256": "12eab977b5b4f258c8ce49ba91ee4bbc9dff86325aab43d551bf7ee697de1e78", - "verdict": { - "operator_id": "verification.safety-reachability", - "operator_version": "0.1.0", - "model_id": "convert-skill-verified-v1", - "decision": "applicable", - "satisfied": [ - { - "id": "automaton-states", - "check": "has-facet:states", - "description": "A discrete-event facet with declared states.", - "satisfied": true - }, - { - "id": "automaton-events", - "check": "has-facet:events", - "description": "A declared event alphabet.", - "satisfied": true - }, - { - "id": "automaton-transitions", - "check": "has-facet:transitions", - "description": "Plant transitions over the declared states and events.", - "satisfied": true - }, - { - "id": "spec-present", - "check": "has-spec-forbidden", - "description": "A specification naming forbidden states or forbidden (state, event) transitions — safety must be named, not assumed.", - "satisfied": true, - "obtainable": true - }, - { - "id": "transition-lineage", - "check": "evidence-present:transitions", - "description": "Transitions carry evidence references into the real system.", - "satisfied": true, - "obtainable": true - } - ] - }, - "output": { - "reachable": false, - "violating_trace": [], - "reachable_states": [ - "FLOW_EXTRACTED", - "GENERATED", - "LANG_CHOSEN", - "REPORTED_BLOCKED", - "SHIPPED_VERIFIED", - "SOURCED", - "TEST_FAILED", - "TEST_PASSED", - "TEST_RUN" - ] - }, - "verify": { - "schema_ok": true, - "invariants": [ - { - "invariant": "violating-trace-is-a-declared-path", - "passed": true - }, - { - "invariant": "violating-trace-ends-forbidden", - "passed": true - }, - { - "invariant": "reachable-iff-witness", - "passed": true - } - ], - "accepted": true - }, - "claim_status": "theorem-only" - }, - { - "operator_id": "verification.safety-reachability", - "operator_version": "0.1.0", - "variant_id": "convert-skill-transcribed-v1", - "input_sha256": "a43832bbaed492a45ec71e49878278950ccdf1db691908c5bcfb7d3a33c064fb", - "output_sha256": "aa377ce2c4f59cc78e208279ecc291cc0c09111bb2868866bb646a70d8bbf211", - "verdict": { - "operator_id": "verification.safety-reachability", - "operator_version": "0.1.0", - "model_id": "convert-skill-transcribed-v1", - "decision": "applicable", - "satisfied": [ - { - "id": "automaton-states", - "check": "has-facet:states", - "description": "A discrete-event facet with declared states.", - "satisfied": true - }, - { - "id": "automaton-events", - "check": "has-facet:events", - "description": "A declared event alphabet.", - "satisfied": true - }, - { - "id": "automaton-transitions", - "check": "has-facet:transitions", - "description": "Plant transitions over the declared states and events.", - "satisfied": true - }, - { - "id": "spec-present", - "check": "has-spec-forbidden", - "description": "A specification naming forbidden states or forbidden (state, event) transitions — safety must be named, not assumed.", - "satisfied": true, - "obtainable": true - }, - { - "id": "transition-lineage", - "check": "evidence-present:transitions", - "description": "Transitions carry evidence references into the real system.", - "satisfied": true, - "obtainable": true - } - ] - }, - "output": { - "reachable": true, - "violating_trace": [ - { - "from": "SOURCED", - "event": "extract_flow", - "to": "FLOW_EXTRACTED" - }, - { - "from": "FLOW_EXTRACTED", - "event": "pick_language", - "to": "LANG_CHOSEN" - }, - { - "from": "LANG_CHOSEN", - "event": "generate_program", - "to": "GENERATED" - }, - { - "from": "GENERATED", - "event": "complete_untested", - "to": "SHIPPED_UNVERIFIED" - } - ], - "reachable_states": [ - "FLOW_EXTRACTED", - "GENERATED", - "LANG_CHOSEN", - "SHIPPED_UNVERIFIED", - "SOURCED" - ] - }, - "verify": { - "schema_ok": true, - "invariants": [ - { - "invariant": "violating-trace-is-a-declared-path", - "passed": true - }, - { - "invariant": "violating-trace-ends-forbidden", - "passed": true - }, - { - "invariant": "reachable-iff-witness", - "passed": true - } - ], - "accepted": true - }, - "claim_status": "theorem-only" - } - ], - "comparisons": [ - { - "operator_id": "verification.safety-reachability", - "property": "forbidden-unreachable", - "status": "decided", - "satisfying": [ - "convert-skill-verified-v1" - ], - "rejected": [ - { - "variant_id": "convert-skill-transcribed-v1", - "counterexample": [ - { - "from": "SOURCED", - "event": "extract_flow", - "to": "FLOW_EXTRACTED" - }, - { - "from": "FLOW_EXTRACTED", - "event": "pick_language", - "to": "LANG_CHOSEN" - }, - { - "from": "LANG_CHOSEN", - "event": "generate_program", - "to": "GENERATED" - }, - { - "from": "GENERATED", - "event": "complete_untested", - "to": "SHIPPED_UNVERIFIED" - } - ] - } - ], - "undetermined": [] - } - ], - "unknowns": [ - "Design A refuses complete_untested structurally: the event is in the alphabet, but the converter program offers no transition — Require(test.exit_code == 0) stands between GENERATED and completion.", - "Regeneration is bounded by a retry counter in the converter program; the model treats the bound as data, not modeled state.", - "Design B ships whatever the model asserts compiles; nothing observes the generated program executing." - ] -} diff --git a/docs/locus/protocol-rw.discharge.json b/docs/locus/protocol-rw.discharge.json deleted file mode 100644 index 4c08a5c..0000000 --- a/docs/locus/protocol-rw.discharge.json +++ /dev/null @@ -1,77 +0,0 @@ -{ - "schema_version": 1, - "obligations": [ - { - "id": "disable-mechanism:accept_response", - "mechanism": "guard.CheckResponse validates the result against the pending request's embedded JSON schema before acceptance (internal/guard/guard.go)", - "evidence": ["labs/22-yield/yield/internal/guard/guard.go"], - "refusing_test": "guard.TestRefusesSchemaInvalidResult; conformance.TestGuardRefusals (all four languages)" - }, - { - "id": "disable-mechanism:accept_stale", - "mechanism": "guard.CheckResponse refuses any response whose sequence is not the pending operation's, and refuses rewriting completed sequences (internal/guard/guard.go)", - "evidence": ["labs/22-yield/yield/internal/guard/guard.go"], - "refusing_test": "guard.TestRefusesStaleResponse, guard.TestRefusesDuplicateWithDifferentContent; conformance.TestGuardRefusals" - }, - { - "id": "disable-mechanism:complete", - "mechanism": "engine.terminate calls guard.CheckCompletion before appending run.completed (internal/engine/engine.go)", - "evidence": ["labs/22-yield/yield/internal/engine/engine.go"], - "refusing_test": "guard.TestAllowsCompletionWithPassedRequirements; conformance.TestCrossLanguageTraceEquality (completion observed with all requirements passed)" - }, - { - "id": "disable-mechanism:complete_unproven", - "mechanism": "guard.CheckCompletion refuses completion when any requirement failed; the SDKs make completion structurally unreachable past a failed Require (internal/guard/guard.go; sdk/*)", - "evidence": ["labs/22-yield/yield/internal/guard/guard.go", "labs/22-yield/yield/sdk/yield/yield.go"], - "refusing_test": "guard.TestRefusesCompletionAfterFailedRequirement; conformance.TestFailedRequirementNeverCompletes (all four languages)" - }, - { - "id": "disable-mechanism:declare_blocked", - "mechanism": "SDK Blocked terminal maps to run.blocked in engine.terminate; only the program can raise it (sdk/*; internal/engine/engine.go)", - "evidence": ["labs/22-yield/yield/internal/engine/engine.go"], - "refusing_test": "conformance.TestBlockedTerminal (all four languages)" - }, - { - "id": "disable-mechanism:declare_refused", - "mechanism": "SDK Refused terminal maps to run.refused in engine.terminate (sdk/*; internal/engine/engine.go)", - "evidence": ["labs/22-yield/yield/internal/engine/engine.go"], - "refusing_test": "conformance.TestRefusedTerminal (all four languages)" - }, - { - "id": "disable-mechanism:migrate_digest", - "mechanism": "guard.CheckDigest only rebinds under the explicit --accept-new-digest flag; digest.migrated is logged (internal/guard/guard.go; internal/engine/engine.go)", - "evidence": ["labs/22-yield/yield/internal/guard/guard.go"], - "refusing_test": "guard.TestRefusesDigestMismatchWithoutMigration; engine.TestDigestMismatchRefusedThenMigrates" - }, - { - "id": "disable-mechanism:reject_stale", - "mechanism": "guard rejections are appended to the run log as response.rejected and surfaced as typed errors (internal/engine/engine.go rejected())", - "evidence": ["labs/22-yield/yield/internal/engine/engine.go"], - "refusing_test": "engine.TestEndToEndRunResumeComplete (stale response refused and recorded)" - }, - { - "id": "disable-mechanism:schema_reject", - "mechanism": "protocol.ValidateResult compiles the embedded schema and rejects non-conforming results at the acceptance boundary (internal/protocol/protocol.go)", - "evidence": ["labs/22-yield/yield/internal/protocol/protocol.go"], - "refusing_test": "protocol.TestValidateResult; conformance.TestGuardRefusals" - }, - { - "id": "disable-mechanism:start", - "mechanism": "engine.StartRun is the only run creator; runlog.Create refuses to overwrite an existing run (internal/runlog/runlog.go)", - "evidence": ["labs/22-yield/yield/internal/runlog/runlog.go"], - "refusing_test": "runlog.TestCreateRefusesOverwrite" - }, - { - "id": "disable-mechanism:yield_op", - "mechanism": "operations enter the log only via engine.advance from a decoded ProgramOutput; the SDKs emit exactly one output per execution (internal/engine/engine.go; sdk/*)", - "evidence": ["labs/22-yield/yield/internal/engine/engine.go"], - "refusing_test": "conformance.TestCrossLanguageTraceEquality (operation stream observed identical across languages, IR-validated)" - }, - { - "id": "event-completeness", - "mechanism": "single-writer inventory: every run-state mutation is a runlog.Append in engine.go/runlog.go; the guard reconstructs state exclusively from the log", - "evidence": ["labs/22-yield/yield/internal/runlog/runlog.go", "labs/22-yield/yield/internal/engine/engine.go"], - "refusing_test": "runlog.TestOpenRefusesBrokenSequence (out-of-band edits break the monotone sequence and are refused on open); conformance suite observes all event types" - } - ] -} diff --git a/docs/locus/sdk-contract.json b/docs/locus/sdk-contract.json deleted file mode 100644 index 0fa6646..0000000 --- a/docs/locus/sdk-contract.json +++ /dev/null @@ -1,231 +0,0 @@ -{ - "schema_version": 1, - "id": "yield-sdk-execution-contract-v1", - "subject": "Yield SDK execution contract: one skill-program execution loads the journal, replays recorded operations with per-step digest comparison, and emits exactly one protocol output (request, terminal, or diverged) before exit. The reference is the supervisor's expectation of the observable output stream.", - "evidence": [ - { - "path": "labs/22-yield/yield/sdk/yield/yield.go", - "note": "Go SDK: step() replay/compare/emit and Main() terminal emission \u2014 the reference behavior all four SDKs refine" - }, - { - "path": "labs/22-yield/yield/internal/engine/engine.go", - "note": "supervisor: execute() consumes exactly one ProgramOutput per subprocess execution" - } - ], - "states": [ - { - "id": "START" - }, - { - "id": "LOOP" - }, - { - "id": "COMPARE" - }, - { - "id": "EMIT_REQ" - }, - { - "id": "EMIT_TERM" - }, - { - "id": "EMIT_DIV" - }, - { - "id": "EXITING" - }, - { - "id": "DONE", - "marked": true - } - ], - "events": [ - { - "id": "load_journal", - "controllable": true, - "observable": false - }, - { - "id": "produce_recorded_op", - "controllable": true, - "observable": false - }, - { - "id": "digest_match", - "controllable": true, - "observable": false - }, - { - "id": "digest_mismatch", - "controllable": false, - "observable": false - }, - { - "id": "produce_new_op", - "controllable": true, - "observable": false - }, - { - "id": "program_returns", - "controllable": true, - "observable": false - }, - { - "id": "requirement_fails", - "controllable": false, - "observable": false - }, - { - "id": "emit_request", - "controllable": true, - "observable": true - }, - { - "id": "emit_terminal", - "controllable": true, - "observable": true - }, - { - "id": "emit_diverged", - "controllable": true, - "observable": true - }, - { - "id": "exit_process", - "controllable": true, - "observable": true - } - ], - "transitions": [ - { - "from": "START", - "event": "load_journal", - "to": "LOOP", - "evidence": [ - 0 - ] - }, - { - "from": "LOOP", - "event": "produce_recorded_op", - "to": "COMPARE", - "evidence": [ - 0 - ] - }, - { - "from": "COMPARE", - "event": "digest_match", - "to": "LOOP", - "evidence": [ - 0 - ] - }, - { - "from": "COMPARE", - "event": "digest_mismatch", - "to": "EMIT_DIV", - "evidence": [ - 0 - ] - }, - { - "from": "LOOP", - "event": "produce_new_op", - "to": "EMIT_REQ", - "evidence": [ - 0 - ] - }, - { - "from": "LOOP", - "event": "program_returns", - "to": "EMIT_TERM", - "evidence": [ - 0 - ] - }, - { - "from": "LOOP", - "event": "requirement_fails", - "to": "EMIT_TERM", - "evidence": [ - 0 - ] - }, - { - "from": "EMIT_REQ", - "event": "emit_request", - "to": "EXITING", - "evidence": [ - 0 - ] - }, - { - "from": "EMIT_TERM", - "event": "emit_terminal", - "to": "EXITING", - "evidence": [ - 0 - ] - }, - { - "from": "EMIT_DIV", - "event": "emit_diverged", - "to": "EXITING", - "evidence": [ - 0 - ] - }, - { - "from": "EXITING", - "event": "exit_process", - "to": "DONE", - "evidence": [ - 1 - ] - } - ], - "reference": { - "states": [ - { - "id": "R0" - }, - { - "id": "R1" - }, - { - "id": "R2" - } - ], - "transitions": [ - { - "from": "R0", - "event": "emit_request", - "to": "R1" - }, - { - "from": "R0", - "event": "emit_terminal", - "to": "R1" - }, - { - "from": "R0", - "event": "emit_diverged", - "to": "R1" - }, - { - "from": "R1", - "event": "exit_process", - "to": "R2" - } - ] - }, - "targets": { - "selector": "marked" - }, - "unknowns": [ - "A future output variant must be added coherently to every SDK surface, the canonical IR, protocol admission, engine dispatch, and conformance fixtures.", - "Determinism between yields is the program author's obligation in every language; the contract detects divergence, it cannot prevent nondeterminism." - ] -} diff --git a/docs/locus/yield-diag-correlated.json b/docs/locus/yield-diag-correlated.json deleted file mode 100644 index ee1eb8e..0000000 --- a/docs/locus/yield-diag-correlated.json +++ /dev/null @@ -1,344 +0,0 @@ -{ - "schema_version": 1, - "id": "yield-offprotocol-correlated-v1", - "subject": "Yield off-protocol fault diagnosis, correlated mode: a host adapter surfaces agent actions as observed events correlated with the run log.", - "evidence": [ - { - "path": "private/yield-landing/index.html", - "note": "design artifact: run-log states, five primitives, stale/duplicate rejection, evidence-bound completion, replay-diverges-loudly" - } - ], - "states": [ - { - "id": "CREATED" - }, - { - "id": "RUNNING" - }, - { - "id": "PENDING_OP" - }, - { - "id": "OFF_PROTOCOL" - }, - { - "id": "STALE_RECEIVED" - }, - { - "id": "VALIDATING" - }, - { - "id": "REPLAYING" - }, - { - "id": "REQ_FAILED" - }, - { - "id": "DIVERGED" - }, - { - "id": "COMPLETED", - "marked": true - }, - { - "id": "BLOCKED", - "marked": true - }, - { - "id": "REFUSED", - "marked": true - } - ], - "events": [ - { - "id": "start", - "controllable": true, - "observable": true - }, - { - "id": "yield_op", - "controllable": true, - "observable": true - }, - { - "id": "submit_response", - "controllable": false, - "observable": true - }, - { - "id": "submit_stale", - "controllable": false, - "observable": true - }, - { - "id": "reject_stale", - "controllable": true, - "observable": true - }, - { - "id": "accept_stale", - "controllable": true, - "observable": true - }, - { - "id": "schema_reject", - "controllable": true, - "observable": true - }, - { - "id": "accept_response", - "controllable": true, - "observable": true - }, - { - "id": "replay_ok", - "controllable": false, - "observable": true - }, - { - "id": "replay_diverge", - "controllable": false, - "observable": true - }, - { - "id": "migrate_digest", - "controllable": true, - "observable": true - }, - { - "id": "require_fail", - "controllable": false, - "observable": true - }, - { - "id": "complete", - "controllable": true, - "observable": true - }, - { - "id": "complete_unproven", - "controllable": true, - "observable": true - }, - { - "id": "declare_blocked", - "controllable": true, - "observable": true - }, - { - "id": "declare_refused", - "controllable": true, - "observable": true - }, - { - "id": "archive", - "controllable": false, - "observable": true - }, - { - "id": "agent_off_protocol", - "controllable": false, - "observable": true - } - ], - "transitions": [ - { - "from": "CREATED", - "event": "start", - "to": "RUNNING", - "evidence": [ - 0 - ] - }, - { - "from": "RUNNING", - "event": "yield_op", - "to": "PENDING_OP", - "evidence": [ - 0 - ] - }, - { - "from": "RUNNING", - "event": "require_fail", - "to": "REQ_FAILED", - "evidence": [ - 0 - ] - }, - { - "from": "RUNNING", - "event": "complete", - "to": "COMPLETED", - "evidence": [ - 0 - ] - }, - { - "from": "RUNNING", - "event": "declare_blocked", - "to": "BLOCKED", - "evidence": [ - 0 - ] - }, - { - "from": "RUNNING", - "event": "declare_refused", - "to": "REFUSED", - "evidence": [ - 0 - ] - }, - { - "from": "PENDING_OP", - "event": "submit_response", - "to": "VALIDATING", - "evidence": [ - 0 - ] - }, - { - "from": "PENDING_OP", - "event": "submit_stale", - "to": "STALE_RECEIVED", - "evidence": [ - 0 - ] - }, - { - "from": "STALE_RECEIVED", - "event": "reject_stale", - "to": "PENDING_OP", - "evidence": [ - 0 - ] - }, - { - "from": "STALE_RECEIVED", - "event": "accept_stale", - "to": "REPLAYING", - "evidence": [ - 0 - ] - }, - { - "from": "VALIDATING", - "event": "schema_reject", - "to": "PENDING_OP", - "evidence": [ - 0 - ] - }, - { - "from": "VALIDATING", - "event": "accept_response", - "to": "REPLAYING", - "evidence": [ - 0 - ] - }, - { - "from": "REPLAYING", - "event": "replay_ok", - "to": "RUNNING", - "evidence": [ - 0 - ] - }, - { - "from": "REPLAYING", - "event": "replay_diverge", - "to": "DIVERGED", - "evidence": [ - 0 - ] - }, - { - "from": "DIVERGED", - "event": "migrate_digest", - "to": "REPLAYING", - "evidence": [ - 0 - ] - }, - { - "from": "DIVERGED", - "event": "declare_blocked", - "to": "BLOCKED", - "evidence": [ - 0 - ] - }, - { - "from": "REQ_FAILED", - "event": "declare_blocked", - "to": "BLOCKED", - "evidence": [ - 0 - ] - }, - { - "from": "REQ_FAILED", - "event": "complete_unproven", - "to": "COMPLETED", - "evidence": [ - 0 - ] - }, - { - "from": "COMPLETED", - "event": "archive", - "to": "COMPLETED", - "evidence": [ - 0 - ] - }, - { - "from": "BLOCKED", - "event": "archive", - "to": "BLOCKED", - "evidence": [ - 0 - ] - }, - { - "from": "REFUSED", - "event": "archive", - "to": "REFUSED", - "evidence": [ - 0 - ] - }, - { - "from": "PENDING_OP", - "event": "agent_off_protocol", - "to": "OFF_PROTOCOL", - "evidence": [ - 0 - ] - }, - { - "from": "OFF_PROTOCOL", - "event": "submit_response", - "to": "VALIDATING", - "evidence": [ - 0 - ] - } - ], - "spec": { - "description": "Entering OFF_PROTOCOL \u2014 the agent performed actions outside the yielded operation \u2014 is the fault under diagnosis.", - "forbidden_states": [ - "OFF_PROTOCOL" - ] - }, - "targets": { - "selector": "marked" - }, - "unknowns": [ - "The runtime is not yet implemented; this model is the design intent for labs/22-yield (Go), grounded only in the design artifact.", - "agent_task response content can be fabricated while schema-valid; schema_reject only rejects shape, not truth.", - "Whether run_command is executed by yskill itself (observed fact) or by the agent (transcription) is a design decision pending in the plan." - ] -} \ No newline at end of file diff --git a/docs/locus/yield-diag-portable.json b/docs/locus/yield-diag-portable.json deleted file mode 100644 index b0500b1..0000000 --- a/docs/locus/yield-diag-portable.json +++ /dev/null @@ -1,344 +0,0 @@ -{ - "schema_version": 1, - "id": "yield-offprotocol-portable-v1", - "subject": "Yield off-protocol fault diagnosis, portable mode: the agent acts outside the yielded operation; the run log sees only protocol events.", - "evidence": [ - { - "path": "private/yield-landing/index.html", - "note": "design artifact: run-log states, five primitives, stale/duplicate rejection, evidence-bound completion, replay-diverges-loudly" - } - ], - "states": [ - { - "id": "CREATED" - }, - { - "id": "RUNNING" - }, - { - "id": "PENDING_OP" - }, - { - "id": "OFF_PROTOCOL" - }, - { - "id": "STALE_RECEIVED" - }, - { - "id": "VALIDATING" - }, - { - "id": "REPLAYING" - }, - { - "id": "REQ_FAILED" - }, - { - "id": "DIVERGED" - }, - { - "id": "COMPLETED", - "marked": true - }, - { - "id": "BLOCKED", - "marked": true - }, - { - "id": "REFUSED", - "marked": true - } - ], - "events": [ - { - "id": "start", - "controllable": true, - "observable": true - }, - { - "id": "yield_op", - "controllable": true, - "observable": true - }, - { - "id": "submit_response", - "controllable": false, - "observable": true - }, - { - "id": "submit_stale", - "controllable": false, - "observable": true - }, - { - "id": "reject_stale", - "controllable": true, - "observable": true - }, - { - "id": "accept_stale", - "controllable": true, - "observable": true - }, - { - "id": "schema_reject", - "controllable": true, - "observable": true - }, - { - "id": "accept_response", - "controllable": true, - "observable": true - }, - { - "id": "replay_ok", - "controllable": false, - "observable": true - }, - { - "id": "replay_diverge", - "controllable": false, - "observable": true - }, - { - "id": "migrate_digest", - "controllable": true, - "observable": true - }, - { - "id": "require_fail", - "controllable": false, - "observable": true - }, - { - "id": "complete", - "controllable": true, - "observable": true - }, - { - "id": "complete_unproven", - "controllable": true, - "observable": true - }, - { - "id": "declare_blocked", - "controllable": true, - "observable": true - }, - { - "id": "declare_refused", - "controllable": true, - "observable": true - }, - { - "id": "archive", - "controllable": false, - "observable": true - }, - { - "id": "agent_off_protocol", - "controllable": false, - "observable": false - } - ], - "transitions": [ - { - "from": "CREATED", - "event": "start", - "to": "RUNNING", - "evidence": [ - 0 - ] - }, - { - "from": "RUNNING", - "event": "yield_op", - "to": "PENDING_OP", - "evidence": [ - 0 - ] - }, - { - "from": "RUNNING", - "event": "require_fail", - "to": "REQ_FAILED", - "evidence": [ - 0 - ] - }, - { - "from": "RUNNING", - "event": "complete", - "to": "COMPLETED", - "evidence": [ - 0 - ] - }, - { - "from": "RUNNING", - "event": "declare_blocked", - "to": "BLOCKED", - "evidence": [ - 0 - ] - }, - { - "from": "RUNNING", - "event": "declare_refused", - "to": "REFUSED", - "evidence": [ - 0 - ] - }, - { - "from": "PENDING_OP", - "event": "submit_response", - "to": "VALIDATING", - "evidence": [ - 0 - ] - }, - { - "from": "PENDING_OP", - "event": "submit_stale", - "to": "STALE_RECEIVED", - "evidence": [ - 0 - ] - }, - { - "from": "STALE_RECEIVED", - "event": "reject_stale", - "to": "PENDING_OP", - "evidence": [ - 0 - ] - }, - { - "from": "STALE_RECEIVED", - "event": "accept_stale", - "to": "REPLAYING", - "evidence": [ - 0 - ] - }, - { - "from": "VALIDATING", - "event": "schema_reject", - "to": "PENDING_OP", - "evidence": [ - 0 - ] - }, - { - "from": "VALIDATING", - "event": "accept_response", - "to": "REPLAYING", - "evidence": [ - 0 - ] - }, - { - "from": "REPLAYING", - "event": "replay_ok", - "to": "RUNNING", - "evidence": [ - 0 - ] - }, - { - "from": "REPLAYING", - "event": "replay_diverge", - "to": "DIVERGED", - "evidence": [ - 0 - ] - }, - { - "from": "DIVERGED", - "event": "migrate_digest", - "to": "REPLAYING", - "evidence": [ - 0 - ] - }, - { - "from": "DIVERGED", - "event": "declare_blocked", - "to": "BLOCKED", - "evidence": [ - 0 - ] - }, - { - "from": "REQ_FAILED", - "event": "declare_blocked", - "to": "BLOCKED", - "evidence": [ - 0 - ] - }, - { - "from": "REQ_FAILED", - "event": "complete_unproven", - "to": "COMPLETED", - "evidence": [ - 0 - ] - }, - { - "from": "COMPLETED", - "event": "archive", - "to": "COMPLETED", - "evidence": [ - 0 - ] - }, - { - "from": "BLOCKED", - "event": "archive", - "to": "BLOCKED", - "evidence": [ - 0 - ] - }, - { - "from": "REFUSED", - "event": "archive", - "to": "REFUSED", - "evidence": [ - 0 - ] - }, - { - "from": "PENDING_OP", - "event": "agent_off_protocol", - "to": "OFF_PROTOCOL", - "evidence": [ - 0 - ] - }, - { - "from": "OFF_PROTOCOL", - "event": "submit_response", - "to": "VALIDATING", - "evidence": [ - 0 - ] - } - ], - "spec": { - "description": "Entering OFF_PROTOCOL \u2014 the agent performed actions outside the yielded operation \u2014 is the fault under diagnosis.", - "forbidden_states": [ - "OFF_PROTOCOL" - ] - }, - "targets": { - "selector": "marked" - }, - "unknowns": [ - "The runtime is not yet implemented; this model is the design intent for labs/22-yield (Go), grounded only in the design artifact.", - "agent_task response content can be fabricated while schema-valid; schema_reject only rejects shape, not truth.", - "Whether run_command is executed by yskill itself (observed fact) or by the agent (transcription) is a design decision pending in the plan." - ] -} \ No newline at end of file diff --git a/docs/locus/yield-protocol.json b/docs/locus/yield-protocol.json deleted file mode 100644 index 222c5f7..0000000 --- a/docs/locus/yield-protocol.json +++ /dev/null @@ -1,327 +0,0 @@ -{ - "schema_version": 1, - "id": "yield-run-lifecycle-protocol-v1", - "subject": "Yield run lifecycle (labs/22-yield design): a Go yskill runtime executes a deterministic skill program that yields typed operations to a coding agent; append-only run log, replay-based resume; evidence-bound completion.", - "evidence": [ - { - "path": "private/yield-landing/index.html", - "note": "design artifact: run-log states, five primitives, stale/duplicate rejection, evidence-bound completion, replay-diverges-loudly" - } - ], - "states": [ - { - "id": "CREATED" - }, - { - "id": "RUNNING" - }, - { - "id": "PENDING_OP" - }, - { - "id": "STALE_RECEIVED" - }, - { - "id": "VALIDATING" - }, - { - "id": "REPLAYING" - }, - { - "id": "REQ_FAILED" - }, - { - "id": "DIVERGED" - }, - { - "id": "COMPLETED", - "marked": true - }, - { - "id": "BLOCKED", - "marked": true - }, - { - "id": "REFUSED", - "marked": true - } - ], - "events": [ - { - "id": "start", - "controllable": true, - "observable": true - }, - { - "id": "yield_op", - "controllable": true, - "observable": true - }, - { - "id": "submit_response", - "controllable": false, - "observable": true - }, - { - "id": "submit_stale", - "controllable": false, - "observable": true - }, - { - "id": "reject_stale", - "controllable": true, - "observable": true - }, - { - "id": "accept_stale", - "controllable": true, - "observable": true - }, - { - "id": "schema_reject", - "controllable": true, - "observable": true - }, - { - "id": "accept_response", - "controllable": true, - "observable": true - }, - { - "id": "replay_ok", - "controllable": false, - "observable": true - }, - { - "id": "replay_diverge", - "controllable": false, - "observable": true - }, - { - "id": "migrate_digest", - "controllable": true, - "observable": true - }, - { - "id": "require_fail", - "controllable": false, - "observable": true - }, - { - "id": "complete", - "controllable": true, - "observable": true - }, - { - "id": "complete_unproven", - "controllable": true, - "observable": true - }, - { - "id": "declare_blocked", - "controllable": true, - "observable": true - }, - { - "id": "declare_refused", - "controllable": true, - "observable": true - }, - { - "id": "archive", - "controllable": false, - "observable": true - } - ], - "transitions": [ - { - "from": "CREATED", - "event": "start", - "to": "RUNNING", - "evidence": [ - 0 - ] - }, - { - "from": "RUNNING", - "event": "yield_op", - "to": "PENDING_OP", - "evidence": [ - 0 - ] - }, - { - "from": "RUNNING", - "event": "require_fail", - "to": "REQ_FAILED", - "evidence": [ - 0 - ] - }, - { - "from": "RUNNING", - "event": "complete", - "to": "COMPLETED", - "evidence": [ - 0 - ] - }, - { - "from": "RUNNING", - "event": "declare_blocked", - "to": "BLOCKED", - "evidence": [ - 0 - ] - }, - { - "from": "RUNNING", - "event": "declare_refused", - "to": "REFUSED", - "evidence": [ - 0 - ] - }, - { - "from": "PENDING_OP", - "event": "submit_response", - "to": "VALIDATING", - "evidence": [ - 0 - ] - }, - { - "from": "PENDING_OP", - "event": "submit_stale", - "to": "STALE_RECEIVED", - "evidence": [ - 0 - ] - }, - { - "from": "STALE_RECEIVED", - "event": "reject_stale", - "to": "PENDING_OP", - "evidence": [ - 0 - ] - }, - { - "from": "STALE_RECEIVED", - "event": "accept_stale", - "to": "REPLAYING", - "evidence": [ - 0 - ] - }, - { - "from": "VALIDATING", - "event": "schema_reject", - "to": "PENDING_OP", - "evidence": [ - 0 - ] - }, - { - "from": "VALIDATING", - "event": "accept_response", - "to": "REPLAYING", - "evidence": [ - 0 - ] - }, - { - "from": "REPLAYING", - "event": "replay_ok", - "to": "RUNNING", - "evidence": [ - 0 - ] - }, - { - "from": "REPLAYING", - "event": "replay_diverge", - "to": "DIVERGED", - "evidence": [ - 0 - ] - }, - { - "from": "DIVERGED", - "event": "migrate_digest", - "to": "REPLAYING", - "evidence": [ - 0 - ] - }, - { - "from": "DIVERGED", - "event": "declare_blocked", - "to": "BLOCKED", - "evidence": [ - 0 - ] - }, - { - "from": "REQ_FAILED", - "event": "declare_blocked", - "to": "BLOCKED", - "evidence": [ - 0 - ] - }, - { - "from": "REQ_FAILED", - "event": "complete_unproven", - "to": "COMPLETED", - "evidence": [ - 0 - ] - }, - { - "from": "COMPLETED", - "event": "archive", - "to": "COMPLETED", - "evidence": [ - 0 - ] - }, - { - "from": "BLOCKED", - "event": "archive", - "to": "BLOCKED", - "evidence": [ - 0 - ] - }, - { - "from": "REFUSED", - "event": "archive", - "to": "REFUSED", - "evidence": [ - 0 - ] - } - ], - "spec": { - "description": "Protocol-integrity spec: a stale/duplicate response must never be accepted into replay, and a run whose requirement failed must never complete.", - "forbidden_transitions": [ - { - "from": "STALE_RECEIVED", - "event": "accept_stale" - }, - { - "from": "REQ_FAILED", - "event": "complete_unproven" - } - ] - }, - "targets": { - "selector": "marked" - }, - "unknowns": [ - "The runtime is not yet implemented; this model is the design intent for labs/22-yield (Go), grounded only in the design artifact.", - "agent_task response content can be fabricated while schema-valid; schema_reject only rejects shape, not truth.", - "Whether run_command is executed by yskill itself (observed fact) or by the agent (transcription) is a design decision pending in the plan." - ] -} \ No newline at end of file diff --git a/docs/reference/guarantees.md b/docs/reference/guarantees.md index 98fe170..220ce85 100644 --- a/docs/reference/guarantees.md +++ b/docs/reference/guarantees.md @@ -26,6 +26,5 @@ orchestrator. Use `RunCommand` for facts the machine can observe, `AskUser` for human -authority, and explicit tests for the paths that matter. The formal scope is -documented in [`locus-yield.md`](../locus-yield.md) and -[`locus-conformance.md`](../locus-conformance.md). +authority, and explicit tests for the paths that matter. Runtime and +conformance tests define the verified scope. diff --git a/evals/results/latest.json b/evals/results/latest.json index 769b95d..5968aa3 100644 --- a/evals/results/latest.json +++ b/evals/results/latest.json @@ -1,8 +1,8 @@ { "schema_version": 2, "methodology_version": "1.1", - "generated_at": "2026-08-07T06:48:04.494Z", - "source_digest": "b84acf911139d392a12774d10b255d9ff396e91f6356d349920560e75b90d4f3", + "generated_at": "2026-08-07T09:37:20.395Z", + "source_digest": "88346db6f97443ded683c99283a07f2695805bf2628e113acab5fbc8a041e268", "status": "passed", "workflow_conformance": { "passed": 40, diff --git a/examples/convert-skill/main.go b/examples/convert-skill/main.go index 2870b03..f0e4cd8 100644 --- a/examples/convert-skill/main.go +++ b/examples/convert-skill/main.go @@ -1,9 +1,8 @@ // convert-skill: the converter is itself a Yield skill. It turns an // existing prose SKILL.md into a Yield program in the operator's chosen // language, and it completes ONLY when the generated skill passes its own -// fixture run under yskill test — the Locus-decided design -// (docs/locus/convert-verified.json vs convert-transcribed.json: shipping -// on the model's transcription is rejected with a violating trace). +// fixture run under yskill test. A transcription alone cannot complete the +// conversion. // // Division of labor: the program owns the pipeline order, the language // menu, the retry bound, and the evidence gate. The model owns reading diff --git a/internal/conformance/conformance_test.go b/internal/conformance/conformance_test.go index a4bcec1..88e83ab 100644 --- a/internal/conformance/conformance_test.go +++ b/internal/conformance/conformance_test.go @@ -2,10 +2,8 @@ // program, written in Go, TypeScript, Python, and Rust, driven through the // real supervisor, must exhibit identical observable protocol behavior. // -// The scenario matrix is the discharge of the Locus derivation's -// obligations (docs/locus-conformance.md maps each obligation to the test -// that observes it). Languages whose toolchain is absent are skipped with -// a notice — CI provides all four. +// The scenario matrix verifies the shared contract. Languages whose toolchain +// is absent are skipped with a notice. CI provides all four. package conformance import ( diff --git a/internal/guard/guard.go b/internal/guard/guard.go index 2a1372e..33f921d 100644 --- a/internal/guard/guard.go +++ b/internal/guard/guard.go @@ -1,7 +1,5 @@ -// Package guard owns every refusal in the protocol. Each rejection reason -// corresponds to a supervisory obligation from the Locus derivation -// (docs/locus): the controllability theorem rests on these events being -// genuinely refusable, so each has a named check and a refusing test. +// Package guard owns every protocol refusal. Each rejection reason has a +// named check and a test that proves the request is refused. package guard import ( diff --git a/internal/guard/guard_test.go b/internal/guard/guard_test.go index 15b9959..b7a76bf 100644 --- a/internal/guard/guard_test.go +++ b/internal/guard/guard_test.go @@ -8,9 +8,7 @@ import ( "github.com/operatorstack/yield/internal/protocol" ) -// These tests are the discharge of the supervisory obligations from the -// Locus derivation (docs/locus): each controllable event the theorem -// rests on has a genuine refusing mechanism, exhibited here. +// These tests verify that every declared rejection has a working refusal path. func pendingState() *RunState { return &RunState{ diff --git a/ir/README.md b/ir/README.md index 0cfb0ee..341e949 100644 --- a/ir/README.md +++ b/ir/README.md @@ -16,21 +16,17 @@ surface and nothing else. | `yield.v1/journal.schema.json` | the replay input: run identity + answered operations in order | | `yield.v1/program-output.schema.json` | the single output of one skill-program execution: `request` \| `terminal` \| `diverged` | -## The SDK execution contract (Locus-certified) +## The SDK execution contract -Every SDK must exhibit the contract certified in -`docs/locus/sdk-contract.json` (trace-refinement: refines the supervisor's -expectation; nonblocking): +Every SDK must implement this tested contract: 1. Read the journal from the file named by `YIELD_JOURNAL`. 2. Re-execute the program from the top. For every operation the program produces while journal entries remain: recompute the request digest and compare with the recorded entry **before consuming its response**. On mismatch, emit `diverged` and exit. This per-step check is not - optional — the rival design (supervisor-only frontier checking) is - rejected with a violating trace in `docs/locus/drv-ad50b13e….json`: - a drifted operation would silently consume a recorded response meant - for a different question. + optional. Without it, a changed operation could consume a recorded + response meant for a different question. 3. At the first operation past the journal, emit a `request` output and exit. When the program returns, emit a `terminal` output (`completed` | `blocked` | `refused`; a failed requirement emits diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..dd45d80 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,1308 @@ +{ + "name": "@operatorstack/yield-repository", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "@operatorstack/yield-repository", + "devDependencies": { + "@changesets/cli": "2.31.1", + "yaml": "2.9.0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.7.tgz", + "integrity": "sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@changesets/apply-release-plan": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/@changesets/apply-release-plan/-/apply-release-plan-7.1.1.tgz", + "integrity": "sha512-9qPCm/rLx/xoOFXIHGB229+4GOL76S4MC+7tyOuTsR6+1jYlfFDQORdvwR5hDA6y4FL2BPt3qpbcQIS+dW85LA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/config": "^3.1.4", + "@changesets/get-version-range-type": "^0.4.0", + "@changesets/git": "^3.0.4", + "@changesets/should-skip-package": "^0.1.2", + "@changesets/types": "^6.1.0", + "@manypkg/get-packages": "^1.1.3", + "detect-indent": "^6.0.0", + "fs-extra": "^7.0.1", + "lodash.startcase": "^4.4.0", + "outdent": "^0.5.0", + "prettier": "^2.7.1", + "resolve-from": "^5.0.0", + "semver": "^7.5.3" + } + }, + "node_modules/@changesets/assemble-release-plan": { + "version": "6.0.10", + "resolved": "https://registry.npmjs.org/@changesets/assemble-release-plan/-/assemble-release-plan-6.0.10.tgz", + "integrity": "sha512-rSDcqdJ9KbVyjpBIuCidhvZNIiVt1XaIYp73ycVQRIA5n/j6wQaEk0ChRLMUQ1vkxZe51PTQ9OIhbg6HQMW45A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/errors": "^0.2.0", + "@changesets/get-dependents-graph": "^2.1.4", + "@changesets/should-skip-package": "^0.1.2", + "@changesets/types": "^6.1.0", + "@manypkg/get-packages": "^1.1.3", + "semver": "^7.5.3" + } + }, + "node_modules/@changesets/changelog-git": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@changesets/changelog-git/-/changelog-git-0.2.1.tgz", + "integrity": "sha512-x/xEleCFLH28c3bQeQIyeZf8lFXyDFVn1SgcBiR2Tw/r4IAWlk1fzxCEZ6NxQAjF2Nwtczoen3OA2qR+UawQ8Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/types": "^6.1.0" + } + }, + "node_modules/@changesets/cli": { + "version": "2.31.1", + "resolved": "https://registry.npmjs.org/@changesets/cli/-/cli-2.31.1.tgz", + "integrity": "sha512-uO05WTcRBwuVOJVSW8Cmpqw6q0WDL53ajGCMyszutvOe5toOnunbpM4jZzf+qxBOz7i0AzopZ8diBuewjmF40w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/apply-release-plan": "^7.1.1", + "@changesets/assemble-release-plan": "^6.0.10", + "@changesets/changelog-git": "^0.2.1", + "@changesets/config": "^3.1.4", + "@changesets/errors": "^0.2.0", + "@changesets/get-dependents-graph": "^2.1.4", + "@changesets/get-release-plan": "^4.0.16", + "@changesets/git": "^3.0.4", + "@changesets/logger": "^0.1.1", + "@changesets/pre": "^2.0.2", + "@changesets/read": "^0.6.7", + "@changesets/should-skip-package": "^0.1.2", + "@changesets/types": "^6.1.0", + "@changesets/write": "^0.4.0", + "@inquirer/external-editor": "^1.0.2", + "@manypkg/get-packages": "^1.1.3", + "ansi-colors": "^4.1.3", + "enquirer": "^2.4.1", + "fs-extra": "^7.0.1", + "mri": "^1.2.0", + "package-manager-detector": "^0.2.0", + "picocolors": "^1.1.0", + "resolve-from": "^5.0.0", + "semver": "^7.5.3", + "spawndamnit": "^3.0.1", + "term-size": "^2.1.0" + }, + "bin": { + "changeset": "bin.js" + } + }, + "node_modules/@changesets/config": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/@changesets/config/-/config-3.1.4.tgz", + "integrity": "sha512-pf0bvD/v6WI2cRlZ6hzpjtZdSlXDXMAJ+Iz7xfFzV4ZxJ8OGGAON+1qYc99ZPrijnt4xp3VGG7eNvAOGS24V1Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/errors": "^0.2.0", + "@changesets/get-dependents-graph": "^2.1.4", + "@changesets/logger": "^0.1.1", + "@changesets/should-skip-package": "^0.1.2", + "@changesets/types": "^6.1.0", + "@manypkg/get-packages": "^1.1.3", + "fs-extra": "^7.0.1", + "micromatch": "^4.0.8" + } + }, + "node_modules/@changesets/errors": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@changesets/errors/-/errors-0.2.0.tgz", + "integrity": "sha512-6BLOQUscTpZeGljvyQXlWOItQyU71kCdGz7Pi8H8zdw6BI0g3m43iL4xKUVPWtG+qrrL9DTjpdn8eYuCQSRpow==", + "dev": true, + "license": "MIT", + "dependencies": { + "extendable-error": "^0.1.5" + } + }, + "node_modules/@changesets/get-dependents-graph": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@changesets/get-dependents-graph/-/get-dependents-graph-2.1.4.tgz", + "integrity": "sha512-ZsS00x6WvmHq3sQv8oCMwL0f/z3wbXCVuSVTJwCnnmbC/iBdNJGFx1EcbMG4PC6sXRyH69liM4A2WKXzn/kRPg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/types": "^6.1.0", + "@manypkg/get-packages": "^1.1.3", + "picocolors": "^1.1.0", + "semver": "^7.5.3" + } + }, + "node_modules/@changesets/get-release-plan": { + "version": "4.0.16", + "resolved": "https://registry.npmjs.org/@changesets/get-release-plan/-/get-release-plan-4.0.16.tgz", + "integrity": "sha512-2K5Om6CrMPm45rtvckfzWo7e9jOVCKLCnXia5eUPaURH7/LWzri7pK1TycdzAuAtehLkW7VPbWLCSExTHmiI6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/assemble-release-plan": "^6.0.10", + "@changesets/config": "^3.1.4", + "@changesets/pre": "^2.0.2", + "@changesets/read": "^0.6.7", + "@changesets/types": "^6.1.0", + "@manypkg/get-packages": "^1.1.3" + } + }, + "node_modules/@changesets/get-version-range-type": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@changesets/get-version-range-type/-/get-version-range-type-0.4.0.tgz", + "integrity": "sha512-hwawtob9DryoGTpixy1D3ZXbGgJu1Rhr+ySH2PvTLHvkZuQ7sRT4oQwMh0hbqZH1weAooedEjRsbrWcGLCeyVQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@changesets/git": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@changesets/git/-/git-3.0.4.tgz", + "integrity": "sha512-BXANzRFkX+XcC1q/d27NKvlJ1yf7PSAgi8JG6dt8EfbHFHi4neau7mufcSca5zRhwOL8j9s6EqsxmT+s+/E6Sw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/errors": "^0.2.0", + "@manypkg/get-packages": "^1.1.3", + "is-subdir": "^1.1.1", + "micromatch": "^4.0.8", + "spawndamnit": "^3.0.1" + } + }, + "node_modules/@changesets/logger": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@changesets/logger/-/logger-0.1.1.tgz", + "integrity": "sha512-OQtR36ZlnuTxKqoW4Sv6x5YIhOmClRd5pWsjZsddYxpWs517R0HkyiefQPIytCVh4ZcC5x9XaG8KTdd5iRQUfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "picocolors": "^1.1.0" + } + }, + "node_modules/@changesets/parse": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@changesets/parse/-/parse-0.4.3.tgz", + "integrity": "sha512-ZDmNc53+dXdWEv7fqIUSgRQOLYoUom5Z40gmLgmATmYR9NbL6FJJHwakcCpzaeCy+1D0m0n7mT4jj2B/MQPl7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/types": "^6.1.0", + "js-yaml": "^4.1.1" + } + }, + "node_modules/@changesets/pre": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@changesets/pre/-/pre-2.0.2.tgz", + "integrity": "sha512-HaL/gEyFVvkf9KFg6484wR9s0qjAXlZ8qWPDkTyKF6+zqjBe/I2mygg3MbpZ++hdi0ToqNUF8cjj7fBy0dg8Ug==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/errors": "^0.2.0", + "@changesets/types": "^6.1.0", + "@manypkg/get-packages": "^1.1.3", + "fs-extra": "^7.0.1" + } + }, + "node_modules/@changesets/read": { + "version": "0.6.7", + "resolved": "https://registry.npmjs.org/@changesets/read/-/read-0.6.7.tgz", + "integrity": "sha512-D1G4AUYGrBEk8vj8MGwf75k9GpN6XL3wg8i42P2jZZwFLXnlr2Pn7r9yuQNbaMCarP7ZQWNJbV6XLeysAIMhTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/git": "^3.0.4", + "@changesets/logger": "^0.1.1", + "@changesets/parse": "^0.4.3", + "@changesets/types": "^6.1.0", + "fs-extra": "^7.0.1", + "p-filter": "^2.1.0", + "picocolors": "^1.1.0" + } + }, + "node_modules/@changesets/should-skip-package": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@changesets/should-skip-package/-/should-skip-package-0.1.2.tgz", + "integrity": "sha512-qAK/WrqWLNCP22UDdBTMPH5f41elVDlsNyat180A33dWxuUDyNpg6fPi/FyTZwRriVjg0L8gnjJn2F9XAoF0qw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/types": "^6.1.0", + "@manypkg/get-packages": "^1.1.3" + } + }, + "node_modules/@changesets/types": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@changesets/types/-/types-6.1.0.tgz", + "integrity": "sha512-rKQcJ+o1nKNgeoYRHKOS07tAMNd3YSN0uHaJOZYjBAgxfV7TUE7JE+z4BzZdQwb5hKaYbayKN5KrYV7ODb2rAA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@changesets/write": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@changesets/write/-/write-0.4.0.tgz", + "integrity": "sha512-CdTLvIOPiCNuH71pyDu3rA+Q0n65cmAbXnwWH84rKGiFumFzkmHNT8KHTMEchcxN+Kl8I54xGUhJ7l3E7X396Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/types": "^6.1.0", + "fs-extra": "^7.0.1", + "human-id": "^4.1.1", + "prettier": "^2.7.1" + } + }, + "node_modules/@inquirer/external-editor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@inquirer/external-editor/-/external-editor-1.0.3.tgz", + "integrity": "sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA==", + "dev": true, + "license": "MIT", + "dependencies": { + "chardet": "^2.1.1", + "iconv-lite": "^0.7.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@manypkg/find-root": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@manypkg/find-root/-/find-root-1.1.0.tgz", + "integrity": "sha512-mki5uBvhHzO8kYYix/WRy2WX8S3B5wdVSc9D6KcU5lQNglP2yt58/VfLuAK49glRXChosY8ap2oJ1qgma3GUVA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.5.5", + "@types/node": "^12.7.1", + "find-up": "^4.1.0", + "fs-extra": "^8.1.0" + } + }, + "node_modules/@manypkg/find-root/node_modules/@types/node": { + "version": "12.20.55", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", + "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@manypkg/find-root/node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/@manypkg/get-packages": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@manypkg/get-packages/-/get-packages-1.1.3.tgz", + "integrity": "sha512-fo+QhuU3qE/2TQMQmbVMqaQ6EWbMhi4ABWP+O4AM1NqPBuy0OrApV5LO6BrrgnhtAHS2NH6RrVk9OL181tTi8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.5.5", + "@changesets/types": "^4.0.1", + "@manypkg/find-root": "^1.1.0", + "fs-extra": "^8.1.0", + "globby": "^11.0.0", + "read-yaml-file": "^1.1.0" + } + }, + "node_modules/@manypkg/get-packages/node_modules/@changesets/types": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@changesets/types/-/types-4.1.0.tgz", + "integrity": "sha512-LDQvVDv5Kb50ny2s25Fhm3d9QSZimsoUGBsUioj6MC3qbMUCuC8GPIvk/M6IvXx3lYhAs0lwWUQLb+VIEUCECw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@manypkg/get-packages/node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@types/node": { + "version": "26.1.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-26.1.2.tgz", + "integrity": "sha512-Vu4a5UFA9rIIFJ7rB/Vaafh9lrCQszopTCx6KjFboXTGQbPNasehVR5TEiithSDGyd1DEiUByggTZsg8jukeIg==", + "extraneous": true, + "license": "MIT", + "dependencies": { + "undici-types": "~8.3.0" + } + }, + "node_modules/ansi-colors": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/better-path-resolve": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/better-path-resolve/-/better-path-resolve-1.0.0.tgz", + "integrity": "sha512-pbnl5XzGBdrFU/wT4jqmJVPn2B6UHPBOhzMQkY/SPUPB6QtUXtmBHBIwCbXJol93mOpGMnQyP/+BB19q04xj7g==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-windows": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/chardet": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-2.2.0.tgz", + "integrity": "sha512-rddelWYNPRrXq6PtNEN2S3f6t9ILzvqaN5pVgi4kqt9jHQaXIial9PznB5iSPVlQSLNaaH22ItWz3EJtQ10+OA==", + "dev": true, + "license": "MIT" + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/detect-indent": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz", + "integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/enquirer": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz", + "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-colors": "^4.1.1", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/extendable-error": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/extendable-error/-/extendable-error-0.1.7.tgz", + "integrity": "sha512-UOiS2in6/Q0FK0R0q6UY9vYpQ21mr/Qn1KOnte7vsACuNJf514WvCCUHSRCPcgjPT2bAhNIJdlE6bVap1GKmeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fastq": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz", + "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/human-id": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/human-id/-/human-id-4.2.0.tgz", + "integrity": "sha512-K3GbkIWqyvvlpfhBPlbEvD97TtqBpAYA4kt+cn2lD2x2HuohzZCibcA2nOlnJT6exqvJLggoB5nv2dNf192nEA==", + "dev": true, + "license": "MIT", + "bin": { + "human-id": "dist/cli.js" + } + }, + "node_modules/iconv-lite": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.3.tgz", + "integrity": "sha512-IKXpvIzjnC9XTAUbVBcMfGS0EPaIXtW6v+zr+RRp+hqULEpo0owZax6wyRwPOJbWbzjYspQwusTsfVr0ifh4uQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-subdir": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-subdir/-/is-subdir-1.2.0.tgz", + "integrity": "sha512-2AT6j+gXe/1ueqbW6fLZJiIw3F8iXGJtt0yDrZaBhAZEG1raiTxKWU+IPqMCzQAXOUCKdA4UDMgacKH25XG2Cw==", + "dev": true, + "license": "MIT", + "dependencies": { + "better-path-resolve": "1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/js-yaml": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.1.tgz", + "integrity": "sha512-CY6crGq313MX8GkwvB7tzgp99vjQxY1++5y10/BKN/GUfHqWaOGQMNZkBvqSzsZKWk/ijwHlWzzkLulsGHhjWQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/puzrin" + }, + { + "type": "github", + "url": "https://github.com/sponsors/nodeca" + } + ], + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "dev": true, + "license": "MIT", + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lodash.startcase": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.startcase/-/lodash.startcase-4.4.0.tgz", + "integrity": "sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==", + "dev": true, + "license": "MIT" + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mri": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", + "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/outdent": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/outdent/-/outdent-0.5.0.tgz", + "integrity": "sha512-/jHxFIzoMXdqPzTaCpFzAAWhpkSjZPF4Vsn6jAfNpmbH/ymsmd7Qc6VE9BGn0L6YMj6uwpQLxCECpus4ukKS9Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/p-filter": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-filter/-/p-filter-2.1.0.tgz", + "integrity": "sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-map": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-map": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", + "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/package-manager-detector": { + "version": "0.2.11", + "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-0.2.11.tgz", + "integrity": "sha512-BEnLolu+yuz22S56CU1SUKq3XC3PkwD5wv4ikR4MfGvnRVcmzXR9DwSlW2fEamyTPyXHomBJRzgapeuBvRNzJQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "quansync": "^0.2.7" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/prettier": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", + "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/quansync": { + "version": "0.2.11", + "resolved": "https://registry.npmjs.org/quansync/-/quansync-0.2.11.tgz", + "integrity": "sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/antfu" + }, + { + "type": "individual", + "url": "https://github.com/sponsors/sxzz" + } + ], + "license": "MIT" + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/read-yaml-file": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/read-yaml-file/-/read-yaml-file-1.1.0.tgz", + "integrity": "sha512-VIMnQi/Z4HT2Fxuwg5KrY174U1VdUIASQVWXXyqtNRtxSr9IYkn1rsI6Tb6HsrHCmB7gVpNwX6JxPTHcH6IoTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.5", + "js-yaml": "^3.6.1", + "pify": "^4.0.1", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/read-yaml-file/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/read-yaml-file/node_modules/js-yaml": { + "version": "3.15.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.15.1.tgz", + "integrity": "sha512-S99WuO3HlhO3XN41EtYUNl9zzXjoJx7QvmipxsJVxtCBT0YHEFy+iOJhjSvrmV12nYhWpZaM8lPHkJm0yUMbag==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true, + "license": "MIT" + }, + "node_modules/semver": { + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/spawndamnit": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spawndamnit/-/spawndamnit-3.0.1.tgz", + "integrity": "sha512-MmnduQUuHCoFckZoWnXsTg7JaiLBJrKFj9UI2MbRPGaJeVpsLcVBu6P/IGZovziM/YBsellCmsprgNA+w0CzVg==", + "dev": true, + "license": "SEE LICENSE IN LICENSE", + "dependencies": { + "cross-spawn": "^7.0.5", + "signal-exit": "^4.0.1" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/term-size": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.1.tgz", + "integrity": "sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/undici-types": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-8.3.0.tgz", + "integrity": "sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ==", + "extraneous": true, + "license": "MIT" + }, + "node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/yaml": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.9.0.tgz", + "integrity": "sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==", + "dev": true, + "license": "ISC", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14.6" + }, + "funding": { + "url": "https://github.com/sponsors/eemeli" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..5278ae6 --- /dev/null +++ b/package.json @@ -0,0 +1,13 @@ +{ + "name": "@operatorstack/yield-repository", + "private": true, + "scripts": { + "changeset": "changeset", + "release:plan": "node scripts/release-plan.mjs", + "test:release": "node --test scripts/*.test.mjs packaging/*.test.mjs" + }, + "devDependencies": { + "@changesets/cli": "2.31.1", + "yaml": "2.9.0" + } +} diff --git a/packaging/assemble.mjs b/packaging/assemble.mjs index 0a1248b..c321dff 100644 --- a/packaging/assemble.mjs +++ b/packaging/assemble.mjs @@ -1,5 +1,5 @@ #!/usr/bin/env node -import { chmod, cp, mkdir, readFile, rm, stat, writeFile } from "node:fs/promises"; +import { chmod, cp, mkdir, readFile, realpath, rm, stat, writeFile } from "node:fs/promises"; import { basename, join, resolve } from "node:path"; import { createHash } from "node:crypto"; import process from "node:process"; @@ -44,8 +44,17 @@ async function assembleNpm({ version, binaries, output }) { const npm = join(output, "npm"); const main = join(npm, "yield"); await cp(join(root, "sdk/typescript"), main, { recursive: true, filter: (source) => !source.includes("node_modules") && !source.includes("/dist") }); + await Promise.all([ + cp(join(root, "README.md"), join(main, "README.md")), + cp(join(root, "LICENSE"), join(main, "LICENSE")), + ]); const packageJson = await json(join(main, "package.json")); packageJson.version = version; + packageJson.publishConfig = { + access: "public", + provenance: true, + registry: "https://registry.npmjs.org/", + }; packageJson.optionalDependencies = Object.fromEntries(targets.map((target) => [npmPackage(target), version])); await writeFile(join(main, "package.json"), `${JSON.stringify(packageJson, null, 2)}\n`); @@ -54,10 +63,14 @@ async function assembleNpm({ version, binaries, output }) { const runtime = target.goos === "windows" ? "yskill.exe" : "yskill"; await mkdir(directory, { recursive: true }); await copyBinary(join(binaries, binaryName(target)), join(directory, runtime)); + await cp(join(root, "LICENSE"), join(directory, "LICENSE")); await writeFile(join(directory, "package.json"), `${JSON.stringify({ name: npmPackage(target), version, description: `Yield runtime for ${target.id}`, license: "MIT", os: [target.nodeOs], cpu: [target.nodeCpu], main: `./${runtime}`, - files: [runtime], repository: { type: "git", url: "https://github.com/operatorstack/yield" }, + files: [runtime, "LICENSE"], repository: { type: "git", url: "git+https://github.com/operatorstack/yield.git" }, + homepage: "https://github.com/operatorstack/yield#readme", + bugs: { url: "https://github.com/operatorstack/yield/issues" }, + publishConfig: { access: "public", provenance: true, registry: "https://registry.npmjs.org/" }, }, null, 2)}\n`); } } @@ -109,6 +122,12 @@ export async function assemble(options) { await writeFile(join(options.output, "SHA256SUMS.json"), `${JSON.stringify({ version: options.version, artifacts: records }, null, 2)}\n`); } -if (process.argv[1] && resolve(process.argv[1]) === resolve(import.meta.filename)) { - assemble(parseArgs(process.argv.slice(2))).catch((error) => { console.error(`assemble: ${error.message}`); process.exit(1); }); +if (process.argv[1]) { + const [entrypoint, modulePath] = await Promise.all([ + realpath(resolve(process.argv[1])), + realpath(import.meta.filename), + ]); + if (entrypoint === modulePath) { + assemble(parseArgs(process.argv.slice(2))).catch((error) => { console.error(`assemble: ${error.message}`); process.exit(1); }); + } } diff --git a/packaging/assemble.test.mjs b/packaging/assemble.test.mjs new file mode 100644 index 0000000..d411cc7 --- /dev/null +++ b/packaging/assemble.test.mjs @@ -0,0 +1,47 @@ +import test from "node:test"; +import assert from "node:assert/strict"; +import { mkdtemp, mkdir, readFile, rm, writeFile } from "node:fs/promises"; +import { join } from "node:path"; +import { tmpdir } from "node:os"; +import { assemble } from "./assemble.mjs"; +import { binaryName, npmPackage, targets } from "./targets.mjs"; + +test("assembles one public npm package and six matching runtimes", async (t) => { + const root = await mkdtemp(join(tmpdir(), "yield-assemble-")); + t.after(() => rm(root, { recursive: true, force: true })); + + const binaries = join(root, "bin"); + const output = join(root, "packages"); + await mkdir(binaries); + for (const target of targets) { + await writeFile(join(binaries, binaryName(target)), `runtime:${target.id}`); + } + + await assemble({ version: "1.2.3", binaries, output }); + const readJson = async (path) => JSON.parse(await readFile(path, "utf8")); + const main = await readJson(join(output, "npm/yield/package.json")); + + assert.equal(main.name, "@operatorstack/yield"); + assert.equal(main.version, "1.2.3"); + assert.deepEqual(main.publishConfig, { + access: "public", + provenance: true, + registry: "https://registry.npmjs.org/", + }); + assert.deepEqual( + main.optionalDependencies, + Object.fromEntries(targets.map((target) => [npmPackage(target), "1.2.3"])), + ); + assert.match(await readFile(join(output, "npm/yield/README.md"), "utf8"), /^# Yield/m); + assert.match(await readFile(join(output, "npm/yield/LICENSE"), "utf8"), /MIT License/); + + for (const target of targets) { + const runtime = await readJson(join(output, `npm/${target.id}/package.json`)); + assert.equal(runtime.name, npmPackage(target)); + assert.equal(runtime.version, "1.2.3"); + assert.deepEqual(runtime.os, [target.nodeOs]); + assert.deepEqual(runtime.cpu, [target.nodeCpu]); + assert.equal(runtime.publishConfig.provenance, true); + assert.match(await readFile(join(output, `npm/${target.id}/LICENSE`), "utf8"), /MIT License/); + } +}); diff --git a/release-notes/2026-08-01-multi-language-and-converter.md b/release-notes/2026-08-01-multi-language-and-converter.md index 3d5ca09..3435574 100644 --- a/release-notes/2026-08-01-multi-language-and-converter.md +++ b/release-notes/2026-08-01-multi-language-and-converter.md @@ -2,7 +2,7 @@ Yield is now multi-language. The canonical `ir/yield.v1` schemas define everything that crosses a process boundary, and four SDKs implement the -same Locus-certified execution contract: Go (`sdk/yield`), TypeScript +same tested execution contract: Go (`sdk/yield`), TypeScript (`sdk/typescript`, Node ≥ 23.6), Python (`sdk/python`, import `yieldskill`), and Rust (`sdk/rust`, crate `yieldskill`). Non-Go skills declare their runner in `skill.json`. diff --git a/release-notes/2026-08-07-public-npm-channels.md b/release-notes/2026-08-07-public-npm-channels.md new file mode 100644 index 0000000..1dec7d0 --- /dev/null +++ b/release-notes/2026-08-07-public-npm-channels.md @@ -0,0 +1,6 @@ +## Public npm channels + +- Publish `@operatorstack/yield` with six platform-specific runtime packages. +- Send merged revisions to the `canary` dist-tag using immutable prerelease versions. +- Publish stable versions to `latest` only through an explicit release dispatch bound to an immutable Git tag. +- Authenticate from GitHub Actions with npm trusted publishing and automatic provenance; no long-lived npm publishing token is stored. diff --git a/scripts/audit-repository-controls.mjs b/scripts/audit-repository-controls.mjs new file mode 100644 index 0000000..1d78422 --- /dev/null +++ b/scripts/audit-repository-controls.mjs @@ -0,0 +1,59 @@ +#!/usr/bin/env node +import process from "node:process"; +import { resolve } from "node:path"; +import { pathToFileURL } from "node:url"; + +const requiredChecks = [ + "Go and agent registration (ubuntu-latest)", + "Go and agent registration (macos-latest)", + "Go and agent registration (windows-latest)", + "Release authority and full validation", +]; + +function expect(condition, message) { + if (!condition) throw new Error(message); +} + +export function auditRepositoryControls({ workflow, actions, protection, rulesets }) { + expect(workflow.default_workflow_permissions === "read", "default workflow permissions must be read-only"); + expect(workflow.can_approve_pull_request_reviews === false, "workflows must not approve pull requests"); + expect(actions.enabled === true && actions.sha_pinning_required === true, "Actions must require immutable SHA references"); + expect(protection.enforce_admins?.enabled === true, "administrators must not bypass main protection"); + expect(protection.required_status_checks?.strict === true, "required checks must run against current main"); + expect(protection.allow_force_pushes?.enabled === false, "main must reject force pushes"); + expect(protection.allow_deletions?.enabled === false, "main must reject deletion"); + const contexts = new Set(protection.required_status_checks?.contexts ?? []); + for (const check of requiredChecks) expect(contexts.has(check), `main is missing required check: ${check}`); + const tagRule = rulesets.find((ruleset) => ruleset.name === "Immutable Yield release tags"); + expect(tagRule?.target === "tag" && tagRule.enforcement === "active", "immutable release-tag ruleset must be active"); + return { requiredChecks: requiredChecks.length, immutableTagRuleset: tagRule.id }; +} + +async function github(path) { + const repository = process.env.GITHUB_REPOSITORY ?? "operatorstack/yield"; + const response = await fetch(`https://api.github.com/repos/${repository}/${path}`, { + headers: { + Accept: "application/vnd.github+json", + Authorization: `Bearer ${process.env.GH_TOKEN}`, + "X-GitHub-Api-Version": "2022-11-28", + }, + }); + if (!response.ok) throw new Error(`${path}: GitHub HTTP ${response.status}`); + return response.json(); +} + +async function main() { + expect(process.env.GH_TOKEN, "GH_TOKEN is required"); + const [workflow, actions, protection, rulesets] = await Promise.all([ + github("actions/permissions/workflow"), + github("actions/permissions"), + github("branches/main/protection"), + github("rulesets"), + ]); + const result = auditRepositoryControls({ workflow, actions, protection, rulesets }); + console.log(`repository-controls: ${result.requiredChecks} required checks and immutable tag ruleset ${result.immutableTagRuleset} verified`); +} + +if (process.argv[1] && import.meta.url === pathToFileURL(resolve(process.argv[1])).href) { + main().catch((error) => { console.error(`repository-controls: ${error.message}`); process.exit(1); }); +} diff --git a/scripts/audit-repository-controls.test.mjs b/scripts/audit-repository-controls.test.mjs new file mode 100644 index 0000000..f3abc0f --- /dev/null +++ b/scripts/audit-repository-controls.test.mjs @@ -0,0 +1,32 @@ +import test from "node:test"; +import assert from "node:assert/strict"; +import { auditRepositoryControls } from "./audit-repository-controls.mjs"; + +function controls(overrides = {}) { + return { + workflow: { default_workflow_permissions: "read", can_approve_pull_request_reviews: false }, + actions: { enabled: true, sha_pinning_required: true }, + protection: { + enforce_admins: { enabled: true }, + required_status_checks: { strict: true, contexts: [ + "Go and agent registration (ubuntu-latest)", + "Go and agent registration (macos-latest)", + "Go and agent registration (windows-latest)", + "Release authority and full validation", + ] }, + allow_force_pushes: { enabled: false }, + allow_deletions: { enabled: false }, + }, + rulesets: [{ id: 1, name: "Immutable Yield release tags", target: "tag", enforcement: "active" }], + ...overrides, + }; +} + +test("accepts the complete repository control surface", () => { + assert.equal(auditRepositoryControls(controls()).requiredChecks, 4); +}); + +test("refuses a bypassable administrator or mutable action reference policy", () => { + assert.throws(() => auditRepositoryControls(controls({ protection: { ...controls().protection, enforce_admins: { enabled: false } } })), /administrators/); + assert.throws(() => auditRepositoryControls(controls({ actions: { enabled: true, sha_pinning_required: false } })), /immutable SHA/); +}); diff --git a/scripts/check-release-control.mjs b/scripts/check-release-control.mjs new file mode 100644 index 0000000..cd5b407 --- /dev/null +++ b/scripts/check-release-control.mjs @@ -0,0 +1,84 @@ +#!/usr/bin/env node +import { readdir, readFile, stat } from "node:fs/promises"; +import { resolve } from "node:path"; +import process from "node:process"; +import { pathToFileURL } from "node:url"; +import { parse } from "yaml"; + +const SHA_REF = /^[^\s@]+@[0-9a-f]{40}$/; + +function expect(condition, message) { + if (!condition) throw new Error(message); +} + +function usesIn(value, found = []) { + if (Array.isArray(value)) { + for (const item of value) usesIn(item, found); + } else if (value && typeof value === "object") { + for (const [key, item] of Object.entries(value)) { + if (key === "uses" && typeof item === "string") found.push(item); + else usesIn(item, found); + } + } + return found; +} + +async function exists(path) { + return stat(path).then(() => true, () => false); +} + +export async function checkReleaseControl(root = resolve(import.meta.dirname, "..")) { + const workflowDir = resolve(root, ".github/workflows"); + const names = (await readdir(workflowDir)).filter((name) => name.endsWith(".yml") || name.endsWith(".yaml")); + const workflows = {}; + const raw = {}; + for (const name of names) { + raw[name] = await readFile(resolve(workflowDir, name), "utf8"); + workflows[name] = parse(raw[name]); + for (const action of usesIn(workflows[name])) { + expect(action.startsWith("./") || SHA_REF.test(action), `${name}: action is not pinned to a full commit SHA: ${action}`); + } + } + + expect(!(await exists(resolve(root, "UPSTREAM.json"))), "UPSTREAM.json must be removed after graduation"); + expect(!names.includes("sync-upstream.yml"), "projection sync workflow must be removed after graduation"); + + const release = workflows["release.yml"]; + expect(release, "release.yml is required"); + expect(JSON.stringify(Object.keys(release.on ?? {}).sort()) === JSON.stringify(["workflow_dispatch"]), "stable release must be dispatch-only"); + expect(release.permissions?.contents === "read", "release planning must be read-only"); + expect(release.jobs?.release?.permissions?.contents === "write", "tag creation alone needs contents:write"); + expect(release.jobs?.release?.environment === "release-control", "release authorization must use the protected release-control environment"); + expect(raw["release.yml"].includes("--draft"), "release controller must create a draft release"); + expect(!raw["release.yml"].includes("--draft=false"), "release controller must not finalize its own release"); + + const npm = workflows["npm-publish.yml"]; + expect(npm, "npm-publish.yml is required"); + expect(npm.permissions?.contents === "read" && npm.permissions?.["id-token"] === "write", "npm publisher must use read-only source plus OIDC"); + expect(npm.on?.push?.branches?.includes("main"), "npm canary must follow public main"); + expect(npm.on?.workflow_run?.workflows?.includes("Release Yield"), "stable npm must consume the release controller receipt"); + expect(raw["npm-publish.yml"].indexOf("Publish platform runtimes") < raw["npm-publish.yml"].indexOf("Publish SDK and CLI"), "runtime packages must publish before the SDK package"); + + const privateRegistry = workflows["private-registry.yml"]; + expect(privateRegistry && !privateRegistry.on?.push, "private stable publishing must not accept direct tag pushes"); + expect(privateRegistry.jobs?.publish?.environment === "private-production", "private publishing must use its protected environment"); + + const finalizer = workflows["release-finalize.yml"]; + expect(finalizer?.permissions?.actions === "read" && finalizer.permissions?.contents === "read", "finalizer preflight must be read-only"); + expect(finalizer.jobs?.finalize?.permissions?.contents === "write", "receipt-complete finalization alone needs contents:write"); + expect(finalizer.jobs?.finalize?.needs === "resolve", "finalization must follow read-only tag resolution"); + expect(raw["release-finalize.yml"].includes("--draft=false"), "only the receipt finalizer may publish the GitHub release"); + expect(!raw["release-finalize.yml"].includes("private-registry.yml"), "the private mirror must not block public release finalization"); + + for (const [name, text] of Object.entries(raw)) { + expect(!/NPM_TOKEN|NODE_AUTH_TOKEN|secrets\.npm/i.test(text), `${name}: long-lived npm credentials are forbidden`); + } + + return { workflows: names.length, externalActionsPinned: names.flatMap((name) => usesIn(workflows[name])).filter((ref) => !ref.startsWith("./")).length }; +} + +if (process.argv[1] && import.meta.url === pathToFileURL(resolve(process.argv[1])).href) { + checkReleaseControl() + .then((result) => console.log(`release-control: ${result.workflows} workflows and ${result.externalActionsPinned} pinned action references verified`)) + .catch((error) => { console.error(`release-control: ${error.message}`); process.exit(1); }); +} diff --git a/scripts/check-release-control.test.mjs b/scripts/check-release-control.test.mjs new file mode 100644 index 0000000..64d3b83 --- /dev/null +++ b/scripts/check-release-control.test.mjs @@ -0,0 +1,9 @@ +import test from "node:test"; +import assert from "node:assert/strict"; +import { checkReleaseControl } from "./check-release-control.mjs"; + +test("repository workflows preserve the supervised release boundary", async () => { + const result = await checkReleaseControl(); + assert.ok(result.workflows >= 5); + assert.ok(result.externalActionsPinned > 0); +}); diff --git a/scripts/release-plan.mjs b/scripts/release-plan.mjs new file mode 100644 index 0000000..b1ebb72 --- /dev/null +++ b/scripts/release-plan.mjs @@ -0,0 +1,91 @@ +#!/usr/bin/env node +import { execFileSync } from "node:child_process"; +import { readFile, writeFile } from "node:fs/promises"; +import { resolve } from "node:path"; +import process from "node:process"; +import { pathToFileURL } from "node:url"; +import { parse as parseYaml } from "yaml"; + +const PACKAGE = "@operatorstack/yield"; +const levels = { patch: 0, minor: 1, major: 2 }; + +function parseArgs(argv) { + const result = {}; + for (let index = 0; index < argv.length; index += 2) { + const key = argv[index]; + if (!key?.startsWith("--") || argv[index + 1] === undefined) throw new Error(`invalid argument ${key ?? ""}`); + result[key.slice(2)] = argv[index + 1]; + } + return result; +} + +function git(args) { + return execFileSync("git", args, { encoding: "utf8" }).trim(); +} + +export function parseChangeset(text, path = "changeset") { + const match = /^---\r?\n([\s\S]*?)\r?\n---\r?\n([\s\S]+)$/.exec(text); + if (!match) throw new Error(`${path}: expected YAML frontmatter and a summary`); + const releases = parseYaml(match[1]); + if (!releases || typeof releases !== "object" || Array.isArray(releases)) throw new Error(`${path}: frontmatter must be a package map`); + const entries = Object.entries(releases); + if (entries.length !== 1 || entries[0][0] !== PACKAGE) throw new Error(`${path}: only ${PACKAGE} may declare release intent`); + const bump = entries[0][1]; + if (!(bump in levels)) throw new Error(`${path}: bump must be patch, minor, or major`); + const summary = match[2].trim(); + if (!summary) throw new Error(`${path}: summary must not be empty`); + return { bump, summary, path }; +} + +export function bumpVersion(version, bump) { + if (!/^\d+\.\d+\.\d+$/.test(version)) throw new Error(`invalid base version ${version}`); + const [major, minor, patch] = version.split(".").map(Number); + if (bump === "major") return `${major + 1}.0.0`; + if (bump === "minor") return `${major}.${minor + 1}.0`; + if (bump === "patch") return `${major}.${minor}.${patch + 1}`; + throw new Error(`invalid bump ${bump}`); +} + +export function planRelease({ baseVersion, changesets, requestedBump = "auto" }) { + if (!changesets.length) throw new Error("stable releases require at least one pending Changeset"); + if (requestedBump !== "auto" && !(requestedBump in levels)) throw new Error(`invalid requested bump ${requestedBump}`); + const declaredBump = changesets.map(({ bump }) => bump).sort((a, b) => levels[b] - levels[a])[0]; + if (requestedBump !== "auto" && levels[requestedBump] < levels[declaredBump]) { + throw new Error(`requested ${requestedBump} cannot lower declared ${declaredBump}`); + } + const bump = requestedBump === "auto" ? declaredBump : requestedBump; + return { baseVersion, bump, version: bumpVersion(baseVersion, bump), changesets }; +} + +async function main() { + const args = parseArgs(process.argv.slice(2)); + const requestedBump = args.bump ?? "auto"; + const baseTag = args.base ?? git(["tag", "--list", "v[0-9]*", "--sort=-v:refname"]).split("\n")[0]; + if (!/^v\d+\.\d+\.\d+$/.test(baseTag)) throw new Error("no valid stable base tag found"); + git(["rev-parse", "--verify", `refs/tags/${baseTag}`]); + const paths = git(["diff", "--name-only", "--diff-filter=A", `${baseTag}..HEAD`, "--", ".changeset/*.md"]) + .split("\n") + .filter((path) => path && path !== ".changeset/README.md"); + const changesets = []; + for (const path of paths) changesets.push(parseChangeset(await readFile(path, "utf8"), path)); + const plan = planRelease({ baseVersion: baseTag.slice(1), changesets, requestedBump }); + const sourceSha = git(["rev-parse", "HEAD"]); + const notes = [`# Yield ${plan.version}`, "", ...plan.changesets.flatMap(({ summary }) => [`- ${summary}`, ""])].join("\n").trimEnd() + "\n"; + if (args.notes) await writeFile(args.notes, notes); + if (args.output) { + await writeFile(args.output, [ + `base_tag=${baseTag}`, + `bump=${plan.bump}`, + `version=${plan.version}`, + `tag=v${plan.version}`, + `source_sha=${sourceSha}`, + `changeset_count=${plan.changesets.length}`, + "", + ].join("\n"), { flag: "a" }); + } + process.stdout.write(`${JSON.stringify({ ...plan, baseTag, sourceSha }, null, 2)}\n`); +} + +if (process.argv[1] && import.meta.url === pathToFileURL(resolve(process.argv[1])).href) { + main().catch((error) => { console.error(`release-plan: ${error.message}`); process.exit(1); }); +} diff --git a/scripts/release-plan.test.mjs b/scripts/release-plan.test.mjs new file mode 100644 index 0000000..5ca4a25 --- /dev/null +++ b/scripts/release-plan.test.mjs @@ -0,0 +1,29 @@ +import test from "node:test"; +import assert from "node:assert/strict"; +import { bumpVersion, parseChangeset, planRelease } from "./release-plan.mjs"; + +const changeset = (bump, summary = "Ship it") => parseChangeset(`---\n"@operatorstack/yield": ${bump}\n---\n\n${summary}\n`); + +test("aggregates the highest pending Changeset bump", () => { + assert.equal(planRelease({ baseVersion: "0.1.29", changesets: [changeset("patch"), changeset("minor")] }).version, "0.2.0"); +}); + +test("allows an explicit bump to raise but not lower intent", () => { + assert.equal(planRelease({ baseVersion: "0.1.29", changesets: [changeset("patch")], requestedBump: "major" }).version, "1.0.0"); + assert.throws(() => planRelease({ baseVersion: "0.1.29", changesets: [changeset("major")], requestedBump: "minor" }), /cannot lower/); +}); + +test("requires pending release intent", () => { + assert.throws(() => planRelease({ baseVersion: "0.1.29", changesets: [] }), /at least one/); +}); + +test("rejects another package or malformed bump", () => { + assert.throws(() => parseChangeset(`---\nother: patch\n---\n\nNo\n`), /only @operatorstack\/yield/); + assert.throws(() => parseChangeset(`---\n"@operatorstack/yield": huge\n---\n\nNo\n`), /patch, minor, or major/); +}); + +test("applies ordinary semantic version increments", () => { + assert.equal(bumpVersion("0.1.29", "patch"), "0.1.30"); + assert.equal(bumpVersion("0.1.29", "minor"), "0.2.0"); + assert.equal(bumpVersion("0.1.29", "major"), "1.0.0"); +}); diff --git a/sdk/python/yieldskill/__init__.py b/sdk/python/yieldskill/__init__.py index 6a3dcb6..1e4da7a 100644 --- a/sdk/python/yieldskill/__init__.py +++ b/sdk/python/yieldskill/__init__.py @@ -1,6 +1,6 @@ """Yield skill-program SDK for Python (yield.v1). -Implements the Locus-certified SDK execution contract (see ir/README.md): +Implements the tested SDK execution contract (see ir/README.md): load the journal, replay recorded operations with a digest comparison at EVERY replayed step before consuming its response, emit exactly one program output (request | terminal | diverged) on stdout, then exit. @@ -182,9 +182,8 @@ def _step(self, req: dict) -> dict: want = _request_digest(entry["request"]) got = _request_digest(req) if want != got: - # Mandatory per-step check: consuming a recorded response - # for a drifted operation is the forbidden state the rival - # design fails (docs/locus/drv-ad50b13e…). + # Mandatory per-step check: a changed operation must not + # consume a recorded response meant for another operation. raise _EmitSignal( { "type": "diverged", diff --git a/sdk/rust/src/lib.rs b/sdk/rust/src/lib.rs index e3ed93d..4cc9001 100644 --- a/sdk/rust/src/lib.rs +++ b/sdk/rust/src/lib.rs @@ -1,6 +1,6 @@ //! Yield skill-program SDK for Rust (yield.v1). //! -//! Implements the Locus-certified SDK execution contract (see ir/README.md): +//! Implements the tested SDK execution contract (see ir/README.md): //! load the journal, replay recorded operations with a digest comparison at //! EVERY replayed step before consuming its response, emit exactly one //! program output (request | terminal | diverged) on stdout, then exit. @@ -300,9 +300,8 @@ impl Context { } /// The certified contract's step: replay with a mandatory per-step - /// digest check, or emit-and-exit at the frontier. Consuming a recorded - /// response for a drifted operation is the forbidden state the rival - /// design fails (docs/locus/drv-ad50b13e…). + /// digest check, or emit-and-exit at the frontier. A changed operation + /// must not consume a response recorded for another operation. fn step(&mut self, req: Request) -> ResponseEnvelope { let seq = (self.idx + 1) as u64; if self.idx < self.journal.entries.len() { diff --git a/sdk/typescript/package.json b/sdk/typescript/package.json index 862bb7e..e6878c4 100644 --- a/sdk/typescript/package.json +++ b/sdk/typescript/package.json @@ -1,7 +1,7 @@ { "name": "@operatorstack/yield", "version": "0.1.0", - "description": "Build portable, resumable skill workflows in TypeScript.", + "description": "Yield skill-program SDK for TypeScript: turn SKILL.md workflows into resumable programs.", "license": "MIT", "type": "module", "files": [ @@ -29,7 +29,23 @@ }, "repository": { "type": "git", - "url": "https://github.com/operatorstack/yield.git", + "url": "git+https://github.com/operatorstack/yield.git", "directory": "sdk/typescript" + }, + "homepage": "https://github.com/operatorstack/yield#readme", + "bugs": { + "url": "https://github.com/operatorstack/yield/issues" + }, + "keywords": [ + "agent", + "skills", + "workflow", + "resumable", + "cli" + ], + "publishConfig": { + "access": "public", + "provenance": true, + "registry": "https://registry.npmjs.org/" } } diff --git a/sdk/typescript/src/index.ts b/sdk/typescript/src/index.ts index a4fe5a8..e4a5b0f 100644 --- a/sdk/typescript/src/index.ts +++ b/sdk/typescript/src/index.ts @@ -1,6 +1,6 @@ // Yield skill-program SDK for TypeScript (yield.v1). // -// Implements the Locus-certified SDK execution contract (see ir/README.md): +// Implements the tested SDK execution contract (see ir/README.md): // load the journal, replay recorded operations with a digest comparison at // EVERY replayed step before consuming its response, emit exactly one // program output (request | terminal | diverged) on stdout, then exit.