Skip to content

feat: Add query-index-optimizer skill for EDS content ops - #189

Open
focusgts wants to merge 5 commits into
adobe:mainfrom
focusgts:feat/eds-query-index-optimizer
Open

feat: Add query-index-optimizer skill for EDS content ops#189
focusgts wants to merge 5 commits into
adobe:mainfrom
focusgts:feat/eds-query-index-optimizer

Conversation

@focusgts

Copy link
Copy Markdown
Contributor

Summary

Adds the query-index-optimizer skill to the EDS content ops plugin.

Audits and tunes the query index — analyzes indexed properties against actual usage, checks index size and pagination, and generates helix-query.yaml recommendations.

Follows the established format (functional description, External Content Safety, concrete code examples, reference file for progressive disclosure, Apache-2.0). Submitted as a standalone PR per @trieloff's request to keep one skill per PR.

Test plan

  • tessl-review passes (≥80

@trieloff

Copy link
Copy Markdown
Contributor

@dominique-pfister this seems to be your area of expertise, can you take a look, please?


### Key Concepts

- **helix-query.yaml** — Lives in the GitHub repo root. Defines which properties to index and how they are sourced (from metadata, headings, or content).

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This is no longer true: it lives in the configuration, see: https://www.aem.live/developer/indexing#setting-up-an-initial-index-with-the-index-admin-tool

### Key Concepts

- **helix-query.yaml** — Lives in the GitHub repo root. Defines which properties to index and how they are sourced (from metadata, headings, or content).
- **query-index.json** — The live JSON endpoint. Returns an array of page entries with the indexed properties.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This is just the default name of the query index, it can also be named differently.

- **helix-query.yaml** — Lives in the GitHub repo root. Defines which properties to index and how they are sourced (from metadata, headings, or content).
- **query-index.json** — The live JSON endpoint. Returns an array of page entries with the indexed properties.
- **Consumers** — Blocks and components that fetch `query-index.json` to build dynamic lists: navigation, footer, card lists, search results, recent posts, tag-filtered collections.
- **Default limit** — The index returns a maximum of 500 entries by default. Sites with more pages need to paginate or increase the limit.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Wrong, it returns 1000 entries by default, as documented here: https://www.aem.live/developer/spreadsheets#offset-and-limit

- **query-index.json** — The live JSON endpoint. Returns an array of page entries with the indexed properties.
- **Consumers** — Blocks and components that fetch `query-index.json` to build dynamic lists: navigation, footer, card lists, search results, recent posts, tag-filtered collections.
- **Default limit** — The index returns a maximum of 500 entries by default. Sites with more pages need to paginate or increase the limit.
- **Index freshness** — The index updates when pages are previewed or published via Sidekick. Unpublished pages remain in the index until explicitly removed.

@dominique-pfister dominique-pfister Jun 29, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Wrong, should be:

The index updates when pages are published. (via Sidekick or programmatically does not matter)


## How the EDS Query Index Works

The query index is the primary mechanism for blocks and components to discover and list content in an EDS site. It is configured via a `helix-query.yaml` file in the GitHub repository and served as JSON at `/query-index.json`.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

@dominique-pfister dominique-pfister left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Already found 4 errors in the first few lines that are repeated later, please fix and align with the current documentation.

…docs

Address @dominique-pfister review:
- Index is configured via the Index Admin tool / Admin API, not a
  helix-query.yaml file in the GitHub repo
- query-index.json is the default index name; indices can be named differently
- Default entry limit is 1000, not 500 (per the spreadsheets doc)
- Pages are indexed on publish, not preview
- Cite the indexing and spreadsheets docs as sources of truth

Co-Authored-By: claude-flow <ruv@ruv.net>
@focusgts

Copy link
Copy Markdown
Contributor Author

Thanks @dominique-pfister — these are exactly right, and I appreciate the careful review with the doc links. I've corrected all four against the current docs: index configured via the Index Admin tool (not a repo helix-query.yaml), query-index.json as the default name, the 1000-entry default limit per the spreadsheets doc, and indexing on publish. I also cited the indexing and spreadsheets docs as sources of truth in the reference file. The fix is pushed.

You're right that these repeat — we're doing a documentation-grounded pass over the rest of our skills to catch the same class of staleness. Appreciate you keeping the bar high.

@focusgts

Copy link
Copy Markdown
Contributor Author

@dominique-pfister @trieloff — your review here prompted us to audit our entire content-ops suite against the current aem.live docs, not just this skill. We found the same class of staleness (the helix-query.yaml → Index Admin change, the 1000-entry default, publish-vs-preview indexing, and a few others such as the current helix-sitemap.yaml schema and the RUM Bundler API shape) in several already-merged skills, and we have doc-grounded corrections ready, each cited to an aem.live page.

Would you prefer one PR per skill (per the usual process here) or a single batched corrections PR? Happy to do whichever is easiest to review. Thanks again — the review made the whole set better.

@trieloff

trieloff commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

One PR per skill, please.

@focusgts

focusgts commented Aug 10, 2026

Copy link
Copy Markdown
Contributor Author

cc @trieloff

Friendly nudge — Dominique's four corrections were fixed and pushed on June 29, each aligned with the current aem.live docs and cited in the reference file.

And understood on one PR per skill for the corrections to the already-merged skills — we'll submit those individually. Anything else needed on this one? (The red tessl-review is the fork-secrets auth issue — ✘ Please authenticate with Tessl to continue — same as on #186 when it merged.)

@focusgts

Copy link
Copy Markdown
Contributor Author

Thanks @dominique-pfister. All five are fixed and aligned with the current docs. Index configuration is now described as managed via the Index Admin tool (not a repo file), query-index.json is called out as the default name (sites can define others), the default limit is corrected to 1000 with the offset/limit doc linked, and the index is described as updating when pages are published (Sidekick or programmatic, the method does not matter). Ready for another look whenever you have a moment.

Copy link
Copy Markdown
Contributor

The failing tessl-review check here is not a problem with this skill — it's a CI limitation.

This PR comes from a fork, and GitHub does not expose repository secrets to workflow runs triggered by pull_request from forks. So secrets.TESSL_TOKEN was empty, setup-tessl installed an unauthenticated CLI, and the review bailed immediately:

✘ Please authenticate with Tessl to continue. Run `tessl login` to sign up or log in.
##[warning]tessl review run failed for query-index-optimizer (exit code 1)

The workflow then counts that tool/auth error as a failure and reports it as 1 skill(s) scored below 80% — but the skill was never actually scored.

Local review result

I ran the review locally against this PR's head (cbfa302):

Review Score: 85% — passes the 80% threshold.

  • Validation: PASSED (0 errors, 0 warnings), all 16 checks green
  • Description: 93% — specificity 5/5, trigger terms 4/5, completeness 5/5, distinctiveness 5/5
  • Content: 71% — conciseness 3/5, actionability 4/5, workflow clarity 4/5, progressive disclosure 5/5

Optional polish the judge suggested, if you'd like to raise the content score:

  • Trim the "When to Use" section and drop explanations of things the agent already knows (what card blocks do, what consumers are).
  • Add executable snippets for Steps 4–5 (sitemap fetch/parse, HTTP status checking) rather than describing the process in prose.
  • Add a validation checkpoint between Steps 2 and 3 to confirm the index definition matches the live index output before mapping consumers.

None of these are blocking — the skill passes as-is.

I'm opening a separate PR to fix the workflow so fork PRs are handled properly (skipped cleanly when the token isn't available, instead of reported as a quality failure).

