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

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .cargo/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,4 @@ TRACEDECAY_DATA_DIR = { value = "target/test-profile/.tracedecay", force = false
# https://nexte.st/docs/installation/pre-built-binaries/
test-all = "nextest run --workspace --no-fail-fast"
test-ci = "nextest run --workspace --no-fail-fast"
dogfood = "run --quiet --release --bin tracedecay -- dogfood"
5 changes: 5 additions & 0 deletions .changeset/runtime-routing-ci-hardening.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"tracedecay": patch
---

Fix project and user session attribution across modern registry aliases, report analytics from sharded session stores, bound autonomous memory-curator requests and recover from stale oversize failures, expose the Hermes plugin skill through first-turn discovery, and harden CI/release concurrency without disabling Windows coverage.
52 changes: 52 additions & 0 deletions .claude/skills/dogfooding-tracedecay/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
---
name: dogfooding-tracedecay
description: Use when installing a TraceDecay checkout for live local development, refreshing the globally available binary without a release, or validating agents and the daemon against unmerged TraceDecay changes.
---

# Dogfooding TraceDecay

Use the repository command. Do not run release upgrade or point agents at
`target/`; Cargo may replace or lock that binary during later builds.

## Install the checkout

1. Confirm the checkout/branch contains the exact changes to dogfood and that
unrelated worktrees are not being built accidentally.
2. From that checkout's root, run:

```bash
cargo dogfood
```

3. Treat any nonzero exit as incomplete deployment. Inspect the printed stage,
post-update, daemon, or doctor failure before retrying.

The command builds the release binary, copies it outside the repository to
`~/.local/lib/tracedecay/dogfood/tracedecay`, atomically replaces
`~/.local/bin/tracedecay`, refreshes tracked integrations through the normal
post-update lifecycle, restarts the managed daemon, and runs health checks.
Cargo's isolated `target/test-profile/.tracedecay` profile is removed before
the live refresh.

## Verify live use

Run these only after `cargo dogfood` succeeds:

```bash
command -v tracedecay
tracedecay --version
tracedecay daemon status
tracedecay doctor
```

Then reproduce the changed host scenario with the ordinary global
`tracedecay` command. Inspect relevant service/host logs. Restart a host only
when its integration is in-process or its plugin module cannot hot-reload.

## Guardrails

- Do not run `tracedecay upgrade` for checkout dogfood; it installs a published
release.
- Do not kill host-owned MCP shim processes indiscriminately.
- Do not delete the source worktree until its commits are pushed and merged.
- Re-run `cargo dogfood` after any source change that must reach live agents.
52 changes: 52 additions & 0 deletions .codex/skills/dogfooding-tracedecay/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
---
name: dogfooding-tracedecay
description: Use when installing a TraceDecay checkout for live local development, refreshing the globally available binary without a release, or validating agents and the daemon against unmerged TraceDecay changes.
---

# Dogfooding TraceDecay

Use the repository command. Do not run release upgrade or point agents at
`target/`; Cargo may replace or lock that binary during later builds.

## Install the checkout

1. Confirm the checkout/branch contains the exact changes to dogfood and that
unrelated worktrees are not being built accidentally.
2. From that checkout's root, run:

```bash
cargo dogfood
```

3. Treat any nonzero exit as incomplete deployment. Inspect the printed stage,
post-update, daemon, or doctor failure before retrying.

The command builds the release binary, copies it outside the repository to
`~/.local/lib/tracedecay/dogfood/tracedecay`, atomically replaces
`~/.local/bin/tracedecay`, refreshes tracked integrations through the normal
post-update lifecycle, restarts the managed daemon, and runs health checks.
Cargo's isolated `target/test-profile/.tracedecay` profile is removed before
the live refresh.

## Verify live use

Run these only after `cargo dogfood` succeeds:

```bash
command -v tracedecay
tracedecay --version
tracedecay daemon status
tracedecay doctor
```

Then reproduce the changed host scenario with the ordinary global
`tracedecay` command. Inspect relevant service/host logs. Restart a host only
when its integration is in-process or its plugin module cannot hot-reload.

## Guardrails

- Do not run `tracedecay upgrade` for checkout dogfood; it installs a published
release.
- Do not kill host-owned MCP shim processes indiscriminately.
- Do not delete the source worktree until its commits are pushed and merged.
- Re-run `cargo dogfood` after any source change that must reach live agents.
4 changes: 4 additions & 0 deletions .codex/skills/dogfooding-tracedecay/agents/openai.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
interface:
display_name: "Dogfood TraceDecay"
short_description: "Install and verify local TraceDecay builds"
default_prompt: "Use $dogfooding-tracedecay to install this checkout globally and verify the live runtime."
5 changes: 4 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,9 @@ jobs:
- name: Test release workflow contract
run: bash tests/release_workflow_contract_test.sh

- name: Test local dogfood command contract
run: bash tests/dogfood_command_test.sh

- name: Check release version drift
run: scripts/check-release-drift.sh

Expand Down Expand Up @@ -306,7 +309,7 @@ jobs:

windows-test:
name: Test Windows
if: ${{ always() && (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository || contains(fromJSON('["master","feature/holographic-memory"]'), github.event.pull_request.base.ref)) }}
if: ${{ !cancelled() && (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository || contains(fromJSON('["master","feature/holographic-memory"]'), github.event.pull_request.base.ref)) }}
needs: windows-test-shard
runs-on: ubuntu-latest
steps:
Expand Down
50 changes: 35 additions & 15 deletions .github/workflows/release-beta.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ on:
release:
types: [published]
workflow_dispatch:
inputs:
release_tag:
description: "Existing prerelease tag to rebuild and publish, for example v0.1.0-beta.1"
required: true
type: string

# Only runs for prerelease tags — stable releases handled by release.yml

Expand All @@ -16,11 +21,16 @@ permissions:

env:
CARGO_TERM_COLOR: always
RELEASE_TAG: ${{ github.event_name == 'workflow_dispatch' && inputs.release_tag || github.event.release.tag_name }}

concurrency:
group: release-beta-${{ github.event_name == 'workflow_dispatch' && inputs.release_tag || github.event.release.tag_name }}
cancel-in-progress: false

jobs:
build:
name: Build ${{ matrix.name }}
if: vars.BETA_CHANNEL_ENABLED == 'true' && github.event.release.prerelease
if: vars.BETA_CHANNEL_ENABLED == 'true' && (github.event_name == 'workflow_dispatch' || github.event.release.prerelease)
runs-on: ${{ matrix.runner }}
strategy:
fail-fast: false
Expand All @@ -46,7 +56,17 @@ jobs:
archive: zip

steps:
- name: Validate manual prerelease rebuild
if: github.event_name == 'workflow_dispatch'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
shell: bash
run: |
test "$(gh release view "$RELEASE_TAG" --repo "${{ github.repository }}" --json isPrerelease --jq .isPrerelease)" = true

- uses: actions/checkout@v4
with:
ref: ${{ env.RELEASE_TAG }}

- uses: actions/setup-node@v4
with:
Expand Down Expand Up @@ -93,7 +113,7 @@ jobs:
id: version
shell: bash
run: |
VERSION="${GITHUB_REF_NAME#v}"
VERSION="${RELEASE_TAG#v}"
echo "version=$VERSION" >> "$GITHUB_OUTPUT"

# --- Binary archive (all platforms) ---
Expand All @@ -102,20 +122,20 @@ jobs:
if: matrix.archive == 'tar.gz'
run: |
cd target/${{ matrix.target }}/release
tar czf ../../../tracedecay-beta-${{ github.ref_name }}-${{ matrix.name }}.tar.gz tracedecay
tar czf ../../../tracedecay-beta-${{ env.RELEASE_TAG }}-${{ matrix.name }}.tar.gz tracedecay
cd ../../..

- name: Package binary (windows)
if: matrix.archive == 'zip'
shell: pwsh
run: |
Compress-Archive -Path target/${{ matrix.target }}/release/tracedecay.exe -DestinationPath tracedecay-beta-${{ github.ref_name }}-${{ matrix.name }}.zip
Compress-Archive -Path target/${{ matrix.target }}/release/tracedecay.exe -DestinationPath tracedecay-beta-${{ env.RELEASE_TAG }}-${{ matrix.name }}.zip

- name: Upload binary archive
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
shell: bash
run: gh release upload ${{ github.ref_name }} tracedecay-beta-${{ github.ref_name }}-${{ matrix.name }}.${{ matrix.archive }} --clobber
run: gh release upload "$RELEASE_TAG" tracedecay-beta-${{ env.RELEASE_TAG }}-${{ matrix.name }}.${{ matrix.archive }} --clobber

# --- Homebrew bottle (only for platforms with bottle_tag) ---

Expand All @@ -138,7 +158,7 @@ jobs:

update-homebrew:
name: Update Homebrew tap (beta)
if: vars.BETA_CHANNEL_ENABLED == 'true' && github.event.release.prerelease && needs.build.result == 'success'
if: vars.BETA_CHANNEL_ENABLED == 'true' && needs.build.result == 'success'
needs: build
runs-on: ubuntu-latest
steps:
Expand All @@ -147,7 +167,7 @@ jobs:
- name: Get version
id: version
run: |
VERSION="${GITHUB_REF_NAME#v}"
VERSION="${RELEASE_TAG#v}"
echo "version=$VERSION" >> "$GITHUB_OUTPUT"

- name: Download bottle artifacts
Expand All @@ -161,12 +181,12 @@ jobs:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
for f in bottles/tracedecay-beta-*.bottle.tar.gz; do
gh release upload "${GITHUB_REF_NAME}" "$f" --clobber
gh release upload "$RELEASE_TAG" "$f" --clobber
done

- name: Download source tarball
run: |
curl -sL "https://github.com/${{ github.repository }}/archive/refs/tags/${GITHUB_REF_NAME}.tar.gz" -o "source.tar.gz"
curl -sL "https://github.com/${{ github.repository }}/archive/refs/tags/${RELEASE_TAG}.tar.gz" -o "source.tar.gz"

- name: Compute SHA256 hashes
id: hashes
Expand Down Expand Up @@ -232,7 +252,7 @@ jobs:

update-scoop:
name: Update Scoop bucket (beta)
if: vars.BETA_CHANNEL_ENABLED == 'true' && github.event.release.prerelease && needs.build.result == 'success'
if: vars.BETA_CHANNEL_ENABLED == 'true' && needs.build.result == 'success'
needs: build
runs-on: ubuntu-latest
steps:
Expand All @@ -241,15 +261,15 @@ jobs:
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
VERSION="${GITHUB_REF_NAME#v}"
VERSION="${RELEASE_TAG#v}"
echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
echo "tag=${GITHUB_REF_NAME}" >> "$GITHUB_OUTPUT"
echo "tag=${RELEASE_TAG}" >> "$GITHUB_OUTPUT"

gh release download "${GITHUB_REF_NAME}" \
gh release download "${RELEASE_TAG}" \
--repo "${{ github.repository }}" \
--pattern "tracedecay-beta-${GITHUB_REF_NAME}-x86_64-windows.zip" \
--pattern "tracedecay-beta-${RELEASE_TAG}-x86_64-windows.zip" \
--dir .
SHA256=$(sha256sum "tracedecay-beta-${GITHUB_REF_NAME}-x86_64-windows.zip" | cut -d' ' -f1)
SHA256=$(sha256sum "tracedecay-beta-${RELEASE_TAG}-x86_64-windows.zip" | cut -d' ' -f1)
echo "sha256_win64=${SHA256}" >> "$GITHUB_OUTPUT"

# NOTE: the Scoop bucket (ScriptedAlchemy/scoop-bucket) is an external
Expand Down
9 changes: 6 additions & 3 deletions .github/workflows/release-plz.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@ permissions:
env:
CARGO_TERM_COLOR: always

# Publishing mutates crates.io and GitHub release state. Serialize master
# updates, but never cancel a publication after it has started.
concurrency:
group: release-plz-${{ github.ref }}
cancel-in-progress: false

jobs:
release-plz-release:
name: Publish crate and create GitHub release
Expand Down Expand Up @@ -92,9 +98,6 @@ jobs:
permissions:
contents: write
pull-requests: write
concurrency:
group: release-plz-${{ github.ref }}
cancel-in-progress: false
steps:
- name: Checkout repository
uses: actions/checkout@v4
Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/release-pr-integrity.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ permissions:
contents: read
pull-requests: read

concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number }}
cancel-in-progress: true

