<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
<channel>
<title><![CDATA[ Chronicles of Technology ]]></title>
<description><![CDATA[ Thoughts, stories and ideas. ]]></description>
<link>https://chronicler.tech</link>
<image>
    <url>https://chronicler.tech/favicon.png</url>
    <title>Chronicles of Technology</title>
    <link>https://chronicler.tech</link>
</image>
<lastBuildDate>Wed, 22 Apr 2026 09:19:46 -0400</lastBuildDate>
<atom:link href="https://chronicler.tech" rel="self" type="application/rss+xml"/>
<ttl>60</ttl>

    <item>
        <title><![CDATA[ Cline: Bring Your Own AI ]]></title>
        <description><![CDATA[ Keeping playing with local models and surrounding services, I replaced the original Ollama service with its lean and fast relative - Llama.cpp. The transition didn&#39;t sit well with the VS Code Cline plugin, so I had to conduct some research and make a few changes. ]]></description>
        <link>https://chronicler.tech/cline-bring-your-own-ai/</link>
        <guid isPermaLink="false">69c5ca777528d6000158257a</guid>
        <category><![CDATA[  ]]></category>
        <dc:creator><![CDATA[  ]]></dc:creator>
        <pubDate>Mon, 30 Mar 2026 11:38:45 -0400</pubDate>
        <media:content url="https://chronicler.tech/content/images/2026/03/autonomous-art-nuvoue.jpg" medium="image"/>
        <content:encoded><![CDATA[ <p>Keeping playing with local models and surrounding services, I replaced the <a href="https://chronicler.tech/cline-use-local-workstation" rel="noreferrer">original Ollama service</a>&nbsp;with its lean and fast relative - <a href="https://github.com/ggml-org/llama.cpp?ref=chronicler.tech" rel="noreferrer">Llama.cpp</a>. The transition didn't sit well with the VS Code Cline plugin, so I had to conduct some research and make a few changes.   </p><p>Although Ollama and Llama.cpp are close relatives, the disparity API is significant enough to break the Cline functionality. Short research yielded two alternatives: an OpenAI-compatible API and an Anthropic-compatible API. </p><p>I have decided to start with the Anthropic option, but quickly gave up. Anthropic provider for Cline allows you to specify a custom model endpoint, but model names are pre-coded, and you can only choose one from the dropdown. Reasonably enough, my server container declines messages with an unknown model name. </p><p>Next try was for the "OpenAI Compatible" provider. This provider is fully customizable and can either retrieve the list of models registered on the server or allow you to specify any other model name. </p><div class="kg-card kg-callout-card kg-callout-card-blue"><div class="kg-callout-emoji">❓</div><div class="kg-callout-text">Due to unknown reasons, it didn't work for me. Nut I just paste the active model name into the field to match the preloaded one.</div></div><p>Since I started the server with the GPT OSS argument  <em>--gpt-oss-20b-default, </em>the  model name for the Cline configuration is <strong>gpt-oss-20b. </strong>Another difference from Ollama, the OpenAI-compatible provider requires the API key. Use one if you define it through the server configuration, or put any value if your server is not protected. </p><p>Save the provider configuration, and select your new model for plans and acts.  </p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://chronicler.tech/content/images/2026/03/Screenshot-2026-03-26-at-6.13.27---PM.png" class="kg-image" alt="" loading="lazy" width="2000" height="1347" srcset="https://chronicler.tech/content/images/size/w600/2026/03/Screenshot-2026-03-26-at-6.13.27---PM.png 600w, https://chronicler.tech/content/images/size/w1000/2026/03/Screenshot-2026-03-26-at-6.13.27---PM.png 1000w, https://chronicler.tech/content/images/size/w1600/2026/03/Screenshot-2026-03-26-at-6.13.27---PM.png 1600w, https://chronicler.tech/content/images/size/w2400/2026/03/Screenshot-2026-03-26-at-6.13.27---PM.png 2400w" sizes="(min-width: 720px) 720px"><figcaption><span style="white-space: pre-wrap;">Local Model linters the project code.</span></figcaption></figure><p> There are no new takeaways or revelations:</p><ul><li> Local models, as good as your acceleration hardware. On the RTX3060, the 12 GB of video RAM drastically limits the size of models you can run and response speed. </li><li> The same limits force the usage of smaller context windows, which makes your agent a little bit dimmer than its youngest relatives. </li><li>Although the modern models do not demonstrate record speeds, the local model is more like a human; some answers take minutes to process and complete. Be patient.  </li><li>You may experiment with agents and skills, but you may want to keep your configuration files very lean. </li></ul><p>With all that said, I keep my local agent for simple executions that do not require complex autonomy or deep reasoning and planning. Especially if you know the limitations and can deal with them.  </p> ]]></content:encoded>
    </item>
    <item>
        <title><![CDATA[ Autonomously create a multi-tiered web application using VS Code + Cline + Claude Sonnet (round 2) ]]></title>
        <description><![CDATA[ In this rather lengthy post, I&#39;ll describe how I went about using agentic AI code generation to autonomously create, build, and deploy a custom web application from scratch.

I submitted 1 prompt that initially described the application I wanted, followed by 12 more follow-up prompts throughout the duration ]]></description>
        <link>https://chronicler.tech/autonomously-create-a-multi-tiered-web-application-using-vs-code-cline-claude-sonnet-round-2/</link>
        <guid isPermaLink="false">69b6ff777528d6000158228f</guid>
        <category><![CDATA[  ]]></category>
        <dc:creator><![CDATA[  ]]></dc:creator>
        <pubDate>Mon, 16 Mar 2026 20:14:06 -0400</pubDate>
        <media:content url="https://chronicler.tech/content/images/2026/03/Untitled-1.png" medium="image"/>
        <content:encoded><![CDATA[ <p>In this rather lengthy post, I'll describe how I went about using agentic AI code generation to autonomously create, build, and deploy a custom web application from scratch.</p><p>I submitted 1 prompt that initially described the application I wanted, followed by 12 more follow-up prompts throughout the duration of the session for a <strong>total of 13 prompts</strong>. The session lasted an <strong>estimated 6-7 hours </strong>and the <strong>total cost was $28.9049</strong> utilizing <strong>Anthropic Claude Sonnet 4.6 </strong>as the LLM (this model was released on February 17, 2026).</p><p>What I want to see is if modern day AI agents can design, develop, and deploy a 3-tier application to the cloud autonomously with little to no human intervention (hint: it can):</p><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/image-72.png" class="kg-image" alt="" loading="lazy" width="1096" height="580" srcset="https://chronicler.tech/content/images/size/w600/2026/03/image-72.png 600w, https://chronicler.tech/content/images/size/w1000/2026/03/image-72.png 1000w, https://chronicler.tech/content/images/2026/03/image-72.png 1096w" sizes="(min-width: 720px) 720px"></figure><p>The current state of autonomous AI coding agents is honestly impressive. If you look at the software development lifecycle diagram below, the large majority of the steps were actually successfully performed by the AI agent.</p><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/llnkedin-cloud-architecture.png" class="kg-image" alt="" loading="lazy" width="990" height="475" srcset="https://chronicler.tech/content/images/size/w600/2026/03/llnkedin-cloud-architecture.png 600w, https://chronicler.tech/content/images/2026/03/llnkedin-cloud-architecture.png 990w" sizes="(min-width: 720px) 720px"></figure><p>So are we able to go from "idea" to "production" in a matter of hours? Yes, it's getting there.</p><p>A little of the prerequisite content below is reused from <a href="https://chronicler.tech/autonomously-create-a-multi-tiered-web-application-using-vs-code-cline-claude-opus/" rel="noreferrer">this blog post</a> of mine which was an earlier attempt from a few days ago, but this post is a different example and a slightly better documented effort.</p><p>(Note: I use "Cline" and "AI agent" interchangeably in this post.)</p><h2 id="what-is-autonomous-code-generation">What is Autonomous Code Generation?</h2><p>Let's get a few concepts clarified first.</p><p><em>AI code generation</em> is generally meant to refer to a developer's use of AI to assist in code generation through human prompting. The human (i.e., developer) types what he'd like to see, and the AI somehow automagically creates the code.</p><p>I use the term <em>autonomous code generation </em>where through the use of human prompts, an AI agent independently performs multiple steps of the software development lifecycle, including coding the application, building it (i.e., packaging it), and deploying it. The level of autonomy can become a topic of debate, which I'll shed some light on.</p><p>The following screenshot is one of the pages of the completed application. I deem the exercise a success. I could have continued engaging the AI agent to refine the application, enhance the look-and-feel even further, add more functionality, enable security, create separate non-production and production environments in the cloud, and so on. It would just take longer and cost more money.</p><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/image-58.png" class="kg-image" alt="" loading="lazy" width="1432" height="1651" srcset="https://chronicler.tech/content/images/size/w600/2026/03/image-58.png 600w, https://chronicler.tech/content/images/size/w1000/2026/03/image-58.png 1000w, https://chronicler.tech/content/images/2026/03/image-58.png 1432w" sizes="(min-width: 720px) 720px"></figure><h3 id="what-was-i-aiming-for">What was I aiming for?</h3><p>I remember coming across this table from <a href="https://www.stride.build/thought-leadership/the-6-levels-of-codegen-automation?ref=chronicler.tech" rel="noreferrer">Stride Conductor</a> a couple of years ago that laid out the different levels of AI code automation. It's hard to believe that just two years ago we were floating around <em>Level-2 Semi-Autonomous</em>, and here we are today almost nearly reaching <em>Level 5 Full Automation</em>.</p><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/image-61.png" class="kg-image" alt="" loading="lazy" width="1026" height="635" srcset="https://chronicler.tech/content/images/size/w600/2026/03/image-61.png 600w, https://chronicler.tech/content/images/size/w1000/2026/03/image-61.png 1000w, https://chronicler.tech/content/images/2026/03/image-61.png 1026w" sizes="(min-width: 720px) 720px"></figure><p>The purpose of this exercise is to see if we're able to reach automation <em>Level 4</em> or even a <em>Level 5 </em>(note: it was a Level 4).</p><p>The entire development process was 100% autonomous, the build phase was 100% autonomous, and the deployment steps were 95% autonomous. Deployment included provisioning all Oracle Cloud Infrastructure (OCI) services and resources, creating sample data, inserting seed data into the database, downloading free-to-use images, installing an <em>nginx </em>reverse proxy and <em>Gunicorn</em> server, as well as deploying/configuring the Python application in a compute instance.</p><p>I provided minimal guidance to the AI agent on the design of the target cloud architecture. The only mandate was to store all data in an Oracle Autonomous AI Database and to try to use as many free tier services within OCI as possible.</p><p>Lots of bugs in the code and errors during deployment were encountered, but the AI agent worked through all of it on its own.</p><p>There were a couple of areas of confusion/conflict between me and the AI agent. For example, I had updated all the API token values in the <code>terraform.tfvars</code> early on in the process (this was practically the only manual step needed), but it was overwritten later when the AI agent started creating all the Terraform files. Also, I manually added a second approved sender in the Email Delivery service on the OCI console (to send out emails), and I'm guessing it would not have worked if I let the AI agent do it since there was a permission exception on the console and I had to use elevated access to perform this particular step.</p><p>But aside from these two manual interventions, the rest of the process was entirely autonomous.</p><h2 id="software-tools-used">Software Tools Used</h2><p>In this exercise, I attempted to leverage certain tools to perform autonomous code generation. These multiple tools and services included:</p><ol><li><strong>Visual Studio Code </strong>(aka VS Code) - A lightweight, extensible source code editor (i.e., IDE) from Microsoft with a large ecosystem of extensions for many programming languages.</li><li><strong>Cline </strong>- An open-source AI coding assistant that integrates with development environments such as VS Code to autonomously plan, write, modify, and run code using large language models such as Claude Sonnet.</li><li><strong>Claude Sonnet </strong>- Anthropic’s best performance-value large language model (LLM) designed for reasoning, coding, and problem-solving tasks.</li><li><strong>Oracle Cloud Infrastructure </strong>(aka OCI) - Oracle’s enterprise cloud platform that provides compute, storage, networking, databases, and AI services for building and running scalable applications.</li></ol><p>Essentially the only software you need to download is VS Code to get started. Later on during development, other tools such as Terraform and various Python packages will be downloaded automatically by the AI agent.</p><h2 id="summary-of-steps">Summary of Steps</h2><p>This is a list of all activities performed, and each one is detailed below.</p><ol><li>Create an API key to access the Claude models</li><li>Download and install VS Code</li><li>Install the Cline extension in VS Code</li><li>Set up your API provider and model in Cline</li><li>Create an empty project</li><li>Add a Cline rules files (optional)</li><li>Decide on auto-approve for the AI agent</li><li>Write an initial prompt to design your application</li><li>Ask the AI Agent (Cline) to create a "Plan"</li><li>Switch to "Act" mode for the AI agent to generate the code</li><li>Get the required API tokens from the OCI Console (manual step)</li><li>Let Cline provision the cloud resources autonomously</li><li>Manually verify the database objects (optional)</li><li>Test the application</li><li>Generate SMTP credentials (manual)</li><li>Create a cloud architecture diagram (optional)</li><li>Generate documentation summary (optional)</li><li>Shutdown the cloud servers to save money (optional)</li></ol><hr><h2 id="1-create-an-api-key-to-access-the-claude-models">1. Create an API key to access the Claude models</h2><p>You will need to create an account on the Claude platform, create an API key, and purchase some credits. This API key will be con</p><ol><li>Navigate to <a href="https://platform.claude.com/?ref=chronicler.tech" rel="noreferrer">platform.claude.com</a> and create a free account.</li></ol><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/image-16.png" class="kg-image" alt="" loading="lazy" width="1028" height="593" srcset="https://chronicler.tech/content/images/size/w600/2026/03/image-16.png 600w, https://chronicler.tech/content/images/size/w1000/2026/03/image-16.png 1000w, https://chronicler.tech/content/images/2026/03/image-16.png 1028w" sizes="(min-width: 720px) 720px"></figure><ol start="2"><li>After logging in, click on "API Keys --&gt; Create Key", give your key any name, click "Add", and copy the value of the API and store it somewhere (<strong>it will never be displayed again, so save it someplace safe!</strong>).</li></ol><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/image-17.png" class="kg-image" alt="" loading="lazy" width="1432" height="734" srcset="https://chronicler.tech/content/images/size/w600/2026/03/image-17.png 600w, https://chronicler.tech/content/images/size/w1000/2026/03/image-17.png 1000w, https://chronicler.tech/content/images/2026/03/image-17.png 1432w" sizes="(min-width: 720px) 720px"></figure><ol start="3"><li>Click on "Settings --&gt; Billing --&gt; Buy credits" and purchase any amount of credits to start with (e.g., $10). </li></ol><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/image-18.png" class="kg-image" alt="" loading="lazy" width="1432" height="666" srcset="https://chronicler.tech/content/images/size/w600/2026/03/image-18.png 600w, https://chronicler.tech/content/images/size/w1000/2026/03/image-18.png 1000w, https://chronicler.tech/content/images/2026/03/image-18.png 1432w" sizes="(min-width: 720px) 720px"></figure><h2 id="2-download-and-install-vs-code">2. Download and install VS Code</h2><p>Download and install the VS Code IDE. This is a straightforward process.</p><ol><li>Navigate to <a href="https://code.visualstudio.com/download?ref=chronicler.tech">code.visualstudio.com/download</a>, then download and install the software.</li></ol><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/image-15.png" class="kg-image" alt="" loading="lazy" width="1432" height="734" srcset="https://chronicler.tech/content/images/size/w600/2026/03/image-15.png 600w, https://chronicler.tech/content/images/size/w1000/2026/03/image-15.png 1000w, https://chronicler.tech/content/images/2026/03/image-15.png 1432w" sizes="(min-width: 720px) 720px"></figure><h2 id="3-install-the-cline-extension-in-vs-code">3. Install the Cline extension in VS Code</h2><p>Cline is an autonomous coding agent that is used inside VS Code and is available via an extension. Alternatives include Claude Code and Oracle Code Assist.</p><ol><li>Open VS Code.</li><li>Click on the "Extensions" button on the left.</li><li>Search for "cline".</li><li>Click on "Install". </li></ol><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/image-19.png" class="kg-image" alt="" loading="lazy" width="632" height="370" srcset="https://chronicler.tech/content/images/size/w600/2026/03/image-19.png 600w, https://chronicler.tech/content/images/2026/03/image-19.png 632w"></figure><p>Cline is now ready for use.</p><h2 id="4-set-up-your-api-provider-and-model-in-cline">4. Set up your API provider and model in Cline</h2><p>Now that Cline is installed, it's not still ready for use. Cline relies on a 3rd party LLM model of your choice. Now that we've created an API key within Claude from earlier, we will use those values here.</p><ol><li>If the Cline sidebar is not showing in VS Code, click on the <em>Toggle Secondary Side Bar</em> button on the top right or click CTRL+ALT+B.</li><li>Click on the <em>Settings</em> icon.</li><li>Select "Anthropic" as the API Provider.</li><li>Enter the API key that you created in the Claude platform console.</li><li>Select a model such as "claude-sonnet-4.6".</li></ol><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/image-20.png" class="kg-image" alt="" loading="lazy" width="1440" height="622" srcset="https://chronicler.tech/content/images/size/w600/2026/03/image-20.png 600w, https://chronicler.tech/content/images/size/w1000/2026/03/image-20.png 1000w, https://chronicler.tech/content/images/2026/03/image-20.png 1440w" sizes="(min-width: 720px) 720px"></figure><p>Now Cline, your AI chatbot and agent, is ready for use!</p><h2 id="5-create-an-empty-project">5. Create an empty project</h2><p>Start with an empty project.</p><ol><li>Click on "File".</li><li>Click on "Open Folder" and select an empty folder on your local file system.</li></ol><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/image-64.png" class="kg-image" alt="" loading="lazy" width="621" height="368" srcset="https://chronicler.tech/content/images/size/w600/2026/03/image-64.png 600w, https://chronicler.tech/content/images/2026/03/image-64.png 621w"></figure><h2 id="6-add-a-cline-rules-files-optional">6. Add a Cline rules files (optional) </h2><p>Cline rules files are markdown documents (<code>.md</code> files) that define persistent instructions and coding standards for Cline, stored in the <code>/.clinerules</code> directory to maintain consistent behavior across sessions.</p><p>Cline rules serve as a persistent memory for Cline, which otherwise resets completely between sessions, ensuring consistent behavior and adherence to project-specific standards.</p><ol><li>Create a subfolder in your project called <code>.clinerules</code>.</li><li>Create one or more filenames (e.g., <code>coding.md</code>, <code>testing.md</code>) and in plain English describe the rules for your standards.</li></ol><p>Below is a single rules files that I created with some basic rules. If you are using a specific programming language, you can be more specific in your rules and coding standards.</p><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/image-32.png" class="kg-image" alt="" loading="lazy" width="2000" height="1183" srcset="https://chronicler.tech/content/images/size/w600/2026/03/image-32.png 600w, https://chronicler.tech/content/images/size/w1000/2026/03/image-32.png 1000w, https://chronicler.tech/content/images/size/w1600/2026/03/image-32.png 1600w, https://chronicler.tech/content/images/2026/03/image-32.png 2160w" sizes="(min-width: 720px) 720px"></figure><h2 id="7-decide-on-auto-approve-for-the-ai-agent">7. Decide on auto-approve for the AI agent</h2><p>Before you start engaging with Cline (by pressing the play button, highlighted in red), note the sections highlighted in blue first.</p><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/image-65.png" class="kg-image" alt="" loading="lazy" width="1440" height="664" srcset="https://chronicler.tech/content/images/size/w600/2026/03/image-65.png 600w, https://chronicler.tech/content/images/size/w1000/2026/03/image-65.png 1000w, https://chronicler.tech/content/images/2026/03/image-65.png 1440w" sizes="(min-width: 720px) 720px"></figure><p> It's important to understand a few things.</p><p><strong>Plan or Act?</strong></p><p>Typically, you want to select "Plan" first. Cline here generates a step-by-step strategy and it doesn't actually do anything. It will not create any code. It will not perform any actions. It will simply present you with a proposed plan of what it intends on doing. This allows you to refine your design before asking the AI agent to implement it.</p><p>With Plan:</p><ul><li>No changes are made.</li><li>No files are edited.</li><li>No commands are executed.</li></ul><p>Agentic AI systems can be dangerous if they act immediately. Plan gives you a preview of the AI's reasoning and intended actions.</p><p>In Act mode, Cline executes the plan.</p><p>It will read and edit files, run terminal commands, download and install dependencies, run builds, create and update code, and so on.</p><p><strong>Auto-approve or not?</strong></p><p>Auto-approve controls whether the developer must approve each operation during Act mode.</p><p>If auto-approve is on, as shown in the last figure above, Cline will automatically perform certain actions without asking. It is not unusual to be asked for hundreds of approvals in a single session, so setting auto-approve may seem tempting, but it obviously comes with its risks.</p><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/image-34.png" class="kg-image" alt="" loading="lazy" width="372" height="632"></figure><p>In this exercise, I had set auto-approve on every action; reading files, editing files, and executing commands.</p><h2 id="8-write-an-initial-prompt-to-design-your-application">8. Write an initial prompt to design your application</h2><p>In a text editor, start by creating a prompt of the application. Here is the prompt I spent time writing for my "Presidents of the United States" application.</p><pre><code class="language-AI prompt">1. PROJECT NAME: "Presidents of the United States"

Act as an expert Full-Stack Cloud Architect and Python Developer. Your goal is to build a modern, serverless web application deployed on Oracle Cloud Infrastructure (OCI) using Python.

2 GOAL:
- Create a simple, modern, visually impressive web application that provides basic information of all presidents of the United States of America.

3. FUNCTIONAL REQUIREMENTS:
- The web application will be called "Presidents of the United States".
- The web application should use a modern, responsive UI.
- The web application should default to a dark mode style, but provide the ability to switch to a light style.
- The welcome page of the application should be a simple welcome page, where the user clicks on "Enter" or something like that to enter the application.
- The second page should be a gallery of every single president. Every president should have a professional looking, flattering photo.
- Each president will have a tag line under it, giving an impression of that president.
- There should be a thumbs up and a thumbs down icon. Clicking on the thumbs up icon will show a popup with text that describes a notable or impressive feat this president has done. Clicking on the thumbs down icon will show a popup with text that describes a major failing or shameful act that this present has done.
- There should be an option to click on the president to take it to a detailed page of the president.
- The detailed page should provide at least a page of details of each president. On this page, there should be a mail icon, where clicking it will popup a field that requests an email address, and the details of the president will be emailed to that email address.

4. NON-FUNCTIONAL REQUIREMENTS
- The web application should use a modern and stylistic CSS template.
- None of the pages requires authentication, so all pages are publicly accessible.
- The web application will be deployed to Oracle Cloud Infrastructure (OCI).
- Emails should be sent in HTML format using the OCI Email Delivery service.
- On the bottom of each page will be a footer that states "© 2026 Path Infotech LLC".
- Include Terraform scripts to automatically provision all required infrastructure. 
- Any combination of services is acceptable, but the simpler the architecture, the better.
- The web application should be developed in Python.
- Provide test cases and instructions on how to run the test cases.
- The code should include comments describing some information throughout the code.
- Detailed instructions to create the infrastructure within OCI should be provided.
- Detailed instructions to deploy the web application to OCI should be provided.
- Include anything relevant you think should be added.
- The web application should be publicly accessible.
- The database should be Oracle Autonomous Database in OCI that stores the details of each president.
- Use a serverless architecture as much as possible.
- All OCI services provisioned should include a tag with a tag name of "webapp" and value "uspresidents".
- Use free tier services within OCI whenever possible.
- Provide instructions on how to install, setup, and execute the Infrastructure-as-Code scripts.
- Provide instructions to setting up the public/private RSA key pair on the client host where Terraform will be executed.
- Provide instructions on where to place the Terraform configuration file information returned from the OCI console.
- I want you create the public/private key pair, and after I upload the public key to the OCI console, I will update "terraform.tfvars", afterwards I want you to perform all provisioning, deployment, and testing fully autonomously on your own.</code></pre><p>In an ideal scenario, I would be much more specific in my functional requirements, dictating navigation paths, grid layout, text I wanted to see, and so on. I would also add more technical requirements, detailing the language, services, and frameworks I want to use, add any restrictions and constraints, and so on.</p><p>Some people like starting with a light prompt as you see above, and continue engaging the AI agent to continue refining it, while others (such as myself) prefer spending the effort up front to be as specific as possible.</p><h2 id="5-ask-the-ai-agent-cline-to-create-a-plan">5. Ask the AI agent (Cline) to create a "Plan"</h2><p>Now that the prompt is created, it's time to submit it to Cline.</p><ol><li>Paste the entire prompt in the box.</li><li>Click on "Plan".</li><li>Click on the play button.</li></ol><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/image-35.png" class="kg-image" alt="" loading="lazy" width="2000" height="1183" srcset="https://chronicler.tech/content/images/size/w600/2026/03/image-35.png 600w, https://chronicler.tech/content/images/size/w1000/2026/03/image-35.png 1000w, https://chronicler.tech/content/images/size/w1600/2026/03/image-35.png 1600w, https://chronicler.tech/content/images/2026/03/image-35.png 2160w" sizes="(min-width: 720px) 720px"></figure><p>Cline will take several minutes and start spitting out output. Up until this point, the cost was $0.0801.</p><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/image-37.png" class="kg-image" alt="" loading="lazy" width="2000" height="1183" srcset="https://chronicler.tech/content/images/size/w600/2026/03/image-37.png 600w, https://chronicler.tech/content/images/size/w1000/2026/03/image-37.png 1000w, https://chronicler.tech/content/images/size/w1600/2026/03/image-37.png 1600w, https://chronicler.tech/content/images/2026/03/image-37.png 2160w" sizes="(min-width: 720px) 720px"></figure><p>Scrolling down through the output, I can see all the services that Cline intends on using.</p><p>WARNING: The brief text architecture in the last image was not the final architecture that Cline actually used. At some point it decided to go a different route when it ran started running into deployment errors during execution.</p><p>Cline stated that it would use the API Gateway, Functions, Object Storage, and Container Registry. None of these were used in the end.</p><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/-2D546456-D6ED-442C-B742-C2E6BCBAFF06-.png" class="kg-image" alt="" loading="lazy" width="2000" height="454" srcset="https://chronicler.tech/content/images/size/w600/2026/03/-2D546456-D6ED-442C-B742-C2E6BCBAFF06-.png 600w, https://chronicler.tech/content/images/size/w1000/2026/03/-2D546456-D6ED-442C-B742-C2E6BCBAFF06-.png 1000w, https://chronicler.tech/content/images/size/w1600/2026/03/-2D546456-D6ED-442C-B742-C2E6BCBAFF06-.png 1600w, https://chronicler.tech/content/images/2026/03/-2D546456-D6ED-442C-B742-C2E6BCBAFF06-.png 2032w" sizes="(min-width: 720px) 720px"></figure><p>Cline laid out the entire project structure. Remember, none of this has been created yet.</p><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/image-39.png" class="kg-image" alt="" loading="lazy" width="602" height="1769" srcset="https://chronicler.tech/content/images/size/w600/2026/03/image-39.png 600w, https://chronicler.tech/content/images/2026/03/image-39.png 602w"></figure><p>At the end of the output, Cline wanted me to confirm a few things:</p><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/-6D6E0929-DA28-411C-BCC6-22DBFCFE908C-.png" class="kg-image" alt="" loading="lazy" width="1551" height="212" srcset="https://chronicler.tech/content/images/size/w600/2026/03/-6D6E0929-DA28-411C-BCC6-22DBFCFE908C-.png 600w, https://chronicler.tech/content/images/size/w1000/2026/03/-6D6E0929-DA28-411C-BCC6-22DBFCFE908C-.png 1000w, https://chronicler.tech/content/images/2026/03/-6D6E0929-DA28-411C-BCC6-22DBFCFE908C-.png 1551w" sizes="(min-width: 720px) 720px"></figure><p>I responded with the following:</p><blockquote>1.  OCI Region: us-ashburn-1<br>2.  I already have an OCI tenancy/account already set up.<br>3.  Email address should be "<a>noreply@revelationtech.com</a>". Please provide instructions on how to verify the domain in OCI Email Delivery, or if you can automate it with Terraform that would be better.<br>4.  I prefer Flask.</blockquote><p>Now that Cline had its answers, it summarized the execution plan. Very few of the steps needed to be done manually as I had requested:</p><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/image-40.png" class="kg-image" alt="" loading="lazy" width="593" height="554"></figure><p>But I then noticed that Cline suggested doing a remote HTTP reference to the images. Basically, it wanted to hyperlink the images to Wikemedia directly, and I didn't want that. So I asked it the following:</p><blockquote>One more thing. I want all images hosted locally, and the local images referenced by URL in the database. I do not want to link to the publicly available Wikimedia Commons URLs.</blockquote><p>After which Cline said that it would create a download script in Python to eventually do just that:</p><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/-B65015C5-E8AE-4E4F-BB77-7E5D3133791E-.png" class="kg-image" alt="" loading="lazy" width="1287" height="344" srcset="https://chronicler.tech/content/images/size/w600/2026/03/-B65015C5-E8AE-4E4F-BB77-7E5D3133791E-.png 600w, https://chronicler.tech/content/images/size/w1000/2026/03/-B65015C5-E8AE-4E4F-BB77-7E5D3133791E-.png 1000w, https://chronicler.tech/content/images/2026/03/-B65015C5-E8AE-4E4F-BB77-7E5D3133791E-.png 1287w" sizes="(min-width: 720px) 720px"></figure><p>The total final cost of the Plan phase was <strong>$0.1783 </strong>using <strong>Claude Sonnet 4.6 </strong>and took <strong>16 minutes and 47 seconds</strong>. This included the time it took for me to respond with my follow-up prompts. </p><p>Remember, none of the above had been created up until this point.</p><h2 id="10-switch-to-act-mode-for-the-ai-agent-to-generate-the-code">10. Switch to "Act" mode for the AI agent to generate the code</h2><p>Now that I've reviewed the plan, it's time to "Act", or execute the plan.</p><ol><li>Click on the "Act" button.</li><li>If nothing happens, type a message like "Act" and click on the play button.</li></ol><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/image-41.png" class="kg-image" alt="" loading="lazy" width="2000" height="1183" srcset="https://chronicler.tech/content/images/size/w600/2026/03/image-41.png 600w, https://chronicler.tech/content/images/size/w1000/2026/03/image-41.png 1000w, https://chronicler.tech/content/images/size/w1600/2026/03/image-41.png 1600w, https://chronicler.tech/content/images/2026/03/image-41.png 2160w" sizes="(min-width: 720px) 720px"></figure><p>For the next several hours, or however long it takes, Cline will start creating all files. I asked it to create the public/private key pair for me, which it did. I needed this in order to get the API tokens from the OCI console. These tokens will later be added to the Terraform configuration files so that it can provision the cloud services.</p><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/image-42.png" class="kg-image" alt="" loading="lazy" width="2000" height="1183" srcset="https://chronicler.tech/content/images/size/w600/2026/03/image-42.png 600w, https://chronicler.tech/content/images/size/w1000/2026/03/image-42.png 1000w, https://chronicler.tech/content/images/size/w1600/2026/03/image-42.png 1600w, https://chronicler.tech/content/images/2026/03/image-42.png 2160w" sizes="(min-width: 720px) 720px"></figure><p>I see here that the public key was created. That's exactly what I needed. </p><ol start="2"><li>Copy the public key.</li></ol><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/-715AE015-50F4-4EC4-A08D-441192166106-.png" class="kg-image" alt="" loading="lazy" width="897" height="612" srcset="https://chronicler.tech/content/images/size/w600/2026/03/-715AE015-50F4-4EC4-A08D-441192166106-.png 600w, https://chronicler.tech/content/images/2026/03/-715AE015-50F4-4EC4-A08D-441192166106-.png 897w" sizes="(min-width: 720px) 720px"></figure><h2 id="11-get-the-required-api-tokens-from-the-oci-console-manual-step">11. Get the required API tokens from the OCI Console (manual step) </h2><p>Now that the public key was created on my local machine, I need to paste it in the OCI console to get all my API tokens. These tokens will eventually be saved into my local client so that Cline can run the Terraform scripts to create my cloud resources.</p><ol><li>Login to the your <a href="https://cloud.oracle.com/?ref=chronicler.tech" rel="noreferrer">cloud.oracle.com</a> account.</li><li>Click on the profile icon.</li><li>Click on "User settings".</li><li>Navigate to the "Tokens and keys" subtab.</li><li>Click on "Add API key".</li></ol><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/image-43.png" class="kg-image" alt="" loading="lazy" width="1432" height="734" srcset="https://chronicler.tech/content/images/size/w600/2026/03/image-43.png 600w, https://chronicler.tech/content/images/size/w1000/2026/03/image-43.png 1000w, https://chronicler.tech/content/images/2026/03/image-43.png 1432w" sizes="(min-width: 720px) 720px"></figure><ol start="6"><li>Select "Paste a public key", paste the key, and submit.</li></ol><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/-592C73B3-5224-430D-8CCE-DBE8243CCB56-.png" class="kg-image" alt="" loading="lazy" width="1064" height="855" srcset="https://chronicler.tech/content/images/size/w600/2026/03/-592C73B3-5224-430D-8CCE-DBE8243CCB56-.png 600w, https://chronicler.tech/content/images/size/w1000/2026/03/-592C73B3-5224-430D-8CCE-DBE8243CCB56-.png 1000w, https://chronicler.tech/content/images/2026/03/-592C73B3-5224-430D-8CCE-DBE8243CCB56-.png 1064w" sizes="(min-width: 720px) 720px"></figure><ol start="7"><li>Copy all these values, as they will be needed later.</li></ol><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/image-66.png" class="kg-image" alt="" loading="lazy" width="836" height="643" srcset="https://chronicler.tech/content/images/size/w600/2026/03/image-66.png 600w, https://chronicler.tech/content/images/2026/03/image-66.png 836w" sizes="(min-width: 720px) 720px"></figure><ol start="8"><li>Now under the <code>/terraform</code> folder in VS Code, create a file called <code>terraform.tfvars</code> and paste your values as shown. You will need to add your Compartment ID as well.</li></ol><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/-DDBE0C34-887B-46BE-8F70-D93C4825D9E0-.png" class="kg-image" alt="" loading="lazy" width="1052" height="756" srcset="https://chronicler.tech/content/images/size/w600/2026/03/-DDBE0C34-887B-46BE-8F70-D93C4825D9E0-.png 600w, https://chronicler.tech/content/images/size/w1000/2026/03/-DDBE0C34-887B-46BE-8F70-D93C4825D9E0-.png 1000w, https://chronicler.tech/content/images/2026/03/-DDBE0C34-887B-46BE-8F70-D93C4825D9E0-.png 1052w" sizes="(min-width: 720px) 720px"></figure><p>WARNING: This file was overwritten later on when Cline started created all the files. So I had to redo this step later.</p><h3 id="why-does-cline-hang-sometimes">Why does Cline hang sometimes?</h3><p>Every so often, Cline would appear to hang. It looks like it's still "Thinking..." but there is no indication of activity. Even submitting a prompt does nothing.</p><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/image-45.png" class="kg-image" alt="" loading="lazy" width="462" height="330"></figure><p>It is safe to click on "Cancel" and then "Resume Task". But more often than not, it's not hung and it's just the model thinking and reasoning behind the scenes. Don't be surprised with having to wait an hour plus to see some activity.</p><p>Also, every now and then you may run out of tokens and receive this message.</p><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/-287B3114-8925-4AE5-A97A-1002B1F7015F-.png" class="kg-image" alt="" loading="lazy" width="1057" height="152" srcset="https://chronicler.tech/content/images/size/w600/2026/03/-287B3114-8925-4AE5-A97A-1002B1F7015F-.png 600w, https://chronicler.tech/content/images/size/w1000/2026/03/-287B3114-8925-4AE5-A97A-1002B1F7015F-.png 1000w, https://chronicler.tech/content/images/2026/03/-287B3114-8925-4AE5-A97A-1002B1F7015F-.png 1057w" sizes="(min-width: 720px) 720px"></figure><p>Simply login to the Claude platform at <a href="https://platform.claude.com/?ref=chronicler.tech" rel="noreferrer">platform.claude.com</a> and purchase some credits. Though it may look it, it won't be made available immediately, so come back an hour later before trying to continue.</p><h2 id="12-let-cline-provision-the-cloud-resources-autonomously">12. Let Cline provision the cloud resources autonomously</h2><p>Cline will continue creating all the files in the project (155 of them total!). Depending on the complexity of your project and the model you've chosen, times may vary. The good thing is that on the top of the chat window you can see a list of the main tasks.</p><ol><li>Let Cline continue working.</li><li>Observe the status on the top of the Cline chatbar until you see that all tasks have been completed (as shown in the following snippet).</li></ol><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/-48A52128-0E3D-4C1F-8C65-834F645D0F84-.png" class="kg-image" alt="" loading="lazy" width="681" height="434" srcset="https://chronicler.tech/content/images/size/w600/2026/03/-48A52128-0E3D-4C1F-8C65-834F645D0F84-.png 600w, https://chronicler.tech/content/images/2026/03/-48A52128-0E3D-4C1F-8C65-834F645D0F84-.png 681w"></figure><p>Every now and then, Cline may ask you a question such as the following. In most cases, accepting the answer is acceptable.</p><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/-DA24DDB0-A0E9-4AC3-B7A7-05B002443324-.png" class="kg-image" alt="" loading="lazy" width="851" height="708" srcset="https://chronicler.tech/content/images/size/w600/2026/03/-DA24DDB0-A0E9-4AC3-B7A7-05B002443324-.png 600w, https://chronicler.tech/content/images/2026/03/-DA24DDB0-A0E9-4AC3-B7A7-05B002443324-.png 851w" sizes="(min-width: 720px) 720px"></figure><p>After my 8 tasks were completed, I wasn't sure whether the cloud services and resources were created by Cline (i.e., Did Cline run the Terraform scripts to create all the cloud resources?). I do recall that in the Plan phase, it said that I needed to run it manually, but there's no harm in asking my AI agent:</p><blockquote>Is the cloud infrastructure provisioned (i.e., did you run the Terraform scripts to create all resources in the cloud)?</blockquote><p>Cline confirmed that it had not run it, and gave me three options to choose from. I did not select any one of those options (yet).</p><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/-8F50C2C4-2D4B-4C3D-8784-AEC602333CC6-.png" class="kg-image" alt="" loading="lazy" width="947" height="449" srcset="https://chronicler.tech/content/images/size/w600/2026/03/-8F50C2C4-2D4B-4C3D-8784-AEC602333CC6-.png 600w, https://chronicler.tech/content/images/2026/03/-8F50C2C4-2D4B-4C3D-8784-AEC602333CC6-.png 947w" sizes="(min-width: 720px) 720px"></figure><p>That's because I noticed that my <code>terraform.tfvars</code> file was overwritten. So I went and re-pasted my API token values again and saved the file.</p><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/-59B3B813-73BF-4EE9-9F24-E0AFE3644F27-.png" class="kg-image" alt="" loading="lazy" width="1755" height="1022" srcset="https://chronicler.tech/content/images/size/w600/2026/03/-59B3B813-73BF-4EE9-9F24-E0AFE3644F27-.png 600w, https://chronicler.tech/content/images/size/w1000/2026/03/-59B3B813-73BF-4EE9-9F24-E0AFE3644F27-.png 1000w, https://chronicler.tech/content/images/size/w1600/2026/03/-59B3B813-73BF-4EE9-9F24-E0AFE3644F27-.png 1600w, https://chronicler.tech/content/images/2026/03/-59B3B813-73BF-4EE9-9F24-E0AFE3644F27-.png 1755w" sizes="(min-width: 720px) 720px"></figure><p>But what value should I use for the compute SSH key that was in the file (not shown above)? Let's ask Cline!</p><blockquote>Where do I get the "Compute SSH key" from? It is a required value in "terraform.tfvars"?</blockquote><p>Cline decided to figure it out and do it all itself, thankfully.</p><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/-188B17F9-A7A2-47B8-ACE3-75DB413B8CCC-.png" class="kg-image" alt="" loading="lazy" width="1768" height="824" srcset="https://chronicler.tech/content/images/size/w600/2026/03/-188B17F9-A7A2-47B8-ACE3-75DB413B8CCC-.png 600w, https://chronicler.tech/content/images/size/w1000/2026/03/-188B17F9-A7A2-47B8-ACE3-75DB413B8CCC-.png 1000w, https://chronicler.tech/content/images/size/w1600/2026/03/-188B17F9-A7A2-47B8-ACE3-75DB413B8CCC-.png 1600w, https://chronicler.tech/content/images/2026/03/-188B17F9-A7A2-47B8-ACE3-75DB413B8CCC-.png 1768w" sizes="(min-width: 720px) 720px"></figure><p>After about 5 minutes, it finally got the key.</p><p>Now here is the part where all it needed to do was to copy the key from the terminal and paste it into the <code>terraform.tfvars</code> configuration file. This led to incredible struggles by the AI agent. It had issues with Windows wrapping the string, faced challenges with special characters, and so on. After struggling for quite some time, Cline finally decided to write a whole Python script just to copy the key value from the terminal prompt and paste it into the configuration file. But it worked, and that's what mattered. I could have saved 15 minutes of AI thinking if I just copied and pasted it myself though.</p><p>Cline then decided to mess everything up and must have created a new private key or something. Who knows. Because the Terraform script wasn't authenticating. So I just followed its lead and answered its questions when it asked me to check certain values in the OCI console.</p><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/image-67.png" class="kg-image" alt="" loading="lazy" width="845" height="380" srcset="https://chronicler.tech/content/images/size/w600/2026/03/image-67.png 600w, https://chronicler.tech/content/images/2026/03/image-67.png 845w" sizes="(min-width: 720px) 720px"></figure><p>It eventually worked in the end. Yes, it did in fact create a new private key for some odd reason.</p><p>Cline continued proceeding with running the Terraform scripts via <code>terraform apply</code> and observing the output. In the following screenshot, it seems it ran into an issue. In this case, it tried to use a feature that was not available in the free tier of the Oracle Autonomous AI Database, so it updated the script to remove this feature.</p><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/image-47.png" class="kg-image" alt="" loading="lazy" width="2000" height="1183" srcset="https://chronicler.tech/content/images/size/w600/2026/03/image-47.png 600w, https://chronicler.tech/content/images/size/w1000/2026/03/image-47.png 1000w, https://chronicler.tech/content/images/size/w1600/2026/03/image-47.png 1600w, https://chronicler.tech/content/images/2026/03/image-47.png 2160w" sizes="(min-width: 720px) 720px"></figure><p>Keep in mind that these are merely a few glimpses into the issues that Cline experienced (there were many!), but it worked through them all autonomously and rarely needed my input.</p><p>Though the Terraform scripts were completed, as you can see in the following screenshot, it did give me a public URL of the application. The cloud resources were now fully provisioned, but the application was actually not deployed yet.</p><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/-D6B8F115-2F68-47C6-B4A9-93678AA5B30C-.png" class="kg-image" alt="" loading="lazy" width="1122" height="439" srcset="https://chronicler.tech/content/images/size/w600/2026/03/-D6B8F115-2F68-47C6-B4A9-93678AA5B30C-.png 600w, https://chronicler.tech/content/images/size/w1000/2026/03/-D6B8F115-2F68-47C6-B4A9-93678AA5B30C-.png 1000w, https://chronicler.tech/content/images/2026/03/-D6B8F115-2F68-47C6-B4A9-93678AA5B30C-.png 1122w" sizes="(min-width: 720px) 720px"></figure><p>That is where Cline began a lengthy process of installing nginx, Gunicorn, and deploying my Python Flask application onto a compute instance. The following screenshot is just a progress point.</p><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/-837C039A-45A2-4F82-A7F9-F8030286B944-.png" class="kg-image" alt="" loading="lazy" width="1766" height="795" srcset="https://chronicler.tech/content/images/size/w600/2026/03/-837C039A-45A2-4F82-A7F9-F8030286B944-.png 600w, https://chronicler.tech/content/images/size/w1000/2026/03/-837C039A-45A2-4F82-A7F9-F8030286B944-.png 1000w, https://chronicler.tech/content/images/size/w1600/2026/03/-837C039A-45A2-4F82-A7F9-F8030286B944-.png 1600w, https://chronicler.tech/content/images/2026/03/-837C039A-45A2-4F82-A7F9-F8030286B944-.png 1766w" sizes="(min-width: 720px) 720px"></figure><p>At this time, I must have missed why Cline decided to switch up the architecture that it had originally planned. Instead of deploying the code onto a serverless OCI Function fronted by an API Gateway, it decided drop those and deploy the application on a compute instance instead.</p><p>Here is another issue where Cline tried to connect to the database but failed. However, after 15 minutes of autonomous troubleshooting, it was successful in the end.</p><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/-FE2C2461-5853-492B-BE89-8EB6B428D9FA-.png" class="kg-image" alt="" loading="lazy" width="1766" height="723" srcset="https://chronicler.tech/content/images/size/w600/2026/03/-FE2C2461-5853-492B-BE89-8EB6B428D9FA-.png 600w, https://chronicler.tech/content/images/size/w1000/2026/03/-FE2C2461-5853-492B-BE89-8EB6B428D9FA-.png 1000w, https://chronicler.tech/content/images/size/w1600/2026/03/-FE2C2461-5853-492B-BE89-8EB6B428D9FA-.png 1600w, https://chronicler.tech/content/images/2026/03/-FE2C2461-5853-492B-BE89-8EB6B428D9FA-.png 1766w" sizes="(min-width: 720px) 720px"></figure><p>It now was able to successfully connect to the database!</p><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/-A6190E39-DF69-4393-96FA-93CA250F4499-.png" class="kg-image" alt="" loading="lazy" width="1763" height="656" srcset="https://chronicler.tech/content/images/size/w600/2026/03/-A6190E39-DF69-4393-96FA-93CA250F4499-.png 600w, https://chronicler.tech/content/images/size/w1000/2026/03/-A6190E39-DF69-4393-96FA-93CA250F4499-.png 1000w, https://chronicler.tech/content/images/size/w1600/2026/03/-A6190E39-DF69-4393-96FA-93CA250F4499-.png 1600w, https://chronicler.tech/content/images/2026/03/-A6190E39-DF69-4393-96FA-93CA250F4499-.png 1763w" sizes="(min-width: 720px) 720px"></figure><p>Cline wanted to insert the seeded data, but ran into yet another issue. Apparently, in the CREATE TABLE script, it named one of the columns "number" but NUMBER is a reserved word in the database. As with all other errors, it managed to rewrite the script, and retry the process again.</p><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/-F2930093-516C-450E-9C29-B9D29E73D3A9-.png" class="kg-image" alt="" loading="lazy" width="1763" height="830" srcset="https://chronicler.tech/content/images/size/w600/2026/03/-F2930093-516C-450E-9C29-B9D29E73D3A9-.png 600w, https://chronicler.tech/content/images/size/w1000/2026/03/-F2930093-516C-450E-9C29-B9D29E73D3A9-.png 1000w, https://chronicler.tech/content/images/size/w1600/2026/03/-F2930093-516C-450E-9C29-B9D29E73D3A9-.png 1600w, https://chronicler.tech/content/images/2026/03/-F2930093-516C-450E-9C29-B9D29E73D3A9-.png 1763w" sizes="(min-width: 720px) 720px"></figure><h2 id="13-manually-verify-the-database-objects-optional">13. Manually verify the database objects (optional)</h2><p>I wanted to verify and make sure that the database objects and data were in the database. The Oracle Autonomous AI Database in the OCI console gives you the ability to run SQL statements against the database. Here you can see that all was good.</p><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/image-51.png" class="kg-image" alt="" loading="lazy" width="2000" height="1025" srcset="https://chronicler.tech/content/images/size/w600/2026/03/image-51.png 600w, https://chronicler.tech/content/images/size/w1000/2026/03/image-51.png 1000w, https://chronicler.tech/content/images/size/w1600/2026/03/image-51.png 1600w, https://chronicler.tech/content/images/2026/03/image-51.png 2148w" sizes="(min-width: 720px) 720px"></figure><p>One of my requirements was to tag every cloud resource with a custom <em>name:value</em> pair of <em>webapp:uspresidents</em>. You can see that the database has this tag.</p><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/image-68.png" class="kg-image" alt="" loading="lazy" width="1718" height="880" srcset="https://chronicler.tech/content/images/size/w600/2026/03/image-68.png 600w, https://chronicler.tech/content/images/size/w1000/2026/03/image-68.png 1000w, https://chronicler.tech/content/images/size/w1600/2026/03/image-68.png 1600w, https://chronicler.tech/content/images/2026/03/image-68.png 1718w" sizes="(min-width: 720px) 720px"></figure><p>I was able to confirm that my compute instance also had the tag.</p><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/image-69.png" class="kg-image" alt="" loading="lazy" width="1718" height="880" srcset="https://chronicler.tech/content/images/size/w600/2026/03/image-69.png 600w, https://chronicler.tech/content/images/size/w1000/2026/03/image-69.png 1000w, https://chronicler.tech/content/images/size/w1600/2026/03/image-69.png 1600w, https://chronicler.tech/content/images/2026/03/image-69.png 1718w" sizes="(min-width: 720px) 720px"></figure><h2 id="14-test-the-application">14. Test the application</h2><p>Cline gave me a link to the public IP address and here's the final application. It looked professional, sharp, clean, and modern. I was impressed.</p><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/image-48.png" class="kg-image" alt="" loading="lazy" width="2000" height="1240" srcset="https://chronicler.tech/content/images/size/w600/2026/03/image-48.png 600w, https://chronicler.tech/content/images/size/w1000/2026/03/image-48.png 1000w, https://chronicler.tech/content/images/size/w1600/2026/03/image-48.png 1600w, https://chronicler.tech/content/images/2026/03/image-48.png 2148w" sizes="(min-width: 720px) 720px"></figure><p>I told Cline about that the images were not showing up. This is what I said:</p><blockquote>When I navigate to <a href="http://157.151.235.148/?ref=chronicler.tech">http://157.151.235.148</a>, everything works fine. However, none of the portraits for the presidents are showing up. It seems that the direct URL of the images are all "<a href="http://157.151.235.148/static/images/presidents/placeholder.jpg?ref=chronicler.tech">http://157.151.235.148/static/images/presidents/placeholder.jpg</a>" which appears to be a placeholder.</blockquote><p>Cline had issues linking to, and even downloading, approved for-use images from Wikimedia. Cline finally found out that Wikimedia places restrictions on robots and had rate limits. It tried using their API to get the images, but was unsuccessful.</p><p>So Cline ended up putting placeholders initials as you see here.</p><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/image-49.png" class="kg-image" alt="" loading="lazy" width="1432" height="1652" srcset="https://chronicler.tech/content/images/size/w600/2026/03/image-49.png 600w, https://chronicler.tech/content/images/size/w1000/2026/03/image-49.png 1000w, https://chronicler.tech/content/images/2026/03/image-49.png 1432w" sizes="(min-width: 720px) 720px"></figure><p>All my requirements were satisfied and the application was working as expected (mostly).</p><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/image-50.png" class="kg-image" alt="" loading="lazy" width="2000" height="2212" srcset="https://chronicler.tech/content/images/size/w600/2026/03/image-50.png 600w, https://chronicler.tech/content/images/size/w1000/2026/03/image-50.png 1000w, https://chronicler.tech/content/images/size/w1600/2026/03/image-50.png 1600w, https://chronicler.tech/content/images/2026/03/image-50.png 2148w" sizes="(min-width: 720px) 720px"></figure><p>Though Cline had already run its test cases, I wanted to run the full suite of tests manually myself, so I opened up <code>TESTING.md</code> document the instructions stated that all I needed to do was simply type <code>pytest</code> in the terminal window. </p><p>All test cases that Cline had created passed.</p><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/image-46.png" class="kg-image" alt="" loading="lazy" width="2000" height="1183" srcset="https://chronicler.tech/content/images/size/w600/2026/03/image-46.png 600w, https://chronicler.tech/content/images/size/w1000/2026/03/image-46.png 1000w, https://chronicler.tech/content/images/size/w1600/2026/03/image-46.png 1600w, https://chronicler.tech/content/images/2026/03/image-46.png 2160w" sizes="(min-width: 720px) 720px"></figure><h2 id="15-generate-smtp-credentials-manual">15. Generate SMTP credentials (manual)</h2><p>The email functionality in the application wasn't working though. I would get an error on the web page when I submitted my email address. So I let Cline know:</p><blockquote>When I try to send the email, upon clicking on "Send Details", I receive the error "Failed to send email. Please try again later."</blockquote><p>Cline offered some suggestions:</p><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/-62EC3BBE-E0AC-4AC0-B150-714ACBDA349C-.png" class="kg-image" alt="" loading="lazy" width="1205" height="390" srcset="https://chronicler.tech/content/images/size/w600/2026/03/-62EC3BBE-E0AC-4AC0-B150-714ACBDA349C-.png 600w, https://chronicler.tech/content/images/size/w1000/2026/03/-62EC3BBE-E0AC-4AC0-B150-714ACBDA349C-.png 1000w, https://chronicler.tech/content/images/2026/03/-62EC3BBE-E0AC-4AC0-B150-714ACBDA349C-.png 1205w" sizes="(min-width: 720px) 720px"></figure><p>The problem is, these steps were not accurate. The suggested navigation in the OCI console didn't exist and I couldn't find where to generate the SMTP credentials.</p><p>I referred to the Oracle documentation. And guess what? It wasn't accurate either. I wasn't sure what was going on. But at least Cline was consistent with the Oracle documentation.</p><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/-15A54F3E-9317-4BD5-935F-9C155CA4D77E-.png" class="kg-image" alt="" loading="lazy" width="1708" height="636" srcset="https://chronicler.tech/content/images/size/w600/2026/03/-15A54F3E-9317-4BD5-935F-9C155CA4D77E-.png 600w, https://chronicler.tech/content/images/size/w1000/2026/03/-15A54F3E-9317-4BD5-935F-9C155CA4D77E-.png 1000w, https://chronicler.tech/content/images/size/w1600/2026/03/-15A54F3E-9317-4BD5-935F-9C155CA4D77E-.png 1600w, https://chronicler.tech/content/images/2026/03/-15A54F3E-9317-4BD5-935F-9C155CA4D77E-.png 1708w" sizes="(min-width: 720px) 720px"></figure><p>So I asked ChatGPT. Now the instructions from ChatGPT weren't exact or perfect either, but it had the right idea. As ChatGPT suspected, I was indeed using the newer Identity Domains, and I was finally able to generate the SMTP credentials.</p><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/-61B3B4A3-7CE9-4FB0-8E97-EB6E1351F804-.png" class="kg-image" alt="" loading="lazy" width="1287" height="680" srcset="https://chronicler.tech/content/images/size/w600/2026/03/-61B3B4A3-7CE9-4FB0-8E97-EB6E1351F804-.png 600w, https://chronicler.tech/content/images/size/w1000/2026/03/-61B3B4A3-7CE9-4FB0-8E97-EB6E1351F804-.png 1000w, https://chronicler.tech/content/images/2026/03/-61B3B4A3-7CE9-4FB0-8E97-EB6E1351F804-.png 1287w" sizes="(min-width: 720px) 720px"></figure><p>Here's the page on the OCI console where the SMTP credential was finally created.</p><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/image-54.png" class="kg-image" alt="" loading="lazy" width="2000" height="1025" srcset="https://chronicler.tech/content/images/size/w600/2026/03/image-54.png 600w, https://chronicler.tech/content/images/size/w1000/2026/03/image-54.png 1000w, https://chronicler.tech/content/images/size/w1600/2026/03/image-54.png 1600w, https://chronicler.tech/content/images/2026/03/image-54.png 2148w" sizes="(min-width: 720px) 720px"></figure><p>It still wasn't working, so Cline stated that I had to add an approved sender in the OCI console, and gave me the appropriate instructions to do so.</p><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/-514CE2D5-1B2E-4F44-A426-2CD57D28BE87-.png" class="kg-image" alt="" loading="lazy" width="1197" height="450" srcset="https://chronicler.tech/content/images/size/w600/2026/03/-514CE2D5-1B2E-4F44-A426-2CD57D28BE87-.png 600w, https://chronicler.tech/content/images/size/w1000/2026/03/-514CE2D5-1B2E-4F44-A426-2CD57D28BE87-.png 1000w, https://chronicler.tech/content/images/2026/03/-514CE2D5-1B2E-4F44-A426-2CD57D28BE87-.png 1197w" sizes="(min-width: 720px) 720px"></figure><p>The approved sender was added on the OCI console, and I manually added my tag as well as shown.</p><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/image-55.png" class="kg-image" alt="" loading="lazy" width="2000" height="1025" srcset="https://chronicler.tech/content/images/size/w600/2026/03/image-55.png 600w, https://chronicler.tech/content/images/size/w1000/2026/03/image-55.png 1000w, https://chronicler.tech/content/images/size/w1600/2026/03/image-55.png 1600w, https://chronicler.tech/content/images/2026/03/image-55.png 2148w" sizes="(min-width: 720px) 720px"></figure><p>Now when I submit my email address in the web application, I no longer received an error. But did I actually receive the email?</p><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/-08197DD9-08E2-4329-B52A-D01CFD4F2C10-.png" class="kg-image" alt="" loading="lazy" width="746" height="760" srcset="https://chronicler.tech/content/images/size/w600/2026/03/-08197DD9-08E2-4329-B52A-D01CFD4F2C10-.png 600w, https://chronicler.tech/content/images/2026/03/-08197DD9-08E2-4329-B52A-D01CFD4F2C10-.png 746w" sizes="(min-width: 720px) 720px"></figure><p>The OCI Email Delivery service seemed to confirm that 1 email was received by the service and 1 email was relayed, so that was a good sign.</p><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/image-70.png" class="kg-image" alt="" loading="lazy" width="1718" height="880" srcset="https://chronicler.tech/content/images/size/w600/2026/03/image-70.png 600w, https://chronicler.tech/content/images/size/w1000/2026/03/image-70.png 1000w, https://chronicler.tech/content/images/size/w1600/2026/03/image-70.png 1600w, https://chronicler.tech/content/images/2026/03/image-70.png 1718w" sizes="(min-width: 720px) 720px"></figure><p>The email was actually in my Spam folder, and the resulting output was very nice.</p><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/image-56.png" class="kg-image" alt="" loading="lazy" width="1351" height="1224" srcset="https://chronicler.tech/content/images/size/w600/2026/03/image-56.png 600w, https://chronicler.tech/content/images/size/w1000/2026/03/image-56.png 1000w, https://chronicler.tech/content/images/2026/03/image-56.png 1351w" sizes="(min-width: 720px) 720px"></figure><h2 id="16-refine-the-application-optional">16. Refine the application (optional)</h2><p>I still wasn't happy with the fact that I had placeholder initials in lieu of official portraits of the presidents. I know Cline had spent a significant amount of time trying to pull them from Wikimedia (unsuccessfully), but I made this request nonetheless:</p><blockquote>I don't like the current placeholder for the portraits which just shows the initials of each president. Are there alternate resources you can use to get actual portrait photos of each president?</blockquote><p>After much churning, somehow, somewhere, Cline was able to get some photos and it was looking great as you can see!</p><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/image-58.png" class="kg-image" alt="" loading="lazy" width="1432" height="1651" srcset="https://chronicler.tech/content/images/size/w600/2026/03/image-58.png 600w, https://chronicler.tech/content/images/size/w1000/2026/03/image-58.png 1000w, https://chronicler.tech/content/images/2026/03/image-58.png 1432w" sizes="(min-width: 720px) 720px"></figure><p>And here's the detail page.</p><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/image-60.png" class="kg-image" alt="" loading="lazy" width="1571" height="2373" srcset="https://chronicler.tech/content/images/size/w600/2026/03/image-60.png 600w, https://chronicler.tech/content/images/size/w1000/2026/03/image-60.png 1000w, https://chronicler.tech/content/images/2026/03/image-60.png 1571w" sizes="(min-width: 720px) 720px"></figure><h2 id="16-create-a-cloud-architecture-diagram-optional">16. Create a cloud architecture diagram (optional)</h2><p>Now, when Cline was in the Act phase executing the Plan that we had developed together, I noticed that it really didn't follow the original Plan, specifically in regards to the cloud architecture. I know this because as I was observing the AI agent perform its actions over the course of two hours, I noticed it was constantly pushing code to a compute instance, but there was no mention of a compute instance in the original plan.</p><p>So here I asked Cline to generate an architecture diagram for me using OCI format standards:</p><blockquote>Create a custom architecture diagram that shows the cloud architecture in place and its components/services/resources. It should follow the standard OCI format and service icons as documented here: <a href="https://docs.oracle.com/en-us/iaas/Content/General/Reference/graphicsfordiagrams.htm?ref=chronicler.tech">https://docs.oracle.com/en-us/iaas/Content/General/Reference/graphicsfordiagrams.htm</a></blockquote><p>This was the final architecture. It wasn't what I would consider a pretty "cloud" architecture diagram, as it included details often not found in these types of diagrams, but it provided sufficient detail for me to understand the overall design.</p><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/image-59.png" class="kg-image" alt="" loading="lazy" width="1086" height="731" srcset="https://chronicler.tech/content/images/size/w600/2026/03/image-59.png 600w, https://chronicler.tech/content/images/size/w1000/2026/03/image-59.png 1000w, https://chronicler.tech/content/images/2026/03/image-59.png 1086w" sizes="(min-width: 720px) 720px"></figure><p>I preferred the original architecture, and I suppose I could have insisted that it re-architect the entire application to go full serverless, leveraging OCI Functions and add an API Gateway to front the application. But I didn't go that route.</p><h2 id="17-generate-documentation-summary-optional">17. Generate documentation summary (optional)</h2><p>There's unfortunately no way to export the entire chat history with Cline. It would be incredibly useful to go through all the actions that Cline took offline. That way, I'd know exactly what the AI agent performed.</p><p>So my other best option is to ask it to generate something:</p><blockquote>Export this entire chat session, maintaining all formatting and include all responses, and save it in an HTML file under the /docs folder. Additionally, include a section with some basic statistics such as total number of files in the project, frameworks used, OCI services used, patterns used, total session duration, and other relevant metrics. Include results of the testing. Includes key errors and steps to resolve them. Also include suggested future recommendations.</blockquote><p>Cline generated a detailed export, but it's more of a session summary than a word-for-word chat export. This summary was still incredibly useful.</p><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/image-62.png" class="kg-image" alt="" loading="lazy" width="2000" height="18659" srcset="https://chronicler.tech/content/images/size/w600/2026/03/image-62.png 600w, https://chronicler.tech/content/images/size/w1000/2026/03/image-62.png 1000w, https://chronicler.tech/content/images/size/w1600/2026/03/image-62.png 1600w, https://chronicler.tech/content/images/2026/03/image-62.png 2148w" sizes="(min-width: 720px) 720px"></figure><h2 id="18-shutdown-the-cloud-servers-to-save-money-optional">18. Shutdown the cloud servers to save money (optional)</h2><p>Cline based the cloud design on a single compute instance and a single Autonomous AI Database. When browsing the OCI console, I was able to confirm that the database was indeed the free tier option, so I would not be paying anything for it. However, I had noticed during the Act phase that Cline was unsuccessful trying to start up the free tier compute instance, likely because I exhausted my free tier limits.</p><p>So after testing, I asked Cline to:</p><blockquote>Shutdown the compute instance and the database instance.</blockquote><p>Not only did the AI agent get the resource OCIDs from the Terraform state file to shut them both down, but it also created a companion <code>start_oci_resources.py</code> script so that I can easily restart them later.</p><p>Even better, when the VM is up, Cline mentioned that the services would auto-start.</p><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/-07C2B5B4-A674-43DD-A786-CB9CD27C4D0A-.png" class="kg-image" alt="" loading="lazy" width="743" height="393" srcset="https://chronicler.tech/content/images/size/w600/2026/03/-07C2B5B4-A674-43DD-A786-CB9CD27C4D0A-.png 600w, https://chronicler.tech/content/images/2026/03/-07C2B5B4-A674-43DD-A786-CB9CD27C4D0A-.png 743w" sizes="(min-width: 720px) 720px"></figure><hr><h2 id="conclusion-final-thoughts">Conclusion &amp; Final Thoughts</h2><p>This effort took quite a while, but not as long as it would have taken had I programmed it all from scratch. This may have taken me anywhere from 20-40 hours to complete manually.</p><blockquote>What was the total duration of the session, minus all the wait times of inactivity caused by me? Provide a response in hours and minutes.</blockquote><p>Cline estimated the net active AI working time to be 9 hours and 29 minutes, in addition to 52 minutes of human "wait" times, but I don't believe this to be accurate. There was probably a 3 hour pause caused by me as I went out to dinner and putting the kids to bed when I came back. So my rough duration estimate would be 6-7 hours instead.</p><p>Though I tout Cline as being "autonomous", it really operates on a permission-based model (i.e., it won't do anything unexpected). The human/developer still needs to approve most actions, unless you decide to auto-approve everything like I did.</p><p>One of the biggest risks of fully autonomous code creation is the loss of developer control (I have a whole <a href="https://chronicler.tech/ai-code-generation-overview-risks-and-challenges/" rel="noreferrer">post</a> on AI code generation risks and mitigations worth reading). As I let the AI agent loose, it created code, encountered errors, troubleshooted the errors, fixed the bugs, and repeated the process hundreds of times. Given that I let the AI agent select the development framework and design the architecture, as time passed, I starting becoming unaware of what it was doing. This was partly due to me keeping auto-approve on, mostly because I didn't want to spend another two days reviewing and validating every single change the AI agent wanted to do before approving it.</p><p>Also, 2026 is the year of the MCP Server. I mention nothing of MCP Servers this time around, but stay tuned for a future post.</p><p>In conclusion, there are a very few important things worth noting:</p><ul><li><strong>Use AI agents whenever you can during your programming sessions. </strong>AI agents (like Cline) are powerful, so don't hesitate taking advantage of them. Ask it to clarify items, refine the code, or perform mundane manual steps for you.</li><li><strong>AI agents can save you an unbelievable amount of time. </strong>It can easily reduce the time it would take a human to manually troubleshoot and resolve issues by 99%. It is truly amazing.</li><li><strong>Repeating the same set of instructions will likely not yield the same output. </strong>That's because current generative AI models are non-deterministic. AI models will usually produce different outputs even if the input is exactly the same each time. My application above will likely look drastically different if I repeated the same exercise again.</li><li><strong>The AI agent can seem to work in circles when trying to resolve simple problems. </strong>But it goes about it methodically and eventually finds a fix.</li><li><strong>AI agents but can be dangerous. </strong>Here's a <a href="https://www.pcmag.com/news/meta-security-researchers-openclaw-ai-agent-accidentally-deleted-her-emails?ref=chronicler.tech" rel="noreferrer">recent article</a> on how an AI agent deleted Meta's AI Alignment Director's entire email inbox irrecoverably.</li><li><strong>Auto-approve is exceptionally dangerous.</strong> It is not recommended, though it would take considerably more time to review every proposed course of action by the AI agent.</li></ul><p>Try the app here as long while it stays up: <a href="http://157.151.235.148/?ref=chronicler.tech">http://pathinfotech.app/</a></p> ]]></content:encoded>
    </item>
    <item>
        <title><![CDATA[ Autonomously create a multi-tiered web application using VS Code + Cline + Claude Opus ]]></title>
        <description><![CDATA[ In this rather lengthy post, I&#39;ll describe how I went about using agentic AI code generation to autonomously create, build, and deploy a custom web application.


What is Autonomous Code Generation?

Let&#39;s get a few concepts clarified first.

AI code generation is generally meant to refer ]]></description>
        <link>https://chronicler.tech/autonomously-create-a-multi-tiered-web-application-using-vs-code-cline-claude-opus/</link>
        <guid isPermaLink="false">69b18c6d7528d600015820aa</guid>
        <category><![CDATA[  ]]></category>
        <dc:creator><![CDATA[  ]]></dc:creator>
        <pubDate>Thu, 12 Mar 2026 23:22:45 -0400</pubDate>
        <media:content url="https://chronicler.tech/content/images/2026/03/Untitled.png" medium="image"/>
        <content:encoded><![CDATA[ <p>In this rather lengthy post, I'll describe how I went about using agentic AI code generation to autonomously create, build, and deploy a custom web application.</p><h2 id="what-is-autonomous-code-generation">What is Autonomous Code Generation?</h2><p>Let's get a few concepts clarified first.</p><p><em>AI code generation</em> is generally meant to refer to a developer's use of AI to assist in code generation through human prompting. The human (i.e., developer) types what he'd like to see, and the AI somehow automagically creates the code.</p><p>I use the term <em>autonomous code generation </em>where, through the use of human prompts, an AI agent independently performs multiple steps of the software development lifecycle, including coding the application, building it (i.e., packaging it), and deploying it.</p><p>In this exercise, I attempted to leverage certain tools to perform autonomous code generation.</p><p>The following screenshot is one of the pages of the completed application. The effort was eventually a success. Had I spent more time on it, I would have continued to refine it, improved the look-and-feel, added more functionality, created separate non-production and production environments in the cloud, and so on.</p><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/image-30.png" class="kg-image" alt="" loading="lazy" width="1263" height="782" srcset="https://chronicler.tech/content/images/size/w600/2026/03/image-30.png 600w, https://chronicler.tech/content/images/size/w1000/2026/03/image-30.png 1000w, https://chronicler.tech/content/images/2026/03/image-30.png 1263w" sizes="(min-width: 720px) 720px"></figure><h2 id="conclusion">Conclusion</h2><p>This is a rather lengthy post, going into semi-detail of what I went through creating a simple e-commerce web application. But let me start by summarizing my experience:</p>
<!--kg-card-begin: html-->
<style>
/* Allow normal wrapping */
.wrap-text {
    white-space: normal; /* default: text wraps automatically */
}
</style>
<table border="1" cellpadding="20" cellspacing="20" width="600pt" class="wrap-text">
 <tr bgcolor="lightblue">
  <td style="width:100pt"></td>
  <td style="width:250pt"><b>What Went Right</b></td>
  <td style="width:250pt"><b>What Went Wrong</b></td>
 </tr>
 <tr>
  <td><b>Prompt</b></td>
  <td class="wrap-text"><b>The LLM does a good job of filling in the blanks if details are light.</b><br><br>With lack of specifics, the LLM (specifically Claude Opus) tries its best to create a solution following sound practices.<br><br>For example, in my requirements I only specified two OCI services that I wanted used, but it created a solid architecture</td>
  <td class="wrap-text"><b>I didn't like the UI, but that's mostly due to zero guidance from me.</b><br><br>The UI was not necessary to my liking, and either more specificity in my prompt or continued refinement to the agent would have gotten it a better point.</td>
 </tr>
 <tr>
  <td><b>Cost</b></td>
  <td class="wrap-text"><b>$32 for 5 hours of AI assisted coding is pretty darn good.</b><br><br>The exact figure was actually $32.35 and this was across 4 sessions over 5 hours. For a company, they would gladly pay that amount if it meant reducing the development effort from 2 weeks to 5 hours, which it did in this case.</td>
  <td class="wrap-text"><b>$32 for pilot testing is too much for me.</b><br><br>In the end, this was still a trial for me. If I incurred this cost on every pilot or POC, in addition to cloud hosting costs, it becomes too much to bear.<br><br>So the real question is, are these AI coding agents ready for primetime and production use?</td>
 </tr>
 <tr>
  <td><b>AI Agent</b></td>
  <td class="wrap-text"><b>The AI agent impressively took full control of the cloud deployment.</b><br><br>The Cline AI agent really took over when it came to deploying the container to OCI Functions. It ran autonomously and resolved the tens of deployment issues on its own until it was completed successfully.</td>
  <td class="wrap-text"><b>I didn't leverage the AI agent when I should have, instead of doing certain steps manually.</b><br><br>It slipped my mind that I could have leveraged the AI agent to create the generate the public/private key, install the OCI client, install Terraform, and apply the Terraform configuration, as I did all those steps manually.<br><br>All that was needed was some information from the OCI console ahead of time (that part must be done manually).</td>
 </tr>
</table>
<!--kg-card-end: html-->
<h2 id="software-tools-used">Software Tools Used</h2><p>This effort I embarked on relied on multiple tools and services.</p><ol><li><strong>Visual Studio Code </strong>(aka VS Code) - A lightweight, extensible source code editor (i.e., IDE) from Microsoft with a large ecosystem of extensions for many programming languages.</li><li><strong>Cline </strong>- An open-source AI coding assistant that integrates with development environments such as VS Code to autonomously plan, write, modify, and run code using large language models such as Claude Opus.</li><li><strong>Claude Opus </strong>- Anthropic’s most capable large language model (LLM) designed for advanced reasoning, coding, and complex problem-solving tasks.</li><li><strong>Oracle Cloud Infrastructure </strong>(aka OCI) - Oracle’s enterprise cloud platform that provides compute, storage, networking, databases, and AI services for building and running scalable applications.</li></ol><p>Essentially the only software you need to download is VS Code. Later on during development, other tools such as Terraform and the OCI CLI and various Python packages will be downloaded by the AI agent.</p><hr><h2 id="1-create-an-api-key-for-claude-opus">1. Create an API key for Claude Opus</h2><p>You will need to create an account on the Claude platform, create an API key, and purchase some credits. This API key will be con</p><ol><li>Navigate to <a href="https://platform.claude.com/?ref=chronicler.tech" rel="noreferrer">platform.claude.com</a> and create a free account.</li></ol><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/image-16.png" class="kg-image" alt="" loading="lazy" width="1028" height="593" srcset="https://chronicler.tech/content/images/size/w600/2026/03/image-16.png 600w, https://chronicler.tech/content/images/size/w1000/2026/03/image-16.png 1000w, https://chronicler.tech/content/images/2026/03/image-16.png 1028w" sizes="(min-width: 720px) 720px"></figure><ol start="2"><li>After logging in, click on "API Keys --&gt; Create Key", give your key any name, click "Add", and copy the value of the API and store it somewhere (<strong>it will never be displayed again, so save it someplace safe!</strong>).</li></ol><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/image-17.png" class="kg-image" alt="" loading="lazy" width="1432" height="734" srcset="https://chronicler.tech/content/images/size/w600/2026/03/image-17.png 600w, https://chronicler.tech/content/images/size/w1000/2026/03/image-17.png 1000w, https://chronicler.tech/content/images/2026/03/image-17.png 1432w" sizes="(min-width: 720px) 720px"></figure><ol start="3"><li>Click on "Settings --&gt; Billing --&gt; Buy credits" and purchase any amount of credits to start with (e.g., $10). </li></ol><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/image-18.png" class="kg-image" alt="" loading="lazy" width="1432" height="666" srcset="https://chronicler.tech/content/images/size/w600/2026/03/image-18.png 600w, https://chronicler.tech/content/images/size/w1000/2026/03/image-18.png 1000w, https://chronicler.tech/content/images/2026/03/image-18.png 1432w" sizes="(min-width: 720px) 720px"></figure><h2 id="2-download-and-install-vs-code">2. Download and Install VS Code</h2><p>Download and install VS Code. It is a straightforward process.</p><ol><li>Navigate to <a href="https://code.visualstudio.com/download?ref=chronicler.tech">code.visualstudio.com/download</a>, download, and install the software.</li></ol><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/image-15.png" class="kg-image" alt="" loading="lazy" width="1432" height="734" srcset="https://chronicler.tech/content/images/size/w600/2026/03/image-15.png 600w, https://chronicler.tech/content/images/size/w1000/2026/03/image-15.png 1000w, https://chronicler.tech/content/images/2026/03/image-15.png 1432w" sizes="(min-width: 720px) 720px"></figure><h2 id="3-install-the-cline-extension-in-vs-code">3. Install the Cline Extension in VS Code</h2><p>Cline is an autonomous coding agent that is used inside VS Code and is available via an extension. Alternatives include Claude Code and Oracle Code Assist.</p><ol><li>Open VS Code.</li><li>Click on the "Extensions" button on the left.</li><li>Search for "cline".</li><li>Click on "Install". </li></ol><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/image-19.png" class="kg-image" alt="" loading="lazy" width="632" height="370" srcset="https://chronicler.tech/content/images/size/w600/2026/03/image-19.png 600w, https://chronicler.tech/content/images/2026/03/image-19.png 632w"></figure><p>Cline is now ready for use.</p><h2 id="4-configure-the-model-in-cline">4. Configure the Model in Cline</h2><p>Now that Cline is installed, it is not still ready for use. Cline relies on a 3rd party LLM model of your choice. Now that we've created an API key within Claude, we will use those values here.</p><ol><li>If the Cline sidebar is not showing in VS Code, click on the <em>Toggle Secondary Side Bar</em> button on the top right or click CTRL+ALT+B.</li><li>Click on the <em>Settings</em> icon.</li><li>Select "Anthropic" as the API Provider.</li><li>Enter the API key that you created in the Claude platform console.</li><li>Select a model such as "claude-sonnet-4.6".</li></ol><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/image-20.png" class="kg-image" alt="" loading="lazy" width="1440" height="622" srcset="https://chronicler.tech/content/images/size/w600/2026/03/image-20.png 600w, https://chronicler.tech/content/images/size/w1000/2026/03/image-20.png 1000w, https://chronicler.tech/content/images/2026/03/image-20.png 1440w" sizes="(min-width: 720px) 720px"></figure><p>Now Cline is ready for use!</p><h2 id="5-create-a-first-draft-of-your-prompt">5. Create a First Draft of Your Prompt</h2><p>In a text editor, start by creating a prompt of the application. Here is the prompt I created.</p><pre><code class="language-AI prompt">I want you to create a web application for me.

The details of this web application are as follows:
* The web application will be called "My Comic Book Collection".
* The web application should use a modern, responsive UI.
* The web application should use a CSS template or style similar to what is found on https://github.com/projects.
* None of the pages requires authentication, so all pages are publicly accessible.
* The web application is intended to list my comic book collection.
* Every comic book series has one or more issues (for example, the series name could be "Amazing Spider-Man volume 2" of which I only own issues 10-20).
* Each series has a price. Individual issues are not sold separately. Only entire series can be sold.
* Users can add or remove series from their cart.
* The IDE is Visual Studio Code.
* The extension being used is Cline.
* The API provider is Anthropic.
* The model is Claude Opus 4.6.
* A list of all series should be shown. Each series should display the cover of the first issue of the series, alongside the title and issues numbers owned. The user can simply add the series to the cart from here.
* The user can click on a series, after which they are taken to a page showing the cover of each comic book in the series, it's issue number, and condition (Mint, Near Mint, Very Fine, Fine, Very Good, Good, Fair, Poor).
* The web application should have an impressive home page, with impressive graphics and images that appeal to the typical comic book buyer. Generate any images needed for this page.
* When the user chooses to check out, it will send him a list of his cart in table format in an HTML email using the Oracle Cloud Infrastructure (OCI) Email Delivery service, after which his cart is cleared.
* Each page will have a logo on it. Create a new custom logo for this.
* On the bottom of each page will be a footer that states "© 2025 Ahmed Aboulnaga".
* The web application will be deployed to Oracle Cloud Infrastructure (OCI).
* Include Terraform scripts to automatically provision all required infrastructure.
* Any combination of services is acceptable, but the simpler the architecture, the better.
* The web application should be developed in Python.
* Provide test cases and instructions on how to run the test cases.
* The code should include comments describing some information throughout the code.
* Detailed instructions to create the infrastructure within OCI should be provided.
* Detailed instructions to deploy the web application to OCI should be provided.
* Include anything relevant you think should be added.
* The web application should be publicly accessible.
* The database should be Oracle Autonomous Database in OCI.
* All data should be stored in the Oracle Autonomous Database.
* Use a serverless architecture as much as possible.
* Provide instructions on how to install, setup, and execute the Infrastructure-as-Code scripts.
* Provide instructions to setting up the public/private RSA key pair on the client host where Terraform will be executed.
* Provide instructions on where to place the Terraform configuration file information returned from the OCI console.</code></pre><p>This prompt covers, to the best of my experience, what I'm looking for in the application.</p><p>The quality of the output will only be as good as my prompt. The more details and specifics I add to the prompt, the less guessing the LLM has to do.</p><h2 id="6-use-meta-prompting-to-improve-the-prompt">6. Use Meta Prompting to Improve the Prompt</h2><p>Now that your prompt is <em>mostly</em> ready, let's use meta prompting to refine it. Meta prompting&nbsp;is a prompt engineering technique in generative AI where you ask a chatbot (such as ChatGPT or Gemini) to help you in creating a prompt.</p><p>In this case, my prompt is mostly ready, but we need some assistance improving it.</p><pre><code class="language-AI prompt">ROLE: &lt;&lt;&lt; I am a web developer. &gt;&gt;&gt;

CONTEXT: &lt;&lt;&lt; I need help creating a prompt to use in my AI code generator.&gt;&gt;&gt;

EXPECTATION: &lt;&lt;&lt; I want you to create me a prompt that I will use in my AI coding agent (Cline) to create a web application for me. Refine the prompt and make sure it is detailed enough to produce a high quality output.

---paste the entire prompt above here---

&gt;&gt;&gt;</code></pre><p>Depending on which chatbot you use, the output could be drastically different, but it will nonetheless be an improvement and made more specific to AI coding agent.</p><p>This is the updated prompt generated by Gemini:</p><pre><code class="language-AI prompt"># Project Name: "My Comic Book Collection" Web Application

Act as an expert Full-Stack Cloud Architect and Python Developer. Your goal is to build a modern, serverless web application deployed on Oracle Cloud Infrastructure (OCI) using Python.

## 1. Tech Stack &amp; Architecture
- **Backend:** Python (Flask or FastAPI) deployed via OCI Functions (Serverless).
- **Frontend:** Responsive UI using HTML5/JS/CSS, styled with a professional "GitHub Projects" aesthetic (clean grids, muted borders, high-contrast labels).
- **Database:** Oracle Autonomous Database (Serverless).
- **Infrastructure:** Terraform for all OCI resources.
- **Email Service:** OCI Email Delivery via SMTP/SDK.
- **Hosting:** OCI Object Storage (Static Frontend) or OCI API Gateway + Functions.

## 2. Functional Requirements
- **Home Page:** A high-impact landing page with comic-themed hero graphics. Generate a custom SVG/CSS logo for "My Comic Book Collection".
- **Gallery View:** List all comic series. Display: First issue cover image, Title, Issue range (e.g., 10-20), and Price. Include a "Quick Add to Cart" button.
- **Series Detail Page:** Display a grid of all individual issues in a series with cover images, issue numbers, and condition ratings (Mint to Poor).
- **Cart &amp; Checkout:** - No authentication required.
    - Persistent cart (Session or LocalStorage).
    - Checkout triggers an HTML email via OCI Email Delivery containing a formatted &lt;table&gt; of the items.
    - Clear cart post-checkout.
- **Footer:** Must include "© 2025 Path Infotech LLC" on every page.

## 3. Infrastructure &amp; DevOps (Terraform)
Provide complete Terraform scripts to:
- Provision a VCN and necessary subnets.
- Spin up an Oracle Autonomous Database.
- Configure OCI Email Delivery and approved senders.
- Deploy the Python application code to OCI Functions.
- Set up API Gateway to route traffic to the functions.

## 4. Documentation &amp; Setup Instructions
Please provide the following in separate Markdown files:
- **Client Setup:** Instructions for generating RSA Key Pairs (PEM format) and configuring the OCI CLI/Terraform provider.
- **Terraform Execution:** Where to place the `tenancy_ocid`, `user_ocid`, and `fingerprint` from the OCI Console.
- **Deployment:** Step-by-step guide to `terraform init`, `apply`, and deploying the Python code.
- **Testing:** Provide a `pytest` suite and instructions for running integration tests against the API.
- **Sample Data:** Create sample data and sample images.

## 5. Design Guidelines
- Use a "GitHub-like" UI: San-serif fonts, `#f6f8fa` backgrounds, and rounded card borders.
- Code must be heavily commented for educational purposes.
- Ensure all OCI resources are within the Free Tier limits where possible.
</code></pre><p>This is the prompt that will eventually be used in Cline.</p><p>Note here that I did not define the target architecture in the cloud aside from the use of the Oracle Autonomous Database and OCI Email Delivery services. Everything else is up to the AI agent to choose.</p><h2 id="7-submit-the-prompt-to-cline-to-create-the-application">7. Submit the Prompt to Cline to Create the Application</h2><p>Copy the entire prompt from earlier, and back within VS Code, paste it in the prompt.</p><ol><li>In VS Code, open a new, empty folder to host your project files (in this example, I had an empty folder called <code>comic-collection</code>).</li><li>Paste the prompt.</li><li>Click on the play button highlighted in red.</li></ol><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/image-21.png" class="kg-image" alt="" loading="lazy" width="1800" height="830" srcset="https://chronicler.tech/content/images/size/w600/2026/03/image-21.png 600w, https://chronicler.tech/content/images/size/w1000/2026/03/image-21.png 1000w, https://chronicler.tech/content/images/size/w1600/2026/03/image-21.png 1600w, https://chronicler.tech/content/images/2026/03/image-21.png 1800w" sizes="(min-width: 720px) 720px"></figure><p>But before you do, note the sections highlighted in blue. It's important to know a few things:</p><p><strong>Plan or Act?</strong></p><p>Typically, you want to select "Plan" first. Cline here generates a step-by-step strategy and it doesn't actually do anything. It will not create any code. It will not perform any actions. It will simply create a plan.</p><p>With Plan:</p><ul><li>No changes are made.</li><li>No files are edited.</li><li>No commands are executed.</li></ul><p>Agentic AI systems can be dangerous if they act immediately. Plan gives you a preview of the AI's reasoning and intended actions.</p><p>In Act mode, Cline executes the plan.</p><p>It will read and edit files, run terminal commands, download and install dependencies, run builds, create and update code, and so on.</p><p><strong>Auto-approve or not?</strong></p><p>Auto-approve controls whether the developer must approve each operation during Act mode.</p><p>If auto-approve is on, as shown in the figure above, Cline will automatically perform certain actions without asking. It is not unusual to be asked for hundreds of approvals in a single session, so setting auto-approve may seem like the ideal choice, but it comes with its risks obviously.</p><p>Here's a screenshot of one of the SVG images that it created as part of the sample data generation:</p><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/Untitled2.png" class="kg-image" alt="" loading="lazy" width="2000" height="1183" srcset="https://chronicler.tech/content/images/size/w600/2026/03/Untitled2.png 600w, https://chronicler.tech/content/images/size/w1000/2026/03/Untitled2.png 1000w, https://chronicler.tech/content/images/size/w1600/2026/03/Untitled2.png 1600w, https://chronicler.tech/content/images/2026/03/Untitled2.png 2160w" sizes="(min-width: 720px) 720px"></figure><h2 id="8-review-documentation-upon-completion">8. Review Documentation Upon Completion</h2><p>In my little exercise here, I set auto-approve to on and I set it to Act immediately, bypassing the Plan phase. It still performs the planning, but it just doesn't wait for my review.</p><p>After a few hours with some back and forth with the AI agent, my entire codebase is generated. Test cases were created. Documentation was written. Everything is ready to go. All this, and I don't even know what the underlying architecture is.</p><p>There was a well written <code>README.md</code> file that provided a high-level details, shown here.</p><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/image-23.png" class="kg-image" alt="" loading="lazy" width="811" height="2486" srcset="https://chronicler.tech/content/images/size/w600/2026/03/image-23.png 600w, https://chronicler.tech/content/images/2026/03/image-23.png 811w" sizes="(min-width: 720px) 720px"></figure><p>This is the diagram it generated in SVG format. Cline (via the Claude Opus LLM) exceeded my expectations in the design of the cloud architecture. It decided on:</p><ul><li><strong>Object Storage</strong> to hold all frontend static files</li><li><strong>API Gateway</strong> as a proxy to the backend web services</li><li><strong>OCI Functions</strong> to host the webservers</li><li><strong>Container Registry</strong> to host the container artifacts</li><li><strong>Autonomous Database</strong>, since I requested all data to be stored in it</li><li><strong>OCI Email Service</strong>, since I requested it to be used</li><li>All <strong>VCN</strong>/networking and <strong>IAM Policy</strong> setup</li></ul><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/-656A07D0-3653-4F49-B2B4-C85B4D7D2EFD-.png" class="kg-image" alt="" loading="lazy" width="1356" height="1004" srcset="https://chronicler.tech/content/images/size/w600/2026/03/-656A07D0-3653-4F49-B2B4-C85B4D7D2EFD-.png 600w, https://chronicler.tech/content/images/size/w1000/2026/03/-656A07D0-3653-4F49-B2B4-C85B4D7D2EFD-.png 1000w, https://chronicler.tech/content/images/2026/03/-656A07D0-3653-4F49-B2B4-C85B4D7D2EFD-.png 1356w" sizes="(min-width: 720px) 720px"></figure><p>It also delivered a <code>~/docs</code> subfolder which included even more documentation. Now to get this application deployed, I just need to go through the 01, 02, and 03 documents.</p><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/image-24.png" class="kg-image" alt="" loading="lazy" width="260" height="362"></figure><h2 id="9-testing-the-application-locally">9. Testing the Application Locally</h2><p>Cline started up application locally, with the frontend running on http://localhost:3000 and the backend Flask application running on http://localhost:8080. Here, you can see that it started both the HTTP server and the Flask server. But where's the database on my localhost?</p><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/-D962C724-6413-4B00-8388-B94BB38A6DF0-.png" class="kg-image" alt="" loading="lazy" width="1051" height="448" srcset="https://chronicler.tech/content/images/size/w600/2026/03/-D962C724-6413-4B00-8388-B94BB38A6DF0-.png 600w, https://chronicler.tech/content/images/size/w1000/2026/03/-D962C724-6413-4B00-8388-B94BB38A6DF0-.png 1000w, https://chronicler.tech/content/images/2026/03/-D962C724-6413-4B00-8388-B94BB38A6DF0-.png 1051w" sizes="(min-width: 720px) 720px"></figure><p>But the images weren't rendering correctly, so Cline spent some time troubleshooting to try to figure out why that was so. Here is an example of one of the troubleshooting steps (opening the file locally first).</p><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/-9AAFF2E8-DBC6-46E8-9837-355BAB78AB4F-.png" class="kg-image" alt="" loading="lazy" width="1055" height="534" srcset="https://chronicler.tech/content/images/size/w600/2026/03/-9AAFF2E8-DBC6-46E8-9837-355BAB78AB4F-.png 600w, https://chronicler.tech/content/images/size/w1000/2026/03/-9AAFF2E8-DBC6-46E8-9837-355BAB78AB4F-.png 1000w, https://chronicler.tech/content/images/2026/03/-9AAFF2E8-DBC6-46E8-9837-355BAB78AB4F-.png 1055w" sizes="(min-width: 720px) 720px"></figure><p>Cline stated that the root cause was that Python's built-in <code>http.server</code> on Windows serves SVG files with an incorrect MIME type (due to Windows registry MIME mappings), causing browsers to reject them. Anyway, it fixed it.</p><p>I manually ran the test cases using <code>pytest</code>, as indicated in the documentation, but I received an error indicating that the command was not recognized (see the first line in the following screenshot).</p><p>Cline executed the command to install <code>pytest</code>, ran through the test cases (21 passed, 2 failed), then proceeded to fix the code related to the two failed test cases.</p><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/image-27.png" class="kg-image" alt="" loading="lazy" width="700" height="697" srcset="https://chronicler.tech/content/images/size/w600/2026/03/image-27.png 600w, https://chronicler.tech/content/images/2026/03/image-27.png 700w"></figure><h2 id="9-manually-running-terraform">9. Manually Running Terraform</h2><p>I had originally requested Cline to use Terraform for infrastructure provisioning. It created all the Terraform <code>.tf</code> scripts for me, but I won't be able to run them unless I perform the following:</p><ol><li>Install Terraform, openssl, and the OCI client on my host machine (i.e., my laptop).</li><li>Populate certain cloud credentials in the <code>terraform.tfvars</code> files.</li><li>Generate the public/private key pairs.</li></ol><p>Full instructions were included in the readme files that were generated, but the execution wasn't flawless. I followed the instructions to create my key pairs:</p><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/image-25.png" class="kg-image" alt="" loading="lazy" width="1354" height="423" srcset="https://chronicler.tech/content/images/size/w600/2026/03/image-25.png 600w, https://chronicler.tech/content/images/size/w1000/2026/03/image-25.png 1000w, https://chronicler.tech/content/images/2026/03/image-25.png 1354w" sizes="(min-width: 720px) 720px"></figure><p>I ran into issues installing the OCI client and used a combination of Google and Cline to figure it out. One of the issues was some Window execution policy thingie.</p><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/Untitled4.png" class="kg-image" alt="" loading="lazy" width="1350" height="767" srcset="https://chronicler.tech/content/images/size/w600/2026/03/Untitled4.png 600w, https://chronicler.tech/content/images/size/w1000/2026/03/Untitled4.png 1000w, https://chronicler.tech/content/images/2026/03/Untitled4.png 1350w" sizes="(min-width: 720px) 720px"></figure><p>The <code>02-TERRAFORM-CONFIG.md</code> file provided me all instructions and mentioned what values it needed from the OCI console:</p><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/-3920742C-2FDA-4BEB-9530-DB9A793E48CC-.png" class="kg-image" alt="" loading="lazy" width="900" height="519" srcset="https://chronicler.tech/content/images/size/w600/2026/03/-3920742C-2FDA-4BEB-9530-DB9A793E48CC-.png 600w, https://chronicler.tech/content/images/2026/03/-3920742C-2FDA-4BEB-9530-DB9A793E48CC-.png 900w" sizes="(min-width: 720px) 720px"></figure><p>But I ran into more issues running Terraform where I had to prompt Cline multiple times for assistance. Here are some of my prompts:</p><ol><li>The command Cline provided to install Terraform didn't work.</li></ol><blockquote>When the command "choco install terraform" in Windows, I got this error: "choco : The term 'choco' is not recognized as the name of a cmdlet, function,"</blockquote><ol start="2"><li>Creating the API Gateway failed.</li></ol><blockquote>I received this error when running "terraform apply": &lt;&lt;&lt;oci_apigateway_deployment.comic_api: Creating...<br>╷<br>│ Error: 400-InvalidParameter, Invalid specification.routes[0].backend.functionId: should be an ocid of type fnfunc<br>│ Suggestion: Please update the parameter(s) in the Terraform config as per error message Invalid specification.routes[0].backend.functionId: should be an ocid of type fnfunc<br>│ Documentation: <a href="https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/apigateway_deployment?ref=chronicler.tech">https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/apigateway_deployment</a><br>│ API Reference:<br>│ Request Target: POST <a href="https://apigateway.us-ashburn-1.oci.oraclecloud.com/20190501/deployments?ref=chronicler.tech">https://apigateway.us-ashburn-1.oci.oraclecloud.com/20190501/deployments</a><br>│ Provider version: 8.4.0, released on 2026-03-04.<br>│ Service: Apigateway Deployment<br>│ Operation Name: CreateDeployment<br>│ OPC request ID: 4ff0aad05a433a0933724dd6659936c4/7C0155C4A9B1B2C22297AB694941449E/EC5637563A0E838E979FEB6C3D7C0DD0&gt;&gt;&gt;</blockquote><ol start="3"><li>It seems that there is a minor bug in the Terraform script to create the Autonomous Database. It fixed it automatically and asked me to try again.</li></ol><blockquote>When I ran the command "terraform apply" I received the following error: &lt;&lt;&lt; Error: Unsupported attribute<br>│<br>│ on adb.tf line 26, in resource "oci_database_autonomous_database" "comic_adb":<br>│ 26: data_storage_size_in_gbs,<br>│<br>│ This object has no argument, nested block, or exported attribute named<br>│ "data_storage_size_in_gbs". Did you mean "data_storage_size_in_gb"? &gt;&gt;&gt;</blockquote><ol start="4"><li>Another problem create the OCI Function.</li></ol><blockquote>When I ran the command "terraform apply" I received the following error: &lt;&lt;&lt; oci_functions_function.comic_function: Creating...<br>╷<br>│ Error: 400-InvalidParameter, Invalid Image us-ashburn-1.ocir.io/raastechinc/comic-collection/comic-api:0.0.1 does not exist or you do not have access to use it<br>│ Suggestion: Please update the parameter(s) in the Terraform config as per error message Invalid Image us-ashburn-1.ocir.io/raastechinc/comic-collection/comic-api:0.0.1 does not exist or you do not have access to use it<br>│ Documentation: <a href="https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/functions_function?ref=chronicler.tech">https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/functions_function</a><br>│ API Reference: <a href="https://docs.oracle.com/iaas/api/?ref=chronicler.tech#/en/functions/20181201/Function/CreateFunction">https://docs.oracle.com/iaas/api/#/en/functions/20181201/Function/CreateFunction</a><br>│ Request Target: POST <a href="https://functions.us-ashburn-1.oci.oraclecloud.com/20181201/functions?ref=chronicler.tech">https://functions.us-ashburn-1.oci.oraclecloud.com/20181201/functions</a><br>│ Provider version: 8.4.0, released on 2026-03-04.<br>│ Service: Functions Function<br>│ Operation Name: CreateFunction<br>│ OPC request ID: 6b999f5955c10285ce291326a706f9fc/2D395F47FE488AA6FA98AB69494144DA/0A4140C3F31DBA7E83041640FB9E214C<br>│<br>│<br>│ with oci_functions_function.comic_function,<br>│ on functions.tf line 32, in resource "oci_functions_function" "comic_function":<br>│ 32: resource "oci_functions_function" "comic_function" { &gt;&gt;&gt;</blockquote><p>Cline responded with resolutions to each and every one of these and I was successful in creating the entire infrastructure.</p><h2 id="10-deploy-the-container">10. Deploy the Container</h2><p>I ran into a number of errors when following the instructions in <code>03-DEPLOYMENT.md</code> to deploy all the code. Here's a stripped down version of that deployment guide:</p><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/image-26.png" class="kg-image" alt="" loading="lazy" width="533" height="1143"></figure><p>First, I asked it Cline to do the following:</p><blockquote>Can you update "03-DEPLOYMENT.md" and update Step 3 to make it using Microsoft Windows commands, not Linux commands?</blockquote><p>Steps 2.a and 2.b went fine which were all the Terraform stuff. Now that all the OCI services were provisioned, I ran a script to populate the database with sample data. I also ran into authentication issues, and after 15 minutes of back-and-forth with the AI agent, we were able to resolve it (something to do with password complexity).</p><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/Untitled6.png" class="kg-image" alt="" loading="lazy" width="1734" height="927" srcset="https://chronicler.tech/content/images/size/w600/2026/03/Untitled6.png 600w, https://chronicler.tech/content/images/size/w1000/2026/03/Untitled6.png 1000w, https://chronicler.tech/content/images/size/w1600/2026/03/Untitled6.png 1600w, https://chronicler.tech/content/images/2026/03/Untitled6.png 1734w" sizes="(min-width: 720px) 720px"></figure><p>I was able to confirm on the OCI console that the data was there:</p><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/Untitled9.png" class="kg-image" alt="" loading="lazy" width="1427" height="726" srcset="https://chronicler.tech/content/images/size/w600/2026/03/Untitled9.png 600w, https://chronicler.tech/content/images/size/w1000/2026/03/Untitled9.png 1000w, https://chronicler.tech/content/images/2026/03/Untitled9.png 1427w" sizes="(min-width: 720px) 720px"></figure><p>As I approached Step 3.b, which is deploying the OCI function, I ran into multiple issues:</p><blockquote>When I ran "fn use context oci-context" I received the following error &lt;&lt;&lt; Fn: error replacing file with tempfile &gt;&gt;&gt; Also, which directory am I supposed to be in when I run this command?</blockquote><blockquote>When I ran the "docker" command I received the following error &lt;&lt;&lt; WARNING! Using --password via the CLI is insecure. Use --password-stdin.<br>error during connect: in the default daemon configuration on Windows, the docker client must be run with elevated privileges to connect: Post "http://%2F%2F.%2Fpipe%2Fdocker_engine/v1.24/auth": open //./pipe/docker_engine: The system cannot find the file specified. &gt;&gt;&gt;</blockquote><blockquote>I started the Docker Desktop successfully. Running "docker info" just hangs indefinitely (I waited for at least 5 minutes). And the "docker login" command also hangs indefinitely (I waited for at least 5 minutes).</blockquote><p>The Cline AI agent took over from here. The agent tried deploying unsuccessfully (remember, I gave it auto-approve permissions to execute any command it wants to), it observed the error, analyzed what the root cause could be, fixed it (sometimes successfully, sometimes unsuccessfully), and on failed fixes it would continue troubleshooting until it got it right. There were a lot of issues, but Cline figured it all out.</p><p>After the OCI Function was deployed, it took the OCID on its own, updated the Terraform scripts with the value of the OCID, and applied the change via Terraform to update the API Gateway... all automatically on its own!</p><p>All along the way, it continued fixing the documentation, code, and Terraform scripts as needed.</p><h2 id="11-testing-the-deployed-application">11. Testing the Deployed Application</h2><p>Now that the application was deployed successfully on the cloud, Cline gave me the public URL. Here are a couple of screenshots of the application.</p><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/1bee3fa0-c64d-42d5-8465-7924dcb2c8f2.png" class="kg-image" alt="" loading="lazy" width="2000" height="1016" srcset="https://chronicler.tech/content/images/size/w600/2026/03/1bee3fa0-c64d-42d5-8465-7924dcb2c8f2.png 600w, https://chronicler.tech/content/images/size/w1000/2026/03/1bee3fa0-c64d-42d5-8465-7924dcb2c8f2.png 1000w, https://chronicler.tech/content/images/size/w1600/2026/03/1bee3fa0-c64d-42d5-8465-7924dcb2c8f2.png 1600w, https://chronicler.tech/content/images/2026/03/1bee3fa0-c64d-42d5-8465-7924dcb2c8f2.png 2160w" sizes="(min-width: 720px) 720px"></figure><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/cdb1ccc2-437d-40c6-961c-6b3b7d9e541d.png" class="kg-image" alt="" loading="lazy" width="2000" height="1016" srcset="https://chronicler.tech/content/images/size/w600/2026/03/cdb1ccc2-437d-40c6-961c-6b3b7d9e541d.png 600w, https://chronicler.tech/content/images/size/w1000/2026/03/cdb1ccc2-437d-40c6-961c-6b3b7d9e541d.png 1000w, https://chronicler.tech/content/images/size/w1600/2026/03/cdb1ccc2-437d-40c6-961c-6b3b7d9e541d.png 1600w, https://chronicler.tech/content/images/2026/03/cdb1ccc2-437d-40c6-961c-6b3b7d9e541d.png 2160w" sizes="(min-width: 720px) 720px"></figure><p>All the functionality was working, from navigation, to adding to the cart, to checking out.</p><h2 id="12-testing-the-deployed-application">12. Testing the Deployed Application</h2><p>I asked Cline the following aftewards:</p><blockquote>Export this entire chat into an HTML file(s) maintaining all formatting and images.</blockquote><p>Unfortunately, it did not do as I expected. I wanted a word-for-word export of the entire chat history, maintaining all formatting. Instead, it created a fully comprehensive (and impressive) HTML file with an organized version of what took place.</p><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/image-28.png" class="kg-image" alt="" loading="lazy" width="1521" height="25837" srcset="https://chronicler.tech/content/images/size/w600/2026/03/image-28.png 600w, https://chronicler.tech/content/images/size/w1000/2026/03/image-28.png 1000w, https://chronicler.tech/content/images/2026/03/image-28.png 1521w" sizes="(min-width: 720px) 720px"></figure><p>But from this writeup, this was one of the key information that I was looking for:</p><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/image-29.png" class="kg-image" alt="" loading="lazy" width="724" height="396" srcset="https://chronicler.tech/content/images/size/w600/2026/03/image-29.png 600w, https://chronicler.tech/content/images/2026/03/image-29.png 724w" sizes="(min-width: 720px) 720px"></figure><p>Across 4 sessions, the total engagement time was ~5 hours with a total cost of $32.35.</p> ]]></content:encoded>
    </item>
    <item>
        <title><![CDATA[ The OWASP DevSecOps Maturity Model (DSOMM) ]]></title>
        <description><![CDATA[ The Open Worldwide Application Security Project (OWASP) is a nonprofit foundation dedicated to improving the security of software through open-source projects, community-led initiatives, and educational resources. It&#39;s a vendor-neutral organization, meaning it does not endorse commercial products or services, ensuring that its guidance remains unbiased and community-driven.

OWASP ]]></description>
        <link>https://chronicler.tech/the-owasp-devsecops-maturity-model-dsomm/</link>
        <guid isPermaLink="false">698aab61151af50001e3a3b2</guid>
        <category><![CDATA[  ]]></category>
        <dc:creator><![CDATA[  ]]></dc:creator>
        <pubDate>Tue, 10 Mar 2026 10:28:02 -0400</pubDate>
        <media:content url="https://chronicler.tech/content/images/2026/02/owasp.png" medium="image"/>
        <content:encoded><![CDATA[ <p>The&nbsp;<strong>Open Worldwide Application Security Project (</strong><a href="https://owasp.org/?ref=chronicler.tech" rel="noreferrer"><strong>OWASP</strong></a><strong>)</strong>&nbsp;is a&nbsp;nonprofit foundation&nbsp;dedicated to improving the security of software through&nbsp;open-source projects,&nbsp;community-led initiatives, and&nbsp;educational resources. It's a&nbsp;vendor-neutral&nbsp;organization, meaning it does not endorse commercial products or services, ensuring that its guidance remains unbiased and community-driven.</p><p>OWASP is best known for the <em>OWASP Top 10</em>, a regularly updated list of the most critical web application security risks.</p><p>So I recently published my third book title <a href="https://www.amazon.com/DevSecOps-Oracle-Cloud-Automating-Infrastructure/dp/0138029415/?ref=chronicler.tech" rel="noreferrer">DevSecOps in Oracle Cloud</a>. This is a huge book hitting 640 pages in length. A lot of topics were covered, namely DevSecOps concepts, open-source tools, and obviously Oracle Cloud services that enable DevSecOps. It was through my book research and subsequent conference presentations that I came across and learned about the <strong>OWASP DevSecOps Maturity Model (DSOMM)</strong>.</p><p>(On a side note, here's another <a href="https://chronicler.tech/principles-of-secdevops/" rel="noreferrer">blog post</a> of mine that describes the differences between DevSecOps and SecDevOps.)</p><h2 id="from-on-prem-to-devsecops">From On-Prem to DevSecOps</h2><p>Every organization is at a different stage in their DevSecOps journey. Here's a diagram I created that shows the typical long-term evolution an organization may go through as it matures towards DevSecOps. </p><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/02/-F3246FE8-1730-4F7F-AAC0-AD4A91638F4A-.png" class="kg-image" alt="" loading="lazy" width="1389" height="613" srcset="https://chronicler.tech/content/images/size/w600/2026/02/-F3246FE8-1730-4F7F-AAC0-AD4A91638F4A-.png 600w, https://chronicler.tech/content/images/size/w1000/2026/02/-F3246FE8-1730-4F7F-AAC0-AD4A91638F4A-.png 1000w, https://chronicler.tech/content/images/2026/02/-F3246FE8-1730-4F7F-AAC0-AD4A91638F4A-.png 1389w" sizes="(min-width: 720px) 720px"></figure><p>If you're still in the early phases of your cloud journey, DevSecOps will likely not be on your mind. You have enough on your plate establishing your cloud standards, best practices, and governance. But as you continue to mature, you start introducing DevOps, hopefully followed by DevSecOps.</p><p>I used this diagram in several of my presentations on the topic, and I feel it is a self-explanatory way of depicting the <em>challenges</em>, <em>needs</em>, and <em>enablers</em> of each phase of the journey.</p><h2 id="introducing-dsomm">Introducing DSOMM</h2><p>I came across the <a href="https://owasp.org/www-project-devsecops-maturity-model/?ref=chronicler.tech" rel="noreferrer">DevSecOps Maturity Model</a> (DSOMM) in 2025, but it was originally introduced by OWASP in 2017.</p><p>The&nbsp;DSOMM&nbsp;is a framework designed to integrate security into DevOps practices effectively. It provides a structured approach to assess and enhance security measures across the software development lifecycle, ensuring that security is not overlooked during the implementation of DevOps strategies.</p><p>I love the graphical depiction of the model. Here, it provides a visual representation of your DevSecOps maturity level in an easy to understand color-coded diagram. The greener, the better. The darker the green, the more mature you are. More greens in the outer layers, the higher your mature level is.</p><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/02/image-28.png" class="kg-image" alt="" loading="lazy" width="558" height="553"></figure><p>DSOMM includes 6 core dimensions:</p><ul><li>Build &amp; Deployment</li><li>Culture &amp; Organization</li><li>Implementation</li><li>Information Gathering</li><li>Test &amp; Verification</li></ul><p>Each dimension includes multiple sub-dimensions, shown in the figure above.</p><p>An interactive model where you can build your own representation can be found at <a href="https://dsomm.owasp.org/?ref=chronicler.tech" rel="noreferrer">dsomm.owasp.org</a>. When clicking on a cell that represents the subdimension and maturity level, you are presented with a lifecycle toggle.</p><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/image-13.png" class="kg-image" alt="" loading="lazy" width="1745" height="942" srcset="https://chronicler.tech/content/images/size/w600/2026/03/image-13.png 600w, https://chronicler.tech/content/images/size/w1000/2026/03/image-13.png 1000w, https://chronicler.tech/content/images/size/w1600/2026/03/image-13.png 1600w, https://chronicler.tech/content/images/2026/03/image-13.png 1745w" sizes="(min-width: 720px) 720px"></figure><p>For example, the following diagram shows how when clicking on the cell (see #1 in the diagram) representing the <em>Deployment</em> subdimension at <em>Maturity Level 5</em>, you are presented with a deployment initiative (see #2), in this case, <em>Blue/Green Deployment</em>, and you can use toggle to indicate where you are in the lifecycle of this effort. Based on the whether you just started or if its fully implemented, the shade of green will change.</p><h2 id="what-next">What next?</h2><p>The following figure shows where you ideally want to be, which is seeing dark green on every sub-dimension in the outermost layer. Though practically impossible to achieve, the goal is to at least aim for it.</p><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/image-9.png" class="kg-image" alt="" loading="lazy" width="1024" height="1015" srcset="https://chronicler.tech/content/images/size/w600/2026/03/image-9.png 600w, https://chronicler.tech/content/images/size/w1000/2026/03/image-9.png 1000w, https://chronicler.tech/content/images/2026/03/image-9.png 1024w" sizes="(min-width: 720px) 720px"></figure><p>But what are you supposed to do with this model?</p><p>Go online and you'll read that it's a "framework" or a "roadmap" or an "assessment" or a "benchmark." None of these are necessarily wrong, as the OWASP DSOMM ultimately aims to help your organization incrementally improve security within DevOps practices.</p><p>But here is a simple actionable plan I suggest:</p><ol><li>Assess your current environment (don't overthink it), and use <a href="https://dsomm.owasp.org/?ref=chronicler.tech" rel="noreferrer">dsomm.owasp.org</a> to create a visual snapshot of your current state (creating a radar diagram like the above).</li><li>Use it to identify major gaps across various dimensions, and prioritize high-impact security activities that should be focused on.</li><li>Repeat every 6 months, and compare to previous snapshots over time.</li></ol><p>I keep using the word "journey" when it comes to DevSecOps, because it truly is. Startups shouldn't aim for Maturity Level 4 across the board. DSOMM is initially most effective when you pick Maturity Level 1 for everything and only Maturity Level 3 for your highest-risk areas.</p><p>One last note, you might find in some DSOMM documentation that Maturity Levels are described between 1 and 4 and in others between 1 and 5, the latter being the more recent one. But don't sweat it too much.</p> ]]></content:encoded>
    </item>
    <item>
        <title><![CDATA[ AI Code Generation: Overview, Risks, and Challenges ]]></title>
        <description><![CDATA[ AI code generation relies on machine learning and natural language processing to automatically generate code. It is such a broad definition and can imply anything from simple autocompletion to fully autonomous development.

Other common synonyms for &quot;AI code generation&quot; in use today are:

 * Vibe coding - Coined by ]]></description>
        <link>https://chronicler.tech/ai-code-generation-overview-risks-and-challenges/</link>
        <guid isPermaLink="false">69ae1f4b7528d60001581f83</guid>
        <category><![CDATA[  ]]></category>
        <dc:creator><![CDATA[  ]]></dc:creator>
        <pubDate>Mon, 09 Mar 2026 14:11:42 -0400</pubDate>
        <media:content url="https://chronicler.tech/content/images/2026/03/ai-blog.png" medium="image"/>
        <content:encoded><![CDATA[ <p>AI code generation relies on machine learning and natural language processing to automatically generate code. It is such a broad definition and can imply anything from simple autocompletion to fully autonomous development.</p><p>Other common synonyms for "AI code generation" in use today are:</p><ul><li><strong>Vibe coding </strong>- Coined by <a href="https://www.linkedin.com/in/andrej-karpathy-9a650716/?ref=chronicler.tech" rel="noreferrer">Andrej Karpathy</a>, but my least favorite term. Describes a high-level approach where a developer provides natural language "vibes" or intent, and the AI handles the implementation without the user needing to touch the syntax.</li><li><strong>Agentic development</strong> - Refers to using autonomous AI agents that don't just write snippets, but can plan, execute, test, and debug multi-file changes across an entire repository independently.</li><li><strong>AI-assisted programming </strong>- A broad, professional term for a collaborative workflow where a human developer remains the primary pilot while using AI to accelerate routine tasks like boilerplate or refactoring.</li><li><strong>Prompt-to-code </strong>- Not a commonly used term but recently referred to as NLP-Dev (Natural Language Programming-Development). Describes the specific technical act of translating a human-language description directly into executable source code.</li><li><strong>Autonomous coding </strong>- My specific area of interest. Minimal to zero human intervention needed here.</li></ul><p>I may use many of these terms interchangeably, but in the end, they all mean the same thing, which is to leverage natural language prompting to assist in code creation with little to no human intervention.</p><p>Below you'll get a simple and generic overview of AI code generation, but my initial intent of this post was to highlight some of the risks (and possible mitigations) of over-reliance on AI code generation. Read on...</p><h2 id="why-use-ai-code-generation"><strong>Why use AI code generation?</strong></h2><p>If not obvious already, some of the benefits of AI code generation include:</p><ul><li>Enables developers to generate code faster</li><li>Accelerates debugging and troubleshooting</li><li>Boosts developer productivity</li><li>Rapid experimentation</li><li>Quickly and efficiently test and debug code</li><li>Reduces the work of manually writing lines of code</li><li>Alleviates developer’s mental load and reduces burnout</li><li>Frees developers to focus on higher-value work</li><li>Makes code development accessible to non-developers</li></ul><p>Rapid experimentation and accelerating development seem to be the top two benefits often cited.</p><h2 id="how-does-ai-code-generation-work">How does AI code generation work?</h2><p>The following diagram provides a simple explanation of how AI code generation works.</p><p>First, the developer enters a prompt using natural language to a plugin within the IDE. This could be a simple "Create an HTML-based calculator application." The plugin makes an API call to a provider's model (you choose the provider and model), usually at a cost per call. The response is returned by the model. The response could be informational or instruct the plugin to begin manipulating your local code for you (i.e., operating as an "agent").</p><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/image-8.png" class="kg-image" alt="" loading="lazy" width="848" height="424" srcset="https://chronicler.tech/content/images/size/w600/2026/03/image-8.png 600w, https://chronicler.tech/content/images/2026/03/image-8.png 848w" sizes="(min-width: 720px) 720px"></figure><h2 id="what-are-some-risks-and-challenges-of-ai-code-generation">What are some risks and challenges of AI code generation?</h2><ol><li><strong>Low quality code </strong>- Hallucinations, lack of consistency, and poor coding standards can be experienced. Repeated attempts for the agent to fix code can be unsuccessful.</li><li><strong>Security vulnerabilities </strong>- Data poisoning is a real problem. For example, there are over 1 billion repos in GitHub, 278 million of them public. No doubt that a significant number of these repos have malicious code intentionally embedded within them with serious vulnerabilities so that unsuspecting folks are compromised when they download and execute the code. Now imagine GitHub Copilot being trained on this code.</li><li><strong>Data privacy </strong>- Your code and data could be used for model training, particularly if you are not on a paid business or enterprise plan.</li><li><strong>Licensing &amp; copyright risks </strong>- The model could potentially include open-source code without attribution. This is all new territory and implications within the industry are yet to be seen.</li><li><strong>Cost </strong>- The more calls that are made through continuous prompting by the developer, the larger your code set, and the higher quality the model you are using, then expect more $$$ required. Food for thought: If it takes 10 seconds to generate code but 20 minutes to verify it, was it actually faster/cheaper?</li><li><strong>Speed </strong>- Complex tasks on certain models can take considerable time (50+ minutes for a single request) and still be riddled with bugs.</li><li><strong>Risk of technical debt </strong>- Can create long-term maintenance challenges due to poorly structured or inconsistent implementation.</li><li><strong>Skills atrophy </strong>- Coding skills of developers can erode over time.</li><li><strong>Loss of developer control </strong>- Too much developer dependency on AI can contribute to reduced understanding of codebase.</li></ol><h2 id="how-do-you-mitigate-some-of-the-risks-of-ai-code-generation">How do you mitigate some of the risks of AI code generation?</h2><p>Taking each of the risks from the previous section, here are some approaches to mitigate each of those risks.</p><ol><li><strong>Low quality code </strong>–&gt; Always review AI generated code.</li><li><strong>Security vulnerabilities </strong>–&gt; Enforce mandatory scanning of your code with SAST tools within your pipelines.</li><li><strong>Data privacy </strong>–&gt; Consider self-hosted AI coding assistants and/or verify vendor’s policies. Always read the fine print.</li><li><strong>Licensing &amp; copyright risks </strong>–&gt; Run generated code through license scanners and/or verify vendor’s policies. Some vendors (e.g., Microsoft for GitHub Copilot) include indemnification clauses in their upper tiered plans. GitHub Copilot also has an "exclusion" filter to prevent the AI from suggestion code that matches public repositories.</li><li><strong>Cost </strong>–&gt; Consider lower cost models (e.g., Claude Sonnet 4.6 versus Claude Opus 4.6; see my other post on this <a href="https://chronicler.tech/comparing-the-claude-sonet-4-6-and-claude-opus-4-6-llm-models/" rel="noreferrer">here</a>).</li><li><strong>Speed </strong>–&gt; Consider models that emphasize speed over quality for non-complex scenarios (e.g., front-end stuff) (see my other post on this <a href="https://chronicler.tech/comparing-the-claude-sonet-4-6-and-claude-opus-4-6-llm-models/" rel="noreferrer">here</a>).</li><li><strong>Risk of technical debt </strong>–&gt; If you have bandwidth restrictions to perform code reviews, consider automated static code analysis tools.</li><li><strong>Skills atrophy </strong>- Developers should periodically implement components or modules manually and conduct design reviews.</li><li><strong>Loss of developer control </strong>–&gt; Mandate that AI-generated code be treated as a draft and thus requires developer validation first, ensuring that it aligns with the overarching architecture. This is easier said than done though.</li></ol><p>The reality is, there is no single tool that stops AI risk. Leveraging layered defense, implement SAST (for the code), SCA (for the libraries), and a human (for the logic).</p><p>One of my fears of modern AI and autonomous code generation is that it may eventually create a generation of <em>Copy-Paste Developers</em> who can't debug the foundations of their own code.</p> ]]></content:encoded>
    </item>
    <item>
        <title><![CDATA[ Comparing the Claude Sonnet 4.6 and Claude Opus 4.6 LLM models ]]></title>
        <description><![CDATA[ So we&#39;re told that Claude Sonnet 4.6 is an LLM that is optimized for speed and balanced performance when it comes to AI code generation, while Claude Opus 4.6 excels in maximum reasoning, coding, and complex problem-solving tasks (i.e., more expensive). I have so far ]]></description>
        <link>https://chronicler.tech/comparing-the-claude-sonet-4-6-and-claude-opus-4-6-llm-models/</link>
        <guid isPermaLink="false">69ada1527528d60001581e3d</guid>
        <category><![CDATA[  ]]></category>
        <dc:creator><![CDATA[  ]]></dc:creator>
        <pubDate>Sun, 08 Mar 2026 17:33:35 -0400</pubDate>
        <media:content url="https://chronicler.tech/content/images/2026/03/7a5f688b-2353-488c-b1e1-ce2db102b727.png" medium="image"/>
        <content:encoded><![CDATA[ <p>So we're told that <strong>Claude Sonnet 4.6 </strong>is an LLM that is optimized for speed and balanced performance when it comes to AI code generation, while <strong>Claude Opus 4.6 </strong>excels in maximum reasoning, coding, and complex problem-solving tasks (i.e., more expensive). I have so far used both models for AI code generation/assistance/vibing. Both models were released in February 2026 and represent a shift from "chat" to "agents."</p><p>Recently as I was preparing a demo on <strong>Visual Studio Code + Cline + Claude Opus </strong>for an upcoming conference presentation I will be giving, I ran through a specific use case. This was the first time I used the latest Claude Opus 4.6, and my previous experience had only been with Sonnet. I was shocked that the entire autonomous application generation and deployment took 5 hours and cost $32.35, both higher than I expected. But then again, we were all warned that Opus was more expensive and took longer. In all fairness, the model created a database-driven application with a front-end, backend, Terraform scripts, and "mostly" autonomous deployment to Oracle Cloud Infrastructure.</p><p>So I embarked on a mini exercise to try to get some real world experience comparing Sonnet and Opus. I ran two tests detailed below and compared the results.</p><h2 id="test-1-recreating-the-r-type-game">Test #1: Recreating the R-Type Game</h2><p>Back in 1988, there was an awesome game I had called R-Type on the Commodore 64. Could modern day AI code assistants recreate it for me?</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://chronicler.tech/content/images/2026/03/image-5.png" class="kg-image" alt="" loading="lazy" width="639" height="399" srcset="https://chronicler.tech/content/images/size/w600/2026/03/image-5.png 600w, https://chronicler.tech/content/images/2026/03/image-5.png 639w"><figcaption><span style="white-space: pre-wrap;">R-Type on the Commodore 64</span></figcaption></figure><h3 id="the-prompt">The Prompt</h3><p>This was the prompt I used and submitted to both models; Sonnet 4.6 and Opus 4.6. Coming up with the prompt involved a little bit of meta prompting (where you ask the chatbot to help you create a more precise and detailed prompt).</p><pre><code class="language-AI prompt">You are an expert JavaScript game developer.

Create a small browser game inspired by the classic side-scrolling shooter **R-Type**, originally released on the **Commodore 64**. This must NOT be a full recreation of the original game. It should only capture the core gameplay idea: a side-scrolling spaceship shooter. The first page should be welcome page, like a placeholder where the user can click on a button and be taken to another page which runs the game.

Requirements:

GAMEPLAY

* The game runs entirely in the browser.
* The player controls a spaceship flying from left to right while the world scrolls right-to-left.
* The ship can:
  * Move up/down/left/right
  * Shoot projectiles forward
* Enemies enter from the right side of the screen.
* Enemies move in simple patterns (sine wave, straight line, or diagonal).
* Enemy ships can be destroyed by the player's shots.
* Collision with enemies reduces player health.
* The level ends after ~60 seconds or when the player reaches the end of the scrolling map.
* Include a small boss or large enemy at the end of the level.

LEVEL DESIGN

* Only ONE short level.
* Automatically scrolling background.
* Parallax background layers to simulate depth.
* The level should contain:
  * 3–5 enemy waves
  * A final boss
* After the boss is defeated, display a "Level Complete" screen.

GRAPHICS STYLE

* This is a **2D game**, but the graphics should be styled to look **pseudo-3D** using:
  * lighting gradients
  * shading
  * highlights
  * soft shadows
  * layered sprites
* Avoid pixel-art Commodore style.
* Instead use smooth vector-style or canvas-rendered shapes that appear modern.
* All rendering should be done using HTML5 Canvas.

TECHNICAL REQUIREMENTS

* Use plain JavaScript (ES6+).
* No heavy frameworks.
* Small libraries are allowed only if necessary.
* Use requestAnimationFrame for the game loop.
* Organize the code cleanly into module.
* The project should run by simply opening `index.html`.
* Generate simple shapes procedurally if possible instead of image files.

VISUAL DETAILS

* Background space with stars
* Moving nebula layer
* Metallic-looking player ship with lighting
* Enemy ships with glowing engines
* Laser shots with glow effects
* Explosions using particles

CONTROLS
Keyboard controls:

* Arrow keys → movement
* Spacebar → shoot

GAME HUD
Display:

* Player health
* Score
* Level progress bar

CODE QUALITY

* Write clear, readable code.
* Include comments explaining the game loop and rendering logic.
* Avoid unnecessary complexity.
* Ensure the game runs at ~60 FPS.</code></pre><h3 id="sonnet-results">Sonnet Results</h3><p>The game created by Sonnet was a bit superior to the Opus version. I preferred the look of the welcome page created by Sonnet as you can see here.</p><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/R-Void-Galaxy-Strike-03-07-2026_10_13_PM.png" class="kg-image" alt="" loading="lazy" width="2000" height="1025" srcset="https://chronicler.tech/content/images/size/w600/2026/03/R-Void-Galaxy-Strike-03-07-2026_10_13_PM.png 600w, https://chronicler.tech/content/images/size/w1000/2026/03/R-Void-Galaxy-Strike-03-07-2026_10_13_PM.png 1000w, https://chronicler.tech/content/images/size/w1600/2026/03/R-Void-Galaxy-Strike-03-07-2026_10_13_PM.png 1600w, https://chronicler.tech/content/images/2026/03/R-Void-Galaxy-Strike-03-07-2026_10_13_PM.png 2148w" sizes="(min-width: 720px) 720px"></figure><p>And though you can't see it here, the animation of your spacecraft would tilt upwards and downwards at an angle when moved, versus a static shaped craft in the Opus version. Note that I never specified the animation behavior to either model.</p><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/R-Void-Galaxy-Strike-03-07-2026_10_10_PM.png" class="kg-image" alt="" loading="lazy" width="2000" height="1025" srcset="https://chronicler.tech/content/images/size/w600/2026/03/R-Void-Galaxy-Strike-03-07-2026_10_10_PM.png 600w, https://chronicler.tech/content/images/size/w1000/2026/03/R-Void-Galaxy-Strike-03-07-2026_10_10_PM.png 1000w, https://chronicler.tech/content/images/size/w1600/2026/03/R-Void-Galaxy-Strike-03-07-2026_10_10_PM.png 1600w, https://chronicler.tech/content/images/2026/03/R-Void-Galaxy-Strike-03-07-2026_10_10_PM.png 2148w" sizes="(min-width: 720px) 720px"></figure><h3 id="opus-results">Opus Results</h3><p>The difference in the final result between Sonnet and Opus versions was not significant. Though I preferred the look of the welcome page of the Sonnet version (versus the Opus version below), keep in mind I wasn't explicit in my prompt in regards to the layout, design, or aesthetic preference. Specificity in prompting would have yielded better results, and I could have re-engaged the model to continue tweaking it to my liking, which I did not do in this test.</p><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/NOVA-STRIKE-----Side-Scrolling-Shooter-03-07-2026_10_13_PM-1.png" class="kg-image" alt="" loading="lazy" width="2000" height="1025" srcset="https://chronicler.tech/content/images/size/w600/2026/03/NOVA-STRIKE-----Side-Scrolling-Shooter-03-07-2026_10_13_PM-1.png 600w, https://chronicler.tech/content/images/size/w1000/2026/03/NOVA-STRIKE-----Side-Scrolling-Shooter-03-07-2026_10_13_PM-1.png 1000w, https://chronicler.tech/content/images/size/w1600/2026/03/NOVA-STRIKE-----Side-Scrolling-Shooter-03-07-2026_10_13_PM-1.png 1600w, https://chronicler.tech/content/images/2026/03/NOVA-STRIKE-----Side-Scrolling-Shooter-03-07-2026_10_13_PM-1.png 2148w" sizes="(min-width: 720px) 720px"></figure><p>The gameplay window in the Opus version did not fill the entire browser as you can see below, but the Sonnet version did. Again, with additional re-prompting I could have requested from the model to do so.</p><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/NOVA-STRIKE-----In-Game-03-07-2026_10_10_PM.png" class="kg-image" alt="" loading="lazy" width="2000" height="1025" srcset="https://chronicler.tech/content/images/size/w600/2026/03/NOVA-STRIKE-----In-Game-03-07-2026_10_10_PM.png 600w, https://chronicler.tech/content/images/size/w1000/2026/03/NOVA-STRIKE-----In-Game-03-07-2026_10_10_PM.png 1000w, https://chronicler.tech/content/images/size/w1600/2026/03/NOVA-STRIKE-----In-Game-03-07-2026_10_10_PM.png 1600w, https://chronicler.tech/content/images/2026/03/NOVA-STRIKE-----In-Game-03-07-2026_10_10_PM.png 2148w" sizes="(min-width: 720px) 720px"></figure><h3 id="conclusion-of-test-1">Conclusion of Test #1</h3><p>I am reminded of this tweet.</p><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/image-6.png" class="kg-image" alt="" loading="lazy" width="581" height="255"></figure><p>Generally speaking (and I say this with some hesitancy), the results of your AI generated code is only as good as the quality of your prompt. But by providing more details, specifics, and clarifications during re-prompting can you achieve your desired output.</p><p>This table compares the cost, duration, and tools for both. Given that there was no difference in cost or time taken to generate the application, Sonnet wins by a small margin due to better gameplay animations and more pleasing welcome page.</p>
<!--kg-card-begin: html-->
<table border="1" cellpadding="20" cellspacing="20" width="600pt">
 <tr bgcolor="lightblue">
  <td width="64" style="width:100pt"></td>
  <td width="64" style="width:250pt"><b>Sonnet 4.6</b></td>
  <td width="64" style="width:250pt"><b>Opus 4.6</b></td>
 </tr>
 <tr>
  <td><b>Cost</b></td>
  <td>$2.34 </td>
  <td>$2.33 </td>
 </tr>
 <tr>
  <td><b>Duration</b></td>
  <td>21 minutes</td>
  <td>17 minutes</td>
 </tr>
 <tr>
  <td><b>Tools</b></td>
  <td>JavaScript (ES6+)<br>
    HTML5<br>
    CSS3<br>
    HTML5 Canvas API<br>
    Web APIs (e.g., requestAnimationFrame)<br>
    Python (local HTTP server)<br>
    Puppeteer (testing)<br>
    No external libraries were used</td>
  <td>JavaScript (ES6+)<br>
    HTML5<br>
    CSS3<br>
    HTML5 Canvas API<br>
    Web APIs (e.g., requestAnimationFrame)<br>
    No test cases developed<br>
    No external libraries were used</td>
 </tr>
</table>
<!--kg-card-end: html-->
<h2 id="test-2-the-multidimensional-benchmark-test">Test #2: The Multidimensional Benchmark Test</h2><p>I asked ChatGPT to help me come up with a prompt that can measure the performance of each of the two models. It generated a single prompt (below) that I pasted into the Cline plugin in VS Code.</p><p>The prompt instructed the model to build a small but meaningful application that tests several dimensions of AI capability:</p><ul><li>algorithmic reasoning</li><li>code architecture decisions</li><li>UI generation</li><li>structured data handling</li><li>documentation clarity</li><li>self-evaluation</li></ul><p>This type of multi-dimensional benchmark task is commonly used in LLM evaluation because it tests planning + implementation + explanation, rather than just code generation.</p><h3 id="the-prompt-1">The Prompt</h3><p>The application to be generated from this prompt is a mini AI evaluation dashboard that includes algorithmic tasks and analysis.</p><pre><code class="language-AI prompt">You are an expert software architect and engineer.

Your task is to design and implement a small application that can be used to evaluate the reasoning, coding, architecture, and explanation capabilities of an AI model.

The application must be complex enough to require planning and multiple components, but small enough to be implemented in under ~600 lines of code total.

OBJECTIVE
Create a self-contained application that tests the following capabilities:

1. Algorithmic reasoning
2. Data processing
3. Clean software architecture
4. UI generation
5. Explanation and documentation quality

APPLICATION REQUIREMENTS

Build a browser-based application called:

"AI Reasoning Benchmark"

TECH STACK
Use only:

HTML
CSS
Vanilla JavaScript (no frameworks)

The entire application should run locally in the browser.

FEATURES

1. Problem Generator

Create a module that generates several types of problems:

A. Pathfinding problem
- Generate a random 10x10 grid
- Add obstacles randomly
- Start and goal nodes
- Solve with A* or Dijkstra

B. Scheduling optimization
- Given tasks with durations and dependencies
- Compute optimal schedule order

C. Logic puzzle
- Example: simple constraint satisfaction puzzle

The application should solve these problems and visualize the result.

2. Visualization

Include visual components:

Grid visualization for pathfinding

Dependency graph visualization for scheduling

Simple puzzle explanation output

3. Architecture

The code must be structured clearly:

/app.js
/pathfinding.js
/scheduler.js
/puzzles.js
/ui.js

Explain the design decisions.

4. Benchmark Report

At the end, generate a small report showing:

Number of problems solved
Runtime performance (approximate timing)
Explanation of the solutions
Limitations of the algorithms

5. Self-Evaluation

Add a section where the model writes:

"How well this solution demonstrates AI reasoning capability."

Explain tradeoffs and improvements.

OUTPUT FORMAT

Provide:

1. Project structure
2. Complete source code for each file
3. Setup instructions
4. Short design explanation

IMPORTANT

Do NOT over-engineer.
Do NOT use external libraries.
Keep code readable and modular.

The goal is to measure the model's reasoning, structure, and engineering quality.

Focus on clarity, architecture, and correctness.</code></pre><h3 id="sonnet-results-1">Sonnet Results</h3><p>The key differences between the Sonnet (shown below) and Opus outputs appears to be mostly aesthetic. In the conclusion later on, I highlight some differences between the two outputs.</p><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/image-1.png" class="kg-image" alt="" loading="lazy" width="1158" height="4376" srcset="https://chronicler.tech/content/images/size/w600/2026/03/image-1.png 600w, https://chronicler.tech/content/images/size/w1000/2026/03/image-1.png 1000w, https://chronicler.tech/content/images/2026/03/image-1.png 1158w" sizes="(min-width: 720px) 720px"></figure><h3 id="opus-results-1">Opus Results</h3><p>The tests generated by both the Sonnet and Opus (shown here) models were nearly identical in performance, quality, and output, so the differences were mostly negligible. Again, I have highlighted some differences in the conclusion below.</p><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/03/image-2.png" class="kg-image" alt="" loading="lazy" width="905" height="4730" srcset="https://chronicler.tech/content/images/size/w600/2026/03/image-2.png 600w, https://chronicler.tech/content/images/2026/03/image-2.png 905w" sizes="(min-width: 720px) 720px"></figure><h3 id="conclusion-of-test-2">Conclusion of Test #2</h3><p>Aside from a different aesthetic look between the Sonnet-generated application and the Opus-generated one, both actually behaved similarly, with a slight edge given to the Sonnet application.</p><p>The Sonnet application included a better scheduler that measured in days rather than units and was easier to follow, and its self-evaluation was also better, as it provided scoring and clearer explanations. All the other tests in both models were similar in quality, performance, and output.</p><p>As far as the cost and duration, there were also no notable differences. Sonnet is the winner here again due to the reasons mentioned in the previous paragraph.</p>
<!--kg-card-begin: html-->
<table border="1" cellpadding="20" cellspacing="20" width="600pt">
 <tr bgcolor="lightblue">
  <td width="64" style="width:100pt"></td>
  <td width="64" style="width:250pt"><b>Sonnet 4.6</b></td>
  <td width="64" style="width:250pt"><b>Opus 4.6</b></td>
 </tr>
 <tr>
  <td><b>Cost</b></td>
  <td>$0.7977</td>
  <td>$0.7688</td>
 </tr>
 <tr>
  <td><b>Duration</b></td>
  <td>11 minutes</td>
  <td>8 minutes</td>
 </tr>
</table>
<!--kg-card-end: html-->
<h2 id="final-final-conclusion">Final, Final Conclusion</h2><p>Opus is originally designed to excel over Sonnet in these areas:</p><ul><li>Architecture design - By delivering cleaner modularization</li><li>Algorithm choice - By selecting better heuristics</li><li>Code reliability - By producing better working code</li><li>Explanation depth - By employing deeper reasoning</li></ul><p>Sonnet is marketed as a cheaper, faster implementation but delivering simpler solutions. Opus, on the other hand, is marketed as having more advanced reasoning and better architecture. I did not see these tradeoffs in these two tests.</p><p>In fact, some benchmarks (like SWE-bench) show Sonnet 4.6 trailing Opus by only a slim margin (e.g., 1.2-2%) while being significantly faster.</p><p>In terms of pricing, Sonnet 4.6 is $3 per million input tokens and $15 per million output tokens, while Opus 4.6 is $15 per million input tokens and $75 per million output tokens.</p><p>Keep in mind that the tests I ran were not complex. I also did not spent time with the other Sonnet 4.6:1m or Opus 4.6:1m models. Those models increase the context window by about 5x to process larger inputs, and instead of reading projects, they can actually read entire repositories. This is good for parallel and team development, something I don't find necessary in my current work.</p><p>For the complex demo I mentioned at the start of this post, I used Opus 4.6. It generated a multi-tiered web application deployed to the cloud. Opus took care of all infrastructure provisioning and most of the deployment. Bug after bug was resolved automatically by Opus and fully detailed and impressive documentation and reasoning were provided.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://chronicler.tech/content/images/2026/03/image-7.png" class="kg-image" alt="" loading="lazy" width="743" height="390" srcset="https://chronicler.tech/content/images/size/w600/2026/03/image-7.png 600w, https://chronicler.tech/content/images/2026/03/image-7.png 743w" sizes="(min-width: 720px) 720px"><figcaption><span style="white-space: pre-wrap;">Snapshot of my semi-complex project that I plan on demoing</span></figcaption></figure><p>How would this complex project have fared under Sonnet? I'm not sure. Other blogs seem to recommend Sonnet for UI/UX and Opus for backend/database schema logic. In conclusion, I wish I could provide you with a concrete recommendation on which model to use when, but I may personally lean towards Sonnet.</p> ]]></content:encoded>
    </item>
    <item>
        <title><![CDATA[ Things to watch out for when implementing DR for OIC ]]></title>
        <description><![CDATA[ Oracle Integration Cloud (OIC) is a fully managed, highly available integration platform that abstracts much of the underlying infrastructure from customers.

For those who aim for resiliency, implementing disaster recovery (DR) is one approach that protects against cloud region failures. There are two approaches to implementing DR, but that&#39; ]]></description>
        <link>https://chronicler.tech/things-to-watch-out-for-when-implementing-dr-for-oic/</link>
        <guid isPermaLink="false">697f9165151af50001e3a293</guid>
        <category><![CDATA[  ]]></category>
        <dc:creator><![CDATA[  ]]></dc:creator>
        <pubDate>Sun, 01 Feb 2026 13:05:01 -0500</pubDate>
        <media:content url="https://chronicler.tech/content/images/2026/02/ChatGPT-Image-Feb-1--2026--12_57_23-PM.png" medium="image"/>
        <content:encoded><![CDATA[ <p>Oracle Integration Cloud (OIC) is a fully managed, highly available integration platform that abstracts much of the underlying infrastructure from customers.</p><p>For those who aim for resiliency, implementing disaster recovery (DR) is one approach that protects against cloud region failures. There are two approaches to implementing DR, but that's for a separate blog post. In this post, however, I'd like to outline some of the real challenges and key areas to watch out for when designing and implementing DR for OIC. Even if you opt for the one-click Oracle-Managed DR turnkey solution, you should be aware of these.</p><p>There are too many areas that need to be watched out for, from the network setup complexity to managing credentials to understanding how your integrations will behave in the event of a failover. Some others areas of awareness are mentioned below.</p><blockquote><strong>Manual Metadata Synchronization</strong><br>The single biggest responsibility. If your CI/CD process is not robust and disciplined, your primary and secondary instances will drift, and your DR plan will fail.</blockquote><blockquote><strong>Loss of In-Flight Data</strong><br>There is no built-in mechanism to recover transactions that were actively processing during an outage.</blockquote><blockquote><strong>Runtime vs. Design-Time URL</strong><br>The custom endpoint is for runtime traffic only. Developers and administrators must still use the region-specific URL to access the OIC design console. This can cause confusion if not managed properly.</blockquote><blockquote><strong>Post-Failover Cleanup</strong><br>An emergency failover leaves artifacts running in the original primary region. Manual cleanup and resetting the DR configuration are required before you can fail back, as documented in "Resetting DR Configuration After a Failover".</blockquote><blockquote><strong>Component Exclusions</strong><br>Visual Builder (VB) and Process Automation (OPA) require separate DR handling.</blockquote><blockquote><strong>Certificates</strong><br>SSL certificates must be managed and present in both regions.</blockquote><p>OIC provides a robust, enterprise-grade integration platform. The biggest risks when implementing DR are assumptions, drift, and lack of operational rigor.</p><p>If you're serious about OIC disaster recovery:</p><ul><li>Automate everything you reasonably can</li><li>Build in recovery, atomicity, and validations in your integrations</li><li>Test annually</li><li>Align business expectations with platform realities</li></ul> ]]></content:encoded>
    </item>
    <item>
        <title><![CDATA[ What is Gatling.io, the popular open-source load testing tool? ]]></title>
        <description><![CDATA[ Performance testing is an umbrella term for a broad range of tests that evaluate a system&#39;s overall speed, stability, scalability, and resource usage. Load testing, in contrast, is a specific type of performance testing focused solely on measuring system behavior under a particular, expected amount of user traffic ]]></description>
        <link>https://chronicler.tech/what-is-gatling-io-the-popular-open-source-load-testing-tool/</link>
        <guid isPermaLink="false">6971340c151af50001e3a1c2</guid>
        <category><![CDATA[  ]]></category>
        <dc:creator><![CDATA[  ]]></dc:creator>
        <pubDate>Thu, 22 Jan 2026 10:14:13 -0500</pubDate>
        <media:content url="https://chronicler.tech/content/images/2026/01/68b7320e6cc4818a2a61b561_Opengraph_Gatling_Website.png" medium="image"/>
        <content:encoded><![CDATA[ <p><strong>Performance testing</strong>&nbsp;is an umbrella term for a broad range of tests that evaluate a system's overall speed, stability, scalability, and resource usage.&nbsp;<strong>Load testing</strong>, in contrast, is a specific&nbsp;<em>type</em>&nbsp;of performance testing focused solely on measuring system behavior under a particular, expected amount of user traffic or workload.&nbsp;</p><p>Basically...</p><ul><li><strong>Performance Testing:</strong>&nbsp;Goes deeper to analyze bottlenecks, measure response times, and validate scalability.</li><li><strong>Load Testing:</strong>&nbsp;Simulates thousands of concurrent users to check system behavior under heavy traffic.</li></ul><p><a href="https://gatling.io/?ref=chronicler.tech" rel="noreferrer">Gatling.io</a> is&nbsp;both a&nbsp;<em>load testing </em>and <em>performance testing </em>tool, functioning as a comprehensive framework to simulate user traffic, identify bottlenecks, and assess system performance under various conditions, with a strong emphasis on developer-friendly, code-based scripting for web apps, APIs, and microservices.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://chronicler.tech/content/images/2026/01/image-5.png" class="kg-image" alt="" loading="lazy" width="1320" height="919" srcset="https://chronicler.tech/content/images/size/w600/2026/01/image-5.png 600w, https://chronicler.tech/content/images/size/w1000/2026/01/image-5.png 1000w, https://chronicler.tech/content/images/2026/01/image-5.png 1320w" sizes="(min-width: 720px) 720px"><figcaption><span style="white-space: pre-wrap;">The www.gatling.io website</span></figcaption></figure><p><a href="https://gatling.io/?ref=chronicler.tech" rel="noreferrer">Gatling.io</a> is&nbsp;a popular, open-source load testing platform and offers both a free Community Edition and an advanced Enterprise version.</p><h2 id="brief-comparison-to-apache-jmeter">Brief Comparison to Apache JMeter</h2><p>I am neither an expert in Gatling.io nor <a href="https://jmeter.apache.org/?ref=chronicler.tech" rel="noreferrer">Apache JMeter</a>, but have used both of them for isolated testing. For reference, Apache JMeter was created in 1998 and Gatling.io in 2011. </p>
<!--kg-card-begin: html-->
<table border="0" cellpadding="0" cellspacing="0">
 <tr>
  <td></td>
  <td style="background-color: #EEEEEE;"><b>Gatling</b></td>
  <td style="background-color: #EEEEEE;"><b>Apache JMeter</b></td>
 </tr>
 <tr>
  <td style="background-color: #DDDDFF;" nowrap><b>Performance</b></td>
  <td><font style="color: #00CC00">✔</font> <b>High performance</b>: Asynchronous architecture uses fewer resources for high concurrency</td>
  <td><font style="color: red">✘</font> <b>Resource intensive</b>: Thread-based architecture can use more CPU/memory</td>
 </tr>

 <tr>
  <td style="background-color: #DDDDFF;" nowrap><b>GUI</b></td>
  <td><font style="color: red">✘</font> <b>No built-in GUI</b>: Test creation is code-based</td>
  <td><font style="color: red">✘</font> <b>GUI Lock-in</b>: Script changes often require opening the UI</td>
 </tr>

 <tr>
  <td style="background-color: #DDDDFF;" nowrap><b>CI/CD</b></td>
  <td><font style="color: #00CC00">✔</font> <b>CI/CD Friendly</b>: Built for modern pipelines; better source control integration</td>
  <td><font style="color: red">✘</font> <b>Less CI/CD Friendly</b>: GUI dependency makes source control and automation harder</td>
 </tr>

 <tr>
  <td style="background-color: #DDDDFF;" nowrap><b>Reporting</b></td>
  <td><font style="color: #00CC00">✔</font> <b>Clear Reporting</b>: Generates detailed, readable HTML reports</td>
  <td></td>
 </tr>

 <tr>
  <td style="background-color: #DDDDFF;" nowrap><b>Plugins</b></td>
  <td></td>
  <td><font style="color: #00CC00">✔</font> <b>Massive Plugin Ecosystem</b>: Huge number of available plugins</td>
 </tr>

</table>
<!--kg-card-end: html-->
<p>Check out my next blog post on Installing and running Gatling.io.</p> ]]></content:encoded>
    </item>
    <item>
        <title><![CDATA[ Verifying integrity of Python packages ]]></title>
        <description><![CDATA[ Python&#39;s ecosystem is one of its greatest strengths. Every time you install a package with pip, you&#39;re pulling code from the internet and executing it in your environment. That makes package integrity verification a critical (and often skipped) security step.

This post covers:

 * How to download ]]></description>
        <link>https://chronicler.tech/verifying-integrity-of-python-packages/</link>
        <guid isPermaLink="false">69611878151af50001e3a0cf</guid>
        <category><![CDATA[  ]]></category>
        <dc:creator><![CDATA[  ]]></dc:creator>
        <pubDate>Tue, 20 Jan 2026 13:23:42 -0500</pubDate>
        <media:content url="https://chronicler.tech/content/images/2026/01/pythonhash.png" medium="image"/>
        <content:encoded><![CDATA[ <p>Python's ecosystem is one of its greatest strengths. Every time you install a package with <code>pip</code>, you're pulling code from the internet and executing it in your environment. That makes package integrity verification a critical (and often skipped) security step.</p><p>This post covers:</p><ul><li>How to download packages with <code>pip</code></li><li>How to verify their integrity</li><li>Why integrity verification matters</li></ul><h2 id="how-pip-downloads-packages">How pip Downloads Packages</h2><p>The most common way developers install a Python package is by running a command like this:</p><pre><code class="language-bash">pip install requests
</code></pre><p>By default, <code>pip</code>:</p><ol><li>Resolves dependencies</li><li>Downloads package files from Python Package Index (PyPI)</li><li>Installs them into your environment</li></ol><p><code>pip</code> uses HTTPS behind the scenes, which protects against basic man-in-the-middle attacks, but HTTPS alone does not guarantee that the package itself hasn’t been tampered with or replaced upstream (for example, through compromised accounts or malicious uploads).</p><p>That’s where integrity verification comes in.</p><h2 id="how-to-verify-package-integrity-with-pip">How to Verify Package Integrity with pip</h2><p>Perhaps the best option is to use hash verification. Here, you tell <code>pip</code> exactly which file is allowed to be installed by giving it a cryptographic fingerprint (hash). If the file is different in any way, <code>pip</code> refuses to install it.</p><ol><li>Install the package normally (once). This lets <code>pip</code> resolve dependencies and identify the exact version. It may install other dependencies (i.e., additional packages).</li></ol><pre><code class="language-bash">pip install requests</code></pre><ol start="2"><li>Generate a requirements file with pinned versions.</li></ol><pre><code class="language-bash">pip freeze &gt; requirements.txt</code></pre><ol start="3"><li>View the generated  <code>requirements.txt</code> file. This lists all downloaded packages and their versions, but the integrity of the packages is not yet verified. The file may look something like this:</li></ol><pre><code class="language-bash">certifi==2023.11.17
charset-normalizer==3.3.2
idna==3.6
requests==2.31.0
urllib3==2.1.0</code></pre><ol start="3"><li>Download all packages in the <code>requirements.txt</code> file to a <code>packages/</code> subfolder so that you can tell <code>pip</code> which exact files are allowed.</li></ol><pre><code class="language-bash">pip download -r requirements.txt -d packages/</code></pre><ol start="4"><li>Get the exact filename of the downloaded package you wish to get the hash for. For example, the command below will return "requests-2.32.5-py3-none-any.whl".</li></ol><pre><code class="language-bash">dir packages\requests*</code></pre><ol start="5"><li>Generate the hash for this single package. <code>pip hash</code> can only be run on one file at a time.</li></ol><pre><code class="language-bash">pip hash packages/requests-2.32.5-py3-none-any.whl</code></pre><p>You will get an output which lists the package name and its hash like this:</p><pre><code class="language-bash">c:\Temp&gt;pip hash packages/requests-2.32.5-py3-none-any.whl

packages/requests-2.32.5-py3-none-any.whl:
--hash=sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6</code></pre><ol start="5"><li>Update <code>requirements.txt</code> and paste the hash into each line. Now repeat this for every package.</li></ol><pre><code class="language-bash">certifi==2023.11.17
charset-normalizer==3.3.2
idna==3.6
requests==2.31.0 \
    --hash=sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6
urllib3==2.1.0</code></pre><ol start="6"><li>As you install your packages in your higher up environments, enforce hash checking on all future installations as shown.</li></ol><pre><code class="language-bash">pip install --require-hashes -r requirements.txt</code></pre><p><code>pip</code> will now refuse to install anything that doesn’t match the expected version and cryptographic hash. This protects you against tampered packages and dependency confusion.</p><h2 id="why-verifying-package-integrity-is-important">Why Verifying Package Integrity Is Important</h2><ol><li><strong>Supply chain attacks are increasing</strong></li></ol><p>Attackers increasingly target:</p><ul><li>Maintainer accounts</li><li>CI pipelines</li><li>Dependency confusion vulnerabilities</li></ul><p>Once malicious code is published, it spreads instantly to thousands of systems via automated installs.</p><p><strong>2. Transitive dependencies multiply risk</strong></p><p>You may install one package, but <code>pip</code> may install dozens more automatically. If any dependency in the chain is compromised, your application is compromised.</p><p>Hash verification locks the entire dependency tree to known-good artifacts.</p><ol start="3"><li><strong>Builds must be reproducible</strong></li></ol><p>Without integrity checks, the same build today may not match tomorrow if a package is updated.</p><h2 id="what-about-virtual-environments-and-docker">What About Virtual Environments and Docker?</h2><p>Virtual environments and containers do not solve integrity. They only isolate where the code runs. You still need to verify what goes <em>into</em> those environments. So the verification instructions mentioned above is still needed.</p><p>Example in Docker:</p><pre><code class="language-dockerfile">COPY requirements.txt .
RUN pip install --require-hashes -r requirements.txt
</code></pre><h2 id="summary">Summary</h2><p>At minimum, there are two practices you should consider starting doing:</p><ol><li>Store hash values of your packages in <code>requirements.txt</code></li><li>Always use <code>pip install --require-hashes</code></li></ol><p>While <code>pip</code> makes installing software incredibly easy, it also makes it easy to run unverified code in production. With pinned versions in <code>requirements.txt</code> and hash verification during installs, you can reduce risk.</p> ]]></content:encoded>
    </item>
    <item>
        <title><![CDATA[ OCI: Serve Content with Caddy ]]></title>
        <description><![CDATA[ Object Storage is a powerful, flexible, and cost-effective way to store and serve enormous amounts of data. Let me walk you through a real-life use case with an odd twist. ]]></description>
        <link>https://chronicler.tech/oci-serve-content-with-caddy/</link>
        <guid isPermaLink="false">69593286151af50001e39f92</guid>
        <category><![CDATA[  ]]></category>
        <dc:creator><![CDATA[  ]]></dc:creator>
        <pubDate>Tue, 13 Jan 2026 08:45:44 -0500</pubDate>
        <media:content url="https://chronicler.tech/content/images/2026/01/caddy-open-graph.jpg" medium="image"/>
        <content:encoded><![CDATA[ <p>Object Storage is a powerful, flexible, and cost-effective way to store and serve enormous amounts of data. Let me walk you through a real-life use case with an odd twist.</p><p>Applications and services interact with buckets using the provided API, command-line interface, SDK, and good old URL. Each method has its own benefits, and one uses them as needed. In my scenario, the application handles uploads and replacements, while <a href="https://caddyserver.com/?ref=chronicler.tech" rel="noreferrer">Caddy</a> (the lightweight web server) handles the web front and proxies requests to application components.</p><p>In this scenario, a Caddy server masks the actual bucket URL, using rewrite rules and configuration variables. Plus, for static content in the bucket, we need to inject the access token or a <a href="https://docs.oracle.com/en-us/iaas/Content/Object/Tasks/usingpreauthenticatedrequests.htm?ref=chronicler.tech" rel="noreferrer">Pre-Authenticated Request (PAR)</a>. </p><div class="kg-card kg-callout-card kg-callout-card-blue"><div class="kg-callout-emoji">💡</div><div class="kg-callout-text">Pre-authenticated requests allow access objects in the bucket according assigned permissions and filters. </div></div><p>The final request processing steps are: </p><ul><li>Identify a static content request, for example, path matches/images/*.</li><li>Rewrite the request to match the object's URI in the target bucket. </li><li>Forward the new request to the bucket, using the recommended <a href="https://docs.oracle.com/en/cloud/paas/autonomous-database/dedicated/adbdj/?ref=chronicler.tech#GUID-44211DA6-B4E5-4D2B-91D7-976B63848F7C" rel="noreferrer">Oracle Object Storage URI</a>. </li></ul><p>For a while, Oracle has introduced dedicated object storage endpoints. To see the difference between the traditional and recommended URI, open any object in the bucket. </p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://chronicler.tech/content/images/2026/01/image.png" class="kg-image" alt="" loading="lazy" width="1910" height="848" srcset="https://chronicler.tech/content/images/size/w600/2026/01/image.png 600w, https://chronicler.tech/content/images/size/w1000/2026/01/image.png 1000w, https://chronicler.tech/content/images/size/w1600/2026/01/image.png 1600w, https://chronicler.tech/content/images/2026/01/image.png 1910w" sizes="(min-width: 720px) 720px"><figcaption><span style="white-space: pre-wrap;">The warning sign with the new URI.</span></figcaption></figure><p>Following <a href="https://12factor.net/config?ref=chronicler.tech" rel="noreferrer">the third factor</a>, the complete URI in the configuration should look like: </p><pre><code class="language-bash">https://${OCI_SPACE}.objectstorage.${OCI_REGION}.oci.
customer-oci.com/p/${OCI_PAR}/n/${OCI_SPACE}/b/${OCI_BUCKET}/o/${URI} </code></pre><p> Where variables are: </p><ul><li>OCI_REGION - the target OCI region, in my case: <strong>us-ashburn-1</strong>.</li><li>OCI_SPACE - the unique identifier, one per tenancy. You may see it in other services that rely on object storage, for example, Container Registry. </li><li>OCI_PAR - The token, required for private bucket access. In my case, the par token works only for objects with names beginning with images/*</li><li>OCI_BUCKET - The name of the bucket, with the site objects. </li></ul><p>The configuration file for my application is </p><figure class="kg-card kg-code-card"><pre><code class="language-javascript">app.example.com {
    
    map {$OCI_PAR} {oci_path} {oci_host} { 	
     PUBLIC  /n/{$OCI_SPACE}/b/{$OCI_BUCKET}/o/{uri}        				
     default /p/{$OCI_PAR}/n/{$OCI_SPACE}/b/{$OCI_BUCKET}/o/{uri} ${OCI_SPACE}.objectstorage.${OCI_REGION}.oci.
customer-oci.com
	}

    @asset expression `{uri}.startsWith("/images/")`
    route @asset {
	   rewrite /images/* {oci_path}
	   reverse_proxy https://{oci_host} {
            transport http {
			   tls
	        }	
        } 
    }
	reverse_proxy http://app_host:8080
	encode gzip zstd
}
</code></pre><figcaption><p><span style="white-space: pre-wrap;">Caddy Server Configuration</span></p></figcaption></figure><p>Some explanation for <strong>map </strong> and <strong>@asset </strong>definitions:</p><ul><li>The <strong>map </strong>structure uses the $OCI_PAR environment variable to calculate Caddy variables <strong>oci_path</strong> and <strong>oci_host</strong>. If $OCI_PAR contains public, the object path would not contain the $OCI_PAR token; otherwise (default case), it will start with the /p/ clause. Since the Object Storage host FQDN does not depend on the token value, only the default section declares the value, and it will be the same for all cases. </li><li>The precalculated condition <strong>@asset</strong> evaluates to <em>True</em> or <em>False</em> for the expression, depending on whether the URI starts with the string "<em>/images/</em>". </li></ul><p>The route intercepts requests when the @asset expression is True, then rewrites the request path using the generated object path and sends the result to the bucket over a TLS connection. </p><p>I have tested this scenario using OCI CLI, Node.js SDK, and simple cURL calls from the command line. It worked, and my compute instance could access objects, yet the Caddy container has continued to throw the host access error. After a short investigation, I realised that the Caddy container, for some mysterious reason, was unable to resolve the recommended OCI Object Storage URI. Yet, it had no issues resolving the classic Object Storage URL. </p><p>After a minor adjustment in the mapping declaration, Caddy was able to serve static requests.  </p><pre><code class="language-javascript">map {$OCI_PAR} {oci_path} {oci_host} { 	
    PUBLIC  /n/{$OCI_SPACE}/b/{$OCI_BUCKET}/o/{uri}        				
    default /p/{$OCI_PAR}/n/{$OCI_SPACE}/b/{$OCI_BUCKET}/o/{uri} objectstorage.${OCI_REGION}.oraclecloud.com
}</code></pre> ]]></content:encoded>
    </item>
    <item>
        <title><![CDATA[ Check Python package version with pip ]]></title>
        <description><![CDATA[ To find the installed version of a Python package, you can use pip in a few different ways to do so.

Using pip show displays detailed metadata for a specific package, including its version, location, and dependencies.

Example:

pip show requests

Output:

Name: requests
Version: 2.32.3
Summary: Python ]]></description>
        <link>https://chronicler.tech/check-python-package-version-with-pip/</link>
        <guid isPermaLink="false">69642352151af50001e3a113</guid>
        <category><![CDATA[  ]]></category>
        <dc:creator><![CDATA[  ]]></dc:creator>
        <pubDate>Mon, 12 Jan 2026 21:00:37 -0500</pubDate>
        <media:content url="https://chronicler.tech/content/images/2026/01/pip.png" medium="image"/>
        <content:encoded><![CDATA[ <p>To find the installed version of a Python package, you can use <code>pip</code> in a few different ways to do so.</p><p>Using <code>pip show</code> displays detailed metadata for a specific package, including its version, location, and dependencies.</p><p><strong>Example:</strong></p><pre><code class="language-bash">pip show requests</code></pre><p><strong>Output:</strong></p><pre><code class="language-bash">Name: requests
Version: 2.32.3
Summary: Python HTTP for Humans.
Home-page: https://requests.readthedocs.io
Author: Kenneth Reitz
Author-email: me@kennethreitz.org
License: Apache-2.0
Location: C:\Users\ahmed\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.12_qbz5n2kfra8p0\LocalCache\local-packages\Python312\site-packages
Requires: certifi, charset-normalizer, idna, urllib3
Required-by: locust</code></pre><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/01/image-1.png" class="kg-image" alt="" loading="lazy" width="1110" height="463" srcset="https://chronicler.tech/content/images/size/w600/2026/01/image-1.png 600w, https://chronicler.tech/content/images/size/w1000/2026/01/image-1.png 1000w, https://chronicler.tech/content/images/2026/01/image-1.png 1110w" sizes="(min-width: 720px) 720px"></figure><p>Using <code>pip list</code> lists all installed packages with their versions in a list format.</p><p><strong>Example:</strong></p><pre><code class="language-bash">pip list | findstr requests    # Windows
pip list | grep requests       # Linux</code></pre><p><strong>Output:</strong></p><pre><code class="language-bash">requests           2.32.3</code></pre><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2026/01/image-4.png" class="kg-image" alt="" loading="lazy" width="1062" height="233" srcset="https://chronicler.tech/content/images/size/w600/2026/01/image-4.png 600w, https://chronicler.tech/content/images/size/w1000/2026/01/image-4.png 1000w, https://chronicler.tech/content/images/2026/01/image-4.png 1062w" sizes="(min-width: 720px) 720px"></figure> ]]></content:encoded>
    </item>
    <item>
        <title><![CDATA[ OCI: Network Path Analyzer ]]></title>
        <description><![CDATA[ It surprises me how often I have issues with network connectivity. All the years of training, wizards, templates, but there is always something to fix. Lucky me, Oracle Cloud offers you a great tool - the Network Path Analyzer. ]]></description>
        <link>https://chronicler.tech/oci-network-path-analyzer/</link>
        <guid isPermaLink="false">69480839151af50001e39e57</guid>
        <category><![CDATA[  ]]></category>
        <dc:creator><![CDATA[  ]]></dc:creator>
        <pubDate>Tue, 23 Dec 2025 08:45:59 -0500</pubDate>
        <media:content url="https://images.unsplash.com/photo-1737202294743-9a32238dc425?crop&#x3D;entropy&amp;cs&#x3D;tinysrgb&amp;fit&#x3D;max&amp;fm&#x3D;jpg&amp;ixid&#x3D;M3wxMTc3M3wwfDF8c2VhcmNofDk2fHxwYXRoJTIwY3J1bWJzfGVufDB8fHx8MTc2NjMyODUzOHww&amp;ixlib&#x3D;rb-4.1.0&amp;q&#x3D;80&amp;w&#x3D;2000" medium="image"/>
        <content:encoded><![CDATA[ <p>It surprises me how often I have issues with network connectivity. All the years of training, wizards, templates, but there is always something to fix. Lucky me, Oracle Cloud offers you a great tool - the <a href="https://docs.oracle.com/en-us/iaas/Content/Network/Concepts/path_analyzer.htm?ref=chronicler.tech" rel="noreferrer">Network Path Analyzer</a>.</p><p>Let's start with the scene:</p><ul><li> I have a templated Virtual Cloud Network with public and private subnets, with all default gateways. </li><li>A single instance in the public subnet is up and accessible from a local terminal application.</li><li>The default security list was updated to allow IPv6 and IPv4 traffic for ports 80 and 443.</li><li>An instance firewall allows HTTP/HTTPS services in the public zone </li><li>Public domain resolves to the public IPv4 address of  the instance</li></ul><p>Yet, the service on the box is not reachable. Let's start with the necessary preparations. </p><ol><li>Find your router's IP address. Usually, I've run <strong>curl http://ip.me, </strong>but on MacOS, it prefers the IPv6 stack, and when it reports IPv4, the result is questionable. To find my public IPv4 address, I used the service htps://ip4only.me  and its counterpart - https://ip6only.me. </li><li>Make sure your firewall ports are open, and you have a listener on the port in question.</li></ol><pre><code class="language-bash">[opc@oci-vm ~]$ sudo firewall-cmd --list-all
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: enp0s6
  sources: 
  services: dhcpv6-client http https ssh
  ports: 
  protocols: 
  forward: yes
  masquerade: no
  forward-ports: 
  source-ports: 
  icmp-blocks: 
  rich rules: 
[opc@oci-vm ~]$ mkdir -p /tmp/empty/
[opc@oci-vm ~]$ sudo python -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
</code></pre><p>Now we have everything we need for the network tests.</p><div class="kg-card kg-callout-card kg-callout-card-pink"><div class="kg-callout-emoji">❗</div><div class="kg-callout-text">Please take note that I run a minimal HTTP server in the temporary empty folder. It takes seconds for botnets to discover an open, well-known port and attack it. So always be careful with such exercises and don't keep non-secured ports open longer than you need.</div></div><ol><li>We start by accessing the Oracle Cloud Infrastructure Console - https://cloud.oracle.com. Make sure your account has sufficient privileges to create IAM policies; otherwise, you should request that account administrators adjust your privileges, as in the next few steps. </li><li> The network path Analyzer may offer you to create the policy in advance, but you may want to customize the policy rules below to meet your specific security requirements. The generic  set of statements is below:</li></ol><figure class="kg-card kg-code-card"><pre><code>allow any-user to inspect compartments in tenancy where all { request.principal.type = 'vnpa-service' }
allow any-user to read instances in tenancy where all { request.principal.type = 'vnpa-service' }
allow any-user to read virtual-network-family in tenancy where all { request.principal.type = 'vnpa-service' }
allow any-user to read load-balancers in tenancy where all { request.principal.type = 'vnpa-service' }
allow any-user to read network-security-group in tenancy where all { request.principal.type = 'vnpa-service' }</code></pre><figcaption><p dir="ltr"><span style="white-space: pre-wrap;">Default VNPA-Policy content </span></p></figcaption></figure><ol start="3"><li>Save the polycy body. Fix any errors you may have.</li><li>Create one more policy that allows account users to use the service. Don't forget to narrow down the privileges listed below. </li></ol><figure class="kg-card kg-code-card"><pre><code>allow group Administrators to manage vn-path-analyzer-test in tenancy</code></pre><figcaption><p dir="ltr"><span style="white-space: pre-wrap;">Allows Manage VPNA tests in Tenancy </span></p></figcaption></figure><ol start="5"><li>Now, we could create some tests and identify potential issues. Locate the Network Path Analyzer service. From the main navigation menu, it is under <em>Networking</em>/<em>Network Command Center.</em></li><li>To create a new test, click the "<strong>Create path analysis</strong>" button, right above the table in the central area.  </li><li>The form starts with basic definitions, including the test name, the compartment to save the configuration, and the network protocol. Fill out the appropriate values.</li><li>Next is the source definition. I used my IPv4 address from the preparations, but I suppose any valid "white" IP address will work. Of course, it could be another VCN or an on-premises IP address. Additionally, you may specify a specific source port. </li><li>For the destination, check the "<strong>Find OCI resource</strong>" option, then select the destination type. I select "OCI Compute Instance (VNIC)" and specify the compute instance name and the network interface. If drop-downs are empty, adjust compartments for both choices. </li><li>  The final adjustment is to pick an IP address from the drop-down list. I choose the public IP, and specify the port to test.</li><li>Select if you want to do a bi-directional or a uni-directional test, and click the "<strong>Run analysis</strong>" button at the bottom of the form. </li><li>The form will show you the progress of the examination. It could take a few minutes, but you may save the test configuration using the "<strong>Save analysis</strong>". </li></ol><p>The Network Path Analyzer produces a report as shown in the screenshot below.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://chronicler.tech/content/images/2025/12/image-7.png" class="kg-image" alt="" loading="lazy" width="2000" height="1543" srcset="https://chronicler.tech/content/images/size/w600/2025/12/image-7.png 600w, https://chronicler.tech/content/images/size/w1000/2025/12/image-7.png 1000w, https://chronicler.tech/content/images/size/w1600/2025/12/image-7.png 1600w, https://chronicler.tech/content/images/size/w2400/2025/12/image-7.png 2400w" sizes="(min-width: 720px) 720px"><figcaption><span style="white-space: pre-wrap;">Access blocked by Security Rules. </span></figcaption></figure><p>Analysis suggests that I have issues with some security rules. After close examination (for the fifth time!) I've found the root cause.  My IPv4 ports 80 and 443 were listed as source ports instead of destination ports.  </p><p>I rerun the analysis with the corrected Security List and confirm that my public port is accessible in both directions. </p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://chronicler.tech/content/images/2025/12/image-8.png" class="kg-image" alt="" loading="lazy" width="2000" height="1010" srcset="https://chronicler.tech/content/images/size/w600/2025/12/image-8.png 600w, https://chronicler.tech/content/images/size/w1000/2025/12/image-8.png 1000w, https://chronicler.tech/content/images/size/w1600/2025/12/image-8.png 1600w, https://chronicler.tech/content/images/size/w2400/2025/12/image-8.png 2400w" sizes="(min-width: 720px) 720px"><figcaption><span style="white-space: pre-wrap;">Successful Bidirectional Report </span></figcaption></figure><p>While my minute use case for Network Patch Analyzer seems a little bit excessive, think about: </p><ul><li>Complex, multi-cloud and hybrid environments. Even finding the root cause's vicinity may save you weeks of close examination and cross-team calls. </li><li>Sometimes you have to provide the hard evidence that your network configuration is correct and operable. And nothing is better than a positive report from a trusted source. </li></ul><p>To conclude, I should mention that all hyperscalers offer similar functionality. Amazon offers <a href="https://docs.aws.amazon.com/vpc/latest/reachability/what-is-reachability-analyzer.html?ref=chronicler.tech" rel="noreferrer">Reachability Analyzer</a>, Google has <a href="https://docs.cloud.google.com/network-intelligence-center/docs/connectivity-tests/how-to/running-connectivity-tests?ref=chronicler.tech" rel="noreferrer">Connectivity Tests</a>, and Microsoft names it <a href="https://learn.microsoft.com/en-us/azure/virtual-network-manager/concept-virtual-network-verifier?ref=chronicler.tech" rel="noreferrer">Virtual Network Verifier</a>.   </p> ]]></content:encoded>
    </item>
    <item>
        <title><![CDATA[ Can AI developers take advantage of Oracle Database 26ai? ]]></title>
        <description><![CDATA[ Under the hood, Oracle Database 26ai is technically the same release family as 23ai (it&#39;s RU 23.26), but Oracle renamed it to signal that they&#39;ve fundamentally moved from adding AI features to adopting an AI-native architecture.

But if you look past the name change, there& ]]></description>
        <link>https://chronicler.tech/can-ai-developers-take-advantage-of-oracle-database-26ai/</link>
        <guid isPermaLink="false">6945a7ec151af50001e39e03</guid>
        <category><![CDATA[  ]]></category>
        <dc:creator><![CDATA[  ]]></dc:creator>
        <pubDate>Fri, 19 Dec 2025 15:05:25 -0500</pubDate>
        <media:content url="https://chronicler.tech/content/images/2025/12/rc24-database-26ai.jpg" medium="image"/>
        <content:encoded><![CDATA[ <p>Under the hood, <a href="https://blog.zeddba.com/2025/12/03/oracle-ai-database-26ai-released/?ref=chronicler.tech" rel="noreferrer">Oracle Database 26ai</a> is technically the same release family as 23ai (it's RU 23.26), but Oracle renamed it to signal that they've fundamentally moved from <em>adding AI features</em> to adopting an <em>AI-native</em> architecture.</p><p>But if you look past the name change, there's something more interesting happening here. Oracle isn't just adding a "vector" data type and calling it a day. They're trying to solve the biggest headache in modern AI development: <a href="https://www.techtarget.com/whatis/definition/data-gravity?ref=chronicler.tech" rel="noreferrer">data gravity</a>.</p><blockquote>Data gravity refers to how large collections of data naturally pull in applications, services, and even more data. Just like physical gravity increases with mass, the "pull" grows as the data volume grows. Data lakes and data warehouses are common examples of environments where data gravity occurs.</blockquote><p>The following figure (borrowed from <a href="https://salesforcedevops.net/index.php/2025/07/30/the-invisible-force-determining-your-ai-future-understanding-data-gravity/?ref=chronicler.tech" rel="noreferrer">here</a>), demonstrates how the larger the data, the more it attracts applications, services, and more data.</p><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2025/12/image-5.png" class="kg-image" alt="" loading="lazy" width="645" height="433" srcset="https://chronicler.tech/content/images/size/w600/2025/12/image-5.png 600w, https://chronicler.tech/content/images/2025/12/image-5.png 645w"></figure><p>Furthermore, of the many advantages that Oracle Database 26ai offers for modern day developers, some include:</p><ul><li><strong>JSON-Relational Duality:</strong> Oracle Database 26ai treats vectors, JSON, and relational data as the same thing. You can store data as rows (for the DBAs) but fetch and update them as JSON documents (for the frontend). There is no need for object-relationship mapping anymore.</li><li><strong>Built-in LLM Integration:</strong> With 26ai, you can call an LLM directly via SQL. You can literally run a query that says, <em>"Find me the top 5 customers, and summarize their last three support tickets,"</em> and the database handles the RAG pipeline internally.</li><li><strong>The "Zero-Upgrade" Upgrade:</strong> One thing the AI-generated blogs miss is that 26ai is delivered as a Release Update (RU). If you’re on 23ai, you just patch.</li></ul><h3 id="the-old-way-we-build-ai-apps-right-now">The "Old" Way We Build AI Apps Right Now</h3><p>As AI developers, most of us have spent the last year building RAG (Retrieval-Augmented Generation) pipelines like this:</p><ol><li>Export data from our "source of truth" (Oracle Database).</li><li>Push it through an ETL pipeline.</li><li>Index it in a separate vector database (Pinecone, Weaviate, etc.).</li><li>Hope the two stay in sync.</li></ol><p>It’s brittle, it’s expensive, and it’s a security nightmare.</p><h3 id="developing-with-oracle-database-26ai">Developing with Oracle Database 26ai</h3><p>Now take a look at the following figure. Oracle is moving reasoning (such as AI agents and vector search) away from the application tier and into the data layer. </p><figure class="kg-card kg-image-card"><img src="https://chronicler.tech/content/images/2025/12/image-6.png" class="kg-image" alt="" loading="lazy" width="802" height="415" srcset="https://chronicler.tech/content/images/size/w600/2025/12/image-6.png 600w, https://chronicler.tech/content/images/2025/12/image-6.png 802w" sizes="(min-width: 720px) 720px"></figure><p>This is one of the problems that Oracle is trying to solve for the modern day AI developer... by providing a simplified, unified, and secure platform for AI development.</p><p>If you’re still on 19c, skip 23ai and head straight for 26ai. The water's fine, and you can finally stop managing that separate vector database.</p> ]]></content:encoded>
    </item>
    <item>
        <title><![CDATA[ OCI: Please, Try Again Later ]]></title>
        <description><![CDATA[ Recently, I ran into an interesting problem: the system attempts to read the bucket before the new object is available. Fortunately, the OCI SDK offers retry policies and rules, allowing you to take control over retry strategies. ]]></description>
        <link>https://chronicler.tech/oci-please-try-again-later/</link>
        <guid isPermaLink="false">693a1ebc151af50001e39ccc</guid>
        <category><![CDATA[  ]]></category>
        <dc:creator><![CDATA[  ]]></dc:creator>
        <pubDate>Tue, 16 Dec 2025 08:45:03 -0500</pubDate>
        <media:content url="https://images.unsplash.com/photo-1686641944143-b82f19ad0c2e?crop&#x3D;entropy&amp;cs&#x3D;tinysrgb&amp;fit&#x3D;max&amp;fm&#x3D;jpg&amp;ixid&#x3D;M3wxMTc3M3wwfDF8c2VhcmNofDJ8fHRyaWVzfGVufDB8fHx8MTc2NTQxNjYyOXww&amp;ixlib&#x3D;rb-4.1.0&amp;q&#x3D;80&amp;w&#x3D;2000" medium="image"/>
        <content:encoded><![CDATA[ <p>Recently, I ran into an interesting problem: the system attempts to read the bucket before the new object is available. Fortunately, the OCI SDK offers retry policies and rules, allowing you to take control over retry strategies. </p><p>I did some code refactoring (a fancy name for a total rewrite of the component), and as a result, my class went completely asynchronous. The new and improved functionality led to the new roadblock. With full asynchronicity, the system tries to read an object before an OCI bucket completes an upload. Unfortunately, I can't control the code usage; all I can do is implement one of the retry strategies. </p><p>The good news is that the OCI SDK provides this functionality at the <a href="https://docs.oracle.com/en-us/iaas/Content/API/SDKDocs/typescriptsdkconcepts.htm?ref=chronicler.tech#typescriptsdkconcepts_topic_Retries" rel="noreferrer">client or at the operation level</a>. TypeScript/JavaScript and Python libraries provide similar mechanisms for defining complex behavioral patterns to handle timeouts, errors, and delays. In my scenario, all I need is a small lag between the moment when objects are uploaded, the method returns a new resource URI, and the time when the OCI bucket makes them available for access. Since I don't want to retry all operations, I will add retry configurations only to "exists" and "read" operations.  </p><p>The code below shows how to use the retry configuration. For the sake of clarity, I stripped out all surrounding code, the constructor, authentication, and service functions. </p><figure class="kg-card kg-code-card"><pre><code class="language-javascript">async exists(fileName, targetDir) {
  const targetName = 
    buildPath(this.getTargetDir(this.pathPrefix), targetDir, fileName);
  const headOp = {
      objectName: stripLeadingSlash(targetName),
      bucketName: this.bucket,
      namespaceName: this.namespace,
      retryConfiguration: {
        retryCondition:  common.DefaultRetryCondition,
        terminationStrategy: new   
          common.MaxAttemptsTerminationStrategy(this.retryAttempts)
       } 
  }
  return this.build().then(storage =&gt; {
    storage.headObject(headOp)
       .then((result) =&gt; { 
                return true;
       })
       .catch((err) =&gt; {    
         if (err.statusCode === 404) {
            return false;
         } else {
            throw err;
         }
       });
  });
}</code></pre><figcaption><p dir="ltr"><span style="white-space: pre-wrap;">Sample check if Object Exists</span></p></figcaption></figure><p>I altered the default retry strategy to terminate after a defined number of retry attempts. By default, the client will try eight times before giving up (according to the <a href="https://docs.oracle.com/en-us/iaas/tools/python/latest/sdk_behaviors/retries.html?highlight=retry&ref=chronicler.tech#default-retry-strategy" rel="noreferrer">Python SDK</a>). It seems a bit high to me, so I'll set max retries to three. The termination strategy may be one of the preconfigured options, or you may define a custom one using custom retry configuration and various strategies. </p><p>Tests from my local machine demonstrate that the retry configuration works, and on the second retry attempt, my client reads the object from the OCI bucket. </p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://chronicler.tech/content/images/2025/12/image-2.png" class="kg-image" alt="" loading="lazy" width="1524" height="768" srcset="https://chronicler.tech/content/images/size/w600/2025/12/image-2.png 600w, https://chronicler.tech/content/images/size/w1000/2025/12/image-2.png 1000w, https://chronicler.tech/content/images/2025/12/image-2.png 1524w" sizes="(min-width: 720px) 720px"><figcaption><span style="white-space: pre-wrap;">Handling Object Availability</span></figcaption></figure><p>An extra configuration option for the OCI client, or an additional configuration parameter, allows you to save time and effort on implementing custom error handling.  SDK offers a comprehensive set of predefined strategies and conditions. I'll give you a hint: the Python documentation is way better than the [<em>Type|Java</em>]Script one, so you may want to read the Python SDK documentation to grasp the overall idea and apply it to the JavaScript code. </p> ]]></content:encoded>
    </item>
    <item>
        <title><![CDATA[ Skipping Through Tests ]]></title>
        <description><![CDATA[ When developing something that should withstand public use, a good set of tests is always beneficial; however, sometimes you may want to skip a few without changing the code. ]]></description>
        <link>https://chronicler.tech/skipping-through-tests/</link>
        <guid isPermaLink="false">692e1233151af50001e39ba8</guid>
        <category><![CDATA[  ]]></category>
        <dc:creator><![CDATA[  ]]></dc:creator>
        <pubDate>Tue, 09 Dec 2025 08:45:19 -0500</pubDate>
        <media:content url="https://chronicler.tech/content/images/2025/12/oci-replatform1.drawio.png" medium="image"/>
        <content:encoded><![CDATA[ <p>When developing something that should withstand public use, a good set of tests is always beneficial; however, sometimes you may want to skip a few without changing the code. </p><p>One should design test cases with automation in mind. It means that the ideal test suite runs against the target environment and, on the happy path, leaves nothing behind but a report. For my specific example, it's a system adapter for the OCI Buckets. The set of tests that I developed:</p><ul><li>Test Basic Functionality<ul><li>Test all parameters present</li><li>Test basic methods </li></ul></li><li>Tests the OCI SDK functionality<ul><li>Test OCI connectivity and access </li><li>Test bucket access </li><li>Perform PUT/GET tasks </li><li>Test FETCH and DELETE </li></ul></li></ul><p>Means that at the end of the case, the target bucket will contain no artefacts, except log entries. However, for some cases, it would be useful to see what objects are in the bucket. My tests were built with <a href="https://mochajs.org/?ref=chronicler.tech" rel="noreferrer">Mocha.js</a>. The framework offers excellent flexibility, allowing you to select and test suites and cases, including filtering by description. </p><figure class="kg-card kg-code-card"><pre><code class="language-bash"># Runs All Tests in Folder
$ _mocha -- tests/*.test.js

# Run Specific Test File
$ _mocha -- tests/BasicFunctions.test.js

# Run only tests, having matching description 
$ _mocha --grep "Storage Adapter" -- tests/*.test.js</code></pre><figcaption><p><span style="white-space: pre-wrap;">Select Tests and Cases</span></p></figcaption></figure><p>But if you want to skip a specific test, you'll need to make some logic changes. I checked a few options and settled on the most universal approach: environment variables. Here is an example of skipping test file deletion.</p><figure class="kg-card kg-code-card"><pre><code class="language-javascript">it('should delete the file from the bucket', async function () {
  if (process.env.KEEP_FILES) 
    this.skip()
  else
     return adapter.delete(pth.basename(testImage.name),
                'save-test').then((result) =&gt; {
                assert.ok(result, 'File deletion failed');
            }).catch(err =&gt; {
                assert.fail(`File deletion failed with error:
                ${err.message}`);
            });
});</code></pre><figcaption><p><span style="white-space: pre-wrap;">Delete File Test</span></p></figcaption></figure><p>Now, this step checks whether the <strong>KEEP_FILES </strong>variable is declared, and if so skips the deleteion step.</p><figure class="kg-card kg-code-card"><pre><code class="language-bash"># Runs All Tests but keeps test files
$ KEEP_FILES=yes _mocha -- tests/*.test.js
</code></pre><figcaption><p><span style="white-space: pre-wrap;">Skip the deletion step.</span></p></figcaption></figure> ]]></content:encoded>
    </item>

</channel>
</rss>