Skip to content

NextRole

Source catalog · Knowledge graph

Facts

FactValue
Statusdormant
Hosting platformother
Repositoryhttps://github.com/meta4m/NextRole
Tech stacklanguage: javascript, runtime: google-apps-script, cli: node, data: google-sheets, ai: gemini-api, tooling: clasp
Tagsjob-search, google-workspace, apps-script, gemini, ai, productivity, privacy
Last audited2026-09-15
Upstream dependenciesNone declared
Downstream dependenciesNone declared

Secrets manifest

Key names and metadata only. Encrypted records are available in this project’s vault below.

KeyDescriptionEnvironmentsRequired
GEMINI_API_KEYGoogle Gemini API key used by the Apps Script GeminiProvider (stored via the ‘NextRole > Set Gemini API Key’ menu into Apps Script Properties) and by the local Node CLI via the GEMINI_API_KEY environment variable; without it all AI operations throwproduction, developmentYes

Overview

Project Overview: NextRole

1. Executive Summary

  • Mission: A zero-infrastructure, AI-powered job search workflow — capture job postings, normalize them with Gemini, score matches against a personal profile and rubric, review/adjust the resume, draft tailored materials, and send recruiter emails only after explicit approval.
  • Target Audience: A few dozen trusted family/friends of the operator (per docs/nextrole-plan.md), each running the workflow inside their own Google account; the operator is the first user.
  • Primary Maintainer: The operator (meta4m) — private solo project.

2. Current Status & Roadmap

  • Lifecycle State: dormant — v0.1.0 scaffold completed in a single session (2 commits on 2026-07-09: initial scaffold + deployment guide) with no commits in the ~10 weeks since.
  • The Apps Script implementation and the mirror-image local Node CLI both appear complete for v1; docs/deploy.md notes the one-time interactive Google OAuth steps remain for whoever deploys.
  • The plan doc defers the optional central control plane (“Default to no central dependency for v1”) and future providers beyond Gemini; no in-repo roadmap beyond v1.

3. Core Capabilities

  • Workbook setup: NextRole > Setup Workbook creates the six Sheet tabs (Instructions, Profile, Jobs, Score Rubric, Applications, Activity Log), Gmail labels, and the Drive root folder.
  • Job capture: manual paste, Gmail-label capture of recruiter/referral emails, and an optional token-gated bookmarklet that POSTs page URL + selected text to an Apps Script web app.
  • AI pipeline (Gemini default, gemini-1.5-flash): normalize → score against a 10-criterion weighted rubric (shortlist threshold 75) → resume review → tailored resume/cover-letter/outreach drafts, all with strict JSON schema validation before anything is written to Sheets.
  • Apply with approval: job-board applications stay manual; recruiter/referral emails become Gmail drafts that are sent only after the user marks them Approved.
  • Follow-up tracking: Calendar reminders and Gmail label-driven status updates.
  • Local Node CLI (npm run jobsearch): the same normalize/score/review/draft pipeline against a local .jobsearch/ JSON store, with MOCK_AI=true for keyless testing.

4. Key References

  • Repository: meta4m/NextRole
  • Production URL: none — “production” is each user’s Google account (Sheet-bound Apps Script pushed via clasp); there is no public URL or central server.
  • Architecture Docs: architecture.md · Deployment Guide: deployment.md

Architecture

Architecture & System Design: NextRole

1. System Topology

graph TD
User[User in Google Sheet] -->|custom NextRole menu| GAS[Apps Script project<br/>bound to the Sheet]
GAS --> Sheets[Google Sheets<br/>6 workflow tabs]
GAS --> Drive[Google Drive<br/>NextRole folder + Docs]
GAS --> Gmail[Gmail<br/>labels, drafts, approved sends]
GAS --> Calendar[Google Calendar<br/>follow-up reminders]
GAS -->|UrlFetchApp, key from Properties| Gemini[Gemini API<br/>generativelanguage.googleapis.com]
BM[Browser bookmarklet] -->|POST url + selected text, token-gated| WebApp[Apps Script web app doGet/doPost]
WebApp --> Sheets
CLI[Local Node CLI<br/>cli/index.js] -->|fetch, GEMINI_API_KEY env| Gemini
CLI --> Store[(.jobsearch/ local JSON store<br/>profile, jobs, applications, rubric)]

