Compare commits
2 commits
28bd256ac7
...
1f19bfbdd5
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1f19bfbdd5 | ||
|
|
dbaf840ebe |
7 changed files with 260 additions and 2 deletions
63
model-outputs/01-architectural-risk-claude-sonnet-4.6.md
Normal file
63
model-outputs/01-architectural-risk-claude-sonnet-4.6.md
Normal file
|
|
@ -0,0 +1,63 @@
|
||||||
|
model: claude-sonnet-4-6
|
||||||
|
prompt: model-tests/01-architectural-risk.md
|
||||||
|
context: AGENTS.md
|
||||||
|
date: 2026-06-04
|
||||||
|
reference: true
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
decision 1: sqlite with "postgres-ready schema"
|
||||||
|
|
||||||
|
the risk is that "postgres-ready" is not a state sqlite enforces — it's a promise
|
||||||
|
the developer keeps. sqlite is dramatically more permissive than postgres: no
|
||||||
|
strict foreign key enforcement by default, no real enum types, no CHECK
|
||||||
|
constraints with the same semantics, different RETURNING behavior, and timestamp
|
||||||
|
handling that silently accepts junk. the gap only surfaces at migration time,
|
||||||
|
which is exactly the worst moment to discover it. the specific trap for this
|
||||||
|
codebase is the reaction model — user + post + emoji + timestamp with no counter
|
||||||
|
normalization is fine, but if you're using sqlite's flexible typing and unquoted
|
||||||
|
column names anywhere, your postgres migration will break on things that look like
|
||||||
|
they should work. the tus resumable upload state also tends to involve upserts
|
||||||
|
and returning clauses that differ between the two.
|
||||||
|
|
||||||
|
mitigation: enforce PRAGMA strict = ON from day one (bun:sqlite supports it). this
|
||||||
|
makes sqlite reject type mismatches the same way postgres would, and it's a
|
||||||
|
one-liner that costs nothing and catches the class of bugs that makes migrations
|
||||||
|
painful.
|
||||||
|
|
||||||
|
---
|
||||||
|
decision 2: federation off via a flag, activitypub data model active from day one
|
||||||
|
|
||||||
|
the risk is not technical complexity — fedify handles that. the risk is that
|
||||||
|
"flag-flippable later" assumes your object URIs are stable and your actor
|
||||||
|
resolution works correctly before you have any external consumers to test against.
|
||||||
|
when you eventually flip the flag, you'll discover that your webfinger endpoint
|
||||||
|
was returning the wrong content-type, your @context was subtly wrong, or your
|
||||||
|
outbox pagination was broken — and you'll find out from confused server admins on
|
||||||
|
the other end, not from a test suite. activitypub interoperability is notoriously
|
||||||
|
hard to verify in isolation.
|
||||||
|
|
||||||
|
mitigation: stand up a second test instance (even just a local second process) and
|
||||||
|
do one real federation handshake before v1 ships, even with the flag off in
|
||||||
|
production. you don't need to turn it on publicly — you just need to know it
|
||||||
|
works. this is maybe two hours of work and it retires the "unknown unknowns" risk
|
||||||
|
entirely.
|
||||||
|
|
||||||
|
---
|
||||||
|
decision 3: magic-link email auth with no passwords and no push notifications
|
||||||
|
|
||||||
|
the hidden complexity here is account recovery under adversarial conditions. magic
|
||||||
|
links depend entirely on email delivery. if the user's inbox is inaccessible
|
||||||
|
(spam filter swallowed the link, mail provider down, user changed email and didn't
|
||||||
|
update), there is no fallback — no password reset, no SMS, no TOTP. for a small
|
||||||
|
invite-only community this is probably fine in practice, but the specific failure
|
||||||
|
mode is: user gets a new phone, opens eutopic, tries to log in, email goes to spam
|
||||||
|
or their old address, and they're locked out with no self-service recovery path.
|
||||||
|
they have to contact you, the admin, directly. that's not catastrophic at 50 users
|
||||||
|
— it's actually fine — but it needs to be a named operational responsibility, not
|
||||||
|
a discovered one.
|
||||||
|
|
||||||
|
mitigation: add a simple admin-side "resend invite / reassign email" capability
|
||||||
|
before the first non-technical user onboards. one endpoint, admin-only, takes a
|
||||||
|
username and a new email. this is 20 lines of backend code and it means account
|
||||||
|
recovery is always solvable without a production incident.
|
||||||
42
model-outputs/01-architectural-risk-deepseek-reasoner.md
Normal file
42
model-outputs/01-architectural-risk-deepseek-reasoner.md
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
model: deepseek-reasoner
|
||||||
|
prompt: model-tests/01-architectural-risk.md
|
||||||
|
date: 2026-06-04
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
1. fedify/activitypub from day one, federation off
|
||||||
|
|
||||||
|
the risk is paying a nontrivial complexity tax (uri-based ids everywhere, fedify's
|
||||||
|
type system coupled to elysia, ap protocol shapes in the data model) for a
|
||||||
|
feature that's gated behind an off flag. fedify is a small team and its bun/elysia
|
||||||
|
binding may not keep pace with runtime changes. you'll debug fedify internals
|
||||||
|
before you ever federate a single post. mitigation: wrap all fedify calls behind a
|
||||||
|
thin repository/port interface in the domain layer. if fedify breaks or stalls,
|
||||||
|
you swap to a minimal ap implementation without touching business logic. don't let
|
||||||
|
fedify's types bleed into your controllers.
|
||||||
|
|
||||||
|
2. sqlite with "postgres-ready" schema
|
||||||
|
|
||||||
|
the classic migration trap. sqlite and postgres differ in transaction semantics,
|
||||||
|
query planning, type coercion, and concurrency (wal vs mvcc). writing sql that
|
||||||
|
performs well on both is harder than committing to one. the specific pattern i'd
|
||||||
|
watch: bun:sqlite is synchronous — sqlite calls block the elysia event loop. for
|
||||||
|
5-50 users it's fine, but the moment you need queries that use postgres-specific
|
||||||
|
features (jsonb, partial indexes, ctes for complex follows) you'll have rewritten
|
||||||
|
significant code anyway. mitigation: commit to sqlite fully. use wal mode, measure
|
||||||
|
whether event-loop blocking matters at your scale, and only design a thin query
|
||||||
|
adapter — not a dual-runtime schema. the "just swap the connection string" plan
|
||||||
|
doesn't survive contact with real query differences.
|
||||||
|
|
||||||
|
3. tus.io resumable uploads from the first alpha
|
||||||
|
|
||||||
|
the biggest hidden complexity in the stack. tus is a protocol, not a plug-in. on
|
||||||
|
the flutter side you need: platform-specific background upload services
|
||||||
|
(urlsession on ios / workmanager on android), a chunk-state machine, and resume
|
||||||
|
logic. on the server: chunk reassembly, temp storage for partial uploads, cleanup
|
||||||
|
of abandoned transfers. for 5-50 users posting a few photos a day, a simple
|
||||||
|
multipart upload with exponential backoff covers 95% of the same use case with a
|
||||||
|
fraction of the surface area. mitigation: ship the alpha with plain multipart
|
||||||
|
upload behind a clean interface. add tus only when real-world users on bad
|
||||||
|
connections demonstrably need it. you'll know when because they'll tell you — 5
|
||||||
|
people on a train is a clearer signal than any architecture doc.
|
||||||
|
|
@ -0,0 +1,65 @@
|
||||||
|
model: gemma-4-e4b-it-OptiQ-4bit
|
||||||
|
prompt: model-tests/01-architectural-risk.md
|
||||||
|
context: AGENTS.md + docs/CONCEPT.md + docs/OPEN-QUESTIONS.md
|
||||||
|
date: 2026-06-04
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
thinking carefully... i'm looking at concept.md, open-questions.md, and the
|
||||||
|
implied context from AGENTS.md—even though i haven't read AGENTS.md yet, the other
|
||||||
|
docs give enough signal to start the high-level risk assessment for a pre-build
|
||||||
|
review, focusing on architecture rather than feature completeness yet. the core
|
||||||
|
tension seems to be "simple feel vs. robust future proofing."
|
||||||
|
|
||||||
|
i see three high-risk areas stemming from the confluence of tech choices and
|
||||||
|
philosophical constraints.
|
||||||
|
|
||||||
|
the first is integrating activitypub/fedify while keeping federation disabled
|
||||||
|
(lines 81-83 in concept.md). the risk here isn't just that it's "upfront cost is
|
||||||
|
minimal," but rather the operational overhead of managing a protocol layer that
|
||||||
|
could suddenly be flipped on, which introduces non-trivial state management and
|
||||||
|
dependency complexity even if the feature is inert. making those URIs standard
|
||||||
|
from day one sounds good, but keeping them "off" while carrying the plumbing for
|
||||||
|
"on" creates latent complexity debt.
|
||||||
|
|
||||||
|
mitigation: define an extremely explicit, versioned configuration flag (e.g.,
|
||||||
|
activitypub_federation_enabled: false) checked at runtime by a monolithic routing
|
||||||
|
service, not loosely scattered. if this flag is ever toggled in production (even
|
||||||
|
for staging), the code path executing federation logic must be instantly testable
|
||||||
|
and roll-back friendly via config change alone.
|
||||||
|
|
||||||
|
the second big risk is the background/resumable upload pipeline (tus.io, lines
|
||||||
|
91-95). meta's perceived "instantness" versus a distributed upload mechanism is a
|
||||||
|
major user experience divergence. while the architecture supports it,
|
||||||
|
implementation complexity skyrockets when considering edge cases: network drops
|
||||||
|
mid-upload across multiple background processing contexts (ios background tasks,
|
||||||
|
android workmanager) combined with filesystem/s3 migration (line 52). state
|
||||||
|
synchronization for resumable uploads across these heterogeneous environments is
|
||||||
|
hard.
|
||||||
|
|
||||||
|
mitigation: start by locking down the mobile client's upload state caching locally
|
||||||
|
(e.g., using a simple encrypted sqlite file on the client device) before tackling
|
||||||
|
server-side resilience for version 1. initial V1 should prioritize making the
|
||||||
|
upload appear instant to the user via local caching, and only push the full
|
||||||
|
resiliency layer post-MVP inside a tight scope.
|
||||||
|
|
||||||
|
the third risk is unifying the "no hierarchy" value with the feature set,
|
||||||
|
specifically around reactions and potential future comments. in concept.md (lines
|
||||||
|
122-139) and open-questions.md, there's a constant pivot away from counts/public
|
||||||
|
visibility (reactions are stored as user + post + emoji + timestamp, not counters,
|
||||||
|
confirmed in closed section 32). while this protects the value statement against
|
||||||
|
"dopamine grift," it heavily complicates feed sorting/discoverability if those
|
||||||
|
values ever become necessary. the user base is small, but scaling this philosophy
|
||||||
|
becomes difficult.
|
||||||
|
|
||||||
|
mitigation: codify the "no counts" rule as an immutable architectural constraint
|
||||||
|
that is flagged in the AGENTS.md (line 74) and enforced by linting checks against
|
||||||
|
any future PR that introduces a counter field for engagement. if the community
|
||||||
|
later demands "what are people thinking?" (i.e., counts), the system must require
|
||||||
|
a full re-architecture via a staged 'v2 migration' rather than incremental feature
|
||||||
|
creep.
|
||||||
|
|
||||||
|
i identified three risks:
|
||||||
|
1. activitypub plumbing complexity with federation off.
|
||||||
|
2. complex state synchronization for resumable uploads across mobile platforms.
|
||||||
|
3. maintaining "no hierarchy" by forbidding engagement counters entirely.
|
||||||
33
model-outputs/01-architectural-risk-glm-4.7.md
Normal file
33
model-outputs/01-architectural-risk-glm-4.7.md
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
model: glm-4.7
|
||||||
|
prompt: model-tests/01-architectural-risk.md
|
||||||
|
date: 2026-06-04
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
three highest-risk decisions:
|
||||||
|
|
||||||
|
storage migration (filesystem → s3-compatible). open priority 0 question flagged
|
||||||
|
in OPEN-QUESTIONS.md. moving existing user media after launch means rewriting
|
||||||
|
database references, handling broken links, and likely requiring a period where
|
||||||
|
both systems coexist. risk: data loss or broken media references during migration.
|
||||||
|
mitigation: write to both filesystem and s3-compatible storage from day one
|
||||||
|
(dual-write), making migration a matter of retiring the filesystem backend rather
|
||||||
|
than moving data.
|
||||||
|
|
||||||
|
sqlite → postgres migration path. called "postgres-ready" but no documented
|
||||||
|
strategy exists. sqlite and postgres have different constraint semantics,
|
||||||
|
transaction behaviors, and query capabilities. a photo-first app will hit sqlite
|
||||||
|
limits faster than a text-only one. risk: architectural assumptions that don't
|
||||||
|
port, breaking migrations or queries at scale. mitigation: use a repository
|
||||||
|
pattern to abstract database specifics, add a migration test suite with realistic
|
||||||
|
media volume early, and document which postgres features you're avoiding to stay
|
||||||
|
sqlite-compatible.
|
||||||
|
|
||||||
|
fedify integration without v1 activation. fedify is in the stack but federation is
|
||||||
|
off, planned for v2/v3. building the core data model without understanding
|
||||||
|
fedify's requirements could force major refactoring later. risk: discovering
|
||||||
|
incompatibilities between your current schema and fedify's activitypub model
|
||||||
|
constraints after users have data. mitigation: prototype a minimal fedify
|
||||||
|
integration now to understand its schema and protocol requirements, then design
|
||||||
|
your core data model with those constraints in mind even if federation remains
|
||||||
|
inactive.
|
||||||
48
model-outputs/01-architectural-risk-qwen3.5-9b.md
Normal file
48
model-outputs/01-architectural-risk-qwen3.5-9b.md
Normal file
|
|
@ -0,0 +1,48 @@
|
||||||
|
model: qwen3.5-9b
|
||||||
|
prompt: model-tests/01-architectural-risk.md
|
||||||
|
context: AGENTS.md
|
||||||
|
date: 2026-06-04
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
the three highest-risk architectural choices are the is_admin flag without RBAC
|
||||||
|
primitives, deferring DMs to v2 via external handles instead of in-app messaging,
|
||||||
|
and relying on fs storage with no migration plan until after media ingestion is
|
||||||
|
live.
|
||||||
|
|
||||||
|
first, locking down "admin-only surveys" with a single boolean flag on the user
|
||||||
|
table creates a single point of failure for trust and access control. if you need
|
||||||
|
to revoke admin rights or split duties later without rewriting the core auth flow,
|
||||||
|
you are stuck. the risk here is operational lock-in where one person controls all
|
||||||
|
feedback loops and the app has no mechanism to audit who actually created what. i
|
||||||
|
estimate a 40–60% chance you will face a hard refactor when v2 needs granular
|
||||||
|
permissions for events or fundraising moderation. mitigate this by designing user
|
||||||
|
records with an empty policy map {} that maps roles (admin, mod, poster) to action
|
||||||
|
sets upfront in the schema, even if only one role exists now.
|
||||||
|
|
||||||
|
second, handling DMs via external social handle strings means you lose the ability
|
||||||
|
to resolve addresses within eutopic and force users to leave your app for
|
||||||
|
conversation. this is a user retention risk because photo comments will naturally
|
||||||
|
drift toward private chat, but you've built no bridge into that space. it also
|
||||||
|
complicates v2 scope creep if you later decide to build DMs: you'd need to
|
||||||
|
retrofit an internal message store or convince users to migrate their existing
|
||||||
|
external threads. the probability of needing to rewrite the onboarding and profile
|
||||||
|
flow is 30–50%. mitigate this by implementing a minimal internal /messages table
|
||||||
|
with ephemeral in-app routing (pushed to v2) now, keeping it isolated from the
|
||||||
|
main feed logic so you can toggle visibility without touching backend routes.
|
||||||
|
|
||||||
|
third, storing media on local fs before committing to an s3-compatible abstraction
|
||||||
|
layer creates silent failure modes when disk space fills up or hardware degrades.
|
||||||
|
with 5–50 users each uploading 10 photos at 5mb average, you'll hit a terabyte
|
||||||
|
wall in ~100 days if growth accelerates. migrating mid-data is painful because of
|
||||||
|
checksums and broken links. the risk surfaces only after you've ingested critical
|
||||||
|
community content. i see a 60–70% chance this path forces an emergency rewrite
|
||||||
|
during v2 prep when disk space becomes tight or backups fail. mitigate by mocking
|
||||||
|
MediaStorage as an interface with fs impl now, but enforce a pre-check on first
|
||||||
|
upload that writes metadata to a central catalog table and verifies free-space
|
||||||
|
before accepting the file stream.
|
||||||
|
|
||||||
|
you're building something intentional here, but these three decisions will bite if
|
||||||
|
you ship without planning for their evolution paths.
|
||||||
|
|
||||||
|
✻ Crunched for 1m 2s
|
||||||
|
|
@ -4,6 +4,6 @@ version: 1
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
read @AGENTS.md. you are a senior backend engineer reviewing this project's architectural decisions before the first line of code is written.
|
read @AGENTS.md and @CONCEPT.md and @OPEN_QUESTIONS.md. you are a senior backend engineer reviewing this project's architectural decisions before the first line of code is written.
|
||||||
|
|
||||||
identify up to three decisions that carry the most technical risk or hidden complexity. for each one: name the decision, explain the specific risk, and suggest one mitigation. be direct — this is a pre-build review, not a validation exercise.
|
identify up to three decisions that carry the most technical risk or hidden complexity. for each one: name the decision, explain the specific risk, and suggest one mitigation. be direct — this is a pre-build review, not a validation exercise.
|
||||||
7
model-tests/05-short_subprompt.md
Normal file
7
model-tests/05-short_subprompt.md
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
tests: stack analysis, constraint awareness, length discipline
|
||||||
|
context: AGENTS.md
|
||||||
|
version: 1
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
read @AGENTS.md and provide thoughts on the `## stack (settled)` section. your response should be a general analysis of the strengths/weaknesses of the stack. limit your response to max 6 sentences.
|
||||||
Loading…
Reference in a new issue