Gully's work, audited against best practice
On this page
- Evidence labels
- 1. Who and what, so nobody guesses
- 2. How Gully works (so we can judge it fairly)
- 3. Item-by-item verdicts
- 4. Where Gully is silent (the gaps are ours to own)
- 5. Our execution against his spec and against best practice
- 6. Best-practice scorecard for Gully's spec alone
- 7. External checks that bear on his spec
- 8. Verdict
Written 25 Oct 2026, Dubai time (UTC+4). Internal side. External best-practice and X cases are in research/ (see the last section).
Evidence labels
- [V] I checked it myself this run: a live fetch, a file read, or a read-only GSC/GA4 pull.
- [R] It comes from a team report or spec. I read the report; I did not re-run the work.
- [U] I could not verify it.
Verdicts: Sound (matches best practice), Partly (right idea, gap in the idea or in the execution), Wrong, Unverified.
1. Who and what, so nobody guesses
- "Gully" is Mark Gullickson. The documents call his firm INVRT, not INVT. Gmail also shows an expAInd thread. I report what the sources say. [V]
- What he delivered is a handoff spec: "BuyDubai / Dalia: Joining the knowledge into one useful service", dated 24 Oct 2026 (15 pages), plus Technical Contracts and Build Stories companions. [V] (
evidence/invrt-handoff.txt) - It says so itself: "this is the documentary implementation plan… It does not report changes or tests on your running system." [V]
- Its scope is the Dalia knowledge service: identity, metric definitions, evidence, updates, property matching, tool and channel contracts. Website facts and JSON-LD are one output (section 11 of the spec). [V]
- It is not a programmatic-SEO plan. It says nothing about index policy, page quality at scale, or Google's scaled-content rules. That is a gap in what we asked for, not a fault in what he wrote.
- The brief says "we ingested Gully's INVT learnings and used them". Evidence says the team took parts: the metric register, deterministic rebuild, the facts manifest and the release gate. The service itself (contracts, evidence lifecycle, change propagation, matching) is not built. The 36-fixture runner passed 3 and returned NOT_IMPLEMENTED for 33 when I read it. [R]
2. How Gully works (so we can judge it fairly)
He tags every claim: [A] source-reported, [B] proposed, [D–F] external standards. He refuses to treat "intended" as "done" (for example: "Appendix descriptions of graph-first answering should be treated as the intended route until the caller is connected and traced"). He asks for one traced example before widening. That is better practice than most agency handoffs. [V]
3. Item-by-item verdicts
| # | Gully's position | Best-practice test | Verdict | Evidence |
|---|---|---|---|---|
| 1 | Keep the existing stack (Supabase, marts, onto_g graph, Node on Vercel). No new graph DB, no host migration. | Do not rebuild what works. Add contracts at the seams. | Sound | Spec section 2. [V] |
| 2 | Every number has one definition. "The LLM should choose and explain, never calculate." | Single metric layer (dbt metrics / semantic layer). Numbers computed in code, language model only phrases. | Sound. Adopted. | Our metrics.yaml and factlib.py (FL.get). Only 25 of 192 (metric, slice) pairs were registered in metrics.yaml at the 23 Oct cube [R]. The 24 Oct update claims 55 families and a 27/27 formula check in staging [R]. Two builds, two dates, not a contradiction, but the live pages do not yet read the register. |
| 3 | Reversible identity crosswalk on strongest keys (DLD project number, licence, group ID). Ambiguous matches go to review. | Master-data practice: deterministic keys first, no silent fuzzy merges, keep history. | Sound. Adopted in staging. | Registers: 186 communities, 6,166 buildings; 13 earlier LLM-guessed project mappings dropped. [R] Registers exist in staging only. [R] |
| 4 | Do not pick a winner between two conflicting values by "confidence score". Keep both with their bases. | Lineage and reconciliation: surface the conflict. | Sound. Partly proved. | Peninsula Three: site 156 sales, cube 158, onto_c 35. Team's trace says 35 came from an un-reconciled Supabase slice taken before 2026 rows were joined. [R] I did not re-run the trace. The "Completed" vs "ACTIVE 93.1%" status gap is explained as escrow-register lag. That is an inference [U]. |
| 5 | A failed read returns unavailable, never "no sales". | Fail loudly; no silent zeros. | Sound | The cube-proof found 972 rows with NULL fact_id and non-reproducible builds on the 23 Oct cube. [R] The principle matters. |
| 6 | Evidence and revision lifecycle; idempotent change propagation with acknowledgements; withdrawal and CDN purge proof. | Idempotent pipelines, replayable events, takedown SLAs. | Sound in principle. Partly right-sized. | For a daily static rebuild, cube_hash in every page manifest is a coarse, cheap version of the same idea. The full event/ack design suits Dalia (live answers), not static pages. Not built. [R] |
| 7 | Hard-filter property matching: building fit is not a verified available offer. | Do not claim stock you do not have. | Sound | Team's answer: find_properties returns verified_available_inventory = [] unless a feed under 7 days old exists. No live listing feed. [R] |
| 8 | Website facts and JSON-LD are projections of the same accepted record. Structured data must match visible text. | Google structured-data policy: markup must reflect visible content. | Sound. Matches Google's own page. | Google AI features doc: structured data must match visible text. [V] Our pages carry 3 ld+json blocks and a facts-manifest on the six community pages I sampled. [V] |
| 9 | "No invented public review aggregate or rich-result promise." | Google review-snippet policy; avoid fake reviews. | Sound | benidorm.co.uk follows it: its only "Rating" is a Hotel starRating (official class), not a review. [V] |
| 10 | Finite slices M1–M9, S00–S21, each with a "done when". Start with one traced building. | Thin vertical slices with acceptance tests. | Sound | Spec section 12. First increment M1–M5. [V] |
| 11 | Acceptance: deterministic checks for identity, amounts, periods, access. Humans judge usefulness. An LLM judge may triage, not decide. E100 and R30 sets. Paul's blind test, 15/20 target "still to agree". | Eval practice: golden sets, human review, no sole LLM judge. | Sound | Spec section 13. He flags the 15/20 target as proposed, not agreed. [V] |
| 12 | Measured speeds (43 ms card query, 2.2 s search) "do not establish a speed ratio". | Honest benchmarking. | Sound | Spec section 13. [V] |
| 13 | RAG: pre-filter before vector search; one canonical rag_search; never mix embedding models in one index. |
Standard hybrid-retrieval practice. | Sound (team's reading of it) | Update 24 Oct: unfiltered rag_search 1.4–2.9 s on a 2 GB Supabase vs 80–250 ms local. [R] |
| 14 | Source rights tiers (public_citable vs internal_assist_only). |
Licence and attribution hygiene. | Sound. Not yet implemented. | Decision recorded 24 Oct. [R] Property Finder and Google Places data carry real rights questions; see MISSING. |
| 15 | The pack's catalogue size: 54,683 corpus documents, 29,686 onto_g entities. | Quote counts only with date and basis. | Unverified | He labels them "dated planner estimates, not current measured coverage". I agree and did not measure. [U] |
4. Where Gully is silent (the gaps are ours to own)
- Index policy at scale. Nothing on which pages deserve to exist, thin-page thresholds,
noindex, or Google's scaled-content-abuse policy. Google says pages "generated mainly to manipulate rankings" can be excluded from Search "however created". [V] This is where our biggest live risk sits (section 5). - Observability. No freshness SLOs, no alerting on nightly failures, no dashboard of link rates over time.
- Cost. No cost model. Our own spend gate (caps USD 10 per community, USD 25 per day; log shows max cumulative about USD 0.78) came from us, not him. [R]
- Measurement. No plan to tie data-layer changes to search or AI-referral outcomes.
- Project and deploy map. Nothing in the spec says where code, deploy repo and Vercel project live. See
PROJECTS.md. - Rollback of public pages. Covered for purge, not for "which deploy do I restore". We built that ourselves (deployment id and rollback target recorded for Town Square). [R]
5. Our execution against his spec and against best practice
5.1 What we got right [V unless marked]
- Release gate with teeth.
io_release.shrunslint_pages.pyand stops with "NUMBER LINT FAILED… no deploy" (script dated 22 Oct). [V] - Mutation-tested lint and an independent auditor (a second agent that never writes app code) on a six-rung status ladder. [R]
- Deterministic cube rebuild reported 0 diff in both directions on the staged cube (9,645,491 rows). [R]
- Honest page language. Community pages say what they could not confirm. Town Square: 0 "could not confirm" lines; JVC 45; Motor City 29. [V]
- Reversible deploys. Town Square went live 25 Oct about 10:57 Dubai time; rollback target recorded. [R]
5.2 What does not meet best practice yet
| Finding | Evidence | Standard it fails |
|---|---|---|
| Gate date. The brief says the publish gate has been on since 24 Oct. Correct: number lint existed 21–22 Oct; the no-manifest check was added 24 Oct; the quality eval was wired into release scripts only on 25 Oct (deploy scripts dated 10:41–12:28 Dubai time). Town Square on 25 Oct was the first fully gated live deploy. | File mtimes. [V] | Gates before publish, not after the complaint. |
5,931 agent pages (72.7% of 8,156 sitemap URLs) have no facts-manifest, no data-fact-id, no cube hash. They sit outside the gate. |
Live sitemap and two sampled pages. [V] | Lineage: every number traceable. |
About 90,000 unit pages are live and un-gated. /sitemap-units-1.xml and -2.xml hold 45,000 URLs each. They are not named in sitemap-index.xml or robots.txt. A sampled page (Unit 111, 161 Jumeirah Lane) is 200, index, follow, no facts-manifest, about 915 words including site navigation, title "worth AED 1.86M, sold AED 1.75M Feb 2026". The 20 Oct SOT entry says these sitemaps were once in the index and submitted to Search Console. |
Live fetch 25 Oct about 13:35 Dubai time [V]; SOT [R]. | Lineage; scaled-content policy; a per-unit "worth" estimate printed without a trace. This is a bigger un-gated set than the agent pages. |
| Agent pages are thin and templated. About 5,000 characters of text. Sample: "closed 1 sales (AED 2.3m)" and a month table that is mostly zeros. Bio copied from the agent's own profile. A templated "The agent's view" quote is attributed to a named broker. Whether he wrote it is unverified. | /agents/amit-masand/, /agents/masuma-noorani/. [V] |
Google scaled-content and thin-content policies; E-E-A-T honesty. This is the single largest SEO exposure. |
Three community pages still live without facts. discovery-gardens, jvt, dubai-silicon-oasis: 0 data-fact-id, and the placeholder "not shown yet". (On JVC, Motor City and Town Square, "not shown" is a real note about villa price per sq ft, not a placeholder.) |
Live fetch 25 Oct about 13:25 Dubai time. [V] | Gate coverage; the 24 Oct complaint covered five thin pages. Two of them (Town Square, Motor City) are now fixed. |
Mixed cube hashes live. Five community pages carry the 23 Oct hash 661f7039…; Town Square carries 74bc4c52…. |
Live manifests. [V] | One revision per release (Gully section 11). |
Staleness against the claim. Town Square says "12 months to 22 October 2026" on 25 Oct. llms.txt says "Data to 2026-10-22… rebuilt (2026-10-23)". Agent pages say "Checked 23 October 2026". The nightly job failed on 21 and 24 Oct and restored the last good build. |
Live fetch; PROJECT file. [V/R] | A freshness SLO with an alert. |
| Mixed hand-typed and cube numbers. JVC video section hard-codes 1,296; cube says 1,273. | PROJECT file. [R] | Single source of truth. |
| Link rates. Sales to community 87.9%; sales to tower 75.5% (did not reproduce); leases to building 30.8%; Property Finder to DLD 84.3% vs 73.4% unexplained. | Registers report. [R] | Reconciliation targets and published match rates. |
Eval calibration. community_eval.py pass line 85 was set against the gold page (Business Bay scored 100). Not calibrated against outcomes. Town Square 44.7 → 79.3 → 95.9. |
Eval baseline. [R] | A score is only as good as its calibration. The builder's own gate can be gamed; the independent auditor mitigates this. |
Gate weaknesses logged by the auditor: eval check used grep PASS; exclusion enforced only at depth 1; 17,193 Traks-only edits shipped in the overlay. |
Gate recheck 3, read in an agent transcript. I could not re-find the 17,193 figure in the Studio docs on 25 Oct [U]. | Defence in depth. |
6. Best-practice scorecard for Gully's spec alone
| Dimension | Score | Why |
|---|---|---|
| Data engineering design (contracts, lineage, idempotency, testing) | 8.5/10 | Full coverage. Honest labels. Unbuilt. |
| Honesty and epistemics | 9.5/10 | Tags every claim. Refuses to overstate. |
| Fit to a static-page growth business | 5/10 | Built for a chat service. Silent on SEO risk and measurement. |
| Evidence it works | 2/10 | A plan. Three of 36 fixtures pass. |
7. External checks that bear on his spec
- Google's AI features page: no special schema, no new machine-readable files or "AI text files" needed; pages must be indexed and snippet-eligible. [V] So our
llms.txtandllms-full.txtare harmless and cheap, but we must not credit them for traffic. - X research (see
research/x-posts.md): Glenn Gabe documented a large programmatic site losing Google visibility (National Today, verified). An Ahrefs schema test found no ranking lift. An SE Ranking study found no llms.txt effect. Many success claims are self-reported. [R, from the other executor] - For cases and external best practice, read
research/x-posts.md. The filesresearch/cases.mdandresearch/best-practice.mdwere not on disk when I finished; any reference to them in the x-posts file is unresolved.
8. Verdict
Gully's spec is sound, careful and mostly adopted in spirit. It is not yet a running system, and it does not cover the biggest risk on the site we ship (thin pages at scale). The team's own gate and register work is real and good. The gap between design and what is live is the story.