Skip to content

FE-844: Elicitation gaps architecture#197

Merged
lunelson merged 4 commits into
nextfrom
ln/fe-844-elicitation-gaps
Jun 11, 2026
Merged

FE-844: Elicitation gaps architecture#197
lunelson merged 4 commits into
nextfrom
ln/fe-844-elicitation-gaps

Conversation

@lunelson

@lunelson lunelson commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Replace the elicitation backlog with the typed elicitation-gaps obligation register.
  • Seed the grounding catalog, add command support, and derive coverage live from the graph.
  • Add the first capability-readiness gate over elicitation gaps without storing readiness grades.

lunelson commented Jun 10, 2026

Copy link
Copy Markdown
Contributor Author

This stack of pull requests is managed by Graphite. Learn more about stacking.

@lunelson lunelson changed the title Remodel elicitation_backlog into elicitation_gaps obligation register FE-844: Elicitation gaps architecture Jun 11, 2026
@lunelson lunelson marked this pull request as ready for review June 11, 2026 07:52
Copilot AI review requested due to automatic review settings June 11, 2026 07:52
@cursor

cursor Bot commented Jun 11, 2026

Copy link
Copy Markdown

PR Summary

Medium Risk
SQLite migrations reshape the elicitation register and rename columns, which affects seeding, read-back, and downstream readiness projections; follow-on work still depends on this substrate landing cleanly.

Overview
Replaces the elicitation backlog persistence model with elicitation_gaps: obligations carry disposition, readiness band, predicate metadata, and importance, with self-referential arose_from_gap_id instead of backlog status/closed_at_lsn.

Migration 0004_gaps_node_kind_reference anchors each gap on the graph ontology via refers_to plus a free-form question, dropping the typology name column—aligning stored gaps with D75-L (one node-kind vocabulary, not a parallel typology).

Adds docs/design/ELICITATION_QUESTIONS.md as a priming catalog for the elicitor (examples by NodeKind, not persisted schema) and links it from docs/README.md. memory/PLAN.md records completion of elicitation-gaps-remodel and gaps-node-kind-reference, sequences capability-readiness ahead of the context-pipeline trio, and retargets elicitation-driver to the new gap shape.

Reviewed by Cursor Bugbot for commit 74aa041. Bugbot is set up for automated code reviews on this repo. Configure here.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR remodels the former elicitation backlog into a typed elicitation_gaps obligation register, derives structural gap coverage at read time from the graph, and introduces an initial capability-readiness evaluator that can proceed, proceed with low epistemic confidence, or negotiate via an establishment offer.

Changes:

  • Replace elicitation_backlog schema/table/commands/queries with elicitation_gaps (typed predicate + disposition + importance, plus live-derived coverage/answered).
  • Add a session/capability-readiness projection + tests that gates capabilities over relevant grounding gaps without importing stored-grade symbols.
  • Update topology/docs/tests/migrations to reflect the new gaps register and observed shape ownership.

Reviewed changes

Copilot reviewed 23 out of 24 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
src/projections/session/capability-readiness.ts Adds capability readiness evaluator over relevant elicitation gaps.
src/projections/session/capability-readiness.test.ts Covers readiness outcomes + live presence-derived flip integration.
src/projections/README.md Registers the new session projection and its invariants/tests.
src/graph/schema/kinds.ts Adds GAP_DISPOSITIONS + GAP_PREDICATE_KINDS enums.
src/graph/schema/elicitation-gaps.ts Introduces ElicitationGap + predicate/disposition types.
src/graph/schema/elicitation-backlog.ts Deletes the obsolete backlog entry type definitions.
src/graph/README.md Updates architecture docs to reference elicitation_gaps register + owner query.
src/graph/queries.ts Implements getElicitationGaps and presence-based coverage derivation.
src/graph/queries.test.ts Updates query tests to assert live presence-derived coverage behavior.
src/graph/observed-shapes-coverage.test.ts Renames observed shape entry to elicitation_gaps.
src/graph/index.ts Re-exports gaps schema/types + getElicitationGaps.
src/graph/command-executor.ts Seeds gaps at spec creation; adds create + disposition commands; adds predicate validation.
src/graph/command-executor.test.ts Updates executor tests for seeding, create, and disposition behavior.
src/graph/architecture.test.ts Updates enum-taxonomy boundary checks for new gap enums.
src/db/schema.ts Replaces elicitation_backlog table with elicitation_gaps columns/constraints.
src/db/row-schemas.ts Updates drizzle-typebox row schema exports for elicitation gaps.
src/db/README.md Documents the new elicitation_gaps register and derived-coverage semantics.
memory/SPEC.md Updates readiness and elicitation semantics to center gaps + capability-readiness.
memory/PLAN.md Promotes/records the remodel + follow-on frontiers and sequencing notes.
memory/cards/gaps-node-kind-reference--node-kind-reference.md Adds an active scope card for the node-kind reference follow-on.
drizzle/meta/0003_snapshot.json Updates migration snapshot to reflect elicitation_gaps.
drizzle/0003_outstanding_black_bird.sql Updates migration SQL to create elicitation_gaps.
docs/README.md Adds the elicitation question catalog to docs index.
docs/design/ELICITATION_QUESTIONS.md Adds per-kind elicitation question priming catalog.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +425 to +444
if (!VALID_GAP_PREDICATE_KINDS.includes(predicate.kind)) {
diagnostics.push({ field: 'predicate.kind', message: 'predicate kind is not valid' });
return;
}

