Foothold · Boise Apartments · internal

The design map.

Three modules, ninety-four capabilities, and an honest mark against each one. What runs today, what needs building, what waits on Liberty, and what's decided and waiting on its build spec. Nothing waits on you as of 13 August.

As of 13 Aug 2026
Built from the 31 Jul, 3 Aug + 5 Aug live probes
All twenty decisions answered 13 Aug
Design locked · build specs next
The shape

Nearly two thirds of it is buildable right now

Every capability across the three modules, marked. The bar is the real count of all ninety-four; the tracks below show the load-bearing ones.

3 live
63 buildable now
8 Liberty
11 decided
9 never
Live in production today Buildable now, reads only, nothing blocking Blocked on Liberty, a permission or an answer Decided 13 Aug, awaiting its build spec; writes still gated by rule 2 Blocked on you, none left. All twenty decisions answered 13 Aug. Never in Entrata, lives in GHL or ours Unknown, none left. All five granted methods were probed on 5 August.

Nearly two thirds of the system can be built today with nothing but reads. Liberty's group grant landed on 3 August, all six reads we asked for on 31 July, and the last five of those were probed on 5 August. Every one works. That emptied the unknown column and took buildable from 54 to 61. A second pass the same day found pets in the lease read, named, thirty of the fifty-two leases, which moved the pet gift out of the never column and took buildable to 62. Then your three decisions on 5 August moved two more. Filing a resident's service ticket used to sit in the "blocked on you" column; it now sits with Liberty, because sendWorkOrders isn't on the key and nobody has ever asked for it. Logging a recognition touch back to Entrata moved the same way, later the same day, when you reversed your own decision to park sendLeaseActivities and put it on the ask list instead. So Liberty is eight, not six, and you were twelve, not fourteen. Then your 10 August decision moved one more. "What the resident follow-up actually is" came out of your column entirely: you decided it's an AI-generated personal message about the resident's specific issue ("did your back door get fixed?"), not the survey that got cut, and it runs on work-order fields we already read, so nothing blocks building it. That put you at eleven, and buildable at sixty-three. Four things are genuinely waiting on Liberty: Aspen and Summerset onto the key, the apply link, that work-order permission, and the activity note, the last two in one email. Your signature still unblocks the entire mirror-into-Entrata half of Modules 1 and 2, and you've decided it's coming, on the properties you own, the day Foothold goes live on them. And nine things will never be in Entrata at all, so they have to live in GHL or a store we own. Then on 13 August you answered all twenty open decisions, and your column emptied to zero. Everything that was waiting on you is now decided and awaiting its build spec; the writes among them still sit behind rule 2's three conditions, unchanged. Liberty's side changed shape the same day: Aspen and Summerset are already being onboarded, in flight rather than un-asked, and the sendWorkOrders + sendLeaseActivities email is tabled by your call, written but unsent, so those two stay in Liberty's column as an ask on hold. The design is locked. Locked is not buildable: nine build-spec areas get written next, before any code.

The spine

Your dividing line

The single rule the whole front end hangs on, stated as you defined it on 31 July.

Before the line

They exist only in GHL

Ebook downloads, waitlist signups, the nurture ladder, every email blast and broadcast. Nothing touches Entrata. Bulk marketing never crosses in either direction, ever.

They name a property
After the line

Every 1:1 mirrors into Entrata

A guest card is created, and chat, email and text all log against it. Liberty sees the whole thread in the system they already work in.

Two things to hold alongside it. Today the Entrata side of that line is entirely write-blocked, so crossing it produces a local record and a queued intent, and Liberty sees exactly nothing. The rule describes the finished system, not the one running now. Your 5 Aug decision gives that a date on the buildings you own, Aspen then Summerset, once each is live and signed off in writing. It gives Owyhee nothing, that one stays read-only because it isn't yours, so whatever we build to let Liberty see us there is the permanent answer, not a stopgap. And there's one deliberate exception: escalation to a human doesn't ride the line. It goes out of band to what Liberty actually watches, which Alex confirmed on 3 August is email and not their Google or Breakroom chats, and only files the Entrata note as the record, so a prospect asking for a person never waits on a permission.

