From ab87d537512a0859f5c4bdf636d6f5c2f898197b Mon Sep 17 00:00:00 2001 From: "glm-5.3-flash" Date: Sun, 8 Nov 2026 12:28:05 +0000 Subject: [PATCH] docs(phase0): gitea feature survey; requirements re-anchor - survey the 28.3.0 gitea feature catalog schema-derived from the sqlite snapshot plus a read-only production-db pass; 117 tables grouped into 26 feature areas with draft dispositions anchored to workflows, user classes, and ADR-002 (no observed-usage bias) - record production-db ground truth the walk lacked: zero 2FA, zero real OAuth apps, one unverified GPG key, and the exact ten-repo push-mirror roster (a direct OQ-FG-07 migration input) - re-anchor the phase 0 requirements work: requirements derive from a vision plus workflows, user classes, and ADRs with zero version-based hedging; the walk and survey are sizing/validation inputs, never the requirements source - fix the walk-rule vocabulary: every disposition lands at a named roadmap milestone or is explicitly rejected; 'deferred without a named home' removed - rewrite the convergence checklist into session-sized line items (vision.md, requirements.md, roadmap/feature map, 0.1 as milestone 1, then the existing downstream items) Verification: em-dash grep clean across AGENTS.md scope; docs-only change (no Cargo manifest in the repo yet, cargo set not applicable) --- docs/research/gitea-feature-survey.md | 170 ++++++++++++++++++++++++++ docs/research/phase-0.md | 68 +++++++++-- 2 files changed, 229 insertions(+), 9 deletions(-) create mode 100644 docs/research/gitea-feature-survey.md diff --git a/docs/research/gitea-feature-survey.md b/docs/research/gitea-feature-survey.md new file mode 100644 index 0000000..0997bc6 --- /dev/null +++ b/docs/research/gitea-feature-survey.md @@ -0,0 +1,170 @@ +--- +status: draft +last_updated: 2026-11-08 +--- + +# Gitea feature survey (requirements anchor input) + +A schema-derived enumeration of gitea's feature catalog, independent of +what the alkforge deployment happens to use. Purpose: remove the +"replace exactly what was observed" bias from the requirements +derivation (phase-0 sect 9 checklist; deployment-walk sect 11) by +listing *what the incumbent can do*, then classifying against the +anchor (family workflows, user classes, ADR-002 scope and posture), +not against observed usage alone. + +This document is the fact base plus a draft classification. Final +dispositions land in `docs/research/requirements.md`; anything here +marked as flagged is an owner-input question collected by that work. + +## 1. Method and provenance + +- **Snapshot schema**: `/workspace/research/git/gitea.db` (the + pre-migration sqlite deployment, gitea migration version 323): + 112 tables. No honker-specific tables present; the file is clean + gitea schema. +- **Current schema**: read-only pass on the live 28.3.0 Postgres on + dev1 (2026-11-08, via `information_schema` only): 117 base tables. + Nothing was written; no gitea source was read (AGENTS.md convention + 13); table semantics come from table/row observation plus operator + docs in `/workspace/system/dev1/`. +- **Vintage gap**: closed. The sqlite snapshot and the live schema + differ by exactly five tables (`action_run_attempt`, + `action_run_attempt_job_id_index`, `action_run_job_summary`, + `action_scoped_workflow_source`, `audit_event`), all Actions/audit + related. Their union is the complete 28.3.0 catalog, so no release + notes cross-check is needed. +- **Tables map to features many-to-one**: `action_run*` is one + feature area; `team_*` is another; single tables (`repository`, + `issue`, `webhook`) can be whole features. The catalog below is + organized by feature area, not by table. + +## 2. Current-usage ground truth (production db, read-only, 2026-11-08) + +Row counts that extend the deployment walk (walk sect 10 covered +issues/PRs/LFS/access tokens/webhooks/protected branches already; +these are the ones the walk did not cover, or sharpen): + +| Table | Rows | Reading | +|---|---|---| +| two_factor | 0 | no 2FA enrolled by anyone today | +| webauthn_credential | 0 | no webauthn | +| gpg_key | 1 | one key, owned by `deepseek-v4-pro`, **unverified**: effectively unused | +| oauth2_application | 5 | all five are gitea's stock client registrations (`tea`, `Gitea App`, `gitea-vscode`, `git-credential-oauth`, `Git Credential Manager`); zero user-created apps | +| access_token / auth_token | 0 | no API tokens | +| webhook | 0 | none | +| deploy_key | 0 | none | +| secret | 0 | no repo/user secrets (Actions feature, unused) | +| commit_status | 0 | no CI status reporting | +| session | 0 | no live web sessions | +| mirror (pull mirror) | 0 | no scheduled pulls of external repos | +| push_mirror | **10** | the exact mirror roster, see below | +| repo_redirect / renamed_branch | 0 | no URL-stability history | +| protected_branch / protected_tag | 0 | none (walk already recorded this) | +| repo_archiver | 0 | no archive downloads built in the retention window | +| user_blocking | 0 | none | +| audit_event | 0 | unused (table is new in this vintage) | + +**The push-mirror roster** (migration input for OQ-FG-07; ten repos +mirror to GitHub today, all owned by `alkdev`): +`reverse-proxy`, `alknet`, `drizzlebox`, `open-memory`, `open-tasks`, +`operations`, `taskgraph_ts`, `typebox`, `typemap`, `wraith`. Each +carries a remote-name random suffix; the GitHub PAT rides in gitea's +DB (the anti-pattern the family posture replaces via alkvault). + +## 3. The feature catalog (117 tables by feature area) + +Draft disposition per area: `required` (the capability is needed at +full scope), `reshaped` (the capability is required but the family +shape differs materially from gitea's), `dropped` (not needed, with +the anchor evidence), `flagged` (owner question, listed in sect 5). +Dispositions cite their anchor: **W** = family workflows +(`docs/sdd_process.md`), **U** = user classes, **A** = ADR-002/scope/ +posture, **V** = verified usage (walk or sect 2). + +| # | Feature area (tables) | Disposition | Anchor and evidence | +|---|---|---|---| +| 1 | Git hosting core `repository`, `branch`, `collaboration`, `access`, `repo_unit`, `dbfs_*` | **required** | A, V: both git doors are the load-bearing surface (walk sect 3, 5); direct push, arbitrary branches, high churn, private half per identity. `dbfs_*` is gitea-internal storage, not a user feature; alkforge's storage posture is alkstore/alkblobs | +| 2 | URL cosmetics `renamed_branch`, `repo_redirect`, `repo_license`, `repo_topic`, `topic`, `repo_transfer` | **dropped** | V: 0 rows everywhere. Redirects/transfers interact with the inbound-link question (walk sect 8.2): flagged there, not here; rename-without-redirect is a UX nicety the family has never used | +| 3 | Tags/releases `release`, `attachment` | **reshaped** | V: 87 tags org-wide are the release surface; release *objects* (notes/attachments) are 0 and unused. Tags + tag browsing carry the capability; no release machinery | +| 4 | Issues domain `issue`, `issue_*` (8 tables), `label`, `milestone`, `comment`, `reaction`, `tracked_time`, `stopwatch`, `attachment` | **dropped** | V: 0 org-wide across all history (DB-verified both halves). Lens 1 (walk sect 11): review/coordination lives in opencode sessions by design. Gitea-catalog candidate review, not auto-roadmap | +| 5 | PR domain `pull_request`, `pull_auto_merge`, `review`, `review_state` | **dropped** | V: 0 everywhere; review is in-session. Same lens-1 candidate status as #4 | +| 6 | Projects/kanban `project`, `project_board`, `project_issue` | **dropped** | V: unused. Same candidate status | +| 7 | Wiki | **dropped** | V: 0 pages (404s everywhere, walk sect 3); coordination lives in repos and family docs, not a forge wiki | +| 8 | Actions CI `action`, `action_run*` (7), `action_runner*` (2), `action_schedule*` (2), `action_scoped_workflow_source`, `action_task*`, `action_tasks_version`, `action_variable`, `action_artifact`, `secret` | **dropped** | V: 0 runners, 0 runs, 0 workflow files, 0 secrets. Verification happens in-session (W). The family's own research on runners/external compute lives in `/workspace/system/docs/research/` (gitea-actions-runners.md, external-compute-providers.md); that work re-enters only via the requirements review. `commit_status*` (3 tables) is the reporting half of this area: dropped with it | +| 9 | Language stats `language_stat` | **dropped** | V: the walk's live-incident precedent (blob-heavy language detection burning CPU, sect 10.1) is cost without value; the agent-first audience does not read language badges | +| 10 | Webhooks `webhook`, `hook_task` | **dropped** | V: 0. No consumers wired outbound ever | +| 11 | Packages `package*` (7 tables) | **dropped** | V: 0 packages; artifacts move via crates.io + GitHub mirrors, outside the forge | +| 12 | LFS `lfs_lock`, `lfs_meta_object` | **dropped, trigger recorded** | V: unused, heaviest blob ~3.2 MB (walk sect 3). The capability exists in the family stack already (alkgit ADR-022 door on alkblobs); it re-enters on a named trigger (large design media), as a roadmap item with a home, not a hedge | +| 13 | Mirroring `push_mirror`, `mirror` (pull) | **reshaped (push)** / **dropped (pull)** | V: 10 push-mirrors live today (sect 2 roster); owner ideal is all public OSS repos mirrored (walk sect 4). Capability re-homed: alkvault reference, assembly-layer bearer injection (walk sect 4 item 10). Pull-mirroring unused; import-from-URL is a different capability (#14) | +| 14 | Import from external git URLs (+ `task` dashboard-task table) | **required** | V: `typebox`/`typemap` carry full upstream history; migration must preserve import-style histories (walk sect 4), and future imports are ordinary family operation (W). In gitea this rides the migration UI; in alkforge it rides clone-push through the protocol halves; `task` is gitea-internal async-task bookkeeping, not a user feature | +| 15 | Accounts/identity core `user`, `public_key`, `email_address` | **reshaped** | A: identity is alkcall/alkssh fingerprint-resolved, keys in alkvault (AGENTS.md conventions 5, 6); about ten accounts, twelve ed25519 keys (walk sect 10.3). Admin-provisioned only (V: registration disabled). `email_address`: flagged (sect 5, Q3): agents have none | +| 16 | Web sessions `session` | **reshaped** | U/A: alkforge's web view is read-only public in 0.1; any future authenticated web surface gets alkstore-backed sessions with vault-held keying (OQ-FG-04), not gitea's table | +| 17 | Social `follow`, `star`, `watch`, `notice`, `notification`, `user_badge`, `badge`, `upload` | **dropped** | V: 0 everywhere; audience is consumers of code, not social accounts | +| 18 | Auth alternatives `access_token`, `auth_token`, `oauth2_*` (3), `login_source`, `external_login_user`, `gpg_key`, `gpg_key_import`, `user_open_id` | **dropped** | V: 0 tokens, 0 real OAuth apps (stock only), OpenID disabled by design (gitea.md), GPG keys unused (one unverified row). Commit signing, where wanted, happens in sessions, not as a forge service | +| 19 | Second-factor `two_factor`, `webauthn_credential` | **flagged** | V: 0 enrolled. Q1 (sect 5): if alkforge has any authenticated web surface at all, does it want second-factor security, or does the family handle the admin boundary elsewhere | +| 20 | Orgs/teams `org_user`, `team`, `team_invite`, `team_repo`, `team_unit`, `team_user` | **reshaped** | V: one org, everyone in it writes `main` everywhere (walk sect 6); team granularity never used. The simplified owner/org/account model in phase-0 sect 5 carries what is real; `team_*` granularity re-enters only via the requirements review | +| 21 | Push gating `protected_branch`, `protected_tag`, `deploy_key` | **dropped** | V: 0 rows; the coordination model is direct push with no gating (W); deploy keys never used, per-identity keys instead | +| 22 | Search/indexing `repo_indexer_status` | **dropped** | V: unused; agent consumers have local clones. Candidate review can re-add code search later; not a default | +| 23 | Archive download `repo_archiver` | **flagged** | V: 0 built in the retention window; crawl-abuse precedent (walk sect 10.1) argues for care on any new public serving path (OQ-FG-09). Q2 (sect 5) | +| 24 | Audit `audit_event` | **dropped**, capability question moved | V: 0 rows (table is recent). Whether admin/grant actions need an audit trail is a family-posture question (Q4), answered in requirements.md on its own merits, not as a gitea port | +| 25 | User misc `user_setting`, `user_redirect`, `user_blocking`, `email_hash` | **dropped** | V: 0/unused; settings surface has no user population in 0.1 | +| 26 | Internals `app_state`, `system_setting`, `version`, `notice` | **dropped** | gitea bookkeeping, not capabilities; alkforge's config posture is OQ-FG-06 | + +## 4. Disposition summary + +- **Required or reshaped** (the capability set alkforge carries): + git hosting core (#1), tags as releases (#3), push mirroring + (#13), external-history import (#14), accounts/identity (#15), + web sessions (#16), org model (#20). Counted with the walk's + load-bearing list (two doors, minimal web view, branch workflow), + this is the full capability inventory: nothing in gitea's catalog + is simultaneously required and absent from it. +- **Dropped with recorded evidence**: issues/PRs/wiki/projects (#4-7), + Actions CI (#8), language stats (#9), webhooks (#10), packages + (#11), LFS (#12), pull-mirroring (#13), social (#17), auth + alternatives (#18), org-team granularity beyond the simple model + (#20), push gating (#21), code search (#22), audit table (#24), + cosmetics (#2, #25, #26). Dropped items are candidates for the + requirements.md anchor review (walk lens 1 applies: zero usage here + means "not needed in gitea", not "never wanted"); a drop is a + decision with evidence, and re-entry happens only through that + review with a named milestone. +- **Flagged** (owner questions, sect 5): two-factor (#19), archive + downloads (#23), plus the cross-cutting inbound-link (#2) and + audit-trail (#24) capability questions. + +## 5. Flagged questions for owner input + +1. **Authenticated web surface and second factor.** gitea today has + no 2FA and no live sessions, and admin work happens server-side. + If alkforge 0.1 renders a read-only public web view only, the + second-factor question is moot at that milestone. Does the owner + want any authenticated web surface (an admin console, account + self-service) in the visible roadmap at all, and if so with what + security class? Alternatively the whole admin surface could stay + server-side (config + alkstore + alkvault), leaving the web view + permanently unauthenticated. +2. **Archive downloads on the public web view.** Cheap capability, + but it is one more public serving path with the crawl-abuse + precedent attached. In scope for 0.1, later, or not at all? +3. **Email in the account model.** gitea requires email addresses; + the family accounts are agent identities that have none. Does the + human account need one (for what?), or is the account model + email-free? +4. **Admin-action audit trail.** gitea's `audit_event` arrived + recently and is unused here. Separately from gitea entirely: + should identity/grant/config changes in alkforge produce an audit + record (alkstore rows, tracing with bounded retention), or is + standing system-level logging sufficient? + +## 6. What this document is not + +- It is not the final requirements catalog: dispositions here are + draft inputs; `requirements.md` owns the anchored catalog, and the + roadmap/feature map owns anything that survives into future + milestones. +- It is not sizing: door load, traffic pressure, and migration shape + come from the deployment walk. +- It is not a scope assertion for alkforge 0.1: 0.1 is defined by the + roadmap (phase-0 sect 9), not by this survey. diff --git a/docs/research/phase-0.md b/docs/research/phase-0.md index 41a7bae..13447ea 100644 --- a/docs/research/phase-0.md +++ b/docs/research/phase-0.md @@ -17,9 +17,16 @@ This is a **draft**: the sections below record what is already settled by family decisions and published crates, then set up the work items that still need real research. The load-bearing-surface enumeration (§3) has been walked against the live deployment -([`deployment-walk.md`](deployment-walk.md)); the remaining work items -are the web-view disposition (OQ-FG-05), the git round trip (§8.2), -and the SSR spike (§8.3). +([`deployment-walk.md`](deployment-walk.md)), and gitea's full feature +catalog has been enumerated independently of observed usage +([`gitea-feature-survey.md`](gitea-feature-survey.md)). The +requirements work is being re-anchored (2026-11-08): requirements +derive from a vision plus the family's workflows, user classes, and +ADRs, with the walk and the survey serving as sizing and validation +inputs; the checklist (§9) carries the session-sized work items and +their order. The remaining research items are the web-view +disposition (OQ-FG-05), the git round trip (§8.2), and the SSR spike +(§8.3). ## 1. What alkforge is @@ -170,11 +177,19 @@ them): 1. Behavior only: enumerate endpoints, features, and workflows from the outside (what is configured, what is used in logs/configs), never from gitea source (license posture, AGENTS.md convention 13). -2. Every finding lands in one of three buckets: load-bearing (must +2. (Corrected 2026-11-08, the requirements re-anchor, phase-0 sect + 9) Every finding lands in one of three buckets: load-bearing (must appear in the 0.1 spec), inertia (dropped, with a migration note), - deferred (real need, later version). -3. The output becomes the feature-freeze line for alkforge 0.1 and the - migration plan's source of truth. + roadmap (a real capability with a named home: a milestone on the + roadmap, or an explicit decision not to carry it). "Deferred + without a named home" is removed from the vocabulary; zero-usage + features get a "why" before any drop (walk doc's sect 11 + correction lenses). +3. (Corrected 2026-11-08) The walk output sizes the doors the + requirements traverse, supplies the migration plan's source of + truth, and validates the separately derived requirements catalog + against observed reality. The 0.1 freeze line is milestone 1 of + the requirements roadmap, not this walk's output. ## 4. Mapping needs onto the family stack @@ -428,11 +443,39 @@ priority (each run per the POC-placement rules in ## 9. Convergence checklist (what Phase 0 must produce) +Items are session-sized units of work: each gets a focused session +rather than being batched into a broad "finish phase 0" sweep. The +requirements work is re-anchored (2026-11-08): the requirements +catalog, the roadmap, and the 0.1 scope derive from a vision plus the +family's workflows, user classes, and ADRs, with zero version-based +hedging in the derivation (every requirement lands at a named +milestone or is explicitly rejected, with a recorded reason); the +deployment walk and the feature survey serve as sizing and validation +inputs to that derivation, never as its source. + - [x] Load-bearing gitea surface enumerated (OQ-FG-01; §3 template filled with real findings: see [`deployment-walk.md`](deployment-walk.md); residues that need host access are listed there in sect 8) -- [ ] 0.1 feature freeze list agreed from those findings +- [x] Gitea feature catalog enumerated independently of observed + usage, with draft dispositions and owner flags + ([`gitea-feature-survey.md`](gitea-feature-survey.md)); the + flagged questions there (sect 5) get owner answers during the + requirements work +- [ ] `vision.md`: the generalized guiding document (what the forge + is, its user classes, its principles, the long arc toward + alkgit's distributed-platform goal); feeds the requirements + work +- [ ] `requirements.md`: the anchored requirements catalog (each + requirement carrying statement, source, and justification; + dispositions closed-set); the survey's flagged questions and + the gitea-catalog dropped items get their anchor review here +- [ ] Roadmap/feature map in `requirements.md`: milestones as + version-bump feature batches, ordered and justified; detailed + decomposition stays lazy and per-milestone, following the + alkssh implementation-plan wave pattern +- [ ] 0.1 scope dispositioned as milestone 1 of the roadmap + (cutover-capable), superseding the walk-derived freeze framing - [ ] Stack mapping validated (§4) against the real surface; updated with door gaps - [ ] Upstream asks list (OQ-07) finalized and filed in the owning @@ -440,7 +483,9 @@ priority (each run per the POC-placement rules in - [ ] Repo/permission model (§5) and identity wiring settled enough for the Phase 1 spec - [ ] Config/secrets layout (OQ-FG-06) dispositioned -- [ ] Migration path (OQ-FG-07) sketched +- [ ] Migration path (OQ-FG-07) sketched, sized by the walk and the + survey (the survey's push-mirror roster, sect 2, is a direct + input) - [ ] OQ-FG seeds dispositioned or carried to Phase 1's open-questions.md - [ ] Family OQ-06/OQ-07 updates written back to @@ -476,3 +521,8 @@ priority (each run per the POC-placement rules in - Deployment walk findings: [`deployment-walk.md`](deployment-walk.md) (the §3 work item's output; live deployment enumerated 2026-11-07) +- Gitea feature survey: + [`gitea-feature-survey.md`](gitea-feature-survey.md) (the + schema-derived catalog of 28.3.0's feature set; production-db + ground truth of 2026-11-08 incl. the push-mirror roster; draft + dispositions and owner flags for the requirements work)