Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
11f3e1a
wix-app: one SDK lookup call per feature, with the call shape
kobiburnley Oct 8, 2026
9dd66aa
wix-app: sdk-lookup takes the public signature and the spec's filter …
kobiburnley Oct 8, 2026
fdc2e36
wix-app: sdk-lookup names the index file's path, points other methods…
kobiburnley Oct 8, 2026
ddf1ff8
wix-app: sdk-lookup derives every record from the .d.ts files, drop s…
kobiburnley Oct 8, 2026
1788bff
wix-app: sdk-lookup prints the keys of a search, query or list call's…
kobiburnley Oct 8, 2026
e8c1a98
wix-app: DATA_SOURCES.md back under the 10,000-char fetch limit
kobiburnley Oct 8, 2026
7e78a4e
Merge remote-tracking branch 'origin/main' into wix-app/sdk-lookup-poc
kobiburnley Oct 8, 2026
2686f42
ci: test wix-app's sdk-lookup.cjs on trimmed copies of real SDK packages
kobiburnley Oct 8, 2026
ed08857
wix-app: sdk-lookup prints a builder's query-object form, and keeps a…
kobiburnley Oct 9, 2026
b4c919e
wix-app: sdk-lookup sets a query form's keys last, the same order as …
kobiburnley Oct 9, 2026
3fbce34
wix-app: say how to key a map by an SDK enum without TS7053
kobiburnley Oct 9, 2026
380e7f3
Merge remote-tracking branch 'origin/main' into wix-app/sdk-lookup-poc
kobiburnley Oct 12, 2026
dec274f
wix-app: the SDK lookup says how to apply a search term (#1745)
kobiburnley Oct 13, 2026
4aa2611
Merge remote-tracking branch 'origin/main' into wix-app/sdk-lookup-poc
kobiburnley Oct 13, 2026
6cee451
wix-app: address the #1684 review of the SDK lookup
kobiburnley Oct 14, 2026
0c32c1f
skill-eval: rebuild dist for the tag-globs change in evalforge-core
kobiburnley Oct 14, 2026
1688e7c
wix-app: the SDK lookup ranks shared namespaces by the module map, no…
kobiburnley Oct 14, 2026
14e147a
wix-app: with no module map row, the lookup prefers the package named…
kobiburnley Oct 14, 2026
6500d22
wix-app: the SDK lookup prints the entity type and package lines befo…
kobiburnley Oct 15, 2026
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
12 changes: 7 additions & 5 deletions .github/actions/evalforge-skill-gate/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -239,11 +239,12 @@ Changed paths are classified in a **fixed precedence, first match wins**:

| # | Changed path | Result |
|---|---|---|
| 1 | matches `ignore-globs` | ignored, silently |
| 2 | matches `broad-impact-globs` | **broad impact** → the whole suite is in play |
| 3 | `<reference-dir>/DASHBOARD_PAGE.md` | tag `dashboard-page` — lowercase, `_` → `-`, drop `.md` |
| 4 | `<reference-dir>/dashboard-page/API_SPEC.md` | tag `dashboard-page` — the directory name is already the tag |
| 5 | any other file under `skill-dir` | **unmapped** — warned about, triggers nothing |
| 1 | matches a `tag-globs` glob | the tags that line names — a script the skill tells the agent to run, inside an ignored directory |
| 2 | matches `ignore-globs` | ignored, silently |
| 3 | matches `broad-impact-globs` | **broad impact** → the whole suite is in play |
| 4 | `<reference-dir>/DASHBOARD_PAGE.md` | tag `dashboard-page` — lowercase, `_` → `-`, drop `.md` |
| 5 | `<reference-dir>/dashboard-page/API_SPEC.md` | tag `dashboard-page` — the directory name is already the tag |
| 6 | any other file under `skill-dir` | **unmapped** — warned about, triggers nothing |
| — | the scenario glob | no tag; changed scenarios are included in the run directly |
| — | anything else | ignored |

Expand Down Expand Up @@ -294,6 +295,7 @@ capability version, no run — so a coverage failure reports in seconds and cost
| `reference-dir` | `gate` | `references` | Relative to `skill-dir` |
| `ignore-globs` | `gate` | `scripts/**` | Newline-separated, relative to `skill-dir` |
| `broad-impact-globs` | `gate` | `SKILL.md` + the six cross-cutting references | Newline-separated, relative to `skill-dir` |
| `tag-globs` | `gate` | none | Newline-separated `glob: tag[, tag]`, relative to `skill-dir`; checked before `ignore-globs` |
| `max-scenarios` | `gate` | `25` | Touched scenarios kept first; anything cut is named in the comment |
| `runs-per-scenario` | `gate` | `1` | Max `20`. Each scenario repeats this many times **per arm**, so an intermittent failure is visible instead of indistinguishable from a regression — at proportional cost. An intermittent failure counts as a failure |
| `base-arm-grace-seconds` | `gate` | `60` | Max `300`. `0` means "don't wait for the base arm at all". Window the base arm gets after the PR arm completes before its poll is cancelled. Exceeding it degrades the comment to "attribution unavailable" without affecting the verdict — the base eval run itself still completes server-side either way |
Expand Down
4 changes: 4 additions & 0 deletions .github/actions/evalforge-skill-gate/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ inputs:
required: false
default: |
scripts/**
tag-globs:
description: 'Newline-separated "glob: tag[, tag]" lines, relative to skill-dir. A changed file that matches derives those tags; checked before ignore-globs, so it can name a script under scripts/'
required: false
default: ''
broad-impact-globs:
description: 'Newline-separated globs, relative to skill-dir, whose changes put the whole suite in play. These derive no tag of their own and are never coverage-checked'
required: false
Expand Down
27 changes: 24 additions & 3 deletions .github/actions/evalforge-skill-gate/dist/index.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion .github/actions/evalforge-skill-gate/src/utils/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import * as github from '@actions/github';
import {
DEFAULT_BASE_ARM_GRACE_SECONDS, DEFAULT_BROAD_IMPACT_GLOBS, DEFAULT_IGNORE_GLOBS, DEFAULT_MAX_SCENARIOS,
DEFAULT_REFERENCE_DIR, DEFAULT_RUNS_PER_SCENARIO, ensureHttps, safeGetSecret, getPrNumber,
readHeadRepoFullName,
parseTagGlobs, readHeadRepoFullName, type TagGlob,
} from '@wix/evalforge-core';

/** Subdirectory the base-SHA checkout lands in, matching the yaml-gate workflows. */
Expand Down Expand Up @@ -77,6 +77,7 @@ export type GateConfig = {
referenceDir: string;
ignoreGlobs: string[];
broadImpactGlobs: string[];
tagGlobs: TagGlob[];
maxScenarios: number;
/** The action input stays `blocking` — that name is the public contract and reads right in YAML. */
isBlocking: boolean;
Expand Down Expand Up @@ -266,6 +267,7 @@ export function getGateConfig(): GateConfig {
referenceDir: core.getInput('reference-dir') || DEFAULT_REFERENCE_DIR,
ignoreGlobs: getMultilineList('ignore-globs', DEFAULT_IGNORE_GLOBS),
broadImpactGlobs: getMultilineList('broad-impact-globs', DEFAULT_BROAD_IMPACT_GLOBS),
tagGlobs: parseTagGlobs(getMultilineList('tag-globs', [])),
maxScenarios,
isBlocking: core.getInput('blocking') === 'true',
owner,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ function deriveChangeScope(
referenceDir: config.referenceDir,
ignoreGlobs: config.ignoreGlobs,
broadImpactGlobs: config.broadImpactGlobs,
tagGlobs: config.tagGlobs,
});
const touchedPaths = new Set(touchedScenarioPaths(
changedFiles.map(file => ({ path: file.filename, status: file.status })),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ describe('action.yml', () => {
'mode', 'github-token', 'evalforge-url', 'evalforge-project-id',
'evalforge-app-id', 'evalforge-app-secret', 'evals-glob',
'capability-id', 'agent-id', 'skill-dir', 'reference-dir',
'ignore-globs', 'broad-impact-globs', 'max-scenarios', 'blocking', 'runs-per-scenario',
'ignore-globs', 'broad-impact-globs', 'tag-globs', 'max-scenarios', 'blocking', 'runs-per-scenario',
'base-arm-grace-seconds', 'eval-run-id',
]) {
expect(Object.keys(action.inputs), name).toContain(name);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ const CONFIG: GateConfig = {
referenceDir: 'references',
ignoreGlobs: ['scripts/**'],
broadImpactGlobs: ['SKILL.md'],
tagGlobs: [],
maxScenarios: 25,
isBlocking: true,
owner: 'wix',
Expand Down
18 changes: 18 additions & 0 deletions .github/actions/evalforge-skill-gate/tests/config.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,24 @@ describe('getGateConfig', () => {
expect(getGateConfig().broadImpactGlobs).toEqual(['SKILL.md', 'docs/README.md']);
});

it('parses tag-globs lines into a glob and its tags', async () => {
setInputs({ ...REQUIRED_GATE_INPUTS, 'tag-globs': 'scripts/sdk-lookup.cjs: sdk-module-map, dashboard-page\n' });
const { getGateConfig } = await import('../src/utils/config');
expect(getGateConfig().tagGlobs).toEqual([{ glob: 'scripts/sdk-lookup.cjs', tags: ['sdk-module-map', 'dashboard-page'] }]);
});

it('defaults tag-globs to none', async () => {
setInputs(REQUIRED_GATE_INPUTS);
const { getGateConfig } = await import('../src/utils/config');
expect(getGateConfig().tagGlobs).toEqual([]);
});

it('rejects a tag-globs line with no tag', async () => {
setInputs({ ...REQUIRED_GATE_INPUTS, 'tag-globs': 'scripts/sdk-lookup.cjs' });
const { getGateConfig } = await import('../src/utils/config');
expect(() => getGateConfig()).toThrow(/tag-globs line must be/);
});

it('treats blocking: true as blocking and anything else as soaking', async () => {
setInputs({ ...REQUIRED_GATE_INPUTS, blocking: 'true' });
const { getGateConfig } = await import('../src/utils/config');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ const CONFIG: GateConfig = {
referenceDir: 'references',
ignoreGlobs: ['scripts/**'],
broadImpactGlobs: ['SKILL.md'],
tagGlobs: [],
maxScenarios: 25,
isBlocking: true,
owner: 'wix',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ const CONFIG: GateConfig = {
referenceDir: 'references',
ignoreGlobs: ['scripts/**'],
broadImpactGlobs: ['SKILL.md'],
tagGlobs: [],
maxScenarios: 25,
isBlocking: true,
owner: 'wix',
Expand Down
25 changes: 22 additions & 3 deletions .github/actions/evalforge-yaml-gate/dist/index.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

25 changes: 22 additions & 3 deletions .github/actions/skill-eval/dist/index.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 16 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,9 @@ jobs:
match() { echo "$changed" | grep -qE "$1"; }

# The wix-app harness itself is included: a change to extract.mjs or its deps can
# break the typecheck just as a reference-doc change can.
if match '^skills/wix-app/|^\.github/wix-app-typecheck/'; then
# break the typecheck just as a reference-doc change can. So is the sdk-lookup
# test and its fixtures, which test a wix-app script.
if match '^skills/wix-app/|^\.github/wix-app-typecheck/|^scripts/test-sdk-lookup\.cjs$|^scripts/fixtures/sdk-lookup/'; then
echo "wix_app=true" >> "$GITHUB_OUTPUT"
else
echo "wix_app=false" >> "$GITHUB_OUTPUT"
Expand Down Expand Up @@ -272,9 +273,21 @@ jobs:
exit 1
fi

# The skill's scripts ship without a build or an eval of their own (derive-tags
# gives scripts/** no tag), so this is what catches a broken sdk-lookup.cjs.
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
if: ${{ needs.detect.outputs.wix_app == 'true' }}
with:
node-version: '22'

- name: wix-app — sdk-lookup tests

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

derive-tags.ts:21 ignores scripts/**, so changes to sdk-lookup.cjs or sdk-curated.json run no evals (as with #1745), yet the skill tells the agent to trust the script over the typings. I suggest mapping these files to the sdk-module-map / dashboard-page tags.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 6cee451. The skill gate has a new tag-globs input (glob: tag[, tag] lines), checked before ignore-globs. evalforge-wix-app-gate.yml maps scripts/sdk-lookup.cjs and scripts/sdk-curated.json to sdk-module-map and dashboard-page. deriveTags, the config and the README are updated, with tests. The gate runs the action from main, so the mapping takes effect after this PR merges.

if: ${{ needs.detect.outputs.wix_app == 'true' }}
run: node --test scripts/test-sdk-lookup.cjs

- name: Summary
run: |
echo "evalforge: ${{ needs.detect.outputs.evalforge }}"
if [ "${{ needs.detect.outputs.evalforge }}" = "false" ]; then
echo "wix-app sdk-lookup: ${{ needs.detect.outputs.wix_app }}"
if [ "${{ needs.detect.outputs.evalforge }}" = "false" ] && [ "${{ needs.detect.outputs.wix_app }}" = "false" ]; then
echo "No tested areas changed — nothing to do."
fi
5 changes: 5 additions & 0 deletions .github/workflows/evalforge-wix-app-gate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,11 @@ jobs:
evalforge-app-secret: ${{ secrets.AUTO_SKILLS_PIPELINE_APP_SECRET }}
evals-glob: 'yaml/wix-app-evals/**/*.{yml,yaml}'
skill-dir: skills/wix-app
# SKILL.md tells the agent to trust the SDK lookup over the typings, so a change to it
# runs the scenarios that call it rather than nothing (scripts/** is ignored).
tag-globs: |
scripts/sdk-lookup.cjs: sdk-module-map, dashboard-page
scripts/sdk-curated.json: sdk-module-map, dashboard-page
# Inline rather than repo vars: neither is a secret, and in the workflow file they
# appear in the diff, get reviewed when they change, and document what the gate
# evaluates against. As repo vars they could be edited silently.
Expand Down
Loading