FreeLattice · Celeste reading home

Public, free to read, reuse, and adapt — Kirk Patrick Miller's notice for this edition. Not a patent grant.

Public work excerpts — privacy boundaries marked · c03

f78bcc9b01 · words 1532 · characters 23239–35488

Previous section · Next section

Exact section text · Full source · Source index

Archive pages whose extracted text matched this section: 1206, 1207, 1208, 1209. Unmatched pages stay on the source record with the checked page method. They are not guessed into a section.

No topic tag was earned for this page under the recorded evidence rule.

// ── Project root and path lock ──
var PROJECT_ROOT_REAL = null;
function projectRootReal() {
  if (!PROJECT_ROOT_REAL) {
    var wanted = path.resolve(process.env.FL_PROJECT || process.cwd());
    try { PROJECT_ROOT_REAL = fs.realpathSync(wanted); } catch (e) { PROJECT_ROOT_REAL = wanted; }
  }
  return PROJECT_ROOT_REAL;
}

## Exact source excerpt, characters 20818–21002

function isInside(root, candidate) {
  var rel = path.relative(root, candidate);
  return rel === '' || (!(rel === '..' || rel.startsWith('..' + path.sep)) && !path.isAbsolute(rel));
}

## Exact source excerpt, characters 21004–22564

const BRIDGE_FORBIDDEN_TOP = ['.git', '.ssh'];
function lockedPath(relPath, opts) {
  opts = opts || {};
  if (typeof relPath !== 'string' || !relPath || relPath.length > 1024 || hasControlChars(relPath)) {
    return { error: 400, reason: 'bad-path' };
  }
  if (path.isAbsolute(relPath) || /^[a-zA-Z]:/.test(relPath) || relPath.charAt(0) === '\\') {
    return { error: 403, reason: 'absolute-path' };
  }
  var root = projectRootReal();
  var full = path.resolve(root, relPath);
  if (!isInside(root, full)) return { error: 403, reason: 'outside-project' };
  var rel = path.relative(root, full);
  var top = rel.split(path.sep)[0];
  if (!opts.allowRoot && rel === '') return { error: 400, reason: 'root-not-allowed' };
  if (BRIDGE_FORBIDDEN_TOP.indexOf(top) !== -1 || /^\.env(\.|$)/.test(path.basename(rel))) {
    return { error: 403, reason: 'forbidden-path' };
  }
  // Realpath the nearest existing ancestor (or the file itself) so a
  // symlink inside the project cannot point writes outside it.
  var probe = full;
  for (;;) {
    try { fs.lstatSync(probe); break; }
    catch (e) {
      if (e.code !== 'ENOENT') return { error: 403, reason: 'stat-failed' };
      var up = path.dirname(probe);
      if (up === probe) return { error: 403, reason: 'no-ancestor' };
      probe = up;
    }
  }
  var real;
  try { real = fs.realpathSync(probe); } catch (e) { return { error: 403, reason: 'dangling-symlink' }; }
  if (!isInside(root, real)) return { error: 403, reason: 'symlink-outside' };
  return { full: full, rel: rel === '' ? '.' : rel };
}

## Exact source excerpt, characters 22566–22724