2. Core Components & Subsystems

  • src/Code.js — menu entry points, “Set Gemini API Key” prompt, browser-capture bookmarklet builder, local operational-health sync.
  • src/Config.js — frozen constants: app metadata, tab names, job/approval statuses, sheet headers, default 10-criterion score rubric, Script Properties keys.
  • src/Sheets.js — workbook setup and table read/write helpers (rows ↔ objects by header).
  • src/AiProvider.js / src/GeminiProvider.js — provider-neutral interface with per-operation JSON schemas, and the Gemini adapter (v1beta .../generateContent, temperature 0.2, responseMimeType: application/json, JSON extraction + validation).
  • src/Jobs.js — normalize/score/review/draft workflows over selected rows, plus the web-app doGet/doPost capture endpoint with capture-token validation.
  • src/GmailCalendar.js / src/DriveDocs.js — Gmail labels, drafts, approved sending, follow-up reminders; Drive folders, Doc creation, resume loading.
  • cli/ — Node mirror of the pipeline (index.js commands, ai.js prompts/schemas/mock mode, store.js .jobsearch/ JSON files) for local testing without Google.
  • src/appsscript.json — V8 runtime; least-privilege OAuth scopes (spreadsheets.currentonly, documents, drive.file, gmail.modify, calendar.events, external_request, scriptapp).

