48 Commits

Author SHA1 Message Date
-Puter
8d43bea58e fix(resume): proxy empty success responses 2026-07-14 02:22:32 +05:30
-Puter
a2292dd155 fix(roleplay): register resumed sessions for tickets 2026-07-14 01:38:40 +05:30
-Puter
4985605638 fix(roleplay): expose saved draft controls 2026-07-14 01:25:25 +05:30
-Puter
626684ea7e fix: forward user identity to resume service 2026-07-13 22:49:59 +05:30
-Puter
5eaf4ae1ea fix backend service user identity forwarding 2026-07-13 21:19:55 +05:30
-Puter
eafca3aafb feat: issue scoped websocket session tickets 2026-07-13 20:19:11 +05:30
-Puter
8c0f8e1d57 Make Course A2A gateway transport-only 2026-07-13 20:13:57 +05:30
-Puter
4c59151e37 Avoid duplicate Course scoring events 2026-07-13 20:13:53 +05:30
-Puter
a3c4a91cbe Project Course swipe gateway events 2026-07-13 20:13:53 +05:30
-Puter
4fa4a8bbd1 test: remove tautological service token assertion 2026-07-13 20:12:59 +05:30
-Puter
d71b7ede08 test: cover service token config resolution 2026-07-13 20:12:59 +05:30
-Puter
1f778fe3ea Prevent Course gateway score double counting 2026-07-13 20:12:59 +05:30
-Puter
fc06317832 fix(auth): remove compose service token fallback 2026-07-13 20:12:59 +05:30
-Puter
a1e05b0337 Add focused Course and Matchmaking route tests 2026-07-13 20:12:59 +05:30
-Puter
70c3634178 Remove backend dev A2A auth fallback 2026-07-13 20:12:59 +05:30
-Puter
26e0e54488 fix(staging): pin verified models and resume route 2026-07-13 18:04:49 +05:30
Sai-karthik
3a7a6c46a8 Cover task-aware curator handoffs 2026-07-13 10:11:27 +00:00
-Puter
9cb1027f4c fix(staging): make compose guard host-portable 2026-07-13 05:12:20 +05:30
-Puter
d2e3f49519 chore(staging): guard backend compose topology 2026-07-13 05:10:54 +05:30
-Puter
80884fc0b6 fix(staging): pin canonical service networks 2026-07-13 05:04:37 +05:30
-Puter
b93cc81d93 fix curator sprint to use canonical onboarding 2026-07-13 04:28:27 +05:30
-Puter
982942fa6e fix onboarding GET service auth seam 2026-07-13 04:15:01 +05:30
-Puter
fdc320b995 fix onboarding GET service network and rev10 serialization 2026-07-13 03:59:13 +05:30
-Puter
4b652358d3 fix curator sprint ICP reconciliation 2026-07-13 03:43:37 +05:30
-Puter
e7546142b6 fix curator sprint access choice reconciliation 2026-07-13 02:39:29 +05:30
-Puter
e50be827ca fix(scripts): repair onboarding-bulk-reset with A2A user-service endpoint
Rewire Phase 1 to call the user-service POST /api/v1/users/onboarding-reset A2A
endpoint (targeting by clerk_id) instead of the per-user authenticated DELETE
route, which could not reach all users. A 404 from user-service means the user
has no profile (backend-only) — a clean skip that does not block Phase 2.

Phase 2 (backend ledger reset via resetOnboardingLedger) now runs ONLY after
Phase 1 succeeds or is skipped; a non-404 pref error blocks the ledger for that
user to avoid inconsistent state. Triple guard (NODE_ENV=staging,
ONBOARDING_BULK_RESET_ALLOWED=true, --confirm) and aggregate-only output are
preserved. Add source-structure assertions for the CLI contract.
2026-07-12 20:50:17 +05:30
-Puter
c54e12972c fix(onboarding): synthetic PATCH /me stale content-length socket close
patchPreferencesRequest forwarded inbound headers (including
content-length from the browser PATCH body) but set a DIFFERENT body
({ preferences }). The Request constructor does NOT recompute
content-length when an explicit body is provided alongside forwarded
headers, so user-service waited for bytes that never arrived and closed
the socket (~2.8s 'other side closed') → uncaught → 500.

Delete content-length and transfer-encoding before constructing the
synthetic request so undici recomputes them from the actual body. Apply
the same defensive deletes in fetchUserProfile.

Extract patchPreferencesRequest into the DB-free
src/services/user-profile.ts module (alongside fetchUserProfile) so the
regression test imports the REAL function and asserts content-length /
transfer-encoding / host / cookie are stripped and the body is the
synthetic { preferences } blob. tsc clean; existing onboarding tests
pass.
2026-07-12 20:29:40 +05:30
-Puter
ad1318424b fix(onboarding): PATCH /onboarding 500 — fetchUserProfile must GET /me
PATCH /onboarding read its JSON body via c.req.json() (consuming
c.req.raw), then passed c.req.raw to fetchUserProfile → fetchUserService,
which called req.arrayBuffer() on the already-consumed body:
TypeError: Body is unusable. The global onError caught it as a 500
{"error":"internal"}, so every access-choice save failed. GET
/onboarding worked only because it never reads a body.

fetchUserProfile is a read; it must never replay the inbound method or
body. Extract it (+ userServiceTarget) into a DB-free module that issues
an explicit GET /me with forwarded headers, sidestepping body reuse
entirely and fixing a latent wrong-method bug (PATCH /onboarding would
have issued a PATCH /me write for a read).

