mirror of
https://github.com/J3vb/OwnCord.git
synced 2026-09-03 03:50:00 +03:00
fix: close the three B0 P0 gates and record a measured baseline (#1409)
* chore(security): stop tracking the private security-finding reports
docs/security-findings/ holds detailed reports for defects that are not yet
fixed. The directory was untracked but not ignored, so any 'git add .' would
have published seven unfixed vulnerability traces to a public repository.
Findings are coordinated through private GitHub Security Advisories
(docs/security.md); only opaque identifiers and safe status belong in tracked
plans.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix(client): repair the two red P0 unit contracts (G-01, G-02)
G-02: noise-suppression-restart stubbed MediaStream with
vi.fn().mockImplementation(arrow), which is not constructible. Vitest 4 threw
'is not a constructor' at the new MediaStream([inputTrack]) call in
noise-suppression.ts before reaching any assertion. Replaced with a real
class; the OC-0277 assertions are unchanged.
G-01: message-list's OC-0217 guard was inverted, not merely stale. It spied on
AbortSignal.prototype.addEventListener and asserted zero abort registrations,
but the leak it names registered row listeners via
element.addEventListener(..., { signal }) — a path that never calls that
prototype method. Measured: the leak produces 0 registrations (test passes),
while the OC-0286 fix rotates a per-window AbortSignal.any and produces 5
across 5 distinct signals (test fails). The guard passed on the bug and failed
on the fix.
It now captures the signal each window's row listeners register against and
asserts the invariant its name always claimed: one signal per rendered window,
a fresh signal per jump, and every superseded window already aborted with
exactly one live. Verified both directions — green on the fix, and
'expected 1 to be 5' with beginRowRender() reverted to rowSignal = ac.signal.
Client suite: 5257 passed, 0 failed (was 5255 passed, 2 failed).
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix(client): make the Playwright suite terminate
The runner finished every test and then never exited, printing no summary — so
the failure read as 'tests never finish' when it was 'process never exits'.
getActiveResourcesInfo() at hang time showed a live ProcessWrap plus several
PipeWrap: the Vite dev server was still running. Playwright's webServer
teardown does not kill it here.
Measured, full suite each time:
npm run dev hangs, tests pass
node node_modules/vite/bin/vite.js hangs, tests pass
reuseExistingServer: false hangs, tests pass
gracefulShutdown SIGTERM/3s hangs, tests pass
npx vite exits, 290 of 293 FAIL
no webServer (pre-started) exits, 293 pass in 33s
npx only appears to fix it: npx exits once Vite is up, Playwright reads that as
the server dying and tears the group down mid-run, so later tests get
ERR_CONNECTION_REFUSED.
globalTeardown now kills the process listening on the dev port, releasing the
runner's handle. The webServer command spawns Vite's entry point directly so
the listening process is Playwright's own child — via 'npm run dev' the npm
process would still hold the handle open. It also reaps servers orphaned by an
interrupted run, which reuseExistingServer would otherwise silently adopt.
An earlier revision used netstat, which is not on PATH in every shell here; the
swallowed ENOENT made the fix look applied while the hang persisted. It now
uses PowerShell on Windows and lsof elsewhere, and warns on failure rather than
failing silently.
npm run test:e2e: exit 0, 293 passed, 37s, reproducible, no orphan listener.
playwright.config.prod.ts carried the same npm-wrapper shape.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* chore(client): align .nvmrc with the Node version CI uses
Three versions were in play, not two: .nvmrc said 20, CI pins 24, and the
machine the audit was measured on runs 26. A baseline measured against .nvmrc
is not the baseline CI produces, which defeats the point of B0.
Scoped to .nvmrc only. The full single-source-of-truth work — package engines,
contributor docs, release — stays in B1 (RL-17 / C-01).
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* docs(plans): add the beta audit set and the B0 baseline
The 2026-08-23 audit set has been sitting untracked: repository-health and
repository-layout audits, beta product requirements, requirement traceability,
the issue register, and the B0-B10 roadmap. They are the plan of record for
beta and belong in the repository.
Adds b0-baseline-2026-08-25.md, which supersedes the roadmap's 'current
evidence snapshot'. Every row is marked measured or carried, so nothing is
inherited silently. It also records three audit claims that did not survive
verification:
- G-01 was an inverted guard, not a stale assertion — it passed on the bug
and failed on the fix.
- The Playwright hang matched none of the three hypotheses; the runner could
not kill its own dev server.
- The golangci-lint toolchain failure is refuted: 19 linters run, 0 issues,
verified with -v to rule out the known zero-linters false-green.
Adds b0-dev-branch-protection.sh, which records the applied dev branch
protection and the reasoning behind each setting.
Security detail stays private: the register carries only opaque SEC-* families
and safe closure criteria, per the roadmap's public/private handling policy.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* chore(graphify): refresh the knowledge graph
Own commit, per CLAUDE.md — the graph payload does not belong in the diff of
the changes that triggered it.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* docs(plans): add the active-plan index and fix a stale status header (G-04)
Planning documents had no recorded state, so a reader could not tell current
guidance from shipped history. docs/plans/README.md now indexes every plan as
active, partially implemented, design-only, or shipped, and names the source of
truth for each concern so a defect count is never read out of a plan.
Status is recorded in the index rather than by moving or rewriting the
historical plans, so links from audits and commit messages keep resolving.
One real stale claim found and fixed: audit-2026-08-19-remediation.md still
read 'in progress 2026-08-19' while its own phase table showed phases 1-6 done
2026-08-20 (merged 03fcb7d5, PR #1396) with only phase 7 pending. The header
had drifted because the table was updated in place and the header was not.
No plan was found claiming '0 open findings'.
Also records the Step 8 staleness pass in the B0 baseline: all 38 open OC
records still resolve to a live file:line at this commit, so none is superseded
by later work. Adjudicating them individually is bughunt-fix work, not B0.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* Update graph output files and manifest with new metadata
- Updated graph.html and graph.json with new binary data.
- Modified manifest.json to reflect changes in file modification times and AST hashes for several documents.
- Added new entry for README.md in the manifest with its corresponding metadata.
* docs(plans): close the Docker and coverage leftovers in the B0 baseline
Docker smoke: measured and passing. Image builds at 50.1 MB and boots on :8443
with TLS; docker-smoke.sh exits 0.
Server coverage: re-measured at 74.6% aggregate, confirming the figure carried
from the audit rather than continuing to inherit it.
Two findings from doing it:
ENV-03 — docker-smoke.sh cannot be run from Git Bash on Windows. MSYS path
conversion rewrites the container-internal /chatserver into
'C:/Program Files/Git/chatserver', so docker exec fails 127 and the script
reports 'container never reported healthy within 30s' — indistinguishable from
a real boot regression. MSYS_NO_PATHCONV=1 makes the same script pass. CI is
Linux and unaffected, but Windows is an official contributor platform (RL-20).
The CI Docker job is gated on main, so it is skipped for any PR targeting dev
— a dev-targeted change cannot get Docker evidence from CI at all.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* chore(graphify): refresh the knowledge graph
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -28,6 +28,12 @@ docs/research/
|
||||
docs/superpowers/
|
||||
/skills/
|
||||
|
||||
# Detailed security reports for findings that are not yet fixed. This repo is
|
||||
# public (docs/security.md): reproduction traces for a live defect must never
|
||||
# be committed. Findings are coordinated through private GitHub Security
|
||||
# Advisories; only opaque identifiers and safe status go in tracked plans.
|
||||
docs/security-findings/
|
||||
|
||||
# Mutation-testing output (npm run test:mutate). Local-only by design: a
|
||||
# surviving-mutant report maps exactly which behaviour nothing tests.
|
||||
Client/tauri-client/.stryker-tmp/
|
||||
|
||||
@@ -1 +1 @@
|
||||
20
|
||||
24
|
||||
|
||||
@@ -40,7 +40,10 @@ export default defineConfig({
|
||||
],
|
||||
|
||||
webServer: {
|
||||
command: "npm run preview",
|
||||
// Spawn Vite directly rather than through npm — see the note in
|
||||
// playwright.config.ts: an `npm run` wrapper leaves vite alive as an
|
||||
// orphaned grandchild on teardown and the runner never exits.
|
||||
command: "npx vite preview",
|
||||
url: "http://localhost:4173",
|
||||
reuseExistingServer: !process.env.CI,
|
||||
timeout: 60_000,
|
||||
|
||||
@@ -43,8 +43,16 @@ export default defineConfig({
|
||||
},
|
||||
],
|
||||
|
||||
// Kills the dev server the runner cannot kill itself; without it the suite
|
||||
// passes and then hangs forever. See tests/e2e/global-teardown.ts.
|
||||
globalTeardown: "./tests/e2e/global-teardown.ts",
|
||||
|
||||
webServer: {
|
||||
command: "npm run dev",
|
||||
// Run Vite's entry point directly so the listening process IS Playwright's
|
||||
// child — globalTeardown kills the listener, which only releases the
|
||||
// runner's ChildProcess handle if that listener is the child itself. Going
|
||||
// through `npm run dev` would leave the npm process holding it open.
|
||||
command: "node node_modules/vite/bin/vite.js",
|
||||
url: "http://localhost:1420",
|
||||
reuseExistingServer: !process.env.CI,
|
||||
timeout: 60_000,
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
import { execFileSync } from "node:child_process";
|
||||
|
||||
/**
|
||||
* Force-kill the dev server Playwright leaves running, so the runner can exit.
|
||||
*
|
||||
* Playwright's own `webServer` teardown does not stop the Vite dev server on
|
||||
* Windows. After the last test the runner still holds a live ChildProcess
|
||||
* handle plus its stdio pipes (`process.getActiveResourcesInfo()` reports
|
||||
* `ProcessWrap` + several `PipeWrap`), the event loop never drains, and
|
||||
* `playwright test` hangs forever with the whole suite already passed —
|
||||
* printing no summary, which is why the failure looked like "tests never
|
||||
* finish" rather than "process never exits".
|
||||
*
|
||||
* Every in-Playwright workaround was tried and failed the same way: spawning
|
||||
* through `npm run dev`, spawning Vite's entry point directly,
|
||||
* `reuseExistingServer: false`, and `gracefulShutdown`. Spawning through `npx`
|
||||
* appears to fix it only because npx exits as soon as Vite is up; Playwright
|
||||
* reads that as the server dying, tears the group down mid-run, and every
|
||||
* later test fails with ERR_CONNECTION_REFUSED.
|
||||
*
|
||||
* Killing the listener here closes the runner's handle so the process exits
|
||||
* normally. It also reaps servers orphaned by an earlier interrupted run,
|
||||
* which `reuseExistingServer` would otherwise silently adopt.
|
||||
*
|
||||
* Failing to kill must not fail an otherwise green suite, but it must not be
|
||||
* silent either: an earlier revision used `netstat`, which is not on PATH in
|
||||
* every shell here, and the swallowed ENOENT made this look fixed when the
|
||||
* hang was still present.
|
||||
*/
|
||||
const BASE_URL = process.env.PLAYWRIGHT_BASE_URL ?? "http://localhost:1420";
|
||||
|
||||
export default function globalTeardown(): void {
|
||||
const port = Number(new URL(BASE_URL).port);
|
||||
if (!Number.isInteger(port) || port <= 0) return;
|
||||
try {
|
||||
if (process.platform === "win32") {
|
||||
killListenerWindows(port);
|
||||
} else {
|
||||
killListenerPosix(port);
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn(
|
||||
`[global-teardown] could not stop the dev server on port ${port}; ` +
|
||||
`the runner may hang. ${String(error)}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Children first, then the listener itself: Vite spawns esbuild, which
|
||||
* inherits the stdio pipes the runner is waiting on.
|
||||
*/
|
||||
function killListenerWindows(port: number): void {
|
||||
execFileSync(
|
||||
"powershell",
|
||||
[
|
||||
"-NoProfile",
|
||||
"-NonInteractive",
|
||||
"-Command",
|
||||
`$ids = @(Get-NetTCPConnection -LocalPort ${port} -State Listen -ErrorAction SilentlyContinue |` +
|
||||
` Select-Object -ExpandProperty OwningProcess -Unique);` +
|
||||
` foreach ($id in $ids) {` +
|
||||
` Get-CimInstance Win32_Process -Filter "ParentProcessId=$id" -ErrorAction SilentlyContinue |` +
|
||||
` ForEach-Object { Stop-Process -Id $_.ProcessId -Force -ErrorAction SilentlyContinue };` +
|
||||
` Stop-Process -Id $id -Force -ErrorAction SilentlyContinue }`,
|
||||
],
|
||||
{ stdio: "ignore" },
|
||||
);
|
||||
}
|
||||
|
||||
function killListenerPosix(port: number): void {
|
||||
const out = execFileSync("lsof", ["-ti", `tcp:${port}`, "-sTCP:LISTEN"], {
|
||||
encoding: "utf8",
|
||||
});
|
||||
for (const pid of new Set(out.split(/\s+/).filter(Boolean).map(Number))) {
|
||||
if (Number.isInteger(pid) && pid > 0) {
|
||||
try {
|
||||
process.kill(pid, "SIGKILL");
|
||||
} catch {
|
||||
// Already gone.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -252,27 +252,55 @@ describe("MessageList", () => {
|
||||
expect(container.querySelector('[data-testid="message-150"]')).not.toBeNull();
|
||||
});
|
||||
|
||||
it("OC-0217: repeated jumps do not each register a permanent abort listener on the component-lifetime signal", () => {
|
||||
it("OC-0217/OC-0286: repeated jumps do not each register a permanent row listener on the component-lifetime signal", () => {
|
||||
// As a user clicking a reply bar's jump arrow, a search hit, or a pinned
|
||||
// entry repeatedly does across a live session.
|
||||
const messages = Array.from({ length: 10 }, (_, i) => makeMessage({ id: i + 1 }));
|
||||
setMessages(1, messages);
|
||||
msgList.mount(container);
|
||||
|
||||
// Row listeners are registered as addEventListener(type, fn, { signal }).
|
||||
// Installed after mount() so it only observes what scrollToMessage does,
|
||||
// not mount's own (single, expected) abort registration.
|
||||
const addEventListenerSpy = vi.spyOn(AbortSignal.prototype, "addEventListener");
|
||||
// not mount's own (single, expected) registrations.
|
||||
const addEventListenerSpy = vi.spyOn(EventTarget.prototype, "addEventListener");
|
||||
|
||||
for (let i = 1; i <= 5; i++) {
|
||||
expect(msgList.scrollToMessage(i)).toBe(true);
|
||||
/** Distinct AbortSignals handed to row listeners since the previous call. */
|
||||
function rowSignalsSinceLastRender(): AbortSignal[] {
|
||||
const signals = addEventListenerSpy.mock.calls
|
||||
.map((call) => call[2])
|
||||
.filter(
|
||||
(opts): opts is AddEventListenerOptions =>
|
||||
typeof opts === "object" && opts !== null && "signal" in opts,
|
||||
)
|
||||
.map((opts) => opts.signal)
|
||||
.filter((signal): signal is AbortSignal => signal != null);
|
||||
addEventListenerSpy.mockClear();
|
||||
return [...new Set(signals)];
|
||||
}
|
||||
|
||||
// Each jump's highlight-flash cleanup must not add a new listener to the
|
||||
// whole-lifetime AbortSignal — that accumulates one listener (and pins
|
||||
// one detached row element through its closure) per jump, released only
|
||||
// when the channel unmounts, not when that jump's flash finishes.
|
||||
const abortRegistrations = addEventListenerSpy.mock.calls.filter(([type]) => type === "abort");
|
||||
expect(abortRegistrations.length).toBe(0);
|
||||
const windowSignals: AbortSignal[] = [];
|
||||
for (let i = 1; i <= 5; i++) {
|
||||
expect(msgList.scrollToMessage(i)).toBe(true);
|
||||
const [signal, ...extra] = rowSignalsSinceLastRender();
|
||||
// Every row in a rendered window shares that window's single signal.
|
||||
expect(extra).toHaveLength(0);
|
||||
if (signal === undefined) throw new Error(`jump ${i} rendered no row listeners`);
|
||||
windowSignals.push(signal);
|
||||
}
|
||||
|
||||
// Each jump renders against a fresh signal, so nothing accumulates row
|
||||
// listeners on one long-lived signal.
|
||||
expect(new Set(windowSignals).size).toBe(windowSignals.length);
|
||||
|
||||
// A superseded window is released by the render that replaced it, not
|
||||
// deferred to destroy(). Before OC-0286 rows registered directly against
|
||||
// the component-lifetime signal (`ac.signal`), so all five of these would
|
||||
// still be live here, each pinning a whole window of detached rows and
|
||||
// everything they reference — videos, images, embeds, tooltips.
|
||||
const superseded = windowSignals.slice(0, -1);
|
||||
const current = windowSignals[windowSignals.length - 1];
|
||||
expect(superseded.every((signal) => signal.aborted)).toBe(true);
|
||||
expect(current?.aborted).toBe(false);
|
||||
|
||||
addEventListenerSpy.mockRestore();
|
||||
});
|
||||
|
||||
@@ -60,9 +60,19 @@ function makeFakeAudioContext() {
|
||||
|
||||
describe("createRNNoiseProcessor restart (OC-0277)", () => {
|
||||
beforeEach(() => {
|
||||
// Must be a real constructor: noise-suppression.ts calls
|
||||
// `new MediaStream([inputTrack])` before handing the result to the (mocked,
|
||||
// argument-ignoring) createMediaStreamSource. A vi.fn() whose
|
||||
// implementation is an arrow function is not constructible, so Vitest 4
|
||||
// throws "is not a constructor" there instead of running the assertions.
|
||||
vi.stubGlobal(
|
||||
"MediaStream",
|
||||
vi.fn().mockImplementation((tracks: unknown[]) => ({ tracks })),
|
||||
class {
|
||||
tracks: unknown[];
|
||||
constructor(tracks: unknown[] = []) {
|
||||
this.tracks = tracks;
|
||||
}
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@@ -0,0 +1,130 @@
|
||||
# OwnCord full repository-health audit
|
||||
|
||||
**Audited:** 2026-08-23
|
||||
**Audited head:** `5cc0888964e26276d1aca145e83270a2c1b9febd` (`dev`)
|
||||
**Conclusion:** strong server foundation; not beta-ready
|
||||
|
||||
## Executive status
|
||||
|
||||
OwnCord is in a promising but pre-beta state. The server is the stronger half:
|
||||
its principal build, race, deadlock, tagged-test, and vet gates pass. The
|
||||
client has a substantial desktop foundation, but its required unit-coverage
|
||||
gate is red and its full Playwright process does not terminate. The approved
|
||||
browser/PWA/phone/tablet product is mostly still a planned workstream.
|
||||
|
||||
| Area | Status | Evidence-based conclusion |
|
||||
| ---------------------- | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| Server core | Strong / amber | Builds and concurrency-oriented tests pass; coverage is 74.6%; architecture, security boundaries, capacity, and operations still need work. |
|
||||
| Desktop client | Amber-red | TypeScript, build, static checks, Rust checks, and browser smoke pass; 5,255 unit tests pass but 2 fail, and Playwright does not exit cleanly. |
|
||||
| Browser/PWA/mobile | Red | No production browser target, optional server-hosted bundle, PWA lifecycle, Web Push, or beta-quality mobile navigation is complete. |
|
||||
| Security/privacy | Red / pending | Private current-head security evidence contains unresolved work. The restarted independent deep scan was not sealed because it produced no manifest or result before the audit budget limit. |
|
||||
| CI/release/platforms | Amber-red | Signing, checksums, source snapshots, and cold-boot foundations are good; exact-SHA dev evidence, ARM64 coverage, multi-architecture Docker, and native release qualification remain incomplete. |
|
||||
| Repository/community | Amber | Server/client separation is understandable; a focused client-layout and contributor-experience migration is justified. |
|
||||
| Overall beta readiness | Red | Do not publish the public beta from this head. |
|
||||
|
||||
## Validation evidence
|
||||
|
||||
### Server
|
||||
|
||||
- Default, OpenTelemetry, Wazero-tagged WASM runtime, and combined builds pass.
|
||||
- `go vet`, the full race suite, deadlock tests, and tag-gated tests pass.
|
||||
- CI-style aggregate coverage is 74.6%; there are many tests and fuzz targets,
|
||||
but no benchmark baseline for the highest-risk hot paths.
|
||||
- Docker validation was unavailable locally because no Docker daemon was
|
||||
attached. Local `golangci-lint` could not load because its binary and module
|
||||
toolchains differed; this needs matched-tool or CI evidence.
|
||||
- Structural debt remains in large hub/serve/lifecycle files and numerous
|
||||
direct database call sites.
|
||||
|
||||
### Client
|
||||
|
||||
- Application and E2E typechecks, ESLint, Prettier, Knip, production npm audit,
|
||||
Vite build, Rust Clippy, and 115 Rust tests pass.
|
||||
- Vitest coverage is red: 5,255 passed and 2 failed in the message-list and
|
||||
noise-suppression restart contracts.
|
||||
- Three direct Chromium browser tests pass, but this is a narrow API harness,
|
||||
not a production browser client.
|
||||
- The 293-test Playwright journey reaches its test activity but does not exit;
|
||||
an isolated five-test voice-widget run also hangs.
|
||||
- Oxlint exits successfully but reports 471 warnings. The largest lazy feature
|
||||
output is approximately 2.0 MB minified / 1.345 MB gzip, with additional
|
||||
oversized-chunk and dynamic-import warnings.
|
||||
|
||||
### Repository and release
|
||||
|
||||
- The audited SHA has no GitHub Actions run, so local evidence is not an
|
||||
exact-SHA integration qualification.
|
||||
- The release workflow has good signing, checksum, source-snapshot, and
|
||||
server-cold-boot foundations, but the approved Windows/Linux ARM64 and
|
||||
multi-architecture Docker matrix is not complete.
|
||||
- Node guidance is inconsistent (`.nvmrc` 20 versus CI 24); the repository
|
||||
needs one enforced version source.
|
||||
- Generated graph/ledger artifacts, protocol ownership, tool discovery, hooks,
|
||||
issue intake, and externally triggered automation all need explicit policy.
|
||||
|
||||
## Product gaps that block beta
|
||||
|
||||
The approved requirements require server-hosted browser support disabled by
|
||||
default, shared desktop/browser contracts, PWA installation, phones/tablets,
|
||||
opt-in per-server Web Push, N/N-1/N-2 protocol epochs, recovery kits, session
|
||||
alerts and sign-out-everywhere, deletion that survives restore, configurable
|
||||
retention, Message Requests, moderation reports/appeals, NSFW no-fetch-before-
|
||||
consent, translation-ready English text, and the full release architecture
|
||||
matrix. Most of these are absent or only partial today.
|
||||
|
||||
## Repository structure decision
|
||||
|
||||
A targeted migration is justified, not a rewrite:
|
||||
|
||||
1. Flatten `Client/tauri-client/` to `Client/` in adjacent pure-move and
|
||||
mechanical-path-rewrite commits.
|
||||
2. Keep one shared UI and add typed desktop/browser platform contracts later in
|
||||
B7, after server-first contracts and services are stable.
|
||||
3. Keep `Server/` and its package tree stable.
|
||||
4. Make protocol schema, generated artifacts, tools, hooks, and contributor
|
||||
commands explicit and reproducible.
|
||||
|
||||
## Deployment constraints that must be designed into beta
|
||||
|
||||
Public domains and eligible stable public IPs can use built-in ACME. Private
|
||||
or reserved LAN addresses cannot receive public-CA certificates and require a
|
||||
server-local CA plus one-time trust installation on each browser device. Web
|
||||
service workers, media capture, screen sharing, and Push API behavior require a
|
||||
secure context in normal browser use. See the [Let’s Encrypt IP certificate
|
||||
guidance](https://letsencrypt.org/2026/01/15/6day-and-ip-general-availability),
|
||||
[ACME challenges](https://letsencrypt.org/docs/challenge-types/), and [W3C
|
||||
secure-context standards](https://www.w3.org/TR/secure-contexts/).
|
||||
|
||||
Fully offline browser use can work after local trust onboarding, but closed-app
|
||||
Web Push cannot be treated as an offline capability. CGNAT, blocked ports, and
|
||||
changing raw IP origins remain operator/network limitations rather than bugs
|
||||
OwnCord can hide.
|
||||
|
||||
## Phased route
|
||||
|
||||
The approved execution sequence is B0–B10:
|
||||
|
||||
`B0 truth → B1 repository foundation → B2 protocol/trust → B3 server guardrails → B4 identity/privacy → B5 community/moderation → B6 deployment/capacity → B7 shared desktop platform → B8 browser/PWA/mobile → B9 unified UX/accessibility → B10 qualification/public release`
|
||||
|
||||
No phase closes on elapsed time. Each phase requires exact-SHA evidence, and
|
||||
B10 additionally requires a complete platform/deployment matrix, migration,
|
||||
restore, rollback, security, accessibility, capacity, and release scorecard.
|
||||
|
||||
## Audit artifacts
|
||||
|
||||
- [Beta product requirements](plans/beta-product-requirements-2026-08-23.md)
|
||||
- [Exhaustive issue register](plans/repo-health-issue-register-2026-08-23.md)
|
||||
- [Server-first roadmap](plans/repo-health-roadmap-2026-08-23.md)
|
||||
- [Requirement traceability](plans/beta-requirements-traceability-2026-08-23.md)
|
||||
- [Repository-layout audit](audit-2026-08-23-repository-layout.md)
|
||||
|
||||
The detailed reports under `docs/security-findings/` are intentionally
|
||||
untracked/private and must not be committed to a public repository before
|
||||
coordinated remediation.
|
||||
|
||||
## Recommended first implementation slice
|
||||
|
||||
Begin B0 only: repair the two failing unit contracts, make Playwright terminate
|
||||
reliably, obtain matched lint/Docker evidence, reconcile private security
|
||||
findings, and run the full exact-SHA matrix. Then perform the isolated B1
|
||||
repository migration before implementing new client features.
|
||||
@@ -0,0 +1,175 @@
|
||||
# OwnCord repository-layout and contributor-experience audit
|
||||
|
||||
**Audited:** 2026-08-23
|
||||
**Audited head:** `5cc0888964e26276d1aca145e83270a2c1b9febd` (`dev`)
|
||||
**Decision:** a targeted, isolated layout phase is justified; a wholesale
|
||||
repository or server rewrite is not
|
||||
**Product input:**
|
||||
[beta-product-requirements-2026-08-23.md](plans/beta-product-requirements-2026-08-23.md)
|
||||
**Canonical work register:**
|
||||
[repo-health-issue-register-2026-08-23.md](plans/repo-health-issue-register-2026-08-23.md)
|
||||
|
||||
## Executive verdict
|
||||
|
||||
OwnCord's top-level server/client separation is understandable and the Go
|
||||
server's package layout is generally healthy. The repository does not need a
|
||||
monorepo rewrite, a `Server/` rename, or broad movement of historical documents.
|
||||
|
||||
A smaller structural phase is worthwhile before beta feature work because the
|
||||
new browser/PWA requirement exposes a real boundary problem: the only client is
|
||||
nested and named as Tauri-specific, while the shared frontend directly imports
|
||||
native Tauri APIs in at least 20 production files. Contributor entry points,
|
||||
branch automation, release coverage, generated artifacts, and active-document
|
||||
navigation also need consolidation.
|
||||
|
||||
The structural work must be mechanical and independently reversible. File
|
||||
moves and path rewrites must not contain functional changes, and the later
|
||||
platform-boundary extraction must preserve behavior behind tests before adding
|
||||
the browser implementation.
|
||||
|
||||
Priorities follow the health register: P0 is a red required gate, P1 must close
|
||||
before beta, and P2 is scheduled architecture, quality, or operational debt.
|
||||
|
||||
## What should remain stable
|
||||
|
||||
- Keep `Server/` and its existing domain packages. Later hotspot extraction is
|
||||
architecture work, not repository layout work.
|
||||
- Keep existing release asset names and updater contracts so alpha-to-beta
|
||||
upgrades do not break.
|
||||
- Keep one shared client UI, store, protocol, and domain implementation. Do not
|
||||
fork a second web application.
|
||||
- Keep build-required generated sources committed: sqlc output, generated
|
||||
protocol types, Tauri-generated bindings, and runtime assets required by a
|
||||
release build.
|
||||
- Keep historical audits and plans at their existing paths. Index their status
|
||||
instead of moving them and breaking references.
|
||||
- Keep the canonical findings ledger until a deliberate tracker migration
|
||||
provides equivalent history and validation.
|
||||
|
||||
## Recommended target
|
||||
|
||||
```text
|
||||
Client/
|
||||
package.json
|
||||
src/
|
||||
platform/
|
||||
contracts/
|
||||
browser/
|
||||
desktop/
|
||||
src-tauri/
|
||||
tests/
|
||||
Server/
|
||||
protocol/
|
||||
schema.json
|
||||
deploy/
|
||||
docs/
|
||||
README.md
|
||||
plans/
|
||||
tools/
|
||||
```
|
||||
|
||||
The current `Client/tauri-client/` content should be flattened into `Client/`
|
||||
as two adjacent non-functional commits: first pure file moves, then mechanical
|
||||
rewrites of active paths. `Client/` has no other tracked child, and the current
|
||||
name incorrectly implies that browser/PWA support should become a separate
|
||||
application. The capitalized `Client/` and `Server/` names may remain: changing
|
||||
both for style alone would create widespread path churn without improving a
|
||||
runtime or contributor boundary.
|
||||
|
||||
The protocol schema is executable cross-component source and should move from
|
||||
`docs/protocol-schema.json` to a small root `protocol/` boundary. Documentation
|
||||
continues to explain the contract, while root tooling owns generation for both
|
||||
consumers.
|
||||
|
||||
## Findings
|
||||
|
||||
| ID | Pri | Finding | Required disposition |
|
||||
| ----- | --: | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| RL-01 | P1 | All tracked client content is under the redundant `Client/tauri-client/` level, and active automation/documentation hard-code that path. The name is misleading now that browser/PWA is approved. | Flatten to `Client/` in two adjacent non-functional commits—pure moves, then active-path rewrites—and leave historical evidence untouched. |
|
||||
| RL-02 | P1 | At least 20 frontend files directly import `@tauri-apps/*`; API, WebSocket, credentials, profiles, notifications, media, LiveKit, updates, logs, and window state do not have a browser-neutral platform seam. | Record the target boundary during the layout phase, then introduce typed `platform/contracts`, `platform/desktop`, and `platform/browser` ownership in client phase B7. Add contract tests that run against both adapters. |
|
||||
| RL-03 | P1 | The Vite configuration contains Tauri-specific HTML transformation, and there is no independent browser/PWA production build contract. | In client phase B7, split shared build configuration from target adapters and add explicit `build:web` and `build:desktop` gates using one application source tree. |
|
||||
| RL-04 | P2 | Root `package.json` exposes release and hook commands but no discoverable bootstrap, format, generated-code, server, client, or full verification entry points. | Add a cross-platform root command facade. Decide workspace consolidation from measured install/lockfile behavior rather than requiring Node for ordinary Go-only work. |
|
||||
| RL-05 | P2 | Three JavaScript package/lock roots are maintained separately, while dependency automation does not cover all of them. | Either adopt a documented npm workspace or add complete per-package automation; retain component-local commands and deterministic lockfile installs. |
|
||||
| RL-06 | P2 | Tracked `graphify-out/` is about 20 MB, led by a roughly 19.3 MB generated JSON graph. Portable regeneration was not demonstrated in this audit environment because the available launcher failed before a query could run. Repeated refreshes grow normal Git history. | Stop tracking large graph payloads after providing a portable regeneration command and CI/release artifact. Do not rewrite published history. A compact architecture report may remain if it is mechanically verified. |
|
||||
| RL-07 | P2 | `.superpowers/FINDINGS.md` duplicates the canonical ledger as a large generated rendering. The canonical JSON ledger remains necessary today. | Keep the authoritative JSON ledger, remove the tracked human rendering after a drift check exists, and generate it on demand or as a downloadable CI artifact. |
|
||||
| RL-08 | P2 | A prebuilt example `hello.wasm` is committed for a plugin system that is experimental and disabled, without a source-drift verification gate. | Keep its source, stop tracking the prebuilt example, and compile/verify it deterministically in CI or release checks without making an API compatibility promise. |
|
||||
| RL-09 | P2 | Cross-component protocol source lives under `docs/`, while a server-owned generator writes both Go and TypeScript consumers. | Move the schema/generator entry point to the root protocol/tool boundary and verify both generated outputs from one command. |
|
||||
| RL-10 | P1 | `Server/scripts/seed.go` is included in broad Go package discovery and its initialization creates a runtime data directory during test discovery. | Move executable tools under a conventional `cmd/` or tool package and remove import/test-time filesystem side effects. |
|
||||
| RL-11 | P2 | A client “unit” test reads server admin HTML directly, hiding a cross-component contract inside the wrong ownership and test tier. | Move the invariant to the owning server test or a clearly named root contract/system-test tier. Inventory siblings before moving only one file. |
|
||||
| RL-12 | P2 | There is no canonical docs landing page that distinguishes active guidance, reference material, historical audits, and superseded plans. Active files also disagree about Node and branch policy. | Add `docs/README.md` and a plan index; mark status without relocating historical evidence. Generate or check high-value version/branch/platform facts. |
|
||||
| RL-13 | P2 | The Go module declares `github.com/owncord/server`, while the public repository is `github.com/J3vb/OwnCord`. | Align the module to `github.com/J3vb/OwnCord/Server` in an isolated mechanical change and verify every import, generator, build tag, source archive, and downstream instruction. |
|
||||
| RL-14 | P0 | `dev` can receive direct commits without an exact-SHA CI run because push CI covers `main`, while `dev` relies on PR or manual events. | Add protected PR-only integration or run the complete blocking matrix for every `dev` push. This duplicates G-03 and must map to one canonical issue. |
|
||||
| RL-15 | P1 | Release automation does not cover the approved platform matrix: Windows ARM64 client/server, Linux ARM64 server, and multi-architecture Docker publication are missing. | Add build, package, install/boot smoke, signing, manifest, and update checks for all BPR-010/BPR-011 targets. |
|
||||
| RL-16 | P1 | A version tag can start publication without proving that the exact tagged commit completed the full beta gate. | Couple release publication to green exact-SHA evidence and a protected release approval; retain current version, signature, checksum, cold-boot, and source-snapshot strengths. |
|
||||
| RL-17 | P1 | Client `.nvmrc` and active contributor docs say Node 20 while CI/release use Node 24; package metadata does not enforce the intended Node/npm versions. | Establish one Node 24 source of truth read by local setup, packages, CI, release, and documentation. This duplicates C-01 and must map to one canonical issue. |
|
||||
| RL-18 | P1 | Dependency automation omits root tooling, `tools/mcp-introspect`, and Docker; runtime/build containers use mutable tags. | Cover every dependency root, pin or automatically review container digests, and produce signed SBOM/provenance evidence for releases. |
|
||||
| RL-19 | P2 | Formatting/lint coverage omits material Markdown, YAML, JSON, CSS, Rust formatting, repository-wide Go formatting, shell scripts, and workflow syntax. There is no root `.editorconfig`. | Add fast, cross-platform format and repository-lint gates with generated/vendor exclusions and one editor baseline. |
|
||||
| RL-20 | P2 | Committed hooks are POSIX shell and invoke `make`, but Windows is an official contributor platform without those prerequisites being explicit. | Make hooks thin optional wrappers around cross-platform root commands and document any Git Bash dependency until removed. |
|
||||
| RL-21 | P2 | Community intake does not match the approved model: feature requests still become Issues, and bug forms omit browser/PWA, ARM64, deployment mode, and architecture detail. | Route ideas/feedback to Discussions and modernize bug forms, PR guidance, contributor entry points, and support links. |
|
||||
| RL-22 | P1 | Authorization for externally triggered paid repository automation is not sufficiently constrained. | Limit execution to explicitly trusted maintainers, retain least-privilege permissions, add cost-abuse regression tests, and keep the concrete pre-fix mechanism private. |
|
||||
|
||||
## Strong foundations to preserve
|
||||
|
||||
- CI already exercises Go build tags, race/deadlock behavior, TypeScript/Rust
|
||||
checks, a limited browser harness, mocked-desktop Playwright, Docker smoke,
|
||||
vulnerability checks, and coverage artifacts. These are foundations, not
|
||||
evidence that a production browser/PWA client exists.
|
||||
- GitHub Actions are SHA-pinned and generally use narrow permissions.
|
||||
- Release automation already checks version agreement, cold-boots the built
|
||||
server, signs metadata, verifies signatures, generates checksums, and
|
||||
publishes an AGPL source snapshot.
|
||||
- `.gitattributes` enforces stable line endings and ignore files cover most
|
||||
ordinary build/runtime output.
|
||||
- Component documentation is detailed; the primary problem is discoverability
|
||||
and stale duplicated facts, not absence of technical knowledge.
|
||||
|
||||
## Isolated implementation sequence
|
||||
|
||||
1. Restore the two currently red client test contracts, make the full and
|
||||
isolated Playwright runs terminate after completion, and establish the exact
|
||||
baseline checks. Structural validation must start green.
|
||||
2. Add the docs/plan index and root cross-platform command facade, then align
|
||||
Node 24 and branch/CI truth.
|
||||
3. Relocate or stop tracking non-product generated artifacts after their
|
||||
replacement generation/artifact paths are proven.
|
||||
4. Flatten `Client/tauri-client/` to `Client/` as two adjacent commits in one
|
||||
PR: pure file moves, then mechanical active-path rewrites. Neither commit
|
||||
changes behavior.
|
||||
5. Record the browser-neutral contract map and owners. Implement the adapters,
|
||||
native extraction, and web production build later in client phase B7 after
|
||||
the server-first phases close.
|
||||
6. Move protocol ownership to the root and verify both generated consumers.
|
||||
7. Reclassify cross-stack tests and executable tools; remove test-time
|
||||
filesystem side effects.
|
||||
8. Correct platform/release/dependency automation independently of the moves.
|
||||
9. Run the full server, client, Rust, browser, generated-code, Docker, and
|
||||
release-path matrix on the exact resulting SHA.
|
||||
|
||||
## Exit gate
|
||||
|
||||
- a fresh Windows or Linux contributor can find one setup path and run scoped
|
||||
or full checks without guessing directories;
|
||||
- existing desktop behavior and release/update names are unchanged;
|
||||
- the browser-neutral contract design, owners, and B7 validation plan are
|
||||
approved without prematurely refactoring client runtime behavior;
|
||||
- every supported release architecture has an owned automation path;
|
||||
- every active commit on `dev` has exact-SHA CI evidence;
|
||||
- generated sources and large analysis artifacts have explicit, reproducible,
|
||||
separately verified ownership;
|
||||
- no active documentation contradicts branch, Node, platform, support, plugin,
|
||||
or beta-scope policy;
|
||||
- the complete baseline is green and the worktree contains no accidental build
|
||||
or generated output.
|
||||
|
||||
## Migration risks and controls
|
||||
|
||||
| Risk | Control |
|
||||
| --------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| Hard-coded client paths are missed | Inventory active references before the move; run workflow, hook, generator, docs-link, package, and release-manifest checks afterward. |
|
||||
| Browser and desktop behavior diverge | One shared application plus tested platform contracts; no copied feature implementations. |
|
||||
| Root tooling makes Node mandatory for server contributors | Keep direct Go commands supported and make the root facade a convenience/orchestration layer. |
|
||||
| Release or updater compatibility breaks | Do not rename binaries/assets; smoke installation, update manifests, signatures, and in-place upgrades. |
|
||||
| Rename obscures functional review | Pure-move and mechanical-path-rewrite commits are followed by separately reviewed adapter changes. |
|
||||
| Generated analysis output disappears without replacement | Prove local generation and downloadable CI artifacts before untracking; retain published Git history. |
|
||||
|
||||
No production source was moved or changed during this audit.
|
||||
@@ -0,0 +1,75 @@
|
||||
# Plan index
|
||||
|
||||
Closes G-04. Historical plans are kept at their existing paths — links from
|
||||
audits and commit messages must keep resolving — so status is recorded **here**
|
||||
rather than by moving or rewriting them.
|
||||
|
||||
A plan's own header can drift out of date after its table is updated in place.
|
||||
Where that has happened it is called out below, and **this index is the
|
||||
authority**.
|
||||
|
||||
## Active — these drive current work
|
||||
|
||||
| Plan | State |
|
||||
| --- | --- |
|
||||
| [beta-product-requirements-2026-08-23](beta-product-requirements-2026-08-23.md) | Approved beta scope, frozen. 57 `BPR-*` requirements. |
|
||||
| [repo-health-roadmap-2026-08-23](repo-health-roadmap-2026-08-23.md) | Phase order and gates, B0–B10. No phase complete. |
|
||||
| [repo-health-issue-register-2026-08-23](repo-health-issue-register-2026-08-23.md) | 88 planning rows. Public-safe; not a replacement for the ledger. |
|
||||
| [beta-requirements-traceability-2026-08-23](beta-requirements-traceability-2026-08-23.md) | Requirement → phase → evidence map. No row is release-qualified. |
|
||||
| [b0-baseline-2026-08-25](b0-baseline-2026-08-25.md) | **Supersedes the roadmap's "current evidence snapshot."** B0 measurements and dispositions. |
|
||||
| [audit-2026-08-19-remediation](audit-2026-08-19-remediation.md) | Phases 1–6 done 2026-08-20; **phase 7 pending**. Its header still reads "in progress 2026-08-19" — stale; the phase table is correct. |
|
||||
|
||||
## Partially implemented
|
||||
|
||||
| Plan | State |
|
||||
| --- | --- |
|
||||
| [bug-detection-improvements](bug-detection-improvements.md) | Tier 1a (`make fuzz`) and Tier 2 (five ESLint rules) shipped 2026-08-08. Remaining tiers open. |
|
||||
|
||||
## Design only — not implemented
|
||||
|
||||
| Plan | State |
|
||||
| --- | --- |
|
||||
| [slash-commands](slash-commands.md) | Design only. No implementation; not in beta scope. |
|
||||
|
||||
## Shipped — kept for history, do not use as current status
|
||||
|
||||
| Plan | Shipped |
|
||||
| --- | --- |
|
||||
| [audit-2026-07-19-decisions](audit-2026-07-19-decisions.md) | Decisions recorded; greenlit items implemented through 2026-07-23. |
|
||||
| [channel-visibility-unification](channel-visibility-unification.md) | 2026-07-20 (D9), re-verified 2026-08-04. |
|
||||
| [v2-dispatch-migration](v2-dispatch-migration.md) | 2026-07-20 (D10), re-verified 2026-08-04. |
|
||||
| [tauri-capability-narrowing](tauri-capability-narrowing.md) | 2026-07-20, re-verified 2026-08-04. |
|
||||
| [http-tofu-proxy](http-tofu-proxy.md) | 2026-07-19, re-verified 2026-08-04. |
|
||||
| [permission-middleware-consolidation](permission-middleware-consolidation.md) | 2026-07-23 (D13), re-verified 2026-08-04. |
|
||||
| [security-hardening-remediation](security-hardening-remediation.md) | 2026-07-23, re-confirmed 2026-08-04. |
|
||||
| [security-scan-2026-07-22-remediation](security-scan-2026-07-22-remediation.md) | All 8 findings F1–F8 closed, verified 2026-08-04. |
|
||||
| [sqlc-adoption](sqlc-adoption.md) | Shipped, verified 2026-08-04. |
|
||||
| [discord-parity](discord-parity.md) | Phases 1–6 complete, verified 2026-08-04. Phase 1's table reads as a gap list but every row shipped. |
|
||||
| [infrastructure-roadmap](infrastructure-roadmap.md) | 2026-08-15, with two recorded leftovers (TOTP persister seam; published capacity numbers). |
|
||||
|
||||
## Where status actually lives
|
||||
|
||||
Planning documents are not trackers. Do not read a defect count out of one.
|
||||
|
||||
| Concern | Source of truth |
|
||||
| --- | --- |
|
||||
| Defect status | `.superpowers/findings-ledger.json` (`FINDINGS.md` is rendered from it) |
|
||||
| Security-sensitive defects | Private GitHub Security Advisories |
|
||||
| Product scope | [beta-product-requirements-2026-08-23](beta-product-requirements-2026-08-23.md) |
|
||||
| Phase order and gates | [repo-health-roadmap-2026-08-23](repo-health-roadmap-2026-08-23.md) |
|
||||
| Current measured baseline | [b0-baseline-2026-08-25](b0-baseline-2026-08-25.md) |
|
||||
|
||||
Ledger at 2026-08-25: **306 fixed / 38 open / 3 declined / 1 duplicate = 348**.
|
||||
All 38 open records still resolve to a live `file:line` at
|
||||
`5cc0888964e26276d1aca145e83270a2c1b9febd` — none is stale. Verify with:
|
||||
|
||||
```
|
||||
node .superpowers/render-ledger.mjs --check
|
||||
```
|
||||
|
||||
## Adding a plan
|
||||
|
||||
1. Give it a `**Status:**` line with a date, and update that line — not only
|
||||
the phase table — when it changes.
|
||||
2. Add a row here. A plan absent from this index has no recorded status.
|
||||
3. Mark a superseded plan here; leave it at its path so existing links resolve.
|
||||
@@ -1,7 +1,9 @@
|
||||
# Audit 2026-08-19 Remediation — Phased Plan
|
||||
|
||||
**Status:** in progress 2026-08-19 — phases execute in order; each phase's
|
||||
status is updated in place when it lands.
|
||||
**Status:** in progress — phases 1–6 landed 2026-08-20 (merged as `03fcb7d5`,
|
||||
PR #1396); **phase 7 is still pending**. Phases execute in order; each phase's
|
||||
status is updated in place when it lands, so the table below is authoritative
|
||||
for per-phase state. Indexed in [README.md](README.md).
|
||||
**Source:** [audit-2026-08-19.md](../audit-2026-08-19.md) — this plan executes
|
||||
its §8 MUST-fix verdict and §9.1 fix order verbatim. Items outside that list
|
||||
(§6 DEBT beyond D-01..D-05, §9.2 alpha-exit work) are deliberately NOT in
|
||||
|
||||
@@ -0,0 +1,214 @@
|
||||
# B0 baseline and audit reconciliation
|
||||
|
||||
**Measured:** 2026-08-25
|
||||
**Base commit:** `5cc0888964e26276d1aca145e83270a2c1b9febd` (the audited head)
|
||||
**Branch:** `fix/b0-baseline-2026-08-25`
|
||||
**Supersedes the "current evidence snapshot" in**
|
||||
[repo-health-roadmap-2026-08-23.md](repo-health-roadmap-2026-08-23.md)
|
||||
|
||||
Every row below is either **measured** in this session or explicitly marked
|
||||
**carried** from the 2026-08-23 audit without re-verification. Nothing is
|
||||
inherited silently.
|
||||
|
||||
## Environment
|
||||
|
||||
| Tool | Version | Note |
|
||||
| --- | --- | --- |
|
||||
| Node | 26.4.0 | **Local only.** CI pins 24. See ENV-01. |
|
||||
| npm | 11.17.0 | |
|
||||
| Go | 1.26.7 | Matches `Server/go.mod` `toolchain go1.26.7`. |
|
||||
| golangci-lint | 2.11.3 (built with go1.26.5) | Runs correctly despite the mismatch. See G-05. |
|
||||
| Playwright | 1.62.1 | |
|
||||
| Vitest / Vite / TypeScript | 4.1.11 / 8.2.2 / 6.0.3 | |
|
||||
| oxlint / eslint / prettier | 1.79.0 / 10.9.0 / 3.9.6 | |
|
||||
| Client version | 1.2.0-alpha.3 | |
|
||||
|
||||
## Measured results
|
||||
|
||||
| Gate | Result | Provenance |
|
||||
| --- | --- | --- |
|
||||
| Server build — default | pass | measured |
|
||||
| Server build — `otel` | pass | measured |
|
||||
| Server build — `wazero` | pass | measured |
|
||||
| Server build — `otel wazero` | pass | measured |
|
||||
| `go vet ./...` | pass | measured |
|
||||
| `golangci-lint run ./...` | **0 issues**, 19 linters active, 1.18s | measured |
|
||||
| Go `-race ./...` | pass (exit 0, no data race) | measured |
|
||||
| Go `-tags deadlock ./...` | pass (exit 0) | measured |
|
||||
| Client unit + integration | **5257 passed / 192 files, 0 failed** | measured |
|
||||
| Client `tsc` (build + e2e + root) | pass | measured |
|
||||
| Client `prettier --check` | pass | measured |
|
||||
| Client `npm run lint` | pass (exit 0) | measured |
|
||||
| oxlint warnings | **471** | measured — unchanged from audit |
|
||||
| Playwright full suite | **293 passed, exit 0, 37s** | measured |
|
||||
| Client production build | pass, 401ms | measured |
|
||||
| Docker build + boot smoke | **pass** — image 50.1 MB, boots on `:8443` with TLS | measured (see ENV-02) |
|
||||
| Server coverage | **74.6% aggregate** | measured — confirms the carried figure exactly |
|
||||
| Rust clippy + 115 tests | pass | **carried**, not re-measured |
|
||||
|
||||
### Bundle sizes (measured)
|
||||
|
||||
| Chunk | Minified | Gzip |
|
||||
| --- | ---: | ---: |
|
||||
| `livekitSession` | 1,998.25 kB | 1,344.96 kB |
|
||||
| `livekit` | 495.41 kB | 127.88 kB |
|
||||
| `MainPage` | 192.18 kB | 58.92 kB |
|
||||
| `index` | 187.18 kB | 59.07 kB |
|
||||
| `SettingsOverlay` | 47.56 kB | 13.98 kB |
|
||||
|
||||
Confirms the audit's "~2.0 MB minified / 1.345 MB gzip" for the largest lazy
|
||||
chunk. This is the budget baseline B7 ratchets against.
|
||||
|
||||
## Dispositions
|
||||
|
||||
### Closed
|
||||
|
||||
| ID | Was | Now | Evidence |
|
||||
| --- | --- | --- | --- |
|
||||
| G-01 | P0 confirmed | **fixed** | See "G-01 was inverted" below. |
|
||||
| G-02 | P0 confirmed | **fixed** | `MediaStream` stub replaced with a real constructible class; Vitest 4 threw `is not a constructor` at `noise-suppression.ts:162` before, passes after. OC-0277 assertions unchanged. |
|
||||
| Playwright non-termination | P0-adjacent confirmed | **fixed** | Root cause and fix below. |
|
||||
| G-03 | P0 confirmed | **fixed** | `dev` branch protection applied 2026-08-25: PR required, `required_approving_review_count: 0`, `enforce_admins: true`, force-pushes and deletions off. Every dev commit now arrives via PR and hits the existing `pull_request` trigger. Also closes RL-14. Status checks still unpinned — see below. |
|
||||
|
||||
### Refuted
|
||||
|
||||
| ID | Claim | Finding |
|
||||
| --- | --- | --- |
|
||||
| G-05 | "Local `golangci-lint` could not load because its Go 1.26.5 build mismatched the module's Go 1.26.7 toolchain." | **Does not reproduce.** `golangci-lint run ./...` completes with 19 active linters (bodyclose, contextcheck, cyclop, dupl, errcheck, funlen, gocritic, gosec, govet, ineffassign, modernize, nestif, nilerr, prealloc, staticcheck, unconvert, unparam, unused, wastedassign) in 1.18s and reports 0 issues. Verified with `-v` specifically to rule out the known zero-linters false-green. The gate does not need waiving or CI substitution. |
|
||||
|
||||
### Still open
|
||||
|
||||
| ID | Pri | State | Note |
|
||||
| --- | --- | --- | --- |
|
||||
| ~~G-03~~ | P0 | **closed 2026-08-25** | `dev` is PR-only: PR required, 0 approvals, enforced on admins, force-pushes off. Moved to Closed. |
|
||||
| G-04 | P1 | **mostly closed** | Active-plan index added at [README.md](README.md): every plan in `docs/plans/` now has a recorded state (active / partial / design-only / shipped). One real stale claim found and fixed — `audit-2026-08-19-remediation.md` still read "in progress 2026-08-19" while its own table showed phases 1–6 done 2026-08-20 with only phase 7 pending. No plan was found claiming "0 open findings". Remaining: the *automated* check that prevents conflicting status/count claims (B1). |
|
||||
| ENV-02 | — | **closed** | Docker smoke now measured locally and passing. Moved to Closed. |
|
||||
|
||||
### New findings
|
||||
|
||||
| ID | Pri | Finding |
|
||||
| --- | --- | --- |
|
||||
| ENV-03 | P2 | **`docker-smoke.sh` cannot be run from Git Bash on Windows.** MSYS path conversion rewrites the container-internal path `/chatserver` into `C:/Program Files/Git/chatserver`, so `docker exec` fails with exit 127 and the script reports `container never reported healthy within 30s` — indistinguishable from a genuine boot regression. The image is fine; with `MSYS_NO_PATHCONV=1` the same script passes. CI is unaffected (Linux). Windows is an official contributor platform, so the script should either set this itself or document it — related to RL-20. |
|
||||
| ENV-01 | P2 | **Three Node versions were in play**, not two. `.nvmrc` said 20, CI says 24, and the local runtime is 26.4.0. `.nvmrc` is now 24 to match CI. The local runtime remains 26, so every "measured" row above was produced on Node 26, not CI's 24 — this is the one standing gap between this baseline and a CI baseline. Full single-source-of-truth work stays in B1 (RL-17 / C-01). |
|
||||
|
||||
## G-01 was inverted, not stale
|
||||
|
||||
The register recorded G-01 as a stale assertion. It is worse than that: the
|
||||
original test **passed on the bug and failed on the fix**.
|
||||
|
||||
`message-list.test.ts` spied on `AbortSignal.prototype.addEventListener` and
|
||||
asserted zero `"abort"` registrations. Two things were true:
|
||||
|
||||
- The pre-OC-0286 leak registered row listeners as
|
||||
`element.addEventListener(type, fn, { signal: ac.signal })`. That path never
|
||||
calls `AbortSignal.prototype.addEventListener`, so the leak produced **zero**
|
||||
registrations and the assertion passed.
|
||||
- The OC-0286 fix rotates a per-window controller and hands rows
|
||||
`AbortSignal.any([ac.signal, rowAc.signal])`. Each rebuild registers one
|
||||
listener on a fresh signal, so five jumps produced **five** registrations and
|
||||
the assertion failed.
|
||||
|
||||
Measured directly: with the fix, 5 registrations across **5 distinct** signals,
|
||||
4 already aborted and 1 live. With the fix reverted, **0** registrations.
|
||||
|
||||
The test now captures the signal each window's row listeners are registered
|
||||
against and asserts the invariant its name always claimed:
|
||||
|
||||
- every rendered window's rows share exactly one signal;
|
||||
- each jump renders against a *fresh* signal (nothing accumulates);
|
||||
- every superseded window's signal is already aborted, and exactly one is live.
|
||||
|
||||
Verified both directions: green on the fix, and with `beginRowRender()` reverted
|
||||
to `rowSignal = ac.signal` it fails with `expected 1 to be 5` — the accumulation
|
||||
shape, named precisely.
|
||||
|
||||
## Playwright non-termination: root cause
|
||||
|
||||
None of the three hypotheses in the B0 plan was correct.
|
||||
|
||||
The runner finished every test and then never exited, printing no summary — so
|
||||
the failure looked like "tests never finish" when it was "process never exits."
|
||||
`process.getActiveResourcesInfo()` at hang time showed the runner holding a live
|
||||
`ProcessWrap` plus several `PipeWrap`: the Vite dev server was still alive.
|
||||
|
||||
Playwright's `webServer` teardown does not kill it on Windows. Measured:
|
||||
|
||||
| webServer setup | Terminates | Tests |
|
||||
| --- | --- | --- |
|
||||
| `npm run dev` | no — hangs | pass |
|
||||
| `node node_modules/vite/bin/vite.js` | no — hangs | pass |
|
||||
| `reuseExistingServer: false` | no — hangs | pass |
|
||||
| `gracefulShutdown: { SIGTERM, 3s }` | no — hangs | pass |
|
||||
| `npx vite` | yes | **290 of 293 fail** |
|
||||
| no `webServer` (server pre-started) | yes | 293 pass in 33s |
|
||||
|
||||
`npx vite` only appears to work: npx exits once Vite is up, Playwright reads
|
||||
that as the server dying and tears the group down mid-run, so later tests fail
|
||||
with `ERR_CONNECTION_REFUSED`.
|
||||
|
||||
**Fix:** `tests/e2e/global-teardown.ts` kills the process listening on the dev
|
||||
port after the run, which releases the runner's handle. The `webServer` command
|
||||
spawns Vite's entry point directly so the listening process *is* Playwright's
|
||||
child — through `npm run dev` the npm process would still hold the handle open.
|
||||
|
||||
Result: `npm run test:e2e` exits 0 in 37s with 293 passed, reproducibly, leaving
|
||||
no orphaned listener. Before, it never exited at any timeout.
|
||||
|
||||
An earlier revision of the teardown used `netstat`, which is not on PATH in
|
||||
every shell here; the swallowed `ENOENT` made the fix look effective while the
|
||||
hang was still present. It now uses PowerShell on Windows, `lsof` elsewhere, and
|
||||
**warns on failure instead of failing silently**.
|
||||
|
||||
## G-03 — the one decision B0 still needs
|
||||
|
||||
`.github/workflows/ci.yml` triggers on `push: [main]` and
|
||||
`pull_request: [main, dev]`. A direct push to `dev` with no open PR receives no
|
||||
run at all, which is exactly why the audited head has no CI evidence.
|
||||
|
||||
The existing `concurrency` group is `ci-${{ github.ref }}`. A dev push is
|
||||
`refs/heads/dev` and its PR is `refs/pull/N/merge` — **different groups**, so
|
||||
adding `dev` to `push` genuinely double-runs the suite while a dev→main PR is
|
||||
open. The trigger comment records that as the original reason for removing it.
|
||||
|
||||
**Decision (2026-08-25): make `dev` PR-only** via branch protection. No workflow
|
||||
change is needed — the existing `pull_request: [main, dev]` trigger already
|
||||
covers every PR — and no run is duplicated. Direct pushes to `dev` stop being
|
||||
possible, which is the point.
|
||||
|
||||
The rejected alternative was adding `dev` to `push.branches`: a one-line change
|
||||
that keeps direct pushes but runs the full matrix twice per push whenever a
|
||||
dev→main PR is open, because the two events fall in different `concurrency`
|
||||
groups.
|
||||
|
||||
Apply with [`b0-dev-branch-protection.sh`](b0-dev-branch-protection.sh), which
|
||||
records the settings and the reasoning. It must be run by a human: repository
|
||||
settings writes are blocked from the agent sandbox. Status-check pinning is
|
||||
deliberately left unset until the exact job names are confirmed from a green
|
||||
run — requiring names that never report would deadlock every PR.
|
||||
|
||||
This is the canonical owner for layout finding RL-14; close both as one issue.
|
||||
|
||||
## Docker evidence has to come from a local run
|
||||
|
||||
The CI Docker job is gated `if: github.ref_name == 'main' || github.base_ref ==
|
||||
'main'`, so it is **skipped on any PR targeting `dev`** — including the PR that
|
||||
carries this baseline. A dev-targeted change therefore cannot obtain Docker
|
||||
evidence from CI at all; it must be run locally (or the gate widened). Measured
|
||||
here: image builds at 50.1 MB and `docker-smoke.sh` exits 0.
|
||||
|
||||
## Not yet done in B0
|
||||
- Step 6 follow-up: pin required status checks on `dev` once the exact job
|
||||
names are confirmed from the first green PR run
|
||||
(`gh api repos/J3vb/OwnCord/commits/dev/check-runs -q '.check_runs[].name'`).
|
||||
Until then a PR is required but may still merge red.
|
||||
- Step 8: individual adjudication of the 38 open `OC-*` records. The count was
|
||||
verified as **306 fixed / 38 open / 3 declined / 1 duplicate = 348**, matching
|
||||
the register, and a staleness pass confirmed **all 38 still resolve to a live
|
||||
`file:line`** at this commit — none is superseded by later work, so all 38 are
|
||||
genuinely open (11 medium, 27 low, all from hunt `general-2026-08-22-b`).
|
||||
Deciding each one is bughunt-fix work, not B0 work. The duplicate pairs the
|
||||
register names are mapped: RL-14↔G-03 (closed together here) and RL-17↔C-01
|
||||
(Node, partly addressed by ENV-01).
|
||||
- Step 9: nothing outstanding. Coverage re-measured at 74.6%; the only figure
|
||||
still carried is Rust clippy + 115 tests.
|
||||
- Step 10: HP-0 sign-off.
|
||||
@@ -0,0 +1,57 @@
|
||||
#!/usr/bin/env bash
|
||||
# G-03 / RL-14: make `dev` PR-only so every integration commit gets CI.
|
||||
#
|
||||
# Today `.github/workflows/ci.yml` triggers on `push: [main]` and
|
||||
# `pull_request: [main, dev]`. A direct push to `dev` with no open PR runs
|
||||
# nothing at all — which is why the audited head 5cc08889 has no CI evidence.
|
||||
# Requiring a PR routes every dev commit through the existing pull_request
|
||||
# trigger, with no workflow change and no duplicated runs.
|
||||
#
|
||||
# Run this yourself: Claude Code's sandbox blocks repo-settings writes.
|
||||
# bash docs/plans/b0-dev-branch-protection.sh
|
||||
#
|
||||
# Choices worth knowing:
|
||||
# required_approving_review_count: 0
|
||||
# A PR is required, but you can merge your own without a second person.
|
||||
# Anything above 0 would lock a solo maintainer out entirely.
|
||||
# enforce_admins: true
|
||||
# Applies to you too. With `false` an admin silently bypasses the PR
|
||||
# requirement, which on a solo-admin repo makes the whole guard
|
||||
# decorative. Toggle it off any time if you need an emergency push.
|
||||
# required_status_checks: null
|
||||
# Deliberately not set yet. Requiring check names that never report
|
||||
# deadlocks every PR, so pin them only after confirming the exact job
|
||||
# names from a green run:
|
||||
# gh api repos/J3vb/OwnCord/commits/dev/check-runs \
|
||||
# -q '.check_runs[].name'
|
||||
#
|
||||
# To undo:
|
||||
# gh api -X DELETE repos/J3vb/OwnCord/branches/dev/protection
|
||||
set -euo pipefail
|
||||
|
||||
REPO="${REPO:-J3vb/OwnCord}"
|
||||
|
||||
gh api -X PUT "repos/${REPO}/branches/dev/protection" --input - <<'JSON'
|
||||
{
|
||||
"required_status_checks": null,
|
||||
"enforce_admins": true,
|
||||
"required_pull_request_reviews": {
|
||||
"required_approving_review_count": 0,
|
||||
"dismiss_stale_reviews": false,
|
||||
"require_code_owner_reviews": false
|
||||
},
|
||||
"restrictions": null,
|
||||
"allow_force_pushes": false,
|
||||
"allow_deletions": false,
|
||||
"required_conversation_resolution": false,
|
||||
"required_linear_history": false
|
||||
}
|
||||
JSON
|
||||
|
||||
echo
|
||||
echo "Applied. Verifying:"
|
||||
gh api "repos/${REPO}/branches/dev/protection" -q '
|
||||
" PR required: " + ((.required_pull_request_reviews != null)|tostring),
|
||||
" approvals needed: " + (.required_pull_request_reviews.required_approving_review_count|tostring),
|
||||
" applies to admins:" + (.enforce_admins.enabled|tostring),
|
||||
" force pushes: " + (.allow_force_pushes.enabled|tostring)'
|
||||
@@ -0,0 +1,147 @@
|
||||
# OwnCord beta product requirements
|
||||
|
||||
**Approved:** 2026-08-23
|
||||
**Release target:** first public beta after the `1.2.0-alpha.*` line
|
||||
**Planning model:** quality-gated, with no calendar deadline
|
||||
**Owner authority:** product decisions below are fixed; engineering may choose
|
||||
the safest and most performant implementation that satisfies them.
|
||||
|
||||
This document records the decisions that define “beta-ready.” It is the product
|
||||
input to the repository-health issue register and phased roadmap; it is not an
|
||||
implementation checklist by itself.
|
||||
|
||||
Companion documents:
|
||||
|
||||
- [repository-health issue register](repo-health-issue-register-2026-08-23.md);
|
||||
- [server-first beta roadmap](repo-health-roadmap-2026-08-23.md);
|
||||
- [repository-layout audit](../audit-2026-08-23-repository-layout.md).
|
||||
|
||||
## Release and scope
|
||||
|
||||
| ID | Requirement |
|
||||
| ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| BPR-001 | Beta is a public GitHub release that anyone can download. |
|
||||
| BPR-002 | There is no deadline. A phase closes only when its evidence and exit gates are green. |
|
||||
| BPR-003 | Beta scope is frozen to this document. New ideas go to the post-beta backlog unless needed for security, correctness, accessibility, platform parity, or completion of an approved feature. |
|
||||
| BPR-004 | Existing alpha server data, attachments, configuration, credentials, and client settings must survive an in-place beta upgrade. |
|
||||
| BPR-005 | Unsigned payloads are deterministic where the platform permits, packaging is repeatable, and releases carry signed provenance/SBOM evidence. Checksums, signatures, update metadata, source snapshots, and the final published artifacts are verified before publication; timestamped platform signatures are not required to be byte-identical across rebuilds. |
|
||||
|
||||
## Supported platforms and delivery
|
||||
|
||||
| ID | Requirement |
|
||||
| ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| BPR-010 | Official desktop targets are Windows x64, Windows ARM64, Linux x64, and Linux ARM64. Native Windows ARM64 validation is available; Linux ARM64 may use cross-build and emulated smoke evidence until real hardware is available. |
|
||||
| BPR-011 | The supported server matrix is Windows x64/ARM64 executables, Linux x64/ARM64 archives, and multi-architecture Docker images for `linux/amd64` and `linux/arm64`. Docker is the primary deployment path; standalone binaries remain fully tested release assets. |
|
||||
| BPR-012 | Each server is independently hosted by its owner. The project operates no official OwnCord community server or identity service. |
|
||||
| BPR-013 | Internet-facing servers commonly run directly behind port forwarding. A reverse proxy must not be required. |
|
||||
| BPR-014 | Domain names and raw public IP addresses are supported connection addresses. |
|
||||
| BPR-015 | Public domains and stable public IPs use a built-in automatic public-CA certificate lifecycle. Private LAN/offline deployments use a server-generated local CA with guided, unavoidable one-time trust installation on each browser device. Owners may instead supply a certificate explicitly; no reverse proxy or recurring manual renewal is required by the default paths. |
|
||||
| BPR-016 | Private LAN-only and fully offline deployments are first-class supported modes. Offline browser use works after local certificate trust, while internet-dependent capabilities such as closed-app Web Push clearly report that they are unavailable. |
|
||||
|
||||
## Browser and PWA client
|
||||
|
||||
| ID | Requirement |
|
||||
| ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| BPR-020 | A server may host the browser client only when its owner explicitly enables it; it is disabled by default. |
|
||||
| BPR-021 | The browser client targets desktop parity wherever browser APIs permit. Installer, desktop updater, system tray, and native OS integrations are desktop-only. |
|
||||
| BPR-022 | Phones and tablets are official browser targets. Layout, touch input, virtual keyboards, safe areas, media constraints, and accessibility must be tested. |
|
||||
| BPR-023 | The browser client is installable as a Progressive Web App with icons, standalone presentation, and safely cached application assets. |
|
||||
| BPR-024 | Background Web Push is supported where the browser and operating system permit it. It requires explicit owner and user opt-in, uses no OwnCord-operated relay, and degrades honestly on offline or unsupported systems. |
|
||||
| BPR-025 | The desktop and browser clients share product behavior and contracts rather than becoming divergent applications. |
|
||||
|
||||
## Capacity and compatibility
|
||||
|
||||
| ID | Requirement |
|
||||
| ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| BPR-030 | The beta reference profile supports at least 250 registered users, 100 simultaneous connections, and 25 concurrent voice participants per server, backed by published measurements on stated hardware. |
|
||||
| BPR-031 | A server owner upgrades the server before users install the corresponding client update. |
|
||||
| BPR-032 | An upgraded server supports the current advertised protocol epoch and the previous two epochs (`N/N-1/N-2`). Patch releases that retain an epoch remain compatible; prerelease and release metadata declare their epoch explicitly. The server-bundled browser client matches its server and is not an independently versioned compatibility generation. A new client is not required to support an older server. |
|
||||
| BPR-033 | Connected users receive a clear update notification and can install the compatible client release. Clients outside the compatibility window fail safely with an actionable update requirement. |
|
||||
| BPR-034 | One client connects to one server at a time. Saved profiles remain isolated and easy to switch; background multi-server aggregation is outside beta. |
|
||||
| BPR-035 | One server-local account may have multiple simultaneous device sessions, with a device/session list, new-login notice, individual revocation, and sign-out-everywhere. |
|
||||
|
||||
## Identity, registration, and recovery
|
||||
|
||||
| ID | Requirement |
|
||||
| ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| BPR-040 | Accounts and usernames are local to each server. There is no global OwnCord identity. |
|
||||
| BPR-041 | New servers default to invite-only registration. Owners may explicitly enable approval-based or open registration. |
|
||||
| BPR-042 | All messages, files, calls, and moderation features require an authenticated account. Anonymous guest access is outside beta. |
|
||||
| BPR-043 | Email is optional. Registration and recovery work without SMTP or any central service. |
|
||||
| BPR-044 | Account recovery uses a locally generated recovery kit whose server-side secrets are stored only in protected, non-reversible form and rotate after use. |
|
||||
| BPR-045 | Administrators may issue short-lived recovery credentials after local identity verification. Recovery revokes affected sessions and creates a safe audit record. |
|
||||
| BPR-046 | Existing TOTP multi-factor authentication and emergency recovery codes remain supported beta features. Optional SMTP recovery may be enabled, but SMTP and all external services remain nonessential to registration, login, and local recovery. Security questions are prohibited. |
|
||||
|
||||
## Privacy, deletion, and retention
|
||||
|
||||
| ID | Requirement |
|
||||
| ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| BPR-050 | OwnCord follows Discord's hybrid privacy model: text and files are available to the trusted server for delivery, search, moderation, and backup; voice, video, and screen sharing are end-to-end encrypted between participants. |
|
||||
| BPR-051 | The server-operator trust model is disclosed plainly. Transport and at-rest controls do not claim to hide stored text or files from the machine owner. |
|
||||
| BPR-052 | Account deletion erases the user's profile, credentials, sessions, messages, reactions, uploads, and other authored data rather than leaving attributed or anonymized content behind. |
|
||||
| BPR-053 | Necessary integrity records retain no identifying or content data after deletion. Immutable moderation/audit history survives only as an unlinkable event category, time, action class, and integrity proof after the subject mapping is cryptographically erased. Durable deletion markers prevent a later backup restore from silently resurrecting erased data. |
|
||||
| BPR-054 | Message history is retained indefinitely by default. Owners may configure automatic retention at server or channel scope, with corresponding attachment cleanup. |
|
||||
| BPR-055 | OwnCord sends no automatic product or usage telemetry. Diagnostics remain local and support-bundle export is user initiated. Any future crash reporting is explicit opt-in. |
|
||||
|
||||
## Messaging, content, and safety
|
||||
|
||||
| ID | Requirement |
|
||||
| ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| BPR-060 | First-time direct messages enter a Message Requests inbox. A recipient may safely preview, accept, ignore, delete, or block; acceptance establishes a server-local trusted-sender relationship. |
|
||||
| BPR-061 | Link previews, GIF search, YouTube/media embeds, and existing rich external content remain supported and must meet the beta security, privacy, accessibility, failure-state, and performance gates. Provider expansion beyond the existing set is optional and otherwise post-beta. |
|
||||
| BPR-062 | Automatic external retrieval uses privacy-preserving, resource-bounded, SSRF-resistant boundaries with strict redirect, address, type, size, time, concurrency, cache, and offline behavior. |
|
||||
| BPR-063 | Owner-designated NSFW channels remain supported. They require explicit labels and per-user acknowledgement, with concealed previews and no automatic third-party media loading before consent. |
|
||||
| BPR-064 | English is the only officially supported beta language. User-facing text is organized so community translations can be added later without a rewrite. |
|
||||
|
||||
## Moderation
|
||||
|
||||
| ID | Requirement |
|
||||
| ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| BPR-070 | Users can report messages, users, and attachments to that server's local moderators. There is no central OwnCord moderation service. |
|
||||
| BPR-071 | Desktop, browser, and PWA clients contain a permission-gated Moderation Center for the report queue, evidence and surrounding context, assignment, status, internal notes, actions, and immutable audit history. |
|
||||
| BPR-072 | Day-to-day moderator actions include warning, timeout, content removal, kick, and ban according to narrowly assigned role permissions. Operational TLS, backup, and update controls remain owner-only. |
|
||||
| BPR-073 | Moderated users can submit a rate-limited in-app appeal to local moderators and receive status updates. Appeal decisions are audited. |
|
||||
|
||||
## Extensions and deferred systems
|
||||
|
||||
| ID | Requirement |
|
||||
| ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| BPR-080 | The WASM plugin runtime remains experimental and disabled by default. No beta plugin API compatibility promise is made because no supported plugins exist yet. |
|
||||
| BPR-081 | The audit identifies cohesive features and provider integrations that could become plugins later, without moving them behind the experimental runtime during beta. |
|
||||
| BPR-082 | Server federation, cross-server messaging, and federation-specific architecture work are outside beta. The idea may be reconsidered only after the beta codebase and operations are healthy. |
|
||||
| BPR-083 | There is no centralized public server directory. Owners distribute addresses and invite links themselves. |
|
||||
|
||||
## Client experience and accessibility
|
||||
|
||||
| ID | Requirement |
|
||||
| ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| BPR-090 | Preserve OwnCord's recognizable visual identity and familiar workflows while improving consistency, responsiveness, accessibility, and performance. A wholesale visual rebrand is outside beta. |
|
||||
| BPR-091 | Accessibility is a release property across keyboard, pointer, touch, screen reader, reduced-motion, contrast, focus, zoom, and responsive layouts—not a later cosmetic pass. |
|
||||
| BPR-092 | Browser limitations and offline states are explicit. The UI does not present unavailable media, push, update, or network behavior as functional. |
|
||||
|
||||
## Community and governance
|
||||
|
||||
| ID | Requirement |
|
||||
| ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| BPR-100 | GitHub Issues is the official bug tracker; GitHub Discussions hosts support, ideas, and community feedback. |
|
||||
| BPR-101 | Vulnerabilities use private GitHub security reporting and are not disclosed through public issues before coordinated remediation. |
|
||||
| BPR-102 | Community pull requests are welcome. Contributor documentation defines setup, scope, quality gates, generated files, review expectations, and safe security reporting. |
|
||||
| BPR-103 | Repository layout and contributor experience are audited before implementation. A restructure occurs only when evidence shows a durable improvement and is performed as an isolated, migration-safe phase. |
|
||||
|
||||
## Engineering-controlled choices
|
||||
|
||||
Within these product boundaries, implementation details such as cryptographic
|
||||
libraries, data structures, cache policy, browser/version matrix, performance
|
||||
budgets, backup schedule, CI topology, branch automation, module boundaries,
|
||||
and release mechanics are chosen for security, maintainability, and measured
|
||||
performance. Material tradeoffs and accepted risks must still be recorded.
|
||||
|
||||
## Explicitly outside beta
|
||||
|
||||
- server federation and cross-server identity;
|
||||
- native macOS, iOS, or Android applications;
|
||||
- more than one active server connection per client;
|
||||
- anonymous guest access or a public server directory;
|
||||
- a stable third-party plugin API or bundled third-party plugins;
|
||||
- an OwnCord-operated hosting, identity, telemetry, push, or moderation service;
|
||||
- unrelated feature expansion after this scope freeze.
|
||||
@@ -0,0 +1,187 @@
|
||||
# OwnCord beta requirement traceability
|
||||
|
||||
**Prepared:** 2026-08-23
|
||||
**Requirements source:**
|
||||
[beta-product-requirements-2026-08-23.md](beta-product-requirements-2026-08-23.md)
|
||||
**Execution source:**
|
||||
[public-beta roadmap](repo-health-roadmap-2026-08-23.md)
|
||||
**Structural input:**
|
||||
[repository-layout audit](../audit-2026-08-23-repository-layout.md)
|
||||
**Current status:** all 57 requirements are mapped; none is release-qualified
|
||||
|
||||
## How to use this document
|
||||
|
||||
- The primary phase owns the implementation invariant, coordinates any
|
||||
downstream consumers, and records the first acceptance evidence.
|
||||
- A phase range means every earlier exit gate in that range is a prerequisite.
|
||||
- Some server-owned requirements need later client proof. Those rows name B7,
|
||||
B8, or B9 evidence explicitly and remain open until that proof exists.
|
||||
- B10 repeats every applicable verification against one immutable release
|
||||
candidate. Earlier green evidence cannot substitute for release evidence.
|
||||
- Security-sensitive proof is linked from a private advisory. The public row
|
||||
records only the security property, test category, and pass/fail status.
|
||||
- The canonical product wording remains in the requirements source. Short
|
||||
labels here are navigation aids, not replacements.
|
||||
|
||||
## Phase ownership
|
||||
|
||||
| Phase | Primary requirement IDs |
|
||||
| ---------------------------------------------------- | ---------------------------------------------------------------------------------------- |
|
||||
| B0 — truth and scope | BPR-002, BPR-003 |
|
||||
| B1 — repository and contributor foundation | BPR-100, BPR-101, BPR-102, BPR-103 |
|
||||
| B2 — server protocol, trust, and compatibility | BPR-031, BPR-032, BPR-040, BPR-050, BPR-051, BPR-080, BPR-081, BPR-082, BPR-083 |
|
||||
| B3 — server architecture and guardrails | No direct product requirement; mandatory prerequisite for B4–B10 |
|
||||
| B4 — identity, recovery, privacy, and data lifecycle | BPR-041, BPR-042, BPR-043, BPR-044, BPR-045, BPR-046, BPR-052, BPR-053, BPR-054, BPR-055 |
|
||||
| B5 — community, content, and moderation services | BPR-060, BPR-061, BPR-062, BPR-063, BPR-070, BPR-071, BPR-072, BPR-073 |
|
||||
| B6 — deployment, operations, and capacity | BPR-011, BPR-012, BPR-013, BPR-014, BPR-015, BPR-016, BPR-030 |
|
||||
| B7 — shared client platform and desktop parity | BPR-033, BPR-034, BPR-035 |
|
||||
| B8 — browser, PWA, phone, and tablet | BPR-020, BPR-021, BPR-022, BPR-023, BPR-024, BPR-025 |
|
||||
| B9 — unified UX, accessibility, and polish | BPR-064, BPR-090, BPR-091, BPR-092 |
|
||||
| B10 — qualification and release | BPR-001, BPR-004, BPR-005, BPR-010; final proof for every row |
|
||||
|
||||
## Release and scope
|
||||
|
||||
| ID | Short label | Primary phase | Prerequisites | Minimum verification and closure evidence |
|
||||
| ------- | -------------------------------------- | ------------- | ------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| BPR-001 | Public GitHub beta | B10 | B0–B9; BPR-005 and BPR-010 | Public release points to the qualified tag; an unauthenticated user can download every declared asset; install/cold-boot smoke succeeds; release page, source, checksums, signatures, SBOM, provenance, and support links agree. |
|
||||
| BPR-002 | No deadline; evidence gates | B0 | Approved requirements | Every phase template omits calendar-based completion, records exact-SHA evidence, and blocks closure when any exit row is red or unavailable. B10 confirms all phase scorecards are green. |
|
||||
| BPR-003 | Frozen beta scope | B0 | Approved requirements; canonical issue intake | Issue/Discussion triage maps work to a BPR or post-beta label; phase diffs show no unapproved feature; any exception records why it is required for security, correctness, accessibility, parity, or an approved feature. |
|
||||
| BPR-004 | In-place alpha-to-beta upgrade | B10 | B2 protocol; B4 migrations/deletion markers; B6 deployment/backup; B7 client settings | Upgrade representative alpha Docker and standalone datasets to the RC and verify row/file/config/credential/attachment/client-setting checksums and behavior; rehearse interrupted upgrade, restart, backup restore, and declared rollback without loss. |
|
||||
| BPR-005 | Deterministic, signed release evidence | B10 | B1 release gates; B6 supply chain; B7/B8 artifacts | Rebuild unsigned payloads twice where the platform permits and compare; repeat packaging; verify timestamped-signature exception; validate checksums, signatures, update metadata, source snapshot, signed SBOM/provenance, cold boot, and exact published bytes. |
|
||||
|
||||
## Supported platforms and delivery
|
||||
|
||||
| ID | Short label | Primary phase | Prerequisites | Minimum verification and closure evidence |
|
||||
| ------- | --------------------------------------- | ------------- | ------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| BPR-010 | Four desktop targets | B10 | B6 server artifacts; B7 desktop; B8/B9 shared-client qualification | Windows x64, native Windows ARM64, Linux x64, and Linux ARM64 packages build and pass install, boot, connect, media, update, rollback, and recovery smoke. Linux ARM64 evidence states whether it is cross-build/emulated or real hardware. |
|
||||
| BPR-011 | Complete server artifact matrix | B6 | B1 CI/release foundation; B3 lifecycle | Windows x64/ARM64 executables, Linux x64/ARM64 archives, and Docker linux/amd64 plus linux/arm64 are published from one commit; every artifact cold-boots, migrates, reports healthy, serves traffic, drains, restarts, and preserves data. |
|
||||
| BPR-012 | Independently owner-hosted | B6 | B2 central-dependency audit; B4 local identity/recovery | Fresh deployment, registration, login, messaging, moderation, update verification, recovery, and backup work without an OwnCord account/service; controlled network capture shows no undeclared central dependency. |
|
||||
| BPR-013 | No required reverse proxy | B6 | B2 trust contracts; B6 TLS configuration | Domain and public-IP deployments work through documented direct port forwarding with the built-in TLS path; a clean install contains no reverse-proxy prerequisite; blocked-port/CGNAT limits fail actionably. |
|
||||
| BPR-014 | Domain and raw public IP | B6 | BPR-013; certificate-mode design | Automated integration covers DNS name, eligible stable IPv4, and eligible stable IPv6 origins through HTTPS/WSS, reconnect, update, and browser-origin checks; address changes and unsupported cases are explicit. |
|
||||
| BPR-015 | Automatic public CA and guided local CA | B6 | B2 trust model; protected persistent configuration | ACME staging covers public domain and eligible public IP issue/renew/expiry/hot reload; LAN/offline covers local-CA generation, fingerprint, one-time trust install, rotation, and removal on supported browser devices; owner-supplied certificate mode also passes. |
|
||||
| BPR-016 | LAN-only and fully offline | B6 | BPR-015; B4 local recovery; B5 offline service behavior | After local trust, server and client cold-boot, authenticate, message, call where local media permits, back up, restore, and update from local artifacts with internet blocked; internet-dependent push/provider features report unavailable without retry storms. |
|
||||
|
||||
## Browser and PWA client
|
||||
|
||||
| ID | Short label | Primary phase | Prerequisites | Minimum verification and closure evidence |
|
||||
| ------- | ---------------------------------------- | ------------- | ---------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| BPR-020 | Optional server-hosted browser client | B8 | B6 default-off host/origin contract; B7 web contract build | Clean server exposes no browser application while disabled; owner enablement serves the version-matched signed bundle; disable removes access without affecting API/desktop; upgrade and rollback keep the setting and bundle consistent. |
|
||||
| BPR-021 | Browser desktop parity within API limits | B8 | B5 services; B7 shared contracts; BPR-020 | Requirement-journey comparison passes on desktop and supported browsers; every intentional difference has an API-based rationale and honest UI; installer, updater, tray, and native integrations remain desktop-only. |
|
||||
| BPR-022 | Phone and tablet browser support | B8 | B7 contracts; responsive navigation design; BPR-021 | Real Android phone/tablet and iPhone/iPad plus automation cover navigation, touch targets, virtual keyboard, safe areas, orientation, zoom/reflow, media constraints, screen reader, and recovery/moderation workflows. |
|
||||
| BPR-023 | Installable PWA | B8 | BPR-020; secure origin; cache policy | Manifest/icons/standalone launch pass installability checks; service worker is correctly scoped; only approved application assets cache; version change, stale cache, offline fallback, logout, and server rollback do not expose messages, credentials, attachments, or moderator evidence. |
|
||||
| BPR-024 | Opt-in Web Push without OwnCord relay | B8 | B5 per-server push backend; B6 HTTPS; BPR-023 | Owner-disabled, user-denied, subscribed, revoked, expired, 404/410 cleanup, VAPID rotation, click routing, offline, iOS installed-PWA, and unsupported cases pass; default payload is generic and network inspection shows no OwnCord relay. |
|
||||
| BPR-025 | One shared product and contracts | B8 | B1 target layout; B7 platform contracts; BPR-021 | Static checks keep native imports inside desktop ownership; the same domain/store/protocol suites run against desktop and browser adapters; no copied feature implementation or independently versioned browser protocol exists. |
|
||||
|
||||
## Capacity and compatibility
|
||||
|
||||
| ID | Short label | Primary phase | Prerequisites | Minimum verification and closure evidence |
|
||||
| ------- | -------------------------------------- | ------------- | --------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| BPR-030 | 250/100/25 reference profile | B6 | B3 benchmarks/simulation; B5 completed services | Reproducible load run on stated hardware sustains 250 registered users, 100 simultaneous connections, and 25 concurrent voice participants; publish configuration, duration, p50/p95/p99 latency, errors, CPU, memory, disk/database waits, network, reconnect, and recovery behavior. |
|
||||
| BPR-031 | Server upgrades first | B2 | B1 protocol owner and release metadata | Update-state tests prove the old server never directs users to an incompatible new client; server upgrade exposes signed compatible-client metadata; operator and client wording describes the sequence. |
|
||||
| BPR-032 | Protocol epochs N/N-1/N-2 | B2 | B1 generated protocol gate; BPR-031 | Fixtures for epochs N, N-1, and N-2 connect and exercise required journeys; N-3 rejects safely; patch versions within an epoch interoperate; prerelease/release metadata declares epoch; bundled browser version always matches server. |
|
||||
| BPR-033 | Update notice and safe incompatibility | B7 | BPR-031 and BPR-032; signed update metadata | Connected clients in-window receive a clear notice and can verify/install the compatible release; incompatible clients show an actionable non-destructive requirement; tampered, missing, offline, rollback, and user-deferral cases pass. |
|
||||
| BPR-034 | One active server connection | B7 | BPR-040; isolated profile storage; platform contracts | Instrumented unit/E2E tests prove only one live server transport/media session exists; switching tears down old resources, isolates credentials/cache/notifications, preserves profiles, and never aggregates background servers. |
|
||||
| BPR-035 | Multiple device sessions | B7 | B4 session inventory/revocation and login events; BPR-034 | Two or more devices remain active for one account; list labels/current-device state are correct; new-login notice appears; individual revoke affects only its target; sign-out-everywhere revokes all tokens and live connections. |
|
||||
|
||||
## Identity, registration, and recovery
|
||||
|
||||
| ID | Short label | Primary phase | Prerequisites | Minimum verification and closure evidence |
|
||||
| ------- | ------------------------------------------------- | ------------- | ----------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| BPR-040 | Server-local accounts | B2 | B1 protocol boundary; no central identity | The same username can represent unrelated identities on two servers; credentials, sessions, recovery, profiles, and moderation never cross; dependency/network audit finds no global identifier or OwnCord identity lookup. |
|
||||
| BPR-041 | Invite-only default, optional approval/open | B4 | B3 configuration/domain boundaries; BPR-040 | Fresh install is invite-only; valid/expired/revoked/concurrent invite tests pass; explicit transitions to approval/open and back are audited; upgrade preserves the owner's chosen mode without silently opening registration. |
|
||||
| BPR-042 | Authentication required; no guests | B4 | B2 canonical auth/authz; BPR-041 | Anonymous requests and sockets cannot message, upload, call, report, moderate, or fetch protected data; revoked/expired/partial sessions fail uniformly; UI and public docs expose no guest path. |
|
||||
| BPR-043 | Email optional and no central recovery dependency | B4 | BPR-040; local recovery design | Registration, login, recovery, device revocation, and administration pass with SMTP unset and internet blocked; optional email absence never blocks account creation or local recovery. |
|
||||
| BPR-044 | Rotating local recovery kit | B4 | B3 secret-storage guardrails; BPR-043 | Kit generation/recovery/replay/concurrency/restart tests prove only protected non-reversible server material is stored; one successful use rotates/invalidates it; logs, audit, backup, and support bundles contain no usable secret. |
|
||||
| BPR-045 | Admin-assisted short-lived recovery | B4 | BPR-044; canonical audit/session revocation | Issuance requires authorized admin and recorded local-verification decision; credential expires, is single-use and rate-limited; success revokes affected sessions; unauthorized, replay, concurrent, restart, and audit-redaction tests pass. |
|
||||
| BPR-046 | TOTP, emergency codes, optional SMTP | B4 | BPR-043–BPR-045; current MFA migration fixtures | Existing TOTP and emergency recovery codes survive upgrade/restart and pass enrollment, verification, replay, rotation, exhaustion, clock-skew, revocation, and recovery tests; SMTP failure cannot block local paths; configuration/UI contain no security questions. |
|
||||
|
||||
## Privacy, deletion, and retention
|
||||
|
||||
| ID | Short label | Primary phase | Prerequisites | Minimum verification and closure evidence |
|
||||
| ------- | -------------------------------------------------- | ------------- | ----------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| BPR-050 | Hybrid privacy and media E2EE | B2 | B1 protocol ownership; private threat model | Storage inspection confirms the trusted server can deliver/search/moderate/backup text and files; authenticated media interoperability and adversarial membership/rekey/removal tests demonstrate participant E2EE for voice, video, and screen share; docs state the boundary accurately. |
|
||||
| BPR-051 | Plain server-operator trust disclosure | B2 | BPR-050; B1 docs source of truth | Setup, privacy, backup, moderator, and client disclosures say the machine owner can access stored text/files and distinguish transport/at-rest controls from E2EE; technical review and user comprehension check find no contradictory claim. |
|
||||
| BPR-052 | Erase all user-authored data | B4 | B3 data ownership inventory; BPR-042; backup fixtures | Deletion traverses profile, credentials, sessions, messages, reactions, uploads, thumbnails/cache, request/report references, and every later data class; pre/post database and storage inventory is empty for the subject; interruption resumes safely; B7/B9 UI confirms impact and completion. |
|
||||
| BPR-053 | Unlinkable integrity history and anti-resurrection | B4 | BPR-052; cryptographic mapping and backup design | After deletion, audit/moderation rows retain only allowed event category, time, action class, and integrity proof; subject/content mapping key is cryptographically erased; correlation attempts fail; restore of an older backup reapplies the durable deletion marker and cannot resurrect data. |
|
||||
| BPR-054 | Indefinite default and configurable retention | B4 | B3 scheduler/lifecycle; BPR-052/BPR-053 | Fresh and upgraded servers default to indefinite history; server/channel policies handle precedence, clock boundaries, restart, batches, attachments, cache/search, reports/audit, deletion, and disk pressure; owner UI/docs preview and confirm effects. |
|
||||
| BPR-055 | No automatic telemetry | B4 | B1 dependency inventory; local diagnostics design | Network capture across install, startup, use, crash, update check, offline, and support workflows shows no automatic product/usage reporting; support bundle requires user action and passes secret/content review; any future crash option defaults off and records consent. |
|
||||
|
||||
## Messaging, content, and safety
|
||||
|
||||
| ID | Short label | Primary phase | Prerequisites | Minimum verification and closure evidence |
|
||||
| ------- | --------------------------------------- | ------------- | ----------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| BPR-060 | Message Requests | B5 | B4 identity/block/deletion/retention; B3 state-machine guardrails | Server state/property tests cover pending, safe preview, accept, ignore, delete, block, races, reconnect, multi-device, retention, and deletion; B9 desktop/browser/mobile E2E proves inbox UX and that only acceptance creates server-local trust. |
|
||||
| BPR-061 | Preserve existing rich content safely | B5 | BPR-062; current provider/feature inventory | Existing link preview, GIF search, YouTube/media embed, and rich-content journeys pass security, privacy, accessibility, offline/failure, and performance budgets on B9 clients; provider expansion is not required and any new provider maps to post-beta unless separately justified. |
|
||||
| BPR-062 | Bounded privacy-safe external retrieval | B5 | B2 trust model; B3 bounded-work guardrails | Private adversarial suite covers DNS rebinding/resolution, IPv4/IPv6/private addresses, redirect chains, type sniffing, compressed/streamed size, timeout, concurrency, cache partition/expiry, residual buffering, cancellation, and offline behavior for every fetch path. |
|
||||
| BPR-063 | NSFW consent before load | B5 | BPR-062; per-user preference/authz storage | Server and B9 client tests prove explicit owner label plus per-user acknowledgement; previews stay concealed; network inspection confirms content and third-party media are not requested before consent; revoke, new device, logout, accessibility, and moderator cases pass. |
|
||||
| BPR-064 | English-only, translation-ready | B9 | B7/B8 shared UI; frozen beta strings | All user-facing strings are inventoried behind translation-ready boundaries with no required second language; dynamic/plural/error/accessibility strings are covered; static scan finds unjustified hard-coded UI text; layout tolerates representative expansion. |
|
||||
|
||||
## Moderation
|
||||
|
||||
| ID | Short label | Primary phase | Prerequisites | Minimum verification and closure evidence |
|
||||
| ------- | ---------------------------------- | ------------- | ---------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| BPR-070 | Local reports only | B5 | B4 identity/deletion/retention; B2 permissions | Authenticated users can report message/user/attachment to their own server; cross-server/central delivery is impossible; duplicate/rate-limit/block/deleted-target/access-control tests pass; B9 clients expose the flows without leaking reporter/evidence. |
|
||||
| BPR-071 | Permission-gated Moderation Center | B5 | BPR-070; B2 audit/authz; B7/B8 clients | Service tests cover queue, evidence/context, assignment, status, notes, action links, immutable history, retention, and deletion unlinking; B9 desktop/browser/PWA E2E proves permitted roles see correct data and all others see none. |
|
||||
| BPR-072 | Narrow moderator actions | B5 | BPR-071; canonical effective permissions | Role matrix and adversarial tests cover warning, timeout, removal, kick, ban, hierarchy, self/peer/owner targets, concurrent changes, voice/text effects, and audit; B9 UI hides/blocks unauthorized actions; TLS/backup/update remain owner-only. |
|
||||
| BPR-073 | Rate-limited local appeals | B5 | BPR-071/BPR-072; B4 rate limits/notifications | State/property tests cover submission, rate limit, assignment, status, decision, notification, repeat/closed/blocked users, deletion, retention, and audit; B9 clients show only authorized appeal content and accurate status. |
|
||||
|
||||
## Extensions and deferred systems
|
||||
|
||||
| ID | Short label | Primary phase | Prerequisites | Minimum verification and closure evidence |
|
||||
| ------- | ------------------------------------- | ------------- | ------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| BPR-080 | Experimental WASM disabled by default | B2 | B1 artifact provenance; configuration audit | Fresh, upgraded, Docker, and standalone configurations leave WASM disabled; release/docs/UI mark it experimental with no compatibility promise; example WASM is reproducible or provenance-verified; enabling requires explicit owner action. |
|
||||
| BPR-081 | Identify future plugin candidates | B2 | B0 audit; B3 boundary inventory | Architecture note lists cohesive candidates and why they are separable, while explicitly keeping auth/authz, TLS, safe fetch, quota, E2EE, updater, deletion, recovery, and moderation audit in core; no beta feature is moved to WASM. |
|
||||
| BPR-082 | No federation in beta | B2 | B0 scope freeze; BPR-040 | Protocol/API/config/release review finds no federation, cross-server identity, or cross-server messaging feature; plans/issues route the idea post-beta; generic work is accepted only when justified by a current non-federation requirement. |
|
||||
| BPR-083 | No centralized public directory | B2 | BPR-012 and BPR-040 | Server/client/config/network review finds no automatic listing, discovery submission, central browse/search, or OwnCord directory dependency; owner-shared addresses and invite links pass connect/onboarding tests. |
|
||||
|
||||
## Client experience and accessibility
|
||||
|
||||
| ID | Short label | Primary phase | Prerequisites | Minimum verification and closure evidence |
|
||||
| ------- | ------------------------------------ | ------------- | -------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| BPR-090 | Preserve and polish OwnCord identity | B9 | B7 desktop baseline; B8 responsive client; design tokens | Visual regression and owner review show recognizable navigation/identity and familiar workflows across targets; consistency, responsiveness, accessibility, startup, interaction, and bundle budgets improve or meet accepted baselines; no wholesale rebrand. |
|
||||
| BPR-091 | Accessibility is release-blocking | B9 | B7 semantic foundations; B8 mobile/browser behavior | Automated accessibility plus manual keyboard, pointer, touch, screen reader, reduced-motion, contrast, focus, zoom/reflow, virtual-keyboard, safe-area, error/announcement, and media-control checks pass every critical journey on supported targets. |
|
||||
| BPR-092 | Honest browser/offline limitations | B9 | B6 deployment modes; B8 capability detection | Browser/device/network matrix verifies unavailable media, push, screen capture, updater, native integration, certificate, and offline behavior is disabled or explained actionably; no control falsely reports success; recovery after capability/network return passes. |
|
||||
|
||||
## Community and governance
|
||||
|
||||
| ID | Short label | Primary phase | Prerequisites | Minimum verification and closure evidence |
|
||||
| ------- | ------------------------------------------- | ------------- | -------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| BPR-100 | Issues for bugs; Discussions for community | B1 | B0 scope/intake model | Repository navigation, issue forms, blank-issue policy, Discussions links, support links, and contribution docs route bugs to Issues and support/ideas/feedback to Discussions; dry-run submissions reach the intended destination. |
|
||||
| BPR-101 | Private coordinated vulnerability reporting | B1 | B0 private/public handling; repository security settings | Security policy and forms point to private GitHub reporting; public templates warn against disclosure; permissions and a tabletop report prove private receipt, triage, advisory, fix, coordinated disclosure, and safe public status. |
|
||||
| BPR-102 | Community pull requests supported | B1 | B0 gates; root command facade | A fresh Windows and Linux contributor follows docs to bootstrap, run scoped/full checks, understand scope/generated files/review/security rules, and submit a passing sample change; CI feedback matches local commands. |
|
||||
| BPR-103 | Evidence-based isolated restructure | B1 | Layout audit; green B0 baseline | Targeted migration uses adjacent pure-move and mechanical-path-rewrite commits, preserves release names/desktop behavior/history, proves all active references and generated ownership, and passes the complete exact-SHA matrix; no wholesale repository/server rewrite occurs. |
|
||||
|
||||
## Cross-cutting qualification rule
|
||||
|
||||
A row may be marked:
|
||||
|
||||
- planned: prerequisites or implementation have not started;
|
||||
- in progress: the primary phase owns active work;
|
||||
- implemented, awaiting downstream proof: the server/core invariant is green
|
||||
but a named client or deployment journey is not;
|
||||
- phase-verified: all evidence named in the row is green on that phase commit;
|
||||
- release-qualified: B10 repeated the evidence on the immutable release
|
||||
candidate.
|
||||
|
||||
Only release-qualified satisfies beta. No row is release-qualified at the
|
||||
audited head; implementation maturity ranges from an existing partial
|
||||
foundation to entirely absent and must be refreshed during B0.
|
||||
|
||||
## Completeness check
|
||||
|
||||
The map contains exactly the approved IDs:
|
||||
|
||||
- BPR-001 through BPR-005;
|
||||
- BPR-010 through BPR-016;
|
||||
- BPR-020 through BPR-025;
|
||||
- BPR-030 through BPR-035;
|
||||
- BPR-040 through BPR-046;
|
||||
- BPR-050 through BPR-055;
|
||||
- BPR-060 through BPR-064;
|
||||
- BPR-070 through BPR-073;
|
||||
- BPR-080 through BPR-083;
|
||||
- BPR-090 through BPR-092;
|
||||
- BPR-100 through BPR-103.
|
||||
|
||||
Gaps in the numeric sequence are intentional category spacing, not missing
|
||||
requirements.
|
||||
@@ -0,0 +1,330 @@
|
||||
# OwnCord repository-health issue register
|
||||
|
||||
**As of:** 2026-08-23
|
||||
**Audited head:** `5cc0888964e26276d1aca145e83270a2c1b9febd` (`dev`)
|
||||
**Release target:** first public beta, quality-gated with no calendar deadline
|
||||
**Purpose:** exhaustive, public-safe planning index for bringing the server,
|
||||
desktop client, browser/PWA client, repository, and release process to the
|
||||
approved beta bar.
|
||||
|
||||
Companion documents:
|
||||
|
||||
- [Beta product requirements](beta-product-requirements-2026-08-23.md)
|
||||
- [Repository-layout audit](../audit-2026-08-23-repository-layout.md)
|
||||
- [Phased beta roadmap](repo-health-roadmap-2026-08-23.md)
|
||||
|
||||
This document is a planning view, not a replacement for
|
||||
`.superpowers/findings-ledger.json`. The ledger remains authoritative for
|
||||
`OC-*` finding status. Security-sensitive reproduction detail belongs in a
|
||||
private GitHub Security Advisory; this public register contains only opaque
|
||||
work packages and non-sensitive acceptance criteria.
|
||||
|
||||
## Overall status
|
||||
|
||||
**OwnCord is not beta-ready at this audited head.** The server has a strong
|
||||
tested foundation, but security remediation, compatibility, deployment,
|
||||
capacity, identity, recovery, deletion, retention, and moderation work remain.
|
||||
The desktop client has broad automated coverage, but its required unit-coverage
|
||||
gate is red and its full Playwright run does not terminate. The approved
|
||||
browser/PWA/phone/tablet client is mostly not implemented.
|
||||
|
||||
| Surface | Evidence at the audited head | Health conclusion |
|
||||
| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------ |
|
||||
| Server builds | Default, OpenTelemetry, Wazero, and combined build-tag variants pass; `go vet` passes | Strong |
|
||||
| Server behavior | Full race suite, deadlock suite, and tagged tests pass; CI-style aggregate coverage is 74.6% | Strong, with missing coverage/performance gates |
|
||||
| Server local limitations | Docker daemon was unavailable; local `golangci-lint` could not load because its Go 1.26.5 build mismatched the module's Go 1.26.7 toolchain | CI/container evidence still required for the exact SHA |
|
||||
| Client static/build | App and E2E typechecks, ESLint, Prettier, Knip, production dependency audit, Vite build, Rust Clippy, and 115 Rust tests pass | Healthy foundation |
|
||||
| Client unit coverage | 5,255 tests pass and 2 fail (`message-list` and `noise-suppression-restart`) | Required gate red |
|
||||
| Client browser tests | Three Chromium browser tests pass | Useful but too narrow |
|
||||
| Client Playwright | All 293 test start markers appeared with no reported assertion failure, but the run never exited; an isolated five-test voice-widget run also hung | Cannot be claimed green |
|
||||
| Client bundles | Build succeeds, but RNNoise/live-session output is about 2.0 MB minified / 1.345 MB gzip and Vite reports oversized/dynamic-import warnings | Performance work required |
|
||||
| Browser/PWA/mobile | No standalone browser production target, optional server hosting, PWA, Web Push, or beta-quality phone/tablet navigation exists | Major beta capability gap |
|
||||
| Security | A private current-HEAD source review identified unresolved security-boundary work; public tracking uses opaque remediation families while detailed evidence remains private | Beta blocker; details remain private |
|
||||
| Repository/release | Exact `dev` SHA has no Actions run; supported ARM64 and multi-architecture release coverage is incomplete | Beta blocker |
|
||||
|
||||
## Classification and counting rules
|
||||
|
||||
Priority:
|
||||
|
||||
- **P0:** a required gate is red or the audited integration cannot be released.
|
||||
- **P1:** close before beta; security, authorization, data safety, compatibility,
|
||||
or major reliability/release risk.
|
||||
- **P2:** scheduled architecture, performance, accessibility, operational, or
|
||||
contributor-experience debt.
|
||||
- **P3:** low-risk cleanup, monitoring, or an explicitly recorded decision.
|
||||
|
||||
State:
|
||||
|
||||
- **confirmed:** reproduced, validated, or directly observed at the audited head.
|
||||
- **verify:** credible evidence exists, but a focused reproduction is required.
|
||||
- **decision:** the owner must select and record one supported direction.
|
||||
- **watch:** an upstream or accepted risk has no demonstrated reachable defect.
|
||||
- **resolved/superseded:** the original observation is no longer current; a
|
||||
broader active item owns any remaining work.
|
||||
|
||||
The tables deliberately separate four kinds of work. They must not be added
|
||||
together as if each row were a unique defect:
|
||||
|
||||
1. `OC-*` rows are the canonical open defect ledger.
|
||||
2. `G/C/S/R/L-*` rows are audit work packages, guardrails, or architecture debt.
|
||||
3. `SEC-*` rows are opaque security-remediation families; duplicates are
|
||||
explicitly named.
|
||||
4. `BG-*` rows are approved beta capabilities that are absent or incomplete,
|
||||
not regressions in an already-complete feature.
|
||||
|
||||
## Canonical findings-ledger truth
|
||||
|
||||
| Status | Count |
|
||||
| --------- | ------: |
|
||||
| Fixed | 306 |
|
||||
| Open | 38 |
|
||||
| Declined | 3 |
|
||||
| Duplicate | 1 |
|
||||
| **Total** | **348** |
|
||||
|
||||
All 38 open records are listed below. Closing a planning row does not close an
|
||||
`OC-*` record: the implementation, regression test, focused verification, full
|
||||
required gates, and ledger update must land together.
|
||||
|
||||
## Immediate gate and truth issues
|
||||
|
||||
| ID | Pri | State | Issue and evidence | Phase | Closure evidence |
|
||||
| ---- | --: | --------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----- | ----------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| G-01 | P0 | confirmed | `message-list.test.ts` expects zero abort registrations while current row-scoped cancellation registers five; the full coverage run fails. | B0 | Test states the intended row-lifetime invariant, proves the historical leak shape, and passes in the complete Node 24/Vitest 4 run. |
|
||||
| G-02 | P0 | confirmed | `noise-suppression-restart.test.ts` supplies a non-constructible arrow-function mock for `MediaStream`; Vitest 4 rejects it. | B0 | Constructible test double, meaningful RED proof, and complete coverage run green. |
|
||||
| G-03 | P0 | confirmed | Current `dev` SHA has no Actions run because ordinary `dev` pushes are not covered by the complete push matrix. This is the canonical owner for layout finding RL-14. | B0/B1 | Every integration SHA receives the protected full blocking matrix; this exact SHA or its superseding remediation SHA is green. |
|
||||
| G-04 | P1 | confirmed | The ledger now correctly exposes 38 open items, but older plans/snapshots still claim zero open or leave shipped phases pending. | B0/B1 | Active-plan index identifies current, complete, and superseded documents; automated checks prevent conflicting status/count claims. |
|
||||
|
||||
## Canonical open defect ledger
|
||||
|
||||
The wording below is intentionally concise. The ledger contains the detailed
|
||||
evidence, reproduction, and suggested fix for each record.
|
||||
|
||||
| ID | Sev | Area | Public-safe defect summary | Phase | Required closure evidence |
|
||||
| ------- | ------ | ----------------------- | --------------------------------------------------------------------------------------------------------------------------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| OC-0311 | Medium | Client voice/E2EE | A leave event from another readable voice channel can mutate the active call's peer-key state. | B2/B7 | Scope leave handling to the active channel and cover reordered leave/join/replay sequences. |
|
||||
| OC-0312 | Medium | Client PTT | Binding push-to-talk during a call can clear mute ownership before the deferred mute applies, leaving PTT unusable. | B7 | Preserve the PTT ownership transition atomically and test mid-call binding/restart. |
|
||||
| OC-0313 | Medium | Client profiles | Legacy per-user volume fallback is repeatedly copied across server profiles instead of being consumed once. | B4/B7 | One-time scoped migration, legacy-key removal, and cross-server isolation tests. |
|
||||
| OC-0314 | Medium | Client identity | The client discards the server's partial-success warning when a credential change succeeds but session revocation does not. | B4/B9 | Surface warnings for password/TOTP changes with an action to review sessions; test all affected endpoints. |
|
||||
| OC-0315 | Medium | Client replay | Replay-gate timestamps mix naive UTC server values with local wall-clock parsing. | B2/B7 | One UTC parsing contract and timezone-varied replay boundary tests. |
|
||||
| OC-0316 | Medium | Server/client E2EE | WebSocket resume restores peer public keys but not a room key rotated during the outage. | B2/B7 | Resume re-establishes the current room key and the security indicator cannot claim success prematurely; rotation/outage test passes. |
|
||||
| OC-0317 | Medium | Client DM state | The replay path can regress a DM's `lastMessageId`, undermining duplicate-count protection. | B2/B7 | Monotonic last-message updates with duplicate, out-of-order, and reconnect tests. |
|
||||
| OC-0318 | Medium | Server plugins | Install-time and restart-time plugin manifest precedence differs between JSON and TOML. | B2 | One canonical manifest contract or explicit ambiguity rejection; install/restart parity test. |
|
||||
| OC-0319 | Medium | Client accessibility | The Large Font preference is overridden by a higher-priority inline font-size value. | B9 | Verified text-scale change across restart, zoom, responsive layouts, and accessibility checks. |
|
||||
| OC-0320 | Medium | Server updater | Server self-update selects Linux AMD64 independently of the running architecture. | B6/B10 | Architecture-aware manifest selection and signed update/rollback smoke on every supported server target. |
|
||||
| OC-0321 | Medium | Server TOTP | A TOTP key-file read failure can be treated as absence and lead to key replacement. | B4 | Generate only on confirmed non-existence; all other read errors fail closed without modifying the file. |
|
||||
| OC-0322 | Low | Client connection | TypeScript host validation accepts a hostname form rejected by the native proxy. | B2/B7 | Shared validation corpus produces identical browser, desktop, and Rust decisions. |
|
||||
| OC-0323 | Low | Server unread state | Mark-read/channel-focus can overwrite a mention count from a newer message using a stale snapshot. | B3/B5 | Atomic/monotonic read-state update with concurrent-message regression coverage. |
|
||||
| OC-0324 | Low | Server auth | Login rate-limit identity folding differs from SQLite account lookup semantics. | B4 | Account lookup and limiter use one tested canonical identity rule, including Unicode collision cases. |
|
||||
| OC-0325 | Low | Client search | Search results parse naive UTC timestamps as local time. | B7/B9 | Shared UTC parser and timezone/day-boundary rendering tests. |
|
||||
| OC-0326 | Low | Client pins | Pinned-message timestamps parse naive UTC values as local time. | B7/B9 | Shared UTC parser and timezone/day-boundary rendering tests. |
|
||||
| OC-0327 | Low | Server voice moderation | Server mute/deafen also affects screen-share audio contrary to the product contract. | B5 | Effective moderation applies only to intended media sources; SFU and client-policy tests agree. |
|
||||
| OC-0328 | Low | Client unread state | Channel badges lack the message-ID replay guard already used by DMs. | B2/B7 | Monotonic channel replay guard with duplicate/out-of-order/reconnect tests. |
|
||||
| OC-0329 | Low | Client privacy | Legacy DM profile notes fall back across servers indefinitely. | B4/B7 | One-time server-scoped migration, old-key removal, and cross-server privacy test. |
|
||||
| OC-0330 | Low | Client pins | Pinned messages discard author identity and therefore cannot resolve nicknames. | B7/B9 | Preserve author ID and render the same display identity as ordinary messages. |
|
||||
| OC-0331 | Low | Server admin UI | API-token Created/Last Used values parse naive UTC timestamps as local time. | B6/B9 | Shared UTC contract and timezone/day-boundary admin tests. |
|
||||
| OC-0332 | Low | Client updater | Bare IPv6 server addresses produce an invalid updater URL. | B6/B10 | Central URL builder brackets IPv6 literals and passes domain/IPv4/IPv6/update smoke tests. |
|
||||
| OC-0333 | Low | Client voice UI | Voice-roster render identity does not change when a participant is renamed mid-call. | B7/B9 | Reactive identity signature and rename-in-call test. |
|
||||
| OC-0334 | Low | Client PTT | Escape closes Settings and can simultaneously be saved as the captured PTT key. | B7/B9 | Escape cancels capture without persistence; teardown and timeout paths are tested. |
|
||||
| OC-0335 | Low | Client lifecycle | Each Add Server modal retains listeners and its removed subtree for the connect-page lifetime. | B7 | Modal-owned abort lifecycle; repeated open/close instrumentation shows no accumulation. |
|
||||
| OC-0336 | Low | Client lifecycle | Server-profile rows re-register page-lifetime listeners on every render. | B7 | Row/render ownership prevents accumulation under repeated updates and teardown. |
|
||||
| OC-0337 | Low | Server replay | Cold-tier voice replay truncation can discard the newest events and reconstruct the wrong roster. | B2/B3 | Ordered, bounded replay retains the correct window; boundary/resume tests reconstruct the authoritative roster. |
|
||||
| OC-0338 | Low | Server plugins | TOML plugin manifests can omit configured memory and CPU resource limits. | B2/B3 | Explicit TOML mapping and JSON/TOML resource-limit parity tests. |
|
||||
| OC-0339 | Low | Server config | A valid but empty configuration section is reported as an unknown ineffective key. | B6 | Empty known sections are accepted; true unknown keys remain actionable and tested. |
|
||||
| OC-0340 | Low | Server CLI | A negative API-token expiry can create a token that never expires. | B4/B6 | CLI and HTTP share positive-expiry validation; negative/zero/boundary tests fail safely. |
|
||||
| OC-0341 | Low | Server CLI | A numeric token label cannot be revoked because parsing commits to the ID path. | B4/B6 | Unambiguous ID/label selection or safe fallback with numeric-label regression tests. |
|
||||
| OC-0342 | Low | Client voice UI | Voice avatar letter/color derives from username while the adjacent label may be a nickname. | B9 | Avatar and label consistently derive from the displayed identity. |
|
||||
| OC-0343 | Low | Desktop shell | Clicking the tray icon can hide a minimized window instead of restoring it. | B7/B9 | Minimized windows unminimize and focus; only visible, non-minimized windows toggle hidden. |
|
||||
| OC-0344 | Low | Server TLS | Automatic HTTP-to-HTTPS redirect assumes port 443 instead of the configured HTTPS endpoint. | B6 | Redirect derives the configured public origin/port and passes default/custom/domain/IP tests. |
|
||||
| OC-0345 | Low | Server owner auth | Owner middleware repeats a role read and maps a transient read failure to forbidden. | B3/B4 | Reuse the authenticated context and preserve correct unavailable/unauthorized distinctions in failure tests. |
|
||||
| OC-0346 | Low | Server telemetry | Panic recovery reads trace context before tracing middleware creates it. | B3/B6 | Middleware order gives recoveries the active trace ID; panic-path structured-log test passes. |
|
||||
| OC-0347 | Low | Client DM voice UI | A DM call label reads but does not subscribe to DM state, so it remains stale. | B7/B9 | Subscribe to the owning state and test mid-call rename/update. |
|
||||
| OC-0348 | Low | Client presence | The online-count header includes the local invisible user while the member list presents that user as offline. | B7/B9 | Count and list share one visibility policy with invisible-status regression tests. |
|
||||
|
||||
## Public-safe security remediation
|
||||
|
||||
An independent current-HEAD security review produced detailed reports that
|
||||
remain untracked/private until fixed or coordinated through private advisories.
|
||||
This register carries only non-sensitive security properties and opaque
|
||||
remediation families; an apparently related engineering row is not evidence
|
||||
that any private report is fixed.
|
||||
|
||||
| ID | Pri | State | Opaque remediation family | Phase | Public closure evidence |
|
||||
| ------ | --: | --------- | --------------------------------------------------------- | ----- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| SEC-01 | P1 | confirmed | Atomic concurrent password-confirmation admission. | B4 | One server-owned admission decision, bounded concurrent attempts, and race/load regression coverage. |
|
||||
| SEC-02 | P1 | confirmed | Effective channel-level voice moderation permissions. | B5 | Voice moderation delegates to the same effective-permission policy as the authoritative channel action, with override and denial tests. |
|
||||
| SEC-03 | P1 | confirmed | Bounded per-response and aggregate preview/media reads. | B2/B5 | Streaming limits are enforced before buffering; aggregate memory/concurrency budgets, timeout, cancellation, and adversarial boundary tests pass. |
|
||||
| SEC-04 | P1 | confirmed | Durable per-user/server storage quotas and disk headroom. | B3/B6 | Transaction-safe quotas cover files and cumulative storage; low-disk behavior fails safely and is exercised by restart/concurrency tests. |
|
||||
|
||||
## Client engineering issues
|
||||
|
||||
These are broader gates and work packages; canonical `OC-*` defects above are
|
||||
not recounted here.
|
||||
|
||||
| ID | Pri | State | Issue and evidence | Phase | Closure evidence |
|
||||
| ---- | --: | --------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| C-01 | P1 | confirmed | `.nvmrc`/active docs use Node 20, while CI uses Node 24 and package metadata does not enforce the intended runtime. Canonical owner for RL-17. | B1 | One Node/npm source of truth drives local setup, packages, CI, release, and docs; wrong majors fail fast. |
|
||||
| C-02 | P1 | confirmed | Oxlint exits zero with 471 warnings, concentrated in LiveKit/E2EE bindings. | B7 | Narrowly allow intentional generated/external names, fix actionable warnings, and make the blocking invocation warning-free. |
|
||||
| C-03 | P1 | confirmed | Coverage cannot complete because G-01/G-02 fail, and exercised entry/orchestration files remain excluded. | B0/B7 | Green full report includes exercised production files; exclusions are minimal and documented; thresholds ratchet from an honest baseline. |
|
||||
| C-04 | P2 | confirmed | Unit/E2E runs emit expected warnings and large expected debug/error output, obscuring unexpected failures. | B7 | Expected logs are captured/asserted; a green run has no unexplained runtime warnings or log flood. |
|
||||
| C-05 | P3 | confirmed | Knip passes with four configuration hints. | B7 | No hints, or each retained exception has a current inline rationale. |
|
||||
| C-06 | P0 | confirmed | Full Playwright and an isolated voice-widget subset fail to terminate on Windows after their observed test activity. | B0/B10 | Playwright exits unaided locally and in CI; the cause is regression-tested and no child process remains. |
|
||||
| C-07 | P1 | confirmed | Static RNNoise inclusion creates an approximately 2.0 MB minified / 1.345 MB gzip feature chunk. | B7/B9 | Load on demand, cache after first use, and prove voice/noise restart/fallback behavior. |
|
||||
| C-08 | P2 | confirmed | Vite warns about oversized chunks, but no startup/route/feature bundle budget blocks regressions. | B7/B9 | Recorded gzip budgets fail CI on regression and distinguish startup from lazy feature cost. |
|
||||
| C-09 | P1 | confirmed | Desktop external-preview destination policy is not fully centralized at the native trust boundary. | B2/B7 | One native policy owns resolution, redirects, destinations, time/body limits, and parsing; broad capability scope is removed. |
|
||||
| C-10 | P1 | confirmed | Client CSP permits broad HTTPS/WSS destinations and lacks a generated per-deployment allowlist contract. | B2/B7/B8 | Required origins/protocols are inventoried and minimized for desktop/browser modes with functional regression tests. |
|
||||
| C-11 | P2 | confirmed | Four production import cycles remain in LiveKit/audio and message attachment/media/embed code. | B7 | Production graph is acyclic or an approved seam and boundary test documents each unavoidable cycle. |
|
||||
| C-12 | P2 | confirmed | High-change client modules remain very large, including LiveKit/E2EE, dispatcher, and settings surfaces. | B7/B9 | Responsibility maps guide cohesive extractions behind stable tested seams without behavior or coverage regression. |
|
||||
| C-13 | P2 | confirmed | Duplicated color/host literals, many timer call sites, and an O(n) sidebar DOM-rebuild TODO remain. | B7/B9 | Shared tokens/config, lifecycle-owned timers, and measured incremental sidebar updates replace the duplication/hot path. |
|
||||
| C-14 | P1 | confirmed | Native smoke configuration exists but is absent from blocking CI because it needs a built app and real server. | B10 | Release candidates run packaged native smoke on the supported Windows/Linux architecture matrix. |
|
||||
| C-15 | P1 | confirmed | Full Tauri packaging is not a routine exact-SHA integration gate. | B1/B10 | Cost-conscious integration/nightly/RC jobs package without exposing signing secrets to untrusted dependency PRs. |
|
||||
| C-16 | P2 | confirmed | Mutation fixes landed after the last measured 67.04% baseline; the suite was not rerun. | B7/B10 | Fresh baseline, survivor triage, and ratcheted targets for critical transport/auth/E2EE modules. |
|
||||
| C-17 | P3 | confirmed | Direct real-browser coverage is only three Chromium tests and is concentrated on RNNoise. | B8/B10 | Browser-only API risk inventory drives blocking Chromium/Firefox/WebKit coverage plus real-device qualification where emulation is insufficient. |
|
||||
| C-18 | P3 | watch | Cargo has no known reachable vulnerability, but allowed unmaintained transitive crates and compatible patches require ownership. | B10 | Compatible patches are reviewed; warnings are revisited each dependency cycle; platform migration path is recorded. |
|
||||
|
||||
## Server engineering issues
|
||||
|
||||
| ID | Pri | State | Issue and evidence | Phase | Closure evidence |
|
||||
| ---- | --: | --------- | ----------------------------------------------------------------------------------------------------------------------------------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| S-01 | P1 | confirmed | Typing currently checks a weaker permission than posting. | B2/B3 | Typing delegates to the same send-policy predicate; denial, announcement, and override tests prevent drift. |
|
||||
| S-02 | P1 | confirmed | Invite create/revoke are privileged mutations without the audit coverage used by sibling mutation families. | B4/B5 | Successful create/revoke produce safe, non-secret audit events; failure behavior is tested. |
|
||||
| S-03 | P2 | confirmed | Admin channel name/topic/category validation lacks one explicit rune/normalization contract. | B3/B5 | Shared limits cover admin and user writers; boundary tests count runes, not bytes. |
|
||||
| S-04 | P2 | confirmed | Sibling admin channel lookups expose inconsistent DM/not-found response contracts. | B3 | One non-DM resolution policy and response contract covers both paths. |
|
||||
| S-05 | P2 | confirmed | Repository-wide Go formatting is not a required gate. | B1 | Tree is formatted and a fast required gate fails future drift. |
|
||||
| S-06 | P2 | confirmed | Server coverage is uploaded without a global or core-package regression floor; current aggregate is 74.6%. | B3/B10 | Documented baseline/exclusions and ratcheted global/core thresholds. |
|
||||
| S-07 | P2 | confirmed | Thousands of tests and 17 fuzz targets exist, but there are no Go benchmarks for hub/replay, permission, DB, or fan-out hot paths. | B6/B10 | Stable microbenchmarks and reference load baselines cover the highest-risk paths. |
|
||||
| S-08 | P2 | confirmed | Large lifecycle/hub/serve files remain structural hotspots. | B3 | Cohesive extractions preserve lifecycle, locking, race, and deadlock invariants. |
|
||||
| S-09 | P2 | confirmed | API/admin/WebSocket layers still contain many direct database call sites. | B3 | Each use moves behind a narrow service/store seam or is documented as an intentional transaction/composition boundary. |
|
||||
| S-10 | P2 | confirmed | Auth routes still consume raw database ownership and are the first intended S-09 migration slice. | B3/B4 | Tested AuthService/narrow interfaces preserve enumeration and sentinel-error behavior. |
|
||||
| S-11 | P2 | confirmed | Hub construction uses post-construction collaborator setters, leaving required wiring temporally coupled to `Run`. | B3 | Required collaborators are validated constructor/options inputs; only genuinely dynamic dependencies remain mutable. |
|
||||
| S-12 | P2 | confirmed | Ready/refresh/WebSocket paths mirror message send-permission policy by hand. | B3 | All paths delegate to one value-taking predicate with parity tests. |
|
||||
| S-13 | P2 | confirmed | Durable TOTP used-code and partial-auth persister work remains incomplete. | B4 | Hash-only persistence, expiry, restart, and failure-mode tests land without persisting sliding rate-limit windows. |
|
||||
| S-14 | P1 | confirmed | Load tooling exists, but no supported capacity result is published for the approved 250 users / 100 connections / 25 voice profile. | B6/B10 | Reproducible report states hardware/software, CPU, memory, DB waits, p95/p99 latency, and pass/fail thresholds. |
|
||||
| S-15 | P3 | verify | `voice_speakers` and `member_leave` remain reserved protocol entries with no production emit site. | B2 | Compatibility review removes unused entries before the epoch freeze or explicitly reserves and fixtures them; schema, generated types, docs, and tests agree. |
|
||||
| S-16 | P3 | verify | Voice key-holder TOCTOU hardening remains a documented follow-up without a demonstrated contract failure. | B2/B3 | Threat-model review either records why outer checks suffice or adds an in-function recheck and race-focused private test. |
|
||||
| S-17 | P3 | watch | Vulnerability tooling found no reachable Go advisory, while non-called/unmaintained upstream paths remain. | B6/B10 | Dependency path is monitored, compatible fixes are applied, and reachable-symbol scanning remains required. |
|
||||
|
||||
## Repository, CI, documentation, and supply chain
|
||||
|
||||
| ID | Pri | State | Issue and evidence | Phase | Closure evidence |
|
||||
| ---- | --: | ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------- | --------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| R-01 | P1 | confirmed | Real-server admin E2E remains job-level non-blocking; its approximately 30-green graduation evidence is not recorded. | B10 | Thirty consecutive required integration runs or an equivalent statistically justified criterion passes before the job becomes blocking. |
|
||||
| R-02 | P2 | confirmed | Active documents disagree whether contributors branch/PR against `main` or `dev`. | B0/B1 | One protected branch model is reflected in docs, automation, templates, and repository settings. |
|
||||
| R-03 | P2 | resolved/superseded | The graph was refreshed at the audited head, resolving the old stale-SHA observation; generated-artifact ownership and local launcher portability remain under L-06. | B1 | No separate action; L-06 owns the remaining artifact-policy exit gate. |
|
||||
| R-04 | P1 | confirmed | Build/runtime container references use mutable tags without complete digest-refresh ownership. Canonical beta owner for the release supply-chain portion of RL-18. | B1/B6 | Reviewed immutable digests or automated digest PRs with smoke tests cover release/runtime images. |
|
||||
| R-05 | P2 | confirmed | Repeated API/schema/protocol prose drift is guarded mostly by a PR checkbox. | B1/B2 | Generated inventories/contract tests cover machine-checkable facts and the remaining prose has an explicit review gate. |
|
||||
| R-06 | P2 | confirmed | Active, completed, historical, and superseded plans are not indexed consistently. | B0/B1 | Docs landing page and plan index expose status; link/status checks catch contradictions. |
|
||||
| R-07 | P2 | confirmed | Major dependency, license, SBOM, and provenance review lacks one documented cadence across all dependency roots. | B1/B6/B10 | Automated coverage plus a dated recurring major/license review and signed release SBOM/provenance. |
|
||||
| R-08 | P1 | confirmed | No single beta scorecard defines allowed open priorities, platform coverage, security sign-off, soak, upgrade/restore drills, or performance evidence. | B0/B10 | Owner-approved scorecard is green after the release-candidate soak and links every evidence artifact. |
|
||||
| R-09 | P1 | confirmed | A version tag can publish without proof that the exact tagged SHA completed the protected beta gate. Canonical owner for RL-16. | B1/B10 | Publication consumes immutable exact-SHA gate evidence and a protected release approval. |
|
||||
|
||||
## Repository layout and contributor experience
|
||||
|
||||
The layout audit recommends a targeted, isolated migration—not a wholesale
|
||||
monorepo/server rewrite. Pure moves, mechanical path rewrites, and
|
||||
behavior-changing work must remain in separate reviewable commits.
|
||||
|
||||
| ID | Pri | Source | Required work | Phase | Closure evidence |
|
||||
| ---- | --: | ------ | ------------------------------------------------------------------------------------------------------------------------------------------ | ----- | ----------------------------------------------------------------------------------------------------------------------- |
|
||||
| L-01 | P1 | RL-01 | Flatten `Client/tauri-client/` to `Client/` as two adjacent non-functional commits: pure file moves, then mechanical active-path rewrites. | B1 | History/release asset names are preserved and the full baseline is unchanged after both commits. |
|
||||
| L-02 | P1 | RL-02 | Record the browser/desktop platform-contract map in B1, then introduce typed adapters for native-dependent frontend services. | B7 | The same adapter contract suite passes for desktop and browser implementations. |
|
||||
| L-03 | P1 | RL-03 | Establish independent `build:web` and `build:desktop` contracts from one shared UI after server-first phases close. | B7 | Both production builds are required and target-specific behavior is isolated. |
|
||||
| L-04 | P2 | RL-04 | Add cross-platform root bootstrap, format, generation, scoped, and full verification commands. | B1 | Fresh Windows/Linux contributors can discover and run the intended checks; Go-only direct commands remain supported. |
|
||||
| L-05 | P2 | RL-05 | Record the workspace decision and cover every lock root with deterministic install/dependency automation. | B1 | Measured rationale, immutable installs, and update coverage for all package roots. |
|
||||
| L-06 | P2 | RL-06 | Make large Graphify payloads reproducible CI artifacts; retain only a compact deterministic report if needed. | B1 | Portable local/CI generation works, committed report drift is checked, and published history is not rewritten. |
|
||||
| L-07 | P2 | RL-07 | Remove the tracked duplicate human rendering after deterministic on-demand/CI rendering and a drift check exist. | B1 | The JSON ledger remains canonical; a downloadable rendering is reproducible and CI rejects generation failure or drift. |
|
||||
| L-08 | P2 | RL-08 | Keep the example WASM source, stop tracking its prebuilt output, and compile/verify it in CI or release checks. | B1/B2 | Deterministic source build passes and no stable plugin API promise is implied. |
|
||||
| L-09 | P2 | RL-09 | Move protocol schema/generator ownership to a root protocol/tool boundary. | B1/B2 | One command generates Go and TypeScript consumers with zero drift. |
|
||||
| L-10 | P1 | RL-10 | Move executable tooling under conventional command ownership and remove package-discovery filesystem side effects. | B1 | Broad Go discovery is read-only and tool execution is explicit/tested. |
|
||||
| L-11 | P2 | RL-11 | Reclassify cross-stack invariants under an explicit owner or root system-contract tier. | B1 | Test names/location/commands expose ownership and CI runs the correct tier. |
|
||||
| L-12 | P2 | RL-13 | Align the Go module namespace to `github.com/J3vb/OwnCord/Server` in an isolated mechanical change. | B1 | Imports, generators, build tags, source archives, and downstream instructions agree. |
|
||||
| L-13 | P2 | RL-19 | Add an editor baseline and repository gates for Markdown, YAML, JSON, CSS, Rust, Go, shell, and workflows. | B1 | Cross-platform fast checks cover material tracked sources with explicit generated/vendor exclusions. |
|
||||
| L-14 | P2 | RL-20 | Make hooks portable and remove undocumented `make`/POSIX assumptions on Windows. | B1 | Hooks are thin optional wrappers around cross-platform root commands; prerequisites are explicit. |
|
||||
| L-15 | P2 | RL-21 | Route ideas/feedback to Discussions and modernize issue forms for browser, ARM64, deployment mode, and security reporting. | B1 | Intake matches BPR-100..102 and captures reproducible environment details. |
|
||||
| L-16 | P1 | RL-22 | Harden authorization for externally triggered paid automation. | B1 | Trusted authorization, least privilege, and cost-abuse regression tests are required. |
|
||||
|
||||
Layout findings reconciled elsewhere: RL-12 is owned by R-06; RL-14 by G-03;
|
||||
RL-15 by BG-20; RL-16 by R-09; RL-17 by C-01; and RL-18 by L-05,
|
||||
R-04, and R-07.
|
||||
|
||||
## Approved beta capability gaps
|
||||
|
||||
Every row below is required by the frozen beta product requirements. These are
|
||||
feature-completion gaps, not additions beyond scope.
|
||||
|
||||
| ID | Pri | State | Missing or incomplete beta capability | Phase | Exit evidence |
|
||||
| ----- | --: | --------- | ----------------------------------------------------------------------------------------------------------------------------------------- | --------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| BG-01 | P1 | confirmed | Optional server-hosted browser client, disabled by default. | B5/B8 | Owner opt-in controls hosting; disabled mode exposes no app route/assets; enabled mode passes upgrade/security smoke. |
|
||||
| BG-02 | P1 | confirmed | Installable PWA with safe shell caching, icons, standalone presentation, and update behavior. | B8 | Manifest/installability audits pass; service worker never caches API/messages/credentials and handles version changes safely. |
|
||||
| BG-03 | P1 | confirmed | Beta-quality responsive phone/tablet navigation, touch, keyboard, safe-area, and media UX. | B8/B9 | Real-device and emulated phone/tablet matrix passes defined journeys and accessibility checks. |
|
||||
| BG-04 | P1 | confirmed | Browser parity for credentials, transport, notifications, media/calls/E2EE, files, and safe external content where browser APIs allow. | B7/B8/B9 | Shared behavior/contract suite passes; every unavoidable browser limitation is explicit and safely degraded. |
|
||||
| BG-05 | P1 | confirmed | Per-server owner/user opt-in Web Push without an OwnCord-operated relay. | B5/B8 | Per-server keys/subscriptions, permission UX, unsubscribe/cleanup, privacy defaults, and supported-platform delivery tests pass. |
|
||||
| BG-06 | P1 | confirmed | Secure browser deployment for domains, raw public IPs, LAN, and offline modes without a required reverse proxy or routine manual renewal. | B6/B8 | Domain/IP automated TLS, private-LAN local-trust onboarding, manual-cert escape hatch, renewal/restart tests, and honest limitations are documented. |
|
||||
| BG-07 | P1 | confirmed | Explicit server/current-and-previous-two-client protocol negotiation and safe rejection. | B2/B7/B10 | N/N-1/N-2 compatibility matrix passes; out-of-window clients fail with an actionable update requirement. |
|
||||
| BG-08 | P1 | confirmed | New-login notices and sign-out-everywhere UI; per-session list/revoke backend exists but is not a complete user journey. | B4/B9 | Multi-device list, individual/all revocation, notices, stale-device handling, and audit tests pass. |
|
||||
| BG-09 | P1 | confirmed | Offline recovery kit, audited admin-assisted reset, and optional SMTP recovery. | B4/B9 | Non-reversible server storage, one-time rotation, session revocation, rate limits, operator/user UX, and restore tests pass. |
|
||||
| BG-10 | P1 | confirmed | Complete closed/invite/approval/open registration modes with invite-only default. | B4/B9 | Mode transitions, approvals, abuse limits, invitations, audit, and migration tests pass. |
|
||||
| BG-11 | P1 | confirmed | Full account erasure and backup non-resurrection. | B4 | Profile/auth/session/message/reaction/upload deletion is transactional/resumable, integrity logs are deidentified, and restore honors deletion markers. |
|
||||
| BG-12 | P1 | confirmed | Configurable server/channel retention with corresponding attachment cleanup. | B4/B5/B9 | Default indefinite retention remains; scheduled deletion, holds, audit, storage cleanup, backup/restore, and boundary tests pass. |
|
||||
| BG-13 | P1 | confirmed | Discord-style Message Requests for first-time DMs. | B5/B9 | Preview/accept/ignore/delete/block/trust relationship behavior is abuse-resistant and consistent across desktop/browser/PWA. |
|
||||
| BG-14 | P1 | confirmed | Local reports, permission-gated Moderation Center, workflow/audit history, moderator actions, and appeals. | B5/B9 | Report/evidence/assignment/status/notes/actions/appeal journeys enforce narrow permissions and immutable audit records. |
|
||||
| BG-15 | P1 | confirmed | Privacy-safe support bundle and verified zero automatic telemetry. | B6/B9 | Redaction tests and user preview/consent protect secrets/content; network audit proves no automatic product telemetry. |
|
||||
| BG-16 | P1 | confirmed | English-only but translation-ready user-facing text organization. | B7/B9 | User-visible strings are inventoried/extracted or deliberately exempted; locale/time/plural formatting has a stable seam. |
|
||||
| BG-17 | P1 | confirmed | Plugin-candidate boundary audit and consistent experimental/disabled labeling. | B2 | Candidate integrations are documented for post-beta; beta core security/identity/update/moderation/deletion remains core; no compatibility promise leaks. |
|
||||
| BG-18 | P1 | confirmed | NSFW consent must prevent fetch/render leakage before acknowledgement, not merely overlay already-mounted content. | B5/B9 | No content, preview, attachment, or third-party request occurs pre-consent; blur/gate/revoke tests pass. |
|
||||
| BG-19 | P1 | confirmed | Secure polish for link previews, GIFs, YouTube, and rich media. | B5/B9 | Provider boundaries, privacy controls, bounded retrieval, consent, caching, failure UX, and offline behavior pass shared tests. |
|
||||
| BG-20 | P1 | confirmed | Public-beta packaging/update matrix for Windows x64/ARM64, Linux x64/ARM64, server binaries, and multi-architecture Docker. | B6/B10 | Build, install/boot, signature/checksum, manifest, in-place alpha upgrade, rollback, and update tests pass on every approved architecture. |
|
||||
|
||||
## Discovery passes required before claiming exhaustive coverage
|
||||
|
||||
No finite static audit proves the absence of every latent defect. The strongest
|
||||
defensible completion claim is that each defined risk surface was inspected,
|
||||
candidates were independently validated, and accepted risks have owners. The
|
||||
following focused passes are mandatory during B0 through B10:
|
||||
|
||||
1. Authentication, session, recovery, TOTP, registration, and authorization
|
||||
sibling sweep.
|
||||
2. WebSocket sequencing, replay, replacement, compatibility, and lock-order
|
||||
simulation.
|
||||
3. Voice/LiveKit/E2EE lifecycle, moderation, resume, and fault injection.
|
||||
4. Client async lifetimes, detached DOM/listeners, timers, cancellation, and
|
||||
stale snapshots.
|
||||
5. Desktop proxy/TOFU/updater/signing, browser TLS/PWA/push, secure-context, and
|
||||
secrets-at-rest threat review.
|
||||
6. Database migrations, account deletion, retention, backup/restore,
|
||||
non-resurrection, disk-full, and crash consistency.
|
||||
7. Release supply chain, container provenance, dependency licenses, SBOM, and
|
||||
exact-SHA publication controls.
|
||||
8. Performance/memory profiling for startup, large histories, reconnect storms,
|
||||
100 connections, 25 voice participants, media restart, and long sessions.
|
||||
9. Keyboard, focus, screen reader, reduced motion, contrast, zoom, touch,
|
||||
phone/tablet layout, virtual keyboard, and destructive UX journeys.
|
||||
10. API/protocol/schema/config/documentation contract diff, including
|
||||
N/N-1/N-2 compatibility fixtures.
|
||||
11. Test-quality audit: stale assertions, tests that cannot fail, mutation
|
||||
survivors, fuzz targets, real-browser/native gaps, and shutdown leaks.
|
||||
12. Operational drills: unhealthy DB/disk/hub, certificate renewal, offline/LAN
|
||||
trust, backup recovery, updater rollback, and release artifact boot/install.
|
||||
|
||||
Each pass returns **confirmed / refuted / duplicate / accepted / blocked**.
|
||||
Security-sensitive confirmed detail moves to a private advisory before public
|
||||
planning or implementation discussion.
|
||||
|
||||
## Explicitly outside beta
|
||||
|
||||
Do not convert these into health-remediation work unless they reveal a defect
|
||||
in an approved beta contract:
|
||||
|
||||
- federation, cross-server identity, or cross-server messaging;
|
||||
- more than one active server connection per client;
|
||||
- anonymous guests or a centralized server directory;
|
||||
- native macOS, iOS, or Android applications;
|
||||
- a stable plugin API or bundled third-party plugins;
|
||||
- OwnCord-operated hosting, identity, push relay, telemetry, or moderation;
|
||||
- unrelated feature expansion after the frozen scope.
|
||||
|
||||
Good post-beta plugin candidates include GIF/embed providers, slash
|
||||
commands/bots/automation, webhooks/integrations, optional moderation automation
|
||||
with human/audit control retained, UI tabs, import/export bridges, and
|
||||
observability exporters. Authentication, authorization, TLS, safe fetch,
|
||||
quotas, E2EE, updates, moderation audit, deletion, and recovery remain beta core.
|
||||
File diff suppressed because it is too large
Load Diff
Generated
+160
-107
@@ -1,15 +1,15 @@
|
||||
{
|
||||
"0": "newRoleCRUDService",
|
||||
"0": "markdown.ts",
|
||||
"1": "createElement",
|
||||
"2": "testing.T",
|
||||
"3": "livekitSession.ts",
|
||||
"4": "dispatcher.ts",
|
||||
"3": "LiveKitSession",
|
||||
"4": "channels.store.ts",
|
||||
"5": "openMigratedMemory",
|
||||
"6": "context.Context",
|
||||
"7": "buildChannelRouter",
|
||||
"8": "MessageInput.ts",
|
||||
"9": "attachments.ts",
|
||||
"10": "DMService",
|
||||
"8": "seedMemberUser",
|
||||
"9": "MessageInput.ts",
|
||||
"10": "members.store.ts",
|
||||
"11": "waitRegistered",
|
||||
"12": "types.ts",
|
||||
"13": "NewAdminAPI",
|
||||
@@ -26,24 +26,24 @@
|
||||
"24": "newAuthTestDB",
|
||||
"25": "newMigratedTestDB",
|
||||
"26": "time.Time",
|
||||
"27": "Config",
|
||||
"27": "test-utils.ts",
|
||||
"28": "secret_store.rs",
|
||||
"29": "Hub",
|
||||
"30": "database/sql.Result",
|
||||
"31": "newUploadTestDB",
|
||||
"32": "AppearanceTab.ts",
|
||||
"33": "writeJSON",
|
||||
"34": "AuditWriter",
|
||||
"32": "VideoGrid.ts",
|
||||
"33": "net/http.HandlerFunc",
|
||||
"34": "newAdminTestDB",
|
||||
"35": "HashToken",
|
||||
"36": "content-parser.ts",
|
||||
"37": "drag-reorder.test.ts",
|
||||
"36": "attachments.ts",
|
||||
"37": "DMService",
|
||||
"38": "newRegistryWithDir",
|
||||
"39": "messages.store.ts",
|
||||
"39": "dispatcher.ts",
|
||||
"40": "Instance",
|
||||
"41": "Queries",
|
||||
"41": "screenShare.ts",
|
||||
"42": "NewChecker",
|
||||
"43": "middleware_test.go",
|
||||
"44": "MainPage.ts",
|
||||
"44": "UserBar.ts",
|
||||
"45": "DB",
|
||||
"46": "testing.F",
|
||||
"47": "Result",
|
||||
@@ -51,26 +51,26 @@
|
||||
"49": "native/helpers.ts",
|
||||
"50": "NewRouter",
|
||||
"51": "profileCreateToken",
|
||||
"52": "User",
|
||||
"52": "buildErrorMsg",
|
||||
"53": "newTestDB",
|
||||
"54": "MemberList.ts",
|
||||
"54": "MainPage.ts",
|
||||
"55": "newServeHub",
|
||||
"56": "3. Security",
|
||||
"57": "permissions_test.go",
|
||||
"58": "seedMemberUser",
|
||||
"58": "newOverrideFixture",
|
||||
"59": "postJSONWithToken",
|
||||
"60": "http_proxy.rs",
|
||||
"61": "newVoiceTestDB",
|
||||
"62": "livekit_test.go",
|
||||
"63": "dbgen/models.go",
|
||||
"64": "ProfileManager",
|
||||
"65": "architecture/README.md",
|
||||
"65": "README.md",
|
||||
"66": "devDependencies",
|
||||
"67": "LoadOrGenerate",
|
||||
"68": "helpers_test.go",
|
||||
"69": "ConnectPage.ts",
|
||||
"69": "main.ts",
|
||||
"70": "Security Policy",
|
||||
"71": "Role",
|
||||
"71": "WriteAudit",
|
||||
"72": "channels.sql.go",
|
||||
"73": "Deployment Guide",
|
||||
"74": "livekit_proxy_test.go",
|
||||
@@ -81,62 +81,62 @@
|
||||
"79": "db/db.go",
|
||||
"80": "Tables",
|
||||
"81": "newMentionFixture",
|
||||
"82": "message.go",
|
||||
"82": "messages_test.go",
|
||||
"83": "newWAFMiddleware",
|
||||
"84": "ws.ts",
|
||||
"84": "Config",
|
||||
"85": "storage_test.go",
|
||||
"86": "Migrate",
|
||||
"87": "Hub",
|
||||
"88": "admin/export_test.go",
|
||||
"89": "logger.ts",
|
||||
"89": "dispatcher.test.ts",
|
||||
"90": "updater_test.go",
|
||||
"91": "newTestMessageService",
|
||||
"92": "textAssetServer",
|
||||
"92": "newTestUpdater",
|
||||
"93": "Hub",
|
||||
"94": "compilerOptions",
|
||||
"95": "OwnCord — Repo Health Audit",
|
||||
"96": "net/http.Request",
|
||||
"96": "handleCreateEmoji",
|
||||
"97": "emoji_handler_test.go",
|
||||
"98": "buildErrorMsg",
|
||||
"99": "channelFromFields",
|
||||
"100": "openAdminTestDB",
|
||||
"101": "NewEventRingBuffer",
|
||||
"98": "buildVoiceLeave",
|
||||
"99": "media.ts",
|
||||
"100": "doRequest",
|
||||
"101": "handleRestoreBackup",
|
||||
"102": "Auth Endpoints",
|
||||
"103": "MigrateFS",
|
||||
"104": "PermissionService",
|
||||
"104": "Queries",
|
||||
"105": "Save",
|
||||
"106": "REST API Reference",
|
||||
"107": "deps.go",
|
||||
"107": "RateLimiter",
|
||||
"108": "joinVoice",
|
||||
"109": "ptt.rs",
|
||||
"110": "OwnCord Audit — Documentation Accuracy & UI/UX Test Coverage (2026-08-04)",
|
||||
"111": "scripts",
|
||||
"112": "checkSourceWith",
|
||||
"113": "Load",
|
||||
"114": "handleVoiceE2EEAnnounceV2",
|
||||
"115": "Registry",
|
||||
"114": "Registry",
|
||||
"115": "AdminActions.ts",
|
||||
"116": "newEmitTestHub",
|
||||
"117": "Plan: Remediate security-hardening review regressions",
|
||||
"118": "verify.go",
|
||||
"119": "chdirTemp",
|
||||
"120": "StartEventPruner",
|
||||
"120": "NewEventPersister",
|
||||
"121": "EnsureLiveKitBinary",
|
||||
"122": "clientip_test.go",
|
||||
"123": "reaction-tooltip.ts",
|
||||
"124": "VoiceTopic",
|
||||
"125": "gif_handler_test.go",
|
||||
"126": "e2e/helpers.ts",
|
||||
"123": "Queries",
|
||||
"124": "newRoleCRUDService",
|
||||
"125": "net/http.Handler",
|
||||
"126": "navigateToMainPage",
|
||||
"127": "messages.sql.go",
|
||||
"128": "Channel Endpoints",
|
||||
"129": "newSignedTestUpdater",
|
||||
"130": "host_http_test.go",
|
||||
"131": "Topic",
|
||||
"131": "VoiceTopic",
|
||||
"132": "DB",
|
||||
"133": "users",
|
||||
"134": "Client",
|
||||
"135": "Queries",
|
||||
"136": "handleChatCommandV2",
|
||||
"137": "Queries",
|
||||
"135": "ConnectPageCallbacks",
|
||||
"136": "newWazeroTestRegistry",
|
||||
"137": "OwnCord beta requirement traceability",
|
||||
"138": "wizardHandler",
|
||||
"139": "middleware_and_spawn_test.go",
|
||||
"140": "password_test.go",
|
||||
@@ -144,20 +144,20 @@
|
||||
"142": "handleVoiceTokenRefreshV2",
|
||||
"143": "pubsub_test.go",
|
||||
"144": "newChannelTestAPI",
|
||||
"145": "gapProbeSSEWriter",
|
||||
"146": "setupPrecheck",
|
||||
"145": "TestHandleLogStream_EntryWrittenDuringBackfillIsDelivered",
|
||||
"146": "net/http.Request",
|
||||
"147": "log/slog.Value",
|
||||
"148": "Updater",
|
||||
"149": "seedChannel",
|
||||
"149": "Queries",
|
||||
"150": "dependencies",
|
||||
"151": "newHarvestVoiceDB",
|
||||
"152": "Config Key Reference",
|
||||
"153": "Queries",
|
||||
"154": "markdown.ts",
|
||||
"155": "NewRegistry",
|
||||
"156": "OwnCord Client UX Specification (target state)",
|
||||
"157": "OwnCord — Comprehensive Project Audit",
|
||||
"158": "streamPreview.ts",
|
||||
"153": "connectionStats.ts",
|
||||
"154": "FenwickTree",
|
||||
"155": "totp_test.go",
|
||||
"156": "github.com/owncord/server/syncutil.Mutex",
|
||||
"157": "NewRegistry",
|
||||
"158": "ChannelSidebar.ts",
|
||||
"159": "deep-link.ts",
|
||||
"160": "testing.M",
|
||||
"161": "newMockDB",
|
||||
@@ -166,24 +166,24 @@
|
||||
"164": "buildTauriMockScript",
|
||||
"165": "OwnCord Introspection MCP Server",
|
||||
"166": "Bug-detection improvements — design",
|
||||
"167": "EventPersister",
|
||||
"167": "ux/README.md",
|
||||
"168": "eslint-rules.js",
|
||||
"169": "DB",
|
||||
"170": "OwnCord — Security Review",
|
||||
"171": "Plan: Slash command dispatcher in WS",
|
||||
"172": "vad-worklet-timing.test.ts",
|
||||
"173": "ChannelTopic",
|
||||
"174": "fakeStore",
|
||||
"174": "rate-limiter.ts",
|
||||
"175": "Open",
|
||||
"176": "RateLimiter",
|
||||
"177": "Key",
|
||||
"176": "MountAuthRoutes",
|
||||
"177": "e2e/helpers.ts",
|
||||
"178": "fallback_crypto.rs",
|
||||
"179": "Direct Messages",
|
||||
"180": "WebSocket Protocol Reference",
|
||||
"181": "command.go",
|
||||
"182": "NewRingBuffer",
|
||||
"183": "ws-load.js",
|
||||
"184": "newDMFixture",
|
||||
"184": "NewMessageService",
|
||||
"185": "handler",
|
||||
"186": "tauri-client/package.json",
|
||||
"187": "screen-share-tracks.test.ts",
|
||||
@@ -206,15 +206,15 @@
|
||||
"204": "handleVoiceE2EEOfferV2",
|
||||
"205": "AudioPipeline",
|
||||
"206": "Messaging — target UX",
|
||||
"207": "serviceErrorToResult",
|
||||
"208": "LiveKitProcess",
|
||||
"207": "B0 baseline and audit reconciliation",
|
||||
"208": "message.go",
|
||||
"209": "LiveKitClient",
|
||||
"210": "migrate.go",
|
||||
"211": "VoiceAudioTab.ts",
|
||||
"212": "Manifest",
|
||||
"213": "newWazeroTestRegistry",
|
||||
"214": "1. Channel sidebar",
|
||||
"215": "doRequest",
|
||||
"211": "voice-audio-tab.test.ts",
|
||||
"212": "OwnCord beta product requirements",
|
||||
"213": "OwnCord repository-health issue register",
|
||||
"214": "Queries",
|
||||
"215": "newTestRoleService",
|
||||
"216": "knip.json",
|
||||
"217": "RNNoiseProcessor",
|
||||
"218": "Store",
|
||||
@@ -223,13 +223,13 @@
|
||||
"221": "Connection & Authentication — target UX",
|
||||
"222": "Settings & Admin — target UX",
|
||||
"223": "buildClientUpdateRouter",
|
||||
"224": "EventSink",
|
||||
"224": "DeviceManager",
|
||||
"225": "newTestRoleService",
|
||||
"226": "event.go",
|
||||
"227": "NewTopicRateLimiter",
|
||||
"228": "Skill Authoring — taxonomy, licensing, confidentiality, editing rules",
|
||||
"229": ".oxlintrc.json",
|
||||
"230": "net/http.Handler",
|
||||
"230": "setupDiagnosticsRouter",
|
||||
"231": "e2e/dm-system.spec.ts",
|
||||
"232": "Queries",
|
||||
"233": "emoji.sql.go",
|
||||
@@ -238,20 +238,20 @@
|
||||
"236": "Voice Signaling",
|
||||
"237": "Quick Start Guide",
|
||||
"238": "OwnCord — Test Audit",
|
||||
"239": "newBackupFileDB",
|
||||
"239": "OwnCord public-beta execution roadmap",
|
||||
"240": "index.mjs",
|
||||
"241": "Checker",
|
||||
"241": "Channel",
|
||||
"242": "bughunt.harness.mjs",
|
||||
"243": "voice-audio-tab.test.ts",
|
||||
"244": "reactions.sql.go",
|
||||
"243": "video-grid.test.ts",
|
||||
"244": "context.CancelFunc",
|
||||
"245": "Channel Permission Overrides",
|
||||
"246": "Server Stats & User Administration",
|
||||
"247": ".DeleteAccount",
|
||||
"248": "scanPluginDirectory",
|
||||
"249": "Channel",
|
||||
"248": "loadPref",
|
||||
"249": "syntax-highlight.ts",
|
||||
"250": "slashFS",
|
||||
"251": "Running the bughunt pipeline",
|
||||
"252": "VideoGrid.ts",
|
||||
"252": "EventSink",
|
||||
"253": "reconnectAfterCertAccept",
|
||||
"254": "setupVoiceRoom",
|
||||
"255": "emoji-voicemod.parity.spec.ts",
|
||||
@@ -259,10 +259,10 @@
|
||||
"257": "include",
|
||||
"258": "VoiceWidgetOptions",
|
||||
"259": "Custom Emoji",
|
||||
"260": "OwnCord — Test-Coverage Audit",
|
||||
"260": "LiveKitProcess",
|
||||
"261": "OriginAcceptOptions",
|
||||
"262": "EventRingBuffer",
|
||||
"263": "setupRouter",
|
||||
"263": "OwnCord full repository-health audit",
|
||||
"264": "newTokenTestDB",
|
||||
"265": "scripts",
|
||||
"266": "bughunt-fix.harness.mjs",
|
||||
@@ -274,31 +274,31 @@
|
||||
"272": "Queries",
|
||||
"273": "TestChannelVisibility_RESTWSAgreement",
|
||||
"274": "Hub",
|
||||
"275": "Finish the V2 Dispatch Migration (backlog item 11) — Design",
|
||||
"275": "plans/README.md",
|
||||
"276": "Port Forwarding Guide",
|
||||
"277": "Chat Messages",
|
||||
"278": "hello/main.go",
|
||||
"279": "cancelAfterArm",
|
||||
"280": "Queries",
|
||||
"279": "profile_fields_test.go",
|
||||
"280": "noise-suppression.ts",
|
||||
"281": "Client HTTP TOFU Proxy (D5) — Design",
|
||||
"282": "create_tray",
|
||||
"283": "API Tokens",
|
||||
"284": "Backups",
|
||||
"285": "Plugin Administration",
|
||||
"286": "Invite Endpoints",
|
||||
"287": ".UpdateUserProfile",
|
||||
"287": "Manifest",
|
||||
"288": "Infrastructure roadmap — design",
|
||||
"289": "Member Updates",
|
||||
"290": "genprotocol/main.go",
|
||||
"291": "RingBuffer",
|
||||
"292": "TestOwnerOnlyMiddleware_OwnerAllowed",
|
||||
"292": "AuditWriter",
|
||||
"293": "ChatSendCmd",
|
||||
"294": "Environments, Activation Setup, and Handoff-Doc Mode",
|
||||
"295": "newBlockService",
|
||||
"295": "scanPluginDirectory",
|
||||
"296": "capabilities-scope.test.ts",
|
||||
"297": "notifications.ts",
|
||||
"297": "window-state.ts",
|
||||
"298": "GET /admin/api/updates",
|
||||
"299": "Channel-Visibility Unification (backlog item 3) — Design",
|
||||
"299": ".deliverBroadcast",
|
||||
"300": "sqlc Adoption (D2) — Progress & Plan",
|
||||
"301": "Authentication Flow",
|
||||
"302": "Voice Moderation",
|
||||
@@ -307,28 +307,28 @@
|
||||
"305": "prettier",
|
||||
"306": "openFileDB",
|
||||
"307": "hello plugin",
|
||||
"308": "TestHandlePresenceUpdate_BareStatusReadFailureAbortsBeforeCommit",
|
||||
"309": "groupDMFixture",
|
||||
"308": "handleVoiceE2EEAnnounceV2",
|
||||
"309": "IsUniqueConstraintError",
|
||||
"310": "Tauri HTTP Capability Narrowing — Design",
|
||||
"311": "protocol_contract_test.go",
|
||||
"312": "ChatCommandCmd",
|
||||
"313": "ci-check",
|
||||
"314": "Comprehensive Review (scheduled or fallback)",
|
||||
"315": "Credential storage",
|
||||
"316": "extractChatserverFromTarGz",
|
||||
"316": "buildChannelUpdate",
|
||||
"317": "cert-tofu.spec.ts",
|
||||
"318": "navigateToMainPageReady",
|
||||
"319": "newDeafenRaceDB",
|
||||
"318": "updater.spec.ts",
|
||||
"319": "OwnCord repository-layout and contributor-experience audit",
|
||||
"320": "tsconfig.build.json",
|
||||
"321": "User Blocks",
|
||||
"322": "PATCH /admin/api/settings",
|
||||
"323": "GET /api/v1/gif/search",
|
||||
"324": "First-Run Setup",
|
||||
"325": "LiveKit Endpoints",
|
||||
"326": "fuzzOpenMigratedMemory",
|
||||
"327": "README.md",
|
||||
"326": "reactions.sql.go",
|
||||
"327": "Tailscale Guide (Zero-Config Remote Access)",
|
||||
"328": "LiveKitProcess",
|
||||
"329": "erroringMembersStore",
|
||||
"329": "Voice, Video & E2EE — target UX",
|
||||
"330": "ChatEditCmd",
|
||||
"331": "VoiceE2EEOfferCmd",
|
||||
"332": "VoiceModDeafenCmd",
|
||||
@@ -339,11 +339,11 @@
|
||||
"337": "OwnCord Architecture Blueprints",
|
||||
"338": "Voice End-to-End Encryption",
|
||||
"339": "feature_request.md",
|
||||
"340": "TestEnableVideoSlot_SameUserDoubleStreamCountsTwoSlots",
|
||||
"341": "isAddrInUse",
|
||||
"342": "adminPanelSource",
|
||||
"340": "ResolveTokenHash",
|
||||
"341": "VerifyTOTPCodeOnce",
|
||||
"342": "Hub",
|
||||
"343": "ChatDeleteCmd",
|
||||
"344": "Permission-Middleware Consolidation (audit finding A-2026-07-16) — Design",
|
||||
"344": "OwnCord — Test-Coverage Audit",
|
||||
"345": "MessageDeletedDMEvent",
|
||||
"346": "MessageEditedDMEvent",
|
||||
"347": "MessageSentDMEvent",
|
||||
@@ -368,7 +368,7 @@
|
||||
"366": "VoiceE2EEOfferGuardedEvent",
|
||||
"367": "File Upload and Serving",
|
||||
"368": "Server Logs (SSE)",
|
||||
"369": "livekit-client",
|
||||
"369": "B0 — Restore truth, freeze scope, and reconcile the audit",
|
||||
"370": "CallSignalEvent",
|
||||
"371": "DMChannelOpenEvent",
|
||||
"372": "MessageDeletedChannelEvent",
|
||||
@@ -412,17 +412,17 @@
|
||||
"410": "Transport Layer",
|
||||
"411": "pre-commit",
|
||||
"412": "pre-push",
|
||||
"413": "stubBroadcastAllEvent",
|
||||
"413": "scaledAuthLimit",
|
||||
"414": "seedUser",
|
||||
"415": "@stryker-mutator/api/core",
|
||||
"415": "global-keybinds.test.ts",
|
||||
"416": "015_plugins.sql",
|
||||
"417": "tryLoadPluginTOML",
|
||||
"418": "tryLoadPluginTOML",
|
||||
"419": "roleDeletingInvalidator",
|
||||
"420": "buildMetricsRouter",
|
||||
"419": "Queries",
|
||||
"420": "mockTauriFullSessionWithVoice",
|
||||
"421": "syscall.SysProcAttr",
|
||||
"422": "@tauri-apps/api/core",
|
||||
"423": "@tauri-apps/api/event",
|
||||
"422": ".UpdateUserProfile",
|
||||
"423": "B10 — Qualify and publish the public beta",
|
||||
"424": "protocol-change/SKILL.md",
|
||||
"425": "strip-appimage-bundled-libs.sh",
|
||||
"426": "build.rs",
|
||||
@@ -448,7 +448,7 @@
|
||||
"446": "voice-test.sh",
|
||||
"447": "proc_spawner_nix.go",
|
||||
"448": "proc_spawner_win.go",
|
||||
"449": "failNthInstallStore",
|
||||
"449": "OwnCord — Comprehensive Project Audit",
|
||||
"450": "playwright.config.ts",
|
||||
"451": "playwright.config.admin.ts",
|
||||
"452": "playwright.config.native.ts",
|
||||
@@ -529,14 +529,67 @@
|
||||
"527": "hub_livekit.go",
|
||||
"528": "hub_sweep.go",
|
||||
"529": "message_types.go",
|
||||
"530": "handleLogStream",
|
||||
"531": "docker-smoke.sh",
|
||||
"532": "TestRegisterNow_ReplacementNeverLosesAConcurrentGlobalBroadcast",
|
||||
"532": "B1 — Isolated repository and contributor foundation",
|
||||
"533": "prettier",
|
||||
"534": "buildUserUpdate",
|
||||
"535": "@vitest/coverage-v8",
|
||||
"536": "RunningInContainer",
|
||||
"540": "RunningUnderSupervisor",
|
||||
"536": "B2 — Freeze server protocol, trust, and compatibility contracts",
|
||||
"537": "2. Code Quality",
|
||||
"538": "B3 — Strengthen server architecture and permanent guardrails",
|
||||
"539": "B4 — Complete identity, recovery, privacy, and data lifecycle",
|
||||
"540": "B5 — Add community, content, and moderation services",
|
||||
"541": "buildChannelDelete",
|
||||
"542": "addrinuse_unix.go",
|
||||
"543": "addrinuse_windows.go",
|
||||
"544": "msg-actions-bar-focus-css.test.ts",
|
||||
"546": "hub_wiring_test.go"
|
||||
"545": "navigation-guard.ts",
|
||||
"546": "hub_wiring_test.go",
|
||||
"547": "volume-menu.test.ts",
|
||||
"548": "New",
|
||||
"549": "B6 — Qualify server deployment, operations, and capacity",
|
||||
"550": "MetricsSources",
|
||||
"551": "B7 — Establish the shared client platform and desktop parity",
|
||||
"552": "updater.test.ts",
|
||||
"553": "B8 — Deliver browser, PWA, phone, and tablet support",
|
||||
"554": "B9 — Complete unified feature UX, accessibility, and polish",
|
||||
"555": "groupDMFixture",
|
||||
"556": ".finishVoiceLeave",
|
||||
"557": "protocolTypes.ts",
|
||||
"558": "TestNewRouter_DeleteAccount_BroadcastsMemberBanOverWS",
|
||||
"559": "4. Dependencies & Supply Chain",
|
||||
"560": "global-teardown.ts",
|
||||
"561": "newDeafenRaceDB",
|
||||
"562": "5. Test Coverage & Quality",
|
||||
"563": ".RoundTrip",
|
||||
"564": "perm_grid_test.go",
|
||||
"565": "NewRoleService",
|
||||
"566": "buildMetricsRouter",
|
||||
"567": "TestAdminAPI_PatchUser_RoleChangeBroadcastsEvenIfRoleReReadFails",
|
||||
"568": "isAddrInUse",
|
||||
"569": "TestRegisterNow_ReplacementNeverLosesAConcurrentGlobalBroadcast",
|
||||
"570": "b0-dev-branch-protection.sh",
|
||||
"571": "extractChatserverFromTarGz",
|
||||
"572": "1. Architecture",
|
||||
"573": "6. CI/CD & DevEx",
|
||||
"574": "7. Observability",
|
||||
"575": "TestHandleVoiceCameraV2_RefusedWhenScreenshareSlotFull",
|
||||
"576": "audio-pipeline-vad-worklet.test.ts",
|
||||
"577": ".applyMicMuteState",
|
||||
"578": "RunningUnderSupervisor",
|
||||
"579": "Non-negotiable execution rules",
|
||||
"580": "failNthInstallStore",
|
||||
"581": "TestAdminAuthMiddleware_DBErrorIsNotUnauthorized",
|
||||
"582": "Security Policy",
|
||||
"583": "TestEnableVideoSlot_SameUserDoubleStreamCountsTwoSlots",
|
||||
"584": "D7 — Module map",
|
||||
"585": "D5 — Entity-relationship overview",
|
||||
"586": "WebSocket / Real-time Engine",
|
||||
"587": "adminPanelSource",
|
||||
"588": "ParseLevel",
|
||||
"589": "roleDeletingInvalidator",
|
||||
"590": "identityKeyFailStore",
|
||||
"591": "BuildTOTPURI",
|
||||
"592": "errDMParticipantsStore"
|
||||
}
|
||||
|
||||
Generated
+1
-1
File diff suppressed because one or more lines are too long
Generated
+752
-515
File diff suppressed because it is too large
Load Diff
Generated
+4
-4
File diff suppressed because one or more lines are too long
Generated
+184596
-180387
File diff suppressed because it is too large
Load Diff
Generated
+73
-18
@@ -65,13 +65,13 @@
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"Client/tauri-client/playwright.config.prod.ts": {
|
||||
"mtime": 1786170197.4131606,
|
||||
"ast_hash": "0dac892deba2829313ccdf6c143c71f2",
|
||||
"mtime": 1787679075.9573913,
|
||||
"ast_hash": "f05b50cd3b34b2ba5e73c392855e5295",
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"Client/tauri-client/playwright.config.ts": {
|
||||
"mtime": 1786170197.4131606,
|
||||
"ast_hash": "bfe3a55de10fbd49b10ec64a82dda72a",
|
||||
"mtime": 1787680447.7455137,
|
||||
"ast_hash": "2a719ee4664789fa46b6f3485b642f1f",
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"Client/tauri-client/public/rnnoise-worklet.js": {
|
||||
@@ -265,7 +265,7 @@
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"Client/tauri-client/src/components/MessageList.ts": {
|
||||
"mtime": 1787374179.4595952,
|
||||
"mtime": 1787677584.0872686,
|
||||
"ast_hash": "7e6c97785402409dfbb86f2ab93b8898",
|
||||
"semantic_hash": ""
|
||||
},
|
||||
@@ -1765,8 +1765,8 @@
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"Client/tauri-client/tests/unit/message-list.test.ts": {
|
||||
"mtime": 1787315994.5674324,
|
||||
"ast_hash": "60e418a9cea78f3fb87cc2dc2a953c10",
|
||||
"mtime": 1787677629.307052,
|
||||
"ast_hash": "075f30e7cfd293f2f431dcb433c038fc",
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"Client/tauri-client/tests/unit/messages-store-detached.test.ts": {
|
||||
@@ -5481,17 +5481,17 @@
|
||||
},
|
||||
"Client/tauri-client/src-tauri/capabilities/default.json": {
|
||||
"mtime": 1786272933.6755219,
|
||||
"ast_hash": "",
|
||||
"ast_hash": "72fd589daf6497717ac840ef00c9660f",
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"Server/plugin/examples/hello/plugin.json": {
|
||||
"mtime": 1784557739.5584006,
|
||||
"ast_hash": "",
|
||||
"ast_hash": "bdf9b835ac2e05602839d0ceb9a9b6d0",
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"docs/protocol-schema.json": {
|
||||
"mtime": 1786170197.508181,
|
||||
"ast_hash": "",
|
||||
"ast_hash": "98858de1d31ba62f7d0b036816f97123",
|
||||
"semantic_hash": ""
|
||||
},
|
||||
".superpowers/render-ledger.mjs": {
|
||||
@@ -5511,12 +5511,12 @@
|
||||
},
|
||||
"Client/tauri-client/src-tauri/tauri.conf.json": {
|
||||
"mtime": 1786894298.5036547,
|
||||
"ast_hash": "",
|
||||
"ast_hash": "f05bbc86946be8157b818eb83315c87f",
|
||||
"semantic_hash": ""
|
||||
},
|
||||
".superpowers/findings-ledger.json": {
|
||||
"mtime": 1787315994.518129,
|
||||
"ast_hash": "",
|
||||
"mtime": 1787475158.2240584,
|
||||
"ast_hash": "a375ce7a17d27b0056c17a85b67faa9e",
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"Client/tauri-client/src/lib/hostValidation.ts": {
|
||||
@@ -5736,7 +5736,7 @@
|
||||
},
|
||||
".claude/settings.json": {
|
||||
"mtime": 1787315994.513591,
|
||||
"ast_hash": "",
|
||||
"ast_hash": "738882db20f8c5b64daeaa6ed3e72975",
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"Client/tauri-client/tests/unit/AccessibilityTab.test.ts": {
|
||||
@@ -5800,8 +5800,8 @@
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"docs/plans/audit-2026-08-19-remediation.md": {
|
||||
"mtime": 1787315994.6150818,
|
||||
"ast_hash": "b6379e0a3ccbb5a0fbeceff9297ac504",
|
||||
"mtime": 1787681881.467493,
|
||||
"ast_hash": "d195e5f29ce1da5cf819ed9bf11daa84",
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"Client/tauri-client/tests/unit/attachments-ipv6-host.test.ts": {
|
||||
@@ -5870,8 +5870,8 @@
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"Client/tauri-client/tests/unit/noise-suppression-restart.test.ts": {
|
||||
"mtime": 1787374179.4701009,
|
||||
"ast_hash": "d8061747a815edeb02095d26b7f45623",
|
||||
"mtime": 1787677273.8526669,
|
||||
"ast_hash": "24adbd03c9de64abe3df0869698d5390",
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"Server/api/dm_handler_presence_test.go": {
|
||||
@@ -5913,5 +5913,60 @@
|
||||
"mtime": 1787374179.4826498,
|
||||
"ast_hash": "a5fb5a398f57ae453e1a778447c08097",
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"Client/tauri-client/.claude/settings.local.json": {
|
||||
"mtime": 1787679067.8054585,
|
||||
"ast_hash": "2173c4505a11b9c6e4c16b7c9bb6b7c6",
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"Client/tauri-client/tests/e2e/global-teardown.ts": {
|
||||
"mtime": 1787680865.5704248,
|
||||
"ast_hash": "68f60f8ff871057aee63f8e813f254e1",
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"docs/plans/b0-dev-branch-protection.sh": {
|
||||
"mtime": 1787681445.4251657,
|
||||
"ast_hash": "fa5fc5fa5c7f031681283d63cdf07470",
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"docs/audit-2026-08-23-repository-health.md": {
|
||||
"mtime": 1787494372.0207314,
|
||||
"ast_hash": "424f7648e41f710a015d99c6c5c049d8",
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"docs/audit-2026-08-23-repository-layout.md": {
|
||||
"mtime": 1787494273.40985,
|
||||
"ast_hash": "4b36fce2100ea3cd57fe81f616b2fbfe",
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"docs/plans/b0-baseline-2026-08-25.md": {
|
||||
"mtime": 1787682500.136333,
|
||||
"ast_hash": "d51567658e0bd27bc8265d3464d03216",
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"docs/plans/beta-product-requirements-2026-08-23.md": {
|
||||
"mtime": 1787494273.3761857,
|
||||
"ast_hash": "30d40fa62d41c9ef8a3e29598a87d7aa",
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"docs/plans/beta-requirements-traceability-2026-08-23.md": {
|
||||
"mtime": 1787494273.594238,
|
||||
"ast_hash": "aa9e767f7ac04b2990839b55ca3b358b",
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"docs/plans/repo-health-issue-register-2026-08-23.md": {
|
||||
"mtime": 1787494273.477049,
|
||||
"ast_hash": "8eb081fa6b652a1d888aaac433b629d6",
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"docs/plans/repo-health-roadmap-2026-08-23.md": {
|
||||
"mtime": 1787494273.5659218,
|
||||
"ast_hash": "654c5dd6e06767af7cd3a4b5f8d335f5",
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"docs/plans/README.md": {
|
||||
"mtime": 1787681873.978382,
|
||||
"ast_hash": "2ccde857b78f53592c50cdad51f456fb",
|
||||
"semantic_hash": ""
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user