Chapter 3.6 Advanced Governance and State Management

Chapter 2.4 introduced manual_override_active as a boolean CRM property: when true, Workflow B skips the automated lifecycle transition and holds the contact in place. That flag is the entire Part II governance record. It captures state but nothing about the decision that produced it.

This chapter extends the boolean into a four-field governance record and adds the override lifecycle state machine the boolean cannot express. It also introduces policy versioning and approval chain patterns required for AI systems operating under compliance accountability. The extension is backward-compatible: the boolean is retained; four additional fields extend it.

Learning Objectives

After completing this chapter, you will be able to:

  • Explain why a boolean manual_override_active flag is insufficient for production governance and describe the four failure modes it produces in a real deployment.
  • Implement the four extended governance fields (override_expires_at, override_reason_code, override_authorized_by, override_policy_version) in the HubSpot Deal schema.
  • Design the override state machine (NOT_ACTIVE → ACTIVE → EXPIRED → CLEARED) and implement the transition logic in n8n, including the automated expiry check workflow.
  • Apply the deal_governance_tier property to scope governance intensity by deal risk level, configuring tier-appropriate override requirements for each tier.
  • Build the governance audit history entry format that makes every override decision fully reconstructible: who, when, why, under what policy, and for how long.
  • Write a Mini-ADR documenting a governance calibration decision for the Meridian platform, with rationale that addresses compliance, operational, and engineering trade-offs.

3.6.1 Why Boolean Governance Breaks Down

Section 3.0.2 Structural Limits of Part II described the boolean governance limit: a single boolean cannot capture who set the override, why, when it expires, or which policy authorized it. At Part II scale a single advisory team, known contacts, supervised workflow the boolean is sufficient. At Part III scale, four failure scenarios make the boolean inadequate.

Failure 1 Permanent override accumulation

Without an expiry field, overrides set manually remain active indefinitely unless someone remembers to clear them. A contact placed under manual_override_active = true for an active negotiation six months ago remains suppressed today. The system cannot distinguish a current negotiation from a forgotten toggle.

Failure 2 Unattributed override

When a compliance audit asks who authorized suppression of the automated advisory path for a contact, manual_override_active = true provides no answer. Without override_authorized_by, the governance record cannot be attributed.

Failure 3 Policy version opacity

When policy guidelines change, contacts overridden under the old policy cannot be identified without override_policy_version. Re-review after a policy update requires querying contacts by the policy version that was active when the override was set.

Failure 4 No expiry enforcement

With only a boolean, Workflow B checks the flag but cannot check whether the flag has expired. Expiry requires a datetime field the boolean does not provide.

TipDesign Practice

These are not documentation failures. They are system failures. A system that cannot distinguish a current negotiation hold from a six-month-old forgotten toggle is making routing decisions based on stale state. That stale state propagates into the observability metrics from Chapter 3.5 specifically into p6_last_advisory_path, where contacts suppressed by stale overrides never appear in the normal distribution.


3.6.2 Rich State Models

Rich State Models

The Part II governance model has two states:

NOT_ACTIVE  ←→  ACTIVE

The Part III governance model has four states, each corresponding to a verifiable property combination on the Contact:

State Condition System behavior
NOT_ACTIVE manual_override_active = false Normal AI-driven transition
ACTIVE manual_override_active = true AND override_expires_at > now() Override applied; AI transition suppressed
EXPIRED manual_override_active = true AND override_expires_at ≤ now() System detects expiry; clears override; resumes normal transition
CLEARED Override was manually cleared before override_expires_at Same result as NOT_ACTIVE; logged as intentional early clear

Governance state is derived at execution time from existing properties, never stored as a separate field.

The state is not stored as a named property it is derived from the combination of manual_override_active and override_expires_at at execution time. This avoids a fifth property that could fall out of sync with the other two. A system that stores derived state in a separate property creates a consistency hazard. A system that derives state at execution time does not.

TipDesign Practice

Never store derived state in a CRM property if you can compute it from properties that are already being maintained. manual_override_active + override_expires_at together define the governance state. A third override_state property would duplicate this derivation and create a consistency hazard.