Verified against staging logs (TypeError stack at fetchUserService →
fetchUserProfile → PATCH handler). Focused regression test consumes the
body first and asserts GET + no body re-read + profile parse; tsc clean.
2026-07-12 20:14:22 +05:30
-Puter
62208d385f feat(onboarding): persist resettable user state 2026-07-12 19:23:29 +05:30
Sai-karthik
411ad591bf fix: route curator tasks to unified service pages 2026-07-11 23:02:29 +00:00
-Puter
5f5b08bfda fix(events): prevent userEventActor queue saturation from duplicate routing
Root cause: recordGrowEvent returned the existing row on dedupe hits, and
routeGrowEventToUserActor was called unconditionally — so every duplicate
ingest re-enqueued the same event to the actor queue, saturating it.

Fix at the persistence boundary:
- recordGrowEventWithResult returns {event, inserted} using atomic
  onConflictDoNothing().returning() (row present = fresh insert, no row =
  dedupe hit). No clock heuristics, no xmax probe.
- Conflict lookup tries dedupeKey first, then id PK fallback, covering both
  constraint types.
- shouldRouteGrowEvent(event, inserted) gates routing to only newly-inserted,
  user-resolved, pending events. Dedupe hits never re-enqueue.
- recordGrowEvent kept as thin .event wrapper — zero changes to ~10 callers.

Fix the actor run loop (mirrors workflow-run-actor.ts):
- tryStep with catch:['timeout','exhausted'] replaces step+rethrow. Per-event
  failure is marked terminal in a separate record-failure step, loop advances.
- isProcessableStatus guard allows pending/processing/processed — only skips
  failed/unresolved. This ensures mission reducers (actor-only) still run on
  events that got synchronous projections.
- Status guard + claim moved inside tryStep's run for atomic retry unit.
- onError handler added to workflow().

Ingress callers migrated (3 paths):
- redis-consumer recordAndRoute: shouldRouteGrowEvent gate + always mark
  processed after projections.
- routes/events.ts ingest: shouldRouteGrowEvent gate + always mark processed.
- v1/events/events-routes.ts /track: inserted flag for dedupe skip.

Tests: 3 new (event-dedupe-routing, user-event-actor-advance,
event-ingress-route-integration with injectable enqueue proving 5x duplicate
ingest enqueues exactly once). All existing touched-scope tests green.

Co-authored-by: independent review (2 rounds)
2026-07-11 06:19:38 +05:30
-Puter
3f2dabd23d fix(events): bound actor routing latency 2026-07-10 20:26:38 +05:30
-Puter
ac7bdca912 feat(backend): REST-authoritative qscore pipeline with Redis opt-in
- Gate both Redis ingestion paths (canonical + legacy) behind separate
  default-off flags (GROW_EVENTS_REDIS_ENABLED, LEGACY_SERVICE_REDIS_ENABLED).
  The redis module is never imported when both flags are off.
- Sever legacy URL cascade: interview/roleplay/resume/courses Redis URLs
  resolve ONLY from their own explicit env vars, never from REDIS_URL or
  GROW_EVENTS_REDIS_URL.
- Export resolveRedisConfig() pure resolver for testability.
- Fix onboarding signal ID from 'onboarding.completed_baseline' to
  'onboarding.completed' (registry-valid in all v2 formula JSONs).
- Ensure interview/roleplay completed events emit at least a single
  completion signal when session_count/scenario_count is absent (default 1).
- Extract computeStreakFromDays() into streak-utils.ts (pure, no DB dep)
  with defensive dedup so duplicate days never inflate streaks.
- Add focused tests: redis-gating, signal-registry membership, count
  fallback, streak policy (current/longest/duplicate/gap/recovery/7-day),
  service-ingest projector behavior.
- typecheck: 80 pre-existing errors unchanged, 0 new.
2026-07-10 20:12:13 +05:30
-Puter
64c245535f feat(events): project course and matchmaking activity 2026-07-09 18:55:00 +05:30
Sai-karthik
4353e8fe33 Align curator sprint with static task docs 2026-07-02 19:54:50 +00:00
Sai-karthik
6432734f74 Split curator ICP and task registries 2026-07-02 17:59:07 +00:00
Sai-karthik
0394dfbca0 Verify static curator handoff registry 2026-07-02 13:18:49 +00:00
a6b0cf3a00 feat: add passive cross-service actions 2026-06-29 23:18:45 +05:30
210b577462 feat: add passive mission lifecycle 2026-06-29 22:15:59 +05:30
Sai-karthik
1b90e5db39 fix: inline service registry event contracts 2026-06-28 08:27:04 +00:00
685f2dcd24 feat: implement onboarding ledger event handling and related tests 2026-06-28 04:03:39 +05:30
-Puter
750a6ab03b puter fix: service registry and curator onboaridng data fix, home feed route fixes 2026-06-24 15:30:00 +05:30
Sai-karthik
bff336baa7 Add generated content quality smoke 2026-06-22 23:16:52 +00:00
Sai-karthik
cad24ea089 Keep public service catalog registry-only 2026-06-22 22:48:30 +00:00
Sai-karthik
459832a2a3 Add service registry acceptance probe 2026-06-22 22:35:06 +00:00
Sai-karthik
a3a84faae7 Add service gateway write-flow smoke 2026-06-22 22:19:03 +00:00
Sai-karthik
fe62662cb6 Harden service gateway smoke coverage 2026-06-22 21:46:06 +00:00
-Puter
289f6f7844 feat: add grow agent, conversation routes, pnpm migration, and scripts 2026-06-03 14:53:35 +05:30