Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion .github/ISSUE_TEMPLATE/bug_report.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@ body:
attributes:
value: |
Thanks for taking the time to report a bug. Please fill in the
details below so we can reproduce and fix it quickly.
details below so the community can reproduce and evaluate it.

FTW Community has no guaranteed response or resolution time. Do not
include credentials, access tokens, private keys, or unredacted
configuration and energy data.
- type: textarea
id: what-happened
attributes:
Expand Down
6 changes: 6 additions & 0 deletions .github/ISSUE_TEMPLATE/config.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
blank_issues_enabled: false
contact_links:
- name: Community support policy
url: https://github.com/srcfl/ftw/blob/master/SUPPORT.md
about: Read what community support covers, how to ask for help, and where commercial support begins.
- name: Discussions
url: https://github.com/srcfl/ftw/discussions
about: Questions, ideas, and open-ended conversation belong here. Issues are for concrete bugs and feature requests.
- name: FTW Discord
url: https://discord.gg/25xcBzQaux
about: Join the community for setup questions, driver work, and peer-to-peer help.
32 changes: 28 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,14 @@ optional full mathematical optimizer uses Python/CVXPY; official containers
include that runtime and native installs fall back safely to the Go planner when
it is unavailable.

FTW is maintained by Sourceful Labs AB and project contributors. It is a
self-hosted open-source project, not a hosted Sourceful service; the local
control path does not depend on Sourceful cloud services.
FTW Community is maintained by Sourceful Energy (Sourceful Labs AB) and project
contributors. It is a self-hosted open-source project, not a hosted Sourceful
service; the local control path does not depend on Sourceful cloud services.

The Community edition is free under Apache-2.0 and comes without official
support or service-level commitments. Help is provided by the community on a
best-effort basis. Sourceful offers separate commercial services for teams that
need supported deployments, integrations, fleet operations, or an SLA.

> **Upgrading an existing Forty Two Watts installation?** Follow the
> step-by-step [legacy upgrade guide in Swedish and English](docs/upgrade-from-legacy.md).
Expand Down Expand Up @@ -253,11 +258,30 @@ first boot, so application patch releases do not rebuild the base OS image.
Do not hand-edit `CHANGELOG.md` or manually bump `package.json`; pending
release notes live in `.changeset/*.md`.

## Community
## Community and Support