3.6.3 The Four Extended Governance Fields

The Four Extended Governance Fields

The four fields added to the Part II boolean:

Property Type Description Example
override_expires_at Datetime When the override automatically expires 2025-09-30T23:59:59Z
override_reason_code Enumeration Controlled vocabulary for why the override was set ACTIVE_NEGOTIATION
override_authorized_by Single-line text Identity of the team member who set the override sarah.chen@vap.com
override_policy_version Single-line text Policy version in effect when the override was set POLICY-2025-Q3

All four are defined in the Lifecycle Governance property group alongside manual_override_active.

Reason code enumeration for the Vantage Advisory Partners domain:

Code Meaning Typical expiry
ACTIVE_NEGOTIATION Partner is actively in conversation; suppress automated follow-up 30 days
COMPLIANCE_HOLD Legal or compliance review pending Until cleared manually
PARTNER_REFERRAL Originated from a partner relationship requiring human handling 60 days
COOLING_PERIOD Recent rejection; avoid automated re-engagement 90 days
SYSTEM_REMEDIATION Data quality issue being resolved 7 days

The reason code enumeration is a governance decision, not a technical one. The appropriate codes depend on the domain and the team’s workflows. The codes above are calibrated for VAP. The Meridian Venture Partners capstone domain requires different codes (see ADR-6D Governance Calibration Rationale). A team that reuses VAP reason codes in a Meridian context will have an enumeration that does not match its actual override reasons. A team that calibrates reason codes to its domain will have an enumeration that is usable in a compliance audit.


3.6.4 Override Lifecycle

Override Lifecycle

The override lifecycle defines the valid transitions between states and the workflow actions that execute them.

Set transition (NOT_ACTIVE → ACTIVE):

A team member manually updates the Contact in HubSpot, setting: 1. manual_override_active = true 2. override_expires_at = current date + duration appropriate for the reason code 3. override_reason_code = the appropriate enum value 4. override_authorized_by = the team member’s email 5. override_policy_version = the current policy version string

Expiry transition (ACTIVE → EXPIRED → NOT_ACTIVE):

At the start of every Workflow B execution, before checking manual_override_active, a Check Expiry IF node computes:

override_expires_at < now()  AND  manual_override_active = true

If true: Workflow B clears all five governance fields, writes a governance audit note to the Contact (see 3.6.7 Governance History and Audit Trails), and continues with normal transition processing. The contact is in NOT_ACTIVE state for the remainder of the execution.

Manual clear transition (ACTIVE → CLEARED → NOT_ACTIVE):

A team member manually sets manual_override_active = false before expiry. The four extended fields should also be cleared at this point. The governance audit note records the manual clear with the team member’s action timestamp.

CautionProduction Risk

Do not clear only manual_override_active and leave the four extended fields populated. The next Check Expiry evaluation will compute the state from both manual_override_active AND override_expires_at. If manual_override_active = false but override_expires_at is still a future date, the derived state is NOT_ACTIVE (correct behavior) but the stale extended fields create a misleading governance record if they appear in a compliance audit.


3.6.5 Policy Versions

Policy Versions

override_policy_version captures which governance policy governed each override decision making contacts overridden under an old policy identifiable and re-reviewable after a policy change.

The override_policy_version field captures which version of the governance policy was in effect when the override was authorized. Policy versions follow a structured naming convention:

POLICY-{YYYY}-{QN}

Example: POLICY-2025-Q3 is the policy in effect for Q3 2025.

A policy version update occurs when governance rules change new reason codes added, expiry duration defaults revised, approval authority changed. When a policy update occurs:

  1. The new policy version string is communicated to all team members authorized to set overrides.
  2. Overrides set after the update carry the new version string.
  3. Overrides set under the previous version remain under that version string until they expire or are manually cleared.
  4. A HubSpot Contacts Search query filtered on override_policy_version = POLICY-2025-Q2 returns all contacts that require review under the new policy.

This is the mechanism that resolves Failure 3 from 3.6.1 Why Boolean Governance Breaks Down: contacts overridden under an old policy are identifiable and re-reviewable without manual tracking.


