1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
<?php
// api/debug/agent-replies.php — outbound half of the maintenance thread.
// Hermes (or the operator) writes replies here; the in-page agent reads them with
// `feedback-inbox`. nginx gates this path behind the WebX11 admin session, so it is
// owner-only: never expose it in the public debug/course location block.
require_once __DIR__ . '/config.php';
define('REPLIES_DIR', __DIR__ . '/../../data/maintenance');
define('REPLIES_FILE', REPLIES_DIR . '/replies.json');
if (!is_dir(REPLIES_DIR)) {
@mkdir(REPLIES_DIR, 0775, true);
@chgrp(REPLIES_DIR, 'www-data');
}
$method = $_SERVER['REQUEST_METHOD'];
if ($method === 'GET') {
$since = $_GET['since'] ?? null;
$all = load_json(REPLIES_FILE);
if (!is_array($all)) $all = [];
if ($since) {
$all = array_values(array_filter($all, fn($r) => ($r['created_at'] ?? '') > $since));
}
json_response(['success' => true, 'replies' => array_slice($all, -100)]);
}
if ($method !== 'POST') {
error_response('Method not allowed', 405);
}
// v4.6.71: retired. Two write paths meant two truths — messages written here never
// reached the chat thread, so they looked like a conversation nobody answered.
// One write path now: /api/chat/post.php (contract: _docs/chat-contract.md).
http_response_code(410);
header('Content-Type: application/json');
echo json_encode([
'success' => false,
'code' => 'gone',
'error' => 'POST /api/debug/agent-replies.php is retired',
'use' => '/spaces/newos4/api/chat/post.php',
'contract'=> '/spaces/newos4/_docs/chat-contract.md',
'read' => '/spaces/newos4/api/chat/poll.php',
]);
exit;
|