← back to Sample Followup Sweep
lib/george-transport.js
57 lines
'use strict';
const http = require('node:http');
const { assertPreSendCompliance, REQUIRED_FROM } = require('./pre-send-gate');
const SENDABLE_PATHS = new Set(['/api/send', '/api/drafts']);
function assertSendablePayload(payload) {
assertPreSendCompliance({
from: payload?.account === 'info' ? REQUIRED_FROM : '',
subject: payload?.subject,
body: payload?.body,
});
return payload;
}
function createGmailDraftArtifact(payload) {
return assertSendablePayload(payload);
}
// TK-11409: strip George's internal provenance banner from every vendor-facing message.
// George's withSourceFooter() prepends a visible "From job: node · <timestamp>" block INSIDE the
// message body unless the caller passes no_source_tag. Nothing in this pipeline was passing it, so
// that banner shipped to vendors on every chase — verified present in the drafts AND in chases
// already SENT on 09/01 and 09/04. Every path through this transport is a vendor-facing letter
// (/api/send and /api/drafts are the only sendable paths), so the flag belongs HERE rather than at
// each of the four call sites: a per-caller flag is a step someone must remember, and this ticket
// is a catalogue of what happens when a safety step depends on being remembered.
function stripSourceBanner(payload) {
if (payload && typeof payload === 'object' && payload.no_source_tag === undefined) {
payload.no_source_tag = true;
}
return payload;
}
async function georgeRequest({ path, payload, headers = {}, requestImpl = http.request }) {
if (!SENDABLE_PATHS.has(path)) throw new Error(`Unsupported sendable George path: ${path}`);
assertSendablePayload(payload); // Must run before serialization, credential reads, or network setup.
stripSourceBanner(payload);
const body = JSON.stringify(payload);
return new Promise((resolve) => {
const req = requestImpl({
host: '127.0.0.1', port: 9850, path, method: 'POST',
headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(body), ...headers },
}, (response) => {
let responseBody = '';
response.on('data', (chunk) => { responseBody += chunk; });
response.on('end', () => resolve({ statusCode: response.statusCode || 0, body: responseBody }));
});
req.on('error', (error) => resolve({ statusCode: 0, body: error.message }));
req.write(body);
req.end();
});
}
module.exports = { assertSendablePayload, createGmailDraftArtifact, georgeRequest, stripSourceBanner, SENDABLE_PATHS };