Imported from sarimraza773/internflow (
AGENTS.md). Install upstream withnpx skills add sarimraza773/internflow. Copyright stays with the author.
InternFlow agent conventions
These instructions apply to the entire repository.
Scope and product boundaries
- Inspect the repository and current tool versions before making broad changes.
- State a short plan and relevant assumptions before editing.
- Implement only the feature requested. Do not add authentication, AI, browser extensions, reminders, uploads, email, deployment, or unrelated infrastructure unless explicitly authorized.
- Do not commit, push, add remotes, deploy, or store production secrets unless the user explicitly asks.
- Distinguish current behavior from planned architecture in documentation and handoffs.
Stack and package management
- Use npm and preserve
package-lock.json. - Use the Next.js App Router, strict TypeScript, Tailwind CSS, Prisma/PostgreSQL, Zod, React Hook Form, and Vitest.
- Prefer stable APIs supported by the installed versions. Check official documentation before adopting version-sensitive APIs.
- Do not replace the stack or add a second framework without explicit approval.
- Add dependencies only when the requested feature needs them.
Architecture
- Prefer Server Components for reads. Use Client Components only for browser interaction, form state, or optimistic/pending UI.
- Keep page components focused on routing and composition.
- Put application code under
src/features/applications:schemasfor validationservicesfor business rulesdatafor Prisma queries and repositoriesactionsfor Server Action boundariescomponentsfor feature UI
- Keep reusable primitives in
src/components/uiand shared infrastructure insrc/lib. - Keep candidate profile, education, experience, and saved-answer code under
src/features/profileusing the same schemas/services/data/actions/components boundaries. - Do not import the server Prisma client into Client Components.
- Reuse the Prisma singleton from
src/lib/prisma.ts.
Data and security
- Scope every application read and mutation by
userId, even before authentication exists. - Derive the current user ID from the verified server session at every page, Server Action, and route boundary. Never accept a user ID from client-controlled input.
- Keep password hashes and authentication credentials in server-only modules and use explicit safe Prisma selections when returning users.
- Treat a record owned by another user as not found; do not expose its existence.
- Record a status-history row only when the status changes.
- Update the application and insert status history in one transaction.
- Add a new versioned migration for schema changes. Never rewrite an applied migration.
- Keep seed data realistic, deterministic, and safe to rerun.
- Access private uploaded files only through a server-only storage abstraction. Store local-development files outside
publicwith generated keys, and serve them only after a session-derived owner check. - Never pass private storage keys or extracted résumé text to Client Components.
- Keep candidate records and saved answers owner-scoped by construction. Never accept saved-answer usage metadata from clients, and never log profile or answer content.
- Preserve unanswered profile booleans as null. Saved-question normalization must remain deterministic, and duplicate normalized questions must never silently overwrite an existing answer.
Validation and forms
- Validate all mutation inputs on the server with the shared Zod schema.
- Client validation improves usability but is not a security boundary.
- Keep company and role required.
- Accept only HTTP(S) job URLs, valid emails, real ISO dates, non-negative salaries, three-letter uppercase currencies, and
salaryMin <= salaryMax. - Show clear accessible field errors and a non-field server error.
- Label controls and preserve keyboard/focus behavior.
UI
- Preserve the current restrained slate/blue visual direction and responsive layout.
- Prefer small shadcn/ui-style primitives over a large component abstraction.
- Include empty, loading, success, validation-error, and server-error states for new workflows.
- Confirm destructive actions and make their target explicit.
Quality
Before handing off a code change, run:
npm run format
npm run lint
npm run typecheck
npm test
npm run build
For schema changes, also run:
npx prisma validate
npm run db:generate
Run database migrations and seed when Docker/PostgreSQL is available. Never claim a check passed unless it ran successfully. Report environmental blockers separately from code failures.
Tests should cover business behavior, validation boundaries, owner scoping, transactions/status history, and practical query behavior. Do not add assertions that merely increase the test count.
Documentation
- Keep
.env.example, Docker Compose, package scripts, migrations, README setup steps, and actual behavior aligned. - Update README architecture and deferred-feature sections when either changes.
- Handoffs must include exact launch commands, validation results, remaining issues, and a bounded recommended next task.
Browser extension
- Keep extension runtime code isolated under the
extension/npm workspace; the Next.js application must not import it. - Preserve explicit user activation, review-before-fill, top-level-document scope, and the permission set
activeTab,scripting,storage, andsidePanel. Do not add persistent host permissions without a separately reviewed requirement. - Keep DOM detection and native-control filling in the runtime-injected content bundle, coordination/transient state in the service worker, and React UI in the side panel.
- Keep mapping pure, deterministic, versioned, and provider-independent. Phase 5 question normalization semantics must remain aligned.
- Production extension builds must use an empty data provider until a secure pairing phase is explicitly authorized. Never copy real profile, saved-answer, resume, authentication, or page data into extension fixtures.
- Never submit forms, click navigation, fill excluded sensitive fields, run remote code, make telemetry/network requests, or persist scanned values.
- Phase 7 pairing uses only
http://localhost:3000andhttp://127.0.0.1:3000, fixed versioned routes, and optional host permissions requested for one selected origin from the Connect gesture. Keep productionhost_permissionsempty and reject unexpected manifest permissions. - Keep raw extension bearer tokens and the random installation identifier only in trusted
storage.local; keep canonical snapshots only in worker memory or trustedstorage.session. Content scripts and host pages must never receive credentials or a complete snapshot. - Authenticate extension APIs only with hashed, expiring, individually revocable opaque bearer tokens. Never share Auth.js cookies/JWTs, place tokens in URLs/DOM/logs, store raw credentials in PostgreSQL, reflect arbitrary CORS origins, or accept arbitrary proxy destinations.
- Keep the live snapshot owner-scoped and minimal: no IDs unless operationally required, normalized-question keys, applications, analytics, protected demographics, résumé binaries/text/keys, passwords, or sessions. Preserve nullable and user-authored values and deterministic ordering/revisions.
- Pairing approval and one-time token issuance must remain transactional and idempotent. Expired, denied, consumed, malformed, or secret-mismatched requests issue nothing. A lost successful poll response requires a fresh pairing; do not persist raw tokens for retry.
- Disconnect/revocation must clear live scan proposals and transient snapshots; authoritative 401 responses clear the credential. Do not silently fall back to demo data after pairing.
- Phase 8 local AI may classify only eligible deterministic
UNMAPPEDfield meaning after a separate user click. All Ollama calls originate in a server-only module and use exactlyhttp://127.0.0.1:11434orhttp://localhost:11434; never add an Ollama extension permission, cloud provider, arbitrary proxy URL, or broadOLLAMA_ORIGINS. - Send only bounded field labels, safe headings/options/control metadata, ephemeral IDs, and the canonical-key allowlist to local AI. Never send existing values, profile/saved-answer values, résumé or job-description content, page HTML/screenshots, credentials, protected demographics, excluded controls, or complete snapshots.
- Deterministic mappings and exclusions remain authoritative before and after AI. AI returns canonical keys only; every AI suggestion is transient, visibly labeled, review-required, unselected, cancellable/discardable, and cleared on disconnect or stale navigation. Never generate an answer or submit a form.
- Phase 9 classifier evaluation uses only the versioned generated non-personal corpus, never runs automatically, never stores prompts or raw responses, and never changes the selected production model. Mandatory safety thresholds are not negotiable based on model size.
- Keep Ollama health/model caches short-lived and refreshable, provider timeouts and response sizes bounded, and the local-provider circuit breaker per-process, bounded, and keyed only by loopback provider plus model. Provider failure must never remove deterministic proposals.
- Phase 10 grounded answers require an explicitly selected owner-scoped résumé, bounded deterministic retrieval, request-scoped opaque evidence references, strict post-generation claim validation, and both classifier and grounded-answer suitability gates. Complete résumés, snapshots, instruction collections, prompts, and raw model responses never enter content scripts.
- Structured instructions replace hidden model memory. Persistent changes require explicit confirmation and owner scoping; session instructions stay transient. Equal-precedence conflicts stop generation, and no instruction can override facts, deterministic exclusions, or the no-submission boundary.
- Generation defaults to
MANUALand filling toREVIEW_EVERYTHING. Automatic modes never fill consequential or excluded fields and the trusted worker must recheck scan freshness, suitability, grounding, warnings, manual changes, and automation settings before sending one final value to the content script.