3.6.6 Approval Chains

Approval Chains

Part II governance has no approval chain any team member with HubSpot access can set manual_override_active = true. At Part III scale, some reason codes require authorization above the individual level.

Approval chain design for VAP:

Reason code Self-service Requires approval
ACTIVE_NEGOTIATION ✅ Any team member
COOLING_PERIOD ✅ Any team member
SYSTEM_REMEDIATION ✅ Any team member
PARTNER_REFERRAL ✅ Partner Relations lead
COMPLIANCE_HOLD ✅ Compliance officer

The approval chain is not enforced technically in Part III it is enforced by override_authorized_by, which records who authorized the override, and by periodic governance audits that verify the field matches the required approver for the reason code. Technical enforcement (requiring a second team member to confirm before the override is applied) is a capability for Phase 7 and beyond.

TipDesign Practice

Record the approval chain in the governance properties, not in the workflow logic. The workflow checks manual_override_active it does not verify that the right person authorized it. That verification happens in governance audits, not at execution time. Mixing approval logic into the workflow creates a brittle coupling between business rules and workflow code.


3.6.7 Governance History and Audit Trails

Part II audit history (from Chapter 2.4 and the Part II Capstone) captures the automation trail: which workflow stage a contact passed through, when the lifecycle transition fired, what the AI returned. It does not capture governance decisions.

Part III governance history captures the governance trail: when an override was set, by whom, under what reason code, for how long, and when it was cleared (manually or by expiry). This is a separate record type.

Implementation: Write a HubSpot Note to the Contact record for each governance event. Notes are timestamped by HubSpot automatically and appear in the Contact activity timeline. The Note body uses a structured format:

GOVERNANCE EVENT: {event_type}
Timestamp: {ISO 8601}
Reason code: {override_reason_code}
Authorized by: {override_authorized_by}
Expires at: {override_expires_at}
Policy version: {override_policy_version}
---
{Free-text context, if any}

event_type values: OVERRIDE_SET, OVERRIDE_EXPIRED_AUTO_CLEARED, OVERRIDE_MANUALLY_CLEARED.

Part II vs. Part III governance record comparison:

Field Part II audit Part III governance record
Automation events ✅ Captured (workflow stage timestamps) ✅ Inherited
AI advisory outputs ✅ Captured (confidence, path, source) ✅ Inherited via p6_ properties
Override state ✅ Boolean recorded ✅ Four-field record
Override reason ❌ Not captured override_reason_code
Override attribution ❌ Not captured override_authorized_by
Override expiry ❌ Not captured override_expires_at
Policy version ❌ Not captured override_policy_version
Event history ❌ Snapshot only (current boolean value) ✅ Time-series Notes on Contact

The Part II audit trail answers: did the automation run correctly? The Part III governance record answers: was every control decision authorized, attributed, time-bounded, and documented? Compliance review requires both.


Reference Diagrams

Figure 3.6.1 Override State Machine

Figure 38.1 shows the four governance states and the transitions between them. State is derived at execution time from manual_override_active and override_expires_at it is not stored as a separate property.

%%{init:{"theme":"base","themeVariables":{"primaryColor":"#eef2ff","primaryTextColor":"#1e1b4b","primaryBorderColor":"#6366f1","lineColor":"#6366f1","clusterBkg":"#f8f9ff","clusterBorder":"#6366f1","titleColor":"#1e1b4b","edgeLabelBackground":"#f6f4ef","fontFamily":"system-ui,sans-serif","fontSize":"13px"}}}%%

stateDiagram-v2
    [*] --> NOT_ACTIVE
    NOT_ACTIVE --> ACTIVE: override set
    ACTIVE --> EXPIRED: expiry reached
    ACTIVE --> CLEARED: manual clear
    EXPIRED --> NOT_ACTIVE: governance note written
    CLEARED --> NOT_ACTIVE: governance note written

Figure 38.1: Override Lifecycle State Model. Four-state override lifecycle: NOT_ACTIVE → ACTIVE on set, ACTIVE → EXPIRED on auto-clear, ACTIVE → CLEARED on manual clear. State derived at execution time, never stored separately.

