A two-sided agent workspace for Singapore homeowners and interior-design SMEs.
References, notes and practical constraints become one versioned living-room brief. AI suggestions stay proposals, conflicts stay visible, and approval is explicit.
Live demo · Quick start · How it works · Agent loop · Safety & evaluation · Deploy · Write-up (PDF) · 简体中文
A reference image does not say whether someone likes its oak, its lighting, its layout or the whole room. The same word ("warm", "hotel-like") means different things to a homeowner and a designer, and the misunderstanding usually surfaces at the first concept as another revision. AlignSpace focuses on agreement, not image generation: it keeps one explicit shared state, asks the question that removes the most uncertainty, and releases the brief only when both people approve the same version.
Note
Built by Four Wolf Kings (8QFDUS2I) for the NUS-ISS Show Me Your Agents hackathon, Design Inspiration problem (Public category). Trial prototype: demo data is synthetic, and no time-saving or ROI result is claimed yet. AlignSpace is a requirements-alignment aid, not construction, structural, electrical, regulatory or pricing advice.
Two browser sessions, synthetic data, offline note rules, sped up about 3×. Full captioned recording: python scripts/e2e_golden_path.py <url> video.
| Real Singapore inspiration Browse 57 attributed HDB, condo and landed homes, compare style cues and save up to six. Saved homes are weak evidence and never count as confirmed preferences. |
Suggestions, not decisions Notes are read through the organiser's Claude Sonnet 4.5 API, or by explicit offline keyword rules. Every result is labelled proposed until the homeowner confirms or rejects it. |
One question at a time 8 core decisions and 55 conditional follow-ups. The next question is the one with the largest expected uncertainty reduction for that person's role, in ten-question rounds you can pause. |
| Suggested next step An evidence-weighted belief per decision and a constrained policy that picks one safe action per role: ask, confirm, compare, resolve, approve or invite. The weights are hand-set and shown in the UI. |
Two sides, one state The designer joins from a private single-use link and owns layout, care and constraints. A constraint that contradicts a confirmed preference opens a conflict and blocks approval. |
Explicit approval Both people approve the same SHA-256 content hash from their own sessions, and any later edit clears both approvals. Export the brief as schema-valid JSON or print it to PDF. |
| Grounded references Local BM25 over 22 attributed design-handbook excerpts plus Getty AAT terminology. Retrieval abstains on no overlap and skips excerpts that mention must-avoid items. |
English / 中文 A persistent language switch covers the interface, the questions, the 28 housing types and bilingual search. |
Guardrails by default Prompt-injection resistant parsing, role-bound sessions, stale-write rejection, bounded model calls and an audit trail for every change. |
| Step | Homeowner | Designer | Agent |
|---|---|---|---|
| Collect | Goals, must-avoid items, notes, saved homes | — | Stores evidence with source and consent |
| Suggest | Confirms or rejects each suggestion | — | Proposes attributes from notes; never confirms |
| Ask | Style, mood, colour, material, lighting, function | Layout, maintenance | Picks the highest-value question per role |
| Align | Revises a preference if needed | Adds constraints with rationale and severity | Opens conflicts, blocks approval, never picks the trade-off |
| Approve | Approves in own session | Approves in own session | Binds both approvals to one content hash |
|
Observe → estimate → decide → check → stop.
The belief never confirms anything and is excluded from the signed brief. Every suggestion and what happened next is logged, so a policy can later be trained on real outcomes. Details: docs/22. |
| Layer | Technology and role |
|---|---|
| Web app | Vanilla JavaScript, English / Chinese, strict CSP, no keys in the browser |
| API and orchestrator | FastAPI, Pydantic; membership and role checks, typed actions, optimistic versioning, audit events |
| State | SQLite (WAL), one JSON design state per project, SHA-256 content hash for approvals |
| Reasoning | Adaptive question selection, evidence-weighted belief, constrained next-step policy, conflict and readiness checks |
| Model | Organiser Claude Sonnet 4.5 JSON API behind an adapter; schema-validated, bounded, never silently replaced by offline rules |
| Knowledge | Local BM25 over attributed handbook excerpts, Getty AAT terms, 57 attributed Singapore homes |
| Hosting | One AWS Lightsail medium instance, systemd service behind Caddy (HTTPS) |
Requires Python 3.11.
git clone https://github.com/JaspinXu/AlignSpace.git
cd AlignSpace
python -m venv .venv
# Windows: .venv\Scripts\activate macOS/Linux: source .venv/bin/activate
pip install -r requirements-dev.txt
cp .env.example .env # PowerShell: Copy-Item .env.example .env
python -m uvicorn app.main:app --reload --host 127.0.0.1 --port 8010Open http://127.0.0.1:8010. Without credentials, set ALIGNSPACE_ANALYSIS_MODE=offline: offline rules read only explicit positive keywords in notes, and the UI says so.
- Choose Start my room brief, or Try a guided sample for labelled sample notes.
- Add goals, a must-avoid item and a note, then Suggest preferences from notes. Confirm or reject each suggestion.
- Answer the questions. The side panel shows the suggested next step and how clear each decision is.
- Invite my designer and open the link in a private window: a session cannot hold both roles.
- As the designer, answer layout and care, then add a constraint that contradicts a confirmed preference and resolve the conflict.
- Approve from both sessions, then export JSON or print to PDF. Edit anything afterwards and both approvals disappear.
Configuration
Keys belong in the server-side .env only (ignored by Git and the Docker context). Real environment variables take precedence.
| Variable | Purpose |
|---|---|
LLM_GATEWAY_URL, LLM_GATEWAY_API_KEY, LLM_MODEL |
Organiser JSON API for note analysis |
ALIGNSPACE_ANALYSIS_MODE |
gateway or offline |
ALIGNSPACE_ALLOW_IMAGES |
Enable image analysis (off until a vision endpoint passes a known-image check) |
VISION_API_FORMAT, VISION_GATEWAY_URL, VISION_GATEWAY_API_KEY, VISION_MODEL |
Optional vision provider: openai, anthropic or ollama format |
ALIGNSPACE_PROJECT_RUN_LIMIT, ALIGNSPACE_DAILY_RUN_LIMIT |
Analysis caps (defaults 20 per project, 100 per rolling day; 10 s cooldown). The public deployment runs 20 and 40. |
ALIGNSPACE_DB_PATH, ALIGNSPACE_UPLOAD_DIR |
SQLite file and private upload folder |
ALIGNSPACE_SECURE_COOKIES |
true when served over HTTPS |
Each analysis uses at most 10 references and two HTTP attempts. 401/403 errors and timeouts are not retried blindly. Model calls run outside the database transaction, and results are committed only if the state version still matches.
| Risk | Control |
|---|---|
| Prompt injection | Notes, image text and retrieved text are evidence only; model output is parsed against a closed vocabulary and can only create proposed attributes |
| Over-automation | People confirm preferences, resolve conflicts and approve; critical constraints require professional review |
| Cross-project access | Possession-based HttpOnly SameSite=Strict sessions, per-project membership, role bound at invitation claim, cross-origin writes rejected |
| Replay and races | Single-use 24-hour invitations stored as digests; optimistic versioning; approvals bound to a content hash |
| Privacy | Consent required; images decoded, resized, metadata-stripped and served only to project members |
| Runaway cost | Per-project and global request caps, cooldown, bounded retries, explicit offline mode |
python -m pytest -q # 77 tests
python scripts/simulate_belief.py # belief recovery on synthetic data
# Two-session browser run (synthetic data, offline mode), writes docs/evidence/
ALIGNSPACE_ANALYSIS_MODE=offline ALIGNSPACE_DB_PATH=/tmp/e2e.db python -m uvicorn app.main:app --port 8011
python scripts/e2e_golden_path.py http://127.0.0.1:8011Every push runs the same checks in GitHub Actions: ruff, the test suite, the belief simulation and a schema check on the recorded brief.
Evidence: verification report · run results · example approved brief · evaluation plan.
The assessed build runs on the organiser-provided AWS Lightsail medium instance. From Git Bash, macOS or Linux, with the change committed:
scripts/deploy_lightsail.sh ubuntu@<PUBLIC_IP> ~/.ssh/alignspace-lightsail.pem # https://<PUBLIC_IP>.sslip.ioThe script ships git archive HEAD only (no local database, uploads or secrets). It installs a versioned release, keeps .env and data between releases, runs a hardened systemd service behind Caddy, checks /health, and rolls back if the check fails. Open ports 80 and 443 in the Lightsail firewall first. See the deployment runbook. For local Docker: docker compose up --build (port 8000).
| Area | Status |
|---|---|
| User evidence | Owner trial pending; no external homeowner–designer study, time saving or ROI result yet |
| Image understanding | Adapter ready but disabled: the organiser gateway returned NO_IMAGE on a known-image probe. Notes are analysed; images are stored privately and displayed |
| Belief and policy | Hand-set, uncalibrated weights; a constrained bandit, not a trained RL policy |
| Identity | Possession-based browser sessions; no accounts or recovery |
| Scope | Living room only; single-instance SQLite |
Project structure
app/
main.py FastAPI app, session middleware, typed endpoints
engine.py Design state, adaptive questions, conflicts, readiness, approvals
belief.py Evidence-weighted belief and constrained next-step policy
gateway.py Organiser LLM / vision adapters, bounded and schema-validated
interview.py 55 conditional detail questions (EN / 中文)
knowledge.py BM25 retrieval over attributed handbook excerpts
discovery.py Singapore home previews (parse-only, no script execution)
access.py, store.py Memberships, invitations, SQLite store and audit
static/ Web app, styles, locale data
schemas/ Design brief JSON schema
scripts/ Deploy, E2E run, belief simulation, locale build
deploy/ systemd unit and Caddyfile
tests/ 77 unit, API and regression tests
docs/ Product, agent, safety, evaluation, deployment and submission docs
evidence/ E2E results, screenshots, example brief
writeup/ Write-up source and PDF
assets/readme/ README figures
Documentation map
Documents under docs/ include design proposals that are not what runs today — for example docs/05 describes a serverless AWS target, while the assessed build is a single Lightsail instance. This README and the verification report are the current implementation record.
| Topic | Documents |
|---|---|
| Problem and scope | Official context · Product requirements · Business case |
| Experience | Research plan · Experience spec · UI design · Singapore discovery |
| Agents and data | Agent system design · Architecture · Contracts · Belief and next step |
| Knowledge and language | Grounded design knowledge · Adaptive interviews and languages |
| Safety and evaluation | Safety and privacy · Evaluation plan · Verification report · User trial |
| Delivery | Roadmap · Decision log · Assets register · Deployment runbook · Demo and pitch · Submission checklist · Submission kit |
Hackathon delivery
- Shortlisting: 28 September 2026, 09:00 SGT, posted in
#submission: team code, project name, GitHub URL, video URL, PDF write-up, deployment evidence or URL. - Finale: 10 October 2026, 08:30 SGT, face-to-face demo; finalist updates in
#final-submission. - Assessed build on one organiser Lightsail medium instance, using the organiser's inference allocation.
- Post template, organiser questions, video script and link check: submission kit.
Code is released under the MIT License. Design-handbook excerpts, Singapore listing metadata and linked images, and Getty AAT terms keep their original owners' terms: they are attributed and linked for discussion, not relicensed (see the end of LICENSE). All screenshots and demo data in this repository are synthetic.