<?xml version="1.0" encoding="UTF-8"?><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" version="2.0" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:googleplay="http://www.google.com/schemas/play-podcasts/1.0"><channel><title><![CDATA[nfosignal: Builder's Workshop]]></title><description><![CDATA[Technical walkthroughs, code, architecture decisions, and how-to guides for developers and builders.]]></description><link>https://nfosignal.substack.com/s/builders-workshop</link><image><url>https://substackcdn.com/image/fetch/$s_!vTOf!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fnfosignal.substack.com%2Fimg%2Fsubstack.png</url><title>nfosignal: Builder&apos;s Workshop</title><link>https://nfosignal.substack.com/s/builders-workshop</link></image><generator>Substack</generator><lastBuildDate>Mon, 08 Jun 2026 04:12:37 GMT</lastBuildDate><atom:link href="https://nfosignal.substack.com/feed" rel="self" type="application/rss+xml"/><copyright><![CDATA[Neal Foster]]></copyright><language><![CDATA[en]]></language><webMaster><![CDATA[nfosignal@substack.com]]></webMaster><itunes:owner><itunes:email><![CDATA[nfosignal@substack.com]]></itunes:email><itunes:name><![CDATA[nfos]]></itunes:name></itunes:owner><itunes:author><![CDATA[nfos]]></itunes:author><googleplay:owner><![CDATA[nfosignal@substack.com]]></googleplay:owner><googleplay:email><![CDATA[nfosignal@substack.com]]></googleplay:email><googleplay:author><![CDATA[nfos]]></googleplay:author><itunes:block><![CDATA[Yes]]></itunes:block><item><title><![CDATA[From API Call to Bedrock in Five Files]]></title><description><![CDATA[The previous post explained the rationale for moving from direct Anthropic API (Application Programming Interface) calls to AWS (Amazon Web Services) Bedrock.]]></description><link>https://nfosignal.substack.com/p/from-api-call-to-bedrock-in-five</link><guid isPermaLink="false">https://nfosignal.substack.com/p/from-api-call-to-bedrock-in-five</guid><dc:creator><![CDATA[nfos]]></dc:creator><pubDate>Sun, 10 May 2026 15:01:27 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!MTC1!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f984c80-8e19-4039-adbc-e675c1dac0f9_1096x368.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!MTC1!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f984c80-8e19-4039-adbc-e675c1dac0f9_1096x368.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!MTC1!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f984c80-8e19-4039-adbc-e675c1dac0f9_1096x368.png 424w, https://substackcdn.com/image/fetch/$s_!MTC1!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f984c80-8e19-4039-adbc-e675c1dac0f9_1096x368.png 848w, https://substackcdn.com/image/fetch/$s_!MTC1!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f984c80-8e19-4039-adbc-e675c1dac0f9_1096x368.png 1272w, https://substackcdn.com/image/fetch/$s_!MTC1!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f984c80-8e19-4039-adbc-e675c1dac0f9_1096x368.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!MTC1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f984c80-8e19-4039-adbc-e675c1dac0f9_1096x368.png" width="1096" height="368" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5f984c80-8e19-4039-adbc-e675c1dac0f9_1096x368.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:368,&quot;width&quot;:1096,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:54215,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://nealcfoster.substack.com/i/192629775?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f984c80-8e19-4039-adbc-e675c1dac0f9_1096x368.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!MTC1!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f984c80-8e19-4039-adbc-e675c1dac0f9_1096x368.png 424w, https://substackcdn.com/image/fetch/$s_!MTC1!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f984c80-8e19-4039-adbc-e675c1dac0f9_1096x368.png 848w, https://substackcdn.com/image/fetch/$s_!MTC1!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f984c80-8e19-4039-adbc-e675c1dac0f9_1096x368.png 1272w, https://substackcdn.com/image/fetch/$s_!MTC1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f984c80-8e19-4039-adbc-e675c1dac0f9_1096x368.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The previous post explained the rationale for moving from direct Anthropic API (Application Programming Interface) calls to AWS (Amazon Web Services) Bedrock. This one builds a working application and migrates it, file by file, so you can follow along and do the same thing.</p><p>The whole project is in a public repo: github.com/nealvybe/knockknock-bedrock. Clone it, set up a virtual environment, and run each file to see exactly what changes at each step.</p><pre><code><code>git clone https://github.com/nealvybe/knockknock-bedrock.git
cd knockknock-bedrock
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt</code></code></pre><p>Then copy .env.example to .env and fill in your credentials. The direct API files need your ANTHROPIC_API_KEY. The Bedrock files need your AWS_PROFILE (or AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY) and AWS_REGION.</p><pre><code><code>cp .env.example .env</code></code></pre><p>The app is a knock knock joke generator. You give it a topic, pick a style and an optional character voice, and it writes knock knock jokes. Simple enough to understand in five minutes. Complex enough to show real patterns: multi-turn conversations, prompt caching, and the wrapper abstraction that makes provider migration trivial.</p><h2>File 1: knockknock.py</h2><p>This is the starting point. A single-turn joke generator using the direct Anthropic API.</p><pre><code><code>python knockknock.py</code></code></pre><pre><code><code>Topic: hugs

Knock knock.
Who's there?
Hug.
Hug who?
Hug-ry for some affection!</code></code></pre><p>The code is about 40 lines. An Anthropic client, a system prompt that defines the format rules, and a single API call. The system prompt does most of the work. It tells Claude to only respond with knock knock jokes, to use the traditional format, and to incorporate whatever topic the user provides. Nothing else. No intro, no commentary. Just the joke.</p><p>This version takes a topic, makes one call, prints the result, and exits. It works, but it is a dead end. One joke per run. No way to refine, no memory of what it already told you.</p><h2>File 2: knockknock_v2.py</h2><p>This version adds three things: style selection (corny, clever, or kid-friendly), an optional character voice, and a conversation loop that remembers what jokes it already told.</p><pre><code><code>python knockknock_v2.py</code></code></pre><pre><code><code>Topic: puppies
Style (corny/clever/kid-friendly) [corny]: corny
Character (optional, e.g. Yoda, Batman, Gordon Ramsay): Gordon Ramsay

Knock knock.
Who's there?
Puppy.
Puppy who?
Puppy hell, this dog's so raw it's still chasing its bloody tail!

Another joke? (y/n): y
Topic [puppies]: mars
Style (corny/clever/kid-friendly) [corny]: clever
Character (e.g. Yoda, Batman, Gordon Ramsay) [Gordon Ramsay]: Yoda

Knock knock.
Who's there?
Mars.
Mars who?
Mars bars, eat them I do not. Only the red planet, strong with the Force it is!

Another joke? (y/n): n</code></code></pre><p>The conversation history is stored as a list of messages. Each joke the model generates gets appended to the list, so on the next turn the model sees everything it already said and avoids repeating itself. Defaults carry forward between turns. Hit enter to keep the same topic, style, or character. Change any of them to mix things up.</p><p>This is still using the direct Anthropic API. Same client, same authentication. If you have an API key, this file runs.File 3: knockknock_bedrock.py</p><p>Same app. Three lines changed.</p><p>The import switches from anthropic to AnthropicBedrock. The client initialization adds a region and profile parameter. The model ID switches from the Anthropic shorthand (claude-sonnet-4-20250514) to Bedrock&#8217;s cross-region format (us.anthropic.claude-sonnet-4-20250514-v1:0). Everything else is identical. The system prompt, the message structure, the conversation loop, the response parsing. All the same.</p><pre><code><code>python knockknock_bedrock.py</code></code></pre><pre><code><code>Topic: Philadelphia
Style (corny/clever/kid-friendly) [corny]: corny
Character (optional, e.g. Yoda, Batman, Gordon Ramsay): Batman

