Skip to content

Comments

Phase 0 Tail v2: LEGACY_THIN_EMIT compat tagging, leak closure, Crucible stub#622

Open
wileland wants to merge 1 commit intocodex/compat-envelope-contract-v1-exec-2026-02-21from
codex/implement-phase-0-tail-v2-compat-tagging
Open

Phase 0 Tail v2: LEGACY_THIN_EMIT compat tagging, leak closure, Crucible stub#622
wileland wants to merge 1 commit intocodex/compat-envelope-contract-v1-exec-2026-02-21from
codex/implement-phase-0-tail-v2-compat-tagging

Conversation

@wileland
Copy link
Owner

Motivation

  • Harden the ENTRY_ANALYZED envelope contract to preserve backward compatibility for legacy thin emits while making legacy provenance explicit.
  • Preserve existing permissive behavior for partial + [] and keep complete + [] invalid except when explicitly marked with NO_MEANING_DETECTED.
  • Add a deterministic, side-effect-free gate for Crucible execution and close common leak channels from GraphQL errors and noisy Mongoose debug in sensitive environments.

Description

  • Compat tagging: extended applyLegacyEntryAnalyzedCompatibility() to append LEGACY_THIN_EMIT to warningCodes for true legacy-thin emits while preserving the coercion to processingStatus: 'partial' and bloomCards: [] (file: server/src/orchestration/eventBus.js).
  • Validation lock: added NO_MEANING_DETECTED to PROCESSING_WARNING_CODE and updated validateEntryAnalyzedEnvelope() to allow processingStatus === 'complete' with empty bloomCards only when the NO_MEANING_DETECTED warning is present (file: server/src/utils/failureFirewall.js and server/src/utils/failureFirewallContracts.js).
  • Deterministic Crucible gate + stub: implemented shouldRunCrucibleStub() and runCrucibleStub() to run a safe, no-op log only when processingStatus === 'complete' && bloomCards.length > 0, and added contract doc docs/contracts/crucible-listener-contract.md; legacy side-effectful listener path remains unchanged (file: server/src/orchestration/crucibleListener.js).
  • Leak closure: added sanitizeApolloFormatError() to strip stacks, nested causes, and redact raw DB error messages from GraphQL formatted errors (file: server/src/utils/graphqlErrorSanitizer.js), and added suppressMongooseDebugForSensitiveEnvs() to disable Mongoose debug in production/test and invoked it from the worker runner (files: server/src/utils/mongooseDebug.js, server/src/workers/runner.js).
  • Tests: added deterministic tests covering legacy-thin tagging, explicit reflection partial emits (untagged), complete+[] truth-table with NO_MEANING_DETECTED, and Crucible gate behavior (files under server/src/orchestration/__tests__ and server/src/utils/__tests__).

Testing

  • Ran the targeted unit suite with pnpm -C server exec vitest run src/orchestration/__tests__/eventBus.contract.test.ts src/orchestration/__tests__/crucibleListener.test.js src/utils/__tests__/failureFirewall.test.ts src/utils/__tests__/graphqlErrorSanitizer.test.ts src/utils/__tests__/mongooseDebug.test.ts and all included tests passed.
  • Attempted pnpm -C server test and pnpm -w test but the full workspace test runs failed in this environment due to missing external workspace packages (express, supertest, mongoose, openai, jsonwebtoken, langfuse), which are environmental dependency limitations rather than logic regressions.
  • Changes are intentionally surgical and limited to server/src/**, server/tests/**, docs/contracts/**, and the task spec file; unit coverage was added for the new behaviors and passed in the focused harness.

Codex Task

@github-actions
Copy link

github-actions bot commented Feb 21, 2026

Audit

Audit artifacts not found.

Schema

No drift detected ✅

Codex

No Codex outputs yet.

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a0b1d40efb

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +187 to +188
detachAnalyzedListener = onEntryAnalyzed((payload) => {
Promise.resolve(runCrucibleStub(payload)).catch((error) => {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Keep ENTRY_ANALYZED hooked to runSideEffects

registerCrucibleListener() now wires the primary onEntryAnalyzed subscription to runCrucibleStub only, so ENTRY_ANALYZED envelopes from the active reflection worker path (server/src/workers/reflection.worker.js) no longer execute awardBaselineXp or createPendingTrial. Before this change the same subscription called handleEntryAnalyzed, and there are no server/src/** emitters for the legacy utils/events/eventBus channel, so queued reflection flows lose XP/trial side effects instead of just adding a gate.

Useful? React with 👍 / 👎.

return RAW_DB_ERROR_PATTERN.test(message) ? 'Internal server error' : message;
};

export const sanitizeApolloFormatError = (formattedError = {}) => {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Wire Apollo sanitizer into the GraphQL server

This sanitizer is added but not connected to Apollo error formatting, so the redaction logic never runs in production; a repo-wide search shows sanitizeApolloFormatError is only imported by its unit test. Without passing it as formatError in server initialization, stack/cause sanitization remains a no-op despite this patch’s leak-closure goal.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant