init
This commit is contained in:
commit
b15b95781c
108 changed files with 14802 additions and 0 deletions
41
docs/agents/HANDOFF_TEMPLATE.md
Normal file
41
docs/agents/HANDOFF_TEMPLATE.md
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
# Agent Handoff Template
|
||||
|
||||
## Agent
|
||||
|
||||
Name:
|
||||
|
||||
Stage:
|
||||
|
||||
Date:
|
||||
|
||||
## Scope
|
||||
|
||||
Describe the exact work completed in this stage.
|
||||
|
||||
## Files Changed
|
||||
|
||||
List every important file changed.
|
||||
|
||||
## Database Changes
|
||||
|
||||
List migrations, schema changes, or database assumptions.
|
||||
|
||||
## API Or Route Changes
|
||||
|
||||
List endpoints, handlers, middleware, or route groups added or changed.
|
||||
|
||||
## Commands And Tests Run
|
||||
|
||||
List the commands executed and summarize the result.
|
||||
|
||||
## Known Limitations
|
||||
|
||||
List anything incomplete, risky, or intentionally deferred.
|
||||
|
||||
## Recommended Next Step
|
||||
|
||||
Explain what the next agent should do first.
|
||||
|
||||
## Notes For Validator
|
||||
|
||||
Mention anything that deserves extra attention during validation.
|
||||
174
docs/agents/OPERATOR_QUICKSTART_RU.md
Normal file
174
docs/agents/OPERATOR_QUICKSTART_RU.md
Normal file
|
|
@ -0,0 +1,174 @@
|
|||
# Operator Quickstart
|
||||
|
||||
## Куда смотреть в первую очередь
|
||||
|
||||
Тебе для работы нужны только эти файлы:
|
||||
|
||||
1. `/Users/delete/projects/update_server/docs/agents/WORKFLOW.md`
|
||||
2. `/Users/delete/projects/update_server/PRODUCT_SPEC.md`
|
||||
3. `/Users/delete/projects/update_server/IMPLEMENTATION_PLAN.md`
|
||||
4. `/Users/delete/projects/update_server/DEVELOPMENT_WORKFLOW.md`
|
||||
|
||||
Перед каждым новым агентом дополнительно смотри:
|
||||
|
||||
- последний файл из `/Users/delete/projects/update_server/docs/agents/handoffs`
|
||||
- последний файл из `/Users/delete/projects/update_server/docs/agents/validation`
|
||||
|
||||
## Что запускать по порядку
|
||||
|
||||
Всегда идёшь по одной и той же схеме:
|
||||
|
||||
1. запускаешь implementation agent;
|
||||
2. ждёшь, пока он закончит код и создаст handoff;
|
||||
3. запускаешь validator;
|
||||
4. если `APPROVED`, переходишь к следующему агенту;
|
||||
5. если `CHANGES_REQUIRED`, заново запускаешь того же агента с его handoff и validation report.
|
||||
|
||||
Порядок агентов смотри в:
|
||||
|
||||
- `/Users/delete/projects/update_server/docs/agents/WORKFLOW.md`
|
||||
|
||||
## Базовый промт для implementation agent
|
||||
|
||||
Копируй этот промт и меняй только название агента и секцию.
|
||||
|
||||
```text
|
||||
You are <AGENT NAME>.
|
||||
|
||||
Read these files first:
|
||||
- /Users/delete/projects/update_server/docs/agents/WORKFLOW.md
|
||||
- /Users/delete/projects/update_server/PRODUCT_SPEC.md
|
||||
- /Users/delete/projects/update_server/IMPLEMENTATION_PLAN.md
|
||||
- /Users/delete/projects/update_server/DEVELOPMENT_WORKFLOW.md
|
||||
|
||||
Then read:
|
||||
- the section for "<AGENT NAME>" in WORKFLOW.md
|
||||
- the latest file in /Users/delete/projects/update_server/docs/agents/handoffs if it exists
|
||||
- the latest file in /Users/delete/projects/update_server/docs/agents/validation if it exists
|
||||
|
||||
Follow the rules and fixed decisions exactly.
|
||||
Work only within your assigned scope.
|
||||
Do not redesign unrelated parts.
|
||||
After implementation:
|
||||
- create or update code
|
||||
- run relevant checks if possible
|
||||
- create a handoff file in /Users/delete/projects/update_server/docs/agents/handoffs using /Users/delete/projects/update_server/docs/agents/HANDOFF_TEMPLATE.md
|
||||
|
||||
In your final response:
|
||||
- summarize what you changed
|
||||
- list files changed
|
||||
- list checks run
|
||||
- mention limitations
|
||||
- mention the exact next recommended step
|
||||
```
|
||||
|
||||
## Базовый промт для validator
|
||||
|
||||
```text
|
||||
You are the validation agent.
|
||||
|
||||
Read these files first:
|
||||
- /Users/delete/projects/update_server/docs/agents/WORKFLOW.md
|
||||
- /Users/delete/projects/update_server/PRODUCT_SPEC.md
|
||||
- /Users/delete/projects/update_server/IMPLEMENTATION_PLAN.md
|
||||
- /Users/delete/projects/update_server/DEVELOPMENT_WORKFLOW.md
|
||||
|
||||
Then read:
|
||||
- the section for "<AGENT NAME>" in WORKFLOW.md
|
||||
- the latest file in /Users/delete/projects/update_server/docs/agents/handoffs
|
||||
|
||||
Review the code produced for that stage.
|
||||
Run relevant tests or checks if possible.
|
||||
Look for:
|
||||
- missing scope items
|
||||
- regressions
|
||||
- spec mismatches
|
||||
- unsafe behavior
|
||||
- missing tests
|
||||
|
||||
Create a validation report in /Users/delete/projects/update_server/docs/agents/validation using /Users/delete/projects/update_server/docs/agents/VALIDATION_TEMPLATE.md
|
||||
|
||||
Finish with exactly one status:
|
||||
- APPROVED
|
||||
- or CHANGES_REQUIRED
|
||||
```
|
||||
|
||||
## Базовый промт для доработки после замечаний
|
||||
|
||||
Если валидатор вернул `CHANGES_REQUIRED`, используй такой промт для того же агента:
|
||||
|
||||
```text
|
||||
You are <AGENT NAME> continuing the same stage.
|
||||
|
||||
Read these files first:
|
||||
- /Users/delete/projects/update_server/docs/agents/WORKFLOW.md
|
||||
- /Users/delete/projects/update_server/PRODUCT_SPEC.md
|
||||
- /Users/delete/projects/update_server/IMPLEMENTATION_PLAN.md
|
||||
- /Users/delete/projects/update_server/DEVELOPMENT_WORKFLOW.md
|
||||
|
||||
Then read:
|
||||
- your stage section in WORKFLOW.md
|
||||
- your last handoff file
|
||||
- the latest validation report in /Users/delete/projects/update_server/docs/agents/validation
|
||||
|
||||
Fix all blocking issues from the validation report.
|
||||
Do not start the next stage.
|
||||
Stay within your original scope unless a fix strictly requires a small adjacent change.
|
||||
|
||||
After fixes:
|
||||
- update the code
|
||||
- update or create a new handoff file
|
||||
- summarize exactly which validation findings were fixed
|
||||
```
|
||||
|
||||
## Что поставить через Homebrew
|
||||
|
||||
### Минимум для локальной разработки
|
||||
|
||||
```bash
|
||||
brew install go sqlite goose just air
|
||||
```
|
||||
|
||||
Что это даёт:
|
||||
|
||||
- `go` — сам Go-компилятор и `go mod`
|
||||
- `sqlite` — локальная SQLite CLI, удобно смотреть базу руками
|
||||
- `goose` — миграции базы
|
||||
- `just` — удобный runner для коротких команд проекта
|
||||
- `air` — live reload для локальной разработки Go-сервера
|
||||
|
||||
### Опционально, но очень полезно
|
||||
|
||||
```bash
|
||||
brew install caddy
|
||||
```
|
||||
|
||||
`caddy` пригодится позже для локального прогона reverse proxy и HTTPS-подобной схемы.
|
||||
|
||||
### Если захочешь локально проверять контейнеры
|
||||
|
||||
```bash
|
||||
brew install --cask docker-desktop
|
||||
```
|
||||
|
||||
Если Docker Desktop тебе не нравится, можно потом выбрать более лёгкую схему с `colima`, но для старта это не обязательно.
|
||||
|
||||
## Что ещё желательно иметь
|
||||
|
||||
Это не Homebrew-пакет проекта, но на Mac очень желательно:
|
||||
|
||||
```bash
|
||||
xcode-select --install
|
||||
```
|
||||
|
||||
Это ставит Command Line Tools и часто экономит кучу времени при сборке Go-зависимостей.
|
||||
|
||||
## Самый короткий практический сценарий
|
||||
|
||||
1. ставишь `go sqlite goose just air`;
|
||||
2. открываешь `docs/agents/WORKFLOW.md`;
|
||||
3. копируешь базовый промт для `Agent 01 - Foundation`;
|
||||
4. запускаешь агента;
|
||||
5. проверяешь, что он создал handoff;
|
||||
6. копируешь промт для validator;
|
||||
7. после `APPROVED` переходишь к следующему агенту.
|
||||
29
docs/agents/VALIDATION_TEMPLATE.md
Normal file
29
docs/agents/VALIDATION_TEMPLATE.md
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
# Validation Report Template
|
||||
|
||||
## Validator
|
||||
|
||||
Name:
|
||||
|
||||
Stage Reviewed:
|
||||
|
||||
Date:
|
||||
|
||||
## Reviewed Inputs
|
||||
|
||||
List the files, handoffs, diffs, and tests reviewed.
|
||||
|
||||
## Findings
|
||||
|
||||
List concrete bugs, regressions, or risks.
|
||||
|
||||
## Required Fixes
|
||||
|
||||
List the fixes required before approval.
|
||||
|
||||
## Optional Improvements
|
||||
|
||||
List anything useful but non-blocking.
|
||||
|
||||
## Status
|
||||
|
||||
`APPROVED` or `CHANGES_REQUIRED`
|
||||
543
docs/agents/WORKFLOW.md
Normal file
543
docs/agents/WORKFLOW.md
Normal file
|
|
@ -0,0 +1,543 @@
|
|||
# AI Agent Workflow Runbook
|
||||
|
||||
## 1. Purpose
|
||||
|
||||
This document defines how to implement the update server with sequential AI agents.
|
||||
|
||||
The workflow is designed for:
|
||||
|
||||
- one human operator who launches agents one by one;
|
||||
- one implementation agent per stage;
|
||||
- one validation agent after each stage;
|
||||
- file-based handoff instead of direct agent-to-agent chat.
|
||||
|
||||
## 2. Source Of Truth
|
||||
|
||||
Every implementation agent must read these files before starting:
|
||||
|
||||
- `/Users/delete/projects/update_server/PRODUCT_SPEC.md`
|
||||
- `/Users/delete/projects/update_server/IMPLEMENTATION_PLAN.md`
|
||||
- `/Users/delete/projects/update_server/DEVELOPMENT_WORKFLOW.md`
|
||||
- `/Users/delete/projects/update_server/docs/agents/WORKFLOW.md`
|
||||
|
||||
Every agent must also read the latest handoff and validation files if they exist.
|
||||
|
||||
## 3. Fixed Technical Decisions
|
||||
|
||||
These decisions are considered fixed unless the human operator explicitly changes them.
|
||||
|
||||
- Language: Go
|
||||
- Router: `chi`
|
||||
- Database: `SQLite`
|
||||
- HTML strategy: server-rendered HTML templates
|
||||
- Artifact storage: local filesystem
|
||||
- Deployment shape: app container behind Caddy or Nginx
|
||||
- Web auth: session-based authentication
|
||||
- Client auth: `Authorization: Bearer <api_key>`
|
||||
- API key access modes:
|
||||
- `all_projects`
|
||||
- `project_allow_list`
|
||||
- `project_deny_list`
|
||||
- `tag_allow_list`
|
||||
- `tag_deny_list`
|
||||
- One API key must use exactly one scope mode at a time
|
||||
- Projects support tags from day one
|
||||
- Security is mandatory, not optional
|
||||
|
||||
## 4. Shared Workspace Rules
|
||||
|
||||
All code lives in the main repository.
|
||||
|
||||
Agents should use these implementation paths:
|
||||
|
||||
- `/Users/delete/projects/update_server/cmd/server`
|
||||
- `/Users/delete/projects/update_server/internal`
|
||||
- `/Users/delete/projects/update_server/web`
|
||||
- `/Users/delete/projects/update_server/migrations`
|
||||
|
||||
Agents must use these coordination paths:
|
||||
|
||||
- handoffs: `/Users/delete/projects/update_server/docs/agents/handoffs`
|
||||
- validations: `/Users/delete/projects/update_server/docs/agents/validation`
|
||||
|
||||
If an agent needs to communicate something to the next agent, it must do so through:
|
||||
|
||||
- code changes;
|
||||
- a handoff file;
|
||||
- updates to spec or implementation docs if architecture changed.
|
||||
|
||||
Agents should not rely on hidden memory or previous chat state.
|
||||
|
||||
## 5. Handoff Protocol
|
||||
|
||||
After finishing work, every implementation agent must create a handoff file:
|
||||
|
||||
- naming format: `NN-agent-name.md`
|
||||
- example: `01-foundation.md`
|
||||
|
||||
Each handoff file should be saved in:
|
||||
|
||||
- `/Users/delete/projects/update_server/docs/agents/handoffs`
|
||||
|
||||
The handoff file must include:
|
||||
|
||||
- scope of work;
|
||||
- files changed;
|
||||
- migrations added or changed;
|
||||
- endpoints added or changed;
|
||||
- tests or commands run;
|
||||
- known limitations;
|
||||
- exact next recommended step.
|
||||
|
||||
Use this template:
|
||||
|
||||
- `/Users/delete/projects/update_server/docs/agents/HANDOFF_TEMPLATE.md`
|
||||
|
||||
## 6. Validation Protocol
|
||||
|
||||
After each implementation agent finishes, run a validation agent before moving to the next stage.
|
||||
|
||||
The validation agent should:
|
||||
|
||||
- read the current agent section in this file;
|
||||
- read the latest handoff file;
|
||||
- inspect code changes;
|
||||
- run relevant tests or checks;
|
||||
- produce a validation report.
|
||||
|
||||
Validation files should be saved in:
|
||||
|
||||
- `/Users/delete/projects/update_server/docs/agents/validation`
|
||||
|
||||
Use this template:
|
||||
|
||||
- `/Users/delete/projects/update_server/docs/agents/VALIDATION_TEMPLATE.md`
|
||||
|
||||
Validation result must end in one of these statuses:
|
||||
|
||||
- `APPROVED`
|
||||
- `CHANGES_REQUIRED`
|
||||
|
||||
Do not launch the next implementation agent until the previous stage is `APPROVED`.
|
||||
|
||||
## 7. Agent Count
|
||||
|
||||
Recommended sequence:
|
||||
|
||||
- 7 implementation agents
|
||||
- 1 validation agent role used after every stage
|
||||
|
||||
The validation agent can be the same AI system reused every time.
|
||||
|
||||
## 8. Agent 01 - Foundation
|
||||
|
||||
### Mission
|
||||
|
||||
Set up the repository skeleton and the minimum runnable Go application.
|
||||
|
||||
### Ownership
|
||||
|
||||
This agent owns:
|
||||
|
||||
- Go module initialization
|
||||
- basic app boot
|
||||
- config loading
|
||||
- HTTP router setup
|
||||
- health endpoint
|
||||
- base middleware wiring
|
||||
- template bootstrapping
|
||||
- initial developer commands
|
||||
|
||||
### Deliverables
|
||||
|
||||
This agent must produce:
|
||||
|
||||
- runnable server entrypoint
|
||||
- config package
|
||||
- base router with route groups
|
||||
- health endpoint
|
||||
- base HTML layout structure
|
||||
- initial project structure under `cmd`, `internal`, and `web`
|
||||
|
||||
### Out Of Scope
|
||||
|
||||
This agent must not implement:
|
||||
|
||||
- business logic
|
||||
- database schema
|
||||
- authentication flows
|
||||
- release upload
|
||||
- API keys
|
||||
|
||||
### Acceptance Criteria
|
||||
|
||||
- the app starts successfully;
|
||||
- a health endpoint responds;
|
||||
- the code structure matches the implementation plan;
|
||||
- the project is ready for migrations and feature modules.
|
||||
|
||||
## 9. Agent 02 - Database And Migrations
|
||||
|
||||
### Mission
|
||||
|
||||
Create the data model, migrations, and database access foundation.
|
||||
|
||||
### Ownership
|
||||
|
||||
This agent owns:
|
||||
|
||||
- migration setup
|
||||
- database connection layer
|
||||
- schema design
|
||||
- repository or query layer foundation
|
||||
|
||||
### Deliverables
|
||||
|
||||
This agent must implement tables for:
|
||||
|
||||
- `users`
|
||||
- `projects`
|
||||
- `tags`
|
||||
- `project_tags`
|
||||
- `releases`
|
||||
- `api_keys`
|
||||
- `api_key_project_access`
|
||||
- `api_key_tag_access`
|
||||
- `sessions` if needed
|
||||
- `audit_logs` if included in the first pass
|
||||
|
||||
### Out Of Scope
|
||||
|
||||
This agent must not implement:
|
||||
|
||||
- login UI
|
||||
- upload endpoints
|
||||
- full business workflows
|
||||
|
||||
### Acceptance Criteria
|
||||
|
||||
- migrations can be applied cleanly;
|
||||
- schema matches the spec;
|
||||
- access tables support project and tag based key scopes;
|
||||
- database layer is ready for the next agents.
|
||||
|
||||
## 10. Agent 03 - Authentication And Admin Sessions
|
||||
|
||||
### Mission
|
||||
|
||||
Implement admin authentication and session management.
|
||||
|
||||
### Ownership
|
||||
|
||||
This agent owns:
|
||||
|
||||
- admin bootstrap user creation
|
||||
- password hashing
|
||||
- login and logout flow
|
||||
- session middleware
|
||||
- role checks foundation
|
||||
|
||||
### Deliverables
|
||||
|
||||
This agent must produce:
|
||||
|
||||
- login form and login handler
|
||||
- session creation and invalidation
|
||||
- protected admin route group
|
||||
- admin bootstrap from environment or setup logic
|
||||
|
||||
### Out Of Scope
|
||||
|
||||
This agent must not implement:
|
||||
|
||||
- project management
|
||||
- release upload
|
||||
- API key logic
|
||||
|
||||
### Acceptance Criteria
|
||||
|
||||
- admin can log in and log out;
|
||||
- protected routes are actually protected;
|
||||
- passwords are hashed securely;
|
||||
- session handling works reliably.
|
||||
|
||||
## 11. Agent 04 - Projects, Tags, And Releases
|
||||
|
||||
### Mission
|
||||
|
||||
Implement core product data management: projects, project tags, and release upload metadata flow.
|
||||
|
||||
### Ownership
|
||||
|
||||
This agent owns:
|
||||
|
||||
- project CRUD
|
||||
- tag CRUD
|
||||
- attach or detach tags from projects
|
||||
- release metadata handling
|
||||
- artifact storage abstraction
|
||||
- upload flow and checksum generation
|
||||
|
||||
### Deliverables
|
||||
|
||||
This agent must produce:
|
||||
|
||||
- project create, edit, list, archive flow
|
||||
- tag create, edit, list flow
|
||||
- project-tag assignment
|
||||
- release upload service
|
||||
- artifact persistence on disk
|
||||
- checksum capture
|
||||
|
||||
### Out Of Scope
|
||||
|
||||
This agent must not implement:
|
||||
|
||||
- API key access logic
|
||||
- external client update endpoints
|
||||
|
||||
### Acceptance Criteria
|
||||
|
||||
- admin can manage projects and tags;
|
||||
- admin can upload a release to a project;
|
||||
- release metadata is stored in the database;
|
||||
- artifact files are stored outside the public web root.
|
||||
|
||||
## 12. Agent 05 - API Keys And Access Control
|
||||
|
||||
### Mission
|
||||
|
||||
Implement API key generation, hashing, permissions, and scope evaluation.
|
||||
|
||||
### Ownership
|
||||
|
||||
This agent owns:
|
||||
|
||||
- secure API key generation
|
||||
- API key hashing and lookup
|
||||
- permission flags
|
||||
- access scope evaluation
|
||||
- project allow or deny list rules
|
||||
- tag allow or deny list rules
|
||||
|
||||
### Deliverables
|
||||
|
||||
This agent must produce:
|
||||
|
||||
- API key creation flow
|
||||
- one-time key reveal behavior
|
||||
- key activation and revocation
|
||||
- permission middleware for API key routes
|
||||
- project and tag access resolution logic
|
||||
|
||||
### Out Of Scope
|
||||
|
||||
This agent must not implement:
|
||||
|
||||
- final UI polish
|
||||
- deployment hardening
|
||||
|
||||
### Acceptance Criteria
|
||||
|
||||
- API keys are stored hashed;
|
||||
- only authorized projects are visible to a given key;
|
||||
- allow-list and deny-list logic works for projects and tags;
|
||||
- disabled or expired keys are rejected.
|
||||
|
||||
## 13. Agent 06 - Client API And Admin UI
|
||||
|
||||
### Mission
|
||||
|
||||
Implement the usable product experience for admins and client applications.
|
||||
|
||||
### Ownership
|
||||
|
||||
This agent owns:
|
||||
|
||||
- admin pages for projects, tags, releases, and API keys
|
||||
- client-facing update endpoints
|
||||
- latest-release lookup
|
||||
- release metadata endpoint
|
||||
- authenticated download endpoint
|
||||
|
||||
### Deliverables
|
||||
|
||||
This agent must produce:
|
||||
|
||||
- admin pages that cover the main flows
|
||||
- client endpoint to list accessible projects
|
||||
- client endpoint to get latest release metadata
|
||||
- client endpoint to download a release
|
||||
|
||||
### Out Of Scope
|
||||
|
||||
This agent must not implement:
|
||||
|
||||
- deep security hardening beyond local route protection
|
||||
- production reverse proxy setup
|
||||
|
||||
### Acceptance Criteria
|
||||
|
||||
- an admin can complete the full product flow from the browser;
|
||||
- a client can authenticate with a bearer API key;
|
||||
- a client can discover and download only authorized updates.
|
||||
|
||||
## 14. Agent 07 - Security And Deployment Hardening
|
||||
|
||||
### Mission
|
||||
|
||||
Make the system safe and deployable on an internet-facing server.
|
||||
|
||||
### Ownership
|
||||
|
||||
This agent owns:
|
||||
|
||||
- security headers
|
||||
- rate limiting
|
||||
- request timeouts
|
||||
- CSRF finishing pass
|
||||
- safer cookie settings
|
||||
- reverse proxy examples
|
||||
- Docker and deployment finishing pass
|
||||
- backup and operational notes
|
||||
|
||||
### Deliverables
|
||||
|
||||
This agent must produce:
|
||||
|
||||
- hardened HTTP server settings
|
||||
- production-ready container setup
|
||||
- Caddy or Nginx example configuration
|
||||
- deployment notes for Proxmox
|
||||
- security review fixes that fit the current architecture
|
||||
|
||||
### Out Of Scope
|
||||
|
||||
This agent must not redesign the product or data model unless a critical security issue requires it.
|
||||
|
||||
### Acceptance Criteria
|
||||
|
||||
- the service is ready to run behind HTTPS;
|
||||
- admin and client traffic have sane security defaults;
|
||||
- artifacts are not directly exposed;
|
||||
- deployment instructions are complete enough for first production rollout.
|
||||
|
||||
## 15. Validation Agent Role
|
||||
|
||||
### Mission
|
||||
|
||||
Review each completed stage before the next implementation agent starts.
|
||||
|
||||
### Required Checks
|
||||
|
||||
The validation agent should verify:
|
||||
|
||||
- scope completion;
|
||||
- obvious regressions;
|
||||
- schema or route mismatches;
|
||||
- missing tests;
|
||||
- unsafe behavior;
|
||||
- contradictions with the spec.
|
||||
|
||||
### Output
|
||||
|
||||
The validation agent must write one validation file per stage and finish with:
|
||||
|
||||
- `APPROVED`
|
||||
- or `CHANGES_REQUIRED`
|
||||
|
||||
## 16. Operator Guide For Human User
|
||||
|
||||
Этот раздел специально для тебя, на русском.
|
||||
|
||||
### Общая схема запуска
|
||||
|
||||
Запускаешь агентов строго по порядку:
|
||||
|
||||
1. `Agent 01 - Foundation`
|
||||
2. `Validator`
|
||||
3. `Agent 02 - Database And Migrations`
|
||||
4. `Validator`
|
||||
5. `Agent 03 - Authentication And Admin Sessions`
|
||||
6. `Validator`
|
||||
7. `Agent 04 - Projects, Tags, And Releases`
|
||||
8. `Validator`
|
||||
9. `Agent 05 - API Keys And Access Control`
|
||||
10. `Validator`
|
||||
11. `Agent 06 - Client API And Admin UI`
|
||||
12. `Validator`
|
||||
13. `Agent 07 - Security And Deployment Hardening`
|
||||
14. `Final Validator`
|
||||
|
||||
### Как запускать каждый этап
|
||||
|
||||
Для каждого нового агента даёшь ему один и тот же базовый контекст:
|
||||
|
||||
- прочитать `PRODUCT_SPEC.md`
|
||||
- прочитать `IMPLEMENTATION_PLAN.md`
|
||||
- прочитать `DEVELOPMENT_WORKFLOW.md`
|
||||
- прочитать `docs/agents/WORKFLOW.md`
|
||||
- прочитать последний handoff-файл
|
||||
- прочитать последний validation-файл, если он есть
|
||||
|
||||
После этого говоришь агенту работать только в рамках его секции из этого runbook.
|
||||
|
||||
### Что требовать от каждого агента
|
||||
|
||||
После завершения этапа агент обязан:
|
||||
|
||||
- внести код;
|
||||
- если нужно, обновить документацию;
|
||||
- создать handoff-файл в `docs/agents/handoffs`;
|
||||
- перечислить, что сделано;
|
||||
- перечислить, что не сделано;
|
||||
- указать, что должен делать следующий агент.
|
||||
|
||||
### Когда запускать валидатора
|
||||
|
||||
Валидатора запускаешь после каждого агента.
|
||||
|
||||
Ему даёшь задачу:
|
||||
|
||||
- прочитать соответствующую секцию агента из `docs/agents/WORKFLOW.md`;
|
||||
- прочитать свежий handoff;
|
||||
- проверить код;
|
||||
- проверить, не нарушена ли спецификация;
|
||||
- выдать `APPROVED` или `CHANGES_REQUIRED`;
|
||||
- сохранить отчёт в `docs/agents/validation`.
|
||||
|
||||
### Если валидатор нашёл проблемы
|
||||
|
||||
Если статус `CHANGES_REQUIRED`, то:
|
||||
|
||||
1. не переходишь к следующему агенту;
|
||||
2. запускаешь того же самого агента повторно;
|
||||
3. даёшь ему его прошлый handoff и validation report;
|
||||
4. просишь закрыть замечания;
|
||||
5. снова запускаешь валидатора.
|
||||
|
||||
### Когда использовать меня как валидатора
|
||||
|
||||
Меня лучше использовать:
|
||||
|
||||
- после каждого крупного этапа;
|
||||
- перед миграциями базы;
|
||||
- перед этапом security hardening;
|
||||
- перед первым Docker/deploy;
|
||||
- перед выкладкой на Proxmox.
|
||||
|
||||
### Практически удобный режим
|
||||
|
||||
Самый удобный режим для тебя такой:
|
||||
|
||||
1. локально на Mac запускаешь первого агента;
|
||||
2. проверяешь, что handoff-файл создался;
|
||||
3. зовёшь меня как валидатора;
|
||||
4. после `APPROVED` запускаешь следующего агента;
|
||||
5. когда дойдёшь до конца, только потом собираешь контейнер и переносишь на Proxmox.
|
||||
|
||||
### Главный принцип
|
||||
|
||||
Следующий агент никогда не стартует без handoff от прошлого и без validation report.
|
||||
|
||||
Это защитит тебя от хаоса, повторной работы и скрытых поломок между этапами.
|
||||
79
docs/agents/handoffs/01-foundation.md
Normal file
79
docs/agents/handoffs/01-foundation.md
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
# Agent
|
||||
|
||||
Name: Agent 01 - Foundation
|
||||
|
||||
Stage: Foundation
|
||||
|
||||
Date: 2026-04-13
|
||||
|
||||
## Scope
|
||||
|
||||
Set up the initial runnable Go application skeleton for the update server.
|
||||
|
||||
Completed in this stage:
|
||||
|
||||
- initialized the Go module;
|
||||
- added the server entrypoint and graceful app bootstrap;
|
||||
- implemented environment-based config loading with sensible local defaults;
|
||||
- wired the base `chi` router, middleware stack, and route groups;
|
||||
- added a JSON health endpoint;
|
||||
- added template bootstrapping and the first server-rendered HTML pages;
|
||||
- added base static assets and a `Justfile` for local run/build/test tasks;
|
||||
- created the `migrations` directory placeholder for the next stage.
|
||||
|
||||
## Files Changed
|
||||
|
||||
- `/Users/delete/projects/update_server/.gitignore`
|
||||
- `/Users/delete/projects/update_server/go.mod`
|
||||
- `/Users/delete/projects/update_server/go.sum`
|
||||
- `/Users/delete/projects/update_server/Justfile`
|
||||
- `/Users/delete/projects/update_server/cmd/server/main.go`
|
||||
- `/Users/delete/projects/update_server/internal/app/app.go`
|
||||
- `/Users/delete/projects/update_server/internal/config/config.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/router.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/middleware.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/handlers.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/render.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/response.go`
|
||||
- `/Users/delete/projects/update_server/web/templates/layouts/base.gohtml`
|
||||
- `/Users/delete/projects/update_server/web/templates/pages/home.gohtml`
|
||||
- `/Users/delete/projects/update_server/web/templates/pages/admin.gohtml`
|
||||
- `/Users/delete/projects/update_server/web/static/app.css`
|
||||
- `/Users/delete/projects/update_server/migrations/README.md`
|
||||
|
||||
## Database Changes
|
||||
|
||||
- no schema or migration files were added in this stage;
|
||||
- created `/Users/delete/projects/update_server/migrations` with a placeholder README so Agent 02 can own the first migration set cleanly.
|
||||
|
||||
## API Or Route Changes
|
||||
|
||||
- added `GET /healthz` returning JSON status;
|
||||
- added `GET /` as the foundation landing page;
|
||||
- added `GET /admin` as the reserved admin route group entry;
|
||||
- added `GET /api/v1` as the reserved versioned API route group entry;
|
||||
- added static asset serving under `/static/*`.
|
||||
|
||||
## Commands And Tests Run
|
||||
|
||||
- `gofmt -w ./cmd ./internal` - completed successfully;
|
||||
- `go mod tidy` - completed successfully after running with normal network/cache access;
|
||||
- `go test ./...` - completed successfully;
|
||||
- `go build -o /tmp/update-server ./cmd/server` - completed successfully;
|
||||
- started `/tmp/update-server` on `127.0.0.1:18080` and verified `curl http://127.0.0.1:18080/healthz` returned `200 OK` JSON.
|
||||
|
||||
## Known Limitations
|
||||
|
||||
- no database connection or migration runner exists yet;
|
||||
- no authentication, sessions, uploads, or business modules are implemented yet;
|
||||
- template loading currently reads from the filesystem path configured by `TEMPLATES_DIR`;
|
||||
- a local `data-dev/` directory is created on startup and is intentionally ignored via `.gitignore`.
|
||||
|
||||
## Recommended Next Step
|
||||
|
||||
Agent 02 should implement the SQLite foundation next: add the migration tool flow, create the initial schema files for the spec tables, and introduce the database connection/repository layer without changing the existing app bootstrap, config contract, or route-group structure.
|
||||
|
||||
## Notes For Validator
|
||||
|
||||
- there were no prior stage handoff or validation reports yet; only the directory README placeholders existed;
|
||||
- pay attention to whether the app boots from the repo root, whether `/healthz` responds, and whether the route groups remain ready for later auth and feature modules.
|
||||
105
docs/agents/handoffs/02-database.md
Normal file
105
docs/agents/handoffs/02-database.md
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
# Agent
|
||||
|
||||
Name: Agent 02 - Database And Migrations
|
||||
|
||||
Stage: Database And Migrations
|
||||
|
||||
Date: 2026-04-13
|
||||
|
||||
## Scope
|
||||
|
||||
Created the SQLite data layer foundation for the update server.
|
||||
|
||||
Completed in this stage:
|
||||
|
||||
- added SQLite config values for `SQLITE_PATH` and `MIGRATIONS_DIR`;
|
||||
- added a database connection layer with SQLite pragmas, health checks, and transaction scaffolding;
|
||||
- implemented an ordered SQL migration runner with checksum tracking in `schema_migrations`;
|
||||
- created the initial schema for `users`, `projects`, `tags`, `project_tags`, `releases`, `api_keys`, `api_key_project_access`, `api_key_tag_access`, `sessions`, and `audit_logs`;
|
||||
- added indexes and update triggers for mutable tables;
|
||||
- added schema guards so API key project/tag access rows match the key’s selected `scope_mode`;
|
||||
- wired database open + migrate into app startup without changing the existing route-group layout;
|
||||
- added a standalone `cmd/migrate` entrypoint and `just migrate`;
|
||||
- added migration tests and refreshed the health endpoint to report SQLite readiness.
|
||||
|
||||
## Files Changed
|
||||
|
||||
- `/Users/delete/projects/update_server/go.mod`
|
||||
- `/Users/delete/projects/update_server/go.sum`
|
||||
- `/Users/delete/projects/update_server/Justfile`
|
||||
- `/Users/delete/projects/update_server/cmd/migrate/main.go`
|
||||
- `/Users/delete/projects/update_server/internal/app/app.go`
|
||||
- `/Users/delete/projects/update_server/internal/config/config.go`
|
||||
- `/Users/delete/projects/update_server/internal/db/models.go`
|
||||
- `/Users/delete/projects/update_server/internal/db/open.go`
|
||||
- `/Users/delete/projects/update_server/internal/db/migrate.go`
|
||||
- `/Users/delete/projects/update_server/internal/db/store.go`
|
||||
- `/Users/delete/projects/update_server/internal/db/migrate_test.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/router.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/handlers.go`
|
||||
- `/Users/delete/projects/update_server/migrations/README.md`
|
||||
- `/Users/delete/projects/update_server/migrations/0001_initial_schema.sql`
|
||||
- `/Users/delete/projects/update_server/migrations/0002_indexes_and_triggers.sql`
|
||||
- `/Users/delete/projects/update_server/migrations/0003_api_key_scope_guards.sql`
|
||||
|
||||
## Database Changes
|
||||
|
||||
Added migrations:
|
||||
|
||||
- `0001_initial_schema.sql`
|
||||
- `0002_indexes_and_triggers.sql`
|
||||
- `0003_api_key_scope_guards.sql`
|
||||
|
||||
Schema notes:
|
||||
|
||||
- timestamps are stored as UTC RFC3339-like text values;
|
||||
- `api_keys.scope_mode` is constrained to the agreed modes:
|
||||
- `all_projects`
|
||||
- `project_allow_list`
|
||||
- `project_deny_list`
|
||||
- `tag_allow_list`
|
||||
- `tag_deny_list`
|
||||
- `api_key_project_access` only accepts keys in project-based modes;
|
||||
- `api_key_tag_access` only accepts keys in tag-based modes;
|
||||
- changing an API key to an incompatible scope mode is blocked if incompatible access rows already exist;
|
||||
- `sessions` stores hashed session tokens, not raw tokens;
|
||||
- `audit_logs` storage is included, but no runtime writes are wired yet.
|
||||
|
||||
## API Or Route Changes
|
||||
|
||||
- no new route groups or business endpoints were added;
|
||||
- `GET /healthz` now includes SQLite readiness and returns `503` if the store is unavailable;
|
||||
- updated the placeholder `/` and `/api/v1` responses to reflect database readiness.
|
||||
|
||||
## Commands And Tests Run
|
||||
|
||||
- `gofmt -w ./cmd ./internal` - completed successfully;
|
||||
- `go mod tidy` - initially failed in the sandbox due Go cache/network restrictions; completed successfully after rerunning with normal access and temporary Go caches;
|
||||
- `GOCACHE=/tmp/go-build-sqlite3 GOMODCACHE=/tmp/go-mod-sqlite3 go test ./...` - passed;
|
||||
- `GOCACHE=/tmp/go-build-sqlite3 GOMODCACHE=/tmp/go-mod-sqlite3 go build -o /tmp/update-server ./cmd/server` - passed;
|
||||
- `GOCACHE=/tmp/go-build-sqlite3 GOMODCACHE=/tmp/go-mod-sqlite3 go build -o /tmp/update-migrate ./cmd/migrate` - passed;
|
||||
- `APP_BASE_URL=http://127.0.0.1:18080 DATA_DIR=/tmp/update-server-db-dev-2 /tmp/update-migrate` - applied migrations successfully to a fresh temp SQLite database;
|
||||
- `sqlite3 /tmp/update-server-db-dev-2/db.sqlite 'SELECT name FROM schema_migrations ORDER BY name;'` - confirmed all three migrations were recorded;
|
||||
- started `/tmp/update-server` on `127.0.0.1:18080` and verified:
|
||||
- `GET /` -> `200 OK`
|
||||
- `GET /api/v1` -> `200 OK`
|
||||
- `GET /healthz` -> `200 OK` with `"database":"ok"`
|
||||
|
||||
## Known Limitations
|
||||
|
||||
- repository structs are intentionally scaffolding-only in this stage; feature-specific query methods are still for later agents to add;
|
||||
- no auth/session business logic is implemented yet beyond the schema and store foundation;
|
||||
- `audit_logs` exists in schema only; event production is deferred;
|
||||
- scope-mode enforcement now covers schema consistency for access-link rows, but full project/tag access evaluation logic is still for the API key stage;
|
||||
- existing local databases created before the final scope-guard addition need the new `0003_api_key_scope_guards.sql` migration applied, which the updated startup path now does automatically.
|
||||
|
||||
## Recommended Next Step
|
||||
|
||||
Agent 03 should implement admin authentication next using the new `users` and `sessions` tables: bootstrap the first admin user from environment, hash passwords, create/invalidate session records, and protect the `/admin` route group with session middleware.
|
||||
|
||||
## Notes For Validator
|
||||
|
||||
- pay extra attention to migration immutability: `schema_migrations` stores a checksum and should reject edited applied files;
|
||||
- validate that the default server startup path now opens SQLite and auto-applies `0001` -> `0003`;
|
||||
- validate that project/tag access link rows are rejected when the parent API key uses the wrong `scope_mode`;
|
||||
- the workspace is not a git repository, so diff-based review may need to rely on direct file inspection.
|
||||
92
docs/agents/handoffs/03-auth.md
Normal file
92
docs/agents/handoffs/03-auth.md
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
# Agent
|
||||
|
||||
Name: Agent 03 - Authentication And Admin Sessions
|
||||
|
||||
Stage: Authentication And Admin Sessions
|
||||
|
||||
Date: 2026-04-14
|
||||
|
||||
## Scope
|
||||
|
||||
Implemented admin authentication and session management on top of the existing `users` and `sessions` tables.
|
||||
|
||||
Completed in this stage:
|
||||
|
||||
- added auth-related config for bootstrap credentials, session cookie naming, session TTL, and secure-cookie detection from `APP_BASE_URL`;
|
||||
- implemented bcrypt password hashing and verification in a dedicated `internal/auth` service;
|
||||
- added admin bootstrap logic that creates the first active admin user from `ADMIN_EMAIL` and `ADMIN_PASSWORD` when no active admin exists yet;
|
||||
- implemented user/session repository methods for bootstrap lookup, login, session lookup, session touch, and logout invalidation;
|
||||
- added secure random session token generation with SHA-256 hashed token storage in SQLite;
|
||||
- wired login and logout handlers plus authenticated session middleware into the existing `chi` route-group structure;
|
||||
- protected the `/admin` route group with session and role checks;
|
||||
- replaced the placeholder admin page with a protected authenticated dashboard and added a server-rendered login form;
|
||||
- added tests for bootstrap behavior and the login/protected-route/logout flow.
|
||||
|
||||
## Files Changed
|
||||
|
||||
- `/Users/delete/projects/update_server/go.mod`
|
||||
- `/Users/delete/projects/update_server/go.sum`
|
||||
- `/Users/delete/projects/update_server/internal/app/app.go`
|
||||
- `/Users/delete/projects/update_server/internal/config/config.go`
|
||||
- `/Users/delete/projects/update_server/internal/auth/context.go`
|
||||
- `/Users/delete/projects/update_server/internal/auth/password.go`
|
||||
- `/Users/delete/projects/update_server/internal/auth/service.go`
|
||||
- `/Users/delete/projects/update_server/internal/auth/service_test.go`
|
||||
- `/Users/delete/projects/update_server/internal/db/errors.go`
|
||||
- `/Users/delete/projects/update_server/internal/db/models.go`
|
||||
- `/Users/delete/projects/update_server/internal/db/time.go`
|
||||
- `/Users/delete/projects/update_server/internal/db/users.go`
|
||||
- `/Users/delete/projects/update_server/internal/db/sessions.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/router.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/render.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/handlers.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/auth_handlers.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/auth_middleware.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/auth_integration_test.go`
|
||||
- `/Users/delete/projects/update_server/web/templates/layouts/base.gohtml`
|
||||
- `/Users/delete/projects/update_server/web/templates/pages/home.gohtml`
|
||||
- `/Users/delete/projects/update_server/web/templates/pages/admin.gohtml`
|
||||
- `/Users/delete/projects/update_server/web/templates/pages/login.gohtml`
|
||||
- `/Users/delete/projects/update_server/web/static/app.css`
|
||||
|
||||
## Database Changes
|
||||
|
||||
- no schema or migration changes were required in this stage;
|
||||
- the existing `users` and `sessions` tables from Agent 02 are now actively used for bootstrap, login, session lookup, and logout invalidation;
|
||||
- session tokens continue to be stored hashed only;
|
||||
- user `last_login_at` and session `last_seen_at` are now updated by runtime auth flows.
|
||||
|
||||
## API Or Route Changes
|
||||
|
||||
- added `GET /admin/login` for the server-rendered login form;
|
||||
- added `POST /admin/login` to authenticate an admin user and issue a session cookie;
|
||||
- added `POST /admin/logout` to invalidate the current session and clear the cookie;
|
||||
- changed `/admin` from a public placeholder to a protected route group guarded by session middleware and admin-role checks;
|
||||
- retained the existing `/api/v1` route scaffold unchanged.
|
||||
|
||||
## Commands And Tests Run
|
||||
|
||||
- `gofmt -w ./cmd ./internal` - passed;
|
||||
- `GOCACHE=/tmp/go-build-auth GOMODCACHE=/tmp/go-mod-auth go mod tidy` - initially failed in the sandbox due network/DNS restrictions, then passed after rerunning with approval;
|
||||
- `GOCACHE=/tmp/go-build-auth GOMODCACHE=/tmp/go-mod-auth go test ./...` - passed;
|
||||
- `GOCACHE=/tmp/go-build-auth GOMODCACHE=/tmp/go-mod-auth go build -o /tmp/update-server-auth ./cmd/server` - passed;
|
||||
- `GOCACHE=/tmp/go-build-auth GOMODCACHE=/tmp/go-mod-auth go build -o /tmp/update-migrate-auth ./cmd/migrate` - passed.
|
||||
|
||||
## Known Limitations
|
||||
|
||||
- CSRF protection is not implemented yet for admin forms; this remains for the hardening stage;
|
||||
- login rate limiting is not implemented yet;
|
||||
- bootstrap is environment-driven only in this stage; there is no separate one-time bootstrap CLI yet;
|
||||
- if no active admin exists and the configured `ADMIN_EMAIL` already belongs to a non-admin user, bootstrap currently logs a warning and leaves that conflict for an operator to resolve;
|
||||
- there is no admin user-management UI yet beyond the initial bootstrap/login foundation.
|
||||
|
||||
## Recommended Next Step
|
||||
|
||||
Agent 04 should build project, tag, and release management on top of the now-protected `/admin` route group, reusing the authenticated session context instead of adding a parallel auth path.
|
||||
|
||||
## Notes For Validator
|
||||
|
||||
- verify that `POST /admin/login` creates a DB-backed session and stores only the token hash in SQLite, not the raw cookie value;
|
||||
- verify that `/admin` redirects when unauthenticated and succeeds when the issued session cookie is replayed;
|
||||
- verify that `POST /admin/logout` invalidates the existing session record so the old cookie no longer grants access;
|
||||
- verify bootstrap behavior both when `ADMIN_EMAIL` and `ADMIN_PASSWORD` are present and when they are absent.
|
||||
105
docs/agents/handoffs/04-projects-releases.md
Normal file
105
docs/agents/handoffs/04-projects-releases.md
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
# Agent
|
||||
|
||||
Name: Agent 04 - Projects, Tags, And Releases
|
||||
|
||||
Stage: Projects, Tags, And Releases
|
||||
|
||||
Date: 2026-04-14
|
||||
|
||||
## Scope
|
||||
|
||||
Implemented the core product data management stage on top of the existing authenticated `/admin` route group.
|
||||
|
||||
Completed in this stage:
|
||||
|
||||
- added artifact storage configuration rooted under `DATA_DIR/artifacts`, with validation that artifacts stay outside the public static directory;
|
||||
- implemented local filesystem artifact storage with temp-file staging and final path validation;
|
||||
- added project repository methods for create, update, list, archive toggle, and project-tag assignment queries;
|
||||
- added tag repository methods for create, update, list, delete-if-unused, and project usage queries;
|
||||
- added release repository methods for create, lookup, and per-project release listing;
|
||||
- implemented a release upload service that sanitizes filenames, streams uploads to a temp artifact, computes SHA-256 checksums, detects content type, moves the file into structured private storage, and writes release metadata to SQLite;
|
||||
- extended the protected admin router with project list/create/detail/archive routes, tag list/create/detail/delete routes, project-tag attach or detach actions, and release upload handling;
|
||||
- replaced the placeholder dashboard with project/tag/release-aware admin pages and added server-rendered templates for project list, project detail, project creation, tag list, and tag detail;
|
||||
- added integration coverage for the admin flow that logs in, creates and edits project/tag data, attaches tags, uploads a release, verifies the checksum and sanitized filename, and checks the artifact on disk.
|
||||
|
||||
## Files Changed
|
||||
|
||||
- `/Users/delete/projects/update_server/internal/app/app.go`
|
||||
- `/Users/delete/projects/update_server/internal/config/config.go`
|
||||
- `/Users/delete/projects/update_server/internal/db/errors.go`
|
||||
- `/Users/delete/projects/update_server/internal/db/models.go`
|
||||
- `/Users/delete/projects/update_server/internal/db/projects.go`
|
||||
- `/Users/delete/projects/update_server/internal/db/tags.go`
|
||||
- `/Users/delete/projects/update_server/internal/db/releases.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/router.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/render.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/view_data.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/handlers.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/auth_handlers.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/admin_common.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/admin_projects.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/admin_tags.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/auth_integration_test.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/projects_integration_test.go`
|
||||
- `/Users/delete/projects/update_server/internal/releases/service.go`
|
||||
- `/Users/delete/projects/update_server/internal/slug/slug.go`
|
||||
- `/Users/delete/projects/update_server/internal/storage/local.go`
|
||||
- `/Users/delete/projects/update_server/web/templates/layouts/base.gohtml`
|
||||
- `/Users/delete/projects/update_server/web/templates/pages/admin.gohtml`
|
||||
- `/Users/delete/projects/update_server/web/templates/pages/home.gohtml`
|
||||
- `/Users/delete/projects/update_server/web/templates/pages/login.gohtml`
|
||||
- `/Users/delete/projects/update_server/web/templates/pages/projects.gohtml`
|
||||
- `/Users/delete/projects/update_server/web/templates/pages/project_form.gohtml`
|
||||
- `/Users/delete/projects/update_server/web/templates/pages/project_detail.gohtml`
|
||||
- `/Users/delete/projects/update_server/web/templates/pages/tags.gohtml`
|
||||
- `/Users/delete/projects/update_server/web/templates/pages/tag_form.gohtml`
|
||||
- `/Users/delete/projects/update_server/web/static/app.css`
|
||||
- `/Users/delete/projects/update_server/docs/agents/handoffs/04-projects-releases.md`
|
||||
|
||||
## Database Changes
|
||||
|
||||
- no schema or migration changes were required in this stage;
|
||||
- the existing `projects`, `tags`, `project_tags`, and `releases` tables are now actively used by repository methods and protected admin workflows;
|
||||
- release `storage_path` values are now persisted as relative paths underneath the configured artifact root;
|
||||
- release rows now store sanitized filenames, SHA-256 checksum values, detected content type, file size, release notes, and uploader linkage.
|
||||
|
||||
## API Or Route Changes
|
||||
|
||||
- added `GET /admin/projects` for the protected project list page;
|
||||
- added `GET /admin/projects/new` and `POST /admin/projects` for project creation;
|
||||
- added `GET /admin/projects/{projectID}` and `POST /admin/projects/{projectID}` for project detail and editing;
|
||||
- added `POST /admin/projects/{projectID}/archive` for archive or restore actions;
|
||||
- added `POST /admin/projects/{projectID}/tags` and `POST /admin/projects/{projectID}/tags/{tagID}/detach` for project-tag assignment;
|
||||
- added `POST /admin/projects/{projectID}/releases` for protected release uploads;
|
||||
- added `GET /admin/tags`, `GET /admin/tags/new`, and `POST /admin/tags` for tag list and creation;
|
||||
- added `GET /admin/tags/{tagID}`, `POST /admin/tags/{tagID}`, and `POST /admin/tags/{tagID}/delete` for tag edit and delete-if-unused behavior;
|
||||
- updated `GET /admin` to show project/tag/release summary data instead of the auth-only placeholder;
|
||||
- kept `/api/v1` unchanged and intentionally did not add API key or client update endpoints in this stage.
|
||||
|
||||
## Commands And Tests Run
|
||||
|
||||
- `gofmt -w ./internal ./cmd` - passed;
|
||||
- `GOCACHE=/tmp/go-build-agent04 GOMODCACHE=/tmp/go-mod-agent04 go test ./...` - initially failed in the sandbox due dependency download DNS restrictions, then passed after rerunning with approval;
|
||||
- `GOCACHE=/tmp/go-build-agent04 GOMODCACHE=/tmp/go-mod-agent04 go build -o /tmp/update-server-agent04 ./cmd/server` - passed;
|
||||
- `GOCACHE=/tmp/go-build-agent04 GOMODCACHE=/tmp/go-mod-agent04 go build -o /tmp/update-migrate-agent04 ./cmd/migrate` - passed.
|
||||
|
||||
## Known Limitations
|
||||
|
||||
- CSRF protection is still not implemented for admin forms, including the new project, tag, archive, and upload actions;
|
||||
- release deletion or disable flows are not implemented in this stage;
|
||||
- there is still no client-facing download or metadata endpoint for releases; only the protected admin upload and metadata path is present;
|
||||
- duplicate project slugs, tag slugs, and `(project_id, version, build)` release combinations are rejected rather than offering replace-in-place behavior;
|
||||
- upload handling currently relies on the standard multipart temp-file path before final storage, which is acceptable for MVP but not yet a custom streaming parser.
|
||||
|
||||
## Recommended Next Step
|
||||
|
||||
Agent 05 should implement API key generation, hashing, permissions, and scope evaluation on top of the now-working project and tag data model, using the existing `projects`, `tags`, and assignment relationships for allow-list and deny-list management.
|
||||
|
||||
## Notes For Validator
|
||||
|
||||
- verify that all new admin project and tag routes remain inside the existing authenticated `/admin` route group and reuse the session context;
|
||||
- verify that uploaded artifacts land under `DATA_DIR/artifacts` and not under `web/static`;
|
||||
- verify that uploaded filenames are sanitized before persistence and that `releases.checksum_sha256` matches the actual file bytes on disk;
|
||||
- verify that release metadata rows are written to SQLite with the expected storage path, size, content type, and uploader linkage;
|
||||
- verify that project archive or restore toggles `projects.is_active`;
|
||||
- verify that tag deletion is blocked while the tag is still attached to a project.
|
||||
63
docs/agents/handoffs/05-api-keys-fix.md
Normal file
63
docs/agents/handoffs/05-api-keys-fix.md
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
# Agent
|
||||
|
||||
Name: Agent 05 - API Keys And Access Control (fix round)
|
||||
|
||||
Stage: API Keys And Access Control
|
||||
|
||||
Date: 2026-04-14
|
||||
|
||||
## Scope
|
||||
|
||||
Fixed the validation findings for Agent 05 without expanding into the client API stage.
|
||||
|
||||
Completed in this fix round:
|
||||
|
||||
- added explicit anti-cache headers for the one-time raw API key reveal response so the secret-bearing HTML is marked non-cacheable;
|
||||
- changed the immediate post-create detail render to hydrate from the persisted API key record and persisted scope rows while still showing the raw key only on that one response;
|
||||
- extended HTTP integration coverage to verify:
|
||||
- the creation response includes anti-cache headers;
|
||||
- the creation response shows saved name, description, scope mode, permissions, and selected project or tag rules;
|
||||
- the raw key is present on the creation response and absent on later detail loads.
|
||||
|
||||
## Files Changed
|
||||
|
||||
- `/Users/delete/projects/update_server/internal/http/admin_api_keys.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/api_keys_integration_test.go`
|
||||
- `/Users/delete/projects/update_server/docs/agents/handoffs/05-api-keys-fix.md`
|
||||
|
||||
## Database Changes
|
||||
|
||||
- no schema or migration changes were required;
|
||||
- the existing API key hash and scope storage model remains unchanged.
|
||||
|
||||
## API Or Route Changes
|
||||
|
||||
- no routes were added or removed;
|
||||
- `POST /admin/api-keys` now returns the one-time reveal page with explicit anti-cache headers:
|
||||
- `Cache-Control: no-store, private, max-age=0`
|
||||
- `Pragma: no-cache`
|
||||
- `Expires: 0`
|
||||
|
||||
## Commands And Tests Run
|
||||
|
||||
- `gofmt -w internal/http/admin_api_keys.go internal/http/api_keys_integration_test.go` - passed;
|
||||
- `GOCACHE=/tmp/go-build-agent05-fix GOMODCACHE=/tmp/go-mod-agent05-2 go test ./internal/http` - passed;
|
||||
- `GOCACHE=/tmp/go-build-agent05-fix-all GOMODCACHE=/tmp/go-mod-agent05-2 go test ./...` - passed;
|
||||
- `GOCACHE=/tmp/go-build-agent05-fix-build GOMODCACHE=/tmp/go-mod-agent05-2 go build -o /tmp/update-server-agent05-fix ./cmd/server` - passed;
|
||||
- `GOCACHE=/tmp/go-build-agent05-fix-build2 GOMODCACHE=/tmp/go-mod-agent05-2 go build -o /tmp/update-migrate-agent05-fix ./cmd/migrate` - passed.
|
||||
|
||||
## Known Limitations
|
||||
|
||||
- the one-time reveal still intentionally happens on the direct POST response rather than a redirect flow so the raw key never has to enter query strings or persistent storage;
|
||||
- CSRF protection is still not implemented for admin API key forms;
|
||||
- the client `/api/v1` endpoints still do not use the API key middleware yet; that remains for Agent 06.
|
||||
|
||||
## Recommended Next Step
|
||||
|
||||
Agent 06 should wire the existing API key middleware into the client `/api/v1` endpoints for accessible project listing, latest release lookup, and authenticated artifact download.
|
||||
|
||||
## Notes For Validator
|
||||
|
||||
- verify that the post-create response shows persisted saved values immediately, without requiring a manual refresh;
|
||||
- verify that the raw key appears only on the secret-bearing creation response and not on later `GET /admin/api-keys/{id}` detail loads;
|
||||
- verify the one-time reveal response includes the anti-cache headers listed above.
|
||||
90
docs/agents/handoffs/05-api-keys.md
Normal file
90
docs/agents/handoffs/05-api-keys.md
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
# Agent
|
||||
|
||||
Name: Agent 05 - API Keys And Access Control
|
||||
|
||||
Stage: API Keys And Access Control
|
||||
|
||||
Date: 2026-04-14
|
||||
|
||||
## Scope
|
||||
|
||||
Implemented the API key lifecycle and access-control stage on top of the existing authenticated admin workspace and the project or tag model from Agent 04.
|
||||
|
||||
Completed in this stage:
|
||||
|
||||
- added a dedicated `internal/apikeys` service for secure API key generation, SHA-256 hashing, lookup, lifecycle checks, and project scope evaluation;
|
||||
- implemented full API key repository support for create, update, list, revoke or activate, last-used tracking, project and tag rule storage, and effective access queries;
|
||||
- added minimal protected admin pages for API key list, creation, detail, update, and revoke or activate actions;
|
||||
- implemented one-time raw key reveal behavior by showing the generated key only in the immediate creation response while persisting only the short prefix and hash;
|
||||
- added permission and project-scope middleware helpers for future `/api/v1` client routes using bearer authentication;
|
||||
- added integration and unit coverage for hashed storage, expired or revoked key rejection, all five scope modes, scope transitions, middleware enforcement, and admin key management flow.
|
||||
|
||||
## Files Changed
|
||||
|
||||
- `/Users/delete/projects/update_server/internal/app/app.go`
|
||||
- `/Users/delete/projects/update_server/internal/db/models.go`
|
||||
- `/Users/delete/projects/update_server/internal/db/apikeys.go`
|
||||
- `/Users/delete/projects/update_server/internal/apikeys/context.go`
|
||||
- `/Users/delete/projects/update_server/internal/apikeys/service.go`
|
||||
- `/Users/delete/projects/update_server/internal/apikeys/service_test.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/router.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/handlers.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/view_data.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/admin_api_keys.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/api_key_middleware.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/api_key_middleware_test.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/api_keys_integration_test.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/auth_integration_test.go`
|
||||
- `/Users/delete/projects/update_server/web/templates/layouts/base.gohtml`
|
||||
- `/Users/delete/projects/update_server/web/templates/pages/api_keys.gohtml`
|
||||
- `/Users/delete/projects/update_server/web/templates/pages/api_key_form.gohtml`
|
||||
- `/Users/delete/projects/update_server/web/static/app.css`
|
||||
- `/Users/delete/projects/update_server/docs/agents/handoffs/05-api-keys.md`
|
||||
|
||||
## Database Changes
|
||||
|
||||
- no new migrations were required because the existing `api_keys`, `api_key_project_access`, and `api_key_tag_access` tables already existed from Agent 02 and the scope guard triggers already existed from migration `0003_api_key_scope_guards.sql`;
|
||||
- the new repository code now actively uses those tables and trigger rules for key lifecycle, project allow or deny lists, and tag allow or deny lists;
|
||||
- API keys are stored with a short visible `key_prefix` and a hashed `key_hash`; the raw key is never persisted.
|
||||
|
||||
## API Or Route Changes
|
||||
|
||||
- added protected admin routes:
|
||||
- `GET /admin/api-keys`
|
||||
- `GET /admin/api-keys/new`
|
||||
- `POST /admin/api-keys`
|
||||
- `GET /admin/api-keys/{apiKeyID}`
|
||||
- `POST /admin/api-keys/{apiKeyID}`
|
||||
- `POST /admin/api-keys/{apiKeyID}/activate`
|
||||
- added reusable middleware helpers for future client API routes:
|
||||
- `requireAPIKey`
|
||||
- `requireAPIKeyPermission`
|
||||
- `requireAPIKeyProjectAccess`
|
||||
- kept `/api/v1` client endpoints themselves out of scope for this stage so Agent 06 can wire them onto the new middleware and access-resolution layer.
|
||||
|
||||
## Commands And Tests Run
|
||||
|
||||
- `gofmt -w internal/app/app.go internal/db/models.go internal/db/apikeys.go internal/apikeys/context.go internal/apikeys/service.go internal/http/router.go internal/http/handlers.go internal/http/view_data.go internal/http/admin_api_keys.go internal/http/api_key_middleware.go internal/http/auth_integration_test.go internal/apikeys/service_test.go internal/http/api_key_middleware_test.go internal/http/api_keys_integration_test.go` - passed;
|
||||
- `GOCACHE=/tmp/go-build-agent05-2 GOMODCACHE=/tmp/go-mod-agent05-2 go test ./...` - passed after downloading dependencies with approval;
|
||||
- `GOCACHE=/tmp/go-build-agent05-build GOMODCACHE=/tmp/go-mod-agent05-2 go build -o /tmp/update-server-agent05 ./cmd/server` - passed;
|
||||
- `GOCACHE=/tmp/go-build-agent05-build2 GOMODCACHE=/tmp/go-mod-agent05-2 go build -o /tmp/update-migrate-agent05 ./cmd/migrate` - passed.
|
||||
|
||||
## Known Limitations
|
||||
|
||||
- CSRF protection is still not implemented for admin forms, including the new API key creation, update, and revoke or activate actions;
|
||||
- the admin API key UI is intentionally minimal and functional rather than polished;
|
||||
- the one-time reveal happens on the direct POST response instead of a PRG redirect because the raw key must not be placed into query strings or persistent storage;
|
||||
- no live client `/api/v1` endpoints use the new middleware yet; the groundwork is ready but the actual project list, latest-release, and download endpoints remain for Agent 06;
|
||||
- expiration input currently accepts either empty, `YYYY-MM-DD`, or full RFC3339 UTC text rather than a more polished timezone-aware widget.
|
||||
|
||||
## Recommended Next Step
|
||||
|
||||
Agent 06 should wire the new `requireAPIKey`, `requireAPIKeyPermission`, and `requireAPIKeyProjectAccess` middleware into the client `/api/v1` endpoints for accessible-project listing, latest release lookup, and authenticated artifact download.
|
||||
|
||||
## Notes For Validator
|
||||
|
||||
- verify that only `key_prefix` and `key_hash` are stored in SQLite and that the raw key appears only in the immediate creation response;
|
||||
- verify that revoked or expired keys are rejected by `requireAPIKey` with `401` and that missing permissions or blocked project scope return `403`;
|
||||
- verify effective access resolution across all five scope modes, especially that archived projects do not appear in accessible-project results;
|
||||
- verify scope transitions clear the incompatible access rows so the existing migration guards continue to succeed;
|
||||
- verify the admin detail page preview matches the effective active project set for the key.
|
||||
100
docs/agents/handoffs/06-client-api-ui.md
Normal file
100
docs/agents/handoffs/06-client-api-ui.md
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
# Agent
|
||||
|
||||
Name: Agent 06 - Client API And Admin UI
|
||||
|
||||
Stage: Client API And Admin UI
|
||||
|
||||
Date: 2026-04-15
|
||||
|
||||
## Scope
|
||||
|
||||
Implemented the usable end-to-end product flow for admins and client applications on top of the existing project, release, and API key work from Agents 04 and 05.
|
||||
|
||||
Completed in this stage:
|
||||
|
||||
- added bearer-authenticated client endpoints under `/api/v1` for:
|
||||
- listing accessible active projects;
|
||||
- looking up the latest active release for an accessible project;
|
||||
- fetching release metadata by release ID for an accessible project;
|
||||
- downloading private release artifacts by release ID after auth, permission, and scope checks;
|
||||
- reused the existing API key middleware and scope-evaluation service so disabled or expired keys return `401`, missing download permission returns `403`, and inaccessible projects or releases return `404` to avoid leaking unauthorized resources;
|
||||
- added project slug lookup and latest-active-release repository queries so client handlers can resolve project-scoped metadata cleanly from persisted release rows;
|
||||
- added a safe artifact-open path on top of the existing private local storage so downloads stream from the artifact root instead of exposing raw filesystem paths or static URLs;
|
||||
- updated the API index and the home or dashboard copy so the live client API is discoverable instead of still looking like a placeholder;
|
||||
- added small admin UI improvements on project detail and API key detail pages that show the client API paths and a bearer-auth quick-start example after an admin uploads a release or creates a key;
|
||||
- added integration coverage for the client flow, including auth failures, scope enforcement, latest-release selection, release metadata lookup, and authorized or unauthorized download behavior.
|
||||
|
||||
## Files Changed
|
||||
|
||||
- `/Users/delete/projects/update_server/internal/db/projects.go`
|
||||
- `/Users/delete/projects/update_server/internal/db/releases.go`
|
||||
- `/Users/delete/projects/update_server/internal/storage/local.go`
|
||||
- `/Users/delete/projects/update_server/internal/releases/service.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/router.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/handlers.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/admin_common.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/admin_projects.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/view_data.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/client_api.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/client_api_integration_test.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/api_keys_integration_test.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/projects_integration_test.go`
|
||||
- `/Users/delete/projects/update_server/web/templates/pages/project_detail.gohtml`
|
||||
- `/Users/delete/projects/update_server/web/templates/pages/api_key_form.gohtml`
|
||||
- `/Users/delete/projects/update_server/web/templates/pages/api_keys.gohtml`
|
||||
- `/Users/delete/projects/update_server/web/static/app.css`
|
||||
- `/Users/delete/projects/update_server/docs/agents/handoffs/06-client-api-ui.md`
|
||||
|
||||
## Database Changes
|
||||
|
||||
- no new migrations or schema changes were required;
|
||||
- added repository queries against the existing `projects` and `releases` tables:
|
||||
- project lookup by slug;
|
||||
- latest active release lookup ordered by persisted `created_at DESC, id DESC`;
|
||||
- continued using the existing API key scope tables and scope modes without redesign.
|
||||
|
||||
## API Or Route Changes
|
||||
|
||||
- kept `GET /api/v1` public and upgraded it from a placeholder to a real client API index;
|
||||
- added protected client routes behind bearer API key auth plus `can_download` permission:
|
||||
- `GET /api/v1/projects`
|
||||
- `GET /api/v1/projects/{projectSlug}/releases/latest`
|
||||
- `GET /api/v1/releases/{releaseID}`
|
||||
- `GET /api/v1/releases/{releaseID}/download`
|
||||
- resource access behavior for client routes:
|
||||
- missing, invalid, disabled, or expired API key -> `401`
|
||||
- authenticated key without download permission -> `403`
|
||||
- inaccessible or archived project or release -> `404`
|
||||
- admin UI additions:
|
||||
- project detail page now shows the relevant client API paths for that project and latest release;
|
||||
- API key detail page now shows a bearer-auth quick-start example plus the accessible project metadata paths.
|
||||
|
||||
## Commands And Tests Run
|
||||
|
||||
- `gofmt -w internal/db/projects.go internal/db/releases.go internal/storage/local.go internal/http/view_data.go internal/http/admin_common.go internal/http/admin_projects.go internal/http/router.go internal/http/handlers.go internal/http/client_api.go internal/releases/service.go internal/http/api_keys_integration_test.go internal/http/projects_integration_test.go internal/http/client_api_integration_test.go` - passed
|
||||
- `GOCACHE=/tmp/go-build-agent06-http GOMODCACHE=/tmp/go-mod-agent06-http go test ./internal/http ./internal/releases ./internal/db ./internal/apikeys` - initially failed in sandbox because module downloads could not resolve DNS, then passed after rerunning with approval
|
||||
- `GOCACHE=/tmp/go-build-agent06-all GOMODCACHE=/tmp/go-mod-agent06-http go test ./...` - passed
|
||||
- `GOCACHE=/tmp/go-build-agent06-build GOMODCACHE=/tmp/go-mod-agent06-http go build -o /tmp/update-server-agent06 ./cmd/server` - passed
|
||||
- `GOCACHE=/tmp/go-build-agent06-migrate GOMODCACHE=/tmp/go-mod-agent06-http go build -o /tmp/update-migrate-agent06 ./cmd/migrate` - passed
|
||||
|
||||
## Known Limitations
|
||||
|
||||
- “Latest” currently means the newest active persisted release by `created_at` and `id`, not semantic-version comparison;
|
||||
- the optional client query parameters mentioned in the product spec (`current_version`, `channel`, `platform`, `arch`) are still not implemented;
|
||||
- the client API does not yet expose full per-project release listing; this stage focused on the required list, latest-metadata, metadata-by-ID, and download flow;
|
||||
- the admin quick-start example can show the real raw key only on the one-time create response; later detail views intentionally fall back to a placeholder token;
|
||||
- broader hardening work such as CSRF completion, rate limiting, security headers, audit logging polish, and deployment proxy setup remains out of scope for this stage.
|
||||
|
||||
## Recommended Next Step
|
||||
|
||||
Run the validation pass for Agent 06, then move to Agent 07 to implement the planned hardening and deployment-focused follow-up: CSRF, security headers, rate limiting, audit/logging polish, and deployment readiness around the now-working end-to-end product flow.
|
||||
|
||||
## Notes For Validator
|
||||
|
||||
- verify that client routes require `Authorization: Bearer <api_key>` and that disabled or expired keys are rejected with `401`;
|
||||
- verify that client routes require `can_download` and return `403` when the key authenticates but lacks download permission;
|
||||
- verify that unauthorized, archived, or out-of-scope projects and releases return `404` from metadata and download paths rather than leaking through a `403`;
|
||||
- verify that `GET /api/v1/projects` returns only active projects allowed by the key’s scope evaluation;
|
||||
- verify that the latest-release endpoint selects the newest active persisted release row for the project;
|
||||
- verify that the download endpoint streams bytes from private artifact storage and does not expose static URLs or raw filesystem paths;
|
||||
- verify that the project detail and API key detail admin pages visibly expose the new client API quick-start information.
|
||||
134
docs/agents/handoffs/07-security-deploy.md
Normal file
134
docs/agents/handoffs/07-security-deploy.md
Normal file
|
|
@ -0,0 +1,134 @@
|
|||
# Agent
|
||||
|
||||
Name: Agent 07 - Security And Deployment Hardening
|
||||
|
||||
Stage: Security And Deployment Hardening
|
||||
|
||||
Date: 2026-04-15
|
||||
|
||||
## Scope
|
||||
|
||||
Hardened the existing Go/chi/SQLite application for internet-facing deployment without changing the product model or admin/client flow.
|
||||
|
||||
Completed in this stage:
|
||||
|
||||
- added stricter HTTP server defaults:
|
||||
- `ReadHeaderTimeout`
|
||||
- `MaxHeaderBytes`
|
||||
- higher default read/write/idle timeouts suitable for uploads and authenticated downloads
|
||||
- added global security headers and route-specific cache controls:
|
||||
- `Content-Security-Policy`
|
||||
- `X-Frame-Options`
|
||||
- `X-Content-Type-Options`
|
||||
- `Referrer-Policy`
|
||||
- `Permissions-Policy`
|
||||
- `Cross-Origin-Opener-Policy`
|
||||
- `Cross-Origin-Resource-Policy`
|
||||
- `Strict-Transport-Security` when `APP_BASE_URL` is `https`
|
||||
- `Cache-Control: no-store` on admin and protected client API responses
|
||||
- `Vary: Cookie` or `Vary: Authorization` on the appropriate routes
|
||||
- added trusted-proxy awareness so forwarded headers are only trusted when `TRUST_PROXY_HEADERS=true`;
|
||||
- added in-memory rate limiting for:
|
||||
- `POST /admin/login`
|
||||
- protected client API routes under `/api/v1`
|
||||
- added CSRF protection for all admin POST flows, including login, logout, project/tag/API key forms, tag attach or detach, archive or restore, and multipart release upload;
|
||||
- rotated or cleared the admin CSRF cookie on login and logout, and scoped both session and CSRF cookies to `/admin`;
|
||||
- tightened local data directory permissions for SQLite and data storage;
|
||||
- added regression coverage for CSRF rejection, hardened cookie defaults, security headers, and both rate-limited route groups;
|
||||
- added first-pass deployment assets:
|
||||
- multi-stage `Dockerfile`
|
||||
- hardened `docker-compose.yml`
|
||||
- Caddy example
|
||||
- Nginx example
|
||||
- env example
|
||||
- deployment, Proxmox, backup, and restore notes.
|
||||
|
||||
## Files Changed
|
||||
|
||||
- `/Users/delete/projects/update_server/internal/config/config.go`
|
||||
- `/Users/delete/projects/update_server/internal/app/app.go`
|
||||
- `/Users/delete/projects/update_server/internal/db/open.go`
|
||||
- `/Users/delete/projects/update_server/internal/auth/service.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/router.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/security.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/rate_limit.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/csrf.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/auth_handlers.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/admin_common.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/admin_api_keys.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/view_data.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/auth_integration_test.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/projects_integration_test.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/api_keys_integration_test.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/security_integration_test.go`
|
||||
- `/Users/delete/projects/update_server/web/templates/layouts/base.gohtml`
|
||||
- `/Users/delete/projects/update_server/web/templates/pages/login.gohtml`
|
||||
- `/Users/delete/projects/update_server/web/templates/pages/project_form.gohtml`
|
||||
- `/Users/delete/projects/update_server/web/templates/pages/project_detail.gohtml`
|
||||
- `/Users/delete/projects/update_server/web/templates/pages/tag_form.gohtml`
|
||||
- `/Users/delete/projects/update_server/web/templates/pages/api_key_form.gohtml`
|
||||
- `/Users/delete/projects/update_server/web/templates/partials/csrf_field.gohtml`
|
||||
- `/Users/delete/projects/update_server/.dockerignore`
|
||||
- `/Users/delete/projects/update_server/Dockerfile`
|
||||
- `/Users/delete/projects/update_server/docker-compose.yml`
|
||||
- `/Users/delete/projects/update_server/deploy/Caddyfile.example`
|
||||
- `/Users/delete/projects/update_server/deploy/nginx.update-server.conf.example`
|
||||
- `/Users/delete/projects/update_server/deploy/update-server.env.example`
|
||||
- `/Users/delete/projects/update_server/docs/DEPLOYMENT.md`
|
||||
- `/Users/delete/projects/update_server/docs/agents/handoffs/07-security-deploy.md`
|
||||
|
||||
## Database Changes
|
||||
|
||||
- no migrations or schema changes were required;
|
||||
- SQLite remains the production database;
|
||||
- deployment notes now explicitly call out WAL-mode backup and restore handling for:
|
||||
- `db.sqlite`
|
||||
- `db.sqlite-wal`
|
||||
- `db.sqlite-shm`
|
||||
- `artifacts/`.
|
||||
|
||||
## API Or Route Changes
|
||||
|
||||
- no new product endpoints were added;
|
||||
- middleware behavior changed for existing routes:
|
||||
- all `/admin` responses now emit hardened headers and `no-store` caching rules;
|
||||
- all `/admin` POST routes now require a valid CSRF token;
|
||||
- `POST /admin/login` is rate limited by client IP;
|
||||
- protected `/api/v1` routes now emit hardened headers and `no-store` caching rules;
|
||||
- protected `/api/v1` routes are rate limited by client IP before API-key auth;
|
||||
- session cookies are now scoped to `/admin` and retain `HttpOnly`, `SameSite=Lax`, and conditional `Secure`;
|
||||
- CSRF cookies are now scoped to `/admin` and use `HttpOnly`, `SameSite=Strict`, and conditional `Secure`.
|
||||
|
||||
## Commands And Tests Run
|
||||
|
||||
- `gofmt -w internal/config/config.go internal/app/app.go internal/db/open.go internal/auth/service.go internal/http/router.go internal/http/security.go internal/http/rate_limit.go internal/http/csrf.go internal/http/auth_handlers.go internal/http/view_data.go internal/http/admin_common.go internal/http/admin_api_keys.go internal/http/auth_integration_test.go internal/http/projects_integration_test.go internal/http/api_keys_integration_test.go internal/http/security_integration_test.go` - passed
|
||||
- `go test ./internal/http` - passed
|
||||
- `go test ./...` - passed
|
||||
- `go build ./cmd/server` - passed
|
||||
- `go build ./cmd/migrate` - passed
|
||||
- `docker compose config` - could not run in this environment because `docker` is not installed
|
||||
|
||||
## Known Limitations
|
||||
|
||||
- rate limiting is in-memory and per-process, so counters reset on restart and are not shared across multiple app instances;
|
||||
- Docker and reverse-proxy examples were added and reviewed statically, but they were not live-validated here because Docker is unavailable in this workspace;
|
||||
- `Strict-Transport-Security` only appears when `APP_BASE_URL` is configured with `https`, which is the intended production setup behind TLS termination;
|
||||
- the proxy still must be configured correctly to keep the app private and to strip or control forwarded headers before `TRUST_PROXY_HEADERS=true` is safe.
|
||||
|
||||
## Recommended Next Step
|
||||
|
||||
Run the Agent 07 validation pass, with special attention to:
|
||||
|
||||
- CSRF enforcement on every admin POST flow, including multipart upload;
|
||||
- security headers and private-cache headers on admin and protected client API responses;
|
||||
- login and client API rate limiting behavior;
|
||||
- cookie flags and `/admin` cookie scoping;
|
||||
- deployment docs and example proxy/container files on a host that has Docker and a reverse proxy available.
|
||||
|
||||
## Notes For Validator
|
||||
|
||||
- verify that a missing or invalid admin CSRF token returns `403` and that the normal admin flows still succeed when the token is present;
|
||||
- verify that session cookies are only scoped to `/admin` and that secure-cookie behavior follows the configured `APP_BASE_URL` scheme;
|
||||
- verify that `TRUST_PROXY_HEADERS=false` leaves client IP handling on the socket remote address;
|
||||
- verify that protected `/api/v1` responses include `Cache-Control: no-store`, `Vary: Authorization`, and the shared security headers;
|
||||
- if possible, validate `docker compose up --build` plus one reverse-proxy example on a real machine, since that could not be executed in this environment.
|
||||
13
docs/agents/handoffs/README.md
Normal file
13
docs/agents/handoffs/README.md
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
# Handoffs Directory
|
||||
|
||||
Save one handoff markdown file here after every implementation stage.
|
||||
|
||||
Naming convention:
|
||||
|
||||
- `01-foundation.md`
|
||||
- `02-database.md`
|
||||
- `03-auth.md`
|
||||
- `04-projects-releases.md`
|
||||
- `05-api-keys.md`
|
||||
- `06-client-api-ui.md`
|
||||
- `07-security-deploy.md`
|
||||
45
docs/agents/validation/01-foundation-validation.md
Normal file
45
docs/agents/validation/01-foundation-validation.md
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
# Validation Report Template
|
||||
|
||||
## Validator
|
||||
|
||||
Name: Codex Validation Agent
|
||||
|
||||
Stage Reviewed: Agent 01 - Foundation
|
||||
|
||||
Date: 2026-04-13
|
||||
|
||||
## Reviewed Inputs
|
||||
|
||||
- `/Users/delete/projects/update_server/docs/agents/WORKFLOW.md`
|
||||
- `/Users/delete/projects/update_server/PRODUCT_SPEC.md`
|
||||
- `/Users/delete/projects/update_server/IMPLEMENTATION_PLAN.md`
|
||||
- `/Users/delete/projects/update_server/DEVELOPMENT_WORKFLOW.md`
|
||||
- `/Users/delete/projects/update_server/docs/agents/OPERATOR_QUICKSTART_RU.md`
|
||||
- `/Users/delete/projects/update_server/docs/agents/handoffs/01-foundation.md`
|
||||
- implementation files under `cmd/server`, `internal/app`, `internal/config`, `internal/http`, `web/templates`, `web/static`, and `migrations`
|
||||
- `go test ./...` -> passed
|
||||
- `go build -o /tmp/update-server ./cmd/server` -> passed
|
||||
- live smoke checks against `127.0.0.1:18080`:
|
||||
- `GET /healthz` -> `200 OK`
|
||||
- `GET /` -> `200 OK`
|
||||
- `GET /admin` -> `200 OK`
|
||||
- `GET /api/v1` -> `200 OK`
|
||||
|
||||
## Findings
|
||||
|
||||
No blocking findings.
|
||||
|
||||
The stage stays within the agreed scope, the server boots successfully, the route scaffolding is present, and the template/static foundation is ready for Agent 02.
|
||||
|
||||
## Required Fixes
|
||||
|
||||
None.
|
||||
|
||||
## Optional Improvements
|
||||
|
||||
- Add a small smoke-test suite for the foundation routes in a later stage once the HTTP surface becomes more stable.
|
||||
- Initialize a git repository if you want future validators to compare diffs with `git status` and `git diff`.
|
||||
|
||||
## Status
|
||||
|
||||
`APPROVED`
|
||||
54
docs/agents/validation/02-database-validation.md
Normal file
54
docs/agents/validation/02-database-validation.md
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
# Validation Report Template
|
||||
|
||||
## Validator
|
||||
|
||||
Name: Codex Validation Agent
|
||||
|
||||
Stage Reviewed: Agent 02 - Database And Migrations
|
||||
|
||||
Date: 2026-04-14
|
||||
|
||||
## Reviewed Inputs
|
||||
|
||||
- `/Users/delete/projects/update_server/docs/agents/WORKFLOW.md`
|
||||
- `/Users/delete/projects/update_server/PRODUCT_SPEC.md`
|
||||
- `/Users/delete/projects/update_server/IMPLEMENTATION_PLAN.md`
|
||||
- `/Users/delete/projects/update_server/DEVELOPMENT_WORKFLOW.md`
|
||||
- `/Users/delete/projects/update_server/docs/agents/OPERATOR_QUICKSTART_RU.md`
|
||||
- `/Users/delete/projects/update_server/docs/agents/handoffs/02-database.md`
|
||||
- previous validation report: `/Users/delete/projects/update_server/docs/agents/validation/01-foundation-validation.md`
|
||||
- implementation files under `cmd/migrate`, `internal/db`, `internal/config`, `internal/app`, `internal/http`, and `migrations`
|
||||
- `.gitignore` and `Justfile`
|
||||
- `GOCACHE=/tmp/go-build-agent02 GOMODCACHE=/tmp/go-mod-agent02 go test ./...` -> passed
|
||||
- `GOCACHE=/tmp/go-build-agent02 GOMODCACHE=/tmp/go-mod-agent02 go build -o /tmp/update-server-agent02-bin ./cmd/server` -> passed
|
||||
- `GOCACHE=/tmp/go-build-agent02 GOMODCACHE=/tmp/go-mod-agent02 go build -o /tmp/update-migrate-agent02-bin ./cmd/migrate` -> passed
|
||||
- `DATA_DIR=/tmp/update-server-agent02 APP_BASE_URL=http://127.0.0.1:18080 /tmp/update-migrate` -> passed
|
||||
- live smoke checks against `127.0.0.1:18081` after starting `/tmp/update-server-agent02-bin` with a fresh `DATA_DIR`:
|
||||
- `GET /healthz` -> `200 OK` with `"database":"ok"`
|
||||
- `GET /` -> `200 OK`
|
||||
- `GET /api/v1` -> `200 OK`
|
||||
|
||||
## Findings
|
||||
|
||||
No blocking findings.
|
||||
|
||||
The stage satisfies the agreed scope:
|
||||
|
||||
- the SQLite schema covers the required tables;
|
||||
- migrations are present and executable;
|
||||
- migration checksum tracking is implemented and tested;
|
||||
- the server startup path opens SQLite and auto-applies migrations;
|
||||
- the health endpoint now reflects database readiness.
|
||||
|
||||
## Required Fixes
|
||||
|
||||
None.
|
||||
|
||||
## Optional Improvements
|
||||
|
||||
- Add explicit tests for `scope_mode` transition guard behavior, not just incompatible access-row insertion.
|
||||
- Update the small home-page eyebrow copy from `Foundation Stage` to something database-specific for consistency.
|
||||
|
||||
## Status
|
||||
|
||||
`APPROVED`
|
||||
57
docs/agents/validation/03-auth-validation.md
Normal file
57
docs/agents/validation/03-auth-validation.md
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
# Validation Report Template
|
||||
|
||||
## Validator
|
||||
|
||||
Name: Codex Validation Agent
|
||||
|
||||
Stage Reviewed: Agent 03 - Authentication And Admin Sessions
|
||||
|
||||
Date: 2026-04-14
|
||||
|
||||
## Reviewed Inputs
|
||||
|
||||
- `/Users/delete/projects/update_server/docs/agents/WORKFLOW.md`
|
||||
- `/Users/delete/projects/update_server/PRODUCT_SPEC.md`
|
||||
- `/Users/delete/projects/update_server/IMPLEMENTATION_PLAN.md`
|
||||
- `/Users/delete/projects/update_server/DEVELOPMENT_WORKFLOW.md`
|
||||
- `/Users/delete/projects/update_server/docs/agents/OPERATOR_QUICKSTART_RU.md`
|
||||
- `/Users/delete/projects/update_server/docs/agents/handoffs/03-auth.md`
|
||||
- previous validation report: `/Users/delete/projects/update_server/docs/agents/validation/02-database-validation.md`
|
||||
- implementation files under `internal/auth`, `internal/db`, `internal/http`, `internal/app`, `internal/config`, and `web/templates`
|
||||
- `GOCACHE=/tmp/go-build-auth-validate GOMODCACHE=/tmp/go-mod-auth-validate go test ./...` -> passed
|
||||
- `GOCACHE=/tmp/go-build-auth-validate GOMODCACHE=/tmp/go-mod-auth-validate go build -o /tmp/update-server-auth-validate ./cmd/server` -> passed
|
||||
- `GOCACHE=/tmp/go-build-auth-validate GOMODCACHE=/tmp/go-mod-auth-validate go build -o /tmp/update-migrate-auth-validate ./cmd/migrate` -> passed
|
||||
- live smoke checks against `127.0.0.1:18082` after starting `/tmp/update-server-auth-validate` with fresh bootstrap credentials and a fresh `DATA_DIR`:
|
||||
- `GET /admin` -> `303 See Other` to `/admin/login`
|
||||
- `GET /admin/login` -> `200 OK`
|
||||
- `POST /admin/login` -> `303 See Other` with session cookie
|
||||
- `GET /admin` with valid cookie -> `200 OK`
|
||||
- SQLite inspection confirmed `sessions.token_hash` stores the SHA-256 of the cookie token, not the raw token
|
||||
- `POST /admin/logout` -> `303 See Other`
|
||||
- `GET /admin` with the old cookie after logout -> `303 See Other` to `/admin/login`
|
||||
- SQLite inspection confirmed the session row was invalidated
|
||||
|
||||
## Findings
|
||||
|
||||
No blocking findings.
|
||||
|
||||
The stage satisfies the agreed scope:
|
||||
|
||||
- bootstrap admin creation is wired from environment configuration;
|
||||
- passwords are hashed with bcrypt;
|
||||
- session tokens are generated securely and stored hashed in SQLite;
|
||||
- the `/admin` route group is protected by session middleware and role checks;
|
||||
- login and logout behavior works in live validation, including old-cookie rejection after logout.
|
||||
|
||||
## Required Fixes
|
||||
|
||||
None.
|
||||
|
||||
## Optional Improvements
|
||||
|
||||
- Decide explicitly in a later stage whether the login endpoint should stay generic for any active user session or reject non-admin roles up front for the current admin-only UI.
|
||||
- Add CSRF protection when the security-hardening stage begins, especially for `POST /admin/logout` and future admin forms.
|
||||
|
||||
## Status
|
||||
|
||||
`APPROVED`
|
||||
62
docs/agents/validation/04-projects-releases-validation.md
Normal file
62
docs/agents/validation/04-projects-releases-validation.md
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
# Validation Report Template
|
||||
|
||||
## Validator
|
||||
|
||||
Name: Codex Validation Agent
|
||||
|
||||
Stage Reviewed: Agent 04 - Projects, Tags, And Releases
|
||||
|
||||
Date: 2026-04-14
|
||||
|
||||
## Reviewed Inputs
|
||||
|
||||
- `/Users/delete/projects/update_server/docs/agents/WORKFLOW.md`
|
||||
- `/Users/delete/projects/update_server/PRODUCT_SPEC.md`
|
||||
- `/Users/delete/projects/update_server/IMPLEMENTATION_PLAN.md`
|
||||
- `/Users/delete/projects/update_server/DEVELOPMENT_WORKFLOW.md`
|
||||
- `/Users/delete/projects/update_server/docs/agents/OPERATOR_QUICKSTART_RU.md`
|
||||
- `/Users/delete/projects/update_server/docs/agents/handoffs/04-projects-releases.md`
|
||||
- previous validation report: `/Users/delete/projects/update_server/docs/agents/validation/03-auth-validation.md`
|
||||
- implementation files under `internal/db`, `internal/http`, `internal/releases`, `internal/storage`, `internal/slug`, `internal/app`, `internal/config`, and `web/templates`
|
||||
- `GOCACHE=/tmp/go-build-agent04-validate GOMODCACHE=/tmp/go-mod-agent04-validate go test ./...` -> passed
|
||||
- `GOCACHE=/tmp/go-build-agent04-validate GOMODCACHE=/tmp/go-mod-agent04-validate go build -o /tmp/update-server-agent04-validate ./cmd/server` -> passed
|
||||
- `GOCACHE=/tmp/go-build-agent04-validate GOMODCACHE=/tmp/go-mod-agent04-validate go build -o /tmp/update-migrate-agent04-validate ./cmd/migrate` -> passed
|
||||
- live smoke checks against `127.0.0.1:18083` after starting `/tmp/update-server-agent04-validate` with fresh bootstrap credentials and a fresh `DATA_DIR`:
|
||||
- `GET /admin/projects` without session -> `303 See Other` to `/admin/login?next=%2Fadmin%2Fprojects`
|
||||
- `POST /admin/login` -> `303 See Other` with session cookie
|
||||
- `GET /admin/projects` with session -> `200 OK`
|
||||
- `POST /admin/projects` -> project created
|
||||
- `POST /admin/tags` -> tag created
|
||||
- `POST /admin/projects/1/tags` -> tag attached
|
||||
- `POST /admin/projects/1/releases` with multipart file upload -> `303 See Other`
|
||||
- SQLite inspection confirmed project, tag, project-tag link, and release metadata rows
|
||||
- filesystem inspection confirmed artifact saved under `DATA_DIR/artifacts/...`, outside `web/static`
|
||||
- checksum of stored artifact matched `releases.checksum_sha256`
|
||||
- `POST /admin/tags/1/delete` while tag was still attached -> redirected with `tag-in-use`
|
||||
- `POST /admin/projects/1/archive` -> project became archived in SQLite and UI
|
||||
|
||||
## Findings
|
||||
|
||||
No blocking findings.
|
||||
|
||||
The stage satisfies the agreed scope:
|
||||
|
||||
- protected admin CRUD flows exist for projects and tags;
|
||||
- project-tag assignment works;
|
||||
- release uploads are stored under the private artifact directory;
|
||||
- release metadata is persisted with sanitized filename, checksum, size, content type, storage path, and uploader linkage;
|
||||
- archive and tag-in-use protection behaviors work in live validation.
|
||||
|
||||
## Required Fixes
|
||||
|
||||
None.
|
||||
|
||||
## Optional Improvements
|
||||
|
||||
- Add an explicit unit or integration test for rejecting uploads that exceed `MAX_UPLOAD_BYTES`.
|
||||
- Consider surfacing a success flash on the projects list page for newly created items instead of only redirecting to detail pages.
|
||||
- Add release disable/delete flows in a later stage when the product needs release lifecycle management beyond upload.
|
||||
|
||||
## Status
|
||||
|
||||
`APPROVED`
|
||||
64
docs/agents/validation/05-api-keys-validation.md
Normal file
64
docs/agents/validation/05-api-keys-validation.md
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
# Validation Report Template
|
||||
|
||||
## Validator
|
||||
|
||||
Name: Codex Validation Agent
|
||||
|
||||
Stage Reviewed: Agent 05 - API Keys And Access Control
|
||||
|
||||
Date: 2026-04-14
|
||||
|
||||
## Reviewed Inputs
|
||||
|
||||
- `/Users/delete/projects/update_server/docs/agents/WORKFLOW.md`
|
||||
- `/Users/delete/projects/update_server/PRODUCT_SPEC.md`
|
||||
- `/Users/delete/projects/update_server/IMPLEMENTATION_PLAN.md`
|
||||
- `/Users/delete/projects/update_server/DEVELOPMENT_WORKFLOW.md`
|
||||
- `/Users/delete/projects/update_server/docs/agents/OPERATOR_QUICKSTART_RU.md`
|
||||
- `/Users/delete/projects/update_server/docs/agents/handoffs/05-api-keys.md`
|
||||
- `/Users/delete/projects/update_server/docs/agents/handoffs/05-api-keys-fix.md`
|
||||
- previous stage validation report: `/Users/delete/projects/update_server/docs/agents/validation/04-projects-releases-validation.md`
|
||||
- implementation files under `internal/apikeys`, `internal/db`, `internal/http`, `internal/app`, and `web/templates`
|
||||
- `GOCACHE=/tmp/go-build-agent05-revalidate GOMODCACHE=/tmp/go-mod-agent05-revalidate go test ./...` -> passed
|
||||
- `GOCACHE=/tmp/go-build-agent05-rebuild GOMODCACHE=/tmp/go-mod-agent05-rebuild go build -o /tmp/update-server-agent05-revalidate ./cmd/server` -> passed
|
||||
- `GOCACHE=/tmp/go-build-agent05-remigrate GOMODCACHE=/tmp/go-mod-agent05-remigrate go build -o /tmp/update-migrate-agent05-revalidate ./cmd/migrate` -> passed
|
||||
- live smoke checks against `127.0.0.1:18085` after starting `/tmp/update-server-agent05-revalidate` with a fresh `DATA_DIR`:
|
||||
- `GET /healthz` -> `200 OK`
|
||||
- `GET /admin/api-keys` without session -> `303 See Other` to `/admin/login?next=%2Fadmin%2Fapi-keys`
|
||||
- `POST /admin/login` -> `303 See Other` with session cookie
|
||||
- `POST /admin/projects` -> project created
|
||||
- `POST /admin/tags` -> tag created
|
||||
- `POST /admin/projects/1/tags` -> tag attached
|
||||
- `POST /admin/api-keys` -> `200 OK` with `Cache-Control: no-store, private, max-age=0`, `Pragma: no-cache`, and `Expires: 0`
|
||||
- the create response showed the raw key once and also showed the persisted saved values immediately: name, description, selected scope mode, permissions, selected tag rule, and effective access preview
|
||||
- `GET /admin/api-keys/1` after creation -> `200 OK`, raw key no longer present in HTML
|
||||
- SQLite inspection confirmed only `key_hash` was stored and confirmed the persisted tag scope row in `api_key_tag_access`
|
||||
|
||||
## Findings
|
||||
|
||||
No blocking findings.
|
||||
|
||||
The previously reported issues are fixed:
|
||||
|
||||
- the secret-bearing creation response is explicitly marked non-cacheable;
|
||||
- the immediate post-create detail page is hydrated from persisted data while still showing the raw key only on that one response.
|
||||
|
||||
The stage now satisfies the agreed scope:
|
||||
|
||||
- API keys are generated securely and stored hashed;
|
||||
- admin UI supports create, update, and revoke flows;
|
||||
- allow-list and deny-list groundwork is in place for both projects and tags;
|
||||
- middleware and scope evaluation are covered by tests and the create-flow regressions are fixed.
|
||||
|
||||
## Required Fixes
|
||||
|
||||
None.
|
||||
|
||||
## Optional Improvements
|
||||
|
||||
- Consider a future POST-Redirect-GET plus short-lived flash-secret design if you want to avoid browser refresh resubmitting the create form while still keeping the raw key out of persistent storage.
|
||||
- Later client API validation should explicitly exercise disabled and expired keys through the public `/api/v1` endpoints once Agent 06 wires them in.
|
||||
|
||||
## Status
|
||||
|
||||
`APPROVED`
|
||||
77
docs/agents/validation/06-client-api-ui-validation.md
Normal file
77
docs/agents/validation/06-client-api-ui-validation.md
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
# Validation Report Template
|
||||
|
||||
## Validator
|
||||
|
||||
Name: Codex Validation Agent
|
||||
|
||||
Stage Reviewed: Agent 06 - Client API And Admin UI
|
||||
|
||||
Date: 2026-04-15
|
||||
|
||||
## Reviewed Inputs
|
||||
|
||||
- `/Users/delete/projects/update_server/docs/agents/WORKFLOW.md`
|
||||
- `/Users/delete/projects/update_server/PRODUCT_SPEC.md`
|
||||
- `/Users/delete/projects/update_server/IMPLEMENTATION_PLAN.md`
|
||||
- `/Users/delete/projects/update_server/DEVELOPMENT_WORKFLOW.md`
|
||||
- `/Users/delete/projects/update_server/docs/agents/OPERATOR_QUICKSTART_RU.md`
|
||||
- `/Users/delete/projects/update_server/docs/agents/handoffs/06-client-api-ui.md`
|
||||
- previous stage validation report: `/Users/delete/projects/update_server/docs/agents/validation/05-api-keys-validation.md`
|
||||
- implementation files under `internal/http`, `internal/db`, `internal/releases`, `internal/storage`, `web/templates`, and `web/static`
|
||||
- `GOCACHE=/tmp/go-build-agent06-validate GOMODCACHE=/tmp/go-mod-agent06-http go test ./...` -> passed
|
||||
- `GOCACHE=/tmp/go-build-agent06-build-validate GOMODCACHE=/tmp/go-mod-agent06-http go build -o /tmp/update-server-agent06-validate ./cmd/server` -> passed
|
||||
- `GOCACHE=/tmp/go-build-agent06-migrate-validate GOMODCACHE=/tmp/go-mod-agent06-http go build -o /tmp/update-migrate-agent06-validate ./cmd/migrate` -> passed
|
||||
- live smoke checks against `127.0.0.1:18086` after starting `/tmp/update-server-agent06-validate` with a fresh `DATA_DIR`:
|
||||
- `GET /healthz` -> `200 OK`
|
||||
- `GET /api/v1` -> `200 OK` with public JSON index documenting bearer auth and the client routes
|
||||
- `GET /api/v1/projects` without bearer token -> `401 Unauthorized` with `WWW-Authenticate: Bearer`
|
||||
- admin login succeeded and a fresh test dataset was created:
|
||||
- active projects: `desktop-app`, `mobile-app`
|
||||
- archived project: `legacy-app`
|
||||
- releases created for desktop, mobile, and legacy projects
|
||||
- tag-scoped API key with `can_download`
|
||||
- API key without `can_download`
|
||||
- expired API key
|
||||
- `GET /api/v1/projects` with the allowed tag-scoped key -> `200 OK`, returning only active authorized project `desktop-app`
|
||||
- `GET /api/v1/projects` with key lacking `can_download` -> `403 Forbidden`
|
||||
- `GET /api/v1/projects` with expired key -> `401 Unauthorized`
|
||||
- `GET /api/v1/projects/desktop-app/releases/latest` with allowed key -> `200 OK`, returning latest active desktop release `1.1.0 / build-2`
|
||||
- `GET /api/v1/projects/mobile-app/releases/latest` with allowed key -> `404 Not Found`
|
||||
- `GET /api/v1/releases/3` for out-of-scope mobile release -> `404 Not Found`
|
||||
- `GET /api/v1/releases/4` for archived-project release -> `404 Not Found`
|
||||
- `GET /api/v1/releases/2` with allowed key -> `200 OK`, returning authorized release metadata
|
||||
- `GET /api/v1/releases/2/download` with allowed key -> `200 OK`, streamed `desktop-release-1.1.0` with `Content-Disposition: attachment; filename=desktop-app-1.1.0.zip`
|
||||
- `GET /admin/projects/1` with admin session -> `200 OK`, page showed `/api/v1/projects/desktop-app/releases/latest`, `/api/v1/releases/2`, and `/api/v1/releases/2/download`
|
||||
- `GET /admin/api-keys/1` with admin session -> `200 OK`, page showed bearer-auth quick-start guidance and accessible client API paths
|
||||
- SQLite inspection of `/tmp/update-server-agent06-live/db.sqlite` confirmed:
|
||||
- latest desktop release persisted as release ID `2`
|
||||
- mobile release persisted as release ID `3`
|
||||
- archived-project release persisted as release ID `4`
|
||||
- validation API keys persisted with the expected permission and expiry states
|
||||
|
||||
## Findings
|
||||
|
||||
No blocking findings.
|
||||
|
||||
The stage satisfies the agreed scope:
|
||||
|
||||
- the public `/api/v1` index is usable and documents the client routes;
|
||||
- bearer-authenticated client endpoints enforce API key authentication and `can_download`;
|
||||
- client project listing returns only active authorized projects;
|
||||
- latest-release lookup, metadata lookup, and artifact download work for authorized resources;
|
||||
- out-of-scope and archived resources are hidden behind `404`;
|
||||
- downloads stream from private artifact storage instead of exposing static URLs;
|
||||
- admin pages expose the new client API paths and quick-start guidance.
|
||||
|
||||
## Required Fixes
|
||||
|
||||
None.
|
||||
|
||||
## Optional Improvements
|
||||
|
||||
- If the product later needs richer updater logic, add support for semantic-version comparison or explicit release channels instead of using newest persisted `created_at` as the definition of “latest”.
|
||||
- Agent 07 should harden the now-working client API with security headers, rate limiting, CSRF coverage for admin POST forms, and deployment-ready reverse proxy guidance.
|
||||
|
||||
## Status
|
||||
|
||||
`APPROVED`
|
||||
88
docs/agents/validation/07-security-deploy-validation.md
Normal file
88
docs/agents/validation/07-security-deploy-validation.md
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
# Validation Report Template
|
||||
|
||||
## Validator
|
||||
|
||||
Name: Codex Validation Agent
|
||||
|
||||
Stage Reviewed: Agent 07 - Security And Deployment Hardening
|
||||
|
||||
Date: 2026-04-15
|
||||
|
||||
## Reviewed Inputs
|
||||
|
||||
- `/Users/delete/projects/update_server/docs/agents/WORKFLOW.md`
|
||||
- `/Users/delete/projects/update_server/PRODUCT_SPEC.md`
|
||||
- `/Users/delete/projects/update_server/IMPLEMENTATION_PLAN.md`
|
||||
- `/Users/delete/projects/update_server/DEVELOPMENT_WORKFLOW.md`
|
||||
- `/Users/delete/projects/update_server/docs/agents/OPERATOR_QUICKSTART_RU.md`
|
||||
- `/Users/delete/projects/update_server/docs/agents/handoffs/07-security-deploy.md`
|
||||
- previous stage validation report: `/Users/delete/projects/update_server/docs/agents/validation/06-client-api-ui-validation.md`
|
||||
- implementation files under `internal/config`, `internal/app`, `internal/db`, `internal/auth`, `internal/http`, `web/templates`, `deploy`, and root deployment files
|
||||
- `GOCACHE=/tmp/go-build-agent07-validate GOMODCACHE=/tmp/go-mod-agent06-http go test ./...` -> passed
|
||||
- `GOCACHE=/tmp/go-build-agent07-build GOMODCACHE=/tmp/go-mod-agent06-http go build -o /tmp/update-server-agent07-validate ./cmd/server` -> passed
|
||||
- `GOCACHE=/tmp/go-build-agent07-migrate GOMODCACHE=/tmp/go-mod-agent06-http go build -o /tmp/update-migrate-agent07-validate ./cmd/migrate` -> passed
|
||||
- `command -v docker` -> command not available in this environment, so `docker compose config` and container runtime checks could not be executed here
|
||||
- live smoke checks against an HTTP-configured hardened server on `127.0.0.1:18088`:
|
||||
- `GET /admin/login` -> `200 OK` with:
|
||||
- `Cache-Control: no-store, private, max-age=0`
|
||||
- `Content-Security-Policy`
|
||||
- `X-Frame-Options: DENY`
|
||||
- `X-Content-Type-Options: nosniff`
|
||||
- `Referrer-Policy: no-referrer`
|
||||
- `Permissions-Policy`
|
||||
- `Cross-Origin-Opener-Policy: same-origin`
|
||||
- `Cross-Origin-Resource-Policy: same-origin`
|
||||
- `Vary: Cookie`
|
||||
- CSRF cookie scoped to `/admin`, `HttpOnly`, `SameSite=Strict`
|
||||
- `POST /admin/login` without CSRF token -> `403 Forbidden`
|
||||
- `POST /admin/login` with valid CSRF token -> `303 See Other` with:
|
||||
- session cookie scoped to `/admin`
|
||||
- `HttpOnly`
|
||||
- `SameSite=Lax`
|
||||
- rotated CSRF cookie scoped to `/admin`
|
||||
- `GET /api/v1/projects` without bearer token -> `401 Unauthorized` with:
|
||||
- `Cache-Control: no-store, private, max-age=0`
|
||||
- `Vary: Authorization`
|
||||
- shared security headers
|
||||
- created a download-capable API key through the hardened admin flow and verified:
|
||||
- first two `GET /api/v1/projects` requests -> `200 OK`
|
||||
- third request -> `429 Too Many Requests` with `Retry-After: 1`
|
||||
- changing `X-Forwarded-For` between those requests did not bypass the rate limit while `TRUST_PROXY_HEADERS` remained false, confirming socket-address behavior in practice
|
||||
- live smoke checks against an HTTPS-configured hardened server on `127.0.0.1:18089` with `APP_BASE_URL=https://updates.example.com`:
|
||||
- `GET /admin/login` -> `200 OK` with `Strict-Transport-Security: max-age=31536000`
|
||||
- CSRF cookie carried `Secure`, `Path=/admin`, `HttpOnly`, `SameSite=Strict`
|
||||
- `POST /admin/login` with valid CSRF token -> `303 See Other` with session cookie carrying `Secure`, `Path=/admin`, `HttpOnly`, `SameSite=Lax`
|
||||
- static review of deployment artifacts:
|
||||
- `Dockerfile`
|
||||
- `docker-compose.yml`
|
||||
- `deploy/Caddyfile.example`
|
||||
- `deploy/nginx.update-server.conf.example`
|
||||
- `deploy/update-server.env.example`
|
||||
- `docs/DEPLOYMENT.md`
|
||||
|
||||
## Findings
|
||||
|
||||
No blocking findings.
|
||||
|
||||
The stage satisfies the agreed scope:
|
||||
|
||||
- admin and protected client routes emit sane security defaults;
|
||||
- CSRF protection is enforced on admin POST flows;
|
||||
- cookies are scoped to `/admin` and switch to `Secure` when the public base URL is HTTPS;
|
||||
- login and protected client API rate limits work;
|
||||
- trusted proxy handling is opt-in;
|
||||
- deployment and backup or restore documentation is present and coherent with the current architecture;
|
||||
- artifacts remain private and continue flowing through authenticated application endpoints.
|
||||
|
||||
## Required Fixes
|
||||
|
||||
None.
|
||||
|
||||
## Optional Improvements
|
||||
|
||||
- Run `docker compose up --build` and one reverse-proxy example on the real target host before first production exposure, since Docker was unavailable in this validation environment.
|
||||
- If you later run multiple app instances, replace the current in-memory rate limiter with a shared store-backed or proxy-backed limiter.
|
||||
|
||||
## Status
|
||||
|
||||
`APPROVED`
|
||||
13
docs/agents/validation/README.md
Normal file
13
docs/agents/validation/README.md
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
# Validation Directory
|
||||
|
||||
Save one validation markdown file here after every validation pass.
|
||||
|
||||
Naming convention:
|
||||
|
||||
- `01-foundation-validation.md`
|
||||
- `02-database-validation.md`
|
||||
- `03-auth-validation.md`
|
||||
- `04-projects-releases-validation.md`
|
||||
- `05-api-keys-validation.md`
|
||||
- `06-client-api-ui-validation.md`
|
||||
- `07-security-deploy-validation.md`
|
||||
Loading…
Add table
Add a link
Reference in a new issue