Figure 3.6.2 Override Lifecycle

Figure 38.2 shows the full lifecycle of a single override from set through expiry or manual clear, with all five governance fields populated at each stage.

%%{init:{"theme":"base","themeVariables":{"primaryColor":"#eef2ff","primaryTextColor":"#1e1b4b","primaryBorderColor":"#6366f1","lineColor":"#6366f1","clusterBkg":"#f8f9ff","clusterBorder":"#6366f1","titleColor":"#1e1b4b","edgeLabelBackground":"#f6f4ef","fontFamily":"system-ui,sans-serif","fontSize":"13px"}}}%%

flowchart TD
    A["t=0: Override SET manual_override_active=true expires_at=t+30d reason=Broker negotiation policy_version=2.1"]:::process --> B["t=15d: Workflow blocked ACTIVE override governance gate logs block"]:::fallback
    B --> C{"Resolution path"}:::decision
    C -->|"Path A auto-expiry"| D["t=30d: EXPIRES → NOT_ACTIVE governance note written"]:::process
    C -->|"Path B manual clear"| E["t=22d: Ops clears override → CLEARED → NOT_ACTIVE governance note written"]:::process
    classDef trigger  fill:#dcfce7,stroke:#16a34a,color:#14532d,font-weight:600
    classDef process  fill:#eef2ff,stroke:#6366f1,color:#1e1b4b
    classDef decision fill:#fef9c3,stroke:#ca8a04,color:#78350f,font-weight:600
    classDef success  fill:#d1fae5,stroke:#059669,color:#064e3b,font-weight:700
    classDef fallback fill:#fee2e2,stroke:#dc2626,color:#7f1d1d
Figure 38.2: Override Lifecycle with Governance Fields. Single override lifecycle from set through auto-expiry or manual clear, with all five governance field values shown at each event.

ADR-6D Governance Calibration Rationale

Mini-ADR 6.6-D | Context: The Meridian Venture Partners capstone domain processes 200–300 VC deal submissions per quarter. Meridian’s compliance team requires that all override decisions be attributed, time-bounded, and auditable under the firm’s LP reporting obligations. The governance property group from Chapter 3.6 must be calibrated for this domain before the capstone workflow is built.

Decision: Override expiry durations for Meridian are calibrated to deal cycle time rather than contact relationship duration: DEAL_IN_DILIGENCE (60 days typical diligence cycle), COMPLIANCE_HOLD (manual-clear only no expiry until compliance officer clears), LP_RELATIONSHIP (90 days LP-referred deals require extended hold), REGULATORY_REVIEW (manual-clear only), DATA_QUALITY (7 days). All overrides require authorization by a Managing Director or above, recorded in override_authorized_by. Policy version follows the same POLICY-{YYYY}-{QN} convention.

Rationale: Deal cycle times at Meridian are longer than contact relationship cycles at VAP. A 30-day expiry appropriate for VAP’s ACTIVE_NEGOTIATION code would fire mid-diligence at Meridian. The DEAL_IN_DILIGENCE code is Meridian-specific and does not exist in the VAP enumeration reason code enumerations are domain-calibrated, not universal.

The manual-clear-only codes (COMPLIANCE_HOLD, REGULATORY_REVIEW) exist because regulatory events have no predictable end date. Auto-expiry would restore AI-driven transitions while the hold is still legally required.

This ADR prepares for Capstone ADR-D, which formalizes governance calibration in the full seven-field format.


Practical Exercise 3.6 Extended Governance Property Group

Business Scenario

Vantage Advisory Partners has been using manual_override_active to suppress automated lifecycle transitions for contacts in active negotiations. The boolean works but when a compliance review asks who authorized a six-week-old suppression and why, no one can answer. Overrides set months ago remain active because there is no expiry mechanism.

The Problem

A boolean flag records current state but nothing about the decision that produced it. The team cannot identify which overrides were set under an old policy, attribute any override to an authorizing team member, or automatically expire overrides when the business condition ends.

The Architectural Solution

