diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 95786770..cb99e617 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -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: diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 110bdbf5..11c076b0 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -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. diff --git a/README.md b/README.md index 74f28c2c..176c283e 100644 --- a/README.md +++ b/README.md @@ -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). @@ -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 diff --git a/SUPPORT.md b/SUPPORT.md new file mode 100644 index 00000000..dd48dffa --- /dev/null +++ b/SUPPORT.md @@ -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. diff --git a/docs/adr/0004-community-and-commercial-model.md b/docs/adr/0004-community-and-commercial-model.md new file mode 100644 index 00000000..3027d0d6 --- /dev/null +++ b/docs/adr/0004-community-and-commercial-model.md @@ -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. diff --git a/docs/website-cutover.md b/docs/website-cutover.md new file mode 100644 index 00000000..d0b96fa0 --- /dev/null +++ b/docs/website-cutover.md @@ -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: + +- +- + +## 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 ; +- 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 +. + +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.