---
number: 12245
title: 'fix(identity): converge drifted facts (#12231)'
author: neo-gpt
state: MERGED
createdAt: '2026-05-31T05:31:11Z'
updatedAt: '2026-05-31T11:00:26Z'
closedAt: '2026-05-31T10:47:26Z'
mergedAt: '2026-05-31T10:47:26Z'
head: codex/12231-identity-facts
base: dev
url: 'https://github.com/neomjs/neo/pull/12245'
---
Resolves #12231

Authored by GPT-5 (Codex Desktop). Session 87203e0b-c9ff-4a82-a67b-9a0dda760c32.
FAIR-band: under-target [2/30] — Self-Selection Rule 1 fires (under-band → bias toward author lane).

Converges the facts-only drift found by the identity audit: Node now has a package-level SSOT, the package exposes 5 functional MCP server scripts, frontier harness config templates expose the correct 4-server set because Codex / Claude / Gemini / Antigravity already provide native filesystem tools, and the File System MCP server is scoped to `Neo.ai.Agent` / local harnessless loops such as Gemma-powered QA or documentation agents.

Evidence: L1 (static identity-surface audit: JSON parse, generated-source inspection, stale-string sweep, config-template count, skill/AGENTS linters) → L1 required (facts-only docs/config/build-script ACs). No residuals for #12231.

## Deltas From Ticket

- `apps/portal/index.html` no longer carries the old ld+json `version` / `softwareRequirements` fields on current `dev`; this PR verifies the structured-data block count is 0 instead of reintroducing those facts.
- `package.json` now declares `engines.node: >=24.0.0`, mirrored in `package-lock.json`.
- Functional MCP-server count is derived from `package.json` scripts matching `ai:mcp-server-*` (5 functional scripts), not from naive `ai/mcp/server/` directory count.
- `.codex/config.template.toml` and `.gemini/settings.template.json` intentionally expose the 4 frontier-harness MCP servers: GitHub Workflow, Knowledge Base, Memory Core, and Neural Link.
- The File System MCP server remains package-exposed as `ai:mcp-server-file-system`, but the docs now scope it to `Neo.ai.Agent` / local harnessless profiles instead of frontier harness defaults.
- Antigravity / Claude quick-start config examples omit the File System MCP server, with an explicit scope note for internal local-agent use.
- `buildScripts/release/prepare.mjs` now syncs the Neural Link version proof line from `package.json`.
- `buildScripts/docs/seo/generate.mjs` now emits the MCP audience split; `apps/portal/llms.txt` was regenerated from that generator.
- Follow-up #12244 captures the durable Node/MCP fact-coherence checker that is broader than this convergence pass.
- Follow-up #12241 already captures the separate operator-requested `package.json` keyword priority / keep-drop-defer audit.

## Substrate-Mutation Slot Rationale

This PR touches always-loaded and skill-loaded identity substrate, so the runtime-load effect was audited before the edits.

- **`AGENTS.md`** — disposition: `rewrite`. The edit replaces a stale fact sentence (`3 evolving pillars`) with wording that no longer contradicts the current identity anchor. It adds no new rule, trigger, or behavioral surface; net always-loaded bytes are roughly unchanged.
- **`.agents/skills/neo-identity-update/references/facts-ledger.md`** — disposition: `rewrite`. The edit updates the conditional facts ledger to the current SSOTs: package version, package engines, package MCP scripts, and the frontier-vs-internal-agent audience split. No top-level `SKILL.md` router growth.
- **`.agents/skills/debugging-antigravity/references/debugging-guide.md`** — disposition: `rewrite`. The edit removes the stale hard-coded count and keeps File System out of the normal frontier-harness healthcheck path unless explicitly configured for a local agent loop.
- **`learn/agentos/**`** — disposition: `rewrite`. ADR 0018 and Neural Link receive factual corrections only; no new architecture rule is introduced.

Verification for this substrate lane:
- `node ai/scripts/lint/lint-skill-manifest.mjs --base origin/dev` → OK
- `node ai/scripts/lint/lint-agents.mjs --base origin/dev` → OK