Extend the Lifecycle Governance property group with four fields that transform the boolean into an attributable, time-bounded, policy-versioned governance record. Add a Check Expiry node to Workflow B that enforces expiry on every execution and writes a time-series governance Note to the Contact record.

Updated Workflow

Figure 38.3 shows the updated Workflow B with the Check Override Expiry gate: expired overrides trigger a field-clear and governance note before the normal AI-driven transition path resumes.

%%{init:{"theme":"base","themeVariables":{"primaryColor":"#eef2ff","primaryTextColor":"#1e1b4b","primaryBorderColor":"#6366f1","lineColor":"#6366f1","clusterBkg":"#f8f9ff","clusterBorder":"#6366f1","titleColor":"#1e1b4b","edgeLabelBackground":"#f6f4ef","fontFamily":"system-ui,sans-serif","fontSize":"13px"}}}%%

flowchart TD
    A(["Workflow B Trigger"]):::trigger --> B{"Check Override Expiry (IF node)"}:::decision
    B -->|"expired"| C["Clear All 5 Governance Fields (HubSpot Update)"]:::process
    C --> D["Write Governance Note OVERRIDE_EXPIRED_AUTO_CLEARED"]:::process
    D --> E["Normal AI-Driven Transition Path"]:::process
    B -->|"not expired"| E
    classDef trigger  fill:#dcfce7,stroke:#16a34a,color:#14532d,font-weight:600
    classDef process  fill:#eef2ff,stroke:#6366f1,color:#1e1b4b
    classDef decision fill:#fef9c3,stroke:#ca8a04,color:#78350f,font-weight:600
    classDef success  fill:#d1fae5,stroke:#059669,color:#064e3b,font-weight:700
    classDef fallback fill:#fee2e2,stroke:#dc2626,color:#7f1d1d
Figure 38.3: Workflow B Expiry Enforcement. Workflow B with expiry enforcement: expired overrides clear all five governance fields and write an audit note before the normal AI transition resumes.

Step 1 Add the Four Properties to HubSpot

Purpose

Extend the Lifecycle Governance property group with the four fields that transform the boolean manual_override_active flag into a full governance record. These properties are the data foundation for every subsequent step in this practical without them, the Check Expiry node has no datetime field to compare, the governance Note has no reason code to record, and compliance review cannot identify who authorized an override or under which policy.


Operation Summary

Property Value
Location HubSpot Property Settings → Lifecycle Governance group
Primary Function Define four structured governance fields alongside manual_override_active
Input Manual HubSpot property configuration
Output Four new Contact properties available for workflow reads and writes

Property Configuration Table

Property HubSpot Type Configuration Notes
override_expires_at Date and time Must be datetime, not text required for n8n $now.toISO() comparison in Check Expiry
override_reason_code Dropdown select Add the five VAP reason codes from 3.6.3 The Four Extended Governance Fields as enum values
override_authorized_by Single-line text Accepts email address of the authorizing team member
override_policy_version Single-line text Default value: POLICY-2025-Q3; update when governance policy changes

Engineering Rationale

NoteEngineering Rationale

override_expires_at must be created as a HubSpot datetime property not a text field because the n8n $now.toISO() comparison in the Check Expiry node requires a datetime type for the less-than comparison to evaluate correctly. A text field will not produce a meaningful datetime comparison. Creating it as text is the single most common setup error in this practical. If an existing override is not expiring when expected, verify the property type in HubSpot Settings before debugging the workflow logic.


Step 2 Add the Check Expiry Node to Workflow B

Purpose

Enforce automated override expiry on every Workflow B execution. Without this node, expired overrides remain active indefinitely contacts whose override duration has elapsed continue to have their AI-driven lifecycle transitions suppressed even though no current business reason exists. The Check Expiry node evaluates the governance state at execution time and clears the stale override before the existing manual_override_active check is reached.


Operation Summary

Property Value
Node Type IF node (Check Override Expiry)
Position First node in Workflow B before the existing manual_override_active IF node
Primary Function Detect expired overrides and route to the auto-clear path
Input Contact record with five governance fields
Output Expired path (clears fields + writes Note) or Not-expired path (continues normally)