3. Data Flow & Storage Contracts

  • Canonical database: the user’s Google Sheet — tabs Instructions, Profile, Jobs, Score Rubric, Applications, Activity Log; job status pipeline Captured → Needs Review → Scored → Shortlisted → Materials Drafted → Ready to Apply → Applied → Follow Up → Interviewing → Rejected → Archived.
  • Documents: resumes, tailored materials, and review reports are Google Docs under the NextRole Drive folder; Profile.base_resume_doc_id points at the base resume.
  • Secrets/IDs: Apps Script Properties — GEMINI_API_KEY, DEFAULT_AI_PROVIDER, DEFAULT_AI_MODEL, DRIVE_ROOT_FOLDER_ID, SPREADSHEET_ID, CAPTURE_TOKEN (auto-generated per user by Setup Workbook; never stored in Sheet cells).
  • CLI store: gitignored .jobsearch/*.json (profile, jobs, applications, rubric). No server-side storage anywhere; v1 has no central dashboard (“Sync Operational Health” logs locally only).

4. Architectural Decision Records (ADRs)

ADR-01: Google Workspace-first, zero infrastructure
  • Context: Free, low-maintenance tool for a few dozen family/friends; private job/resume data must stay user-owned.
  • Decision: The entire workflow runs as a Sheet-bound Apps Script inside each user’s Google account; no central server in v1.
  • Consequences: $0 hosting and strong privacy defaults; constrained by Apps Script quotas, and features needing a backend (shared keys, central health) are deferred.
ADR-02: Pluggable AI provider with strict JSON schema validation
  • Context: Prompts and response shapes must not leak provider-specific logic into workflows.
  • Decision: AiProvider interface + per-operation JSON schemas; Gemini is the first adapter; every AI result is validated before touching Sheets, failures log to Activity Log and leave status unchanged.
  • Consequences: New providers (OpenAI, Anthropic, local) are additive; schema drift degrades gracefully instead of corrupting the Jobs tab.
ADR-03: Human-in-the-loop apply model
  • Context: Automated job-board submission is risky/out of scope; emails must never send unreviewed.
  • Decision: Job boards are always applied to manually; recruiter emails are drafted in Gmail and sent only when approval_status is Approved.
  • Consequences: Trustworthy by construction; full automation of applications remains explicitly out of scope.
ADR-04: Dual runtime — Apps Script plus a local Node CLI
  • Context: Iterating on prompts inside Apps Script is slow and needs Google auth.
  • Decision: cli/ reimplements the same operations (shared prompt/schema text, mock mode) against a local JSON store.
  • Consequences: The AI pipeline is testable offline with MOCK_AI=true; the cost is a second implementation that must be kept in sync manually.

Deployment

Deployment & Operational Runbook: NextRole

1. Hosting & Environments

EnvironmentPlatformURL / EndpointDeploy Trigger
ProductionGoogle Apps Script (Sheet-bound, per user)Each user’s Google Sheet; web-app URL only if browser capture is deployedManual npm run clasp:push
Local devNode.js CLI.jobsearch/ local store, no serverN/A

There is no public production URL and no central server — “deployment” means pushing Apps Script source into a user’s Google account.

2. Prerequisites & Toolchain

  • Node.js + npm (only for clasp and the local CLI; @google/clasp is the sole devDependency).
  • A Google account that will own the Sheet, Drive folder, Gmail labels, and Calendar events.
  • A Gemini API key for real AI operations (gemini-1.5-flash default, overridable via Profile.ai_model).

3. Local Development Setup

Terminal window
git clone https://github.com/meta4m/NextRole.git
cd NextRole
npm install
npm run validate # node --check on all src/ and cli/ files
MOCK_AI=true npm run jobsearch -- setup # local store, no API key needed
MOCK_AI=true npm run jobsearch -- normalize
MOCK_AI=true npm run jobsearch -- score
export GEMINI_API_KEY="..." # for real AI calls
npm run jobsearch -- job add "https://example.com/job" "Job description text..."

4. Environment & Secrets Provisioning

Refer to spec.yml for declared secret keys.

  • Secret Injection: Retrieve ciphertext from the 2brain vault and decrypt locally into .env.local.
  • Apps Script runtime: store the key via the Sheet menu NextRole > Set Gemini API Key — it lands in Apps Script Properties, never in Sheet cells.
  • Local CLI: export GEMINI_API_KEY in the shell (or use MOCK_AI=true).
  • Note: CAPTURE_TOKEN (browser-capture gate) is auto-generated per user by Setup Workbook and is not vault-provisioned — keep the generated bookmarklet private.

5. Deployment Commands

Terminal window
npx clasp login # one-time interactive Google OAuth
npm run clasp:create # create Sheet + bound Apps Script project (.clasp.json, gitignored)
npm run clasp:push # upload src/* to Apps Script
# Then in the Sheet: NextRole > Setup Workbook, > Set Gemini API Key, fill Profile tab
# Optional, for browser capture: Apps Script editor > Deploy > New deployment > Web app (Execute as: Me)
# Update workflow after pulling new code:
git pull && npm run validate && npm run clasp:push

6. Verification & Health Checks

  • npm run validate passes (syntax check on all src/ and cli/ files).
  • CLI smoke: MOCK_AI=true npm run jobsearch -- normalize && MOCK_AI=true npm run jobsearch -- score completes against the local store.
  • In-Sheet manual validation (from docs/setup.md): paste a job description → Normalize Selected Jobs → Score Selected Jobs → set base_resume_doc_id → Review Resume For Selected Jobs → Draft Materials → verify Docs appear under the Drive root → Create Gmail Draft, approve, Send Approved Drafts.
  • Check the Activity Log tab for per-action errors; NextRole > Sync Operational Health prints counts (local only in v1).

7. Incident Response & Rollback

  • Rollback: git checkout <good-sha> && npm run clasp:push — pushes fully replace the Apps Script source; Sheet/Drive/Gmail data is untouched by pushes.
  • Bad AI output: schema validation failures are logged to Activity Log with job status left unchanged; re-run the menu action or switch ai_model/provider.
  • Quota exhaustion: Apps Script/Gmail quotas pause automation (drafts stay unsent); process rows in smaller batches via menu selection.
  • Compromised capture token: re-run Setup Workbook to regenerate CAPTURE_TOKEN and re-create the bookmarklet; old token stops validating.

Project vault

Cloudflare Access authorization and your passphrase are required to retrieve and decrypt stored values.

Client-Side Encrypted Secret Vault

Zero-knowledge architecture. Secrets are encrypted client-side using Web Crypto AES-256-GCM before leaving this browser tab. Edge databases store only ciphertext, IV, and salt.

Encrypted Records for nextrole (0)

Encrypted records have not been loaded.

Add / Rotate Encrypted Secret