Knock knock.
Who's there?
Philly.
Philly who?
Philly up the Batmobile, Robin - we've got crime to fight in the City of Brotherly Love!</code></code></pre><p>Same output. Now it is running through your AWS account with IAM (Identity and Access Management) authentication, CloudTrail logging, and consolidated billing.</p><p>To run this, you need two things set up in AWS first.</p><p>First, enable model access. In the AWS Console, go to Amazon Bedrock, click Model access in the left sidebar, then Manage model access. Check the Anthropic Claude models you want to use and submit. Approval is usually instant.</p><p>Second, add the IAM policy. If your application is already using AWS for anything (S3, Lambda, DynamoDB), you probably already have IAM roles set up. Adding Bedrock is one JSON policy attachment.</p><pre><code><code>{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "bedrock:InvokeModel",
            "Resource": "arn:aws:bedrock:us-east-1::foundation-model/anthropic.*"
        }
    ]
}</code></code></pre><p>Attach that to your existing role and you are done. No new credentials, no separate auth system. The same IAM infrastructure you already trust.</p><h2>File 4: knockknock_cached.py</h2><p>One change from the Bedrock version. The system parameter switches from a plain string to a list containing a single object with a cache_control field.</p><p>The system prompt in this app is short, so the savings here are small. But the pattern matters. In a production application where your system prompt is thousands of tokens (detailed instructions, style rules, domain context, few-shot examples), prompt caching changes the economics.</p><p>The first call caches the system prompt at a small write premium (1.25x the normal input cost). Every subsequent call within 5 minutes reads from cache at 0.1x. For a multi-turn conversation like this joke generator, that means the first joke pays a slight premium and every joke after that gets the system prompt for 90% less.</p><p>For longer-lived sessions (agent loops, chat applications), there is a 1-hour cache option at 2x write cost:</p><pre><code><code>"cache_control": {"type": "ephemeral", "ttl": "3600s"}</code></code></pre><p>That pays off after two cache reads.File 5: llm_wrapper.py + knockknock_final.py</p><p>This is the file structure we use in production. The wrapper module (llm_wrapper.py) contains a single function called call_llm(). It handles the client initialization, the caching, the model selection. About 30 lines.</p><p>The application (knockknock_final.py) imports call_llm and uses it. It never imports the Anthropic SDK (Software Development Kit) directly. It has no idea whether it is talking to the Anthropic API, Bedrock, or anything else. It passes a system prompt and a message list, and gets a string back.</p><pre><code><code>from llm_wrapper import call_llm

joke = call_llm(SYSTEM_PROMPT, messages)</code></code></pre><p>That is the entire integration surface. When we migrated our production system from the direct API to Bedrock, this wrapper was the only thing that changed. Claude Code made the edit in the wrapper file. We tested it. It worked. The rest of the application had no idea anything was different.</p><p>This pattern also makes model switching easy. Running Haiku for low-cost tasks and Sonnet for complex ones is just a matter of passing the model as an argument. Adding retry logic, logging, or token counting means changing the wrapper once. Every call in the application benefits without touching any application code.</p><h2>The progression</h2><p>Looking at the five files side by side, the diff between each step is small:</p><p>File 1 to File 2: add the conversation loop, style, and character inputs. File 2 to File 3: change the import, client, and model ID (three lines). File 3 to File 4: switch system from string to list with cache_control (one structural change). File 4 to File 5: extract the LLM call into its own module (architectural, not functional).</p><p>Each step is one concept. No file introduces more than one new idea. You can diff any two adjacent files and see exactly what changed and why.</p><p>The repo is at github.com/nealvybe/knockknock-bedrock. Clone it, follow along, and you will have a working Bedrock application in about 15 minutes.</p>]]></content:encoded></item><item><title><![CDATA[From Claude to Bedrock]]></title><description><![CDATA[Most people who use Claude interact with it in one of two ways: the website at claude.ai, or Claude Code in the terminal.]]></description><link>https://nfosignal.substack.com/p/from-claude-to-bedrock</link><guid isPermaLink="false">https://nfosignal.substack.com/p/from-claude-to-bedrock</guid><dc:creator><![CDATA[nfos]]></dc:creator><pubDate>Wed, 06 May 2026 02:47:15 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!EzG2!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faa1230d1-f6ac-4111-a15a-d7fa3446513d_1508x666.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!EzG2!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faa1230d1-f6ac-4111-a15a-d7fa3446513d_1508x666.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!EzG2!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faa1230d1-f6ac-4111-a15a-d7fa3446513d_1508x666.png 424w, https://substackcdn.com/image/fetch/$s_!EzG2!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faa1230d1-f6ac-4111-a15a-d7fa3446513d_1508x666.png 848w, https://substackcdn.com/image/fetch/$s_!EzG2!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faa1230d1-f6ac-4111-a15a-d7fa3446513d_1508x666.png 1272w, https://substackcdn.com/image/fetch/$s_!EzG2!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faa1230d1-f6ac-4111-a15a-d7fa3446513d_1508x666.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!EzG2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faa1230d1-f6ac-4111-a15a-d7fa3446513d_1508x666.png" width="1456" height="643" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/aa1230d1-f6ac-4111-a15a-d7fa3446513d_1508x666.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:643,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:94611,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://nealcfoster.substack.com/i/192629489?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faa1230d1-f6ac-4111-a15a-d7fa3446513d_1508x666.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!EzG2!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faa1230d1-f6ac-4111-a15a-d7fa3446513d_1508x666.png 424w, https://substackcdn.com/image/fetch/$s_!EzG2!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faa1230d1-f6ac-4111-a15a-d7fa3446513d_1508x666.png 848w, https://substackcdn.com/image/fetch/$s_!EzG2!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faa1230d1-f6ac-4111-a15a-d7fa3446513d_1508x666.png 1272w, https://substackcdn.com/image/fetch/$s_!EzG2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faa1230d1-f6ac-4111-a15a-d7fa3446513d_1508x666.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Most people who use Claude interact with it in one of two ways: the website at claude.ai, or Claude Code in the terminal. Both are products built by Anthropic. You type something, Claude responds. The infrastructure behind it is invisible.</p><p>When you start building software that uses Claude, the relationship changes. You are no longer a user. You are a developer making API calls. That distinction matters more than it sounds like it should, because it changes how you pay, what you can control, and where the compute actually runs.</p><p>This post explains the path from using Claude as a consumer to running it as infrastructure through AWS Bedrock, and why we made that shift.</p><h2>The API layer</h2><p>The Anthropic API is how developers send prompts to Claude programmatically. Instead of typing into a chat window, your code sends a request to Anthropic&#8217;s servers with a prompt, a model name, and some parameters. The response comes back as structured data you can parse, store, or pass along.</p><p>Setting up is fast. You create an account at console.anthropic.com, generate an API key, and start making calls. The Python SDK is a few lines:</p><pre><code><code>import anthropic