function runGit(args) {
  return execFileSync('git', args, { cwd: projectRootReal(), encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'], timeout: 30000 });
}

## Exact source excerpt, characters 22726–23143

function runSmokeFile(timeoutMs) {
  // No shell: node binary + fixed script path. stdout and stderr joined.
  var r = spawnSync(process.execPath, ['tests/smoke.js'], {
    cwd: projectRootReal(), timeout: timeoutMs, encoding: 'utf8', maxBuffer: 64 * 1024 * 1024
  });
  return { status: r.status, out: String(r.stdout || '') + String(r.stderr || ''), error: r.error };
}
// ── end LAYER bridge-lock-v0 helpers ──
```

## Exact source excerpt, characters 23145–23193

### Block B: `handleRequest` (replaces L111-129)

## Exact source excerpt, characters 23195–23561

```js
function handleRequest(req, res) {
  // LAYER bridge-lock-v0: the old `Access-Control-Allow-Origin: *` is superseded here.
  var origin = req.headers.origin || '';
  var pathname = String(req.url || '/').split('?')[0];
  res.setHeader('Content-Type', 'application/json');
  res.setHeader('Vary', 'Origin');
  res.setHeader('X-Content-Type-Options', 'nosniff');

## Exact source excerpt, characters 23563–23782

  // 1. Host guard (DNS rebinding): only 127.0.0.1 / localhost.
  if (!hostAllowed(req.headers.host)) {
    req.resume();
    return respond(res, 403, { error: 'Host not allowed', bridgeLock: BRIDGE_LOCK_VERSION });
  }

## Exact source excerpt, characters 23784–24743

  // 2. Origin guard. Browsers always send Origin on cross-origin fetches and
  //    preflights. No Origin = local CLI or same-machine tool (still needs
  //    the token for anything that changes state).
  if (origin && !originAllowed(origin)) {
    if (pathname === '/code/git/commit') {
      ledgerAppend({ route: pathname, origin: origin, result: 'refused:origin' });
    }
    req.resume();
    return respond(res, 403, { error: 'Origin not on the FreeLattice allowlist', bridgeLock: BRIDGE_LOCK_VERSION });
  }
  if (origin) {
    res.setHeader('Access-Control-Allow-Origin', origin);
    res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
    res.setHeader('Access-Control-Allow-Headers', 'Content-Type, X-Agent-Id, X-FL-Bridge-Token');
    res.setHeader('Access-Control-Max-Age', '600');
    if (req.headers['access-control-request-private-network']) {
      res.setHeader('Access-Control-Allow-Private-Network', 'true');
    }
  }

## Exact source excerpt, characters 24745–24833

  if (req.method === 'OPTIONS') { req.resume(); res.writeHead(204); res.end(); return; }

## Exact source excerpt, characters 24835–25217

  // 3. Token guard.
  if (needsToken(req.method, pathname) && !tokenOk(req)) {
    if (pathname === '/code/git/commit') {
      ledgerAppend({ route: pathname, origin: origin, result: 'refused:token' });
    }
    req.resume();
    return respond(res, 401, { error: 'Pair with the Agent Bridge first (token missing or stale).', pair: 'code', bridgeLock: BRIDGE_LOCK_VERSION });
  }

## Exact source excerpt, characters 25219–25356

  // Allow requests to act as a different agent via X-Agent-Id header
  var requestAgentId = req.headers['x-agent-id'] || agentId.meshId;

## Exact source excerpt, characters 25358–26237

  // 4. Body cap. Drain the rest so the client sees the 413 cleanly.
  var chunks = [];
  var size = 0;
  var tooBig = false;
  req.on('data', function(chunk) {
    size += chunk.length;
    if (size > MAX_BODY_BYTES) { tooBig = true; chunks = []; return; }
    if (!tooBig) chunks.push(chunk);
  });
  req.on('end', function() {
    if (tooBig) return respond(res, 413, { error: 'Body too large (max ' + MAX_BODY_BYTES + ' bytes)' });
    var body = Buffer.concat(chunks).toString('utf8');
    var data = {};
    if (body) {
      try { data = JSON.parse(body); }
      catch (e) { return respond(res, 400, { error: 'Body is not valid JSON' }); }
      if (!data || typeof data !== 'object' || Array.isArray(data)) return respond(res, 400, { error: 'Body must be a JSON object' });
    }
    route(req.url, req.method, data, res, requestAgentId, { origin: origin });
  });
}
```

## Exact source excerpt, characters 26239–26286

### Block C: pairing routes (insert after L133)

## Exact source excerpt, characters 26288–27643

```js
  // ── LAYER bridge-lock-v0: pairing ──
  if (url === '/pair' && method === 'POST') {
    var now = Date.now();
    if (!pairState.code || now > pairState.expires) newPairCode('expired');
    if (now < pairState.coolUntil) return respond(res, 429, { error: 'Resting for a moment. Try again in 30 seconds.' });
    var given = normalizePairCode(data.code);
    var good = given.length === 6 &&
      crypto.timingSafeEqual(Buffer.from(given, 'utf8'), Buffer.from(pairState.code, 'utf8'));
    if (!good) {
      pairState.tries += 1;
      if (pairState.tries >= PAIR_MAX_TRIES) {
        ledgerAppend({ kind: 'pair', route: '/pair', origin: (meta && meta.origin) || '', result: 'refused:lockout' });
        newPairCode('lockout');
        return respond(res, 429, { error: 'Too many tries. The bridge window shows a new code.' });
      }
      return respond(res, 403, { error: 'That code does not match. Check the bridge window.', triesLeft: PAIR_MAX_TRIES - pairState.tries });
    }
    ledgerAppend({ kind: 'pair', route: '/pair', origin: (meta && meta.origin) || '', result: 'ok' });
    console.log('  \u2726 Paired with ' + ((meta && meta.origin) || 'a local tool') + '.');
    newPairCode('used'); // single use: the next device gets a fresh code
    return respond(res, 200, { token: BRIDGE_TOKEN, bridgeLock: BRIDGE_LOCK_VERSION });
  }

## Exact source excerpt, characters 27645–27760

  if (url === '/pair/check') {
    return respond(res, 200, { ok: true, bridgeLock: BRIDGE_LOCK_VERSION });
  }
```

## Exact source excerpt, characters 27762–27807

### Block D: code routes (replaces L992-1140)

## Exact source excerpt, characters 27809–28239

```js
  // ══════════════════════════════════════════════════
  // LATTICE CODE — Self-improving infrastructure
  // Read and search are free. Write/patch/commit need approval.
  // LAYER bridge-lock-v0: every route below is token-gated in
  // handleRequest (needsToken). Paths go through lockedPath().
  // No shell anywhere: execFileSync / spawnSync with argument arrays.
  // ══════════════════════════════════════════════════

## Exact source excerpt, characters 28241–28280

  var PROJECT_ROOT = projectRootReal();

## Exact source excerpt, characters 28282–28489

  // Superseded by lockedPath (bridge-lock-v0). Kept so old callers still work.
  function safePath(relPath) {
    var lp = lockedPath(relPath, { allowRoot: true });
    return lp.error ? null : lp.full;
  }

## Exact source excerpt, characters 28491–29530

  // GET /code/tree — list project files
  if (url.startsWith('/code/tree')) {
    var tp = new URL('http://l' + url).searchParams;
    var subdir = tp.get('path') || '.';
    var target = safePath(subdir);
    if (!target) return respond(res, 403, { error: 'Path outside project' });
    try {
      function listDir(dir, depth) {
        if (depth > 3) return [];
        return fs.readdirSync(dir, { withFileTypes: true })
          .filter(function(e) { return !e.name.startsWith('.') && e.name !== 'node_modules' && !e.isSymbolicLink(); })
          .map(function(e) {
            var rel = path.relative(PROJECT_ROOT, path.join(dir, e.name));
            if (e.isDirectory()) return { name: e.name, type: 'dir', path: rel, children: listDir(path.join(dir, e.name), depth + 1) };
            return { name: e.name, type: 'file', path: rel, size: fs.statSync(path.join(dir, e.name)).size };
          });
      }
      return respond(res, 200, listDir(target, 0));
    } catch(e) { return respond(res, 500, { error: e.message }); }
  }

## Exact source excerpt, characters 29532–30424

  // GET /code/read?path=...&start=N&end=N
  if (url.startsWith('/code/read')) {
    var rp = new URL('http://l' + url).searchParams;
    var filePath = rp.get('path');
    var start = parseInt(rp.get('start') || '0', 10);
    var end = parseInt(rp.get('end') || '0', 10);
    var full = safePath(filePath);
    if (!full) return respond(res, 403, { error: 'Path outside project' });
    try {
      var content = fs.readFileSync(full, 'utf8');
      var lines = content.split('\n');
      if (start > 0 || end > 0) {
        return respond(res, 200, { path: filePath, lines: lines.slice(Math.max(0, start - 1), end || lines.length), start: start, end: end || lines.length, totalLines: lines.length });
      }
      return respond(res, 200, { path: filePath, content: content, totalLines: lines.length });
    } catch(e) { return respond(res, 404, { error: 'Not found: ' + filePath }); }
  }

## Exact source excerpt, characters 30426–31609

  // GET /code/search?q=...&path=docs/
  if (url.startsWith('/code/search')) {
    var sp = new URL('http://l' + url).searchParams;
    var query = sp.get('q') || '';
    var searchLp = lockedPath(sp.get('path') || 'docs', { allowRoot: true });
    if (searchLp.error) return respond(res, searchLp.error, { error: 'Search path refused', reason: searchLp.reason });
    if (!query || query.length > 200 || hasControlChars(query)) return respond(res, 400, { error: 'q must be 1-200 printable characters' });
    try {
      var out = execFileSync('grep', ['-rn', '--include=*.js', '--include=*.html', '--include=*.css', '--include=*.md',
        '-e', query, '--', searchLp.rel], { cwd: PROJECT_ROOT, timeout: 10000, encoding: 'utf8',
        maxBuffer: 32 * 1024 * 1024, stdio: ['ignore', 'pipe', 'ignore'] });
      var matches = out.split('\n').filter(Boolean).slice(0, 50).map(function(l) { var p = l.split(':'); return { file: p[0], line: parseInt(p[1], 10), text: p.slice(2).join(':').trim() }; });
      return respond(res, 200, { query: query, matches: matches, count: matches.length });
    } catch(e) { return respond(res, 200, { query: query, matches: [], count: 0 }); }
  }

## Exact source excerpt, characters 31611–32407