Skip to content

feat: show progress against the direction proof gate - #14

Merged
nish3451 merged 1 commit into
mainfrom
lane3/direction-proof-gate
Aug 7, 2026
Merged

nish3451 merged 1 commit into
mainfrom
lane3/direction-proof-gate

Conversation

@nish3451

@nish3451 nish3451 commented Aug 7, 2026

Copy link
Copy Markdown
Collaborator

Intended outcome

Make the 5-approved/recorded/sent Loom and 40-qualified-touch proof gate visible on the generated operator surface without inventing evidence or sending outreach.

What changed

  • Adds deterministic aggregate counters and explicit pending/unknown/missing states.
  • Counts only approved sheet rows, valid recorded Loom URLs, sent proof tied to exact Loom URLs, and scored prospect touches.
  • Adds a fixture that excludes drafts, raw placeholders, unapproved rows, bare touches, and private identifiers.

Verify

  • Focused proof-gate test — passed
  • npm test — 126 checks passed
  • npm run ci — 126 checks passed
  • sgscan — no new security findings
  • git diff --check — passed
  • Grok review — ship; no required repairs

Co-Authored-By: Claude noreply@anthropic.com

Summary by CodeRabbit

  • New Features

    • Added direction-proof progress tracking for approved, recorded, and sent Loom evidence, plus qualified-touch requirements.
    • Market proof reports now show progress, pending items, unknown records, and missing evidence in both Markdown and JSON formats.
  • Documentation

    • Documented direction-proof requirements, evidence sources, and current proof status.
  • Tests

    • Added automated coverage for proof counting, privacy filtering, repeatable report generation, data integrity, and empty-data scenarios.

… run

Add a generated Direction Proof Gate section to the 11/10 Proof Run surface
showing approved/recorded/sent Loom progress against 5 and qualified-touch
progress against 40, with source and definition text and explicit pending,
unknown, and missing states. Counters read only existing repository state:
approval rows and recorded Loom URLs in prospects/loom-links.txt, and
pipeline touches/sentAt/notes under prospects/<slug>/. Drafts, raw LOOM_URL
placeholders, unapproved rows, and prospects without touch evidence never
count. Regenerated the tracked surface from a clean tree at the fixed clock
date so the deterministic operator-surface gate stays byte-identical, and
added a focused fixture test proving the counters.

@greptile-apps greptile-apps 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.

nish3451 has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.

@coderabbitai

coderabbitai Bot commented Aug 7, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The market proof export now tracks approved, recorded, sent, and qualified-touch Direction Proof Gate metrics. It emits the metrics in Markdown and JSON. An end-to-end harness validates controlled fixtures and edge cases.

Changes

Direction Proof Gate

Layer / File(s) Summary
Gate calculation and output
scripts/export-market-proof-run.mjs, growth-brain/ops/11-10-proof-run.md
The exporter validates Loom evidence, detects sent-proof references, counts qualified touches, and reports pending, unknown, and missing counts in Markdown and JSON.
Gate integration validation
scripts/test-direction-proof-gate.mjs
The test harness validates gate counts, generated output, privacy filtering, deterministic regeneration, sheet immutability, and empty inputs.
Test command wiring
package.json
The ci and test scripts run the direction-proof-gate and active-operator-surfaces tests.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant LoomLinksSheet
  participant ProspectPipeline
  participant ExportMarketProofRun
  LoomLinksSheet->>ExportMarketProofRun: Provide Loom approval and recording data
  ProspectPipeline->>ExportMarketProofRun: Provide sent-proof and touch evidence
  ExportMarketProofRun->>ExportMarketProofRun: Calculate Direction Proof Gate metrics
  ExportMarketProofRun-->>LoomLinksSheet: Preserve input sheet
  ExportMarketProofRun-->>ProspectPipeline: Emit Markdown and JSON proof results
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: adding progress counters for the Direction Proof Gate.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch lane3/direction-proof-gate

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai 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.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@scripts/export-market-proof-run.mjs`:
- Line 335: Update the missing-touch calculation in the export output to clamp
40 minus directionGate.qualifiedTouches at zero using the requested Math.max
behavior, and add a fixture covering more than 40 qualifying touches to verify
no negative count is reported.
- Line 333: Update the pending-recording message in the export output to
accurately describe all rows counted by directionGate.pendingRecording: approved
rows lacking a valid recorded Loom URL, including empty or malformed values.
Either use this broader wording or report raw placeholders and malformed URLs as
separate categories.
- Around line 141-142: Update the referencesLoom logic to inspect only sent
notes and touches, extract URL tokens from their text, and require an exact
token equality with row.loomUrl instead of using substring matching. Add a
fixture covering a different URL that merely contains row.loomUrl as a
substring.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 557a4fa5-4423-4bd4-a142-5bb0b25c488f

📥 Commits

Reviewing files that changed from the base of the PR and between 430bfd3 and 3138c6e.

📒 Files selected for processing (4)
  • growth-brain/ops/11-10-proof-run.md
  • package.json
  • scripts/export-market-proof-run.mjs
  • scripts/test-direction-proof-gate.mjs

Comment on lines +141 to +142
const referencesLoom = notes.some((note) => note?.action === "sent" && String(note.note || "").includes(row.loomUrl))
|| touches.some((touch) => touch?.action === "sent" && String(touch.note || "").includes(row.loomUrl));

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Require an exact Loom URL reference.

String.prototype.includes() accepts a different URL that contains row.loomUrl as a substring. It can count invalid sent proof. Extract URL tokens from each sent note or touch, then compare each token to row.loomUrl for equality. Add a near-match fixture.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/export-market-proof-run.mjs` around lines 141 - 142, Update the
referencesLoom logic to inspect only sent notes and touches, extract URL tokens
from their text, and require an exact token equality with row.loomUrl instead of
using substring matching. Add a fixture covering a different URL that merely
contains row.loomUrl as a substring.