The three modules

Where each piece actually stands

Load-bearing capabilities only. Highlighted rows are the ones gating the most behind them.

Module 01

Front-end leasing

Capture, qualify, converse, tour, hand off. Ebook to application.

Ebook & waitlist capture into GHLShipped. Write-only, tagged, referral capture works.
Availability pipeline to the siteAccess gate cleared. Remaining work is wiring, not permission.
Guest-card dedupe by emailA read. Works today.
The property-interest triggerAnswered 13 Aug: AI judgment decides, gated hard on (phone OR email) AND a first name. No guest card without a way to follow up. Awaiting build spec.
Creating the guest cardDecided 13 Aug: in the first sign-off, sendLeads + updateLeads at go-live. Rule 2 still bars the write until you own the property, Foothold is live on it, and the sign-off is on paper.
Website chat & email botOur transport. Needs the AI-disclosure review first.
TextingTwilio. A2P 10DLC registration is the long pole.
Entrata sending anythingNo send method exists in 128. It logs, it never transmits.
Logging communications to EntrataDecided 13 Aug: every 1:1 logs onto the lead's own Entrata record via updateLeads events, numeric typeId, transcript in comments, plus the five-line weekly digest. No standalone Liberty-facing page. A write, so rule 2's three conditions still gate it; it queues until then.
Showing real tour availabilityProbed 5 Aug and the calendar is configured, not empty: 30-minute tours, 2 hours' lead time, agent-guided M-F 8 to 4, self-guided all seven days 6 to 6. Liberty still books by hand, so show it as availability, never as a promise.
Consent check before any messageProbed 5 Aug. Opt-in per channel per resident, and the customer IDs come off the lease read. A gate on the send path, not a report.
Booking a tourDecided 13 Aug: propose for agent-guided, commit for self-guided. Committing is a write; rule 2 still gates it.
Application handoffDecided: hand over the hosted URL, never collect the data.
The apply URL itselfConfig item. Asked Alex 3 Aug whether every property has a standing apply link. Unanswered.
Tracking application progressScreening status and stage are readable.
Escalation: the alert that reaches a humanAnswered 3 Aug: email Liberty's leasing team. Per-property recipient, they're restructuring.
Escalation: the Entrata noteA write, inside the go-live signature scoped 13 Aug. Costs the record nothing but timing.
A ticket or task for a prospectNo such object anywhere in 63,848 lines of spec.
A Foothold lead source"Website" is Liberty's site. Ours has nowhere to land. Rides in the tabled sendWorkOrders email whenever it goes (your 13 Aug call); the GHL reconciler gets built regardless.
Setting lead statusRead-only. Entrata assigns it, we can't.
Amenities & concessionsBoth calls succeed and return nothing. Not configured.
Gated by: go-live plus the signature, scoped 13 Aug: sendLeads + updateLeads at go-live, on owned properties. The tour calendar is probed and real.
Module 02

Physical touches

Move-in, birthday, pre-renewal, referral, review. Handwrytten and gift cards.

