forked from EduCraft/curriculum-project-hub
docs: resolve product surface audit
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
# Audit the accepted product surface for production completeness
|
||||
|
||||
Type: research
|
||||
Status: open
|
||||
Status: resolved
|
||||
|
||||
## Question
|
||||
|
||||
@@ -11,3 +11,48 @@ policy-limit, emergency workload-control, and Feishu flows are absent,
|
||||
unreachable, or only test-facing rather than usable in the initial production
|
||||
service? Treat ADR-0022's capacity control surfaces as part of the accepted
|
||||
product boundary.
|
||||
|
||||
## Answer
|
||||
|
||||
The current Hub is not a usable or production-complete SaaS product surface.
|
||||
Its Organization-scoped JSON APIs and single-Feishu-app Agent Run path are
|
||||
worth retaining, but the running service has one process-global Feishu
|
||||
app/bot, one global provider key/base URL, no Organization connection/secret
|
||||
plane, no platform-administrator control plane, and no real Organization or
|
||||
platform management UI. OAuth redirects a successful login to an unmounted
|
||||
`/admin/org/:orgSlug` route.
|
||||
|
||||
Two real Fastify integration probes, each run twice, proved that an authenticated
|
||||
Organization ADMIN receives 404 at the post-login destination and two distinct
|
||||
Organization return paths produce the same OAuth `client_id`. Official Feishu
|
||||
documentation also proves that `open_id` is application-scoped, `user_id` is
|
||||
tenant-scoped, and `union_id` only links applications from the same application
|
||||
provider. The current globally unique `User.feishuOpenId`, raw `chatId`, event
|
||||
identity, OAuth state and one-listener composition therefore cannot safely
|
||||
route independently customer-owned applications.
|
||||
|
||||
ADR-0022 remains an additional release blocker: beyond a process-memory
|
||||
Project queue and global max-turn setting, layered limits, durable
|
||||
Organization-fair admission, hard storage/run/process budgets, alerts and
|
||||
audited emergency brakes have no complete persistence or product surface.
|
||||
|
||||
The full verdict, deterministic probe results, root causes, retained seams and
|
||||
required end-to-end release evidence are in the
|
||||
[accepted SaaS product-surface completeness audit](../assets/product-surface-completeness-audit.md).
|
||||
The detailed route/schema/test matrix is in the
|
||||
[accepted product-surface code inventory](../assets/product-surface-code-inventory.md),
|
||||
and the Feishu identifier/OAuth/event/long-connection facts are in the
|
||||
[Feishu product-surface primary sources](../assets/product-surface-feishu-primary-sources.md).
|
||||
|
||||
The newly-clear execution frontier is:
|
||||
|
||||
- [Decide the platform-administrator identity and audit boundary](42-decide-platform-admin-identity-audit.md)
|
||||
- [Implement the Organization connection and secret plane](43-implement-org-connection-secret-plane.md)
|
||||
- [Route Feishu identity and traffic by Organization connection](44-route-feishu-by-org-connection.md)
|
||||
- [Build the private platform-administrator control plane](45-build-private-platform-admin-control-plane.md)
|
||||
- [Build the private Organization-administrator control plane](46-build-private-org-admin-control-plane.md)
|
||||
|
||||
Existing tickets 23 and 32–38 remain the owners of durable ingress/admission,
|
||||
capacity enforcement, usage alerts, workload brakes and calibration. Ticket 08
|
||||
now requires all of these product slices before claiming the production release
|
||||
gate.
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
Type: task
|
||||
Status: open
|
||||
Blocked by: 01, 02, 03, 04, 05, 06, 07, 09, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41
|
||||
Blocked by: 01, 02, 03, 04, 05, 06, 07, 09, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46
|
||||
|
||||
## Question
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
Type: task
|
||||
Status: open
|
||||
Blocked by: 44
|
||||
|
||||
## Question
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
Type: task
|
||||
Status: open
|
||||
Blocked by: 18
|
||||
Blocked by: 18, 44
|
||||
|
||||
## Question
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
Type: task
|
||||
Status: open
|
||||
Blocked by: 44
|
||||
|
||||
## Question
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
Type: task
|
||||
Status: open
|
||||
Blocked by: 20, 22
|
||||
Blocked by: 20, 22, 44
|
||||
|
||||
## Question
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
Type: task
|
||||
Status: open
|
||||
Blocked by: 19, 24, 29, 32
|
||||
Blocked by: 19, 24, 29, 32, 43
|
||||
|
||||
## Question
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
Type: task
|
||||
Status: open
|
||||
Blocked by: 22, 23, 24, 27, 30, 32, 33
|
||||
Blocked by: 22, 23, 24, 27, 30, 32, 33, 45
|
||||
|
||||
## Question
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
Type: task
|
||||
Status: open
|
||||
Blocked by: 10, 12, 14, 19, 23, 24, 25, 26, 29, 39, 41
|
||||
Blocked by: 10, 12, 14, 19, 23, 24, 25, 26, 29, 39, 41, 43
|
||||
|
||||
## Question
|
||||
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
# Decide the platform-administrator identity and audit boundary
|
||||
|
||||
Type: grilling
|
||||
Status: open
|
||||
|
||||
## Question
|
||||
|
||||
Which identity issuer, bootstrap and recovery procedure, invite/allowlist model,
|
||||
session claims, role lifecycle, separation from Organization membership, and
|
||||
append-only audit contract will authenticate Platform Administrators for the
|
||||
initial service? The decision must keep `/admin/platform` private, make every
|
||||
Organization/connection/workload-control mutation attributable, and define a
|
||||
reviewable break-glass path without treating platform staff as customer members.
|
||||
@@ -0,0 +1,16 @@
|
||||
# Implement the Organization connection and secret plane
|
||||
|
||||
Type: task
|
||||
Status: open
|
||||
Blocked by: 19
|
||||
|
||||
## Question
|
||||
|
||||
Implement encrypted, versioned, Organization-scoped Feishu Application and
|
||||
model Provider Connection records plus one resolver boundary. Support one
|
||||
customer-owned Feishu app per Organization, Organization-admin-managed BYOK,
|
||||
and one distinct platform-managed key/base URL per Organization; enforce which
|
||||
administrator may write each mode, readiness and rotation lifecycle, runtime
|
||||
resolution from Organization/Project, redacted observability, backup/key
|
||||
recovery hooks, and no process-global credential fallback or plaintext leakage
|
||||
into business rows, logs, HTTP responses, or agent environments.
|
||||
@@ -0,0 +1,17 @@
|
||||
# Route Feishu identity and traffic by Organization connection
|
||||
|
||||
Type: task
|
||||
Status: open
|
||||
Blocked by: 20, 22, 43
|
||||
|
||||
## Question
|
||||
|
||||
Make every Feishu OAuth, WebSocket/event, card action, directory sync, chat
|
||||
binding, API call, and outbound message start from an explicit active
|
||||
Organization Feishu Application Connection. Model external user, chat, event,
|
||||
and callback identifiers in that connection's namespace; bind OAuth state to
|
||||
the intended Organization/application; run and observe one listener/client
|
||||
lifecycle per configured app; and prove two customer-owned apps with colliding
|
||||
provider-local identifiers cannot authenticate, bind, authorize, deduplicate,
|
||||
rate-limit, or deliver across Organizations. Do not infer tenant from a global
|
||||
`open_id`, `chat_id`, or from the user's membership count.
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
# Build the private platform-administrator control plane
|
||||
|
||||
Type: task
|
||||
Status: open
|
||||
Blocked by: 20, 27, 28, 42, 43, 44
|
||||
|
||||
## Question
|
||||
|
||||
Implement authenticated `requirePlatformAdmin` APIs and a private
|
||||
`/admin/platform` web area for Platform Administrators to create/list/update
|
||||
Organizations, bootstrap their OWNER, view/change lifecycle state, configure
|
||||
and test each customer-owned Feishu Application, configure the Organization's
|
||||
distinct platform-managed Provider Connection, and manage platform-admin
|
||||
allowlisting. Prove anonymous users, ordinary members, and Organization admins
|
||||
cannot load either page data or mutations; every sensitive action is validated,
|
||||
redacted, audited, observable, and covered by browser-level critical-journey
|
||||
tests. Emergency workload controls remain integrated through ticket 37.
|
||||
@@ -0,0 +1,17 @@
|
||||
# Build the private Organization-administrator control plane
|
||||
|
||||
Type: task
|
||||
Status: open
|
||||
Blocked by: 20, 27, 28, 32, 36, 43, 44
|
||||
|
||||
## Question
|
||||
|
||||
Turn the guarded Organization JSON APIs into a usable private
|
||||
`/admin/org/:orgSlug` web control plane for OWNER/ADMIN users. Cover members and
|
||||
roles, teams and Project access, Folders/Projects/chat unbinding, sessions and
|
||||
usage, model/role/run policy, Organization policy limits and alerts, Feishu
|
||||
connection readiness, Provider Credential Mode selection, and BYOK key/base URL
|
||||
management without ever displaying stored plaintext. Preserve server-side
|
||||
authorization on every request, define safe loading/error/empty states, and
|
||||
prove login redirect plus browser journeys, cross-Organization denial, MEMBER
|
||||
denial, secret redaction, and logout/session expiry end to end.
|
||||
Reference in New Issue
Block a user