Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions .claude/commands/sync-sources.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ You are running the NoMoreApply source sync. This command is triggered after new

- All team members (Angel Aytov, Catalin Waack, Cosmin Poieana) are male. Use he/him pronouns in all profile prose.
- Bullet text in `sources/` must never contain manual line breaks. Write each bullet as a single continuous line; let the PDF engine wrap naturally.
- Brand red accent is `#e8002d`. Do not use `#DC143C`.
- Brand red accent is `#DC143C` (confirmed against the live nomoreapply.com; matches the `nma` repo source).
- Writing style rules are in `CLAUDE.md`: no em dashes, no AI filler, concrete outcomes, active voice.

## 1. Identify updated resources
Expand All @@ -25,7 +25,8 @@ For each person with new resources, follow CLAUDE.md procedure 2 (Syncing resour

- Read **all** resource files for that person in `resources/` (not just the newest)
- Synthesize into their `sources/*.md` file: brochure-style, not a CV dump
- The sharpest version of each section: Summary (2-3 sentences, lead with outcome), Expertise (5-8 bullets, technically specific, no manual line breaks), Notable Work (3-5 highlights with company + outcome), Tech Stack (categorized), Background (education, distinctions, community)
- The sharpest version of each section: Summary (2-3 sentences, lead with outcome and strongest claim, first paragraph self-contained and under ~50 words since the team brochure extracts it verbatim), Expertise (5-8 bullets, technically specific, no manual line breaks), Notable Work (**capped at 6**; rank candidates by named brand → hard number → recency → positioning fit → technical distinctiveness to decide which 6 survive, demote the rest to `## Also` as one-liners, then order the surviving 6 chronologically by end date descending; brand-first naming, e.g. `VONQ via Wandercode`, `ElectaCar for Navigator Insurance Brokers`), Tech Stack (categorized), Background (education, distinctions, community)
- Update `proof:` front matter (3-4 metric-led fragments) if a new resource surfaces a stronger number or brand
- Remove `<!-- TODO -->` comments for any gaps that are now filled
- Keep remaining TODOs for still-missing data
- Log a source-level audit trail entry in `docs/audit-trail.md` (see CLAUDE.md format)
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/build-pdfs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,12 @@ jobs:
uses: actions/cache@v5
with:
path: /tmp/pandoc.deb
key: pandoc-3.9.0.2
key: pandoc-3.11

- name: Install Pandoc
run: |
if [ ! -f /tmp/pandoc.deb ]; then
curl -sLo /tmp/pandoc.deb https://github.com/jgm/pandoc/releases/download/3.9.0.2/pandoc-3.9.0.2-1-amd64.deb
curl -sLo /tmp/pandoc.deb https://github.com/jgm/pandoc/releases/download/3.11/pandoc-3.11-1-amd64.deb
fi
sudo dpkg -i /tmp/pandoc.deb

Expand All @@ -46,12 +46,12 @@ jobs:
uses: actions/cache@v5
with:
path: /usr/local/bin/typst
key: typst-0.14.2
key: typst-0.15.1

- name: Install Typst
if: steps.cache-typst.outputs.cache-hit != 'true'
run: |
curl -sL https://github.com/typst/typst/releases/download/v0.14.2/typst-x86_64-unknown-linux-musl.tar.xz \
curl -sL https://github.com/typst/typst/releases/download/v0.15.1/typst-x86_64-unknown-linux-musl.tar.xz \
| tar -xJ --strip-components=1 -C /usr/local/bin typst-x86_64-unknown-linux-musl/typst

- name: Build PDFs
Expand Down
1 change: 1 addition & 0 deletions AGENTS.md
37 changes: 24 additions & 13 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# CLAUDE.md: NoMoreApply/services

This file and `.claude/commands/` are the single source of truth for agent instructions in this repo. `AGENTS.md` is a symlink to this file, kept for tools that look for that name specifically. Never fork it into a real copy: a duplicate freezes at whatever it was at migration time and silently drifts out of sync with every change made here. If a tool ever writes a standalone `AGENTS.md` or an `.agents/` directory, that is a bug in the migration, not a second source of truth: delete it and re-symlink.

## Project

PDF brochure pipeline for the NoMoreApply engineering collective. Converts per-person Markdown profiles into polished PDFs (one team brochure + individual pages) via Pandoc + Typst, built automatically in CI and published to GitHub Pages.
Expand All @@ -10,15 +12,16 @@ PDF brochure pipeline for the NoMoreApply engineering collective. Converts per-p

**Template:** `templates/nomoreapply.typ` — design aligned to nomoreapply.com brand.

**Design tokens:**
**Design tokens** (canonical table, keep in sync with `templates/nomoreapply.typ`):
- Background: `#FAFAFA` (off-white)
- Text: `#09090B` (near-black)
- Accent: `#e8002d` (NMA brand red — role lines, team taglines only)
- Secondary: `#71717A` (muted grey)
- Text primary: `#09090B` (near-black, also the dark-band fill)
- Text secondary: `#52525B`
- Text tertiary / eyebrow: `#71717A` (muted grey), faint variant `#A1A1AA`
- Accent: `#DC143C` (NMA brand red, confirmed against the live nomoreapply.com: role lines, team taglines, accent bars only)
- Dividers: `#E4E4E7` (light grey rules and card borders)
- Font: Inter, weights 400/600/700
- Name: 26pt bold, tracking -0.02em
- Section headings: 7.5pt bold uppercase, tracking 0.1em, grey rule
- Section headings: 7.5pt bold uppercase eyebrow (`#A1A1AA`), tracking 0.12em, 2pt red accent bar above

**Fallback option:** WeasyPrint/CSS - if Typst hits layout limitations. Document trigger and rationale in `docs/audit-trail.md` before switching.

Expand All @@ -44,12 +47,17 @@ All prose in `sources/` must follow these rules. Apply them when extracting or e

## Source Markdown Schema

Each `sources/*.md` file must follow the same YAML front matter + H2 section structure so the template can consume them consistently. Sections in order:
1. `## Summary`
2. `## Expertise`
3. `## Notable Work`
4. `## Tech Stack`
5. `## Background`
Each `sources/*.md` file must follow the same YAML front matter + H2 section structure so the template can consume them consistently.

**Front matter** additionally carries `proof:`, a list of 3-4 metric-led fragments (e.g. `"7 of 10 DAX companies"`). This renders as the stat band under the contact line. Avoid `@word` in these fragments and in body prose generally: Pandoc parses it as a citation (`#cite(<word>, ...)`), which fails the build with "the document does not contain a bibliography" since there is no bibliography configured.

**Body sections, in order:**
1. `## Summary` - 2-3 sentences. Lead with the outcome and the strongest claim, not biography. The team brochure (`scripts/assemble-team.sh`) extracts only the **first paragraph** (up to the first blank line) for the team card, so keep that opening paragraph self-contained and under ~50 words.
2. `## Expertise` - 5-8 bullets. The team brochure also extracts the **first 4 bullets** here, so lead with the strongest ones.
3. `## Notable Work` - **capped at 6 entries.** Write each as an H3 heading (company/project) followed by an italic meta line (`*Role · Years*`), then prose or bullets. Italics are reserved for this meta line only (the template renders all `*emphasis*` at 9pt muted grey document-wide, so inline emphasis in prose reads as a rendering glitch, not a style choice). Adding a 7th entry means demoting one to `## Also`. Ranking rubric decides which entries make the cut, applied in order: named client or brand a buyer recognises → a hard number → recency → fit with current positioning → technical distinctiveness (ties break toward recency). Every full entry needs at least one number; no metric means it belongs in `## Also`. **Order the entries chronologically** (by end date descending, then start date descending) rather than by rubric strength, so the section reads as a timeline. For an entry titled by the company you delivered through, put the recognisable brand first: `VONQ via Wandercode`, not `Wandercode via VONQ`. For an entry titled by a product you built for a client, use `for`: `ElectaCar for Navigator Insurance Brokers`.
4. `## Also` - one-liners for demoted or minor work. Keep brand names visible, cut the detail.
5. `## Tech Stack` - Categorized list: languages, frameworks, infra, AI/ML tools.
6. `## Background` - Education, distinctions, speaking, community.

Gaps (e.g. missing CV data) are marked with `<!-- TODO: ... -->` comments inline.

Expand All @@ -64,6 +72,7 @@ When new material arrives for a person (CV, LinkedIn export, website snapshot, p
1. Place the file in `resources/` with the naming convention `{FirstName}_{LastName}-{type}-{DD_MM_YYYY}.ext`, using today's date.
2. Add or update the corresponding entry in `metadata.yml`: file, person, type, source_url, added date, notes.
3. If this replaces an older file of the same type, keep the old file (historical record) and add the new one alongside it with the updated date suffix.
4. If the resource was written for a specific role or audience (e.g. a CV targeted at an iOS position), add a `target:` field to its `metadata.yml` entry recording that intent. A role-targeted resource describes the same work through a different lens: mine it for facts, never let its framing drive the person's positioning.

Do not edit \`sources/\` yet. That is a separate step.

Expand All @@ -74,8 +83,10 @@ When resources have been updated and the source markdown needs to reflect them:
1. Read the relevant files in `resources/` for the person being updated.
2. Extract and distill content into the person's `sources/*.md` file, following the schema above. This is a one-way sync: `resources/` is the source of truth.
3. Keep the prose tight: brochure-style, not a CV dump. Each section should be the sharpest possible version of the person's story.
4. Mark any gaps where data is unavailable with `<!-- TODO: describe what's missing -->`.
5. Do not touch other people's source files in the same operation.
4. **Enforce the cap.** `## Notable Work` never exceeds 6 entries. Adding one means ranking all candidates by the rubric in the schema section above and demoting the weakest to `## Also`. Never just append.
5. Update `proof:` in front matter whenever a new hard number or brand surfaces that outranks what's currently there.
6. Mark any gaps where data is unavailable with `<!-- TODO: describe what's missing -->`.
7. Do not touch other people's source files in the same operation.

After editing `sources/`, the commit and push triggers CI. PDFs rebuild automatically.

Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ $(TEAM_PDF): $(TEAM_MD) $(TEMPLATE) | $(OUTDIR)
--variable=team:true \
-o $@ $<

$(TEAM_MD): $(SOURCES)/team.md $(addprefix $(SOURCES)/,$(addsuffix .md,$(MEMBERS))) | $(OUTDIR)
$(TEAM_MD): $(SOURCES)/team.md $(addprefix $(SOURCES)/,$(addsuffix .md,$(MEMBERS))) scripts/assemble-team.sh | $(OUTDIR)
bash scripts/assemble-team.sh $@ $(SOURCES)/team.md $(addprefix $(SOURCES)/,$(addsuffix .md,$(MEMBERS)))

$(OUTDIR):
Expand Down
24 changes: 24 additions & 0 deletions docs/audit-trail.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,30 @@

---

**2026-09-04** - Code review fixes: heading orphans, metadata-injection bug, agent-file duplication

Decision: Fixed a Typst template bug where `#name$`, `$role$`, and `$proof$` were interpolated inside `"..."` string literals. Pandoc renders substituted metadata as content, not a string, so a `proof:` item containing a quote or `@mention` broke the build with a syntax error, and one containing `~` or `*emphasis*` printed escaped Typst source into the PDF. Fixed at the interpolation site by switching to `[...]` content blocks; verified with a synthetic `proof:` value containing all four characters. Separately fixed the level-2/3 heading show rules, which returned loose `text()` + `v()` and had discarded Typst's default heading-to-body stickiness, the opposite of the intended fix: reproduced two profiles ending a page on a bare heading. Wrapped both in `block(sticky: true)` and deleted the unused `workentry()` helper that was meant to do this but was never called. Added `breakable: false` to team member cards, which were splitting across the page break. Extended `scripts/assemble-team.sh`'s escaping to `[ ] < >`, since `]` closes the Typst content block the injected text lands inside and was not covered. Replaced the untracked `AGENTS.md` and `.agents/skills/source-command-sync-sources/SKILL.md`, both frozen copies of this repo's pre-PR state from an earlier migration (same-second timestamps), with a tracked `AGENTS.md` symlink to `CLAUDE.md` and deletion of `.agents/`, so there is one source of truth instead of a copy that silently reverts on the next sync. Reordered `## Notable Work` chronologically (end date descending) in all three profiles per the schema, corrected `via` direction to lead with the recognisable brand (`VONQ via Wandercode`, `Mercedes-Benz via DEMICON`), and introduced `for` for a product built for a named client (`ElectaCar for Navigator Insurance Brokers`). Trimmed Cosmin's Summary opening paragraph to the ~50-word cap the schema introduced but the file itself violated. Replaced Angel's proof-band claim of "15+ years" with a dated-range fragment, since the same diff that added it also flagged the years figure as unverified in a `<!-- TODO -->`.

Rationale: A full review of the branch caught that two of the PR's headline claims (heading orphan protection, unescaped-injection safety) were not actually true of the shipped code, which the pre-existing audit entry above has now been corrected to reflect rather than left standing.

---

**2026-09-04** - Positioning overhaul: brand red correction, distillation cap, template rebuild

Decision: Corrected the brand accent from `#e8002d` back to `#DC143C` after confirming against the live nomoreapply.com (`about-*.js` and its CSS carry 13+ occurrences of `#DC143C`, zero `#e8002d`) and the `nma` repo source (19 occurrences). The 2026-04-09 "correction" to `#e8002d` was itself wrong. Added a `proof:` front-matter field (3-4 metric fragments rendered as a stat band) and a `## Also` section to the source schema, with `## Notable Work` capped at 6 entries and a ranking rubric (named brand → hard number → recency → positioning fit → technical distinctiveness). Rebuilt `templates/nomoreapply.typ`: running header on pages 2+, accent bars above section headings, two-tone H3 + italic-meta work entries, a proof band under the contact line, `block(sticky: true)` on section and work-entry headings so they can't strand at page bottoms, coherent bullet spacing (the old `#set list` / `#show list: set par` pair contradicted each other), and one dark CTA band on the team brochure. Fixed two bugs in `scripts/assemble-team.sh`: the team-card summary window took the first 4 non-empty lines (pulling in a full paragraph plus testimonial) instead of the first paragraph, and member text was injected into Typst content unescaped for `# $ @ \ [ ] < >`. Bumped CI's pinned Pandoc/Typst (3.9.0.2/0.14.2 to 3.11/0.15.1) to match local dev, closing a toolchain gap that could pass locally and fail in CI. Added a `target:` metadata field for role-targeted resources (a CV written for a specific role describes the same work through a different lens; it should be mined for facts, not read as a repositioning signal).

Rationale: Catalin's feedback ("layout looks broken and I think the positioning is too weak") traced to one root cause across all three profiles: the sync process accumulates Notable Work entries and never evicts (his had grown to 14, Angel's to 9), so proof gets buried in prose instead of leading the page. The template was still its original minimum-viable draft and implemented none of `nma/references/design.md`'s "proof over promises" or "no walls of text" principles. Considered switching to LaTeX per Catalin's suggestion; rejected, since the 2026-04-06 switch to Typst was for build speed (XeLaTeX took 3-5 minutes vs Typst's seconds) and every device his LaTeX CV uses (header, accent rule, two-tone entries) is a few lines of Typst once actually written.

---

**2026-09-04** - Updated all three profiles: capped Notable Work, added proof bands, mined Catalin's iOS CV

What changed: Catalin's `## Notable Work` cut from 14 to 6 full entries (ElectaCar/Navigator Insurance Brokers, HeyAmigo+AmigoEngine, VOXR, FAMFAM via DAYONE, Syntax, BreakEats), remainder moved to `## Also`. Role and Summary rewritten to lead with his "the model is rarely the bottleneck" positioning and DAX/government proof instead of a "started at 14" biography opening. Mined his new iOS-targeted CV for facts absent from the AI-consultant CV: ElectaCar's client is Navigator Insurance Brokers, 100+ vehicle models, Syntax's 100+ instructors and 27,000+ quiz results, AmigoEngine pairing, BreakEats' nine frequency bands and Swift/LiveKit/WebRTC detail, the new open-source TailRemote project, VoxR as revenue-share employment. Angel's Notable Work cut from 9 to 6 (kept AI Expert, DEMICON/Mercedes-Benz, Toyota Connected, Credit Suisse, Y TREE, Metapack; demoted Smart Wealth AG and Trading 212), and the unexplained 2009-2017 timeline gap against his "over 15 years" claim is now flagged with a `<!-- TODO -->` instead of left silent. Cosmin's file was already at the 6-entry cap; no cuts, but promoted previously-buried proof (two acquisitions, 5,000+ job channels, 10k-user community, ~2B tokens/month) into the new `proof:` field.

Why: New resource added (`resources/Catalin_Waack-cv-ios-04_09_2026.pdf`, an iOS-role-targeted CV Catalin sent alongside his layout feedback). Cross-referencing it against the existing AI-consultant CV surfaced facts neither prior sync had captured. The cap and rubric come from the same-day schema change (see pipeline decision above) and were applied to all three profiles in one pass since the accumulation problem was universal, not Catalin-specific.

---

**2026-09-04** - Updated Catalin: refreshed CV and website resynced

What changed: Corrected the 2024 job history: the "DAYONE, Senior Frontend" entry was conflating two different clients. FAMFAM (Keinemusik DJ collective music/event app, React Native/Expo/TypeScript, 12,000+ users, App Store Top 10 Music) is now its own entry via DAYONE; the AEM migration work is a separate client, Verlag des Österreichischen Gewerkschaftsbundes. Added ElectaCar (2026), Google Ads Operations Platform (2026), and expanded Rivoara to cover the paired Runtime Affiliate platform. Updated Heyamigo's npm downloads to 15,000+ (was 2,000). Rewrote Summary to lead with 20 years in tech, independent since 2018, the "model is rarely the bottleneck" positioning quote, and added the OneCode GmbH testimonial. Corrected location from Romania to Germany (remote, EU/international). Expanded Tech Stack with AI/agent tooling confirmed on both sources: LangChain/LangGraph, Haystack, RAGFlow, MCP, GEO/LLMO, Temporal, pgvector, Drizzle ORM, Google Ads API, Shopify Admin API. Corrected edeltravel/Luxury Essence entry to cover both the travel publishing platform (170+ articles) and the design framework, dated 2022-2023.
Expand Down
2 changes: 1 addition & 1 deletion docs/blueprints/about-page.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ Match nomoreapply.com exactly:
- Background: `#f5f5f3` (light cream)
- White sections: `#ffffff`
- Near-black text: `#111111`
- Accent: `#e8002d` (red used sparingly: hero accents, value highlights, CTAs)
- Accent: `#DC143C` (red, used sparingly: hero accents, value highlights, CTAs)
- Muted text: `#777777`
- Borders: `#e2e2de`
- Font: Inter (weights 400–900) + JetBrains Mono for labels and metadata
Expand Down
Loading