Some checks failed
Use-case regression gate / usecase-regressions (push) Failing after 6m58s
Assistant: codex Assistant-Model: gpt-6-astra Assistant-Session: 01a18e2d-f513-7742-b8e7-12af0b744ff3
220 lines
8.9 KiB
Markdown
220 lines
8.9 KiB
Markdown
# Bubble auth for automated export (CSOC-WP-0001-T02)
|
|
|
|
## Do not put credentials in chat or git
|
|
|
|
| Artefact | Where it belongs |
|
|
|----------|------------------|
|
|
| Email / password | Local `0600` files and/or OpenBao — **never** chat, PRs, workplans |
|
|
| Playwright `storage-state.json` | `~/.config/coulomb-social/auth/` mode `0600` (gitignored) |
|
|
| Export dumps | Local under auth dir or `docs/migration/samples/_local/` (gitignored) |
|
|
|
|
Agents will **not** accept a password pasted into the conversation. That would
|
|
land secrets in session logs.
|
|
|
|
## What a member session can do
|
|
|
|
With **your coulomb.social member** login, automation can:
|
|
|
|
- Open authenticated Bubble routes (`/vw_pages`, `/vw_spaces`, …)
|
|
- Capture HTML/text/screenshots for mapping
|
|
- Intercept browser network calls (sometimes useful for JSON payloads)
|
|
|
|
A **member** session usually **cannot**:
|
|
|
|
- Full Bubble **editor** data-type field export
|
|
- Admin “export all data” unless your account is an app admin with that power
|
|
|
|
If you need full schema dumps, use Bubble editor as the same human, or grant
|
|
editor access to a dedicated automation identity (still via OpenBao, not chat).
|
|
|
|
## Path A — Interactive session (recommended if MFA/CAPTCHA)
|
|
|
|
On the workstation:
|
|
|
|
```bash
|
|
cd ~/coulomb-social
|
|
./scripts/capture-auth-state.sh
|
|
```
|
|
|
|
1. Browser opens `https://coulomb.social`.
|
|
2. Log in as **you**.
|
|
3. Open a real app surface (e.g. Research / Pages — not only the landing root).
|
|
4. Press **Enter** in the terminal.
|
|
|
|
Session file:
|
|
|
|
```text
|
|
~/.config/coulomb-social/auth/storage-state.json # mode 0600
|
|
```
|
|
|
|
Probe (should **not** stay on bare `/` if login worked):
|
|
|
|
```bash
|
|
cd ~/coulomb-social/scripts
|
|
node ./probe-auth-session.mjs
|
|
# expect something like …/vw_pages or another app path
|
|
```
|
|
|
|
Then:
|
|
|
|
```bash
|
|
./scripts/export-bubble-session.sh
|
|
```
|
|
|
|
## Path B — Password files (only if no interactive MFA)
|
|
|
|
You write secrets **yourself** on disk (agent never sees the values in chat):
|
|
|
|
```bash
|
|
AUTH="$HOME/.config/coulomb-social/auth"
|
|
mkdir -p "$AUTH"
|
|
chmod 700 "$AUTH"
|
|
|
|
# Replace with your real values — run in your terminal only
|
|
printf '%s' 'your@email.example' > "$AUTH/email"
|
|
printf '%s' 'your-password-here' > "$AUTH/password"
|
|
chmod 600 "$AUTH/email" "$AUTH/password"
|
|
|
|
cd ~/coulomb-social
|
|
./scripts/capture-auth-state.sh --from-password-files
|
|
# If Bubble shows MFA/CAPTCHA, fall back to Path A.
|
|
```
|
|
|
|
Optional OpenBao (when CCR/policy applied — see `docs/design-extract-auth.md`):
|
|
|
|
```text
|
|
tenants/binky/coulomb-social/bubble-member → EMAIL, PASSWORD
|
|
```
|
|
|
|
## Path C — Keep session warm for agents
|
|
|
|
Once `storage-state.json` exists and probe looks authenticated:
|
|
|
|
1. Tell the agent: *“Session is captured under the default XDG auth path; run export.”*
|
|
2. Do **not** paste the file contents.
|
|
3. Re-run `capture-auth-state.sh` when the session expires (probe lands on `/` only).
|
|
|
|
Agents with local filesystem access can then run export without further human
|
|
login **until cookies die**.
|
|
|
|
## Export outputs
|
|
|
|
Default dump directory (not for commit of raw HTML):
|
|
|
|
```text
|
|
~/.config/coulomb-social/auth/exports/YYYYMMDD-HHMMSS/
|
|
probe-url.txt
|
|
routes/
|
|
network/
|
|
SUMMARY.md
|
|
```
|
|
|
|
Redacted notes for the repo go under `docs/migration/` after review.
|
|
|
|
## Security checklist
|
|
|
|
- [ ] Secrets only in `~/.config/coulomb-social/auth/` (700/600)
|
|
- [ ] No password in chat, Slack, or git
|
|
- [ ] No `storage-state.json` committed (`.gitignore`)
|
|
- [ ] Prefer a **dedicated** Bubble user with least privilege if this becomes long-lived automation
|
|
- [ ] Rotate password if it was ever pasted into an unsafe channel
|
|
|
|
## Related
|
|
|
|
- `docs/design-extract-auth.md` — designlang / OpenBao detail
|
|
- `scripts/capture-auth-state.sh`
|
|
- `scripts/export-bubble-session.sh`
|
|
- CSOC-WP-0001-T02
|
|
|
|
## Targeted fresh first-use-case capture
|
|
|
|
For the nominated ReichelAg transfer, use explicit target mode after renewing
|
|
the session. This excludes August seed data, selects the space in the Pages
|
|
filter then applies Search, rejects expired signature cookies, and refuses
|
|
a one-page or body-incomplete target. A captured tree still needs reconciliation
|
|
against the latest expected protocol and private membership map before import.
|
|
|
|
```bash
|
|
COULOMB_SOCIAL_TARGET_SPACE_LABEL=ReichelAG node scripts/export-bubble-corpus.mjs
|
|
```
|
|
|
|
Set COULOMB_SOCIAL_CORPUS_DIR to a private directory if needed. Do not put raw
|
|
exports in the checkout. Default target route is /vw_pages; override via
|
|
COULOMB_SOCIAL_CAPTURE_ROUTE only after confirming the actual authenticated
|
|
protocol surface. A successful public-route load is not authentication proof.
|
|
|
|
|
|
## Retained Visual capture and review bundle
|
|
|
|
The October31 all-space bundle now has a separate private Visual preparation at
|
|
`~/.config/coulomb-social/auth/exports/visual-bundle-20261031`. The original
|
|
`review-bundle-20261031` remains unchanged.242Visual references were captured from
|
|
108URLs on the one recorded Bubble CDN, producing90distinct images.236draft
|
|
article pages and67space indexes link local hashed assets. All90images decode in
|
|
an offline browser; this is not a source/product appearance verdict or an import.
|
|
|
|
The reusable collector is `scripts/capture-bubble-visuals.py ORIGINAL --output NEW`.
|
|
It requires a complete hash-bound original bundle, a new private directory outside
|
|
repositories, and the exact known CDN over HTTPS. It refuses redirects, alternate
|
|
origins, credentials in URLs, active/unknown image formats, source drift, oversized
|
|
responses and existing output. No stored browser credentials are read or sent.
|
|
A missing final reconciliation.json means partial output, which must be retained
|
|
for review rather than used as an import bundle. Original body/date bytes are not
|
|
rewritten; only the compiler's empty Visual metadata is replaced.
|
|
|
|
Verification for the completed bundle (read-only):
|
|
|
|
```bash
|
|
python3 scripts/verify-bubble-visual-preservation.py \
|
|
~/.config/coulomb-social/auth/exports/review-bundle-20261031 \
|
|
~/.config/coulomb-social/auth/exports/visual-bundle-20261031
|
|
node scripts/verify-bubble-visuals.mjs \
|
|
~/.config/coulomb-social/auth/exports/visual-bundle-20261031
|
|
```
|
|
|
|
Only aggregate results belong in Git/chat. Images, titles, source URLs and original
|
|
records remain private. The new bundle retains all71spaces and the existing
|
|
graph/grant/fidelity gates.18body links and one attachment flag are still
|
|
unreconciled. Captured Visual bytes do not authorize copying memberships or
|
|
productive import. Public proof: docs/release/bubble-visual-preparation-2026-10-31.json.
|
|
|
|
## Private access reconciliation
|
|
|
|
`scripts/audit-bubble-access.py ORIGINAL NEW_PRIVATE_DIRECTORY` inventories the
|
|
retained source ownership, membership and visibility fields without proposing
|
|
target grants. It requires private, hash-bound source snapshots and refuses
|
|
source drift, symlinks, public files, hard links, existing output and output
|
|
inside the original bundle or this repository. The JSON and escaped, network-free
|
|
HTML review are private; stdout contains aggregate counts and hashes only.
|
|
|
|
The October 31 review is at
|
|
`~/.config/coulomb-social/auth/exports/access-review-20261031/index.html`.
|
|
It covers 70 fresh spaces, 245 article records and one inventory-only space.
|
|
Three distinct source account references remain to be linked through authoritative
|
|
identity evidence. Nine creator references are unresolved. A missing source
|
|
membership field is unknown, not an empty list. Source role names and visibility
|
|
values are preserved for review; no equivalence with target owner/member/viewer
|
|
permissions is assumed. The accepted ReichelAG owner grant remains evidence for
|
|
that cohort alone. See `docs/release/bubble-access-audit-2026-10-31.json`.
|
|
|
|
## Body links and deferred scrap relations
|
|
|
|
`scripts/verify-bubble-body-resources.py ORIGINAL VISUAL --output PRIVATE_JSON`
|
|
checks source hashes, recompiles original draft bytes, checks prepared bodies and
|
|
compares reference attributes before and after the product sanitizer. It neither
|
|
fetches destinations nor changes source files. Its stdout receipt contains only
|
|
aggregate counts and hashes. Raw references and deferred scrap descriptors belong
|
|
in the separate private report, outside both bundles and the checkout.
|
|
|
|
The October 31 proof verifies 18 distinct body-link entries with 28 occurrences,
|
|
all preserved by the product renderer. It also verifies 242 source bodies and 236
|
|
prepared pages. This does not prove remote availability or Bubble appearance.
|
|
Four `_list_custom_scrap` values are deferred strings, not captured record lists;
|
|
the compiler now preserves them as unresolved review flags instead of silently
|
|
omitting them. Explicit empty lists remain distinct from missing or deferred data.
|
|
These four records and the separate attachment-flagged article still need source
|
|
recovery or disposition. Do not interpret the strings as article IDs or infer
|
|
that the attachment flag enumerates all resources. The supplemental report is
|
|
`~/.config/coulomb-social/auth/exports/body-resources-20261031.json`; the existing
|
|
original and Visual bundle receipts remain unchanged. Public proof:
|
|
`docs/release/bubble-body-resources-2026-10-31.json`.
|