<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>James Galley - Writing</title>
  <subtitle>Notes and articles on business operations, systems integration, agentic AI, and where they meet.</subtitle>
  <link rel="self" href="https://jamesgalley.com/feed.xml"/>
  <link rel="alternate" href="https://jamesgalley.com/writing"/>
  <id>https://jamesgalley.com/</id>
  <updated>2026-08-05T15:20:15.000Z</updated>
  <author><name>James Galley</name></author>
  <entry>
    <title>A runaway train and the anatomy of a bad alert</title>
    <link rel="alternate" href="https://jamesgalley.com/writing/a-runaway-train-and-the-anatomy-of-a-bad-alert"/>
    <id>https://jamesgalley.com/writing/a-runaway-train-and-the-anatomy-of-a-bad-alert</id>
    <updated>2026-08-02T21:37:01+01:00</updated>
    <published>2026-08-02T00:00:00.000Z</published>
    <category term="Human error"/>
    <category term="Monitoring"/>
    <category term="Incident response"/>
    <summary>The 1988 Gare de Lyon rail accident, and what its instruments, alerts and emergency mechanisms have to say about how we monitor and run software systems.</summary>
    <author><name>James Galley</name></author>
  </entry>
  <entry>
    <title>Using AI to help write articles</title>
    <link rel="alternate" href="https://jamesgalley.com/writing/using-ai-to-help-write-articles"/>
    <id>https://jamesgalley.com/writing/using-ai-to-help-write-articles</id>
    <updated>2026-08-02T23:04:18+01:00</updated>
    <published>2026-07-28T00:00:00.000Z</published>
    <category term="AI"/>
    <category term="Writing"/>
    <summary>How I use AI in the loop when writing articles for this site: scaffold first, rewrite everything, bank the corrections, and never publish what you don't know.</summary>
    <author><name>James Galley</name></author>
  </entry>
  <entry>
    <title>Serverless search: a Lambda fan-out over S3</title>
    <link rel="alternate" href="https://jamesgalley.com/writing/serverless-search-a-lambda-fan-out-over-s3"/>
    <id>https://jamesgalley.com/writing/serverless-search-a-lambda-fan-out-over-s3</id>
    <updated>2026-08-05T16:20:15+01:00</updated>
    <published>2026-07-23T00:00:00.000Z</published>
    <category term="AWS"/>
    <category term="Serverless"/>
    <category term="Search"/>
    <category term="Lambda"/>
    <summary>Full-text search with no index at all: raw text in S3, a fleet of parallel Lambda functions scanning byte ranges, and benchmarks of what that buys - plus the Bloom filters that let the brute force skip most of the corpus. Part three of the serverless search series.</summary>
    <author><name>James Galley</name></author>
  </entry>
  <entry>
    <title>Novel strategies for serverless search</title>
    <link rel="alternate" href="https://jamesgalley.com/writing/novel-strategies-for-serverless-search"/>
    <id>https://jamesgalley.com/writing/novel-strategies-for-serverless-search</id>
    <updated>2026-07-20T08:54:32+01:00</updated>
    <published>2026-07-16T00:00:00.000Z</published>
    <category term="AWS"/>
    <category term="Serverless"/>
    <category term="Search"/>
    <summary>Searching a million records without running a search cluster. The first in a series on serverless search in AWS, looking at why Athena and OpenSearch Serverless don't quite fit the problem, and previewing five alternative strategies.</summary>
    <author><name>James Galley</name></author>
  </entry>
  <entry>
    <title>Serverless search: an inverted index in DynamoDB</title>
    <link rel="alternate" href="https://jamesgalley.com/writing/serverless-search-an-inverted-index-in-dynamodb"/>
    <id>https://jamesgalley.com/writing/serverless-search-an-inverted-index-in-dynamodb</id>
    <updated>2026-08-05T16:20:15+01:00</updated>
    <published>2026-07-16T00:00:00.000Z</published>
    <category term="AWS"/>
    <category term="Serverless"/>
    <category term="Search"/>
    <category term="DynamoDB"/>
    <summary>DynamoDB has no full-text search of its own, but its talent for key lookups is enough to build one: tokenising documents into an inverted index, searching it with single queries, and keeping it fresh with Streams. Part two of the serverless search series.</summary>
    <author><name>James Galley</name></author>
  </entry>
  <entry>
    <title>Digital transformation in the AI era</title>
    <link rel="alternate" href="https://jamesgalley.com/writing/digital-transformation-in-the-ai-era"/>
    <id>https://jamesgalley.com/writing/digital-transformation-in-the-ai-era</id>
    <updated>2026-07-13T23:14:55+01:00</updated>
    <published>2026-07-13T00:00:00.000Z</published>
    <category term="Agentic AI"/>
    <category term="Business operations"/>
    <category term="Integration"/>
    <summary>Agentic AI is the next chapter of digital transformation, and the businesses that already digitised and connected their operations are the ones positioned to benefit. A worked example from Si Novi's own books.</summary>
    <author><name>James Galley</name></author>
  </entry>
  <entry>
    <title>AI automation for business: where it fits, and where it doesn't</title>
    <link rel="alternate" href="https://jamesgalley.com/writing/ai-automation-for-business"/>
    <id>https://jamesgalley.com/writing/ai-automation-for-business</id>
    <updated>2026-07-13T23:14:55+01:00</updated>
    <published>2026-06-26T00:00:00.000Z</published>
    <category term="Agentic AI"/>
    <category term="Business operations"/>
    <category term="Automation"/>
    <summary>AI can automate the judgement-heavy middle of your operations - reading messy inputs, routine decisions, exceptions - but only once your systems are connected. A practical guide to what works, what doesn't, and how to start.</summary>
    <author><name>James Galley</name></author>
  </entry>
  <entry>
    <title>What happens when the phone locks?</title>
    <link rel="alternate" href="https://jamesgalley.com/writing/what-happens-when-the-phone-locks"/>
    <id>https://jamesgalley.com/writing/what-happens-when-the-phone-locks</id>
    <updated>2026-07-13T21:56:51+01:00</updated>
    <published>2026-03-24T00:00:00.000Z</published>
    <category term="User experience"/>
    <category term="Mobile"/>
    <category term="Architecture"/>
    <summary>A support chat that asks you to keep your phone awake is a sign the architecture has pushed its problem onto the customer. On designing mobile web sessions that survive interruption.</summary>
    <author><name>James Galley</name></author>
  </entry>
  <entry>
    <title>Permissions-Policy HTTP header</title>
    <link rel="alternate" href="https://jamesgalley.com/writing/permissions-policy-http-header"/>
    <id>https://jamesgalley.com/writing/permissions-policy-http-header</id>
    <updated>2026-07-13T20:27:34+01:00</updated>
    <published>2025-03-11T00:00:00.000Z</published>
    <category term="Security"/>
    <summary>How the Permissions-Policy header controls access to browser features like camera, microphone and geolocation, its syntax, and how to set it in Apache and PHP.</summary>
    <author><name>James Galley</name></author>
  </entry>
  <entry>
    <title>Referrer-Policy HTTP header</title>
    <link rel="alternate" href="https://jamesgalley.com/writing/referrer-policy-http-header"/>
    <id>https://jamesgalley.com/writing/referrer-policy-http-header</id>
    <updated>2026-07-13T20:27:34+01:00</updated>
    <published>2024-10-08T00:00:00.000Z</published>
    <category term="Security"/>
    <summary>How the Referrer-Policy header controls what URL information is shared with other sites, the values available, and how to set a sensible default in Apache and PHP.</summary>
    <author><name>James Galley</name></author>
  </entry>
  <entry>
    <title>Common aws s3 cp examples</title>
    <link rel="alternate" href="https://jamesgalley.com/writing/common-aws-s3-cp-examples"/>
    <id>https://jamesgalley.com/writing/common-aws-s3-cp-examples</id>
    <updated>2026-07-13T20:27:34+01:00</updated>
    <published>2024-06-18T00:00:00.000Z</published>
    <category term="AWS"/>
    <category term="Command line"/>
    <summary>Handy aws s3 cp command examples for copying single files and directories to and from Amazon S3, including recursive copies, content type and cache headers, and streaming with stdin and stdout.</summary>
    <author><name>James Galley</name></author>
  </entry>
  <entry>
    <title>Common aws s3 sync examples</title>
    <link rel="alternate" href="https://jamesgalley.com/writing/common-aws-s3-sync-examples"/>
    <id>https://jamesgalley.com/writing/common-aws-s3-sync-examples</id>
    <updated>2026-07-13T20:27:34+01:00</updated>
    <published>2024-06-18T00:00:00.000Z</published>
    <category term="AWS"/>
    <category term="Command line"/>
    <summary>Handy aws s3 sync command examples for uploading, downloading, mirroring with --delete, filtering, cache headers and dry runs, from deploying static sites to S3.</summary>
    <author><name>James Galley</name></author>
  </entry>
  <entry>
    <title>X-Content-Type-Options HTTP header</title>
    <link rel="alternate" href="https://jamesgalley.com/writing/x-content-type-options-http-header"/>
    <id>https://jamesgalley.com/writing/x-content-type-options-http-header</id>
    <updated>2026-07-13T20:27:34+01:00</updated>
    <published>2024-04-16T00:00:00.000Z</published>
    <category term="Security"/>
    <summary>What the X-Content-Type-Options nosniff header does, why MIME-type sniffing is a risk, and how to set it in Apache, PHP and on AWS CloudFront.</summary>
    <author><name>James Galley</name></author>
  </entry>
  <entry>
    <title>Content-Security-Policy HTTP header</title>
    <link rel="alternate" href="https://jamesgalley.com/writing/content-security-policy-http-header"/>
    <id>https://jamesgalley.com/writing/content-security-policy-http-header</id>
    <updated>2026-07-13T20:27:34+01:00</updated>
    <published>2023-11-14T00:00:00.000Z</published>
    <category term="Security"/>
    <summary>How the Content-Security-Policy header controls which resources a page can load, its key directives, report-only mode, and how to set it in Apache, PHP and AWS CloudFront.</summary>
    <author><name>James Galley</name></author>
  </entry>
  <entry>
    <title>Common rsync examples for macOS and Linux</title>
    <link rel="alternate" href="https://jamesgalley.com/writing/common-rsync-examples"/>
    <id>https://jamesgalley.com/writing/common-rsync-examples</id>
    <updated>2026-07-13T20:27:34+01:00</updated>
    <published>2023-07-31T00:00:00.000Z</published>
    <category term="DevOps"/>
    <category term="Linux"/>
    <summary>Practical rsync command examples for file synchronisation, backup, and deployment workflows.</summary>
    <author><name>James Galley</name></author>
  </entry>
  <entry>
    <title>Strict-Transport-Security HTTP header</title>
    <link rel="alternate" href="https://jamesgalley.com/writing/strict-transport-security"/>
    <id>https://jamesgalley.com/writing/strict-transport-security</id>
    <updated>2026-08-05T16:20:15+01:00</updated>
    <published>2023-03-26T00:00:00.000Z</published>
    <category term="Security"/>
    <category term="HTTP headers"/>
    <summary>How to set the Strict-Transport-Security (HSTS) header to enforce HTTPS, with examples for Apache, PHP, Yii 2, Lambda@Edge and CloudFront functions, and the max-age, includeSubDomains and preload directives explained.</summary>
    <author><name>James Galley</name></author>
  </entry>
  <entry>
    <title>X-Frame-Options HTTP header</title>
    <link rel="alternate" href="https://jamesgalley.com/writing/x-frame-options"/>
    <id>https://jamesgalley.com/writing/x-frame-options</id>
    <updated>2026-08-05T16:20:15+01:00</updated>
    <published>2023-01-08T00:00:00.000Z</published>
    <category term="Security"/>
    <category term="HTTP headers"/>
    <summary>How to set the X-Frame-Options header to prevent clickjacking, with examples for Apache, PHP, Yii 2, Node.js and Remix - and what the &quot;refused to display in a frame&quot; browser error means.</summary>
    <author><name>James Galley</name></author>
  </entry>
  <entry>
    <title>How to use S3 getObject as a promise in Node.js</title>
    <link rel="alternate" href="https://jamesgalley.com/writing/how-to-use-s3-getobject-as-a-promise-in-node-js"/>
    <id>https://jamesgalley.com/writing/how-to-use-s3-getobject-as-a-promise-in-node-js</id>
    <updated>2026-08-04T23:05:45+01:00</updated>
    <published>2022-07-13T00:00:00.000Z</published>
    <category term="AWS"/>
    <category term="Node.js"/>
    <summary>Using S3 GetObject with promises and async/await in Node.js, updated for AWS SDK v3 - including how to read the streaming Body it returns.</summary>
    <author><name>James Galley</name></author>
  </entry>
  <entry>
    <title>Cron jobs on Elastic Beanstalk PHP apps</title>
    <link rel="alternate" href="https://jamesgalley.com/writing/cron-jobs-on-elastic-beanstalk"/>
    <id>https://jamesgalley.com/writing/cron-jobs-on-elastic-beanstalk</id>
    <updated>2026-07-13T20:27:34+01:00</updated>
    <published>2022-03-10T00:00:00.000Z</published>
    <category term="AWS"/>
    <category term="DevOps"/>
    <summary>How to add a cron job to an Elastic Beanstalk PHP app, and how to make your environment variables available to the cron.</summary>
    <author><name>James Galley</name></author>
  </entry>
  <entry>
    <title>Using SSL and CloudFront with a single-instance Elastic Beanstalk app</title>
    <link rel="alternate" href="https://jamesgalley.com/writing/cloudfront-ssl-single-instance-elastic-beanstalk"/>
    <id>https://jamesgalley.com/writing/cloudfront-ssl-single-instance-elastic-beanstalk</id>
    <updated>2026-07-13T20:27:34+01:00</updated>
    <published>2020-04-16T00:00:00.000Z</published>
    <category term="AWS"/>
    <category term="CloudFront"/>
    <category term="PHP"/>
    <summary>Adding HTTPS to a single-instance Elastic Beanstalk PHP application by putting CloudFront in front of it, including the Apache and Yii2 configuration needed.</summary>
    <author><name>James Galley</name></author>
  </entry>
  <entry>
    <title>Using Captcha to prevent bots, spam and abuse</title>
    <link rel="alternate" href="https://jamesgalley.com/writing/using-captcha-to-prevent-bots-and-spam"/>
    <id>https://jamesgalley.com/writing/using-captcha-to-prevent-bots-and-spam</id>
    <updated>2026-07-13T20:27:34+01:00</updated>
    <published>2020-04-14T00:00:00.000Z</published>
    <category term="Security"/>
    <category term="Web applications"/>
    <summary>How adding a Captcha widget like Google's reCaptcha to your website's public forms helps keep out automated bots.</summary>
    <author><name>James Galley</name></author>
  </entry>
  <entry>
    <title>Multiple AWS sub-accounts and cross-account role switching</title>
    <link rel="alternate" href="https://jamesgalley.com/writing/aws-sub-accounts-and-cross-account-roles"/>
    <id>https://jamesgalley.com/writing/aws-sub-accounts-and-cross-account-roles</id>
    <updated>2026-07-13T20:27:34+01:00</updated>
    <published>2019-12-30T00:00:00.000Z</published>
    <category term="AWS"/>
    <category term="IAM"/>
    <category term="Security"/>
    <summary>How to set up AWS sub-accounts and cross-account IAM roles for secure, isolated access across multiple AWS environments.</summary>
    <author><name>James Galley</name></author>
  </entry>
  <entry>
    <title>Converting Yii 1 models to Yii 2</title>
    <link rel="alternate" href="https://jamesgalley.com/writing/converting-yii-1-models-to-yii-2"/>
    <id>https://jamesgalley.com/writing/converting-yii-1-models-to-yii-2</id>
    <updated>2026-07-13T20:27:34+01:00</updated>
    <published>2019-12-01T00:00:00.000Z</published>
    <category term="PHP"/>
    <category term="Yii"/>
    <summary>A technical guide to migrating Yii 1 models to Yii 2, covering namespaces, validation rules, relations, and search methods.</summary>
    <author><name>James Galley</name></author>
  </entry>
  <entry>
    <title>Digital transformation</title>
    <link rel="alternate" href="https://jamesgalley.com/writing/digital-transformation"/>
    <id>https://jamesgalley.com/writing/digital-transformation</id>
    <updated>2026-07-13T20:27:34+01:00</updated>
    <published>2019-08-19T00:00:00.000Z</published>
    <category term="Business operations"/>
    <category term="Automation"/>
    <category term="Integration"/>
    <summary>Digitising business processes with web applications, integrations and the cloud to save money, reduce duplication and improve efficiency.</summary>
    <author><name>James Galley</name></author>
  </entry>
  <entry>
    <title>When the interface is the hazard</title>
    <link rel="alternate" href="https://jamesgalley.com/writing/when-the-interface-is-the-hazard"/>
    <id>https://jamesgalley.com/writing/when-the-interface-is-the-hazard</id>
    <updated>2026-07-13T20:27:34+01:00</updated>
    <published>2019-08-13T00:00:00.000Z</published>
    <category term="Human-machine interaction"/>
    <category term="Human error"/>
    <category term="Software design"/>
    <summary>The US Navy tore the touchscreen controls out of its destroyers and went back to physical throttles after the USS John S McCain collision. What that says about complexity, human error and designing software people can actually use.</summary>
    <author><name>James Galley</name></author>
  </entry>
  <entry>
    <title>Migrating legacy PHP web applications to the cloud</title>
    <link rel="alternate" href="https://jamesgalley.com/writing/migrating-web-applications-to-the-cloud"/>
    <id>https://jamesgalley.com/writing/migrating-web-applications-to-the-cloud</id>
    <updated>2026-07-13T20:27:34+01:00</updated>
    <published>2018-12-03T00:00:00.000Z</published>
    <category term="Cloud"/>
    <category term="Modernisation"/>
    <category term="AWS"/>
    <summary>How to migrate legacy PHP applications to AWS cloud hosting with no disruption to your business, for scalability and reliability.</summary>
    <author><name>James Galley</name></author>
  </entry>
  <entry>
    <title>Integrating web applications with Xero</title>
    <link rel="alternate" href="https://jamesgalley.com/writing/integrating-web-applications-with-xero"/>
    <id>https://jamesgalley.com/writing/integrating-web-applications-with-xero</id>
    <updated>2026-07-13T20:27:34+01:00</updated>
    <published>2018-08-12T00:00:00.000Z</published>
    <category term="Integration"/>
    <category term="Business operations"/>
    <category term="APIs"/>
    <summary>Using the Xero API to integrate your back-office and operations software, generating invoices and bills automatically.</summary>
    <author><name>James Galley</name></author>
  </entry>
  <entry>
    <title>Upgrading Yii 1 web applications to Yii 2</title>
    <link rel="alternate" href="https://jamesgalley.com/writing/upgrading-yii-1-applications-to-yii-2"/>
    <id>https://jamesgalley.com/writing/upgrading-yii-1-applications-to-yii-2</id>
    <updated>2026-07-13T20:27:34+01:00</updated>
    <published>2018-08-12T00:00:00.000Z</published>
    <category term="PHP"/>
    <category term="Yii"/>
    <summary>A guide to migrating PHP web applications from Yii 1 to Yii 2, covering the differences between versions and upgrade strategies.</summary>
    <author><name>James Galley</name></author>
  </entry>
  <entry>
    <title>PHP web application security and maintenance</title>
    <link rel="alternate" href="https://jamesgalley.com/writing/php-web-application-security"/>
    <id>https://jamesgalley.com/writing/php-web-application-security</id>
    <updated>2026-07-13T20:27:34+01:00</updated>
    <published>2018-04-23T00:00:00.000Z</published>
    <category term="Security"/>
    <category term="DevOps"/>
    <summary>Essential security practices for PHP web applications, including OWASP guidelines, DevOps security, and regular maintenance.</summary>
    <author><name>James Galley</name></author>
  </entry>
  <entry>
    <title>Replacing Excel spreadsheets with web applications</title>
    <link rel="alternate" href="https://jamesgalley.com/writing/replacing-excel-spreadsheets-with-web-applications"/>
    <id>https://jamesgalley.com/writing/replacing-excel-spreadsheets-with-web-applications</id>
    <updated>2026-08-04T22:58:03+01:00</updated>
    <published>2018-01-13T00:00:00.000Z</published>
    <category term="Business operations"/>
    <category term="Web applications"/>
    <category term="AI"/>
    <summary>Why businesses replace spreadsheet processes with web applications, updated for the AI era - and what the data those spreadsheets hold is now worth.</summary>
    <author><name>James Galley</name></author>
  </entry>
</feed>
