Skip to content

Commit da3196c

Browse files
authored
feat(growth): cut over company enrichment to Dawn (#1041)
1 parent 4c1db10 commit da3196c

23 files changed

Lines changed: 766 additions & 2227 deletions

apps/growth-research/README.md

Lines changed: 31 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
The staged application exposes `growth_company`, a private compiled adapter around
66
the generated Dawn company agent. Lifecycle captures bounded company evidence and
77
submits `{ request }`; the managed thread returns `values.result`. The agent cannot
8-
write Growth records or send email. The local comparison harness remains available
8+
write Growth records or send email. The local agent evaluation harness remains available
99
for evaluation, independently of the production rollout switch.
1010

1111
Set `GROWTH_RESEARCH_PRODUCTION_MODE=managed-company-only`, `OPENAI_API_KEY`, and
@@ -18,6 +18,12 @@ already-settled rejection fence without invoking the agent. This permits cleanup
1818
after the managed run becomes terminal. A rejection never updates an existing
1919
fence, so a late replay cannot declare an earlier writer settled.
2020

21+
Lifecycle recovery does not retain crashed research indefinitely. After the
22+
execution deadline plus five minutes, it may fail the attempt and delete temporary
23+
state without a settlement receipt. It verifies thread absence on separate ticks
24+
and verifies trace deletion independently. This V1 policy leaves the duplicate
25+
fence intact and does not claim that elapsed time proves worker termination.
26+
2127
Configure `GROWTH_RESEARCH_TRACE_PROJECT_ID` for manually exported, sanitized
2228
model/tool spans. The exporter accepts `GROWTH_RESEARCH_TRACE_API_KEY` and
2329
`GROWTH_RESEARCH_TRACE_WORKSPACE_ID`, with platform-injected key fallbacks.
@@ -38,8 +44,9 @@ checkpoint deletion and sanitized tracing before enabling automatic publication.
3844

3945
## Local company research pilot
4046

41-
The local pilot compares one bounded Dawn agent with the existing lifecycle enrichment
42-
generator on identical captured company evidence. It has no Growth database connection,
47+
The local pilot evaluates one bounded Dawn agent on synthetic or captured company
48+
evidence. The earlier lifecycle generator comparison is historical. It has no Growth
49+
database connection,
4350
does not resolve people or employment, and cannot send email. The company graph is
4451
private to the managed adapter; evaluation CLI adapters are excluded from staging.
4552

@@ -72,13 +79,12 @@ expected claims/unknowns from the actual captured evidence. Save the reviewed co
7279
under a new name/version. Acquisition is preparation, not a human quality label.
7380

7481
Set `GROWTH_RESEARCH_PILOT_MODE=local-company-only` and configure `OPENAI_API_KEY`
75-
for the agent or `ANTHROPIC_API_KEY` for the baseline through the operator environment.
82+
for the agent through the operator environment.
7683
Never include keys in arguments, fixtures, reports or commits. The local in-process
7784
case context is also required: an environment flag alone cannot authorize pilot tools.
7885

7986
```sh
8087
npx tsx apps/growth-research/scripts/research-pilot.mts run --output /absolute/private/pilot --corpus /absolute/private/pilot/CORPUS_UUID.json --approach agent
81-
npx tsx apps/growth-research/scripts/research-pilot.mts run --output /absolute/private/pilot --corpus /absolute/private/pilot/CORPUS_UUID.json --approach baseline
8288
npx tsx apps/growth-research/scripts/research-pilot.mts inspect --output /absolute/private/pilot --run RUN_UUID
8389
```
8490

@@ -92,21 +98,20 @@ Explicit inspection shows company sources and candidate findings; ordinary progr
9298
prints only opaque IDs and outcome codes. Reports use restrictive atomic writes and
9399
refuse overwrites. Preserve the final index and all failed attempts when comparing runs.
94100

95-
The baseline uses its existing provider/model and 1,200-token/30-second request bounds.
96-
It receives company mode, synthetic adapter form context and zero progress score.
97-
Its raw citations are captured before production normalization. It does not return
98-
quotes: `not_provided` is distinct from failing or passing exact-quote validation.
99-
Provider failure records retain known request/usage/citation diagnostics. Missing usage
100-
and cost are unavailable, never zero. This comparison measures whole approaches with
101-
different providers/models; it does not isolate Dawn's causal contribution.
101+
The lifecycle Anthropic prototype and its baseline execution adapter are retired.
102+
Current evaluation runs the Dawn agent against synthetic or reviewed public company
103+
corpora. Historical baseline reports remain readable and can be included in review
104+
packets; their missing quotes, usage and cost remain unavailable rather than zero.
105+
Historical comparisons used different providers/models and do not isolate Dawn's
106+
causal contribution.
102107

103108
Raw automatic tracing is disabled for local pilot runs. The record reports
104109
`tracing: unavailable`; this slice does not claim sanitized LangSmith tracing is live.
105110
No research findings are automatically published to Growth or typed memory.
106111

107112
### Human comparison
108113

109-
Each invocation emits a blinded review packet. To combine baseline and agent results
114+
Each invocation emits a blinded review packet. To compare historical baseline and agent results
110115
for the same corpus, pass their index UUIDs; mixed corpus hashes/classes are rejected:
111116

112117
```sh
@@ -127,20 +132,20 @@ per-approach scores are persisted as a new review artifact. Aggregate quality sc
127132
remain unavailable while reviews are incomplete, preventing success-only denominators.
128133
Human semantic review is not replaced by model grading or string matching.
129134

130-
### Dogfooding findings ledger
135+
### Historical dogfooding findings ledger
131136

132137
| Finding | Evidence / owning layer | Status and next verification |
133138
| --- | --- | --- |
134139
| Nullable tool fields become required strings | Dawn 0.8.24 compiler JSON schema conversion; observed generated submit schema and failed unknown-field submissions | Upstream core and LangChain conversion regression/fix in progress. Pilot uses the supported authored Zod schema export; a package upgrade must rerun the original extraction probe before declaring the upstream defect released. |
135140
| Bound model calls bypass subclass generation hooks | Real bound-model regression in this application | Guards, request counts and JSON usage capture live at the actual provider fetch boundary; generated graph tests verify it. |
136141
| Page capture yields empty, partial, or mostly navigation evidence | Company-only acquisition against the six documented domains | Outcomes retained. Evaluate extraction improvements separately; do not hide failures by swapping cases. |
137-
| Baseline provider rejects billing state | Live baseline synthetic calls returned a classified billing rejection | External provider funding/configuration required; no quality comparison can be claimed from failed calls. |
138-
| Managed interruption precedes later child checkpoint | Recorded local/cloud Agent Server 0.13.4-node24 probe | Still a live-person integration gate; local cancellation tests are not proof of managed cancellation. |
142+
| Baseline provider rejects billing state | Earlier live baseline synthetic calls returned a classified billing rejection | Historical finding for the retired adapter; failed calls provide no quality comparison. |
143+
| Managed interruption precedes later child checkpoint | Recorded local/cloud Agent Server 0.13.4-node24 probe | Platform limitation covered by late-result rejection and bounded production cleanup; local cancellation tests do not prove managed cancellation. |
139144
| Disabled memory and shared harness persistence behavior | Earlier synthetic compatibility probe on Dawn 0.8.24 | Reproduction-needed against current Dawn before assigning a fix. Pilot has no memory and graph tests use isolated state. |
140145

141-
Keep source snapshots, generated reports and review labels outside git. The full growth
142-
funnel/contact journey and real install/runtime-triggered enrichment are subsequent
143-
slices, after supported company context and the managed data lifecycle are verified.
146+
Keep source snapshots, generated reports and review labels outside git. Lifecycle now
147+
routes form and eligible install/runtime enrichment through the managed company adapter.
148+
The local evaluation harness remains isolated from those production jobs.
144149

145150
## Synthetic compatibility deployment
146151

@@ -258,9 +263,10 @@ Agent Server `0.13.4-node24` can acknowledge interruption before its JavaScript
258263
stops, allowing a later result checkpoint. The generated Dawn graph cancels when a
259264
live `config.signal` is supplied; the official JS sidecar does not forward that
260265
signal. No vendor patch is included. Cancellation and protection against writes
261-
after cancellation remain failed live-use gates. The smoke client's cleanup command
262-
refuses interrupted threads; an operator must independently establish worker
263-
quiescence before deleting those records. A terminal run status alone is insufficient.
266+
after cancellation are a platform limitation. Production rejects late results and
267+
uses the bounded lifecycle cleanup policy above. The older platform smoke client's
268+
cleanup command remains conservative about interrupted threads; that diagnostic
269+
restriction is not the production rollout policy.
264270
Deploy the verified artifact with the official CLI `0.4.21` source archive layout
265271
and the LangSmith control-plane source-upload API. Updates should target the existing deployment ID:
266272
request its upload URL, upload only the verified `.deployment` archive, and submit
@@ -269,8 +275,9 @@ the returned object path with `revision_source: "internal_source"`,
269275
The signed upload requires `Content-Type: application/gzip` and
270276
`X-Goog-Content-Length-Range: 0,209715200`. Configure secrets through the deployment
271277
API; never include an environment file in the archive. Re-enabling synthetic model
272-
tests requires both a provider key and the explicit fixture-mode value. Do not wire
273-
real Growth signals into this deployment until its remaining live-use gates pass.
278+
tests requires both a provider key and the explicit fixture-mode value. Wire
279+
real Growth signals only through the managed company adapter and lifecycle's
280+
durable submission, result validation, and cleanup handlers.
274281

275282
The uncached platform smoke target takes positional fixture, thread and correlation
276283
identifiers. Set `GROWTH_RESEARCH_URL`, `LANGSMITH_API_KEY` when authentication is

apps/growth-research/eslint.config.mjs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,8 @@ export default [
44
{ ignores: ['**/.dawn/**', '**/.deployment/**'] },
55
...baseConfig,
66
{
7-
// Local-only benchmark adapters exercise the exact lifecycle baseline.
8-
// They are excluded from the standalone deployment; copying it would bias comparisons.
9-
files: [
10-
'apps/growth-research/src/pilot/baseline.ts',
11-
'apps/growth-research/src/pilot/acquisition.ts',
12-
],
7+
// Local evaluation uses the same browser capture as lifecycle.
8+
files: ['apps/growth-research/src/pilot/acquisition.ts'],
139
rules: { '@nx/enforce-module-boundaries': 'off' },
1410
},
1511
];

apps/growth-research/scripts/research-pilot.mts

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ export function parsePilotArguments(argv: string[]) {
4242
}
4343
if (allowed[command].some((key) => !args[key]) || !isAbsolute(args.output))
4444
throw new Error('pilot_invalid_arguments');
45-
if (command === 'run' && !['agent', 'baseline'].includes(args.approach))
45+
if (command === 'run' && args.approach !== 'agent')
4646
throw new Error('pilot_invalid_arguments');
4747
if (args.run) z.uuid().parse(args.run);
4848
if (args.packet) z.uuid().parse(args.packet);
@@ -105,11 +105,7 @@ export async function main(
105105
} else if (args.command === 'run') {
106106
if (process.env['GROWTH_RESEARCH_PILOT_MODE'] !== 'local-company-only')
107107
throw new Error('pilot_mode_required');
108-
if (
109-
!process.env[
110-
args.approach === 'agent' ? 'OPENAI_API_KEY' : 'ANTHROPIC_API_KEY'
111-
]
112-
)
108+
if (!process.env['OPENAI_API_KEY'])
113109
throw new Error('pilot_provider_key_required');
114110
const corpus = validateCorpus(await inputJson(args.corpus));
115111
log({
@@ -128,7 +124,7 @@ export async function main(
128124
process.once('SIGINT', cancel);
129125
try {
130126
log(
131-
await runCorpus(corpus, args.approach as 'agent' | 'baseline', {
127+
await runCorpus(corpus, 'agent', {
132128
root: args.output,
133129
revision,
134130
signal: abort.signal,

apps/growth-research/src/pilot/baseline.ts

Lines changed: 0 additions & 156 deletions
This file was deleted.

0 commit comments

Comments
 (0)