diff --git a/authors/gaetano.md b/authors/gaetano.md new file mode 100644 index 00000000..2e0bf202 --- /dev/null +++ b/authors/gaetano.md @@ -0,0 +1,13 @@ +Author: Gaetano +Title: Software Engineer +Description: Gaetano is a software engineer focused on pragmatic developer + tooling, mobile application workflows, and AI-assisted coding systems. He + writes about reproducible engineering processes that make agent output easier + to test, review, and trust. +Author Image: [https://avatars.githubusercontent.com/skrtdev?size=512] +Author LinkedIn: +Author Twitter: +Company Name: +Company Description: +Company Logo Dark: +Company Logo White: diff --git a/definitions/20260604_definition_accessibility_regression.md b/definitions/20260604_definition_accessibility_regression.md new file mode 100644 index 00000000..68fda63f --- /dev/null +++ b/definitions/20260604_definition_accessibility_regression.md @@ -0,0 +1,29 @@ +--- +title: 'Accessibility Regression' +description: + 'An accessibility regression is a code change that makes a product harder to + use with assistive technology, keyboard navigation, or other access needs.' +date: 2026-06-04 +author: 'Gaetano' +--- + +# Accessibility Regression + +## Definition + +An accessibility regression is a change that reduces a product's usability for +people who rely on assistive technology, keyboard navigation, captions, +contrast, predictable focus, or semantic structure. The feature may still look +correct visually while becoming harder or impossible to use for some users. + +## Context and Usage + +Accessibility regressions often appear in small interface edits. A developer +can replace a labeled input with placeholder text, turn a text button into an +icon-only button without an accessible name, remove `aria-live` from a dynamic +status message, or break keyboard focus order while reorganizing a form. + +For example, changing a reset button from `Reset filters` to a visual `x` +without `aria-label="Reset filters"` can remove the button's accessible name. +The visual design still appears clear to sighted users, but screen reader users +hear an ambiguous control. diff --git a/guides/20260604_guide_rehearse_accessibility_regression_triage_in_daytona.md b/guides/20260604_guide_rehearse_accessibility_regression_triage_in_daytona.md new file mode 100644 index 00000000..c5db6413 --- /dev/null +++ b/guides/20260604_guide_rehearse_accessibility_regression_triage_in_daytona.md @@ -0,0 +1,364 @@ +--- +title: 'Rehearse Accessibility Triage in Daytona' +description: + 'Use Omni Engineer and Claude Engineer in a Daytona sandbox to reproduce, + repair, review, and verify an accessibility regression.' +date: 2026-06-04 +author: 'Gaetano' +tags: ['AI', 'accessibility', 'daytona', 'devcontainer'] +--- + +# Rehearse Accessibility Triage in Daytona + +# Introduction + +Accessibility bugs are easy to miss when a change still looks correct in a +browser. A filter form can keep its visual layout while losing a label, an +icon-only reset button can lose its accessible name, and a dynamic status line +can stop announcing updates to assistive technology. That kind of +[accessibility regression](../definitions/20260604_definition_accessibility_regression.md) +often survives casual review because the interface still appears usable to the +developer who changed it. + +AI engineering tools can help, but they need a tight workflow. In this guide, +[Omni Engineer](https://github.com/Doriandarko/omni-engineer) acts as the +repair agent, [Claude Engineer](https://github.com/Doriandarko/claude-engineer) +acts as the accessibility reviewer, and a [Daytona +sandbox](https://www.daytona.io/docs/en/sandboxes/) keeps the exercise +isolated. The goal is not to ask an agent to "make accessibility better." The +goal is to give two agents one reproducible failure, one focused patch, one +review pass, and one executable test suite. + +You will use a small Flask demo project with a deliberately broken branch: + +- [Daytona Accessibility Regression Demo](https://github.com/skrtdev/daytona-a11y-regression-demo) + +The `regression` branch fails tests for four common issues: a search input +without a real label, a reset button without an accessible name, a status +message without a polite live region, and filter buttons without grouped +pressed state. The `main` branch is the fixed reference implementation. + +## TL;DR + +- Add secret-free Dev Container definitions to Omni Engineer and Claude + Engineer so each repository has a portable Python workspace. +- Create one Daytona sandbox with API keys supplied as environment variables. +- Clone the demo project and check out its `regression` branch. +- Ask Omni Engineer to make the smallest semantic markup fix that turns the + failing tests green. +- Ask Claude Engineer to review the exact diff for keyboard, screen reader, and + regression-test gaps. +- Run `pytest -q` and `git diff --check` before treating the repair as ready. + +## Step 1: Prepare the Agent Workspaces + +The companion Dev Container contributions for this workflow are: + +| Repository | Purpose | Pull Request | +| --- | --- | --- | +| Omni Engineer | Python 3.11 workspace, dependency install, and `OPENROUTER_API_KEY` passthrough | [Doriandarko/omni-engineer#45](https://github.com/Doriandarko/omni-engineer/pull/45) | +| Claude Engineer | Python 3.11 workspace, dependency install, `ANTHROPIC_API_KEY` passthrough, optional `E2B_API_KEY`, and port `5000` forwarding | [Doriandarko/claude-engineer#270](https://github.com/Doriandarko/claude-engineer/pull/270) | + +The files are intentionally small. They install each repository's existing +`requirements.txt` and read keys from the local environment: + +```json +{ + "image": "mcr.microsoft.com/devcontainers/python:3.11", + "postCreateCommand": "python -m pip install --upgrade pip && python -m pip install -r requirements.txt", + "remoteUser": "vscode" +} +``` + +The full Omni Engineer version passes `OPENROUTER_API_KEY`. The Claude Engineer +version passes `ANTHROPIC_API_KEY`, optionally passes `E2B_API_KEY`, and +forwards port `5000` for the web UI. Neither file includes a `.env` file or +hard-codes a secret. + +Daytona's current CLI creates and executes commands in sandboxes. The +walkthrough below uses the documented `daytona create`, `daytona exec`, and +`daytona ssh` flow instead of assuming that Daytona automatically interprets a +repository's `devcontainer.json`. The Dev Container files are still useful +because they make each agent repository portable for editors and other +compatible development environments. + +## Step 2: Create a Daytona Sandbox + +Install and authenticate the Daytona CLI before starting. The CLI reference +documents `daytona create --env` for environment variables and `daytona exec +--cwd` for command execution in a selected working directory. + +Export your keys locally: + +```bash +export OPENROUTER_API_KEY="your-openrouter-key" +export ANTHROPIC_API_KEY="your-anthropic-key" +``` + +Create an isolated sandbox: + +```bash +daytona create \ + --name a11y-triage-lab \ + --env OPENROUTER_API_KEY="$OPENROUTER_API_KEY" \ + --env ANTHROPIC_API_KEY="$ANTHROPIC_API_KEY" +``` + +> **Note:** Keep real keys outside Git. If you create the sandbox before +> exporting the variables, recreate the sandbox with the correct `--env` flags +> rather than committing a local `.env` file. + +Clone the two agents and the demo project: + +```bash +daytona exec a11y-triage-lab \ + -- git clone https://github.com/skrtdev/omni-engineer.git /home/daytona/omni-engineer + +daytona exec a11y-triage-lab \ + -- git clone https://github.com/skrtdev/claude-engineer.git /home/daytona/claude-engineer + +daytona exec a11y-triage-lab \ + -- git clone https://github.com/skrtdev/daytona-a11y-regression-demo.git /home/daytona/daytona-a11y-regression-demo +``` + +Check out the intentionally broken branch: + +```bash +daytona exec a11y-triage-lab \ + --cwd /home/daytona/daytona-a11y-regression-demo \ + -- git checkout regression +``` + +Create a separate virtual environment for each repository: + +```bash +daytona exec a11y-triage-lab \ + --cwd /home/daytona/omni-engineer \ + -- sh -lc "python -m venv .venv && .venv/bin/python -m pip install -r requirements.txt" + +daytona exec a11y-triage-lab \ + --cwd /home/daytona/claude-engineer \ + -- sh -lc "python -m venv .venv && .venv/bin/python -m pip install -r requirements.txt" + +daytona exec a11y-triage-lab \ + --cwd /home/daytona/daytona-a11y-regression-demo \ + -- sh -lc "python -m venv .venv && .venv/bin/python -m pip install -r requirements.txt" +``` + +![Accessibility regression triage flow](assets/20260604_guide_rehearse_accessibility_regression_triage_in_daytona_img1.svg) + +The single sandbox keeps the work honest. Omni Engineer sees the failing files, +Claude Engineer reviews the same patch, and the tests run in the same +filesystem instead of in a pasted transcript. + +## Step 3: Reproduce the Regression First + +Run the tests before asking any agent to change code: + +```bash +daytona exec a11y-triage-lab \ + --cwd /home/daytona/daytona-a11y-regression-demo \ + -- .venv/bin/python -m pytest -q +``` + +The `regression` branch should fail four tests: + +| Failing Check | What It Means | +| --- | --- | +| `test_search_input_has_visible_label` | The search input is visually described but not associated with a real `