| Sent Looms | ${directionGate.sentLooms}/5 | recorded Looms whose pipeline has \`sentAt\` plus a sent touch or note naming that exact Loom URL |
| Qualified touches | ${directionGate.qualifiedTouches}/40 | recorded \`touches\` entries with channel or note evidence in lead-scored prospect pipelines |

- Pending: ${directionGate.pendingRecording} approved row(s) still carry a raw Loom placeholder and do not count as recorded.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Describe all pending-recording states.

pendingRecording includes every approved row without a valid Loom URL. An empty or malformed URL increases this count, but the generated text says that every pending row has a raw placeholder. State that the row lacks a valid recorded Loom URL, or report placeholder and malformed values separately.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/export-market-proof-run.mjs` at line 333, Update the
pending-recording message in the export output to accurately describe all rows
counted by directionGate.pendingRecording: approved rows lacking a valid
recorded Loom URL, including empty or malformed values. Either use this broader
wording or report raw placeholders and malformed URLs as separate categories.


- Pending: ${directionGate.pendingRecording} approved row(s) still carry a raw Loom placeholder and do not count as recorded.
- Unknown: ${directionGate.recordedWithoutSentProof} recorded Loom(s) have no pipeline sent proof tied to that Loom URL yet.
- Missing: ${40 - directionGate.qualifiedTouches} qualified touch(es) are still absent; ${directionGate.qualifiedProspectsWithTouches} qualified prospect(s) currently carry touch evidence.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Clamp missing touches at zero.

If qualified touches exceed 40, this output reports a negative missing count. Use Math.max(0, 40 - directionGate.qualifiedTouches) and add a fixture with more than 40 qualifying touches.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/export-market-proof-run.mjs` at line 335, Update the missing-touch
calculation in the export output to clamp 40 minus
directionGate.qualifiedTouches at zero using the requested Math.max behavior,
and add a fixture covering more than 40 qualifying touches to verify no negative
count is reported.

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3138c6e266

ℹ️ 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".

const touches = Array.isArray(pipeline.touches) ? pipeline.touches : [];
const referencesLoom = notes.some((note) => note?.action === "sent" && String(note.note || "").includes(row.loomUrl))
|| touches.some((touch) => touch?.action === "sent" && String(touch.note || "").includes(row.loomUrl));
return Boolean(pipeline.sentAt) && referencesLoom && Boolean(pipeline.sentChannel || pipeline.lastChannel);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Exclude untrusted email sends from the sent-Loom count

When a historical or --force-recorded send uses email while sender setup still has warnings, this predicate counts the Loom as sent. That contradicts the Proof Capture Rules rendered by this same script and check-market-proof-run.mjs, which explicitly rejects email proof until sender trust is clean, so the new direction gate can report progress that the canonical proof check refuses to accept.

Useful? React with 👍 / 👎.

Comment on lines +156 to +159
const approvedRows = loomRows.filter((row) => row.path && existsSync(row.path) && approved(row.approval));
const approvedLooms = approvedRows.length;
const recordedLooms = approvedRows.filter((row) => isValidLoomUrl(row.loomUrl)).length;
const sentLooms = approvedRows.filter((row) => isValidLoomUrl(row.loomUrl) && sentProofFor(row)).length;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Deduplicate Loom rows before counting gate progress

If loom-links.txt contains the same approved row more than once, each copy increments all three Loom counters; five duplicate rows for one sent video therefore display 5/5 approved, recorded, and sent. Because this file is manually maintained and the gate is stated in terms of Looms rather than rows, count distinct prospect/Loom evidence instead of raw rows to prevent duplicate entries from satisfying the proof gate.

Useful? React with 👍 / 👎.

Comment on lines 225 to +228
.sort((a, b) => a.weight - b.weight || a.name.localeCompare(b.name))
.slice(0, limit);

const directionGate = directionGateCounts(

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Compute progress after merging generated sheet rows

When the sheet is missing or does not yet contain a newly selected recording-batch prospect, the gate is calculated from the old sheet here, but the command later appends approved placeholder rows before returning. The generated report and JSON can consequently say 0 approved and 0 pending while the resulting repository state contains up to five approved pending rows; rerunning the command changes the counters without any new evidence.

Useful? React with 👍 / 👎.


- Pending: ${directionGate.pendingRecording} approved row(s) still carry a raw Loom placeholder and do not count as recorded.
- Unknown: ${directionGate.recordedWithoutSentProof} recorded Loom(s) have no pipeline sent proof tied to that Loom URL yet.
- Missing: ${40 - directionGate.qualifiedTouches} qualified touch(es) are still absent; ${directionGate.qualifiedProspectsWithTouches} qualified prospect(s) currently carry touch evidence.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Clamp the missing-touch count at zero

Once the pipeline records more than 40 qualified touches, this subtraction renders values such as Missing: -1 qualified touch(es) are still absent. Continued outreach after satisfying the gate is a normal state, so the operator surface should report zero missing touches rather than a negative deficit.

Useful? React with 👍 / 👎.

@nish3451
nish3451 merged commit 4baa4bb into main Aug 7, 2026
3 checks passed
@nish3451
nish3451 deleted the lane3/direction-proof-gate branch August 7, 2026 11:00
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.

1 participant