Skip to content

feat(auth0): split large references into hub+leaf groups (reference depth)#151

Draft
frederikprijck wants to merge 61 commits into
mainfrom
worktree-reference-depth
Draft

feat(auth0): split large references into hub+leaf groups (reference depth)#151
frederikprijck wants to merge 61 commits into
mainfrom
worktree-reference-depth

Conversation

@frederikprijck

@frederikprijck frederikprijck commented Jul 20, 2026

Copy link
Copy Markdown
Member

What & why

Large reference files forced an agent to load ~100K of tokens even when it needed one section. This introduces one level of depth: references over ~40K become hub + leaf groups so the router pulls only the slice a task needs.

A reference is now either a flat *.md file or a group directory <stem>/ with:

  • index.md — a hub: shared prerequisites + an imperative intent→leaf dispatch table
  • document-section leaves (integrate.md, api-reference.md, patterns.md, setup.md, migration.md; features split by sub-topic)

Navigation is a depth-2 tree: the router reads the hub, which dispatches to exactly one leaf (two hops). A hub may dispatch only to leaves in its own directory; leaves and flat files link to nothing; cross-group links are forbidden. This relaxes the previous strict one-hop rule in a bounded, enforced way.

Changes

  • 15 references split into groups (all files >40K): framework-swift (proof case), android, go, php-api, php, react, java-mvc, ionic-angular, ionic-vue, aspnetcore-auth, expo, nuxt, and features custom-domains, branding, acul. Every carve is byte-lossless.
  • scripts/check_router_reachability.py — recursive discovery, two-level orphan/broken-route checks, and a new SIDEWAYS_TWO_LEVEL_RE (the shared single-level regexes exclude /, so they can't see <group>/<leaf>.md targets). Backward compatible with flat files.
  • scripts/check_routing_evals.py — resolves a grouped slug to <stem>/index.md + the intent's leaf (read from the hub's dispatch table).
  • New unit tests for both checkers (46 total).
  • SKILL.md — one global note in Step 4 telling the agent to read index.md when a target is a group directory; per-intent routing tokens unchanged.
  • DocsAGENTS.md, CONTRIBUTING.md (new "Adding a grouped reference" section), docs/architecture.md, PLUGIN.md updated to the two-hop-through-hub model.

Validation

Deterministic gates (all green):

  • 46 checker unit tests
  • check_router_reachability.py — PASS
  • check_routing_evals.py — PASS (30 cases)
  • validate-skill.sh — PASS
  • skillsaw --strict — Grade A, 0 errors

Behavioral evals (live agent, with-skill vs without-skill delta) confirm the two-hop dispatch works end-to-end. Every grouped framework that ran cleanly shows the skill helping, with no regression on flat files:

Grouped framework with-skill delta
android 18/18 +17
swift 13/16 +3
ionic-angular 16/20 +2
ionic-vue 20/21 +1
expo 13/16 +1

Flat-file regression check: ionic-react +19, flutter-native +17, flutter-web +15, flask +15, spa-js +5, express-jwt +1 — no regressions.