client = anthropic.Anthropic(api_key="your-key")
message = client.messages.create(
    model="claude-sonnet-4-6",
    max_tokens=1024,
    messages=[{"role": "user", "content": "Explain what an API is in one paragraph."}]
)</code></code></pre><p>You pay per token. Inputs and outputs are priced separately. As of March 2026, Claude Sonnet 4.6 costs $3 per million input tokens and $15 per million output tokens. Claude Opus 4.6 is $5 and $25. Claude Haiku 4.5 is $1 and $5.</p><p>For prototyping, this is all you need. You can build a working AI feature in an afternoon. The limitations show up when you move toward production: managing API keys across environments, monitoring costs outside of Anthropic&#8217;s dashboard, needing models from other providers, or wanting enterprise controls around what the model can and cannot say.</p><h2>What Bedrock is</h2><p>Amazon Bedrock is AWS&#8217;s managed service for running foundation models. It is not a model. It is a layer that sits between your application and multiple AI providers, including Anthropic (Claude), Meta (Llama), Mistral, Cohere, AI21 Labs, and Amazon&#8217;s own Nova models.</p><p>When you call Claude through Bedrock, the request goes through AWS infrastructure. The model is the same. The responses are the same. But the billing, authentication, logging, and networking all run through your AWS account.</p><p>The benefits go beyond convenience.</p><p><strong>Multi-model access.</strong> Bedrock gives you one API surface for every supported model. If you want to compare Claude Sonnet against Llama 3 against Mistral Large for a specific task, you change the model ID in your code. You do not manage three separate API keys, three billing relationships, and three sets of documentation. For a team evaluating which model works best for which task, this saves weeks.</p><p><strong>AWS integration.</strong> If your infrastructure already runs on AWS, Bedrock plugs in natively. Authentication uses IAM roles instead of API keys. Logging goes to CloudTrail. Monitoring goes to CloudWatch. Your AI spend shows up on the same AWS bill as everything else. For teams that care about security or compliance, this consolidation matters.</p><p><strong>Guardrails.</strong> Bedrock has a built-in guardrails system that lets you define content policies for your application. You can block specific topics, filter harmful content, redact personally identifiable information from inputs and outputs, and set up automated reasoning checks that validate model responses against factual rules. These are configurable per application. Instead of building your own content filtering layer, you define policies and Bedrock enforces them before the response reaches your user.<strong>Knowledge Bases.</strong> Bedrock offers managed Retrieval-Augmented Generation (RAG). You point it at your data sources (S3 buckets, databases, documents), it handles the indexing, chunking, and embedding. When your application makes a call, Bedrock retrieves relevant context from your data and includes it with the prompt. This is the same pattern teams build manually with vector databases and embedding pipelines, but managed as a service. Guardrails can be applied to knowledge base responses as well.</p><p><strong>Prompt caching.</strong> Both the direct API and Bedrock support prompt caching, but the feature becomes especially valuable at scale. Caching stores the processed version of your prompt prefix so repeated calls with the same system prompt do not reprocess those tokens. The first call writes the cache. Every subsequent call that hits the cache pays only 10% of the normal input price for those cached tokens. For applications making hundreds or thousands of calls with the same base context, the savings are significant. Bedrock added 1-hour cache duration in January 2026, which works well for sustained agent loops and multi-turn conversations.</p><p><strong>Credits.</strong> AWS Activate provides cloud credits to startups. These credits apply to all AWS services, including Bedrock. Which means your Claude API calls, if routed through Bedrock, can be paid with credits instead of cash. For early-stage companies, this changes the math on whether AI features are affordable to build.</p><h2>What made the migration easy</h2><p>Two decisions we made early turned this from a project into a task.</p><p>First, we had abstracted all LLM calls to a single function. Every part of the application that talks to Claude goes through one wrapper. When it was time to switch from the direct Anthropic client to the Bedrock client, there was one function to change. Claude Code made the edit in minutes. No regressions, no missed call sites, no compatibility issues. If your LLM calls are scattered across your codebase, the migration is harder. If they go through one function, it is a find-and-replace.</p><p>Second, our application was already running on AWS with IAM-based authentication. Adding Bedrock access was just attaching a new JSON policy to the existing IAM role through the console. No new credentials to manage, no new authentication flow to build. The permissions were additive, not architectural.</p><p>If you are building an AI application and thinking about this move eventually, those two things (a single LLM wrapper function, and AWS IAM already in place) are worth setting up now even if you are months away from needing Bedrock.</p><h2>The trade-off</h2><p>Bedrock is not always the right choice. New Anthropic features (extended thinking, new model releases, MCP support) tend to land on the direct API first and arrive on Bedrock weeks or months later. If you need the latest capabilities on day one, the direct API is faster.</p><p>The setup is also heavier. What takes five minutes with the Anthropic API (generate a key, install the SDK, make a call) can take an afternoon with Bedrock if you are new to AWS. IAM roles, service permissions, region selection, model access requests. For a quick prototype, the overhead is not worth it.</p><p>The way we handle this: prototype on the direct Anthropic API, deploy through Bedrock. The actual code change, when it comes, is two lines in one function.</p><h2>Where Vybe fits</h2><p>Vybe Capital is an AWS Activate Provider. That means startups in the portfolio can apply for Activate credits through the partnership. The credits apply to all AWS services, including Bedrock. Beyond credits, Vybe provides guidance on the infrastructure decisions described in this post: when to use the direct API versus Bedrock, how to structure LLM calls for easy migration, how to set up caching and guardrails.</p><p>The next post walks through the practical setup, step by step, with a working example you can run yourself.</p><p></p><p><em>Neal Foster is Co-Founder &amp; CTO of SportChartz and Founder &amp; Partner of Vybe Capital.</em></p>]]></content:encoded></item><item><title><![CDATA[Updating the encrypted live site with one Cowork prompt]]></title><description><![CDATA[follow on from last post]]></description><link>https://nfosignal.substack.com/p/updating-the-encrypted-live-site</link><guid isPermaLink="false">https://nfosignal.substack.com/p/updating-the-encrypted-live-site</guid><dc:creator><![CDATA[nfos]]></dc:creator><pubDate>Sun, 19 Apr 2026 23:03:16 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!VNZI!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2c0f4ee-7eda-4383-897d-08185acd41cf_1814x1478.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!VNZI!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2c0f4ee-7eda-4383-897d-08185acd41cf_1814x1478.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!VNZI!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2c0f4ee-7eda-4383-897d-08185acd41cf_1814x1478.png 424w, https://substackcdn.com/image/fetch/$s_!VNZI!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2c0f4ee-7eda-4383-897d-08185acd41cf_1814x1478.png 848w, https://substackcdn.com/image/fetch/$s_!VNZI!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2c0f4ee-7eda-4383-897d-08185acd41cf_1814x1478.png 1272w, https://substackcdn.com/image/fetch/$s_!VNZI!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2c0f4ee-7eda-4383-897d-08185acd41cf_1814x1478.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!VNZI!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2c0f4ee-7eda-4383-897d-08185acd41cf_1814x1478.png" width="1456" height="1186" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e2c0f4ee-7eda-4383-897d-08185acd41cf_1814x1478.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1186,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:297330,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://nealcfoster.substack.com/i/192629190?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2c0f4ee-7eda-4383-897d-08185acd41cf_1814x1478.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!VNZI!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2c0f4ee-7eda-4383-897d-08185acd41cf_1814x1478.png 424w, https://substackcdn.com/image/fetch/$s_!VNZI!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2c0f4ee-7eda-4383-897d-08185acd41cf_1814x1478.png 848w, https://substackcdn.com/image/fetch/$s_!VNZI!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2c0f4ee-7eda-4383-897d-08185acd41cf_1814x1478.png 1272w, https://substackcdn.com/image/fetch/$s_!VNZI!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2c0f4ee-7eda-4383-897d-08185acd41cf_1814x1478.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The <a href="https://nfosignal.substack.com/p/one-prompt-to-live-url">last post</a> built ParkPulse: a single-file HTML prototype, encrypted with StaticCrypt, deployed to GitHub Pages behind a password. This post shows how to update that same site with one prompt.</p><p>The file on GitHub Pages is AES-encrypted ciphertext, so it cannot be edited in place. The workflow is: clone the repo, decrypt the HTML, edit, re-encrypt with the same password, commit, push.</p><h2>What you need</h2><ol><li><p>The live site from the first post (or any StaticCrypt-encrypted site on GitHub Pages)</p></li><li><p>A paid Claude account with the Claude desktop app and Cowork mode enabled</p></li><li><p>A GitHub Personal Access Token with write access to the repo (see the <a href="https://nfosignal.substack.com/p/one-prompt-to-live-url">previous post</a> if you have not set this up)</p></li></ol><h2>The prompt</h2><p>I opened Cowork and pasted this:</p><pre><code><code>I have a live site at nealvybe.github.io/parkpulse-proto that's encrypted
with StaticCrypt (password: pulse2026). The source repo is
github.com/nealvybe/parkpulse-proto. Clone the repo, decrypt the index.html,
and add an "About" page to the top navigation menu. The About page should
describe ParkPulse as a product: what it does, who it's for, and a short
team section with three fictional team members (names, roles, one-line
bios). Match the existing design style and orange accent color. After the
edit, re-encrypt with StaticCrypt using the same password, commit, and
push to GitHub so the live site updates.</code></code></pre><p>The prompt contains everything Cowork needs: the live URL, the password, the repo, the change, and the deploy instruction.</p><h2>What Cowork did</h2><p><strong>Step 1: Clone.</strong> Standard <code>git clone</code>. The repo contained the encrypted <code>index.html</code> (99KB) and a README.</p><p><strong>Step 2: Decrypt.</strong> First error. StaticCrypt&#8217;s decrypt command failed because the repo had no <code>.staticrypt.json</code> config file. That file stores the salt used during encryption. Without it, the decryptor cannot reverse the process.</p><p>Claude solved this by reading the encrypted HTML directly. The StaticCrypt config object is embedded near the bottom of the encrypted output, including the salt:</p><pre><code><code>"staticryptSaltUniqueVariableName":"515fd507a794550948cb85bd91e23474"</code></code></pre><p>Claude extracted that value and passed it to the decrypt command explicitly. The original 825-line prototype came back intact.</p><p><strong>Step 3: Edit.</strong> Claude modified three parts of the decrypted file:</p><ul><li><p>An <code>About</code> link added to the navigation bar</p></li><li><p>A block of CSS for the About page (hero, feature grid, team grid, avatar circles, responsive breakpoints)</p></li><li><p>The About view HTML: product description, audience paragraph, three team member cards</p></li></ul><p>The existing <code>showView()</code> function did not need changes. It was already written to match view names to element IDs dynamically, so adding a new view only required adding the HTML with the right ID. The file went from 825 lines to 988 lines &#8212; 163 lines added.</p><p><strong>Step 4: Re-encrypt.</strong> Same password, same StaticCrypt command. The 988-line source became a 112KB encrypted file.</p><p><strong>Step 5: Commit and push.</strong> Second error. The bare <code>git push</code> failed because Cowork&#8217;s sandbox has no stored GitHub credentials. This is the same issue from the first deployment. Claude authenticated by embedding the Personal Access Token in the push URL. Because the token already had write access to <code>parkpulse-proto</code> from the previous session, the push succeeded on the first authenticated attempt.</p><p><strong>Step 6: Verify.</strong> GitHub Pages redeployed in 36 seconds. Claude loaded the live URL, entered the password, and confirmed the About page rendered. I refreshed the site, typed <code>pulse2026</code>, and saw four nav items instead of three.</p><h2>What the About page contains</h2><p>Three sections, matching the existing design:</p><ul><li><p>A hero with the headline &#8220;Built for building operators&#8221; and a product summary</p></li><li><p>A feature grid (real-time occupancy, revenue intelligence, automated alerts) reusing the landing page&#8217;s card style</p></li><li><p>An audience section naming the three target segments: commercial real estate operators, property management firms, municipal parking authorities</p></li><li><p>A team section: three fictional team members &#8212; Maya Reeves (Co-founder and CEO), James Kowalski (Co-founder and CTO), Sofia Patel (Head of Product) &#8212; with orange avatar circles, roles, and one-line bios</p></li></ul><p>Home, Dashboard, Revenue, and About all navigate correctly. Same password, same URL.</p><h2>What was different from the first deployment</h2><p>The first deployment required one manual fix: scoping my GitHub token to the new repo. This update required zero manual actions because that setup carried over. Two errors came up during the run (missing salt config, missing git credentials), and Claude resolved both without prompting me.</p><p>Total time from pasting the prompt to verifying the update: under five minutes.</p><h2>Try it</h2><ul><li><p>Live site: <a href="https://nealvybe.github.io/parkpulse-proto">nealvybe.github.io/parkpulse-proto</a> (password: <code>pulse2026</code>)</p></li><li><p>Code: <a href="https://github.com/nealvybe/parkpulse-proto">github.com/nealvybe/parkpulse-proto</a></p></li></ul><div><hr></div><p>Neal Foster is Co-Founder &amp; CTO of SportChartz and Founder &amp; Partner of Vybe Capital.</p>]]></content:encoded></item><item><title><![CDATA[Choosing an Agent Framework is an Engineering Decision]]></title><description><![CDATA[We recently went through the agent framework decision at SportChartz.]]></description><link>https://nfosignal.substack.com/p/choosing-an-agent-framework-is-an</link><guid isPermaLink="false">https://nfosignal.substack.com/p/choosing-an-agent-framework-is-an</guid><dc:creator><![CDATA[nfos]]></dc:creator><pubDate>Thu, 16 Apr 2026 11:27:43 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!9kR_!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe46ece58-d6d3-4eaf-adf2-62c5f98443fc_1535x1024.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!9kR_!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe46ece58-d6d3-4eaf-adf2-62c5f98443fc_1535x1024.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!9kR_!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe46ece58-d6d3-4eaf-adf2-62c5f98443fc_1535x1024.png 424w, https://substackcdn.com/image/fetch/$s_!9kR_!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe46ece58-d6d3-4eaf-adf2-62c5f98443fc_1535x1024.png 848w, https://substackcdn.com/image/fetch/$s_!9kR_!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe46ece58-d6d3-4eaf-adf2-62c5f98443fc_1535x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!9kR_!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe46ece58-d6d3-4eaf-adf2-62c5f98443fc_1535x1024.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!9kR_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe46ece58-d6d3-4eaf-adf2-62c5f98443fc_1535x1024.png" width="1456" height="971" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e46ece58-d6d3-4eaf-adf2-62c5f98443fc_1535x1024.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:971,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2227503,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://nealcfoster.substack.com/i/192628638?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe46ece58-d6d3-4eaf-adf2-62c5f98443fc_1535x1024.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!9kR_!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe46ece58-d6d3-4eaf-adf2-62c5f98443fc_1535x1024.png 424w, https://substackcdn.com/image/fetch/$s_!9kR_!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe46ece58-d6d3-4eaf-adf2-62c5f98443fc_1535x1024.png 848w, https://substackcdn.com/image/fetch/$s_!9kR_!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe46ece58-d6d3-4eaf-adf2-62c5f98443fc_1535x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!9kR_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe46ece58-d6d3-4eaf-adf2-62c5f98443fc_1535x1024.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>We recently went through the agent framework decision at SportChartz. We build trading agents that need to monitor live sports games, detect technical signals, and post alerts to our community. When we started, the natural instinct was to reach for a framework. We evaluated a full-featured open-source agent platform against building directly on an LLM SDK. We ended up on the SDK, but the decision turned on the specific characteristics of our application, not on framework quality. The answer is application-dependent, and the questions worth asking before committing are the same regardless of what you&#8217;re building.</p><h2><strong>The context</strong></h2><p>During a busy night with 10+ concurrent games across multiple leagues, our system is monitoring game events in real time, evaluating signal conditions every 60-90 seconds and generating content when something fires. It looked like a multi-agent problem: one process watching games, another monitoring social mentions, another reading community chat, another generating content. The path to our decision mattered more than the outcome, because we learned that the right framework depends entirely on what your application actually does.</p><h2><strong>What&#8217;s out there</strong></h2><p>Agent frameworks sit between your application code and the LLM. They manage the orchestration loop: deciding what tool to call, handling the response, maintaining state, determining the next action. As of early 2026, they roughly fall into three tiers:</p><p><strong>Full-featured platforms</strong> like OpenClaw provide a complete runtime. Gateway process, channel adapters (Slack, Discord, WhatsApp, Telegram), per-agent memory files, heartbeat schedulers, a plugin ecosystem. You define agents, bind them to channels, and the gateway handles routing. These are essentially operating systems for agents, and they&#8217;re powerful when your problem fits the model they were built for.</p><p><strong>Orchestration frameworks</strong> like LangGraph and CrewAI sit one level down. LangGraph gives you graph-based execution with explicit state machines - define nodes and edges, the framework manages state transitions. CrewAI gives you role-based teams where agents have defined roles and the framework coordinates between them. Both are Python-native and have strong adoption for complex workflows.</p><p><strong>LLM SDKs with agent capabilities</strong> like the Claude Agent SDK or OpenAI Agents SDK are the thinnest layer. They expose the model&#8217;s native tool-use in a loop: the model decides what to do, calls tools, gets results, decides again. Subagent delegation, session persistence, context management are built in, but the outer orchestration logic is yours.</p><p>Each tier solves a real problem.</p><h2><strong>The questions that matter</strong></h2><p>The decision breaks down along five questions. Your application&#8217;s position on each one pushes you toward different points on the framework spectrum.</p><h3><strong>Trigger type: internal vs. external</strong></h3><p>Internal trigger means your system decides when to act. A polling loop checks data on a cadence, evaluates conditions, maybe takes action. The timing is yours to control. A timer, a cron job, a scheduled function.</p><p>External trigger means something outside your system initiates the action. A user sends a message. A webhook fires. A WebSocket pushes an event. The system needs to be listening and ready to respond.</p><p>This is the first dimension because it determines whether you need always-on infrastructure. Full-featured agent platforms with channel adapters and WebSocket listeners are purpose-built for external triggers. They keep connections alive, route inbound events to the right agent, and handle the plumbing of being permanently available. If your application is genuinely event-driven across multiple channels, that plumbing is valuable and building it yourself is significant work.</p><p>If your application is internally triggered - running on a cycle, checking data, acting when conditions are met - the always-on infrastructure is overhead you&#8217;re paying for but not using. A timer and an API call handle it.</p><p>There&#8217;s a gray zone. Polling at 60-90 seconds feels like real-time to most users. If someone posts in a community chat and the agent notices on its next cycle 45 seconds later, that&#8217;s fast enough for most applications. The question is whether your latency requirement is measured in seconds (event-driven) or minutes (polling handles it).</p><p>Our trading agents are internally triggered. They poll on a cycle during game windows. If we wanted them to also respond to community chat messages, we&#8217;d add &#8220;read recent chat&#8221; as another input in the same cycle. The architecture doesn&#8217;t change.</p><h3><strong>Decision type: deterministic vs. judgment</strong></h3><p>If the trigger logic is &#8220;when value X exceeds threshold Y, take action Z&#8221; - that&#8217;s code. It&#8217;s a conditional. Routing that decision through an LLM agent loop means paying for a model to evaluate something a boolean check handles. The LLM adds value when you need it to write the alert, interpret context, or make a judgment call. It doesn&#8217;t add value for the threshold check itself.</p><p>Most agent frameworks route every decision through the model by design. That&#8217;s the ReAct loop: observe state, reason about what to do, act, repeat. For applications where the decisions genuinely require interpretation of unstructured input - reading a customer email and deciding which department to route it to, analyzing a document and determining next steps, interpreting ambiguous user intent - the ReAct loop is exactly right.</p><p>For applications where the trigger is deterministic and only the output requires generation, you&#8217;re paying the framework&#8217;s coordination overhead on every cycle for logic that could be an <code>if</code> statement. The research quantifies this: CrewAI consumes roughly 3x the tokens and runs 3x slower than a direct API call for simple single-tool tasks. That overhead is the framework&#8217;s coordination logic, not the model&#8217;s reasoning.</p><p>The practical split that worked for us: deterministic code for signal detection and threshold evaluation, LLM for content generation and contextual judgment. The two concerns don&#8217;t need to live in the same loop.</p><h3><strong>Cost structure at scale</strong></h3><p>Token economics at agent scale are different from chatbot scale and worth modeling before you commit to an architecture.</p><p>A chatbot handles one request, generates a response, moves on. An agent running a polling loop makes API calls every 60-90 seconds for hours. With subagent delegation, a single cycle can be 3-5 API calls. Over a 4-hour window, that&#8217;s 160-240 cycles.</p><p>Framework overhead multiplies the per-cycle cost. For the same simple task (single tool call and response), token consumption varies by framework:</p><ul><li><p>Direct API calls: roughly 150-200 tokens</p></li><li><p>LangGraph: under 900 tokens (minimal overhead)</p></li><li><p>CrewAI: roughly 2,700 tokens (3x multiplier from coordination logic)</p></li></ul><p>At low volume, the difference is negligible. At scale, it compounds. A million daily executions at the direct API rate costs roughly $300/day. The same million through CrewAI&#8217;s coordination layer costs roughly $1,200/day. That&#8217;s $27,000/month in framework overhead.</p><p>Two levers help regardless of framework choice. Model routing (cheap models for routine scanning, expensive models for generation) and prompt caching (reusing the same system prompt and tool definitions across cycles, cutting costs 50%+ on repeated context). Both favor simpler architectures where the context is predictable cycle to cycle. Our polling loop runs every 90 seconds for 4 hours. The overhead is predictable and avoidable.</p><h3><strong>Security surface</strong></h3><p>A full-featured agent framework handles your API keys, social credentials, OAuth tokens, and platform secrets. It&#8217;s another system in the chain with access to sensitive material. OpenClaw, the most popular open-source agent framework with over 350,000 GitHub stars, had a January 2026 security audit that found 512 vulnerabilities, 8 of them critical, including OAuth credentials stored in plaintext JSON files. The framework&#8217;s creator left weeks later to join OpenAI, and the project was handed to a newly formed non-profit foundation that is still establishing its governance processes. In March 2026, the Chinese government banned state agencies from using OpenClaw over security concerns.</p><p>Our agents handle social media tokens, financial API keys, and user authentication credentials. Minimizing the number of systems that touch those credentials is not optional. The thin SDK approach keeps credentials in our code, our infrastructure, our control.</p><h3><strong>Debugging depth</strong></h3><p>Every abstraction layer between your application code and the model is a debugging surface. A full-featured framework wraps LLM calls in its own agent loop (ReAct), which internally may use another orchestration library. That&#8217;s potentially two agent loops and three abstraction layers between your business logic and the model.</p><p>When something breaks, the number of layers determines how quickly you find the problem. Our agents need to post during live game windows. If they stop working at 9pm, we can&#8217;t debug until morning. Fewer layers means faster recovery.</p><h2><strong>How it played out for us</strong></h2><p>Our application landed clearly on the &#8220;simpler is better&#8221; end of every dimension. Internally triggered. Mostly deterministic decision logic. Predictable cost structure. Sensitive credentials in the loop. Time-sensitive operations.</p><p>We went with the thin SDK approach. Single process, direct MCP tool integration, a time-aware scheduler that adjusts behavior based on the game window. The outer loop is about 100 lines of code. It handles 30+ concurrent games, evaluates confluence across 5 technical indicators, and calls the LLM when it needs to generate content. It runs on a container. The costs are predictable.</p><h2><strong>The five dimensions, summarized</strong></h2><p><strong>Trigger type.</strong> Internal (polling, scheduled) favors thin SDKs and custom loops. External (event-driven, multi-channel inbound) favors full-featured platforms with channel adapters.</p><p><strong>Decision type.</strong> Deterministic (thresholds, rules, conditions) favors keeping the LLM out of the decision loop. Judgment-heavy (unstructured input, ambiguous intent, contextual reasoning) favors agent frameworks with ReAct orchestration.</p><p><strong>Cost structure.</strong> Predictable, high-frequency workloads amplify framework overhead. Bursty, variable workloads make framework overhead proportionally smaller. Model routing and caching help in both cases.</p><p><strong>Security surface.</strong> Sensitive credentials favor fewer dependencies and thinner frameworks. Sandboxed operations are less constrained.</p><p><strong>Debugging depth.</strong> Time-sensitive operations favor fewer abstraction layers. Batch operations can absorb more layers in exchange for richer tooling.</p><p><em>Neal Foster is Co-Founder &amp; CTO of SportChartz and Founder &amp; Partner of Vybe Capital.</em></p>]]></content:encoded></item><item><title><![CDATA[One Prompt to Live URL]]></title><description><![CDATA[I wanted to see how far a single prompt could go inside Cowork.]]></description><link>https://nfosignal.substack.com/p/one-prompt-to-live-url</link><guid isPermaLink="false">https://nfosignal.substack.com/p/one-prompt-to-live-url</guid><dc:creator><![CDATA[nfos]]></dc:creator><pubDate>Sat, 11 Apr 2026 18:51:46 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!rd1N!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2ae68fe-9b1c-40ce-b96c-33ee75ceccc8_1434x836.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!rd1N!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2ae68fe-9b1c-40ce-b96c-33ee75ceccc8_1434x836.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!rd1N!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2ae68fe-9b1c-40ce-b96c-33ee75ceccc8_1434x836.png 424w, https://substackcdn.com/image/fetch/$s_!rd1N!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2ae68fe-9b1c-40ce-b96c-33ee75ceccc8_1434x836.png 848w, https://substackcdn.com/image/fetch/$s_!rd1N!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2ae68fe-9b1c-40ce-b96c-33ee75ceccc8_1434x836.png 1272w, https://substackcdn.com/image/fetch/$s_!rd1N!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2ae68fe-9b1c-40ce-b96c-33ee75ceccc8_1434x836.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!rd1N!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2ae68fe-9b1c-40ce-b96c-33ee75ceccc8_1434x836.png" width="1434" height="836" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e2ae68fe-9b1c-40ce-b96c-33ee75ceccc8_1434x836.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:836,&quot;width&quot;:1434,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:185382,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://nealcfoster.substack.com/i/192628933?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2ae68fe-9b1c-40ce-b96c-33ee75ceccc8_1434x836.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!rd1N!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2ae68fe-9b1c-40ce-b96c-33ee75ceccc8_1434x836.png 424w, https://substackcdn.com/image/fetch/$s_!rd1N!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2ae68fe-9b1c-40ce-b96c-33ee75ceccc8_1434x836.png 848w, https://substackcdn.com/image/fetch/$s_!rd1N!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2ae68fe-9b1c-40ce-b96c-33ee75ceccc8_1434x836.png 1272w, https://substackcdn.com/image/fetch/$s_!rd1N!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2ae68fe-9b1c-40ce-b96c-33ee75ceccc8_1434x836.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>I wanted to see how far a single prompt could go inside Cowork. Not a chain of follow-ups. Not a back-and-forth where I steer the AI through each step. One prompt, one shot, from idea to password-protected live site.</p><p>The product is ParkPulse, a parking garage management dashboard for building operators. I made it up. The goal was to test the workflow, not the concept.</p><h2><strong>What you need</strong></h2><ol><li><p>A paid Claude account (<a href="https://claude.com/pricing">Pro at $20/mo or Max at $100/mo</a>) with the <a href="https://claude.ai/download">Claude desktop app</a> and Cowork mode enabled</p></li><li><p>A GitHub account (<a href="https://github.com">github.com</a>, free tier works)</p></li></ol><p>That&#8217;s it. Everything else gets set up along the way.</p><h2><strong>The prompt</strong></h2><p>I opened Cowork and pasted this:</p><blockquote><p>Build me a single-file HTML prototype for a product called ParkPulse, a parking garage management dashboard for building operators. It should have three views:</p><ol><li><p>Landing page with a hero section explaining the product and three feature cards</p></li><li><p>Occupancy dashboard showing 6 garage locations in a city (use Boston) with real-time occupancy percentages, revenue today, and status badges (full, available, maintenance)</p></li><li><p>Revenue timeline showing daily revenue events, rate changes, and capacity alerts in chronological order</p></li></ol><p>Use a light theme with an orange (#ea580c) accent color. No external dependencies. Include search/filter, clickable rows that open a detail panel, and realistic mock data.</p><p>After you build it, deploy it to GitHub Pages under a new public repo called <code>parkpulse-proto</code> in my GitHub account. Then encrypt it with StaticCrypt so visitors need a password. Push the encrypted version using git.</p></blockquote><p>Then I waited.</p><h2><strong>Here&#8217;s what Cowork did</strong></h2><p>About two minutes in, the browser opened and started moving. Claude navigated to GitHub, created a new repository called <code>parkpulse-proto</code>, filled in the description, set it to public, and clicked Create. I watched it happen in real time but didn&#8217;t touch anything.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!VBc-!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27a7c25f-f7ff-4c15-90f7-5205b5d156d2_2576x1904.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!VBc-!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27a7c25f-f7ff-4c15-90f7-5205b5d156d2_2576x1904.png 424w, https://substackcdn.com/image/fetch/$s_!VBc-!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27a7c25f-f7ff-4c15-90f7-5205b5d156d2_2576x1904.png 848w, https://substackcdn.com/image/fetch/$s_!VBc-!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27a7c25f-f7ff-4c15-90f7-5205b5d156d2_2576x1904.png 1272w, https://substackcdn.com/image/fetch/$s_!VBc-!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27a7c25f-f7ff-4c15-90f7-5205b5d156d2_2576x1904.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!VBc-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27a7c25f-f7ff-4c15-90f7-5205b5d156d2_2576x1904.png" width="1456" height="1076" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/27a7c25f-f7ff-4c15-90f7-5205b5d156d2_2576x1904.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1076,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:473755,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://nfosignal.substack.com/i/192628933?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27a7c25f-f7ff-4c15-90f7-5205b5d156d2_2576x1904.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!VBc-!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27a7c25f-f7ff-4c15-90f7-5205b5d156d2_2576x1904.png 424w, https://substackcdn.com/image/fetch/$s_!VBc-!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27a7c25f-f7ff-4c15-90f7-5205b5d156d2_2576x1904.png 848w, https://substackcdn.com/image/fetch/$s_!VBc-!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27a7c25f-f7ff-4c15-90f7-5205b5d156d2_2576x1904.png 1272w, https://substackcdn.com/image/fetch/$s_!VBc-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27a7c25f-f7ff-4c15-90f7-5205b5d156d2_2576x1904.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>In the background, the terminal was running git commands, installing npm packages, committing files. Claude generated an 825-line HTML file (32KB) with all three views, six Boston garages with realistic data, working search and filter, clickable rows, and a slide-out detail panel. All inline CSS and JavaScript, no external dependencies.</p><p>Then Claude encrypted the whole thing with StaticCrypt, running <code>npx staticrypt index.html -p "pulse2026" --short</code> in the terminal on its own. The 825-line prototype (32KB) became an 892-line encrypted file (99KB), with all the original HTML, CSS, and JavaScript baked into an AES-encrypted payload behind a password prompt.</p><p>The first <code>git push</code> failed with a 403.</p><h2><strong>Minor detour: I need to setup a GitHub Personal Access Token</strong></h2><p>Cowork can create repos and navigate GitHub through the browser, but pushing code from the command line requires authentication. GitHub doesn&#8217;t allow password-based git pushes. You need a Personal Access Token (PAT).</p><p>To set one up: GitHub &#8594; Settings &#8594; Developer settings &#8594; Personal access tokens &#8594; Fine-grained tokens. Click &#8220;Generate new token.&#8221; Give it a name, set an expiration, and under Repository access select &#8220;Only select repositories&#8221; and add the repo you&#8217;re deploying to. Under Permissions, grant Contents read and write access. Generate the token and copy it.</p><p>Store the token in your git credential manager or pass it as part of the remote URL so that <code>git push</code> works without prompting for a password. GitHub&#8217;s docs on <a href="https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens">Managing your personal access tokens</a> walk through the options.</p><p>In my case, I already had a token configured, but it was scoped to a different repo. I edited the token&#8217;s repository access, added <code>parkpulse-proto</code>, and saved.</p><p>Claude retried and the push went through.</p><h2><strong>Back to Cowork taking over</strong></h2><p>After that, the browser navigated to the repo&#8217;s Settings page, opened the Pages section, selected <code>main</code> as the source branch, and clicked Save. Then it navigated to the live URL. A password wall appeared.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!8S5_!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f44cb89-46f4-4e1b-96ad-7e5a381baac7_1882x1374.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!8S5_!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f44cb89-46f4-4e1b-96ad-7e5a381baac7_1882x1374.png 424w, https://substackcdn.com/image/fetch/$s_!8S5_!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f44cb89-46f4-4e1b-96ad-7e5a381baac7_1882x1374.png 848w, https://substackcdn.com/image/fetch/$s_!8S5_!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f44cb89-46f4-4e1b-96ad-7e5a381baac7_1882x1374.png 1272w, https://substackcdn.com/image/fetch/$s_!8S5_!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f44cb89-46f4-4e1b-96ad-7e5a381baac7_1882x1374.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!8S5_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f44cb89-46f4-4e1b-96ad-7e5a381baac7_1882x1374.png" width="1456" height="1063" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8f44cb89-46f4-4e1b-96ad-7e5a381baac7_1882x1374.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1063,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:150014,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://nfosignal.substack.com/i/192628933?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f44cb89-46f4-4e1b-96ad-7e5a381baac7_1882x1374.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!8S5_!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f44cb89-46f4-4e1b-96ad-7e5a381baac7_1882x1374.png 424w, https://substackcdn.com/image/fetch/$s_!8S5_!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f44cb89-46f4-4e1b-96ad-7e5a381baac7_1882x1374.png 848w, https://substackcdn.com/image/fetch/$s_!8S5_!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f44cb89-46f4-4e1b-96ad-7e5a381baac7_1882x1374.png 1272w, https://substackcdn.com/image/fetch/$s_!8S5_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f44cb89-46f4-4e1b-96ad-7e5a381baac7_1882x1374.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Claude entered the password, clicked Decrypt, and the full prototype loaded.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!0Gb5!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92d29c1a-5f5f-4822-8e9e-37832150ffdd_1886x1726.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!0Gb5!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92d29c1a-5f5f-4822-8e9e-37832150ffdd_1886x1726.png 424w, https://substackcdn.com/image/fetch/$s_!0Gb5!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92d29c1a-5f5f-4822-8e9e-37832150ffdd_1886x1726.png 848w, https://substackcdn.com/image/fetch/$s_!0Gb5!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92d29c1a-5f5f-4822-8e9e-37832150ffdd_1886x1726.png 1272w, https://substackcdn.com/image/fetch/$s_!0Gb5!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92d29c1a-5f5f-4822-8e9e-37832150ffdd_1886x1726.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!0Gb5!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92d29c1a-5f5f-4822-8e9e-37832150ffdd_1886x1726.png" width="1456" height="1332" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/92d29c1a-5f5f-4822-8e9e-37832150ffdd_1886x1726.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1332,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:392712,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://nfosignal.substack.com/i/192628933?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92d29c1a-5f5f-4822-8e9e-37832150ffdd_1886x1726.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!0Gb5!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92d29c1a-5f5f-4822-8e9e-37832150ffdd_1886x1726.png 424w, https://substackcdn.com/image/fetch/$s_!0Gb5!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92d29c1a-5f5f-4822-8e9e-37832150ffdd_1886x1726.png 848w, https://substackcdn.com/image/fetch/$s_!0Gb5!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92d29c1a-5f5f-4822-8e9e-37832150ffdd_1886x1726.png 1272w, https://substackcdn.com/image/fetch/$s_!0Gb5!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92d29c1a-5f5f-4822-8e9e-37832150ffdd_1886x1726.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The landing page has a hero section with the tagline and three feature cards: Live Occupancy, Revenue Tracking, and Smart Alerts. Clicking &#8220;See the Dashboard&#8221; switches to the occupancy view.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!sjbr!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feb1d4be2-0323-4f7f-add9-3851a13124e4_1882x1598.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!sjbr!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feb1d4be2-0323-4f7f-add9-3851a13124e4_1882x1598.png 424w, https://substackcdn.com/image/fetch/$s_!sjbr!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feb1d4be2-0323-4f7f-add9-3851a13124e4_1882x1598.png 848w, https://substackcdn.com/image/fetch/$s_!sjbr!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feb1d4be2-0323-4f7f-add9-3851a13124e4_1882x1598.png 1272w, https://substackcdn.com/image/fetch/$s_!sjbr!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feb1d4be2-0323-4f7f-add9-3851a13124e4_1882x1598.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!sjbr!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feb1d4be2-0323-4f7f-add9-3851a13124e4_1882x1598.png" width="1456" height="1236" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/eb1d4be2-0323-4f7f-add9-3851a13124e4_1882x1598.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1236,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:316342,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://nfosignal.substack.com/i/192628933?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feb1d4be2-0323-4f7f-add9-3851a13124e4_1882x1598.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!sjbr!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feb1d4be2-0323-4f7f-add9-3851a13124e4_1882x1598.png 424w, https://substackcdn.com/image/fetch/$s_!sjbr!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feb1d4be2-0323-4f7f-add9-3851a13124e4_1882x1598.png 848w, https://substackcdn.com/image/fetch/$s_!sjbr!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feb1d4be2-0323-4f7f-add9-3851a13124e4_1882x1598.png 1272w, https://substackcdn.com/image/fetch/$s_!sjbr!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feb1d4be2-0323-4f7f-add9-3851a13124e4_1882x1598.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The dashboard shows summary cards at the top (total spaces, occupied now, revenue today, average occupancy) and a table of six garages with occupancy bars, space counts, daily revenue, and status badges. Post Office Square is at 94% and marked Full. Kendall Square is at 45% and flagged for Maintenance.</p><p>Clicking a garage name opens a detail panel that slides in from the right.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!sDHi!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F177ff817-60d9-45ef-9b62-581aa5458676_1892x1544.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!sDHi!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F177ff817-60d9-45ef-9b62-581aa5458676_1892x1544.png 424w, https://substackcdn.com/image/fetch/$s_!sDHi!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F177ff817-60d9-45ef-9b62-581aa5458676_1892x1544.png 848w, https://substackcdn.com/image/fetch/$s_!sDHi!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F177ff817-60d9-45ef-9b62-581aa5458676_1892x1544.png 1272w, https://substackcdn.com/image/fetch/$s_!sDHi!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F177ff817-60d9-45ef-9b62-581aa5458676_1892x1544.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!sDHi!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F177ff817-60d9-45ef-9b62-581aa5458676_1892x1544.png" width="1456" height="1188" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/177ff817-60d9-45ef-9b62-581aa5458676_1892x1544.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1188,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:406225,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://nfosignal.substack.com/i/192628933?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F177ff817-60d9-45ef-9b62-581aa5458676_1892x1544.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!sDHi!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F177ff817-60d9-45ef-9b62-581aa5458676_1892x1544.png 424w, https://substackcdn.com/image/fetch/$s_!sDHi!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F177ff817-60d9-45ef-9b62-581aa5458676_1892x1544.png 848w, https://substackcdn.com/image/fetch/$s_!sDHi!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F177ff817-60d9-45ef-9b62-581aa5458676_1892x1544.png 1272w, https://substackcdn.com/image/fetch/$s_!sDHi!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F177ff817-60d9-45ef-9b62-581aa5458676_1892x1544.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The panel shows current stats (occupancy percentage, revenue today, daily rate, monthly rate), garage info (total spaces, hours, manager name, phone number), and recent activity (capacity alerts, revenue milestones, morning rush peaks).</p><p>The third view is a revenue timeline.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!6QHZ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4be10405-a368-4d53-a76c-4597cc4eac73_1878x1446.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!6QHZ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4be10405-a368-4d53-a76c-4597cc4eac73_1878x1446.png 424w, https://substackcdn.com/image/fetch/$s_!6QHZ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4be10405-a368-4d53-a76c-4597cc4eac73_1878x1446.png 848w, https://substackcdn.com/image/fetch/$s_!6QHZ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4be10405-a368-4d53-a76c-4597cc4eac73_1878x1446.png 1272w, https://substackcdn.com/image/fetch/$s_!6QHZ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4be10405-a368-4d53-a76c-4597cc4eac73_1878x1446.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!6QHZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4be10405-a368-4d53-a76c-4597cc4eac73_1878x1446.png" width="1456" height="1121" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/4be10405-a368-4d53-a76c-4597cc4eac73_1878x1446.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1121,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:282483,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://nfosignal.substack.com/i/192628933?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4be10405-a368-4d53-a76c-4597cc4eac73_1878x1446.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!6QHZ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4be10405-a368-4d53-a76c-4597cc4eac73_1878x1446.png 424w, https://substackcdn.com/image/fetch/$s_!6QHZ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4be10405-a368-4d53-a76c-4597cc4eac73_1878x1446.png 848w, https://substackcdn.com/image/fetch/$s_!6QHZ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4be10405-a368-4d53-a76c-4597cc4eac73_1878x1446.png 1272w, https://substackcdn.com/image/fetch/$s_!6QHZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4be10405-a368-4d53-a76c-4597cc4eac73_1878x1446.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Events are grouped by date and color-coded by type. Capacity alerts, surge pricing activations, revenue milestones, event rate changes, maintenance notices. Each entry shows the garage name, a description, and the financial impact. Filter buttons at the top let you narrow by revenue events, rate changes, or alerts only.</p><h2><strong>What came out of it</strong></h2><p>From a single prompt, Cowork generated 825 lines of HTML, CSS, and JavaScript, encrypted the file with StaticCrypt, created a GitHub repo, pushed the code, enabled GitHub Pages, and verified the live site. The only thing I did was fix a token permission. The whole process took under ten minutes.</p><p>You can try the prototype at <a href="https://nealvybe.github.io/parkpulse-proto/">nealvybe.github.io/parkpulse-proto</a>. Password: <code>pulse2026</code>. </p><p>You can view and clone the code at <a href="https://github.com/nealvybe/parkpulse-proto">github.com/nealvybe/parkpulse-proto</a>.</p><p>In a future post, I&#8217;ll show how to make changes to a live encrypted site using the same Cowork workflow.</p><p></p><p><em>Neal Foster is Co-Founder &amp; CTO of SportChartz and Founder &amp; Partner of Vybe Capital.</em></p>]]></content:encoded></item></channel></rss>