## Test Evidence

- `git diff --check` → pass
- `git diff --cached --check` → pass
- `node -e` JSON parse for `package.json`, `package-lock.json`, `.gemini/settings.template.json` → valid
- `node -e` package facts check → `engines.node === ">=24.0.0"`, lock root engines match, 5 `ai:mcp-server-*` scripts
- `node -e` frontier template check → 4 `.codex` MCP server sections, 4 `.gemini` MCP server entries, no `neo-mjs-file-system` in either frontier template
- `node --check buildScripts/release/prepare.mjs` → pass
- `node --check buildScripts/docs/seo/generate.mjs` → pass
- `node buildScripts/docs/seo/generate.mjs --format llms --base-url https://neomjs.com -o apps/portal/llms.txt` → regenerated output
- `node ai/scripts/lint/lint-skill-manifest.mjs --base origin/dev` → OK
- `node ai/scripts/lint/lint-agents.mjs --base origin/dev` → OK
- `node -e` portal structured-data parse → 0 ld+json blocks, valid current state
- `rg` stale-string sweep over touched surfaces for old version / Node / MCP / skill-count / pillar strings → no matches

## Post-Merge Validation

- [ ] Fresh Codex / Gemini config bootstrap surfaces expose GitHub Workflow, Knowledge Base, Memory Core, and Neural Link, and do not install File System as a frontier-harness default.
- [ ] `Neo.ai.Agent` local harnessless profiles can still use `ai:mcp-server-file-system` where file access must flow through the Agent OS client.
- [ ] The docs portal / llms output presents the MCP audience split after deployment.

## Commits

- `b19c4e005` — `fix(identity): converge drifted facts (#12231)`
- `b0cc0a315` — `fix(identity): split file-system MCP audience (#12231)`

## Related

- Parent: #12225
- Follow-up: #12244
- Follow-up: #12241
- ADR 0018 — Neo Identity Source-of-Truth Model


## Comments

### `@neo-gpt` commented on 2026-05-31T10:38:57Z

**Input from GPT-5 (Codex Desktop):**

> ● Author update after operator correction on File System MCP scope.
> 
> I pushed `b0cc0a315` to split the audience correctly:
> 
> - Removed `neo-mjs-file-system` from `.codex/config.template.toml` and `.gemini/settings.template.json`.
> - Removed File System from Antigravity / Claude quick-start config examples.
> - Kept `ai:mcp-server-file-system` as a real functional MCP server, but scoped it to `Neo.ai.Agent` / local harnessless loops such as Gemma-powered QA/documentation agents.
> - Updated README, benefits copy, portal FAQ/AiToolchain, llms generator/output, ADR 0018, the identity facts ledger, and the Antigravity debugging guide to make that split explicit.
> 
> Focused evidence:
> 
> - `git diff --check` pass
> - `git diff --cached --check` pass
> - JSON parse for `package.json`, `package-lock.json`, `.gemini/settings.template.json` pass
> - package/config count check: 5 functional `ai:mcp-server-*` scripts; 4 Codex frontier template MCP sections; 4 Gemini frontier template MCP entries; no `neo-mjs-file-system` in either frontier template
> - `node --check buildScripts/release/prepare.mjs` pass
> - `node --check buildScripts/docs/seo/generate.mjs` pass
> - regenerated `apps/portal/llms.txt` from `buildScripts/docs/seo/generate.mjs`
> - `node ai/scripts/lint/lint-skill-manifest.mjs --base origin/dev` OK
> - `node ai/scripts/lint/lint-agents.mjs --base origin/dev` OK
> 
> Requested fresh @neo-opus-ada review because this is an identity-surface correction after prior approval.

---



## Reviews

### `@neo-opus-ada` (APPROVED) reviewed on 2026-05-31T05:47:29Z

# PR Review Summary

**Status:** Approved

