Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ the project tree if desired.

## Capability map (what's built, by phase)

All 36 phases, P37a, P37b-i, P37b-ii, P37c and P37d are built and tested. One line of current fact per phase; the
All 36 phases, P37a, P37b-i, P37b-ii, P37c, P37d and P38 are built and tested. One line of current fact per phase; the
authoritative rationale and full semantics live in the linked ADR, the design
in `ARCHITECTURE.md`. The old per-phase narrative log this table replaced is
archived verbatim at `docs/archive/claude-md-phase-log-2026-07.md` — do not
Expand Down Expand Up @@ -159,6 +159,7 @@ the code, those win.
| P37b-i | Presence-based partial clones: push, verify and gc walk what the store holds (`reachable_objects_partial`), not the fetch filter; push checks every gap id against the destination before sending; a view gap fails with `GapInView` before any write (preflight at the top of `materialize`, plus `undo` and `sparse set`); a partial clone fetches from its origin only. 37b-ii: on a lazy, online clone `ensure_view` fills the view closure by id before switch, fast-forward, undo and `sparse set`, `sparse set` may widen past the filter, a by-id reply is capped at `min(--max-pack-size, 2 GiB)` (a constant since #213, independent of the object cap) and a refused batch is split. | [0048](docs/adr/0048-presence-based-partial-clones.md) |
| P37c | Merge, cherry-pick and rebase on a partial clone: a tree-recursive engine (`merge_trees`) carries a subtree by id when the sides agree and no protection rule applies, reads only where they differ or a rule intersects, and on a lazy, online clone fills what it asks for by id outside the store lock (a non-lazy clone gets the gap error with `sc backfill <path>`); a carried protected subtree keeps the complete input wrap union; a conflict inside the view is marked and resolved like on a full clone (`sc conflicts`/`sc resolve`/`merge --abort`/`sc commit`; the out-of-view part is grafted from the decided root), while a conflict outside the view, or a result that must be sealed outside it, is refused before any ref, merge-state or working-tree change (fetched objects stay). A subtree identical on all three sides is carried even under a protection rule. Cherry-pick and rebase use the same engine (`replay_commit`): the fold's accumulator may hold absent subtrees, the view is filled before the final write, and a stopped pick or rebase keeps its carried subtrees in the decided root. Mode-only edits now merge and a file/directory collision fails before any write, on full clones too. | [0049](docs/adr/0049-merge-on-partial-clones.md) |
| P37d | Agent sessions on a partial clone: `sc ws fork`/`run`/`harvest`/`abandon` and `sc work` work; a workspace or agent sees the host's sparse view only (`sc work` no longer gets a complete tree there), the view closure is filled (lazy, online) or refused with the gap error before anything is written, a workspace commit grafts the out-of-view subtrees from the base without reading them, and harvest lands through the ADR-0049 merge (any conflict falls back to a `work-<i>` branch as on a full clone) | [0050](docs/adr/0050-sessions-on-partial-clones.md) |
| P38 | Gitea-compatible forge over bare Git and smart HTTP: recorded API subset, scoped auth, protected merges, maintenance and container operations; 24 recorded scenarios and six first-consumer acceptance scenarios pass. Hosted repos have none of the `.sc/` features; SSH and Actions remain outside v1. | [0058](docs/adr/0058-sc-forge-gitea-compatible-git-forge.md) |

## Standing boundaries & gotchas

Expand Down
18 changes: 2 additions & 16 deletions ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -696,27 +696,13 @@ across every phase.

## Active

**P38 — sc-forge** (Proposed, [ADR-0058](docs/adr/0058-sc-forge-gitea-compatible-git-forge.md)):
a Gitea-compatible Git forge (bare repos over smart HTTP, a recorded subset of
`/api/v1`, SQLite metadata) so a platform can swap its project Git host by
config. Design:
`docs/superpowers/specs/2026-10-22-p38-forge-design.md`. Slices F0 (contract
capture) through F6 (acceptance on the first deployment); F0, F1 (server
skeleton, users, organizations, tokens, `admin` CLI), F2a (repositories API, lifecycle
and reconciler, collaborators, branches) and F2b (smart-HTTP git transport via `git http-backend`,
`pre-receive` ref policy, admission control, threat-model pass #1) and F3a (content reads: refs, tags, commits,
trees, contents, archives) and F3b (contents writes: create, update, delete as server-made commits) and F4a (branch protection
enforced on push, contents API and branch delete; commit statuses) and F4b (pull requests, reviews, comments, retention
refs) and F4c (merge with a crash-safe journal, required-check gating, kill -9 and protection-matrix tests) and F5a (two-stage gc, merge-commit retention, runtime cleanup of stale locks and quarantine directories) and F5b (structured logs, graceful SIGTERM drain, bind-gate tests, container image, operations guide) are built. Hosted repos are
bare Git and get none of the `.sc/` features.

Other follow-up work is tracked as GitHub issues and listed under Deferred
below.
No phase is currently active. Follow-up work is tracked under Deferred below.

## Completed phases (usability-first ordering)

| Phase | Goal | Demoable outcome | ADR |
|-------|------|------------------|-----|
| **P38 — sc-forge** | Configurable project Git host | Bare Git over smart HTTP, recorded Gitea API subset, protected merges and operations tooling; all 24 recorded scenarios and all six first-consumer acceptance scenarios pass. Local acceptance only; production migration is separate. | [0058](docs/adr/0058-sc-forge-gitea-compatible-git-forge.md) |
| **P4 — Merge & conflict resolution** | Combine work from two branches | `sc merge <branch>` creates a merge snapshot; clean merges auto-resolve, conflicts are detected and reported | [0012](docs/adr/0012-three-way-merge.md) |
| **P5 — Secret scanner (accidental-plaintext guard)** | Stop plaintext secrets being committed | pattern + entropy scan hard-rejects plaintext secrets, with `sc scan` and a hash-scoped allowlist | [0017](docs/adr/0017-secret-scanner.md) |
| **P6 — Remotes: clone / push / fetch** | Sync a repo between locations | `sc clone <src> <dst>`, `sc push`, `sc fetch` transfer objects + refs; `fetch` then `merge` integrates remote work | [0013](docs/adr/0013-remote-sync-model.md) |
Expand Down
24 changes: 23 additions & 1 deletion docs/adr/0058-sc-forge-gitea-compatible-git-forge.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# ADR-0058: sc-forge, a Gitea-compatible Git forge

- **Status:** Proposed
- **Status:** Accepted (2026-10-25)
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Resolved
- **Date:** 2026-10-22
- **Phase:** 38
- **Builds on:** ADR-0028 (hosted Git through system `git`), ADR-0040 (bearer
Expand Down Expand Up @@ -146,3 +146,25 @@ Whether `has_actions` PATCH is accepted or refused, the `/version` string, and
an eventual TLS option are decided during F1 and F5. Foreign-token codes, merge
message texts and the deliberate departures from Gitea are recorded in the spec
("Contract decisions from the recordings") and `crates/forge/conformance/`.

## Acceptance outcome

F0–F5 are implemented. F6 passed on 2026-10-25 against a disposable local
consumer deployment using forge source `dd563f231092b4c9832f56475a597c7dddd8e825`
(the runtime change merged in #319; its later commit changes only a maintenance
test). All six default consumer scenarios passed together: topology, delivery
including customer merge, request-to-agent-runtime, brownfield import,
brownfield one-shot and Claim recovery. Customer source imports remained on
Gitea. Recovery exercised an actual orchestrator with a controlled harness,
lost-acknowledgement replay, an explicit Worker budget reset and browser
readback without navigation. This is consumer integration evidence, not a
qualification of a real coding model.

The recorded 24-scenario conformance gate remains the reproducible regression
suite in this repository. Consumer evidence is retained in the consumer's
private workspace; it is not available from this repository's CI.

Acceptance does not approve a production migration. The local fixture used
the consumer's Redis-free middleware mode, so production rate limiting was
not qualified. SSH, Actions and the other v1 exclusions above remain excluded;
implementation follow-ons remain tracked in #316.
28 changes: 24 additions & 4 deletions docs/superpowers/specs/2026-10-22-p38-forge-design.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
# Design: sc-forge, a Gitea-compatible Git forge (P38)

- **Date:** 2026-10-22 (revision 2, after independent design review)
- **Status:** Draft, pre-implementation (ADR-0058 is Proposed)
- **ADR:** ADR-0058 is firmed from Proposed to Accepted when the phase is built
(ROADMAP "How a phase gets built")
- **Status:** Accepted (2026-10-25); implementation complete
- **ADR:** [ADR-0058](../../adr/0058-sc-forge-gitea-compatible-git-forge.md) is Accepted (2026-10-25).
- **Contract source:** `crates/forge/conformance/` (recorded from real Gitea
1.22.6 and 1.26.2; see "Conformance") plus the client survey summarized below

Expand Down Expand Up @@ -1071,7 +1070,28 @@ conflict checks. URLs already compare by value, including repository identity. T
now requires wrong mergeability and wrong-repository URL mutations to fail the actual gate.
Refusal texts were fixed in #315; combined-status decisions are recorded under "Statuses" above.
Remaining lifecycle, resource and authentication limits from the implementation comments are tracked
in #316; F6 remains acceptance on the first consumer deployment.
in #316. F6 passed on the first consumer deployment; see below.

## F6 acceptance outcome

Completed on 2026-10-25 using a disposable local consumer deployment and forge
source `dd563f231092b4c9832f56475a597c7dddd8e825` (#319's runtime change).
One complete default sweep passed topology, delivery with customer merge,
request-to-agent-runtime, brownfield import, brownfield one-shot and Claim
recovery. Only the target Git host was selected as sc-forge; customer source
imports stayed on Gitea. The consumer's configuration and fixture repairs
were delivered through its own repositories.

Claim recovery used the real orchestrator with a controlled harness. It
verified failure acknowledgement replay, persistence of the stopped Claim
across restart, explicit budget reset, a second Worker, unchanged Claim
ownership, unique failure/recovery comments and browser-visible recovery
without navigation. It does not qualify a real coding model.

The consumer's private evidence is separate from this repository's reproducible
24-scenario conformance gate. The local run used Redis-free consumer middleware
and did not qualify production rate limiting or authorize QA/production
cutover. Existing v1 exclusions and #316 follow-ons remain in force.

## Open questions

Expand Down
Loading