<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title>HanLHo. - Fractional Architect &amp; Software Product Engineer - agent-skills</title>
    <link rel="self" type="application/atom+xml" href="https://hanlho.com/tags/agent-skills/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://hanlho.com"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2026-03-11T00:00:00+00:00</updated>
    <id>https://hanlho.com/tags/agent-skills/atom.xml</id>
    <entry xml:lang="en">
        <title>Creating architecture diagrams with C4 and coding agents</title>
        <published>2026-03-11T00:00:00+00:00</published>
        <updated>2026-03-11T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://hanlho.com/p/creating-architecture-diagrams-with-c4-and-coding-agents/"/>
        <id>https://hanlho.com/p/creating-architecture-diagrams-with-c4-and-coding-agents/</id>
        
        <content type="html" xml:base="https://hanlho.com/p/creating-architecture-diagrams-with-c4-and-coding-agents/">&lt;p&gt;LLMs can draw diagrams, but you get better results with a conceptual model, a validation loop, and a lightweight verification pass against the codebase than with free-form diagramming.&lt;&#x2F;p&gt;
&lt;p&gt;I used the &lt;a href=&quot;https:&#x2F;&#x2F;c4model.com&quot;&gt;C4 model&lt;&#x2F;a&gt; extensively to map architecture landscapes. Last week I saw an opportunity to catch up with it and try it out with coding agents. I found that modelling architecture in a text-based format with guardrails (a DSL with rules) is easier and more consistent for a coding agent. I tried it out on a small Rust project I know well. This post is a field note of my findings.&lt;&#x2F;p&gt;
&lt;aside class=&quot;sidebar-note sidebar-note-right&quot;&gt;
  &lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;c4model.com&quot;&gt;C4&lt;&#x2F;a&gt; is a zoom-in model for software architecture.&lt;&#x2F;p&gt;
&lt;p&gt;This post discusses only the levels we actually need:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;System context: people and software systems.&lt;&#x2F;li&gt;
&lt;li&gt;Container: deployable&#x2F;runnable things inside a software system.&lt;&#x2F;li&gt;
&lt;li&gt;Component: the main building blocks inside a container.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;A key element for coding agents: C4 can be expressed as a text model (a DSL), so the architecture model can be edited like code and validated&#x2F;exported via a CLI.&lt;&#x2F;p&gt;
&lt;p&gt;C4 is model-as-code: one model, many views&#x2F;diagrams.&lt;&#x2F;p&gt;

