Agents
PHP Memory + Consequence
Install the PHP 8.2+ SDK and enable cURL:
composer require neutron-ai/sdk
The SDK handles memory and agent context. The helper calls industry-library and Consequence endpoints that are not yet exposed as typed PHP methods.
Client and authenticated REST helper
<?php
declare(strict_types=1);
use NeutronAI\NeutronAIClient;
const NUCLEUS_ID = 'checkout-platform';
function requiredEnv(string $name): string
{
$value = getenv($name);
if ($value === false || trim($value) === '') {
throw new RuntimeException("{$name} is required");
}
return $value;
}
function scoped(array $body): array
{
return ['nucleusId' => NUCLEUS_ID, ...$body];
}
function neutronRequest(string $token, string $path, array $body): array
{
$curl = curl_init(rtrim(requiredEnv('NEUTRON_API_URL'), '/') . $path);
if ($curl === false) {
throw new RuntimeException('Unable to initialize cURL');
}
curl_setopt_array($curl, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => [
'authorization: Bearer ' . $token,
'content-type: application/json',
],
CURLOPT_POSTFIELDS => json_encode($body, JSON_THROW_ON_ERROR),
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
]);
$raw_body = curl_exec($curl);
$status = (int) curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
$error = curl_error($curl);
curl_close($curl);
if ($raw_body === false) {
throw new RuntimeException($error ?: 'Neutron request failed');
}
$decoded = json_decode($raw_body, true, flags: JSON_THROW_ON_ERROR);
if ($status >= 400 || !is_array($decoded)) {
throw new RuntimeException("Neutron request failed with HTTP {$status}");
}
return $decoded;
}
$memory = new NeutronAIClient(
base_url: requiredEnv('NEUTRON_API_URL'),
token: requiredEnv('NEUTRON_API_TOKEN'),
nucleus_id: NUCLEUS_ID,
);
Keep workspace, approver, and internal credentials outside the agent runtime.
Install knowledge and remember reviewed history
neutronRequest(
requiredEnv('NEUTRON_WORKSPACE_API_KEY'),
'/v1/platform/industry-library/plugins/ai-engineering-delivery/install',
['nucleusId' => NUCLEUS_ID],
);
$memory->remember([
'scopeId' => 'history:checkout-releases',
'agentId' => 'agent:release-manager',
'type' => 'experience',
'privacyClass' => 'tenant',
'text' => implode(' ', [
'Release 3.7 used a 5% cohort for 20 minutes before expansion.',
'The rollout paused when database lock time exceeded 250 ms.',
'Rollback succeeded. Verify lock duration before expanding similar changes.',
]),
'metadata' => [
'source' => 'approved-release-review',
'release' => '3.7',
'outcome' => 'rolled-back',
],
]);
$context = $memory->agentContext([
'scopeIds' => [
'industry:ai-engineering-delivery',
'service:checkout-api',
'history:checkout-releases',
'policy:production-change',
],
'agentId' => 'agent:release-manager',
'task' => 'Prepare a safe release recommendation for checkout API version 3.8.',
'privacyClasses' => ['tenant'],
'tokenBudget' => 1_600,
'cachePolicy' => [
'mode' => 'prefer_cache',
'keyMode' => 'intent_profile',
'ttlSeconds' => 300,
'includeDynamicRag' => true,
],
]);
Treat $context['promptContext'] as supporting context. Current evidence and the current task remain primary.
Plan and record the decision
$agent_token = requiredEnv('NEUTRON_API_TOKEN');
$decision_scopes = [
'industry:ai-engineering-delivery',
'service:checkout-api',
'history:checkout-releases',
'policy:production-change',
];
$run = neutronRequest($agent_token, '/v1/consequence/plan', scoped([
'scopeIds' => $decision_scopes,
'agentId' => 'agent:release-manager',
'task' => implode(' ', [
'Compare delaying release 3.8, a 1% pilot, a 5% staged rollout,',
'and immediate release while preserving compatibility and the lock budget.',
]),
'domain' => 'engineering_ops',
'objectiveHints' => [
'Reduce customer impact',
'Preserve rollback capability',
'Collect evidence before expansion',
],
'constraintHints' => [
'Database lock time must remain below the approved threshold',
'Expansion requires the accountable release owner',
'Rollback must remain available',
],
'idempotencyKey' => 'checkout-3.8-release-review-v1',
'retentionDays' => 90,
'contextPolicy' => [
'includeMemory' => true,
'includeKnowledge' => true,
'includeContextCapsules' => true,
'includePastDecisions' => true,
'includeReflections' => true,
],
'policy' => [
'mode' => 'deep',
'depth' => 10,
'maxScenarios' => 8,
'maxRuntimeMs' => 8_000,
'requireApprovalAboveRisk' => 'medium',
'allowExecution' => false,
'storeSafeArtifactsOnly' => true,
'includeCounterfactuals' => true,
'includeReflections' => true,
],
]));
$scenario_id = $run['recommendedScenarioId'] ?? null;
if (!is_string($scenario_id) || $scenario_id === '') {
throw new RuntimeException('No scenario satisfied the current decision boundary');
}
$decided = neutronRequest($agent_token, '/v1/consequence/decide', scoped([
'runId' => $run['runId'],
'scopeIds' => ['service:checkout-api', 'policy:production-change'],
'selectedScenarioId' => $scenario_id,
'decisionSummary' => 'Selected the bounded pilot scenario for owner review.',
'rationaleSummary' => implode(' ', [
'The pilot preserves rollback and gathers current lock-duration evidence.',
'Expansion remains conditional on the threshold and owner review.',
]),
]));
$decision = $decided['decisionRecord'] ?? null;
if (!is_array($decision)) {
throw new RuntimeException('The decision record was not created');
}
if (($decision['status'] ?? null) === 'draft') {
neutronRequest(
requiredEnv('NEUTRON_APPROVER_TOKEN'),
'/v1/consequence/approve',
scoped([
'decisionId' => $decision['decisionId'],
'scopeIds' => ['service:checkout-api', 'policy:production-change'],
'note' => 'Release owner approved the pilot only; expansion needs another review.',
]),
);
}
Use the approver token only after verifying the authenticated human's role, scope, and current intent. Approval does not execute the release.
Observe and reflect
After the application performs the separately authorized pilot:
neutronRequest($agent_token, '/v1/consequence/observe', scoped([
'decisionId' => $decision['decisionId'],
'scopeIds' => ['service:checkout-api', 'history:checkout-releases'],
'summary' => 'The 1% pilot completed without customer errors and was held for review.',
'observedMetrics' => [
'pilot_percent' => 1,
'pilot_minutes' => 30,
'database_lock_p95_ms' => 180,
'customer_error_rate' => 0,
],
'unexpectedConsequences' => [
'Cache warm-up took ten minutes longer than estimated.',
],
'sourceRefs' => [
'release-run:checkout-3.8-pilot',
'dashboard:database-locks-2026-08-15',
],
]));
$reflected = neutronRequest(
requiredEnv('NEUTRON_INTERNAL_TOKEN'),
'/v1/consequence/reflect',
scoped([
'decisionId' => $decision['decisionId'],
'scopeIds' => ['service:checkout-api', 'history:checkout-releases'],
]),
);
$lessons = $reflected['reflectionLessons'] ?? [];
$lesson = $lessons === [] ? null : $lessons[array_key_last($lessons)];
Review the lesson before any durable memory promotion.
Return to the shared lifecycle and production checklist.