Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 61 additions & 26 deletions apps/api/src/lib/startup-migrations.ledger.json

Large diffs are not rendered by default.

70 changes: 69 additions & 1 deletion apps/api/src/lib/startup-migrations.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ import {
runMigration0116_resyncSpanishCompanyDataDependencyHealth,
runMigration0117_clearStandingCatalogueAlerts,
runMigration0118_clearDanishFalseBreakerSuccess,
runMigration0119_resyncGermanCompanyDataDependencyHealth,
runStartupMigrations,
type MigrationExecutor,
} from "./startup-migrations.js";
Expand Down Expand Up @@ -1436,6 +1437,7 @@ describe("startup-migrations — BLOCKS list (canonical block set)", () => {
"runMigration0116_resyncSpanishCompanyDataDependencyHealth",
"runMigration0117_clearStandingCatalogueAlerts",
"runMigration0118_clearDanishFalseBreakerSuccess",
"runMigration0119_resyncGermanCompanyDataDependencyHealth",
]);
});
});
Expand Down Expand Up @@ -2319,7 +2321,7 @@ describe("startup-migrations — block identity is unique, not just the function
const numbers = BLOCKS.map((fn) => Number(/runMigration(\d+)_/.exec(fn.name)?.[1] ?? "0"));
const sorted = [...numbers].sort((a, b) => a - b);
expect(numbers).toEqual(sorted);
expect(Math.max(...numbers)).toBe(118);
expect(Math.max(...numbers)).toBe(119);
});
});

Expand Down Expand Up @@ -2904,3 +2906,69 @@ describe("startup-migrations: block 0118 (clear the false Danish breaker success
}
});
});

describe("startup-migrations: block 0119 (resync german-company-data dependency_health)", () => {
const releasedRow = () =>
[{ id: "69a00c0a-7eeb-4e9e-b6ad-e6314ac3a2be", capability_slug: "german-company-data", test_type: "dependency_health" }] as unknown[];

it("rewrites the refused company name to the manifest's SAP SE and writes one event", async () => {
const stub = makeStub({ queue: [{}, [], releasedRow(), {}, {}] });
const result = await runMigration0119_resyncGermanCompanyDataDependencyHealth(stub);
expect(result.rows_affected).toBe(1);
expect(result.outcome).toContain("resynced 1");

const update = stub.renderedSql.find((q) => /update test_suites/i.test(q));
expect(update).toBeDefined();
const setClause = update!.slice(0, update!.toLowerCase().indexOf("where"));
// The manifest's health_check_input, passing live in production's
// schema_check suite on 2026-10-07.
expect(setClause).toContain('{"company_name":"SAP SE"}');
expect(setClause.toLowerCase()).toContain("test_mode = 'live'");
expect(setClause.toLowerCase()).toContain("baseline_output = null");

const events = stub.renderedSql.filter((q) => /insert into health_monitor_events/i.test(q));
expect(events).toHaveLength(1);
expect(events[0]).toContain("auto_fix");
});

it("scopes the UPDATE to german-company-data, dependency_health, and the exact stale input", async () => {
const stub = makeStub({ queue: [{}, [], releasedRow(), {}, {}] });
await runMigration0119_resyncGermanCompanyDataDependencyHealth(stub);
const update = stub.renderedSql.find((q) => /update test_suites/i.test(q))!;
const whereClause = update.slice(update.toLowerCase().indexOf("where"));
expect(whereClause).toContain("test_type = 'dependency_health'");
expect(whereClause).toContain("capability_slug = 'german-company-data'");
// The stale literal, so the known_answer and schema_check suites that
// already hold SAP SE, and this suite once resynced, never match.
expect(whereClause).toContain('{"company_name":"Google"}');
expect(whereClause).not.toContain("SAP SE");
expect(whereClause).not.toContain("spanish-company-data");
});

it("does not claim a resync when no matching stale input remains", async () => {
const stub = makeStub({ queue: [{}, [], [], {}] });
const result = await runMigration0119_resyncGermanCompanyDataDependencyHealth(stub);
expect(result.rows_affected).toBe(0);
expect(stub.renderedSql.join(" | ")).not.toMatch(/insert into health_monitor_events/i);
expect(result.outcome).toMatch(/no matching stale/);
});

it("never fires twice, idempotent on a second boot", async () => {
const stub = makeStub({ queue: [{}, [{ block: "0119_resyncGermanCompanyDataDependencyHealth" }]] });
const result = await runMigration0119_resyncGermanCompanyDataDependencyHealth(stub);
expect(result.rows_affected).toBe(0);
const joined = stub.renderedSql.join(" | ").toLowerCase();
expect(joined).not.toMatch(/update test_suites/);
expect(joined).not.toMatch(/insert into health_monitor_events/);
expect(result.outcome).toMatch(/already applied/);
});

it("no captured statement binds a Date or Buffer (DEC-20260504-A bind-encoder shape)", async () => {
const stub = makeStub({ queue: [{}, [], releasedRow(), {}, {}] });
await runMigration0119_resyncGermanCompanyDataDependencyHealth(stub);
for (const query of stub.captured) {
const chunks = (query as unknown as { queryChunks?: unknown[] }).queryChunks ?? [];
expect(chunks.filter((c) => c instanceof Date || Buffer.isBuffer(c))).toEqual([]);
}
});
});
117 changes: 117 additions & 0 deletions apps/api/src/lib/startup-migrations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4015,6 +4015,7 @@ export const BLOCKS: ReadonlyArray<(tx: MigrationExecutor) => Promise<BlockResul
runMigration0116_resyncSpanishCompanyDataDependencyHealth,
runMigration0117_clearStandingCatalogueAlerts,
runMigration0118_clearDanishFalseBreakerSuccess,
runMigration0119_resyncGermanCompanyDataDependencyHealth,
];