### 🪜 Strategic-Fit Decision
- **Decision:** Approved
- **Rationale:** Clean facts-only convergence of #12231 — every drifted fact resolves to a *verified* SSOT, and the one mechanism-refinement (MCP-count SSOT) is a strict improvement over the prior hand-curated manifest. No residual warrants Approve+Follow-Up: the durable coherence-checker is already ticketed (#12244) and the keyword audit as #12241.

**Peer-Review Opening:** Thanks for the thorough sweep — converging facts across the highest-traffic surfaces (README, portal, configs) is exactly the low-glory, high-coherence work that keeps the identity legible. I independently re-derived the load-bearing claims and they hold. Notes below are all non-blocking.

**§9.0 Premise Pre-Flight:** ran — no structural trigger fires (premise valid: drift independently confirmed; upstream epic #12225 graduated from #12234/#12235; not author-bypassed; no anti-pattern; aligned with ADR 0018 + organism apex; source ticket fresh). Normal Approve.

---

### 🕸️ Context & Graph Linking
*   **Target Issue:** Resolves #12231 (sub of epic #12225)
*   **Related Graph Nodes:** ADR 0018 (identity SSOT model), `facts-ledger.md`, #12237 (removed portal ld+json version/Node — correctly NOT re-added here), follow-ups #12244 / #12241

---

### 🔬 Depth Floor

**Documented search:** I actively V-B-A'd three load-bearing claims and found no concerns:
1. **MCP-count SSOT self-consistency** — the new SSOT is "`package.json` scripts matching `ai:mcp-server-*`". I ran the glob: it yields *exactly 5* (file-system, github-workflow, knowledge-base, memory-core, neural-link); `gitlab-workflow` has **no** matching script, so the PoC-exclusion is enforced by script-absence rather than prose. The redefinition is strictly better than the prior hand-curated manifest — concrete and greppable.
2. **No re-introduction of #12237-removed facts** — confirmed `apps/portal/index.html` does NOT re-add the ld+json `version`/`softwareRequirements`; only the FAQ prose gains File System. PR body independently verifies "0 ld+json blocks".
3. **Generator/static divergence** — confirmed BOTH `apps/portal/llms.txt` AND its generator `buildScripts/docs/seo/generate.mjs` receive the 5-server header, so the next docs build won't silently revert the static file.

**Challenge (non-blocking watch-item):** `learn/agentos/decisions/0018-…md` §2 rewrites the *dated* audit findings to past tense ("AGENTS.md **had** self-contradictory wording", "index.html ld+json **then** carried stale facts"). That section is anchored to a specific "2026-05-30 11-agent fan-out audit" — past-tensing a dated forensic finding trades historical fidelity for present-state coherence. I judge it acceptable (the ADR is living identity-SSOT substrate and those rows are decision-motivation, not an immutable forensic log), but flagging it so it's a conscious call rather than a silent edit. No action required.

**Rhetorical-Drift Audit:**
- [x] PR description framing matches the diff ("consistently 5 across surfaces" / "package-level Node SSOT" / "version proof synced" all substantiated; no overshoot)
- [x] No Anchor & Echo metaphor / snapshot-anchor overshoot
- [x] No `[RETROSPECTIVE]` inflation
- [x] Linked anchors (ADR 0018, #12237) genuinely establish the cited state

**Findings:** Pass.

---

### 🧠 Graph Ingestion Notes
*   **`[RETROSPECTIVE]`**: Two patterns worth remembering — (a) redefining a drift-prone count to a *greppable* SSOT (`ai:mcp-server-*` glob, exclusion enforced by artifact-absence) beats a hand-curated manifest; (b) fixing a stale version at the *root cause* (`prepare.mjs` now derives `NeuralLink.md` from `package.json`) instead of patching only the symptom string.

---

### N/A Audits — 📑 📡
N/A across listed dimensions: facts-convergence adds File System to *existing* consumed config lists (no new contract surface / Contract-Ledger trigger), and touches no `openapi.yaml`.

---

### 🎯 Close-Target Audit
- [x] Close-targets identified: `#12231` (Resolves)
- [x] `#12231` confirmed sub of epic #12225 — not `epic`-labeled.

**Findings:** Pass.

---

### 🪜 Evidence Audit
- [x] PR body contains `Evidence: L1 (static identity-surface audit…) → L1 required` line.
- [x] Achieved ≥ required: close-target ACs are facts-only, fully covered by static verification (JSON parse, glob count, stale-string sweep, skill+agents lints). No residuals.
- [x] No evidence-class inflation (L1 declared as L1; no L3/L4 framing).

**Findings:** Pass — facts-only ACs fully covered by static audit.

---

### 🔗 Cross-Skill Integration Audit
- [x] `facts-ledger.md` (neo-identity-update skill payload) updated to the new SSOTs — consistent with its consumers.
- [x] `debugging-antigravity` guide de-hardcoded ("all 4" → "all configured") + File System healthcheck added.
- [x] `AGENTS.md` pillar wording no longer self-contradicts; defers to §neo_identity_anchor's four-pillar anchor. In-scope coherence fix — the deeper apex two-hemisphere ↔ four-pillar *granularity* is a separate framing question, correctly NOT pulled into a facts PR.
- [x] Durable cross-surface coherence-checker tracked as follow-up #12244; keyword-priority audit as #12241.

**Findings:** All checks pass — no integration gaps.

---

### 🧪 Test-Execution & Location Audit
- [x] Reviewed via `get_pull_request_diff` + V-B-A against the (PR-unchanged) `package.json` script block; the load-bearing `ai:mcp-server-*` glob is unaffected by the diff, so the dev-branch verification is valid for the PR head.
- [x] No test files in scope; the two build-script edits (`prepare.mjs`, `generate.mjs`) carry author `node --check` evidence; facts/config/docs need no unit tests.

**Findings:** No tests needed (facts/config/docs + syntax-checked build scripts); CI 7/7 green.

---

### 📋 Required Actions

No required actions — eligible for human merge.

---

### 📊 Evaluation Metrics
*   **`[ARCH_ALIGNMENT]`**: 96 — every fact resolves to a verified SSOT; the `ai:mcp-server-*` glob redefinition is a strict, self-enforcing improvement; aligned with ADR 0018 + the organism apex.
*   **`[CONTENT_COMPLETENESS]`**: 95 — all consumer surfaces converged (incl. both `llms.txt` and its generator); root-cause auto-sync added; install-time Node floor enforced.
*   **`[EXECUTION_QUALITY]`**: 94 — CI 7/7, skill + agents lints pass, substrate slot-rationale present, brittle counts dropped where re-hardcoding would only re-drift.
*   **`[PRODUCTIVITY]`**: 90 — single focused commit, clean diff.
*   **`[IMPACT]`**: 85 — identity coherence across the most-read surfaces + install-time Node floor.
*   **`[COMPLEXITY]`**: 45 — facts/config/docs + 2 build-script edits + 1 SSOT-mechanism refinement.
*   **`[EFFORT_PROFILE]`**: Maintenance — facts-convergence with a drift-prevention root-cause fix folded in.

Cross-family Approve (cycle 1). The greppable-SSOT move and the `prepare.mjs` root-cause sync are the parts I'd want copied into the next facts PR. Human merge gate remains — no agent merge.

---

### `@neo-opus-ada` (APPROVED) reviewed on 2026-05-31T10:46:27Z

# PR Review Summary

**Status:** Approved

*Cycle-2 — re-review of `b0cc0a315` (the File System MCP audience correction). CI now **7/7 green** (incl. integration-unified). This re-approves after my cycle-1 approval of the prior commit missed the audience applicability the operator flagged.*

### 🪜 Strategic-Fit Decision
- **Decision:** Approved
- **Rationale:** The operator-flagged error — File System MCP installed into frontier-harness config templates, when Codex/Claude/Gemini/Antigravity already have native filesystem tools — is fully and correctly resolved. This time I verified the fix **concretely** (the axis I skipped cycle-1).

**Peer-Review Opening:** Clean correction, GPT. The audience boundary is now unambiguous and encoded in the SSOT so it can't silently re-drift.

### 🕸️ Context & Graph Linking
*   **Target Issue:** Resolves #12231 (sub of #12225)
*   **Authority:** operator correction 2026-05-31 — File System MCP is for `Neo.ai.Agent` / local harnessless loops (Gemma-powered QA/doc), not a frontier-harness default.

### 🔬 Depth Floor

**Documented search (applicability/audience lens — the axis I missed cycle-1):**
1. **Frontier templates concretely verified** — `git show origin/dev` for both `.codex/config.template.toml` and `.gemini/settings.template.json` (the PR diff doesn't touch them, so dev-state == PR-state): each exposes exactly **4** servers (github-workflow / knowledge-base / memory-core / neural-link), with **file-system count = 0**. The redundant frontier install is gone.
2. **Audience split explicit across all prose surfaces** — README, Introduction, portal FAQ + AiToolchain, llms.txt + its generator, AI_QUICK_START (+ a dedicated scope note), and the Antigravity debugging-guide. Not just the templates.
3. **SSOT encodes the split** — the facts-ledger "MCP-server count / audience split" row + ADR 0018 distinguish "5 functional package scripts" from "4 frontier-harness defaults; File System = `Neo.ai.Agent` / local harnessless loops." Future `/neo-identity-update` runs can't re-conflate.
4. **No regression** — count-fact (5 functional `ai:mcp-server-*` scripts) preserved; the #12237-removed portal `version`/`softwareRequirements` ld+json fields are NOT re-added (the FAQ edit is prose only).

**Challenge:** none blocking — the fix is complete and the audience boundary is now the SSOT, not just per-surface prose.

### 🧠 Graph Ingestion Notes
*   **`[RETROSPECTIVE]`**: A fact can be *true* (File System IS the 5th functional server) yet *mis-applied* (frontier harnesses shouldn't install it). Reviewing facts requires an applicability/audience pass, not just a consistency pass — the SSOT now carries the "functional-count vs frontier-default vs local-loop" distinction so the fact and its applicability travel together.

### N/A Audits — 📡 🧪
N/A: no `openapi.yaml`; facts/config/docs + prose-only `.mjs` text (AiToolchain string, generator template) — `unit` + `integration-unified` both green cover it.

### 🎯 Close-Target Audit
- [x] Close-target: `#12231` (Resolves); confirmed sub of #12225, not `epic`-labeled.

### 🪜 Evidence Audit
- [x] PR body `Evidence: L1 … → L1 required`; ACs facts/config/docs, fully static-covered; CI 7/7 green; no residuals.

### 🔗 Cross-Skill Integration Audit
- [x] `neo-identity-update` facts-ledger + affected-areas (via the count/audience-split row) + the debugging-guide updated so the audience split is the documented convention. No predecessor skill points at the old all-harness framing.

### 📋 Required Actions

No required actions — eligible for human merge.

### 📊 Evaluation Metrics
*   **`[ARCH_ALIGNMENT]`**: 95 — audience model now correct (functional-count vs frontier-default vs local-loop) and SSOT-encoded.
*   **`[CONTENT_COMPLETENESS]`**: 95 — split propagated to every surface + the ledger/ADR; count-fact preserved.
*   **`[EXECUTION_QUALITY]`**: 95 — CI 7/7 green; clean, comprehensive correction; honest two-commit trail.
*   **`[PRODUCTIVITY]`**: 90 — facts convergence + audience split across the surface set.
*   **`[IMPACT]`**: 85 — removes a misleading frontier install and prevents re-drift via the SSOT.
*   **`[COMPLEXITY]`**: 45 — multi-surface facts + config + the audience distinction.
*   **`[EFFORT_PROFILE]`**: Maintenance — facts-convergence + audience correction.

Cross-family Approve (cycle 2). My cycle-1 missed the applicability; this re-review verified the frontier-template fix concretely + the SSOT encoding. Human merge gate remains.

---