&lt;&#x2F;aside&gt;
&lt;h2 id=&quot;the-test-project&quot;&gt;The test project&lt;&#x2F;h2&gt;
&lt;p&gt;To try this out, I used one of my personal projects: a text-based &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;lhohan&#x2F;simple-time-tracker&quot;&gt;time-tracking application&lt;&#x2F;a&gt; with two runtime modes (a CLI and a web dashboard). Both operate on the same domain and the same Markdown time-entry files.&lt;&#x2F;p&gt;
&lt;p&gt;The functionality does not matter much for this post, except for two things. First, the codebase is relatively small and easy to analyse. Second, it is well-structured: ports and adapters, plus behaviour-driven, DSL-based acceptance tests.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;ve used C4 on larger landscapes too. I expect the workflow to translate, but the experience will differ on larger (or less structured) codebases.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;building-the-model&quot;&gt;Building the model&lt;&#x2F;h2&gt;
&lt;p&gt;I started the coding agent session with a direct request to build C4 diagrams for the project at system and container level, with the DSL written first.&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#eff1f5;color:#4f5b66;&quot;&gt;&lt;code&gt;&lt;span&gt;build me a c4 model at system level and container level (as defined by the C4 model).
&lt;&#x2F;span&gt;&lt;span&gt;Please create the DSL first
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;reference: c4model.com
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Below, I&#x27;ll go through the process using the diagrams, but keep in mind these are all generated from a text-based DSL. From the start, the agent produced a working model in the Structurizr DSL. I then gave it a &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;lhohan&#x2F;simple-time-tracker&#x2F;blob&#x2F;790b4799892330714977e7092682a9c9fec72499&#x2F;justfile#L109&quot;&gt;command to run Structurizr CLI&lt;&#x2F;a&gt; as a check at each step.&lt;&#x2F;p&gt;
&lt;p&gt;To start with, the agent inspected the Rust codebase to work out the system boundary. It established one &lt;code&gt;Time Tracker&lt;&#x2F;code&gt; software system with two runtime modes: a CLI and a web dashboard. Both use the same Markdown time-entry files.&lt;&#x2F;p&gt;
&lt;p&gt;(Apologies for the dark diagrams; dark mode was enabled when I took these screenshots. To enlarge them, open the images in a new tab.)&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;img&#x2F;c4-llm-system-1.png&quot; alt=&quot;C4 system context diagram (first pass)&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Here is a summary of the session:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;One of the first decisions was scope: whether to model only the web path or both runtime paths. The choice was to represent them as separate containers.&lt;&#x2F;li&gt;
&lt;li&gt;We modelled a software system, two application containers, an internal datastore for run statistics, and the Markdown time-entry files as an external dependency. That first version was structurally correct.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;img&#x2F;c4-llm-container-1.png&quot; alt=&quot;C4 container diagram (first pass)&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;(I had completely forgotten about the runtime statistics feature ...)&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;After the first version, something felt missing between the Markdown files and the CLI&#x2F;web containers: the shared core logic. In C4 terms, that isn&#x27;t another container; it belongs at component level. So I kept the container model strict and added the component level to make the shared logic explicit.&lt;&#x2F;p&gt;
&lt;p&gt;I initially asked it to model the shared core logic as a container, but the agent pushed back, and the model improved because of it. I asked it to add component views for both runtime containers instead of inventing a fake &lt;code&gt;core&lt;&#x2F;code&gt; container. That preserved a strict container model while making the architecture more insightful.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Naming discussions helped sharpen the model. The agent came up with names I was not sure about, but on a first pass it probably did a better job than I would have. One direction I set explicitly was to name things as close as possible to the codebase. The names were not bad, but this is not where I want to leave room for interpretation.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;To support those component views, we introduced a shared component fragment that both CLI and web could include. That shared layer covered parsing, domain types, reporting, and execution statistics. The result was a more accurate picture of how the code is actually organised.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;img&#x2F;c4-llm-component-cli-1.png&quot; alt=&quot;C4 component diagram for the CLI (first pass)&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Once the model structure felt right, I shifted to presentation. I asked the agent to style it so different roles were easier to distinguish: CLI and web containers, shared components, adapters, renderers, and datastores. Then I asked for rounded boxes and a more explicit person-style user element.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The final result:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;img&#x2F;c4-llm-system-dark-1.png&quot; alt=&quot;C4 system context diagram (styled)&quot; &#x2F;&gt;
&lt;img src=&quot;&#x2F;img&#x2F;c4-llm-container-dark-1.png&quot; alt=&quot;C4 container diagram (styled)&quot; &#x2F;&gt;
&lt;img src=&quot;&#x2F;img&#x2F;c4-llm-component-cli-3.png&quot; alt=&quot;C4 component diagram for the CLI (styled)&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;I have also made &lt;a href=&quot;https:&#x2F;&#x2F;lhohan.github.io&#x2F;simple-time-tracker&#x2F;site&#x2F;&quot;&gt;the generated static site with the diagrams&lt;&#x2F;a&gt; available as it was straightforward to do with help from the agent. You can click the small magnifying glass icons to zoom into the next level.&lt;&#x2F;p&gt;
&lt;p&gt;In summary, this result took several passes: boundaries first; then the component layer; then names aligned with the code; and finally presentation.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-dsl-in-practice&quot;&gt;The DSL in practice&lt;&#x2F;h2&gt;
&lt;p&gt;One important artefact we have not discussed yet: the DSL itself. &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;lhohan&#x2F;simple-time-tracker&#x2F;blob&#x2F;790b4799892330714977e7092682a9c9fec72499&#x2F;docs&#x2F;c4&#x2F;time-tracker.dsl&quot;&gt;Here is the full model&lt;&#x2F;a&gt; with the diagrams defined in the Structurizr DSL. All the edits were done by the agent, including the initial creation from scratch. I reviewed, asked questions, and iterated.&lt;&#x2F;p&gt;
&lt;p&gt;Before this, I typed every box and relationship by hand (scrolling up and down the file, or keeping two windows open), added tech stacks (taking care not to confuse the order of strings), and so on. Using the agent was a major documentation speed boost, and the DSL came out clean and organised the way I prefer: relationships after the element definitions, not inside them.&lt;&#x2F;p&gt;
&lt;p&gt;While I see the risk of not thinking things through, being relieved of painstaking manual element&#x2F;relationship editing, working with agent also gave me:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Iteration close to the code&lt;&#x2F;li&gt;
&lt;li&gt;Meaningful discussions on abstraction levels and naming&lt;&#x2F;li&gt;
&lt;li&gt;A knowledgeable architecture assistant at hand&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Why I think it worked: the model is defined in text, so the agent can edit it like code. C4 provides guardrails through a small number of nested abstraction levels, and the DSL keeps names, descriptions, and styles consistent across views. A CLI tool to validate the model closes the loop, so the agent can check its work as it goes.&lt;&#x2F;p&gt;
&lt;p&gt;In addition, you can ask the LLM to review the model, in the context of the actual codebase or not.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;operationalising-the-workflow&quot;&gt;Operationalising the workflow&lt;&#x2F;h2&gt;
&lt;aside class=&quot;sidebar-note sidebar-note-right&quot;&gt;
  &lt;p&gt;I used Codex CLI with Codex 5.3; any other recent coding agent and model will probably work as well.&lt;&#x2F;p&gt;

