Conversation
added 27 commits
June 26, 2026 18:07
…ed tracks) Standalone Fumadocs static-export app at docs-site/ (mirrors the sockguard/docs shell). Four sections: Getting Started, Guides, Advanced, Reference (20 content pages + index), covering clone-canonical install, the agent contract, the data model, privacy boundaries, the skills catalog, and BUSL-1.1 licensing. Builds to a static export; not yet deployed. Standalone (own package-lock), not a root workspace.
vercel.json pins framework=nextjs so `vercel build` detects the static export (a bare project defaults the output dir to public/ and fails). Plus the Vercel-added .gitignore entries so .vercel/ and .env* never get tracked.
Matches the sockguard/drydock convention: docs live under the marketing site, not a separate subdomain/project. docs-site now builds with basePath:/docs + trailingSlash (directory-style export so leaf pages resolve as clean static URLs), and website's build:docs-content prebuild step copies the export into website/public/docs/ so the single rolester-website deploy serves /docs. Drops docs-site/vercel.json (no standalone rolester-docs Vercel project or docs.rolester.codeswhat.com subdomain anymore). public/docs is gitignored (generated by the build).
…exit The Sankey branched Awaiting straight into both Going stale and Ghosted as siblings, so a ghosted app read as a direct Awaiting exit (tooltip "Awaiting → Ghosted") even though every ghosted app was stale first. The Ghosted node was also unlabeled and got shoved under the 1st-round node, so its faded band drooped down into nothing. - 🔄 route the decay band forward as a progression: Awaiting → Going stale carries every pre-response quiet app, then the fully-ghosted subset continues Going stale → Ghosted. "Going stale" is now the cumulative quiet state (stale + ghosted), so its count includes the apps that went on to ghost, matching the round chain, which is already cumulative. - 🎨 label the Ghosted exit and pin it to the top of its own column (2.25) so the faded band peels up off Going stale and leaks away, the mirror of Rejected, which sinks to the bottom.
…read everywhere The reevaluation signal was computed in two places that could drift: the read-only `analyze:outcomes` CLI that track-outcomes shelled out to, and the dashboard. Consolidate onto the SSOT model — `tracker.json#analytics` is computed once by `npm run analytics -- --write` (stamp:false, never moves the freshness pill) and every consumer reads that one block. The per-family numbers require role-family classification the browser can't do, so the persisted block is the only correct source for them. - 🐛 fix(analytics-cli): default the verb to `refresh` when flags are present but no verb is given, so the documented `npm run analytics -- --write` actually runs instead of printing help and exiting 1. Bare `npm run analytics` and `--help` are unchanged. - 📝 docs(agents): add a conditional "refresh analytics" step to the Tracker Write Contract (after Verify, before Re-render). Outcome-changing skills run `npm run analytics -- --write` so the dashboard renders a fresh block; pure comms/scheduling writes skip it. - 🔄 refactor(track-outcomes): STEP 6 reads `analytics.reevaluation` (due/dueReasons/sinceLastReview/thresholds) from the persisted block instead of running `analyze:outcomes` and hand-comparing YAML thresholds. The block applies the comparison; the skill reads `due` and trusts it. - ✨ feat(dashboard): surface reevaluation progress in the strategy-review panel from the persisted block (read like compEstimate — never recomputed client side). Null-safe: older trackers without the block render nothing. Text/amber only, no left-accent strip. - 🔧 config(demo): seed the analytics block into the demo fixture so the public demo shows the surfacing.
The demo fixture was thin — most rows were a status + 2-3 stub conversations with artifact paths that pointed at files that didn't exist. Build it into a realistic, lived-in job search for one persona (Riley Chen) so the dashboard demos with real content: emails, interview notes, transcripts, prep dossiers, and a full offer-to- accept arc. Depth scales with how far each job advanced. - ✨ E Corp — Staff SWE (accepted) is the showcase: a 9-beat arc from referral to signed offer, the offer→counter→revised-offer→accept negotiation, an embedded interview dossier (live cue card + study layer), and a 10-message thread. - ✨ the 7 DEEP rows (2 offers, 2 final rounds, onsite, loop, panel) get rich conversations, comms threads, embedded dossiers, a transcript each, and offer letters for the Aperture/Hooli comparison offers. 3 MEDIUM and 18 LIGHT (applied/screens/rejected/withdrawn) get just enough — a confirmation thread, a screen note, a rejection email — nothing heavy. - ✨ 45 artifact files under examples/demo-workspace/workspace/ (13 JDs, 11 prep packets, 9 transcripts, 9 email-thread exports, 3 offer letters), all grounded in Riley's real track record (Meridian RAG + agentic workflow, Pulsar FDE deploys). - 🐛 fix the candidate email everywhere to riley.chen@rolester.dev (a stray jane.candidate@example.test leftover in the old thread is gone). - 🐛 normalize the generated fields to what the dashboard actually reads: compEstimate → floorK/askK (in $K), followUp → dueAt/note, benefits → the real BENEFIT_EMOJI keys; and fix 3 comm statuses that read as phantom "reply needed" CTAs (Abstergo → waiting, Weyland-Yutani / Massive Dynamic → scheduled). Only E Corp is accepted; 2 genuine needs-reply threads remain (decline Aperture, withdraw Black Mesa). - 📝 docs(roadmap): add the interactive live-demo-on-the-site item to the public roadmap (the build this data renders). Validates clean: schema --verify, verify:tracker (0 errors / 0 warnings), render. Built via a 15-agent workflow (tiered generators → deterministic merge), reviewed + field-corrected + committed by the orchestrator.
…ad scroll The Jobs Sankey over-counted depth and had no celebratory endpoint. Three fixes, all domain-neutral (help real searches too, not just the demo). - ✨ add an "Accepted 🎉" terminal node — accepted offers flow out of their last round into a green celebratory sink, set apart from the live chain so the win reads instantly (was: an accept just sat anonymously at its deepest round). - 🐛 roundCount no longer counts non-evaluative beats as interview rounds. A referral intro, offer call, negotiation, debrief, or reference check is real history but not a round, so an accepted loop was showing as a 9th-round outlier. New NON_ROUND_CONV_RE blocklist → only screens + interviews count (e.g. E Corp 9 → 4 rounds, demo maxRound 9 → 5). - 🗑️ remove the horizontal-scroll affordance (left/right buttons, scroll wrapper, fixed 1800px SVG width, click/scroll/resize handlers). The funnel SVG always scales to fit via preserveAspectRatio meet, so scroll never did anything — it fit even at 9 rounds. SVG is now width:100% responsive and centered. Funnel + shell inline JS/CSS parse clean; client-script + styles guards green.
- 🔄 flip 22/29-interviewing → 66% ghosted / 34% heard back, keyed on real rolester-live ratios; funnel chain thins 6→6→5→3 (maxRound 4), 6 rejected, 1 withdrawn, 3 live - ✨ E Corp = offer-in-hand (decision pending), no accept — offer letter is the freshest artifact, weighed against the live Cyberdyne onsite + Massive panel this week - 🐛 fix a real-person de-id leak (recruiter name) + stale signed/DocuSign content the mechanical pass left, via QA fan-out + 6-agent per-row coherent rewrite (conversations + comm threads + dossiers all reconciled) - 🔧 evergreen dates anchored to meta.demoAnchor=2026-06-26; channels normalized to board/referral/recruiter; analytics block regenerated
- ✨ feat(dashboard-data): avatarMarkup reads an explicit `logo` (app.logo / sourced.logo) ahead of logo.dev, else monogram; wire row.logo through every avatar call site (table, jobs explorer, cards) + applicationJobRow/sourcedJobRow - 📝 docs(AGENTS): add "Company logos" convention — skill writes app.logo when it has one, dashboard reads it, else logo.dev-if-wired, else monogram - 🎨 style(assets): normalize all 29 demo logos to uniform 256x256 white-padded PNG (drop mixed jpg/svg/webp); reconstruct Black Mesa ring+wedge mark - 🔧 config(demo-logos): point DEMO_LOGOS at the .png files + reference the convention - ✨ feat(demo-fixture): wire app.logo on all 29 applications + 2 sourced rows
… bundle The .reveal CSS gate was already fail-open for no-JS, but the IntersectionObserver that adds .visible lived in the bundled SiteInteractions client component. If the inline gate script ran but the bundle was blocked, html.js was set, content was hidden, and nothing revealed it: fail closed. Move the reveal observer into the same inline bootstrap that sets html.js so the gate and the revealer share fate. A blocked bundle now still reveals content. SiteInteractions keeps the squiggle, nav-active, and header-pill enhancements.
…avicon, live-demo pipeline - 🎨 style(website): port drydock-style footer (brand blurb + Product/Project columns + legal + CodesWhat sign-off pill), adapted to rolester warm palette - ✨ feat(website): add Docs nav link + footer links to the Fumadocs site at /docs - ✨ feat(website): footer reveals on scroll via the existing .reveal system; the html.js shim already gates it (no-JS = visible) - 🎨 style(favicon): rat-headshot favicon across the marketing site, the live demo, and the locally-hosted dashboard - ✨ feat(demo): build:demo + deploy:demo pipeline — rebase-demo-dates (evergreen) → render fixture → static bundle → prebuilt Vercel deploy to demo.rolester.codeswhat.com
Reverses the 0.2.4 BUSL-1.1 relicense (3b11cde). Restores the original MIT text and flips every reference: package.json + lockfile license field, the LICENSE file, docs/DISCLAIMER.md, the docs-site disclaimer + what-is-rolester pages, and the marketing-site hero/footer strings (footer "License" links now point at the repo LICENSE instead of mariadb.com/bsl11). Built docs output (website/public/docs) regenerates MIT on the next docs build.
The launch-hygiene leak audit caught the demo deploy script naming the employer org in a code comment — a de-id violation on a public surface. Rephrased the --scope warning to keep the operational guardrail (always pass --scope; never let the CLI default account receive the deploy) without naming the account. Caught + fixed before any push, so it never left the machine.
…muddy strategy card - 🐛 Stop the slide-in drawers casting a shadow while parked off-screen: their Tailwind shadow-2xl plus a custom -18px left shadow bled ~40-68px back onto the page's right edge on every view. Shadow now only renders while open. - 🎨 Drop the white diagonal card sheen in dark mode (it composited to a harsh light→dark diagonal over the dark surface). - 🎨 Re-tint the strategy card for dark mode: the "Next Steps" recommendation banner (peach→dark coral), the review panel (mint→dark teal), and the outcome learning bar tracks (bumped off the surface colour so they actually read).
Replace the static mascot in "Meet your sidekick" with a framed, click-through preview of the real dashboard — a looping screen-recording (Dashboard → Jobs funnel → Calendar → Library) captured at a fixed viewport so there's no padding jank, linking out to the standalone live demo. Adds the DemoEmbed component + .demo-* styles, and the Playwright capture scripts (record-demo-video.mjs drives the tour → webm → ffmpeg GIF; capture-demo-frames.mjs is the fixed-viewport frame fallback).
Rescope the local-first messaging so it reads as what the self-host version gives you, not an anti-cloud creed — leaves clean room for a hosted version later without contradicting the page. - Hero CTA "it's yours, and it's free" → "free & open source" - "The whole loop. Nothing sold separately." → "The whole loop, end to end." - Privacy section: drop "belongs in a cloud database" / the anti-freemium jab; reframe h2 to "Self-host it, and your data stays your own."; "no cloud" chip → "runs locally" - Get section: drop "no account, no cloud"; final CTA scoped to self-host
Command snippets like `-g` and `@anthropic-ai/...` were rendering their hyphens as long ligature dashes. Pin `code` and `.terminal-sticker` to the mono face with ligatures/contextual alternates disabled so hyphens read as hyphens.
…atch The inline bootstrap added `visible` to .reveal nodes before React hydrated, which mutated server-rendered markup and triggered a hydration mismatch. Move the IntersectionObserver into SiteInteractions (post-hydration) and leave the inline script to only set the `js` gate plus a post-load failsafe for the blocked-bundle case. Reduced-motion now resolves purely in CSS.
…e publishing The demo's E Corp offer story used $225K as the initial base, which collides with a known production comp sentinel (225K/225000/220000) — i.e. a real number the release-safety guard bans from tracked files. Shift the fictional initial offer to $222K everywhere it appears (offer doc, tracker activity + comms thread) and adjust the one derived figure ($7K→$10K improvement, ~$362K→~$359K Y1 TC) to stay coherent. Also retire the $220K tactical floor in the Weyland packet (same banned value, K-form the grep missed). release-safety test green.
Mirrors deploy:demo's Build Output API approach (prebuilt, --scope codeswhat) so the marketing site + /docs ship to rolester.codeswhat.com without tripping the Next-16 static-export vercel-build 404 bug.
SKILL.md + config + routing (scoring/UI wiring follows). The skill web-searches role-scoped layoff/financial/sentiment/leadership signals, scores a healthy|watch|risky rating with provenance, persists companyHealth to the tracker, and cross-cuts the fit score only where it hits a stated candidate need (else it stands alone). - .agents/skills/company-health/SKILL.md — firing cost-gate (auto at the interview stage by default, manual anytime), per-dimension research, standalone-rating + selective cross-cut scoring, derive→persist→render, internal-signal-only honesty rail. - config: company_health block in modes.schema.json + modes.example.yml (auto / fire_at_stage / manual_always / recheck_days). - routing: AGENTS.md intent table + Intent Routing + config-consumer, Activity Pulse, and fan-out tables; CLAUDE.md routing line; package.json files allowlist. install-skills globs the dir (23 skills discoverable).
…o fit STEP 6 applies the role-scoped cross-cut: fitDelta is 0 when the rating didn't hit a stated candidate need and a small negative when it did (like benefits feed fit only where valued). Never a hard kill on its own; a stale rating is informational only. No companyHealth = no change.
Card carries a compact Watch/Risky pill (role-scoped detail in the title, healthy stays silent); drawer gets a Company health section — rating-for- function, provenance, as-of, per-dimension rows, and a collapsible evidence list with http(s)-only source links. No left-accent strip; dark-mode re-tints the teal/amber/coral so the rgba literals don't go muddy over dark surfaces.
Healthy/Watch/Risky across E Corp, Massive Dynamic, Cyberdyne so the live demo shows all three states + the stability cross-cut (Cyberdyne's fresh RIF hit the ML org, fitDelta -5). Dates anchored to demoAnchor so the rebase keeps them evergreen; no comp numbers or banned sentinels in any note.
…n + fixture Greens the full suite (912/912) ahead of the 0.3.0 cut. All 24 deferred failures were stale assertions tracking the pre-redesign dashboard + pre-overhaul demo fixture, not regressions — verified each: renamed classes/CSS-var swaps, fixture count/date rebalances, the interviewPacket→interviewDossier artifact contract, and the minified website hydration bootstrap. No source or fixture files changed.
Feature release: role-scoped company-health/sentiment skill, Fumadocs /docs site, Epic 0 outcome analytics, demo-fixture overhaul, website launch-polish, MIT relicense. Full suite green (912/912). Ships MIT.
biggest-littlest
approved these changes
Jun 28, 2026
biggest-littlest
left a comment
Member
There was a problem hiding this comment.
Release contents verified — green suite, release-safety clean, MIT. Approving.
ALARGECOMPANY
approved these changes
Jun 28, 2026
ALARGECOMPANY
left a comment
Member
There was a problem hiding this comment.
Second approval — looks good to ship 0.3.0.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
rolester 0.3.0
Feature release. Cuts
dev(green, 912/912) tomainfor the v0.3.0 tag + npm publish.Highlights
healthy | watch | riskyrating (layoff risk, hiring momentum, financials, sentiment, leadership) that only dents the fit score where a poor dimension intersects a stated candidate need. Cost-gated firing (manual anytime; auto at the interview stage by default), persist-then-render to the tracker, internal signal only — never enters an outbound artifact. Card badge + drawer health section on the dashboard./docs(friendly + advanced tracks).deploy:webpipeline.Quality
release-safetygreen (no personal sentinels, allowlist sane).next→postcss) is in the website build chain only;nextdoes not ship in the publishedrolesterpackage.Publish
Tagging
v0.3.0after merge triggers the OIDC Trusted-Publishing flow (npm provenance), shipping MIT.