Resident & lease trigger dataThe full rent roll reads clean. 52 leases, names, move-in dates.
Welcome card at move-inTrigger readable, Handwrytten needs no Entrata at all.
Resident birth datesFound 5 Aug, and not where we looked. The lease record has none, the lead record does, and the join to the resident is proven. Month and day only, never the year. It covers 65% of current residents, not all of them. We swept the whole history and 57 of the 88 current residents have a date: 18 never appear in the lead data at all and 13 appear with the field blank, and neither gap closes by looking further back. So the birthday touch is real for two thirds of the building and the form below covers the rest.
Birthdays from our own formNow the fallback, not the source, and it carries real weight: roughly a third of the building. That's the 31 of 88 current residents Entrata has no birth date for. Decided 13 Aug: the Welcome Profile rides the mailed Handwrytten welcome packet, the no-birthday annual touch is a Thanksgiving card, and the weekly digest flags new tenants missing a DOB so the gap shrinks.
The years-as-resident variantTenure computes from move-in date today.
Pre-renewal card timingLease ends are readable. Card lands ahead of Liberty's offer.
The pet / no-pet split, and the pet giftSolved 5 Aug. The lease read carries the pets, with names: thirty of the fifty-two leases, thirty-four animals. No form, no new permission. One hard filter: assistance animals aren't pets under fair housing, so they come out of the gift program and out of any pet marketing.
Renewal milestone detectionRenewal state and stage both read.
Sending a renewal offerNo method exists. Liberty does this natively.
A referral record"Referral" appears once in 2.8MB, as a lead-source name.
Referral payout detectionReconcile the GHL code against signed leases.
Review ask: move-in and renewalTwo of the three triggers work today.
Review ask: work-order completegetWorkOrders landed 3 Aug. The third trigger has a real data source now.
Handwrytten & gift cardsDirect API. Account not provisioned. No Entrata dependency.
Logging the touch back to EntrataCards go out and Liberty sees nothing. Moved 5 Aug, from your column to Liberty's. You parked the ask that morning and reversed it the same day, and on 13 Aug you tabled the email, so it's written but unsent: sendLeaseActivities isn't on the key and that ask has never been made, and it rides in the same email as sendWorkOrders rather than a second one, whenever that goes. Until it's sent and granted, our touches log to Foothold's own store and surface in the weekly digest. It's the only method in all 128 that appends an activity, and it puts our touches in their system instead of their inbox, which is less mail for them, not more. Two things it doesn't change: a grant still isn't permission to call it (it's a write, so the sign-off still applies, and at Owyhee it stays unused either way), and it only reaches resident records, which is the half with no other route. ⚠️ Corrected 10 Aug: this row used to end "a lead-level chat can never be logged at all, there's no lead-event write method anywhere in the spec." That was wrong. updateLeads and sendLeads both carry an events array with a free-text comments field and both are on the key. The ask is unchanged, it's for resident touches and that's still the gap. And nothing loosened: appending a lead event is a write, so rule 2 governs it exactly the same way.
Anything running against real residentsNo NPI-owned property on the key yet. Owyhee is Liberty's building. Liberty is onboarding Aspen + Summerset now, in flight as of 13 Aug.
Gated by: Aspen onboarding (in flight with Liberty as of 13 Aug) and one permission. The sendLeaseActivities ask is tabled, written but unsent, riding with sendWorkOrders whenever it goes.
Module 03

Work orders & FlightDeck

Ticket visibility, the resident follow-up, and the bridge into FlightDeck.

Reading work-order statusGranted and probed 3 Aug. Real production work orders came back.
Detecting completionSame grant. The 3 Aug probe returned Completed records.
Work-order webhooksStill IDs only, but the read that hydrates them is on the key now.
Make-ready progress signalCompleted "Make Ready" records read on 3 Aug, parent and child.
Ticket vocabulary & Liberty's staff rosterPicklists probed 5 Aug: categories, problems, priorities, statuses, plus twelve named Liberty employees. Tickets and escalations can name a person. It still doesn't let us assign one, that's a write.
Notice detection & turn startNotice status and available dates both read.
What the resident follow-up actually isAnswered 10 Aug, and it left your column. It's an AI-generated personal message about the resident's specific issue: "did your back door get fixed?" Not the survey that got cut as impersonal, that stays cut. This is the version that survives the objection which killed it, because it's specific, personal, and from the ownership number rather than a form. And it doesn't cross the watch-the-scoreboard line, because the message goes to the resident, not to Liberty: nothing per-ticket is sent to them, asked of them, or logged against them. Runs on fields we already read (problem, location, description), consent-gated both sides, no new permission. One rule comes with it: the AI renders from the real field values and never invents detail, because quoting someone's issue back wrong is worse than being generic. 🚫 Owned properties only, never Owyhee. Closed 13 Aug: poll fires it, qualifying statuses in config, next business morning, an AI-judgment gate decides which tickets deserve one at all, and the review ask is a second message a few days behind, fired on the event, never the reply.
Service-call card left on siteMockup exists. No API involvement.
Tickets by email to the PMStill the whole loop, both directions, and at Owyhee it's permanent. sendWorkOrders has never been granted.
Filing the resident's ticket for themMoved 5 Aug, from your column to Liberty's. You decided the agent should file the work order itself on properties you own, once Foothold is live on them. sendWorkOrders isn't on the key and that ask has never been made, so Liberty gates it now, not you. Two other things ride with it: verify the resident first, because an unverified ticket sends a real tech to a real unit (phone on file is the strongest and cheapest match, unit plus one more factor next, birth date never on its own at 65% coverage, and no match means a human takes it). And until then, and at Owyhee forever, point them at the resident portal, which already carries half the building's 785 tickets. On 13 Aug you tabled the ask, so it stays unsent for now; the redirect posture holds.
FlightDeck: full rent roll52 leases with scheduled charges. Verified.
FlightDeck: loss-to-leaseComputable straight from the API. No PM report needed.
FlightDeck: renewal exposureLease end dates by month.
FlightDeck: NOI actuals90 GL accounts, unit-tagged. Drop-in for the monthly rec.
FlightDeck: NOI vs budgetBudget methods absent. Actuals yes, budget no.
Webhook receiverA Worker. Entrata pushes, so outbound-only holds.
Scoping to "the NPI org"There is no NPI org, and there never will be. Decided 13 Aug: FlightDeck is internal-only today, so scoping is the per-property allowlist, built as a security boundary from the first line. A build spec now, not a decision.
The API product for other asset managersDecided 13 Aug: internal-only today, building toward self-serve software long-term. Not a done-for-you services business. No outside customer in this design.
Gated by: one permission. The tenancy call closed 13 Aug: internal-only today, toward self-serve. Alex's group grant landed 3 Aug, all of it probed 5 Aug. The sendWorkOrders ask is tabled, written but unsent, owned properties only.
Nothing waiting on you

All twenty decisions are answered. Nothing waits on you.

This section used to carry the open list. On 13 August you answered all twenty; the full set with answers is on decisions.html and in DECISIONS.md. The design is locked. Locked is not buildable: nine build-spec areas get written next, before any code, and rule 2 stands untouched. The two heaviest calls stay below for the record, each carrying its answer.

Decision 01 · answered 5 Aug, scoped 13 Aug

You've decided the writes turn on, on the buildings you own, the day Foothold goes live on them.

Nothing is authorised yet, and that matters. Three things have to be true before a single write goes out: you own the property, Foothold is live on it, and you've signed off in writing naming that property and those methods. Aspen first, then Summerset. Owyhee isn't covered and won't be, it's Liberty's building, and everything we've verified so far was measured there, so a working probe was never a licence to write.

The visibility half got its answer on 13 Aug too: Liberty's surfaces are Entrata itself plus a five-line weekly digest email, no standalone Foothold page, and that's the permanent shape at Owyhee, not a stopgap. And the allowlist underneath all of it goes per-property rather than away, same choke point, same fail-safe, unknown property still means read-only. It has to be built that way from the first line, because bolting a per-property gate onto a global bar afterwards is where the accident happens.

Unblocks the write half of Modules 1 and 2, once Aspen is live and signed. Scoped 13 Aug: the first signature names sendLeads + updateLeads at go-live; work orders and lease activities ride a second one. The property-interest trigger got its own answer the same day.
Decision 02 · answered 13 Aug

What is FlightDeck's tenancy model, given there is no NPI org?

Aspen and Summerset will live inside Liberty's Entrata org next to 98 other buildings. Access is org-scoped with per-property grants, so "the NPI org" is really a property-ID subset of a property manager's org.

That makes onboarding per-PM, not per-asset-manager, puts a third party with no contract with NPI in the middle of every sale, and turns the property-ID allowlist into a security boundary rather than a safety rail.

Answered 13 Aug: internal-only today, building toward self-serve software long-term. Not a done-for-you services business. The per-property allowlist still gets built as a security boundary from the first line, because the long-term direction depends on it.

Closed. Module 3's product thesis is settled; what's left there is build spec.
Back from Alex

The 31 July ask landed, and all of it has now been probed

One email, five items, all of it answered on 3 August and every granted method called on 5 August. Four things are open with them now: one is in flight on their side, one is sent and unanswered, and two are written but tabled by your 13 Aug call.

Four things open with Liberty, in this order

1. Aspen and Summerset onto the key. In flight as of 13 Aug: Liberty is already onboarding both, so this is monitor-and-verify, not an ask. It still gates the whole write half, since the write rule only lifts on buildings you own. 2. The apply link. Asked 3 Aug, unanswered, per property, whether tenants can apply anytime. Don't chase it with a second email. 3. sendWorkOrders, for owned properties. New on 5 Aug and never asked in any form. 4. sendLeaseActivities. You parked it on 5 Aug and reversed that the same day, and it goes in the same email as item 3: you're already asking for the bigger write, so the activity note costs one round trip instead of two. Pitch it as what it is for them, our touches landing in their system instead of their inbox. On 13 Aug you tabled that email, so items 3 and 4 are written and waiting on your go, not on a decision. Neither grant is permission to call anything, the sign-off still gates both, and at Owyhee the activity note stays unused even if they say yes.

Work orders, the whole group. Granted

The big one. Granted and probed the same day: real production work orders, including Completed "Make Ready." The picklists went on 5 Aug and came back carrying twelve named Liberty employees, so a ticket can point at a person.

Resident birth dates. Granted, and empty

getMitsLeases works and holds no birth dates at all. The lead record does, so the birthday card has a real source. It just isn't the one we asked for. We measured how far it reaches: 65% of current residents. The rest need the form, and no permission fixes that, so there's nothing more to ask Liberty.

Tour calendar & consent state. Both real

Better than expected. The calendar is configured, not empty, and its self-guided setup matches the lock box story Alex told. Consent returns opt-in per channel. One correction: the window is seven days, not sixty.

How do we reach a human? Answered

Email, not their Google or Breakroom chats. Liberty's direct leasing and manager team, adrienne@libertyassetgroup.com today. They're restructuring that team, so treat the recipient as per-property config.

The measured before-picture

What Owyhee actually looks like

Pulled live on 31 July. One comparable Boise Class C building, and the denominator for every claim the brand thesis makes.

80%
of July leads came from Zillow. 87 of 109.
10%
came direct. The floor to beat, not zero.
52
units, 4 buildings, 4 floor plans, 49 leases current
2
units available, both early September
$125
a month below market on the sampled 2x2, computed straight from the API
76%
of the week has no human on site. Office hours are M-F, 9 to 5.

The probe ran on 31 July, so the month may be short a day and the window wasn't verified as a clean calendar month. Treat 109 and the 80/10 mix as directionally right, not audited. Re-pull a closed month before any of it goes in front of a partner.

Sequencing

What gates what

There is no test company

We asked for one and got a live occupied building instead. Every call is against real residents, real prospects and real staff, which is the whole reason for the read-only rule.

Only Owyhee is on the key

Aspen closes 8/31 and isn't in Liberty's Entrata yet. Summerset either. Module 2 has no property it can legitimately run against until one of them lands. Liberty started onboarding both; in flight as of 13 Aug.

Aspen doesn't inherit writes, it earns them

The read-only rule is still a property-class rule, so the day Aspen onboards it's read-only. Your 5 Aug decision says it comes off, on the buildings you own, when Foothold goes live on them. Three things, all of them: you own it, Foothold is live on it, and you've signed off in writing naming the property and the methods. Owyhee never qualifies, it isn't yours.

The allowlist goes per-property, not away

Same single choke point, same deny-by-default, same fail-safe. What changes is that a named property can carry a named set of permitted writes instead of the list being empty everywhere forever. An unknown or unreadable property config still means read-only. Build it that way from the first line, because retrofitting a per-property gate onto a global bar is exactly where the accident happens.

Half the building already files its own tickets

Of Owyhee's 785 work orders, 390 are resident-portal, 388 staff-entered, 7 system make-readies, and all 71 work-order locations are portal-enabled. That's why we redirect rather than intake, today and at Owyhee permanently. Two things to know before anything counts or texts: priority is dead weight (780 of 785 are Medium, triage on problem and location instead) and 312 of 785 are child tickets, so collapse them or one repair sends three messages.

Responsiveness is an aggregate, and it cuts both ways

Your call, 10 Aug: watch the aggregate, not individual tickets, which affirms the line the whole escalation design already rested on. What's new is that a responsiveness metric should now exist, and the design had none. It computes read-only off the work-order read (created and completed timestamps, plus date filters), no new permission and nothing to ask Liberty for. Measuring the aggregate isn't policing; chasing one ticket still is. ⚠️ It's dual-purpose and that's a constraint, not colour: good numbers are marketing proof, bad numbers are Liberty's accountability metric, so the definition gets written down once and never re-cut by window. Four traps: skip the system make-readies, collapse parent and child, don't segment on priority (780 of 785 are Medium), and confirm the created timestamp actually comes back populated before building on it, because it's in the spec and hasn't been seen live. Worth splitting in-hours from out-of-hours too, since 76% of the week has nobody on site. No target is set yet, and the 24-hour number on the scorecard is a first contact target, not a resolution one.

Filing a ticket means verifying the resident

An unverified ticket sends a real technician to a real unit, so this is a safety gate, not a formality. Phone on file is strongest and cheapest, an inbound text from a matching number is a match with no friction at all. Unrecognised number: unit plus one more factor. Birth date is never the only gate, it covers 65% of residents, so a third of the building couldn't pass it. No match, a human takes it. And the after-hours hole doesn't close: an 11pm Friday ticket still waits for Monday, so a real emergency gets the phone, never a chat handoff and never an email.

Webhooks don't change the poll

Five events exist and none of them is availability or pricing, so the twelve-minute poll stays. What they add is the work-order and application layer. Decided 13 Aug: provision them, bundled into the Aspen + Summerset onboarding already in motion, and observe read-only at Owyhee. The poll stays the design either way.

FlightDeck can move earlier

The asset-management tiles are already unblocked. Rent roll, loss-to-lease, renewal exposure and NOI actuals all read today, so Phase 5 isn't really fifth.

Consent gates the send path now

Opt-in state per resident, per channel, reads clean as of 5 Aug. Nothing goes out to a resident or a lead without checking it first. The pick list behind it is the tightest rate limit on the key, ten calls a minute, so it gets cached rather than called per message.

The pets were in the lease read all along

Found 5 Aug. Thirty of the fifty-two leases have pets, thirty-four animals, and each record carries the pet's name along with type, breed, color, age and weight. It joins to the resident on the same key the birthday does. No form to build, no permission to ask for. One filter is mandatory rather than polite: assistance animals aren't pets under fair housing, so those records come out at ingest, out of the gift program, and out of any pet-themed marketing. The work-order read carries pet info too, which belongs in front of whoever gets sent to the unit.

We never take an SSN

Your call, 5 Aug: NPI has no use for a Social Security number and doesn't want the liability. The lease export defines the field and it's on our key, though Liberty leaves it empty, so there's nothing exposed today. It gets stripped anyway, at the same single choke point that enforces the read-only allowlist, before anything is stored, logged or shown to a model. Same rule on lease documents, where Aspen's forty-four executed leases each do carry one.

The code guard is the only guard

Both write permissions stay enabled by your call, so nothing on Liberty's side will catch our mistake. The maintenance group is reachable now too, reads only, which is a reason to be more careful rather than less. The deny-by-default allowlist has to exist before the first live call, and it has to be per-property from that first call, not global now and split later.