diff --git a/README.md b/README.md new file mode 100644 index 0000000..24d2095 --- /dev/null +++ b/README.md @@ -0,0 +1,57 @@ +# HopWeb + +HopWeb is a collaborative forge for prompt-native software development. + +It uses Git for durable source storage and Gitea for the proven forge substrate, +but makes Hop's workflow the primary product model: + +- a **task** captures the outcome someone wants; +- a **prompt state** records each instruction in its causal context; +- an **attempt** is an isolated line of human or agent work; +- a **checkpoint** freezes the exact tree that was evaluated; +- **evidence** records checks against that immutable checkpoint; +- a **proposal** is a reviewable candidate outcome; and +- an **accepted state** is the current shared truth. + +The product thesis is simple: + +> GitHub organizes collaboration around commits and pull requests. HopWeb +> organizes human-agent collaboration around intent, attempts, evidence, and +> accepted outcomes. + +## Foundation + +Gitea supplies the expensive, mature infrastructure we should not rebuild: + +- Git transport, repositories, LFS, and permissions +- users, organizations, teams, OAuth, and access tokens +- issues, notifications, webhooks, releases, packages, and Actions +- administration, audit surfaces, and deployment primitives + +Hop supplies the differentiating control plane and experience: + +- prompt and state graph persistence +- task and attempt orchestration +- agent identity and attribution +- checkpoint-bound validation evidence +- proposal review and acceptance semantics +- a Hop-native repository, task, attempt, and review interface + +See [the product blueprint](docs/product-blueprint.md) and +[the Gitea foundation decision](docs/adr/0001-gitea-as-forge-foundation.md). + +## First release + +The first useful release is not a complete GitHub clone. It is a private, +single-installation forge where a user can: + +1. create or import a repository; +2. open a task with a prompt; +3. launch one or more isolated agent attempts; +4. watch states, diffs, and checks appear live; +5. compare proposals by outcome and evidence; and +6. accept one proposal into the repository's shared state. + +Everything else should be inherited from Gitea until the Hop workflow proves +that it needs a different abstraction. + diff --git a/docs/adr/0001-gitea-as-forge-foundation.md b/docs/adr/0001-gitea-as-forge-foundation.md new file mode 100644 index 0000000..ea88d79 --- /dev/null +++ b/docs/adr/0001-gitea-as-forge-foundation.md @@ -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. + diff --git a/docs/product-blueprint.md b/docs/product-blueprint.md new file mode 100644 index 0000000..6797d01 --- /dev/null +++ b/docs/product-blueprint.md @@ -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. +