jobs:
release-pr-integrity:
name: Release PR integrity
Expand Down
11 changes: 4 additions & 7 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ on:
inputs:
release_tag:
description: "Existing release tag to rebuild and publish, for example v0.0.17"
required: false
required: true
type: string

# Skip beta/prerelease tags — handled by release-beta.yml
Expand All @@ -21,8 +21,8 @@ env:
CARGO_TERM_COLOR: always

concurrency:
group: release-${{ github.event_name == 'workflow_dispatch' && inputs.release_tag || github.ref }}
cancel-in-progress: true
group: release-${{ github.event_name == 'workflow_dispatch' && inputs.release_tag || github.event.release.tag_name }}
cancel-in-progress: false

jobs:
build:
Expand Down Expand Up @@ -114,12 +114,9 @@ jobs:
id: version
shell: bash
run: |
if [ "${GITHUB_EVENT_NAME}" = "workflow_dispatch" ] && [ -n "${{ inputs.release_tag }}" ]; then
if [ "${GITHUB_EVENT_NAME}" = "workflow_dispatch" ]; then
TAG="${{ inputs.release_tag }}"
VERSION="${TAG#v}"
elif [ "${GITHUB_EVENT_NAME}" = "workflow_dispatch" ]; then
TAG="dry-run-${GITHUB_SHA::7}"
VERSION="${TAG#v}"
else
TAG="${GITHUB_REF_NAME}"
VERSION="${GITHUB_REF_NAME#v}"
Expand Down
Loading
Loading