Copy link
Copy Markdown
Contributor

Follow-up: the workflow fix is up as #308 — it makes fork PRs work, drops the deprecated tessl skill review call, pins the checkout, and stops reporting auth/tooling failures as low scores. Once that lands, re-running this check should score this skill properly.

Copy link
Copy Markdown
Contributor

Correction to my earlier comments — I was working from a stale checkout of main and got the "what needs fixing" part wrong.

The root cause I described is right: that run was an unauthenticated Tessl CLI, because pull_request withholds secrets from fork runs. But it had already been fixed by the time I looked.

  • This run: 2026-07-07T08:49:32Z
  • ci: allow tessl review on fork PRs via gated eval environment (e56e29f): 2026-07-07T10:01:48Z
  • ci: only gate fork PRs, not same-repo (maintainer) PRs (756e8d7): 2026-07-07T10:23:40Z

So the fix landed about 72 minutes after this run. main today already uses pull_request_target with the eval environment gating fork PRs, and already uses tessl review run --workspace --json --threshold. Nothing about the workflow needs changing for this PR to pass — please disregard my earlier note about #308 being required here.

The red check above is simply stale. It is over a month old, so GitHub will not let it be re-run directly. Re-triggering it needs a new commit on the branch, or the branch to be updated from main (this PR is a month behind). Either will produce a fresh run against the current, working workflow.

My local review result stands and is unchanged — this skill scores 85% and passes the 80% threshold.

trieloff pushed a commit that referenced this pull request Aug 21, 2026
When the Tessl CLI fails to run at all — auth failure, network error,
crash — the job counted it as a review failure and reported it as
"N skill(s) scored below 80%". That is misleading: the skill was never
scored. On #189 this surfaced as a red "below 80%" check on
a skill that actually scores 85%, which reads to a contributor as a
quality rejection.

Track those separately as errors and report them as "review could not be
run", with a ⚠️ row and an explanatory note in the step summary. They
still fail the job — they are just no longer confused with low scores.

Also:

- Skip cleanly with an explanatory summary when TESSL_TOKEN is not
  configured, instead of running an unauthenticated CLI and failing.
- Pin actions/checkout and tesslio/setup-tessl to commit SHAs, with
  `# vN` comments so Renovate keeps tracking them.
- Add a concurrency group so superseded runs are cancelled.
- Use a single redirect block in the skip summary, silencing the one
  actionlint/shellcheck warning (SC2129) in this file.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Lars Trieloff <lars@trieloff.net>
focusgts added a commit to focusgts/skills that referenced this pull request Aug 21, 2026
…pets + a definition-vs-live checkpoint (per @trieloff)

- Trim Step 3 to a concise consumer map (drop explanations the agent already knows).
- Add executable snippets for Step 4 (sitemap vs index diff) and Step 5 (stale-entry HTTP check).
- Add a Checkpoint between Steps 2 and 3 to reconcile the index definition against the live output before mapping consumers.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants