Where your data lives
Which server holds your records and files, and what leaves it.
- Version
- 0.8
- Effective date
- Not set — in force for the pilot
- Source
- legal/DATA_RESIDENCY.md
DocSync — Where does my data live?
⚠️ PRE-RELEASE DRAFT — NOT LEGAL ADVICE — NOT SETTLED BY AN AUSTRALIAN LAWYER
What this is. A pre-release draft, prepared for review by an Australian legal practitioner. Not reviewed, settled or approved by one, and not legal advice to anyone. There is no registered company name, ABN, ACN or registered address yet: the bracketed placeholders are real gaps, listed in §11.
And it is nonetheless live, which is why the paragraph above matters. This page is served, without a login, at
docsync.tech/legal/data-residency. It is a statement of fact about where your data sits, not a promise: nobody accepts it and it grants no rights. It is published in draft because a builder deciding whether to put their job records into DocSync is better served by an accurate map they can read today than by a settled one they cannot.What happens next. A settled version will be issued once an Australian legal practitioner has reviewed this pack and every placeholder is filled, and everyone will be asked to accept the settled Terms and Privacy Policy it accompanies. Until then, and this is a rule we hold ourselves to rather than an instruction to you: we will not put this document into a tender or present it as a settled commercial commitment.
Every statement about system behaviour is traceable to source code and infrastructure configuration read on 2026-08-27 (branch
full-web-app-build) and re-verified on 2026-08-31. Where a fact could not be established from code, this page says so in its own words — as a fact about the service — rather than making a claim.The statements about how this deployment is configured — the mail backend, the AI provider, the operator surface, the worker count, the backup destination and retention — were read off the production server itself on 2026-08-31, not from a file in the source repository. An earlier version of this pack drew a deployed value from a repository default and was wrong about it; a configuration claim now names where it was read.
Document version: 0.8 · Effective date: [EFFECTIVE DATE]
| Entity | [LEGAL ENTITY NAME] (ABN [ABN]) |
| Effective date | [EFFECTIVE DATE] — not set. This page is nonetheless published and current today; see the banner above |
| Contact | [CONTACT EMAIL] |
| Companion documents | legal/PRIVACY_POLICY.md · legal/SUBPROCESSORS.md |
The one-paragraph answer
Everything you put into DocSync — your records, your files, your photographs and your backups — is held on one server in [HOSTING REGION]. That server is a virtual machine we rent from Microsoft Azure, so Azure holds it: row 2 of the service-provider list records what Azure receives as everything, because the machine's disks — and any snapshot Azure takes of them — are Azure's to hold, and we have not verified how they are stored. Beyond that hosting provider, no third party holds a copy of your file store or your database: the off-site backup destination has never been set, so no copy of either has ever left the machine.
There is no content delivery network, no third-party object storage, no analytics provider and no log-shipping service.
That is a statement about copies, not about content. Parts of what your team types do leave. Earlier versions of this page tried to say there was only ever one such thing, and were wrong four times running — each time a new path was found next to the one just fixed. So this page no longer makes that kind of claim at all. What follows is the list, measured from the code and the deployment on 2026-08-31. If we find another, it goes in the list.
What leaves that server today is a list, not a count. None of the items on it is your file store or a copy of your database, but one of them does carry record text your team typed: a place name and a pair of coordinates, to the weather service; our own domain name and an administrative email address, to the certificate authority; and AI prompt text, to the model provider. Outbound email is a further path: it is built, it is switched on in the product, and it delivers nothing at all. If we find another, it joins the list — and the list is the only thing that has to change, which is the reason it is written as a list.
(1) A place name and a pair of coordinates. What carries part of a project's location off this server is a list, not a count. Four successive drafts of this pack published a count of it and each one was falsified within the week by a path next to the one just fixed, so the count is gone and the list is what we state: the project's City field; the project's stored latitude and longitude; and the project's own name, which goes to the AI provider in a prompt — path (3) below — and which on a residential job is often the street address. If we find another, it joins the list. The first two are what this paragraph is about. We send the City field to Open-Meteo to turn it into coordinates, and only when it holds a plain place name — letters plus the joiners a locality name can contain, at most four words. The address line is never a source. We then send a latitude, a longitude and a date to the same service for the weather. Those coordinates are the ones stored on the project, which somebody may have typed in by hand rather than obtained from the City field, so they are rounded to two decimal places — about a kilometre — before they are sent: the request names a suburb rather than a building, and the value stored on your project keeps its full precision. No project name, no identifier, no key, and no end-user IP address — the request is made by our server, not by your browser. Open-Meteo is operated from Germany, according to its own published information; we have not independently verified where its servers are. See §6, which states the two limits on the City field.
(2) Our domain name. Sent to Let's Encrypt, in the United States, together with an administrative email address, to issue the certificate that encrypts your connection. No customer information is involved. See §10.
(3) AI prompt text — and this is the one that carries your records. AI features are switched on in the pilot deployment: the provider setting is DeepSeek, a key is configured, and the AI entitlement is active on the one company using DocSync. When someone uses one of the eight AI surfaces, the text of the prompt — record titles, descriptions, short excerpts of a record's own text, and other free text your team typed, which can therefore include a person's name — is sent to that provider, whose endpoint is outside Australia as at 2026-08-31 (§5 explains how that is determined and what would change it). We have not obtained that provider's published terms, so we do not know how long it keeps what we send or whether it uses it to train models, and we will not tell you otherwise. Section 5 says exactly what is sent, and to whom. A company owner can switch AI off for their company at any time, from Company → Editions, at no charge, and you can ask us to do it for you.
(4) Email — built, switched on in the product, and delivering nothing. DocSync composes invitations, password-reset links, notifications, share links, scheduled reports and its own error alerts. On this deployment the mail backend is console, which writes each message to the server's own log and discards it. No message is handed to a mail relay, so our relay, SMTP2GO, receives nothing at all today and is recorded on the service-provider list as receiving nothing. The log line records the recipient address, the subject and the message length; it does not record the body, and it stays on the same server as everything else. The plain product consequence: a password reset, an invitation or a notification reaches nobody. Where DocSync confirms one of those actions on screen it reads this deployment's own email status first and says the message was not emailed rather than implying it was sent — the password-reset screen, the two invitation screens and the meeting-minutes screen all do. Every other screen says nothing about delivery in either direction, so nothing in DocSync should be read as proof that a message arrived. §4 describes what the relay would receive on the day a real mail transport is configured, because that is a configuration change rather than a new release, and this page must be true then too.
Other paths exist in the software and are switched off — an off-site backup destination, a rented GPU host for 3D reconstruction, an inbound-mail provider and an accounting export. They send nothing while they are off. Section 8 lists them, because turning one on is a configuration change rather than a new release.
The picture
flowchart TB
subgraph AU["Australia — one virtual machine in HOSTING REGION"]
direction TB
CADDY["Reverse proxy / TLS<br/><i>the only thing with a public port</i>"]
WEB["Web app"]
API["API server"]
PG[("PostgreSQL<br/><b>all project records</b><br/>+ audit trail")]
MINIO[("Object store<br/><b>documents · drawings<br/>photos · signatures · video</b>")]
BAK[("Nightly backups<br/><i>same disk as the data</i><br/>kept for the retention period in §3.1")]
CADDY --> WEB
CADDY --> API
API --> PG
API --> MINIO
PG -.nightly.-> BAK
MINIO -.nightly.-> BAK
end
USER["Your browser<br/>or site tablet"] -- HTTPS --> CADDY
subgraph OUT["Leaves the server today"]
direction TB
MET["Open-Meteo<br/>City field, then lat/lng + date<br/>coordinates rounded to 2 dp<br/><b>operated from Germany</b><br/>no identifiers, no end-user IP"]
LE["Let's Encrypt — United States<br/>our domain name<br/>+ an admin email address<br/><b>no customer content</b>"]
AI["AI provider — DeepSeek<br/><b>OUTSIDE AUSTRALIA</b><br/>prompt text, incl. free text<br/><b>SWITCHED ON in the pilot</b>"]
end
subgraph NOMAIL["Built, switched on in the product, delivering nothing"]
direction TB
MAIL["Mail relay — SMTP2GO<br/><b>RECEIVES NOTHING TODAY</b><br/>EMAIL_BACKEND=console<br/>messages are logged here and dropped"]
end
API -- "every email: logged, then dropped" --> MAIL
API -- "weather auto-fill" --> MET
CADDY -- "certificate renewal" --> LE
API -- "AI features" --> AI
subgraph DORMANT["Configured but switched OFF today — these receive nothing"]
direction TB
OFFSITE["Azure Blob — off-site backups<br/><b>NOT CONFIGURED</b><br/>nothing has ever left the box"]
GPU["GPU worker — 3D reconstruction<br/><b>NOT CONFIGURED</b><br/>would receive site walkthrough video"]
INB["Inbound email ingestion<br/><b>NOT CONFIGURED</b>"]
ACC["Xero / QuickBooks export<br/><b>NOT CONFIGURED</b>"]
end
BAK -.->|"not enabled"| OFFSITE
MINIO -.->|"not enabled"| GPU
API -.->|"not enabled"| INB
API -.->|"not enabled"| ACC
style AU fill:#e8f4ea,stroke:#2d6a3e,stroke-width:2px
style OUT fill:#fff4e5,stroke:#b5651d,stroke-width:2px
style NOMAIL fill:#f0f0f0,stroke:#888,stroke-dasharray:5 5
style DORMANT fill:#f0f0f0,stroke:#888,stroke-dasharray:5 5
style AI fill:#fdecea,stroke:#c0392b,stroke-width:2px
style PG fill:#ffffff,stroke:#2d6a3e
style MINIO fill:#ffffff,stroke:#2d6a3e
style BAK fill:#ffffff,stroke:#2d6a3eTwo notes on the diagram, so nothing is missed. Diagram labels cannot carry square brackets, so the hosting region appears above as HOSTING REGION without them — it is the same placeholder [HOSTING REGION] listed in §11, and anyone filling the placeholders must change it here too. For the same reason the backup box points at §3.1 rather than printing a number.
1. Primary data — your records
| Question | Answer |
|---|---|
| What | Every project, RFI, drawing register entry, defect, daily log, timesheet, incident, claim, budget line, directory entry and audit-trail entry |
| Where | PostgreSQL 16, running as a container on one virtual machine in [HOSTING REGION] |
| Who else holds a copy | Nobody |
| Reachable from the internet? | No. The database has no published port. Only the reverse proxy is exposed; the database, the file store and both application servers sit on a private network on that host |
| Encrypted at rest? | Not by us. See §7 |
2. Files and photos
| Question | Answer |
|---|---|
| What | Documents, drawings, specifications, photos and their thumbnails, generated PDFs, signature images, site walkthrough video, and your own data-export ZIPs |
| Where | A MinIO object store, a container on the same virtual machine |
| Third-party object storage? | No. Not S3, not Azure Blob, not Google Cloud Storage. The storage endpoint points at a container on the private network |
| How files are keyed | Every object key begins with your company id: {companyId}/{projectId}/{entity}/{uuid}/{filename} |
| Are file keys ever exposed? | No. Downloads stream through an authenticated endpoint; the browser never sees a storage key or a direct storage URL |
| Uploads | Stream through our API with a size cap. There is no direct browser-to-bucket upload, so no upload ever bypasses our access control |
3. Backups
| Question | Answer |
|---|---|
| How often | Nightly |
| What is in a set | A full database dump plus a mirror of every stored object, with a manifest |
| Where | The same disk as the data it backs up, on the same virtual machine |
| How long | Up to [BACKUP_RETENTION_DAYS] days — today that number is 15 (a 14-day retention, evaluated only when the next nightly run happens) |
| Encrypted? | No. The database dump is written in its native format with no encryption step |
| Off-site copy | None today. The off-site target is configured in our scripts but the destination has never been set — nothing has ever left the box |
| How big | 2.4 GB of backup sets on the server as at 2026-08-31, on the same disk as the database they back up |
| When | The prune-and-backup job runs at 02:00 Australian Eastern Time each night |
3.1 What the off-site gap actually means — say this out loud to your IT person
We take a backup of the database and the file store every night and keep it for up to [BACKUP_RETENTION_DAYS] days — but that backup is stored on the same server it is a backup of, no copy has ever been taken off that server, and until that changes we do not offer any disaster-recovery commitment, any recovery point objective for the loss of the server, or any promise to restore your data on request. Today that number is 15.
A backup held on the disk it backs up protects you against a mistake — a bad deployment, a corrupted table, a deletion that should not have happened. It does not protect you against the loss of the server itself. If that server were destroyed the backups would be destroyed with it. We are telling you this rather than describing our "backup regime", because the difference between those two sentences is the whole of the risk you are taking. Old backup sets are only removed after a successful backup, so if backups start failing the history is kept rather than pruned.
We restore-test regularly and the restore path is measured and works — but it has only ever been tested from a backup set that lives on the box being restored, which is not the scenario a disaster-recovery plan exists for.
When off-site backups are enabled, the destination will be Azure Blob Storage, and:
- the storage account's region is chosen independently of the virtual machine's region and must be set to an Australian region, or the residency statement on this page breaks the day backups start;
- it becomes a subprocessor holding a complete copy of the entire database and every uploaded file, and will be listed as such with notice before it is switched on;
- it is not settled whether we would encrypt those backups before upload, and today we would not. Protection would rest on TLS in transit, the storage provider's own at-rest encryption, and the secrecy of a shared-access URL that is itself a bearer credential. We will state the answer here before the first backup leaves, not after.
3.2 What happens to all of this when you delete the account
When a company owner asks us to delete the account we wait at least seven days — and never less than seven full days, because the deadline rounds up to the next midnight in Sydney — during which any owner can cancel and every member sees a banner; after that we destroy the company's records and files from the live service completely, in one operation, proved by a test that walks every table and every foreign key in the database.
Five things survive that deletion, and we would rather you knew all five.
(1) A tombstone. One permanent record holding the company's name, the email address of the person who asked, and the date. It exists so we can answer "was this company deleted, and when" years later, and so a deleted account cannot be silently re-created.
(2) Error diagnostics we could not attribute to you. When something fails on a request that was not signed in — a failed sign-in, an expired reset link, an anonymous view of a share link — we record a diagnostic that carries no company. The deletion cannot find those rows because they are not linked to your company. They age out on their own within 30 days, or sooner once 10,000 have accumulated.
(3) Backups taken before the deletion. See §3. Your data is gone from the live service on the deletion date, and gone everywhere once the backup window closes.
(4) Background jobs that were still running when the purge ran. DocSync sends email through a queue, and a queued message holds the recipient's address, a subject naming your company and the full body of the message. The purge deletes those rows — but it cannot delete one that a worker is holding at that instant. A follow-up sweep chases the stragglers, and deletes them regardless after about three hours. The tombstone carries a count of how many were still outstanding, kept current until it reaches zero, so the record of the deletion can never overstate what was destroyed.
(5) Text already sent to our AI provider. If AI features were switched on — and they are switched on in the pilot deployment — prompt text has already left this server. There is no deletion path to it: we cannot reach another company's systems, and we have not obtained that provider's terms, so we do not know how long it keeps it. Deleting your account does not recall it, in the same way that a report you have already emailed out cannot be recalled. The only control is switching AI off before the text is sent. See §5.
PRIVACY_POLICY.md §11 sets out the full process, including how to cancel a deletion and what an export contains.
4. Email in transit — and it is not in transit today
Read this first, because it changes everything else in this section. No email leaves this server. The deployment's mail backend is console: DocSync renders each message, writes a single line to the server's own log — the recipient address, the subject and the message length, not the body — and discards it. Nothing is handed to a relay, so our relay receives nothing and has received nothing, and the count in the one-paragraph answer above is three rather than four.
The plain product consequence, which we would rather state than bury: invites, password resets, notifications, share links, scheduled reports and our own error alerts reach nobody. A person who asks for a password reset gets no email. The reset screen reads this deployment's own email status before it answers and says the message was not emailed rather than implying it was sent: it tells you a reset link was created, that we cannot confirm it went out, and to ask whoever set up DocSync for your company. The two invitation screens and the meeting-minutes screen do the same. Every other screen says nothing about delivery in either direction, so nothing in DocSync should be read as proof that a message arrived. Any notice we owe you is sent by hand from a person's own mail client.
The rest of this section describes what happens on the day a mail transport is configured, which is a change to one setting and a restart rather than a new release. It is written in the present tense because it must be accurate on that day, and because you should be able to read what you are agreeing to before it becomes true rather than after.
Every email DocSync sends — invites, password resets, notifications, scheduled reports, digests — is queued on our server and handed to a mail relay for delivery.
The relay would see the whole message, not just a link: the recipient's address, the subject, and both the plain-text and HTML bodies. That matters more than it sounds, because:
- subjects carry your data — several are built from a project name or a record title;
- invite and password-reset emails carry live single-use links (14 days and 1 hour respectively);
- scheduled report emails carry a table of your actual record rows, not just a notification.
The relay is SMTP2GO, chosen partly because it is an Australian and New Zealand company; the country in which its mail servers process our messages is not established, and we have asked. Country of incorporation is not country of processing, and we are not going to let one become the other on this page. Its retention period for message content and delivery logs is also not established. Given that report emails carry your record data and invite emails carry live credentials, that gap matters more than it first appears, and it is one of the reasons this page exists in the form it does.
Deliberate counter-example, and a good sign of the design intent: our own operator error alerts strip the exception message before sending, precisely because that field is the one most likely to carry your record titles and names, and an alert leaves the system to a mailbox outside the app's access controls.
5. AI prompts — the only routine flow of your content outside Australia today, and it is switched on
AI features are switched on in the pilot deployment, and prompt text leaves Australia today. This table is written in the present tense because that is the true tense. You should be able to read it whether or not you have decided anything.
Why this page can name a country at all, and what would change it — because the software does not hardcode one. Every AI screen in the product asks the server where a prompt would physically go under the configuration the server is actually running, and the server answers one of three things: offshore — a vendor endpoint whose address we ship (DeepSeek's own host, or Anthropic's, or Google's), and we know where those are; on this server — a local model on loopback, so nothing leaves the machine at all; or unspecified — an endpoint the operator supplied, whose country this process has no way to know, where saying "Australia" would invent a residency claim and saying "offshore" would state a falsehood, so it names no country. That mechanism exists because three screens once hardcoded the words "outside Australia", and a disclosure somebody reads before pressing a button has to describe the deployment they are actually using — a hand-written sentence cannot, because nobody re-reads it when the environment changes.
*As at 2026-08-31 the deployment answers offshore: AI_PROVIDER=deepseek, pointed at the vendor's own endpoint. Everything this page says about the AI provider's country is a fact about that configuration, not a permanent property of DocSync.* Changing it is one environment variable — which is why the screens ask instead of asserting, and why an onshore-or-on-premises answer costs a configuration change rather than a rebuild. If it changes, this page changes with it and the notice commitment applies.
| Question | Answer |
|---|---|
| On or off? | On. Both switches are set: the deployment's provider setting is deepseek with a key configured, and the AI entitlement is active on the one company using DocSync |
| Provider | DeepSeek, at api.deepseek.com — the backend the software is built against |
| Country | Outside Australia as at 2026-08-31 — read from the deployment's configuration, not hardcoded (see the paragraph above this table). The specific country in which it processes is not established. We have not obtained the provider's published terms |
| What goes | Prompt text only: your typed question, record titles and statuses, ≤900-character excerpts of a record's own text, a project manager's weekly-review free text, per-tool counts, role labels. Email addresses, ABN-shaped numbers and Australian phone numbers are stripped automatically |
| What never goes | Files, documents, drawings, photos, video, signature images, full document text, and (unless two separate gates are both open) any money figure |
| Names | Not removed. A pattern-matcher cannot recognise a name. No name field is sent — not the assignee, not the creator, not the attendee, not a contact — but a record title is free text somebody typed, a title can name a person, and on a residential job the project name is often the address. See PRIVACY_POLICY.md §8.3 |
| Stored by us? | No. Nothing AI-generated is written to the database and no prompt or answer is retained. The audit trail records the shape of what was sent — provider, character count, which kinds of fact — never the text |
| Can I refuse it? | Yes, completely and permanently. A company owner switches AI off for their own company from Company → Editions, and you can tell us to do it instead, at no charge. Every AI feature falls back to a deterministic non-AI path and nothing leaves |
| Can it be brought onshore? | Yes. The provider is swappable by one configuration value, and a self-hosted local model option exists that removes the cross-border flow entirely |
What we will not tell you about that provider. The text of the prompt is sent to a third-party provider outside Australia. We do not warrant what that provider does with it, and we will not tell you that your prompt is excluded from that provider's training unless that provider's published terms say so and we have read them. We have not read them. If you require that no customer data reaches any third-party AI provider, tell us and we will keep AI features switched off for your company at no charge.
The order this happened in, stated plainly. We said we would obtain and assess the provider's published terms, and record at docsync.tech/legal/subprocessors for each provider the country in which it processes, how long it keeps API inputs and whether it uses API inputs to train models, before AI was enabled for anyone. That is not what happened: AI was switched on in the pilot first, and the assessment has not been done. The only company on the deployment is our own test company — read from the production database on 2026-08-30 — so no other DocSync customer's records have been involved. That is narrower than it sounds, and the first half of it is the only part we can evidence. Our own test company holds the names of real subcontractors, suppliers and workers; nobody has examined what personal information about those people its records contain; and we therefore do not claim that no individual's personal information has left the country. Australian Privacy Principle 8.1 requires those steps to be taken before a disclosure, not after it, and this page is not going to describe the assessment in the future tense while the disclosure is already happening.
Who turns it on, and what does not stand behind it. In the product a company owner switches AI on for their own company, from Company → Editions, after ticking a box that says the text their team types — including record titles and notes that can name workers and subcontractors — goes to the destination the server reports, that they have told those people or are otherwise permitted to share it, and that the AI provider is a setting our operator can change, including to one outside Australia. The activation is refused without that tick, so for any future activation it is the consent record, not a notice. No step in the software asks us first, and nothing in the software checks whether we have read the provider's terms. That assessment is our discipline as operator, not a control the product enforces.
And the one activation that has ever happened has no acknowledgement behind it. That tick is new. The AI entitlement on the pilot company was switched on 2026-08-24, so it predates the acknowledgement and no acknowledgement was recorded for it. There is no consent artefact standing behind the cross-border disclosure that is actually happening — only this paragraph. Anyone who asks for that artefact should be shown this sentence, not the screen.
What we do promise, because it is ours to promise: we do not use your data to train, fine-tune or improve any machine-learning model of our own, and we never will.
6. Weather and location lookup
For the daily-log weather auto-fill, our server (never your browser) calls Open-Meteo.
- This section covers two of the paths by which part of a project's location leaves: the City field and the project's stored latitude and longitude. The third is the project's own name, sent to the AI provider in a prompt — §5(3) states the list in full. That is a list, not a superlative — see the note below on why this page no longer makes a claim of the "the only thing that ever leaves" shape.
- The City field, and only when it holds a plain place name — letters plus the joiners a locality name can contain (space, hyphen, apostrophe, full stop), at most four words and 60 characters. It is sent to obtain coordinates. The address line is never a source, so there is no unit and no street number to strip: the code does not read it at all. No project name, no identifier, no key.
- A latitude and a longitude, with a date, for the weather itself. These are the coordinates stored on the project, and the project's latitude and longitude are fields a person can type into, so a dwelling-precision figure can sit there without ever having passed through the City check. Since 2026-08-31 they are rounded to two decimal places — about a kilometre — on the way out, so the request names a suburb rather than a building. The value stored on your project keeps its full precision; only the outbound copy is coarsened. Two decimal places costs nothing: the weather model's own grid is kilometres wide.
- How this got here, because the history is the reason not to trust a superlative. For three rounds the code tried to keep an absolute promise by removing what must not go — a regex, then a seven-word designator list, then a positional strip. Each was defeated by an address shape nobody had anticipated, and this page was rewritten each time to match. On 2026-08-31 the approach was inverted and the heuristics were deleted: the value is now sent only if it passes an allow-list that says what a place name is. A digit cannot leave because a value containing one is never sent, not because we tried to take one out. That fix holds; the sentence built on it did not. The fourth writing of "the only location detail that ever leaves" was falsified the same week, by the coordinate above — a path the allow-list never touched. So the superlative is gone and the list is what this page states. If we find another, it joins the list.
- The two limits. First, a street name typed into the City box does leave:
Ocean Drive Terrigalcontains no digits, so the allow-list passes it, and on a residential job that narrows a private dwelling to one street. Excluding it would need a list of street-type words, andSt,BroadwayandBeachare locality names too. Second, the cost: a City value that is not a plain place name —Parramatta NSW 2150, or a whole address typed into the box — yields no coordinates at all, so the project gets no map pin and its daily log falls back to manual weather entry. That costs a feature and discloses nothing, and it is the cheaper of the two failures. The screen that takes the City value says so where a person is typing it. - What happened before that date does not un-happen. Until 2026-08-31 a project with no City set had its address line shortened and sent, and street numbers did reach the geocoder. Projects located under the old rule are not re-geocoded, and the
project.geocodeaudit rows record the query that was sent at the time. - A project is geocoded at most once, ever — the result is stored against the project.
- The weather request sends a latitude, a longitude and a date.
- Because the call originates from our server, no end-user IP address is ever disclosed to the weather provider. This is materially better than a browser-side weather widget.
Open-Meteo is operated from Germany, according to its own published information; we have not independently verified where its servers are. Its logging and commercial terms are not established.
7. Encryption
| Layer | Status |
|---|---|
| In transit, browser → us | HTTPS with automatically issued and renewed certificates, HSTS enabled, HTTP/3 available |
| In transit, us → mail relay | STARTTLS |
| In transit, us → AI provider | HTTPS |
| Between our own containers | Plain HTTP on a private network on one host with no published ports. Not encrypted, and we are not going to call it encrypted |
| At rest — database | Not encrypted by us. No transparent data encryption, no column encryption |
| At rest — file store | Not encrypted by us. No server-side encryption configured |
| At rest — backups | Not encrypted |
| At rest — hosting platform | We do not encrypt it, and whether the hosting platform encrypts the underlying disk is a question for the hosting provider. We have not confirmed it, so we do not count it, and this page does not claim it |
In one sentence, so nobody has to add the rows up: your data is encrypted while it travels to us and it is not encrypted where it is stored: there is no transparent database encryption, no column encryption, the file store is not encrypted, and the backups are not encrypted.
And the rest of the posture, because a residency page is where a reviewer asks. There is no multi-factor authentication for anyone, including us. There is no single sign-on, no email verification at sign-up, and no anomaly detection. There is no breach detection of any kind — the clock on any incident starts when a person tells us, not when a system does. And as at the date of this document we do not hold cyber or professional indemnity insurance. We will tell you when we do.
8. Dormant paths — things that could leave, but do not
Each of these exists in the software and is fail-closed: with its configuration absent, the feature returns an error rather than working insecurely. We list them because enabling one is a configuration change rather than a new release.
| Path | Status | What would leave if enabled |
|---|---|---|
| Off-site backups (Azure Blob) | Not configured — the destination has never been set | A complete copy of the database and every file |
| 3D reconstruction GPU worker | Not configured — every worker route returns an error without its token | Full site walkthrough video files. Note: the worker queue is not scoped to one company — a single worker would receive video from every company on the deployment. A fully on-premises 3D path exists, so this is avoidable |
| Inbound email ingestion | Not configured | Would place third-party senders' addresses, subjects, bodies and attachments inside a project |
| Xero / QuickBooks export | Not configured | Vendor names, line descriptions, amounts, dates |
| Stripe billing | Inbound webhook stub only — nothing is sent to Stripe by this software | — |
We will not enable any of these without updating legal/SUBPROCESSORS.md and giving notice first.
9. What is not in the picture, and why that is worth something
- No content delivery network. No third-party host serves any asset.
- No analytics, telemetry or session replay. Not one analytics package is installed.
- No third-party error tracking. Errors go into our own database with automatic scrubbing and a 30-day maximum.
- No third-party fonts at runtime. Fonts are downloaded at build time and served from our own origin, so no visitor IP address reaches a font host.
- No log shipping. Logs stay on the host. (This is a candid trade-off: it is also why we have no centralised monitoring — see
PRIVACY_POLICY.md§9.3.)
This is enforced structurally, not by policy. The application's Content-Security-Policy blocks network connections to any host other than our own. Adding an analytics beacon would require a code change, not a setting.
10. Two things that are not data residency but get asked in the same breath
- Domain and DNS.
docsync.techis registered through get.tech, with DNS at the same provider. They see registrant details and DNS query traffic. No customer content. How the registrar handles registrant data, and whether WHOIS privacy is enabled, are not established. Separately, and not a privacy matter at all: domain auto-renew is currently switched off, which is a business-continuity risk to a service you would be depending on, and you should hear it from us. - TLS certificates. Issued by Let's Encrypt over ACME. This discloses the domain name and an administrative email address to a United States non-profit, and publishes the domain in public Certificate Transparency logs. No customer content.
11. Placeholders and open items on this page
| Item | Status |
|---|---|
[LEGAL ENTITY NAME], [ABN], [CONTACT EMAIL], [EFFECTIVE DATE] | Not yet established |
[HOSTING REGION] | Must be verified in the hosting portal before this page is published. Four things to check: (1) the virtual machine's region; (2) whether any managed disk or snapshot sits in a different region; (3) whether a backup vault is enabled, which would create a second and possibly cross-region copy; (4) whether boot diagnostics write to a storage account, and that account's region. Until (1) is confirmed this page does not assert "hosted in Australia". The deployment plan specifies australiaeast (Sydney) — but a plan is not a record |
[BACKUP_RETENTION_DAYS] | Code default yields 15. Confirm against the live schedule |
HOSTING REGION inside the diagram | The same [HOSTING REGION] placeholder, written without brackets because diagram labels cannot carry them. A search-and-replace for [HOSTING REGION] will miss it |
Four facts this page reports as "not established", which is a status and not a placeholder — a placeholder is a blank waiting on a fact that exists, and these are questions nobody has answered yet: the mail relay's processing region and retention (§4); the AI provider's jurisdiction, retention and training posture (§5, and PRIVACY_POLICY.md §8.2); the weather provider's logging and commercial terms (§6); and whether the hosting platform encrypts the underlying disk (§7). Each is stated in its own section as what we know and do not know, rather than left as a gap for a reader to discover.
End of draft. Prepared for review by an Australian legal practitioner. No corporate name, ABN, ACN or address has been inferred from the product name or the domain.