fin-central-intranet

FIN Central canonical knowledge vault — Taproot entity profiles, FIN-level decisions, policies, runbooks, role-universal SOP templates, and aggregate intelligence sources.

This is the authored markdown source for FIN Central’s knowledge layer. Operational truth lives in the event store; this vault is the human-authored + agent-projected content that gets ingested into knowledge.domain = doc via the GitHub vault webhook (Phase 5).

Three navigation surfaces

FilePurpose
README.md (this file)Vault purpose, conventions, frontmatter schema, provenance discipline
VAULT_RENDERER_OUTPUTS.mdInventory of auto-generated docs that land here — cadence, sources, landing paths
docs/README.mdTopic index — authored content by subfolder

1. Vault model

  • Authored docs: human-written markdown lives here. Webhook ingest parses every change into knowledge.domain = doc + chunks into operational_memory, transactionally (Engineering Spec §11.5.3).
  • Projected docs: agent-rendered docs (entity profiles, aggregates, observability) deposited by the projector. Carry renderer_version + generated_from_event_ids[].
  • Frontmatter is the contract. The 30+ field DocContent schema (Engineering Spec §3.1) drives every behavior downstream.

2. Directory structure

fin-central-intranet/
├── docs/
│   ├── entity_profiles/        # Taproot canonical: commodity, variety, vendor, customer, region, season, grower, certification, lot, facility
│   ├── aggregate_intelligence/ # Harvest Directory source content (anonymized aggregates, public_anonymized visibility)
│   ├── decisions/              # FIN-level architectural + business decisions — 100% authored sections per §3.4
│   ├── runbooks/               # FIN Central operational runbooks
│   ├── sops/                   # Role-universal SOP templates (tenant vaults override)
│   ├── reference/              # Specs, schemas, glossaries
│   └── policies/               # Anonymization, federal-audience, data-retention policies
├── _attachments/               # Images / PDFs referenced from docs (keep <5MB; larger to R2)
└── .github/
    └── workflows/              # vault-webhook + index-rebuild (wired in Phase 5)

Snapshot subpaths emerge automatically per §11.6:

docs/entity_profiles/commodities/watermelon.md           # current
docs/entity_profiles/commodities/watermelon/2026-W19.md  # weekly — IMMUTABLE
docs/entity_profiles/commodities/watermelon/2026-M05.md  # monthly — IMMUTABLE

3. Frontmatter contract

Per DocContent schema (Engineering Spec §3.1). The renderer/parser enforces these — missing required fields cause ingest to reject the doc.

3.1 All docs (minimum)

---
schema_version: 1
doc_id: stable_snake_case_id
doc_kind: <one of the 11-value enum below>
title: Human-readable title
slug: human-readable-title
source_system: github_vault     # for authored content; projector uses event_projection
visibility: company             # 5-state for authored: personal | company | customer_visible | restricted | confidential
data_plane: universal_intelligence   # private_workspace | relationship_data | universal_intelligence
lifecycle_status: active        # draft | active | archived
tags: [taproot, commodity, watermelon]
source_attribution: ["author:rob_garcia"]
created_at: 2026-05-15T20:00:00Z
updated_at: 2026-05-15T20:00:00Z
---

3.2 doc_kind enum (11 values, Engineering Spec §3.1)

doc_kindAuthored or ProjectedSnapshot?Renderer-version required?
authoredAnono
system_projectedPoptionalyes
decision_recordA only (rejected if mixed)nono
runbookAnono
sopAnono
proof_packagemixed (every authored claim needs citations)weekly+monthlyyes
event_digestPyes (daily/weekly)yes
portal_pagePoptionalyes
entity_profilemixed (≥1 projected section bound to source entity)weekly+monthlyyes
aggregate_intelligencePweekly+monthlyyes
recall_traceP only (rejected if mixed) — legal-grade, deterministicsnapshots requiredyes (mandatory)

3.3 Additional required fields per doc_kind

When doc_kind: entity_profile:

entity_type: commodity          # commodity | variety | vendor | region | customer | lot | grower | facility | certification | season_window
renderer_version: 1.0.0
content_hash: sha256:<64-hex>   # SHA-256 of body — drives incremental embedding §11.7
source_entity:
  domain: commodity             # source knowledge domain
  key: watermelon               # source knowledge key
  last_observed_version: <event_id_or_version>
visibility: tenant_private      # 2-state for entity_profile: tenant_private | public_anonymized
anonymization_policy_id: anonymization_v1_2026_05_15  # required if visibility = public_anonymized

