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
33 changes: 22 additions & 11 deletions .github/workflows/site-preflight.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,28 +29,35 @@ jobs:
node-version: "22"

- name: Install audit tools
run: npm install --no-audit --no-fund
run: npm ci --no-audit --no-fund

- name: Prepare reports directory
run: mkdir -p qa-results

# BLOCKING: the bootloader loads these at runtime with no build step.
- name: Check JavaScript syntax
run: |
set -e
for file in ./*.js; do
node --check "$file"
done
run: npm run qa:js

# BLOCKING: guards architecture, footer, truth and QA drift.
- name: Check portfolio architecture consistency
run: npm run qa:portfolio

# BLOCKING: fully determined by the repository, so it cannot flake.
- name: Validate internal links
run: npm run qa:links 2>&1 | tee qa-results/internal-links.txt

# BLOCKING on structural errors only: html-validate exits 0 when just
# warnings remain, so intentional warnings stay visible without gating.
- name: Validate HTML
continue-on-error: true
run: npm run qa:html 2>&1 | tee qa-results/html-validation.txt
run: |
set -o pipefail
npm run qa:html 2>&1 | tee qa-results/html-validation.txt

# BLOCKING: the baseline is genuinely clean (0 issues).
- name: Check English and Turkish spelling
continue-on-error: true
run: npm run qa:spelling 2>&1 | tee qa-results/spelling.txt
run: |
set -o pipefail
npm run qa:spelling 2>&1 | tee qa-results/spelling.txt

- name: Start local site
run: |
Expand All @@ -64,10 +71,12 @@ jobs:
cat qa-results/local-server.log
exit 1

# BLOCKING: a real WCAG2AA failure must not be merged.
- name: Audit accessibility on mobile viewport
continue-on-error: true
run: npm run qa:a11y -- --json > qa-results/accessibility.json 2> qa-results/accessibility-errors.txt

# REPORT-ONLY: performance depends on runner and third-party CDN latency,
# so it must not gate merges. Scores are summarized and uploaded below.
- name: Run Lighthouse CI
continue-on-error: true
run: npm run qa:lighthouse 2>&1 | tee qa-results/lighthouse.txt
Expand Down Expand Up @@ -126,6 +135,8 @@ jobs:
- name: Check out repository
uses: actions/checkout@v5

# REPORT-ONLY: external hosts rate-limit and block bots. Deterministic
# internal links are enforced by the blocking qa:links step above.
- name: Scan HTML and Markdown links
id: lychee
uses: lycheeverse/lychee-action@v2
Expand Down
17 changes: 7 additions & 10 deletions 404.html
Original file line number Diff line number Diff line change
Expand Up @@ -69,18 +69,15 @@ <h1>This route is not deployed yet.</h1>
<footer class="site-footer">
<div class="footer-inner section-shell">
<div>
<a class="footer-brand" href="index.html">
<img alt="Kaan Balcı logo" src="assets/KAAN BALCI-KÜÇÜK LOGO PNG.png"/>
<span>Kaan Balcı</span>
</a>
<p>AI Designer &amp; Software Developer building practical AI workflows and software products.</p>
<a class="footer-brand" href="index.html"><img alt="Kaan Balcı logo" src="assets/KAAN BALCI-KÜÇÜK LOGO PNG.png"/><span>Kaan Balcı</span></a>
<p data-pv2-en="Forward Deployed Engineer building reliable AI systems and product-minded software." data-pv2-tr="Güvenilir AI sistemleri ve ürün odaklı yazılımlar geliştiren Forward Deployed Engineer.">Forward Deployed Engineer building reliable AI systems and product-minded software.</p>
</div>
<div role="group" aria-label="Social links" class="footer-socials">
<a aria-label="Open GitHub profile" href="https://github.com/UAJOP" rel="noopener" target="_blank" title="GitHub"><i aria-hidden="true" class="bx bxl-github"></i></a>
<a aria-label="Open LinkedIn profile" href="https://www.linkedin.com/in/balcikaan/" rel="noopener" target="_blank" title="LinkedIn"><i aria-hidden="true" class="bx bxl-linkedin-square"></i></a>
<a aria-label="Open Instagram profile" href="https://www.instagram.com/kaan_ba1/" rel="noopener" target="_blank" title="Instagram"><i aria-hidden="true" class="bx bxl-instagram"></i></a>
<a aria-label="Open YouTube channel" href="https://www.youtube.com/channel/UCCoOWMoemn93OX7cHyGTZuA" rel="noopener" target="_blank" title="YouTube"><i aria-hidden="true" class="bx bxl-youtube"></i></a>
<a aria-label="Open X profile" href="https://x.com/KaanAjop" rel="noopener" target="_blank" title="X"><i aria-hidden="true" class="bx bxl-twitter"></i></a>
<a aria-label="Open GitHub profile" href="https://github.com/UAJOP" rel="noopener noreferrer" target="_blank" title="GitHub"><i aria-hidden="true" class="bx bxl-github"></i></a>
<a aria-label="Open LinkedIn profile" href="https://www.linkedin.com/in/balcikaan/" rel="noopener noreferrer" target="_blank" title="LinkedIn"><i aria-hidden="true" class="bx bxl-linkedin-square"></i></a>
<a aria-label="Open Instagram profile" href="https://www.instagram.com/kaan_ba1/" rel="noopener noreferrer" target="_blank" title="Instagram"><i aria-hidden="true" class="bx bxl-instagram"></i></a>
<a aria-label="Open YouTube channel" href="https://www.youtube.com/channel/UCCoOWMoemn93OX7cHyGTZuA" rel="noopener noreferrer" target="_blank" title="YouTube"><i aria-hidden="true" class="bx bxl-youtube"></i></a>
<a aria-label="Open X profile" href="https://x.com/KaanAjop" rel="noopener noreferrer" target="_blank" title="X"><i aria-hidden="true" class="bx bxl-twitter"></i></a>
</div>
</div>
<p class="copyright">© <span data-year=""></span> Kaan Balcı. All rights reserved.</p>
Expand Down
85 changes: 28 additions & 57 deletions CAREER_ALIGNMENT_REPORT.md
Original file line number Diff line number Diff line change
@@ -1,67 +1,38 @@
# Kaanbalci.com — Career Alignment 2026

Branch: `career-alignment-2026`

## Scope completed

- Repositioned the public profile around **AI Designer & Software Developer**.
# Career Alignment 2026 — Historical / Superseded

> **This document is historical.** It records the `career-alignment-2026` pass and is kept for provenance only.
>
> **Do not treat anything below as current instructions.** In particular, the "Remaining work" list at the bottom was written before Portfolio Architecture V2 and has since been completed or deliberately replaced. Acting on it today would undo current work.
>
> For the current state, read instead:
>
> - [`README.md`](README.md) — current positioning, page hierarchy and runtime
> - [`PORTFOLIO_ARCHITECTURE.md`](PORTFOLIO_ARCHITECTURE.md) — architecture rules and source-of-truth policy
> - [`portfolio-data.js`](portfolio-data.js) — the live registry of current product, recruiter and build truth
> - [`QA_BASELINE.md`](QA_BASELINE.md) — current measured quality baseline

## What this pass did (2026)

- Consolidated the public target profile around **Forward Deployed Engineer**, with **AI Designer & Software Developer** retained as professional background.
- Prioritized Conversational AI, Solution Engineering, LLM Evaluation, Workflow Automation and user-centered software products.
- Removed GPA/GNO from visible and hidden website content.
- Contextualized the 50+ project statement as academic, personal, freelance and team-based contributions.
- Corrected Atölye Joyday, CBOT, Outlier AI, Punto Organization and Oceans Team titles, dates and descriptions.
- Corrected Atölye Joyday, CBOT, Outlier AI, Punto Organization and Ocean's Team titles, dates and descriptions.
- Moved Gameathon and Mobidictum out of the professional employment timeline into a secondary activities section.
- Reworked Recruiter Mode around one profile, evidence, role fit, selected projects and one resume action.
- Updated Ajoop, Command Palette, translations and dynamic content to use the same career truth set.
- Centralized every public resume action through one JavaScript constant:

```js
const resumeLink = "https://drive.google.com/file/d/1eERVaYoP-ICuP3xfbzpaDaCo5amwqA8u/view?usp=sharing";
```

- Centralized every public resume action through one JavaScript constant.
- Removed the old resume ID and all public role-specific resume options.
- Removed the outdated Portfolio PDF action until a revised portfolio PDF is available.
- Added `games.html` to `sitemap.xml`.

## Changed files

- `index.html`
- `blog.html`
- `about.html`
- `works.html`
- `script.js`
- `style.css`
- `sitemap.xml`
- `README.md`

## Validation performed

- JavaScript syntax validation for all `.js` files.
- Static HTML validation across all pages.
- Checked for duplicate IDs, missing internal page links and missing page titles/H1 elements.
- Forbidden-claim scan for GPA/GNO, outdated titles, predictive-algorithm claims, old resume IDs and outdated portfolio PDF links.
- Responsive browser tests at 1440, 1024, 768, 430, 390 and 360 px widths.
- Desktop and mobile smoke tests for `index.html`, `blog.html` and `about.html`.
- Interaction tests for:
- Theme switching
- Turkish/English switching
- Mobile navigation
- Recruiter Mode
- Command Palette
- Ajoop resume response
- Hero and About resume buttons
- No horizontal overflow, JavaScript console errors or page errors were detected in the tested flows.

## Deployment notes

- Keep the existing repository `assets/` folder unchanged.
- Upload/merge the changed source files from this package.
- Confirm that the Google Drive resume is publicly viewable in an incognito browser before production deployment.
- After deployment, run a live smoke test on `https://kaanbalci.com` because external CDN resources and GitHub Pages routing cannot be fully reproduced in the local package.
## How it has since been superseded

## Remaining work for later stages
| Item from this pass | Current state |
|---|---|
| Recruiter Mode single profile | Replaced by Recruiter Mode V2 with four capability-focused evidence views and backward-compatible `?role=` deep links, all sharing the same Forward Deployed Engineer target. |
| Resume centralized in a script constant | Now also mirrored in the registry as `profile.resume`. |
| "Reorganize Works into Selected Work and Project Archive" | Done: Works is tiered flagship → supporting evidence → archive. |
| "Create stronger static case-study pages" | Done: SINAMA and Merge Rush have dedicated case studies. |
| "Complete project-detail SEO/noindex decisions" | Done: `project-detail.html` is `noindex, follow` and excluded from the sitemap, enforced by the consistency guard. |
| "Create and reconnect a revised Portfolio PDF" | Still intentionally not exposed publicly. |

- Reorganize Works into Selected Work and Project Archive.
- Create stronger static case-study pages for the most important projects.
- Review certificate names, issuers, dates and URLs against official records.
- Complete project-detail SEO/noindex and sitemap decisions.
- Create and reconnect a revised Portfolio PDF only after its content matches the website, CV, LinkedIn and GitHub.
Historical validation notes and deployment steps from the original report are no longer accurate and have been removed to avoid confusion. The current quality baseline lives in [`QA_BASELINE.md`](QA_BASELINE.md).
47 changes: 35 additions & 12 deletions PORTFOLIO_ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Owns:
- Profile and contact truth
- Flagship project summaries
- Project status / stack / proof
- Role-specific recruiter profiles
- One canonical target title plus capability-focused recruiter evidence profiles
- Build log entries
- Labs catalog
- Sanitized SINAMA Evidence Explorer examples
Expand All @@ -31,7 +31,7 @@ Owns:
- Unified EN/TR attribute copy (`data-pv2-en` / `data-pv2-tr`)
- Runtime synchronization of Ajoop with registry facts
- Recruiter Mode V2 rendering
- Role-specific URLs such as `?role=applied-ai`
- Backward-compatible evidence-focus URLs such as `?role=applied-ai`
- Build Log rendering
- Labs rendering
- SINAMA Evidence Explorer rendering
Expand Down Expand Up @@ -70,7 +70,7 @@ A future semantic assistant should be a separate, explicit product step with sou

## Role deep links

Supported role ids:
Supported evidence-focus ids (the legacy `role` query key remains stable):

- `applied-ai`
- `solution-engineering`
Expand All @@ -81,7 +81,7 @@ Example:

`https://kaanbalci.com/?role=applied-ai`

A valid role parameter selects that evidence profile and opens Recruiter Mode.
A valid parameter selects that evidence focus and opens Recruiter Mode. It must never replace the canonical `profile.primaryTitle` value: **Forward Deployed Engineer**. `profile.backgroundTitle` stores **AI Designer & Software Developer** as professional background, not as a competing target.

## Page hierarchy

Expand Down Expand Up @@ -146,19 +146,42 @@ The current direct request endpoint uses Google Apps Script with `no-cors` brows

The UI may show a **browser submission reference**, but must not call it a server confirmation until the endpoint returns a verifiable response with appropriate CORS handling.

## Canonical site footer

Every public page renders one footer component. It is intentionally plain HTML, not a JS-rendered component, so it survives a JavaScript failure.

Contract:

- Kaan Balcı logo and name, linked to `index.html`
- the current positioning sentence, translated through the V2 `data-pv2-en` / `data-pv2-tr` pattern
- exactly five public social destinations: GitHub, LinkedIn, Instagram, YouTube, X
- the copyright line

Canonical truth lives in `portfolio-data.js`:

- `profile.socials` — the five canonical URLs
- `profile.footerTagline` — the bilingual positioning sentence

The HTML keeps static `href`s; `qa-portfolio-consistency.js` verifies every rendered footer against the registry. Change the registry first, then the footers, so drift is caught rather than merged.

Each icon-only link carries an accessible name and an `aria-hidden` icon, and external links use `target="_blank"` with `rel="noopener noreferrer"`.

## QA

The Site Preflight workflow remains the release safety net and now includes JavaScript syntax validation for all root JS files. V2 adds `labs.html` and `now.html` to Pa11y and Lighthouse coverage.
The Site Preflight workflow is the release gate. Checks whose outcome is fully determined by the repository block a merge; checks that depend on the network or runner load are report-only.

Blocking: JavaScript syntax, portfolio consistency, internal links, structural HTML errors, spelling, Pa11y WCAG 2 AA.

Report-only: Lighthouse, external link availability.

The QA toolchain is pinned in `package.json` with a committed `package-lock.json`, and CI installs with `npm ci`, so a given revision reproduces the same checks later. See `SITE_PREFLIGHT.md` for the rationale and `QA_BASELINE.md` for the current measured baseline.

Before merge:

1. JavaScript syntax validation
2. HTML validation
3. spelling
4. mobile Pa11y
5. Lighthouse
6. broken-link scan
7. interaction review for Recruiter Mode V2, language switch, Ajoop, role deep links and SINAMA Evidence Explorer
1. `npm ci`
2. `npm run qa`
3. Pa11y and Lighthouse against a locally served copy
4. interaction review for Recruiter Mode V2, language switch, Ajoop, role deep links and the SINAMA Evidence Explorer

## Migration note

Expand Down
Loading
Loading