Expiry Condition Logic

// IF node condition both must be true to trigger the expired path
manual_override_active === true
AND
override_expires_at < {{ $now.toISO() }}

If both conditions are true (expired path), execute in sequence: 1. HTTP Request: HubSpot Update Contact set manual_override_active = false, clear all four extended fields. 2. HTTP Request: HubSpot Create Note on Contact body formatted per 3.6.7 Governance History and Audit Trails, event_type: OVERRIDE_EXPIRED_AUTO_CLEARED. 3. Continue execution to the normal AI-driven transition path.

If either condition is false (not expired), bypass the clear path and continue to the existing manual_override_active check.


Output Table

Output Description
Expired path All five governance fields cleared; governance Note written; normal AI transition resumes
Not-expired path No change to governance fields; existing manual_override_active check handles next decision

Engineering Rationale

NoteEngineering Rationale

Governance state is derived at execution time from manual_override_active combined with override_expires_at it is not stored as a third named property. The Check Expiry node is the mechanism that makes this derivation actionable: when expiry is detected, the node transitions the contact from the EXPIRED derived state to NOT_ACTIVE by clearing both fields. Placing this node first in Workflow B ensures that no execution proceeds on a stale override. If expiry detection ran later in the workflow, the existing manual_override_active check would suppress the AI transition before expiry was evaluated.


Step 3 Add the Governance Note to the Manual Override Path

Purpose

Write a time-series audit record to the Contact’s activity timeline for every Workflow B execution that suppresses an AI lifecycle transition. The observability layer from Chapter 3.5 aggregates p6_ properties to measure system behavior but it does not record governance decisions. Without governance Notes, the audit trail shows only that a contact was suppressed; it does not record the reason, authorization, or policy that governed the suppression.


Operation Summary

Property Value
Node Type HTTP Request
Method POST
Endpoint /crm/v3/objects/notes
Primary Function Write structured governance event record to the Contact activity timeline
Trigger When manual_override_active = true AND override_expires_at > now() (active override)
Output HubSpot Note ID; Note appears in Contact activity timeline

Request Payload

{
  "properties": {
    "hs_note_body": "GOVERNANCE EVENT: TRANSITION_SUPPRESSED\nTimestamp: {{$now.toISO()}}\nReason code: {{$json.override_reason_code}}\nAuthorized by: {{$json.override_authorized_by}}\nExpires at: {{$json.override_expires_at}}\nPolicy version: {{$json.override_policy_version}}"
  },
  "associations": [
    {
      "to": { "id": "{{$json.hs_object_id}}" },
      "types": [{ "associationCategory": "HUBSPOT_DEFINED", "associationTypeId": 202 }]
    }
  ]
}

The Note body follows the structured format from 3.6.7 Governance History and Audit Trails. All five governance field values are captured in the Note at the time of the suppression event. HubSpot timestamps the Note automatically.


Request Field Table

Field Required Description
hs_note_body Yes Structured governance event record with all five field values
associations Yes Links the Note to the Contact record for timeline visibility
associationTypeId Yes 202 is the HubSpot-defined association type for Contact → Note

Output Table

Output Description
Note ID HubSpot Note ID confirming the governance record was created
Timeline Note appears in the Contact’s activity timeline with HubSpot’s auto-timestamp

Engineering Rationale

NoteEngineering Rationale

A governance record that shows only current state that manual_override_active was true as of the last Workflow B execution cannot answer compliance questions about when the override was set, how long it was active, or who authorized it. The time-series Notes pattern is what converts the snapshot-only Part II record into the historical audit trail Part III governance requires. Each suppression event produces one Note; over the override’s active period, the Contact’s timeline accumulates a complete record of every execution that respected the override. This record survives even if the governance fields are later cleared.


Step 4 Test the Auto-Expiry Path

Purpose

Verify that the Check Expiry node correctly detects an expired override, executes the full auto-clear sequence, and writes the governance Note before Workflow B continues to the normal AI-driven transition path. This test must pass before activating the workflow for production contacts an undetected expiry means a contact remains suppressed indefinitely.


Operation Summary

