Commit Graph

912 Commits

Author SHA1 Message Date
Ran Shem Tov 8768c8a7e7 Merge remote-tracking branch 'origin/main' into claude/trusting-babbage-f4d48a 2026-06-22 16:11:21 +02:00
Ran Shem Tov fdf588cfbf fix(showcase): green CI for the strands-typescript addition
Two PR checks were red on the new integration:

- check-config-files: add strands-typescript/next.config.ts to the build-
  config allowlist.
- Validate Showcase: update the new-integration guard pins that intentionally
  trip when an integration is added — BORN_IN_SHOWCASE 6→7, calculator
  _from-feature-parity count 18→19, catalog cross-join 874→920 / total_cells
  855→900 / docs_only 19→20 (46 features × 20 integrations), and the aimock
  substring-shadow ceiling 132→133 (+1 from the strands-typescript calculator
  fixture).

Also drop the premature deploy wiring: strands-typescript is removed from
showcase_build.yml (matrix + path filter + ALL_SERVICES) because it has no
Railway service yet (deployed: false) and the railway-envs SSOT test requires
a real service entry. It re-enters the deploy pipeline when the Railway
service is provisioned (external setup per INTEGRATION-CHECKLIST).
2026-06-22 15:36:28 +02:00
Markus Ecker eb94c0b327 Merge branch 'main' into chore/codeowners-angular-team 2026-06-22 14:48:10 +02:00
Alem Tuzlak b2c28a046c Merge branch 'main' into feat/bot-whatsapp 2026-06-22 11:12:54 +02:00
Jordan Ritter ca12d09c36 cvdiag: permanent showcase observability subsystem (probe→backend→aimock→edge) (#5591)
## What

Adds **cvdiag** — a permanent, always-available observability subsystem
for the showcase, built to diagnose the red↔green cell flap on the
staging dashboard and to make that diagnosis a dashboard query rather
than a multi-day forensic hunt in the future.

Captures the full request path with `X-Test-Id` correlation across
**probe → backend → aimock → edge**, across every integration
(TypeScript, Python, Java/spring-ai, .NET):
- Per-language backend emitters (canonical + staged/compile-linked
mirrors), all sharing one schema (`schema.json`, closed-world
`additionalProperties:false`).
- CREATE-only writes to two new PocketBase collections: `cvdiag_events`
and `cvdiag_raw_byte_samples` (additive migrations — no existing data
touched).
- An 8-class flap classifier mapping to the observed failure signatures
(`sse-missing` / `text-unstable` / `dom-missing`).
- DEBUG-tier raw-byte capture (secret-scrubbed) and HMAC-guarded A/B
edge-interference detection.

## Why

The runId flap-fix (`cdc1e90e`, 2026-06-09) did **not** fully resolve
the flap — it was still observed 2026-06-19. cvdiag exists so the
*remaining* cause is observed live with full correlation instead of
inferred.

## Safety / enablement

- **Inert by default.** With `CVDIAG_BACKEND_EMITTER` unset the
subsystem performs zero host mutation (no logging-config changes, no
threads/tasks, no stdout) — verified by
`test_cvdiag_inert_when_disabled`. **To accumulate data, set
`CVDIAG_BACKEND_EMITTER=1` on the showcase services.**
- All per-language scrubbers match the canonical `scrubSecrets`
(sk-/base64url, Bearer, colon-less URL userinfo, size-guard) — verified
with real toolchains (vitest / mvn / dotnet).
- Merged latest `main` (only conflict: a clean `.csproj` include union).

## Verification
- harness `tsc --noEmit` ✓ · `src/cvdiag` vitest 251/251 ✓ ·
`cvdiag-stage-ts --check` in-sync ✓
- Java MessageScrubber 17/17 (mvn) ✓ · .NET CvdiagBackend 5/5 (dotnet
sdk:9.0) ✓ · Python emitters 93/93 (3.12) ✓

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-06-19 20:45:52 -07:00
Jordan Ritter 2e54c925f0 chore(ci): allowlist examples/showcases/arcade-tools/next.config.ts (landed on main un-allowlisted, was failing check-config-files on main + this PR) 2026-06-19 20:10:49 -07:00
Jordan Ritter 6f50bebf0e fix(cvdiag): materialize _shared into integration build-check Docker context (symlink escaped context → 'too many symlinks') (M6) 2026-06-19 14:37:08 -07:00
Jordan Ritter bf6933a436 fix(showcase): unblock promote — skip oxfmt on ephemeral SSOT emit
The showcase_promote.yml resolve-targets job runs
`emit-railway-envs-json.ts`, which shells out to the repo-root
`node_modules/.bin/oxfmt` to produce oxfmt-canonical JSON. That job's
`npm ci` runs in showcase/scripts only and never installs the root oxfmt
binary, so every promote dispatch died at "Generate SSOT artifact" with
`spawnSync .../node_modules/.bin/oxfmt ENOENT` (exit 1) — blocking ALL
promotes, including the team's regular shell-docs promote, since the last
green run on 2026-06-18.

The emitted JSON on the resolve-targets / promote path is EPHEMERAL: it
is parsed in-memory by jq (resolve-promote-targets.sh) and bin/railway to
pick the promote target and is NEVER committed, so oxfmt-canonical
formatting is irrelevant there. Add an explicit `EMIT_SKIP_OXFMT=1`
opt-out that returns the raw `JSON.stringify` form, and set it on both
ephemeral workflow steps.

The DEFAULT (committed-artifact) path is unchanged: oxfmt stays REQUIRED
and fails loud if the binary is absent, because the committed
railway-envs.generated.json must stay oxfmt-canonical or CI's
static_quality.yml `oxfmt --check` auto-format bot fires on the drift.
This is opt-IN-to-skip, never silent-on-absence.

Call sites of emit-railway-envs-json.ts:
- showcase_promote.yml resolve-targets — EMIT_SKIP_OXFMT=1 (this fix).
- showcase_promote.yml promote — EMIT_SKIP_OXFMT=1 (this fix).
- static_quality.yml committed-artifact `--check` — unset, oxfmt required.
- resolve-verify-matrix.ts (showcase_deploy.yml) — only invokes the
  emitter when the committed JSON is absent; the checkout always has it,
  so the default (oxfmt) path is correct and unchanged.

Tests: 2037 showcase/scripts tests pass; 2 new EMIT_SKIP_OXFMT unit tests
assert the skip path emits valid (raw) JSON; the existing oxfmt-canonical
golden tests still gate the committed path.
2026-06-19 14:32:46 -07:00
Jordan Ritter 4a4c0d12b8 fix(showcase): include 12 starters in promote dropdown + regression guard
Regenerated the stale committed showcase_promote.yml so the 12 starter-*
services (+ shell-docs and all existing targets) appear in the service
dispatch choice list (fixes HTTP 422 on
gh workflow run -f service=starter-*). Reverted isProdPromotable to
env-map-only (environments.prod.probe), equivalent to the workflow resolve
predicate. Added a regression test asserting shell-docs + all 12 starters
remain in the generated AND committed dropdown.
2026-06-19 13:53:25 -07:00
Jordan Ritter fada109b72 Merge remote-tracking branch 'origin/main' into blitz/cvdiag-observability/integration
# Conflicts:
#	showcase/integrations/ms-agent-harness-dotnet/agent/BeautifulChatAgent.csproj
2026-06-19 13:51:02 -07:00
Jordan Ritter 73b5c5a798 feat(showcase): tier-ordered dependency-gated cluster promote + lint-prod gate 2026-06-19 12:23:23 -07:00
Ran Shem Tov 0e5b2189e7 feat(showcase): add strands-typescript integration with base demos
Add a new node/TypeScript-backed AWS Strands showcase integration at
showcase/integrations/strands-typescript.

Backend: a node/TS agent server (src/agent/) built on @strands-agents/sdk
`Agent`/`tool` wrapped in @ag-ui/aws-strands `StrandsAgent` and served via
@ag-ui/aws-strands/server (`createStrandsApp`/`addStrandsExpressEndpoint`),
modeled on the upstream ag-ui aws-strands TS example server and the
langgraph-typescript infra. A single shared agent at "/" serves most demos
(tools, shared state via toolBehaviors/stateContextBuilder, HITL,
sub-agents), with tool-free specialized agents mounted at /voice,
/byoc-hashbrown, /byoc-json-render. model-factory targets OpenAI chat
completions and honors OPENAI_API_KEY / OPENAI_BASE_URL so it works behind
the showcase aimock proxy. Node-based Dockerfile + entrypoint run the agent
server (:8000) alongside the Next.js frontend.

Frontend mirrors the strands (Python) sibling's demo set and the
langgraph-typescript conventions, with HttpAgent routes proxying to the TS
agent server.

Scope: base integration + standard demos only. A2UI / declarative-gen-ui /
a2ui-fixed-schema is intentionally excluded (no A2UI agents, routes, demos,
or deps) and layered on later.

Platform wiring (mirrors langgraph-typescript): docker-compose local/dev
services on host port 3119, local-ports.json, packages.json, slug-map.ts
(born-in-showcase), showcase_build.yml matrix + path filter + metadata,
shell-docs/dashboard registries, and a logo asset. The python strands
integration is untouched.
2026-06-19 17:38:02 +02:00
Alem Tuzlak f91f5d6968 Merge remote-tracking branch 'origin/main' into feat/bot-whatsapp
# Conflicts:
#	docs/model-allowlist.json
#	docs~origin_main
#	examples/slack/package.json
2026-06-19 17:26:54 +02:00
Jordan Ritter 7335d58359 fix(showcase): promote pins staging's running digest + verify serving + drift alarm (#5566)
## Summary

Fixes two correctness bugs in the showcase staging→prod promote path
(`showcase/bin/railway`), discovered + live-validated while promoting
the full 19-service cluster.

**Bug #1 — promote pinned the wrong digest.** `resolved_prod_image`
re-resolved the mutable `:latest` tag against *current* GHCR instead of
pinning the digest staging is actually *running*
(`latestDeployment.meta.imageDigest`). When `:latest` drifted after
staging deployed, promote pushed an unvalidated (and once, regressed)
image to prod. Now pins staging's running digest. Adds a loud `⚠️
STAGING DRIFT` warning (promote stdout + `STAGING_DRIFT_MARKER:` →
`promote-fleet.sh` aggregation → both Slack payloads) when staging's
running digest ≠ current `:latest`, so the gap is visible without
blocking the promote.

**Bug #2 — the pin never activated.** `pin_and_verify` used
`serviceInstanceRedeploy`, which replays the *existing* deployment's old
image rather than the just-pinned `source.image`. Config showed the new
digest while prod kept serving the old one (this is why earlier promotes
"succeeded" while prod stayed broken). Switched to
`serviceInstanceDeployV2` + a new `verify_serving_digest!` gate that
polls the new deployment to SUCCESS and **fails loud** if the running
digest ≠ pinned.

Plus CR-round hardening: P2 in-flight race check now reads
`meta.imageDigest` (was dead on tag-form staging) and skips on
`--digest` override; `detect_staging_drift` fails loud (WARN) on
GHCR-resolve failure instead of swallowing; `--digest` override
suppresses spurious drift; `drift_line` LF-stripped at the
`GITHUB_OUTPUT` boundary; multi-service drift join fixed; fallback-log
drift preserved.

## Commits
1. `fix(showcase): pin prod to staging's running digest + loud
staging-drift warning`
2. `fix(showcase): activate prod pin via serviceInstanceDeployV2 +
verify running==pinned`
3. `fix(showcase): harden promote P2 race check + refresh ivar-lint
allowlist`

## Validation
- Live red-green on real Railway: claude-sdk-python prod flipped from
stale → pinned digest via the fixed CLI; all 19 cluster services
promoted green; 5 previously-degraded backends (ag2, llamaindex,
pydantic-ai, ms-agent-python, strands) recovered.
- 15/15 Ruby specs + 15/15 bats green; ruby -c, shellcheck (CI
invocation), actionlint clean.
- 3-round cr-loop (7 agents/round) converged to zero bucket-(a).

## Follow-ups (not in this PR)
- Defensive `.to_s.empty?` on `meta.imageDigest` extraction
(can't-happen on real Railway).
- Test-quality nits (capture_io scoping, weak bats glob, shared mock
fixture).
- Pre-existing verify-prod `succeeded_csv`/`GITHUB_OUTPUT` coupling
(graceful-degraded, audited STAY_IN_C).
- `deploy-to-railway.ts` births prod on `:latest` (the root provisioning
gap); CLI↔workflow notify equivalence (PR2).

## Test plan
- [ ] CI green on PR HEAD
- [ ] (post-merge) a real `gh workflow run showcase_promote.yml` shows
the drift line in the #team-showcase notification when staging is behind
:latest
2026-06-19 07:55:46 -07:00
Sam Julien 3ae761a966 chore(docs): remove retired docs app (#5548)
## Summary
- remove the retired top-level `docs/` Next app and the disabled
docs-sync workflow/script
- add `docs -> showcase/shell-docs` as a top-level symlink for `cd docs`
muscle memory without restoring the old docs tree
- move the docs model allowlist into `showcase/shell-docs/` and retarget
docs validation/doctest extraction to shell-docs content
- update docs/agent guidance and CI path filters so `docs/` is treated
as an alias, not an active separate docs surface
- tighten the pre-commit package check so non-package docs/tooling
changes do not fan out into the full package matrix

## Validation
- `pnpm exec tsx scripts/validate-doc-model-names.ts`
- `pnpm exec tsx scripts/doc-tests/extract.ts`
- `pnpm exec vitest run
scripts/__tests__/validate-doc-model-names.test.ts
scripts/doc-tests/__tests__/extract.test.ts
showcase/harness/src/cli/eval/scope.test.ts`
- `pnpm exec oxlint showcase/harness/src/cli/eval/scope.test.ts
scripts/doc-tests/extract.ts`
- `git diff --cached --check` before follow-up commit
- `test "$(readlink docs)" = "showcase/shell-docs"`
- `test -f docs/package.json`
- `pnpm exec oxfmt --check .claude/docs/documentation.md
.claude/docs/hooks.md AGENTS.md CLAUDE.md CONTRIBUTING.md
showcase/shell-docs/README.md`
- commit hooks passed

## Notes
- historical docs remain recoverable from
`archive/docs-save-do-not-prune` and `archive/docs-retired-2026-06-17`
- I intentionally left Vercel/project teardown out of this PR; this is
repo cleanup only
2026-06-19 07:33:51 -07:00
Benjamin Taylor 4d1e1ef323 fix(release): scope release-workflow concurrency keys by release target
The stable-release (create-pr), publish-release, and canary workflows all
used a target-agnostic concurrency group, so releasing one scope (e.g.
`monorepo`) would queue behind an unrelated scope's run (e.g. `angular`)
despite touching disjoint packages and tags. Fold the release target into
each concurrency key so different scopes run in independent lanes while
same-scope runs stay serialized (cancel-in-progress: false), preserving the
version-bump / tag-push / npm-publish race protection.

publish-release also fires on merged release PRs where `inputs.scope` is
empty; the PR branch `release/publish/<scope>/v<version>` carries the scope
via `github.head_ref`, so the key stays scope-distinct on that path too.

ENT-950

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-19 09:25:29 -05:00
Alem Tuzlak d92959e68d Merge remote-tracking branch 'origin/main' into feat/bot-whatsapp
# Conflicts:
#	.github/workflows/canary.yml
#	.github/workflows/publish-release.yml
#	.github/workflows/stable-release.yml
#	examples/slack/README.md
#	examples/slack/app/index.ts
#	examples/slack/app/sender-context.ts
#	release.config.json
2026-06-19 16:17:16 +02:00
Alem Tuzlak 340722f597 Merge remote-tracking branch 'origin/main' into feat/bot-whatsapp
# Conflicts:
#	examples/slack/package.json
#	pnpm-lock.yaml
#	showcase/shell-docs/src/content/docs/meta.json
2026-06-19 11:22:56 +02:00
Alem Tuzlak 7fe12d6d3c Merge remote-tracking branch 'origin/main' into feat/bot-telegram-adapter
# Conflicts:
#	examples/slack/README.md
#	examples/slack/package.json
#	pnpm-lock.yaml
2026-06-19 11:04:18 +02:00
GeneralJerel 274202938d ci: allowlist oracle-agent-memory showcase next.config.ts
The check-config-files gate requires new build-config files to be listed in
.github/config-allowlist.txt. Registers the new showcase's frontend config.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 16:37:19 -07:00
Jordan Ritter 9708f7ed45 fix(showcase): pin prod to staging's running digest + loud staging-drift warning
Bug #1: resolved_prod_image re-resolved :latest at promote time, so prod
could be pinned to a digest different from what staging is actually serving.
Now resolve via staging_running_digest (latestDeployment meta.imageDigest)
and REFUSE when unavailable. Add detect_staging_drift +
emit_staging_drift_warnings to surface (non-fatally) when :latest has moved
past staging's running digest; aggregate markers across the fleet in
promote-fleet.sh (printf join) and plumb the drift_line through
showcase_promote.yml (both Slack payloads + fallback log + GITHUB_OUTPUT
single-line guard). Skip drift detection on the --digest override path.
2026-06-18 16:20:34 -07:00
Mike Ryan a296c57ef4 fix: sync plugin metadata before release PR creation 2026-06-18 15:03:10 -07:00
Jordan Ritter 07915f3c1c feat(cvdiag): CI perf-regression gate for emit cost (100µs median / 250µs p99) (L2-D) 2026-06-18 14:47:33 -07:00
Mike Ryan 24151b1822 chore: fix release workflow lint 2026-06-18 13:56:01 -07:00
Mike Ryan 64999fb9a9 chore: prepare angular package release 2026-06-18 13:49:35 -07:00
Sam Julien 33a79485b6 chore(docs): remove retired docs app 2026-06-18 10:54:16 -07:00
Alem Tuzlak 02be193fcc ci(release): make @copilotkit/bot-discord a releasable scope 2026-06-18 19:28:25 +02:00
Austin Merrick 4129a0aedf ci(plugin-skills): trigger drift check on runtime package.json changes
The plugin version pins to packages/runtime/package.json, but neither the
lefthook glob nor the plugin-skills-check workflow path filters watched
that file. A routine release bump to the runtime version therefore matched
no trigger and the pin silently rotted between releases (the root cause of
the version drift). Add packages/runtime/package.json to the lefthook glob
and to both the push and pull_request path filters so a version bump
re-runs check:plugin-skills.
2026-06-18 09:23:03 -07:00
Alem Tuzlak 80e95f26d4 ci(release): make @copilotkit/bot-telegram a releasable scope 2026-06-18 15:50:23 +02:00
Alem Tuzlak f9b54fea2c chore(release): enroll @copilotkit/bot-whatsapp in the manual release config
Add a bot-whatsapp release scope to release.config.json and the matching
workflow_dispatch scope dropdowns in publish-release / stable-release / canary,
so the package can be released via the manual CI trigger like bot-slack.
2026-06-18 15:50:08 +02:00
Jordan Ritter 6130c1acf0 ci(showcase): add promote-notify Slack workflow + dry-run harness
Adds .github/workflows/showcase_promote_notify.yml — workflow_dispatch-only
Slack notify workflow for promote results. Posts initiation + threaded reply
to #team-showcase; cross-posts to #oss-alerts on partial/total failure.

Also adds showcase_promote_notify.dry-run.sh — a local render-logic mirror
that decodes the same payload and prints the messages the workflow would
send to Slack, without making any Slack API calls. Used by the pre-merge
runbook and by future CI fixture tests.
2026-06-17 11:28:41 -07:00
Jordan Ritter 5f00cb9771 ci(release): one-click canary publish orchestrator + release-pipeline lint guards (#5370)
## Summary

Ports
[ag-ui-protocol/ag-ui#1914](https://github.com/ag-ui-protocol/ag-ui/pull/1914)
to CopilotKit — plus the two supporting guard files ag-ui already had:

- **`.github/workflows/canary.yml`** — discoverable **`canary /
publish`** `workflow_dispatch` orchestrator. Any maintainer can publish
a prerelease of the branch they're on straight from the Actions tab. It
is a thin orchestrator — it does **not** publish to npm itself:
  1. Guards against `main` and non-branch refs.
2. Mints the devops-bot App token (app-id `1108748`,
`DEVOPS_BOT_PRIVATE_KEY`) with scoped `contents:write` +
`actions:write`.
3. Mirrors the dispatched ref to a unique
`canary/<slug>-<run_id>-<attempt>` branch via the GitHub API (no
checkout).
4. Dispatches **`publish-release.yml --ref canary/<slug> -f
mode=prerelease …`**, locates the run, and waits (`gh run watch
--exit-status` + explicit conclusion check).
5. Deletes the canary ref — status-gated (never yanks the ref under a
still-running delegated run) with a fresh cleanup token (90-min job
ceiling exceeds the 1h App-token TTL).
- **`scripts/release/verify-release-scope-dropdowns.sh`** — drift guard:
the hand-maintained `scope` dropdowns in `publish-release.yml` /
`stable-release.yml` / `canary.yml` must exactly match
`release.config.json`'s `.scopes` keys. Parsers fail loud and distinct
on structural changes instead of silently passing.
- **`.github/workflows/lint-release-workflows.yml`** — actionlint +
shellcheck + the dropdown-sync job over the release pipelines.

### Why a separate orchestrator (and not a flag in publish-release.yml)
- A GitHub Environment's deployment-branch policy is evaluated against
the ref a run is **triggered on** — not branches created mid-run. The
orchestrator exists to get the publish run *onto* a `canary/*` ref.
- `publish-release.yml` holds the **single npm OIDC trusted-publisher
binding**; a second publishing entry point would break OIDC for every
`@copilotkit/*` package. The orchestrator never touches npm.
- The cross-workflow dispatch uses the **App token, not `GITHUB_TOKEN`**
— `GITHUB_TOKEN`-authenticated events never start new workflow runs.

**Note:** the `npm` environment currently has *no* deployment-branch
policy, so the orchestrator is a convenience wrapper today. Tightening
the policy to `main` + `canary/*` + `release/publish/*` (matching
ag-ui's security posture) is being applied as repo configuration
alongside this PR — requires admin. This PR includes the prerequisite:
`publish-commit.yml` (pkg-pr-new) is removed from the `npm` environment,
since it runs on every PR and would be blocked by the policy (it
publishes to pkg.pr.new, not npm, and uses no environment secrets).

## Testing done
- Drift guard: positive run against all three real workflows; negative
tests (scope removed → drift FAIL with diff; bogus scope → FAIL; `case
"${SCOPE}"` quoting refactor → loud parser-degradation FAIL; whole case
block deleted → loud zero-block FAIL; quoted arm `"angular")` →
accepted; blank/comment lines inside `options:` → still parsed; prose
comments mentioning case/SCOPE/in → no false positive).
- `shellcheck` clean at all severities; `bash -n` on every workflow
`run:` block; YAML parses.
- 3 rounds of 7-agent code review converged to zero load-bearing
findings.

## ⚠️ Still to verify before first real use
- [ ] devops-bot App (id 1108748) has **Actions: write** — required for
the in-workflow `gh workflow run`. Safe first test: dispatch once with
`dry_run=true`.
- [ ] First `dry_run=false` run clears the `npm` environment end-to-end
via the App token once the deployment-branch policy is tightened.

🤖 Generated with [Claude Code](https://claude.com/claude-code)


## Post-merge follow-ups (maintainer action required)

These need repo **admin** rights and must happen **in this order**:

1. **Merge this PR first.** `main`'s current `publish-commit.yml`
(pkg-pr-new) still sits in the `npm` environment and runs on every PR
touching `packages/**` — applying the branch policy before this PR lands
would block every snapshot publish. This PR removes that environment
association.

2. **Tighten the `npm` environment's deployment-branch policy** to
`main` + `canary/*` + `release/publish/*` (matching ag-ui). With an
admin-scoped token:

   ```bash
   gh api --method PUT repos/CopilotKit/CopilotKit/environments/npm \
     -F "deployment_branch_policy[protected_branches]=false" \
     -F "deployment_branch_policy[custom_branch_policies]=true"
gh api --method POST
repos/CopilotKit/CopilotKit/environments/npm/deployment-branch-policies
-f name="main" -f type=branch
gh api --method POST
repos/CopilotKit/CopilotKit/environments/npm/deployment-branch-policies
-f name="canary/*" -f type=branch
gh api --method POST
repos/CopilotKit/CopilotKit/environments/npm/deployment-branch-policies
-f name="release/publish/*" -f type=branch
   ```

Or via UI: Settings → Environments → npm → Deployment branches and tags
→ "Selected branches and tags" → add the three patterns above.

Why these three: `main` covers stable `workflow_dispatch` retries and
`stable-release.yml`; `release/publish/*` covers the merged-release-PR
runs (the run's head branch is the release PR branch); `canary/*` covers
the orchestrator's delegated prerelease runs. After this, direct
`mode=prerelease` dispatches from arbitrary feature branches stop
working — the `canary / publish` orchestrator becomes the one-click path
(by design).

3. **Verify the devops-bot App (id `1108748`) has `Actions: write`**
(org/App settings). The orchestrator's `gh workflow run` dispatch 403s
without it. Safe end-to-end test, after step 2: Actions tab → **canary /
publish** → pick any feature branch, any scope, **`dry_run=true`** →
confirm the delegated `release / publish` run is created, watched, and
the `canary/*` ref is deleted afterward.

4. **First real canary** (`dry_run=false`) confirms the npm OIDC publish
clears the environment gate end-to-end on a `canary/*` ref.
2026-06-17 08:22:44 -07:00
Martha Kelly Schumann fae4d30ad8 Merge branch 'main' into codex/fix-docs-model-validator-trigger 2026-06-16 10:10:06 -07:00
Benjamin Taylor 6618d92f72 ci(test-unit): scope build+test to nx affected packages
Run `test / unit` over only the packages affected since the base instead
of building + testing every package 3× across the Node 20/22/24 matrix on
every PR.

- fetch-depth: 0 so affected has a merge-base to diff against.
- Derive NX_BASE/NX_HEAD: PR → merge-base with the base branch tip; push →
  github.event.before with a HEAD~1 fallback.
- Select packages via `nx show projects --affected --projects='packages/**'`
  fed to run-many (the `nx affected` run form ignores --projects and pulls
  in downstream examples/storybook — hence the show-projects → run-many split).
- workflow_dispatch still runs all packages (manual/full run).
- Editing this workflow can't surface as an affected package, so a change to
  test_unit.yml in the range now forces a full all-packages run — this keeps
  the build/test path exercised on the PR that changes it.
- GitHub context passed via env: (not inline ${{ }}) to satisfy zizmor;
  NX_VERBOSE_LOGGING forced off for the JSON-parsing step.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-16 12:08:18 -05:00
Martha Schumann 38e987f7e4 fix(docs): validate showcase docs model names 2026-06-16 09:55:14 -07:00
Jordan Ritter 5afa55f067 chore: drop dead .changeset/ debris and workflow path filters
The repo migrated off @changesets/* to conventional-commit-driven releases.
scripts/release/lib/changes.ts::getChangesSummary reads `git log <lastTag>..HEAD`
commit subjects and never touches .changeset/. No .changeset/config.json,
no @changesets/* in any package.json, no npm scripts reference it.

The 11 .changeset/*.md files describe changes that have either already
shipped (via commit subjects in prior releases) or will ship in the next
release (via the current commit subjects in the v1.60.1..main window) —
the .changeset/ files are inert.

Also removes the dead workflow `paths:` filters in
test_e2e-dojo.yml and test_e2e-legacy-v1.yml that re-fired e2e on
.changeset/ changes — nothing to fire on after the directory is gone.
2026-06-16 00:25:05 -07:00
Jordan Ritter c43ed08e7b ci(e2e-dojo): run dojo suites on 4-vCPU runner (−40% wall-clock) (#5452)
Bumps the dojo e2e matrix from `depot-ubuntu-24.04` (2 vCPU) to
`depot-ubuntu-24.04-4` (4 vCPU) and `NX_PARALLEL: 4` so the build uses
the extra cores. This is the non-serializing way to cut dojo wall-clock
(the build-once dedup tried in #5450 regressed wall-clock and was
reverted).

## Result: −40% wall-clock (measured on CI)

Dojo wall-clock = the single slowest suite (the 15 run in parallel).
Comparison vs the 2-vCPU baseline:

| metric | 2-vCPU baseline | 4-vCPU | Δ |
|---|---|---|---|
| **wall-clock** (long pole `langgraph-python`) | 623s (10.4m) | **373s
(6.2m)** | **−40%** |
| runner-minutes (wall summed, 15 suites) | 105m | 76m | −28% |
| **billed compute** (vCPU-min; 4-vCPU ≈ 2× rate) | ~210 | ~304 |
**+45%** |

Every suite got faster; the long-pole suites benefited most:

| suite | 2-vCPU | 4-vCPU |
|---|---|---|
| langgraph-python | 623s | 373s |
| langgraph-typescript | 547s | 362s |
| langgraph-fastapi | 500s | 337s |
| adk-middleware | 414s | 286s |
| (… all 15 faster …) | | |

Long-pole `langgraph-python` step breakdown:

| phase | 2-vCPU | 4-vCPU |
|---|---|---|
| Build cpk | 82s | 48s |
| Prep dojo | 94s | 52s |
| **Run tests (Playwright)** | **271s** | **117s** |
| total | 623s | 373s |

**Key finding:** the Playwright phase more than halved → the e2e suites
are **CPU/worker-bound, not LLM-latency-bound**. A bigger runner is the
right lever; test sharding is not needed to reach ~6 min.

## Trade-off
−40% wall-clock for **~+45% billed compute** (4-vCPU costs ~2×/min,
partly offset by finishing 28% sooner). If the cost bump isn't worth it
across all 15 suites, a follow-up can scope `-4` to just the slow suites
via a per-matrix `runner` field (wall ~6.5m, smaller cost increase).

Companion to #5450 (unit-test `nx affected`).
2026-06-15 12:49:19 -07:00
Benjamin Taylor 8de9ac5f5b ci(e2e-dojo): bump dojo suites to 4-vCPU runner (experiment)
Measure wall-clock impact of a larger Depot runner on the e2e suites.
The long pole (langgraph-python, ~10.4min) spends ~50% on build/prep
(CPU-bound) and ~43% on the Playwright run. 2->4 vCPU + NX_PARALLEL 4
should speed build/prep; the test-phase gain reveals whether it is
CPU-bound (big win) or LLM-latency-bound (then sharding is the lever).
2026-06-15 12:07:29 -05:00
Mark Fogle 53801f8e04 test(showcase): make sales-dashboard e2e reproduce real-model catalogId omission
The injected/streamed a2ui fixtures all included catalogId, so aimock
replay never exercised the basic-catalog fallback that broke production
(real models omit catalogId per the tool-usage guide). Strip catalogId
from the langgraph-python sales-dashboard secondary-call fixtures and
hard-assert "Catalog not found" is absent outside the charts-rendered
soft branch, so the spec fails without a route defaultCatalogId.

Also repoint the on-demand e2e workflow at the d4/d5-recorded/d6/shared
fixture dirs — it still referenced feature-parity.json, deleted in the
1e66a5f8d fixture reorg, so every /test-aimock run died at aimock start.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-12 18:47:16 +00:00
Jordan Ritter df1b2d572d fix(showcase/spring-ai): consolidate content-red fixes — manifest NSF reasoning canon, Jackson @Primary mapper + RunErrorEvent wire-shape, error-banner pattern, Java tool JSON hardening, .ag-ui-sha pin + CI workflow 2026-06-12 07:59:35 -07:00
Markus Ecker 7be6b5dbb7 add Angular contributors as code owners of the Angular package
Make wolfmanfx (Murat Sari) and rainerhahnekamp (Rainer Hahnekamp) code
owners of packages/angular and packages/v2/angular, alongside core dev.
Repo access itself is granted separately via GitHub collaborator settings.
2026-06-11 17:23:57 +02:00
Maxim 441d854608 ci(release): drop vestigial npm environment from pkg-pr-new workflow
pkg-pr-new publishes snapshot builds to pkg.pr.new, not the npm
registry, and uses no environment-scoped secrets or variables. The
job runs on every push/PR touching packages/**, so the npm
environment's tightened deployment-branch policy (main, canary/*,
release/publish/*) would block every snapshot publish. Removing the
environment association is a prerequisite for the policy.
2026-06-11 01:31:36 +02:00
Maxim b3d2001a0e ci(release): add lint workflow for release pipelines
actionlint over stable-release.yml, publish-release.yml, canary.yml,
and itself; shellcheck (severity warning) over scripts/release shell
scripts; and the release-scope-dropdown-sync job running
verify-release-scope-dropdowns.sh. Scope intentionally narrow to the
release pipelines to avoid drowning unrelated changes in lint noise.

Ported from ag-ui-protocol/ag-ui.
2026-06-11 01:28:36 +02:00
Maxim 0564aa21df ci(release): add one-click canary publish orchestrator workflow
canary / publish: a workflow_dispatch orchestrator that mirrors the
dispatched ref to a unique short-lived canary/<slug>-<run_id>-<attempt>
branch via the GitHub API (devops-bot App token, app-id 1108748),
dispatches publish-release.yml on that ref with mode=prerelease, waits
for the delegated run (gh run watch + explicit conclusion check), and
deletes the ref afterward.

It does NOT publish to npm itself — publish-release.yml holds the
single npm OIDC trusted-publisher binding. Failure paths covered:
suffix validated before any side effect, ref kept when a dispatched
run was never located, ref deleted when the dispatch itself failed,
status-gated deletion + fresh cleanup token for cancellation/timeout
(90-min ceiling exceeds the 1h App-token TTL and queueing behind
publish-release's global concurrency group).

Ported from ag-ui-protocol/ag-ui PR #1914 with cpk adaptations
(scopes from release.config.json; dry_run -> dry-run input mapping).
2026-06-11 01:28:36 +02:00
Tyler Slaton fe685eb46f feat(release): npm release scopes for bot(+bot-ui) and bot-slack
- release.config.json: 'bot' scope versions @copilotkit/bot and
  @copilotkit/bot-ui together (sharedVersion: true, source: bot);
  'bot-slack' is its own scope, mirroring the angular precedent
- ReleaseScope type + VALID_SCOPES arrays + usage strings extended across
  release scripts
- stable-release.yml / publish-release.yml: scope choice options
- bot, bot-ui, bot-slack manifests: drop private, add publishConfig (public),
  repository/homepage/keywords, publint/attw targets; first release v0.0.1
- internal bot-package deps use workspace:~ (tilde): caret on a 0.0.x version
  pins the exact patch, tilde tracks the 0.0.x line; core/shared stay
  workspace:^ (caret is correct at 1.x)

Verified: release-script tests 85/85; prepare-release --scope bot --dry-run
bumps bot AND bot-ui in lockstep; actionlint clean on touched lines.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-10 12:57:13 -07:00
Jordan Ritter c413ec3ddb fix(showcase): report verify-prod=skipped (not success) when prod was never probed
When a promote fails, the succeeded-service set is empty, so verify-prod
hits its skip branch (`exit 0`). The GitHub job result is therefore
`success`, and the notify step rendered `verify-prod=success` in the
#oss-alerts Slack message — a misleading green, since prod was never
probed.

verify-prod now exports a `status` output: `success` after a real probe
passes, `skipped` on the empty-CSV skip. notify reads that output (via
the new bats-tested verify-prod-display.sh) instead of the raw job
result, so the Slack line accurately reads `verify-prod=skipped` vs
`success` vs `failure`. A genuine probe failure / contract violation
exits non-zero (job result `failure`, status never written), and the
display falls back to the job result. Slack formatting is unchanged.

Extracts the display mapping into showcase/scripts/verify-prod-display.sh
(mirroring promote-fleet.sh) with red-green bats coverage, and adds it to
the showcase_validate.yml shellcheck step.
2026-06-08 10:45:07 -07:00
Jordan Ritter 7bde1eef3a ci(showcase): pull Git LFS assets during build so demo images ship real binaries 2026-06-07 10:00:16 -07:00
Ben Taylor 3757ff46cb Merge branch 'main' into ben1/ent-800-remove-defunct-langgraph-python-threads-example 2026-06-05 16:19:37 -05:00
Tyler Slaton 47a4930d26 fix(ci): allow branch prerelease dispatches 2026-06-05 14:07:34 -07:00
Benjamin Taylor f24d43c12a Merge remote-tracking branch 'origin/main' into ben1/ent-800-remove-defunct-langgraph-python-threads-example
# Conflicts:
#	examples/integrations/langgraph-python-threads/apps/app/package.json
#	examples/integrations/langgraph-python-threads/apps/bff/package.json
#	examples/integrations/langgraph-python-threads/package-lock.json
2026-06-05 15:47:55 -05:00