&lt;&#x2F;aside&gt;
&lt;p&gt;Going forward, here is how I will instruct LLMs to work with C4 and keep the architecture diagrams up to date.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;agent-skill&quot;&gt;Agent Skill&lt;&#x2F;h3&gt;
&lt;p&gt;First, after completing this experiment, I turned my learning into &lt;strong&gt;a reusable agent skill called &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;lhohan&#x2F;agent-chisels&#x2F;blob&#x2F;c198e00546f1274e3afcdda58dfd74423fcaa29c&#x2F;agentfiles&#x2F;shared&#x2F;skills&#x2F;modelling-c4-diagrams&#x2F;SKILL.md&quot;&gt;&lt;code&gt;modelling-c4-diagrams&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;&lt;&#x2F;strong&gt;, which I can now use from any project.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;agents-md-instructions&quot;&gt;AGENTS.md instructions&lt;&#x2F;h3&gt;
&lt;p&gt;In the project&#x27;s &lt;code&gt;AGENTS.md&lt;&#x2F;code&gt; I added &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;lhohan&#x2F;simple-time-tracker&#x2F;blob&#x2F;790b4799892330714977e7092682a9c9fec72499&#x2F;AGENTS.md?plain=1#L12&quot;&gt;a short reference&lt;&#x2F;a&gt; so future agents can discover the DSL files and know how to validate&#x2F;export. This avoids repeating the discovery work in each new session.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;markdown&quot; style=&quot;background-color:#eff1f5;color:#4f5b66;&quot; class=&quot;language-markdown &quot;&gt;&lt;code class=&quot;language-markdown&quot; data-lang=&quot;markdown&quot;&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;- &lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#d08770;&quot;&gt;**Architecture docs (C4)**&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;: source DSL at &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;`docs&#x2F;c4&#x2F;time-tracker.dsl`&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt; (shared components in &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;`docs&#x2F;c4&#x2F;shared-tracking-core.dsl`&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;); validate with &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;`just architecture-docs-validate`&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;; export static site with &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;`just architecture-docs-export`
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;verification&quot;&gt;Verification&lt;&#x2F;h3&gt;
&lt;p&gt;In this project, the LLM and I used the following commands to verify the output:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Validate C4 Structurizr DSL:
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;structurizr-cli validate -workspace docs&#x2F;c4&#x2F;time-tracker.dsl&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Export C4 diagrams to docs&#x2F;site for inspection (and GitHub Pages publishing)
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;structurizr-cli export -workspace docs&#x2F;c4&#x2F;time-tracker.dsl -format static -output docs&#x2F;site&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;View the architecture documentation
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;open docs&#x2F;site&#x2F;index.html&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;structurizr-interface-to-llm&quot;&gt;Structurizr interface to LLM&lt;&#x2F;h3&gt;
&lt;p&gt;I found the validation loop with the CLI to work well. If the export succeeds, the DSL is valid and the views conform to the tool&#x27;s rules.&lt;&#x2F;p&gt;
&lt;p&gt;That still does not tell you whether the model is accurate, or whether the diagrams communicate well. The &lt;a href=&quot;https:&#x2F;&#x2F;c4model.com&#x2F;diagrams&#x2F;checklist&quot;&gt;C4 diagram review checklist&lt;&#x2F;a&gt; is a good yardstick.&lt;&#x2F;p&gt;
&lt;p&gt;The LLM did not seem to require much extra instruction to create a proper model and views. I pointed it to c4model.com at the beginning of the session, and that may have been enough context. (Hard to tell what it knows or does under the hood.)&lt;&#x2F;p&gt;
&lt;p&gt;The skill I created and referenced above now serves as a main interface.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;&#x2F;h2&gt;
&lt;p&gt;The architecture model and diagrams are insightful artefacts (&quot;pictures can say more than words&quot;). But most of the thinking and modelling usually happens visually, while recording it often becomes a chore. This experiment showed me that LLMs can help keep a model up to date without turning it into a separate manual process.&lt;&#x2F;p&gt;
&lt;p&gt;When the model is constrained (C4) and expressed as text (a DSL), you can version it like code, review it like code, and validate&#x2F;export it through a CLI. Constrained text models plus validation give coding agents a better architecture-diagram workflow than free-form diagramming.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;addendum-next-experiments&quot;&gt;Addendum: Next experiments&lt;&#x2F;h2&gt;
&lt;p&gt;Some follow-ups I might try if I run this workflow again.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;keeping-the-model-in-sync&quot;&gt;Keeping the model in sync&lt;&#x2F;h3&gt;
&lt;p&gt;Work with the LLM to design how to encode parts of the architecture model directly in the codebase. Use the C4 views as shared context, then define a way to keep the model in sync with the implementation. Unless you are using a very principled framework (maybe Spring in Java?), I expect this to be quite custom per project anyway.&lt;&#x2F;p&gt;
&lt;p&gt;Coding agents may lower the barrier to getting started with this kind of non-obvious quality-improvement work.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;verification-beyond-the-cli&quot;&gt;Verification beyond the CLI&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Use an MCP like Chrome DevTools to inspect exported diagrams as a second verification step.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;One concrete use case: manual editing is often required to position boxes and, especially, dependencies. A visual inspection could double-check that no text boxes overlap and that lines do not cross boxes.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Coding agents could be used to evaluate the shape of the architecture outside of the code.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;publishing-and-representation&quot;&gt;Publishing and representation&lt;&#x2F;h3&gt;
&lt;p&gt;Export to Mermaid (or PlantUML) for embedding in the agent&#x27;s instructions, but keep the Structurizr DSL as the source of truth. Split the DSL so documentation for each container or component lives closer to the code.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;a-better-llm-interface-in-tooling&quot;&gt;A better LLM interface in tooling&lt;&#x2F;h3&gt;
&lt;p&gt;This requires changes to Structurizr. It could provide build&#x2F;run instructions for LLMs via an extensive &lt;code&gt;--help&lt;&#x2F;code&gt; output, or ship &lt;a href=&quot;&#x2F;p&#x2F;add-a-cli-subcommand-to-keep-llm-instructions-in-sync&#x2F;&quot;&gt;a dedicated subcommand that prints LLM instructions&lt;&#x2F;a&gt; (similar to &lt;code&gt;bd prime&lt;&#x2F;code&gt;).&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>A skill to support TIL creation</title>
        <published>2026-03-02T00:00:00+00:00</published>
        <updated>2026-03-02T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://hanlho.com/p/a-skill-to-support-til-creation/"/>
        <id>https://hanlho.com/p/a-skill-to-support-til-creation/</id>
        
        <content type="html" xml:base="https://hanlho.com/p/a-skill-to-support-til-creation/">&lt;p&gt;Skills are a great way to introduce capabilities in your agent flows. To support my &quot;The Day I Learned&quot; &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;lhohan&#x2F;til?tab=readme-ov-file#today-i-learned&quot;&gt;repository&lt;&#x2F;a&gt; and &lt;a href=&quot;https:&#x2F;&#x2F;til.hanlho.com&quot;&gt;website&lt;&#x2F;a&gt;, I created a skill to extract learnings from coding and LLM sessions.&lt;&#x2F;p&gt;
