Skip to content

Commit 495b278

Browse files
xuyushun441-sysos-zhuangclaude
authored
docs: add launch-readiness checklist for team sign-off (#1584)
Synthesizes a read-only, package-by-package launch-readiness sweep into a sign-off checklist: P0 blockers (auth secret fallback, metadata-service fail-open, LIKE/Mongo operator safety, in-memory realtime/feed in clusters), P1 hardening (external-call timeouts, retention, graceful shutdown, env-resolve cache, cluster pubsub durability), P2 test-coverage gaps, and a roadmap section naming the Proposed ADRs explicitly out of v1. Each item has separate Verify and Sign-off boxes — the P0/security findings are sweep-derived and must be hand-verified before any fix or acceptance. Co-authored-by: Jack Zhuang <277994282+os-zhuang@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 9f311f8 commit 495b278

1 file changed

Lines changed: 197 additions & 0 deletions

File tree

docs/launch-readiness.md

Lines changed: 197 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
# Launch Readiness Checklist
2+
3+
**Status:** Draft for team sign-off
4+
**Scope:** Production launch (v1 / GA) of the ObjectStack framework monorepo
5+
**Last reviewed:** 2026-06-04 (`main` @ `9f311f8` — ADR-0030 P3b-2 digest)
6+
7+
---
8+
9+
## How to use this document
10+
11+
Each item has an **owner**, a **verification box**, and a **sign-off box**. The
12+
two are deliberately separate:
13+
14+
-**Verify** — a named engineer has confirmed the finding is real (or a false
15+
positive) by reading the actual code / running a repro. Several items below
16+
originate from an automated package-by-package sweep and are **not yet
17+
hand-verified** — do not action them before verifying.
18+
-**Sign-off** — the fix is merged (or the risk is formally accepted and the
19+
acceptance recorded in the "Notes" column).
20+
21+
A "false positive" still gets ticked on Verify, with a one-line note explaining
22+
why no fix is needed. **Do not mark a P0 signed-off on the strength of the sweep
23+
alone.**
24+
25+
Priority key: **P0** = blocks launch · **P1** = fix at/just-after launch ·
26+
**P2** = test-coverage / hardening gap · **Roadmap** = explicitly out of v1.
27+
28+
---
29+
30+
## Overall posture
31+
32+
The codebase is mature and disciplined. A repo-wide scan found **zero**
33+
`TODO/FIXME/HACK` markers, `console.log` in source, empty `catch` blocks,
34+
`@ts-ignore`, or hard-coded secrets. `main` CI is green (Build/Test Core, Lint &
35+
Type Check, CodeQL). The core tier — `spec`, `objectql`, `plugin-security`,
36+
`runtime`, the SQL drivers, `service-ai` — is assessed production-ready.
37+
38+
Launch risk is concentrated in a small number of themes below, not in code
39+
quality. **The single most important caveat: the security- and data-integrity
40+
findings (§P0) are from an automated sweep and MUST be hand-verified before any
41+
fix or acceptance.**
42+
43+
---
44+
45+
## P0 — Blockers (verify, then fix or formally accept)
46+
47+
> Every P0 below must be **hand-verified** first — some may be false positives or
48+
> already-guarded. Do not ship without each row at Verify ✓ **and** Sign-off ✓.
49+
50+
### P0-1 — Auth secret falls back to a weak dev secret
51+
- **Area:** `plugin-auth``src/auth-manager.ts` (~L1052–1071, `generateSecret()`)
52+
- **Risk:** If `OS_AUTH_SECRET` is unset in production, the manager logs a warning
53+
and falls back to `dev-secret-<timestamp>`. Session tokens become predictable →
54+
session forgery. (HIGH, security)
55+
- **Action:** Throw (fail boot) when no secret is configured and
56+
`NODE_ENV === 'production'`; add a pre-boot config validation. Document
57+
`OS_AUTH_SECRET` as a required go-live env var.
58+
- **Owner:** _______ · Verify ☐ · Sign-off ☐ · Notes: _______
59+
60+
### P0-2 — Metadata-service failure bypasses all RBAC/RLS (fail-open)
61+
- **Area:** `plugin-security``src/security-plugin.ts:309–312`
62+
- **Risk:** A metadata-resolution error is swallowed and the request proceeds via
63+
`next()` with **no permission checks**. If the metadata service degrades, every
64+
user bypasses RBAC/RLS. (HIGH, security)
65+
- **Action:** Add a circuit-breaker + ERROR-level alerting; add an integration
66+
test asserting "metadata service down ⇒ request denied", not allowed. Decide
67+
fail-closed vs. fail-open explicitly and record the decision.
68+
- **Owner:** _______ · Verify ☐ · Sign-off ☐ · Notes: _______
69+
70+
### P0-3 — Unescaped LIKE metacharacters in `contains`
71+
- **Area:** `driver-sql``src/sql-driver.ts:1565, 1656`
72+
- **Risk:** The `contains` / `$contains` operator embeds the user value into a
73+
`%...%` LIKE pattern without escaping `%` / `_`. Parameterization prevents SQL
74+
injection, but a `%` value matches everything → logic-level filter bypass.
75+
(HIGH, data)
76+
- **Action:** Escape `%` and `_` (and the escape char) before building the LIKE
77+
pattern; add a test with a `%`/`_` payload.
78+
- **Owner:** _______ · Verify ☐ · Sign-off ☐ · Notes: _______
79+
80+
### P0-4 — MongoDB filter passes arbitrary `$` operators through
81+
- **Area:** `driver-mongodb``src/mongodb-filter.ts:82–84`
82+
- **Risk:** Operator keys are passed straight to MongoDB with no allowlist, so
83+
`$where` / `$function` (server-side JS) reach the engine → query-intent bypass
84+
and a potential JS-execution surface. (HIGH **if MongoDB is a launch driver**)
85+
- **Action:** Allowlist safe operators (`$eq/$ne/$gt/$gte/$lt/$lte/$in/$nin/$and/$or/...`);
86+
reject unknown ones at filter-build time. If MongoDB is not a v1 driver, mark
87+
Roadmap instead.
88+
- **Owner:** _______ · Verify ☐ · Sign-off ☐ · Notes: _______
89+
90+
### P0-5 — Realtime & feed are in-memory only (no cluster coordination)
91+
- **Area:** `service-realtime` (`in-memory-realtime-adapter.ts`), `service-feed`
92+
(`in-memory-feed-adapter.ts`)
93+
- **Risk:** Publish/subscribe and feed storage are process-local. In a multi-node
94+
deployment, clients connected to node B never receive node A's events, and feed
95+
data is lost on restart / unbounded in memory. (HIGH **for HA/cluster**;
96+
N/A for single-instance)
97+
- **Action (cluster launch):** Provide a Redis-backed realtime adapter and a
98+
DB-backed feed adapter, **or** formally restrict v1 to single-instance and
99+
document it as non-HA. Enforce a `maxItems` cap if shipping in-memory feed.
100+
- **Owner:** _______ · Verify ☐ · Sign-off ☐ · Notes: _______
101+
102+
---
103+
104+
## P1 — Fix at launch or immediately after
105+
106+
### P1-1 — External calls have no timeout / retry / backoff
107+
- **Area:** `embedder-openai` (`src/index.ts:~157`), `connector-rest` (~L157),
108+
`connector-slack` (~L155), `connector-mcp`
109+
- **Risk:** Naked `fetch` with no timeout or 429/5xx backoff → a slow or
110+
rate-limited external API hangs the entire agent turn with no recovery.
111+
- **Action:** Add a default request timeout (e.g. 30s, configurable) + exponential
112+
backoff (3 tries) + a circuit breaker; tests for 429 / timeout paths.
113+
- **Owner:** _______ · Verify ☐ · Sign-off ☐ · Notes: _______
114+
115+
### P1-2 — Unbounded growth: execution logs, job runs, event log
116+
- **Area:** `service-automation` (in-memory exec logs, hard 1000 cap),
117+
`service-job` (`sys_job_run`, no retention), `service-messaging`
118+
(event log retention is opt-in)
119+
- **Risk:** Long-running pods OOM; history tables grow without bound.
120+
- **Action:** Make retention **default-on** for all event/run tables; schedule
121+
sweepers at startup; persist automation logs to a table rather than memory.
122+
- **Owner:** _______ · Verify ☐ · Sign-off ☐ · Notes: _______
123+
124+
### P1-3 — No process-level graceful shutdown
125+
- **Area:** `runtime` (`http-server.ts`) + framework adapters
126+
- **Risk:** No SIGTERM/SIGINT handling → in-flight requests dropped on
127+
rolling deploys (K8s SIGKILL after grace period); cluster (Redis) + kernel +
128+
HTTP not drained in a coordinated order.
129+
- **Action:** Ship a graceful-shutdown utility (drain HTTP → stop kernel services
130+
→ close cluster) and wire it into app scaffolding; document a ≥60s grace floor.
131+
- **Owner:** _______ · Verify ☐ · Sign-off ☐ · Notes: _______
132+
133+
### P1-4 — Per-request hostname → environment resolution (no cache)
134+
- **Area:** `rest``src/rest-server.ts:~504–530`
135+
- **Risk:** `resolveByHostname()` runs on every unscoped request → control-plane
136+
latency spike under load; silent fallback to default project masks it.
137+
- **Action:** Add an in-memory TTL cache (~30s) for `hostname → environmentId`.
138+
- **Owner:** _______ · Verify ☐ · Sign-off ☐ · Notes: _______
139+
140+
### P1-5 — Cluster pub/sub is fire-and-forget (metadata-changed)
141+
- **Area:** `service-cluster-redis``src/pubsub.ts:~75–90`
142+
- **Risk:** `publish()` doesn't wait for subscribers; a crash right after a schema
143+
change leaves other nodes with a stale schema until the next full reload.
144+
- **Action:** Acceptable for non-critical events if documented; ensure schema
145+
mutations re-sync on error boundaries (history exists in `sys_metadata_history`).
146+
Record the durability contract.
147+
- **Owner:** _______ · Verify ☐ · Sign-off ☐ · Notes: _______
148+
149+
---
150+
151+
## P2 — Test-coverage & hardening gaps (ready, but shore up)
152+
153+
| ID | Area | Gap | Action | Owner | Verify | Sign-off |
154+
|----|------|-----|--------|-------|:------:|:--------:|
155+
| P2-1 | `metadata-fs` | **NEEDS-WORK.** Atomicity / `watch` replay consistency under concurrent FS writes; 200ms chokidar self-write suppression is racy on slow/network FS | Add fault-injection tests (crash mid-write, concurrent put+delete, watch replay); validate `writeJsonAtomic` | ____ |||
156+
| P2-2 | `cli` | Missing `serve` integration test (kernel init + HMR reload + SIGINT); possible missing `environments.ts` implementation (test exists) | Add serve/dev integration test; confirm `environments` command exists | ____ |||
157+
| P2-3 | `plugin-webhooks` | Thin tests (1 test file); `eventId` dedup can collide on identical-ms timestamps | Add UUID suffix to `eventId`; expand auto-enqueuer tests | ____ |||
158+
| P2-4 | `service-queue` | CAS claim (read-then-update) is not atomic → tolerated duplicate delivery; empty idempotency key bypasses dedup | Enforce non-empty idempotency key; add a lease safety margin; document at-least-once | ____ |||
159+
| P2-5 | `plugin-audit` | `sys_session` mutations are not audited | Confirm login/logout are logged elsewhere (`sys_audit_log`); close the compliance gap if not | ____ |||
160+
| P2-6 | `core` / `runtime` | `getService()` is sync but may return a Promise → unhandled-rejection footgun for plugin authors | Tighten the type / add a guard; document the sync-only contract | ____ |||
161+
162+
---
163+
164+
## Roadmap — Explicitly out of scope for v1 (no action to launch)
165+
166+
These are **designed but unbuilt** and should be named "not in v1" in the release
167+
notes, not treated as blockers.
168+
169+
-**Unverified features — confirm stub vs. minimal, then include or exclude:**
170+
`knowledge-ragflow`, `connector-openapi` (the sweep could not locate full
171+
implementations; the packages exist — verify scope before GA).
172+
-**Proposed ADRs (roadmap):** ADR-0021 (analytics semantic layer),
173+
ADR-0022/0023/0024 (connectors / OpenAPI→connector / MCP connectors),
174+
ADR-0025/0026 (plugin & client-UI distribution), ADR-0027 (metadata authoring
175+
lifecycle), ADR-0028 (naming/namespace isolation), ADR-0029 (kernel object
176+
ownership — **partially landed**: K0 + D7 + several K2 domains), ADR-0033
177+
Phase D (enterprise AI-authoring governance).
178+
179+
---
180+
181+
## Release mechanics
182+
183+
-`main` CI green at the release commit (Build/Test Core, Lint & Type Check, CodeQL).
184+
- ☐ Pending changesets reviewed (4 at last check) and version bump intentional.
185+
-`pnpm run release` path verified (`build``build-console.sh``changeset publish`).
186+
- ☐ Required env vars documented for go-live (at minimum `OS_AUTH_SECRET`; see P0-1).
187+
- ☐ Deployment topology decided: **single-instance** vs. **HA/cluster** (drives P0-5).
188+
189+
---
190+
191+
## Provenance
192+
193+
The per-package findings were produced by an automated, read-only package-by-package
194+
sweep on 2026-06-04 and synthesized here. They are a **starting point for review,
195+
not a verified defect list** — each item carries its own Verify box for exactly
196+
this reason. File:line references are approximate and must be confirmed against
197+
`main` before acting.

0 commit comments

Comments
 (0)