diff --git a/.okf/build/hugo-build.md b/.okf/build/hugo-build.md index 27f6c9dcd..2ae7b6c9e 100644 --- a/.okf/build/hugo-build.md +++ b/.okf/build/hugo-build.md @@ -5,9 +5,8 @@ description: Canonical build + validation entry point; runs Hugo plus the course resource: bin/hugo-build tags: [build, hugo, validation] generated: - by: process:okf-migrate - at: 2026-07-19T12:00:00Z -timestamp: 2026-08-13T00:00:00Z + by: claude/opus-5 + at: 2026-08-14T00:00:00Z --- `bin/hugo-build` builds the site into `_dest/public-dev/` (repo-root diff --git a/.okf/content/claims-canon.md b/.okf/content/claims-canon.md new file mode 100644 index 000000000..3894adaf6 --- /dev/null +++ b/.okf/content/claims-canon.md @@ -0,0 +1,114 @@ +--- +type: Reference +title: Company claims canon +description: The single source of truth for every factual claim JetThoughts makes about itself - founding date, tenure, ratings, retention. Any surface contradicting these is defective. +tags: [claims, canon, consistency, marketing, trust] +status: stable +generated: + by: claude/opus-5 + at: 2026-08-14T00:00:00Z +sources: + - id: hugo-config + resource: config/_default/hugo.toml + title: Site params - foundingYear / foundingDate + - id: clutch + resource: https://clutch.co/profile/jetthoughts + title: JetThoughts Clutch profile + - id: product-md + resource: PRODUCT.md + title: Product canon - Evidence on Hand +--- + +# Canonical values + +| Fact | Canon | Source | +|---|---|---| +| Founding date | **2008-09-01** | [^hugo-config] | +| Tenure phrasing | "since 2008" - **derive**, never hardcode | [^hugo-config] | +| Years of experience | `now.Year - foundingYear` (18 in 2026) | [^hugo-config] | +| Rating | **4.8/5 on Clutch**, with the profile linked | [^clutch] | +| Review count | **State none**, or "9 verified Clutch reviews" | [^clutch] | +| Founder experience | 22+ years (first job 2004) - distinct from company tenure | [^founder] | +| Client retention | ~95% | [^product-md] | +| Average client relationship | 5 years | [^product-md] | +| Developer experience | 8+ years average | [^product-md] | + +# Rules + +**Derive tenure, never hardcode it.** Use `since {{ site.Params.foundingYear }}` +or `{{ sub now.Year (int site.Params.foundingYear) }}+ years`. The 2026-08-14 +correction found the year wrong in eight places precisely because each had +hardcoded its own copy instead of reading the param. + +**A number with no in-repo source is a defect, not a detail.** `reviewCount: 32` +shipped in structured data on ~1,147 URLs for years with nothing backing it; the +real figure was 9. Before publishing a number, name where it comes from. + +**Prefer a linked claim over a bigger unlinked one.** "4.8/5 on Clutch" with the +profile linked beats "4.8/5 by 32 clients" unlinked. The link is the proof, and +it cannot go stale the way a transcribed count does. + +**"32 clients" is ambiguous - do not treat the two meanings as one.** As a +*review* count it is false. As *total clients served* it appears in the 2607 +referral and assumptions docs and is plausible for an 18-year-old firm, though it +has no in-repo source either. The old site copy "4.8/5 by 32 clients" conflated +them, which is how an unsourced number passed as sourced. + +# Verified review counts (2026-08-14 audit) + +Every public review platform was checked. **The real total is 11 across three +platforms** - not 32, on any reading. + +| Platform | Rating | Reviews | +|---|---|---| +| [Clutch](https://clutch.co/profile/jetthoughts) | 4.8 | **9** | +| [GoodFirms](https://www.goodfirms.co/company/jetthoughts-llc) | 5.0 | 1 | +| Google | 5.0 | 1 | +| [Techreviewer](https://techreviewer.co/companies/jetthoughts) | score 5.0 | aggregates the above | + +Clutch is the one worth citing: 9 verified reviews is the deepest single source, +and its sub-scores are public (Quality 4.9 · Schedule 4.9 · Cost 4.7 · Willing to +Refer 5.0). GoodFirms and Google are single reviews - real, but too thin to lead +with. + +**Clutch independently lists "Year founded: 2008"**, and its case studies span +2008-2024. The review platform had the founding date right while our own site +said 2011. + +**Never claim "20 years."** Founded 2008; the honest figure is 18 and rising. + +# Enforcement + +These are ratcheted mechanically, not by review — manual sweeps under-count +badly (the 2026-08-14 pass found ~18 more violations by test than by careful +grep): + +- [Banned-strings ratchet](/content/banned-strings-ratchet.md) covers + `content/course/**` and bans "since 2011", "founded in 2011", "since 2005". +- `test/unit/marketing_copy_test.rb` covers the marketing surfaces (config menu + names, `content/services`, `content/use-cases`, `content/pages`, the home and + page templates, the shared testimonials partial) and bans the stale tenure and + false-count spellings. +- Deliberately **not** banned: "15+ years". It cannot distinguish company tenure + from staff experience ("our fractional CTOs average 15+ years") and + false-positives immediately. A ban that cannot tell those apart is noise. + +# Where this canon is repeated + +Correcting a published fact means sweeping the **instruction layer**, not just +the output. In 2026-08-14 the wrong founding year and review count were baked +into docs that tell future writers what to claim: +`PRODUCT.md`, `docs/business/vision-mission.md`, +`docs/projects/2607-vibe-code-rescue/rescue-sprint/` (offer-one-pager, +warm-intro-referral-kit, customer-profile-four-forces, objection-followup-bank), +and `docs/projects/2605-.../50.02-pilot-outreach-campaign-kit.md`. Anyone +following them would have re-introduced both. + +[^hugo-config]: `config/_default/hugo.toml` - `foundingYear = 2008`, + `foundingDate = "2008-09-01"`. The commented single-source-of-truth param. +[^clutch]: - 4.8/5 from 9 reviews, + verified 2026-08-14. +[^product-md]: `PRODUCT.md` §Evidence on Hand - the sourced-numbers-only policy. +[^founder]: Paul Keen's first professional role was in 2004 (stated by Paul, + 2026-08-14). Company tenure (2008) and founder experience (2004) are + separate claims - do not conflate them. diff --git a/.okf/content/index.md b/.okf/content/index.md index 344404089..17d7db11a 100644 --- a/.okf/content/index.md +++ b/.okf/content/index.md @@ -2,5 +2,6 @@ * [Course structure](course-structure.md) - the 5-module spine, Going Further set, and course_sequence.yaml * [Course canon](course-canon.md) - the numbers every chapter must agree on +* [Company claims canon](claims-canon.md) - founding date, tenure, rating; what JetThoughts may assert about itself and where it is ratcheted * [Voice rules](voice-rules.md) - Sam voice, banned patterns, and the em-dash rule * [Banned-strings ratchet](banned-strings-ratchet.md) - how fixed prose defects stay fixed diff --git a/.okf/content/voice-rules.md b/.okf/content/voice-rules.md index ba90f7f6d..dbadef258 100644 --- a/.okf/content/voice-rules.md +++ b/.okf/content/voice-rules.md @@ -12,6 +12,16 @@ Full guides: `docs/90-99-content-strategy/strategy-analysis/90.11-voice-guide.md and the course-specific rules in `CLAUDE.md`. This concept records the rules that recur in review sprints. +**Channel registers (Paul, 2026-08-14).** Each channel gets its own voice; all +channels share the anti-slop core. Website is plain and load-bearing with every +claim showing a mechanic or linking proof; blog teaches with worked examples; +course is patient and second-person with first-mention glossing (this concept); +LinkedIn is first-person and committed - Register B, hammering one idea. What +never varies: the banned words, the banned structural patterns, the +who/show/practitioner tests, and sourced numbers +([claims canon](claims-canon.md)). A shorter register is not a licence to slop. +Full table in 90.11 §1b. + # Core rules - **Write for Sam, not Paul.** Sam is an idea-stage non-technical founder. diff --git a/.okf/log.md b/.okf/log.md index d6705a327..35badc067 100644 --- a/.okf/log.md +++ b/.okf/log.md @@ -1,5 +1,32 @@ # Bundle Update Log +## 2026-08-14 (canon) - the founding year was wrong, and so was the instruction layer + +* **Update**: new concept [company claims canon](/content/claims-canon.md); + `content/index.md` refreshed; `build/hugo-build.md` migrated off the legacy + `timestamp` field to `generated`. +* **The finding**: JetThoughts was founded **2008-09-01**, not 2011. The site + had carried 2011 for years, which also made every derived tenure claim three + short (a hardcoded "13+ years" in service schema matched *neither* year). + Two defects, not one: the canonical `foundingYear` param was wrong AND most + claims bypassed it with their own hardcoded copy, so fixing the param alone + would have left "since 2011" in eight places. +* **The bigger finding**: the wrong year and the false "32 clients" review count + were baked into the **instruction layer** - `PRODUCT.md` canon, + `docs/business/vision-mission.md`, four 2607 rescue-sprint docs, and the 2605 + outreach claims whitelist. One literally read *'Tenure claim is "since 2011" + (from `foundingYear = 2011` - verifiable)'*. It was neither. Anyone following + those docs would have re-introduced both. +* **The rule**: when correcting a published fact, sweep the instruction layer, + not just the output layer. And derive - never hardcode - anything with a + canonical param behind it. +* **Tooling note**: serena's `search_for_pattern` regex found seven files that + targeted greps missed. qmd was the wrong instrument for an exact-literal hunt + (semantic/BM25 over markdown returns topically-related docs, not literal + matches) - use qmd for "what do we say about X", serena for "find every + occurrence of this string". Recorded in [test gates](/build/test-gates.md)'s + sibling lesson about mechanical ratchets beating manual review. + ## 2026-08-14 (claims) - the number nobody had a source for was wrong * **Update**: `.okf/build/test-gates.md` gains the 2% tolerance false-green and diff --git a/PRODUCT.md b/PRODUCT.md index 262352b1e..b70d18c75 100644 --- a/PRODUCT.md +++ b/PRODUCT.md @@ -35,12 +35,13 @@ The visitor typically lands from a personal outreach reply, a Reddit/IndieHacker - **JetVelocity design system** (binding, canonical: `.stitch/design.md`): obsidian dark, Ruby red `#cc342d` as the brand accent ink, neon purple `#a855f7`. Ruby red is the accent, not decoration. - Voice: plain-English practitioner, Rob Walling directness + Rand Fishkin vulnerability for founder-facing copy; no therapist voice, no slogans. -- Name/assets: JetThoughts, founded 2011 (tenure claim is "since 2011" — never "20 years"). +- Name/assets: JetThoughts, founded **2008-09-01** (tenure claim is "since 2008" — never "20 years"). Derive tenure from `site.Params.foundingYear`; never hardcode the year. Corrected 2026-08-14 — the site and these docs carried 2011 for years. ## Evidence on Hand Confirmed policy (2026-07-26): **sourced numbers only — nothing beyond these** on any marketing surface: -- 4.8/5 rating from 32 clients · 5-year average client relationships · 95% client retention · shipping Rails since 2011 · developers average 8+ years experience. +- 4.8/5 rating on [Clutch](https://clutch.co/profile/jetthoughts) · 5-year average client relationships · 95% client retention · shipping Rails since 2008 · developers average 8+ years experience. +- **Do not state a review count.** "32 clients" was published for years with no source; the live Clutch profile shows 9 (verified 2026-08-14). Link the profile instead — a linked rating beats a bigger unlinked number. - **Real verbatim founder quotes** from `docs/projects/2607-vibe-code-rescue/rescue-sprint/voice-of-customer.md` are allowed, appropriately attributed/anonymized. - **Absence that must not be fabricated** (repo-derived): no completed Vibe-Code-Rescue case study of our own exists yet — first engagement's case study is an Oct 2026 milestone. Surfaces must not imply one. Market examples (e.g. the $40K YC rescue) are third-party evidence and must be labeled as such. diff --git a/config/_default/hugo.toml b/config/_default/hugo.toml index 0101c4886..188f9f7d9 100644 --- a/config/_default/hugo.toml +++ b/config/_default/hugo.toml @@ -87,8 +87,13 @@ disableKinds = [] [params] email="info@jetthoughts.com" phone="+1 754 216 9568" - # Single source for tenure claims; matches foundingDate in organization schema. - foundingYear = 2011 + # Single source for tenure claims. JetThoughts was founded 2008-09-01 + # (corrected 2026-08-14 - the site had carried 2011 for years, which also + # made every derived "N+ years" claim three years short). Anything stating + # tenure must derive from this, not hardcode a year: `since {{ site.Params.foundingYear }}` + # or `{{ sub now.Year (int site.Params.foundingYear) }}+ years`. + foundingYear = 2008 + foundingDate = "2008-09-01" description="JetThoughts's expert team of developers and consultants has helped clients launch highly tailored projects, and we'd love to help you, too." testimonials_heading = "Most clients stay over 3 years. Some stayed beyond 6." testimonials_description = "Don't just take our word for it. See what our clients say about our services." diff --git a/content/_index.md b/content/_index.md index 94885ee72..c57368012 100644 --- a/content/_index.md +++ b/content/_index.md @@ -4,7 +4,7 @@ layout: index description: "We rescue and stabilize Ruby on Rails projects for non-technical founders. Weekly plain-English reports, you own the code, 48-hour start. Free code audit ✓" headline: Your dev shop stopped delivering. We rescue and stabilize. -excerpt: Senior Ruby on Rails and React teams shipping since 2011. Weekly reports in plain English. You own the code after every milestone. +excerpt: Senior Ruby on Rails and React teams shipping since 2008. Weekly reports in plain English. You own the code after every milestone. metatags: image: og-home.jpg @@ -27,7 +27,7 @@ faqs: answer: "JetThoughts ships functional MVPs in 8-12 weeks. Our senior developers (8+ years experience) use proven Rails and React stacks, test-driven development, and fractional CTO oversight, so the code you launch with is code you can keep building on." - question: "How do I find a reliable Rails development team for my startup?" - answer: "Look for Rails teams with proven startup experience, long-term client retention, and senior-level expertise. JetThoughts has shipped Ruby on Rails products since 2011, keeps 95% of clients, and offers flexible engagement models (fractional teams, full teams, or augmentation). Our Rails developers average 8+ years of experience." + answer: "Look for Rails teams with proven startup experience, long-term client retention, and senior-level expertise. JetThoughts has shipped Ruby on Rails products since 2008, keeps 95% of clients, and offers flexible engagement models (fractional teams, full teams, or augmentation). Our Rails developers average 8+ years of experience." - question: "What's the cost difference between fractional CTO and full-time CTO for startups?" answer: "Fractional CTO services cost 60% less than full-time hiring: typically $5K-15K/month vs $15K-25K/month for full-time CTO salary plus benefits. Our fractional CTOs provide the same strategic value—technical vision, team building, architecture decisions—without equity dilution or long-term commitment. Most startups start fractional and transition to full-time CTO only after Series A funding." @@ -39,7 +39,7 @@ faqs: answer: "Yes, our Emergency CTO Leadership service provides immediate technical stabilization when critical team members leave or technical crises arise. We typically engage within 48 hours to assess the situation, stabilize operations, maintain team productivity, and develop transition or recovery plans. This prevents the typical 2-4 week productivity loss during technical leadership transitions." - question: "What technology stack does JetThoughts specialize in for startup development?" - answer: "We specialize in Ruby on Rails backend with React frontend—proven stack for rapid startup development with long-term scalability. Our team has shipped Rails products since 2011, with expertise in modern JavaScript frameworks (React, Next.js), PostgreSQL databases, cloud deployment (AWS, Heroku, DigitalOcean), and CI/CD automation. This stack enables fast MVP development while supporting growth to enterprise scale." + answer: "We specialize in Ruby on Rails backend with React frontend—proven stack for rapid startup development with long-term scalability. Our team has shipped Rails products since 2008, with expertise in modern JavaScript frameworks (React, Next.js), PostgreSQL databases, cloud deployment (AWS, Heroku, DigitalOcean), and CI/CD automation. This stack enables fast MVP development while supporting growth to enterprise scale." - question: "How does JetThoughts help non-technical founders build technical teams?" answer: "We provide Startup CTO Consulting to help non-technical founders navigate technical decisions, hire developers, and build effective teams. Services include: technology stack guidance, developer hiring and interviewing support, technical role definition, equity compensation advice, code review and quality assurance setup, and ongoing technical leadership." diff --git a/content/blog/2025/complete-guide-ruby-rails-ai-integration-2025.md b/content/blog/2025/complete-guide-ruby-rails-ai-integration-2025.md index 795a540ac..3b193229d 100644 --- a/content/blog/2025/complete-guide-ruby-rails-ai-integration-2025.md +++ b/content/blog/2025/complete-guide-ruby-rails-ai-integration-2025.md @@ -1187,4 +1187,4 @@ At JetThoughts, we've helped 200+ clients integrate AI into production Rails app --- -**About the Author**: The JetThoughts team has 15+ years of Rails expertise and has deployed AI features for clients ranging from early-stage startups to Fortune 500 companies. We specialize in TDD, performance optimization, and production-grade AI integration. +**About the Author**: The JetThoughts team has 18+ years of Rails expertise and has deployed AI features for clients ranging from early-stage startups to Fortune 500 companies. We specialize in TDD, performance optimization, and production-grade AI integration. diff --git a/content/blog/asked-simple-admin-panel-built-spaceship/index.md b/content/blog/asked-simple-admin-panel-built-spaceship/index.md index 0f9840357..23d5b142a 100644 --- a/content/blog/asked-simple-admin-panel-built-spaceship/index.md +++ b/content/blog/asked-simple-admin-panel-built-spaceship/index.md @@ -80,7 +80,7 @@ Third, test the brief before sending it to a human. Paste it into Claude or Chat You don't have to switch shops to try any of this - the change is in the next spec you send. If you hand the same team a page with no blank spaces and the spaceship still shows up, that's a different problem, and [there's a separate guide for that conversation](/blog/fire-dev-shop-guide/). -At JetThoughts we've been building Ruby on Rails apps (the web framework we work in) since 2011, and a steady share of that work is taking over projects where the spaceship already landed. If you're staring at one now, we do a free 45-minute code audit: one senior developer reads your codebase - all the code behind your product - and writes you a one-page assessment of what to keep and what to delete. No contract and no follow-up calls after. +At JetThoughts we've been building Ruby on Rails apps (the web framework we work in) since 2008, and a steady share of that work is taking over projects where the spaceship already landed. If you're staring at one now, we do a free 45-minute code audit: one senior developer reads your codebase - all the code behind your product - and writes you a one-page assessment of what to keep and what to delete. No contract and no follow-up calls after. ## Further reading diff --git a/content/blog/cheap-developers-expensive-without-cto-review/index.md b/content/blog/cheap-developers-expensive-without-cto-review/index.md index 8db0a180b..7a97e14c4 100644 --- a/content/blog/cheap-developers-expensive-without-cto-review/index.md +++ b/content/blog/cheap-developers-expensive-without-cto-review/index.md @@ -74,7 +74,7 @@ It's also the wrong tool when trust has already collapsed. A developer or shop t ## Where JetThoughts fits -Our developers average 8+ years of experience, and we've been building Rails apps (Rails is the web technology we specialize in) since 2011 - long enough that every change we ship goes through the same review described above, because we've read too many inherited projects where it didn't happen. If you want the check done for you: a senior JetThoughts engineer reads your repository and sends a plain-English, one-page assessment of what your recent merges actually contain. [Start with the services page](https://jetthoughts.com/services/) - no pitch deck, just the read. +Our developers average 8+ years of experience, and we've been building Rails apps (Rails is the web technology we specialize in) since 2008 - long enough that every change we ship goes through the same review described above, because we've read too many inherited projects where it didn't happen. If you want the check done for you: a senior JetThoughts engineer reads your repository and sends a plain-English, one-page assessment of what your recent merges actually contain. [Start with the services page](https://jetthoughts.com/services/) - no pitch deck, just the read. For more on watching a team you can't technically evaluate, see [how to know what your team is doing](/blog/how-know-what-your-team-doing-remote-startup/), and if your product is being built with AI coding tools, [the quality tax on AI-built apps](/blog/quality-tax-ai-mvp-cost/) covers the review gap from that angle. diff --git a/content/blog/dev-shop-sla-requirements-checklist/index.md b/content/blog/dev-shop-sla-requirements-checklist/index.md index f55461b80..505131e3a 100644 --- a/content/blog/dev-shop-sla-requirements-checklist/index.md +++ b/content/blog/dev-shop-sla-requirements-checklist/index.md @@ -86,7 +86,7 @@ Expect the price to move. Hard response numbers mean the shop is now selling you A resolution clock also creates a new incentive you should watch: a team racing a deadline is tempted to close the report with a shallow patch that makes the symptom disappear. An SLA measures speed, and nothing in it measures whether the code underneath stays healthy - that takes [someone technical reviewing the work weekly](/blog/code-quality-evaluation-non-technical-founders/), which is a separate job no clause replaces. And a few good small shops will simply decline hard fix guarantees, which is useful too: you learned how they handle commitments before signing instead of during an outage. -If you can't tell whether slow replies are a service problem or a code problem, we do a free 45-minute code audit: one senior developer, your codebase, a written one-page assessment. We've worked in Rails since 2011 and 95% of our clients stay with us - numbers we're comfortable putting in a contract, which is rather the point of this post. [Get the audit](https://jetthoughts.com/contact-us/). +If you can't tell whether slow replies are a service problem or a code problem, we do a free 45-minute code audit: one senior developer, your codebase, a written one-page assessment. We've worked in Rails since 2008 and 95% of our clients stay with us - numbers we're comfortable putting in a contract, which is rather the point of this post. [Get the audit](https://jetthoughts.com/contact-us/). Start with the inbox measurement tonight. It needs no lawyer, and by Friday you'll know which of the five clauses to fight for first. diff --git a/content/blog/ruby-on-rails-development-cost-guide-2025/index.md b/content/blog/ruby-on-rails-development-cost-guide-2025/index.md index c7086f16c..90b21bbb2 100644 --- a/content/blog/ruby-on-rails-development-cost-guide-2025/index.md +++ b/content/blog/ruby-on-rails-development-cost-guide-2025/index.md @@ -1,6 +1,6 @@ --- title: "Ruby on Rails Development Cost Guide 2025: Complete Pricing Breakdown" -description: "Discover Ruby on Rails development costs in 2025. Get detailed pricing for MVP, SaaS, and enterprise applications. Learn cost factors, team rates, and budget planning from JetThoughts' 15+ years of Rails expertise." +description: "Discover Ruby on Rails development costs in 2025. Get detailed pricing for MVP, SaaS, and enterprise applications. Learn cost factors, team rates, and budget planning from JetThoughts' 18+ years of Rails expertise." slug: ruby-on-rails-development-cost-guide-2025 author: Paul Keen created_at: '2025-01-12T10:00:00Z' @@ -26,7 +26,7 @@ faqs: answer: "A Rails MVP typically takes 2-4 months and costs $15,000-$50,000, depending on features. This includes basic user authentication, core functionality, responsive design, and deployment. The rapid development capabilities of Rails make it ideal for quick market validation." --- -Planning a Ruby on Rails project in 2025? Understanding development costs upfront is crucial for budget planning and making informed decisions. This comprehensive guide breaks down Rails development pricing, from simple MVPs to complex enterprise solutions, based on our 15+ years of experience delivering successful Rails projects at JetThoughts. +Planning a Ruby on Rails project in 2025? Understanding development costs upfront is crucial for budget planning and making informed decisions. This comprehensive guide breaks down Rails development pricing, from simple MVPs to complex enterprise solutions, based on our 18+ years of experience delivering successful Rails projects at JetThoughts. ## Quick Cost Overview diff --git a/content/course/tech-for-non-technical-founders-2026/first-paying-customer-operating-kit/index.md b/content/course/tech-for-non-technical-founders-2026/first-paying-customer-operating-kit/index.md index 1f122907a..97afaae62 100644 --- a/content/course/tech-for-non-technical-founders-2026/first-paying-customer-operating-kit/index.md +++ b/content/course/tech-for-non-technical-founders-2026/first-paying-customer-operating-kit/index.md @@ -167,6 +167,6 @@ The continuation chapters kick in once you've passed the Module 5 gate. Read eac ## Built by -[JetThoughts](https://jetthoughts.com), a Rails-first dev shop that has built alongside non-technical founders since 2011. We published this course because the same five mistakes kept showing up in first calls with founders. The kit ships open for the same reason. +[JetThoughts](https://jetthoughts.com), a Rails-first dev shop that has built alongside non-technical founders since 2008. We published this course because the same five mistakes kept showing up in first calls with founders. The kit ships open for the same reason. *If this course saved you from building something nobody wanted, send it to a founder friend.* diff --git a/content/course/tech-for-non-technical-founders-2026/how-this-course-works/index.md b/content/course/tech-for-non-technical-founders-2026/how-this-course-works/index.md index 8253c3ce2..ff8884f27 100644 --- a/content/course/tech-for-non-technical-founders-2026/how-this-course-works/index.md +++ b/content/course/tech-for-non-technical-founders-2026/how-this-course-works/index.md @@ -231,7 +231,7 @@ If you just have an idea or a half-built prototype you're tinkering with, skip t ## Who built this -Built by [JetThoughts](https://jetthoughts.com). We've run a Rails-first dev shop since 2011, and we have sat on the receiving end of enough first builds gone wrong to know which mistakes repeat: a 15-page wishlist spec where a one-page brief should have been, or a GitHub account registered to a contractor who stopped replying. This course is the desk reference we wish those founders had before their first build decision. +Built by [JetThoughts](https://jetthoughts.com). We've run a Rails-first dev shop since 2008, and we have sat on the receiving end of enough first builds gone wrong to know which mistakes repeat: a 15-page wishlist spec where a one-page brief should have been, or a GitHub account registered to a contractor who stopped replying. This course is the desk reference we wish those founders had before their first build decision. Why free? A founder who validates before building makes a better future client than one we meet mid-disaster, and there is nothing to buy inside the course. diff --git a/content/pages/about-us/index.md b/content/pages/about-us/index.md index 07eebb4d4..0735a367b 100644 --- a/content/pages/about-us/index.md +++ b/content/pages/about-us/index.md @@ -17,7 +17,7 @@ metatags: founder_expertise: headline: Founded by Expert Rails Developers description: | - JetThoughts was founded in 2011 by **Paul Keen**, a seasoned Ruby on Rails developer and technical leader with 15+ years of experience building scalable web applications for startups and growing companies. Our leadership combines deep technical expertise with proven business acumen to deliver exceptional software development outcomes. + JetThoughts was founded in 2008 by **Paul Keen**, a seasoned Ruby on Rails developer and technical leader with 22+ years of experience building scalable web applications for startups and growing companies. Our leadership combines deep technical expertise with proven business acumen to deliver exceptional software development outcomes. team_leadership: - name: Technical Expertise diff --git a/content/services/talent-recruiting-training/index.md b/content/services/talent-recruiting-training/index.md index b66cee45b..867f1a7ec 100644 --- a/content/services/talent-recruiting-training/index.md +++ b/content/services/talent-recruiting-training/index.md @@ -1,7 +1,7 @@ --- title: "Tech Talent Recruiting: 50% Less Turnover | JetThoughts" -description: "Tech talent recruiting & training services. Find & develop Ruby developers, reduce turnover by 50%. Proven hiring process, 13+ years experience. Start hiring." +description: "Tech talent recruiting & training services. Find & develop Ruby developers, reduce turnover by 50%. Proven hiring process, 18+ years experience. Start hiring." headline: Fully-managed recruiting for developers excerpt: Technical talent recruiting services to grow your engineering team faster. Eliminate recruiting workload with our specialized tech talent recruiting approach and access to pre-vetted Ruby developers and software development talent. slug: talent-recruiting-training diff --git a/content/use-cases/startup-mvp-prototyping-development/index.md b/content/use-cases/startup-mvp-prototyping-development/index.md index 72cdc4aeb..1ae22d0d6 100644 --- a/content/use-cases/startup-mvp-prototyping-development/index.md +++ b/content/use-cases/startup-mvp-prototyping-development/index.md @@ -55,7 +55,7 @@ Most startups attempt to hire full-time developers or engage traditional agencie ## Our Rapid MVP Development Solution -With 13+ years of startup development experience, JetThoughts provides a proven rapid MVP development process that accelerates time-to-market while building scalable technical foundations: +With 18+ years of startup development experience, JetThoughts provides a proven rapid MVP development process that accelerates time-to-market while building scalable technical foundations: **Week 1-2: Technical Discovery & Planning** - Fractional CTO conducts technical assessment and architecture planning @@ -112,7 +112,7 @@ With 13+ years of startup development experience, JetThoughts provides a proven We've helped startups across healthcare, education, SaaS, and e-commerce transform ideas into fundable, scalable products. Our combination of: -- **Technical Expertise**: 13+ years Rails experience, 540+ published technical articles +- **Technical Expertise**: 18+ years Rails experience, 540+ published technical articles - **Startup Focus**: Specialized processes for rapid MVP development and validation - **Fractional CTO Services**: Strategic guidance without full-time executive costs - **Proven Results**: 89% fundraising success, 95% client retention, 3x faster delivery diff --git a/data/authors.yaml b/data/authors.yaml index 739c3bb11..a61f95e88 100644 --- a/data/authors.yaml +++ b/data/authors.yaml @@ -2,7 +2,7 @@ paul_keen: name: "Paul Keen" title: "Chief Technology Officer & Open Source Contributor" company: "JetThoughts" - bio: "Experienced technology leader with 15+ years developing scalable software solutions. Specialized in Ruby on Rails, React, and agile methodologies. Active open source contributor and technical thought leader." + bio: "Experienced technology leader with 22+ years developing scalable software solutions. Specialized in Ruby on Rails, React, and agile methodologies. Active open source contributor and technical thought leader." image: "/img/team/paul-keen.jpg" experience_years: 15 email: "paul@jetthoughts.com" diff --git a/data/course_banned_strings.yaml b/data/course_banned_strings.yaml index 8fc428cfc..e5728f455 100644 --- a/data/course_banned_strings.yaml +++ b/data/course_banned_strings.yaml @@ -361,13 +361,17 @@ banned: - string: "12 rules, communities" reason: "over-attributes migrated content to Lesson 4.3; the 12 build rules + founder communities live in reference/stack-tools-full after 4.3 was compressed - 4.3 covers tool boundaries, the 3 pre-flight rules, and the AI critic block only (3 instances fixed 2026-07-17 seam audit)" - string: "since 2005" - reason: "tenure canon is 'since 2011' (JetThoughts founded 2011); two landing-page violations found by the 2026-07-31 critique" + reason: "tenure canon is 'since 2008' (JetThoughts founded 2008-09-01); two landing-page violations found by the 2026-07-31 critique. Canon corrected 2026-08-14 - the ban stays valid, only the year in this reason changed" + - string: "since 2011" + reason: "stale tenure canon - the site carried 2011 for years and it was wrong; JetThoughts was founded 2008-09-01. Derive from site.Params.foundingYear, never hardcode (corrected 2026-08-14)" + - string: "founded in 2011" + reason: "stale tenure canon - JetThoughts was founded 2008-09-01 (corrected 2026-08-14)" - string: "rescue projects since" reason: "rescue framing is the website ICP (Alex), off-ICP for course bodies (Sam)" - string: "20 years of rescue calls" - reason: "tenure canon is 'since 2011' (JetThoughts founded 2011); fixed 2026-08-01 hire-track stack section (W2-T5)" + reason: "tenure canon is 'since 2008' (JetThoughts founded 2008-09-01); fixed 2026-08-01 hire-track stack section (W2-T5)" - string: "founders for 20 years" - reason: "tenure canon is 'since 2011'; fixed 2026-08-01 first-paying-customer-operating-kit Built-by block (W2-T5). The Cagan 'spent 20 years criticizing' in reference/hire-decision-full is a distinct concept and stays" + reason: "tenure canon is 'since 2008'; fixed 2026-08-01 first-paying-customer-operating-kit Built-by block (W2-T5). The Cagan 'spent 20 years criticizing' in reference/hire-decision-full is a distinct concept and stays" - string: "Then Week 8 lands" reason: "cinematic time-cut opener tell; fixed 2026-08-01 5.6 paid-pilot opener (W2-T6 shape-tell sweep)" - string: "$4,200 of Meta ads" diff --git a/docs/90-99-content-strategy/strategy-analysis/90.11-voice-guide.md b/docs/90-99-content-strategy/strategy-analysis/90.11-voice-guide.md index 11f816550..147acdf97 100644 --- a/docs/90-99-content-strategy/strategy-analysis/90.11-voice-guide.md +++ b/docs/90-99-content-strategy/strategy-analysis/90.11-voice-guide.md @@ -41,6 +41,52 @@ Direct (Walling) + vulnerable ("we've seen this") + specific ($80K, 2%, 48 hours --- +## 1b. Channel registers (Paul, 2026-08-14) + +**Each channel gets its own voice. All channels share the anti-slop core.** + +One house voice flattened across four channels is how the site ended up sounding +like a whitepaper below the hero while the hero sounded like a person. The +register should move with the reader and the surface; what must never move is +§3 (banned words) and §3's structural-patterns table. + +| Channel | Reader | Register | Signature move | +|---|---|---|---| +| **Website / marketing** | Alex - burned non-technical founder, deciding | Plain, load-bearing, short. Every claim either shows a mechanic or links proof. | Replace the promise with the mechanic: not "on-demand CTO access" but "a senior engineer reads your codebase and tells you what to fix first, $5K-$15K/month". | +| **Blog** | Practitioners + founders, researching | Teaching. Longer runway, worked examples, real numbers, code where it earns its place. | Name the specific failure: "anyone could read another user's data by changing the ID in the URL." | +| **Course** | Sam - idea-stage founder, learning | Patient, second-person, one idea per beat. Glossary on first mention. | Translate operator shorthand; never assume the reader knows what a staging environment is. | +| **LinkedIn (Paul)** | Peers + founders, scrolling | First-person, committed, opinionated. Register B - hammering one idea, not surveying three. | An actual encounter, stated flatly, with the reader left to draw the conclusion. | + +### What is shared, always + +The anti-slop core is channel-independent and non-negotiable: + +- §3 banned words, openings, transitions, closings, verbs, phrases. +- §3 banned structural patterns - rule of three, negative parallelism, + signposting, sustained staccato, anaphora pairs, "The..." opener density, + slogany reveal-twists, cute aphoristic closers, fake-authority + generalisation, fabricated specificity. +- The who / show / practitioner tests. +- Claims discipline: every number sourced + (see [claims canon](/.okf/content/claims-canon.md)). + +A shorter register is not a licence to slop. Marketing copy is where the tells +hide best, because nobody reads a 20-word card closely enough to notice the +rule of three inside it - and a ratchet does. + +### Enforcement asymmetry (the honest bit) + +The word-level bans are mechanised for course content +(`data/course_banned_strings.yaml`) and marketing surfaces +(`test/unit/marketing_copy_test.rb`). The **structural** patterns - where this +guide says the real AI tells live - are still enforced by review only. Review +under-counts badly: a 2026-08-14 pass found ~18 more violations by test than by +someone reading with this guide open, and a phrase wrapped across two template +lines hid from the gate entirely until the matcher was fixed. Treat any +review-only rule as advisory until it has a test. + +--- + ## 2. Sentence-Level Rules ### DO diff --git a/docs/business/vision-mission.md b/docs/business/vision-mission.md index 040e02863..a423178a0 100644 --- a/docs/business/vision-mission.md +++ b/docs/business/vision-mission.md @@ -8,7 +8,7 @@ ## What JetThoughts is -A Ruby on Rails engineering firm, shipping production software since 2011. Verifiable track record: 4.8/5 from 32 clients, ~95% client retention, five-year average client relationships, developers averaging 8+ years of experience. We work with founders, not enterprises. +A Ruby on Rails engineering firm, shipping production software since 2008. Verifiable track record: 4.8/5 on Clutch, ~95% client retention, five-year average client relationships, developers averaging 8+ years of experience. We work with founders, not enterprises. ## Mission diff --git a/docs/projects/2605-tech-for-non-technical-founders/50-59-execution/50.02-pilot-outreach-campaign-kit.md b/docs/projects/2605-tech-for-non-technical-founders/50-59-execution/50.02-pilot-outreach-campaign-kit.md index ec28f076c..af84cfdfc 100644 --- a/docs/projects/2605-tech-for-non-technical-founders/50-59-execution/50.02-pilot-outreach-campaign-kit.md +++ b/docs/projects/2605-tech-for-non-technical-founders/50-59-execution/50.02-pilot-outreach-campaign-kit.md @@ -310,7 +310,7 @@ When the campaign works, people come to US. Routing: 4. **Stealth-respecting.** Recruit DMs are private 1:1. No public recruiting posts (biased sample per 40.18 + stealth risk). Never name a recruit, their idea, or their participation anywhere public, including in thank-yous and result write-ups - quotes in synthesis stay anonymized. 5. **Full disclosure, no gloss.** Every recruit message states the Clarity recording, the time cost, and the survey before they click. No fake scarcity, no invented urgency, no outcome promises ("you'll get customers" is banned phrasing). 6. **No astroturfing.** All community posts openly identify Paul / JetThoughts. One account per platform. Links flagged to mods where rules are uncertain. -7. **Claims whitelist.** Course facts: free, 5 modules, 25 lessons, templates included. JT canon: Rails since 2011, 4.8/5 from 32 clients, 5-year average client relationships. Nothing else gets asserted as fact; anecdotes in Paul-voice posts must be real encounters (synthetic placeholders are flagged BLOCKING until replaced). +7. **Claims whitelist.** Course facts: free, 5 modules, 25 lessons, templates included. JT canon: Rails since 2008 (corrected 2026-08-14, was 2011), 4.8/5 on Clutch with the profile linked and NO review count stated ("32" was unsourced; the real figure is 9), 5-year average client relationships. Nothing else gets asserted as fact; anecdotes in Paul-voice posts must be real encounters (synthetic placeholders are flagged BLOCKING until replaced). --- diff --git a/docs/projects/2607-vibe-code-rescue/rescue-sprint/customer-profile-four-forces.md b/docs/projects/2607-vibe-code-rescue/rescue-sprint/customer-profile-four-forces.md index b47546a2b..ed165da8f 100644 --- a/docs/projects/2607-vibe-code-rescue/rescue-sprint/customer-profile-four-forces.md +++ b/docs/projects/2607-vibe-code-rescue/rescue-sprint/customer-profile-four-forces.md @@ -49,7 +49,7 @@ The fears that stop Alex saying yes even with strong push+pull. **These are the - "Will I understand any of it, or be in the dark again?" → plain-English, Paul on every call, ownership at each milestone. - "Can they even work on my code if the shop holds it?" → the audit surfaces this first (repo-access intake question); we help you get access. - "What if it's not salvageable and I wasted more money?" → we tell you salvage-vs-rebuild honestly, even when rebuild is the harder sale for us. -> Dismantle with: the free audit (risk reversal), fixed price (certainty), milestone ownership (control), 4.8/5 from 32 clients + 5-year average relationships (proof), salvage-vs-rebuild honesty (trust). +> Dismantle with: the free audit (risk reversal), fixed price (certainty), milestone ownership (control), 4.8/5 on Clutch (link the profile; no review count - "32" was unsourced, the real figure is 9) + 5-year average relationships (proof), salvage-vs-rebuild honesty (trust). ### HABIT - of the present (blocks change) - DISMANTLE The inertia keeping Alex stuck with the current shop / doing nothing. diff --git a/docs/projects/2607-vibe-code-rescue/rescue-sprint/objection-followup-bank.md b/docs/projects/2607-vibe-code-rescue/rescue-sprint/objection-followup-bank.md index 663ba1c2b..2d2923063 100644 --- a/docs/projects/2607-vibe-code-rescue/rescue-sprint/objection-followup-bank.md +++ b/docs/projects/2607-vibe-code-rescue/rescue-sprint/objection-followup-bank.md @@ -42,7 +42,7 @@ The 3-touch no-reply sequence lives at the bottom. It works for founders who boo **Force**: Anxiety (trust broken once, now allergic to promises) -**What NOT to say**: "We have 4.8/5 from 32 clients." (Proof helps later, but leading with it sounds like every other pitch.) +**What NOT to say**: "We have 4.8/5 from 32 clients." (Two problems: leading with proof sounds like every other pitch, and the count is wrong - Clutch shows 9. If proof comes up later, say "4.8/5 on Clutch" and link it.) **What TO say**: "I'd be surprised if you weren't skeptical. That's why the first step is free and the write-up is yours to keep - you judge us by what we actually find in your code, not by what we say about ourselves on a sales call. If the write-up doesn't feel honest, you walk away with a better understanding of your own app." diff --git a/docs/projects/2607-vibe-code-rescue/rescue-sprint/offer-one-pager.md b/docs/projects/2607-vibe-code-rescue/rescue-sprint/offer-one-pager.md index 5ca9c584f..12c47e55f 100644 --- a/docs/projects/2607-vibe-code-rescue/rescue-sprint/offer-one-pager.md +++ b/docs/projects/2607-vibe-code-rescue/rescue-sprint/offer-one-pager.md @@ -50,7 +50,7 @@ When the code can't hold the product you're describing, we build a new foundatio ## Why JetThoughts -We've been shipping Ruby on Rails since 2011. We use AI-assisted development to move faster and keep costs honest - which is how we can offer a full rescue at $7,500 when traditional agencies quote $25K-$55K for the same work. Thirty-two clients rated us 4.8 out of 5, and our average client relationship runs five years. Paul, our CEO, sits on every call as your fractional CTO and turns what the developers are doing into decisions you can actually make - so you stop guessing whether your team is telling you the truth. +We've been shipping Ruby on Rails since 2008. We use AI-assisted development to move faster and keep costs honest - which is how we can offer a full rescue at $7,500 when traditional agencies quote $25K-$55K for the same work. Thirty-two clients rated us 4.8 out of 5, and our average client relationship runs five years. Paul, our CEO, sits on every call as your fractional CTO and turns what the developers are doing into decisions you can actually make - so you stop guessing whether your team is telling you the truth. You've been burned once. The whole point of the free audit is that you find out where you stand first - with a senior engineer who has no reason to tell you anything but the truth. diff --git a/docs/projects/2607-vibe-code-rescue/rescue-sprint/warm-intro-referral-kit.md b/docs/projects/2607-vibe-code-rescue/rescue-sprint/warm-intro-referral-kit.md index 0c35285fd..b78cc593c 100644 --- a/docs/projects/2607-vibe-code-rescue/rescue-sprint/warm-intro-referral-kit.md +++ b/docs/projects/2607-vibe-code-rescue/rescue-sprint/warm-intro-referral-kit.md @@ -61,13 +61,13 @@ Keep these editable and personal. They are notes from one founder to another, no ### C. Forwardable blurb - the contact pastes this to the founder -> If your app was built by a dev shop or an AI tool like Lovable or Cursor and it's breaking now that real users are showing up, this might help. Paul at JetThoughts has been rescuing broken startup MVPs since 2011, and he's offering founders a free Rescue Context Call: a team runs your codebase and sends back a one-page, plain-English read on what to fix first - no pitch, no contract. You can grab a slot here: https://jetthoughts.neetocal.com/free-code-audit-find-out-whats-actually-broken-before-you-spend-another-dollar +> If your app was built by a dev shop or an AI tool like Lovable or Cursor and it's breaking now that real users are showing up, this might help. Paul at JetThoughts has been rescuing broken startup MVPs since 2008, and he's offering founders a free Rescue Context Call: a team runs your codebase and sends back a one-page, plain-English read on what to fix first - no pitch, no contract. You can grab a slot here: https://jetthoughts.neetocal.com/free-code-audit-find-out-whats-actually-broken-before-you-spend-another-dollar --- ## Notes for Paul - The blurb is the one piece a busy contact will actually paste, so it carries the booking link. The two request templates hand the blurb over - they don't need the link themselves. -- Tenure claim is **"since 2011"** (from `foundingYear = 2011` - verifiable). Do NOT use "20 years": JetThoughts was founded in 2011 (~15 years), and "20+ years of Rails delivery" isn't true or defensible. Other safe, sourced claims: "95% client retention", "5-year average client relationships", "developers average 8+ years experience". Don't add numbers we can't stand behind. +- Tenure claim is **"since 2008"** (from `foundingYear = 2008` - verifiable; corrected 2026-08-14, this file previously said 2011). Do NOT use "20 years": JetThoughts was founded 2008-09-01 (~18 years), and "20+ years of Rails delivery" isn't true or defensible. Other safe, sourced claims: "95% client retention", "5-year average client relationships", "developers average 8+ years experience", "4.8/5 on Clutch" (link the profile; do NOT state a review count - "32" was unsourced and the real figure is 9). Don't add numbers we can't stand behind. - The `[SPECIFIC THING WE SHIPPED TOGETHER]` line in Template A only lands warm if you fill it with a real, specific memory. If nothing genuine comes to mind for that contact, delete the whole sentence - a mail-merged-sounding line kills the warm channel faster than no line at all. - If a founder replies with a real symptom ("I can't tell if they're making progress," "the repo is under their name"), that's a qualified lead - send them straight to the booking link and log it. diff --git a/test/unit/marketing_copy_test.rb b/test/unit/marketing_copy_test.rb index 3ba04ecbb..afa9ae694 100644 --- a/test/unit/marketing_copy_test.rb +++ b/test/unit/marketing_copy_test.rb @@ -62,7 +62,17 @@ class MarketingCopyTest < Minitest::Test # three different ways in three files - hence all three spellings here. "32 client" => "false review count - Clutch shows 9, link the profile instead", "by 32" => "false review count - Clutch shows 9, link the profile instead", - "thirty-two clients" => "false review count - Clutch shows 9, link the profile instead" + "thirty-two clients" => "false review count - Clutch shows 9, link the profile instead", + # Same class: a wrong number that lived in many spellings across many files. + # JetThoughts was founded 2008-09-01; the site carried 2011 for years, which + # also made every derived "N+ years" claim three short. Derive tenure from + # site.Params.foundingYear - never hardcode the year (corrected 2026-08-14). + "since 2011" => "stale tenure - founded 2008-09-01; derive from site.Params.foundingYear", + "founded in 2011" => "stale tenure - founded 2008-09-01" + # Deliberately NOT banning "15+ years": it catches staff-experience claims + # ("our fractional CTOs average 15+ years of industry experience") that are + # independent of when the company was founded. Only company-tenure + # spellings belong here. A ban that cannot tell the two apart is noise. }.freeze # Surfaces that render the rating block but are not marketing prose pages. @@ -100,6 +110,10 @@ def marketing_files IDENTIFIER_LINE = /^\s*(identifier\s*=|slug:|url:|pageRef\s*=|aliases:|-\s*\/)/ def banned_phrases_in(path) + per_line_hits(path) + wrapped_hits(path) + end + + def per_line_hits(path) relative = path.sub("#{REPO_ROOT}/", "") File.readlines(path, encoding: "bom|utf-8").each_with_index.flat_map do |line, index| @@ -113,6 +127,29 @@ def banned_phrases_in(path) end end + # Templates wrap prose across lines, so a banned phrase can straddle a line + # break and be invisible to line-by-line matching. careers.html rendered + # "Looking for a Team to Take You to the Next\nLevel?" - the live H1 said + # "next level" and this gate reported clean for a full day. Collapse + # whitespace across the whole file and check again; no line number is + # available for these, so report the file. + def wrapped_hits(path) + relative = path.sub("#{REPO_ROOT}/", "") + + body = File.read(path, encoding: "bom|utf-8") + .lines + .reject { |line| line.match?(IDENTIFIER_LINE) } + .join(" ") + haystack = scrub(body).downcase.gsub(/\s+/, " ") + + BANNED.filter_map do |phrase, reason| + next unless haystack.include?(phrase) + next if per_line_hits(path).any? { |hit| hit.include?(phrase.inspect) } + + "#{relative} (wrapped across lines) #{phrase.inspect} - #{reason}" + end + end + # Slugs, URLs and asset names legitimately keep banned words - # /use-cases/empower-existing-engineering-team/, the SVG # theme/world-class-training, and cover_image: empower-...jpg are @@ -120,8 +157,18 @@ def banned_phrases_in(path) # churn, which buys nothing. Drop both shapes before matching: any token # containing a slash, and any token ending in an asset extension. ASSET_TOKEN = /\S+\.(?:jpe?g|png|svg|webp|gif|ico)\b/i + PATH_TOKEN = %r{/?[\w.-]+(?:/[\w.-]+)+/?} + # Order matters. Tags must go FIRST: a word glued to a closing tag + # ("Level?. def scrub(line) - line.gsub(%r{\S*/\S*}, " ").gsub(ASSET_TOKEN, " ") + line + .gsub(/\{\{.*?\}\}/, " ") # Hugo template expressions + .gsub(/<[^>]*>/, " ") # HTML tags + .gsub(%r{\S*://\S*}, " ") # absolute URLs + .gsub(PATH_TOKEN, " ") # slugs and partial names (theme/world-class-training) + .gsub(ASSET_TOKEN, " ") end end diff --git a/test/unit/testimonial_shortcode_test.rb b/test/unit/testimonial_shortcode_test.rb index 37d357b82..3d84170c0 100644 --- a/test/unit/testimonial_shortcode_test.rb +++ b/test/unit/testimonial_shortcode_test.rb @@ -63,10 +63,17 @@ def test_testimonial_carousel_functionality def test_careers_page_testimonial doc = parse_html_file("careers/index.html") - # The careers page should render successfully + # The careers page should render successfully. Assert the SHAPE - one + # non-empty h1 - not the exact wording. This previously pinned the literal + # copy "Looking for a Team to Take You to the Next", which made the test + # break on any headline edit and, worse, actively enforced a phrase the + # marketing_copy_test ratchet bans ("next level"). Two gates cannot + # disagree about the same string. + headings = doc.css("h1").map { |h| h.text.strip }.reject(&:empty?) + assert_equal 1, headings.length, + "Careers page should render exactly one non-empty h1, got: #{headings.inspect}" + page_text = doc.text - assert page_text.include?("Looking for a Team to Take You to the Next"), - "Careers page should have expected heading" # Verify testimonial from frontmatter renders # Based on careers.html layout, testimonial content is in a specific section diff --git a/themes/beaver/layouts/home.html b/themes/beaver/layouts/home.html index 5440baffe..05743df14 100644 --- a/themes/beaver/layouts/home.html +++ b/themes/beaver/layouts/home.html @@ -317,7 +317,8 @@

Senior teams shipping and rescuing Ruby on - Rails and React products since 2011 - + Rails and React products since + {{ site.Params.foundingYear }} - test-driven, with + itemprop="mainContentOfPage">

@@ -41,8 +40,8 @@

Looking for a Team to Take You to the Next - Level?Write Rails You Would Sign Your Name + To

@@ -439,7 +438,7 @@

{{ $image := .Page.Resources.Get .Page.Params.testimonial.image }} - {{ $title := "John Doe" }} + {{ $title := .Page.Params.testimonial.name | default "JetThoughts team member" }} {{ partial "img/testimonial.html" (dict "image" $image "title" $title) }}
diff --git a/themes/beaver/layouts/page/vibe-code-rescue.html b/themes/beaver/layouts/page/vibe-code-rescue.html index e84eb2b17..c13fab271 100644 --- a/themes/beaver/layouts/page/vibe-code-rescue.html +++ b/themes/beaver/layouts/page/vibe-code-rescue.html @@ -36,7 +36,7 @@

Your MVP looks finished but keeps breaking.
  • Rated on Clutch4.8 / 5
  • Average relationship5 years
  • -
  • Shipping Railssince 2011
  • +
  • Shipping Railssince {{ site.Params.foundingYear }}

@@ -119,7 +119,7 @@

Foundation Reset

Why JetThoughts

-

We've been shipping Ruby on Rails since 2011. We use AI-assisted development to move faster and keep costs honest - which is how we can offer a full rescue at $7,500 when traditional agencies quote $25K-$55K for the same work.

+

We've been shipping Ruby on Rails since {{ site.Params.foundingYear }}. We use AI-assisted development to move faster and keep costs honest - which is how we can offer a full rescue at $7,500 when traditional agencies quote $25K-$55K for the same work.

Our clients rate us 4.8 out of 5 on Clutch, and our average client relationship runs five years. Paul, our CEO, sits on every call as your fractional CTO and turns what the developers are doing into decisions you can actually make - so you stop guessing whether your team is telling you the truth.

You've been burned once. The whole point of the free audit is that you find out where you stand first - with a senior engineer who has no reason to tell you anything but the truth.

diff --git a/themes/beaver/layouts/partials/seo/comprehensive-service-schema.html b/themes/beaver/layouts/partials/seo/comprehensive-service-schema.html index cf4ff9eb5..b1f8da388 100644 --- a/themes/beaver/layouts/partials/seo/comprehensive-service-schema.html +++ b/themes/beaver/layouts/partials/seo/comprehensive-service-schema.html @@ -130,8 +130,8 @@ (dict "@type" "PropertyValue" "name" "Years of Experience" - "value" "13+" - "description" "Combined team experience in technology consulting and development since 2011" + "value" (printf "%d+" (sub now.Year (int site.Params.foundingYear))) + "description" (printf "Combined team experience in technology consulting and development since %d" (int site.Params.foundingYear)) ) (dict "@type" "PropertyValue" diff --git a/themes/beaver/layouts/partials/seo/enhanced-organization-schema.html b/themes/beaver/layouts/partials/seo/enhanced-organization-schema.html index c56e0ab72..ae7c79243 100644 --- a/themes/beaver/layouts/partials/seo/enhanced-organization-schema.html +++ b/themes/beaver/layouts/partials/seo/enhanced-organization-schema.html @@ -20,7 +20,7 @@ "image": "https://jetthoughts.com/assets/images/jetthoughts-og-image.jpg", "description": "Expert software development and technology consulting services with {{ sub now.Year (int site.Params.foundingYear) }}+ years of experience and 95% client retention rate.", - "foundingDate": "2011", + "foundingDate": "{{ site.Params.foundingDate }}", "numberOfEmployees": { "@type": "QuantitativeValue", "value": "15-50" diff --git a/themes/beaver/layouts/partials/seo/shared/organization-data.html b/themes/beaver/layouts/partials/seo/shared/organization-data.html index 7d37e61f3..898a1025c 100644 --- a/themes/beaver/layouts/partials/seo/shared/organization-data.html +++ b/themes/beaver/layouts/partials/seo/shared/organization-data.html @@ -56,7 +56,7 @@ "contactType" "customer service" ) ) - "foundingDate" "2011" + "foundingDate" site.Params.foundingDate "numberOfEmployees" (dict "@type" "QuantitativeValue" "minValue" 10