Define HopWeb as a prompt-native forge built on a maintainable Gitea foundation
Hop-State: A_06FN3NFQ6P95HFKCSC22JMR Hop-Proposal: R_06FN3NF43ARPM6SBXX0F15R Hop-Task: T_06FN3MVGY3MT82ESQ89BND0 Hop-Attempt: AT_06FN3MVGY092BFA5MR9C7EG
This commit is contained in:
@@ -0,0 +1,69 @@
|
||||
# ADR 0001: Use Gitea as the forge foundation
|
||||
|
||||
- Status: Accepted
|
||||
- Date: 2026-07-11
|
||||
|
||||
## Context
|
||||
|
||||
HopWeb needs reliable Git hosting, repository permissions, users and
|
||||
organizations, review primitives, webhooks, CI integration, packages, releases,
|
||||
and administration. Rebuilding this foundation would delay the Hop-native
|
||||
workflow and create a large security and maintenance burden.
|
||||
|
||||
Gitea is a mature, MIT-licensed, Go-based forge with a REST API, OAuth2 provider,
|
||||
webhooks, Git LFS, package registries, and a production-capable Actions system.
|
||||
It supports custom assets, themes, templates, and repository tabs, which are
|
||||
enough to prototype a unified Hop experience without immediately carrying a
|
||||
large source fork.
|
||||
|
||||
## Decision
|
||||
|
||||
Use a pinned upstream Gitea release as the forge substrate. Build Hop as a
|
||||
separate control-plane service and Hop-native web experience that integrates
|
||||
with Gitea through stable APIs, webhooks, OAuth, and Git protocols.
|
||||
|
||||
Adopt a staged customization policy:
|
||||
|
||||
1. configuration, branding, templates, assets, and API integration;
|
||||
2. small upstreamable extension points where integration seams are missing;
|
||||
3. a shallow maintained fork only for essential Hop-native behavior.
|
||||
|
||||
Hop domain data will live outside the Gitea schema. Cross-service operations
|
||||
will use stable IDs, idempotency keys, and explicit reconciliation rather than
|
||||
distributed database writes.
|
||||
|
||||
## Consequences
|
||||
|
||||
### Positive
|
||||
|
||||
- The team can focus on Hop's state model and collaboration experience.
|
||||
- Standard Git clients and familiar forge features work from the beginning.
|
||||
- Gitea security fixes and features can be consumed from upstream.
|
||||
- A separable control plane makes the Hop model portable to another Git host.
|
||||
|
||||
### Costs and risks
|
||||
|
||||
- A visually unified product must compose two service boundaries.
|
||||
- Some acceptance operations need careful compensation and reconciliation.
|
||||
- Template overrides are version-sensitive.
|
||||
- A deep fork would make upstream upgrades expensive.
|
||||
- Public multi-tenant runners require a stronger isolation model than Gitea's
|
||||
default trusted-runner assumptions.
|
||||
|
||||
## Guardrails
|
||||
|
||||
- Pin exact Gitea versions and test upgrades in automation.
|
||||
- Keep a patch ledger for every source-level deviation from upstream.
|
||||
- Never edit vendored Gitea code for branding alone.
|
||||
- Prefer contributing generic extension points upstream.
|
||||
- Keep the Hop control plane independently testable and deployable.
|
||||
- Threat-model Git hooks, webhooks, runner registration, job tokens, and
|
||||
untrusted repository content before supporting public execution.
|
||||
|
||||
## Revisit when
|
||||
|
||||
- Gitea's architecture prevents a core Hop invariant;
|
||||
- the source patch set grows beyond a routinely rebaseable size;
|
||||
- transactional acceptance cannot be made reliable across the boundary; or
|
||||
- operating two services costs more than owning a cohesive fork.
|
||||
|
||||
@@ -0,0 +1,170 @@
|
||||
# HopWeb product blueprint
|
||||
|
||||
## Product position
|
||||
|
||||
HopWeb is not "Gitea with AI buttons." It is a forge whose source of truth is a
|
||||
causal record of intent and verified outcomes, with Git underneath for universal
|
||||
tool compatibility.
|
||||
|
||||
The core screen should answer four questions without reconstructing them from a
|
||||
commit history:
|
||||
|
||||
1. What outcome was requested?
|
||||
2. Who or what tried to produce it?
|
||||
3. What exact result was checked, and what passed?
|
||||
4. Which outcome became shared truth, and why?
|
||||
|
||||
## Concept mapping
|
||||
|
||||
| Conventional forge | HopWeb primary concept | Notes |
|
||||
| --- | --- | --- |
|
||||
| Issue | Task | Outcome plus its evolving prompt history |
|
||||
| Branch/worktree | Attempt | Isolated work by a human, agent, or team |
|
||||
| Commit | Checkpoint/state | Immutable tree plus causal parents and metadata |
|
||||
| CI status | Evidence | Bound to the exact checkpoint that was tested |
|
||||
| Pull request | Proposal | Candidate outcome with intent, evidence, and diff |
|
||||
| Merge | Accept/land | Advances the accepted state after validation |
|
||||
| Commit graph | State graph | Includes prompts, checkpoints, proposals, and outcomes |
|
||||
| Contributor | Actor | Human or agent identity with attribution and policy |
|
||||
|
||||
Git branches, commits, and pull requests remain available as compatibility
|
||||
views. They should not dictate the Hop-native experience.
|
||||
|
||||
## System shape
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
UI["Hop-native web UI"] --> API["Hop control-plane API"]
|
||||
API --> HDB["Hop state and evidence store"]
|
||||
API --> ORCH["Attempt orchestrator"]
|
||||
ORCH --> RUN["Isolated agent runners"]
|
||||
API --> GAPI["Gitea API and webhooks"]
|
||||
GAPI --> GIT["Git repositories"]
|
||||
GAPI --> FORGE["Identity, permissions, issues, Actions, packages"]
|
||||
RUN --> GIT
|
||||
RUN --> HDB
|
||||
```
|
||||
|
||||
### Ownership boundary
|
||||
|
||||
**Gitea owns** repositories, Git protocol, blob storage, users, organizations,
|
||||
teams, baseline authorization, webhooks, Actions, releases, and packages.
|
||||
|
||||
**Hop owns** tasks, prompts, attempts, state graph edges, agent sessions,
|
||||
checkpoints, evidence, proposals, acceptance policy, and orchestration.
|
||||
|
||||
**The Hop UI composes both.** A user should experience one product even when the
|
||||
data comes from two services.
|
||||
|
||||
## Integration strategy
|
||||
|
||||
Start from an unmodified, pinned Gitea release and integrate through its API,
|
||||
webhooks, OAuth, custom templates, and custom assets. This lets us validate the
|
||||
workflow while preserving straightforward upstream upgrades.
|
||||
|
||||
Maintain a shallow source fork only when a required experience cannot be built
|
||||
cleanly through those seams—for example, a first-class state graph inside every
|
||||
repository route or authorization decisions that must be transactional with Git
|
||||
writes. Every fork patch must be small, isolated, tested, and documented with an
|
||||
upstream issue or a reason it is intentionally Hop-specific.
|
||||
|
||||
Do not put Hop's domain tables directly into Gitea's database. Services may
|
||||
share stable identifiers, but each service owns its schema and migrations.
|
||||
|
||||
## Primary experience
|
||||
|
||||
### Repository home
|
||||
|
||||
Lead with active tasks, recent accepted outcomes, running attempts, and failing
|
||||
evidence. Files and commits remain one click away, not the default narrative.
|
||||
|
||||
### Task page
|
||||
|
||||
Show the current requested outcome, prompt history, constraints, linked issues,
|
||||
all attempts, and the policy required for acceptance.
|
||||
|
||||
### Attempt page
|
||||
|
||||
Stream agent activity and expose the evolving state graph, working diff,
|
||||
checkpoints, check results, cost/runtime metadata, and interventions from humans.
|
||||
|
||||
### Proposal review
|
||||
|
||||
Review by outcome first: summary, behavioral changes, evidence, risks, then file
|
||||
diff. Let reviewers compare multiple proposals for the same task side by side.
|
||||
|
||||
### Acceptance
|
||||
|
||||
Acceptance is a named product event. It advances the repository's accepted Hop
|
||||
state, records the actor and policy decision, and materializes the corresponding
|
||||
Git change atomically or fails without advancing either view.
|
||||
|
||||
## Initial domain model
|
||||
|
||||
- `repositories`: link a Hop repository to its Gitea repository identifier.
|
||||
- `tasks`: requested outcome, status, creator, and acceptance policy.
|
||||
- `states`: immutable typed nodes with tree identity, digest, actor, and time.
|
||||
- `state_edges`: ordered, role-labelled causal relationships between states.
|
||||
- `attempts`: isolated execution contexts associated with a task and base state.
|
||||
- `checks`: commands or policies evaluated against an immutable checkpoint.
|
||||
- `evidence`: normalized results, logs, artifacts, and provenance for checks.
|
||||
- `proposals`: frozen candidate outcomes and their review status.
|
||||
- `acceptances`: atomic record linking a proposal, accepted state, and Git ref.
|
||||
- `actors`: human, service, and agent identities plus attestable metadata.
|
||||
|
||||
Use opaque, sortable IDs and repository-scoped uniqueness. Treat all mutable
|
||||
status fields as projections of an append-only event history where auditability
|
||||
matters.
|
||||
|
||||
## Delivery sequence
|
||||
|
||||
### Milestone 0 — foundation
|
||||
|
||||
- Pin and run Gitea locally with PostgreSQL and object storage boundaries.
|
||||
- Add a Hop control-plane service and database.
|
||||
- Establish Gitea OAuth/API authentication and webhook verification.
|
||||
- Link Hop repositories to Gitea repositories.
|
||||
- Define upgrade policy and an automated upstream rebase test.
|
||||
|
||||
### Milestone 1 — task to accepted outcome
|
||||
|
||||
- Create tasks and capture prompt states.
|
||||
- Launch isolated attempts through a runner interface.
|
||||
- Ingest checkpoints and checkpoint-bound check evidence.
|
||||
- Freeze proposals and display their diffs.
|
||||
- Accept a validated proposal and advance the Git default branch.
|
||||
|
||||
### Milestone 2 — native collaboration
|
||||
|
||||
- Multiple concurrent attempts and proposal comparison.
|
||||
- Human intervention and prompt follow-ups within an attempt.
|
||||
- Review policies, approvals, protected accepted state, and audit history.
|
||||
- Notifications and task/attempt dashboards.
|
||||
|
||||
### Milestone 3 — ecosystem
|
||||
|
||||
- Public repositories and discoverability.
|
||||
- Agent marketplace and reusable execution profiles.
|
||||
- Organization policy, billing, usage controls, and hosted runners.
|
||||
- GitHub/GitLab import and bidirectional compatibility workflows.
|
||||
|
||||
## Non-negotiable invariants
|
||||
|
||||
- A prompt is captured before project effects begin.
|
||||
- Evidence always identifies the immutable checkpoint it evaluated.
|
||||
- A proposal never changes after it is frozen.
|
||||
- Acceptance never silently includes unrelated workspace effects.
|
||||
- Human and agent actions are distinguishable and attributable.
|
||||
- Git operations remain possible with standard Git clients.
|
||||
- Hop state can be exported without requiring the HopWeb service forever.
|
||||
|
||||
## Decisions still to make
|
||||
|
||||
- Hosted SaaS, self-hosted distribution, or both for the first release.
|
||||
- Runner isolation boundary: container, microVM, or pluggable backends.
|
||||
- Whether accepted Hop state is encoded into Git refs/notes in addition to the
|
||||
Hop database for portability and disaster recovery.
|
||||
- The first authentication path: Gitea as OAuth provider or a shared external
|
||||
identity provider.
|
||||
- Product name: retain HopWeb internally or choose a public forge name.
|
||||
|
||||
Reference in New Issue
Block a user