- Discord: [discord.gg/25xcBzQaux](https://discord.gg/25xcBzQaux)
- Discussions: [github.com/srcfl/ftw/discussions](https://github.com/srcfl/ftw/discussions)
- Issues: [github.com/srcfl/ftw/issues](https://github.com/srcfl/ftw/issues)

FTW Community is built in public. Bug reports, driver improvements,
documentation, tests, and pull requests are welcome. Community channels do not
carry guaranteed response times and are not a substitute for operational
support. See [`SUPPORT.md`](SUPPORT.md) for the support boundary and responsible
ways to ask for help.

## Commercial Deployments

Apache-2.0 permits commercial use of FTW Community; no separate license is
required to use the open-source code. Sourceful's commercial offering is for
organizations that need more than the community project provides: deployment
and integration work, fleet and managed operations, long-term maintenance,
certified device support, or contractual support and service levels.

Contact [Sourceful Energy](https://www.sourceful.energy/contact) to scope a
supported deployment. The open-source and commercial model is recorded in
[`docs/adr/0004-community-and-commercial-model.md`](docs/adr/0004-community-and-commercial-model.md).

## License

Licensed under the Apache License, Version 2.0 — see [`LICENSE`](LICENSE) and
Expand Down
47 changes: 47 additions & 0 deletions SUPPORT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# FTW support

FTW Community is a self-hosted, Apache-2.0-licensed project maintained by
Sourceful Energy (Sourceful Labs AB) and project contributors.

## Community support

The Community edition is provided as-is, without official support, guaranteed
response times, service-level commitments, or warranties. The Apache-2.0
license contains the complete warranty and liability terms.

Use the public community channels for help:

- ask setup and usage questions in the
[FTW Discord](https://discord.gg/25xcBzQaux);
- use [GitHub Discussions](https://github.com/srcfl/ftw/discussions) for
searchable questions, ideas, and open-ended technical conversation;
- report reproducible bugs and request features in
[GitHub Issues](https://github.com/srcfl/ftw/issues);
- propose fixes, drivers, tests, and documentation through pull requests.

Maintainers and community members may help on a best-effort basis. A question
may receive no response, and a fix may not arrive on a particular schedule.
Never post credentials, private keys, access tokens, unredacted configuration,
or personally identifying energy data in a public channel.

## What the community project does not include

Community support does not include remote troubleshooting of a live site,
deployment ownership, device certification, custom integration work, upgrade
guarantees, incident response, or an SLA. Operators remain responsible for
their installation, configuration, electrical safety, backups, and recovery.

## Commercial support

Sourceful offers separately scoped commercial services for organizations that
need a supported deployment. These can include architecture and rollout,
custom integrations, fleet and managed operations, long-term maintenance,
certified device support, and contractual support or service levels.

Commercial services are separate from the Apache-2.0 license. The license
already permits commercial use of FTW Community; purchasing support is about a
supported outcome and additional Sourceful services, not permission to use the
open-source code.

Contact [Sourceful Energy](https://www.sourceful.energy/contact) to discuss a
commercial deployment.
69 changes: 69 additions & 0 deletions docs/adr/0004-community-and-commercial-model.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# ADR 0004 — Community and commercial model

- Status: Accepted (2026-07-17)
- Extends: [ADR 0002](0002-ftw-name-and-sourceful-stewardship.md)

## Context

FTW is part of Sourceful Energy and is intended to grow as a community-driven
home energy management project. Home users need a complete, useful, local-first
system they can run and improve without depending on a hosted Sourceful control
path. Sourceful also needs a clear commercial offer for organizations that
require delivery ownership, fleet operations, integrations, or contractual
support.

A non-commercial restriction would conflict with the Open Source Definition
and with the project's existing Apache-2.0 license. Apache-2.0 permits use,
modification, distribution, and commercial offerings subject to its terms. The
project therefore cannot simultaneously remain Apache-2.0 open source and
require every commercial user to purchase a license.

## Decision

FTW uses an open-core business model with a genuinely open-source Community
edition.

### FTW Community

- remains licensed under Apache-2.0;
- includes the local runtime, dashboard, optimizer interfaces, device drivers,
public APIs, and community integrations shipped in this repository;
- is useful as a self-hosted HEMS without a mandatory Sourceful cloud service;
- is maintained by Sourceful Energy (Sourceful Labs AB) and project
contributors;
- accepts community issues and pull requests under the existing DCO process;
- is provided as-is with community support only, without official support,
guaranteed response times, warranties, or an SLA.

### Sourceful commercial offering

Sourceful may separately sell supported deployments and capabilities such as
integration and rollout work, fleet and managed operations, long-term
maintenance, certified device support, white-label or OEM delivery, and
contractual support or service levels.

Commercial services do not change the rights granted by Apache-2.0. A company
may use FTW Community commercially without purchasing a license. The paid offer
provides additional software or services and an accountable delivery
relationship; it is not a fee for permission to use the Community code.

New commercial-only functionality must live behind an explicit repository,
package, service, or distribution boundary and carry its own license terms. It
must not be presented as part of the Apache-2.0 Community edition.

## Consequences

- FTW can be described without qualification as open source.
- Community contributors and adopters get predictable Apache-2.0 rights.
- Sourceful cannot prevent a third party from building a commercial offering
from the Apache-licensed code, although trademark and endorsement rules still
apply.
- Sourceful differentiates through enterprise capabilities, managed services,
official support, operational experience, and the FTW/Sourceful brands.
- Previously released Apache-2.0 code remains available under that license.
- Public project copy must say "community support only" rather than imply that
commercial use requires a separate software license.

If preventing third-party commercial use becomes more important than remaining
open source, that would require a new decision and a source-available license
for future releases. It must not be described as Apache-2.0 or OSI open source.
159 changes: 159 additions & 0 deletions docs/website-cutover.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
# FTW website cutover

This runbook moves the public project website from `fortytwowatts.com` to
`ftw.sourceful.energy`. It does not migrate owner access, WebAuthn credentials,
the relay, or TURN.

## Safety boundary

Only these website hosts are in scope:

- `fortytwowatts.com`
- `www.fortytwowatts.com`
- `ftw.sourceful.energy`

Do not redirect, delete, or change the security identity of:

- `home.fortytwowatts.com`
- `relay.fortytwowatts.com`
- any other `fortytwowatts.com` subdomain

`home.fortytwowatts.com` remains the WebAuthn RP ID until the separate passkey
migration is designed, rolled out, and observed. A redirect rule matching
`*.fortytwowatts.com` is therefore unsafe.

## Observed state on 2026-07-17

- `fortytwowatts.com` and `www.fortytwowatts.com` resolve through Cloudflare.
- The legacy public website returns `200` and is served through AWS
Amplify/CloudFront.
- `home.fortytwowatts.com` and `relay.fortytwowatts.com` still resolve through
Cloudflare.
- The public website repository has been transferred to `srcfl/ftw-web`.
- Cloudflare Pages project `ftw` is Git-integrated with `srcfl/ftw-web`; its
production branch is `main` and the production deployment is active at
`ftw-613.pages.dev`.
- `ftw.sourceful.energy` has been registered as a Pages custom domain, but is
pending because the required CNAME record has not yet been created.
- `ftw.sourceful.energy`, `relay.ftw.sourceful.energy`, and
`turn.ftw.sourceful.energy` do not currently resolve.

Re-run every observation immediately before cutover. DNS and cloud state can
change independently of this repository.

## Phase 1 — publish the canonical site

The repository transfer, product-story merge, Git-integrated Pages project,
and production deployment are complete.

1. In the `sourceful.energy` Cloudflare zone, create this DNS record:

| Type | Name | Target | Proxy |
|---|---|---|---|
| CNAME | `ftw` | `ftw-613.pages.dev` | Proxied |

The Pages custom-domain association must exist before creating the CNAME;
it already exists for `ftw.sourceful.energy`.
2. Wait until the Pages custom domain reports `active` and verify the issued
certificate covers `ftw.sourceful.energy`.
3. Verify the canonical site before creating any redirect from the legacy
domain.

Cloudflare documents Git-connected Pages projects and custom domains here:

- <https://developers.cloudflare.com/pages/get-started/git-integration/>
- <https://developers.cloudflare.com/pages/configuration/custom-domains/>

## Phase 2 — verify the canonical site

Do not redirect the legacy site until all of these pass:

```bash
curl -fsSIL https://ftw.sourceful.energy/
curl -fsSL https://ftw.sourceful.energy/ | rg \
'FTW|Apache-2.0|Community support only|Sourceful Energy'
```

Verify in a browser on desktop and mobile:

- canonical URL, title, description, Open Graph, Twitter, and JSON-LD use
`ftw.sourceful.energy` and `srcfl/ftw`;
- the page contains no active Forty Two Watts, 42W, `frahlg`, or MIT project
claims;
- installation commands use `srcfl/ftw`;
- community support is explicitly best-effort with no SLA;
- the commercial call to action sells a supported outcome, not permission to
use Apache-2.0 code;
- the visual language follows <https://design.sourceful.energy/DESIGN.md>;
- internal anchors and the GitHub, Discord, support, license, trademark, and
Sourceful contact links work;
- no browser console errors or horizontal mobile overflow are present.

## Phase 3 — redirect only the legacy website hosts

Create two Cloudflare Single Redirect rules. Do not use an include-subdomains
option and do not use a wildcard hostname to the left of
`fortytwowatts.com`.

### Apex rule

- Request wildcard: `http*://fortytwowatts.com/*`
- Target wildcard: `https://ftw.sourceful.energy/${2}`
- Status: `301`
- Preserve query string: enabled

### WWW rule

- Request wildcard: `http*://www.fortytwowatts.com/*`
- Target wildcard: `https://ftw.sourceful.energy/${2}`
- Status: `301`
- Preserve query string: enabled

Cloudflare documents this exact path- and query-preserving hostname pattern at
<https://developers.cloudflare.com/rules/url-forwarding/examples/redirect-all-different-hostname/>.

If Cloudflare offers a combined custom-expression rule instead, its match must
still be equivalent to:

```text
http.host in {"fortytwowatts.com" "www.fortytwowatts.com"}
```

It must not match `home.fortytwowatts.com` or `relay.fortytwowatts.com`.

## Phase 4 — cutover verification

```bash
curl -sSI https://fortytwowatts.com/
curl -sSI 'https://fortytwowatts.com/docs/example?from=legacy'
curl -sSI https://www.fortytwowatts.com/
curl -sSI https://home.fortytwowatts.com/
curl -sSI https://relay.fortytwowatts.com/
```

Expected results:

- the first three requests return one permanent redirect to the canonical FTW
host, preserving path and query;
- `home.fortytwowatts.com` and `relay.fortytwowatts.com` do not redirect to the
marketing site;
- `ftw.sourceful.energy` returns the canonical page directly without a loop;
- TLS is valid on every retained host.

After DNS caches have settled, submit the new canonical URL and sitemap to the
search consoles in use and update external project profiles that still point at
the legacy apex.

## Rollback

1. Disable the two Cloudflare Single Redirect rules.
2. Confirm `fortytwowatts.com` and `www.fortytwowatts.com` once again return the
previous Amplify deployment.
3. Leave the `ftw.sourceful.energy` Pages custom domain online while diagnosing
it unless it is itself causing the incident.
4. Do not alter `home.fortytwowatts.com` as part of website rollback.

Keep the previous Amplify deployment available until the canonical site and
redirects have been stable through at least one DNS TTL and one normal release
cycle. After that observation period, delete the legacy Amplify domain
association and app as a separate cleanup step.
Loading