if (predicate.kind === 'presence') {
if (!Number.isInteger(predicate.minimum) || predicate.minimum < 1) {
diagnostics.push({ field: 'predicate.minimum', message: 'minimum must be a positive integer' });
}
if (predicate.plane !== undefined && !isNodePlane(predicate.plane)) {
diagnostics.push({ field: 'predicate.plane', message: 'plane is not valid' });
}
if (predicate.band !== undefined && !isReadinessBand(predicate.band)) {
diagnostics.push({ field: 'predicate.band', message: 'band is not valid' });
}
if (predicate.nodeKind === undefined && predicate.band === undefined) {
diagnostics.push({ field: 'predicate', message: 'presence predicate needs nodeKind or band' });
}
}
}
Comment thread src/graph/queries.ts
Comment on lines +356 to +366
function deriveGapCoverage(
db: BrunchDb,
specId: number,
predicate: GapPredicate,
disposition: GapDisposition,
): number {
if (disposition === 'not_applicable' || disposition === 'irrelevant' || disposition === 'answered')
return 1;
if (predicate.kind === 'presence') return derivePresenceCoverage(db, specId, predicate);
return 0;
}
Comment on lines +59 to +65
function relevantGapRecords(
capability: CapabilityId,
gaps: readonly ElicitationGap[],
): readonly ElicitationGap[] {
const relevantNames = CAPABILITY_RELEVANT_GAPS[capability];
return relevantNames.map((name) => gaps.find((gap) => gap.name === name) ?? missingGap(name));
}
Comment thread src/graph/queries.ts
Comment on lines +373 to +375
const storedDisposition = row.disposition as GapDisposition;
const predicate = JSON.parse(row.predicate) as GapPredicate;
const coverage = deriveGapCoverage(db, row.spec_id, predicate, storedDisposition);

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit fc7d5d6. Configure here.

Comment thread drizzle/0004_gaps_node_kind_reference.sql
Comment thread src/graph/queries.ts
@lunelson lunelson force-pushed the ln/fe-844-elicitation-gaps branch from fc7d5d6 to 708c25d Compare June 11, 2026 14:30
@lunelson lunelson force-pushed the ln/fe-845-brunch-chrome-pass-i branch from b4186e2 to 25dc094 Compare June 11, 2026 14:30
Base automatically changed from ln/fe-845-brunch-chrome-pass-i to next June 11, 2026 14:31
lunelson added 4 commits June 11, 2026 16:32
Replace the FE-823 question-instance / open|closed backlog with the D65-L
typed coverage-obligation model: ElicitationGap carries name + rationale,
the presence|field|coverage|manual predicate union, importance + derived
coverage, and a disposition enum. Seed the 8-typology grounding catalog at
createSpec, add createElicitationGap / setElicitationGapDisposition
mutations through CommandExecutor, and derive presence coverage/answered
live from the graph at read-back (anti-shadowing: no stored structural
state). Regenerate migration + Drizzle snapshot; reconcile SPEC/PLAN and
graph/db topology READMEs. field/coverage derivation and manual
satisficiency remain downstream.
Introduce the D74-L gate (src/projections/session/capability-readiness.ts):
an explicit capability -> relevant-gaps map and evaluateCapabilityReadiness
returning proceed / proceed_low_epistemic / negotiate(EstablishmentOffer),
driven by live gap coverage with no stored readiness grade. Read-only
judgment; never refuses outright (I31-L). Coexists with the existing grade
gating for now. Reconcile SPEC/PLAN and projections README.

Deferred follow-ons (capability-readiness frontier): readiness-estimate
projection, MIN_GRADE consumer rewire, stored-grade deletion, and
chrome.phase/chatMode removal.
@lunelson lunelson force-pushed the ln/fe-844-elicitation-gaps branch from 708c25d to 74aa041 Compare June 11, 2026 14:33
@lunelson lunelson merged commit 4d9790a into next Jun 11, 2026
6 checks passed
@lunelson lunelson deleted the ln/fe-844-elicitation-gaps branch June 11, 2026 14:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants