ProjectHub Recruiter Alpha
Answers from Bradley Matera's verified professional information and can explain Scout's own runtime. The public widget is the concrete production use of Scout today.
These docs describe the Scout engine as it exists inside ProjectHub Recruiter Alpha today. They separate released production behavior from integrated development behavior and historical records. Source code and current runtime configuration take precedence when older prose describes a superseded model or path.
Scout is the intelligence and orchestration layer currently used by ProjectHub Recruiter Alpha. The public implementation combines deterministic query/state/evidence handling with a generative language layer and post-generation factual validation.
@cf/meta/llama-3.1-8b-instruct-fast for normal generation, while retrieval, session handling, evidence selection, tools, validation, telemetry, and persistence run in ProjectHub's backend process.ProjectHub has moved quickly enough that some checked-in reports describe earlier Ollama-only phases. This documentation uses the following precedence when sources disagree:
data/scout-runtime-knowledge.json.develop@e74ac22b; PR #32 promoted the exact tree 92b4d149 to master@7d011708. The released runtime includes structured semantic query plans, canonical identity precedence, answer obligations/completeness checks, proposition-scoped validation, and empty-KB portability coverage. Deterministic verification reached 1452/1452 tests and Recall@6 1.000.b071e4e4 and protected integration 4f5ee971 have different Git ancestry but the same Git tree a0066cc8. ProjectHub-dev records 4f5ee971 as its staging source. PR #29 used an ancestry-preserving release commit rather than forcing the conflicting direct develop→master PR #25.
Answers from Bradley Matera's verified professional information and can explain Scout's own runtime. The public widget is the concrete production use of Scout today.
Empty/no-KB behavior, canonical identity resolution, structured semantic planning, and portable entity/property handling are now part of the released runtime. Formal domain-package contracts, reusable workflow packages, and self-service installation remain productization work.
The architecture is being pushed toward portability, but these docs describe the implementation that can be inspected and tested now rather than the intended end state.
The released browser widget is a single JavaScript artifact hosted on GitHub Pages. Embedding it loads the ProjectHub UI and connects recruiter-style questions to the ProjectHub backend.
<script src="https://bradleymatera.github.io/ProjectHub/ProjectHub.js"></script>
git clone https://github.com/BradleyMatera/ProjectHub.git cd ProjectHub npm ci npm test npm run eval-retrieval npm run build node --check server-gemini.js
Scout does not send an entire knowledge base to a model and hope the model behaves. Deterministic backend stages prepare the request and evidence first; the model is used for language generation inside that boundary.
/api/chat is rate-limited by IP. JSON bodies are capped by Express and messages are bounded before deeper processing.Verified application knowledge is flattened into searchable RAG chunks. Okapi BM25 scores those chunks locally. Context-bearing questions can combine literal, expanded, and rewritten query views using Reciprocal Rank Fusion.
Lexical relevance scoring over bundled verified knowledge. No hosted vector database is required for the current corpus.
Normalizes input, protects technology terms, corrects common typos, classifies intent, and can rewrite follow-ups.
Contextual follow-ups can fuse multiple BM25 rankings; standalone queries can retain direct BM25 when it ranks better.
npm run test:retrieval npm run eval-retrieval
The checked-in 40-query golden set has a documented Recall@6 of 1.000 and MRR@6 of 0.971. CI independently rejects a retrieval run if Recall@6 falls below 0.90. Treat the benchmark as a scoped retrieval measurement, not as an end-to-end answer-accuracy percentage.
The current runtime does not rely only on raw transcript text. It maintains structured session state so follow-ups can refer to previously discussed projects, roles, comparisons, names, and unresolved references.
| State | Purpose |
|---|---|
| Recent turns | Five recent compact/sanitized user and assistant turns are used for bounded conversational context. |
| Topic / intent | Tracks what the conversation is about so short follow-ups are not interpreted in isolation. |
| Projects / comparisons | Maintains active and comparison entities for phrases such as “that project” or “the other one.” |
| Job / role context | Preserves the requested role or job context for fit/evidence questions. |
| User profile state | Conversation-control intents can commit visitor name/profile state before generation. |
| Unresolved references | Allows the runtime to distinguish a missing referent from evidence that actually says “no.” |
feat/generic-conversation-sets@cddb3bc (server-owned discourse frames, generated clarification, CLARIFICATION control mode) shipped through PR #31 and is in production master@7d011708.A response contract describes what an answer is allowed to mean before the final language is generated. This is separate from style or phrasing.
Open-world claims are not supposed to become false simply because the knowledge base does not contain evidence for them.
Captures answer direction such as YES, NO, MIXED, FIT, PARTIAL_FIT, NOT_FIT, or UNKNOWN where applicable.
Ranks relevant facts, identifies required entities, and carries important limitations the answer must preserve.
Constrains seniority, unsupported relationships, false premises, and other claims that must not survive generation.
The current tool layer gathers structured evidence. It does not expose arbitrary shell execution or write access to external business systems.
| Tool | Current purpose |
|---|---|
search_portfolio | Search verified projects, experience, skills, and certifications for recruiter evidence. |
get_project | Return verified details for one named project. |
compare_projects | Compare two to four verified projects by purpose, technology, category, and public URL. |
match_role | Match a role or pasted job description against verified skills, experience, projects, and gaps. |
get_candidate_profile | Return a selected verified profile section without exposing private/sensitive profile data. |
get_skill_evidence | Classify evidence for whether a technology or skill is directly supported, adjacent, or unknown. |
build_recruiter_brief | Assemble a structured recruiter-facing brief from verified data. |
The generative boundary lives behind lib/local-model-router.js. Application orchestration calls the router rather than coding directly against one provider.
| Path | Status | Behavior |
|---|---|---|
| Cloudflare Workers AI | Production | Normal production generation using @cf/meta/llama-3.1-8b-instruct-fast. |
| Ollama | Dev / eval | Current local development/evaluation model is qwen2.5:1.5b. |
| Cloudflare → Ollama fallback | Gated | Disabled by default when Cloudflare is primary. Requires explicit fallback enablement and SCOUT_OLLAMA_QUALIFIED=true. |
| Browser WebGPU generation | Experimental | Client packet/validation routes exist for experimentation; browser-side generation is not the production primary path. |
The current provider adapter records a Workers AI free allocation of 10,000 neurons/day. That is a shared account allocation, not a per-user allowance. The adapter recognizes allocation exhaustion and does not silently switch to paid-only models.
0 with top-p 0.9. The Cloudflare adapter also defaults to temperature 0. Cloudflare-primary Ollama fallback remains disabled by default and requires explicit fallback enablement plus SCOUT_OLLAMA_QUALIFIED=true.@cf/meta/llama-3.1-8b-instruct-fast. Cloudflare does not publish a token-to-neuron rate for that exact identifier on its current pricing table. Token-derived neuron usage is therefore unknown / unverified unless the provider supplies actual neuron usage. The published 4,119 / 34,868 rates belong to @cf/meta/llama-3.1-8b-instruct-fp8-fast.Scout checks the generated reply against retrieved/structured evidence and the response contract. The validator is responsible for rejecting unsupported factual content, not for making the prose sound nicer.
Checks named entities and numeric claims against the evidence supplied to the answer path.
Prevents a real technology from being attached to the wrong project or experience merely because both exist somewhere in the corpus.
Checks whether generated meaning matches TRUE/FALSE/UNKNOWN evidence and expected answer direction.
Rejects inflated titles, unsupported experience levels, and prohibited claim patterns.
Invalid primary generation can be sent through a constrained repair path. Repair is still validated before acceptance.
If reliable generative output cannot be produced, the server can return an INFERENCE_UNAVAILABLE / TECHNICAL_ERROR result rather than inventing a factual answer.
proseSource | Meaning |
|---|---|
| MODEL_GENERATION | The visible conversational answer was generated by the configured model from bounded context and passed the runtime checks. |
| DIRECT_KB | Canonical verified knowledge supplied a direct answer path without model-authored prose for that response. |
| TECHNICAL_ERROR | The infrastructure/generation path could not produce a reliable answer. This is an error state, not evidence about the user or domain. |
The current ProjectHub frontend is deliberately lightweight: vanilla JavaScript source modules are assembled into one embeddable ProjectHub.js artifact. The widget owns UI/session behavior; the backend remains authoritative for knowledge retrieval, evidence, inference, validation, and structured state.
data.js · utils.js · logic.js · ui.jsThe committed single-file artifact is checked in CI to make sure it matches these source modules.
The public widget is served from the ProjectHub GitHub Pages deployment; staging uses the ProjectHub-dev mirror.
The production ProjectHub backend is reachable at https://projecthub-chat.bradleymatera.dev. These endpoints describe the current application implementation; they are not a public multi-tenant API-key/SLA product.
| Method / route | Purpose |
|---|---|
GET / | Basic service identity/status. |
GET /health/live | Liveness probe. Confirms the process is alive. |
GET /health/ready | Readiness probe. Returns ready only after the model path and knowledge are verified/loaded. |
GET /health | Detailed runtime/build/provider/state/telemetry snapshot. |
POST /api/chat | Main conversation endpoint used by the widget. |
POST /api/client-packet | Experimental browser-local mode: prepares a client-safe evidence packet and temporary run ID. |
POST /api/client-validate | Experimental browser-local mode: validates a browser-generated answer against the same server-held evidence. |
GET /api/chat-log | Operational chat-log view used by current backend diagnostics. |
{
"message": "Which project best demonstrates AWS experience?",
"sessionId": "per-tab-session-id",
"history": [
{
"user": "What is Bradley strongest at?",
"assistant": "..."
}
]
}{
"ok": true,
"reply": "...",
"provider": "cloudflare",
"model": "@cf/meta/llama-3.1-8b-instruct-fast",
"proseSource": "MODEL_GENERATION",
"pipeline": ["..."],
"contract": {
"intent": "...",
"directAnswer": "...",
"factState": "..."
},
"agent": {
"retrievalCandidates": [],
"selectedEvidence": [],
"generationCalls": []
},
"sessionMemory": {
"turns": 5,
"retained": true
}
}ok, proseSource, provider/model, contract, and failure fields.The runtime exposes enough metadata to distinguish retrieval, generation, validation, model/provider use, build provenance, and usage accounting.
| Signal | What it tells you |
|---|---|
| Build source | Repository, branch, and commit recorded by deployment/build provenance. |
| Provider / model | Which inference backend/model was configured or actually called. |
| Generation calls | Attempt index/type, success, accepted state, model, tokens, actual neurons when supplied, and an exact-model estimate only when a verified rate exists. |
| Retrieval candidates | Evidence candidates considered before final selection. |
| Selected evidence | The smaller evidence set passed into the RAG synthesis path. |
| Validation | Validator verdict/outcome and repair/failure information. |
| Latency | Provider and total request timings used to enforce/inspect the response contract. |
| Cost ledger | Optional accounting of LLM-adjacent events, token usage, provider-reported neuron usage when available, exact-model estimates when verified, unknown/unpriced markers when not verified, and response egress when enabled. |
curl https://projecthub-chat.bradleymatera.dev/health curl https://projecthub-chat.bradleymatera.dev/health/live curl https://projecthub-chat.bradleymatera.dev/health/ready
Production secrets are not committed. The table below documents the important configuration surfaces visible in the current source. Defaults can differ between development examples and deployed production environment values.
| Variable | Meaning | Current/source default |
|---|---|---|
PORT | Express port. | 3000 |
HOST | Bind host. | 127.0.0.1 |
KNOWLEDGE_FILE | Bundled knowledge JSON path. | data/recruiter-knowledge.json |
ALLOWED_ORIGINS | Comma-separated browser origins accepted by CORS. | Environment-specific |
RATE_LIMIT_MAX | Maximum chat requests per minute per IP. | 20 |
USE_BM25_RETRIEVAL | Enable local BM25 retrieval. | Enabled unless set to false |
SCOUT_AGENT_MODE | Selects lite/full/legacy execution mode. Release work targets lite mode. | Deployment-configured |
SCOUT_INFERENCE_PROVIDER | cloudflare, ollama, or auto. | auto in router |
CLOUDFLARE_ACCOUNT_ID | Workers AI account ID. | Required for Cloudflare path |
CLOUDFLARE_API_TOKEN | Workers AI API token. | Required for Cloudflare path |
CLOUDFLARE_MODEL | Workers AI model name. | @cf/meta/llama-3.1-8b-instruct-fast |
OLLAMA_URL | Local/container Ollama endpoint. | http://localhost:11434 |
OLLAMA_MODEL | Local development/eval model. | qwen2.5:1.5b in router |
SCOUT_OLLAMA_PRODUCTION_FALLBACK_ENABLED | Explicitly opts Cloudflare-primary runtime into Ollama emergency fallback. | Disabled |
SCOUT_OLLAMA_QUALIFIED | Second gate required before production Ollama fallback can be used. | Disabled |
REQUEST_DEADLINE_MS | End-to-end request deadline. | 15000 |
GEN_TIMEOUT_MS | Generation timeout inside the request envelope. | 12500 |
COST_TRACKER | Enable cost/usage ledger persistence. | Off unless true |
FEATURE_PREVIEW_ENABLED | Expose the private preview static route on the preview environment. | Off unless true |
PORT=3000 HOST=127.0.0.1 SCOUT_AGENT_MODE=lite SCOUT_INFERENCE_PROVIDER=cloudflare CLOUDFLARE_ACCOUNT_ID=your-account-id CLOUDFLARE_API_TOKEN=your-api-token CLOUDFLARE_MODEL=@cf/meta/llama-3.1-8b-instruct-fast REQUEST_DEADLINE_MS=15000 GEN_TIMEOUT_MS=12500 USE_BM25_RETRIEVAL=true RATE_LIMIT_MAX=20
ollama pull qwen2.5:1.5b # .env SCOUT_AGENT_MODE=lite SCOUT_INFERENCE_PROVIDER=ollama OLLAMA_URL=http://127.0.0.1:11434 OLLAMA_MODEL=qwen2.5:1.5b REQUEST_DEADLINE_MS=15000 USE_BM25_RETRIEVAL=true
node server-gemini.js curl http://127.0.0.1:3000/health/live curl http://127.0.0.1:3000/health/ready curl http://127.0.0.1:3000/health
.env. Cloudflare account IDs/tokens and any other secrets belong in the deployment environment or local ignored files.The repository includes a Docker path intended to make backend/inference testing reproducible without relying on whatever happens to be installed on the host.
docker compose up --build -d curl http://localhost:3000/health docker compose run --rm test-runner npm test
deploy-gcp.sh path is legacy and is intended to be replaced by qualified Docker image deployment. Do not describe the migration as already complete.The documentation avoids turning one historic score into a general quality claim. The useful part is the checked-in test/eval surface and the commands needed to reproduce a result.
| Command | Coverage |
|---|---|
npm test | Node unit test suite under test/**/*.test.js. |
npm run test:retrieval | BM25, query-understanding, and RRF unit tests. |
npm run eval-retrieval | 40-query golden retrieval evaluation. |
npm run eval:local-api | API acceptance/evaluation runner against a configured local target. |
npm run eval:scout | Scout evaluation harness. |
npm run eval:tools | Tool-selection evaluation. |
npm run eval:conversation | Conversation behavior evaluation. |
npm run eval:production-conversations | Python production-conversation regression harness. |
npm run build | Vite/analytics build freshness. |
node --check server-gemini.js | Server syntax check. |
ProjectHub.js bundle freshness against source modules.| September 5 released-tree verification | Recorded result | Scope |
|---|---|---|
| Local test suite | 1019/1019 | Release-hardening tree; zero skipped in PR evidence. |
| Retrieval Recall@6 | 1.000 | Released-tree retrieval verification. |
| Retrieval MRR@6 | 0.942 | Released-tree retrieval verification. |
| Phase 7/8 live gate | 94/132 turns · 21/33 conversations | Dated pre-release run at 4d39995. |
| Inference-unavailable outcomes | 14/38 remaining failures | Observed failure category in that dated run; not proof of external root cause. |
| Environment | Source | Frontend / backend |
|---|---|---|
| Feature preview | Clean feat/* branch | SSH-tunneled private preview; loopback-only development service. |
| Development staging | ProjectHub:develop mirrored to ProjectHub-dev:main | bradleymatera.github.io/ProjectHub-dev/ + dev.projecthub-chat.bradleymatera.dev |
| Production | ProjectHub:master | bradleymatera.github.io/ProjectHub/ + projecthub-chat.bradleymatera.dev |
develop.develop; required CI must pass.master. The September 5 release used a master-parented commit carrying the qualified develop tree.npm test npm run build node --check server-gemini.js git diff --check # Retrieval / conversation changes npm run eval-retrieval PROJECTHUB_API_URL=http://127.0.0.1:<port> npm run eval:local-api python3 test-production-conversations.py \ --url http://127.0.0.1:<port>/api/chat \ --delay 2.5
develop@e74ac22b; PR #32 promoted the exact tree 92b4d149 to master@7d011708. ProjectHub-dev main 201beb9c records e74ac22b as its staging source.b071e4e4 and protected integration 4f5ee971 have different Git ancestry but the same Git tree a0066cc8. ProjectHub-dev records 4f5ee971 as its staging source. PR #29 used an ancestry-preserving release commit rather than forcing the conflicting direct develop→master PR #25.
feat/generic-conversation-sets@cddb3bc (server-owned discourse frames, generated clarification, CLARIFICATION control mode) shipped through PR #31 and is in production master@7d011708.| Symptom | Check first | Likely area |
|---|---|---|
/health/ready returns 503 | Inspect modelVerified and knowledgeReady. | Provider/model health or knowledge load. |
INFERENCE_UNAVAILABLE | Inspect provider/model, generation attempts, deadline, and Cloudflare/Ollama health. | Generation/provider path. Do not treat as a factual answer. |
| Cloudflare 429 / allocation error | Inspect provider error type and daily neuron usage. | Free allocation/rate capacity. |
| Correct topic, wrong fact relationship | Inspect selected evidence + grounding validator result. | Evidence selection, relationship/provenance validation. |
| Follow-up loses referent | Inspect session state, rewritten query, and recent-turn input. | Conversation resolver / query understanding. |
| “No” when evidence is merely absent | Inspect factState, directAnswer, response policy, and contract. | Open-world UNKNOWN handling. |
| Retrieval quality drops | Run npm run eval-retrieval and inspect changed query/chunk logic. | BM25, query understanding, RRF, knowledge chunks. |
| Widget changes not reflected | Run build/CI bundle freshness check. | ProjectHub.js source/artifact mismatch. |
| Staging looks like production | Inspect staging source marker and routing rules. | Mirror/deployment provenance. |
npm test npm run eval-retrieval node --check server-gemini.js curl http://127.0.0.1:3000/health curl http://127.0.0.1:3000/health/ready
data/scout-runtime-knowledge.json is still marked lastVerified: 2026-08-21 and retains the superseded sentence assigning 4,119 / 34,868 to Scout's normal -fast model. This site treats that sentence as stale and follows executable provider/accounting code instead.
| Path | Responsibility |
|---|---|
server-gemini.js | Express API, request lifecycle, deadlines, knowledge loading, state integration, response shaping, telemetry and operational routes. |
lib/rag-chunks.js | Flattens verified knowledge into retrieval chunks. |
lib/query-understanding.js | Normalization, typo handling, protected terms, intent/context rewrite. |
lib/bm25.js | Okapi BM25 lexical retrieval. |
lib/rrf.js | Contextual reciprocal-rank fusion. |
lib/session-state.js | Structured server-owned conversation state. |
lib/response-policy.js | Conversation-control and substantive response policy classification. |
lib/response-contract.js | Intent, fact state, polarity, boundaries, claim ceilings and semantic answer constraints. |
lib/agent-tools.js | Allowlisted read-only evidence tools. |
lib/rag-agent.js | RAG-first generation, evidence selection, tool enrichment, repair and generation accounting. |
lib/local-model-router.js | Inference provider abstraction and Cloudflare/Ollama routing/fallback gates. |
lib/cloudflare-provider.js | Workers AI REST adapter, model restrictions, usage/neuron accounting and provider errors. |
lib/grounding-validator.js | Grounding, relationship, provenance, semantic and overclaim validation. |
data/scout-runtime-knowledge.json | Current production-facing facts about Scout's runtime/model/provider/cost controls. |
data/eval-golden.json | Retrieval golden set used by the checked-in evaluator. |
.github/workflows/test.yml | Automated build, audit, syntax, retrieval, knowledge, secret and staging checks. |
PROJECTHUB-DEVELOPMENT-AND-RELEASE-SPEC.md | Canonical release environments, promotion sequence, acceptance and rollback process. |