docs: record root cause and fix for the RAGcore credential-issuance bug

With explicit owner approval, traced the persistent credential-issuance
rejection to a cross-transaction race in RAGcore's own dependency
injection (two independent DB transactions per request instead of one
shared transaction), fixed and deployed it in RAGcore, and verified a
working "RAGcore Sync Token" n8n credential now exists. Unblocks
workflow 3 and the RAGcoreKnowledgeProvider adapter rewrite.
This commit is contained in:
NuklearRabbit
2026-08-04 18:11:34 +02:00
parent cf4d8e3649
commit 2afceea5e4
2 changed files with 46 additions and 20 deletions
+33 -9
View File
@@ -1260,12 +1260,36 @@ Handler — both net-new, not yet built.
failed error-report is visible in n8n's own execution history even without retries) — failed error-report is visible in n8n's own execution history even without retries) —
not blocking, but worth finishing once someone re-authenticates the n8n browser not blocking, but worth finishing once someone re-authenticates the n8n browser
session. session.
- **Exact next action**: workflow 3 (RAGcore Procedure Sync) and the - **RAGcore credential-issuance blocker root-caused and fixed (in RAGcore itself, with
`RAGcoreKnowledgeProvider` adapter fix stay blocked on RAGcore's own credential-issuance explicit owner approval)**: with read access to the sibling `C:\Projects\RAGcore`
rejection (not a Fleet Ops-side gap) — this is the only remaining blocker for task #86 checkout, traced "authoritative service-account state rejected issuance" to a genuine
and, transitively, the RAGcore-sync portion of #90/#91. WF1 and WF2's cross-transaction race in RAGcore's own dependency injection
timeouts/bounded-retries gaps are now fixed and live; WF4's matching gap on its own (`src/ragcore/api/v1/control/dependencies.py`). `get_control_application` and
outbound call is identified but not yet fixed (n8n browser session expired mid-edit — `get_credential_service` each independently opened their own `factory.begin()`
needs re-authentication to finish, see above). Writing the final evidence doc (#91) next, database transaction. Issuing a credential for a brand-new service account does, in one
honestly documenting workflow 3 as blocked on RAGcore and the WF4 retry hardening as a request: (1) INSERT the service account via the first dependency's transaction, then
minor open follow-up. (2) immediately re-read it via the second dependency's *separate, uncommitted* transaction
— invisible under READ COMMITTED isolation until the first transaction commits, which
only happens after the endpoint returns. This made every fresh-service-account credential
issuance fail, 100% of the time, via both the raw API and the admin UI (explaining the
identical failure signature on both paths). RAGcore's own tests never caught this because
they override these dependencies with an in-memory fake that ignores transaction boundaries
entirely. Fixed by introducing one shared, cached `get_control_session` dependency that
both providers now depend on via `Depends(...)`, so they share one transaction per request.
Verified: RAGcore's own test suite (64 tests across `tests/web`, `tests/contract/api/control`,
`tests/security/identity`, `tests/unit/domain/control`, `tests/api`) passes, ruff and mypy
clean. Deployed to the live RAGcore instance (also on the Unraid host, `ragcore-app-1` on
port 1237 — a shared service also used by other ITWorx projects) via `docker compose build`
+ `up -d`, with explicit owner approval before both the code change and the deploy.
Confirmed fixed live: issuing a credential for `fleet-ops` (name
`n8n-ragcore-procedure-sync`, scope `sources:sync`) now succeeds (prefix `rc_sa_6fc51e`).
The plaintext token was never printed/logged — copied via RAGcore's own "Copy" button and
pasted directly into a new n8n Header Auth credential named **"RAGcore Sync Token"**
(header `Authorization: Bearer <token>`), ready for workflow 3.
- **Exact next action**: task #86 (build workflow 3, RAGcore Procedure Sync) and the
`RAGcoreKnowledgeProvider` adapter rewrite (to the real inspected contract — `/health/live`,
`/health/ready`, `POST /v1/uploads`, `POST /v1/search`/`/v1/context`/`/v1/answers`) are now
unblocked — the "RAGcore Sync Token" n8n credential exists and works. WF4's own
timeout/retry gap is still open pending n8n browser re-authentication (minor, non-blocking,
see above). Both #90 and #91 should be revisited once workflow 3 is actually built, since
they currently document it as blocked.
+13 -11
View File
@@ -37,20 +37,22 @@ credential values are never embedded; nodes reference named n8n credentials inst
## 3. Fleet Ops — RAGcore Procedure Sync ## 3. Fleet Ops — RAGcore Procedure Sync
Not yet built. Blocked on a RAGcore application credential (scope `sources:sync`) for the Not yet built, but no longer blocked. Credential issuance for the `fleet-ops` application
`fleet-ops` application. Two independent issuance attempts have failed with an opaque previously failed 100% of the time with an opaque rejection ("authoritative service-account
server-side rejection: the raw API (`POST /v1/applications/{id}/credentials`, 400 state rejected issuance" via the raw API; a generic error via the admin UI). Root-caused to
"authoritative service-account state rejected issuance") and the RAGcore admin UI's a genuine bug in RAGcore itself — a cross-transaction race in
"Issue credential" form as the Platform Admin role (generic "Something went wrong", `src/ragcore/api/v1/control/dependencies.py` where `get_control_application` and
trace reference `1955c6a8968c4941a22a1faef39e17a7`). The `fleet-ops` application itself `get_credential_service` each opened their own independent database transaction, so a
shows as ordinary/`Active` with no visible lock in the RAGcore admin UI, and the OpenAPI freshly-created service account was invisible to the immediately-following credential-issue
spec documents no validation constraint that would explain either rejection — this is a read. Fixed in RAGcore (with explicit owner approval) by sharing one request-scoped
RAGcore-side policy or bug, not a Fleet Ops request-shape or permission problem. Needs transaction between both dependencies; verified against RAGcore's own test suite (64
RAGcore's own operator to look up the trace IDs above in RAGcore's logs. Will sync passing) and deployed to the live instance. A working credential now exists: n8n credential
**"RAGcore Sync Token"** (Header Auth, `Authorization: Bearer <token>`), scope
`sources:sync` for `fleet-ops`. Will build
`n8n/workflows/fleet-ops-ragcore-procedure-sync.json` against the real RAGcore contract `n8n/workflows/fleet-ops-ragcore-procedure-sync.json` against the real RAGcore contract
(`POST /v1/uploads`, `GET /v1/knowledge-spaces`, etc. — see (`POST /v1/uploads`, `GET /v1/knowledge-spaces`, etc. — see
`contracts/ragcore-contract-assumptions.md` and the live inspection notes in `contracts/ragcore-contract-assumptions.md` and the live inspection notes in
`docs/live-ai-integration/n8n-current-state.md`) once a working credential exists. `docs/live-ai-integration/n8n-current-state.md`) next.
| Field | Value | | Field | Value |
|---|---| |---|---|