&lt;p&gt;The skill below is installed in my global agent settings (&lt;code&gt;AGENTS.md&lt;&#x2F;code&gt;), and from each project I can call it to create a TIL in a dedicated project location.&lt;&#x2F;p&gt;
&lt;p&gt;In my &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;lhohan&#x2F;til&quot;&gt;til project&lt;&#x2F;a&gt;, I also have &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;lhohan&#x2F;til&#x2F;blob&#x2F;3ccfd2a085514871674407fceb711ec15f21c788&#x2F;.work-dir&#x2F;scripts&#x2F;scan-and-move-tils.sh&quot;&gt;a script&lt;&#x2F;a&gt; that collects these across all projects. This is usually where I do some reordering and rewriting, but this skill works well and removes friction when sharing short learning snippets. Instead of creating a markdown file manually in the correct format, this gives me a structured draft that I only need to rework. It is much easier to improve something than to start from a blank canvas.&lt;&#x2F;p&gt;
&lt;p&gt;Full skill definition:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;markdown&quot; style=&quot;background-color:#eff1f5;color:#4f5b66;&quot; class=&quot;language-markdown &quot;&gt;&lt;code class=&quot;language-markdown&quot; data-lang=&quot;markdown&quot;&gt;&lt;span style=&quot;background-color:#dfe1e8;color:#4f5b66;&quot;&gt;---
&lt;&#x2F;span&gt;&lt;span&gt;name: til-learning-partner
&lt;&#x2F;span&gt;&lt;span&gt;description: Use when successful tool usage should be captured as a concise, utilitarian TIL note or Tilly is mentioned.
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;---
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;# TIL Learning Partner
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;## Overview
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;Capture short, practical &amp;quot;Today I Learned&amp;quot; notes from successful outcomes.
&lt;&#x2F;span&gt;&lt;span&gt;Each note is a standalone markdown file in &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;`docs&#x2F;tils&#x2F;`&lt;&#x2F;span&gt;&lt;span&gt; with a slug-only filename.
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;## Trigger Conditions
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;- User asks to capture or write a TIL.
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;- A command&#x2F;tool outcome usage is successful and worth preserving.
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;- User asks to summarize what worked into a reusable note.
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;## Workflow
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;1. Confirm the outcome is successful and concrete.
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;2. Ask one lightweight prompt: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;`Capture this as a TIL?`
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;3. If user declines, do not write a file.
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;4. If user confirms, extract one focused learning:
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;   - Issue solved
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;   - How it was solved
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;   - Key command(s) learned
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;   - Practical takeaway
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;5. Generate a slug from the learning title and save to &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;`docs&#x2F;tils&#x2F;&amp;lt;slug&amp;gt;.md`&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;.
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;6. If &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;`docs&#x2F;tils&#x2F;&amp;lt;slug&amp;gt;.md`&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt; exists, use deterministic suffixes:
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;   - &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;`&amp;lt;slug&amp;gt;-2.md`&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;`&amp;lt;slug&amp;gt;-3.md`&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;, and so on.
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;## Output Contract
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;- Path: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;`docs&#x2F;tils&#x2F;&amp;lt;slug&amp;gt;.md`
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;- Slug rules:
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;  - Lowercase
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;  - ASCII-safe
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;  - Hyphen-separated words
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;  - No date in filename or slug
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;## TIL Template
&lt;&#x2F;span&gt;&lt;span&gt;~~~~&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;markdown
&lt;&#x2F;span&gt;&lt;span&gt;# TIL: &amp;lt;specific issue solved&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;## Issue
&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;one concise problem statement&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;## Solution
&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;what worked and why&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;## Key commands
&lt;&#x2F;span&gt;&lt;span&gt;\```bash
&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;command 1&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;command 2&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;\```
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;## Takeaway
&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;how to apply this next time&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;_Created: YYYY-MM-DD_
&lt;&#x2F;span&gt;&lt;span&gt;~~~~
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;## Guardrails
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;- Keep notes utilitarian, direct, and brief.
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;- Cover one specific learning per file.
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;- Avoid exploratory or uncertain phrasing.
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;- Avoid blog-style storytelling and long introductions.
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;- Do not invent commands or outcomes that were not observed.
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Combining agent skills</title>
        <published>2026-02-26T00:00:00+00:00</published>
        <updated>2026-02-26T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://hanlho.com/p/combining-agent-skills/"/>
        <id>https://hanlho.com/p/combining-agent-skills/</id>
        
        <content type="html" xml:base="https://hanlho.com/p/combining-agent-skills/">&lt;p&gt;A short post on combining skills. It&#x27;s not always clear when a skill will be called or triggered. The easiest way is to put instructions and directly invoke the skill you want by name.&lt;&#x2F;p&gt;
&lt;p&gt;For example, for my &lt;a href=&quot;https:&#x2F;&#x2F;til.hanlho.com&quot;&gt;Today I Learned mini blog site&lt;&#x2F;a&gt;, I have two skills to keep my TILs focussed and concise. One skill evaluates that my text is concise and utilitarian, which is what I expect or aim for in a TIL. And I have a more general skill that I also apply for this blog that creates the text according to UK English &#x27;as done by an English teacher&#x27;.&lt;&#x2F;p&gt;
&lt;p&gt;To combine both, I have the &lt;code&gt;review-til&lt;&#x2F;code&gt; skill that invokes both and specifies the output:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;markdown&quot; style=&quot;background-color:#eff1f5;color:#4f5b66;&quot; class=&quot;language-markdown &quot;&gt;&lt;code class=&quot;language-markdown&quot; data-lang=&quot;markdown&quot;&gt;&lt;span&gt;Review the provided TIL file or text by running both checks in parallel:
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;1. &lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#d08770;&quot;&gt;**TIL Rules Check**&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;: Invoke the &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;`til-rules-checker`&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt; skill to verify content guidelines (word count, focus, clarity, format)
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;2. &lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#d08770;&quot;&gt;**Text Grading**&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;: Invoke the &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;`text-grader`&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt; skill to assess spelling, grammar, and clarity using UK English standards
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;
&lt;&#x2F;span&gt;&lt;span&gt;After both checks complete, provide a unified summary with:
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;- TIL rules verdict (PASS&#x2F;NEEDS REVISION)
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;- Text grade (A&#x2F;B&#x2F;C&#x2F;D&#x2F;F)
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;- Combined list of actionable improvements (if any)
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;
&lt;&#x2F;span&gt;&lt;span&gt;If a file path is provided as an argument, read that file first. If text is provided directly, use that text.
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Note both &lt;code&gt;Invoke the &#x27;...&#x27;&lt;&#x2F;code&gt; instructions.&lt;&#x2F;p&gt;
&lt;p&gt;This works in Codex and Opencode. When I asked to review two TILs at once (&lt;code&gt;Review both non-committed TILs&lt;&#x2F;code&gt;) the result looks like this:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#eff1f5;color:#4f5b66;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Review&lt;&#x2F;span&gt;&lt;span&gt; summary:
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt; beads-query-default-limit.md
&lt;&#x2F;span&gt;&lt;span&gt;      &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt; Word count: 32
&lt;&#x2F;span&gt;&lt;span&gt;      &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt; TIL rules: PASS (focused, clear, non-blog style, utilitarian)
&lt;&#x2F;span&gt;&lt;span&gt;      &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt; Text grade: A (96%)
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt; beads-query-subcommand.md
&lt;&#x2F;span&gt;&lt;span&gt;      &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt; Word count: 55
&lt;&#x2F;span&gt;&lt;span&gt;      &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt; TIL rules: PASS (focused, clear intent, non-blog style, utilitarian)
&lt;&#x2F;span&gt;&lt;span&gt;      &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt; Text grade: B (84%) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;due&lt;&#x2F;span&gt;&lt;span&gt; to grammar issues (hard cap applied)
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;(The reason for the &lt;code&gt;B&lt;&#x2F;code&gt; grade is also detailed in the full output.)&lt;&#x2F;p&gt;
&lt;p&gt;In case you are interested, these are the skills I have currently published online:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;lhohan&#x2F;til&#x2F;blob&#x2F;main&#x2F;.agents&#x2F;skills&#x2F;check-til-rules&#x2F;SKILL.md&quot;&gt;check-til-rules&lt;&#x2F;a&gt;: This is the skill that has my TIL rules.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;lhohan&#x2F;til&#x2F;blob&#x2F;main&#x2F;.agents&#x2F;skills&#x2F;review-til&#x2F;SKILL.md&quot;&gt;review-til&lt;&#x2F;a&gt;: The skill I usually invoke that combines the two skills. The content at the time of writing, aside from the frontmatter, is above.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Experience Report: Building a time-tracking AI assistant</title>
        <published>2026-02-04T00:00:00+00:00</published>
        <updated>2026-02-04T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://hanlho.com/p/experience-report-building-a-time-tracking-ai-assistant/"/>
        <id>https://hanlho.com/p/experience-report-building-a-time-tracking-ai-assistant/</id>
        
        <content type="html" xml:base="https://hanlho.com/p/experience-report-building-a-time-tracking-ai-assistant/">&lt;p&gt;This is a short experience report about using &lt;a href=&quot;https:&#x2F;&#x2F;agentskills.io&#x2F;home&quot;&gt;skills&lt;&#x2F;a&gt; (with Codex and its models) to build a personal AI assistant that helps me maintain my time-tracking log.&lt;&#x2F;p&gt;
&lt;p&gt;To set expectations: the assistant does not manage my calendar or tasks. It helps me keep a time-tracking log that lives in a Markdown file by interpreting logging requests and editing the file for me (while categorising entries correctly).&lt;&#x2F;p&gt;
&lt;p&gt;I start most days with a bit of planning, which means adding entries to that log. The format is completely custom and tailored to my needs, and I wrote a small companion CLI tool, &lt;code&gt;tt&lt;&#x2F;code&gt;, to generate reports from it. (The project is open source on GitHub, but honestly I don&#x27;t think it is useful to anyone other than me.)&lt;&#x2F;p&gt;
&lt;p&gt;To give an idea, this is what a day entry looks like:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;markdown&quot; style=&quot;background-color:#eff1f5;color:#4f5b66;&quot; class=&quot;language-markdown &quot;&gt;&lt;code class=&quot;language-markdown&quot; data-lang=&quot;markdown&quot;&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;## TT 2026-02-04
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;- #admin ##work 30m inbox and daily planning
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;- #prj-content ##work 2h article outline and research notes
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;- #prj-content ##work 1h 30m first draft writing
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;- prj-personal-assistant #llm ##work 1h walking skeleton
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;- prj-personal-assistant #llm ##work 1h create skills
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;- #break ##energy 20m outdoor walk
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;- #learning ##work 1h documentation reading and summary
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And using &lt;code&gt;tt&lt;&#x2F;code&gt;, I can generate reports like:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;markdown&quot; style=&quot;background-color:#eff1f5;color:#4f5b66;&quot; class=&quot;language-markdown &quot;&gt;&lt;code class=&quot;language-markdown&quot; data-lang=&quot;markdown&quot;&gt;&lt;span&gt;Overview 2026-02-04 -&amp;gt; 2026-02-04:
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;- prj-content: 3h 30m
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;- prj-personal-assistant: 2h 00m
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;- learning: 1h 00m
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;- admin: 30m
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;- break: 20m
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;
&lt;&#x2F;span&gt;&lt;span&gt;Total: 7h 20m
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;Breakdown:
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;- ##work: 7h 00m
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;- ##energy: 20m
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Editing the file is not hard, but it is tedious. The goal of this project was not to replace my log format, but to make it easier to operate.&lt;&#x2F;p&gt;
&lt;p&gt;Today I ran a small LLM experiment to make logging less cumbersome. Instead of writing an entry like &lt;code&gt;#prj-personal-assistant #llm #codex ##work 2h Setup walking skeleton&lt;&#x2F;code&gt;, I want to be able to say: &quot;Create a new task to set up a walking skeleton, add tags codex and llm, and attribute the time to the personal assistant project.&quot; And by &quot;say&quot; I mean it literally: I dictate it in normal language, it gets transcribed and sent to the LLM. This turned out to be a surprisingly fast (and fun) experiment with promising first results.&lt;&#x2F;p&gt;
&lt;p&gt;Technical details: I used the Codex agent and its models, mostly Codex 5.2. Working with Codex was smooth, but this post is not about comparing coding agents; I suspect it would work with any capable agent that supports skills.&lt;&#x2F;p&gt;
&lt;p&gt;I started with a log file containing over a year of time entries. That history was a good dataset to prime the LLM on the format: what a day looks like, what an entry line looks like, and how entries should be categorised with tags.&lt;&#x2F;p&gt;
&lt;p&gt;From there I moved into implementation, with a small set of local files and skills.&lt;&#x2F;p&gt;
&lt;p&gt;This is the file tree I ended up with (not ready to call it &quot;architecture&quot; yet):&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;markdown&quot; style=&quot;background-color:#eff1f5;color:#4f5b66;&quot; class=&quot;language-markdown &quot;&gt;&lt;code class=&quot;language-markdown&quot; data-lang=&quot;markdown&quot;&gt;&lt;span&gt;AGENTS.md
&lt;&#x2F;span&gt;&lt;span&gt;skills
&lt;&#x2F;span&gt;&lt;span&gt;├── tt-cli
&lt;&#x2F;span&gt;&lt;span&gt;│   ├── references
&lt;&#x2F;span&gt;&lt;span&gt;│   │   └── command-cheatsheet.md
&lt;&#x2F;span&gt;&lt;span&gt;│   └── SKILL.md
&lt;&#x2F;span&gt;&lt;span&gt;└── tt-log
&lt;&#x2F;span&gt;&lt;span&gt;    ├── references
&lt;&#x2F;span&gt;&lt;span&gt;    │   ├── log-structure.md
&lt;&#x2F;span&gt;&lt;span&gt;    │   ├── tag-inference.md
&lt;&#x2F;span&gt;&lt;span&gt;    │   └── validation.md
&lt;&#x2F;span&gt;&lt;span&gt;    ├── scripts
&lt;&#x2F;span&gt;&lt;span&gt;    │   └── validate_tt_update.py
&lt;&#x2F;span&gt;&lt;span&gt;    └── SKILL.md
&lt;&#x2F;span&gt;&lt;span&gt;time-tracking-log.md
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;code&gt;tt&lt;&#x2F;code&gt; is an abbreviation for &quot;time tracking&quot;.&lt;&#x2F;p&gt;
&lt;p&gt;In practice, &lt;code&gt;AGENTS.md&lt;&#x2F;code&gt; tells the agent which skill to use for which capability:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;markdown&quot; style=&quot;background-color:#eff1f5;color:#4f5b66;&quot; class=&quot;language-markdown &quot;&gt;&lt;code class=&quot;language-markdown&quot; data-lang=&quot;markdown&quot;&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;### Time tracking
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;### Time tracking
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;- Use &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;`tt`&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;, the custom time-tracking CLI, for time-tracking operations.
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;- Use &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;`$tt-log`&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt; for &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;`time-tracking-log.md`&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt; edits, tag inference, and 7h to 8h daily policy checks.
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;- Use &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;`$tt-cli`&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt; for &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;`tt`&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt; command discovery, report commands, and CLI troubleshooting.
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;  - Rule of thumb: log edits&#x2F;validation =&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;`$tt-log`&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;; reporting&#x2F;CLI usage questions =&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;`$tt-cli`&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;.
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The two skills are the heart of the implementation:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;tt-cli&lt;&#x2F;code&gt; handles the &lt;code&gt;tt&lt;&#x2F;code&gt; CLI tool: command discovery, reporting, filters, and general troubleshooting.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;tt-log&lt;&#x2F;code&gt; handles log editing, task insertion, tag inference, section ordering, and policy checks.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;From the start I wanted to use skills because my custom format and tooling are a specialised capability. Initially Codex suggested a single skill, but it was clear to me that reading&#x2F;querying and writing&#x2F;editing were different responsibilities, so I pushed it in that direction (it agreed, ha!).&lt;&#x2F;p&gt;
&lt;p&gt;That split improved the quality of outcomes. Beyond maintainability, making responsibilities explicit made behaviour more predictable, because the CLI skill gives the LLM a way to validate its work. The &lt;code&gt;tt-log&lt;&#x2F;code&gt; skill can focus on reliable edits and validation, while &lt;code&gt;tt-cli&lt;&#x2F;code&gt; handles queries like &quot;how much do I still need to log today?&quot; and validates the log.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;references&lt;&#x2F;code&gt; locations for both skills were set up by the LLM while we created the skills. They are pretty clean in terms of responsibility, and reviewing and refining the split proved useful.&lt;&#x2F;p&gt;
&lt;p&gt;During implementation I also wanted basic checks for &quot;did I log enough today?&quot;, so we added a validation workflow that checks a daily target range (7h to 8h). The logic is always the same, so I had it write a script: &lt;code&gt;skills&#x2F;tt-log&#x2F;scripts&#x2F;validate_tt_update.py&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;I iteratively refined the default logging rules (which tags to use for which kinds of tasks, the fact that not all my days look the same, and so on). I don&#x27;t expect it to be perfect, but I will probably tweak it over the next couple of weeks as exceptions pop up.&lt;&#x2F;p&gt;
&lt;aside class=&quot;sidebar-note sidebar-note-right&quot;&gt;
  &lt;p&gt;As an aside, when finishing up Codex proposed me to create a &#x27;one-page pdf summary&#x27; of this project. I think it did &lt;a href=&quot;&#x2F;pdfs&#x2F;codex-personal-assistant-summary.pdf&quot;&gt;a pretty good job&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;

&lt;&#x2F;aside&gt;
&lt;p&gt;So in short:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Created initial time-tracking skill behaviour for structured log edits based on existing time tracking data.&lt;&#x2F;li&gt;
&lt;li&gt;Split responsibilities into two dedicated skills (&lt;code&gt;tt-log&lt;&#x2F;code&gt; and &lt;code&gt;tt-cli&lt;&#x2F;code&gt;).&lt;&#x2F;li&gt;
&lt;li&gt;Added automated validation for parse integrity, per-day totals, and a daily policy range.&lt;&#x2F;li&gt;
&lt;li&gt;Iteratively refined defaults and behaviour based on real usage (for example, a longer workout-at-noon baseline on Tuesdays).&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Things I can now ask: &quot;I want to fill the rest of the day with work on a project I forgot the tag of. Give me the last 5 projects I recorded time on so I can tell you what to log to.&quot; Before, this was not hard, but it involved a bunch of small chores: checking previous days, finding the right project tag, copying it into a new line, and calculating the time left for the day.&lt;&#x2F;p&gt;
&lt;p&gt;Besides the usefulness (and fun), there was an unexpectedly valuable lesson: AI assistance works best in the same way good code does. Define clear boundaries and add executable checks so changes are easier to make and the system can validate its own work.&lt;&#x2F;p&gt;
</content>
        
    </entry>
</feed>
