File size: 14,903 Bytes
003d5fa
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
"""WHICH STORE THIS DEPLOYMENT IS ALLOWED TO WRITE β€” the fail-closed binding (D-315 / D-298).

β›”β›” THE SENTENCE THIS FILE EXISTS TO MAKE IMPOSSIBLE. Owner, 2026-08-18, verbatim: *"this is so
critical that whenever we do staging, we don't fuck up anyone's data. EVER."* It had already
happened once: `fsanyoto/loopable` became STAGING on 2026-08-14 having never been given a store of
its own, so two different builds wrote tenant #0's real business data. Compose that with D-305
(the store is last-write-wins at whole-document granularity) and a routine staging deploy does not
merely add test rows β€” it can erase a real user's views, fields and typed cell values.

β›” A DEPLOY FLAG IS NOT THE FIX; THE FLAG IS THE THING THAT ALREADY FAILED. The isolation that
existed was bound to a ROLE ("the staging Space"), and a guard bound to a role stops guarding the
moment the role moves β€” which these two Spaces have done twice. So the binding here is on the
container's OWN IDENTITY, which no deploy can forget to pass and no role swap can invalidate.

⭐⭐ THE RULE, AND IT CLASSIFIES THE DEPLOYMENT RATHER THAN THE REPO:

    1. the PRODUCTION deployment (identity in `PRODUCTION_SPACES`)  -> may write anything
    2. any other deployment writing a KNOWN production store        -> REFUSED
    3. any other deployment writing a repo on its OWN allowlist     -> allowed
    4. anything else                                                -> REFUSED

β›” WHY NOT CLASSIFY THE REPO, which is the design everybody reaches for first. A DENYLIST of
production stores fails OPEN for the next tenant nobody remembered to add. A SUFFIX RULE
(`*-staging-data`) pins a SPELLING rather than a claim β€” see [[gate-pins-a-spelling-not-a-claim]] β€”
and a store named without the suffix is unprotected while reading as protected. Rule 4 is the one
that survives a tenant nobody has provisioned yet: an unknown repo is refused, so a store this
deployment was never handed cannot be written by accident.

⭐⭐ AND RULE 4 IS NOT THEORETICAL β€” IT IS THE HALF OF D-315 THE REGISTER ROW DID NOT KNOW ABOUT.
Measured 2026-08-18 by reading both control planes: `royal-imports/cfo-os-staging-data`'s own
`tenants.json` is byte-identical to live's and names **`royal-imports/aios-nurilab-data`,
`aios-gtmlab-data` and `aios-loopable-data`** β€” the three other tenants' REAL stores. So
`--data-repo=` only ever isolated tenant #0; `harness/runtime.py`'s `store.for_repo(repo)` path
resolved three PRODUCTION repos out of the staging store and wrote them, and no flag has ever
touched that path. The exposure is FOUR production stores, not one.

⚠ READS ARE NOT REFUSED, AND THAT IS A DELIBERATE, STATED SCOPE DECISION. `Store.get` is lenient
by contract: a refused read would hand back `{}`, a caller would paint an empty grid, and the whole
Space would read as "no data" rather than as "refused" β€” the exact
[[empty-answer-vs-unfinished-answer]] shape this codebase has shipped before. A refused WRITE is
loud (503, with the reason). So staging still SEES production data when pointed at it; it can no
longer CHANGE it. Narrowing the read is a separate decision and is booked, not smuggled in here.

⚠ ABSENT IDENTITY FAILS CLOSED, AND THE FAILURE LOOKS LIKE AN OUTAGE. If a container exposes none
of the identity variables, it is treated as "not the production deployment" and every write to a
production store refuses. That is the safe direction, but on a live Space it would read as a total
product outage β€” which is why `describe()` reports the RAW observations and not just the verdict:
per D-160 the Space environment cannot be read from outside, so the container has to say what it
saw. One deploy then answers "does SPACE_ID exist here", instead of three.
"""
import os

#: The deployment that OWNS production data. A frozenset rather than a string because the product
#: has had two public addresses before and will again.
#:
#: ⚠ THIS SET IS DUPLICATED IN `aios-web/deploy_web.py` AS `PUBLIC_LIVE`, on purpose and with a
#: gate: `deploy_web` is a standalone CLI that must run without the platform package importable, so
#: it cannot import this. `verify_store_binding.py::section_constants` asserts the two literals
#: agree β€” a constant two features share is a constant that drifts ([[constant-two-features-share]]).
PRODUCTION_SPACES = frozenset({'fsanyoto/runloopable'})