Property Value
Node Type Manual test execution
Test method Set override_expires_at to a past date on a test contact; trigger Workflow B manually
Primary Function Validate the expired path: field clear + Note write + AI transition resume
Input Test contact with all five governance fields set; override_expires_at = yesterday
Output Five fields cleared in HubSpot; governance Note on Contact; normal AI transition fires

Test Setup

// Test contact governance field values to configure before running
manual_override_active:   true
override_expires_at:      // set to yesterday e.g., 2025-06-24T23:59:59Z
override_reason_code:     "ACTIVE_NEGOTIATION"
override_authorized_by:   "test.user@vap.com"
override_policy_version:  "POLICY-2025-Q3"

Set these values on the test contact in HubSpot directly, then trigger Workflow B manually using the n8n Test Workflow button.


Verification Checklist

Verification Item Expected Result
Check Expiry IF node routes to expired path True branch executes
manual_override_active in HubSpot after run false
All four extended fields in HubSpot after run Cleared (empty)
Governance Note on Contact activity timeline Visible with OVERRIDE_EXPIRED_AUTO_CLEARED and all five field values
Workflow B continues to AI-driven transition AI assessment executes normally after expiry clear

Engineering Rationale

NoteEngineering Rationale

Testing the expiry path against a deliberately expired contact is the only way to verify that the datetime comparison in the IF node evaluates correctly for your HubSpot property type and n8n expression syntax. A datetime comparison that silently fails evaluates to false the workflow routes to the not-expired path and the contact remains suppressed with no error. This failure is invisible without an explicit test because it produces no workflow error; it produces incorrect governance behavior.


Step 5 Test the Policy Version Check

Purpose

Verify that contacts overridden under a prior policy version are identifiable and queryable. This test confirms that override_policy_version is being written correctly and that the HubSpot Search filter for policy-versioned contacts works before the governance record is needed for a real compliance review.


Operation Summary

Property Value
Method POST
Endpoint /crm/v3/objects/contacts/search
Primary Function Identify contacts carrying an old policy version string
Input Filter on override_policy_version with a prior version value
Output Array of contacts requiring re-review under the current policy

Request Payload

{
  "filterGroups": [
    {
      "filters": [
        {
          "propertyName": "override_policy_version",
          "operator": "EQ",
          "value": "POLICY-2025-Q2"
        }
      ]
    }
  ],
  "properties": [
    "hs_object_id",
    "firstname",
    "lastname",
    "override_reason_code",
    "override_authorized_by",
    "override_expires_at",
    "override_policy_version"
  ],
  "limit": 100
}

Test Sequence

// Step 1: Run the query expect zero results in a clean test environment
// If zero results: confirm override_policy_version is being written correctly

// Step 2: Manually set one test contact's override_policy_version to "POLICY-2025-Q2"
// Re-run the query expect exactly one result

// Step 3: Verify the result includes all governance fields for that contact
const results = $json.results;
// results.length should be 1; results[0].properties.override_policy_version should be "POLICY-2025-Q2"

Output Table

Output Description
Zero results Expected in a clean test environment no contacts under old policy
One result Expected after manually setting one test contact to old policy version
Full record All governance fields returned for each matching contact for audit review

Engineering Rationale

NoteEngineering Rationale

The policy version check workflow is not exercised during normal Workflow B operations it runs on demand when a policy changes and re-review of older overrides is required. Testing it now, before any policy update actually occurs, confirms the query is correctly constructed and the override_policy_version field is populated on contacts where the override was set correctly. A policy version query that returns zero results when it should return several contacts is not a clean environment it is a data gap that makes the compliance re-review impossible when it is actually needed.

ImportantCritical Requirement

If Check Expiry does not fire on an expired override, verify that override_expires_at is stored as a HubSpot datetime property (not a text property). The n8n $now.toISO() comparison requires a datetime type. If the property was created as text, delete it and re-create it as date and time.

Deliverable: Four extended governance properties added to HubSpot. Workflow B with Check Expiry node. Auto-expiry path tested and verified. Governance Note written on expiry. Policy version query demonstrated.

Estimated time: 3–4 hours.


