Skip to content

Commit b4e62ad

Browse files
authored
docs: consolidate contributor and architecture guidance (#897)
## Summary - consolidate contributor, agent, and design guidance into a single canonical docs structure - slim down top-level entrypoints and redirect agent instructions to the canonical docs set - add architecture and request-lifecycle documentation for faster onboarding ## Verification - docker compose -f .devcontainer/docker-compose.yml run --rm app make setup - docker compose -f .devcontainer/docker-compose.yml run --rm app make ready
1 parent e747b23 commit b4e62ad

6 files changed

Lines changed: 486 additions & 264 deletions

File tree

.github/copilot-instructions.md

Lines changed: 10 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1,75 +1,16 @@
11
# html2rss-web AI Agent Instructions
22

3-
## Overview
3+
This repository uses a centralized documentation structure. All AI agents (including Copilot, Gemini CLI, etc.) must follow the constraints and rules defined in the following files:
44

5-
- Ruby web app that converts websites into RSS 2.0 feeds.
6-
- Built with **Roda** backend + **Preact** frontend, using the **html2rss** gem (+ `html2rss-configs`).
7-
- **Frontend:** Vite-built Preact UI, served alongside Ruby backend.
5+
## Canonical Documentation
86

9-
## Documentation website of core dependencies
7+
- **Agent Constraints**: [AGENTS.md](../AGENTS.md) (Execution rules, verification, and UI principles)
8+
- **Contributor Guide**: [docs/README.md](../docs/README.md) (Architecture, security, setup, and coding style)
9+
- **Design System**: [docs/design-system.md](../docs/design-system.md) (Visual and CSS rules)
1010

11-
Search these pages before using them. Find examples, plugins, UI components, and configuration options.
11+
## Quick Reference for Agents
1212

13-
### Roda
14-
15-
1. https://roda.jeremyevans.net/documentation.html
16-
17-
### Preact & Vite
18-
19-
1. https://preactjs.com/guide/v10/getting-started/
20-
2. https://vite.dev/guide/
21-
22-
### html2rss
23-
24-
1. If available, find source locally in: `../html2rss`.
25-
2. source code on github: https://github.com/html2rss/html2rss
26-
27-
### Test and Linters
28-
29-
1. https://docs.rubocop.org/rubocop/cops.html
30-
2. https://docs.rubocop.org/rubocop-rspec/cops_rspec.html
31-
3. https://rspec.info/features/3-13/rspec-expectations/built-in-matchers/
32-
4. https://www.betterspecs.org/
33-
34-
Fix rubocop `RSpec/MultipleExpectations` adding rspec tag `:aggregate_failures`.
35-
36-
## Core Rules
37-
38-
- ✅ Organise Roda routes via dedicated modules (e.g. `Html2rss::Web::Routes::*`), keeping the main app class thin.
39-
- ✅ Keep helper modules minimal: define entrypoints with `class << self` and push implementation helpers under `private`; avoid `module_function` unless mirroring existing conventions.
40-
- ✅ Validate all inputs. Pass outbound requests through **SSRF filter**.
41-
- ✅ Add caching headers where appropriate (`Rack::Cache`).
42-
- ✅ Errors: friendly messages for users, detailed logging internally.
43-
-**Frontend**: Use Preact components in `frontend/src/`. Keep it simple.
44-
-**CSS**: Use the app-owned frontend styles in `frontend/src/styles/`.
45-
-**Specs**: RSpec for Ruby, build tests for frontend.
46-
- ✅ When a spec needs to tweak environment variables, wrap the example in `ClimateControl.modify` so state is restored automatically.
47-
48-
## Don't
49-
50-
- ❌ Don't use Ruby's URI class or addressable gem directly. Strictly use `Html2rss::Url` only.
51-
- ❌ Don't bypass SSRF filter or weaken CSP.
52-
- ❌ Don't add databases, ORMs, or background jobs.
53-
- ❌ Don't leak stack traces or secrets in responses.
54-
- ❌ Don't reach into private API with `send(...)`; expose what you need at the module level instead.
55-
- ❌ Don't modify `frontend/dist/` - it's generated by build process.
56-
- ❌ NEVER expose the auth token a user provides.
57-
58-
## Environment
59-
60-
- `RACK_ENV` – environment
61-
- `AUTO_SOURCE_ENABLED`, `AUTO_SOURCE_USERNAME`, `AUTO_SOURCE_PASSWORD`, `AUTO_SOURCE_ALLOWED_ORIGINS`
62-
- `HEALTH_CHECK_USERNAME`, `HEALTH_CHECK_PASSWORD`
63-
- `SENTRY_DSN` (optional)
64-
65-
### Verification Steps
66-
67-
- Run `ruby -c app.rb` to check syntax
68-
- Run `bundle exec rspec` to verify tests
69-
- Check `bundle install` removes unused dependencies
70-
71-
## Style
72-
73-
- Add `# frozen_string_literal: true`
74-
- Follow RuboCop style
75-
- YARD doc comments for public methods
13+
- **Environment**: All commands MUST run inside the Dev Container.
14+
- **Verification**: Run `make ready` before any commit.
15+
- **Security**: Follow strict [Security & Safety Rules](../docs/README.md#security--safety-rules).
16+
- **Style**: Follow [Architectural Constraints](../docs/README.md#architectural-constraints) (YARD docs, Roda organization).

AGENTS.md

Lines changed: 34 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,84 +1,51 @@
1-
# Agent Workflow (Dev Container)
1+
# Agent Workflow Constraints
22

3-
## Start the Dev Container
4-
5-
```text
6-
docker compose -f .devcontainer/docker-compose.yml up -d
7-
```
8-
9-
## Commands (run inside the container)
10-
11-
```text
12-
docker compose -f .devcontainer/docker-compose.yml exec -T app make setup
13-
14-
docker compose -f .devcontainer/docker-compose.yml exec -T app make dev
15-
16-
docker compose -f .devcontainer/docker-compose.yml exec -T app make test
17-
18-
docker compose -f .devcontainer/docker-compose.yml exec -T app make ready
19-
20-
docker compose -f .devcontainer/docker-compose.yml exec -T app bundle exec rubocop -F
21-
22-
docker compose -f .devcontainer/docker-compose.yml exec -T app bundle exec rspec
23-
```
24-
25-
Pre-commit gate (required):
26-
27-
```text
28-
docker compose -f .devcontainer/docker-compose.yml exec -T app make ready
29-
```
30-
31-
If you need an interactive shell:
32-
33-
```text
34-
docker compose -f .devcontainer/docker-compose.yml exec app bash
35-
```
36-
37-
---
3+
This document defines execution constraints for AI agents. For general contributor rules, setup commands, architectural constraints, and security policies, see [docs/README.md](docs/README.md).
384

395
## Collaboration Agreement (Agent ↔ User)
406

41-
## Interview Answers (ID-able) + Expert Recommendations
42-
43-
**DoD:** `make ready` in Dev Container; if applicable, user completes manual smoke test with agent-provided steps.
44-
**Verification:** Always smoke Dev Container + `make ready`.
45-
**Commits:** Group by logical unit after smoke-tested (feature / improvement / refactor).
46-
**Responses:** Changes → Commands → Results → Next steps, ending with a concise one-line summary.
47-
**KISS vs Refactor:** KISS by default; boy-scout refactors allowed if low-risk and simplifying.
48-
**Ambiguity:** Proceed with safest assumption, then confirm.
49-
**Non-negotiables:** Dev Container only; security first.
50-
51-
Expert recommendation: keep workflows terminal-first and keyboard-focused (clear commands, no GUI-only steps).
7+
- **DoD:** `make ready` in Dev Container; if applicable, user completes manual smoke test with agent-provided steps.
8+
- **Verification:** Always smoke Dev Container + `make ready`.
9+
- **Commits:** Group by logical unit after smoke-tested (feature / improvement / refactor).
10+
- **Responses:** Changes → Commands → Results → Next steps, ending with a concise one-line summary.
11+
- **KISS vs Refactor:** KISS by default; boy-scout refactors allowed if low-risk and simplifying.
12+
- **Ambiguity:** Proceed with safest assumption, then confirm.
13+
- **Non-negotiables:** Dev Container only; security first.
5214

53-
## Definition of Done
54-
55-
- Run `make ready` inside the Dev Container.
56-
- If applicable, user completes manual smoke test; agent provides clear instructions.
57-
58-
## Verification Rules
15+
## Agent-Specific Verification Rules
5916

6017
- Always run Dev Container smoke + `make ready` for changes.
18+
- For frontend changes, also verify in `chrome-devtools` MCP at `http://127.0.0.1:4001/` while the Dev Container is running.
19+
- Capture a quick state check for all affected UI states (e.g., guest/member/result) to enforce state parity and avoid duplicate actions.
6120

62-
## Commit Granularity
21+
### Frontend Smoke Checklist
6322

64-
- Group commits by logical units after they have grown and been smoke-tested (feature / improvement / refactor).
23+
- Start the Dev Container and app (`make dev`).
24+
- Open `http://127.0.0.1:4001/` with `chrome-devtools` MCP.
25+
- Validate the primary user path touched by the change.
26+
- Verify all affected states (e.g., guest/member/result) keep the same layout grammar.
27+
- Confirm action uniqueness: one canonical control per outcome in each state.
6528

66-
## Response Format
29+
## UI Execution Principles
6730

68-
- Default: Changes → Commands → Results → Next steps.
69-
- End with a concise one-line summary.
31+
See [docs/design-system.md](docs/design-system.md) for visual rules.
7032

71-
## KISS vs Refactor
33+
- **Task Dominance:** Each UI state should make one user objective obvious and primary. Supporting surfaces and links must yield priority.
34+
- **Copy Minimalism:** Remove text that repeats what the interface already communicates. Prefer action-oriented wording.
35+
- **State Skeleton:** Adjacent UI states should read as the same frame with content changes, not as separate pages.
36+
- **Focus Contract:** Verify browser autofocus and return-focus behavior on initial load and after transitions.
37+
- **Support Compression:** When a user has advanced past setup, reduce the visual weight of support content.
7238

73-
- KISS by default.
74-
- Boy-scout refactors are allowed when they reduce complexity and are low-risk.
75-
76-
## Ambiguity Handling
39+
## Response Format
7740

78-
- Proceed with the safest assumption, then confirm.
41+
1. **Changes:** Briefly list files/symbols modified.
42+
2. **Commands:** Show the verification commands run.
43+
3. **Results:** Summarize the outcome.
44+
4. **Next steps:** Propose the immediate follow-up.
45+
5. **One-line Summary:** End with a concise summary.
7946

8047
## Non-Negotiables
8148

82-
- Security first.
83-
- YARD docs are strict for public Ruby methods in `app/`: every public method must have a YARD docstring with typed `@param` tags (for all params) and typed `@return`.
84-
- When touching non-public methods, add YARD docs when it improves maintenance or clarifies invariants/edge handling.
49+
- **Security first:** No leaking secrets or insecure patterns. See [Security & Safety Rules](docs/README.md#security--safety-rules).
50+
- **YARD docs:** Strict for public Ruby methods in `app/`. Every public method must have a YARD docstring with typed `@param` and `@return`. See [Architectural Constraints](docs/README.md#architectural-constraints).
51+
- **No host execution:** All commands MUST run inside the Dev Container via `make` or `bundle exec`.

README.md

Lines changed: 23 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ html2rss-web converts arbitrary websites into RSS 2.0 feeds with a slim Ruby bac
77
## Links
88

99
- Docs & feed directory: https://html2rss.github.io
10+
- Contributor Guide: [docs/README.md](docs/README.md)
1011
- Discussions: https://github.com/orgs/html2rss/discussions
1112
- Sponsor: https://github.com/sponsors/gildesmarais
1213

@@ -15,29 +16,35 @@ html2rss-web converts arbitrary websites into RSS 2.0 feeds with a slim Ruby bac
1516
- Responsive Preact interface for demo, sign-in, conversion, and result flows.
1617
- Automatic source discovery with token-scoped permissions.
1718
- Signed public feed URLs that work in standard RSS readers.
18-
- Built-in SSRF defences, input validation, and HMAC-protected tokens.
19+
- Built-in URL validation, scoped feed access controls, and HMAC-protected tokens.
1920

20-
## Architecture
21+
## Architecture Overview
2122

2223
- **Backend:** Ruby + Roda, backed by the `html2rss` gem for extraction.
2324
- **Frontend:** Preact app built with Vite into `frontend/dist` and served at `/`.
24-
- **Distribution:** Docker Compose by default; other deployments require manual wiring.
25-
- [Project notes](docs/README.md)
25+
- **Distribution:** Docker Compose by default.
2626

27-
## REST API Snapshot
27+
For detailed architecture and internal rules, see [docs/README.md](docs/README.md).
28+
29+
## Trial Run (Docker Pull And Run)
30+
31+
The published image already includes a sample `config/feeds.yml`, so you can try the app without creating or mounting one first.
2832

2933
```bash
30-
# List available strategies
31-
curl -H "Authorization: Bearer <token>" \
32-
"https://your-domain.com/api/v1/strategies"
33-
34-
# Create a feed and capture the signed public URL
35-
curl -X POST "https://your-domain.com/api/v1/feeds" \
36-
-H "Authorization: Bearer <token>" \
37-
-H "Content-Type: application/json" \
38-
-d '{"url":"https://example.com","name":"Example Feed"}'
34+
docker run --rm \
35+
-p 4000:4000 \
36+
-e RACK_ENV=production \
37+
-e HTML2RSS_SECRET_KEY=$(openssl rand -hex 32) \
38+
html2rss/web
3939
```
4040

41+
Then open:
42+
43+
- `http://localhost:4000/` for the web UI
44+
- `http://localhost:4000/microsoft.com/azure-products.rss` for a built-in Azure updates feed
45+
46+
This trial run is intentionally minimal. Use Docker Compose for Browserless, auto-updates, or local feed overrides.
47+
4148
## Deploy (Docker Compose)
4249

4350
1. Generate a key: `openssl rand -hex 32`.
@@ -46,73 +53,12 @@ curl -X POST "https://your-domain.com/api/v1/feeds" \
4653

4754
UI + API run on `http://localhost:4000`. The app exits if the secret key is missing.
4855

49-
## Development (Dev Container)
56+
## Development
5057

5158
Use the repository's [Dev Container](.devcontainer/README.md) for all local development and tests.
5259
Running the app directly on the host is not supported.
5360

54-
Quick start inside the Dev Container:
55-
56-
```
57-
make setup
58-
make dev
59-
make test
60-
make ready
61-
make yard-verify-public-docs
62-
bundle exec rubocop -F
63-
bundle exec rspec
64-
make openapi
65-
```
66-
67-
Dev URLs: Ruby app at `http://localhost:4000`, frontend dev server at `http://localhost:4001`.
68-
69-
Backend code under the `Html2rss::Web` namespace now lives under `app/web/**`, so Zeitwerk can mirror constant paths directly instead of relying on directory-specific namespace wiring.
70-
`make ready` also runs `rake zeitwerk:verify`, which eager-loads the app and fails on loader drift early.
71-
For contributors and AI agents changing backend structure, follow the rules in [docs/README.md](docs/README.md).
72-
73-
## Make Targets
74-
75-
| Command | Purpose |
76-
| ------------------------------ | ---------------------------------------------------------- |
77-
| `make help` | List available shortcuts. |
78-
| `make setup` | Install Ruby and Node dependencies. |
79-
| `make dev` | Run Ruby (port 4000) and frontend (port 4001) dev servers. |
80-
| `make dev-ruby` | Start only the Ruby server. |
81-
| `make dev-frontend` | Start only the frontend dev server (port 4001). |
82-
| `make test` | Run Ruby and frontend test suites. |
83-
| `make test-ruby` | Run Ruby specs. |
84-
| `make test-frontend` | Run frontend unit and contract tests. |
85-
| `make lint` | Run all linters. |
86-
| `make lintfix` | Auto-fix lint warnings where possible. |
87-
| `make yard-verify-public-docs` | Enforce typed YARD docs for public methods in `app/`. |
88-
| `make openapi` | Regenerate `public/openapi.yaml` from request specs. |
89-
| `make openapi-verify` | Regenerate + fail if OpenAPI file is stale. |
90-
| `make clean` | Remove build artefacts. |
91-
92-
## OpenAPI Contract
93-
94-
The OpenAPI file is generated from Ruby request specs only.
95-
96-
- Regenerate: `make openapi`
97-
- Verify drift (CI behavior): `make openapi-verify`
98-
99-
## Frontend npm Scripts (inside Dev Container)
100-
101-
| Command | Purpose |
102-
| ----------------------- | -------------------------------------------- |
103-
| `npm run dev` | Vite dev server with hot reload (port 4001). |
104-
| `npm run build` | Build static assets into `frontend/dist/`. |
105-
| `npm run test:run` | Unit tests (Vitest). |
106-
| `npm run test:contract` | Contract tests with MSW. |
107-
108-
## Testing Strategy
109-
110-
| Layer | Tooling | Focus |
111-
| ----------------- | ------------------------ | ---------------------------------------------------- |
112-
| Ruby API | RSpec + Rack::Test | Feed creation, retrieval, auth paths. |
113-
| Frontend unit | Vitest + Testing Library | Component rendering and hooks with mocked fetch. |
114-
| Frontend contract | Vitest + MSW | End-to-end fetch flows against mocked API responses. |
115-
| Docker smoke | RSpec (`:docker`) | Net::HTTP probes against the containerised service. |
61+
See the [Contributor Guide](docs/README.md) for setup commands, testing strategy, and backend structure rules.
11662

11763
## Contributing
11864

0 commit comments

Comments
 (0)