Skip to content
Open
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
41 changes: 35 additions & 6 deletions .agents/skills/project-guides/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ When a developer asks an AI coding assistant to implement something, the assista
**MANDATORY RULES FOR WRITING `guide.md`:**

### 1. YAML Frontmatter Schema

`guide.md` must start with this YAML frontmatter structure (added in **Stage 1**):

```yaml
Expand All @@ -47,32 +48,60 @@ sources:
* **sources**: Must be a list of ALL reference URLs used to synthesize the document. Add any URL referenced in the guide's research or inline links here.

### 2. Tone and Formatting

* **Formatting Directives:** Use strict imperative directives (`MANDATORY:`, `DO`, `DO NOT`) only when emphasis is strictly needed (e.g., for critical constraints, security, or common pitfalls). Do not overuse them for every single instruction. Coding agents respond best to rigid constraints when they are selectively applied.
* **Focus:** Keep the guidance focused on the specific use case and short. No fluff. No conversational text. Include a brief overview of the use case and explanation of why the solution outlined in the guide is the recommended approach.
* **Self-Contained:** DO NOT include any external links in the markdown body (`[link text](url)`). All required knowledge to use the feature MUST be fully synthesized into the markdown body. Agents must not be slowed down or require additional resources to implement the guidance.

### 3. Code Snippets

* Include short, heavily commented code snippets.
* Put directives directly in code comments so they are impossible to miss (e.g., `<!-- Always use the required attribute -->`).
* Code comments MUST explain why a value or approach is chosen, not just what the code does. An agent that copies magic values without understanding them will apply them incorrectly. If a value is context-dependent (e.g., a threshold that should vary by use case), say so explicitly.
* **Modern Standards**: Exclusively use ES modules (`import`/`export`) in JavaScript code examples; avoid CommonJS (`require`).
* **Clarifying Arbitrary Values**: Explicitly identify placeholder values (like `2rem` or `50ms`) as example-only in comments to avoid them being mistaken for strict technical constraints.

### 4. Implementation Steps

* The implementation steps should assume any web feature can be used. Choose the best feature for the job, regardless of browser support.
* **DO NOT** suggest modern features just because they are modern. If a modern feature has no distinct user-visible advantage over a legacy feature for the given use case — but will require a more complex fallback implementation — use the legacy feature.
* **DO NOT** include cross-browser fallbacks in the implementation section. Those should only be mentioned in the fallback section.
* Only mark steps as `MANDATORY` if they are truly required for the feature to function. Optional steps (e.g., adding scroll snap, adding an event listener for progressive enhancement) must be labeled as optional. Incorrect use of `MANDATORY` causes agents to implement unnecessary complexity.
* The guide is the agent's **only** source of truth. DO NOT reference `demo.html` or any other file — agents won't have access to them. Everything the agent needs to implement the use case must be in `guide.md`.

### 5. Fallback Strategies
* You **MUST** include a "Fallback strategies" section regardless of Baseline status, as developers may have older baseline targets.
* **MANDATORY**: The `{{ BASELINE_STATUS("feature-id") }}` macro must *always* be placed as the first, standalone line inside the "Fallback strategies" section. Do not place it at the top of the document.
* **OPTIONAL** provide an optional second argument for specific BCD keys: `{{ BASELINE_STATUS("feature-id", "bcd.key") }}`. This is useful when a critical sub-feature's status differs from the overall feature status.

* If the primary implementation relies on features that are not Baseline Widely Available, you **MUST** include a fallback recommendation. This recommendation can be any of the following (in order of preference):
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

this looks like a lot of text and I was having a hard time parsing it myself. i prompted my agent with "Is it repeating itself? And is there a more concise way to make the same additions to this policy?"

and it returned back this:

### 5. Fallback Strategies

If the primary implementation uses features that are not Baseline Widely Available, you **MUST** include a fallback recommendation in this section.

* **Framing:** Frame fallback necessity in terms of Baseline target (e.g., "If your Baseline target does not support X, use...").
* **Assessment:** Start with a broad assessment of the fallback's robustness. Recommend the modern approach if the fallback is robust; highlight complexity/caveats and suggest alternatives (like userland solutions) if it is not.
* **Experience:** **MANDATORY:** Explicitly describe the fallback experience (progressive enhancement vs. feature detection/graceful degradation).
* **Feature Detection:** Prefer checking `HTMLElement.prototype` (e.g., `'onbeforematch' in HTMLElement.prototype`) over `window` or `document`.
* **Fallback Options (in order of preference):**
    1.  **Custom Code:** Short, reliable reimplementation (**<50 lines**) using widely available features.
    2.  **Polyfill:** A robust, performant polyfill (see guidelines below).
    3.  **Abstraction:** A well-tested userland library.
    4.  **Graceful Degradation:** Baseline Newly Available features that degrade gracefully.
    5.  **Progressive Enhancement:** Frame as progressive enhancement only if no robust fallback exists.
* **Faithfulness:** Fallbacks MUST be faithful to the use case. If the primary recommendation gracefully degrades but ultimately doesn't accomplish the core use case, suggest a different fallback if one is available. Graceful degradation **IS** acceptable for features that enhance, but are otherwise not core to the use case.

#### Baseline Status Macros
* **MANDATORY:** Include `{{ BASELINE_STATUS("feature-id") }}` for *every* non-widely available feature used.
* **Placement:** Use separate subsections with their own macros if multiple features are used. **DO NOT** use macros outside the fallback section.
* **BCD Keys:** **OPTIONAL:** Use `{{ BASELINE_STATUS("feature-id", "bcd.key") }}` if a sub-feature's status differs.

#### Polyfill Guidelines
* **Conditional Loading:** **MANDATORY:** ALWAYS conditionally load polyfills only when native support is missing. Prefer build-integrated conditional loading (code splitting) over CDNs.
* **Performance:** **DO NOT** recommend polyfills with significant performance tradeoffs, or those requiring fetching/parsing CSS. Prefer abstractions/userland solutions instead.
* **Prohibited CDNs:** **DO NOT** recommend polyfills from polyfill.io.

it does looks good to me.. my agent said

Zero loss of information: All new policy points from the PR are preserved.

Reduced Redundancy: Conditional loading and performance expectations for polyfills are stated exactly once.

Better Scanability: Clear separation between meta-rules (framing, assessment, experience) and the ordered list of fallback options.

and.. sure.

anyway.. bikeshedding text with models. lol.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

and here's a ~neutral comparison of the two: https://gemini.google.com/share/dc979d042b89

edit: i incorporated its two pieces of feedback into the above revision.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I'm fine with this rewording. I agree with Gemini's assessment that this version don't quite capture the "philosophy" of it as well, but I trust that the LLM can properly interpret both and if so then shorter is better.

The only thing that stands out to me in this version (which was a problem in the previous one as well, just not as obvious), is this line

  • Feature Detection: Prefer checking HTMLElement.prototype (e.g., 'onbeforematch' in HTMLElement.prototype) over window or document.

While this is a good best practice, it's a bit weird to have this specific example as the only example rather than having a general rule. What about updating to this?

  • Feature Detection: Checks should be tightly scoped to the interface rather than the instance (e.g. use Object.hasOwn(HTMLElement.prototype, 'onbeforematch') over 'onbeforematch' in winow)

* A short bit of code (<50 lines) that reliably reimplements the function of the modern feature (specific to the given use case) using widely available features.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

maybe numbered bullets for this nested list?

* A robust and performant polyfill for the modern feature (if one exists) that is conditionally loaded **IFF** the native feature is not supported in the browser.
* A well-tested userland abstraction that implements the use case across browsers.
* If the use case **CAN** be achieved in a simple and robust way using Baseline Newly Available features that degrade gracefully when unsupported, this can be presented as an option to consider, as an alternative _or in addition_ to one of the above.
* If none of the above are possible, or if the use case cannot be implemented without using non-widely-available features, then clearly state this fact and show how to conditionally load the feature(s) as a progressive enhancement only.
* The fallback recommendations **MUST** be faithful to the use case. If the primary recommendation gracefully degrades, but ultimately doesn't accomplish the use case, suggest a different fallback if one is available. Graceful degradation **IS** acceptable for features that enhance, but are otherwise not core to the use case.
* The fallback section **MUST** start with a broad recommendation and assessment of the overall fallback approach, based on its robustness and effectiveness to achieve the given use case.
* If the features recommended in the primary implementation offer meaningful user value, and if the fallback is robust and effective, provide a strong recommendation for this approach, despite the use of non-widely available features.
* If the fallback is complex and has numerous caveats and gotchas, make that clear and consider suggesting alternatives if they exist (e.g., well-tested userland solutions).
* The fallback section should frame fallback necessity in terms of Baseline target, e.g. "If your Baseline target does not support X, use the following fallback..."
* **MANDATORY**: You MUST explicitly describe the fallback experience for unsupported browsers. Explain if the feature is a progressive enhancement (and what the base experience looks like), or show explicit code for feature detection (e.g., `CSS.supports()`, `if ('feature' in window)`) and graceful degradation techniques.
* When recommending feature detection, prefer checking `HTMLElement.prototype` (e.g., `'onbeforematch' in HTMLElement.prototype`) over `window` or `document`, as it is more reliable.
* When recommending a polyfill, ALWAYS show how to conditionally load it only for browsers that need it. Do not instruct agents to unconditionally load polyfills.
* **DO NOT** recommend polyfills from polyfill.io.

#### Baseline status best practices

* **MANDATORY**: the fallback section must include a `{{ BASELINE_STATUS("feature-id") }}` macro for every non-widely available feature included in the primary implementation section.
* If multiple non-widely available features are used, create a separate subsection for each feature fallback with its own `{{ BASELINE_STATUS("feature-id") }}` macro.
* **DO NOT** use the `{{ BASELINE_STATUS("feature-id") }}` outside of the fallback section.
* **OPTIONAL** provide an optional second argument for specific BCD keys: `{{ BASELINE_STATUS("feature-id", "bcd.key") }}`. This is useful when a critical sub-feature's status differs from the overall feature status.

#### Polyfill considerations and best practices

* When recommending a polyfill, ALWAYS show how to conditionally load it only for browsers that need it. Do not instruct agents to unconditionally load polyfills (even small ones).
* Prefer including polyfills in your build (so they can be combined into a polyfill chunk) rather than loading them from a CDN, but **ALWAYS** do so in a way that supports code splitting and conditional loading.
* **DO NOT** recommend polyfills that incur significant performance tradeoffs. Prefer abstraction and userland solutions in these cases, if available.
* **DO NOT** recommend polyfills that require fetching and parsing CSS in order to function.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I don't disagree, but as an example of how this will play out, this will apply to the anchor positioning polyfill, and all anchor positioning use cases will not have reasonable non-duplicative fallbacks.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Yup true. That's deliberate. And unfortunate. But it's the state of things until Bramus gets his way. :)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

+1 to Bramus getting his way 😄

* **DO NOT** recommend loading polyfills from polyfill.io.

## Authoring `expectations.md` and `demo.html`

* **`expectations.md`**: Write a natural language, bulleted list of assertions that must be true if an agent implements the `guide.md` correctly. (e.g., "The input element is styled with a red border only AFTER a blur event").
* **`demo.html`**: The `demo.html` file should be a clean example of a correct implementation of the use case. If possible, it should be self-contained with inline scripts and styles.
* **Warning-Free Demos**: Documentation and demos must adhere to all browser console recommendations, including non-fatal warnings, to ensure clean evaluation runs.
* **Warning-Free Demos**: Documentation and demos must adhere to all browser console recommendations, including non-fatal warnings, to ensure clean evaluation runs.
Loading