<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="http://kaironok.github.io/feed.xml" rel="self" type="application/atom+xml" /><link href="http://kaironok.github.io/" rel="alternate" type="text/html" /><updated>2026-04-24T10:15:13+00:00</updated><id>http://kaironok.github.io/feed.xml</id><title type="html">Katja Kairo</title><subtitle>Write Katja description for your new site here. You can edit this line in _config.yml. It will appear in your document head meta (for Google search results) and in your feed.xml site description.</subtitle><author><name>Katja Kairo</name></author><entry><title type="html">Snuffling Cards JavaScript</title><link href="http://kaironok.github.io/work/snuffling-cards-javascript/" rel="alternate" type="text/html" title="Snuffling Cards JavaScript" /><published>2026-04-22T10:00:00+00:00</published><updated>2026-04-22T10:00:00+00:00</updated><id>http://kaironok.github.io/work/snuffling-cards-javascript</id><content type="html" xml:base="http://kaironok.github.io/work/snuffling-cards-javascript/"><![CDATA[<h1 id="snuffling-cards-javascript">Snuffling Cards JavaScript</h1>

<p class="exp-tracker-app-wrap"><a href="https://snufflingcards.pages.dev/" class="exp-tracker-app-btn">Snuffling Cards App</a></p>]]></content><author><name>{&quot;bio&quot;=&gt;&quot;Let&apos;s build ideas! Reach out via the links below.&quot;, &quot;avatar&quot;=&gt;&quot;assets/images/da.jpeg&quot;, &quot;links&quot;=&gt;[{&quot;label&quot;=&gt;&quot;Email&quot;, &quot;icon&quot;=&gt;&quot;fas fa-fw fa-envelope-square&quot;, &quot;url&quot;=&gt;&quot;mailto:katerina.kairo@gmail.com&quot;}, {&quot;label&quot;=&gt;&quot;LinkedIn&quot;, &quot;icon&quot;=&gt;&quot;fas fa-fw fa-link&quot;, &quot;url&quot;=&gt;&quot;https://www.linkedin.com/in/katja-kairo-b3223546/&quot;}]}</name></author><category term="work" /><category term="javascript" /><category term="frontend" /><category term="software-development" /><summary type="html"><![CDATA[A new software development post about building the Snuffling Cards front-end interface in JavaScript.]]></summary></entry><entry><title type="html">Travel Expense Tracker</title><link href="http://kaironok.github.io/work/expensetracker/" rel="alternate" type="text/html" title="Travel Expense Tracker" /><published>2026-04-03T06:00:00+00:00</published><updated>2026-04-03T06:00:00+00:00</updated><id>http://kaironok.github.io/work/expensetracker</id><content type="html" xml:base="http://kaironok.github.io/work/expensetracker/"><![CDATA[<p><strong>Travel Expense Tracker APP. REST API</strong></p>

<hr />

<p class="exp-tracker-app-wrap"><a href="https://kairono.pythonanywhere.com/" class="exp-tracker-app-btn">Travel Expense Tracker App</a></p>

<hr />

<h1 id="acceptance-criteria-high-level">Acceptance Criteria (High Level)</h1>

<p>High-Level Acceptance Criteria here</p>

<ol>
  <li>Authentication flow works end-to-end</li>
  <li>Add/edit expense with fields: Your name, Expense, Amount, Category.</li>
  <li>Users can create, view, update, and delete their own expenses.</li>
  <li>Input form appears before charts.</li>
  <li>Reporting and analytics</li>
  <li>API contract and documentation consistency</li>
  <li>Postman collection and API reference reflect current payload/validation rules.</li>
  <li>Quality gate (automated tests)
    <ul>
      <li>Fast route/API validation tests pass.</li>
      <li>Playwright E2E happy-path and auth-guard tests pass.</li>
      <li>CI test workflow installs dependencies/browser and runs the suite successfully.</li>
    </ul>
  </li>
</ol>

<h2 id="out-of-scope">Out of Scope</h2>

<p>Password reset email, OAuth/social login, multi-tenant admin, shared wallets, attachments/receipts, budgets, recurring rules, export CSV, non-SQL production DB — not required by this spec unless you extend it.</p>]]></content><author><name>{&quot;bio&quot;=&gt;&quot;Let&apos;s build ideas! Reach out via the links below.&quot;, &quot;avatar&quot;=&gt;&quot;assets/images/da.jpeg&quot;, &quot;links&quot;=&gt;[{&quot;label&quot;=&gt;&quot;Email&quot;, &quot;icon&quot;=&gt;&quot;fas fa-fw fa-envelope-square&quot;, &quot;url&quot;=&gt;&quot;mailto:katerina.kairo@gmail.com&quot;}, {&quot;label&quot;=&gt;&quot;LinkedIn&quot;, &quot;icon&quot;=&gt;&quot;fas fa-fw fa-link&quot;, &quot;url&quot;=&gt;&quot;https://www.linkedin.com/in/katja-kairo-b3223546/&quot;}]}</name></author><category term="work" /><category term="python" /><category term="flask" /><category term="software-development" /><category term="api" /><summary type="html"><![CDATA[This is REST API project article]]></summary></entry><entry><title type="html">Testing Assembly</title><link href="http://kaironok.github.io/public-speaking/TestingAssemble/" rel="alternate" type="text/html" title="Testing Assembly" /><published>2026-03-01T21:13:27+00:00</published><updated>2026-03-01T21:13:27+00:00</updated><id>http://kaironok.github.io/public-speaking/TestingAssemble</id><content type="html" xml:base="http://kaironok.github.io/public-speaking/TestingAssemble/"><![CDATA[<p>Call for Speakers is Open</p>

<hr />

<p>Working on submitting my application. Two topics I currently think about</p>

<div class="columns-wrapper">
<div class="column-box column-green">
<h3>You Can't Test AI Like Software, So What Now?</h3>
<ul>
<li>Why deterministic testing fails</li>
<li>Shift from validation → observation &amp; monitoring</li>
<li>Continuous quality vs release-based quality</li>
<li>The human role in AI quality</li>
</ul>
</div>
<div class="column-box column-blue">
<h3>It Takes More Than QA: Building Quality with Data Teams</h3>
<ul>
<li>Working with data engineers &amp; data scientists</li>
<li>Workshops, shared understanding</li>
<li>Misalignment problems you've seen</li>
<li>Practical collaboration model</li>
</ul>
</div>
</div>

<p><a href="https://testingassembly.fistb.fi/2026/02/17/ta-2026-call-for-speakers/" style="display: inline-block; padding: 10px 20px; margin: 5px; background: linear-gradient(135deg, #414979, #949191); color: #fff; font-weight: bold; text-decoration: none; border-radius: 5px; border: 2px solid #b4b6b431;">✓ Call for Speakers</a></p>]]></content><author><name>{&quot;bio&quot;=&gt;&quot;Let&apos;s build ideas! Reach out via the links below.&quot;, &quot;avatar&quot;=&gt;&quot;assets/images/da.jpeg&quot;, &quot;links&quot;=&gt;[{&quot;label&quot;=&gt;&quot;Email&quot;, &quot;icon&quot;=&gt;&quot;fas fa-fw fa-envelope-square&quot;, &quot;url&quot;=&gt;&quot;mailto:katerina.kairo@gmail.com&quot;}, {&quot;label&quot;=&gt;&quot;LinkedIn&quot;, &quot;icon&quot;=&gt;&quot;fas fa-fw fa-link&quot;, &quot;url&quot;=&gt;&quot;https://www.linkedin.com/in/katja-kairo-b3223546/&quot;}]}</name></author><category term="public-speaking" /><category term="public speaking" /><summary type="html"><![CDATA[This article is about Testing Assembly Talk Preparation.]]></summary></entry><entry><title type="html">When QA meets AI or Everything Everywhere All at Once</title><link href="http://kaironok.github.io/public-speaking/WhenQAmeetsAI/" rel="alternate" type="text/html" title="When QA meets AI or Everything Everywhere All at Once" /><published>2026-03-01T21:13:27+00:00</published><updated>2026-03-01T21:13:27+00:00</updated><id>http://kaironok.github.io/public-speaking/WhenQAmeetsAI</id><content type="html" xml:base="http://kaironok.github.io/public-speaking/WhenQAmeetsAI/"><![CDATA[<p>Presentation for Finnish Testing MeetUp</p>

<h1 id="when-qa-meets-ai-or-everything-everywhere-all-at-once"><strong>When QA meets AI or Everything Everywhere All at Once</strong></h1>

<p><img src="/assets/images/qa.jpeg" alt="from event" /></p>

<hr />

<p>Artificial intelligence is no longer a futuristic concept, it is embedded deeply into today’s digital products, business processes and decision-making systems. As AI continues to evolve at remarkable speed, the role of Quality Assurance must evolve with it. Ensuring quality in AI‑driven systems is no longer about verifying deterministic outputs; it’s about understanding complexity, probabilities and the dynamic nature of systems.</p>

<p>AI’s conceptual roots stretch back to the 1950s, when early researchers sought to build machines capable of imitating human intelligence. Understanding how AI systems learn, reason and evolve has become essential for modern QA.</p>

<p>Unlike traditional software, which follows predefined rules and produces predictable outcomes, AI systems operate probabilistically. They adapt based on data, making them inherently less stable and more prone to unanticipated behavior. This shift requires QA teams to rethink their methods, frameworks and expectations.</p>

<p>During my presentation “When QA Meets AI,” I focused on some challenges we face when testing systems today.
I walked through concept drift, explaining how models can silently lose accuracy as real-world conditions change. I also covered data poisoning, highlighting how even small issues in data quality can significantly impact outcomes. We also explored adversarial testing, showing how subtle, almost invisible input changes can lead to unexpected or incorrect model behavior.</p>

<p>What made this especially valuable was not just the theory, but connecting these topics to real world QA responsibilities how we, as quality professionals, need to detect, question and continuously validate AI systems in changing environments.</p>

<p>The presentation resonated strongly with the audience, sparking discussion and reflection, which felt nice.</p>]]></content><author><name>{&quot;bio&quot;=&gt;&quot;Let&apos;s build ideas! Reach out via the links below.&quot;, &quot;avatar&quot;=&gt;&quot;assets/images/da.jpeg&quot;, &quot;links&quot;=&gt;[{&quot;label&quot;=&gt;&quot;Email&quot;, &quot;icon&quot;=&gt;&quot;fas fa-fw fa-envelope-square&quot;, &quot;url&quot;=&gt;&quot;mailto:katerina.kairo@gmail.com&quot;}, {&quot;label&quot;=&gt;&quot;LinkedIn&quot;, &quot;icon&quot;=&gt;&quot;fas fa-fw fa-link&quot;, &quot;url&quot;=&gt;&quot;https://www.linkedin.com/in/katja-kairo-b3223546/&quot;}]}</name></author><category term="public-speaking" /><category term="public speaking" /><summary type="html"><![CDATA[This article is about Hugging Face experiment.]]></summary></entry><entry><title type="html">API Days Conference</title><link href="http://kaironok.github.io/public-speaking/APIDays/" rel="alternate" type="text/html" title="API Days Conference" /><published>2026-02-01T21:13:27+00:00</published><updated>2026-02-01T21:13:27+00:00</updated><id>http://kaironok.github.io/public-speaking/APIDays</id><content type="html" xml:base="http://kaironok.github.io/public-speaking/APIDays/"><![CDATA[<p>Here to communities and events!</p>

<p>I had a chance to attend the API Days Conference in Helsinki, Finland 2025. The conference brought together professionals from the API ecosystem, including developers, architects and business leaders. It was a great opportunity to learn about the latest trends and best practices in API design, development and management.</p>

<h3 id="api-days-conference-in-helsinki-finland">API Days Conference in Helsinki, Finland</h3>
<p><img src="/assets/images/pre.jpeg" alt="from event" /></p>

<hr />

<p>SAVE THE DATE!
APIOps Helsinki 2026 will bring the API community together again in June. This hands-on conference is an opportunity to work on current topics, connect with peers, and learn through workshops, expert panels and APIOps clinics.</p>

<blockquote>
  <p>🗓️ 2.-3.6.2026
📍 Epicenter, Helsinki, Finland</p>
</blockquote>

<p>(Psst! Early bird tickets are on sale now - register early and secure your place at the conference at a reduced price)</p>

<p>Osaango is partnering with apidays and other partners for this event, proudly continuing the APIdays Helsinki tradition.</p>

<p>For 2026 my speech topic is “Boosting API Testing with AI. Postman”, more details in that post  <span style="color: #2bc910; font-weight: bold;">LINK</span> [Boosting API Testing with AI.] (https://silver-palm-tree-5wpjrr79gp9c7959-4000.app.github.dev/ai/PostmanAPI/)</p>]]></content><author><name>{&quot;bio&quot;=&gt;&quot;Let&apos;s build ideas! Reach out via the links below.&quot;, &quot;avatar&quot;=&gt;&quot;assets/images/da.jpeg&quot;, &quot;links&quot;=&gt;[{&quot;label&quot;=&gt;&quot;Email&quot;, &quot;icon&quot;=&gt;&quot;fas fa-fw fa-envelope-square&quot;, &quot;url&quot;=&gt;&quot;mailto:katerina.kairo@gmail.com&quot;}, {&quot;label&quot;=&gt;&quot;LinkedIn&quot;, &quot;icon&quot;=&gt;&quot;fas fa-fw fa-link&quot;, &quot;url&quot;=&gt;&quot;https://www.linkedin.com/in/katja-kairo-b3223546/&quot;}]}</name></author><category term="public-speaking" /><category term="meetup" /><category term="testing" /><category term="community" /><summary type="html"><![CDATA[This article showcases API Days conference events.]]></summary></entry><entry><title type="html">Agentic Copilot</title><link href="http://kaironok.github.io/ai/Copilot-Studio-Agent-Academy/" rel="alternate" type="text/html" title="Agentic Copilot" /><published>2026-02-01T21:13:27+00:00</published><updated>2026-02-01T21:13:27+00:00</updated><id>http://kaironok.github.io/ai/Copilot%20Studio%20Agent%20Academy</id><content type="html" xml:base="http://kaironok.github.io/ai/Copilot-Studio-Agent-Academy/"><![CDATA[<h1 id="copilot-studio-agents">Copilot Studio Agents</h1>

<p>Many of us began with prompt engineering, agents represent a fundamental shift. Copilot Studio Academy allows to get familiar with tools free of charge, for the beginning at least. Here is my journey so far.</p>

<h2 id="recruit-level-it-helpdesk-device-selection-agent">Recruit Level. IT Helpdesk Device Selection Agent</h2>

<p>This agent helps employees choose the right equipment when joining a company or upgrading their devices.</p>

<p><a href="https://microsoft.github.io/agent-academy/recruit/" style="display: inline-block; padding: 10px 20px; margin: 5px; background: linear-gradient(135deg, #414979, #949191); color: #fff; font-weight: bold; text-decoration: none; border-radius: 5px; border: 2px solid #b4b6b431;">✓ Agent Academy Recruit</a></p>

<p>This is DONE.</p>

<hr />
<p><img src="/assets/images/Helpdesk.jpeg" alt="Recruit" />
—</p>

<p>Problem: Employees needs a laptop, and wow cannot decide which one.
Solution: The IT Helpdesk Agent guides users through the decision process.</p>

<p>The agent can:</p>
<ol>
  <li>Recommend suitable devices</li>
  <li>Check compatibility with company standards</li>
  <li>Suggest accessories or additional tools</li>
</ol>

<p>This reduces the number of manual IT requests. The agent acts as a decision support system for IT procurement. The result is not just a response, but a persistent and reusable capability, moving from isolated interactions to designed systems. The Academy articulates this evolution well, agents combine large language models with retrieval mechanisms (RAG) to transition from passive responses to active task execution and automation.</p>

<h2 id="microsoft-copilot-studio-recruit-is-completed">Microsoft Copilot Studio Recruit is Completed</h2>
<p><img src="/assets/images/re.jpeg" alt="Recruit" /></p>

<h1 id="operative-level">Operative Level</h1>

<p>In Operative tasks get more complex. The level focuses on building enterprise-grade multi-agent systems and applying them to real business scenarios using Microsoft Copilot Studio. As part of the course outcomes, I designed and implemented two AI agents:</p>

<p>🤖 Hiring Agent
Automates core hiring workflow orchestration and candidate evaluation.</p>

<p>🎤 Interviewing Agent
Prepares interview materials, analyzes candidate fit, and supports the interview process. The goal was to design Hiring and Interviewing Agents that support recruiters and hiring managers. Key implementation areas are:</p>

<ol>
  <li>Multi-Agent Architecture</li>
  <li>Trigger-Based Automation</li>
  <li>Responsible AI and Safety Controls</li>
  <li>Enterprise Data Grounding</li>
  <li>MCP Server Configuration</li>
</ol>

<h2 id="mission-accomplished">Mission accomplished</h2>

<p><img src="/assets/images/Op.jpeg" alt="Operative" /></p>

<h3 id="interviewing-agent">Interviewing Agent</h3>

<p><img src="/assets/images/IA.jpeg" alt="Operative" /></p>

<hr />

<h3 id="hiring-agent">Hiring Agent</h3>

<p><img src="/assets/images/HA.jpeg" alt="Operative" /></p>

<h2 id="practical-constraints">Practical constraints</h2>

<ul>
  <li>You need the right environment (Microsoft 365, Dataverse, all permissions - you basically admin too)</li>
  <li>Licensing matters</li>
  <li>Some features depend on access levels</li>
  <li>Not everything works out-of-the-box</li>
  <li>In other words: this is real-world engineering</li>
</ul>]]></content><author><name>{&quot;bio&quot;=&gt;&quot;Let&apos;s build ideas! Reach out via the links below.&quot;, &quot;avatar&quot;=&gt;&quot;assets/images/da.jpeg&quot;, &quot;links&quot;=&gt;[{&quot;label&quot;=&gt;&quot;Email&quot;, &quot;icon&quot;=&gt;&quot;fas fa-fw fa-envelope-square&quot;, &quot;url&quot;=&gt;&quot;mailto:katerina.kairo@gmail.com&quot;}, {&quot;label&quot;=&gt;&quot;LinkedIn&quot;, &quot;icon&quot;=&gt;&quot;fas fa-fw fa-link&quot;, &quot;url&quot;=&gt;&quot;https://www.linkedin.com/in/katja-kairo-b3223546/&quot;}]}</name></author><category term="AI" /><category term="testing" /><category term="python" /><summary type="html"><![CDATA[This article is about development and testing with AI.]]></summary></entry><entry><title type="html">Finnish Testing Meetup</title><link href="http://kaironok.github.io/public-speaking/Finnishmeetup/" rel="alternate" type="text/html" title="Finnish Testing Meetup" /><published>2026-02-01T21:13:27+00:00</published><updated>2026-02-01T21:13:27+00:00</updated><id>http://kaironok.github.io/public-speaking/Finnishmeetup</id><content type="html" xml:base="http://kaironok.github.io/public-speaking/Finnishmeetup/"><![CDATA[<p>Here to communities and events!</p>

<p>Meetup events bringing together professionals across testing community. The event combines networking, knowledge sharing with focus on the future of software testing.</p>

<h1 id="finnish-testing-meetup-in-helsinki-finland">Finnish Testing Meetup in Helsinki, Finland</h1>

<p><a href="https://www.meetup.com/finland-testing-meetup-group/" style="display: inline-block; padding: 10px 20px; margin: 5px; background: linear-gradient(135deg, #414979, #949191); color: #fff; font-weight: bold; text-decoration: none; border-radius: 5px; border: 2px solid #b4b6b431;">✓ Find the group here</a></p>

<h2 id="about-participation">About participation</h2>

<p>Last meetup was a great opportunity to meet people and take part in discussions. I contributed to the program by sharing insights and actively participating in conversations about testing practices, challenges and innovation. The event also featured a competition for the Best Tester of the Year, highlighting excellence within the field.</p>

<h2 id="key-takeaways">Key takeaways</h2>

<p>The presentations and discussions strengthened connections within the community and reinforced the importance of continuous learning and quality in testing.</p>

<h2 id="-voting-is-closed-">✨ Voting is closed! ✨</h2>

<p>You can cast your vote <a href="https://www.tieturi.fi/blogi/ehdota-seuraavaa-vuoden-testaajaa/">here</a>.</p>]]></content><author><name>{&quot;bio&quot;=&gt;&quot;Let&apos;s build ideas! Reach out via the links below.&quot;, &quot;avatar&quot;=&gt;&quot;assets/images/da.jpeg&quot;, &quot;links&quot;=&gt;[{&quot;label&quot;=&gt;&quot;Email&quot;, &quot;icon&quot;=&gt;&quot;fas fa-fw fa-envelope-square&quot;, &quot;url&quot;=&gt;&quot;mailto:katerina.kairo@gmail.com&quot;}, {&quot;label&quot;=&gt;&quot;LinkedIn&quot;, &quot;icon&quot;=&gt;&quot;fas fa-fw fa-link&quot;, &quot;url&quot;=&gt;&quot;https://www.linkedin.com/in/katja-kairo-b3223546/&quot;}]}</name></author><category term="public-speaking" /><category term="meetup" /><category term="testing" /><category term="community" /><summary type="html"><![CDATA[This article showcases testing communities events.]]></summary></entry><entry><title type="html">REST API Quality Gates</title><link href="http://kaironok.github.io/ai/RestAPI/" rel="alternate" type="text/html" title="REST API Quality Gates" /><published>2026-02-01T21:13:27+00:00</published><updated>2026-02-01T21:13:27+00:00</updated><id>http://kaironok.github.io/ai/RestAPI</id><content type="html" xml:base="http://kaironok.github.io/ai/RestAPI/"><![CDATA[<h1 id="rest-api-quality-gates">REST API Quality Gates</h1>

<p>If you’re building AI-powered applications, a solid understanding of REST is not optional, it’s foundational. The same principles that made REST the backbone of traditional web systems have made it a perfect fit for AI services: clear resource modeling, stateless interactions, and standard HTTP semantics.</p>

<p>Most AI models don’t manage state. Every request must carry its own context. That’s not a limitation, it’s exactly where REST shines. While refreshing my own skills and preparing for an upcoming APIOps talk, I built my own REST API and defining quality gates around it.</p>

<p>Reframing, while remembering Testing Automation Pyramid by M.Cohn: API testing is not just another layer, it’s the layer where quality gate actually takes shape. Think about it: If you’re working with AI, it’s worth asking: are you validating your system where it matters or only where it’s visible?</p>

<p><a href="https://www.mountaingoatsoftware.com/blog/the-forgotten-layer-of-the-test-automation-pyramid">Testing Automation Pyramid by M.Cohn</a></p>

<p>So how and why API testing adds the layer of quality?</p>

<p><strong>REST API Quality gates</strong></p>

<p><img src="/assets/images/qg.jpeg" alt="Pyramid" /></p>

<p class="exp-tracker-app-wrap"><a href="https://kairono.pythonanywhere.com/tracker" class="exp-tracker-app-btn">Travel Expense Tracker (AI Features in Progress)</a></p>

<p>Before AI new feature change is merged into the Travel Expense Tracker, I expect a certain level of confidence in overall quality. Not assumed, not implied, but verified. And yet, without the structure, these checks are drifting. This is why I started to draft quality gates.</p>

<p>Quality gates are automated checks that must pass before a change is considered ready. They are not just a checklist, but a structure for thinking about where and how we validate behavior. And as with test automation in general, the effectiveness of these gates depends on how well they are distributed.</p>

<p>They follow the same principle as the test automation pyramid: many fast, focused checks at the bottom, and only a few broader, slower checks at the top.</p>

<p>At the foundation are unit-level gates. Fast, precise, and close to the code. When they fail, they point directly to the problem area. This is where most validation should happen, because it is the cheapest place to detect issues and the easiest place to fix them.</p>

<p>Above that sits the <strong>API layer 1</strong>, first in-process. <strong>REST</strong> rules, validation logic, authentication resolution. This layer ensures that the application behaves correctly as a service.</p>

<p>Moving further up, the <strong>API layer 2</strong> is exercised again, but this time over real HTTP. This layer acts as a contract, ensuring that what is exposed externally matches expectations.</p>

<p>At the top are end-to-end gates. These cover critical user journeys: registering, adding an expense, logging out and back in, handling authentication redirects. They are the most visible tests, but also the most expensive. For that reason, they are kept intentionally small in number. Their purpose is not to validate every detail, but to confirm that the system works as a whole.</p>

<p>In practice what often goes wrong is not the absence of tests, but imbalance. Too many checks at the top, too few at the bottom. Too much reliance on slow, brittle validation, and not enough confidence built early. Thinking in Quality gates is meant to correct that imbalance. This ensures that most issues are caught where they are cheapest to fix, while still preserving a thin layer of high-level validation where it matters most.</p>

<p><strong>Journey to be continued ..</strong></p>]]></content><author><name>{&quot;bio&quot;=&gt;&quot;Let&apos;s build ideas! Reach out via the links below.&quot;, &quot;avatar&quot;=&gt;&quot;assets/images/da.jpeg&quot;, &quot;links&quot;=&gt;[{&quot;label&quot;=&gt;&quot;Email&quot;, &quot;icon&quot;=&gt;&quot;fas fa-fw fa-envelope-square&quot;, &quot;url&quot;=&gt;&quot;mailto:katerina.kairo@gmail.com&quot;}, {&quot;label&quot;=&gt;&quot;LinkedIn&quot;, &quot;icon&quot;=&gt;&quot;fas fa-fw fa-link&quot;, &quot;url&quot;=&gt;&quot;https://www.linkedin.com/in/katja-kairo-b3223546/&quot;}]}</name></author><category term="AI" /><category term="testing" /><category term="python" /><summary type="html"><![CDATA[REST API Quality Gates]]></summary></entry><entry><title type="html">Building Website with AI</title><link href="http://kaironok.github.io/work/BuildingWebsiteWithAIAgent/" rel="alternate" type="text/html" title="Building Website with AI" /><published>2026-02-01T11:00:00+00:00</published><updated>2026-02-01T11:00:00+00:00</updated><id>http://kaironok.github.io/work/BuildingWebsiteWithAIAgent</id><content type="html" xml:base="http://kaironok.github.io/work/BuildingWebsiteWithAIAgent/"><![CDATA[<h1 id="building-this-site-with-an-ai-agent-step-by-step">Building this site with an AI agent (step by step)</h1>

<p>This site is a <strong>GitHub Pages</strong> project. Most of the customization, content passes and troubleshooting happened in the editor <strong>together with an AI agent</strong> (the same kind of workflow you get in Cursor, Copilot Chat, or similar): I described the goal, reviewed proposed diffs, ran the site locally, and steered when something looked wrong. Note: document the progress into separate notebook etc., that will help to remember the tasks.</p>

<p>Below is the path we actually followed—not a generic tutorial, but the sequence that got <em>this</em> repository to a shippable state.</p>

<h2 id="1-start-from-a-working-baseline">1. Start from a working baseline</h2>

<ul>
  <li>Jekyll via <strong><code class="language-plaintext highlighter-rouge">github-pages</code></strong>, theme loaded with <code class="language-plaintext highlighter-rouge">remote_theme: mmistakes/minimal-mistakes</code> in <code class="language-plaintext highlighter-rouge">_config.yml</code>, plus the usual plugin group (<code class="language-plaintext highlighter-rouge">jekyll-paginate</code>, <code class="language-plaintext highlighter-rouge">jekyll-feed</code>, and friends in the <code class="language-plaintext highlighter-rouge">Gemfile</code>).</li>
  <li>Synced with GitHub.</li>
  <li>Outcome: One clear source of truth: whatever is on <code class="language-plaintext highlighter-rouge">main</code> is what visitors see after the Pages workflow runs.</li>
</ul>

<h2 id="2-install-gems">2. Install gems</h2>

<ul>
  <li>Installed gems with <code class="language-plaintext highlighter-rouge">bundle install</code> and ran <code class="language-plaintext highlighter-rouge">bundle exec jekyll serve</code> to catch Liquid errors and broken includes before pushing.</li>
  <li>Ruby 3.4 on Windows: the optional <strong><code class="language-plaintext highlighter-rouge">wdm</code></strong> watcher gem was dropped from the <code class="language-plaintext highlighter-rouge">Gemfile</code> because its native extension often fails on newer Ruby—the site still builds; auto-reload during <code class="language-plaintext highlighter-rouge">serve</code> is just a bit slower.</li>
  <li><strong>Outcome:</strong> A repeatable command (<code class="language-plaintext highlighter-rouge">jekyll serve</code>) that validates changes in minutes.</li>
</ul>

<h2 id="3-make-the-site-yours-in-_configyml-and-data-files">3. Make the site <em>yours</em> in <code class="language-plaintext highlighter-rouge">_config.yml</code> and data files</h2>

<ul>
  <li><strong>Site identity:</strong> title, <code class="language-plaintext highlighter-rouge">url</code> / <code class="language-plaintext highlighter-rouge">baseurl</code>, GitHub username, search toggle, and defaults for layouts (posts, pages).</li>
  <li><strong>Author profile:</strong> wired through <strong><code class="language-plaintext highlighter-rouge">_data/authors.yml</code></strong> so posts can set <code class="language-plaintext highlighter-rouge">author: …</code> and pick up bio, avatar, and social links consistently.</li>
  <li><strong>Outcome:</strong> Shared metadata instead of duplicating author blocks in every file.</li>
</ul>

<h2 id="4-layer-a-custom-look-without-forking-the-theme">4. Layer a custom look without forking the theme</h2>

<ul>
  <li><strong><code class="language-plaintext highlighter-rouge">_sass/design-tokens.scss</code></strong> — colors, radii, spacing, and motion variables used across the skin.</li>
  <li><strong>SCSS overrides</strong> — files such as <code class="language-plaintext highlighter-rouge">_sass/default.scss</code>, <code class="language-plaintext highlighter-rouge">nav.scss</code>, <code class="language-plaintext highlighter-rouge">home.scss</code>, <code class="language-plaintext highlighter-rouge">grid_layout.scss</code>, <code class="language-plaintext highlighter-rouge">footer.scss</code>, <code class="language-plaintext highlighter-rouge">post.scss</code>, and <code class="language-plaintext highlighter-rouge">taxonomy.scss</code> adjust layout density, cards, and archive presentation while following the theme’s structure.</li>
  <li><strong><code class="language-plaintext highlighter-rouge">assets/css/custom.scss</code></strong> — entry point that pulls overrides together for the build.</li>
  <li><strong><code class="language-plaintext highlighter-rouge">_includes/head/custom.html</code></strong> — extra font links (for example <strong>Cormorant Garamond</strong>, <strong>Newsreader</strong>, <strong>DM Sans</strong>) and any head snippets the theme leaves open.</li>
  <li><strong><code class="language-plaintext highlighter-rouge">_includes/footer/custom.html</code></strong> — small extensions to the shared footer when needed.</li>
</ul>

<p>We iterated visually more than once: try a direction, preview in the browser, <strong>revert or refine</strong> when something felt too heavy or off-brand. The AI was useful for generating coherent SCSS across many files; <strong>I still chose</strong> what matched the site’s tone.</p>

<h2 id="5-layouts-navigation-and-bilingual-structure">5. Layouts, navigation, and bilingual structure</h2>

<ul>
  <li><strong>Custom layouts</strong> under <code class="language-plaintext highlighter-rouge">_layouts/</code> (for example <code class="language-plaintext highlighter-rouge">home.html</code>, <code class="language-plaintext highlighter-rouge">posts.html</code>, category layouts) shape how listings and hero sections behave.</li>
  <li><strong><code class="language-plaintext highlighter-rouge">_data/navigation.yml</code></strong> and <strong><code class="language-plaintext highlighter-rouge">_data/translations.yml</code></strong> feed the primary nav and language switcher.</li>
  <li><strong><code class="language-plaintext highlighter-rouge">_includes/language-switcher.html</code></strong> connects English pages with their Finnish counterparts.</li>
  <li><strong>Finnish section</strong> lives under <strong><code class="language-plaintext highlighter-rouge">fi/</code></strong> (pages mirrored from the root where it makes sense), and Finnish posts use <code class="language-plaintext highlighter-rouge">lang: fi</code>, <code class="language-plaintext highlighter-rouge">permalink: /fi/...</code>, and <code class="language-plaintext highlighter-rouge">lang_ref</code> back to the English URL.</li>
</ul>

<p><strong>Outcome:</strong> One repo, two languages, with explicit cross-links instead of duplicate sites.</p>

<h2 id="6-content-workflow-posts-as-small-projects">6. Content workflow: posts as small projects</h2>

<ul>
  <li><strong>Each post</strong> is a Markdown file under <code class="language-plaintext highlighter-rouge">_posts/</code> with front matter (<code class="language-plaintext highlighter-rouge">title</code>, <code class="language-plaintext highlighter-rouge">tags</code>, <code class="language-plaintext highlighter-rouge">categories</code>, <code class="language-plaintext highlighter-rouge">header</code>, <code class="language-plaintext highlighter-rouge">description</code>, optional <code class="language-plaintext highlighter-rouge">highlight_home</code>).</li>
  <li><strong>Long-form or spec-style posts</strong> (for example the expense tracker write-up) were drafted in passes: outline → sections → tables → tighten wording; the assistant helped keep structure and terminology consistent.</li>
  <li><strong>Parallel EN/FI posts</strong> share the same factual content; Finnish versions carry translated titles, descriptions, and body copy, plus <code class="language-plaintext highlighter-rouge">lang_ref</code> for pairing.</li>
</ul>

<h2 id="what-worked-well">What worked well</h2>

<ul>
  <li><strong>Concrete prompts</strong> beat vague ones: “match Minimal Mistakes variables,” “do not fork the theme,” “keep <code class="language-plaintext highlighter-rouge">fi/</code> permalinks stable.”</li>
  <li><strong>Letting the agent run terminal checks</strong> (<code class="language-plaintext highlighter-rouge">bundle exec jekyll build</code>, status, diff) caught issues early.</li>
  <li><strong>Treating AI output as a proposal:</strong> always skim the diff; typography and spacing need a human eye.</li>
</ul>

<h2 id="what-i-still-do-myself">What I still do myself</h2>

<ul>
  <li><strong>Final editorial voice</strong> on posts and bios.</li>
  <li><strong>Deciding what <em>not</em> to ship</strong> (experiments removed, dependencies dropped).</li>
  <li><strong>Privacy and accuracy</strong>—anything public-facing is still my responsibility.</li>
</ul>

<hr />

<p>If you are building something similar: clone a Minimal Mistakes starter, turn on <code class="language-plaintext highlighter-rouge">jekyll serve</code>, keep overrides in <code class="language-plaintext highlighter-rouge">_sass</code> + <code class="language-plaintext highlighter-rouge">_includes</code>, and use an AI agent as a <strong>fast editor and refactor partner</strong>—not a substitute for reviewing what goes to <code class="language-plaintext highlighter-rouge">main</code>.</p>

<p><em>Finnish version: <a href="/fi/work/BuildingWebsiteWithAIAgent/">Verkkosivuston rakentaminen tekoälyagentilla</a>.</em></p>]]></content><author><name>{&quot;bio&quot;=&gt;&quot;Let&apos;s build ideas! Reach out via the links below.&quot;, &quot;avatar&quot;=&gt;&quot;assets/images/da.jpeg&quot;, &quot;links&quot;=&gt;[{&quot;label&quot;=&gt;&quot;Email&quot;, &quot;icon&quot;=&gt;&quot;fas fa-fw fa-envelope-square&quot;, &quot;url&quot;=&gt;&quot;mailto:katerina.kairo@gmail.com&quot;}, {&quot;label&quot;=&gt;&quot;LinkedIn&quot;, &quot;icon&quot;=&gt;&quot;fas fa-fw fa-link&quot;, &quot;url&quot;=&gt;&quot;https://www.linkedin.com/in/katja-kairo-b3223546/&quot;}]}</name></author><category term="work" /><category term="software-development" /><summary type="html"><![CDATA[How this GitHub Pages site was built step by step with an AI coding assistant—Jekyll, Minimal Mistakes, design tokens, bilingual content, and practical lessons.]]></summary></entry></feed>