Known follow-ups (not blocking)

  • Migration eval cases (swift-migration, android-migration) score low purely because their judge graders time out — the cases compile the project, flooding the 60s claude -p judge with .build/ + SDK-checkout noise. Objective graders pass and migrated files are correct. This is a pre-existing eval-harness limitation (judges should exclude .build//node_modules//checkouts), not a defect in the migration leaves.
  • framework-swift/index.md (~16K) folded its Setup Guide into the hub instead of extracting a setup.md leaf — it was the proof case, carved before the document-section leaf axis was standardized. Worth a follow-up re-carve so the reference implementation matches the pattern the other 14 groups use.

@coderabbitai

coderabbitai Bot commented Jul 20, 2026

Copy link
Copy Markdown

Review Change Stack

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 265f0706-3fe5-401f-97cd-5c83f889c3da

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch worktree-reference-depth

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

# Conflicts:
#	plugins/auth0/skills/auth0/references/framework-aspnetcore-auth.md
#	plugins/auth0/skills/auth0/references/framework-expo.md
#	plugins/auth0/skills/auth0/references/framework-go.md
#	plugins/auth0/skills/auth0/references/framework-java-mvc.md
#	plugins/auth0/skills/auth0/references/framework-php-api.md
#	plugins/auth0/skills/auth0/references/framework-react.md
@frederikprijck
frederikprijck marked this pull request as draft July 20, 2026 12:38
The #144 merge modified flat reference files this branch had already split
into hub+leaf groups (modify/delete conflicts). The delete side was committed
in the merge (3b6ddaf) but the manual ports into the leaf files were left
uncommitted. Commit them: your-*.com placeholders -> RFC-2606 example.com forms
in go/patterns, react/patterns, php-api/integrate, aspnetcore-auth/patterns,
expo/patterns, java-mvc/api-reference.
# Conflicts:
#	plugins/auth0/skills/auth0/references/framework-java-mvc.md
@frederikprijck
frederikprijck force-pushed the worktree-reference-depth branch from 97d340b to bd1b08e Compare July 20, 2026 16:04
@github-actions

Copy link
Copy Markdown

✅ skillsaw — All checks passed

Full report
skillsaw 0.16.0
Linting: /home/runner/work/agent-skills/agent-skills


Scanned:
  Repo type: agentskills, coderabbit, marketplace
  Plugins:   1
  Skills:    1
  Rules run: 51
  Took:      1.3s

Summary:
  Errors:   0
  Warnings: 0
  Grade:    A (1.30 weighted violations per 10k tokens)
  13 info-level violation(s) count toward the grade — run with -v to see them

✓ All checks passed!

skillsaw 0.16.0 · config · custom rules · run

The proof-case swift group was carved before the document-section leaf axis
was standardized. Two structural issues fixed:

- index.md folded the whole Setup Guide into the hub -> extracted to setup.md;
  index.md is now a lean 47-line hub (rules + prereqs + when-not + dispatch)
  matching react/android.
- integrate.md was three concatenated docs (Integration + API Reference &
  Testing + Integration Patterns) plus a stray migration-flavored Common
  Mistakes tail -> split into integrate.md / api-reference.md / patterns.md;
  the migration tail moved into migration.md.

Lossless: 82 code fences in = 82 out; all API tables and pattern sections
preserved. Hub dispatch adds setup/api-reference/patterns 'Then, as needed'
rows. Reachability + routing-evals + 50 unit tests + validate-skill.sh pass.
The 'Adding a reference' section pointed contributors at
tests/routing-cases.json, which does not exist. The file lives at repo-root
evals/routing-cases.json -- what CI (.github/workflows/skillsaw.yml) and the
checker's fallback actually read.
The uniform-folder refactor made every reference a <name>/ directory, but
the naming-convention prose in AGENTS.md, CONTRIBUTING.md, and the
check_router_reachability.py docstring still wrote framework-<name>.md etc.
Update them to directory form for consistency with the shipped layout.
…leaf

The framework-nuxt leaf-group carve moved route-protection, session-store,
and advanced-example content into patterns.md, but integrate.md still said
'see the ... section below' — the content is no longer below. Restore the
pre-v2 'secondary, reachable via pointer' design (definePageMeta was always
in a separate route-protection leaf, never the primary path) by pointing at
'this group's patterns guide' instead, matching the other leaf groups'
convention. The hub index.md already routes advanced seekers to patterns.md.
Also drop the stale 'Common Examples' label (no such section post-carve).
@frederikprijck
frederikprijck force-pushed the worktree-reference-depth branch from 0d7658d to edec431 Compare July 24, 2026 09:38
…overable

The hub's only machine-followable pointer to patterns.md labelled it
'advanced route-protection / session-store patterns', which reads as
optional — so an agent doing a quickstart with a protected page didn't load
patterns.md and missed the page-level definePageMeta middleware it needed.
Relabel the pointer to name definePageMeta/page protection explicitly and
note integrate.md covers only baseline global/server middleware. Keeps the
pre-v2 design (definePageMeta stays out of the primary integrate path,
reachable via the hub) while closing the discoverability gap.
…reference (+migration)

Reduce leaf sprawl: fold setup.md, patterns.md, and the tiny mfa.md into
integrate.md (Setup / Integration Patterns / MFA sections), keeping only the
API/config lookup (api-reference.md) and the eval-required migration.md as
separate leaves. Lossless — every section, code block, and table preserved;
in-file cross-references rewritten from 'this group's X leaf' to 'the X
section below'. Hub dispatch updated: feature:mfa now routes to integrate.md.

Target shape for all leaf groups: index.md + 2 content leaves (+migration
where the SDK has a major-version upgrade). Proof case for the rest.
Apply the framework-swift recipe (a9fb663) across the remaining 13 leaf
groups so every group is index.md + exactly 2 content leaves, with
migration.md as the only allowed 3rd exception (android, swift).

Framework groups (android, aspnetcore-auth, expo, go, ionic-angular,
ionic-vue, java-mvc, php-api, php, react): fold setup.md + patterns.md
into integrate.md (## Setup, ## Integration Patterns); keep
api-reference.md; keep migration.md untouched for android.

Feature groups: feature-branding folds templates->guide, examples->
api-reference; feature-custom-domains folds advanced->guide, examples->
api-reference; feature-acul folds patterns->guide and cli-reference->
sdk-reference, then renames sdk-reference->api-reference.

Lossless (every section preserved), in-file cross-refs rewritten to
'... section below', hub dispatch tables repointed to surviving leaves.
Leaf-sink invariant, routing evals, reachability, and skillsaw --strict
all green. Follow-up PR will add per-file Tables of Contents.
Relocate each framework leaf group's Quick Start Workflow up from
integrate.md into the hub index.md as `## Quick start`, so the hub is
immediately actionable without a second read. Depth (setup variants,
Common Mistakes, pattern catalog) stays in integrate.md. Dispatch tables
unchanged; same-file cross-refs rewritten to prose role references to
preserve the leaf-sink rule.

Groups: react, android, go, php, php-api, expo, ionic-angular,
ionic-vue, java-mvc, aspnetcore-auth (Blazor/Razor variants retained in
integrate.md), nuxt (Quick Setup + Built-in Routes + Composables moved;
Protecting Routes depth retained).
…ntation inline)

Relocate orientation front-matter up from guide.md into the hub index.md
for feature-branding, feature-custom-domains, and feature-acul, matching
the pre-v2 SKILL.md standalone shape. The detailed capability/phase
playbooks stay in guide.md; dispatch rows unchanged.

- branding: moved Capabilities, Prompt style, Plan mode, Verify-in-browser,
  Key Concepts, Prerequisites, capability dispatch entries, Common
  Mistakes, References (boundary: first # Capability H1). Rewrote stale
  SKILL.md cross-refs to hub-index prose.
- custom-domains: moved Overview, Interaction style, Error-code triage,
  Capabilities, Key Concepts, Prerequisites, Common Mistakes (boundary:
  ## Advanced, keeping MCD/certs/DNS-playbook depth in guide.md).
- acul: moved Reference Hierarchy, auth0-acul-samples Architecture,
  Prerequisites (boundary: ## Phase 0); removed a pre-existing duplicate
  Prerequisites block; rewrote same-file refs that became cross-file.
…sections

The go hub carried standalone ## Install SDK and ## Configure .env
sections predating this feature; the relocated ## Quick start repeats both
verbatim (Steps 1 and 3). Drop the duplicates so go matches the swift
template shape (Critical rules → Prerequisites → When NOT to Use →
Quick start → Choose your task). Final-review Minor finding.
…tent

Replace architecture jargon with plain doc roles throughout the skill:
- '# Auth0 X — reference hub' title suffix dropped (matches index-only refs)
- 'hub'/'hub index' -> 'overview'; 'guide leaf' -> 'guide';
  'api-reference leaf' -> 'API reference'; 'migration leaf' -> 'migration guide'
- 'read the leaf'/'Read only the leaf (or leaves)' -> 'reference(s)'
- SKILL.md routing note: 'intent->leaf'/'single leaf' -> 'document'

No structural change; dispatch tables and routing unchanged.
The callout restated what each Step 4 intent block already emits
(explicit references/{name}/index.md paths) and what each index.md's
own '## Choose your task' section conveys on arrival. Migration-era
scaffolding; trimming it lightens the always-loaded router.
Generated lockfile for the dev-only behavioral eval harness; keep it
out of version control (file remains on disk).
if [[ "$OSTYPE" == "darwin"* ]]; then
brew install auth0/auth0-cli/auth0
else
curl -sSfL https://raw.githubusercontent.com/auth0/auth0-cli/main/install.sh -o /tmp/auth0-install.sh

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Semgrep identified an issue in your code:

Installation script downloaded to world-writable /tmp directory can be replaced by local attackers before execution, allowing credential theft during subsequent auth0 login step.

More details about this

The curl command downloads an installation script directly to /tmp/auth0-install.sh, which is a world-writable temporary directory. An attacker with local access to the system could exploit this in several ways:

  1. Pre-execution replacement: Before the script runs (the sh /tmp/auth0-install.sh line), an attacker with local access to /tmp could replace /tmp/auth0-install.sh with a malicious script that installs a backdoor or exfiltrates credentials instead of installing the Auth0 CLI.

  2. Race condition: An attacker could monitor /tmp for the creation of auth0-install.sh, quickly replace it with malicious code, and have that code execute with the same privileges as the parent shell script—potentially with elevated privileges if this runs as root.

  3. Persistence: Since /tmp is often world-writable and world-readable, an attacker could plant a trojanized version of the script there and wait for legitimate users to run this installation process, compromising multiple systems and stealing credentials during the Auth0 login step (auth0 login will prompt for credentials that could be intercepted).

The vulnerability is particularly severe because the script later calls auth0 login, which will prompt for sensitive authentication credentials that could be stolen if the downloaded script has been compromised.

To resolve this comment:

✨ Commit fix suggestion

Suggested change
curl -sSfL https://raw.githubusercontent.com/auth0/auth0-cli/main/install.sh -o /tmp/auth0-install.sh
curl -sSfL https://raw.githubusercontent.com/auth0/auth0-cli/main/install.sh | sh -s -- -b /usr/local/bin
View step-by-step instructions
  1. Replace the curl download-to-/tmp pattern with a direct pipe to sh, which avoids writing an executable script to a temporary path entirely: change the three lines (curl ... -o /tmp/auth0-install.sh, echo "Review...", sh /tmp/auth0-install.sh ...) to curl -sSfL https://raw.githubusercontent.com/auth0/auth0-cli/main/install.sh | sh -s -- -b /usr/local/bin.

Alternatively, if you want to keep the review step for auditability, download the script to the current working directory instead of /tmp: use -o ./auth0-install.sh and then run sh ./auth0-install.sh -b /usr/local/bin && rm ./auth0-install.sh. Writing to the project directory rather than /tmp avoids the hidden-staging-path pattern that malware commonly exploits.

💬 Ignore this finding

Reply with Semgrep commands to ignore this finding.

  • /fp <comment> for false positive
  • /ar <comment> for acceptable risk
  • /other <comment> for all other reasons

Alternatively, triage in Semgrep AppSec Platform to ignore the finding created by skill-download-tmp-exec.

You can view more details about this finding in the Semgrep AppSec Platform.

The index-only and grouped framework loops asserted the identical
condition (framework-<name>/index.md exists); neither verified a leaf,
so the split distinguished nothing the script checks. Collapse to one
EXPECTED_FRAMEWORKS roster. Real hub/leaf structure is enforced by
check_router_reachability.py.
Same redundancy as the framework loops: the index-only and grouped
feature loops both asserted only that feature-<name>/index.md exists.
Collapse to one EXPECTED_FEATURES roster (organizations stays separate
for its line-count check).
The merged rosters now carry the same members as main; reorder them to
main's sequence so the diff is limited to the loop consolidation, not a
spurious reordering.
…ss JWT reference (#158)

Ported from origin/main 3002420 into the carved reference layout. express-jwt is
a pure-rename group (single index.md == the old flat file), so main's post-fix
content applies wholesale.
Ported from origin/main e295fd6 into the carved layout. The stray ')' after the
packageId assignment survived on this branch (predates the fix); it lives in the
hub index.md logout snippet, not a leaf.
Ported from origin/main b472904 into the carved layout. Two hunks: the
runtimeConfig comment lands in the hub index.md's nuxt.config.ts block; the
anti-hardcoding Common-Mistakes row lands in integrate.md (where the mistakes
table now lives after the split).
)

Ported from origin/main 7e9ce86 into the carved layout. Both logout samples
(quick-start in index.md, detailed in integrate.md) had onSuccess(result: Void)
under a Callback<Void?, ...> type parameter — the nullability mismatch fails
Kotlin compilation.
…rence (#157)

Ported from origin/main a3e0db8 into the carved layout. Three hunks: the
quick-start IMPORTANT note in index.md, the anti-hardcoding Common-Mistakes row
in integrate.md, and the api-reference.md replacement of the literal-credential
getInstance("CLIENT_ID","DOMAIN") variant with strings.xml-only guidance.
Ported from origin/main d1b1985 into the carved layout. The claims example used
IDTokenClaimsValidation().validate() — an internal validation helper, not a
public claims API. Replace with credentialsManager.user (UserInfo?) plus a
JWTDecode manual-decode example. Lands in the swift api-reference.md leaf.
Ported from origin/main 97b9d9a into the carved layout. Two hunks: the
never-pass-credentials-in-code IMPORTANT blockquote after the automatic/manual
choose block in index.md, and the anti-hardcoding Common-Mistakes row in
integrate.md.
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.

1 participant