#: The stores that hold REAL customer business data. Enumerated 2026-08-18 from the live control
#: plane (`royal-imports/cfo-os-data::tenants.json`), not guessed.
#:
#: β›” THIS LIST IS RULE 2, NOT THE WHOLE GUARD. It exists to make a DELIBERATE mis-pointing loud β€”
#: `OS_DATA_REPO=royal-imports/cfo-os-data` typed on a laptop, or a production repo added to a
#: sandbox allowlist by hand. Rule 4 is what covers a tenant provisioned after this line was
#: written, which is why the file does not depend on this staying complete.
PRODUCTION_STORES = frozenset({
    'royal-imports/cfo-os-data',            # tenant #0 β€” Royal Imports
    'royal-imports/aios-nurilab-data',      # Nurilab
    'royal-imports/aios-gtmlab-data',       # GTM Lab
    'royal-imports/aios-loopable-data',     # Loopable
})

#: The historical default of `OS_DATA_REPO`. Kept as a name so the resolution below can say what it
#: is refusing to assume, rather than repeating a literal.
PRODUCTION_DEFAULT_STORE = 'royal-imports/cfo-os-data'

#: The env vars a Hugging Face Space container sets to describe itself, in the order they are
#: trusted. `SPACE_ID` is the canonical one; the pair is the documented fallback. Read as a LIST so
#: `describe()` can report every one of them and what it held.
_IDENTITY_VARS = ('SPACE_ID', 'SPACE_AUTHOR_NAME', 'SPACE_REPO_NAME', 'SPACE_HOST')

#: The env a NON-production deployment uses to name the stores it may write, beyond `OS_DATA_REPO`.
#: Comma-separated.
#:
#: ⭐ THE POLARITY IS THE POINT, and it is what keeps trap 1 satisfied. Forgetting to set this
#: makes a deployment write LESS, never more β€” so an omitted deploy argument is a refusal, not a
#: silent grant. That is the exact inverse of `--data-repo`, whose omission printed
#: "OS_DATA_REPO unchanged" and left a Space on production.
_SANDBOX_STORES_VAR = 'AIOS_SANDBOX_STORES'

#: The local (no-identity) escape hatch. Present β‡’ writes to production stores are permitted from a
#: machine with no Space identity, AND every commit this process makes is stamped distinguishably
#: (see `local_commit_suffix`). Deliberately does NOT widen a Space: a container that HAS an
#: identity and is not production is refused with no override, because that is the case the owner
#: said "EVER" about.
_LOCAL_OPT_IN_VAR = 'AIOS_ALLOW_PRODUCTION_DATA'


class StoreWriteRefused(RuntimeError):
    """A write this deployment is not allowed to make.

    β›” DELIBERATELY NOT A SUBCLASS OF `grid_events.StoreUnavailable`, and the reason is the routes.
    Several of them carry `except StoreUnavailable:` blocks that DEGRADE to a session-scoped
    fallback workspace β€” correct for an outage, catastrophic for a refusal, because the user would
    be told the change was saved somewhere. A distinct type falls through all of them to the
    app-level handler, which answers 503 with the reason and never claims a save.
    """


def _env(name):
    return str(os.environ.get(name) or '').strip()


def deployment_id():
    """This container's own identity, or `''` when it is not a Space (i.e. local dev).

    ⚠ NOT DERIVED FROM ANY DEPLOY ARGUMENT. That is the whole design: `SPACE_ID` is set by the
    platform inside the container, so it cannot be forgotten, mistyped, or left behind by a Space
    that changed role without being redeployed.
    """
    sid = _env('SPACE_ID')
    if sid:
        return sid
    author, repo = _env('SPACE_AUTHOR_NAME'), _env('SPACE_REPO_NAME')
    if author and repo:
        return f'{author}/{repo}'
    return ''


def is_production_deployment():
    """True only on the deployment that owns production data. Unknown β‡’ False (fail closed)."""
    return deployment_id() in PRODUCTION_SPACES


def is_space():
    """True when this process is running inside a Space at all.

    The distinction matters exactly once: a Space that is not production gets NO override, while a
    laptop does. `deployment_id()` conflates them into `''`, so ask separately.
    """
    return bool(deployment_id())


def sandbox_allowlist():
    """The repos a non-production deployment may write: `OS_DATA_REPO` + `AIOS_SANDBOX_STORES`."""
    allowed = {r.strip() for r in _env(_SANDBOX_STORES_VAR).split(',') if r.strip()}
    own = _env('OS_DATA_REPO')
    if own:
        allowed.add(own)
    return frozenset(allowed)


def local_override():
    """True when a machine with no Space identity has explicitly opted in to production data."""
    return (not is_space()) and _env(_LOCAL_OPT_IN_VAR) == '1'


def default_store():
    """What `OS_DATA_REPO` resolves to when it is unset.

    β›”β›” FACT (1) OF D-315 DIES HERE: `core/store.py` used to read
    `os.environ.get('OS_DATA_REPO', 'royal-imports/cfo-os-data')`, so a Space that was never given
    the key β€” every NEW Space, by construction β€” came up bound to tenant #0's real business data.
    The default now exists ONLY on the deployment that owns it.

    ⚠ IT STILL RETURNS THE PRODUCTION ID ELSEWHERE, RATHER THAN `None` OR `''`, AND THAT IS
    DELIBERATE. A `None` repo would make `Store.__init__` β€” which runs at IMPORT time via
    `_DEFAULT = for_repo(REPO)` β€” raise or bind something nonsensical, killing the app and every
    gate on any non-production machine. Returning the real id keeps binding total and lets
    `write_refusal` refuse the WRITE with a message that names the actual problem. Reads still
    work, so a developer sees a populated app that will not let them damage it.
    """
    return PRODUCTION_DEFAULT_STORE