/**
Expand Down Expand Up @@ -5957,3 +5958,119 @@ export async function runMigration0118_clearDanishFalseBreakerSuccess(
duration_ms: Date.now() - startedAt,
};
}

// Block 0119 (2026-10-10): resync the `german-company-data`
// `dependency_health` suite's input from `{"company_name":"Google"}` to the
// manifest's `health_check_input`, `{"company_name":"SAP SE"}` -- the last
// of the six registries DQ-33 named, and the same root cause blocks 0114,
// 0115 and 0116 fixed for the other five: the manifest was corrected and the
// pre-existing row never was, because `onboard.ts --backfill` only ever
// updated known_answer.
//
// "Google" is correctly refused: OpenRegister's search is fuzzy, it returns
// no confident German registry match for the bare name, and a registry name
// search must score and refuse, never take the first result. So the suite
// has failed on a correct refusal (its last run, 2026-10-07T00:06Z: "No
// confident German registry match for "Google"") and never measured whether
// the registry is reachable, the one question a dependency_health suite
// exists to answer.
//
// Verified in production, read-only, on 2026-10-10: the capability's live
// schema_check suite (6714cbe5-8a76-48b8-9b7a-22c6cbeadd4c) holds exactly
// `{"company_name":"SAP SE"}`, runs in `live` mode through the production
// OpenRegister key, and passed at 2026-10-07T00:18Z -- twelve minutes after
// this suite failed on "Google". The key exists only in production, so that
// run is the verification. DQ-33 deferred this block until the OpenRegister
// allowance reset on 2026-10-07, so a passing check would not compete with
// the paying buyer's German lookups. Exactly one test_suites row holds
// `{"company_name":"Google"}` for this capability
// (69a00c0a-7eeb-4e9e-b6ad-e6314ac3a2be), `test_mode = 'live'`.
//
// Workload this resumes (Bulk-Operation Deploy Protocol, DEC-20260504-B):
// one suite, already running on its schedule, starts passing. A passing run
// spends one OpenRegister credit where a refused one spends roughly none;
// the suite has run about once every few days, against 474 of 500 credits
// left on 2026-10-10 (resets 2026-11-06). Not a bulk-operation resumption
// event; no pre-drain or throttle needed.
//
// Disjoint from M040 (block 0111), which only INSERTs german-company-data
// known_answer fixture rows and never updates a dependency_health row.
//
// Authority: DEC-20260815-A and DEC-20260822-A (an obvious, reversible,
// evidence-backed correction of our own test input).

export async function runMigration0119_resyncGermanCompanyDataDependencyHealth(
tx: MigrationExecutor,
): Promise<BlockResult> {
const startedAt = Date.now();
const BLOCK = "0119_resyncGermanCompanyDataDependencyHealth";

await tx.execute(sql`
CREATE TABLE IF NOT EXISTS startup_migration_ledger (
block text PRIMARY KEY,
applied_at timestamptz NOT NULL DEFAULT now(),
rows_affected integer NOT NULL DEFAULT 0
)`);

const prior = (await tx.execute(sql`
SELECT block FROM startup_migration_ledger WHERE block = ${BLOCK}
`)) as unknown as Array<{ block: string }>;

if (prior.length > 0) {
return {
block: BLOCK,
outcome: "no change (already applied once)",
rows_affected: 0,
duration_ms: Date.now() - startedAt,
};
}

const released = (await tx.execute(sql`
UPDATE test_suites
SET input = '{"company_name":"SAP SE"}'::jsonb,
baseline_output = NULL,
baseline_captured_at = NULL,
test_mode = 'live',
updated_at = now()
WHERE test_type = 'dependency_health'
AND capability_slug = 'german-company-data'
AND input = '{"company_name":"Google"}'::jsonb
RETURNING id, capability_slug, test_type
`)) as unknown as Array<{ id: string; capability_slug: string; test_type: string }>;

for (const row of released) {
await tx.execute(sql`
INSERT INTO health_monitor_events (event_type, capability_slug, tier, action_taken, details, human_override)
VALUES (
'auto_fix',
${row.capability_slug},
2,
'resynced_stale_dependency_health_input',
${JSON.stringify({
test_suite_id: row.id,
test_type: row.test_type,
reason:
"stored dependency_health input (company_name Google) is correctly refused as having no confident German registry match, so the suite failed on a refusal and never measured availability; the manifest's health_check_input had already been corrected to company_name SAP SE but the pre-existing row was never resynced (onboard.ts --backfill only ever updated known_answer). SAP SE verified by the capability's own live schema_check suite passing in production on 2026-10-07.",
source: "startup-migration 0119",
})}::jsonb,
true
)
`);
}

await tx.execute(sql`
INSERT INTO startup_migration_ledger (block, rows_affected)
VALUES (${BLOCK}, ${released.length})
ON CONFLICT (block) DO NOTHING
`);

return {
block: BLOCK,
outcome:
released.length === 0
? "no matching stale german-company-data dependency_health input remains"
: `resynced ${released.length} suite(s): ${released.map((r) => `${r.capability_slug}/${r.test_type}`).join(", ")}`,
rows_affected: released.length,
duration_ms: Date.now() - startedAt,
};
}
10 changes: 10 additions & 0 deletions docs/company/DECISION-QUEUE.md
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,16 @@ this period and none are lost; it is taken off sale until the registry answers
our live system, which is a hosting question, not anything for you. This
entry's own subject is now only the German check, still waiting for 7 October.
This entry stays open until you close it.
*Update 2026-10-10 — the German correction is written and goes live with this
morning's change.* The supplier allowance reset on 7 October, which removed
the reason to wait. The other reason — that the corrected value could not be
checked from here — turned out not to need checking from here: the German
service's own second live check already uses the corrected value, and it
passed in the live system on 7 October, twelve minutes after the old one
failed. The same deploy-time route used for the other five corrects it; it
costs about one supplier credit each time the check runs, against an
allowance that is almost untouched this month. With that, all six registries
this entry named are corrected. It stays open until you close it.

**DQ-32** · `answered` · owner Petter · raised 2026-09-11T20:00Z · answered 2026-09-11 — **after the switch from Notion, the digest's "action required" means decisions waiting on you**
*Answered:* Petter, in chat, accepting the recommendation: the repo-native
Expand Down
13 changes: 13 additions & 0 deletions docs/company/GOALS.md
Original file line number Diff line number Diff line change
Expand Up @@ -1191,6 +1191,19 @@ conversion.
`x402:v1:59273355…` has bought one jwt-decode (2c) every day 09-27..10-02,
~01:00–04:30Z — a scheduled job, worth cents.

- **The 10-01 surge did not hold; the week of 09-28 closed on one buyer**
(measured 2026-10-10; `payerFacts` per UTC day and per week, equal to the
commercial pack). Week of 09-28 closed **€53.35** (rising from €36.13),
94.0% one buyer (€50.13 vs €3.22). The largest buyer's daily spend since:
€9.48 (10-02), €0.73, €5.19, €2.92, €4.86, €9.69, €6.02, €3.05 — no day
near 10-01's €16.28. Week of 10-05 is **€31.34 at day 6**, 85.9% one buyer,
so it will close near the 09-21 level, not the 09-28 one. Below the largest
buyer, two small habits are firming: the account buyer bought on 5 of 6
days this week (€3.05, already above last week's €2.62), and wallet
`x402:v1:2e55b616…` on 4 days (€0.75). The daily jwt-decode wallet
stopped after 10-02. Still no second buyer worth more than a few euros a
week; concentration, not growth, remains the read. No outreach.

## Active experiments (M1)

| id | bet | measure | kill criterion |
Expand Down
67 changes: 67 additions & 0 deletions docs/company/briefs/2026-10-10.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# 2026-10-10

## 1. Business performance

The week ending 4 October closed at €53.35, up from €36.13 the week before.
This week stands at €31.34 with one day to go, so it will close well below
last week, about where it was a fortnight ago.

**The conclusion: last week's rise was one buyer having one big day, not a
new level of business.** That buyer spent €16 on 1 October. Since then it
has spent from under €1 to about €10 a day, and about €5 on a typical day. It
provided 94 cents of every euro last week and 86 cents this week. Our
revenue still rises and falls with one customer's workload.

The rest of our revenue is small, but it is becoming more regular. The
card-paying customer is buying daily again, on five of the six days so far,
and has already spent more than in all of last week. A second wallet buyer
has bought on four days this week. Together they are worth a few euros a
week. That is a habit forming, not yet a second customer. The buyer who made
one tiny purchase every night stopped after 2 October.

## 2. What materially changed

There were no morning reports between 3 and 9 October. The scheduled runs
simply did not start, and nothing in the record says why; a computer that
was off or asleep is the likely reason. I checked the whole eight days this
morning. No service was taken off sale, nothing broke on a paying path apart
from the one loss below, and the other warnings were the usual outside
services being slow or briefly down.

One real loss turned up. On 5 October a wallet buyer sent about two dozen French
company lookups in three minutes. The French registry turned eight of them
away for coming too fast, and those sales were lost. Customers who pay
through an account get one automatic second try in that situation, but
customers who pay with a wallet do not. The money was small. It matters
because wallet payments are nearly all of our revenue.

The prepaid web-search allowance expires on 8 November with about 94% of it
unused. Nothing needs buying; the unused part is already paid for.

## 3. Fixed automatically

The daily check of German company lookups had been testing a search our own
service correctly refuses, so every day it reported a fault that did not
exist. I held off fixing it until the supplier allowance reset on 7 October,
so it would not use lookups the paying buyer needed. The correct test value
had already passed in the live system on 7 October, and the fix goes live
with today's update. That removes the most frequent false alarm, and all six
company-registry checks you were asked about in September are now corrected.
You can close that item whenever you like.

The weekly deep check, which could not read our database for a month until
you approved the read-only password on 2 October, now reads it every week. It
still shows red. That is because of two clean-up jobs on our own records,
not because it is blind.

## 4. Working on now

**Find a second buyer, so one customer's quiet week cannot halve revenue.**

**Stop losing wallet sales when a supplier briefly says "slow down".**

**Get the weekly deep check to green, so a real problem in it stands out.**

## 5. Needs your decision

Nothing needs your decision today.
5 changes: 3 additions & 2 deletions docs/project/legacy-authority-inventory.json
Original file line number Diff line number Diff line change
Expand Up @@ -530,7 +530,7 @@
{
"path": "docs/company",
"owner_area": "company-governance",
"sha256": "f2eaf397b982218f79c5f929cf67b588eb749c5fd50153f806382b333767998e",
"sha256": "d7ca9d914f947fa1fcf84996fa5a28e64e60b78032445afa8a9f07c3ad4ed4fb",
"detected_references": [
".claude/commands/ceo-brief.md",
".github/workflows/ci.yml",
Expand Down Expand Up @@ -643,6 +643,7 @@
"handoff/_general/from-code/2026-09-26-checkin-morning.md",
"handoff/_general/from-code/2026-09-27-checkin-morning.md",
"handoff/_general/from-code/2026-10-02-checkin-morning.md",
"handoff/_general/from-code/2026-10-10-checkin-morning.md",
"scripts/check-claims.mjs",
"scripts/check-docs-index.test.mjs",
"scripts/claims-lib.mjs",
Expand Down Expand Up @@ -775,7 +776,7 @@
{
"path": "handoff",
"owner_area": "session-handoffs",
"sha256": "72c6d7e1abef57f2c9e47c24adc4c54f25b5a4e87f1eb3f623ba4f84c5c2cc14",
"sha256": "b43716614cd0bee5b2898e57c98ba4ed98f10c0ffbf255e500e8da418e7d4cc8",
"detected_references": [
".agents/skills/go/SKILL.md",
".agents/skills/source-command-end-session/SKILL.md",
Expand Down
3 changes: 2 additions & 1 deletion handoff/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,11 @@
> relocated. Session-start reading order is `docs/README.md` →
> `docs/programs/README.md`, never a sweep through this table.

315 files (288 with a recorded intent, 27 without).
316 files (289 with a recorded intent, 27 without).

| date | file | intent |
| --- | --- | --- |
| 2026-10-10 | [`handoff/_general/from-code/2026-10-10-checkin-morning.md`](_general/from-code/2026-10-10-checkin-morning.md) | run the 2026-10-10 operating session under DAILY-RUN.md — the first |
| 2026-10-02 | [`handoff/_general/from-code/2026-10-02-dq34-weekly-drift-credential.md`](_general/from-code/2026-10-02-dq34-weekly-drift-credential.md) | carry out Petter's in-session answer to DQ-34 ("install the database |
| 2026-10-02 | [`handoff/_general/from-code/2026-10-02-checkin-morning.md`](_general/from-code/2026-10-02-checkin-morning.md) | run the 2026-10-02 operating session under DAILY-RUN.md — the first |
| 2026-09-27 | [`handoff/_general/from-code/2026-09-27-checkin-morning.md`](_general/from-code/2026-09-27-checkin-morning.md) | run the 2026-09-27 operating session under DAILY-RUN.md — measure the |
Expand Down
Loading
Loading