When doc_kind: system_projected | aggregate_intelligence | recall_trace:

renderer_version: 1.0.0
content_hash: sha256:<64-hex>
snapshot_period: 2026-W19       # null/omitted for current/live; required for snapshots
generated_from_event_ids: [evt_..., evt_...]

When sourced from GitHub vault (set by ingest, not by author):

github:
  owner: fin-platform
  repo: fin-central-intranet
  branch: main
  path: docs/entity_profiles/commodities/watermelon.md
  commit_sha: <full-sha>

4. Section model (Engineering Spec §3.4)

A doc body is composed of typed sections. Authored and projected sections are NEVER mixed within a single paragraph. The frontmatter declares body_section_map[]:

body_section_map:
  - section_id: overview
    anchor: "#overview"
    kind: authored
    author_actor_id: a0000000-0000-0000-0000-000000000100
    author_commit_sha: <sha>
    fact_citations: []
    confidence: authored
 
  - section_id: arrival_chart
    anchor: "#arrival-chart"
    kind: projected
    projection_source: events            # events | knowledge_aggregate | external_source | agent_generated
    generated_from_event_ids: [evt_..., evt_...]
    generator_module: commodity_profile_renderer
    renderer_version: 1.0.0
    fact_citations: [{anchor: "#arrival-chart", event_ids: [evt_...], confidence: observed}]
    confidence: observed

Per-doc_kind hard rules (enforced at write time):

  • decision_record body = 100% authored sections
  • recall_trace body = 100% projected sections (legal-grade, deterministic)
  • entity_profile body = ≥1 projected section bound to source entity row
  • proof_package may mix, but every authored claim must include fact_citations[]

5. Provenance & citation discipline

Every non-trivial claim cited. The system enforces this at the tool boundary, not as a writing guideline.

5.1 Fact citations (Engineering Spec §3.3)

fact_citations:
  - claim_anchor: "#post-harvest-temp"
    event_ids: [evt_lot_received_..., evt_temp_exception_...]
    knowledge_keys: ["commodity:watermelon"]
    external_source_uri: "https://www.ers.usda.gov/..."
    confidence: observed | inferred | external_authoritative

Confidence is rendered visually (§3.5):

  • observed — plain (raw event data or authoritative external publication)
  • inferred — soft typographic marker; hover reveals inference chain (requires inference_notes)
  • external_authoritative — inline source attribution (USDA, FDA, GAP body)
  • authored — plain when cited; “no citation” warning when missing

For legal-grade doc kinds (recall_trace, proof_package, federal audience), missing citations are a CI failure (§15).

5.2 Cite-then-claim contract (§13.6) — agent-generated prose

Any MCP tool generating doc prose returns a structured array of attributed claims, never free prose. Empty evidence → 400 NoEvidenceProvided. Each claim requires cited_chunk_ids[] (≥1). Confidence = minimum across cited chunks. Ungrounded topics surface in unresolved_topics[], NOT in the doc body. This is how ungrounded LLM content becomes structurally impossible to ship.

5.3 walk_provenance (§8.12)

Given a doc + anchor, the walk_provenance MCP tool walks the citation chain back to raw events, returning tree | flat | mermaid. CI gate runs this on every claim in recall_trace before commit. Privileged variant includes actor/IP/device.

5.4 External source drift (§13.7)

Every external citation records observed_content_hash + observed_at. Weekly drift monitor fetches + compares. On mismatch:

  • external_source_drift_detected event
  • Doc transitions to lifecycle_status: stale_external_citation
  • Banner shown in doc reader
  • Reviewer either revalidates (new hash + external_citation_revalidated event) or proposes edit via propose_doc_edit

6. Snapshots & content-hash discipline (§11.6, §11.7)

6.1 Snapshot pattern

For entity_profile + aggregate_intelligence + proof_package docs:

  • Current live doc at canonical path (e.g., docs/entity_profiles/commodities/watermelon.md)
  • Weekly snapshot at <path>/<YEAR-Wnn>.md (e.g., 2026-W19.md)
  • Monthly snapshot at <path>/<YEAR-Mnn>.md (e.g., 2026-M05.md)

Snapshot semantics:

  • snapshot_period field set in frontmatter
  • lifecycle_status: archived from the moment of write
  • Immutable — any later upsert with the same snapshot key returns 409 SnapshotImmutable
  • The current doc’s aliases[] does NOT include snapshot IDs; snapshots are separate citation targets so “what we knew in W19” stays addressable