def write_refusal(repo):
    """`None` if this deployment may write `repo`, else the sentence explaining why not.

    ⭐ RETURNS A REASON RATHER THAN A BOOL, because [[report-the-cause-before-you-fix-it]]: a
    silent refusal makes every theory about it unfalsifiable, and this one fires on a path where
    the operator cannot read the container's environment (D-160).
    """
    rid = str(repo or '').strip()
    if not rid:
        return ('no store repo is bound. Refusing to guess: an unnamed store is how a deployment '
                'ends up on somebody else\'s data.')
    if is_production_deployment():
        return None                                   # rule 1 β€” the live Space owns its data
    if rid in PRODUCTION_STORES:                      # rule 2 β€” never, from anywhere else
        if local_override():
            return None
        who = deployment_id() or 'this machine (no Space identity)'
        if is_space():
            return (f'{who} is not the production deployment, so it may not write {rid}, which '
                    f'holds real customer data. Point this Space at its own store with '
                    f'--data-repo=, or add it to {_SANDBOX_STORES_VAR}. There is no override for '
                    f'a Space: a build that is not live never writes live data.')
        return (f'{who} may not write {rid}, which holds real customer data. Set OS_DATA_REPO to a '
                f'sandbox store, or set {_LOCAL_OPT_IN_VAR}=1 to opt in deliberately (every commit '
                f'is then stamped as a local write so it can be told apart afterwards).')
    allow = sandbox_allowlist()                       # rule 3 β€” what it was explicitly handed
    if rid in allow:
        return None
    who = deployment_id() or 'this machine (no Space identity)'
    listed = ', '.join(sorted(allow)) or '(nothing)'
    return (f'{who} was not given {rid}. A non-production deployment may write only the stores it '
            f'was handed: {listed}. Add it to {_SANDBOX_STORES_VAR} if that is intended.')


def check_write(repo, operation='write'):
    """Raise `StoreWriteRefused` unless this deployment may write `repo`. The one enforcement door."""
    reason = write_refusal(repo)
    if reason:
        raise StoreWriteRefused(f'{operation} to {repo!r} refused: {reason}')


def local_commit_suffix():
    """A marker appended to commit messages made under the local override, else `''`.

    ⭐ THIS IS THE SECOND HALF OF D-298's EXIT CONDITION, satisfied rather than argued around: *"a
    local run either cannot reach the live store without an explicit opt-in, OR stamps its commits
    distinguishably"*. The measured complaint was that a laptop's commits were titled
    `update user_tables` β€” byte-identical to what the live Space writes every few minutes β€” so a
    local run and production were indistinguishable in the store's git history, which is the ONLY
    audit trail this product has. Both clauses now hold: the opt-in is required AND it stamps.
    """
    if not local_override():
        return ''
    import getpass                                   # noqa: PLC0415 β€” only on the opt-in path
    import socket                                    # noqa: PLC0415
    try:
        who = getpass.getuser()
    except Exception:                                # noqa: BLE001
        who = 'unknown'
    try:
        host = socket.gethostname()
    except Exception:                                # noqa: BLE001
        host = 'unknown'
    return f' [LOCAL DEV {who}@{host}]'


def describe(repo=None):
    """What this container sees about itself β€” the payload behind the status field.

    β›” IT REPORTS THE RAW OBSERVATIONS, NOT ONLY THE VERDICT, and that is the point rather than
    debug noise. D-160 established that a Space's environment cannot be read from outside, so
    "is staging on the right store?" is a question only the container can answer. A verdict alone
    ("production: false") cannot distinguish "SPACE_ID says staging" from "SPACE_ID does not exist
    on this platform at all" β€” two states with the same verdict and completely different fixes.
    Reporting the variables makes ONE deploy answer it.

    ⚠ Carries no secret: a Space id and a dataset repo id are public names. The DATA is not, and
    none of it is here. The field is session-gated anyway (see `routes_admin.settings`).
    """
    rid = str(repo or '').strip()
    return {
        'deployment': deployment_id(),
        'production': is_production_deployment(),
        'repo': rid,
        'writable': write_refusal(rid) is None if rid else False,
        'refusal': write_refusal(rid) if rid else None,
        'localOverride': local_override(),
        'allowlist': sorted(sandbox_allowlist()),
        # The raw half. `''` means "the variable is absent", which is itself the answer on a
        # platform that does not set it.
        'observed': {name: _env(name) for name in _IDENTITY_VARS},
    }