Production Consideration

The governance Note pattern is the most frequently skipped step in practice teams implement the four fields but omit the Note-writing on lifecycle events. Notes are required for the capstone’s compliance audit deliverable: without them, the governance record shows current state but not history. A contact whose override expired three months ago has no audit trail in a Notes-free implementation.

For teams operating under active compliance requirements, consider adding a weekly reconciliation query that checks for contacts where manual_override_active = true but override_authorized_by is empty indicating an override was set without completing the full five-field record. Flag these contacts in the Slack #vap-ops channel.


Discussion Questions

  1. The governance state is derived from manual_override_active and override_expires_at rather than stored as a named property. What is the consistency risk of this approach, and under what condition would the derived state produce a wrong result?

  2. The approval chain for COMPLIANCE_HOLD and PARTNER_REFERRAL is recorded in override_authorized_by but is not technically enforced by the workflow. A team member could set override_reason_code = COMPLIANCE_HOLD with their own email in override_authorized_by. What is the minimum system change that would technically enforce the approval requirement without rebuilding the workflow?

  3. Mini-ADR 6.6-D calibrates expiry durations for Meridian Venture Partners based on deal cycle time. What additional domain information would you want before finalizing the DEAL_IN_DILIGENCE expiry at 60 days? What signal in the observability data from Chapter 3.5 would tell you the calibration was wrong?


Chapter Summary

The Part II manual_override_active boolean captures state but not the decision that produced it. The Part III four-field governance record override_expires_at, override_reason_code, override_authorized_by, override_policy_version transforms the boolean into an attributable, time-bounded, policy-versioned governance record.

Key Principle

A governance system that records only current state cannot answer who set an override, why, for how long, or under which policy. The four extended fields transform a boolean into a full governance record that survives compliance review.

Four states (NOT_ACTIVE, ACTIVE, EXPIRED, CLEARED) are derived at execution time from the combination of manual_override_active and override_expires_at. The Check Expiry node in Workflow B detects and auto-clears expired overrides on every execution. Governance Notes provide a time-series audit trail that the snapshot-only Part II record cannot.

Mini-ADR 6.6-D calibrates the governance model for the Meridian Venture Partners capstone domain, establishing domain-specific reason codes and expiry durations based on deal cycle time rather than the relationship-cycle calibration appropriate for VAP.


Transition to Chapter 3.7

Chapters 3.5 and 6.6 establish what can be measured (observability) and what can be controlled (governance). Neither answers how the system can be tested before a change goes live and how the effects of a prompt update, model change, or architecture modification can be verified in advance.

Chapter 3.7 introduces the testing and evaluation framework for AI systems: fixture sets, regression suites, and the evaluation workflow that uses the prompt version correlation from Prompt Version Correlation and Drift Rate as the pass/fail signal. The p6_prompt_version property written in Chapter 3.5 connects directly to the fixture-based evaluation approach in Chapter 3.7.


Key Takeaways

  1. The Part II boolean captures state but not the decision that produced it. Four failure scenarios permanent accumulation, unattributed overrides, policy opacity, and no expiry enforcement make the boolean insufficient at Part III scale.
  2. The Part III governance state (NOT_ACTIVE, ACTIVE, EXPIRED, CLEARED) is derived from manual_override_active combined with override_expires_at at execution time. It is not stored as a separate property.
  3. The four extended fields are: override_expires_at (datetime), override_reason_code (enumeration), override_authorized_by (text), override_policy_version (text).
  4. The Check Expiry node runs at the start of every Workflow B execution. When expiry is detected, the workflow auto-clears all five fields, writes a governance Note, and continues to the normal AI-driven transition path.
  5. Governance Notes provide a time-series audit trail on the Contact. Each override lifecycle event set, auto-expired, manually cleared produces a structured Note with all five governance field values at that point in time.
  6. Reason code enumerations and expiry durations are domain-calibrated, not universal. VAP calibrates to relationship cycle time; Meridian calibrates to deal cycle time. Mini-ADR 6.6-D prepares for Capstone ADR-D.

End of Chapter 3.6 Advanced Governance and State Management