diff --git a/model-outputs/01-architectural-risk-claude-sonnet-4.6.md b/model-outputs/01-architectural-risk-claude-sonnet-4.6.md new file mode 100644 index 0000000..4f1e684 --- /dev/null +++ b/model-outputs/01-architectural-risk-claude-sonnet-4.6.md @@ -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. diff --git a/model-outputs/01-architectural-risk-deepseek-reasoner.md b/model-outputs/01-architectural-risk-deepseek-reasoner.md new file mode 100644 index 0000000..598cd4b --- /dev/null +++ b/model-outputs/01-architectural-risk-deepseek-reasoner.md @@ -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. diff --git a/model-outputs/01-architectural-risk-gemma-optiq-agents-concept-openq.md b/model-outputs/01-architectural-risk-gemma-optiq-agents-concept-openq.md new file mode 100644 index 0000000..db9c0ec --- /dev/null +++ b/model-outputs/01-architectural-risk-gemma-optiq-agents-concept-openq.md @@ -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. diff --git a/model-outputs/01-architectural-risk-glm-4.7.md b/model-outputs/01-architectural-risk-glm-4.7.md new file mode 100644 index 0000000..71ebcde --- /dev/null +++ b/model-outputs/01-architectural-risk-glm-4.7.md @@ -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. diff --git a/model-outputs/01-architectural-risk-qwen3.5-9b.md b/model-outputs/01-architectural-risk-qwen3.5-9b.md new file mode 100644 index 0000000..eccbfdb --- /dev/null +++ b/model-outputs/01-architectural-risk-qwen3.5-9b.md @@ -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 diff --git a/model-tests/05-short_subprompt.md b/model-tests/05-short_subprompt.md new file mode 100644 index 0000000..95b2bfa --- /dev/null +++ b/model-tests/05-short_subprompt.md @@ -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.