Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
48 changes: 48 additions & 0 deletions .forge/features/saicharan-blade-portfolio/spec.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Saicharan Blade Dev Application Spec

Status: Approved

## User-facing purpose

Present Saicharan Ramineni's developer application as one continuous cinematic handoff inside Blade. Reviewers first meet Tech Knight at full scale, watch a black hole pull him out of the scene, and see Saicharan's live portfolio emerge from the same singularity rather than reaching it through a separate content section.

## Users / actors

- Knight Hacks Dev Lead and application reviewers
- Knight Hacks members and public visitors

## User-visible interface

A single public page at `/saicharan-ramineni` with an automatic, full-viewport 3D sequence. Tech Knight begins fully present, a black hole forms behind him and pulls the live model into its core, and the full-viewport sandboxed frame of `saicharanramineni.com` expands outward from that core. The site borrows only the cinematic ambition of Saicharan's existing portfolio.

## Scope

### In scope

- Responsive portfolio presentation at `/saicharan-ramineni`
- A custom modeled Tech Knight delivered as a real-time WebGL scene
- A black-hole departure built from true 3D geometry, shaders, particles, post-processing, and the live GLB, with no image placeholder
- A direct résumé link, a visible intro-skip control, and an automatic singularity transition into the personal site
- A fixed-source server bridge for the personal site because its upstream response denies direct framing
- Motion that respects reduced-motion preferences

### Out of scope

- Authentication, persistence, forms, or API work
- Changes to other Blade routes or shared packages
- A separate deployed site

## Acceptance criteria

- The route visibly identifies Saicharan Ramineni and his engineering focus.
- The opening shows the real Tech Knight model at full scale before the departure begins.
- A black hole forms behind Tech Knight, visibly bends the surrounding field, and pulls the live model into its core with a readable sense of depth and acceleration.
- No raster stand-in is shown while the Tech Knight loads.
- The personal-site frame is already loading behind the cinematic and is revealed outward from the black-hole core as one continuous transition.
- A visible skip control reveals the portfolio without trapping visitors in the animation.
- The layout remains usable on desktop and 320px-wide screens.
- Motion and hover effects do not hide information or block reduced-motion users.

## Open questions

- None. The user granted creative control and explicitly limited the existing portfolio reference to cinematic feeling rather than content or composition.
58 changes: 58 additions & 0 deletions .forge/features/saicharan-blade-portfolio/srd.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# Saicharan Blade Dev Application SRD

Status: Approved

## Technical purpose

Add a self-contained public developer-application route to Blade without changing platform behavior.

## Relevant principles