Federal-grade evidence packs SHOULD cite snapshots, not current docs, so claims remain pinned to a specific point in time.

Snapshot schedule:

  • Weekly: Mondays 06:00 tenant-local — freezes the prior week
  • Monthly: 1st of month 06:00 tenant-local — freezes the prior month

6.2 Incremental embedding via content_hash

content_hash (SHA-256 of body) drives selective re-embedding:

  • Every chunk carries its parent doc’s content_hash at embedding time
  • On doc.indexed, compare new hash to chunk-side hash; only re-embed changed chunks
  • Frontmatter-only changes (tag edits, status changes) DO NOT trigger re-embedding
  • Renderer-version bumps DO trigger re-embedding + require explicit backfill plan at docs/migrations/renderer-version-bumps.md

Embedding cost guard: single batch >2,500 docs requires paging via doc.embedding_batch_paged.

[[commodity:watermelon|watermelon]]           # typed wikilink — resolves fast
[[decision_record:demarcation_2026_05_15|the demarcation decision]]
[[policy:anonymization_v1|anonymization policy]]

Untyped wikilinks ([[watermelon]]) resolve via path lookup — slower; prefer typed.

8. Vault webhook lifecycle (§7, §5)

On every push to main:

  1. GitHub webhook → Cloudflare Worker route, signature verified
  2. Worker maps repo to tenant/vault config (env vars OR tenant config knowledge row)
  3. Parser produces DocContent from the markdown
  4. Single transaction (§11.5.3):
    • upsert knowledge.domain = doc row
    • write chunks to operational_memory (with content_hash carry-through)
    • upsert backlinks to doc_backlink_projection
    • upsert entity-doc mapping to entity_doc_projection
  5. Lifecycle event emitted inside transaction: doc.ingested then doc.indexed
  6. waitUntil queues fan-out: render request, FTS reindex, embedding job

Nightly reconciler verifies coherence; emits doc.coherence_drift_detected on mismatch.

9. Doc-CQRS migrations — LIVE on fin-central staging (2026-05-23 update)

The doc-CQRS migrations referenced in Engineering Spec §11.5.1 + §11.5.2 — doc_backlink_projection and entity_doc_projectionare LIVE on fin-central staging. They landed at slots 065_doc_backlink_projection.sql and 066_entity_doc_projection.sql in fin-agentic/db/migrations/ (the originally-intended slots 045/046 were already taken by unrelated index migrations, so the doc-CQRS pair was renumbered per ADR-005). Both rows are applied in fin-central staging’s schema_migrations table per the holistic-integration audit (2026-05-23) live SELECT — see audit/integration-audit-2026-05-23/cross-repo/STAGING-VERIFICATIONS.md §A.

With these migrations live, the vault webhook now upserts the doc row + chunks AND populates the doc_backlink_projection + entity_doc_projection tables in the single ingest transaction (§11.5.3 / §8 step 4). Authoring + ingest work for entity_profile docs is fully wired end-to-end.

Historical note: Prior to 2026-05-23 this section read: “doc_backlink_projection (intended migration 045) and entity_doc_projection (intended migration 046) — do not yet exist in db/migrations/.” That statement is stale; updated as part of FCI-A-08 reconciliation.

  • Engineering spec (v0.2): fin-agentic/docs/engineering/FIN_INTRANET_HUMAN_AGENT_PROJECTION_ENGINEERING_SPEC_2026-05-13.md
  • Projection catalog: fin-agentic/docs/projections/PROJECTION_CATALOG_2026-05-15.md
  • High-level design: fin-agentic/docs/design/FIN_INTRANET_HUMAN_AGENT_PROJECTION_LAYER_DESIGN_2026-05-13.md
  • Demarcation plan: fin-agentic/docs/architecture/FIN_CENTRAL_TENANT_DEMARCATION_PLAN_2026-05-15.md
  • Phase 5 bootstrap runbook: fin-agentic/docs/runbooks/PHASE_5_FIN_CENTRAL_INTRANET_BOOTSTRAP_RUNBOOK_2026-05-15.md
  • Anonymization policy: fin-agentic/docs/policies/anonymization/FIN_ANONYMIZATION_POLICY_V1_2026-05-15.md

11. Bootstrap status

Bootstrapped 2026-05-15 as part of Phase 1 §4 of the demarcation runbook. Content lives behind Cloudflare Access once Phase 5 wires Quartz + Pages + Access.