Skip to content

feat: harden Agent Ready discovery surface - #28

Merged
Videirafo merged 6 commits into
mainfrom
feat/27-agent-ready-hardening
Sep 7, 2026
Merged

feat: harden Agent Ready discovery surface#28
Videirafo merged 6 commits into
mainfrom
feat/27-agent-ready-hardening

Conversation

@Videirafo

Copy link
Copy Markdown
Owner

Closes #27

Changes

  • adds <lastmod> to the canonical sitemap entry;
  • restructures AGENTS.md with Installation, Configuration, Usage and Examples sections;
  • keeps sitemap.xml focused on the canonical HTML Playground;
  • adds root Accept: text/markdown content negotiation;
  • adds canonical /index.md markdown mirror with frontmatter and sitemap section;
  • increases readable HTML content for crawler extraction;
  • aligns app/package version to 0.6.0;
  • adds HEAD support for /;
  • adds tests for scanner-critical discovery contracts.

Invariants preserved

  • no change to tool-policy semantics;
  • no change to tenant isolation or approval rules;
  • no secrets or external providers;
  • public Render URL remains canonical.

Baseline

Agent Ready before this PR: overall 45/100, site 13/15, llms.txt 100/100, accessibility 100/100.

@Videirafo
Videirafo merged commit aa1409e into main Sep 7, 2026
5 checks passed

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1dd6de34f3

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +41 to +42
accept = request.headers.get("accept", "").lower()
if request.method == "GET" and "text/markdown" in accept:

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Honor Accept quality weights when selecting Markdown

When a client sends an Accept header such as text/html, text/markdown;q=0 or prefers HTML with a higher quality value, this substring check still returns Markdown—even though Markdown may be explicitly unacceptable. Parse the media ranges and quality weights so Markdown is selected only when it is acceptable and preferred.

Useful? React with 👍 / 👎.

@app.api_route("/", methods=["GET", "HEAD"], response_class=HTMLResponse, include_in_schema=False)
def playground(request: Request) -> Response:
accept = request.headers.get("accept", "").lower()
if request.method == "GET" and "text/markdown" in accept:

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Negotiate HEAD requests consistently with GET

For HEAD / with Accept: text/markdown, the method guard skips the Markdown branch and reports HTML headers, while the corresponding GET selects Markdown. Clients and discovery scanners commonly use HEAD to inspect a representation, so apply the same content negotiation to HEAD while allowing the server to suppress the body.

Useful? React with 👍 / 👎.

Comment on lines +43 to +46
return PlainTextResponse(
PLAYGROUND_MD,
media_type="text/markdown",
headers=MARKDOWN_HEADERS,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Mark the negotiated root response as varying on Accept

The Markdown representation returned from / is cacheable but does not include Vary: Accept. An intermediary that caches a Markdown request can therefore reuse that response for a later ordinary browser request to the same URL and serve Markdown instead of HTML. Add Vary: Accept to the negotiated root responses.

Useful? React with 👍 / 👎.

Comment on lines +90 to +91
python -m venv .venv
pip install -e \".[dev]\"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Install dependencies through the newly created virtualenv

When these documented commands are run in a fresh shell, creating .venv does not activate it, so the subsequent bare pip resolves to the caller's existing environment and installs the package globally or into another environment despite the isolation claim. Activate .venv first or invoke .venv/bin/python -m pip directly.

Useful? React with 👍 / 👎.

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.

Raise Agent Ready score and close remaining discovery gaps

1 participant