- [React and Next.js principles](../../../docs/agentic-development/forge-engineering-principles.md#react-and-nextjs-principles)
- [Frontend design-system principles](../../../docs/agentic-development/forge-engineering-principles.md#frontend-design-system-principles)
- [Blade design system](../../../apps/blade/DESIGN_SYSTEM.md)

## Access policy

Public and unauthenticated. No session, role, or permission checks.

## Architecture / data flow

The App Router page renders a Blade-local client gate. Its cinematic component initializes Three.js, loads and normalizes the Blender-authored `.glb` Tech Knight, and begins with the real model fully visible at a viewport-filling scale. A time-based sequence holds that hero composition, forms a shader-driven accretion disc and event horizon behind the model, bends stars and particle trails toward the core, then moves, stretches, rotates, dims, and shrinks the live GLB into the singularity. Dynamic rim lights, spatial rings, lensing geometry, a terminal energy flash, and Unreal bloom support the departure without a raster placeholder.

The full-viewport sandboxed iframe begins loading behind the cinematic layer. Once the model reaches the event horizon and the iframe is ready, the gate expands a circular clip from the singularity's screen position until the personal site occupies the viewport; the Three.js layer fades only after the reveal is established. `GET /saicharan-ramineni/site` fetches only the fixed personal-site origin, injects a base URL for remote assets, omits the upstream `X-Frame-Options: DENY` header, and returns cached HTML. Because Cloudflare Rocket Loader rewrites the portfolio's scripts to request-scoped inert MIME types, the bridge restores those scripts to `text/javascript`, removes their loader metadata, and omits the redundant Rocket Loader script. A narrow history guard retries cross-origin `pushState` and `replaceState` calls without a URL, preventing Next.js from resolving the local bridge path against the remote base URL. This lets the original portfolio hydrate and run its Gargantua WebGL renderer unchanged. Hash navigation stays inside the frame; route links open on the personal-site origin. The fixed-source frame grants scripts and same-origin access so its runtime can use the browser APIs it requires.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🛡️ Analyzed with Security Review | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

sed -n '1,140p' apps/blade/src/app/_components/applications/saicharan-portfolio-gate.tsx
printf '\n--- route ---\n'
sed -n '1,120p' apps/blade/src/app/saicharan-ramineni/site/route.ts

Repository: KnightHacks/forge

Length of output: 5797


🤖 get_repo_knowledge executed:

get_repo_knowledge KnightHacks/forge /tmp/coderabbit-repo-knowledge/knighthacks-forge-24c72cfe

Length of output: 3924


🏁 Script executed:

sed -n '1,140p' apps/blade/src/app/_components/applications/saicharan-portfolio-gate.tsx
sed -n '1,120p' apps/blade/src/app/saicharan-ramineni/site/route.ts

Repository: KnightHacks/forge

Length of output: 5782


Security Misconfiguration

Reachability: External
Exploitability: Moderate
CWE: CWE-829 — Inclusion of Functionality from Untrusted Control Sphere

Serve the bridged portfolio from a separate origin.

allow-scripts with allow-same-origin lets a compromised portfolio script access same-origin Blade state through window.parent.


## tRPC/API behavior

None.

## Validation

No user input or runtime data requires validation.

## Data / migration / compatibility

No data, schema, environment, or migration changes. Blade adds `three` and `@types/three`; its Three.js version matches the existing Guild dependency. Checked-in Blender and Node generator scripts make the `.glb` reproducible. Regeneration requires Blender or `BLENDER_BIN`. The personal-site bridge has no user-controlled upstream URL and stores no content or credentials.

## Discord integration

None.

## Configurability review

Would this require a developer change next year?

- Answer: Yes, because this is an intentionally personal, one-off application route owned by the applicant rather than recurring organizational configuration.
- If yes, why is hard-coding acceptable or what admin-configurable path is planned? The route is portfolio content, not operational Blade state.

## React / frontend constraints

Keep `page.tsx` server-side and thin. Confine the WebGL lifecycle to one client boundary, clean up GPU and post-processing resources on unmount, cap pixel density, and keep identity and navigation semantic outside the canvas. Keep React state changes phase-based rather than frame-based; Three.js owns per-frame transforms while the gate owns the one-time portfolio reveal. The timeline may pause at the reveal threshold until the iframe reports ready. A visible skip control bypasses the cinematic. Reduced motion uses a static Tech Knight composition and an explicit portfolio action rather than automatic spatial movement. If WebGL or model loading fails, reveal the already-loaded portfolio instead of leaving a blank scene.

## Testing / verification strategy

Run file formatting, targeted ESLint, Blade typecheck, React analysis for changed files, model regeneration, a production Blade build when environment validation permits, and local route rendering.

## Open questions

- None.
77 changes: 77 additions & 0 deletions .forge/features/saicharan-blade-portfolio/status.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# Saicharan Blade Dev Application Status

Current phase: Complete

## Decision log

- 2026-09-08: Use the supplied portfolio only as evidence for factual links and cinematic ambition; do not reuse its content structure or composition.
- 2026-09-08: Keep the route public, static, server-first, and isolated to Blade.
- 2026-09-08: Replace the rejected dashboard treatment with an editorial layout and a real procedural Tech Knight `.glb` rendered in Three.js.
- 2026-09-08: Build the application around a dark cinematic arrival, pale editorial letter, deep-navy field notes, vivid-cyan open-source proof, and a restrained closing statement.
- 2026-09-08: Replace the primitive Three.js prototype with a Blender-authored hard-surface model matching the supplied 2D silhouette: crown, black faceplate, cyan eyes and seams, layered armor, articulated pointing hand, faulds, oversized greaves, and asymmetric circuit cape.
- 2026-09-08: After model approval, implement the Celestial-inspired entrance as a reverse departure: a singularity ignites, the actual GLB travels along a curved depth path, and spatial light, streaks, shockwaves, and bloom resolve around it.
- 2026-09-08: Remove the generated image fallback and canvas-texture portal. The animation now begins only when the real 3D model is loaded and uses true scene geometry throughout.
- 2026-09-08: Delay Tech Knight visibility until after the energy-field prelude and fade the real GLB materials in during translation.
- 2026-09-08: Remove the application letter, project field notes, open-source details, contact block, and profile list. End on one personal-site handoff instead.
- 2026-09-08: Because the personal site returns `X-Frame-Options: DENY`, use a fixed-source HTML bridge and a sandboxed iframe; browser history provides the return path.
- 2026-09-08: Restore Cloudflare-transformed script MIME types, remove Rocket Loader, and guard the one cross-origin history mutation caused by the remote base URL so the original portfolio and Gargantua runtime execute unchanged.
- 2026-09-09: Replace the arrival-and-button flow with one automatic eclipse transition: Tech Knight begins full-scale, a black hole pulls the real GLB backward, and the already-loaded portfolio expands from the same core.

## Open questions

- None.

## Task list

- [x] Confirm goal, route, source material, and scope from the user's request.
- [x] Complete `spec.md`, `srd.md`, and `test-cases.md`.
- [x] Treat the user's explicit redesign request as approval for the supplied portfolio direction.
- [x] Build the portfolio page.
- [x] Generate and integrate the Tech Knight model.
- [x] Replace the prototype with the high-fidelity Blender model.
- [x] Rebuild the entire page with an application-specific editorial system and original writing.
- [x] Implement the full automatic 3D entrance and scroll handoff.
- [x] Remove the raster placeholder from the component, generator, and asset directory.
- [x] Delay model visibility and materialize its real materials after the entrance prelude.
- [x] Replace the detailed application sections with one minimal handoff surface.
- [x] Add and validate the sandboxed personal-site frame.
- [x] Restore the personal site's original cinematic WebGL runtime inside the frame.
- [x] Validate code and responsive presentation.
- [x] Rebuild the Three.js timeline around the full-scale departure.
- [x] Reveal the portfolio through the singularity without a separate handoff section.
- [x] Add skip, reduced-motion, loading, and WebGL-failure paths.
- [x] Validate the new cinematic on desktop and 320px mobile.
- [x] Update the existing draft PR.

## Validation / commands

- `pnpm exec prettier --write ...` — pass
- targeted ESLint with 8 GB heap — pass
- Blade `tsc --noEmit` with 8 GB heap — pass before rebasing onto the latest upstream `main`
- `pnpm analyze:react apps/blade/src/app/_components/applications` — pass (3 files, 3 components, 0 failures)
- `pnpm analyze:react:changed` — pass (4 files, 3 components, 0 failures)
- `pnpm format` — pass (24 tasks)
- `NODE_OPTIONS=--max-old-space-size=8192 pnpm lint` — pass (31 tasks; existing warnings, no errors)
- `NODE_OPTIONS=--max-old-space-size=8192 pnpm typecheck` — pass before rebasing onto the latest upstream `main` (33 tasks)
- Post-rebase Blade typecheck — blocked by existing judging/API errors in files outside this feature diff; no reported error points to the application
- `pnpm --filter=@forge/blade build` with process-only validation values — pass before rebase; route emitted as static and bridge as dynamic
- Tech Knight regeneration through Blender 5.2 — pass
- Local `/saicharan-ramineni` render — HTTP 200
- Local `/saicharan-ramineni/site` bridge — HTTP 200 with injected remote base URL
- Bridged portfolio response — executable original scripts with Cloudflare's inert wrappers removed
- Live frame inspection — `cosmos-ready`; genuine canvas visible at 1614×1490 CSS-pixel-backed resolution; no new runtime errors
- Post-rebase browser review — Tech Knight hero and original Gargantua handoff captured in the checked-in review screenshots
- 2026-09-09 desktop browser review — full-scale hero, extraction path, singularity reveal, live portfolio, and skip/unmount behavior pass
- 2026-09-09 320px browser review — full-scale hero, mobile extraction path, controls, typography, and final portfolio presentation pass
- 2026-09-09 `pnpm analyze:react:changed` — pass (4 files, 3 components, 0 failures)
- 2026-09-09 `pnpm format` — pass (24 tasks)
- 2026-09-09 `NODE_OPTIONS=--max-old-space-size=8192 pnpm lint` — pass (31 tasks; existing warnings, no errors)
- 2026-09-09 `NODE_OPTIONS=--max-old-space-size=8192 pnpm typecheck` — pass (33 tasks)
- 2026-09-09 `pnpm --filter=@forge/blade build` with process-only validation values — pass; the application route is static and the bridge is dynamic
- 2026-09-09 `/saicharan-ramineni` and `/saicharan-ramineni/site` — HTTP 200

## Links

- PRs: https://github.com/KnightHacks/forge/pull/554
- Issues: https://github.com/KnightHacks/forge/issues/553
- Discord/thread context:
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
142 changes: 142 additions & 0 deletions .forge/features/saicharan-blade-portfolio/test-cases.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
# Saicharan Blade Portfolio Test Cases

Status: Approved

## Scope

Validate the public application route, real-time 3D departure, singularity-to-portfolio reveal, sandboxed personal-site frame, responsive layout, loading behavior, and reduced-motion behavior. Authentication and backend behavior are excluded.

## Test placement plan

Blade route and component checks through Prettier, ESLint, TypeScript, React analysis, model regeneration, and local HTTP rendering.

## Test cases

### TC-001: Portfolio identity and navigation

Setup:

- Blade is running locally.

Action:

- Visit `/saicharan-ramineni` and follow the primary links.

Expected observations:

- Saicharan's name, Blade application identity, résumé, and intro-skip action are visible and usable without duplicated portfolio detail.

### TC-002: Responsive presentation

Setup:

- Render the page at desktop and 320px mobile widths.

Action:

- Inspect the full page and primary navigation.

Expected observations:

- Content wraps without document-level horizontal overflow, touch targets remain usable, and key content is not clipped.

### TC-003: Automatic 3D departure

Setup:

- Load the route in a WebGL-capable browser.

Action:

- Load the opening cinematic and allow its timeline to complete without interacting.

Expected observations:

- The live Tech Knight GLB is the opening focal point at full scale.
- A black hole forms behind the model with a black event horizon, luminous accretion structure, warped particles, and responsive scene lighting.
- Tech Knight accelerates backward into the core, with controlled rotation, stretching, scale loss, and material fade that remain spatially aligned with the singularity.
- No PNG, canvas texture, or other model placeholder is displayed.

### TC-004: Singularity portfolio reveal

Setup:

- Load the route with a working personal-site bridge.

Action:

- Allow the departure to reach the event horizon.

Expected observations:

- The personal site reveals from the black-hole core rather than appearing as an unrelated page replacement.
- The reveal expands to the full viewport without a flash, blank frame, or visible iframe edge.
- The Three.js layer disappears only after the portfolio is established.

### TC-005: Personal-site bridge

Setup:

- Reach the completed singularity reveal.

Action:

- Inspect and interact with the revealed personal site.

Expected observations:

- The Blade cinematic yields to a full-viewport frame of the personal website.
- The frame loads through the fixed local bridge despite the upstream site's direct-frame denial.
- Cloudflare's transformed script types and Rocket Loader wrapper are absent from the bridged response, while the original portfolio scripts remain executable.
- The portfolio reaches `cosmos-ready`; its genuine Gargantua canvas is visible and sized above the default 300×150 canvas dimensions.
- The remote-base history guard prevents cross-origin `pushState` and `replaceState` crashes during hydration.
- Hash links remain in-frame; route and external links open outside it.
- The fixed-source frame is sandboxed with the script and same-origin capabilities required by the original renderer.

### TC-006: Skip control

Setup:

- Load the route while the cinematic is running.

Action:

- Select “Skip intro”.

Expected observations:

- The portfolio is revealed immediately and the visitor is not trapped behind the WebGL sequence.

## Negative / regression cases

### TC-NEG-001: Reduced motion

Setup:

- The visitor enables reduced motion.

Action:

- Load and navigate the portfolio.

Expected observations:

- Tech Knight is shown in a static full-scale composition, decorative motion does not autoplay, and an explicit action reveals the portfolio.

### TC-NEG-002: Model or WebGL unavailable

Setup:

- Prevent the `.glb` from loading or use a browser without WebGL.

Action:

- Load the portfolio.

Expected observations:

- The already-loading personal-site frame is revealed, no misleading raster model substitute appears, and the visitor does not remain on a broken cinematic surface.

## Open questions

- None.
3 changes: 3 additions & 0 deletions apps/blade/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"clean": "git clean -xdf .cache .next .turbo node_modules",
"dev": "pnpm with-env next dev --port 3000",
"format": "prettier --check . --ignore-path ../../.gitignore",
"generate:tech-knight": "node scripts/generate-tech-knight-model.mjs",
"lint": "eslint",
"start": "pnpm with-env next start",
"typecheck": "tsc --noEmit",
Expand Down Expand Up @@ -56,6 +57,7 @@
"react-dom": "^19.2.4",
"recharts": "^3.7.0",
"superjson": "2.2.6",
"three": "^0.185.1",
"tw-animate-css": "^1.4.0",
"zod": "catalog:"
},
Expand All @@ -72,6 +74,7 @@
"@types/node": "^25.3.2",
"@types/react": "^19.2.14",
"@types/react-dom": "^19.2.3",
"@types/three": "^0.185.1",
"dotenv-cli": "^11.0.0",
"eslint": "catalog:",
"jiti": "^2.6.1",
Expand Down
Binary file added apps/blade/public/saicharan/tech-knight.glb
Binary file not shown.
31 changes: 31 additions & 0 deletions apps/blade/scripts/generate-tech-knight-model.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { spawnSync } from "node:child_process";
import { existsSync } from "node:fs";
import { resolve } from "node:path";

const candidates = [
process.env.BLENDER_BIN,
"/Applications/Blender.app/Contents/MacOS/Blender",
"blender",
].filter(Boolean);

const blender = candidates.find(
(candidate) => candidate === "blender" || existsSync(candidate),
);

if (!blender) {
throw new Error(
"Blender was not found. Install Blender or set BLENDER_BIN before generating the Tech Knight model.",
);
}

const script = resolve(process.cwd(), "scripts/generate-tech-knight-model.py");
const result = spawnSync(
blender,
["--background", "--python-exit-code", "1", "--python", script],
{
stdio: "inherit",
},
);

if (result.error) throw result.error;
process.exit(result.status ?? 1);
Loading